summaryrefslogtreecommitdiffstats
path: root/lemote/gnewsense/tags/2.6.32-libre-lemote_0lxo
diff options
context:
space:
mode:
authorAlexandre Oliva <lxoliva@fsfla.org>2009-12-19 03:00:00 +0000
committerAlexandre Oliva <lxoliva@fsfla.org>2009-12-19 03:00:00 +0000
commit4afcc01dea725c1f751c84d10f11c50b9069f7ef (patch)
tree8fb552f7df593ae3d037371c270bce57a3152491 /lemote/gnewsense/tags/2.6.32-libre-lemote_0lxo
parent17e4c337b24f2716f5530ef98b5efd7ccc99b485 (diff)
downloadlinux-libre-raptor-4afcc01dea725c1f751c84d10f11c50b9069f7ef.tar.gz
linux-libre-raptor-4afcc01dea725c1f751c84d10f11c50b9069f7ef.zip
2.6.32-libre-lemote_0lxo
Diffstat (limited to 'lemote/gnewsense/tags/2.6.32-libre-lemote_0lxo')
-rw-r--r--lemote/gnewsense/tags/2.6.32-libre-lemote_0lxo/2.6.32-loongson.patch77830
-rw-r--r--lemote/gnewsense/tags/2.6.32-libre-lemote_0lxo/2.6.32-yeeloong-battery.patch401
-rw-r--r--lemote/gnewsense/tags/2.6.32-libre-lemote_0lxo/freedo.patch5273
-rw-r--r--lemote/gnewsense/tags/2.6.32-libre-lemote_0lxo/lxo-config.patch2236
-rw-r--r--lemote/gnewsense/tags/2.6.32-libre-lemote_0lxo/series4
5 files changed, 85744 insertions, 0 deletions
diff --git a/lemote/gnewsense/tags/2.6.32-libre-lemote_0lxo/2.6.32-loongson.patch b/lemote/gnewsense/tags/2.6.32-libre-lemote_0lxo/2.6.32-loongson.patch
new file mode 100644
index 000000000..8ec37ef8a
--- /dev/null
+++ b/lemote/gnewsense/tags/2.6.32-libre-lemote_0lxo/2.6.32-loongson.patch
@@ -0,0 +1,77830 @@
+This is a git diff between the non-Free Linux upstream release
+and the corresponding branch maintained by Lemote.
+
+It doesn't pass 2.6.32-libre's deblob-check, but it's all false
+positives. - lxoliva 2009-12-12
+
+diff --git a/Makefile b/Makefile
+index f5cdb72..1f6a8e2 100644
+--- a/Makefile
++++ b/Makefile
+@@ -180,7 +180,7 @@ SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
+ # Default value for CROSS_COMPILE is not to prefix executables
+ # Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile
+ export KBUILD_BUILDHOST := $(SUBARCH)
+-ARCH ?= $(SUBARCH)
++ARCH ?= mips
+ CROSS_COMPILE ?=
+
+ # Architecture as present in compile.h
+@@ -221,8 +221,8 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
+
+ HOSTCC = gcc
+ HOSTCXX = g++
+-HOSTCFLAGS = -Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer
+-HOSTCXXFLAGS = -O2
++HOSTCFLAGS = -Wall -Wmissing-prototypes -Wstrict-prototypes -O3 -fomit-frame-pointer
++HOSTCXXFLAGS = -O3
+
+ # Decide whether to build built-in, modular, or both.
+ # Normally, just do built-in.
+@@ -523,7 +523,7 @@ all: vmlinux
+ ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
+ KBUILD_CFLAGS += -Os
+ else
+-KBUILD_CFLAGS += -O2
++KBUILD_CFLAGS += -O3
+ endif
+
+ include $(srctree)/arch/$(SRCARCH)/Makefile
+diff --git a/README.linux-4-loongson b/README.linux-4-loongson
+new file mode 100644
+index 0000000..091ac92
+--- /dev/null
++++ b/README.linux-4-loongson
+@@ -0,0 +1,155 @@
++
++ About Linux For Loongson
++
++ author: falcon <wuzhangjin@gmail.com>
++ update: Mon Nov 23 13:56:47 CST 2009
++
++(This file is only for linux 2.6.32 and later version)
++
++1. Loongson
++
++Please refer to README.loongson
++
++2. Lemote
++
++Please refer to README.loongson
++
++3. Linux for Loongson
++
++3.1 Introduction
++
++This git repository: git://dev.lemote.com/rt4ls.git is maintained by "Wu
++Zhangjin" <wuzhangjin@gmail.com>, and plan to support all of the loongson
++family machines, but now, it only support parts of them. and the main aim of
++this git repository is pushing the loongson support into the mainline.
++
++Supported(made by Lemote):
++
++ FuLoong-2E Mini PC
++ FuLoong-2F Mini PC
++ MengLoong-2F(7'') netbook
++ YeeLoong-2F(8.9'',10'') netbook
++ Network Attached System
++ LynLoong ALLINONE machine
++
++plan to Support:
++
++ Gdium
++
++3.2 Configuration
++
++default config file for the supported machines:
++
++FuLoong-2E Mini PC: arch/mips/configs/fuloong2e_defconfig
++All Lemote 2F family machines: arch/mips/configs/lemote2f_defconfig
++
++$ cp /path/to/xxxx_defconfig .
++$ make menuconfig
++
++3.3 Compiling
++
++Local compiling
++
++$ make -j2
++
++Cross Compiling
++
++Download existing Toolchains
++
++Gcc 3.4.6: http://www.lemote.com/upfiles/gcc-3.4.6-newbin.tar.gz
++Gcc 4.3: http://www.lemote.com/upfiles/gcc-4.3-cross-loongson.tar.gz
++Gcc 4.4: ftp://mirror.lzu.edu.cn/software/loongson/toolchain/gcc-4.4-cross-toolchain-loongson2f.tar.gz
++
++build your own
++
++CLFS: http://cross-lfs.org/view/svn/mips/cross-tools/chapter.html
++Gentoo: http://www.lemote.com/bbs/viewthread.php?tid=5530&highlight=gentoo
++Distcc: http://rostedt.homelinux.com/distcc/index-mips.html
++
++Compile it
++
++$ make -j2 ARCH=mips CROSS_COMPILE=<prefix>-
++
++Installation
++
++Create a directory for installation
++
++$ mkdir linux-loongson
++
++Install modules and images
++
++$ make modules_install INSTALL_MOD_PATH=/path/to/linux-loongson/
++$ make install INSTALL_PATH=/path/to/linux-loongson/
++
++Copy Images to /boot/
++
++Copy modules to /lib/modules/<linux-verion>/
++
++Create an kernel entry in /boot/boot.cfg
++
++And If you are using an old PMON, a new kernel command line argument is need to
++add for your machine, here is the list:
++
++ OR
++ machtype=lemote-fuloong-2e-box 2e-box
++ machtype=lemote-fuloong-2f-box 2f-box
++ machtype=lemote-mengloong-2f-7inches 7
++ machtype=lemote-yeeloong-2f-8.9inches 8.9
++ machtype=lemote-nas-2f nas
++ machtype=lemote-lynloong-2f lynloong
++
++4. Status
++
++4.1 FuLoong-2E Mini PC
++
++This support have been merged into mainline.
++
++4.2 Lemote-2F family machines
++
++The support will be available from mainline 2.6.33
++
++4.3 Dexxon Gidum
++
++This support is available here:
++
++git://git.linux-cisco.org/linux-mips.git
++
++5. More
++
++5.1 Linux for YeeLoong
++
++5.1.1 Configuration for YeeLoong netbook
++
++CPUFreq Support
++
++ CONFIG_CS5536_MFGPT
++ CONFIG_LOONGSON2_CPUFREQ
++
++STD Support
++
++ CONFIG_PM
++ CONFIG_HIBERNATION
++ CONFIG_PM_STD_PARTITION="<Your Swap Partition>"
++
++STR Support
++
++ CONFIG_PM
++ CONFIG_SUSPEND
++
++YeeLoong Platform Specific Support
++
++ CONFIG_APM_EMULATION (battery management)
++ CONFIG_LEMOTE_YEELOONG2F_PDEV (backlight, hotkey, lm-sensors...)
++
++RTL8187B wifi driver:
++
++ CONFIG_RTL8187B
++
++SM712 video driver:
++
++ CONFIG_FB_SM7XX
++
++5.1.2 Known Issues
++
++The wifi driver can not survive after resuming from STD, but can survive from
++STR.
+diff --git a/README.loongson b/README.loongson
+new file mode 100644
+index 0000000..97b2cd0
+--- /dev/null
++++ b/README.loongson
+@@ -0,0 +1,83 @@
++
++ About Loongson
++
++ author: falcon <wuzhangjin@gmail.com>
++ update: Mon Nov 23 13:56:47 CST 2009
++
++1. Loongson
++
++Loongson is a family of general-purpose MIPS(el, little endian)-compatible CPUs
++developed at Institute of Computing Technology (ICT), Chinese Academy of
++Sciences (CAS) in the People's Republic of China.
++
++Home: http://www.loongson.cn
++
++2. Lemote
++
++Lemote Inc. is the first and authoritative company made loongson2 family
++machines. The products include FuLoong-2E mini PC, FuLoong-2F mini PC,
++YeeLoong-2F laptop/netbook, Network Attached System and LynLoong ALLINONE
++machine.
++
++Home: http://www.lemote.com/english
++Products: http://www.lemote.com/english/products.html
++Dev-Home: http://dev.lemote.com/, http://dev.lemote.com/code/
++
++3. Discussion
++
++http://groups.google.com/group/loongson-dev?hl=en
++
++http://www.lemote.com/bbs/forumdisplay.php?fid=48&page=1&styleid=7
++
++4. Resources
++
++4.1 Kernel
++
++ For Lemote Products:
++
++ http://dev.lemote.com/code/linux_loongson (used in products)
++ http://dev.lemote.com/code/rt4ls (for upstream & real time support)
++
++ For Dexxon Gdium:
++
++ git://git.linux-cisco.org/linux-mips.git
++
++4.2 BIOS & Bootloader: PMON
++
++ For Lemote Products:
++
++ http://dev.lemote.com/cgit/pmon.git
++
++ For Dexxon Gdium:
++
++ http://dev.lemote.com/code/pmon-gdium
++
++4.3 ToolChains
++
++You are recommended to use the latest Gcc 4.4 for which provides the loongson
++specific support. and also, a binutils patch is needed for loongson2f:
++https://groups.google.com/group/archlinux-for-loongson/web/binutils-2.19.1-loongson2f-3.patch
++
++4.4 Distributions
++
++Theoretically, all distributions support MIPS is available to loongson family
++machines, but currently, only Debian, gNewSense and Mandriva provide specific
++support for loongson.
++
++ Debian:
++ From Lemote:
++
++ deb http://dev.lemote.com/debian lenny main contrib non-free
++ deb http://dev.lemote.com/debian-loongson loongson main
++
++ From BJLX.org.cn:
++
++ deb http://www.bjlx.org.cn/debian testing main contrib non-free
++
++ gNewSense:
++
++ http://www.gnewsense.org/static/homepage/
++
++5. References
++
++https://groups.google.com/group/archlinux-for-loongson/web/loongson
+diff --git a/README.module-4-loongson b/README.module-4-loongson
+new file mode 100644
+index 0000000..2b9ca32
+--- /dev/null
++++ b/README.module-4-loongson
+@@ -0,0 +1,3 @@
++
++The platform specific modules can be loaded automatically now, you have no need
++to modify the /etc/modules.
+diff --git a/README.rtl8187b-wifi b/README.rtl8187b-wifi
+new file mode 100644
+index 0000000..a6b299d
+--- /dev/null
++++ b/README.rtl8187b-wifi
+@@ -0,0 +1,16 @@
++
++
++ RTL8187B wifi driver for YeeLoong-2F netbook
++
++Currently, the wifi driver is disabled by default, if you want to enable it
++when booting, please add the following line into /etc/rc.local:
++
++echo 1 > /sys/class/rfkill/rfkill0/state
++
++And If you want to use Fn+F5 to control the wifi, please ensure the
++yeeloong_laptop module is compiled into the kernel or loaded.
++
++And also, the NetworkManager are recommended to install to manage it.
++
++And an existing issue: The wifi can not survive after resuming from STD, but
++can survive from STR.
+diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
+index fd7620f..9c69cd9 100644
+--- a/arch/mips/Kconfig
++++ b/arch/mips/Kconfig
+@@ -5,9 +5,14 @@ config MIPS
+ select HAVE_IDE
+ select HAVE_OPROFILE
+ select HAVE_ARCH_KGDB
++ select HAVE_FUNCTION_TRACER
++ select HAVE_FUNCTION_TRACE_MCOUNT_TEST
++ select HAVE_DYNAMIC_FTRACE
++ select HAVE_FTRACE_MCOUNT_RECORD
++ select HAVE_FUNCTION_GRAPH_TRACER
+ # Horrible source of confusion. Die, die, die ...
+ select EMBEDDED
+- select RTC_LIB if !LEMOTE_FULOONG2E
++ select RTC_LIB if !MACH_LOONGSON
+
+ mainmenu "Linux/MIPS Kernel Configuration"
+
+@@ -22,6 +27,7 @@ choice
+
+ config MACH_ALCHEMY
+ bool "Alchemy processor based machines"
++ select SYS_SUPPORTS_ZBOOT
+
+ config AR7
+ bool "Texas Instruments AR7"
+@@ -36,6 +42,7 @@ config AR7
+ select SYS_HAS_EARLY_PRINTK
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
++ select SYS_SUPPORTS_ZBOOT_UART16550
+ select GENERIC_GPIO
+ select GCD
+ select VLYNQ
+@@ -192,6 +199,7 @@ config LASAT
+
+ config MACH_LOONGSON
+ bool "Loongson family of machines"
++ select SYS_SUPPORTS_ZBOOT_UART16550
+ help
+ This enables the support of Loongson family of machines.
+
+@@ -233,6 +241,7 @@ config MIPS_MALTA
+ select SYS_SUPPORTS_MIPS_CMP
+ select SYS_SUPPORTS_MULTITHREADING
+ select SYS_SUPPORTS_SMARTMIPS
++ select SYS_SUPPORTS_ZBOOT
+ help
+ This enables support for the MIPS Technologies Malta evaluation
+ board.
+@@ -334,6 +343,24 @@ config PMC_YOSEMITE
+ Yosemite is an evaluation board for the RM9000x2 processor
+ manufactured by PMC-Sierra.
+
++config POWERTV
++ bool "Cisco PowerTV"
++ select BOOT_ELF32
++ select CEVT_R4K
++ select CPU_MIPSR2_IRQ_VI
++ select CPU_MIPSR2_IRQ_EI
++ select CSRC_POWERTV
++ select DMA_NONCOHERENT
++ select HW_HAS_PCI
++ select SYS_HAS_EARLY_PRINTK
++ select SYS_HAS_CPU_MIPS32_R2
++ select SYS_SUPPORTS_32BIT_KERNEL
++ select SYS_SUPPORTS_BIG_ENDIAN
++ select SYS_SUPPORTS_HIGHMEM
++ select USB_OHCI_LITTLE_ENDIAN
++ help
++ This enables support for the Cisco PowerTV Platform.
++
+ config SGI_IP22
+ bool "SGI IP22 (Indy/Indigo2)"
+ select ARC
+@@ -679,6 +706,7 @@ source "arch/mips/bcm63xx/Kconfig"
+ source "arch/mips/jazz/Kconfig"
+ source "arch/mips/lasat/Kconfig"
+ source "arch/mips/pmc-sierra/Kconfig"
++source "arch/mips/powertv/Kconfig"
+ source "arch/mips/sgi-ip27/Kconfig"
+ source "arch/mips/sibyte/Kconfig"
+ source "arch/mips/txx9/Kconfig"
+@@ -778,6 +806,9 @@ config CSRC_BCM1480
+ config CSRC_IOASIC
+ bool
+
++config CSRC_POWERTV
++ bool
++
+ config CSRC_R4K_LIB
+ bool
+
+@@ -807,8 +838,8 @@ config DMA_NEED_PCI_MAP_STATE
+ bool
+
+ config EARLY_PRINTK
+- bool "Early printk" if EMBEDDED && DEBUG_KERNEL
+- depends on SYS_HAS_EARLY_PRINTK
++ bool "Early printk" if EMBEDDED
++ depends on SYS_HAS_EARLY_PRINTK && DEBUG_KERNEL
+ default y
+ help
+ This option enables special console drivers which allow the kernel
+@@ -1069,6 +1100,21 @@ config CPU_LOONGSON2E
+ The Loongson 2E processor implements the MIPS III instruction set
+ with many extensions.
+
++ It has an internal FPGA northbridge, which is compatiable to
++ bonito64.
++
++config CPU_LOONGSON2F
++ bool "Loongson 2F"
++ depends on SYS_HAS_CPU_LOONGSON2F
++ select CPU_LOONGSON2
++ help
++ The Loongson 2F processor implements the MIPS III instruction set
++ with many extensions.
++
++ Loongson2F have built-in DDR2 and PCIX controller. The PCIX controller
++ have a similar programming interface with FPGA northbridge used in
++ Loongson2E.
++
+ config CPU_MIPS32_R1
+ bool "MIPS32 Release 1"
+ depends on SYS_HAS_CPU_MIPS32_R1
+@@ -1294,6 +1340,17 @@ config CPU_CAVIUM_OCTEON
+
+ endchoice
+
++config SYS_SUPPORTS_ZBOOT
++ bool
++ select HAVE_KERNEL_GZIP
++ select HAVE_KERNEL_BZIP2
++ select HAVE_KERNEL_LZMA
++ select HAVE_KERNEL_LZO
++
++config SYS_SUPPORTS_ZBOOT_UART16550
++ bool
++ select SYS_SUPPORTS_ZBOOT
++
+ config CPU_LOONGSON2
+ bool
+ select CPU_SUPPORTS_32BIT_KERNEL
+@@ -1303,6 +1360,12 @@ config CPU_LOONGSON2
+ config SYS_HAS_CPU_LOONGSON2E
+ bool
+
++config SYS_HAS_CPU_LOONGSON2F
++ bool
++ select CPU_SUPPORTS_CPUFREQ
++ select CPU_SUPPORTS_ADDRWINCFG if 64BIT
++ select CPU_SUPPORTS_UNCACHED_ACCELERATED
++
+ config SYS_HAS_CPU_MIPS32_R1
+ bool
+
+@@ -1411,8 +1474,17 @@ config CPU_SUPPORTS_32BIT_KERNEL
+ bool
+ config CPU_SUPPORTS_64BIT_KERNEL
+ bool
++config CPU_SUPPORTS_CPUFREQ
++ bool
++config CPU_SUPPORTS_ADDRWINCFG
++ bool
+ config CPU_SUPPORTS_HUGEPAGES
+ bool
++config CPU_SUPPORTS_UNCACHED_ACCELERATED
++ bool
++config MIPS_PGD_C0_CONTEXT
++ bool
++ default y if 64BIT && CPU_MIPSR2
+
+ #
+ # Set to y for ptrace access to watch registers.
+@@ -1896,6 +1968,24 @@ config NR_CPUS
+ source "kernel/time/Kconfig"
+
+ #
++# High Resolution sched_clock() Configuration
++#
++
++config HR_SCHED_CLOCK
++ bool "High Resolution sched_clock()"
++ depends on CSRC_R4K
++ default n
++ help
++ This option enables the MIPS c0 count based high resolution
++ sched_clock().
++
++ If you need a ns precision timestamp, you are recommended to enable
++ this option. For example, if you are using the Ftrace subsystem to do
++ real time tracing, this option is needed.
++
++ If unsure, disable it.
++
++#
+ # Timer Interrupt Frequency Configuration
+ #
+
+@@ -2024,15 +2114,6 @@ config STACKTRACE_SUPPORT
+
+ source "init/Kconfig"
+
+-config PROBE_INITRD_HEADER
+- bool "Probe initrd header created by addinitrd"
+- depends on BLK_DEV_INITRD
+- help
+- Probe initrd header at the last page of kernel image.
+- Say Y here if you are using arch/mips/boot/addinitrd.c to
+- add initrd or initramfs image to the kernel image.
+- Otherwise, say N.
+-
+ source "kernel/Kconfig.freezer"
+
+ menu "Bus options (PCI, PCMCIA, EISA, ISA, TC)"
+@@ -2104,6 +2185,7 @@ config MMU
+
+ config I8253
+ bool
++ select MIPS_EXTERNAL_TIMER
+
+ config ZONE_DMA32
+ bool
+@@ -2180,6 +2262,8 @@ source "kernel/power/Kconfig"
+
+ endmenu
+
++source "arch/mips/kernel/cpufreq/Kconfig"
++
+ source "net/Kconfig"
+
+ source "drivers/Kconfig"
+diff --git a/arch/mips/Makefile b/arch/mips/Makefile
+index 77f5021..fdb70f7 100644
+--- a/arch/mips/Makefile
++++ b/arch/mips/Makefile
+@@ -48,7 +48,16 @@ ifneq ($(SUBARCH),$(ARCH))
+ endif
+ endif
+
++ifndef CONFIG_FUNCTION_TRACER
+ cflags-y := -ffunction-sections
++endif
++ifdef CONFIG_FUNCTION_GRAPH_TRACER
++ ifndef KBUILD_MCOUNT_RA_ADDRESS
++ ifeq ($(call cc-option-yn,-mmcount-ra-address), y)
++ cflags-y += -mmcount-ra-address -DKBUILD_MCOUNT_RA_ADDRESS
++ endif
++ endif
++endif
+ cflags-y += $(call cc-option, -mno-check-zero-division)
+
+ ifdef CONFIG_32BIT
+@@ -69,6 +78,7 @@ endif
+
+ all-$(CONFIG_BOOT_ELF32) := $(vmlinux-32)
+ all-$(CONFIG_BOOT_ELF64) := $(vmlinux-64)
++all-$(CONFIG_SYS_SUPPORTS_ZBOOT)+= vmlinuz
+
+ #
+ # GCC uses -G 0 -mabicalls -fpic as default. We don't want PIC in the kernel
+@@ -124,6 +134,11 @@ cflags-$(CONFIG_CPU_TX49XX) += -march=r4600 -Wa,--trap
+ cflags-$(CONFIG_CPU_LOONGSON2) += -Wa,--trap
+ cflags-$(CONFIG_CPU_LOONGSON2E) += \
+ $(call cc-option,-march=loongson2e,-march=r4600)
++cflags-$(CONFIG_CPU_LOONGSON2F) += \
++ $(call cc-option,-march=loongson2f,-march=r4600) \
++ $(call as-option,-Wa$(comma)-mfix-ls2f-kernel,) \
++ $(call as-option,-Wa$(comma)-mfix-loongson2f-nop,) \
++ $(call as-option,-Wa$(comma)-mfix-loongson2f-jump,)
+
+ cflags-$(CONFIG_CPU_MIPS32_R1) += $(call cc-option,-march=mips32,-mips32 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \
+ -Wa,-mips32 -Wa,--trap
+@@ -324,6 +339,7 @@ core-$(CONFIG_MACH_LOONGSON) +=arch/mips/loongson/
+ cflags-$(CONFIG_MACH_LOONGSON) += -I$(srctree)/arch/mips/include/asm/mach-loongson \
+ -mno-branch-likely
+ load-$(CONFIG_LEMOTE_FULOONG2E) +=0xffffffff80100000
++load-$(CONFIG_LEMOTE_MACH2F) +=0xffffffff80200000
+
+ #
+ # MIPS Malta board
+@@ -331,7 +347,7 @@ load-$(CONFIG_LEMOTE_FULOONG2E) +=0xffffffff80100000
+ core-$(CONFIG_MIPS_MALTA) += arch/mips/mti-malta/
+ cflags-$(CONFIG_MIPS_MALTA) += -I$(srctree)/arch/mips/include/asm/mach-malta
+ load-$(CONFIG_MIPS_MALTA) += 0xffffffff80100000
+-all-$(CONFIG_MIPS_MALTA) := vmlinux.bin
++all-$(CONFIG_MIPS_MALTA) := vmlinuz.bin
+
+ #
+ # MIPS SIM
+@@ -441,6 +457,13 @@ core-$(CONFIG_NEC_MARKEINS) += arch/mips/emma/markeins/
+ load-$(CONFIG_NEC_MARKEINS) += 0xffffffff88100000
+
+ #
++# Cisco PowerTV Platform
++#
++core-$(CONFIG_POWERTV) += arch/mips/powertv/
++cflags-$(CONFIG_POWERTV) += -I$(srctree)/arch/mips/include/asm/mach-powertv
++load-$(CONFIG_POWERTV) += 0xffffffff90800000
++
++#
+ # SGI IP22 (Indy/Indigo2)
+ #
+ # Set the load address to >= 0xffffffff88069000 if you want to leave space for
+@@ -581,7 +604,7 @@ load-$(CONFIG_SNI_RM) += 0xffffffff80600000
+ else
+ load-$(CONFIG_SNI_RM) += 0xffffffff80030000
+ endif
+-all-$(CONFIG_SNI_RM) := vmlinux.ecoff
++all-$(CONFIG_SNI_RM) := vmlinuz.ecoff
+
+ #
+ # Common TXx9
+@@ -699,9 +722,23 @@ vmlinux.64: vmlinux
+ $(OBJCOPY) -O $(64bit-bfd) $(OBJCOPYFLAGS) $< $@
+
+ makeboot =$(Q)$(MAKE) $(build)=arch/mips/boot VMLINUX=$(vmlinux-32) $(1)
++makezboot =$(Q)$(MAKE) $(build)=arch/mips/boot/compressed \
++ VMLINUX_LOAD_ADDRESS=$(load-y) 32bit-bfd=$(32bit-bfd) $(1)
+
+ all: $(all-y)
+
++vmlinuz: vmlinux FORCE
++ +@$(call makezboot,$@)
++
++vmlinuz.bin: vmlinux
++ +@$(call makezboot,$@)
++
++vmlinuz.ecoff: vmlinux
++ +@$(call makezboot,$@)
++
++vmlinuz.srec: vmlinux
++ +@$(call makezboot,$@)
++
+ vmlinux.bin: $(vmlinux-32)
+ +@$(call makeboot,$@)
+
+@@ -726,11 +763,13 @@ endif
+
+ install:
+ $(Q)install -D -m 755 vmlinux $(INSTALL_PATH)/vmlinux-$(KERNELRELEASE)
++ $(Q)install -D -m 755 vmlinuz $(INSTALL_PATH)/vmlinuz-$(KERNELRELEASE)
+ $(Q)install -D -m 644 .config $(INSTALL_PATH)/config-$(KERNELRELEASE)
+ $(Q)install -D -m 644 System.map $(INSTALL_PATH)/System.map-$(KERNELRELEASE)
+
+ archclean:
+ @$(MAKE) $(clean)=arch/mips/boot
++ @$(MAKE) $(clean)=arch/mips/boot/compressed
+ @$(MAKE) $(clean)=arch/mips/lasat
+
+ define archhelp
+@@ -738,10 +777,18 @@ define archhelp
+ echo ' vmlinux.ecoff - ECOFF boot image'
+ echo ' vmlinux.bin - Raw binary boot image'
+ echo ' vmlinux.srec - SREC boot image'
++ echo ' vmlinuz - Compressed boot(zboot) image'
++ echo ' vmlinuz.ecoff - ECOFF zboot image'
++ echo ' vmlinuz.bin - Raw binary zboot image'
++ echo ' vmlinuz.srec - SREC zboot image'
+ echo
+ echo ' These will be default as apropriate for a configured platform.'
+ endef
+
+ CLEAN_FILES += vmlinux.32 \
+ vmlinux.64 \
+- vmlinux.ecoff
++ vmlinux.ecoff \
++ vmlinuz \
++ vmlinuz.ecoff \
++ vmlinuz.bin \
++ vmlinuz.srec
+diff --git a/arch/mips/alchemy/Kconfig b/arch/mips/alchemy/Kconfig
+index 00b498e..22f4ff5 100644
+--- a/arch/mips/alchemy/Kconfig
++++ b/arch/mips/alchemy/Kconfig
+@@ -20,12 +20,14 @@ config MIPS_MTX1
+ select HW_HAS_PCI
+ select SOC_AU1500
+ select SYS_SUPPORTS_LITTLE_ENDIAN
++ select SYS_HAS_EARLY_PRINTK
+
+ config MIPS_BOSPORUS
+ bool "Alchemy Bosporus board"
+ select SOC_AU1500
+ select DMA_NONCOHERENT
+ select SYS_SUPPORTS_LITTLE_ENDIAN
++ select SYS_HAS_EARLY_PRINTK
+
+ config MIPS_DB1000
+ bool "Alchemy DB1000 board"
+@@ -33,12 +35,14 @@ config MIPS_DB1000
+ select DMA_NONCOHERENT
+ select HW_HAS_PCI
+ select SYS_SUPPORTS_LITTLE_ENDIAN
++ select SYS_HAS_EARLY_PRINTK
+
+ config MIPS_DB1100
+ bool "Alchemy DB1100 board"
+ select SOC_AU1100
+ select DMA_NONCOHERENT
+ select SYS_SUPPORTS_LITTLE_ENDIAN
++ select SYS_HAS_EARLY_PRINTK
+
+ config MIPS_DB1200
+ bool "Alchemy DB1200 board"
+@@ -46,6 +50,7 @@ config MIPS_DB1200
+ select DMA_COHERENT
+ select MIPS_DISABLE_OBSOLETE_IDE
+ select SYS_SUPPORTS_LITTLE_ENDIAN
++ select SYS_HAS_EARLY_PRINTK
+
+ config MIPS_DB1500
+ bool "Alchemy DB1500 board"
+@@ -55,6 +60,7 @@ config MIPS_DB1500
+ select MIPS_DISABLE_OBSOLETE_IDE
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_LITTLE_ENDIAN
++ select SYS_HAS_EARLY_PRINTK
+
+ config MIPS_DB1550
+ bool "Alchemy DB1550 board"
+@@ -63,12 +69,14 @@ config MIPS_DB1550
+ select DMA_NONCOHERENT
+ select MIPS_DISABLE_OBSOLETE_IDE
+ select SYS_SUPPORTS_LITTLE_ENDIAN
++ select SYS_HAS_EARLY_PRINTK
+
+ config MIPS_MIRAGE
+ bool "Alchemy Mirage board"
+ select DMA_NONCOHERENT
+ select SOC_AU1500
+ select SYS_SUPPORTS_LITTLE_ENDIAN
++ select SYS_HAS_EARLY_PRINTK
+
+ config MIPS_PB1000
+ bool "Alchemy PB1000 board"
+@@ -77,6 +85,7 @@ config MIPS_PB1000
+ select HW_HAS_PCI
+ select SWAP_IO_SPACE
+ select SYS_SUPPORTS_LITTLE_ENDIAN
++ select SYS_HAS_EARLY_PRINTK
+
+ config MIPS_PB1100
+ bool "Alchemy PB1100 board"
+@@ -85,6 +94,7 @@ config MIPS_PB1100
+ select HW_HAS_PCI
+ select SWAP_IO_SPACE
+ select SYS_SUPPORTS_LITTLE_ENDIAN
++ select SYS_HAS_EARLY_PRINTK
+
+ config MIPS_PB1200
+ bool "Alchemy PB1200 board"
+@@ -92,6 +102,7 @@ config MIPS_PB1200
+ select DMA_NONCOHERENT
+ select MIPS_DISABLE_OBSOLETE_IDE
+ select SYS_SUPPORTS_LITTLE_ENDIAN
++ select SYS_HAS_EARLY_PRINTK
+
+ config MIPS_PB1500
+ bool "Alchemy PB1500 board"
+@@ -99,6 +110,7 @@ config MIPS_PB1500
+ select DMA_NONCOHERENT
+ select HW_HAS_PCI
+ select SYS_SUPPORTS_LITTLE_ENDIAN
++ select SYS_HAS_EARLY_PRINTK
+
+ config MIPS_PB1550
+ bool "Alchemy PB1550 board"
+@@ -107,12 +119,14 @@ config MIPS_PB1550
+ select HW_HAS_PCI
+ select MIPS_DISABLE_OBSOLETE_IDE
+ select SYS_SUPPORTS_LITTLE_ENDIAN
++ select SYS_HAS_EARLY_PRINTK
+
+ config MIPS_XXS1500
+ bool "MyCable XXS1500 board"
+ select DMA_NONCOHERENT
+ select SOC_AU1500
+ select SYS_SUPPORTS_LITTLE_ENDIAN
++ select SYS_HAS_EARLY_PRINTK
+
+ endchoice
+
+diff --git a/arch/mips/alchemy/common/Makefile b/arch/mips/alchemy/common/Makefile
+index b67fb51..abf0eb1 100644
+--- a/arch/mips/alchemy/common/Makefile
++++ b/arch/mips/alchemy/common/Makefile
+@@ -5,7 +5,7 @@
+ # Makefile for the Alchemy Au1xx0 CPUs, generic files.
+ #
+
+-obj-y += prom.o irq.o puts.o time.o reset.o \
++obj-y += prom.o irq.o time.o reset.o \
+ clocks.o platform.o power.o setup.o \
+ sleeper.o dma.o dbdma.o
+
+diff --git a/arch/mips/alchemy/common/dbdma.c b/arch/mips/alchemy/common/dbdma.c
+index 19c1c82..4851308 100644
+--- a/arch/mips/alchemy/common/dbdma.c
++++ b/arch/mips/alchemy/common/dbdma.c
+@@ -30,6 +30,7 @@
+ *
+ */
+
++#include <linux/init.h>
+ #include <linux/kernel.h>
+ #include <linux/slab.h>
+ #include <linux/spinlock.h>
+@@ -58,7 +59,6 @@ static DEFINE_SPINLOCK(au1xxx_dbdma_spin_lock);
+
+ static dbdma_global_t *dbdma_gptr = (dbdma_global_t *)DDMA_GLOBAL_BASE;
+ static int dbdma_initialized;
+-static void au1xxx_dbdma_init(void);
+
+ static dbdev_tab_t dbdev_tab[] = {
+ #ifdef CONFIG_SOC_AU1550
+@@ -250,8 +250,7 @@ u32 au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
+ * which can't be done successfully during board set up.
+ */
+ if (!dbdma_initialized)
+- au1xxx_dbdma_init();
+- dbdma_initialized = 1;
++ return 0;
+
+ stp = find_dbdev_id(srcid);
+ if (stp == NULL)
+@@ -569,7 +568,7 @@ EXPORT_SYMBOL(au1xxx_dbdma_ring_alloc);
+ * This updates the source pointer and byte count. Normally used
+ * for memory to fifo transfers.
+ */
+-u32 _au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags)
++u32 au1xxx_dbdma_put_source(u32 chanid, dma_addr_t buf, int nbytes, u32 flags)
+ {
+ chan_tab_t *ctp;
+ au1x_ddma_desc_t *dp;
+@@ -595,7 +594,7 @@ u32 _au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags)
+ return 0;
+
+ /* Load up buffer address and byte count. */
+- dp->dscr_source0 = virt_to_phys(buf);
++ dp->dscr_source0 = buf & ~0UL;
+ dp->dscr_cmd1 = nbytes;
+ /* Check flags */
+ if (flags & DDMA_FLAGS_IE)
+@@ -622,14 +621,13 @@ u32 _au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags)
+ /* Return something non-zero. */
+ return nbytes;
+ }
+-EXPORT_SYMBOL(_au1xxx_dbdma_put_source);
++EXPORT_SYMBOL(au1xxx_dbdma_put_source);
+
+ /* Put a destination buffer into the DMA ring.
+ * This updates the destination pointer and byte count. Normally used
+ * to place an empty buffer into the ring for fifo to memory transfers.
+ */
+-u32
+-_au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes, u32 flags)
++u32 au1xxx_dbdma_put_dest(u32 chanid, dma_addr_t buf, int nbytes, u32 flags)
+ {
+ chan_tab_t *ctp;
+ au1x_ddma_desc_t *dp;
+@@ -659,7 +657,7 @@ _au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes, u32 flags)
+ if (flags & DDMA_FLAGS_NOIE)
+ dp->dscr_cmd0 &= ~DSCR_CMD0_IE;
+
+- dp->dscr_dest0 = virt_to_phys(buf);
++ dp->dscr_dest0 = buf & ~0UL;
+ dp->dscr_cmd1 = nbytes;
+ #if 0
+ printk(KERN_DEBUG "cmd0:%x cmd1:%x source0:%x source1:%x dest0:%x dest1:%x\n",
+@@ -685,7 +683,7 @@ _au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes, u32 flags)
+ /* Return something non-zero. */
+ return nbytes;
+ }
+-EXPORT_SYMBOL(_au1xxx_dbdma_put_dest);
++EXPORT_SYMBOL(au1xxx_dbdma_put_dest);
+
+ /*
+ * Get a destination buffer into the DMA ring.
+@@ -868,28 +866,6 @@ static irqreturn_t dbdma_interrupt(int irq, void *dev_id)
+ return IRQ_RETVAL(1);
+ }
+
+-static void au1xxx_dbdma_init(void)
+-{
+- int irq_nr;
+-
+- dbdma_gptr->ddma_config = 0;
+- dbdma_gptr->ddma_throttle = 0;
+- dbdma_gptr->ddma_inten = 0xffff;
+- au_sync();
+-
+-#if defined(CONFIG_SOC_AU1550)
+- irq_nr = AU1550_DDMA_INT;
+-#elif defined(CONFIG_SOC_AU1200)
+- irq_nr = AU1200_DDMA_INT;
+-#else
+- #error Unknown Au1x00 SOC
+-#endif
+-
+- if (request_irq(irq_nr, dbdma_interrupt, IRQF_DISABLED,
+- "Au1xxx dbdma", (void *)dbdma_gptr))
+- printk(KERN_ERR "Can't get 1550 dbdma irq");
+-}
+-
+ void au1xxx_dbdma_dump(u32 chanid)
+ {
+ chan_tab_t *ctp;
+@@ -1038,4 +1014,38 @@ void au1xxx_dbdma_resume(void)
+ }
+ }
+ #endif /* CONFIG_PM */
++
++static int __init au1xxx_dbdma_init(void)
++{
++ int irq_nr, ret;
++
++ dbdma_gptr->ddma_config = 0;
++ dbdma_gptr->ddma_throttle = 0;
++ dbdma_gptr->ddma_inten = 0xffff;
++ au_sync();
++
++ switch (alchemy_get_cputype()) {
++ case ALCHEMY_CPU_AU1550:
++ irq_nr = AU1550_DDMA_INT;
++ break;
++ case ALCHEMY_CPU_AU1200:
++ irq_nr = AU1200_DDMA_INT;
++ break;
++ default:
++ return -ENODEV;
++ }
++
++ ret = request_irq(irq_nr, dbdma_interrupt, IRQF_DISABLED,
++ "Au1xxx dbdma", (void *)dbdma_gptr);
++ if (ret)
++ printk(KERN_ERR "Cannot grab DBDMA interrupt!\n");
++ else {
++ dbdma_initialized = 1;
++ printk(KERN_INFO "Alchemy DBDMA initialized\n");
++ }
++
++ return ret;
++}
++subsys_initcall(au1xxx_dbdma_init);
++
+ #endif /* defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) */
+diff --git a/arch/mips/alchemy/common/dma.c b/arch/mips/alchemy/common/dma.c
+index d6fbda2..d527887 100644
+--- a/arch/mips/alchemy/common/dma.c
++++ b/arch/mips/alchemy/common/dma.c
+@@ -29,6 +29,8 @@
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
++
++#include <linux/init.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/errno.h>
+@@ -188,17 +190,14 @@ int request_au1000_dma(int dev_id, const char *dev_str,
+ dev = &dma_dev_table[dev_id];
+
+ if (irqhandler) {
+- chan->irq = AU1000_DMA_INT_BASE + i;
+ chan->irq_dev = irq_dev_id;
+ ret = request_irq(chan->irq, irqhandler, irqflags, dev_str,
+ chan->irq_dev);
+ if (ret) {
+- chan->irq = 0;
+ chan->irq_dev = NULL;
+ return ret;
+ }
+ } else {
+- chan->irq = 0;
+ chan->irq_dev = NULL;
+ }
+
+@@ -226,13 +225,40 @@ void free_au1000_dma(unsigned int dmanr)
+ }
+
+ disable_dma(dmanr);
+- if (chan->irq)
++ if (chan->irq_dev)
+ free_irq(chan->irq, chan->irq_dev);
+
+- chan->irq = 0;
+ chan->irq_dev = NULL;
+ chan->dev_id = -1;
+ }
+ EXPORT_SYMBOL(free_au1000_dma);
+
++static int __init au1000_dma_init(void)
++{
++ int base, i;
++
++ switch (alchemy_get_cputype()) {
++ case ALCHEMY_CPU_AU1000:
++ base = AU1000_DMA_INT_BASE;
++ break;
++ case ALCHEMY_CPU_AU1500:
++ base = AU1500_DMA_INT_BASE;
++ break;
++ case ALCHEMY_CPU_AU1100:
++ base = AU1100_DMA_INT_BASE;
++ break;
++ default:
++ goto out;
++ }
++
++ for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++)
++ au1000_dma_table[i].irq = base + i;
++
++ printk(KERN_INFO "Alchemy DMA initialized\n");
++
++out:
++ return 0;
++}
++arch_initcall(au1000_dma_init);
++
+ #endif /* AU1000 AU1500 AU1100 */
+diff --git a/arch/mips/alchemy/common/irq.c b/arch/mips/alchemy/common/irq.c
+index d670928..960a3ee 100644
+--- a/arch/mips/alchemy/common/irq.c
++++ b/arch/mips/alchemy/common/irq.c
+@@ -39,164 +39,174 @@
+
+ static int au1x_ic_settype(unsigned int irq, unsigned int flow_type);
+
+-/* per-processor fixed function irqs */
+-struct au1xxx_irqmap au1xxx_ic0_map[] __initdata = {
++/* NOTE on interrupt priorities: The original writers of this code said:
++ *
++ * Because of the tight timing of SETUP token to reply transactions,
++ * the USB devices-side packet complete interrupt (USB_DEV_REQ_INT)
++ * needs the highest priority.
++ */
+
++/* per-processor fixed function irqs */
++struct au1xxx_irqmap {
++ int im_irq;
++ int im_type;
++ int im_request; /* set 1 to get higher priority */
++} au1xxx_ic0_map[] __initdata = {
+ #if defined(CONFIG_SOC_AU1000)
+- { AU1000_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_UART2_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_SSI0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_SSI1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
+- { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1000_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1000_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1000_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1000_UART2_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1000_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1000_SSI0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1000_SSI1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1000_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1000_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1000_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1000_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1000_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1000_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1000_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1000_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
++ { AU1000_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1000_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 1 },
+ { AU1000_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
+- { AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1000_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
++ { AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1000_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1000_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1000_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 },
+
+ #elif defined(CONFIG_SOC_AU1500)
+
+- { AU1500_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_PCI_INTA, IRQ_TYPE_LEVEL_LOW, 0 },
+- { AU1000_PCI_INTB, IRQ_TYPE_LEVEL_LOW, 0 },
+- { AU1500_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_PCI_INTC, IRQ_TYPE_LEVEL_LOW, 0 },
+- { AU1000_PCI_INTD, IRQ_TYPE_LEVEL_LOW, 0 },
+- { AU1000_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
+- { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
+- { AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1500_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1500_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1500_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1500_PCI_INTA, IRQ_TYPE_LEVEL_LOW, 0 },
++ { AU1500_PCI_INTB, IRQ_TYPE_LEVEL_LOW, 0 },
++ { AU1500_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1500_PCI_INTC, IRQ_TYPE_LEVEL_LOW, 0 },
++ { AU1500_PCI_INTD, IRQ_TYPE_LEVEL_LOW, 0 },
++ { AU1500_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1500_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1500_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1500_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1500_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1500_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1500_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1500_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1500_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1500_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1500_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1500_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1500_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1500_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1500_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1500_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
++ { AU1500_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 1 },
++ { AU1500_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1500_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
++ { AU1500_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1500_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1500_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1500_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 },
+
+ #elif defined(CONFIG_SOC_AU1100)
+
+- { AU1100_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1100_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1100_SD_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1100_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_SSI0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_SSI1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
+- { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1000_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
+- { AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1100_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1100_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1100_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1100_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1100_SD_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1100_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1100_SSI0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1100_SSI1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1100_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1100_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1100_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1100_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1100_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1100_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1100_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1100_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1100_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1100_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1100_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1100_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1100_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1100_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1100_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1100_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
++ { AU1100_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1100_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1100_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 1 },
++ { AU1100_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1100_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
++ { AU1100_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1100_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1100_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1100_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 },
+
+ #elif defined(CONFIG_SOC_AU1550)
+
+- { AU1550_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1550_PCI_INTA, IRQ_TYPE_LEVEL_LOW, 0 },
+- { AU1550_PCI_INTB, IRQ_TYPE_LEVEL_LOW, 0 },
+- { AU1550_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1550_CRYPTO_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1550_PCI_INTC, IRQ_TYPE_LEVEL_LOW, 0 },
+- { AU1550_PCI_INTD, IRQ_TYPE_LEVEL_LOW, 0 },
+- { AU1550_PCI_RST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
+- { AU1550_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1550_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1550_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1550_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1550_PSC2_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1550_PSC3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
+- { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1550_NAND_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1550_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1550_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1550_PCI_INTA, IRQ_TYPE_LEVEL_LOW, 0 },
++ { AU1550_PCI_INTB, IRQ_TYPE_LEVEL_LOW, 0 },
++ { AU1550_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1550_CRYPTO_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1550_PCI_INTC, IRQ_TYPE_LEVEL_LOW, 0 },
++ { AU1550_PCI_INTD, IRQ_TYPE_LEVEL_LOW, 0 },
++ { AU1550_PCI_RST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
++ { AU1550_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1550_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1550_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1550_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1550_PSC2_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1550_PSC3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1550_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1550_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1550_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1550_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1550_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1550_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1550_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1550_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
++ { AU1550_NAND_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1550_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 1 },
+ { AU1550_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1550_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
+- { AU1550_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1550_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1550_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
++ { AU1550_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1550_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+
+ #elif defined(CONFIG_SOC_AU1200)
+
+- { AU1200_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1200_SWT_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1200_SD_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1200_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1200_MAE_BE_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1200_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1200_MAE_FE_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1200_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1200_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1200_AES_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1200_CAMERA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
+- { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1200_NAND_INT, IRQ_TYPE_EDGE_RISING, 0 },
+- { AU1200_USB_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1200_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+- { AU1200_MAE_BOTH_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1200_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1200_SWT_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1200_SD_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1200_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1200_MAE_BE_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1200_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1200_MAE_FE_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1200_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1200_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1200_AES_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1200_CAMERA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1200_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1200_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1200_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1200_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1200_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1200_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1200_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1200_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
++ { AU1200_NAND_INT, IRQ_TYPE_EDGE_RISING, 0 },
++ { AU1200_USB_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1200_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
++ { AU1200_MAE_BOTH_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+
+ #else
+ #error "Error: Unknown Alchemy SOC"
+@@ -306,7 +316,7 @@ static void au1x_ic1_unmask(unsigned int irq_nr)
+ * nowhere in the current kernel sources is it disabled. --mlau
+ */
+ #if defined(CONFIG_MIPS_PB1000)
+- if (irq_nr == AU1000_GPIO_15)
++ if (irq_nr == AU1000_GPIO15_INT)
+ au_writel(0x4000, PB1000_MDR); /* enable int */
+ #endif
+ au_sync();
+@@ -378,11 +388,13 @@ static void au1x_ic1_maskack(unsigned int irq_nr)
+
+ static int au1x_ic1_setwake(unsigned int irq, unsigned int on)
+ {
+- unsigned int bit = irq - AU1000_INTC1_INT_BASE;
++ int bit = irq - AU1000_INTC1_INT_BASE;
+ unsigned long wakemsk, flags;
+
+- /* only GPIO 0-7 can act as wakeup source: */
+- if ((irq < AU1000_GPIO_0) || (irq > AU1000_GPIO_7))
++ /* only GPIO 0-7 can act as wakeup source. Fortunately these
++ * are wired up identically on all supported variants.
++ */
++ if ((bit < 0) || (bit > 7))
+ return -EINVAL;
+
+ local_irq_save(flags);
+@@ -504,11 +516,11 @@ static int au1x_ic_settype(unsigned int irq, unsigned int flow_type)
+ asmlinkage void plat_irq_dispatch(void)
+ {
+ unsigned int pending = read_c0_status() & read_c0_cause();
+- unsigned long s, off, bit;
++ unsigned long s, off;
+
+ if (pending & CAUSEF_IP7) {
+- do_IRQ(MIPS_CPU_IRQ_BASE + 7);
+- return;
++ off = MIPS_CPU_IRQ_BASE + 7;
++ goto handle;
+ } else if (pending & CAUSEF_IP2) {
+ s = IC0_REQ0INT;
+ off = AU1000_INTC0_INT_BASE;
+@@ -524,30 +536,19 @@ asmlinkage void plat_irq_dispatch(void)
+ } else
+ goto spurious;
+
+- bit = 0;
+ s = au_readl(s);
+ if (unlikely(!s)) {
+ spurious:
+ spurious_interrupt();
+ return;
+ }
+-#ifdef AU1000_USB_DEV_REQ_INT
+- /*
+- * Because of the tight timing of SETUP token to reply
+- * transactions, the USB devices-side packet complete
+- * interrupt needs the highest priority.
+- */
+- bit = 1 << (AU1000_USB_DEV_REQ_INT - AU1000_INTC0_INT_BASE);
+- if ((pending & CAUSEF_IP2) && (s & bit)) {
+- do_IRQ(AU1000_USB_DEV_REQ_INT);
+- return;
+- }
+-#endif
+- do_IRQ(__ffs(s) + off);
++ off += __ffs(s);
++handle:
++ do_IRQ(off);
+ }
+
+ /* setup edge/level and assign request 0/1 */
+-void __init au1xxx_setup_irqmap(struct au1xxx_irqmap *map, int count)
++static void __init setup_irqmap(struct au1xxx_irqmap *map, int count)
+ {
+ unsigned int bit, irq_nr;
+
+@@ -563,11 +564,11 @@ void __init au1xxx_setup_irqmap(struct au1xxx_irqmap *map, int count)
+ if (irq_nr >= AU1000_INTC1_INT_BASE) {
+ bit = irq_nr - AU1000_INTC1_INT_BASE;
+ if (map[count].im_request)
+- au_writel(1 << bit, IC1_ASSIGNCLR);
++ au_writel(1 << bit, IC1_ASSIGNSET);
+ } else {
+ bit = irq_nr - AU1000_INTC0_INT_BASE;
+ if (map[count].im_request)
+- au_writel(1 << bit, IC0_ASSIGNCLR);
++ au_writel(1 << bit, IC0_ASSIGNSET);
+ }
+
+ au1x_ic_settype(irq_nr, map[count].im_type);
+@@ -585,7 +586,7 @@ void __init arch_init_irq(void)
+ au_writel(0xffffffff, IC0_CFG1CLR);
+ au_writel(0xffffffff, IC0_CFG2CLR);
+ au_writel(0xffffffff, IC0_MASKCLR);
+- au_writel(0xffffffff, IC0_ASSIGNSET);
++ au_writel(0xffffffff, IC0_ASSIGNCLR);
+ au_writel(0xffffffff, IC0_WAKECLR);
+ au_writel(0xffffffff, IC0_SRCSET);
+ au_writel(0xffffffff, IC0_FALLINGCLR);
+@@ -596,7 +597,7 @@ void __init arch_init_irq(void)
+ au_writel(0xffffffff, IC1_CFG1CLR);
+ au_writel(0xffffffff, IC1_CFG2CLR);
+ au_writel(0xffffffff, IC1_MASKCLR);
+- au_writel(0xffffffff, IC1_ASSIGNSET);
++ au_writel(0xffffffff, IC1_ASSIGNCLR);
+ au_writel(0xffffffff, IC1_WAKECLR);
+ au_writel(0xffffffff, IC1_SRCSET);
+ au_writel(0xffffffff, IC1_FALLINGCLR);
+@@ -619,11 +620,7 @@ void __init arch_init_irq(void)
+ /*
+ * Initialize IC0, which is fixed per processor.
+ */
+- au1xxx_setup_irqmap(au1xxx_ic0_map, ARRAY_SIZE(au1xxx_ic0_map));
+-
+- /* Boards can register additional (GPIO-based) IRQs.
+- */
+- board_init_irq();
++ setup_irqmap(au1xxx_ic0_map, ARRAY_SIZE(au1xxx_ic0_map));
+
+ set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3);
+ }
+diff --git a/arch/mips/alchemy/common/platform.c b/arch/mips/alchemy/common/platform.c
+index 117f99f..3fbe30c 100644
+--- a/arch/mips/alchemy/common/platform.c
++++ b/arch/mips/alchemy/common/platform.c
+@@ -19,39 +19,40 @@
+ #include <asm/mach-au1x00/au1xxx.h>
+ #include <asm/mach-au1x00/au1xxx_dbdma.h>
+ #include <asm/mach-au1x00/au1100_mmc.h>
+-
+-#define PORT(_base, _irq) \
+- { \
+- .iobase = _base, \
+- .membase = (void __iomem *)_base,\
+- .mapbase = CPHYSADDR(_base), \
+- .irq = _irq, \
+- .regshift = 2, \
+- .iotype = UPIO_AU, \
+- .flags = UPF_SKIP_TEST \
++#include <asm/mach-au1x00/au1xxx_eth.h>
++
++#define PORT(_base, _irq) \
++ { \
++ .mapbase = _base, \
++ .irq = _irq, \
++ .regshift = 2, \
++ .iotype = UPIO_AU, \
++ .flags = UPF_SKIP_TEST | UPF_IOREMAP | \
++ UPF_FIXED_TYPE, \
++ .type = PORT_16550A, \
+ }
+
+ static struct plat_serial8250_port au1x00_uart_data[] = {
+ #if defined(CONFIG_SERIAL_8250_AU1X00)
+ #if defined(CONFIG_SOC_AU1000)
+- PORT(UART0_ADDR, AU1000_UART0_INT),
+- PORT(UART1_ADDR, AU1000_UART1_INT),
+- PORT(UART2_ADDR, AU1000_UART2_INT),
+- PORT(UART3_ADDR, AU1000_UART3_INT),
++ PORT(UART0_PHYS_ADDR, AU1000_UART0_INT),
++ PORT(UART1_PHYS_ADDR, AU1000_UART1_INT),
++ PORT(UART2_PHYS_ADDR, AU1000_UART2_INT),
++ PORT(UART3_PHYS_ADDR, AU1000_UART3_INT),
+ #elif defined(CONFIG_SOC_AU1500)
+- PORT(UART0_ADDR, AU1500_UART0_INT),
+- PORT(UART3_ADDR, AU1500_UART3_INT),
++ PORT(UART0_PHYS_ADDR, AU1500_UART0_INT),
++ PORT(UART3_PHYS_ADDR, AU1500_UART3_INT),
+ #elif defined(CONFIG_SOC_AU1100)
+- PORT(UART0_ADDR, AU1100_UART0_INT),
+- PORT(UART1_ADDR, AU1100_UART1_INT),
+- PORT(UART3_ADDR, AU1100_UART3_INT),
++ PORT(UART0_PHYS_ADDR, AU1100_UART0_INT),
++ PORT(UART1_PHYS_ADDR, AU1100_UART1_INT),
++ PORT(UART3_PHYS_ADDR, AU1100_UART3_INT),
+ #elif defined(CONFIG_SOC_AU1550)
+- PORT(UART0_ADDR, AU1550_UART0_INT),
+- PORT(UART1_ADDR, AU1550_UART1_INT),
+- PORT(UART3_ADDR, AU1550_UART3_INT),
++ PORT(UART0_PHYS_ADDR, AU1550_UART0_INT),
++ PORT(UART1_PHYS_ADDR, AU1550_UART1_INT),
++ PORT(UART3_PHYS_ADDR, AU1550_UART3_INT),
+ #elif defined(CONFIG_SOC_AU1200)
+- PORT(UART0_ADDR, AU1200_UART0_INT),
+- PORT(UART1_ADDR, AU1200_UART1_INT),
++ PORT(UART0_PHYS_ADDR, AU1200_UART0_INT),
++ PORT(UART1_PHYS_ADDR, AU1200_UART1_INT),
+ #endif
+ #endif /* CONFIG_SERIAL_8250_AU1X00 */
+ { },
+@@ -73,8 +74,8 @@ static struct resource au1xxx_usb_ohci_resources[] = {
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+- .start = AU1000_USB_HOST_INT,
+- .end = AU1000_USB_HOST_INT,
++ .start = FOR_PLATFORM_C_USB_HOST_INT,
++ .end = FOR_PLATFORM_C_USB_HOST_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+@@ -132,8 +133,8 @@ static struct resource au1xxx_usb_ehci_resources[] = {
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+- .start = AU1000_USB_HOST_INT,
+- .end = AU1000_USB_HOST_INT,
++ .start = AU1200_USB_INT,
++ .end = AU1200_USB_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+@@ -308,11 +309,6 @@ static struct platform_device au1200_mmc1_device = {
+ #endif /* #ifndef CONFIG_MIPS_DB1200 */
+ #endif /* #ifdef CONFIG_SOC_AU1200 */
+
+-static struct platform_device au1x00_pcmcia_device = {
+- .name = "au1x00-pcmcia",
+- .id = 0,
+-};
+-
+ /* All Alchemy demoboards with I2C have this #define in their headers */
+ #ifdef SMBUS_PSC_BASE
+ static struct resource pbdb_smbus_resources[] = {
+@@ -331,10 +327,91 @@ static struct platform_device pbdb_smbus_device = {
+ };
+ #endif
+
++/* Macro to help defining the Ethernet MAC resources */
++#define MAC_RES(_base, _enable, _irq) \
++ { \
++ .start = CPHYSADDR(_base), \
++ .end = CPHYSADDR(_base + 0xffff), \
++ .flags = IORESOURCE_MEM, \
++ }, \
++ { \
++ .start = CPHYSADDR(_enable), \
++ .end = CPHYSADDR(_enable + 0x3), \
++ .flags = IORESOURCE_MEM, \
++ }, \
++ { \
++ .start = _irq, \
++ .end = _irq, \
++ .flags = IORESOURCE_IRQ \
++ }
++
++static struct resource au1xxx_eth0_resources[] = {
++#if defined(CONFIG_SOC_AU1000)
++ MAC_RES(AU1000_ETH0_BASE, AU1000_MAC0_ENABLE, AU1000_MAC0_DMA_INT),
++#elif defined(CONFIG_SOC_AU1100)
++ MAC_RES(AU1100_ETH0_BASE, AU1100_MAC0_ENABLE, AU1100_MAC0_DMA_INT),
++#elif defined(CONFIG_SOC_AU1550)
++ MAC_RES(AU1550_ETH0_BASE, AU1550_MAC0_ENABLE, AU1550_MAC0_DMA_INT),
++#elif defined(CONFIG_SOC_AU1500)
++ MAC_RES(AU1500_ETH0_BASE, AU1500_MAC0_ENABLE, AU1500_MAC0_DMA_INT),
++#endif
++};
++
++static struct resource au1xxx_eth1_resources[] = {
++#if defined(CONFIG_SOC_AU1000)
++ MAC_RES(AU1000_ETH1_BASE, AU1000_MAC1_ENABLE, AU1000_MAC1_DMA_INT),
++#elif defined(CONFIG_SOC_AU1550)
++ MAC_RES(AU1550_ETH1_BASE, AU1550_MAC1_ENABLE, AU1550_MAC1_DMA_INT),
++#elif defined(CONFIG_SOC_AU1500)
++ MAC_RES(AU1500_ETH1_BASE, AU1500_MAC1_ENABLE, AU1500_MAC1_DMA_INT),
++#endif
++};
++
++static struct au1000_eth_platform_data au1xxx_eth0_platform_data = {
++ .phy1_search_mac0 = 1,
++};
++
++static struct platform_device au1xxx_eth0_device = {
++ .name = "au1000-eth",
++ .id = 0,
++ .num_resources = ARRAY_SIZE(au1xxx_eth0_resources),
++ .resource = au1xxx_eth0_resources,
++ .dev.platform_data = &au1xxx_eth0_platform_data,
++};
++
++#ifndef CONFIG_SOC_AU1100
++static struct au1000_eth_platform_data au1xxx_eth1_platform_data = {
++ .phy1_search_mac0 = 1,
++};
++
++static struct platform_device au1xxx_eth1_device = {
++ .name = "au1000-eth",
++ .id = 1,
++ .num_resources = ARRAY_SIZE(au1xxx_eth1_resources),
++ .resource = au1xxx_eth1_resources,
++ .dev.platform_data = &au1xxx_eth1_platform_data,
++};
++#endif
++
++void __init au1xxx_override_eth_cfg(unsigned int port,
++ struct au1000_eth_platform_data *eth_data)
++{
++ if (!eth_data || port > 1)
++ return;
++
++ if (port == 0)
++ memcpy(&au1xxx_eth0_platform_data, eth_data,
++ sizeof(struct au1000_eth_platform_data));
++#ifndef CONFIG_SOC_AU1100
++ else
++ memcpy(&au1xxx_eth1_platform_data, eth_data,
++ sizeof(struct au1000_eth_platform_data));
++#endif
++}
++
+ static struct platform_device *au1xxx_platform_devices[] __initdata = {
+ &au1xx0_uart_device,
+ &au1xxx_usb_ohci_device,
+- &au1x00_pcmcia_device,
+ #ifdef CONFIG_FB_AU1100
+ &au1100_lcd_device,
+ #endif
+@@ -351,6 +428,7 @@ static struct platform_device *au1xxx_platform_devices[] __initdata = {
+ #ifdef SMBUS_PSC_BASE
+ &pbdb_smbus_device,
+ #endif
++ &au1xxx_eth0_device,
+ };
+
+ static int __init au1xxx_platform_init(void)
+@@ -362,6 +440,12 @@ static int __init au1xxx_platform_init(void)
+ for (i = 0; au1x00_uart_data[i].flags; i++)
+ au1x00_uart_data[i].uartclk = uartclk;
+
++#ifndef CONFIG_SOC_AU1100
++ /* Register second MAC if enabled in pinfunc */
++ if (!(au_readl(SYS_PINFUNC) & (u32)SYS_PF_NI2))
++ platform_device_register(&au1xxx_eth1_device);
++#endif
++
+ return platform_add_devices(au1xxx_platform_devices,
+ ARRAY_SIZE(au1xxx_platform_devices));
+ }
+diff --git a/arch/mips/alchemy/common/puts.c b/arch/mips/alchemy/common/puts.c
+deleted file mode 100644
+index 55bbe24..0000000
+--- a/arch/mips/alchemy/common/puts.c
++++ /dev/null
+@@ -1,68 +0,0 @@
+-/*
+- *
+- * BRIEF MODULE DESCRIPTION
+- * Low level UART routines to directly access Alchemy UART.
+- *
+- * Copyright 2001, 2008 MontaVista Software Inc.
+- * Author: MontaVista Software, Inc. <source@mvista.com>
+- *
+- * 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.
+- */
+-
+-#include <asm/mach-au1x00/au1000.h>
+-
+-#define SERIAL_BASE UART_BASE
+-#define SER_CMD 0x7
+-#define SER_DATA 0x1
+-#define TX_BUSY 0x20
+-
+-#define TIMEOUT 0xffffff
+-#define SLOW_DOWN
+-
+-static volatile unsigned long * const com1 = (unsigned long *)SERIAL_BASE;
+-
+-#ifdef SLOW_DOWN
+-static inline void slow_down(void)
+-{
+- int k;
+-
+- for (k = 0; k < 10000; k++);
+-}
+-#else
+-#define slow_down()
+-#endif
+-
+-void
+-prom_putchar(const unsigned char c)
+-{
+- unsigned char ch;
+- int i = 0;
+-
+- do {
+- ch = com1[SER_CMD];
+- slow_down();
+- i++;
+- if (i > TIMEOUT)
+- break;
+- } while (0 == (ch & TX_BUSY));
+-
+- com1[SER_DATA] = c;
+-}
+diff --git a/arch/mips/alchemy/common/reset.c b/arch/mips/alchemy/common/reset.c
+index 4791011..266afd4 100644
+--- a/arch/mips/alchemy/common/reset.c
++++ b/arch/mips/alchemy/common/reset.c
+@@ -164,9 +164,6 @@ void au1000_halt(void)
+ #ifdef CONFIG_MIPS_MIRAGE
+ gpio_direction_output(210, 1);
+ #endif
+-#ifdef CONFIG_MIPS_DB1200
+- au_writew(au_readw(0xB980001C) | (1 << 14), 0xB980001C);
+-#endif
+ #ifdef CONFIG_PM
+ au_sleep();
+
+diff --git a/arch/mips/alchemy/common/setup.c b/arch/mips/alchemy/common/setup.c
+index 6184baa..375984e 100644
+--- a/arch/mips/alchemy/common/setup.c
++++ b/arch/mips/alchemy/common/setup.c
+@@ -107,7 +107,8 @@ phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size)
+ * The pseudo address we use is 0xF400 0000. Any address over
+ * 0xF400 0000 is a PCMCIA pseudo address.
+ */
+- if ((phys_addr >= 0xF4000000) && (phys_addr < 0xFFFFFFFF))
++ if ((phys_addr >= PCMCIA_ATTR_PSEUDO_PHYS) &&
++ (phys_addr < PCMCIA_PSEUDO_END))
+ return (phys_t)(phys_addr << 4);
+
+ /* default nop */
+diff --git a/arch/mips/alchemy/common/time.c b/arch/mips/alchemy/common/time.c
+index 379a664..2aecb2f 100644
+--- a/arch/mips/alchemy/common/time.c
++++ b/arch/mips/alchemy/common/time.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2008 Manuel Lauss <mano@roarinelk.homelinux.net>
++ * Copyright (C) 2008-2009 Manuel Lauss <manuel.lauss@gmail.com>
+ *
+ * Previous incarnations were:
+ * Copyright (C) 2001, 2006, 2008 MontaVista Software, <source@mvista.com>
+@@ -85,7 +85,6 @@ static struct clock_event_device au1x_rtcmatch2_clockdev = {
+ .name = "rtcmatch2",
+ .features = CLOCK_EVT_FEAT_ONESHOT,
+ .rating = 100,
+- .irq = AU1000_RTC_MATCH2_INT,
+ .set_next_event = au1x_rtcmatch2_set_next_event,
+ .set_mode = au1x_rtcmatch2_set_mode,
+ .cpumask = cpu_all_mask,
+@@ -98,11 +97,13 @@ static struct irqaction au1x_rtcmatch2_irqaction = {
+ .dev_id = &au1x_rtcmatch2_clockdev,
+ };
+
+-void __init plat_time_init(void)
++static int __init alchemy_time_init(unsigned int m2int)
+ {
+ struct clock_event_device *cd = &au1x_rtcmatch2_clockdev;
+ unsigned long t;
+
++ au1x_rtcmatch2_clockdev.irq = m2int;
++
+ /* Check if firmware (YAMON, ...) has enabled 32kHz and clock
+ * has been detected. If so install the rtcmatch2 clocksource,
+ * otherwise don't bother. Note that both bits being set is by
+@@ -148,13 +149,18 @@ void __init plat_time_init(void)
+ cd->max_delta_ns = clockevent_delta2ns(0xffffffff, cd);
+ cd->min_delta_ns = clockevent_delta2ns(8, cd); /* ~0.25ms */
+ clockevents_register_device(cd);
+- setup_irq(AU1000_RTC_MATCH2_INT, &au1x_rtcmatch2_irqaction);
++ setup_irq(m2int, &au1x_rtcmatch2_irqaction);
+
+ printk(KERN_INFO "Alchemy clocksource installed\n");
+
+- return;
++ return 0;
+
+ cntr_err:
++ return -1;
++}
++
++static void __init alchemy_setup_c0timer(void)
++{
+ /*
+ * MIPS kernel assigns 'au1k_wait' to 'cpu_wait' before this
+ * function is called. Because the Alchemy counters are unusable
+@@ -166,3 +172,22 @@ cntr_err:
+ r4k_clockevent_init();
+ init_r4k_clocksource();
+ }
++
++static int alchemy_m2inttab[] __initdata = {
++ AU1000_RTC_MATCH2_INT,
++ AU1500_RTC_MATCH2_INT,
++ AU1100_RTC_MATCH2_INT,
++ AU1550_RTC_MATCH2_INT,
++ AU1200_RTC_MATCH2_INT,
++};
++
++void __init plat_time_init(void)
++{
++ int t;
++
++ t = alchemy_get_cputype();
++ if (t == ALCHEMY_CPU_UNKNOWN)
++ alchemy_setup_c0timer();
++ else if (alchemy_time_init(alchemy_m2inttab[t]))
++ alchemy_setup_c0timer();
++}
+diff --git a/arch/mips/alchemy/devboards/Makefile b/arch/mips/alchemy/devboards/Makefile
+index 730f9f2..ecbd37f 100644
+--- a/arch/mips/alchemy/devboards/Makefile
++++ b/arch/mips/alchemy/devboards/Makefile
+@@ -2,7 +2,7 @@
+ # Alchemy Develboards
+ #
+
+-obj-y += prom.o
++obj-y += prom.o bcsr.o platform.o
+ obj-$(CONFIG_PM) += pm.o
+ obj-$(CONFIG_MIPS_PB1000) += pb1000/
+ obj-$(CONFIG_MIPS_PB1100) += pb1100/
+@@ -11,8 +11,10 @@ obj-$(CONFIG_MIPS_PB1500) += pb1500/
+ obj-$(CONFIG_MIPS_PB1550) += pb1550/
+ obj-$(CONFIG_MIPS_DB1000) += db1x00/
+ obj-$(CONFIG_MIPS_DB1100) += db1x00/
+-obj-$(CONFIG_MIPS_DB1200) += pb1200/
++obj-$(CONFIG_MIPS_DB1200) += db1200/
+ obj-$(CONFIG_MIPS_DB1500) += db1x00/
+ obj-$(CONFIG_MIPS_DB1550) += db1x00/
+ obj-$(CONFIG_MIPS_BOSPORUS) += db1x00/
+ obj-$(CONFIG_MIPS_MIRAGE) += db1x00/
++
++EXTRA_CFLAGS += -Werror
+diff --git a/arch/mips/alchemy/devboards/bcsr.c b/arch/mips/alchemy/devboards/bcsr.c
+new file mode 100644
+index 0000000..3bc4fd2
+--- /dev/null
++++ b/arch/mips/alchemy/devboards/bcsr.c
+@@ -0,0 +1,148 @@
++/*
++ * bcsr.h -- Db1xxx/Pb1xxx Devboard CPLD registers ("BCSR") abstraction.
++ *
++ * All Alchemy development boards (except, of course, the weird PB1000)
++ * have a few registers in a CPLD with standardised layout; they mostly
++ * only differ in base address.
++ * All registers are 16bits wide with 32bit spacing.
++ */
++
++#include <linux/interrupt.h>
++#include <linux/module.h>
++#include <linux/spinlock.h>
++#include <asm/addrspace.h>
++#include <asm/io.h>
++#include <asm/mach-db1x00/bcsr.h>
++
++static struct bcsr_reg {
++ void __iomem *raddr;
++ spinlock_t lock;
++} bcsr_regs[BCSR_CNT];
++
++static void __iomem *bcsr_virt; /* KSEG1 addr of BCSR base */
++static int bcsr_csc_base; /* linux-irq of first cascaded irq */
++
++void __init bcsr_init(unsigned long bcsr1_phys, unsigned long bcsr2_phys)
++{
++ int i;
++
++ bcsr1_phys = KSEG1ADDR(CPHYSADDR(bcsr1_phys));
++ bcsr2_phys = KSEG1ADDR(CPHYSADDR(bcsr2_phys));
++
++ bcsr_virt = (void __iomem *)bcsr1_phys;
++
++ for (i = 0; i < BCSR_CNT; i++) {
++ if (i >= BCSR_HEXLEDS)
++ bcsr_regs[i].raddr = (void __iomem *)bcsr2_phys +
++ (0x04 * (i - BCSR_HEXLEDS));
++ else
++ bcsr_regs[i].raddr = (void __iomem *)bcsr1_phys +
++ (0x04 * i);
++
++ spin_lock_init(&bcsr_regs[i].lock);
++ }
++}
++
++unsigned short bcsr_read(enum bcsr_id reg)
++{
++ unsigned short r;
++ unsigned long flags;
++
++ spin_lock_irqsave(&bcsr_regs[reg].lock, flags);
++ r = __raw_readw(bcsr_regs[reg].raddr);
++ spin_unlock_irqrestore(&bcsr_regs[reg].lock, flags);
++ return r;
++}
++EXPORT_SYMBOL_GPL(bcsr_read);
++
++void bcsr_write(enum bcsr_id reg, unsigned short val)
++{
++ unsigned long flags;
++
++ spin_lock_irqsave(&bcsr_regs[reg].lock, flags);
++ __raw_writew(val, bcsr_regs[reg].raddr);
++ wmb();
++ spin_unlock_irqrestore(&bcsr_regs[reg].lock, flags);
++}
++EXPORT_SYMBOL_GPL(bcsr_write);
++
++void bcsr_mod(enum bcsr_id reg, unsigned short clr, unsigned short set)
++{
++ unsigned short r;
++ unsigned long flags;
++
++ spin_lock_irqsave(&bcsr_regs[reg].lock, flags);
++ r = __raw_readw(bcsr_regs[reg].raddr);
++ r &= ~clr;
++ r |= set;
++ __raw_writew(r, bcsr_regs[reg].raddr);
++ wmb();
++ spin_unlock_irqrestore(&bcsr_regs[reg].lock, flags);
++}
++EXPORT_SYMBOL_GPL(bcsr_mod);
++
++/*
++ * DB1200/PB1200 CPLD IRQ muxer
++ */
++static void bcsr_csc_handler(unsigned int irq, struct irq_desc *d)
++{
++ unsigned short bisr = __raw_readw(bcsr_virt + BCSR_REG_INTSTAT);
++
++ for ( ; bisr; bisr &= bisr - 1)
++ generic_handle_irq(bcsr_csc_base + __ffs(bisr));
++}
++
++/* NOTE: both the enable and mask bits must be cleared, otherwise the
++ * CPLD generates tons of spurious interrupts (at least on my DB1200).
++ * -- mlau
++ */
++static void bcsr_irq_mask(unsigned int irq_nr)
++{
++ unsigned short v = 1 << (irq_nr - bcsr_csc_base);
++ __raw_writew(v, bcsr_virt + BCSR_REG_INTCLR);
++ __raw_writew(v, bcsr_virt + BCSR_REG_MASKCLR);
++ wmb();
++}
++
++static void bcsr_irq_maskack(unsigned int irq_nr)
++{
++ unsigned short v = 1 << (irq_nr - bcsr_csc_base);
++ __raw_writew(v, bcsr_virt + BCSR_REG_INTCLR);
++ __raw_writew(v, bcsr_virt + BCSR_REG_MASKCLR);
++ __raw_writew(v, bcsr_virt + BCSR_REG_INTSTAT); /* ack */
++ wmb();
++}
++
++static void bcsr_irq_unmask(unsigned int irq_nr)
++{
++ unsigned short v = 1 << (irq_nr - bcsr_csc_base);
++ __raw_writew(v, bcsr_virt + BCSR_REG_INTSET);
++ __raw_writew(v, bcsr_virt + BCSR_REG_MASKSET);
++ wmb();
++}
++
++static struct irq_chip bcsr_irq_type = {
++ .name = "CPLD",
++ .mask = bcsr_irq_mask,
++ .mask_ack = bcsr_irq_maskack,
++ .unmask = bcsr_irq_unmask,
++};
++
++void __init bcsr_init_irq(int csc_start, int csc_end, int hook_irq)
++{
++ unsigned int irq;
++
++ /* mask & disable & ack all */
++ __raw_writew(0xffff, bcsr_virt + BCSR_REG_INTCLR);
++ __raw_writew(0xffff, bcsr_virt + BCSR_REG_MASKCLR);
++ __raw_writew(0xffff, bcsr_virt + BCSR_REG_INTSTAT);
++ wmb();
++
++ bcsr_csc_base = csc_start;
++
++ for (irq = csc_start; irq <= csc_end; irq++)
++ set_irq_chip_and_handler_name(irq, &bcsr_irq_type,
++ handle_level_irq, "level");
++
++ set_irq_chained_handler(hook_irq, bcsr_csc_handler);
++}
+diff --git a/arch/mips/alchemy/devboards/db1200/Makefile b/arch/mips/alchemy/devboards/db1200/Makefile
+new file mode 100644
+index 0000000..17840a5
+--- /dev/null
++++ b/arch/mips/alchemy/devboards/db1200/Makefile
+@@ -0,0 +1 @@
++obj-y += setup.o platform.o
+diff --git a/arch/mips/alchemy/devboards/db1200/platform.c b/arch/mips/alchemy/devboards/db1200/platform.c
+new file mode 100644
+index 0000000..d6b3e64
+--- /dev/null
++++ b/arch/mips/alchemy/devboards/db1200/platform.c
+@@ -0,0 +1,561 @@
++/*
++ * DBAu1200 board platform device registration
++ *
++ * Copyright (C) 2008-2009 Manuel Lauss
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#include <linux/dma-mapping.h>
++#include <linux/gpio.h>
++#include <linux/i2c.h>
++#include <linux/init.h>
++#include <linux/io.h>
++#include <linux/leds.h>
++#include <linux/mmc/host.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/nand.h>
++#include <linux/mtd/partitions.h>
++#include <linux/platform_device.h>
++#include <linux/serial_8250.h>
++#include <linux/spi/spi.h>
++#include <linux/spi/flash.h>
++#include <linux/smc91x.h>
++
++#include <asm/mach-au1x00/au1100_mmc.h>
++#include <asm/mach-au1x00/au1xxx_dbdma.h>
++#include <asm/mach-au1x00/au1550_spi.h>
++#include <asm/mach-db1x00/bcsr.h>
++#include <asm/mach-db1x00/db1200.h>
++
++#include "../platform.h"
++
++static struct mtd_partition db1200_spiflash_parts[] = {
++ {
++ .name = "DB1200 SPI flash",
++ .offset = 0,
++ .size = MTDPART_SIZ_FULL,
++ },
++};
++
++static struct flash_platform_data db1200_spiflash_data = {
++ .name = "s25fl001",
++ .parts = db1200_spiflash_parts,
++ .nr_parts = ARRAY_SIZE(db1200_spiflash_parts),
++ .type = "m25p10",
++};
++
++static struct spi_board_info db1200_spi_devs[] __initdata = {
++ {
++ /* TI TMP121AIDBVR temp sensor */
++ .modalias = "tmp121",
++ .max_speed_hz = 2000000,
++ .bus_num = 0,
++ .chip_select = 0,
++ .mode = 0,
++ },
++ {
++ /* Spansion S25FL001D0FMA SPI flash */
++ .modalias = "m25p80",
++ .max_speed_hz = 50000000,
++ .bus_num = 0,
++ .chip_select = 1,
++ .mode = 0,
++ .platform_data = &db1200_spiflash_data,
++ },
++};
++
++static struct i2c_board_info db1200_i2c_devs[] __initdata = {
++ {
++ /* AT24C04-10 I2C eeprom */
++ I2C_BOARD_INFO("24c04", 0x52),
++ },
++ {
++ /* Philips NE1619 temp/voltage sensor (adm1025 drv) */
++ I2C_BOARD_INFO("ne1619", 0x2d),
++ },
++ {
++ /* I2S audio codec WM8731 */
++ I2C_BOARD_INFO("wm8731", 0x1b),
++ },
++};
++
++/**********************************************************************/
++
++static void au1200_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
++ unsigned int ctrl)
++{
++ struct nand_chip *this = mtd->priv;
++ unsigned long ioaddr = (unsigned long)this->IO_ADDR_W;
++
++ ioaddr &= 0xffffff00;
++
++ if (ctrl & NAND_CLE) {
++ ioaddr += MEM_STNAND_CMD;
++ } else if (ctrl & NAND_ALE) {
++ ioaddr += MEM_STNAND_ADDR;
++ } else {
++ /* assume we want to r/w real data by default */
++ ioaddr += MEM_STNAND_DATA;
++ }
++ this->IO_ADDR_R = this->IO_ADDR_W = (void __iomem *)ioaddr;
++ if (cmd != NAND_CMD_NONE) {
++ __raw_writeb(cmd, this->IO_ADDR_W);
++ wmb();
++ }
++}
++
++static int au1200_nand_device_ready(struct mtd_info *mtd)
++{
++ return __raw_readl((void __iomem *)MEM_STSTAT) & 1;
++}
++
++static const char *db1200_part_probes[] = { "cmdlinepart", NULL };
++
++static struct mtd_partition db1200_nand_parts[] = {
++ {
++ .name = "NAND FS 0",
++ .offset = 0,
++ .size = 8 * 1024 * 1024,
++ },
++ {
++ .name = "NAND FS 1",
++ .offset = MTDPART_OFS_APPEND,
++ .size = MTDPART_SIZ_FULL
++ },
++};
++
++struct platform_nand_data db1200_nand_platdata = {
++ .chip = {
++ .nr_chips = 1,
++ .chip_offset = 0,
++ .nr_partitions = ARRAY_SIZE(db1200_nand_parts),
++ .partitions = db1200_nand_parts,
++ .chip_delay = 20,
++ .part_probe_types = db1200_part_probes,
++ },
++ .ctrl = {
++ .dev_ready = au1200_nand_device_ready,
++ .cmd_ctrl = au1200_nand_cmd_ctrl,
++ },
++};
++
++static struct resource db1200_nand_res[] = {
++ [0] = {
++ .start = DB1200_NAND_PHYS_ADDR,
++ .end = DB1200_NAND_PHYS_ADDR + 0xff,
++ .flags = IORESOURCE_MEM,
++ },
++};
++
++static struct platform_device db1200_nand_dev = {
++ .name = "gen_nand",
++ .num_resources = ARRAY_SIZE(db1200_nand_res),
++ .resource = db1200_nand_res,
++ .id = -1,
++ .dev = {
++ .platform_data = &db1200_nand_platdata,
++ }
++};
++
++/**********************************************************************/
++
++static struct smc91x_platdata db1200_eth_data = {
++ .flags = SMC91X_NOWAIT | SMC91X_USE_16BIT,
++ .leda = RPC_LED_100_10,
++ .ledb = RPC_LED_TX_RX,
++};
++
++static struct resource db1200_eth_res[] = {
++ [0] = {
++ .start = DB1200_ETH_PHYS_ADDR,
++ .end = DB1200_ETH_PHYS_ADDR + 0xf,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = DB1200_ETH_INT,
++ .end = DB1200_ETH_INT,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct platform_device db1200_eth_dev = {
++ .dev = {
++ .platform_data = &db1200_eth_data,
++ },
++ .name = "smc91x",
++ .id = -1,
++ .num_resources = ARRAY_SIZE(db1200_eth_res),
++ .resource = db1200_eth_res,
++};
++
++/**********************************************************************/
++
++static struct resource db1200_ide_res[] = {
++ [0] = {
++ .start = DB1200_IDE_PHYS_ADDR,
++ .end = DB1200_IDE_PHYS_ADDR + DB1200_IDE_PHYS_LEN - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = DB1200_IDE_INT,
++ .end = DB1200_IDE_INT,
++ .flags = IORESOURCE_IRQ,
++ }
++};
++
++static u64 ide_dmamask = DMA_32BIT_MASK;
++
++static struct platform_device db1200_ide_dev = {
++ .name = "au1200-ide",
++ .id = 0,
++ .dev = {
++ .dma_mask = &ide_dmamask,
++ .coherent_dma_mask = DMA_32BIT_MASK,
++ },
++ .num_resources = ARRAY_SIZE(db1200_ide_res),
++ .resource = db1200_ide_res,
++};
++
++/**********************************************************************/
++
++static struct platform_device db1200_rtc_dev = {
++ .name = "rtc-au1xxx",
++ .id = -1,
++};
++
++/**********************************************************************/
++
++/* SD carddetects: they're supposed to be edge-triggered, but ack
++ * doesn't seem to work (CPLD Rev 2). Instead, the screaming one
++ * is disabled and its counterpart enabled. The 500ms timeout is
++ * because the carddetect isn't debounced in hardware.
++ */
++static irqreturn_t db1200_mmc_cd(int irq, void *ptr)
++{
++ void(*mmc_cd)(struct mmc_host *, unsigned long);
++
++ if (irq == DB1200_SD0_INSERT_INT) {
++ disable_irq_nosync(DB1200_SD0_INSERT_INT);
++ enable_irq(DB1200_SD0_EJECT_INT);
++ } else {
++ disable_irq_nosync(DB1200_SD0_EJECT_INT);
++ enable_irq(DB1200_SD0_INSERT_INT);
++ }
++
++ /* link against CONFIG_MMC=m */
++ mmc_cd = symbol_get(mmc_detect_change);
++ if (mmc_cd) {
++ mmc_cd(ptr, msecs_to_jiffies(500));
++ symbol_put(mmc_detect_change);
++ }
++
++ return IRQ_HANDLED;
++}
++
++static int db1200_mmc_cd_setup(void *mmc_host, int en)
++{
++ int ret;
++
++ if (en) {
++ ret = request_irq(DB1200_SD0_INSERT_INT, db1200_mmc_cd,
++ IRQF_DISABLED, "sd_insert", mmc_host);
++ if (ret)
++ goto out;
++
++ ret = request_irq(DB1200_SD0_EJECT_INT, db1200_mmc_cd,
++ IRQF_DISABLED, "sd_eject", mmc_host);
++ if (ret) {
++ free_irq(DB1200_SD0_INSERT_INT, mmc_host);
++ goto out;
++ }
++
++ if (bcsr_read(BCSR_SIGSTAT) & BCSR_INT_SD0INSERT)
++ enable_irq(DB1200_SD0_EJECT_INT);
++ else
++ enable_irq(DB1200_SD0_INSERT_INT);
++
++ } else {
++ free_irq(DB1200_SD0_INSERT_INT, mmc_host);
++ free_irq(DB1200_SD0_EJECT_INT, mmc_host);
++ }
++ ret = 0;
++out:
++ return ret;
++}
++
++static void db1200_mmc_set_power(void *mmc_host, int state)
++{
++ if (state) {
++ bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_SD0PWR);
++ msleep(400); /* stabilization time */
++ } else
++ bcsr_mod(BCSR_BOARD, BCSR_BOARD_SD0PWR, 0);
++}
++
++static int db1200_mmc_card_readonly(void *mmc_host)
++{
++ return (bcsr_read(BCSR_STATUS) & BCSR_STATUS_SD0WP) ? 1 : 0;
++}
++
++static int db1200_mmc_card_inserted(void *mmc_host)
++{
++ return (bcsr_read(BCSR_SIGSTAT) & BCSR_INT_SD0INSERT) ? 1 : 0;
++}
++
++static void db1200_mmcled_set(struct led_classdev *led,
++ enum led_brightness brightness)
++{
++ if (brightness != LED_OFF)
++ bcsr_mod(BCSR_LEDS, BCSR_LEDS_LED0, 0);
++ else
++ bcsr_mod(BCSR_LEDS, 0, BCSR_LEDS_LED0);
++}
++
++static struct led_classdev db1200_mmc_led = {
++ .brightness_set = db1200_mmcled_set,
++};
++
++/* needed by arch/mips/alchemy/common/platform.c */
++struct au1xmmc_platform_data au1xmmc_platdata[] = {
++ [0] = {
++ .cd_setup = db1200_mmc_cd_setup,
++ .set_power = db1200_mmc_set_power,
++ .card_inserted = db1200_mmc_card_inserted,
++ .card_readonly = db1200_mmc_card_readonly,
++ .led = &db1200_mmc_led,
++ },
++};
++
++/**********************************************************************/
++
++static struct resource au1200_psc0_res[] = {
++ [0] = {
++ .start = PSC0_PHYS_ADDR,
++ .end = PSC0_PHYS_ADDR + 0x000fffff,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = AU1200_PSC0_INT,
++ .end = AU1200_PSC0_INT,
++ .flags = IORESOURCE_IRQ,
++ },
++ [2] = {
++ .start = DSCR_CMD0_PSC0_TX,
++ .end = DSCR_CMD0_PSC0_TX,
++ .flags = IORESOURCE_DMA,
++ },
++ [3] = {
++ .start = DSCR_CMD0_PSC0_RX,
++ .end = DSCR_CMD0_PSC0_RX,
++ .flags = IORESOURCE_DMA,
++ },
++};
++
++static struct platform_device db1200_i2c_dev = {
++ .name = "au1xpsc_smbus",
++ .id = 0, /* bus number */
++ .num_resources = ARRAY_SIZE(au1200_psc0_res),
++ .resource = au1200_psc0_res,
++};
++
++static void db1200_spi_cs_en(struct au1550_spi_info *spi, int cs, int pol)
++{
++ if (cs)
++ bcsr_mod(BCSR_RESETS, 0, BCSR_RESETS_SPISEL);
++ else
++ bcsr_mod(BCSR_RESETS, BCSR_RESETS_SPISEL, 0);
++}
++
++static struct au1550_spi_info db1200_spi_platdata = {
++ .mainclk_hz = 50000000, /* PSC0 clock */
++ .num_chipselect = 2,
++ .activate_cs = db1200_spi_cs_en,
++};
++
++static u64 spi_dmamask = DMA_32BIT_MASK;
++
++static struct platform_device db1200_spi_dev = {
++ .dev = {
++ .dma_mask = &spi_dmamask,
++ .coherent_dma_mask = DMA_32BIT_MASK,
++ .platform_data = &db1200_spi_platdata,
++ },
++ .name = "au1550-spi",
++ .id = 0, /* bus number */
++ .num_resources = ARRAY_SIZE(au1200_psc0_res),
++ .resource = au1200_psc0_res,
++};
++
++static struct resource au1200_psc1_res[] = {
++ [0] = {
++ .start = PSC1_PHYS_ADDR,
++ .end = PSC1_PHYS_ADDR + 0x000fffff,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = AU1200_PSC1_INT,
++ .end = AU1200_PSC1_INT,
++ .flags = IORESOURCE_IRQ,
++ },
++ [2] = {
++ .start = DSCR_CMD0_PSC1_TX,
++ .end = DSCR_CMD0_PSC1_TX,
++ .flags = IORESOURCE_DMA,
++ },
++ [3] = {
++ .start = DSCR_CMD0_PSC1_RX,
++ .end = DSCR_CMD0_PSC1_RX,
++ .flags = IORESOURCE_DMA,
++ },
++};
++
++static struct platform_device db1200_audio_dev = {
++ /* name assigned later based on switch setting */
++ .id = 1, /* PSC ID */
++ .num_resources = ARRAY_SIZE(au1200_psc1_res),
++ .resource = au1200_psc1_res,
++};
++
++static struct platform_device *db1200_devs[] __initdata = {
++ NULL, /* PSC0, selected by S6.8 */
++ &db1200_ide_dev,
++ &db1200_eth_dev,
++ &db1200_rtc_dev,
++ &db1200_nand_dev,
++ &db1200_audio_dev,
++};
++
++static int __init db1200_dev_init(void)
++{
++ unsigned long pfc;
++ unsigned short sw;
++ int swapped;
++
++ i2c_register_board_info(0, db1200_i2c_devs,
++ ARRAY_SIZE(db1200_i2c_devs));
++ spi_register_board_info(db1200_spi_devs,
++ ARRAY_SIZE(db1200_i2c_devs));
++
++ /* SWITCHES: S6.8 I2C/SPI selector (OFF=I2C ON=SPI)
++ * S6.7 AC97/I2S selector (OFF=AC97 ON=I2S)
++ */
++
++ /* NOTE: GPIO215 controls OTG VBUS supply. In SPI mode however
++ * this pin is claimed by PSC0 (unused though, but pinmux doesn't
++ * allow to free it without crippling the SPI interface).
++ * As a result, in SPI mode, OTG simply won't work (PSC0 uses
++ * it as an input pin which is pulled high on the boards).
++ */
++ pfc = __raw_readl((void __iomem *)SYS_PINFUNC) & ~SYS_PINFUNC_P0A;
++
++ /* switch off OTG VBUS supply */
++ gpio_request(215, "otg-vbus");
++ gpio_direction_output(215, 1);
++
++ printk(KERN_INFO "DB1200 device configuration:\n");
++
++ sw = bcsr_read(BCSR_SWITCHES);
++ if (sw & BCSR_SWITCHES_DIP_8) {
++ db1200_devs[0] = &db1200_i2c_dev;
++ bcsr_mod(BCSR_RESETS, BCSR_RESETS_PSC0MUX, 0);
++
++ pfc |= (2 << 17); /* GPIO2 block owns GPIO215 */
++
++ printk(KERN_INFO " S6.8 OFF: PSC0 mode I2C\n");
++ printk(KERN_INFO " OTG port VBUS supply available!\n");
++ } else {
++ db1200_devs[0] = &db1200_spi_dev;
++ bcsr_mod(BCSR_RESETS, 0, BCSR_RESETS_PSC0MUX);
++
++ pfc |= (1 << 17); /* PSC0 owns GPIO215 */
++
++ printk(KERN_INFO " S6.8 ON : PSC0 mode SPI\n");
++ printk(KERN_INFO " OTG port VBUS supply disabled\n");
++ }
++ __raw_writel(pfc, (void __iomem *)SYS_PINFUNC);
++ wmb();
++
++ /* Audio: DIP7 selects I2S(0)/AC97(1), but need I2C for I2S!
++ * so: DIP7=1 || DIP8=0 => AC97, DIP7=0 && DIP8=1 => I2S
++ */
++ sw &= BCSR_SWITCHES_DIP_8 | BCSR_SWITCHES_DIP_7;
++ if (sw == BCSR_SWITCHES_DIP_8) {
++ bcsr_mod(BCSR_RESETS, 0, BCSR_RESETS_PSC1MUX);
++ db1200_audio_dev.name = "au1xpsc_i2s";
++ printk(KERN_INFO " S6.7 ON : PSC1 mode I2S\n");
++ } else {
++ bcsr_mod(BCSR_RESETS, BCSR_RESETS_PSC1MUX, 0);
++ db1200_audio_dev.name = "au1xpsc_ac97";
++ printk(KERN_INFO " S6.7 OFF: PSC1 mode AC97\n");
++ }
++
++ /* Audio PSC clock is supplied externally. (FIXME: platdata!!) */
++ __raw_writel(PSC_SEL_CLK_SERCLK,
++ (void __iomem *)KSEG1ADDR(PSC1_PHYS_ADDR) + PSC_SEL_OFFSET);
++ wmb();
++
++ db1x_register_pcmcia_socket(PCMCIA_ATTR_PSEUDO_PHYS,
++ PCMCIA_ATTR_PSEUDO_PHYS + 0x00040000 - 1,
++ PCMCIA_MEM_PSEUDO_PHYS,
++ PCMCIA_MEM_PSEUDO_PHYS + 0x00040000 - 1,
++ PCMCIA_IO_PSEUDO_PHYS,
++ PCMCIA_IO_PSEUDO_PHYS + 0x00001000 - 1,
++ DB1200_PC0_INT,
++ DB1200_PC0_INSERT_INT,
++ /*DB1200_PC0_STSCHG_INT*/0,
++ DB1200_PC0_EJECT_INT,
++ 0);
++
++ db1x_register_pcmcia_socket(PCMCIA_ATTR_PSEUDO_PHYS + 0x00400000,
++ PCMCIA_ATTR_PSEUDO_PHYS + 0x00440000 - 1,
++ PCMCIA_MEM_PSEUDO_PHYS + 0x00400000,
++ PCMCIA_MEM_PSEUDO_PHYS + 0x00440000 - 1,
++ PCMCIA_IO_PSEUDO_PHYS + 0x00400000,
++ PCMCIA_IO_PSEUDO_PHYS + 0x00401000 - 1,
++ DB1200_PC1_INT,
++ DB1200_PC1_INSERT_INT,
++ /*DB1200_PC1_STSCHG_INT*/0,
++ DB1200_PC1_EJECT_INT,
++ 1);
++
++ swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1200_SWAPBOOT;
++ db1x_register_norflash(64 << 20, 2, swapped);
++
++ return platform_add_devices(db1200_devs, ARRAY_SIZE(db1200_devs));
++}
++device_initcall(db1200_dev_init);
++
++/* au1200fb calls these: STERBT EINEN TRAGISCHEN TOD!!! */
++int board_au1200fb_panel(void)
++{
++ return (bcsr_read(BCSR_SWITCHES) >> 8) & 0x0f;
++}
++
++int board_au1200fb_panel_init(void)
++{
++ /* Apply power */
++ bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD |
++ BCSR_BOARD_LCDBL);
++ return 0;
++}
++
++int board_au1200fb_panel_shutdown(void)
++{
++ /* Remove power */
++ bcsr_mod(BCSR_BOARD, BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD |
++ BCSR_BOARD_LCDBL, 0);
++ return 0;
++}
+diff --git a/arch/mips/alchemy/devboards/db1200/setup.c b/arch/mips/alchemy/devboards/db1200/setup.c
+new file mode 100644
+index 0000000..a3458c0
+--- /dev/null
++++ b/arch/mips/alchemy/devboards/db1200/setup.c
+@@ -0,0 +1,137 @@
++/*
++ * Alchemy/AMD/RMI DB1200 board setup.
++ *
++ * Licensed under the terms outlined in the file COPYING in the root of
++ * this source archive.
++ */
++
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/io.h>
++#include <linux/kernel.h>
++#include <linux/pm.h>
++#include <asm/mach-au1x00/au1000.h>
++#include <asm/mach-db1x00/bcsr.h>
++#include <asm/mach-db1x00/db1200.h>
++#include <asm/processor.h>
++#include <asm/reboot.h>
++
++const char *get_system_type(void)
++{
++ return "Alchemy Db1200";
++}
++
++static void board_power_off(void)
++{
++ bcsr_write(BCSR_RESETS, 0);
++ bcsr_write(BCSR_SYSTEM, BCSR_SYSTEM_PWROFF | BCSR_SYSTEM_RESET);
++}
++
++void board_reset(void)
++{
++ bcsr_write(BCSR_RESETS, 0);
++ bcsr_write(BCSR_SYSTEM, 0);
++}
++
++void __init board_setup(void)
++{
++ unsigned long freq0, clksrc, div, pfc;
++ unsigned short whoami;
++
++ bcsr_init(DB1200_BCSR_PHYS_ADDR,
++ DB1200_BCSR_PHYS_ADDR + DB1200_BCSR_HEXLED_OFS);
++
++ whoami = bcsr_read(BCSR_WHOAMI);
++ printk(KERN_INFO "Alchemy/AMD/RMI DB1200 Board, CPLD Rev %d"
++ " Board-ID %d Daughtercard ID %d\n",
++ (whoami >> 4) & 0xf, (whoami >> 8) & 0xf, whoami & 0xf);
++
++ /* SMBus/SPI on PSC0, Audio on PSC1 */
++ pfc = __raw_readl((void __iomem *)SYS_PINFUNC);
++ pfc &= ~(SYS_PINFUNC_P0A | SYS_PINFUNC_P0B);
++ pfc &= ~(SYS_PINFUNC_P1A | SYS_PINFUNC_P1B | SYS_PINFUNC_FS3);
++ pfc |= SYS_PINFUNC_P1C; /* SPI is configured later */
++ __raw_writel(pfc, (void __iomem *)SYS_PINFUNC);
++ wmb();
++
++ /* Clock configurations: PSC0: ~50MHz via Clkgen0, derived from
++ * CPU clock; all other clock generators off/unused.
++ */
++ div = (get_au1x00_speed() + 25000000) / 50000000;
++ if (div & 1)
++ div++;
++ div = ((div >> 1) - 1) & 0xff;
++
++ freq0 = div << SYS_FC_FRDIV0_BIT;
++ __raw_writel(freq0, (void __iomem *)SYS_FREQCTRL0);
++ wmb();
++ freq0 |= SYS_FC_FE0; /* enable F0 */
++ __raw_writel(freq0, (void __iomem *)SYS_FREQCTRL0);
++ wmb();
++
++ /* psc0_intclk comes 1:1 from F0 */
++ clksrc = SYS_CS_MUX_FQ0 << SYS_CS_ME0_BIT;
++ __raw_writel(clksrc, (void __iomem *)SYS_CLKSRC);
++ wmb();
++
++ pm_power_off = board_power_off;
++ _machine_halt = board_power_off;
++ _machine_restart = (void(*)(char *))board_reset;
++}
++
++/* use the hexleds to count the number of times the cpu has entered
++ * wait, the dots to indicate whether the CPU is currently idle or
++ * active (dots off = sleeping, dots on = working) for cases where
++ * the number doesn't change for a long(er) period of time.
++ */
++static void db1200_wait(void)
++{
++ __asm__(" .set push \n"
++ " .set mips3 \n"
++ " .set noreorder \n"
++ " cache 0x14, 0(%0) \n"
++ " cache 0x14, 32(%0) \n"
++ " cache 0x14, 64(%0) \n"
++ /* dots off: we're about to call wait */
++ " lui $26, 0xb980 \n"
++ " ori $27, $0, 3 \n"
++ " sb $27, 0x18($26) \n"
++ " sync \n"
++ " nop \n"
++ " wait \n"
++ " nop \n"
++ " nop \n"
++ " nop \n"
++ " nop \n"
++ " nop \n"
++ /* dots on: there's work to do, increment cntr */
++ " lui $26, 0xb980 \n"
++ " sb $0, 0x18($26) \n"
++ " lui $26, 0xb9c0 \n"
++ " lb $27, 0($26) \n"
++ " addiu $27, $27, 1 \n"
++ " sb $27, 0($26) \n"
++ " sync \n"
++ " .set pop \n"
++ : : "r" (db1200_wait));
++}
++
++static int __init db1200_arch_init(void)
++{
++ /* GPIO7 is low-level triggered CPLD cascade */
++ set_irq_type(AU1200_GPIO7_INT, IRQF_TRIGGER_LOW);
++ bcsr_init_irq(DB1200_INT_BEGIN, DB1200_INT_END, AU1200_GPIO7_INT);
++
++ /* do not autoenable these: CPLD has broken edge int handling,
++ * and the CD handler setup requires manual enabling to work
++ * around that.
++ */
++ irq_to_desc(DB1200_SD0_INSERT_INT)->status |= IRQ_NOAUTOEN;
++ irq_to_desc(DB1200_SD0_EJECT_INT)->status |= IRQ_NOAUTOEN;
++
++ if (cpu_wait)
++ cpu_wait = db1200_wait;
++
++ return 0;
++}
++arch_initcall(db1200_arch_init);
+diff --git a/arch/mips/alchemy/devboards/db1x00/Makefile b/arch/mips/alchemy/devboards/db1x00/Makefile
+index 432241a..613c0c0 100644
+--- a/arch/mips/alchemy/devboards/db1x00/Makefile
++++ b/arch/mips/alchemy/devboards/db1x00/Makefile
+@@ -5,4 +5,4 @@
+ # Makefile for the Alchemy Semiconductor DBAu1xx0 boards.
+ #
+
+-obj-y := board_setup.o irqmap.o
++obj-y := board_setup.o platform.o
+diff --git a/arch/mips/alchemy/devboards/db1x00/board_setup.c b/arch/mips/alchemy/devboards/db1x00/board_setup.c
+index de30d8e..b490eff 100644
+--- a/arch/mips/alchemy/devboards/db1x00/board_setup.c
++++ b/arch/mips/alchemy/devboards/db1x00/board_setup.c
+@@ -29,14 +29,59 @@
+
+ #include <linux/gpio.h>
+ #include <linux/init.h>
++#include <linux/interrupt.h>
+
+ #include <asm/mach-au1x00/au1000.h>
++#include <asm/mach-au1x00/au1xxx_eth.h>
+ #include <asm/mach-db1x00/db1x00.h>
++#include <asm/mach-db1x00/bcsr.h>
+
+ #include <prom.h>
+
++#ifdef CONFIG_MIPS_DB1500
++char irq_tab_alchemy[][5] __initdata = {
++ [12] = { -1, AU1500_PCI_INTA, 0xff, 0xff, 0xff }, /* IDSEL 12 - HPT371 */
++ [13] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, AU1500_PCI_INTC, AU1500_PCI_INTD }, /* IDSEL 13 - PCI slot */
++};
++#endif
++
++/*
++ * Micrel/Kendin 5 port switch attached to MAC0,
++ * MAC0 is associated with PHY address 5 (== WAN port)
++ * MAC1 is not associated with any PHY, since it's connected directly
++ * to the switch.
++ * no interrupts are used
++ */
++static struct au1000_eth_platform_data eth0_pdata = {
++ .phy_static_config = 1,
++ .phy_addr = 5,
++};
++
++#ifdef CONFIG_MIPS_BOSPORUS
++char irq_tab_alchemy[][5] __initdata = {
++ [11] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, 0xff, 0xff }, /* IDSEL 11 - miniPCI */
++ [12] = { -1, AU1500_PCI_INTA, 0xff, 0xff, 0xff }, /* IDSEL 12 - SN1741 */
++ [13] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, AU1500_PCI_INTC, AU1500_PCI_INTD }, /* IDSEL 13 - PCI slot */
++};
++
+
+-static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
++#endif
++
++#ifdef CONFIG_MIPS_MIRAGE
++char irq_tab_alchemy[][5] __initdata = {
++ [11] = { -1, AU1500_PCI_INTD, 0xff, 0xff, 0xff }, /* IDSEL 11 - SMI VGX */
++ [12] = { -1, 0xff, 0xff, AU1500_PCI_INTC, 0xff }, /* IDSEL 12 - PNX1300 */
++ [13] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, 0xff, 0xff }, /* IDSEL 13 - miniPCI */
++};
++#endif
++
++#ifdef CONFIG_MIPS_DB1550
++char irq_tab_alchemy[][5] __initdata = {
++ [11] = { -1, AU1550_PCI_INTC, 0xff, 0xff, 0xff }, /* IDSEL 11 - on-board HPT371 */
++ [12] = { -1, AU1550_PCI_INTB, AU1550_PCI_INTC, AU1550_PCI_INTD, AU1550_PCI_INTA }, /* IDSEL 12 - PCI slot 2 (left) */
++ [13] = { -1, AU1550_PCI_INTA, AU1550_PCI_INTB, AU1550_PCI_INTC, AU1550_PCI_INTD }, /* IDSEL 13 - PCI slot 1 (right) */
++};
++#endif
+
+ const char *get_system_type(void)
+ {
+@@ -49,15 +94,47 @@ const char *get_system_type(void)
+
+ void board_reset(void)
+ {
+- /* Hit BCSR.SW_RESET[RESET] */
+- bcsr->swreset = 0x0000;
++ bcsr_write(BCSR_SYSTEM, 0);
+ }
+
+ void __init board_setup(void)
+ {
+- u32 pin_func = 0;
++ unsigned long bcsr1, bcsr2;
++ u32 pin_func;
+ char *argptr;
+
++ bcsr1 = DB1000_BCSR_PHYS_ADDR;
++ bcsr2 = DB1000_BCSR_PHYS_ADDR + DB1000_BCSR_HEXLED_OFS;
++
++ pin_func = 0;
++
++#ifdef CONFIG_MIPS_DB1000
++ printk(KERN_INFO "AMD Alchemy Au1000/Db1000 Board\n");
++#endif
++#ifdef CONFIG_MIPS_DB1500
++ printk(KERN_INFO "AMD Alchemy Au1500/Db1500 Board\n");
++#endif
++#ifdef CONFIG_MIPS_DB1100
++ printk(KERN_INFO "AMD Alchemy Au1100/Db1100 Board\n");
++#endif
++#ifdef CONFIG_MIPS_BOSPORUS
++ au1xxx_override_eth_cfg(0, &eth0_pdata);
++
++ printk(KERN_INFO "AMD Alchemy Bosporus Board\n");
++#endif
++#ifdef CONFIG_MIPS_MIRAGE
++ printk(KERN_INFO "AMD Alchemy Mirage Board\n");
++#endif
++#ifdef CONFIG_MIPS_DB1550
++ printk(KERN_INFO "AMD Alchemy Au1550/Db1550 Board\n");
++
++ bcsr1 = DB1550_BCSR_PHYS_ADDR;
++ bcsr2 = DB1550_BCSR_PHYS_ADDR + DB1550_BCSR_HEXLED_OFS;
++#endif
++
++ /* initialize board register space */
++ bcsr_init(bcsr1, bcsr2);
++
+ argptr = prom_getcmdline();
+ #ifdef CONFIG_SERIAL_8250_CONSOLE
+ argptr = strstr(argptr, "console=");
+@@ -89,11 +166,10 @@ void __init board_setup(void)
+ pin_func = au_readl(SYS_PINFUNC) | SYS_PF_IRF;
+ au_writel(pin_func, SYS_PINFUNC);
+ /* Power off until the driver is in use */
+- bcsr->resets &= ~BCSR_RESETS_IRDA_MODE_MASK;
+- bcsr->resets |= BCSR_RESETS_IRDA_MODE_OFF;
+- au_sync();
++ bcsr_mod(BCSR_RESETS, BCSR_RESETS_IRDA_MODE_MASK,
++ BCSR_RESETS_IRDA_MODE_OFF);
+ #endif
+- bcsr->pcmcia = 0x0000; /* turn off PCMCIA power */
++ bcsr_write(BCSR_PCMCIA, 0); /* turn off PCMCIA power */
+
+ /* Enable GPIO[31:0] inputs */
+ alchemy_gpio1_input_enable();
+@@ -123,23 +199,41 @@ void __init board_setup(void)
+ #endif
+
+ au_sync();
++}
+
+-#ifdef CONFIG_MIPS_DB1000
+- printk(KERN_INFO "AMD Alchemy Au1000/Db1000 Board\n");
+-#endif
+-#ifdef CONFIG_MIPS_DB1500
+- printk(KERN_INFO "AMD Alchemy Au1500/Db1500 Board\n");
+-#endif
+-#ifdef CONFIG_MIPS_DB1100
+- printk(KERN_INFO "AMD Alchemy Au1100/Db1100 Board\n");
+-#endif
+-#ifdef CONFIG_MIPS_BOSPORUS
+- printk(KERN_INFO "AMD Alchemy Bosporus Board\n");
+-#endif
+-#ifdef CONFIG_MIPS_MIRAGE
+- printk(KERN_INFO "AMD Alchemy Mirage Board\n");
+-#endif
+-#ifdef CONFIG_MIPS_DB1550
+- printk(KERN_INFO "AMD Alchemy Au1550/Db1550 Board\n");
++static int __init db1x00_init_irq(void)
++{
++#if defined(CONFIG_MIPS_MIRAGE)
++ set_irq_type(AU1500_GPIO7_INT, IRQF_TRIGGER_RISING); /* TS pendown */
++#elif defined(CONFIG_MIPS_DB1550)
++ set_irq_type(AU1550_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */
++ set_irq_type(AU1550_GPIO1_INT, IRQF_TRIGGER_LOW); /* CD1# */
++ set_irq_type(AU1550_GPIO3_INT, IRQF_TRIGGER_LOW); /* CARD0# */
++ set_irq_type(AU1550_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */
++ set_irq_type(AU1550_GPIO21_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */
++ set_irq_type(AU1550_GPIO22_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */
++#elif defined(CONFIG_MIPS_DB1500)
++ set_irq_type(AU1500_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */
++ set_irq_type(AU1500_GPIO3_INT, IRQF_TRIGGER_LOW); /* CD1# */
++ set_irq_type(AU1500_GPIO2_INT, IRQF_TRIGGER_LOW); /* CARD0# */
++ set_irq_type(AU1500_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */
++ set_irq_type(AU1500_GPIO1_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */
++ set_irq_type(AU1500_GPIO4_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */
++#elif defined(CONFIG_MIPS_DB1100)
++ set_irq_type(AU1100_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */
++ set_irq_type(AU1100_GPIO3_INT, IRQF_TRIGGER_LOW); /* CD1# */
++ set_irq_type(AU1100_GPIO2_INT, IRQF_TRIGGER_LOW); /* CARD0# */
++ set_irq_type(AU1100_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */
++ set_irq_type(AU1100_GPIO1_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */
++ set_irq_type(AU1100_GPIO4_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */
++#elif defined(CONFIG_MIPS_DB1000)
++ set_irq_type(AU1000_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */
++ set_irq_type(AU1000_GPIO3_INT, IRQF_TRIGGER_LOW); /* CD1# */
++ set_irq_type(AU1000_GPIO2_INT, IRQF_TRIGGER_LOW); /* CARD0# */
++ set_irq_type(AU1000_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */
++ set_irq_type(AU1000_GPIO1_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */
++ set_irq_type(AU1000_GPIO4_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */
+ #endif
++ return 0;
+ }
++arch_initcall(db1x00_init_irq);
+diff --git a/arch/mips/alchemy/devboards/db1x00/irqmap.c b/arch/mips/alchemy/devboards/db1x00/irqmap.c
+deleted file mode 100644
+index 0b09025..0000000
+--- a/arch/mips/alchemy/devboards/db1x00/irqmap.c
++++ /dev/null
+@@ -1,90 +0,0 @@
+-/*
+- * BRIEF MODULE DESCRIPTION
+- * Au1xxx irq map table
+- *
+- * Copyright 2003 Embedded Edge, LLC
+- * dan@embeddededge.com
+- *
+- * 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.
+- */
+-
+-#include <linux/init.h>
+-#include <linux/interrupt.h>
+-
+-#include <asm/mach-au1x00/au1000.h>
+-
+-#ifdef CONFIG_MIPS_DB1500
+-char irq_tab_alchemy[][5] __initdata = {
+- [12] = { -1, INTA, INTX, INTX, INTX }, /* IDSEL 12 - HPT371 */
+- [13] = { -1, INTA, INTB, INTC, INTD }, /* IDSEL 13 - PCI slot */
+-};
+-#endif
+-
+-#ifdef CONFIG_MIPS_BOSPORUS
+-char irq_tab_alchemy[][5] __initdata = {
+- [11] = { -1, INTA, INTB, INTX, INTX }, /* IDSEL 11 - miniPCI */
+- [12] = { -1, INTA, INTX, INTX, INTX }, /* IDSEL 12 - SN1741 */
+- [13] = { -1, INTA, INTB, INTC, INTD }, /* IDSEL 13 - PCI slot */
+-};
+-#endif
+-
+-#ifdef CONFIG_MIPS_MIRAGE
+-char irq_tab_alchemy[][5] __initdata = {
+- [11] = { -1, INTD, INTX, INTX, INTX }, /* IDSEL 11 - SMI VGX */
+- [12] = { -1, INTX, INTX, INTC, INTX }, /* IDSEL 12 - PNX1300 */
+- [13] = { -1, INTA, INTB, INTX, INTX }, /* IDSEL 13 - miniPCI */
+-};
+-#endif
+-
+-#ifdef CONFIG_MIPS_DB1550
+-char irq_tab_alchemy[][5] __initdata = {
+- [11] = { -1, INTC, INTX, INTX, INTX }, /* IDSEL 11 - on-board HPT371 */
+- [12] = { -1, INTB, INTC, INTD, INTA }, /* IDSEL 12 - PCI slot 2 (left) */
+- [13] = { -1, INTA, INTB, INTC, INTD }, /* IDSEL 13 - PCI slot 1 (right) */
+-};
+-#endif
+-
+-
+-struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
+-
+-#ifndef CONFIG_MIPS_MIRAGE
+-#ifdef CONFIG_MIPS_DB1550
+- { AU1000_GPIO_3, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 0 IRQ# */
+- { AU1000_GPIO_5, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 1 IRQ# */
+-#else
+- { AU1000_GPIO_0, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 0 Fully_Interted# */
+- { AU1000_GPIO_1, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 0 STSCHG# */
+- { AU1000_GPIO_2, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 0 IRQ# */
+-
+- { AU1000_GPIO_3, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 1 Fully_Interted# */
+- { AU1000_GPIO_4, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 1 STSCHG# */
+- { AU1000_GPIO_5, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 1 IRQ# */
+-#endif
+-#else
+- { AU1000_GPIO_7, IRQF_TRIGGER_RISING, 0 }, /* touchscreen pen down */
+-#endif
+-
+-};
+-
+-void __init board_init_irq(void)
+-{
+- au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map));
+-}
+diff --git a/arch/mips/alchemy/devboards/db1x00/platform.c b/arch/mips/alchemy/devboards/db1x00/platform.c
+new file mode 100644
+index 0000000..62e2a96
+--- /dev/null
++++ b/arch/mips/alchemy/devboards/db1x00/platform.c
+@@ -0,0 +1,118 @@
++/*
++ * DBAu1xxx board platform device registration
++ *
++ * Copyright (C) 2009 Manuel Lauss
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#include <linux/init.h>
++#include <linux/platform_device.h>
++
++#include <asm/mach-au1x00/au1xxx.h>
++#include <asm/mach-db1x00/bcsr.h>
++#include "../platform.h"
++
++/* DB1xxx PCMCIA interrupt sources:
++ * CD0/1 GPIO0/3
++ * STSCHG0/1 GPIO1/4
++ * CARD0/1 GPIO2/5
++ * Db1550: 0/1, 21/22, 3/5
++ */
++
++#define DB1XXX_HAS_PCMCIA
++#define F_SWAPPED (bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT)
++
++#if defined(CONFIG_MIPS_DB1000)
++#define DB1XXX_PCMCIA_CD0 AU1000_GPIO0_INT
++#define DB1XXX_PCMCIA_STSCHG0 AU1000_GPIO1_INT
++#define DB1XXX_PCMCIA_CARD0 AU1000_GPIO2_INT
++#define DB1XXX_PCMCIA_CD1 AU1000_GPIO3_INT
++#define DB1XXX_PCMCIA_STSCHG1 AU1000_GPIO4_INT
++#define DB1XXX_PCMCIA_CARD1 AU1000_GPIO5_INT
++#define BOARD_FLASH_SIZE 0x02000000 /* 32MB */
++#define BOARD_FLASH_WIDTH 4 /* 32-bits */
++#elif defined(CONFIG_MIPS_DB1100)
++#define DB1XXX_PCMCIA_CD0 AU1100_GPIO0_INT
++#define DB1XXX_PCMCIA_STSCHG0 AU1100_GPIO1_INT
++#define DB1XXX_PCMCIA_CARD0 AU1100_GPIO2_INT
++#define DB1XXX_PCMCIA_CD1 AU1100_GPIO3_INT
++#define DB1XXX_PCMCIA_STSCHG1 AU1100_GPIO4_INT
++#define DB1XXX_PCMCIA_CARD1 AU1100_GPIO5_INT
++#define BOARD_FLASH_SIZE 0x02000000 /* 32MB */
++#define BOARD_FLASH_WIDTH 4 /* 32-bits */
++#elif defined(CONFIG_MIPS_DB1500)
++#define DB1XXX_PCMCIA_CD0 AU1500_GPIO0_INT
++#define DB1XXX_PCMCIA_STSCHG0 AU1500_GPIO1_INT
++#define DB1XXX_PCMCIA_CARD0 AU1500_GPIO2_INT
++#define DB1XXX_PCMCIA_CD1 AU1500_GPIO3_INT
++#define DB1XXX_PCMCIA_STSCHG1 AU1500_GPIO4_INT
++#define DB1XXX_PCMCIA_CARD1 AU1500_GPIO5_INT
++#define BOARD_FLASH_SIZE 0x02000000 /* 32MB */
++#define BOARD_FLASH_WIDTH 4 /* 32-bits */
++#elif defined(CONFIG_MIPS_DB1550)
++#define DB1XXX_PCMCIA_CD0 AU1550_GPIO0_INT
++#define DB1XXX_PCMCIA_STSCHG0 AU1550_GPIO21_INT
++#define DB1XXX_PCMCIA_CARD0 AU1550_GPIO3_INT
++#define DB1XXX_PCMCIA_CD1 AU1550_GPIO1_INT
++#define DB1XXX_PCMCIA_STSCHG1 AU1550_GPIO22_INT
++#define DB1XXX_PCMCIA_CARD1 AU1550_GPIO5_INT
++#define BOARD_FLASH_SIZE 0x08000000 /* 128MB */
++#define BOARD_FLASH_WIDTH 4 /* 32-bits */
++#else
++/* other board: no PCMCIA */
++#undef DB1XXX_HAS_PCMCIA
++#undef F_SWAPPED
++#define F_SWAPPED 0
++#if defined(CONFIG_MIPS_BOSPORUS)
++#define BOARD_FLASH_SIZE 0x01000000 /* 16MB */
++#define BOARD_FLASH_WIDTH 2 /* 16-bits */
++#elif defined(CONFIG_MIPS_MIRAGE)
++#define BOARD_FLASH_SIZE 0x04000000 /* 64MB */
++#define BOARD_FLASH_WIDTH 4 /* 32-bits */
++#endif
++#endif
++
++static int __init db1xxx_dev_init(void)
++{
++#ifdef DB1XXX_HAS_PCMCIA
++ db1x_register_pcmcia_socket(PCMCIA_ATTR_PSEUDO_PHYS,
++ PCMCIA_ATTR_PSEUDO_PHYS + 0x00040000 - 1,
++ PCMCIA_MEM_PSEUDO_PHYS,
++ PCMCIA_MEM_PSEUDO_PHYS + 0x00040000 - 1,
++ PCMCIA_IO_PSEUDO_PHYS,
++ PCMCIA_IO_PSEUDO_PHYS + 0x00001000 - 1,
++ DB1XXX_PCMCIA_CARD0,
++ DB1XXX_PCMCIA_CD0,
++ /*DB1XXX_PCMCIA_STSCHG0*/0,
++ 0,
++ 0);
++
++ db1x_register_pcmcia_socket(PCMCIA_ATTR_PSEUDO_PHYS + 0x00400000,
++ PCMCIA_ATTR_PSEUDO_PHYS + 0x00440000 - 1,
++ PCMCIA_MEM_PSEUDO_PHYS + 0x00400000,
++ PCMCIA_MEM_PSEUDO_PHYS + 0x00440000 - 1,
++ PCMCIA_IO_PSEUDO_PHYS + 0x00400000,
++ PCMCIA_IO_PSEUDO_PHYS + 0x00401000 - 1,
++ DB1XXX_PCMCIA_CARD1,
++ DB1XXX_PCMCIA_CD1,
++ /*DB1XXX_PCMCIA_STSCHG1*/0,
++ 0,
++ 1);
++#endif
++ db1x_register_norflash(BOARD_FLASH_SIZE, BOARD_FLASH_WIDTH, F_SWAPPED);
++ return 0;
++}
++device_initcall(db1xxx_dev_init);
+diff --git a/arch/mips/alchemy/devboards/pb1000/board_setup.c b/arch/mips/alchemy/devboards/pb1000/board_setup.c
+index cd27354..28b8bd2 100644
+--- a/arch/mips/alchemy/devboards/pb1000/board_setup.c
++++ b/arch/mips/alchemy/devboards/pb1000/board_setup.c
+@@ -31,11 +31,7 @@
+ #include <asm/mach-pb1x00/pb1000.h>
+ #include <prom.h>
+
+-
+-struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
+- { AU1000_GPIO_15, IRQF_TRIGGER_LOW, 0 },
+-};
+-
++#include "../platform.h"
+
+ const char *get_system_type(void)
+ {
+@@ -46,19 +42,18 @@ void board_reset(void)
+ {
+ }
+
+-void __init board_init_irq(void)
+-{
+- au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map));
+-}
+-
+ void __init board_setup(void)
+ {
+ u32 pin_func, static_cfg0;
+ u32 sys_freqctrl, sys_clksrc;
+ u32 prid = read_c0_prid();
++ char *argptr;
++
++ sys_freqctrl = 0;
++ sys_clksrc = 0;
++ argptr = prom_getcmdline();
+
+ #ifdef CONFIG_SERIAL_8250_CONSOLE
+- char *argptr = prom_getcmdline();
+ argptr = strstr(argptr, "console=");
+ if (argptr == NULL) {
+ argptr = prom_getcmdline();
+@@ -193,3 +188,16 @@ void __init board_setup(void)
+ break;
+ }
+ }
++
++static int __init pb1000_init_irq(void)
++{
++ set_irq_type(AU1000_GPIO15_INT, IRQF_TRIGGER_LOW);
++ return 0;
++}
++arch_initcall(pb1000_init_irq);
++
++static int __init pb1000_device_init(void)
++{
++ return db1x_register_norflash(8 * 1024 * 1024, 4, 0);
++}
++device_initcall(pb1000_device_init);
+diff --git a/arch/mips/alchemy/devboards/pb1100/Makefile b/arch/mips/alchemy/devboards/pb1100/Makefile
+index c586dd7..60cf5b9 100644
+--- a/arch/mips/alchemy/devboards/pb1100/Makefile
++++ b/arch/mips/alchemy/devboards/pb1100/Makefile
+@@ -5,4 +5,5 @@
+ # Makefile for the Alchemy Semiconductor Pb1100 board.
+ #
+
+-obj-y := board_setup.o
++obj-y := board_setup.o platform.o
++
+diff --git a/arch/mips/alchemy/devboards/pb1100/board_setup.c b/arch/mips/alchemy/devboards/pb1100/board_setup.c
+index 6126308..e0bd855 100644
+--- a/arch/mips/alchemy/devboards/pb1100/board_setup.c
++++ b/arch/mips/alchemy/devboards/pb1100/board_setup.c
+@@ -29,19 +29,11 @@
+ #include <linux/interrupt.h>
+
+ #include <asm/mach-au1x00/au1000.h>
+-#include <asm/mach-pb1x00/pb1100.h>
++#include <asm/mach-db1x00/bcsr.h>
+
+ #include <prom.h>
+
+
+-struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
+- { AU1000_GPIO_9, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card Fully_Inserted# */
+- { AU1000_GPIO_10, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card STSCHG# */
+- { AU1000_GPIO_11, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card IRQ# */
+- { AU1000_GPIO_13, IRQF_TRIGGER_LOW, 0 }, /* DC_IRQ# */
+-};
+-
+-
+ const char *get_system_type(void)
+ {
+ return "Alchemy Pb1100";
+@@ -49,13 +41,7 @@ const char *get_system_type(void)
+
+ void board_reset(void)
+ {
+- /* Hit BCSR.RST_VDDI[SOFT_RESET] */
+- au_writel(0x00000000, PB1100_RST_VDDI);
+-}
+-
+-void __init board_init_irq(void)
+-{
+- au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map));
++ bcsr_write(BCSR_SYSTEM, 0);
+ }
+
+ void __init board_setup(void)
+@@ -63,6 +49,9 @@ void __init board_setup(void)
+ volatile void __iomem *base = (volatile void __iomem *)0xac000000UL;
+ char *argptr;
+
++ bcsr_init(DB1000_BCSR_PHYS_ADDR,
++ DB1000_BCSR_PHYS_ADDR + DB1000_BCSR_HEXLED_OFS);
++
+ argptr = prom_getcmdline();
+ #ifdef CONFIG_SERIAL_8250_CONSOLE
+ argptr = strstr(argptr, "console=");
+@@ -155,3 +144,14 @@ void __init board_setup(void)
+ au_sync();
+ }
+ }
++
++static int __init pb1100_init_irq(void)
++{
++ set_irq_type(AU1100_GPIO9_INT, IRQF_TRIGGER_LOW); /* PCCD# */
++ set_irq_type(AU1100_GPIO10_INT, IRQF_TRIGGER_LOW); /* PCSTSCHG# */
++ set_irq_type(AU1100_GPIO11_INT, IRQF_TRIGGER_LOW); /* PCCard# */
++ set_irq_type(AU1100_GPIO13_INT, IRQF_TRIGGER_LOW); /* DC_IRQ# */
++
++ return 0;
++}
++arch_initcall(pb1100_init_irq);
+diff --git a/arch/mips/alchemy/devboards/pb1100/platform.c b/arch/mips/alchemy/devboards/pb1100/platform.c
+new file mode 100644
+index 0000000..bfc5ab6
+--- /dev/null
++++ b/arch/mips/alchemy/devboards/pb1100/platform.c
+@@ -0,0 +1,50 @@
++/*
++ * Pb1100 board platform device registration
++ *
++ * Copyright (C) 2009 Manuel Lauss
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#include <linux/init.h>
++
++#include <asm/mach-au1x00/au1000.h>
++#include <asm/mach-db1x00/bcsr.h>
++
++#include "../platform.h"
++
++static int __init pb1100_dev_init(void)
++{
++ int swapped;
++
++ /* PCMCIA. single socket, identical to Pb1500 */
++ db1x_register_pcmcia_socket(PCMCIA_ATTR_PSEUDO_PHYS,
++ PCMCIA_ATTR_PSEUDO_PHYS + 0x00040000 - 1,
++ PCMCIA_MEM_PSEUDO_PHYS,
++ PCMCIA_MEM_PSEUDO_PHYS + 0x00040000 - 1,
++ PCMCIA_IO_PSEUDO_PHYS,
++ PCMCIA_IO_PSEUDO_PHYS + 0x00001000 - 1,
++ AU1100_GPIO11_INT, /* card */
++ AU1100_GPIO9_INT, /* insert */
++ /*AU1100_GPIO10_INT*/0, /* stschg */
++ 0, /* eject */
++ 0); /* id */
++
++ swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT;
++ db1x_register_norflash(64 * 1024 * 1024, 4, swapped);
++
++ return 0;
++}
++device_initcall(pb1100_dev_init);
+diff --git a/arch/mips/alchemy/devboards/pb1200/Makefile b/arch/mips/alchemy/devboards/pb1200/Makefile
+index c8c3a99..2ea9b02 100644
+--- a/arch/mips/alchemy/devboards/pb1200/Makefile
++++ b/arch/mips/alchemy/devboards/pb1200/Makefile
+@@ -2,6 +2,6 @@
+ # Makefile for the Alchemy Semiconductor Pb1200/DBAu1200 boards.
+ #
+
+-obj-y := board_setup.o irqmap.o platform.o
++obj-y := board_setup.o platform.o
+
+ EXTRA_CFLAGS += -Werror
+diff --git a/arch/mips/alchemy/devboards/pb1200/board_setup.c b/arch/mips/alchemy/devboards/pb1200/board_setup.c
+index 94e6b7e..2cf59e7 100644
+--- a/arch/mips/alchemy/devboards/pb1200/board_setup.c
++++ b/arch/mips/alchemy/devboards/pb1200/board_setup.c
+@@ -25,11 +25,23 @@
+ */
+
+ #include <linux/init.h>
++#include <linux/interrupt.h>
+ #include <linux/sched.h>
+
+-#include <prom.h>
+-#include <au1xxx.h>
++#include <asm/mach-au1x00/au1000.h>
++#include <asm/mach-db1x00/bcsr.h>
+
++#ifdef CONFIG_MIPS_PB1200
++#include <asm/mach-pb1x00/pb1200.h>
++#endif
++
++#ifdef CONFIG_MIPS_DB1200
++#include <asm/mach-db1x00/db1200.h>
++#define PB1200_INT_BEGIN DB1200_INT_BEGIN
++#define PB1200_INT_END DB1200_INT_END
++#endif
++
++#include <prom.h>
+
+ const char *get_system_type(void)
+ {
+@@ -38,14 +50,18 @@ const char *get_system_type(void)
+
+ void board_reset(void)
+ {
+- bcsr->resets = 0;
+- bcsr->system = 0;
++ bcsr_write(BCSR_RESETS, 0);
++ bcsr_write(BCSR_SYSTEM, 0);
+ }
+
+ void __init board_setup(void)
+ {
+ char *argptr;
+
++ printk(KERN_INFO "AMD Alchemy Pb1200 Board\n");
++ bcsr_init(PB1200_BCSR_PHYS_ADDR,
++ PB1200_BCSR_PHYS_ADDR + PB1200_BCSR_HEXLED_OFS);
++
+ argptr = prom_getcmdline();
+ #ifdef CONFIG_SERIAL_8250_CONSOLE
+ argptr = strstr(argptr, "console=");
+@@ -82,7 +98,7 @@ void __init board_setup(void)
+ u32 pin_func;
+
+ /* Select SMBus in CPLD */
+- bcsr->resets &= ~BCSR_RESETS_PCS0MUX;
++ bcsr_mod(BCSR_RESETS, BCSR_RESETS_PSC0MUX, 0);
+
+ pin_func = au_readl(SYS_PINFUNC);
+ au_sync();
+@@ -116,38 +132,54 @@ void __init board_setup(void)
+
+ /*
+ * The Pb1200 development board uses external MUX for PSC0 to
+- * support SMB/SPI. bcsr->resets bit 12: 0=SMB 1=SPI
++ * support SMB/SPI. bcsr_resets bit 12: 0=SMB 1=SPI
+ */
+ #ifdef CONFIG_I2C_AU1550
+- bcsr->resets &= ~BCSR_RESETS_PCS0MUX;
++ bcsr_mod(BCSR_RESETS, BCSR_RESETS_PSC0MUX, 0);
+ #endif
+ au_sync();
++}
+
+-#ifdef CONFIG_MIPS_PB1200
+- printk(KERN_INFO "AMD Alchemy Pb1200 Board\n");
+-#endif
+-#ifdef CONFIG_MIPS_DB1200
+- printk(KERN_INFO "AMD Alchemy Db1200 Board\n");
+-#endif
++static int __init pb1200_init_irq(void)
++{
++ /* We have a problem with CPLD rev 3. */
++ if (BCSR_WHOAMI_CPLD(bcsr_read(BCSR_WHOAMI)) <= 3) {
++ printk(KERN_ERR "WARNING!!!\n");
++ printk(KERN_ERR "WARNING!!!\n");
++ printk(KERN_ERR "WARNING!!!\n");
++ printk(KERN_ERR "WARNING!!!\n");
++ printk(KERN_ERR "WARNING!!!\n");
++ printk(KERN_ERR "WARNING!!!\n");
++ printk(KERN_ERR "Pb1200 must be at CPLD rev 4. Please have Pb1200\n");
++ printk(KERN_ERR "updated to latest revision. This software will\n");
++ printk(KERN_ERR "not work on anything less than CPLD rev 4.\n");
++ printk(KERN_ERR "WARNING!!!\n");
++ printk(KERN_ERR "WARNING!!!\n");
++ printk(KERN_ERR "WARNING!!!\n");
++ printk(KERN_ERR "WARNING!!!\n");
++ printk(KERN_ERR "WARNING!!!\n");
++ printk(KERN_ERR "WARNING!!!\n");
++ panic("Game over. Your score is 0.");
++ }
++
++ set_irq_type(AU1200_GPIO7_INT, IRQF_TRIGGER_LOW);
++ bcsr_init_irq(PB1200_INT_BEGIN, PB1200_INT_END, AU1200_GPIO7_INT);
++
++ return 0;
+ }
++arch_initcall(pb1200_init_irq);
++
+
+ int board_au1200fb_panel(void)
+ {
+- BCSR *bcsr = (BCSR *)BCSR_KSEG1_ADDR;
+- int p;
+-
+- p = bcsr->switches;
+- p >>= 8;
+- p &= 0x0F;
+- return p;
++ return (bcsr_read(BCSR_SWITCHES) >> 8) & 0x0f;
+ }
+
+ int board_au1200fb_panel_init(void)
+ {
+ /* Apply power */
+- BCSR *bcsr = (BCSR *)BCSR_KSEG1_ADDR;
+-
+- bcsr->board |= BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD | BCSR_BOARD_LCDBL;
++ bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD |
++ BCSR_BOARD_LCDBL);
+ /* printk(KERN_DEBUG "board_au1200fb_panel_init()\n"); */
+ return 0;
+ }
+@@ -155,10 +187,8 @@ int board_au1200fb_panel_init(void)
+ int board_au1200fb_panel_shutdown(void)
+ {
+ /* Remove power */
+- BCSR *bcsr = (BCSR *)BCSR_KSEG1_ADDR;
+-
+- bcsr->board &= ~(BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD |
+- BCSR_BOARD_LCDBL);
++ bcsr_mod(BCSR_BOARD, BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD |
++ BCSR_BOARD_LCDBL, 0);
+ /* printk(KERN_DEBUG "board_au1200fb_panel_shutdown()\n"); */
+ return 0;
+ }
+diff --git a/arch/mips/alchemy/devboards/pb1200/irqmap.c b/arch/mips/alchemy/devboards/pb1200/irqmap.c
+deleted file mode 100644
+index fe47498..0000000
+--- a/arch/mips/alchemy/devboards/pb1200/irqmap.c
++++ /dev/null
+@@ -1,134 +0,0 @@
+-/*
+- * BRIEF MODULE DESCRIPTION
+- * Au1xxx irq map table
+- *
+- * 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.
+- */
+-
+-#include <linux/init.h>
+-#include <linux/interrupt.h>
+-
+-#include <asm/mach-au1x00/au1000.h>
+-
+-#ifdef CONFIG_MIPS_PB1200
+-#include <asm/mach-pb1x00/pb1200.h>
+-#endif
+-
+-#ifdef CONFIG_MIPS_DB1200
+-#include <asm/mach-db1x00/db1200.h>
+-#define PB1200_INT_BEGIN DB1200_INT_BEGIN
+-#define PB1200_INT_END DB1200_INT_END
+-#endif
+-
+-struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
+- /* This is external interrupt cascade */
+- { AU1000_GPIO_7, IRQF_TRIGGER_LOW, 0 },
+-};
+-
+-
+-/*
+- * Support for External interrupts on the Pb1200 Development platform.
+- */
+-
+-static void pb1200_cascade_handler(unsigned int irq, struct irq_desc *d)
+-{
+- unsigned short bisr = bcsr->int_status;
+-
+- for ( ; bisr; bisr &= bisr - 1)
+- generic_handle_irq(PB1200_INT_BEGIN + __ffs(bisr));
+-}
+-
+-/* NOTE: both the enable and mask bits must be cleared, otherwise the
+- * CPLD generates tons of spurious interrupts (at least on the DB1200).
+- */
+-static void pb1200_mask_irq(unsigned int irq_nr)
+-{
+- bcsr->intclr_mask = 1 << (irq_nr - PB1200_INT_BEGIN);
+- bcsr->intclr = 1 << (irq_nr - PB1200_INT_BEGIN);
+- au_sync();
+-}
+-
+-static void pb1200_maskack_irq(unsigned int irq_nr)
+-{
+- bcsr->intclr_mask = 1 << (irq_nr - PB1200_INT_BEGIN);
+- bcsr->intclr = 1 << (irq_nr - PB1200_INT_BEGIN);
+- bcsr->int_status = 1 << (irq_nr - PB1200_INT_BEGIN); /* ack */
+- au_sync();
+-}
+-
+-static void pb1200_unmask_irq(unsigned int irq_nr)
+-{
+- bcsr->intset = 1 << (irq_nr - PB1200_INT_BEGIN);
+- bcsr->intset_mask = 1 << (irq_nr - PB1200_INT_BEGIN);
+- au_sync();
+-}
+-
+-static struct irq_chip pb1200_cpld_irq_type = {
+-#ifdef CONFIG_MIPS_PB1200
+- .name = "Pb1200 Ext",
+-#endif
+-#ifdef CONFIG_MIPS_DB1200
+- .name = "Db1200 Ext",
+-#endif
+- .mask = pb1200_mask_irq,
+- .mask_ack = pb1200_maskack_irq,
+- .unmask = pb1200_unmask_irq,
+-};
+-
+-void __init board_init_irq(void)
+-{
+- unsigned int irq;
+-
+- au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map));
+-
+-#ifdef CONFIG_MIPS_PB1200
+- /* We have a problem with CPLD rev 3. */
+- if (((bcsr->whoami & BCSR_WHOAMI_CPLD) >> 4) <= 3) {
+- printk(KERN_ERR "WARNING!!!\n");
+- printk(KERN_ERR "WARNING!!!\n");
+- printk(KERN_ERR "WARNING!!!\n");
+- printk(KERN_ERR "WARNING!!!\n");
+- printk(KERN_ERR "WARNING!!!\n");
+- printk(KERN_ERR "WARNING!!!\n");
+- printk(KERN_ERR "Pb1200 must be at CPLD rev 4. Please have Pb1200\n");
+- printk(KERN_ERR "updated to latest revision. This software will\n");
+- printk(KERN_ERR "not work on anything less than CPLD rev 4.\n");
+- printk(KERN_ERR "WARNING!!!\n");
+- printk(KERN_ERR "WARNING!!!\n");
+- printk(KERN_ERR "WARNING!!!\n");
+- printk(KERN_ERR "WARNING!!!\n");
+- printk(KERN_ERR "WARNING!!!\n");
+- printk(KERN_ERR "WARNING!!!\n");
+- panic("Game over. Your score is 0.");
+- }
+-#endif
+- /* mask & disable & ack all */
+- bcsr->intclr_mask = 0xffff;
+- bcsr->intclr = 0xffff;
+- bcsr->int_status = 0xffff;
+- au_sync();
+-
+- for (irq = PB1200_INT_BEGIN; irq <= PB1200_INT_END; irq++)
+- set_irq_chip_and_handler_name(irq, &pb1200_cpld_irq_type,
+- handle_level_irq, "level");
+-
+- set_irq_chained_handler(AU1000_GPIO_7, pb1200_cascade_handler);
+-}
+diff --git a/arch/mips/alchemy/devboards/pb1200/platform.c b/arch/mips/alchemy/devboards/pb1200/platform.c
+index b93dff4..14e889f 100644
+--- a/arch/mips/alchemy/devboards/pb1200/platform.c
++++ b/arch/mips/alchemy/devboards/pb1200/platform.c
+@@ -26,27 +26,30 @@
+
+ #include <asm/mach-au1x00/au1xxx.h>
+ #include <asm/mach-au1x00/au1100_mmc.h>
++#include <asm/mach-db1x00/bcsr.h>
++
++#include "../platform.h"
+
+ static int mmc_activity;
+
+ static void pb1200mmc0_set_power(void *mmc_host, int state)
+ {
+ if (state)
+- bcsr->board |= BCSR_BOARD_SD0PWR;
++ bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_SD0PWR);
+ else
+- bcsr->board &= ~BCSR_BOARD_SD0PWR;
++ bcsr_mod(BCSR_BOARD, BCSR_BOARD_SD0PWR, 0);
+
+- au_sync_delay(1);
++ msleep(1);
+ }
+
+ static int pb1200mmc0_card_readonly(void *mmc_host)
+ {
+- return (bcsr->status & BCSR_STATUS_SD0WP) ? 1 : 0;
++ return (bcsr_read(BCSR_STATUS) & BCSR_STATUS_SD0WP) ? 1 : 0;
+ }
+
+ static int pb1200mmc0_card_inserted(void *mmc_host)
+ {
+- return (bcsr->sig_status & BCSR_INT_SD0INSERT) ? 1 : 0;
++ return (bcsr_read(BCSR_SIGSTAT) & BCSR_INT_SD0INSERT) ? 1 : 0;
+ }
+
+ static void pb1200_mmcled_set(struct led_classdev *led,
+@@ -54,10 +57,10 @@ static void pb1200_mmcled_set(struct led_classdev *led,
+ {
+ if (brightness != LED_OFF) {
+ if (++mmc_activity == 1)
+- bcsr->disk_leds &= ~(1 << 8);
++ bcsr_mod(BCSR_LEDS, BCSR_LEDS_LED0, 0);
+ } else {
+ if (--mmc_activity == 0)
+- bcsr->disk_leds |= (1 << 8);
++ bcsr_mod(BCSR_LEDS, 0, BCSR_LEDS_LED0);
+ }
+ }
+
+@@ -65,27 +68,25 @@ static struct led_classdev pb1200mmc_led = {
+ .brightness_set = pb1200_mmcled_set,
+ };
+
+-#ifndef CONFIG_MIPS_DB1200
+ static void pb1200mmc1_set_power(void *mmc_host, int state)
+ {
+ if (state)
+- bcsr->board |= BCSR_BOARD_SD1PWR;
++ bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_SD1PWR);
+ else
+- bcsr->board &= ~BCSR_BOARD_SD1PWR;
++ bcsr_mod(BCSR_BOARD, BCSR_BOARD_SD1PWR, 0);
+
+- au_sync_delay(1);
++ msleep(1);
+ }
+
+ static int pb1200mmc1_card_readonly(void *mmc_host)
+ {
+- return (bcsr->status & BCSR_STATUS_SD1WP) ? 1 : 0;
++ return (bcsr_read(BCSR_STATUS) & BCSR_STATUS_SD1WP) ? 1 : 0;
+ }
+
+ static int pb1200mmc1_card_inserted(void *mmc_host)
+ {
+- return (bcsr->sig_status & BCSR_INT_SD1INSERT) ? 1 : 0;
++ return (bcsr_read(BCSR_SIGSTAT) & BCSR_INT_SD1INSERT) ? 1 : 0;
+ }
+-#endif
+
+ const struct au1xmmc_platform_data au1xmmc_platdata[2] = {
+ [0] = {
+@@ -95,7 +96,6 @@ const struct au1xmmc_platform_data au1xmmc_platdata[2] = {
+ .cd_setup = NULL, /* use poll-timer in driver */
+ .led = &pb1200mmc_led,
+ },
+-#ifndef CONFIG_MIPS_DB1200
+ [1] = {
+ .set_power = pb1200mmc1_set_power,
+ .card_inserted = pb1200mmc1_card_inserted,
+@@ -103,7 +103,6 @@ const struct au1xmmc_platform_data au1xmmc_platdata[2] = {
+ .cd_setup = NULL, /* use poll-timer in driver */
+ .led = &pb1200mmc_led,
+ },
+-#endif
+ };
+
+ static struct resource ide_resources[] = {
+@@ -169,8 +168,36 @@ static struct platform_device *board_platform_devices[] __initdata = {
+
+ static int __init board_register_devices(void)
+ {
++ int swapped;
++
++ db1x_register_pcmcia_socket(PCMCIA_ATTR_PSEUDO_PHYS,
++ PCMCIA_ATTR_PSEUDO_PHYS + 0x00040000 - 1,
++ PCMCIA_MEM_PSEUDO_PHYS,
++ PCMCIA_MEM_PSEUDO_PHYS + 0x00040000 - 1,
++ PCMCIA_IO_PSEUDO_PHYS,
++ PCMCIA_IO_PSEUDO_PHYS + 0x00001000 - 1,
++ PB1200_PC0_INT,
++ PB1200_PC0_INSERT_INT,
++ /*PB1200_PC0_STSCHG_INT*/0,
++ PB1200_PC0_EJECT_INT,
++ 0);
++
++ db1x_register_pcmcia_socket(PCMCIA_ATTR_PSEUDO_PHYS + 0x00800000,
++ PCMCIA_ATTR_PSEUDO_PHYS + 0x00840000 - 1,
++ PCMCIA_MEM_PSEUDO_PHYS + 0x00800000,
++ PCMCIA_MEM_PSEUDO_PHYS + 0x00840000 - 1,
++ PCMCIA_IO_PSEUDO_PHYS + 0x00800000,
++ PCMCIA_IO_PSEUDO_PHYS + 0x00801000 - 1,
++ PB1200_PC1_INT,
++ PB1200_PC1_INSERT_INT,
++ /*PB1200_PC1_STSCHG_INT*/0,
++ PB1200_PC1_EJECT_INT,
++ 1);
++
++ swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1200_SWAPBOOT;
++ db1x_register_norflash(128 * 1024 * 1024, 2, swapped);
++
+ return platform_add_devices(board_platform_devices,
+ ARRAY_SIZE(board_platform_devices));
+ }
+-
+-arch_initcall(board_register_devices);
++device_initcall(board_register_devices);
+diff --git a/arch/mips/alchemy/devboards/pb1500/Makefile b/arch/mips/alchemy/devboards/pb1500/Makefile
+index 173b419..c29545d 100644
+--- a/arch/mips/alchemy/devboards/pb1500/Makefile
++++ b/arch/mips/alchemy/devboards/pb1500/Makefile
+@@ -5,4 +5,5 @@
+ # Makefile for the Alchemy Semiconductor Pb1500 board.
+ #
+
+-obj-y := board_setup.o
++obj-y := board_setup.o platform.o
++
+diff --git a/arch/mips/alchemy/devboards/pb1500/board_setup.c b/arch/mips/alchemy/devboards/pb1500/board_setup.c
+index d7a5656..3f0c92c 100644
+--- a/arch/mips/alchemy/devboards/pb1500/board_setup.c
++++ b/arch/mips/alchemy/devboards/pb1500/board_setup.c
+@@ -29,22 +29,14 @@
+ #include <linux/interrupt.h>
+
+ #include <asm/mach-au1x00/au1000.h>
+-#include <asm/mach-pb1x00/pb1500.h>
++#include <asm/mach-db1x00/bcsr.h>
+
+ #include <prom.h>
+
+
+ char irq_tab_alchemy[][5] __initdata = {
+- [12] = { -1, INTA, INTX, INTX, INTX }, /* IDSEL 12 - HPT370 */
+- [13] = { -1, INTA, INTB, INTC, INTD }, /* IDSEL 13 - PCI slot */
+-};
+-
+-struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
+- { AU1500_GPIO_204, IRQF_TRIGGER_HIGH, 0 },
+- { AU1500_GPIO_201, IRQF_TRIGGER_LOW, 0 },
+- { AU1500_GPIO_202, IRQF_TRIGGER_LOW, 0 },
+- { AU1500_GPIO_203, IRQF_TRIGGER_LOW, 0 },
+- { AU1500_GPIO_205, IRQF_TRIGGER_LOW, 0 },
++ [12] = { -1, AU1500_PCI_INTA, 0xff, 0xff, 0xff }, /* IDSEL 12 - HPT370 */
++ [13] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, AU1500_PCI_INTC, AU1500_PCI_INTD }, /* IDSEL 13 - PCI slot */
+ };
+
+
+@@ -55,13 +47,7 @@ const char *get_system_type(void)
+
+ void board_reset(void)
+ {
+- /* Hit BCSR.RST_VDDI[SOFT_RESET] */
+- au_writel(0x00000000, PB1500_RST_VDDI);
+-}
+-
+-void __init board_init_irq(void)
+-{
+- au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map));
++ bcsr_write(BCSR_SYSTEM, 0);
+ }
+
+ void __init board_setup(void)
+@@ -70,6 +56,9 @@ void __init board_setup(void)
+ u32 sys_freqctrl, sys_clksrc;
+ char *argptr;
+
++ bcsr_init(DB1000_BCSR_PHYS_ADDR,
++ DB1000_BCSR_PHYS_ADDR + DB1000_BCSR_HEXLED_OFS);
++
+ argptr = prom_getcmdline();
+ #ifdef CONFIG_SERIAL_8250_CONSOLE
+ argptr = strstr(argptr, "console=");
+@@ -163,3 +152,18 @@ void __init board_setup(void)
+ au_sync();
+ }
+ }
++
++static int __init pb1500_init_irq(void)
++{
++ set_irq_type(AU1500_GPIO9_INT, IRQF_TRIGGER_LOW); /* CD0# */
++ set_irq_type(AU1500_GPIO10_INT, IRQF_TRIGGER_LOW); /* CARD0 */
++ set_irq_type(AU1500_GPIO11_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */
++ set_irq_type(AU1500_GPIO204_INT, IRQF_TRIGGER_HIGH);
++ set_irq_type(AU1500_GPIO201_INT, IRQF_TRIGGER_LOW);
++ set_irq_type(AU1500_GPIO202_INT, IRQF_TRIGGER_LOW);
++ set_irq_type(AU1500_GPIO203_INT, IRQF_TRIGGER_LOW);
++ set_irq_type(AU1500_GPIO205_INT, IRQF_TRIGGER_LOW);
++
++ return 0;
++}
++arch_initcall(pb1500_init_irq);
+diff --git a/arch/mips/alchemy/devboards/pb1500/platform.c b/arch/mips/alchemy/devboards/pb1500/platform.c
+new file mode 100644
+index 0000000..529acb7
+--- /dev/null
++++ b/arch/mips/alchemy/devboards/pb1500/platform.c
+@@ -0,0 +1,49 @@
++/*
++ * Pb1500 board platform device registration
++ *
++ * Copyright (C) 2009 Manuel Lauss
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#include <linux/init.h>
++#include <asm/mach-au1x00/au1000.h>
++#include <asm/mach-db1x00/bcsr.h>
++
++#include "../platform.h"
++
++static int __init pb1500_dev_init(void)
++{
++ int swapped;
++
++ /* PCMCIA. single socket, identical to Pb1500 */
++ db1x_register_pcmcia_socket(PCMCIA_ATTR_PSEUDO_PHYS,
++ PCMCIA_ATTR_PSEUDO_PHYS + 0x00040000 - 1,
++ PCMCIA_MEM_PSEUDO_PHYS,
++ PCMCIA_MEM_PSEUDO_PHYS + 0x00040000 - 1,
++ PCMCIA_IO_PSEUDO_PHYS,
++ PCMCIA_IO_PSEUDO_PHYS + 0x00001000 - 1,
++ AU1500_GPIO11_INT, /* card */
++ AU1500_GPIO9_INT, /* insert */
++ /*AU1500_GPIO10_INT*/0, /* stschg */
++ 0, /* eject */
++ 0); /* id */
++
++ swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT;
++ db1x_register_norflash(64 * 1024 * 1024, 4, swapped);
++
++ return 0;
++}
++device_initcall(pb1500_dev_init);
+diff --git a/arch/mips/alchemy/devboards/pb1550/Makefile b/arch/mips/alchemy/devboards/pb1550/Makefile
+index cff95bc..86b410b 100644
+--- a/arch/mips/alchemy/devboards/pb1550/Makefile
++++ b/arch/mips/alchemy/devboards/pb1550/Makefile
+@@ -5,4 +5,5 @@
+ # Makefile for the Alchemy Semiconductor Pb1550 board.
+ #
+
+-obj-y := board_setup.o
++obj-y := board_setup.o platform.o
++
+diff --git a/arch/mips/alchemy/devboards/pb1550/board_setup.c b/arch/mips/alchemy/devboards/pb1550/board_setup.c
+index b6e9e7d..0d060c3 100644
+--- a/arch/mips/alchemy/devboards/pb1550/board_setup.c
++++ b/arch/mips/alchemy/devboards/pb1550/board_setup.c
+@@ -32,18 +32,15 @@
+
+ #include <asm/mach-au1x00/au1000.h>
+ #include <asm/mach-pb1x00/pb1550.h>
++#include <asm/mach-db1x00/bcsr.h>
++#include <asm/mach-au1x00/gpio.h>
+
+ #include <prom.h>
+
+
+ char irq_tab_alchemy[][5] __initdata = {
+- [12] = { -1, INTB, INTC, INTD, INTA }, /* IDSEL 12 - PCI slot 2 (left) */
+- [13] = { -1, INTA, INTB, INTC, INTD }, /* IDSEL 13 - PCI slot 1 (right) */
+-};
+-
+-struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
+- { AU1000_GPIO_0, IRQF_TRIGGER_LOW, 0 },
+- { AU1000_GPIO_1, IRQF_TRIGGER_LOW, 0 },
++ [12] = { -1, AU1550_PCI_INTB, AU1550_PCI_INTC, AU1550_PCI_INTD, AU1550_PCI_INTA }, /* IDSEL 12 - PCI slot 2 (left) */
++ [13] = { -1, AU1550_PCI_INTA, AU1550_PCI_INTB, AU1550_PCI_INTC, AU1550_PCI_INTD }, /* IDSEL 13 - PCI slot 1 (right) */
+ };
+
+ const char *get_system_type(void)
+@@ -53,22 +50,19 @@ const char *get_system_type(void)
+
+ void board_reset(void)
+ {
+- /* Hit BCSR.SYSTEM[RESET] */
+- au_writew(au_readw(0xAF00001C) & ~BCSR_SYSTEM_RESET, 0xAF00001C);
+-}
+-
+-void __init board_init_irq(void)
+-{
+- au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map));
++ bcsr_write(BCSR_SYSTEM, 0);
+ }
+
+ void __init board_setup(void)
+ {
+ u32 pin_func;
+-
+-#ifdef CONFIG_SERIAL_8250_CONSOLE
+ char *argptr;
++
++ bcsr_init(PB1550_BCSR_PHYS_ADDR,
++ PB1550_BCSR_PHYS_ADDR + PB1550_BCSR_HEXLED_OFS);
++
+ argptr = prom_getcmdline();
++#ifdef CONFIG_SERIAL_8250_CONSOLE
+ argptr = strstr(argptr, "console=");
+ if (argptr == NULL) {
+ argptr = prom_getcmdline();
+@@ -76,6 +70,8 @@ void __init board_setup(void)
+ }
+ #endif
+
++ alchemy_gpio2_enable();
++
+ /*
+ * Enable PSC1 SYNC for AC'97. Normaly done in audio driver,
+ * but it is board specific code, so put it here.
+@@ -85,8 +81,21 @@ void __init board_setup(void)
+ pin_func |= SYS_PF_MUST_BE_SET | SYS_PF_PSC1_S1;
+ au_writel(pin_func, SYS_PINFUNC);
+
+- au_writel(0, (u32)bcsr | 0x10); /* turn off PCMCIA power */
+- au_sync();
++ bcsr_write(BCSR_PCMCIA, 0); /* turn off PCMCIA power */
+
+ printk(KERN_INFO "AMD Alchemy Pb1550 Board\n");
+ }
++
++static int __init pb1550_init_irq(void)
++{
++ set_irq_type(AU1550_GPIO0_INT, IRQF_TRIGGER_LOW);
++ set_irq_type(AU1550_GPIO1_INT, IRQF_TRIGGER_LOW);
++ set_irq_type(AU1550_GPIO201_205_INT, IRQF_TRIGGER_HIGH);
++
++ /* enable both PCMCIA card irqs in the shared line */
++ alchemy_gpio2_enable_int(201);
++ alchemy_gpio2_enable_int(202);
++
++ return 0;
++}
++arch_initcall(pb1550_init_irq);
+diff --git a/arch/mips/alchemy/devboards/pb1550/platform.c b/arch/mips/alchemy/devboards/pb1550/platform.c
+new file mode 100644
+index 0000000..4613391
+--- /dev/null
++++ b/arch/mips/alchemy/devboards/pb1550/platform.c
+@@ -0,0 +1,69 @@
++/*
++ * Pb1550 board platform device registration
++ *
++ * Copyright (C) 2009 Manuel Lauss
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#include <linux/init.h>
++
++#include <asm/mach-au1x00/au1000.h>
++#include <asm/mach-pb1x00/pb1550.h>
++#include <asm/mach-db1x00/bcsr.h>
++
++#include "../platform.h"
++
++static int __init pb1550_dev_init(void)
++{
++ int swapped;
++
++ /* Pb1550, like all others, also has statuschange irqs; however they're
++ * wired up on one of the Au1550's shared GPIO201_205 line, which also
++ * services the PCMCIA card interrupts. So we ignore statuschange and
++ * use the GPIO201_205 exclusively for card interrupts, since a) pcmcia
++ * drivers are used to shared irqs and b) statuschange isn't really use-
++ * ful anyway.
++ */
++ db1x_register_pcmcia_socket(PCMCIA_ATTR_PSEUDO_PHYS,
++ PCMCIA_ATTR_PSEUDO_PHYS + 0x00040000 - 1,
++ PCMCIA_MEM_PSEUDO_PHYS,
++ PCMCIA_MEM_PSEUDO_PHYS + 0x00040000 - 1,
++ PCMCIA_IO_PSEUDO_PHYS,
++ PCMCIA_IO_PSEUDO_PHYS + 0x00001000 - 1,
++ AU1550_GPIO201_205_INT,
++ AU1550_GPIO0_INT,
++ 0,
++ 0,
++ 0);
++
++ db1x_register_pcmcia_socket(PCMCIA_ATTR_PSEUDO_PHYS + 0x00800000,
++ PCMCIA_ATTR_PSEUDO_PHYS + 0x00840000 - 1,
++ PCMCIA_MEM_PSEUDO_PHYS + 0x00800000,
++ PCMCIA_MEM_PSEUDO_PHYS + 0x00840000 - 1,
++ PCMCIA_IO_PSEUDO_PHYS + 0x00800000,
++ PCMCIA_IO_PSEUDO_PHYS + 0x00801000 - 1,
++ AU1550_GPIO201_205_INT,
++ AU1550_GPIO1_INT,
++ 0,
++ 0,
++ 1);
++
++ swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_PB1550_SWAPBOOT;
++ db1x_register_norflash(128 * 1024 * 1024, 4, swapped);
++
++ return 0;
++}
++device_initcall(pb1550_dev_init);
+diff --git a/arch/mips/alchemy/devboards/platform.c b/arch/mips/alchemy/devboards/platform.c
+new file mode 100644
+index 0000000..7f2bcee
+--- /dev/null
++++ b/arch/mips/alchemy/devboards/platform.c
+@@ -0,0 +1,193 @@
++/*
++ * devoard misc stuff.
++ */
++
++#include <linux/init.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/map.h>
++#include <linux/mtd/physmap.h>
++#include <linux/slab.h>
++#include <linux/platform_device.h>
++
++/* register a pcmcia socket */
++int __init db1x_register_pcmcia_socket(unsigned long pseudo_attr_start,
++ unsigned long pseudo_attr_end,
++ unsigned long pseudo_mem_start,
++ unsigned long pseudo_mem_end,
++ unsigned long pseudo_io_start,
++ unsigned long pseudo_io_end,
++ int card_irq,
++ int cd_irq,
++ int stschg_irq,
++ int eject_irq,
++ int id)
++{
++ int cnt, i, ret;
++ struct resource *sr;
++ struct platform_device *pd;
++
++ cnt = 5;
++ if (eject_irq)
++ cnt++;
++ if (stschg_irq)
++ cnt++;
++
++ sr = kzalloc(sizeof(struct resource) * cnt, GFP_KERNEL);
++ if (!sr)
++ return -ENOMEM;
++
++ pd = platform_device_alloc("db1xxx_pcmcia", id);
++ if (!pd) {
++ ret = -ENOMEM;
++ goto out;
++ }
++
++ sr[0].name = "pseudo-attr";
++ sr[0].flags = IORESOURCE_MEM;
++ sr[0].start = pseudo_attr_start;
++ sr[0].end = pseudo_attr_end;
++
++ sr[1].name = "pseudo-mem";
++ sr[1].flags = IORESOURCE_MEM;
++ sr[1].start = pseudo_mem_start;
++ sr[1].end = pseudo_mem_end;
++
++ sr[2].name = "pseudo-io";
++ sr[2].flags = IORESOURCE_MEM;
++ sr[2].start = pseudo_io_start;
++ sr[2].end = pseudo_io_end;
++
++ sr[3].name = "insert";
++ sr[3].flags = IORESOURCE_IRQ;
++ sr[3].start = sr[3].end = cd_irq;
++
++ sr[4].name = "card";
++ sr[4].flags = IORESOURCE_IRQ;
++ sr[4].start = sr[4].end = card_irq;
++
++ i = 5;
++ if (stschg_irq) {
++ sr[i].name = "insert";
++ sr[i].flags = IORESOURCE_IRQ;
++ sr[i].start = sr[i].end = cd_irq;
++ i++;
++ }
++ if (eject_irq) {
++ sr[i].name = "eject";
++ sr[i].flags = IORESOURCE_IRQ;
++ sr[i].start = sr[i].end = eject_irq;
++ }
++
++ pd->resource = sr;
++ pd->num_resources = cnt;
++
++ ret = platform_device_add(pd);
++ if (!ret)
++ return 0;
++
++ platform_device_put(pd);
++out:
++ kfree(sr);
++ return ret;
++}
++
++#define YAMON_SIZE 0x00100000
++#define YAMON_ENV_SIZE 0x00040000
++
++int __init db1x_register_norflash(unsigned long size, int width,
++ int swapped)
++{
++ struct physmap_flash_data *pfd;
++ struct platform_device *pd;
++ struct mtd_partition *parts;
++ struct resource *res;
++ int ret, i;
++
++ if (size < (8 * 1024 * 1024))
++ return -EINVAL;
++
++ ret = -ENOMEM;
++ parts = kzalloc(sizeof(struct mtd_partition) * 5, GFP_KERNEL);
++ if (!parts)
++ goto out;
++
++ res = kzalloc(sizeof(struct resource), GFP_KERNEL);
++ if (!res)
++ goto out1;
++
++ pfd = kzalloc(sizeof(struct physmap_flash_data), GFP_KERNEL);
++ if (!pfd)
++ goto out2;
++
++ pd = platform_device_alloc("physmap-flash", 0);
++ if (!pd)
++ goto out3;
++
++ /* NOR flash ends at 0x20000000, regardless of size */
++ res->start = 0x20000000 - size;
++ res->end = 0x20000000 - 1;
++ res->flags = IORESOURCE_MEM;
++
++ /* partition setup. Most Develboards have a switch which allows
++ * to swap the physical locations of the 2 NOR flash banks.
++ */
++ i = 0;
++ if (!swapped) {
++ /* first NOR chip */
++ parts[i].offset = 0;
++ parts[i].name = "User FS";
++ parts[i].size = size / 2;
++ i++;
++ }
++
++ parts[i].offset = MTDPART_OFS_APPEND;
++ parts[i].name = "User FS 2";
++ parts[i].size = (size / 2) - (0x20000000 - 0x1fc00000);
++ i++;
++
++ parts[i].offset = MTDPART_OFS_APPEND;
++ parts[i].name = "YAMON";
++ parts[i].size = YAMON_SIZE;
++ parts[i].mask_flags = MTD_WRITEABLE;
++ i++;
++
++ parts[i].offset = MTDPART_OFS_APPEND;
++ parts[i].name = "raw kernel";
++ parts[i].size = 0x00400000 - YAMON_SIZE - YAMON_ENV_SIZE;
++ i++;
++
++ parts[i].offset = MTDPART_OFS_APPEND;
++ parts[i].name = "YAMON Env";
++ parts[i].size = YAMON_ENV_SIZE;
++ parts[i].mask_flags = MTD_WRITEABLE;
++ i++;
++
++ if (swapped) {
++ parts[i].offset = MTDPART_OFS_APPEND;
++ parts[i].name = "User FS";
++ parts[i].size = size / 2;
++ i++;
++ }
++
++ pfd->width = width;
++ pfd->parts = parts;
++ pfd->nr_parts = 5;
++
++ pd->dev.platform_data = pfd;
++ pd->resource = res;
++ pd->num_resources = 1;
++
++ ret = platform_device_add(pd);
++ if (!ret)
++ return ret;
++
++ platform_device_put(pd);
++out3:
++ kfree(pfd);
++out2:
++ kfree(res);
++out1:
++ kfree(parts);
++out:
++ return ret;
++}
+diff --git a/arch/mips/alchemy/devboards/platform.h b/arch/mips/alchemy/devboards/platform.h
+new file mode 100644
+index 0000000..828c54e
+--- /dev/null
++++ b/arch/mips/alchemy/devboards/platform.h
+@@ -0,0 +1,21 @@
++#ifndef _DEVBOARD_PLATFORM_H_
++#define _DEVBOARD_PLATFORM_H_
++
++#include <linux/init.h>
++
++int __init db1x_register_pcmcia_socket(unsigned long pseudo_attr_start,
++ unsigned long pseudo_attr_len,
++ unsigned long pseudo_mem_start,
++ unsigned long pseudo_mem_end,
++ unsigned long pseudo_io_start,
++ unsigned long pseudo_io_end,
++ int card_irq,
++ int cd_irq,
++ int stschg_irq,
++ int eject_irq,
++ int id);
++
++int __init db1x_register_norflash(unsigned long size, int width,
++ int swapped);
++
++#endif
+diff --git a/arch/mips/alchemy/devboards/prom.c b/arch/mips/alchemy/devboards/prom.c
+index 0042bd6..b30df5c 100644
+--- a/arch/mips/alchemy/devboards/prom.c
++++ b/arch/mips/alchemy/devboards/prom.c
+@@ -60,3 +60,8 @@ void __init prom_init(void)
+ strict_strtoul(memsize_str, 0, &memsize);
+ add_memory_region(0, memsize, BOOT_MEM_RAM);
+ }
++
++void prom_putchar(unsigned char c)
++{
++ alchemy_uart_putchar(UART0_PHYS_ADDR, c);
++}
+diff --git a/arch/mips/alchemy/mtx-1/Makefile b/arch/mips/alchemy/mtx-1/Makefile
+index 7c67b3d..4a53815 100644
+--- a/arch/mips/alchemy/mtx-1/Makefile
++++ b/arch/mips/alchemy/mtx-1/Makefile
+@@ -6,7 +6,7 @@
+ # Makefile for 4G Systems MTX-1 board.
+ #
+
+-lib-y := init.o board_setup.o irqmap.o
++lib-y := init.o board_setup.o
+ obj-y := platform.o
+
+ EXTRA_CFLAGS += -Werror
+diff --git a/arch/mips/alchemy/mtx-1/board_setup.c b/arch/mips/alchemy/mtx-1/board_setup.c
+index 45b61c9..13577ee 100644
+--- a/arch/mips/alchemy/mtx-1/board_setup.c
++++ b/arch/mips/alchemy/mtx-1/board_setup.c
+@@ -30,11 +30,23 @@
+
+ #include <linux/gpio.h>
+ #include <linux/init.h>
++#include <linux/interrupt.h>
+
+ #include <asm/mach-au1x00/au1000.h>
+
+ #include <prom.h>
+
++char irq_tab_alchemy[][5] __initdata = {
++ [0] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTA, 0xff, 0xff }, /* IDSEL 00 - AdapterA-Slot0 (top) */
++ [1] = { -1, AU1500_PCI_INTB, AU1500_PCI_INTA, 0xff, 0xff }, /* IDSEL 01 - AdapterA-Slot1 (bottom) */
++ [2] = { -1, AU1500_PCI_INTC, AU1500_PCI_INTD, 0xff, 0xff }, /* IDSEL 02 - AdapterB-Slot0 (top) */
++ [3] = { -1, AU1500_PCI_INTD, AU1500_PCI_INTC, 0xff, 0xff }, /* IDSEL 03 - AdapterB-Slot1 (bottom) */
++ [4] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, 0xff, 0xff }, /* IDSEL 04 - AdapterC-Slot0 (top) */
++ [5] = { -1, AU1500_PCI_INTB, AU1500_PCI_INTA, 0xff, 0xff }, /* IDSEL 05 - AdapterC-Slot1 (bottom) */
++ [6] = { -1, AU1500_PCI_INTC, AU1500_PCI_INTD, 0xff, 0xff }, /* IDSEL 06 - AdapterD-Slot0 (top) */
++ [7] = { -1, AU1500_PCI_INTD, AU1500_PCI_INTC, 0xff, 0xff }, /* IDSEL 07 - AdapterD-Slot1 (bottom) */
++};
++
+ extern int (*board_pci_idsel)(unsigned int devsel, int assert);
+ int mtx1_pci_idsel(unsigned int devsel, int assert);
+
+@@ -109,3 +121,15 @@ mtx1_pci_idsel(unsigned int devsel, int assert)
+ au_sync_udelay(1);
+ return 1;
+ }
++
++static int __init mtx1_init_irq(void)
++{
++ set_irq_type(AU1500_GPIO204_INT, IRQF_TRIGGER_HIGH);
++ set_irq_type(AU1500_GPIO201_INT, IRQF_TRIGGER_LOW);
++ set_irq_type(AU1500_GPIO202_INT, IRQF_TRIGGER_LOW);
++ set_irq_type(AU1500_GPIO203_INT, IRQF_TRIGGER_LOW);
++ set_irq_type(AU1500_GPIO205_INT, IRQF_TRIGGER_LOW);
++
++ return 0;
++}
++arch_initcall(mtx1_init_irq);
+diff --git a/arch/mips/alchemy/mtx-1/init.c b/arch/mips/alchemy/mtx-1/init.c
+index 5e871c8..f8d2557 100644
+--- a/arch/mips/alchemy/mtx-1/init.c
++++ b/arch/mips/alchemy/mtx-1/init.c
+@@ -32,6 +32,7 @@
+ #include <linux/init.h>
+
+ #include <asm/bootinfo.h>
++#include <asm/mach-au1x00/au1000.h>
+
+ #include <prom.h>
+
+@@ -58,3 +59,8 @@ void __init prom_init(void)
+ strict_strtoul(memsize_str, 0, &memsize);
+ add_memory_region(0, memsize, BOOT_MEM_RAM);
+ }
++
++void prom_putchar(unsigned char c)
++{
++ alchemy_uart_putchar(UART0_PHYS_ADDR, c);
++}
+diff --git a/arch/mips/alchemy/mtx-1/irqmap.c b/arch/mips/alchemy/mtx-1/irqmap.c
+deleted file mode 100644
+index f1ab12a..0000000
+--- a/arch/mips/alchemy/mtx-1/irqmap.c
++++ /dev/null
+@@ -1,56 +0,0 @@
+-/*
+- * BRIEF MODULE DESCRIPTION
+- * Au1xxx irq map table
+- *
+- * Copyright 2003 Embedded Edge, LLC
+- * dan@embeddededge.com
+- *
+- * 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.
+- */
+-
+-#include <linux/init.h>
+-#include <linux/interrupt.h>
+-#include <asm/mach-au1x00/au1000.h>
+-
+-char irq_tab_alchemy[][5] __initdata = {
+- [0] = { -1, INTA, INTA, INTX, INTX }, /* IDSEL 00 - AdapterA-Slot0 (top) */
+- [1] = { -1, INTB, INTA, INTX, INTX }, /* IDSEL 01 - AdapterA-Slot1 (bottom) */
+- [2] = { -1, INTC, INTD, INTX, INTX }, /* IDSEL 02 - AdapterB-Slot0 (top) */
+- [3] = { -1, INTD, INTC, INTX, INTX }, /* IDSEL 03 - AdapterB-Slot1 (bottom) */
+- [4] = { -1, INTA, INTB, INTX, INTX }, /* IDSEL 04 - AdapterC-Slot0 (top) */
+- [5] = { -1, INTB, INTA, INTX, INTX }, /* IDSEL 05 - AdapterC-Slot1 (bottom) */
+- [6] = { -1, INTC, INTD, INTX, INTX }, /* IDSEL 06 - AdapterD-Slot0 (top) */
+- [7] = { -1, INTD, INTC, INTX, INTX }, /* IDSEL 07 - AdapterD-Slot1 (bottom) */
+-};
+-
+-struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
+- { AU1500_GPIO_204, IRQF_TRIGGER_HIGH, 0 },
+- { AU1500_GPIO_201, IRQF_TRIGGER_LOW, 0 },
+- { AU1500_GPIO_202, IRQF_TRIGGER_LOW, 0 },
+- { AU1500_GPIO_203, IRQF_TRIGGER_LOW, 0 },
+- { AU1500_GPIO_205, IRQF_TRIGGER_LOW, 0 },
+-};
+-
+-
+-void __init board_init_irq(void)
+-{
+- au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map));
+-}
+diff --git a/arch/mips/alchemy/xxs1500/Makefile b/arch/mips/alchemy/xxs1500/Makefile
+index db3c526..4dc81d7 100644
+--- a/arch/mips/alchemy/xxs1500/Makefile
++++ b/arch/mips/alchemy/xxs1500/Makefile
+@@ -5,4 +5,6 @@
+ # Makefile for MyCable XXS1500 board.
+ #
+
+-lib-y := init.o board_setup.o irqmap.o
++lib-y := init.o board_setup.o platform.o
++
++EXTRA_CFLAGS += -Werror
+diff --git a/arch/mips/alchemy/xxs1500/board_setup.c b/arch/mips/alchemy/xxs1500/board_setup.c
+index 4de2d48..21bef8d 100644
+--- a/arch/mips/alchemy/xxs1500/board_setup.c
++++ b/arch/mips/alchemy/xxs1500/board_setup.c
+@@ -25,6 +25,7 @@
+
+ #include <linux/gpio.h>
+ #include <linux/init.h>
++#include <linux/interrupt.h>
+ #include <linux/delay.h>
+
+ #include <asm/mach-au1x00/au1000.h>
+@@ -68,22 +69,6 @@ void __init board_setup(void)
+ /* Enable DTR = USB power up */
+ au_writel(0x01, UART3_ADDR + UART_MCR); /* UART_MCR_DTR is 0x01??? */
+
+-#ifdef CONFIG_PCMCIA_XXS1500
+- /* GPIO 0, 1, and 4 are inputs */
+- alchemy_gpio_direction_input(0);
+- alchemy_gpio_direction_input(1);
+- alchemy_gpio_direction_input(4);
+-
+- /* GPIO2 208/9/10/11 are inputs */
+- alchemy_gpio_direction_input(208);
+- alchemy_gpio_direction_input(209);
+- alchemy_gpio_direction_input(210);
+- alchemy_gpio_direction_input(211);
+-
+- /* Turn off power */
+- alchemy_gpio_direction_output(214, 0);
+-#endif
+-
+ #ifdef CONFIG_PCI
+ #if defined(__MIPSEB__)
+ au_writel(0xf | (2 << 6) | (1 << 4), Au1500_PCI_CFG);
+@@ -92,3 +77,23 @@ void __init board_setup(void)
+ #endif
+ #endif
+ }
++
++static int __init xxs1500_init_irq(void)
++{
++ set_irq_type(AU1500_GPIO204_INT, IRQF_TRIGGER_HIGH);
++ set_irq_type(AU1500_GPIO201_INT, IRQF_TRIGGER_LOW);
++ set_irq_type(AU1500_GPIO202_INT, IRQF_TRIGGER_LOW);
++ set_irq_type(AU1500_GPIO203_INT, IRQF_TRIGGER_LOW);
++ set_irq_type(AU1500_GPIO205_INT, IRQF_TRIGGER_LOW);
++ set_irq_type(AU1500_GPIO207_INT, IRQF_TRIGGER_LOW);
++
++ set_irq_type(AU1500_GPIO0_INT, IRQF_TRIGGER_LOW);
++ set_irq_type(AU1500_GPIO1_INT, IRQF_TRIGGER_LOW);
++ set_irq_type(AU1500_GPIO2_INT, IRQF_TRIGGER_LOW);
++ set_irq_type(AU1500_GPIO3_INT, IRQF_TRIGGER_LOW);
++ set_irq_type(AU1500_GPIO4_INT, IRQF_TRIGGER_LOW); /* CF irq */
++ set_irq_type(AU1500_GPIO5_INT, IRQF_TRIGGER_LOW);
++
++ return 0;
++}
++arch_initcall(xxs1500_init_irq);
+diff --git a/arch/mips/alchemy/xxs1500/init.c b/arch/mips/alchemy/xxs1500/init.c
+index 456fa14..15125c2 100644
+--- a/arch/mips/alchemy/xxs1500/init.c
++++ b/arch/mips/alchemy/xxs1500/init.c
+@@ -30,6 +30,7 @@
+ #include <linux/kernel.h>
+
+ #include <asm/bootinfo.h>
++#include <asm/mach-au1x00/au1000.h>
+
+ #include <prom.h>
+
+@@ -56,3 +57,8 @@ void __init prom_init(void)
+ strict_strtoul(memsize_str, 0, &memsize);
+ add_memory_region(0, memsize, BOOT_MEM_RAM);
+ }
++
++void prom_putchar(unsigned char c)
++{
++ alchemy_uart_putchar(UART0_PHYS_ADDR, c);
++}
+diff --git a/arch/mips/alchemy/xxs1500/irqmap.c b/arch/mips/alchemy/xxs1500/irqmap.c
+deleted file mode 100644
+index 0f0f301..0000000
+--- a/arch/mips/alchemy/xxs1500/irqmap.c
++++ /dev/null
+@@ -1,52 +0,0 @@
+-/*
+- * BRIEF MODULE DESCRIPTION
+- * Au1xxx irq map table
+- *
+- * Copyright 2003 Embedded Edge, LLC
+- * dan@embeddededge.com
+- *
+- * 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.
+- */
+-
+-#include <linux/init.h>
+-#include <linux/interrupt.h>
+-#include <asm/mach-au1x00/au1000.h>
+-
+-struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
+- { AU1500_GPIO_204, IRQF_TRIGGER_HIGH, 0 },
+- { AU1500_GPIO_201, IRQF_TRIGGER_LOW, 0 },
+- { AU1500_GPIO_202, IRQF_TRIGGER_LOW, 0 },
+- { AU1500_GPIO_203, IRQF_TRIGGER_LOW, 0 },
+- { AU1500_GPIO_205, IRQF_TRIGGER_LOW, 0 },
+- { AU1500_GPIO_207, IRQF_TRIGGER_LOW, 0 },
+-
+- { AU1000_GPIO_0, IRQF_TRIGGER_LOW, 0 },
+- { AU1000_GPIO_1, IRQF_TRIGGER_LOW, 0 },
+- { AU1000_GPIO_2, IRQF_TRIGGER_LOW, 0 },
+- { AU1000_GPIO_3, IRQF_TRIGGER_LOW, 0 },
+- { AU1000_GPIO_4, IRQF_TRIGGER_LOW, 0 }, /* CF interrupt */
+- { AU1000_GPIO_5, IRQF_TRIGGER_LOW, 0 },
+-};
+-
+-void __init board_init_irq(void)
+-{
+- au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map));
+-}
+diff --git a/arch/mips/alchemy/xxs1500/platform.c b/arch/mips/alchemy/xxs1500/platform.c
+new file mode 100644
+index 0000000..c14dcaa
+--- /dev/null
++++ b/arch/mips/alchemy/xxs1500/platform.c
+@@ -0,0 +1,63 @@
++/*
++ * XXS1500 board platform device registration
++ *
++ * Copyright (C) 2009 Manuel Lauss
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#include <linux/init.h>
++#include <linux/platform_device.h>
++
++#include <asm/mach-au1x00/au1000.h>
++
++static struct resource xxs1500_pcmcia_res[] = {
++ {
++ .name = "pseudo-io",
++ .flags = IORESOURCE_MEM,
++ .start = PCMCIA_IO_PSEUDO_PHYS,
++ .end = PCMCIA_IO_PSEUDO_PHYS + 0x00040000 - 1,
++ },
++ {
++ .name = "pseudo-attr",
++ .flags = IORESOURCE_MEM,
++ .start = PCMCIA_ATTR_PSEUDO_PHYS,
++ .end = PCMCIA_ATTR_PSEUDO_PHYS + 0x00040000 - 1,
++ },
++ {
++ .name = "pseudo-mem",
++ .flags = IORESOURCE_MEM,
++ .start = PCMCIA_IO_PSEUDO_PHYS,
++ .end = PCMCIA_IO_PSEUDO_PHYS + 0x00040000 - 1,
++ },
++};
++
++static struct platform_device xxs1500_pcmcia_dev = {
++ .name = "xxs1500_pcmcia",
++ .id = -1,
++ .num_resources = ARRAY_SIZE(xxs1500_pcmcia_res),
++ .resource = xxs1500_pcmcia_res,
++};
++
++static struct platform_device *xxs1500_devs[] __initdata = {
++ &xxs1500_pcmcia_dev,
++};
++
++static int __init xxs1500_dev_init(void)
++{
++ return platform_add_devices(xxs1500_devs,
++ ARRAY_SIZE(xxs1500_devs));
++}
++device_initcall(xxs1500_dev_init);
+diff --git a/arch/mips/bcm47xx/prom.c b/arch/mips/bcm47xx/prom.c
+index fb284c3..c51405e 100644
+--- a/arch/mips/bcm47xx/prom.c
++++ b/arch/mips/bcm47xx/prom.c
+@@ -100,11 +100,11 @@ static __init void prom_init_console(void)
+
+ static __init void prom_init_cmdline(void)
+ {
+- static char buf[CL_SIZE] __initdata;
++ static char buf[COMMAND_LINE_SIZE] __initdata;
+
+ /* Get the kernel command line from CFE */
+- if (cfe_getenv("LINUX_CMDLINE", buf, CL_SIZE) >= 0) {
+- buf[CL_SIZE-1] = 0;
++ if (cfe_getenv("LINUX_CMDLINE", buf, COMMAND_LINE_SIZE) >= 0) {
++ buf[COMMAND_LINE_SIZE - 1] = 0;
+ strcpy(arcs_cmdline, buf);
+ }
+
+@@ -112,13 +112,13 @@ static __init void prom_init_cmdline(void)
+ * as CFE is not available anymore later in the boot process. */
+ if ((strstr(arcs_cmdline, "console=")) == NULL) {
+ /* Try to read the default serial port used by CFE */
+- if ((cfe_getenv("BOOT_CONSOLE", buf, CL_SIZE) < 0)
++ if ((cfe_getenv("BOOT_CONSOLE", buf, COMMAND_LINE_SIZE) < 0)
+ || (strncmp("uart", buf, 4)))
+ /* Default to uart0 */
+ strcpy(buf, "uart0");
+
+ /* Compute the new command line */
+- snprintf(arcs_cmdline, CL_SIZE, "%s console=ttyS%c,115200",
++ snprintf(arcs_cmdline, COMMAND_LINE_SIZE, "%s console=ttyS%c,115200",
+ arcs_cmdline, buf[4]);
+ }
+ }
+diff --git a/arch/mips/boot/Makefile b/arch/mips/boot/Makefile
+index 2a209d7..094bc84 100644
+--- a/arch/mips/boot/Makefile
++++ b/arch/mips/boot/Makefile
+@@ -25,7 +25,7 @@ strip-flags = $(addprefix --remove-section=,$(drop-sections))
+
+ VMLINUX = vmlinux
+
+-all: vmlinux.ecoff vmlinux.srec addinitrd
++all: vmlinux.ecoff vmlinux.srec
+
+ vmlinux.ecoff: $(obj)/elf2ecoff $(VMLINUX)
+ $(obj)/elf2ecoff $(VMLINUX) vmlinux.ecoff $(E2EFLAGS)
+@@ -39,11 +39,7 @@ vmlinux.bin: $(VMLINUX)
+ vmlinux.srec: $(VMLINUX)
+ $(OBJCOPY) -S -O srec $(strip-flags) $(VMLINUX) $(obj)/vmlinux.srec
+
+-$(obj)/addinitrd: $(obj)/addinitrd.c
+- $(HOSTCC) -o $@ $^
+-
+-clean-files += addinitrd \
+- elf2ecoff \
++clean-files += elf2ecoff \
+ vmlinux.bin \
+ vmlinux.ecoff \
+ vmlinux.srec
+diff --git a/arch/mips/boot/addinitrd.c b/arch/mips/boot/addinitrd.c
+deleted file mode 100644
+index b5b3feb..0000000
+--- a/arch/mips/boot/addinitrd.c
++++ /dev/null
+@@ -1,131 +0,0 @@
+-/*
+- * addinitrd - program to add a initrd image to an ecoff kernel
+- *
+- * (C) 1999 Thomas Bogendoerfer
+- * minor modifications, cleanup: Guido Guenther <agx@sigxcpu.org>
+- * further cleanup: Maciej W. Rozycki
+- */
+-
+-#include <sys/types.h>
+-#include <sys/stat.h>
+-#include <fcntl.h>
+-#include <unistd.h>
+-#include <stdio.h>
+-#include <netinet/in.h>
+-
+-#include "ecoff.h"
+-
+-#define MIPS_PAGE_SIZE 4096
+-#define MIPS_PAGE_MASK (MIPS_PAGE_SIZE-1)
+-
+-#define swab16(x) \
+- ((unsigned short)( \
+- (((unsigned short)(x) & (unsigned short)0x00ffU) << 8) | \
+- (((unsigned short)(x) & (unsigned short)0xff00U) >> 8) ))
+-
+-#define swab32(x) \
+- ((unsigned int)( \
+- (((unsigned int)(x) & (unsigned int)0x000000ffUL) << 24) | \
+- (((unsigned int)(x) & (unsigned int)0x0000ff00UL) << 8) | \
+- (((unsigned int)(x) & (unsigned int)0x00ff0000UL) >> 8) | \
+- (((unsigned int)(x) & (unsigned int)0xff000000UL) >> 24) ))
+-
+-#define SWAB(a) (swab ? swab32(a) : (a))
+-
+-void die(char *s)
+-{
+- perror(s);
+- exit(1);
+-}
+-
+-int main(int argc, char *argv[])
+-{
+- int fd_vmlinux, fd_initrd, fd_outfile;
+- FILHDR efile;
+- AOUTHDR eaout;
+- SCNHDR esecs[3];
+- struct stat st;
+- char buf[1024];
+- unsigned long loadaddr;
+- unsigned long initrd_header[2];
+- int i, cnt;
+- int swab = 0;
+-
+- if (argc != 4) {
+- printf("Usage: %s <vmlinux> <initrd> <outfile>\n", argv[0]);
+- exit(1);
+- }
+-
+- if ((fd_vmlinux = open (argv[1], O_RDONLY)) < 0)
+- die("open vmlinux");
+- if (read (fd_vmlinux, &efile, sizeof efile) != sizeof efile)
+- die("read file header");
+- if (read (fd_vmlinux, &eaout, sizeof eaout) != sizeof eaout)
+- die("read aout header");
+- if (read (fd_vmlinux, esecs, sizeof esecs) != sizeof esecs)
+- die("read section headers");
+- /*
+- * check whether the file is good for us
+- */
+- /* TBD */
+-
+- /*
+- * check, if we have to swab words
+- */
+- if (ntohs(0xaa55) == 0xaa55) {
+- if (efile.f_magic == swab16(MIPSELMAGIC))
+- swab = 1;
+- } else {
+- if (efile.f_magic == swab16(MIPSEBMAGIC))
+- swab = 1;
+- }
+-
+- /* make sure we have an empty data segment for the initrd */
+- if (eaout.dsize || esecs[1].s_size) {
+- fprintf(stderr, "Data segment not empty. Giving up!\n");
+- exit(1);
+- }
+- if ((fd_initrd = open (argv[2], O_RDONLY)) < 0)
+- die("open initrd");
+- if (fstat (fd_initrd, &st) < 0)
+- die("fstat initrd");
+- loadaddr = ((SWAB(esecs[2].s_vaddr) + SWAB(esecs[2].s_size)
+- + MIPS_PAGE_SIZE-1) & ~MIPS_PAGE_MASK) - 8;
+- if (loadaddr < (SWAB(esecs[2].s_vaddr) + SWAB(esecs[2].s_size)))
+- loadaddr += MIPS_PAGE_SIZE;
+- initrd_header[0] = SWAB(0x494E5244);
+- initrd_header[1] = SWAB(st.st_size);
+- eaout.dsize = esecs[1].s_size = initrd_header[1] = SWAB(st.st_size+8);
+- eaout.data_start = esecs[1].s_vaddr = esecs[1].s_paddr = SWAB(loadaddr);
+-
+- if ((fd_outfile = open (argv[3], O_RDWR|O_CREAT|O_TRUNC, 0666)) < 0)
+- die("open outfile");
+- if (write (fd_outfile, &efile, sizeof efile) != sizeof efile)
+- die("write file header");
+- if (write (fd_outfile, &eaout, sizeof eaout) != sizeof eaout)
+- die("write aout header");
+- if (write (fd_outfile, esecs, sizeof esecs) != sizeof esecs)
+- die("write section headers");
+- /* skip padding */
+- if(lseek(fd_vmlinux, SWAB(esecs[0].s_scnptr), SEEK_SET) == (off_t)-1)
+- die("lseek vmlinux");
+- if(lseek(fd_outfile, SWAB(esecs[0].s_scnptr), SEEK_SET) == (off_t)-1)
+- die("lseek outfile");
+- /* copy text segment */
+- cnt = SWAB(eaout.tsize);
+- while (cnt) {
+- if ((i = read (fd_vmlinux, buf, sizeof buf)) <= 0)
+- die("read vmlinux");
+- if (write (fd_outfile, buf, i) != i)
+- die("write vmlinux");
+- cnt -= i;
+- }
+- if (write (fd_outfile, initrd_header, sizeof initrd_header) != sizeof initrd_header)
+- die("write initrd header");
+- while ((i = read (fd_initrd, buf, sizeof buf)) > 0)
+- if (write (fd_outfile, buf, i) != i)
+- die("write initrd");
+- close(fd_vmlinux);
+- close(fd_initrd);
+- return 0;
+-}
+diff --git a/arch/mips/boot/compressed/Makefile b/arch/mips/boot/compressed/Makefile
+new file mode 100644
+index 0000000..569b6ad
+--- /dev/null
++++ b/arch/mips/boot/compressed/Makefile
+@@ -0,0 +1,99 @@
++#
++# This file is subject to the terms and conditions of the GNU General Public
++# License.
++#
++# Adapted for MIPS Pete Popov, Dan Malek
++#
++# Copyright (C) 1994 by Linus Torvalds
++# Adapted for PowerPC by Gary Thomas
++# modified by Cort (cort@cs.nmt.edu)
++#
++# Copyright (C) 2009 Lemote Inc. & DSLab, Lanzhou University
++# Author: Wu Zhangjin <wuzj@lemote.com>
++#
++
++# compressed kernel load addr: VMLINUZ_LOAD_ADDRESS > VMLINUX_LOAD_ADDRESS + VMLINUX_SIZE
++VMLINUX_SIZE := $(shell wc -c $(objtree)/$(KBUILD_IMAGE) 2>/dev/null | cut -d' ' -f1)
++VMLINUX_SIZE := $(shell [ -n "$(VMLINUX_SIZE)" ] && echo $$(($(VMLINUX_SIZE) + (65536 - $(VMLINUX_SIZE) % 65536))))
++VMLINUZ_LOAD_ADDRESS := 0x$(shell [ -n "$(VMLINUX_SIZE)" ] && printf %x $$(($(VMLINUX_LOAD_ADDRESS) + $(VMLINUX_SIZE))))
++
++# set the default size of the mallocing area for decompressing
++BOOT_HEAP_SIZE := 0x400000
++
++# Disable Function Tracer
++KBUILD_CFLAGS := $(shell echo $(KBUILD_CFLAGS) | sed -e "s/-pg//")
++
++KBUILD_CFLAGS := $(LINUXINCLUDE) $(KBUILD_CFLAGS) -D__KERNEL__ \
++ -DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) -D"VMLINUX_LOAD_ADDRESS_ULL=$(VMLINUX_LOAD_ADDRESS)ull" \
++
++KBUILD_AFLAGS := $(LINUXINCLUDE) $(KBUILD_AFLAGS) -D__ASSEMBLY__ \
++ -DKERNEL_ENTRY=0x$(shell $(NM) $(objtree)/$(KBUILD_IMAGE) 2>/dev/null | grep " kernel_entry" | cut -f1 -d \ ) \
++ -DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE)
++
++obj-y := $(obj)/head.o $(obj)/decompress.o $(obj)/dbg.o $(obj)/cache.o
++
++obj-$(CONFIG_SYS_SUPPORTS_ZBOOT_UART16550) += $(obj)/uart-16550.o
++
++OBJCOPYFLAGS_vmlinux.bin := $(OBJCOPYFLAGS) -O binary -R .comment -S
++$(obj)/vmlinux.bin: $(KBUILD_IMAGE)
++ $(call if_changed,objcopy)
++
++suffix_$(CONFIG_KERNEL_GZIP) = gz
++suffix_$(CONFIG_KERNEL_BZIP2) = bz2
++suffix_$(CONFIG_KERNEL_LZMA) = lzma
++suffix_$(CONFIG_KERNEL_LZO) = lzo
++tool_$(CONFIG_KERNEL_GZIP) = gzip
++tool_$(CONFIG_KERNEL_BZIP2) = bzip2
++tool_$(CONFIG_KERNEL_LZMA) = lzma
++tool_$(CONFIG_KERNEL_LZO) = lzo
++$(obj)/vmlinux.$(suffix_y): $(obj)/vmlinux.bin
++ $(call if_changed,$(tool_y))
++
++$(obj)/piggy.o: $(obj)/vmlinux.$(suffix_y) $(obj)/dummy.o
++ $(Q)$(OBJCOPY) $(OBJCOPYFLAGS) \
++ --add-section=.image=$< \
++ --set-section-flags=.image=contents,alloc,load,readonly,data \
++ $(obj)/dummy.o $@
++
++LDFLAGS_vmlinuz := $(LDFLAGS) -Ttext $(VMLINUZ_LOAD_ADDRESS) -T
++vmlinuz: $(src)/ld.script $(obj-y) $(obj)/piggy.o
++ $(call if_changed,ld)
++ $(Q)$(OBJCOPY) $(OBJCOPYFLAGS) $@
++
++#
++# Some DECstations need all possible sections of an ECOFF executable
++#
++ifdef CONFIG_MACH_DECSTATION
++ E2EFLAGS = -a
++else
++ E2EFLAGS =
++endif
++
++# elf2ecoff can only handle 32bit image
++
++ifdef CONFIG_32BIT
++ VMLINUZ = vmlinuz
++else
++ VMLINUZ = vmlinuz.32
++endif
++
++vmlinuz.32: vmlinuz
++ $(Q)$(OBJCOPY) -O $(32bit-bfd) $(OBJCOPYFLAGS) $< $@
++
++vmlinuz.ecoff: $(obj)/../elf2ecoff $(VMLINUZ)
++ $(Q)$(obj)/../elf2ecoff $(VMLINUZ) vmlinuz.ecoff $(E2EFLAGS)
++
++$(obj)/../elf2ecoff: $(src)/../elf2ecoff.c
++ $(Q)$(HOSTCC) -o $@ $^
++
++OBJCOPYFLAGS_vmlinuz.bin := $(OBJCOPYFLAGS) -O binary
++vmlinuz.bin: vmlinuz
++ $(call if_changed,objcopy)
++
++OBJCOPYFLAGS_vmlinuz.srec := $(OBJCOPYFLAGS) -S -O srec
++vmlinuz.srec: vmlinuz
++ $(call if_changed,objcopy)
++
++clean:
++clean-files += *.o \
++ vmlinu*
+diff --git a/arch/mips/boot/compressed/cache.c b/arch/mips/boot/compressed/cache.c
+new file mode 100644
+index 0000000..b229614
+--- /dev/null
++++ b/arch/mips/boot/compressed/cache.c
+@@ -0,0 +1,44 @@
++#include <asm/addrspace.h>
++
++#define cache32_unroll32(base, op) \
++ __asm__ __volatile__( \
++ " .set push \n" \
++ " .set noreorder \n" \
++ " .set mips3 \n" \
++ " cache %1, 0x000(%0); cache %1, 0x020(%0) \n" \
++ " cache %1, 0x040(%0); cache %1, 0x060(%0) \n" \
++ " cache %1, 0x080(%0); cache %1, 0x0a0(%0) \n" \
++ " cache %1, 0x0c0(%0); cache %1, 0x0e0(%0) \n" \
++ " cache %1, 0x100(%0); cache %1, 0x120(%0) \n" \
++ " cache %1, 0x140(%0); cache %1, 0x160(%0) \n" \
++ " cache %1, 0x180(%0); cache %1, 0x1a0(%0) \n" \
++ " cache %1, 0x1c0(%0); cache %1, 0x1e0(%0) \n" \
++ " cache %1, 0x200(%0); cache %1, 0x220(%0) \n" \
++ " cache %1, 0x240(%0); cache %1, 0x260(%0) \n" \
++ " cache %1, 0x280(%0); cache %1, 0x2a0(%0) \n" \
++ " cache %1, 0x2c0(%0); cache %1, 0x2e0(%0) \n" \
++ " cache %1, 0x300(%0); cache %1, 0x320(%0) \n" \
++ " cache %1, 0x340(%0); cache %1, 0x360(%0) \n" \
++ " cache %1, 0x380(%0); cache %1, 0x3a0(%0) \n" \
++ " cache %1, 0x3c0(%0); cache %1, 0x3e0(%0) \n" \
++ " .set pop \n" \
++ : \
++ : "r" (base), \
++ "i" (op));
++
++#define MEM_SIZE_M 512
++
++void flush_cache_all(void)
++{
++ unsigned long start = CKSEG0ADDR(0x80000000);
++ unsigned long end = start + MEM_SIZE_M * 1024 / 4;
++ unsigned long lsize = 32;
++ unsigned long addr;
++
++ int i;
++
++ for (i = 0; i < 4; i++) {
++ for (addr = start; addr < end; addr += lsize * 32)
++ cache32_unroll32(addr | i, 0x03); /* Index Writeback scache */
++ }
++}
+diff --git a/arch/mips/boot/compressed/dbg.c b/arch/mips/boot/compressed/dbg.c
+new file mode 100644
+index 0000000..ff4dc7a
+--- /dev/null
++++ b/arch/mips/boot/compressed/dbg.c
+@@ -0,0 +1,37 @@
++/*
++ * MIPS-specific debug support for pre-boot environment
++ *
++ * NOTE: putc() is board specific, if your board have a 16550 compatible uart,
++ * please select SYS_SUPPORTS_ZBOOT_UART16550 for your machine. othewise, you
++ * need to implement your own putc().
++ */
++
++#include <linux/init.h>
++#include <linux/types.h>
++
++void __attribute__ ((weak)) putc(char c)
++{
++}
++
++void puts(const char *s)
++{
++ char c;
++ while ((c = *s++) != '\0') {
++ putc(c);
++ if (c == '\n')
++ putc('\r');
++ }
++}
++
++void puthex(unsigned long long val)
++{
++
++ unsigned char buf[10];
++ int i;
++ for (i = 7; i >= 0; i--) {
++ buf[i] = "0123456789ABCDEF"[val & 0x0F];
++ val >>= 4;
++ }
++ buf[8] = '\0';
++ puts(buf);
++}
+diff --git a/arch/mips/boot/compressed/decompress.c b/arch/mips/boot/compressed/decompress.c
+new file mode 100644
+index 0000000..f9a4575
+--- /dev/null
++++ b/arch/mips/boot/compressed/decompress.c
+@@ -0,0 +1,123 @@
++/*
++ * Misc. bootloader code for many machines.
++ *
++ * Copyright 2001 MontaVista Software Inc.
++ * Author: Matt Porter <mporter@mvista.com> Derived from
++ * arch/ppc/boot/prep/misc.c
++ *
++ * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology
++ * Author: Wu Zhangjin <wuzj@lemote.com>
++ *
++ * 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 <linux/types.h>
++#include <linux/kernel.h>
++
++#include <asm/addrspace.h>
++
++/* These two variables specify the free mem region
++ * that can be used for temporary malloc area
++ */
++unsigned long free_mem_ptr;
++unsigned long free_mem_end_ptr;
++char *zimage_start;
++
++/* The linker tells us where the image is. */
++extern unsigned char __image_begin, __image_end;
++
++/* debug interfaces */
++extern void puts(const char *s);
++extern void puthex(unsigned long long val);
++
++void error(char *x)
++{
++ puts("\n\n");
++ puts(x);
++ puts("\n\n -- System halted");
++
++ while (1)
++ ; /* Halt */
++}
++
++/* activate the code for pre-boot environment */
++#define STATIC static
++
++#ifdef CONFIG_KERNEL_GZIP
++void *memcpy(void *dest, const void *src, size_t n)
++{
++ int i;
++ const char *s = src;
++ char *d = dest;
++
++ for (i = 0; i < n; i++)
++ d[i] = s[i];
++ return dest;
++}
++#include "../../../../lib/decompress_inflate.c"
++#endif
++
++#ifdef CONFIG_KERNEL_BZIP2
++void *memset(void *s, int c, size_t n)
++{
++ int i;
++ char *ss = s;
++
++ for (i = 0; i < n; i++)
++ ss[i] = c;
++ return s;
++}
++#include "../../../../lib/decompress_bunzip2.c"
++#endif
++
++#ifdef CONFIG_KERNEL_LZMA
++#include "../../../../lib/decompress_unlzma.c"
++#endif
++
++#ifdef CONFIG_KERNEL_LZO
++#include "../../../../lib/decompress_unlzo.c"
++#endif
++
++extern void flush_cache_all(void);
++
++void decompress_kernel(unsigned long boot_heap_start)
++{
++ int zimage_size;
++
++ /*
++ * We link ourself to an arbitrary low address. When we run, we
++ * relocate outself to that address. __image_beign points to
++ * the part of the image where the zImage is. -- Tom
++ */
++ zimage_start = (char *)(unsigned long)(&__image_begin);
++ zimage_size = (unsigned long)(&__image_end) -
++ (unsigned long)(&__image_begin);
++
++ /*
++ * The zImage and initrd will be between start and _end, so they've
++ * already been moved once. We're good to go now. -- Tom
++ */
++ puts("zimage at: ");
++ puthex((unsigned long)zimage_start);
++ puts(" ");
++ puthex((unsigned long)(zimage_size + zimage_start));
++ puts("\n");
++
++ /* this area are prepared for mallocing when decompressing */
++ free_mem_ptr = boot_heap_start;
++ free_mem_end_ptr = boot_heap_start + BOOT_HEAP_SIZE;
++
++ /* Display standard Linux/MIPS boot prompt for kernel args */
++ puts("Uncompressing Linux at load address ");
++ puthex(VMLINUX_LOAD_ADDRESS_ULL);
++ puts("\n");
++ /* Decompress the kernel with according algorithm */
++ decompress(zimage_start, zimage_size, 0, 0,
++ (void *)VMLINUX_LOAD_ADDRESS_ULL, 0, error);
++ flush_cache_all();
++ /* FIXME: is there a need to flush cache here? */
++ puts("Now, booting the kernel...\n");
++}
+diff --git a/arch/mips/boot/compressed/dummy.c b/arch/mips/boot/compressed/dummy.c
+new file mode 100644
+index 0000000..31dbf45
+--- /dev/null
++++ b/arch/mips/boot/compressed/dummy.c
+@@ -0,0 +1,4 @@
++int main(void)
++{
++ return 0;
++}
+diff --git a/arch/mips/boot/compressed/head.S b/arch/mips/boot/compressed/head.S
+new file mode 100644
+index 0000000..4e65a84
+--- /dev/null
++++ b/arch/mips/boot/compressed/head.S
+@@ -0,0 +1,56 @@
++/*
++ * 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) 1994, 1995 Waldorf Electronics
++ * Written by Ralf Baechle and Andreas Busse
++ * Copyright (C) 1995 - 1999 Ralf Baechle
++ * Copyright (C) 1996 Paul M. Antoine
++ * Modified for DECStation and hence R3000 support by Paul M. Antoine
++ * Further modifications by David S. Miller and Harald Koerfgen
++ * Copyright (C) 1999 Silicon Graphics, Inc.
++ */
++
++#include <asm/asm.h>
++#include <asm/regdef.h>
++
++ .set noreorder
++ .cprestore
++ LEAF(start)
++start:
++ /* Save boot rom start args */
++ move s0, a0
++ move s1, a1
++ move s2, a2
++ move s3, a3
++
++ /* Clear BSS */
++ PTR_LA a0, _edata
++ PTR_LA a2, _end
++1: sw zero, 0(a0)
++ bne a2, a0, 1b
++ addiu a0, a0, 4
++
++ PTR_LA a0, (.heap) /* heap address */
++ PTR_LA sp, (.stack + 8192) /* stack address */
++
++ PTR_LA ra, 2f
++ PTR_LA k0, decompress_kernel
++ jr k0
++ nop
++2:
++ move a0, s0
++ move a1, s1
++ move a2, s2
++ move a3, s3
++ PTR_LI k0, KERNEL_ENTRY
++ jr k0
++ nop
++3:
++ b 3b
++ nop
++ END(start)
++
++ .comm .heap,BOOT_HEAP_SIZE,4
++ .comm .stack,4096*2,4
+diff --git a/arch/mips/boot/compressed/ld.script b/arch/mips/boot/compressed/ld.script
+new file mode 100644
+index 0000000..5d5b18c
+--- /dev/null
++++ b/arch/mips/boot/compressed/ld.script
+@@ -0,0 +1,67 @@
++/*
++ * ld.script for compressed kernel support of MIPS
++ *
++ * Copyright (C) 2009 Lemote Inc.
++ * Author: Wu Zhangjin <wuzhangjin@gmail.com>
++ */
++
++OUTPUT_ARCH(mips)
++ENTRY(start)
++SECTIONS
++{
++ /* . = VMLINUZ_LOAD_ADDRESS */
++ /* read-only */
++ _text = .; /* Text and read-only data */
++ .text : {
++ _ftext = . ;
++ *(.text)
++ *(.rodata)
++ } = 0
++ _etext = .; /* End of text section */
++
++ /* writable */
++ .data : { /* Data */
++ _fdata = . ;
++ *(.data)
++ /* Put the compressed image here, so bss is on the end. */
++ __image_begin = .;
++ *(.image)
++ __image_end = .;
++ CONSTRUCTORS
++ }
++ .sdata : { *(.sdata) }
++ . = ALIGN(4);
++ _edata = .; /* End of data section */
++
++ /* BSS */
++ __bss_start = .;
++ _fbss = .;
++ .sbss : { *(.sbss) *(.scommon) }
++ .bss : {
++ *(.dynbss)
++ *(.bss)
++ *(COMMON)
++ }
++ . = ALIGN(4);
++ _end = . ;
++
++ /* These are needed for ELF backends which have not yet been converted
++ * to the new style linker. */
++
++ .stab 0 : { *(.stab) }
++ .stabstr 0 : { *(.stabstr) }
++
++ /* These must appear regardless of . */
++ .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
++ .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }
++
++ /* Sections to be discarded */
++ /DISCARD/ : {
++ *(.MIPS.options)
++ *(.options)
++ *(.pdr)
++ *(.reginfo)
++ *(.comment)
++ *(.note)
++ }
++}
+diff --git a/arch/mips/boot/compressed/uart-16550.c b/arch/mips/boot/compressed/uart-16550.c
+new file mode 100644
+index 0000000..c9caaf4
+--- /dev/null
++++ b/arch/mips/boot/compressed/uart-16550.c
+@@ -0,0 +1,43 @@
++/*
++ * 16550 compatible uart based serial debug support for zboot
++ */
++
++#include <linux/types.h>
++#include <linux/serial_reg.h>
++#include <linux/init.h>
++
++#include <asm/addrspace.h>
++
++#if defined(CONFIG_MACH_LOONGSON) || defined(CONFIG_MIPS_MALTA)
++#define UART_BASE 0x1fd003f8
++#define PORT(offset) (CKSEG1ADDR(UART_BASE) + (offset))
++#endif
++
++#ifdef CONFIG_AR7
++#include <ar7.h>
++#define PORT(offset) (CKSEG1ADDR(AR7_REGS_UART0) + (4 * offset))
++#endif
++
++#ifndef PORT
++#error please define the serial port address for your own machine
++#endif
++
++static inline unsigned int serial_in(int offset)
++{
++ return *((char *)PORT(offset));
++}
++
++static inline void serial_out(int offset, int value)
++{
++ *((char *)PORT(offset)) = value;
++}
++
++void putc(char c)
++{
++ int timeout = 1024;
++
++ while (((serial_in(UART_LSR) & UART_LSR_THRE) == 0) && (timeout-- > 0))
++ ;
++
++ serial_out(UART_TX, c);
++}
+diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c
+index be711dd..cfdb4c2 100644
+--- a/arch/mips/cavium-octeon/octeon-platform.c
++++ b/arch/mips/cavium-octeon/octeon-platform.c
+@@ -159,6 +159,94 @@ out:
+ }
+ device_initcall(octeon_rng_device_init);
+
++/* Octeon SMI/MDIO interface. */
++static int __init octeon_mdiobus_device_init(void)
++{
++ struct platform_device *pd;
++ int ret = 0;
++
++ if (octeon_is_simulation())
++ return 0; /* No mdio in the simulator. */
++
++ /* The bus number is the platform_device id. */
++ pd = platform_device_alloc("mdio-octeon", 0);
++ if (!pd) {
++ ret = -ENOMEM;
++ goto out;
++ }
++
++ ret = platform_device_add(pd);
++ if (ret)
++ goto fail;
++
++ return ret;
++fail:
++ platform_device_put(pd);
++
++out:
++ return ret;
++
++}
++device_initcall(octeon_mdiobus_device_init);
++
++/* Octeon mgmt port Ethernet interface. */
++static int __init octeon_mgmt_device_init(void)
++{
++ struct platform_device *pd;
++ int ret = 0;
++ int port, num_ports;
++
++ struct resource mgmt_port_resource = {
++ .flags = IORESOURCE_IRQ,
++ .start = -1,
++ .end = -1
++ };
++
++ if (!OCTEON_IS_MODEL(OCTEON_CN56XX) && !OCTEON_IS_MODEL(OCTEON_CN52XX))
++ return 0;
++
++ if (OCTEON_IS_MODEL(OCTEON_CN56XX))
++ num_ports = 1;
++ else
++ num_ports = 2;
++
++ for (port = 0; port < num_ports; port++) {
++ pd = platform_device_alloc("octeon_mgmt", port);
++ if (!pd) {
++ ret = -ENOMEM;
++ goto out;
++ }
++ switch (port) {
++ case 0:
++ mgmt_port_resource.start = OCTEON_IRQ_MII0;
++ break;
++ case 1:
++ mgmt_port_resource.start = OCTEON_IRQ_MII1;
++ break;
++ default:
++ BUG();
++ }
++ mgmt_port_resource.end = mgmt_port_resource.start;
++
++ ret = platform_device_add_resources(pd, &mgmt_port_resource, 1);
++
++ if (ret)
++ goto fail;
++
++ ret = platform_device_add(pd);
++ if (ret)
++ goto fail;
++ }
++ return ret;
++fail:
++ platform_device_put(pd);
++
++out:
++ return ret;
++
++}
++device_initcall(octeon_mgmt_device_init);
++
+ MODULE_AUTHOR("David Daney <ddaney@caviumnetworks.com>");
+ MODULE_LICENSE("GPL");
+ MODULE_DESCRIPTION("Platform driver for Octeon SOC");
+diff --git a/arch/mips/configs/ar7_defconfig b/arch/mips/configs/ar7_defconfig
+index 3564830..2cb304a 100644
+--- a/arch/mips/configs/ar7_defconfig
++++ b/arch/mips/configs/ar7_defconfig
+@@ -265,7 +265,6 @@ CONFIG_DEFAULT_DEADLINE=y
+ # CONFIG_DEFAULT_CFQ is not set
+ # CONFIG_DEFAULT_NOOP is not set
+ CONFIG_DEFAULT_IOSCHED="deadline"
+-CONFIG_PROBE_INITRD_HEADER=y
+ # CONFIG_FREEZER is not set
+
+ #
+diff --git a/arch/mips/configs/cavium-octeon_defconfig b/arch/mips/configs/cavium-octeon_defconfig
+index 7afaa28..1819a4c 100644
+--- a/arch/mips/configs/cavium-octeon_defconfig
++++ b/arch/mips/configs/cavium-octeon_defconfig
+@@ -269,7 +269,6 @@ CONFIG_DEFAULT_CFQ=y
+ # CONFIG_DEFAULT_NOOP is not set
+ CONFIG_DEFAULT_IOSCHED="cfq"
+ CONFIG_CLASSIC_RCU=y
+-# CONFIG_PROBE_INITRD_HEADER is not set
+ # CONFIG_FREEZER is not set
+
+ #
+diff --git a/arch/mips/configs/db1200_defconfig b/arch/mips/configs/db1200_defconfig
+index d73f1de..a7ca995 100644
+--- a/arch/mips/configs/db1200_defconfig
++++ b/arch/mips/configs/db1200_defconfig
+@@ -1,79 +1,101 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.20
+-# Tue Feb 20 21:47:25 2007
++# Linux kernel version: 2.6.32-rc5
++# Mon Nov 2 21:09:28 2009
+ #
+ CONFIG_MIPS=y
+
+ #
+ # Machine selection
+ #
+-CONFIG_ZONE_DMA=y
+ CONFIG_MACH_ALCHEMY=y
+-# CONFIG_MIPS_MTX1 is not set
+-# CONFIG_MIPS_BOSPORUS is not set
+-# CONFIG_MIPS_PB1000 is not set
+-# CONFIG_MIPS_PB1100 is not set
+-# CONFIG_MIPS_PB1500 is not set
+-# CONFIG_MIPS_PB1550 is not set
+-# CONFIG_MIPS_PB1200 is not set
+-# CONFIG_MIPS_DB1000 is not set
+-# CONFIG_MIPS_DB1100 is not set
+-# CONFIG_MIPS_DB1500 is not set
+-# CONFIG_MIPS_DB1550 is not set
+-CONFIG_MIPS_DB1200=y
+-# CONFIG_MIPS_MIRAGE is not set
++# CONFIG_AR7 is not set
+ # CONFIG_BASLER_EXCITE is not set
++# CONFIG_BCM47XX is not set
++# CONFIG_BCM63XX is not set
+ # CONFIG_MIPS_COBALT is not set
+ # CONFIG_MACH_DECSTATION is not set
+ # CONFIG_MACH_JAZZ is not set
++# CONFIG_LASAT is not set
++# CONFIG_MACH_LOONGSON is not set
+ # CONFIG_MIPS_MALTA is not set
+-# CONFIG_WR_PPMC is not set
+ # CONFIG_MIPS_SIM is not set
+-# CONFIG_MOMENCO_JAGUAR_ATX is not set
+-# CONFIG_MIPS_XXS1500 is not set
++# CONFIG_NEC_MARKEINS is not set
++# CONFIG_MACH_VR41XX is not set
++# CONFIG_NXP_STB220 is not set
++# CONFIG_NXP_STB225 is not set
+ # CONFIG_PNX8550_JBS is not set
+ # CONFIG_PNX8550_STB810 is not set
+-# CONFIG_MACH_VR41XX is not set
++# CONFIG_PMC_MSP is not set
+ # CONFIG_PMC_YOSEMITE is not set
+-# CONFIG_MARKEINS is not set
+ # CONFIG_SGI_IP22 is not set
+ # CONFIG_SGI_IP27 is not set
++# CONFIG_SGI_IP28 is not set
+ # CONFIG_SGI_IP32 is not set
+-# CONFIG_SIBYTE_BIGSUR is not set
+-# CONFIG_SIBYTE_SWARM is not set
+-# CONFIG_SIBYTE_SENTOSA is not set
+-# CONFIG_SIBYTE_RHONE is not set
+-# CONFIG_SIBYTE_CARMEL is not set
+-# CONFIG_SIBYTE_LITTLESUR is not set
+ # CONFIG_SIBYTE_CRHINE is not set
++# CONFIG_SIBYTE_CARMEL is not set
+ # CONFIG_SIBYTE_CRHONE is not set
++# CONFIG_SIBYTE_RHONE is not set
++# CONFIG_SIBYTE_SWARM is not set
++# CONFIG_SIBYTE_LITTLESUR is not set
++# CONFIG_SIBYTE_SENTOSA is not set
++# CONFIG_SIBYTE_BIGSUR is not set
+ # CONFIG_SNI_RM is not set
+-# CONFIG_TOSHIBA_JMR3927 is not set
+-# CONFIG_TOSHIBA_RBTX4927 is not set
+-# CONFIG_TOSHIBA_RBTX4938 is not set
++# CONFIG_MACH_TX39XX is not set
++# CONFIG_MACH_TX49XX is not set
++# CONFIG_MIKROTIK_RB532 is not set
++# CONFIG_WR_PPMC is not set
++# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
++# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
++CONFIG_ALCHEMY_GPIO_AU1000=y
++# CONFIG_ALCHEMY_GPIO_INDIRECT is not set
++# CONFIG_MIPS_MTX1 is not set
++# CONFIG_MIPS_BOSPORUS is not set
++# CONFIG_MIPS_DB1000 is not set
++# CONFIG_MIPS_DB1100 is not set
++CONFIG_MIPS_DB1200=y
++# CONFIG_MIPS_DB1500 is not set
++# CONFIG_MIPS_DB1550 is not set
++# CONFIG_MIPS_MIRAGE is not set
++# CONFIG_MIPS_PB1000 is not set
++# CONFIG_MIPS_PB1100 is not set
++# CONFIG_MIPS_PB1200 is not set
++# CONFIG_MIPS_PB1500 is not set
++# CONFIG_MIPS_PB1550 is not set
++# CONFIG_MIPS_XXS1500 is not set
++CONFIG_SOC_AU1200=y
++CONFIG_SOC_AU1X00=y
+ CONFIG_RWSEM_GENERIC_SPINLOCK=y
+ # CONFIG_ARCH_HAS_ILOG2_U32 is not set
+ # CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_ARCH_SUPPORTS_OPROFILE=y
+ CONFIG_GENERIC_FIND_NEXT_BIT=y
+ CONFIG_GENERIC_HWEIGHT=y
+ CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_CLOCKEVENTS=y
+ CONFIG_GENERIC_TIME=y
+-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+-# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
++CONFIG_GENERIC_CMOS_UPDATE=y
++CONFIG_SCHED_OMIT_FRAME_POINTER=y
++CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
++CONFIG_CEVT_R4K_LIB=y
++CONFIG_CSRC_R4K_LIB=y
+ CONFIG_DMA_COHERENT=y
++CONFIG_EARLY_PRINTK=y
++CONFIG_SYS_HAS_EARLY_PRINTK=y
+ CONFIG_MIPS_DISABLE_OBSOLETE_IDE=y
++# CONFIG_NO_IOPORT is not set
++CONFIG_GENERIC_GPIO=y
+ # CONFIG_CPU_BIG_ENDIAN is not set
+ CONFIG_CPU_LITTLE_ENDIAN=y
+ CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+ CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+-CONFIG_SOC_AU1200=y
+-CONFIG_SOC_AU1X00=y
++CONFIG_IRQ_CPU=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+ #
+ # CPU selection
+ #
++# CONFIG_CPU_LOONGSON2E is not set
+ CONFIG_CPU_MIPS32_R1=y
+ # CONFIG_CPU_MIPS32_R2 is not set
+ # CONFIG_CPU_MIPS64_R1 is not set
+@@ -86,6 +108,7 @@ CONFIG_CPU_MIPS32_R1=y
+ # CONFIG_CPU_TX49XX is not set
+ # CONFIG_CPU_R5000 is not set
+ # CONFIG_CPU_R5432 is not set
++# CONFIG_CPU_R5500 is not set
+ # CONFIG_CPU_R6000 is not set
+ # CONFIG_CPU_NEVADA is not set
+ # CONFIG_CPU_R8000 is not set
+@@ -93,11 +116,13 @@ CONFIG_CPU_MIPS32_R1=y
+ # CONFIG_CPU_RM7000 is not set
+ # CONFIG_CPU_RM9000 is not set
+ # CONFIG_CPU_SB1 is not set
++# CONFIG_CPU_CAVIUM_OCTEON is not set
+ CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+ CONFIG_CPU_MIPS32=y
+ CONFIG_CPU_MIPSR1=y
+ CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+ CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
++CONFIG_HARDWARE_WATCHPOINTS=y
+
+ #
+ # Kernel type
+@@ -107,180 +132,204 @@ CONFIG_32BIT=y
+ CONFIG_PAGE_SIZE_4KB=y
+ # CONFIG_PAGE_SIZE_8KB is not set
+ # CONFIG_PAGE_SIZE_16KB is not set
++# CONFIG_PAGE_SIZE_32KB is not set
+ # CONFIG_PAGE_SIZE_64KB is not set
+ CONFIG_CPU_HAS_PREFETCH=y
+ CONFIG_MIPS_MT_DISABLED=y
+ # CONFIG_MIPS_MT_SMP is not set
+ # CONFIG_MIPS_MT_SMTC is not set
+-# CONFIG_MIPS_VPE_LOADER is not set
+ CONFIG_64BIT_PHYS_ADDR=y
+ CONFIG_CPU_HAS_SYNC=y
+ CONFIG_GENERIC_HARDIRQS=y
+ CONFIG_GENERIC_IRQ_PROBE=y
+ CONFIG_CPU_SUPPORTS_HIGHMEM=y
+ CONFIG_ARCH_FLATMEM_ENABLE=y
++CONFIG_ARCH_POPULATES_NODE_MAP=y
+ CONFIG_SELECT_MEMORY_MODEL=y
+ CONFIG_FLATMEM_MANUAL=y
+ # CONFIG_DISCONTIGMEM_MANUAL is not set
+ # CONFIG_SPARSEMEM_MANUAL is not set
+ CONFIG_FLATMEM=y
+ CONFIG_FLAT_NODE_MEM_MAP=y
+-# CONFIG_SPARSEMEM_STATIC is not set
++CONFIG_PAGEFLAGS_EXTENDED=y
+ CONFIG_SPLIT_PTLOCK_CPUS=4
+-# CONFIG_RESOURCES_64BIT is not set
+-CONFIG_ZONE_DMA_FLAG=1
++# CONFIG_PHYS_ADDR_T_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=0
++CONFIG_VIRT_TO_BUS=y
++CONFIG_HAVE_MLOCK=y
++CONFIG_HAVE_MLOCKED_PAGE_BIT=y
++CONFIG_KSM=y
++CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
++CONFIG_TICK_ONESHOT=y
++CONFIG_NO_HZ=y
++CONFIG_HIGH_RES_TIMERS=y
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+ # CONFIG_HZ_48 is not set
+-# CONFIG_HZ_100 is not set
++CONFIG_HZ_100=y
+ # CONFIG_HZ_128 is not set
+ # CONFIG_HZ_250 is not set
+ # CONFIG_HZ_256 is not set
+-CONFIG_HZ_1000=y
++# CONFIG_HZ_1000 is not set
+ # CONFIG_HZ_1024 is not set
+ CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
+-CONFIG_HZ=1000
++CONFIG_HZ=100
+ CONFIG_PREEMPT_NONE=y
+ # CONFIG_PREEMPT_VOLUNTARY is not set
+ # CONFIG_PREEMPT is not set
+ # CONFIG_KEXEC is not set
++# CONFIG_SECCOMP is not set
+ CONFIG_LOCKDEP_SUPPORT=y
+ CONFIG_STACKTRACE_SUPPORT=y
+ CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++CONFIG_CONSTRUCTORS=y
+
+ #
+-# Code maturity level options
++# General setup
+ #
+ CONFIG_EXPERIMENTAL=y
+ CONFIG_BROKEN_ON_SMP=y
+ CONFIG_INIT_ENV_ARG_LIMIT=32
+-
+-#
+-# General setup
+-#
+-CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION="-db1200"
+ CONFIG_LOCALVERSION_AUTO=y
+ CONFIG_SWAP=y
+ CONFIG_SYSVIPC=y
+-# CONFIG_IPC_NS is not set
+ CONFIG_SYSVIPC_SYSCTL=y
+-# CONFIG_POSIX_MQUEUE is not set
++CONFIG_POSIX_MQUEUE=y
++CONFIG_POSIX_MQUEUE_SYSCTL=y
+ # CONFIG_BSD_PROCESS_ACCT is not set
+ # CONFIG_TASKSTATS is not set
+-# CONFIG_UTS_NS is not set
+ # CONFIG_AUDIT is not set
+-CONFIG_IKCONFIG=y
+-CONFIG_IKCONFIG_PROC=y
+-CONFIG_SYSFS_DEPRECATED=y
++
++#
++# RCU Subsystem
++#
++CONFIG_TREE_RCU=y
++# CONFIG_TREE_PREEMPT_RCU is not set
++# CONFIG_RCU_TRACE is not set
++CONFIG_RCU_FANOUT=32
++CONFIG_RCU_FANOUT_EXACT=y
++# CONFIG_TREE_RCU_TRACE is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_LOG_BUF_SHIFT=18
++# CONFIG_GROUP_SCHED is not set
++# CONFIG_CGROUPS is not set
++# CONFIG_SYSFS_DEPRECATED_V2 is not set
+ # CONFIG_RELAY is not set
+-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
++# CONFIG_NAMESPACES is not set
++# CONFIG_BLK_DEV_INITRD is not set
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+ CONFIG_SYSCTL=y
++CONFIG_ANON_INODES=y
+ CONFIG_EMBEDDED=y
+-CONFIG_SYSCTL_SYSCALL=y
+-CONFIG_KALLSYMS=y
+-# CONFIG_KALLSYMS_EXTRA_PASS is not set
++# CONFIG_SYSCTL_SYSCALL is not set
++# CONFIG_KALLSYMS is not set
+ CONFIG_HOTPLUG=y
+ CONFIG_PRINTK=y
+ CONFIG_BUG=y
+ CONFIG_ELF_CORE=y
++# CONFIG_PCSPKR_PLATFORM is not set
+ CONFIG_BASE_FULL=y
+ CONFIG_FUTEX=y
+ CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
+ CONFIG_SHMEM=y
+-CONFIG_SLAB=y
+-CONFIG_VM_EVENT_COUNTERS=y
+-CONFIG_RT_MUTEXES=y
+-# CONFIG_TINY_SHMEM is not set
+-CONFIG_BASE_SMALL=0
++CONFIG_AIO=y
++
++#
++# Kernel Performance Events And Counters
++#
++# CONFIG_VM_EVENT_COUNTERS is not set
++# CONFIG_SLUB_DEBUG is not set
++# CONFIG_COMPAT_BRK is not set
++# CONFIG_SLAB is not set
++CONFIG_SLUB=y
+ # CONFIG_SLOB is not set
++# CONFIG_PROFILING is not set
++CONFIG_HAVE_OPROFILE=y
+
+ #
+-# Loadable module support
++# GCOV-based kernel profiling
+ #
++# CONFIG_SLOW_WORK is not set
++# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
++CONFIG_RT_MUTEXES=y
++CONFIG_BASE_SMALL=0
+ CONFIG_MODULES=y
++# CONFIG_MODULE_FORCE_LOAD is not set
+ CONFIG_MODULE_UNLOAD=y
+ # CONFIG_MODULE_FORCE_UNLOAD is not set
+-CONFIG_MODVERSIONS=y
+-CONFIG_MODULE_SRCVERSION_ALL=y
+-CONFIG_KMOD=y
+-
+-#
+-# Block layer
+-#
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
+ CONFIG_BLOCK=y
+-# CONFIG_LBD is not set
+-# CONFIG_BLK_DEV_IO_TRACE is not set
+-# CONFIG_LSF is not set
++# CONFIG_LBDAF is not set
++# CONFIG_BLK_DEV_BSG is not set
++# CONFIG_BLK_DEV_INTEGRITY is not set
+
+ #
+ # IO Schedulers
+ #
+ CONFIG_IOSCHED_NOOP=y
+-CONFIG_IOSCHED_AS=y
+-CONFIG_IOSCHED_DEADLINE=y
+-CONFIG_IOSCHED_CFQ=y
+-CONFIG_DEFAULT_AS=y
++# CONFIG_IOSCHED_AS is not set
++# CONFIG_IOSCHED_DEADLINE is not set
++# CONFIG_IOSCHED_CFQ is not set
++# CONFIG_DEFAULT_AS is not set
+ # CONFIG_DEFAULT_DEADLINE is not set
+ # CONFIG_DEFAULT_CFQ is not set
+-# CONFIG_DEFAULT_NOOP is not set
+-CONFIG_DEFAULT_IOSCHED="anticipatory"
++CONFIG_DEFAULT_NOOP=y
++CONFIG_DEFAULT_IOSCHED="noop"
++# CONFIG_FREEZER is not set
+
+ #
+ # Bus options (PCI, PCMCIA, EISA, ISA, TC)
+ #
++# CONFIG_ARCH_SUPPORTS_MSI is not set
+ CONFIG_MMU=y
+-
+-#
+-# PCCARD (PCMCIA/CardBus) support
+-#
+-CONFIG_PCCARD=m
++CONFIG_PCCARD=y
+ # CONFIG_PCMCIA_DEBUG is not set
+-CONFIG_PCMCIA=m
++CONFIG_PCMCIA=y
+ CONFIG_PCMCIA_LOAD_CIS=y
+-CONFIG_PCMCIA_IOCTL=y
++# CONFIG_PCMCIA_IOCTL is not set
+
+ #
+ # PC-card bridges
+ #
+-CONFIG_PCMCIA_AU1X00=m
+-
+-#
+-# PCI Hotplug Support
+-#
++# CONFIG_PCMCIA_AU1X00 is not set
++CONFIG_PCMCIA_ALCHEMY_DEVBOARD=y
+
+ #
+ # Executable file formats
+ #
+ CONFIG_BINFMT_ELF=y
+-# CONFIG_BINFMT_MISC is not set
++CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
++# CONFIG_HAVE_AOUT is not set
++CONFIG_BINFMT_MISC=y
+ CONFIG_TRAD_SIGNALS=y
+
+ #
+ # Power management options
+ #
++CONFIG_ARCH_HIBERNATION_POSSIBLE=y
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
+ # CONFIG_PM is not set
+-
+-#
+-# Networking
+-#
+ CONFIG_NET=y
+
+ #
+ # Networking options
+ #
+-# CONFIG_NETDEBUG is not set
+ CONFIG_PACKET=y
+-# CONFIG_PACKET_MMAP is not set
++CONFIG_PACKET_MMAP=y
+ CONFIG_UNIX=y
+-CONFIG_XFRM=y
+-CONFIG_XFRM_USER=m
+-# CONFIG_XFRM_SUB_POLICY is not set
+-CONFIG_XFRM_MIGRATE=y
+-CONFIG_NET_KEY=y
+-CONFIG_NET_KEY_MIGRATE=y
++# CONFIG_NET_KEY is not set
+ CONFIG_INET=y
+ CONFIG_IP_MULTICAST=y
+ # CONFIG_IP_ADVANCED_ROUTER is not set
+ CONFIG_IP_FIB_HASH=y
+-# CONFIG_IP_PNP is not set
++CONFIG_IP_PNP=y
++# CONFIG_IP_PNP_DHCP is not set
++# CONFIG_IP_PNP_BOOTP is not set
++# CONFIG_IP_PNP_RARP is not set
+ # CONFIG_NET_IPIP is not set
+ # CONFIG_NET_IPGRE is not set
+ # CONFIG_IP_MROUTE is not set
+@@ -291,107 +340,25 @@ CONFIG_IP_FIB_HASH=y
+ # CONFIG_INET_IPCOMP is not set
+ # CONFIG_INET_XFRM_TUNNEL is not set
+ # CONFIG_INET_TUNNEL is not set
+-CONFIG_INET_XFRM_MODE_TRANSPORT=m
+-CONFIG_INET_XFRM_MODE_TUNNEL=m
+-CONFIG_INET_XFRM_MODE_BEET=m
+-CONFIG_INET_DIAG=y
+-CONFIG_INET_TCP_DIAG=y
++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
++# CONFIG_INET_XFRM_MODE_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_BEET is not set
++# CONFIG_INET_LRO is not set
++# CONFIG_INET_DIAG is not set
+ # CONFIG_TCP_CONG_ADVANCED is not set
+ CONFIG_TCP_CONG_CUBIC=y
+ CONFIG_DEFAULT_TCP_CONG="cubic"
+-CONFIG_TCP_MD5SIG=y
+-
+-#
+-# IP: Virtual Server Configuration
+-#
+-# CONFIG_IP_VS is not set
++# CONFIG_TCP_MD5SIG is not set
+ # CONFIG_IPV6 is not set
+-# CONFIG_INET6_XFRM_TUNNEL is not set
+-# CONFIG_INET6_TUNNEL is not set
+-CONFIG_NETWORK_SECMARK=y
+-CONFIG_NETFILTER=y
+-# CONFIG_NETFILTER_DEBUG is not set
+-
+-#
+-# Core Netfilter Configuration
+-#
+-# CONFIG_NETFILTER_NETLINK is not set
+-CONFIG_NF_CONNTRACK_ENABLED=m
+-CONFIG_NF_CONNTRACK_SUPPORT=y
+-# CONFIG_IP_NF_CONNTRACK_SUPPORT is not set
+-CONFIG_NF_CONNTRACK=m
+-CONFIG_NF_CT_ACCT=y
+-CONFIG_NF_CONNTRACK_MARK=y
+-CONFIG_NF_CONNTRACK_SECMARK=y
+-CONFIG_NF_CONNTRACK_EVENTS=y
+-CONFIG_NF_CT_PROTO_GRE=m
+-CONFIG_NF_CT_PROTO_SCTP=m
+-CONFIG_NF_CONNTRACK_AMANDA=m
+-CONFIG_NF_CONNTRACK_FTP=m
+-CONFIG_NF_CONNTRACK_H323=m
+-CONFIG_NF_CONNTRACK_IRC=m
+-# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set
+-CONFIG_NF_CONNTRACK_PPTP=m
+-CONFIG_NF_CONNTRACK_SANE=m
+-CONFIG_NF_CONNTRACK_SIP=m
+-CONFIG_NF_CONNTRACK_TFTP=m
+-CONFIG_NETFILTER_XTABLES=m
+-CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+-CONFIG_NETFILTER_XT_TARGET_MARK=m
+-CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+-CONFIG_NETFILTER_XT_TARGET_NFLOG=m
+-CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+-CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
+-CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
+-CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+-CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+-CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+-CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+-CONFIG_NETFILTER_XT_MATCH_DCCP=m
+-CONFIG_NETFILTER_XT_MATCH_DSCP=m
+-CONFIG_NETFILTER_XT_MATCH_ESP=m
+-CONFIG_NETFILTER_XT_MATCH_HELPER=m
+-CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+-CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+-CONFIG_NETFILTER_XT_MATCH_MAC=m
+-CONFIG_NETFILTER_XT_MATCH_MARK=m
+-CONFIG_NETFILTER_XT_MATCH_POLICY=m
+-CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+-CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+-CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+-CONFIG_NETFILTER_XT_MATCH_REALM=m
+-CONFIG_NETFILTER_XT_MATCH_SCTP=m
+-CONFIG_NETFILTER_XT_MATCH_STATE=m
+-CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+-CONFIG_NETFILTER_XT_MATCH_STRING=m
+-CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+-CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
+-
+-#
+-# IP: Netfilter Configuration
+-#
+-CONFIG_NF_CONNTRACK_IPV4=m
+-CONFIG_NF_CONNTRACK_PROC_COMPAT=y
+-# CONFIG_IP_NF_QUEUE is not set
+-# CONFIG_IP_NF_IPTABLES is not set
+-# CONFIG_IP_NF_ARPTABLES is not set
+-
+-#
+-# DCCP Configuration (EXPERIMENTAL)
+-#
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
+ # CONFIG_IP_DCCP is not set
+-
+-#
+-# SCTP Configuration (EXPERIMENTAL)
+-#
+ # CONFIG_IP_SCTP is not set
+-
+-#
+-# TIPC Configuration (EXPERIMENTAL)
+-#
++# CONFIG_RDS is not set
+ # CONFIG_TIPC is not set
+ # CONFIG_ATM is not set
+ # CONFIG_BRIDGE is not set
++# CONFIG_NET_DSA is not set
+ # CONFIG_VLAN_8021Q is not set
+ # CONFIG_DECNET is not set
+ # CONFIG_LLC2 is not set
+@@ -401,21 +368,26 @@ CONFIG_NF_CONNTRACK_PROC_COMPAT=y
+ # CONFIG_LAPB is not set
+ # CONFIG_ECONET is not set
+ # CONFIG_WAN_ROUTER is not set
+-
+-#
+-# QoS and/or fair queueing
+-#
++# CONFIG_PHONET is not set
++# CONFIG_IEEE802154 is not set
+ # CONFIG_NET_SCHED is not set
+-CONFIG_NET_CLS_ROUTE=y
++# CONFIG_DCB is not set
+
+ #
+ # Network testing
+ #
+ # CONFIG_NET_PKTGEN is not set
+ # CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
+ # CONFIG_IRDA is not set
+ # CONFIG_BT is not set
+-# CONFIG_IEEE80211 is not set
++# CONFIG_AF_RXRPC is not set
++# CONFIG_WIRELESS is not set
++# CONFIG_MAC80211_RC_DEFAULT_PID is not set
++# CONFIG_MAC80211_RC_DEFAULT_MINSTREL is not set
++# CONFIG_WIMAX is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
+
+ #
+ # Device Drivers
+@@ -424,25 +396,23 @@ CONFIG_NET_CLS_ROUTE=y
+ #
+ # Generic Driver Options
+ #
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++# CONFIG_DEVTMPFS is not set
+ CONFIG_STANDALONE=y
+ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ CONFIG_FW_LOADER=y
++CONFIG_FIRMWARE_IN_KERNEL=y
++CONFIG_EXTRA_FIRMWARE=""
+ # CONFIG_SYS_HYPERVISOR is not set
+-
+-#
+-# Connector - unified userspace <-> kernelspace linker
+-#
+ # CONFIG_CONNECTOR is not set
+-
+-#
+-# Memory Technology Devices (MTD)
+-#
+ CONFIG_MTD=y
+ # CONFIG_MTD_DEBUG is not set
++# CONFIG_MTD_TESTS is not set
+ # CONFIG_MTD_CONCAT is not set
+ CONFIG_MTD_PARTITIONS=y
+ # CONFIG_MTD_REDBOOT_PARTS is not set
+-# CONFIG_MTD_CMDLINE_PARTS is not set
++CONFIG_MTD_CMDLINE_PARTS=y
++# CONFIG_MTD_AR7_PARTS is not set
+
+ #
+ # User Modules And Translation Layers
+@@ -455,6 +425,7 @@ CONFIG_MTD_BLOCK=y
+ # CONFIG_INFTL is not set
+ # CONFIG_RFD_FTL is not set
+ # CONFIG_SSFDC is not set
++# CONFIG_MTD_OOPS is not set
+
+ #
+ # RAM/ROM/Flash chip drivers
+@@ -463,6 +434,9 @@ CONFIG_MTD_CFI=y
+ # CONFIG_MTD_JEDECPROBE is not set
+ CONFIG_MTD_GEN_PROBE=y
+ # CONFIG_MTD_CFI_ADV_OPTIONS is not set
++# CONFIG_MTD_CFI_NOSWAP is not set
++# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+ CONFIG_MTD_MAP_BANK_WIDTH_1=y
+ CONFIG_MTD_MAP_BANK_WIDTH_2=y
+ CONFIG_MTD_MAP_BANK_WIDTH_4=y
+@@ -480,19 +454,21 @@ CONFIG_MTD_CFI_UTIL=y
+ # CONFIG_MTD_RAM is not set
+ # CONFIG_MTD_ROM is not set
+ # CONFIG_MTD_ABSENT is not set
+-# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+ #
+ # Mapping drivers for chip access
+ #
+ # CONFIG_MTD_COMPLEX_MAPPINGS is not set
+-# CONFIG_MTD_PHYSMAP is not set
+-CONFIG_MTD_ALCHEMY=y
++CONFIG_MTD_PHYSMAP=y
++# CONFIG_MTD_PHYSMAP_COMPAT is not set
+ # CONFIG_MTD_PLATRAM is not set
+
+ #
+ # Self-contained MTD device drivers
+ #
++# CONFIG_MTD_DATAFLASH is not set
++# CONFIG_MTD_M25P80 is not set
++# CONFIG_MTD_SST25L is not set
+ # CONFIG_MTD_SLRAM is not set
+ # CONFIG_MTD_PHRAM is not set
+ # CONFIG_MTD_MTDRAM is not set
+@@ -504,224 +480,129 @@ CONFIG_MTD_ALCHEMY=y
+ # CONFIG_MTD_DOC2000 is not set
+ # CONFIG_MTD_DOC2001 is not set
+ # CONFIG_MTD_DOC2001PLUS is not set
+-
+-#
+-# NAND Flash Device Drivers
+-#
+ CONFIG_MTD_NAND=y
+ # CONFIG_MTD_NAND_VERIFY_WRITE is not set
+ # CONFIG_MTD_NAND_ECC_SMC is not set
++# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+ CONFIG_MTD_NAND_IDS=y
+ # CONFIG_MTD_NAND_AU1550 is not set
+ # CONFIG_MTD_NAND_DISKONCHIP is not set
+ # CONFIG_MTD_NAND_NANDSIM is not set
+-
+-#
+-# OneNAND Flash Device Drivers
+-#
++CONFIG_MTD_NAND_PLATFORM=y
++# CONFIG_MTD_ALAUDA is not set
+ # CONFIG_MTD_ONENAND is not set
+
+ #
+-# Parallel port support
+-#
+-# CONFIG_PARPORT is not set
+-
+-#
+-# Plug and Play support
++# LPDDR flash memory drivers
+ #
+-# CONFIG_PNPACPI is not set
++# CONFIG_MTD_LPDDR is not set
+
+ #
+-# Block devices
++# UBI - Unsorted block images
+ #
++# CONFIG_MTD_UBI is not set
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
+ # CONFIG_BLK_DEV_COW_COMMON is not set
+ CONFIG_BLK_DEV_LOOP=y
+ # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+ # CONFIG_BLK_DEV_NBD is not set
+-CONFIG_BLK_DEV_RAM=y
+-CONFIG_BLK_DEV_RAM_COUNT=16
+-CONFIG_BLK_DEV_RAM_SIZE=4096
+-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+-# CONFIG_BLK_DEV_INITRD is not set
++CONFIG_BLK_DEV_UB=y
++# CONFIG_BLK_DEV_RAM is not set
+ # CONFIG_CDROM_PKTCDVD is not set
+ # CONFIG_ATA_OVER_ETH is not set
+-
+-#
+-# Misc devices
+-#
+-
+-#
+-# ATA/ATAPI/MFM/RLL support
+-#
++# CONFIG_BLK_DEV_HD is not set
++# CONFIG_MISC_DEVICES is not set
++CONFIG_HAVE_IDE=y
+ CONFIG_IDE=y
+-CONFIG_IDE_MAX_HWIFS=4
+-CONFIG_BLK_DEV_IDE=y
+
+ #
+-# Please see Documentation/ide.txt for help/info on IDE drives
++# Please see Documentation/ide/ide.txt for help/info on IDE drives
+ #
++CONFIG_IDE_XFER_MODE=y
++CONFIG_IDE_ATAPI=y
+ # CONFIG_BLK_DEV_IDE_SATA is not set
+-CONFIG_BLK_DEV_IDEDISK=y
+-CONFIG_IDEDISK_MULTI_MODE=y
+-CONFIG_BLK_DEV_IDECS=m
+-# CONFIG_BLK_DEV_IDECD is not set
++CONFIG_IDE_GD=y
++CONFIG_IDE_GD_ATA=y
++# CONFIG_IDE_GD_ATAPI is not set
++CONFIG_BLK_DEV_IDECS=y
++CONFIG_BLK_DEV_IDECD=y
++CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y
+ # CONFIG_BLK_DEV_IDETAPE is not set
+-# CONFIG_BLK_DEV_IDEFLOPPY is not set
+-# CONFIG_BLK_DEV_IDESCSI is not set
+-# CONFIG_IDE_TASK_IOCTL is not set
++CONFIG_IDE_TASK_IOCTL=y
++# CONFIG_IDE_PROC_FS is not set
+
+ #
+ # IDE chipset support/bugfixes
+ #
+-CONFIG_IDE_GENERIC=y
++# CONFIG_IDE_GENERIC is not set
++# CONFIG_BLK_DEV_PLATFORM is not set
+ CONFIG_BLK_DEV_IDE_AU1XXX=y
+ CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA=y
+ # CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA is not set
+-CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ=128
+-# CONFIG_IDE_ARM is not set
+ # CONFIG_BLK_DEV_IDEDMA is not set
+-# CONFIG_IDEDMA_AUTO is not set
+-# CONFIG_BLK_DEV_HD is not set
+
+ #
+ # SCSI device support
+ #
+ # CONFIG_RAID_ATTRS is not set
+-CONFIG_SCSI=y
+-CONFIG_SCSI_TGT=m
++# CONFIG_SCSI is not set
++# CONFIG_SCSI_DMA is not set
+ # CONFIG_SCSI_NETLINK is not set
+-CONFIG_SCSI_PROC_FS=y
+-
+-#
+-# SCSI support type (disk, tape, CD-ROM)
+-#
+-CONFIG_BLK_DEV_SD=y
+-# CONFIG_CHR_DEV_ST is not set
+-# CONFIG_CHR_DEV_OSST is not set
+-CONFIG_BLK_DEV_SR=y
+-# CONFIG_BLK_DEV_SR_VENDOR is not set
+-CONFIG_CHR_DEV_SG=y
+-# CONFIG_CHR_DEV_SCH is not set
+-
+-#
+-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+-#
+-CONFIG_SCSI_MULTI_LUN=y
+-# CONFIG_SCSI_CONSTANTS is not set
+-# CONFIG_SCSI_LOGGING is not set
+-CONFIG_SCSI_SCAN_ASYNC=y
+-
+-#
+-# SCSI Transports
+-#
+-# CONFIG_SCSI_SPI_ATTRS is not set
+-# CONFIG_SCSI_FC_ATTRS is not set
+-# CONFIG_SCSI_ISCSI_ATTRS is not set
+-# CONFIG_SCSI_SAS_ATTRS is not set
+-# CONFIG_SCSI_SAS_LIBSAS is not set
+-
+-#
+-# SCSI low-level drivers
+-#
+-# CONFIG_ISCSI_TCP is not set
+-# CONFIG_SCSI_DEBUG is not set
+-
+-#
+-# PCMCIA SCSI adapter support
+-#
+-# CONFIG_PCMCIA_AHA152X is not set
+-# CONFIG_PCMCIA_FDOMAIN is not set
+-# CONFIG_PCMCIA_NINJA_SCSI is not set
+-# CONFIG_PCMCIA_QLOGIC is not set
+-# CONFIG_PCMCIA_SYM53C500 is not set
+-
+-#
+-# Serial ATA (prod) and Parallel ATA (experimental) drivers
+-#
+ # CONFIG_ATA is not set
+-
+-#
+-# Multi-device support (RAID and LVM)
+-#
+ # CONFIG_MD is not set
+-
+-#
+-# Fusion MPT device support
+-#
+-# CONFIG_FUSION is not set
+-
+-#
+-# IEEE 1394 (FireWire) support
+-#
+-
+-#
+-# I2O device support
+-#
+-
+-#
+-# Network device support
+-#
+ CONFIG_NETDEVICES=y
+ # CONFIG_DUMMY is not set
+ # CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
+ # CONFIG_EQUALIZER is not set
+ # CONFIG_TUN is not set
+-
+-#
+-# PHY device support
+-#
++# CONFIG_VETH is not set
+ # CONFIG_PHYLIB is not set
+-
+-#
+-# Ethernet (10 or 100Mbit)
+-#
+ CONFIG_NET_ETHERNET=y
+-CONFIG_MII=m
++CONFIG_MII=y
++# CONFIG_AX88796 is not set
+ # CONFIG_MIPS_AU1X00_ENET is not set
+-# CONFIG_SMC91X is not set
++CONFIG_SMC91X=y
+ # CONFIG_DM9000 is not set
+-
+-#
+-# Ethernet (1000 Mbit)
+-#
+-
+-#
+-# Ethernet (10000 Mbit)
+-#
+-
+-#
+-# Token Ring devices
+-#
+-
+-#
+-# Wireless LAN (non-hamradio)
+-#
+-# CONFIG_NET_RADIO is not set
+-
+-#
+-# PCMCIA network device support
+-#
++# CONFIG_ENC28J60 is not set
++# CONFIG_ETHOC is not set
++# CONFIG_DNET is not set
++# CONFIG_IBM_NEW_EMAC_ZMII is not set
++# CONFIG_IBM_NEW_EMAC_RGMII is not set
++# CONFIG_IBM_NEW_EMAC_TAH is not set
++# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
++# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
++# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
++# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
++# CONFIG_B44 is not set
++# CONFIG_KS8842 is not set
++# CONFIG_KS8851 is not set
++# CONFIG_KS8851_MLL is not set
++# CONFIG_NETDEV_1000 is not set
++# CONFIG_NETDEV_10000 is not set
++# CONFIG_WLAN is not set
++
++#
++# Enable WiMAX (Networking options) to see the WiMAX drivers
++#
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_USBNET is not set
+ # CONFIG_NET_PCMCIA is not set
+-
+-#
+-# Wan interfaces
+-#
+ # CONFIG_WAN is not set
+ # CONFIG_PPP is not set
+ # CONFIG_SLIP is not set
+-# CONFIG_SHAPER is not set
+ # CONFIG_NETCONSOLE is not set
+ # CONFIG_NETPOLL is not set
+ # CONFIG_NET_POLL_CONTROLLER is not set
+-
+-#
+-# ISDN subsystem
+-#
+ # CONFIG_ISDN is not set
+-
+-#
+-# Telephony Support
+-#
+ # CONFIG_PHONE is not set
+
+ #
+@@ -729,16 +610,16 @@ CONFIG_MII=m
+ #
+ CONFIG_INPUT=y
+ # CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
+
+ #
+ # Userland interfaces
+ #
+ CONFIG_INPUT_MOUSEDEV=y
+-CONFIG_INPUT_MOUSEDEV_PSAUX=y
++# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+ CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+ # CONFIG_INPUT_JOYDEV is not set
+-# CONFIG_INPUT_TSDEV is not set
+ CONFIG_INPUT_EVDEV=y
+ # CONFIG_INPUT_EVBUG is not set
+
+@@ -748,28 +629,26 @@ CONFIG_INPUT_EVDEV=y
+ # CONFIG_INPUT_KEYBOARD is not set
+ # CONFIG_INPUT_MOUSE is not set
+ # CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
+ # CONFIG_INPUT_TOUCHSCREEN is not set
+ # CONFIG_INPUT_MISC is not set
+
+ #
+ # Hardware I/O ports
+ #
+-CONFIG_SERIO=y
+-# CONFIG_SERIO_I8042 is not set
+-CONFIG_SERIO_SERPORT=y
+-# CONFIG_SERIO_LIBPS2 is not set
+-CONFIG_SERIO_RAW=y
++# CONFIG_SERIO is not set
+ # CONFIG_GAMEPORT is not set
+
+ #
+ # Character devices
+ #
+ CONFIG_VT=y
++CONFIG_CONSOLE_TRANSLATIONS=y
+ CONFIG_VT_CONSOLE=y
+ CONFIG_HW_CONSOLE=y
+ CONFIG_VT_HW_CONSOLE_BINDING=y
++CONFIG_DEVKMEM=y
+ # CONFIG_SERIAL_NONSTANDARD is not set
+-# CONFIG_AU1X00_GPIO is not set
+
+ #
+ # Serial drivers
+@@ -777,33 +656,22 @@ CONFIG_VT_HW_CONSOLE_BINDING=y
+ CONFIG_SERIAL_8250=y
+ CONFIG_SERIAL_8250_CONSOLE=y
+ # CONFIG_SERIAL_8250_CS is not set
+-CONFIG_SERIAL_8250_NR_UARTS=4
+-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
++CONFIG_SERIAL_8250_NR_UARTS=2
++CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+ # CONFIG_SERIAL_8250_EXTENDED is not set
+ CONFIG_SERIAL_8250_AU1X00=y
+
+ #
+ # Non-8250 serial port support
+ #
++# CONFIG_SERIAL_MAX3100 is not set
+ CONFIG_SERIAL_CORE=y
+ CONFIG_SERIAL_CORE_CONSOLE=y
+ CONFIG_UNIX98_PTYS=y
+-CONFIG_LEGACY_PTYS=y
+-CONFIG_LEGACY_PTY_COUNT=256
+-
+-#
+-# IPMI
+-#
++# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
++# CONFIG_LEGACY_PTYS is not set
+ # CONFIG_IPMI_HANDLER is not set
+-
+-#
+-# Watchdog Cards
+-#
+-# CONFIG_WATCHDOG is not set
+ # CONFIG_HW_RANDOM is not set
+-# CONFIG_RTC is not set
+-# CONFIG_GEN_RTC is not set
+-# CONFIG_DTLK is not set
+ # CONFIG_R3964 is not set
+
+ #
+@@ -812,225 +680,606 @@ CONFIG_LEGACY_PTY_COUNT=256
+ # CONFIG_SYNCLINK_CS is not set
+ # CONFIG_CARDMAN_4000 is not set
+ # CONFIG_CARDMAN_4040 is not set
++# CONFIG_IPWIRELESS is not set
+ # CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++# CONFIG_I2C_COMPAT is not set
++CONFIG_I2C_CHARDEV=y
++# CONFIG_I2C_HELPER_AUTO is not set
+
+ #
+-# TPM devices
++# I2C Algorithms
+ #
+-# CONFIG_TCG_TPM is not set
++# CONFIG_I2C_ALGOBIT is not set
++# CONFIG_I2C_ALGOPCF is not set
++# CONFIG_I2C_ALGOPCA is not set
+
+ #
+-# I2C support
++# I2C Hardware Bus support
+ #
+-# CONFIG_I2C is not set
+
+ #
+-# SPI support
++# I2C system bus drivers (mostly embedded / system-on-chip)
+ #
+-# CONFIG_SPI is not set
+-# CONFIG_SPI_MASTER is not set
++CONFIG_I2C_AU1550=y
++# CONFIG_I2C_GPIO is not set
++# CONFIG_I2C_OCORES is not set
++# CONFIG_I2C_SIMTEC is not set
+
+ #
+-# Dallas's 1-wire bus
++# External I2C/SMBus adapter drivers
++#
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_TAOS_EVM is not set
++# CONFIG_I2C_TINY_USB is not set
++
++#
++# Other I2C/SMBus bus drivers
++#
++# CONFIG_I2C_PCA_PLATFORM is not set
++# CONFIG_I2C_STUB is not set
++
++#
++# Miscellaneous I2C Chip support
++#
++# CONFIG_DS1682 is not set
++# CONFIG_SENSORS_TSL2550 is not set
++# CONFIG_I2C_DEBUG_CORE is not set
++# CONFIG_I2C_DEBUG_ALGO is not set
++# CONFIG_I2C_DEBUG_BUS is not set
++# CONFIG_I2C_DEBUG_CHIP is not set
++CONFIG_SPI=y
++CONFIG_SPI_MASTER=y
++
++#
++# SPI Master Controller Drivers
++#
++CONFIG_SPI_AU1550=y
++CONFIG_SPI_BITBANG=y
++# CONFIG_SPI_GPIO is not set
++
++#
++# SPI Protocol Masters
++#
++# CONFIG_SPI_SPIDEV is not set
++# CONFIG_SPI_TLE62X0 is not set
++
++#
++# PPS support
++#
++# CONFIG_PPS is not set
++CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
++CONFIG_GPIOLIB=y
++CONFIG_GPIO_SYSFS=y
++
++#
++# Memory mapped GPIO expanders:
+ #
+-# CONFIG_W1 is not set
+
+ #
+-# Hardware Monitoring support
++# I2C GPIO expanders:
+ #
+-# CONFIG_HWMON is not set
+-# CONFIG_HWMON_VID is not set
++# CONFIG_GPIO_MAX732X is not set
++# CONFIG_GPIO_PCA953X is not set
++# CONFIG_GPIO_PCF857X is not set
+
+ #
+-# Multimedia devices
++# PCI GPIO expanders:
+ #
+-# CONFIG_VIDEO_DEV is not set
+
+ #
+-# Digital Video Broadcasting Devices
++# SPI GPIO expanders:
+ #
+-# CONFIG_DVB is not set
++# CONFIG_GPIO_MAX7301 is not set
++# CONFIG_GPIO_MCP23S08 is not set
++# CONFIG_GPIO_MC33880 is not set
++
++#
++# AC97 GPIO expanders:
++#
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++CONFIG_HWMON=y
++CONFIG_HWMON_VID=y
++# CONFIG_HWMON_DEBUG_CHIP is not set
++
++#
++# Native drivers
++#
++# CONFIG_SENSORS_AD7414 is not set
++# CONFIG_SENSORS_AD7418 is not set
++# CONFIG_SENSORS_ADCXX is not set
++# CONFIG_SENSORS_ADM1021 is not set
++CONFIG_SENSORS_ADM1025=y
++# CONFIG_SENSORS_ADM1026 is not set
++# CONFIG_SENSORS_ADM1029 is not set
++# CONFIG_SENSORS_ADM1031 is not set
++# CONFIG_SENSORS_ADM9240 is not set
++# CONFIG_SENSORS_ADT7462 is not set
++# CONFIG_SENSORS_ADT7470 is not set
++# CONFIG_SENSORS_ADT7473 is not set
++# CONFIG_SENSORS_ADT7475 is not set
++# CONFIG_SENSORS_ATXP1 is not set
++# CONFIG_SENSORS_DS1621 is not set
++# CONFIG_SENSORS_F71805F is not set
++# CONFIG_SENSORS_F71882FG is not set
++# CONFIG_SENSORS_F75375S is not set
++# CONFIG_SENSORS_G760A is not set
++# CONFIG_SENSORS_GL518SM is not set
++# CONFIG_SENSORS_GL520SM is not set
++# CONFIG_SENSORS_IT87 is not set
++# CONFIG_SENSORS_LM63 is not set
++CONFIG_SENSORS_LM70=y
++# CONFIG_SENSORS_LM75 is not set
++# CONFIG_SENSORS_LM77 is not set
++# CONFIG_SENSORS_LM78 is not set
++# CONFIG_SENSORS_LM80 is not set
++# CONFIG_SENSORS_LM83 is not set
++# CONFIG_SENSORS_LM85 is not set
++# CONFIG_SENSORS_LM87 is not set
++# CONFIG_SENSORS_LM90 is not set
++# CONFIG_SENSORS_LM92 is not set
++# CONFIG_SENSORS_LM93 is not set
++# CONFIG_SENSORS_LTC4215 is not set
++# CONFIG_SENSORS_LTC4245 is not set
++# CONFIG_SENSORS_LM95241 is not set
++# CONFIG_SENSORS_MAX1111 is not set
++# CONFIG_SENSORS_MAX1619 is not set
++# CONFIG_SENSORS_MAX6650 is not set
++# CONFIG_SENSORS_PC87360 is not set
++# CONFIG_SENSORS_PC87427 is not set
++# CONFIG_SENSORS_PCF8591 is not set
++# CONFIG_SENSORS_SHT15 is not set
++# CONFIG_SENSORS_DME1737 is not set
++# CONFIG_SENSORS_SMSC47M1 is not set
++# CONFIG_SENSORS_SMSC47M192 is not set
++# CONFIG_SENSORS_SMSC47B397 is not set
++# CONFIG_SENSORS_ADS7828 is not set
++# CONFIG_SENSORS_THMC50 is not set
++# CONFIG_SENSORS_TMP401 is not set
++# CONFIG_SENSORS_TMP421 is not set
++# CONFIG_SENSORS_VT1211 is not set
++# CONFIG_SENSORS_W83781D is not set
++# CONFIG_SENSORS_W83791D is not set
++# CONFIG_SENSORS_W83792D is not set
++# CONFIG_SENSORS_W83793 is not set
++# CONFIG_SENSORS_W83L785TS is not set
++# CONFIG_SENSORS_W83L786NG is not set
++# CONFIG_SENSORS_W83627HF is not set
++# CONFIG_SENSORS_W83627EHF is not set
++# CONFIG_SENSORS_LIS3_SPI is not set
++# CONFIG_THERMAL is not set
++# CONFIG_WATCHDOG is not set
++CONFIG_SSB_POSSIBLE=y
++
++#
++# Sonics Silicon Backplane
++#
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_CORE is not set
++# CONFIG_MFD_SM501 is not set
++# CONFIG_HTC_PASIC3 is not set
++# CONFIG_UCB1400_CORE is not set
++# CONFIG_TPS65010 is not set
++# CONFIG_TWL4030_CORE is not set
++# CONFIG_MFD_TMIO is not set
++# CONFIG_PMIC_DA903X is not set
++# CONFIG_MFD_WM8400 is not set
++# CONFIG_MFD_WM831X is not set
++# CONFIG_MFD_WM8350_I2C is not set
++# CONFIG_MFD_PCF50633 is not set
++# CONFIG_MFD_MC13783 is not set
++# CONFIG_AB3100_CORE is not set
++# CONFIG_EZX_PCAP is not set
++# CONFIG_REGULATOR is not set
++# CONFIG_MEDIA_SUPPORT is not set
+
+ #
+ # Graphics support
+ #
+-# CONFIG_FIRMWARE_EDID is not set
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+ CONFIG_FB=y
++# CONFIG_FIRMWARE_EDID is not set
++# CONFIG_FB_DDC is not set
++# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+ CONFIG_FB_CFB_FILLRECT=y
+ CONFIG_FB_CFB_COPYAREA=y
+ CONFIG_FB_CFB_IMAGEBLIT=y
++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
++# CONFIG_FB_SYS_FILLRECT is not set
++# CONFIG_FB_SYS_COPYAREA is not set
++# CONFIG_FB_SYS_IMAGEBLIT is not set
++# CONFIG_FB_FOREIGN_ENDIAN is not set
++# CONFIG_FB_SYS_FOPS is not set
+ # CONFIG_FB_SVGALIB is not set
+ # CONFIG_FB_MACMODES is not set
+ # CONFIG_FB_BACKLIGHT is not set
+ # CONFIG_FB_MODE_HELPERS is not set
+ # CONFIG_FB_TILEBLITTING is not set
++
++#
++# Frame buffer hardware drivers
++#
+ # CONFIG_FB_S1D13XXX is not set
+ CONFIG_FB_AU1200=y
+ # CONFIG_FB_VIRTUAL is not set
++# CONFIG_FB_METRONOME is not set
++# CONFIG_FB_MB862XX is not set
++# CONFIG_FB_BROADSHEET is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
+
+ #
+ # Console display driver support
+ #
+-CONFIG_VGA_CONSOLE=y
+-# CONFIG_VGACON_SOFT_SCROLLBACK is not set
++# CONFIG_VGA_CONSOLE is not set
+ CONFIG_DUMMY_CONSOLE=y
+-# CONFIG_FRAMEBUFFER_CONSOLE is not set
++CONFIG_FRAMEBUFFER_CONSOLE=y
++# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
++# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
++CONFIG_FONTS=y
++# CONFIG_FONT_8x8 is not set
++CONFIG_FONT_8x16=y
++# CONFIG_FONT_6x11 is not set
++# CONFIG_FONT_7x14 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++# CONFIG_FONT_MINI_4x6 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_SUN12x22 is not set
++# CONFIG_FONT_10x18 is not set
++# CONFIG_LOGO is not set
++CONFIG_SOUND=y
++# CONFIG_SOUND_OSS_CORE is not set
++CONFIG_SND=y
++CONFIG_SND_TIMER=y
++CONFIG_SND_PCM=y
++CONFIG_SND_JACK=y
++# CONFIG_SND_SEQUENCER is not set
++# CONFIG_SND_MIXER_OSS is not set
++# CONFIG_SND_PCM_OSS is not set
++# CONFIG_SND_HRTIMER is not set
++CONFIG_SND_DYNAMIC_MINORS=y
++# CONFIG_SND_SUPPORT_OLD_API is not set
++# CONFIG_SND_VERBOSE_PROCFS is not set
++# CONFIG_SND_VERBOSE_PRINTK is not set
++# CONFIG_SND_DEBUG is not set
++CONFIG_SND_VMASTER=y
++# CONFIG_SND_RAWMIDI_SEQ is not set
++# CONFIG_SND_OPL3_LIB_SEQ is not set
++# CONFIG_SND_OPL4_LIB_SEQ is not set
++# CONFIG_SND_SBAWE_SEQ is not set
++# CONFIG_SND_EMU10K1_SEQ is not set
++CONFIG_SND_AC97_CODEC=y
++# CONFIG_SND_DRIVERS is not set
++# CONFIG_SND_SPI is not set
++# CONFIG_SND_MIPS is not set
++# CONFIG_SND_USB is not set
++# CONFIG_SND_PCMCIA is not set
++CONFIG_SND_SOC=y
++CONFIG_SND_SOC_AC97_BUS=y
++CONFIG_SND_SOC_AU1XPSC=y
++CONFIG_SND_SOC_AU1XPSC_I2S=y
++CONFIG_SND_SOC_AU1XPSC_AC97=y
++CONFIG_SND_SOC_DB1200=y
++CONFIG_SND_SOC_I2C_AND_SPI=y
++# CONFIG_SND_SOC_ALL_CODECS is not set
++CONFIG_SND_SOC_AC97_CODEC=y
++CONFIG_SND_SOC_WM8731=y
++# CONFIG_SOUND_PRIME is not set
++CONFIG_AC97_BUS=y
++CONFIG_HID_SUPPORT=y
++CONFIG_HID=y
++CONFIG_HIDRAW=y
++
++#
++# USB Input Devices
++#
++CONFIG_USB_HID=y
++# CONFIG_HID_PID is not set
++CONFIG_USB_HIDDEV=y
++
++#
++# Special HID drivers
++#
++# CONFIG_HID_A4TECH is not set
++# CONFIG_HID_APPLE is not set
++# CONFIG_HID_BELKIN is not set
++# CONFIG_HID_CHERRY is not set
++# CONFIG_HID_CHICONY is not set
++# CONFIG_HID_CYPRESS is not set
++# CONFIG_HID_DRAGONRISE is not set
++# CONFIG_HID_EZKEY is not set
++# CONFIG_HID_KYE is not set
++# CONFIG_HID_GYRATION is not set
++# CONFIG_HID_TWINHAN is not set
++# CONFIG_HID_KENSINGTON is not set
++# CONFIG_HID_LOGITECH is not set
++# CONFIG_HID_MICROSOFT is not set
++# CONFIG_HID_MONTEREY is not set
++# CONFIG_HID_NTRIG is not set
++# CONFIG_HID_PANTHERLORD is not set
++# CONFIG_HID_PETALYNX is not set
++# CONFIG_HID_SAMSUNG is not set
++# CONFIG_HID_SONY is not set
++# CONFIG_HID_SUNPLUS is not set
++# CONFIG_HID_GREENASIA is not set
++# CONFIG_HID_SMARTJOYPLUS is not set
++# CONFIG_HID_TOPSEED is not set
++# CONFIG_HID_THRUSTMASTER is not set
++# CONFIG_HID_ZEROPLUS is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
++CONFIG_USB_ARCH_HAS_EHCI=y
++CONFIG_USB=y
++CONFIG_USB_DEBUG=y
++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+ #
+-# Logo configuration
++# Miscellaneous USB options
+ #
+-CONFIG_LOGO=y
+-CONFIG_LOGO_LINUX_MONO=y
+-CONFIG_LOGO_LINUX_VGA16=y
+-CONFIG_LOGO_LINUX_CLUT224=y
+-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++# CONFIG_USB_DEVICEFS is not set
++# CONFIG_USB_DEVICE_CLASS is not set
++CONFIG_USB_DYNAMIC_MINORS=y
++# CONFIG_USB_OTG is not set
++# CONFIG_USB_OTG_WHITELIST is not set
++# CONFIG_USB_OTG_BLACKLIST_HUB is not set
++# CONFIG_USB_MON is not set
++# CONFIG_USB_WUSB is not set
++# CONFIG_USB_WUSB_CBAF is not set
+
+ #
+-# Sound
++# USB Host Controller Drivers
+ #
+-# CONFIG_SOUND is not set
++# CONFIG_USB_C67X00_HCD is not set
++CONFIG_USB_EHCI_HCD=y
++CONFIG_USB_EHCI_ROOT_HUB_TT=y
++CONFIG_USB_EHCI_TT_NEWSCHED=y
++# CONFIG_USB_OXU210HP_HCD is not set
++# CONFIG_USB_ISP116X_HCD is not set
++# CONFIG_USB_ISP1760_HCD is not set
++# CONFIG_USB_ISP1362_HCD is not set
++CONFIG_USB_OHCI_HCD=y
++# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
++# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
++CONFIG_USB_OHCI_LITTLE_ENDIAN=y
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++# CONFIG_USB_HWA_HCD is not set
+
+ #
+-# HID Devices
++# USB Device Class drivers
+ #
+-CONFIG_HID=y
+-# CONFIG_HID_DEBUG is not set
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++# CONFIG_USB_WDM is not set
++# CONFIG_USB_TMC is not set
+
+ #
+-# USB support
++# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+ #
+-CONFIG_USB_ARCH_HAS_HCD=y
+-CONFIG_USB_ARCH_HAS_OHCI=y
+-CONFIG_USB_ARCH_HAS_EHCI=y
+-# CONFIG_USB is not set
+
+ #
+-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
++# also be needed; see USB_STORAGE Help for more info
++#
++# CONFIG_USB_LIBUSUAL is not set
++
++#
++# USB Imaging devices
+ #
++# CONFIG_USB_MDC800 is not set
+
+ #
+-# USB Gadget Support
++# USB port drivers
+ #
+-CONFIG_USB_GADGET=m
+-# CONFIG_USB_GADGET_DEBUG_FILES is not set
+-# CONFIG_USB_GADGET_NET2280 is not set
+-# CONFIG_USB_GADGET_PXA2XX is not set
+-# CONFIG_USB_GADGET_GOKU is not set
+-# CONFIG_USB_GADGET_LH7A40X is not set
+-# CONFIG_USB_GADGET_OMAP is not set
+-# CONFIG_USB_GADGET_AT91 is not set
+-# CONFIG_USB_GADGET_DUMMY_HCD is not set
+-# CONFIG_USB_GADGET_DUALSPEED is not set
++# CONFIG_USB_SERIAL is not set
+
+ #
+-# MMC/SD Card support
++# USB Miscellaneous drivers
+ #
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_SEVSEG is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_BERRY_CHARGE is not set
++# CONFIG_USB_LED is not set
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_SISUSBVGA is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++# CONFIG_USB_IOWARRIOR is not set
++# CONFIG_USB_TEST is not set
++# CONFIG_USB_ISIGHTFW is not set
++# CONFIG_USB_VST is not set
++# CONFIG_USB_GADGET is not set
++
++#
++# OTG and related infrastructure
++#
++# CONFIG_USB_GPIO_VBUS is not set
++# CONFIG_NOP_USB_XCEIV is not set
+ CONFIG_MMC=y
+ # CONFIG_MMC_DEBUG is not set
+-CONFIG_MMC_BLOCK=y
+-CONFIG_MMC_AU1X=y
++# CONFIG_MMC_UNSAFE_RESUME is not set
+
+ #
+-# LED devices
++# MMC/SD/SDIO Card Drivers
+ #
+-# CONFIG_NEW_LEDS is not set
++CONFIG_MMC_BLOCK=y
++# CONFIG_MMC_BLOCK_BOUNCE is not set
++# CONFIG_SDIO_UART is not set
++# CONFIG_MMC_TEST is not set
+
+ #
+-# LED drivers
++# MMC/SD/SDIO Host Controller Drivers
+ #
++# CONFIG_MMC_SDHCI is not set
++CONFIG_MMC_AU1X=y
++# CONFIG_MMC_AT91 is not set
++# CONFIG_MMC_ATMELMCI is not set
++# CONFIG_MMC_SPI is not set
++# CONFIG_MEMSTICK is not set
++CONFIG_NEW_LEDS=y
++CONFIG_LEDS_CLASS=y
+
+ #
+-# LED Triggers
++# LED drivers
+ #
++# CONFIG_LEDS_PCA9532 is not set
++# CONFIG_LEDS_GPIO is not set
++# CONFIG_LEDS_LP3944 is not set
++# CONFIG_LEDS_PCA955X is not set
++# CONFIG_LEDS_DAC124S085 is not set
++# CONFIG_LEDS_BD2802 is not set
+
+ #
+-# InfiniBand support
++# LED Triggers
+ #
++CONFIG_LEDS_TRIGGERS=y
++# CONFIG_LEDS_TRIGGER_TIMER is not set
++# CONFIG_LEDS_TRIGGER_IDE_DISK is not set
++# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
++# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
++# CONFIG_LEDS_TRIGGER_GPIO is not set
++# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
+
+ #
+-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
++# iptables trigger is under Netfilter config (LED target)
+ #
++# CONFIG_ACCESSIBILITY is not set
++CONFIG_RTC_LIB=y
++CONFIG_RTC_CLASS=y
++CONFIG_RTC_HCTOSYS=y
++CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
++# CONFIG_RTC_DEBUG is not set
+
+ #
+-# Real Time Clock
++# RTC interfaces
+ #
+-# CONFIG_RTC_CLASS is not set
++CONFIG_RTC_INTF_SYSFS=y
++CONFIG_RTC_INTF_PROC=y
++CONFIG_RTC_INTF_DEV=y
++# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
++# CONFIG_RTC_DRV_TEST is not set
+
+ #
+-# DMA Engine support
++# I2C RTC drivers
+ #
+-# CONFIG_DMA_ENGINE is not set
++# CONFIG_RTC_DRV_DS1307 is not set
++# CONFIG_RTC_DRV_DS1374 is not set
++# CONFIG_RTC_DRV_DS1672 is not set
++# CONFIG_RTC_DRV_MAX6900 is not set
++# CONFIG_RTC_DRV_RS5C372 is not set
++# CONFIG_RTC_DRV_ISL1208 is not set
++# CONFIG_RTC_DRV_X1205 is not set
++# CONFIG_RTC_DRV_PCF8563 is not set
++# CONFIG_RTC_DRV_PCF8583 is not set
++# CONFIG_RTC_DRV_M41T80 is not set
++# CONFIG_RTC_DRV_S35390A is not set
++# CONFIG_RTC_DRV_FM3130 is not set
++# CONFIG_RTC_DRV_RX8581 is not set
++# CONFIG_RTC_DRV_RX8025 is not set
+
+ #
+-# DMA Clients
++# SPI RTC drivers
+ #
++# CONFIG_RTC_DRV_M41T94 is not set
++# CONFIG_RTC_DRV_DS1305 is not set
++# CONFIG_RTC_DRV_DS1390 is not set
++# CONFIG_RTC_DRV_MAX6902 is not set
++# CONFIG_RTC_DRV_R9701 is not set
++# CONFIG_RTC_DRV_RS5C348 is not set
++# CONFIG_RTC_DRV_DS3234 is not set
++# CONFIG_RTC_DRV_PCF2123 is not set
+
+ #
+-# DMA Devices
++# Platform RTC drivers
+ #
++# CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1286 is not set
++# CONFIG_RTC_DRV_DS1511 is not set
++# CONFIG_RTC_DRV_DS1553 is not set
++# CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
++# CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T35 is not set
++# CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_BQ4802 is not set
++# CONFIG_RTC_DRV_V3020 is not set
+
+ #
+-# Auxiliary Display support
++# on-CPU RTC drivers
+ #
++CONFIG_RTC_DRV_AU1XXX=y
++# CONFIG_DMADEVICES is not set
++# CONFIG_AUXDISPLAY is not set
++# CONFIG_UIO is not set
+
+ #
+-# Virtualization
++# TI VLYNQ
+ #
++# CONFIG_STAGING is not set
+
+ #
+ # File systems
+ #
+ CONFIG_EXT2_FS=y
+-CONFIG_EXT2_FS_XATTR=y
+-CONFIG_EXT2_FS_POSIX_ACL=y
+-# CONFIG_EXT2_FS_SECURITY is not set
++# CONFIG_EXT2_FS_XATTR is not set
+ # CONFIG_EXT2_FS_XIP is not set
+-CONFIG_EXT3_FS=y
+-CONFIG_EXT3_FS_XATTR=y
+-CONFIG_EXT3_FS_POSIX_ACL=y
+-CONFIG_EXT3_FS_SECURITY=y
+-# CONFIG_EXT4DEV_FS is not set
+-CONFIG_JBD=y
+-# CONFIG_JBD_DEBUG is not set
+-CONFIG_FS_MBCACHE=y
++# CONFIG_EXT3_FS is not set
++# CONFIG_EXT4_FS is not set
+ # CONFIG_REISERFS_FS is not set
+-CONFIG_JFS_FS=y
+-# CONFIG_JFS_POSIX_ACL is not set
+-# CONFIG_JFS_SECURITY is not set
+-# CONFIG_JFS_DEBUG is not set
+-# CONFIG_JFS_STATISTICS is not set
+-CONFIG_FS_POSIX_ACL=y
++# CONFIG_JFS_FS is not set
++# CONFIG_FS_POSIX_ACL is not set
+ # CONFIG_XFS_FS is not set
+-# CONFIG_GFS2_FS is not set
+ # CONFIG_OCFS2_FS is not set
+-# CONFIG_MINIX_FS is not set
+-# CONFIG_ROMFS_FS is not set
++# CONFIG_BTRFS_FS is not set
++# CONFIG_NILFS2_FS is not set
++CONFIG_FILE_LOCKING=y
++CONFIG_FSNOTIFY=y
++CONFIG_DNOTIFY=y
+ CONFIG_INOTIFY=y
+ CONFIG_INOTIFY_USER=y
+ # CONFIG_QUOTA is not set
+-CONFIG_DNOTIFY=y
+ # CONFIG_AUTOFS_FS is not set
+ # CONFIG_AUTOFS4_FS is not set
+ # CONFIG_FUSE_FS is not set
+-CONFIG_GENERIC_ACL=y
++
++#
++# Caches
++#
++# CONFIG_FSCACHE is not set
+
+ #
+ # CD-ROM/DVD Filesystems
+ #
+-CONFIG_ISO9660_FS=m
+-CONFIG_JOLIET=y
+-CONFIG_ZISOFS=y
+-CONFIG_UDF_FS=m
+-CONFIG_UDF_NLS=y
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
+
+ #
+ # DOS/FAT/NT Filesystems
+ #
+-CONFIG_FAT_FS=m
+-CONFIG_MSDOS_FS=m
+-CONFIG_VFAT_FS=m
+-CONFIG_FAT_DEFAULT_CODEPAGE=437
+-CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++# CONFIG_MSDOS_FS is not set
++# CONFIG_VFAT_FS is not set
+ # CONFIG_NTFS_FS is not set
+
+ #
+@@ -1039,19 +1288,15 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=y
+ CONFIG_PROC_SYSCTL=y
++# CONFIG_PROC_PAGE_MONITOR is not set
+ CONFIG_SYSFS=y
+ CONFIG_TMPFS=y
+-CONFIG_TMPFS_POSIX_ACL=y
++# CONFIG_TMPFS_POSIX_ACL is not set
+ # CONFIG_HUGETLB_PAGE is not set
+-CONFIG_RAMFS=y
+-CONFIG_CONFIGFS_FS=m
+-
+-#
+-# Miscellaneous filesystems
+-#
++# CONFIG_CONFIGFS_FS is not set
++CONFIG_MISC_FILESYSTEMS=y
+ # CONFIG_ADFS_FS is not set
+ # CONFIG_AFFS_FS is not set
+-# CONFIG_ECRYPT_FS is not set
+ # CONFIG_HFS_FS is not set
+ # CONFIG_HFSPLUS_FS is not set
+ # CONFIG_BEFS_FS is not set
+@@ -1060,27 +1305,36 @@ CONFIG_CONFIGFS_FS=m
+ CONFIG_JFFS2_FS=y
+ CONFIG_JFFS2_FS_DEBUG=0
+ CONFIG_JFFS2_FS_WRITEBUFFER=y
+-# CONFIG_JFFS2_SUMMARY is not set
++# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
++CONFIG_JFFS2_SUMMARY=y
+ # CONFIG_JFFS2_FS_XATTR is not set
+-# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
++CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+ CONFIG_JFFS2_ZLIB=y
++CONFIG_JFFS2_LZO=y
+ CONFIG_JFFS2_RTIME=y
+-# CONFIG_JFFS2_RUBIN is not set
+-CONFIG_CRAMFS=m
++CONFIG_JFFS2_RUBIN=y
++# CONFIG_JFFS2_CMODE_NONE is not set
++CONFIG_JFFS2_CMODE_PRIORITY=y
++# CONFIG_JFFS2_CMODE_SIZE is not set
++# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
++# CONFIG_CRAMFS is not set
++CONFIG_SQUASHFS=y
++# CONFIG_SQUASHFS_EMBEDDED is not set
++CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+ # CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_OMFS_FS is not set
+ # CONFIG_HPFS_FS is not set
+ # CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
+ # CONFIG_SYSV_FS is not set
+ # CONFIG_UFS_FS is not set
+-
+-#
+-# Network File Systems
+-#
++CONFIG_NETWORK_FILESYSTEMS=y
+ CONFIG_NFS_FS=y
+ CONFIG_NFS_V3=y
+ # CONFIG_NFS_V3_ACL is not set
+ # CONFIG_NFS_V4 is not set
+-# CONFIG_NFS_DIRECTIO is not set
++CONFIG_ROOT_NFS=y
+ # CONFIG_NFSD is not set
+ CONFIG_LOCKD=y
+ CONFIG_LOCKD_V4=y
+@@ -1088,159 +1342,124 @@ CONFIG_NFS_COMMON=y
+ CONFIG_SUNRPC=y
+ # CONFIG_RPCSEC_GSS_KRB5 is not set
+ # CONFIG_RPCSEC_GSS_SPKM3 is not set
+-CONFIG_SMB_FS=y
+-# CONFIG_SMB_NLS_DEFAULT is not set
++# CONFIG_SMB_FS is not set
+ # CONFIG_CIFS is not set
+ # CONFIG_NCP_FS is not set
+ # CONFIG_CODA_FS is not set
+ # CONFIG_AFS_FS is not set
+-# CONFIG_9P_FS is not set
+
+ #
+ # Partition Types
+ #
+-# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
+ CONFIG_MSDOS_PARTITION=y
+-
+-#
+-# Native Language Support
+-#
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_KARMA_PARTITION is not set
++CONFIG_EFI_PARTITION=y
++# CONFIG_SYSV68_PARTITION is not set
+ CONFIG_NLS=y
+ CONFIG_NLS_DEFAULT="iso8859-1"
+-CONFIG_NLS_CODEPAGE_437=m
+-CONFIG_NLS_CODEPAGE_737=m
+-CONFIG_NLS_CODEPAGE_775=m
+-CONFIG_NLS_CODEPAGE_850=m
+-CONFIG_NLS_CODEPAGE_852=m
+-CONFIG_NLS_CODEPAGE_855=m
+-CONFIG_NLS_CODEPAGE_857=m
+-CONFIG_NLS_CODEPAGE_860=m
+-CONFIG_NLS_CODEPAGE_861=m
+-CONFIG_NLS_CODEPAGE_862=m
+-CONFIG_NLS_CODEPAGE_863=m
+-CONFIG_NLS_CODEPAGE_864=m
+-CONFIG_NLS_CODEPAGE_865=m
+-CONFIG_NLS_CODEPAGE_866=m
+-CONFIG_NLS_CODEPAGE_869=m
+-CONFIG_NLS_CODEPAGE_936=m
+-CONFIG_NLS_CODEPAGE_950=m
+-CONFIG_NLS_CODEPAGE_932=m
+-CONFIG_NLS_CODEPAGE_949=m
+-CONFIG_NLS_CODEPAGE_874=m
+-CONFIG_NLS_ISO8859_8=m
+-CONFIG_NLS_CODEPAGE_1250=m
+-CONFIG_NLS_CODEPAGE_1251=m
+-CONFIG_NLS_ASCII=m
+-CONFIG_NLS_ISO8859_1=m
+-CONFIG_NLS_ISO8859_2=m
+-CONFIG_NLS_ISO8859_3=m
+-CONFIG_NLS_ISO8859_4=m
+-CONFIG_NLS_ISO8859_5=m
+-CONFIG_NLS_ISO8859_6=m
+-CONFIG_NLS_ISO8859_7=m
+-CONFIG_NLS_ISO8859_9=m
+-CONFIG_NLS_ISO8859_13=m
+-CONFIG_NLS_ISO8859_14=m
+-CONFIG_NLS_ISO8859_15=m
+-CONFIG_NLS_KOI8_R=m
+-CONFIG_NLS_KOI8_U=m
+-CONFIG_NLS_UTF8=m
+-
+-#
+-# Distributed Lock Manager
+-#
+-CONFIG_DLM=m
+-CONFIG_DLM_TCP=y
+-# CONFIG_DLM_SCTP is not set
+-# CONFIG_DLM_DEBUG is not set
+-
+-#
+-# Profiling support
+-#
+-# CONFIG_PROFILING is not set
++CONFIG_NLS_CODEPAGE_437=y
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++CONFIG_NLS_CODEPAGE_850=y
++CONFIG_NLS_CODEPAGE_852=y
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++# CONFIG_NLS_CODEPAGE_936 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++CONFIG_NLS_CODEPAGE_1250=y
++# CONFIG_NLS_CODEPAGE_1251 is not set
++CONFIG_NLS_ASCII=y
++CONFIG_NLS_ISO8859_1=y
++CONFIG_NLS_ISO8859_2=y
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_13 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++CONFIG_NLS_ISO8859_15=y
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++CONFIG_NLS_UTF8=y
++# CONFIG_DLM is not set
+
+ #
+ # Kernel hacking
+ #
+ CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+ # CONFIG_PRINTK_TIME is not set
+-CONFIG_ENABLE_MUST_CHECK=y
+-# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_ENABLE_WARN_DEPRECATED is not set
++# CONFIG_ENABLE_MUST_CHECK is not set
++CONFIG_FRAME_WARN=1024
++CONFIG_MAGIC_SYSRQ=y
++CONFIG_STRIP_ASM_SYMS=y
+ # CONFIG_UNUSED_SYMBOLS is not set
+ # CONFIG_DEBUG_FS is not set
+ # CONFIG_HEADERS_CHECK is not set
+ # CONFIG_DEBUG_KERNEL is not set
+-CONFIG_LOG_BUF_SHIFT=14
+-CONFIG_CROSSCOMPILE=y
+-CONFIG_CMDLINE="mem=48M"
++# CONFIG_DEBUG_MEMORY_INIT is not set
++# CONFIG_RCU_CPU_STALL_DETECTOR is not set
++CONFIG_TRACING_SUPPORT=y
++# CONFIG_FTRACE is not set
++# CONFIG_SAMPLES is not set
++CONFIG_HAVE_ARCH_KGDB=y
++CONFIG_CMDLINE="console=ttyS0,115200"
+
+ #
+ # Security options
+ #
+-CONFIG_KEYS=y
+-CONFIG_KEYS_DEBUG_PROC_KEYS=y
++# CONFIG_KEYS is not set
+ # CONFIG_SECURITY is not set
+-
+-#
+-# Cryptographic options
+-#
+-CONFIG_CRYPTO=y
+-CONFIG_CRYPTO_ALGAPI=y
+-CONFIG_CRYPTO_BLKCIPHER=m
+-CONFIG_CRYPTO_HASH=m
+-CONFIG_CRYPTO_MANAGER=m
+-CONFIG_CRYPTO_HMAC=m
+-CONFIG_CRYPTO_XCBC=m
+-CONFIG_CRYPTO_NULL=m
+-CONFIG_CRYPTO_MD4=m
+-CONFIG_CRYPTO_MD5=y
+-CONFIG_CRYPTO_SHA1=m
+-CONFIG_CRYPTO_SHA256=m
+-CONFIG_CRYPTO_SHA512=m
+-CONFIG_CRYPTO_WP512=m
+-CONFIG_CRYPTO_TGR192=m
+-CONFIG_CRYPTO_GF128MUL=m
+-CONFIG_CRYPTO_ECB=m
+-CONFIG_CRYPTO_CBC=m
+-CONFIG_CRYPTO_PCBC=m
+-CONFIG_CRYPTO_LRW=m
+-CONFIG_CRYPTO_DES=m
+-CONFIG_CRYPTO_FCRYPT=m
+-CONFIG_CRYPTO_BLOWFISH=m
+-CONFIG_CRYPTO_TWOFISH=m
+-CONFIG_CRYPTO_TWOFISH_COMMON=m
+-CONFIG_CRYPTO_SERPENT=m
+-CONFIG_CRYPTO_AES=m
+-CONFIG_CRYPTO_CAST5=m
+-CONFIG_CRYPTO_CAST6=m
+-CONFIG_CRYPTO_TEA=m
+-CONFIG_CRYPTO_ARC4=m
+-CONFIG_CRYPTO_KHAZAD=m
+-CONFIG_CRYPTO_ANUBIS=m
+-CONFIG_CRYPTO_DEFLATE=m
+-CONFIG_CRYPTO_MICHAEL_MIC=m
+-CONFIG_CRYPTO_CRC32C=m
+-CONFIG_CRYPTO_CAMELLIA=m
+-# CONFIG_CRYPTO_TEST is not set
+-
+-#
+-# Hardware crypto devices
+-#
++CONFIG_SECURITYFS=y
++CONFIG_SECURITY_FILE_CAPABILITIES=y
++# CONFIG_CRYPTO is not set
++# CONFIG_BINARY_PRINTF is not set
+
+ #
+ # Library routines
+ #
+ CONFIG_BITREVERSE=y
+-CONFIG_CRC_CCITT=y
++CONFIG_GENERIC_FIND_LAST_BIT=y
++# CONFIG_CRC_CCITT is not set
+ # CONFIG_CRC16 is not set
++# CONFIG_CRC_T10DIF is not set
++# CONFIG_CRC_ITU_T is not set
+ CONFIG_CRC32=y
+-CONFIG_LIBCRC32C=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
+ CONFIG_ZLIB_INFLATE=y
+ CONFIG_ZLIB_DEFLATE=y
+-CONFIG_TEXTSEARCH=y
+-CONFIG_TEXTSEARCH_KMP=m
+-CONFIG_TEXTSEARCH_BM=m
+-CONFIG_TEXTSEARCH_FSM=m
+-CONFIG_PLIST=y
++CONFIG_LZO_COMPRESS=y
++CONFIG_LZO_DECOMPRESS=y
+ CONFIG_HAS_IOMEM=y
+ CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
++CONFIG_NLATTR=y
+diff --git a/arch/mips/configs/fuloong2e_defconfig b/arch/mips/configs/fuloong2e_defconfig
+index 0197f0d..b3626de 100644
+--- a/arch/mips/configs/fuloong2e_defconfig
++++ b/arch/mips/configs/fuloong2e_defconfig
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.31-rc1
+-# Thu Jul 2 22:37:00 2009
++# Linux kernel version: 2.6.32-rc4
++# Fri Oct 16 13:18:01 2009
+ #
+ CONFIG_MIPS=y
+
+@@ -12,6 +12,7 @@ CONFIG_MIPS=y
+ # CONFIG_AR7 is not set
+ # CONFIG_BASLER_EXCITE is not set
+ # CONFIG_BCM47XX is not set
++# CONFIG_BCM63XX is not set
+ # CONFIG_MIPS_COBALT is not set
+ # CONFIG_MACH_DECSTATION is not set
+ # CONFIG_MACH_JAZZ is not set
+@@ -105,6 +106,8 @@ CONFIG_CPU_LOONGSON2E=y
+ # CONFIG_CPU_RM9000 is not set
+ # CONFIG_CPU_SB1 is not set
+ # CONFIG_CPU_CAVIUM_OCTEON is not set
++CONFIG_SYS_SUPPORTS_ZBOOT=y
++CONFIG_SYS_SUPPORTS_ZBOOT_UART16550=y
+ CONFIG_CPU_LOONGSON2=y
+ CONFIG_SYS_HAS_CPU_LOONGSON2E=y
+ CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+@@ -135,12 +138,16 @@ CONFIG_SYS_SUPPORTS_HIGHMEM=y
+ CONFIG_ARCH_FLATMEM_ENABLE=y
+ CONFIG_ARCH_POPULATES_NODE_MAP=y
+ CONFIG_SELECT_MEMORY_MODEL=y
+-CONFIG_FLATMEM_MANUAL=y
++# CONFIG_FLATMEM_MANUAL is not set
+ # CONFIG_DISCONTIGMEM_MANUAL is not set
+-# CONFIG_SPARSEMEM_MANUAL is not set
+-CONFIG_FLATMEM=y
+-CONFIG_FLAT_NODE_MEM_MAP=y
++CONFIG_SPARSEMEM_MANUAL=y
++CONFIG_SPARSEMEM=y
++CONFIG_HAVE_MEMORY_PRESENT=y
+ CONFIG_SPARSEMEM_STATIC=y
++
++#
++# Memory hotplug is currently incompatible with Software Suspend
++#
+ CONFIG_PAGEFLAGS_EXTENDED=y
+ CONFIG_SPLIT_PTLOCK_CPUS=4
+ CONFIG_PHYS_ADDR_T_64BIT=y
+@@ -148,6 +155,7 @@ CONFIG_ZONE_DMA_FLAG=0
+ CONFIG_VIRT_TO_BUS=y
+ CONFIG_HAVE_MLOCK=y
+ CONFIG_HAVE_MLOCKED_PAGE_BIT=y
++# CONFIG_KSM is not set
+ CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+ CONFIG_TICK_ONESHOT=y
+ CONFIG_NO_HZ=y
+@@ -180,6 +188,12 @@ CONFIG_BROKEN_ON_SMP=y
+ CONFIG_INIT_ENV_ARG_LIMIT=32
+ CONFIG_LOCALVERSION="-fuloong2e"
+ # CONFIG_LOCALVERSION_AUTO is not set
++CONFIG_HAVE_KERNEL_GZIP=y
++CONFIG_HAVE_KERNEL_BZIP2=y
++CONFIG_HAVE_KERNEL_LZMA=y
++CONFIG_KERNEL_GZIP=y
++# CONFIG_KERNEL_BZIP2 is not set
++# CONFIG_KERNEL_LZMA is not set
+ CONFIG_SWAP=y
+ CONFIG_SYSVIPC=y
+ CONFIG_SYSVIPC_SYSCTL=y
+@@ -193,11 +207,12 @@ CONFIG_BSD_PROCESS_ACCT=y
+ #
+ # RCU Subsystem
+ #
+-CONFIG_CLASSIC_RCU=y
+-# CONFIG_TREE_RCU is not set
+-# CONFIG_PREEMPT_RCU is not set
++CONFIG_TREE_RCU=y
++# CONFIG_TREE_PREEMPT_RCU is not set
++# CONFIG_RCU_TRACE is not set
++CONFIG_RCU_FANOUT=64
++# CONFIG_RCU_FANOUT_EXACT is not set
+ # CONFIG_TREE_RCU_TRACE is not set
+-# CONFIG_PREEMPT_RCU_TRACE is not set
+ CONFIG_IKCONFIG=y
+ CONFIG_IKCONFIG_PROC=y
+ CONFIG_LOG_BUF_SHIFT=14
+@@ -235,18 +250,16 @@ CONFIG_SHMEM=y
+ CONFIG_AIO=y
+
+ #
+-# Performance Counters
++# Kernel Performance Events And Counters
+ #
+ CONFIG_VM_EVENT_COUNTERS=y
+ CONFIG_PCI_QUIRKS=y
+-# CONFIG_STRIP_ASM_SYMS is not set
+ # CONFIG_COMPAT_BRK is not set
+ CONFIG_SLAB=y
+ # CONFIG_SLUB is not set
+ # CONFIG_SLOB is not set
+ CONFIG_PROFILING=y
+ CONFIG_TRACEPOINTS=y
+-CONFIG_MARKERS=y
+ CONFIG_OPROFILE=m
+ CONFIG_HAVE_OPROFILE=y
+ CONFIG_HAVE_SYSCALL_WRAPPERS=y
+@@ -255,8 +268,8 @@ CONFIG_HAVE_SYSCALL_WRAPPERS=y
+ # GCOV-based kernel profiling
+ #
+ # CONFIG_GCOV_KERNEL is not set
+-# CONFIG_SLOW_WORK is not set
+-# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
++CONFIG_SLOW_WORK=y
++CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+ CONFIG_SLABINFO=y
+ CONFIG_RT_MUTEXES=y
+ CONFIG_BASE_SMALL=0
+@@ -283,7 +296,7 @@ CONFIG_IOSCHED_CFQ=y
+ CONFIG_DEFAULT_CFQ=y
+ # CONFIG_DEFAULT_NOOP is not set
+ CONFIG_DEFAULT_IOSCHED="cfq"
+-# CONFIG_FREEZER is not set
++CONFIG_FREEZER=y
+
+ #
+ # Bus options (PCI, PCMCIA, EISA, ISA, TC)
+@@ -321,9 +334,14 @@ CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+ CONFIG_ARCH_SUSPEND_POSSIBLE=y
+ CONFIG_PM=y
+ # CONFIG_PM_DEBUG is not set
++CONFIG_PM_SLEEP=y
+ # CONFIG_SUSPEND is not set
+-# CONFIG_HIBERNATION is not set
++CONFIG_HIBERNATION_NVS=y
++CONFIG_HIBERNATION=y
++CONFIG_PM_STD_PARTITION="/dev/hda3"
++# CONFIG_PM_RUNTIME is not set
+ CONFIG_NET=y
++CONFIG_COMPAT_NETLINK_MESSAGES=y
+
+ #
+ # Networking options
+@@ -442,6 +460,7 @@ CONFIG_IP_NF_ARPFILTER=m
+ CONFIG_IP_NF_ARP_MANGLE=m
+ # CONFIG_IP_DCCP is not set
+ # CONFIG_IP_SCTP is not set
++# CONFIG_RDS is not set
+ # CONFIG_TIPC is not set
+ # CONFIG_ATM is not set
+ # CONFIG_BRIDGE is not set
+@@ -473,6 +492,7 @@ CONFIG_NET_CLS_ROUTE=y
+ # CONFIG_AF_RXRPC is not set
+ CONFIG_WIRELESS=y
+ # CONFIG_CFG80211 is not set
++CONFIG_CFG80211_DEFAULT_PS_VALUE=0
+ CONFIG_WIRELESS_OLD_REGULATORY=y
+ CONFIG_WIRELESS_EXT=y
+ CONFIG_WIRELESS_EXT_SYSFS=y
+@@ -481,7 +501,6 @@ CONFIG_WIRELESS_EXT_SYSFS=y
+ #
+ # CFG80211 needs to be enabled for MAC80211
+ #
+-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
+ # CONFIG_WIMAX is not set
+ # CONFIG_RFKILL is not set
+ CONFIG_NET_9P=m
+@@ -495,6 +514,7 @@ CONFIG_NET_9P=m
+ # Generic Driver Options
+ #
+ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++# CONFIG_DEVTMPFS is not set
+ CONFIG_STANDALONE=y
+ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ CONFIG_FW_LOADER=m
+@@ -504,9 +524,9 @@ CONFIG_EXTRA_FIRMWARE=""
+ # CONFIG_CONNECTOR is not set
+ CONFIG_MTD=m
+ # CONFIG_MTD_DEBUG is not set
++# CONFIG_MTD_TESTS is not set
+ # CONFIG_MTD_CONCAT is not set
+ # CONFIG_MTD_PARTITIONS is not set
+-# CONFIG_MTD_TESTS is not set
+
+ #
+ # User Modules And Translation Layers
+@@ -820,6 +840,7 @@ CONFIG_8139TOO=y
+ # CONFIG_SUNDANCE is not set
+ # CONFIG_TLAN is not set
+ # CONFIG_KS8842 is not set
++# CONFIG_KS8851_MLL is not set
+ # CONFIG_VIA_RHINE is not set
+ # CONFIG_SC92031 is not set
+ # CONFIG_ATL2 is not set
+@@ -867,10 +888,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
+ # CONFIG_SFC is not set
+ # CONFIG_BE2NET is not set
+ # CONFIG_TR is not set
+-
+-#
+-# Wireless LAN
+-#
++CONFIG_WLAN=y
+ # CONFIG_WLAN_PRE80211 is not set
+ # CONFIG_WLAN_80211 is not set
+
+@@ -886,6 +904,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
+ # CONFIG_USB_PEGASUS is not set
+ # CONFIG_USB_RTL8150 is not set
+ # CONFIG_USB_USBNET is not set
++# CONFIG_USB_CDC_PHONET is not set
+ # CONFIG_WAN is not set
+ # CONFIG_FDDI is not set
+ # CONFIG_HIPPI is not set
+@@ -933,12 +952,16 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+ # Input Device Drivers
+ #
+ CONFIG_INPUT_KEYBOARD=y
++# CONFIG_KEYBOARD_ADP5588 is not set
+ CONFIG_KEYBOARD_ATKBD=y
+-# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_QT2160 is not set
+ # CONFIG_KEYBOARD_LKKBD is not set
+-# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_KEYBOARD_MAX7359 is not set
+ # CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_OPENCORES is not set
+ # CONFIG_KEYBOARD_STOWAWAY is not set
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
+ CONFIG_INPUT_MOUSE=y
+ CONFIG_MOUSE_PS2=y
+ CONFIG_MOUSE_PS2_ALPS=y
+@@ -946,6 +969,7 @@ CONFIG_MOUSE_PS2_LOGIPS2PP=y
+ CONFIG_MOUSE_PS2_SYNAPTICS=y
+ CONFIG_MOUSE_PS2_TRACKPOINT=y
+ # CONFIG_MOUSE_PS2_ELANTECH is not set
++# CONFIG_MOUSE_PS2_SENTELIC is not set
+ # CONFIG_MOUSE_PS2_TOUCHKIT is not set
+ CONFIG_MOUSE_SERIAL=y
+ # CONFIG_MOUSE_APPLETOUCH is not set
+@@ -1015,6 +1039,7 @@ CONFIG_RTC=y
+ CONFIG_DEVPORT=y
+ CONFIG_I2C=m
+ CONFIG_I2C_BOARDINFO=y
++CONFIG_I2C_COMPAT=y
+ CONFIG_I2C_CHARDEV=m
+ CONFIG_I2C_HELPER_AUTO=y
+
+@@ -1070,9 +1095,6 @@ CONFIG_I2C_VIAPRO=m
+ # Miscellaneous I2C Chip support
+ #
+ # CONFIG_DS1682 is not set
+-# CONFIG_SENSORS_PCF8574 is not set
+-# CONFIG_PCF8575 is not set
+-# CONFIG_SENSORS_PCA9539 is not set
+ # CONFIG_SENSORS_TSL2550 is not set
+ # CONFIG_I2C_DEBUG_CORE is not set
+ # CONFIG_I2C_DEBUG_ALGO is not set
+@@ -1088,7 +1110,6 @@ CONFIG_I2C_VIAPRO=m
+ # CONFIG_POWER_SUPPLY is not set
+ # CONFIG_HWMON is not set
+ # CONFIG_THERMAL is not set
+-# CONFIG_THERMAL_HWMON is not set
+ # CONFIG_WATCHDOG is not set
+ CONFIG_SSB_POSSIBLE=y
+
+@@ -1105,6 +1126,7 @@ CONFIG_SSB_POSSIBLE=y
+ # CONFIG_HTC_PASIC3 is not set
+ # CONFIG_MFD_TMIO is not set
+ # CONFIG_MFD_WM8400 is not set
++# CONFIG_MFD_WM831X is not set
+ # CONFIG_MFD_WM8350_I2C is not set
+ # CONFIG_MFD_PCF50633 is not set
+ # CONFIG_AB3100_CORE is not set
+@@ -1114,6 +1136,7 @@ CONFIG_SSB_POSSIBLE=y
+ #
+ # Graphics support
+ #
++CONFIG_VGA_ARB=y
+ # CONFIG_DRM is not set
+ # CONFIG_VGASTATE is not set
+ CONFIG_VIDEO_OUTPUT_CONTROL=m
+@@ -1198,6 +1221,7 @@ CONFIG_FONT_8x16=y
+ # CONFIG_LOGO is not set
+ CONFIG_SOUND=y
+ CONFIG_SOUND_OSS_CORE=y
++CONFIG_SOUND_OSS_CORE_PRECLAIM=y
+ CONFIG_SND=m
+ CONFIG_SND_TIMER=m
+ CONFIG_SND_PCM=m
+@@ -1304,7 +1328,6 @@ CONFIG_SND_USB=y
+ CONFIG_AC97_BUS=m
+ CONFIG_HID_SUPPORT=y
+ CONFIG_HID=y
+-# CONFIG_HID_DEBUG is not set
+ CONFIG_HIDRAW=y
+
+ #
+@@ -1356,6 +1379,7 @@ CONFIG_USB_EHCI_TT_NEWSCHED=y
+ # CONFIG_USB_OXU210HP_HCD is not set
+ # CONFIG_USB_ISP116X_HCD is not set
+ CONFIG_USB_ISP1760_HCD=m
++# CONFIG_USB_ISP1362_HCD is not set
+ CONFIG_USB_OHCI_HCD=y
+ # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+ # CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+@@ -1453,6 +1477,7 @@ CONFIG_UIO_CIF=m
+ # CONFIG_UIO_SMX is not set
+ # CONFIG_UIO_AEC is not set
+ # CONFIG_UIO_SERCOS3 is not set
++# CONFIG_UIO_PCI_GENERIC is not set
+
+ #
+ # TI VLYNQ
+@@ -1469,10 +1494,10 @@ CONFIG_EXT3_FS=y
+ # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+ # CONFIG_EXT3_FS_XATTR is not set
+ CONFIG_EXT4_FS=m
+-CONFIG_EXT4DEV_COMPAT=y
+ CONFIG_EXT4_FS_XATTR=y
+ CONFIG_EXT4_FS_POSIX_ACL=y
+ CONFIG_EXT4_FS_SECURITY=y
++# CONFIG_EXT4_DEBUG is not set
+ CONFIG_FS_XIP=y
+ CONFIG_JBD=y
+ # CONFIG_JBD_DEBUG is not set
+@@ -1489,6 +1514,7 @@ CONFIG_FS_POSIX_ACL=y
+ # CONFIG_GFS2_FS is not set
+ # CONFIG_OCFS2_FS is not set
+ # CONFIG_BTRFS_FS is not set
++# CONFIG_NILFS2_FS is not set
+ CONFIG_FILE_LOCKING=y
+ CONFIG_FSNOTIFY=y
+ CONFIG_DNOTIFY=y
+@@ -1557,7 +1583,6 @@ CONFIG_OMFS_FS=m
+ # CONFIG_ROMFS_FS is not set
+ # CONFIG_SYSV_FS is not set
+ # CONFIG_UFS_FS is not set
+-# CONFIG_NILFS2_FS is not set
+ CONFIG_NETWORK_FILESYSTEMS=y
+ CONFIG_NFS_FS=m
+ CONFIG_NFS_V3=y
+@@ -1666,6 +1691,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
+ # CONFIG_ENABLE_MUST_CHECK is not set
+ CONFIG_FRAME_WARN=2048
+ # CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_STRIP_ASM_SYMS is not set
+ # CONFIG_UNUSED_SYMBOLS is not set
+ CONFIG_DEBUG_FS=y
+ # CONFIG_HEADERS_CHECK is not set
+@@ -1678,6 +1704,7 @@ CONFIG_NOP_TRACER=y
+ CONFIG_RING_BUFFER=y
+ CONFIG_EVENT_TRACING=y
+ CONFIG_CONTEXT_SWITCH_TRACER=y
++CONFIG_RING_BUFFER_ALLOW_SWAP=y
+ CONFIG_TRACING=y
+ CONFIG_TRACING_SUPPORT=y
+ # CONFIG_FTRACE is not set
+@@ -1742,11 +1769,13 @@ CONFIG_CRYPTO_XTS=m
+ #
+ CONFIG_CRYPTO_HMAC=y
+ # CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_VMAC is not set
+
+ #
+ # Digest
+ #
+ # CONFIG_CRYPTO_CRC32C is not set
++CONFIG_CRYPTO_GHASH=m
+ # CONFIG_CRYPTO_MD4 is not set
+ CONFIG_CRYPTO_MD5=m
+ # CONFIG_CRYPTO_MICHAEL_MIC is not set
+diff --git a/arch/mips/configs/lemote2f_defconfig b/arch/mips/configs/lemote2f_defconfig
+new file mode 100644
+index 0000000..e13bbc1
+--- /dev/null
++++ b/arch/mips/configs/lemote2f_defconfig
+@@ -0,0 +1,2212 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.32
++# Thu Dec 10 17:15:19 2009
++#
++CONFIG_MIPS=y
++
++#
++# Machine selection
++#
++# CONFIG_MACH_ALCHEMY is not set
++# CONFIG_AR7 is not set
++# CONFIG_BASLER_EXCITE is not set
++# CONFIG_BCM47XX is not set
++# CONFIG_BCM63XX is not set
++# CONFIG_MIPS_COBALT is not set
++# CONFIG_MACH_DECSTATION is not set
++# CONFIG_MACH_JAZZ is not set
++# CONFIG_LASAT is not set
++CONFIG_MACH_LOONGSON=y
++# CONFIG_MIPS_MALTA is not set
++# CONFIG_MIPS_SIM is not set
++# CONFIG_NEC_MARKEINS is not set
++# CONFIG_MACH_VR41XX is not set
++# CONFIG_NXP_STB220 is not set
++# CONFIG_NXP_STB225 is not set
++# CONFIG_PNX8550_JBS is not set
++# CONFIG_PNX8550_STB810 is not set
++# CONFIG_PMC_MSP is not set
++# CONFIG_PMC_YOSEMITE is not set
++# CONFIG_POWERTV is not set
++# CONFIG_SGI_IP22 is not set
++# CONFIG_SGI_IP27 is not set
++# CONFIG_SGI_IP28 is not set
++# CONFIG_SGI_IP32 is not set
++# CONFIG_SIBYTE_CRHINE is not set
++# CONFIG_SIBYTE_CARMEL is not set
++# CONFIG_SIBYTE_CRHONE is not set
++# CONFIG_SIBYTE_RHONE is not set
++# CONFIG_SIBYTE_SWARM is not set
++# CONFIG_SIBYTE_LITTLESUR is not set
++# CONFIG_SIBYTE_SENTOSA is not set
++# CONFIG_SIBYTE_BIGSUR is not set
++# CONFIG_SNI_RM is not set
++# CONFIG_MACH_TX39XX is not set
++# CONFIG_MACH_TX49XX is not set
++# CONFIG_MIKROTIK_RB532 is not set
++# CONFIG_WR_PPMC is not set
++# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
++# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
++# CONFIG_ALCHEMY_GPIO_INDIRECT is not set
++CONFIG_ARCH_SPARSEMEM_ENABLE=y
++# CONFIG_LEMOTE_FULOONG2E is not set
++CONFIG_LEMOTE_MACH2F=y
++CONFIG_CS5536=y
++CONFIG_CS5536_MFGPT=y
++CONFIG_LOONGSON_SUSPEND=y
++CONFIG_LOONGSON_UART_BASE=y
++
++#
++# Loongson Platform Specific Drivers
++#
++CONFIG_LOONGSON_PLATFORM_DEVICES=y
++CONFIG_LEMOTE_LYNLOONG2F_PDEV=m
++CONFIG_LEMOTE_YEELOONG2F_PDEV=m
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_ARCH_SUPPORTS_OPROFILE=y
++CONFIG_GENERIC_FIND_NEXT_BIT=y
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_GENERIC_TIME=y
++CONFIG_GENERIC_CMOS_UPDATE=y
++CONFIG_SCHED_OMIT_FRAME_POINTER=y
++CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
++CONFIG_DMA_NONCOHERENT=y
++CONFIG_DMA_NEED_PCI_MAP_STATE=y
++CONFIG_SYS_HAS_EARLY_PRINTK=y
++CONFIG_I8259=y
++# CONFIG_NO_IOPORT is not set
++CONFIG_GENERIC_ISA_DMA=y
++CONFIG_GENERIC_ISA_DMA_SUPPORT_BROKEN=y
++# CONFIG_CPU_BIG_ENDIAN is not set
++CONFIG_CPU_LITTLE_ENDIAN=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
++CONFIG_IRQ_CPU=y
++CONFIG_BOOT_ELF32=y
++CONFIG_MIPS_L1_CACHE_SHIFT=5
++
++#
++# CPU selection
++#
++# CONFIG_CPU_LOONGSON2E is not set
++CONFIG_CPU_LOONGSON2F=y
++# CONFIG_CPU_MIPS32_R1 is not set
++# CONFIG_CPU_MIPS32_R2 is not set
++# CONFIG_CPU_MIPS64_R1 is not set
++# CONFIG_CPU_MIPS64_R2 is not set
++# CONFIG_CPU_R3000 is not set
++# CONFIG_CPU_TX39XX is not set
++# CONFIG_CPU_VR41XX is not set
++# CONFIG_CPU_R4300 is not set
++# CONFIG_CPU_R4X00 is not set
++# CONFIG_CPU_TX49XX is not set
++# CONFIG_CPU_R5000 is not set
++# CONFIG_CPU_R5432 is not set
++# CONFIG_CPU_R5500 is not set
++# CONFIG_CPU_R6000 is not set
++# CONFIG_CPU_NEVADA is not set
++# CONFIG_CPU_R8000 is not set
++# CONFIG_CPU_R10000 is not set
++# CONFIG_CPU_RM7000 is not set
++# CONFIG_CPU_RM9000 is not set
++# CONFIG_CPU_SB1 is not set
++# CONFIG_CPU_CAVIUM_OCTEON is not set
++CONFIG_SYS_SUPPORTS_ZBOOT=y
++CONFIG_SYS_SUPPORTS_ZBOOT_UART16550=y
++CONFIG_CPU_LOONGSON2=y
++CONFIG_SYS_HAS_CPU_LOONGSON2F=y
++CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
++CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
++CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
++CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
++CONFIG_CPU_SUPPORTS_CPUFREQ=y
++CONFIG_CPU_SUPPORTS_ADDRWINCFG=y
++CONFIG_CPU_SUPPORTS_UNCACHED_ACCELERATED=y
++
++#
++# Kernel type
++#
++# CONFIG_32BIT is not set
++CONFIG_64BIT=y
++# CONFIG_PAGE_SIZE_4KB is not set
++# CONFIG_PAGE_SIZE_8KB is not set
++CONFIG_PAGE_SIZE_16KB=y
++# CONFIG_PAGE_SIZE_32KB is not set
++# CONFIG_PAGE_SIZE_64KB is not set
++CONFIG_BOARD_SCACHE=y
++CONFIG_MIPS_MT_DISABLED=y
++# CONFIG_MIPS_MT_SMP is not set
++# CONFIG_MIPS_MT_SMTC is not set
++CONFIG_CPU_HAS_WB=y
++CONFIG_CPU_HAS_SYNC=y
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_CPU_SUPPORTS_HIGHMEM=y
++CONFIG_SYS_SUPPORTS_HIGHMEM=y
++CONFIG_ARCH_POPULATES_NODE_MAP=y
++CONFIG_SELECT_MEMORY_MODEL=y
++# CONFIG_FLATMEM_MANUAL is not set
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++CONFIG_SPARSEMEM_MANUAL=y
++CONFIG_SPARSEMEM=y
++CONFIG_HAVE_MEMORY_PRESENT=y
++CONFIG_SPARSEMEM_STATIC=y
++CONFIG_PAGEFLAGS_EXTENDED=y
++CONFIG_SPLIT_PTLOCK_CPUS=4
++CONFIG_PHYS_ADDR_T_64BIT=y
++CONFIG_ZONE_DMA_FLAG=0
++CONFIG_VIRT_TO_BUS=y
++CONFIG_HAVE_MLOCK=y
++CONFIG_HAVE_MLOCKED_PAGE_BIT=y
++# CONFIG_KSM is not set
++CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
++CONFIG_TICK_ONESHOT=y
++CONFIG_NO_HZ=y
++CONFIG_HIGH_RES_TIMERS=y
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++# CONFIG_HZ_48 is not set
++# CONFIG_HZ_100 is not set
++# CONFIG_HZ_128 is not set
++CONFIG_HZ_250=y
++# CONFIG_HZ_256 is not set
++# CONFIG_HZ_1000 is not set
++# CONFIG_HZ_1024 is not set
++CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
++CONFIG_HZ=250
++# CONFIG_PREEMPT_NONE is not set
++# CONFIG_PREEMPT_VOLUNTARY is not set
++CONFIG_PREEMPT=y
++CONFIG_KEXEC=y
++# CONFIG_SECCOMP is not set
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++CONFIG_CONSTRUCTORS=y
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_LOCK_KERNEL=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++# CONFIG_LOCALVERSION_AUTO is not set
++CONFIG_HAVE_KERNEL_GZIP=y
++CONFIG_HAVE_KERNEL_BZIP2=y
++CONFIG_HAVE_KERNEL_LZMA=y
++CONFIG_HAVE_KERNEL_LZO=y
++CONFIG_KERNEL_GZIP=y
++# CONFIG_KERNEL_BZIP2 is not set
++# CONFIG_KERNEL_LZMA is not set
++# CONFIG_KERNEL_LZO is not set
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++# CONFIG_POSIX_MQUEUE is not set
++CONFIG_BSD_PROCESS_ACCT=y
++CONFIG_BSD_PROCESS_ACCT_V3=y
++# CONFIG_TASKSTATS is not set
++CONFIG_AUDIT=y
++
++#
++# RCU Subsystem
++#
++CONFIG_TREE_RCU=y
++# CONFIG_TREE_PREEMPT_RCU is not set
++# CONFIG_RCU_TRACE is not set
++CONFIG_RCU_FANOUT=64
++# CONFIG_RCU_FANOUT_EXACT is not set
++# CONFIG_TREE_RCU_TRACE is not set
++CONFIG_IKCONFIG=y
++CONFIG_IKCONFIG_PROC=y
++CONFIG_LOG_BUF_SHIFT=15
++# CONFIG_GROUP_SCHED is not set
++# CONFIG_CGROUPS is not set
++CONFIG_SYSFS_DEPRECATED=y
++CONFIG_SYSFS_DEPRECATED_V2=y
++# CONFIG_RELAY is not set
++# CONFIG_NAMESPACES is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++CONFIG_RD_GZIP=y
++CONFIG_RD_BZIP2=y
++CONFIG_RD_LZMA=y
++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
++CONFIG_SYSCTL=y
++CONFIG_ANON_INODES=y
++CONFIG_EMBEDDED=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_PCSPKR_PLATFORM=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_AIO=y
++
++#
++# Kernel Performance Events And Counters
++#
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_PCI_QUIRKS=y
++CONFIG_SLUB_DEBUG=y
++CONFIG_COMPAT_BRK=y
++# CONFIG_SLAB is not set
++CONFIG_SLUB=y
++# CONFIG_SLOB is not set
++CONFIG_PROFILING=y
++CONFIG_TRACEPOINTS=y
++CONFIG_OPROFILE=m
++CONFIG_HAVE_OPROFILE=y
++CONFIG_HAVE_SYSCALL_WRAPPERS=y
++
++#
++# GCOV-based kernel profiling
++#
++# CONFIG_GCOV_KERNEL is not set
++CONFIG_SLOW_WORK=y
++# CONFIG_SLOW_WORK_DEBUG is not set
++CONFIG_HAVE_GENERIC_DMA_COHERENT=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++# CONFIG_MODULE_FORCE_LOAD is not set
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++CONFIG_MODVERSIONS=y
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_BLOCK=y
++CONFIG_BLK_DEV_BSG=y
++CONFIG_BLK_DEV_INTEGRITY=y
++CONFIG_BLOCK_COMPAT=y
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=m
++CONFIG_IOSCHED_DEADLINE=m
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_DEFAULT_AS is not set
++# CONFIG_DEFAULT_DEADLINE is not set
++CONFIG_DEFAULT_CFQ=y
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="cfq"
++CONFIG_FREEZER=y
++
++#
++# Bus options (PCI, PCMCIA, EISA, ISA, TC)
++#
++CONFIG_HW_HAS_PCI=y
++CONFIG_PCI=y
++CONFIG_PCI_DOMAINS=y
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++CONFIG_PCI_LEGACY=y
++# CONFIG_PCI_STUB is not set
++# CONFIG_PCI_IOV is not set
++CONFIG_ISA=y
++CONFIG_MMU=y
++# CONFIG_PCCARD is not set
++# CONFIG_HOTPLUG_PCI is not set
++
++#
++# Executable file formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++# CONFIG_HAVE_AOUT is not set
++CONFIG_BINFMT_MISC=m
++CONFIG_MIPS32_COMPAT=y
++CONFIG_COMPAT=y
++CONFIG_SYSVIPC_COMPAT=y
++CONFIG_MIPS32_O32=y
++CONFIG_MIPS32_N32=y
++CONFIG_BINFMT_ELF32=y
++
++#
++# Power management options
++#
++CONFIG_ARCH_HIBERNATION_POSSIBLE=y
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++CONFIG_PM=y
++# CONFIG_PM_DEBUG is not set
++CONFIG_PM_SLEEP=y
++CONFIG_SUSPEND=y
++CONFIG_SUSPEND_FREEZER=y
++CONFIG_HIBERNATION_NVS=y
++CONFIG_HIBERNATION=y
++CONFIG_PM_STD_PARTITION="/dev/hda3"
++CONFIG_APM_EMULATION=y
++CONFIG_PM_RUNTIME=y
++CONFIG_MIPS_EXTERNAL_TIMER=y
++CONFIG_MIPS_CPUFREQ=y
++
++#
++# CPU Frequency scaling
++#
++CONFIG_CPU_FREQ=y
++CONFIG_CPU_FREQ_TABLE=y
++CONFIG_CPU_FREQ_DEBUG=y
++CONFIG_CPU_FREQ_STAT=m
++CONFIG_CPU_FREQ_STAT_DETAILS=y
++# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
++# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
++# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
++CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
++# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
++CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
++CONFIG_CPU_FREQ_GOV_POWERSAVE=m
++CONFIG_CPU_FREQ_GOV_USERSPACE=m
++CONFIG_CPU_FREQ_GOV_ONDEMAND=y
++CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
++
++#
++# CPUFreq processor drivers
++#
++CONFIG_LOONGSON2_CPUFREQ=m
++CONFIG_NET=y
++CONFIG_COMPAT_NETLINK_MESSAGES=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++CONFIG_PACKET_MMAP=y
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++CONFIG_XFRM_USER=m
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_XFRM_STATISTICS is not set
++CONFIG_NET_KEY=m
++# CONFIG_NET_KEY_MIGRATE is not set
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++CONFIG_IP_ADVANCED_ROUTER=y
++CONFIG_ASK_IP_FIB_HASH=y
++# CONFIG_IP_FIB_TRIE is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_MULTIPLE_TABLES=y
++CONFIG_IP_ROUTE_MULTIPATH=y
++CONFIG_IP_ROUTE_VERBOSE=y
++# CONFIG_IP_PNP is not set
++CONFIG_NET_IPIP=m
++CONFIG_NET_IPGRE=m
++# CONFIG_NET_IPGRE_BROADCAST is not set
++CONFIG_IP_MROUTE=y
++CONFIG_IP_PIMSM_V1=y
++CONFIG_IP_PIMSM_V2=y
++CONFIG_ARPD=y
++CONFIG_SYN_COOKIES=y
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++CONFIG_INET_TUNNEL=m
++CONFIG_INET_XFRM_MODE_TRANSPORT=m
++CONFIG_INET_XFRM_MODE_TUNNEL=m
++CONFIG_INET_XFRM_MODE_BEET=m
++CONFIG_INET_LRO=y
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++CONFIG_TCP_CONG_ADVANCED=y
++CONFIG_TCP_CONG_BIC=y
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_TCP_CONG_WESTWOOD=m
++CONFIG_TCP_CONG_HTCP=m
++# CONFIG_TCP_CONG_HSTCP is not set
++# CONFIG_TCP_CONG_HYBLA is not set
++# CONFIG_TCP_CONG_VEGAS is not set
++# CONFIG_TCP_CONG_SCALABLE is not set
++# CONFIG_TCP_CONG_LP is not set
++# CONFIG_TCP_CONG_VENO is not set
++# CONFIG_TCP_CONG_YEAH is not set
++# CONFIG_TCP_CONG_ILLINOIS is not set
++CONFIG_DEFAULT_BIC=y
++# CONFIG_DEFAULT_CUBIC is not set
++# CONFIG_DEFAULT_HTCP is not set
++# CONFIG_DEFAULT_VEGAS is not set
++# CONFIG_DEFAULT_WESTWOOD is not set
++# CONFIG_DEFAULT_RENO is not set
++CONFIG_DEFAULT_TCP_CONG="bic"
++CONFIG_TCP_MD5SIG=y
++CONFIG_IPV6=m
++CONFIG_IPV6_PRIVACY=y
++CONFIG_IPV6_ROUTER_PREF=y
++# CONFIG_IPV6_ROUTE_INFO is not set
++# CONFIG_IPV6_OPTIMISTIC_DAD is not set
++# CONFIG_INET6_AH is not set
++# CONFIG_INET6_ESP is not set
++# CONFIG_INET6_IPCOMP is not set
++# CONFIG_IPV6_MIP6 is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++CONFIG_INET6_TUNNEL=m
++CONFIG_INET6_XFRM_MODE_TRANSPORT=m
++CONFIG_INET6_XFRM_MODE_TUNNEL=m
++CONFIG_INET6_XFRM_MODE_BEET=m
++# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
++CONFIG_IPV6_SIT=m
++CONFIG_IPV6_NDISC_NODETYPE=y
++CONFIG_IPV6_TUNNEL=m
++CONFIG_IPV6_MULTIPLE_TABLES=y
++CONFIG_IPV6_SUBTREES=y
++# CONFIG_IPV6_MROUTE is not set
++CONFIG_NETWORK_SECMARK=y
++CONFIG_NETFILTER=y
++# CONFIG_NETFILTER_DEBUG is not set
++CONFIG_NETFILTER_ADVANCED=y
++CONFIG_BRIDGE_NETFILTER=y
++
++#
++# Core Netfilter Configuration
++#
++# CONFIG_NETFILTER_NETLINK_QUEUE is not set
++# CONFIG_NETFILTER_NETLINK_LOG is not set
++# CONFIG_NF_CONNTRACK is not set
++# CONFIG_NETFILTER_XTABLES is not set
++# CONFIG_IP_VS is not set
++
++#
++# IP: Netfilter Configuration
++#
++# CONFIG_NF_DEFRAG_IPV4 is not set
++# CONFIG_IP_NF_QUEUE is not set
++# CONFIG_IP_NF_IPTABLES is not set
++# CONFIG_IP_NF_ARPTABLES is not set
++
++#
++# IPv6: Netfilter Configuration
++#
++# CONFIG_IP6_NF_QUEUE is not set
++# CONFIG_IP6_NF_IPTABLES is not set
++# CONFIG_BRIDGE_NF_EBTABLES is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_RDS is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++CONFIG_STP=m
++CONFIG_BRIDGE=m
++# CONFIG_NET_DSA is not set
++CONFIG_VLAN_8021Q=m
++# CONFIG_VLAN_8021Q_GVRP is not set
++# CONFIG_DECNET is not set
++CONFIG_LLC=m
++# CONFIG_LLC2 is not set
++CONFIG_IPX=m
++# CONFIG_IPX_INTERN is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++# CONFIG_PHONET is not set
++# CONFIG_IEEE802154 is not set
++CONFIG_NET_SCHED=y
++
++#
++# Queueing/Scheduling
++#
++# CONFIG_NET_SCH_CBQ is not set
++# CONFIG_NET_SCH_HTB is not set
++# CONFIG_NET_SCH_HFSC is not set
++# CONFIG_NET_SCH_PRIO is not set
++# CONFIG_NET_SCH_MULTIQ is not set
++# CONFIG_NET_SCH_RED is not set
++# CONFIG_NET_SCH_SFQ is not set
++# CONFIG_NET_SCH_TEQL is not set
++# CONFIG_NET_SCH_TBF is not set
++# CONFIG_NET_SCH_GRED is not set
++# CONFIG_NET_SCH_DSMARK is not set
++# CONFIG_NET_SCH_NETEM is not set
++# CONFIG_NET_SCH_DRR is not set
++# CONFIG_NET_SCH_INGRESS is not set
++
++#
++# Classification
++#
++CONFIG_NET_CLS=y
++# CONFIG_NET_CLS_BASIC is not set
++# CONFIG_NET_CLS_TCINDEX is not set
++# CONFIG_NET_CLS_ROUTE4 is not set
++# CONFIG_NET_CLS_FW is not set
++# CONFIG_NET_CLS_U32 is not set
++# CONFIG_NET_CLS_RSVP is not set
++# CONFIG_NET_CLS_RSVP6 is not set
++# CONFIG_NET_CLS_FLOW is not set
++CONFIG_NET_EMATCH=y
++CONFIG_NET_EMATCH_STACK=32
++# CONFIG_NET_EMATCH_CMP is not set
++# CONFIG_NET_EMATCH_NBYTE is not set
++# CONFIG_NET_EMATCH_U32 is not set
++# CONFIG_NET_EMATCH_META is not set
++# CONFIG_NET_EMATCH_TEXT is not set
++CONFIG_NET_CLS_ACT=y
++# CONFIG_NET_ACT_POLICE is not set
++# CONFIG_NET_ACT_GACT is not set
++# CONFIG_NET_ACT_MIRRED is not set
++# CONFIG_NET_ACT_NAT is not set
++# CONFIG_NET_ACT_PEDIT is not set
++# CONFIG_NET_ACT_SIMP is not set
++# CONFIG_NET_ACT_SKBEDIT is not set
++CONFIG_NET_SCH_FIFO=y
++# CONFIG_DCB is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_NET_DROP_MONITOR is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++CONFIG_BT=m
++CONFIG_BT_L2CAP=m
++CONFIG_BT_SCO=m
++CONFIG_BT_RFCOMM=m
++CONFIG_BT_RFCOMM_TTY=y
++CONFIG_BT_BNEP=m
++CONFIG_BT_BNEP_MC_FILTER=y
++CONFIG_BT_BNEP_PROTO_FILTER=y
++CONFIG_BT_HIDP=m
++
++#
++# Bluetooth device drivers
++#
++CONFIG_BT_HCIBTUSB=m
++# CONFIG_BT_HCIBTSDIO is not set
++# CONFIG_BT_HCIUART is not set
++# CONFIG_BT_HCIBCM203X is not set
++# CONFIG_BT_HCIBPA10X is not set
++CONFIG_BT_HCIBFUSB=m
++CONFIG_BT_HCIVHCI=m
++# CONFIG_BT_MRVL is not set
++# CONFIG_AF_RXRPC is not set
++CONFIG_FIB_RULES=y
++CONFIG_WIRELESS=y
++CONFIG_CFG80211=m
++# CONFIG_NL80211_TESTMODE is not set
++# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
++# CONFIG_CFG80211_REG_DEBUG is not set
++CONFIG_CFG80211_DEFAULT_PS=y
++CONFIG_CFG80211_DEFAULT_PS_VALUE=1
++# CONFIG_CFG80211_DEBUGFS is not set
++# CONFIG_WIRELESS_OLD_REGULATORY is not set
++CONFIG_WIRELESS_EXT=y
++CONFIG_WIRELESS_EXT_SYSFS=y
++CONFIG_LIB80211=m
++CONFIG_LIB80211_DEBUG=y
++CONFIG_MAC80211=m
++# CONFIG_MAC80211_RC_PID is not set
++CONFIG_MAC80211_RC_MINSTREL=y
++# CONFIG_MAC80211_RC_DEFAULT_PID is not set
++CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
++CONFIG_MAC80211_RC_DEFAULT="minstrel"
++# CONFIG_MAC80211_MESH is not set
++CONFIG_MAC80211_LEDS=y
++# CONFIG_MAC80211_DEBUGFS is not set
++# CONFIG_MAC80211_DEBUG_MENU is not set
++# CONFIG_WIMAX is not set
++CONFIG_RFKILL=m
++CONFIG_RFKILL_LEDS=y
++CONFIG_RFKILL_INPUT=y
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++# CONFIG_DEVTMPFS is not set
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++CONFIG_FW_LOADER=y
++CONFIG_FIRMWARE_IN_KERNEL=y
++CONFIG_EXTRA_FIRMWARE=""
++# CONFIG_SYS_HYPERVISOR is not set
++CONFIG_CONNECTOR=m
++# CONFIG_MTD is not set
++# CONFIG_PARPORT is not set
++# CONFIG_PNP is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_CPQ_DA is not set
++# CONFIG_BLK_CPQ_CISS_DA is not set
++# CONFIG_BLK_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_UMEM is not set
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++CONFIG_BLK_DEV_CRYPTOLOOP=m
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_SX8 is not set
++# CONFIG_BLK_DEV_UB is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=16
++CONFIG_BLK_DEV_RAM_SIZE=8192
++# CONFIG_BLK_DEV_XIP is not set
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++# CONFIG_BLK_DEV_HD is not set
++# CONFIG_MISC_DEVICES is not set
++CONFIG_EEPROM_93CX6=m
++CONFIG_HAVE_IDE=y
++CONFIG_IDE=y
++
++#
++# Please see Documentation/ide/ide.txt for help/info on IDE drives
++#
++CONFIG_IDE_XFER_MODE=y
++CONFIG_IDE_TIMINGS=y
++# CONFIG_BLK_DEV_IDE_SATA is not set
++CONFIG_IDE_GD=y
++CONFIG_IDE_GD_ATA=y
++# CONFIG_IDE_GD_ATAPI is not set
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++CONFIG_IDE_TASK_IOCTL=y
++CONFIG_IDE_PROC_FS=y
++
++#
++# IDE chipset support/bugfixes
++#
++# CONFIG_IDE_GENERIC is not set
++# CONFIG_BLK_DEV_PLATFORM is not set
++CONFIG_BLK_DEV_IDEDMA_SFF=y
++
++#
++# PCI IDE chipsets support
++#
++CONFIG_BLK_DEV_IDEPCI=y
++# CONFIG_IDEPCI_PCIBUS_ORDER is not set
++# CONFIG_BLK_DEV_GENERIC is not set
++# CONFIG_BLK_DEV_OPTI621 is not set
++CONFIG_BLK_DEV_IDEDMA_PCI=y
++# CONFIG_BLK_DEV_AEC62XX is not set
++# CONFIG_BLK_DEV_ALI15X3 is not set
++CONFIG_BLK_DEV_AMD74XX=y
++# CONFIG_BLK_DEV_CMD64X is not set
++# CONFIG_BLK_DEV_TRIFLEX is not set
++# CONFIG_BLK_DEV_CS5520 is not set
++# CONFIG_BLK_DEV_CS5530 is not set
++# CONFIG_BLK_DEV_HPT366 is not set
++# CONFIG_BLK_DEV_JMICRON is not set
++# CONFIG_BLK_DEV_SC1200 is not set
++# CONFIG_BLK_DEV_PIIX is not set
++# CONFIG_BLK_DEV_IT8172 is not set
++# CONFIG_BLK_DEV_IT8213 is not set
++# CONFIG_BLK_DEV_IT821X is not set
++# CONFIG_BLK_DEV_NS87415 is not set
++# CONFIG_BLK_DEV_PDC202XX_OLD is not set
++# CONFIG_BLK_DEV_PDC202XX_NEW is not set
++# CONFIG_BLK_DEV_SVWKS is not set
++# CONFIG_BLK_DEV_SIIMAGE is not set
++# CONFIG_BLK_DEV_SLC90E66 is not set
++# CONFIG_BLK_DEV_TRM290 is not set
++# CONFIG_BLK_DEV_VIA82CXXX is not set
++# CONFIG_BLK_DEV_TC86C001 is not set
++
++#
++# Other IDE chipsets support
++#
++
++#
++# Note: most of these also require special kernel boot parameters
++#
++# CONFIG_BLK_DEV_4DRIVES is not set
++# CONFIG_BLK_DEV_ALI14XX is not set
++# CONFIG_BLK_DEV_DTC2278 is not set
++# CONFIG_BLK_DEV_HT6560B is not set
++# CONFIG_BLK_DEV_QD65XX is not set
++# CONFIG_BLK_DEV_UMC8672 is not set
++CONFIG_BLK_DEV_IDEDMA=y
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=m
++CONFIG_SCSI_DMA=y
++# CONFIG_SCSI_TGT is not set
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=m
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++CONFIG_CHR_DEV_SG=m
++# CONFIG_CHR_DEV_SCH is not set
++CONFIG_SCSI_MULTI_LUN=y
++# CONFIG_SCSI_CONSTANTS is not set
++# CONFIG_SCSI_LOGGING is not set
++# CONFIG_SCSI_SCAN_ASYNC is not set
++CONFIG_SCSI_WAIT_SCAN=m
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++# CONFIG_SCSI_ISCSI_ATTRS is not set
++# CONFIG_SCSI_SAS_ATTRS is not set
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++# CONFIG_SCSI_LOWLEVEL is not set
++# CONFIG_SCSI_DH is not set
++# CONFIG_SCSI_OSD_INITIATOR is not set
++# CONFIG_ATA is not set
++CONFIG_MD=y
++CONFIG_BLK_DEV_MD=m
++CONFIG_MD_LINEAR=m
++CONFIG_MD_RAID0=m
++CONFIG_MD_RAID1=m
++CONFIG_MD_RAID10=m
++CONFIG_MD_RAID456=m
++CONFIG_MD_RAID6_PQ=m
++# CONFIG_ASYNC_RAID6_TEST is not set
++CONFIG_MD_MULTIPATH=m
++CONFIG_MD_FAULTY=m
++CONFIG_BLK_DEV_DM=m
++CONFIG_DM_DEBUG=y
++CONFIG_DM_CRYPT=m
++CONFIG_DM_SNAPSHOT=m
++CONFIG_DM_MIRROR=m
++CONFIG_DM_LOG_USERSPACE=m
++CONFIG_DM_ZERO=m
++CONFIG_DM_MULTIPATH=m
++CONFIG_DM_MULTIPATH_QL=m
++CONFIG_DM_MULTIPATH_ST=m
++CONFIG_DM_DELAY=m
++CONFIG_DM_UEVENT=y
++# CONFIG_FUSION is not set
++
++#
++# IEEE 1394 (FireWire) support
++#
++
++#
++# You can enable one or both FireWire driver stacks.
++#
++
++#
++# See the help texts for more information.
++#
++# CONFIG_FIREWIRE is not set
++# CONFIG_IEEE1394 is not set
++# CONFIG_I2O is not set
++CONFIG_NETDEVICES=y
++# CONFIG_IFB is not set
++CONFIG_DUMMY=m
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++CONFIG_TUN=m
++CONFIG_VETH=m
++# CONFIG_ARCNET is not set
++# CONFIG_PHYLIB is not set
++CONFIG_NET_ETHERNET=y
++CONFIG_MII=y
++# CONFIG_AX88796 is not set
++# CONFIG_HAPPYMEAL is not set
++# CONFIG_SUNGEM is not set
++# CONFIG_CASSINI is not set
++# CONFIG_NET_VENDOR_3COM is not set
++# CONFIG_NET_VENDOR_SMC is not set
++# CONFIG_SMC91X is not set
++# CONFIG_DM9000 is not set
++# CONFIG_ETHOC is not set
++# CONFIG_NET_VENDOR_RACAL is not set
++# CONFIG_DNET is not set
++# CONFIG_NET_TULIP is not set
++# CONFIG_AT1700 is not set
++# CONFIG_DEPCA is not set
++# CONFIG_HP100 is not set
++# CONFIG_NET_ISA is not set
++# CONFIG_IBM_NEW_EMAC_ZMII is not set
++# CONFIG_IBM_NEW_EMAC_RGMII is not set
++# CONFIG_IBM_NEW_EMAC_TAH is not set
++# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
++# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
++# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
++# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
++CONFIG_NET_PCI=y
++# CONFIG_PCNET32 is not set
++# CONFIG_AMD8111_ETH is not set
++# CONFIG_ADAPTEC_STARFIRE is not set
++# CONFIG_AC3200 is not set
++# CONFIG_APRICOT is not set
++# CONFIG_B44 is not set
++# CONFIG_FORCEDETH is not set
++# CONFIG_CS89x0 is not set
++# CONFIG_TC35815 is not set
++# CONFIG_E100 is not set
++# CONFIG_FEALNX is not set
++# CONFIG_NATSEMI is not set
++# CONFIG_NE2K_PCI is not set
++# CONFIG_8139CP is not set
++CONFIG_8139TOO=y
++# CONFIG_8139TOO_PIO is not set
++# CONFIG_8139TOO_TUNE_TWISTER is not set
++# CONFIG_8139TOO_8129 is not set
++# CONFIG_8139_OLD_RX_RESET is not set
++# CONFIG_R6040 is not set
++# CONFIG_SIS900 is not set
++# CONFIG_EPIC100 is not set
++# CONFIG_SMSC9420 is not set
++# CONFIG_SUNDANCE is not set
++# CONFIG_TLAN is not set
++# CONFIG_KS8842 is not set
++# CONFIG_KS8851_MLL is not set
++# CONFIG_VIA_RHINE is not set
++# CONFIG_SC92031 is not set
++# CONFIG_ATL2 is not set
++CONFIG_NETDEV_1000=y
++# CONFIG_ACENIC is not set
++# CONFIG_DL2K is not set
++# CONFIG_E1000 is not set
++# CONFIG_E1000E is not set
++# CONFIG_IP1000 is not set
++# CONFIG_IGB is not set
++# CONFIG_IGBVF is not set
++# CONFIG_NS83820 is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++CONFIG_R8169=y
++CONFIG_R8169_VLAN=y
++# CONFIG_SIS190 is not set
++# CONFIG_SKGE is not set
++# CONFIG_SKY2 is not set
++# CONFIG_VIA_VELOCITY is not set
++# CONFIG_TIGON3 is not set
++# CONFIG_BNX2 is not set
++# CONFIG_CNIC is not set
++# CONFIG_QLA3XXX is not set
++# CONFIG_ATL1 is not set
++# CONFIG_ATL1E is not set
++# CONFIG_ATL1C is not set
++# CONFIG_JME is not set
++# CONFIG_NETDEV_10000 is not set
++# CONFIG_TR is not set
++CONFIG_WLAN=y
++CONFIG_WLAN_PRE80211=y
++# CONFIG_STRIP is not set
++# CONFIG_WAVELAN is not set
++CONFIG_WLAN_80211=y
++# CONFIG_LIBERTAS is not set
++# CONFIG_LIBERTAS_THINFIRM is not set
++# CONFIG_ATMEL is not set
++# CONFIG_AT76C50X_USB is not set
++# CONFIG_PRISM54 is not set
++# CONFIG_USB_ZD1201 is not set
++# CONFIG_USB_NET_RNDIS_WLAN is not set
++# CONFIG_RTL8180 is not set
++CONFIG_RTL8187B=m
++# CONFIG_ADM8211 is not set
++# CONFIG_MAC80211_HWSIM is not set
++# CONFIG_MWL8K is not set
++# CONFIG_P54_COMMON is not set
++# CONFIG_ATH_COMMON is not set
++# CONFIG_IPW2100 is not set
++# CONFIG_IPW2200 is not set
++# CONFIG_IWLWIFI is not set
++# CONFIG_HOSTAP is not set
++# CONFIG_B43 is not set
++# CONFIG_B43LEGACY is not set
++# CONFIG_ZD1211RW is not set
++# CONFIG_RT2X00 is not set
++# CONFIG_HERMES is not set
++# CONFIG_WL12XX is not set
++# CONFIG_IWM is not set
++
++#
++# Enable WiMAX (Networking options) to see the WiMAX drivers
++#
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++CONFIG_USB_USBNET=m
++CONFIG_USB_NET_AX8817X=m
++CONFIG_USB_NET_CDCETHER=m
++CONFIG_USB_NET_CDC_EEM=m
++# CONFIG_USB_NET_DM9601 is not set
++# CONFIG_USB_NET_SMSC95XX is not set
++# CONFIG_USB_NET_GL620A is not set
++CONFIG_USB_NET_NET1080=m
++# CONFIG_USB_NET_PLUSB is not set
++# CONFIG_USB_NET_MCS7830 is not set
++# CONFIG_USB_NET_RNDIS_HOST is not set
++CONFIG_USB_NET_CDC_SUBSET=m
++# CONFIG_USB_ALI_M5632 is not set
++# CONFIG_USB_AN2720 is not set
++CONFIG_USB_BELKIN=y
++CONFIG_USB_ARMLINUX=y
++# CONFIG_USB_EPSON2888 is not set
++# CONFIG_USB_KC2190 is not set
++CONFIG_USB_NET_ZAURUS=m
++# CONFIG_USB_HSO is not set
++# CONFIG_USB_NET_INT51X1 is not set
++# CONFIG_WAN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_NET_FC is not set
++CONFIG_NETCONSOLE=m
++CONFIG_NETCONSOLE_DYNAMIC=y
++CONFIG_NETPOLL=y
++# CONFIG_NETPOLL_TRAP is not set
++CONFIG_NET_POLL_CONTROLLER=y
++# CONFIG_ISDN is not set
++# CONFIG_PHONE is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++CONFIG_INPUT_POLLDEV=m
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_PSAUX=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_EVBUG is not set
++# CONFIG_INPUT_APMPOWER is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++CONFIG_KEYBOARD_ATKBD=y
++# CONFIG_KEYBOARD_LKKBD is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_OPENCORES is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++CONFIG_INPUT_MOUSE=y
++CONFIG_MOUSE_PS2=y
++# CONFIG_MOUSE_PS2_ALPS is not set
++# CONFIG_MOUSE_PS2_LOGIPS2PP is not set
++CONFIG_MOUSE_PS2_SYNAPTICS=y
++# CONFIG_MOUSE_PS2_TRACKPOINT is not set
++# CONFIG_MOUSE_PS2_ELANTECH is not set
++# CONFIG_MOUSE_PS2_SENTELIC is not set
++# CONFIG_MOUSE_PS2_TOUCHKIT is not set
++# CONFIG_MOUSE_SERIAL is not set
++CONFIG_MOUSE_APPLETOUCH=m
++# CONFIG_MOUSE_BCM5974 is not set
++# CONFIG_MOUSE_INPORT is not set
++# CONFIG_MOUSE_LOGIBM is not set
++# CONFIG_MOUSE_PC110PAD is not set
++# CONFIG_MOUSE_VSXXXAA is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++# CONFIG_INPUT_TOUCHSCREEN is not set
++# CONFIG_INPUT_MISC is not set
++
++#
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++CONFIG_SERIO_I8042=y
++# CONFIG_SERIO_SERPORT is not set
++# CONFIG_SERIO_PCIPS2 is not set
++CONFIG_SERIO_LIBPS2=y
++# CONFIG_SERIO_RAW is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_CONSOLE_TRANSLATIONS=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
++CONFIG_DEVKMEM=y
++CONFIG_SERIAL_NONSTANDARD=y
++# CONFIG_COMPUTONE is not set
++# CONFIG_ROCKETPORT is not set
++# CONFIG_CYCLADES is not set
++# CONFIG_DIGIEPCA is not set
++# CONFIG_MOXA_INTELLIO is not set
++# CONFIG_MOXA_SMARTIO is not set
++# CONFIG_ISI is not set
++# CONFIG_SYNCLINKMP is not set
++# CONFIG_SYNCLINK_GT is not set
++# CONFIG_N_HDLC is not set
++# CONFIG_RISCOM8 is not set
++# CONFIG_SPECIALIX is not set
++# CONFIG_STALDRV is not set
++# CONFIG_NOZOMI is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=m
++# CONFIG_SERIAL_8250_PCI is not set
++CONFIG_SERIAL_8250_NR_UARTS=16
++CONFIG_SERIAL_8250_RUNTIME_UARTS=4
++CONFIG_SERIAL_8250_EXTENDED=y
++CONFIG_SERIAL_8250_MANY_PORTS=y
++CONFIG_SERIAL_8250_FOURPORT=y
++# CONFIG_SERIAL_8250_ACCENT is not set
++# CONFIG_SERIAL_8250_BOCA is not set
++# CONFIG_SERIAL_8250_EXAR_ST16C554 is not set
++# CONFIG_SERIAL_8250_HUB6 is not set
++# CONFIG_SERIAL_8250_SHARE_IRQ is not set
++# CONFIG_SERIAL_8250_DETECT_IRQ is not set
++# CONFIG_SERIAL_8250_RSA is not set
++
++#
++# Non-8250 serial port support
++#
++CONFIG_SERIAL_CORE=m
++# CONFIG_SERIAL_JSM is not set
++CONFIG_UNIX98_PTYS=y
++# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=16
++# CONFIG_IPMI_HANDLER is not set
++CONFIG_HW_RANDOM=y
++# CONFIG_HW_RANDOM_TIMERIOMEM is not set
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_DEVPORT=y
++# CONFIG_I2C is not set
++# CONFIG_SPI is not set
++
++#
++# PPS support
++#
++# CONFIG_PPS is not set
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++CONFIG_HWMON=y
++# CONFIG_HWMON_VID is not set
++# CONFIG_HWMON_DEBUG_CHIP is not set
++
++#
++# Native drivers
++#
++# CONFIG_SENSORS_I5K_AMB is not set
++# CONFIG_SENSORS_F71805F is not set
++# CONFIG_SENSORS_F71882FG is not set
++# CONFIG_SENSORS_IT87 is not set
++# CONFIG_SENSORS_PC87360 is not set
++# CONFIG_SENSORS_PC87427 is not set
++# CONFIG_SENSORS_SIS5595 is not set
++# CONFIG_SENSORS_SMSC47M1 is not set
++# CONFIG_SENSORS_SMSC47B397 is not set
++# CONFIG_SENSORS_VIA686A is not set
++# CONFIG_SENSORS_VT1211 is not set
++# CONFIG_SENSORS_VT8231 is not set
++# CONFIG_SENSORS_W83627HF is not set
++# CONFIG_SENSORS_W83627EHF is not set
++CONFIG_THERMAL=y
++# CONFIG_THERMAL_HWMON is not set
++# CONFIG_WATCHDOG is not set
++CONFIG_SSB_POSSIBLE=y
++
++#
++# Sonics Silicon Backplane
++#
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_CORE is not set
++# CONFIG_MFD_SM501 is not set
++# CONFIG_HTC_PASIC3 is not set
++# CONFIG_MFD_TMIO is not set
++# CONFIG_REGULATOR is not set
++CONFIG_MEDIA_SUPPORT=m
++
++#
++# Multimedia core support
++#
++CONFIG_VIDEO_DEV=m
++CONFIG_VIDEO_V4L2_COMMON=m
++CONFIG_VIDEO_ALLOW_V4L1=y
++CONFIG_VIDEO_V4L1_COMPAT=y
++# CONFIG_DVB_CORE is not set
++CONFIG_VIDEO_MEDIA=m
++
++#
++# Multimedia drivers
++#
++# CONFIG_MEDIA_ATTACH is not set
++CONFIG_VIDEO_V4L2=m
++CONFIG_VIDEO_V4L1=m
++CONFIG_VIDEOBUF_GEN=m
++CONFIG_VIDEOBUF_VMALLOC=m
++CONFIG_VIDEO_CAPTURE_DRIVERS=y
++# CONFIG_VIDEO_ADV_DEBUG is not set
++# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
++CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
++CONFIG_VIDEO_VIVI=m
++# CONFIG_VIDEO_PMS is not set
++# CONFIG_VIDEO_CPIA is not set
++# CONFIG_VIDEO_CPIA2 is not set
++# CONFIG_VIDEO_STRADIS is not set
++CONFIG_V4L_USB_DRIVERS=y
++CONFIG_USB_VIDEO_CLASS=m
++CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
++CONFIG_USB_GSPCA=m
++CONFIG_USB_M5602=m
++CONFIG_USB_STV06XX=m
++# CONFIG_USB_GL860 is not set
++CONFIG_USB_GSPCA_CONEX=m
++CONFIG_USB_GSPCA_ETOMS=m
++CONFIG_USB_GSPCA_FINEPIX=m
++# CONFIG_USB_GSPCA_JEILINJ is not set
++CONFIG_USB_GSPCA_MARS=m
++CONFIG_USB_GSPCA_MR97310A=m
++CONFIG_USB_GSPCA_OV519=m
++CONFIG_USB_GSPCA_OV534=m
++CONFIG_USB_GSPCA_PAC207=m
++CONFIG_USB_GSPCA_PAC7311=m
++CONFIG_USB_GSPCA_SN9C20X=m
++CONFIG_USB_GSPCA_SN9C20X_EVDEV=y
++CONFIG_USB_GSPCA_SONIXB=m
++CONFIG_USB_GSPCA_SONIXJ=m
++CONFIG_USB_GSPCA_SPCA500=m
++CONFIG_USB_GSPCA_SPCA501=m
++CONFIG_USB_GSPCA_SPCA505=m
++CONFIG_USB_GSPCA_SPCA506=m
++CONFIG_USB_GSPCA_SPCA508=m
++CONFIG_USB_GSPCA_SPCA561=m
++CONFIG_USB_GSPCA_SQ905=m
++CONFIG_USB_GSPCA_SQ905C=m
++CONFIG_USB_GSPCA_STK014=m
++CONFIG_USB_GSPCA_SUNPLUS=m
++CONFIG_USB_GSPCA_T613=m
++CONFIG_USB_GSPCA_TV8532=m
++CONFIG_USB_GSPCA_VC032X=m
++CONFIG_USB_GSPCA_ZC3XX=m
++# CONFIG_VIDEO_HDPVR is not set
++# CONFIG_USB_VICAM is not set
++# CONFIG_USB_IBMCAM is not set
++# CONFIG_USB_KONICAWC is not set
++# CONFIG_USB_QUICKCAM_MESSENGER is not set
++CONFIG_USB_ET61X251=m
++# CONFIG_USB_OV511 is not set
++# CONFIG_USB_SE401 is not set
++CONFIG_USB_SN9C102=m
++# CONFIG_USB_STV680 is not set
++CONFIG_USB_ZC0301=m
++# CONFIG_USB_PWC is not set
++CONFIG_USB_PWC_INPUT_EVDEV=y
++CONFIG_USB_ZR364XX=m
++CONFIG_USB_STKWEBCAM=m
++CONFIG_USB_S2255=m
++# CONFIG_RADIO_ADAPTERS is not set
++# CONFIG_DAB is not set
++
++#
++# Graphics support
++#
++CONFIG_VGA_ARB=y
++# CONFIG_DRM is not set
++# CONFIG_VGASTATE is not set
++CONFIG_VIDEO_OUTPUT_CONTROL=y
++CONFIG_FB=y
++CONFIG_FIRMWARE_EDID=y
++# CONFIG_FB_DDC is not set
++CONFIG_FB_BOOT_VESA_SUPPORT=y
++CONFIG_FB_CFB_FILLRECT=y
++CONFIG_FB_CFB_COPYAREA=y
++CONFIG_FB_CFB_IMAGEBLIT=y
++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
++# CONFIG_FB_SYS_FILLRECT is not set
++# CONFIG_FB_SYS_COPYAREA is not set
++# CONFIG_FB_SYS_IMAGEBLIT is not set
++# CONFIG_FB_FOREIGN_ENDIAN is not set
++# CONFIG_FB_SYS_FOPS is not set
++# CONFIG_FB_SVGALIB is not set
++# CONFIG_FB_MACMODES is not set
++# CONFIG_FB_BACKLIGHT is not set
++CONFIG_FB_MODE_HELPERS=y
++CONFIG_FB_TILEBLITTING=y
++
++#
++# Frame buffer hardware drivers
++#
++# CONFIG_FB_CIRRUS is not set
++# CONFIG_FB_PM2 is not set
++# CONFIG_FB_CYBER2000 is not set
++# CONFIG_FB_ASILIANT is not set
++# CONFIG_FB_IMSTT is not set
++# CONFIG_FB_UVESA is not set
++# CONFIG_FB_S1D13XXX is not set
++# CONFIG_FB_NVIDIA is not set
++# CONFIG_FB_RIVA is not set
++# CONFIG_FB_MATROX is not set
++# CONFIG_FB_RADEON is not set
++# CONFIG_FB_ATY128 is not set
++# CONFIG_FB_ATY is not set
++# CONFIG_FB_S3 is not set
++# CONFIG_FB_SAVAGE is not set
++CONFIG_FB_SIS=y
++CONFIG_FB_SIS_300=y
++CONFIG_FB_SIS_315=y
++# CONFIG_FB_VIA is not set
++# CONFIG_FB_NEOMAGIC is not set
++# CONFIG_FB_KYRO is not set
++# CONFIG_FB_3DFX is not set
++# CONFIG_FB_VOODOO1 is not set
++# CONFIG_FB_VT8623 is not set
++# CONFIG_FB_TRIDENT is not set
++# CONFIG_FB_ARK is not set
++# CONFIG_FB_PM3 is not set
++# CONFIG_FB_CARMINE is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FB_METRONOME is not set
++# CONFIG_FB_MB862XX is not set
++# CONFIG_FB_BROADSHEET is not set
++CONFIG_BACKLIGHT_LCD_SUPPORT=y
++# CONFIG_LCD_CLASS_DEVICE is not set
++CONFIG_BACKLIGHT_CLASS_DEVICE=y
++CONFIG_BACKLIGHT_GENERIC=m
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++# CONFIG_MDA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE=y
++# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
++CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
++CONFIG_FONTS=y
++CONFIG_FONT_8x8=y
++CONFIG_FONT_8x16=y
++CONFIG_FONT_6x11=y
++CONFIG_FONT_7x14=y
++CONFIG_FONT_PEARL_8x8=y
++CONFIG_FONT_ACORN_8x8=y
++CONFIG_FONT_MINI_4x6=y
++CONFIG_FONT_SUN8x16=y
++CONFIG_FONT_SUN12x22=y
++CONFIG_FONT_10x18=y
++CONFIG_LOGO=y
++# CONFIG_LOGO_LINUX_MONO is not set
++# CONFIG_LOGO_LINUX_VGA16 is not set
++CONFIG_LOGO_LINUX_CLUT224=y
++CONFIG_SOUND=m
++CONFIG_SOUND_OSS_CORE=y
++CONFIG_SOUND_OSS_CORE_PRECLAIM=y
++CONFIG_SND=m
++CONFIG_SND_TIMER=m
++CONFIG_SND_PCM=m
++CONFIG_SND_HWDEP=m
++CONFIG_SND_RAWMIDI=m
++CONFIG_SND_SEQUENCER=m
++CONFIG_SND_SEQ_DUMMY=m
++CONFIG_SND_OSSEMUL=y
++CONFIG_SND_MIXER_OSS=m
++CONFIG_SND_PCM_OSS=m
++CONFIG_SND_PCM_OSS_PLUGINS=y
++CONFIG_SND_SEQUENCER_OSS=y
++CONFIG_SND_HRTIMER=m
++CONFIG_SND_SEQ_HRTIMER_DEFAULT=y
++# CONFIG_SND_DYNAMIC_MINORS is not set
++CONFIG_SND_SUPPORT_OLD_API=y
++CONFIG_SND_VERBOSE_PROCFS=y
++# CONFIG_SND_VERBOSE_PRINTK is not set
++# CONFIG_SND_DEBUG is not set
++CONFIG_SND_VMASTER=y
++CONFIG_SND_RAWMIDI_SEQ=m
++# CONFIG_SND_OPL3_LIB_SEQ is not set
++# CONFIG_SND_OPL4_LIB_SEQ is not set
++# CONFIG_SND_SBAWE_SEQ is not set
++# CONFIG_SND_EMU10K1_SEQ is not set
++CONFIG_SND_MPU401_UART=m
++CONFIG_SND_AC97_CODEC=m
++CONFIG_SND_DRIVERS=y
++CONFIG_SND_DUMMY=m
++CONFIG_SND_VIRMIDI=m
++# CONFIG_SND_MTPAV is not set
++CONFIG_SND_SERIAL_U16550=m
++CONFIG_SND_MPU401=m
++CONFIG_SND_AC97_POWER_SAVE=y
++CONFIG_SND_AC97_POWER_SAVE_DEFAULT=10
++CONFIG_SND_PCI=y
++# CONFIG_SND_AD1889 is not set
++# CONFIG_SND_ALS300 is not set
++# CONFIG_SND_ALI5451 is not set
++# CONFIG_SND_ATIIXP is not set
++# CONFIG_SND_ATIIXP_MODEM is not set
++# CONFIG_SND_AU8810 is not set
++# CONFIG_SND_AU8820 is not set
++# CONFIG_SND_AU8830 is not set
++# CONFIG_SND_AW2 is not set
++# CONFIG_SND_AZT3328 is not set
++# CONFIG_SND_BT87X is not set
++# CONFIG_SND_CA0106 is not set
++# CONFIG_SND_CMIPCI is not set
++# CONFIG_SND_OXYGEN is not set
++# CONFIG_SND_CS4281 is not set
++# CONFIG_SND_CS46XX is not set
++CONFIG_SND_CS5535AUDIO=m
++# CONFIG_SND_CTXFI is not set
++# CONFIG_SND_DARLA20 is not set
++# CONFIG_SND_GINA20 is not set
++# CONFIG_SND_LAYLA20 is not set
++# CONFIG_SND_DARLA24 is not set
++# CONFIG_SND_GINA24 is not set
++# CONFIG_SND_LAYLA24 is not set
++# CONFIG_SND_MONA is not set
++# CONFIG_SND_MIA is not set
++# CONFIG_SND_ECHO3G is not set
++# CONFIG_SND_INDIGO is not set
++# CONFIG_SND_INDIGOIO is not set
++# CONFIG_SND_INDIGODJ is not set
++# CONFIG_SND_INDIGOIOX is not set
++# CONFIG_SND_INDIGODJX is not set
++# CONFIG_SND_EMU10K1 is not set
++# CONFIG_SND_EMU10K1X is not set
++# CONFIG_SND_ENS1370 is not set
++# CONFIG_SND_ENS1371 is not set
++# CONFIG_SND_ES1938 is not set
++# CONFIG_SND_ES1968 is not set
++# CONFIG_SND_FM801 is not set
++# CONFIG_SND_HDA_INTEL is not set
++# CONFIG_SND_HDSP is not set
++# CONFIG_SND_HDSPM is not set
++# CONFIG_SND_HIFIER is not set
++# CONFIG_SND_ICE1712 is not set
++# CONFIG_SND_ICE1724 is not set
++# CONFIG_SND_INTEL8X0 is not set
++# CONFIG_SND_INTEL8X0M is not set
++# CONFIG_SND_KORG1212 is not set
++# CONFIG_SND_LX6464ES is not set
++# CONFIG_SND_MAESTRO3 is not set
++# CONFIG_SND_MIXART is not set
++# CONFIG_SND_NM256 is not set
++# CONFIG_SND_PCXHR is not set
++# CONFIG_SND_RIPTIDE is not set
++# CONFIG_SND_RME32 is not set
++# CONFIG_SND_RME96 is not set
++# CONFIG_SND_RME9652 is not set
++# CONFIG_SND_SONICVIBES is not set
++# CONFIG_SND_TRIDENT is not set
++# CONFIG_SND_VIA82XX is not set
++# CONFIG_SND_VIA82XX_MODEM is not set
++# CONFIG_SND_VIRTUOSO is not set
++# CONFIG_SND_VX222 is not set
++# CONFIG_SND_YMFPCI is not set
++# CONFIG_SND_MIPS is not set
++CONFIG_SND_USB=y
++CONFIG_SND_USB_AUDIO=m
++CONFIG_SND_USB_CAIAQ=m
++CONFIG_SND_USB_CAIAQ_INPUT=y
++# CONFIG_SND_SOC is not set
++# CONFIG_SOUND_PRIME is not set
++CONFIG_AC97_BUS=m
++CONFIG_HID_SUPPORT=y
++CONFIG_HID=y
++CONFIG_HIDRAW=y
++
++#
++# USB Input Devices
++#
++CONFIG_USB_HID=y
++# CONFIG_HID_PID is not set
++CONFIG_USB_HIDDEV=y
++
++#
++# Special HID drivers
++#
++# CONFIG_HID_A4TECH is not set
++CONFIG_HID_APPLE=m
++# CONFIG_HID_BELKIN is not set
++# CONFIG_HID_CHERRY is not set
++# CONFIG_HID_CHICONY is not set
++# CONFIG_HID_CYPRESS is not set
++# CONFIG_HID_DRAGONRISE is not set
++# CONFIG_HID_EZKEY is not set
++# CONFIG_HID_KYE is not set
++# CONFIG_HID_GYRATION is not set
++# CONFIG_HID_TWINHAN is not set
++# CONFIG_HID_KENSINGTON is not set
++# CONFIG_HID_LOGITECH is not set
++# CONFIG_HID_MICROSOFT is not set
++# CONFIG_HID_MONTEREY is not set
++# CONFIG_HID_NTRIG is not set
++# CONFIG_HID_PANTHERLORD is not set
++# CONFIG_HID_PETALYNX is not set
++# CONFIG_HID_SAMSUNG is not set
++# CONFIG_HID_SONY is not set
++# CONFIG_HID_SUNPLUS is not set
++# CONFIG_HID_GREENASIA is not set
++# CONFIG_HID_SMARTJOYPLUS is not set
++# CONFIG_HID_TOPSEED is not set
++# CONFIG_HID_THRUSTMASTER is not set
++# CONFIG_HID_WACOM is not set
++# CONFIG_HID_ZEROPLUS is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
++CONFIG_USB_ARCH_HAS_EHCI=y
++CONFIG_USB=y
++# CONFIG_USB_DEBUG is not set
++# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
++
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEVICEFS=y
++# CONFIG_USB_DEVICE_CLASS is not set
++CONFIG_USB_DYNAMIC_MINORS=y
++CONFIG_USB_SUSPEND=y
++# CONFIG_USB_OTG is not set
++CONFIG_USB_OTG_WHITELIST=y
++# CONFIG_USB_OTG_BLACKLIST_HUB is not set
++CONFIG_USB_MON=y
++CONFIG_USB_WUSB=m
++# CONFIG_USB_WUSB_CBAF is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_C67X00_HCD is not set
++# CONFIG_USB_XHCI_HCD is not set
++CONFIG_USB_EHCI_HCD=y
++CONFIG_USB_EHCI_ROOT_HUB_TT=y
++# CONFIG_USB_EHCI_TT_NEWSCHED is not set
++# CONFIG_USB_OXU210HP_HCD is not set
++# CONFIG_USB_ISP116X_HCD is not set
++# CONFIG_USB_ISP1760_HCD is not set
++# CONFIG_USB_ISP1362_HCD is not set
++CONFIG_USB_OHCI_HCD=y
++# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
++# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
++CONFIG_USB_OHCI_LITTLE_ENDIAN=y
++CONFIG_USB_UHCI_HCD=m
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++CONFIG_USB_WHCI_HCD=m
++CONFIG_USB_HWA_HCD=m
++# CONFIG_USB_GADGET_MUSB_HDRC is not set
++
++#
++# USB Device Class drivers
++#
++CONFIG_USB_ACM=m
++CONFIG_USB_PRINTER=m
++CONFIG_USB_WDM=m
++# CONFIG_USB_TMC is not set
++
++#
++# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
++#
++
++#
++# also be needed; see USB_STORAGE Help for more info
++#
++CONFIG_USB_STORAGE=m
++# CONFIG_USB_STORAGE_DEBUG is not set
++CONFIG_USB_STORAGE_DATAFAB=m
++CONFIG_USB_STORAGE_FREECOM=m
++CONFIG_USB_STORAGE_ISD200=m
++CONFIG_USB_STORAGE_USBAT=m
++CONFIG_USB_STORAGE_SDDR09=m
++CONFIG_USB_STORAGE_SDDR55=m
++CONFIG_USB_STORAGE_JUMPSHOT=m
++CONFIG_USB_STORAGE_ALAUDA=m
++# CONFIG_USB_STORAGE_ONETOUCH is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
++CONFIG_USB_LIBUSUAL=y
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++
++#
++# USB port drivers
++#
++CONFIG_USB_SERIAL=m
++# CONFIG_USB_EZUSB is not set
++CONFIG_USB_SERIAL_GENERIC=y
++# CONFIG_USB_SERIAL_AIRCABLE is not set
++# CONFIG_USB_SERIAL_ARK3116 is not set
++# CONFIG_USB_SERIAL_BELKIN is not set
++# CONFIG_USB_SERIAL_CH341 is not set
++# CONFIG_USB_SERIAL_WHITEHEAT is not set
++# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
++# CONFIG_USB_SERIAL_CP210X is not set
++# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
++# CONFIG_USB_SERIAL_EMPEG is not set
++# CONFIG_USB_SERIAL_FTDI_SIO is not set
++# CONFIG_USB_SERIAL_FUNSOFT is not set
++# CONFIG_USB_SERIAL_VISOR is not set
++# CONFIG_USB_SERIAL_IPAQ is not set
++# CONFIG_USB_SERIAL_IR is not set
++# CONFIG_USB_SERIAL_EDGEPORT is not set
++# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
++# CONFIG_USB_SERIAL_GARMIN is not set
++# CONFIG_USB_SERIAL_IPW is not set
++# CONFIG_USB_SERIAL_IUU is not set
++# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
++# CONFIG_USB_SERIAL_KEYSPAN is not set
++# CONFIG_USB_SERIAL_KLSI is not set
++# CONFIG_USB_SERIAL_KOBIL_SCT is not set
++# CONFIG_USB_SERIAL_MCT_U232 is not set
++# CONFIG_USB_SERIAL_MOS7720 is not set
++# CONFIG_USB_SERIAL_MOS7840 is not set
++# CONFIG_USB_SERIAL_MOTOROLA is not set
++# CONFIG_USB_SERIAL_NAVMAN is not set
++# CONFIG_USB_SERIAL_PL2303 is not set
++# CONFIG_USB_SERIAL_OTI6858 is not set
++# CONFIG_USB_SERIAL_QUALCOMM is not set
++# CONFIG_USB_SERIAL_SPCP8X5 is not set
++# CONFIG_USB_SERIAL_HP4X is not set
++# CONFIG_USB_SERIAL_SAFE is not set
++# CONFIG_USB_SERIAL_SIEMENS_MPI is not set
++# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
++# CONFIG_USB_SERIAL_SYMBOL is not set
++# CONFIG_USB_SERIAL_TI is not set
++# CONFIG_USB_SERIAL_CYBERJACK is not set
++# CONFIG_USB_SERIAL_XIRCOM is not set
++# CONFIG_USB_SERIAL_OPTION is not set
++# CONFIG_USB_SERIAL_OMNINET is not set
++# CONFIG_USB_SERIAL_OPTICON is not set
++# CONFIG_USB_SERIAL_DEBUG is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_SEVSEG is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_BERRY_CHARGE is not set
++CONFIG_USB_LED=m
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_SISUSBVGA is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++# CONFIG_USB_IOWARRIOR is not set
++# CONFIG_USB_TEST is not set
++# CONFIG_USB_ISIGHTFW is not set
++# CONFIG_USB_VST is not set
++CONFIG_USB_GADGET=m
++# CONFIG_USB_GADGET_DEBUG_FILES is not set
++# CONFIG_USB_GADGET_DEBUG_FS is not set
++CONFIG_USB_GADGET_VBUS_DRAW=2
++CONFIG_USB_GADGET_SELECTED=y
++# CONFIG_USB_GADGET_AT91 is not set
++# CONFIG_USB_GADGET_ATMEL_USBA is not set
++# CONFIG_USB_GADGET_FSL_USB2 is not set
++# CONFIG_USB_GADGET_LH7A40X is not set
++# CONFIG_USB_GADGET_OMAP is not set
++# CONFIG_USB_GADGET_PXA25X is not set
++# CONFIG_USB_GADGET_R8A66597 is not set
++# CONFIG_USB_GADGET_PXA27X is not set
++# CONFIG_USB_GADGET_S3C_HSOTG is not set
++# CONFIG_USB_GADGET_IMX is not set
++# CONFIG_USB_GADGET_S3C2410 is not set
++CONFIG_USB_GADGET_M66592=y
++CONFIG_USB_M66592=m
++# CONFIG_USB_GADGET_AMD5536UDC is not set
++# CONFIG_USB_GADGET_FSL_QE is not set
++# CONFIG_USB_GADGET_CI13XXX is not set
++# CONFIG_USB_GADGET_NET2280 is not set
++# CONFIG_USB_GADGET_GOKU is not set
++# CONFIG_USB_GADGET_LANGWELL is not set
++# CONFIG_USB_GADGET_DUMMY_HCD is not set
++CONFIG_USB_GADGET_DUALSPEED=y
++# CONFIG_USB_ZERO is not set
++# CONFIG_USB_AUDIO is not set
++# CONFIG_USB_ETH is not set
++# CONFIG_USB_GADGETFS is not set
++# CONFIG_USB_FILE_STORAGE is not set
++# CONFIG_USB_G_SERIAL is not set
++# CONFIG_USB_MIDI_GADGET is not set
++# CONFIG_USB_G_PRINTER is not set
++# CONFIG_USB_CDC_COMPOSITE is not set
++
++#
++# OTG and related infrastructure
++#
++# CONFIG_NOP_USB_XCEIV is not set
++CONFIG_UWB=m
++CONFIG_UWB_HWA=m
++CONFIG_UWB_WHCI=m
++# CONFIG_UWB_WLP is not set
++# CONFIG_UWB_I1480U is not set
++CONFIG_MMC=m
++# CONFIG_MMC_DEBUG is not set
++# CONFIG_MMC_UNSAFE_RESUME is not set
++
++#
++# MMC/SD/SDIO Card Drivers
++#
++CONFIG_MMC_BLOCK=m
++CONFIG_MMC_BLOCK_BOUNCE=y
++# CONFIG_SDIO_UART is not set
++# CONFIG_MMC_TEST is not set
++
++#
++# MMC/SD/SDIO Host Controller Drivers
++#
++# CONFIG_MMC_SDHCI is not set
++# CONFIG_MMC_AT91 is not set
++# CONFIG_MMC_ATMELMCI is not set
++# CONFIG_MMC_TIFM_SD is not set
++# CONFIG_MMC_CB710 is not set
++# CONFIG_MMC_VIA_SDMMC is not set
++# CONFIG_MEMSTICK is not set
++CONFIG_NEW_LEDS=y
++CONFIG_LEDS_CLASS=m
++
++#
++# LED drivers
++#
++
++#
++# LED Triggers
++#
++CONFIG_LEDS_TRIGGERS=y
++# CONFIG_LEDS_TRIGGER_TIMER is not set
++# CONFIG_LEDS_TRIGGER_IDE_DISK is not set
++# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
++# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
++# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
++
++#
++# iptables trigger is under Netfilter config (LED target)
++#
++# CONFIG_ACCESSIBILITY is not set
++# CONFIG_INFINIBAND is not set
++CONFIG_RTC_LIB=y
++CONFIG_RTC_CLASS=y
++CONFIG_RTC_HCTOSYS=y
++CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
++# CONFIG_RTC_DEBUG is not set
++
++#
++# RTC interfaces
++#
++CONFIG_RTC_INTF_SYSFS=y
++CONFIG_RTC_INTF_PROC=y
++CONFIG_RTC_INTF_DEV=y
++# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
++# CONFIG_RTC_DRV_TEST is not set
++
++#
++# SPI RTC drivers
++#
++
++#
++# Platform RTC drivers
++#
++CONFIG_RTC_DRV_CMOS=y
++# CONFIG_RTC_DRV_DS1286 is not set
++# CONFIG_RTC_DRV_DS1511 is not set
++# CONFIG_RTC_DRV_DS1553 is not set
++# CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
++# CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T35 is not set
++# CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_BQ4802 is not set
++# CONFIG_RTC_DRV_V3020 is not set
++
++#
++# on-CPU RTC drivers
++#
++# CONFIG_DMADEVICES is not set
++# CONFIG_AUXDISPLAY is not set
++# CONFIG_UIO is not set
++
++#
++# TI VLYNQ
++#
++CONFIG_STAGING=y
++# CONFIG_STAGING_EXCLUDE_BUILD is not set
++# CONFIG_ET131X is not set
++# CONFIG_USB_IP_COMMON is not set
++# CONFIG_W35UND is not set
++# CONFIG_PRISM2_USB is not set
++# CONFIG_ECHO is not set
++# CONFIG_OTUS is not set
++# CONFIG_COMEDI is not set
++# CONFIG_ASUS_OLED is not set
++# CONFIG_ALTERA_PCIE_CHDMA is not set
++# CONFIG_RTL8187SE is not set
++# CONFIG_RTL8192SU is not set
++# CONFIG_RTL8192E is not set
++# CONFIG_INPUT_MIMIO is not set
++# CONFIG_TRANZPORT is not set
++
++#
++# Android
++#
++
++#
++# Qualcomm MSM Camera And Video
++#
++
++#
++# Camera Sensor Selection
++#
++# CONFIG_INPUT_GPIO is not set
++# CONFIG_DST is not set
++# CONFIG_POHMELFS is not set
++# CONFIG_B3DFG is not set
++# CONFIG_PLAN9AUTH is not set
++# CONFIG_LINE6_USB is not set
++# CONFIG_USB_SERIAL_QUATECH2 is not set
++# CONFIG_USB_SERIAL_QUATECH_USB2 is not set
++# CONFIG_VT6655 is not set
++# CONFIG_VT6656 is not set
++# CONFIG_FB_UDL is not set
++# CONFIG_VME_BUS is not set
++
++#
++# RAR Register Driver
++#
++# CONFIG_RAR_REGISTER is not set
++# CONFIG_IIO is not set
++CONFIG_FB_SM7XX=y
++# CONFIG_FB_SM7XX_ACCEL is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=m
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XIP is not set
++CONFIG_EXT3_FS=y
++# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
++CONFIG_EXT3_FS_XATTR=y
++CONFIG_EXT3_FS_POSIX_ACL=y
++CONFIG_EXT3_FS_SECURITY=y
++CONFIG_EXT4_FS=y
++CONFIG_EXT4_FS_XATTR=y
++# CONFIG_EXT4_FS_POSIX_ACL is not set
++# CONFIG_EXT4_FS_SECURITY is not set
++# CONFIG_EXT4_DEBUG is not set
++CONFIG_JBD=y
++# CONFIG_JBD_DEBUG is not set
++CONFIG_JBD2=y
++# CONFIG_JBD2_DEBUG is not set
++CONFIG_FS_MBCACHE=y
++CONFIG_REISERFS_FS=m
++# CONFIG_REISERFS_CHECK is not set
++CONFIG_REISERFS_PROC_INFO=y
++CONFIG_REISERFS_FS_XATTR=y
++# CONFIG_REISERFS_FS_POSIX_ACL is not set
++# CONFIG_REISERFS_FS_SECURITY is not set
++CONFIG_JFS_FS=m
++CONFIG_JFS_POSIX_ACL=y
++# CONFIG_JFS_SECURITY is not set
++# CONFIG_JFS_DEBUG is not set
++# CONFIG_JFS_STATISTICS is not set
++CONFIG_FS_POSIX_ACL=y
++CONFIG_XFS_FS=m
++CONFIG_XFS_QUOTA=y
++CONFIG_XFS_POSIX_ACL=y
++# CONFIG_XFS_RT is not set
++# CONFIG_XFS_DEBUG is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++CONFIG_BTRFS_FS=m
++# CONFIG_BTRFS_FS_POSIX_ACL is not set
++# CONFIG_NILFS2_FS is not set
++CONFIG_FILE_LOCKING=y
++CONFIG_FSNOTIFY=y
++CONFIG_DNOTIFY=y
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++CONFIG_QUOTA=y
++# CONFIG_QUOTA_NETLINK_INTERFACE is not set
++CONFIG_PRINT_QUOTA_WARNING=y
++CONFIG_QUOTA_TREE=m
++# CONFIG_QFMT_V1 is not set
++CONFIG_QFMT_V2=m
++CONFIG_QUOTACTL=y
++CONFIG_AUTOFS_FS=m
++CONFIG_AUTOFS4_FS=m
++# CONFIG_FUSE_FS is not set
++
++#
++# Caches
++#
++CONFIG_FSCACHE=m
++# CONFIG_FSCACHE_STATS is not set
++# CONFIG_FSCACHE_HISTOGRAM is not set
++# CONFIG_FSCACHE_DEBUG is not set
++# CONFIG_FSCACHE_OBJECT_LIST is not set
++CONFIG_CACHEFILES=m
++# CONFIG_CACHEFILES_DEBUG is not set
++# CONFIG_CACHEFILES_HISTOGRAM is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++CONFIG_ISO9660_FS=m
++CONFIG_JOLIET=y
++CONFIG_ZISOFS=y
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=m
++CONFIG_MSDOS_FS=m
++CONFIG_VFAT_FS=m
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++CONFIG_NTFS_FS=m
++# CONFIG_NTFS_DEBUG is not set
++CONFIG_NTFS_RW=y
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_KCORE=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++# CONFIG_TMPFS_POSIX_ACL is not set
++# CONFIG_HUGETLB_PAGE is not set
++CONFIG_CONFIGFS_FS=m
++CONFIG_MISC_FILESYSTEMS=y
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_ECRYPT_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++CONFIG_CRAMFS=m
++CONFIG_SQUASHFS=m
++CONFIG_SQUASHFS_EMBEDDED=y
++CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_OMFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++CONFIG_ROMFS_FS=m
++CONFIG_ROMFS_BACKED_BY_BLOCK=y
++# CONFIG_ROMFS_BACKED_BY_MTD is not set
++# CONFIG_ROMFS_BACKED_BY_BOTH is not set
++CONFIG_ROMFS_ON_BLOCK=y
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=m
++CONFIG_NFS_V3=y
++CONFIG_NFS_V3_ACL=y
++# CONFIG_NFS_V4 is not set
++# CONFIG_NFS_FSCACHE is not set
++CONFIG_NFSD=m
++CONFIG_NFSD_V3=y
++# CONFIG_NFSD_V3_ACL is not set
++CONFIG_NFSD_V4=y
++CONFIG_LOCKD=m
++CONFIG_LOCKD_V4=y
++CONFIG_EXPORTFS=m
++CONFIG_NFS_ACL_SUPPORT=m
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=m
++CONFIG_SUNRPC_GSS=m
++CONFIG_RPCSEC_GSS_KRB5=m
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
++# CONFIG_SMB_FS is not set
++CONFIG_CIFS=m
++# CONFIG_CIFS_STATS is not set
++# CONFIG_CIFS_WEAK_PW_HASH is not set
++# CONFIG_CIFS_UPCALL is not set
++# CONFIG_CIFS_XATTR is not set
++# CONFIG_CIFS_DEBUG2 is not set
++# CONFIG_CIFS_DFS_UPCALL is not set
++# CONFIG_CIFS_EXPERIMENTAL is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="utf-8"
++CONFIG_NLS_CODEPAGE_437=m
++CONFIG_NLS_CODEPAGE_737=m
++CONFIG_NLS_CODEPAGE_775=m
++CONFIG_NLS_CODEPAGE_850=m
++CONFIG_NLS_CODEPAGE_852=m
++CONFIG_NLS_CODEPAGE_855=m
++CONFIG_NLS_CODEPAGE_857=m
++CONFIG_NLS_CODEPAGE_860=m
++CONFIG_NLS_CODEPAGE_861=m
++CONFIG_NLS_CODEPAGE_862=m
++CONFIG_NLS_CODEPAGE_863=m
++CONFIG_NLS_CODEPAGE_864=m
++CONFIG_NLS_CODEPAGE_865=m
++CONFIG_NLS_CODEPAGE_866=m
++CONFIG_NLS_CODEPAGE_869=m
++CONFIG_NLS_CODEPAGE_936=m
++CONFIG_NLS_CODEPAGE_950=m
++CONFIG_NLS_CODEPAGE_932=m
++CONFIG_NLS_CODEPAGE_949=m
++CONFIG_NLS_CODEPAGE_874=m
++CONFIG_NLS_ISO8859_8=m
++CONFIG_NLS_CODEPAGE_1250=m
++CONFIG_NLS_CODEPAGE_1251=m
++CONFIG_NLS_ASCII=m
++CONFIG_NLS_ISO8859_1=m
++CONFIG_NLS_ISO8859_2=m
++CONFIG_NLS_ISO8859_3=m
++CONFIG_NLS_ISO8859_4=m
++CONFIG_NLS_ISO8859_5=m
++CONFIG_NLS_ISO8859_6=m
++CONFIG_NLS_ISO8859_7=m
++CONFIG_NLS_ISO8859_9=m
++CONFIG_NLS_ISO8859_13=m
++CONFIG_NLS_ISO8859_14=m
++CONFIG_NLS_ISO8859_15=m
++CONFIG_NLS_KOI8_R=m
++CONFIG_NLS_KOI8_U=m
++CONFIG_NLS_UTF8=y
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_PRINTK_TIME=y
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_FRAME_WARN=1024
++# CONFIG_MAGIC_SYSRQ is not set
++CONFIG_STRIP_ASM_SYMS=y
++# CONFIG_UNUSED_SYMBOLS is not set
++CONFIG_DEBUG_FS=y
++# CONFIG_HEADERS_CHECK is not set
++# CONFIG_DEBUG_KERNEL is not set
++# CONFIG_SLUB_DEBUG_ON is not set
++# CONFIG_SLUB_STATS is not set
++CONFIG_STACKTRACE=y
++# CONFIG_DEBUG_MEMORY_INIT is not set
++# CONFIG_RCU_CPU_STALL_DETECTOR is not set
++CONFIG_SYSCTL_SYSCALL_CHECK=y
++CONFIG_NOP_TRACER=y
++CONFIG_HAVE_FUNCTION_TRACER=y
++CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
++CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
++CONFIG_HAVE_DYNAMIC_FTRACE=y
++CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
++CONFIG_RING_BUFFER=y
++CONFIG_EVENT_TRACING=y
++CONFIG_CONTEXT_SWITCH_TRACER=y
++CONFIG_RING_BUFFER_ALLOW_SWAP=y
++CONFIG_TRACING=y
++CONFIG_TRACING_SUPPORT=y
++# CONFIG_FTRACE is not set
++# CONFIG_DYNAMIC_DEBUG is not set
++# CONFIG_SAMPLES is not set
++CONFIG_HAVE_ARCH_KGDB=y
++CONFIG_CMDLINE=""
++
++#
++# Security options
++#
++CONFIG_KEYS=y
++CONFIG_KEYS_DEBUG_PROC_KEYS=y
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITYFS is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_XOR_BLOCKS=m
++CONFIG_ASYNC_CORE=m
++CONFIG_ASYNC_MEMCPY=m
++CONFIG_ASYNC_XOR=m
++CONFIG_ASYNC_PQ=m
++CONFIG_ASYNC_RAID6_RECOV=m
++CONFIG_CRYPTO=y
++
++#
++# Crypto core or helper
++#
++CONFIG_CRYPTO_FIPS=y
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_ALGAPI2=y
++CONFIG_CRYPTO_AEAD=m
++CONFIG_CRYPTO_AEAD2=y
++CONFIG_CRYPTO_BLKCIPHER=m
++CONFIG_CRYPTO_BLKCIPHER2=y
++CONFIG_CRYPTO_HASH=y
++CONFIG_CRYPTO_HASH2=y
++CONFIG_CRYPTO_RNG=m
++CONFIG_CRYPTO_RNG2=y
++CONFIG_CRYPTO_PCOMP=y
++CONFIG_CRYPTO_MANAGER=m
++CONFIG_CRYPTO_MANAGER2=y
++CONFIG_CRYPTO_GF128MUL=m
++CONFIG_CRYPTO_NULL=m
++CONFIG_CRYPTO_WORKQUEUE=y
++CONFIG_CRYPTO_CRYPTD=m
++CONFIG_CRYPTO_AUTHENC=m
++CONFIG_CRYPTO_TEST=m
++
++#
++# Authenticated Encryption with Associated Data
++#
++CONFIG_CRYPTO_CCM=m
++CONFIG_CRYPTO_GCM=m
++CONFIG_CRYPTO_SEQIV=m
++
++#
++# Block modes
++#
++CONFIG_CRYPTO_CBC=m
++CONFIG_CRYPTO_CTR=m
++# CONFIG_CRYPTO_CTS is not set
++CONFIG_CRYPTO_ECB=m
++CONFIG_CRYPTO_LRW=m
++CONFIG_CRYPTO_PCBC=m
++CONFIG_CRYPTO_XTS=m
++
++#
++# Hash modes
++#
++CONFIG_CRYPTO_HMAC=m
++CONFIG_CRYPTO_XCBC=m
++# CONFIG_CRYPTO_VMAC is not set
++
++#
++# Digest
++#
++CONFIG_CRYPTO_CRC32C=m
++CONFIG_CRYPTO_GHASH=m
++CONFIG_CRYPTO_MD4=m
++CONFIG_CRYPTO_MD5=y
++CONFIG_CRYPTO_MICHAEL_MIC=m
++CONFIG_CRYPTO_RMD128=m
++CONFIG_CRYPTO_RMD160=m
++CONFIG_CRYPTO_RMD256=m
++CONFIG_CRYPTO_RMD320=m
++CONFIG_CRYPTO_SHA1=m
++CONFIG_CRYPTO_SHA256=m
++CONFIG_CRYPTO_SHA512=m
++CONFIG_CRYPTO_TGR192=m
++CONFIG_CRYPTO_WP512=m
++
++#
++# Ciphers
++#
++CONFIG_CRYPTO_AES=m
++CONFIG_CRYPTO_ANUBIS=m
++CONFIG_CRYPTO_ARC4=m
++CONFIG_CRYPTO_BLOWFISH=m
++CONFIG_CRYPTO_CAMELLIA=m
++CONFIG_CRYPTO_CAST5=m
++CONFIG_CRYPTO_CAST6=m
++CONFIG_CRYPTO_DES=m
++CONFIG_CRYPTO_FCRYPT=m
++CONFIG_CRYPTO_KHAZAD=m
++CONFIG_CRYPTO_SALSA20=m
++CONFIG_CRYPTO_SEED=m
++CONFIG_CRYPTO_SERPENT=m
++CONFIG_CRYPTO_TEA=m
++CONFIG_CRYPTO_TWOFISH=m
++CONFIG_CRYPTO_TWOFISH_COMMON=m
++
++#
++# Compression
++#
++CONFIG_CRYPTO_DEFLATE=m
++CONFIG_CRYPTO_ZLIB=m
++CONFIG_CRYPTO_LZO=m
++
++#
++# Random Number Generation
++#
++CONFIG_CRYPTO_ANSI_CPRNG=m
++CONFIG_CRYPTO_HW=y
++# CONFIG_CRYPTO_DEV_HIFN_795X is not set
++CONFIG_BINARY_PRINTF=y
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++CONFIG_GENERIC_FIND_LAST_BIT=y
++# CONFIG_CRC_CCITT is not set
++CONFIG_CRC16=y
++CONFIG_CRC_T10DIF=y
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++CONFIG_LIBCRC32C=m
++CONFIG_AUDIT_GENERIC=y
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=m
++CONFIG_LZO_COMPRESS=m
++CONFIG_LZO_DECOMPRESS=m
++CONFIG_DECOMPRESS_GZIP=y
++CONFIG_DECOMPRESS_BZIP2=y
++CONFIG_DECOMPRESS_LZMA=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
++CONFIG_NLATTR=y
+diff --git a/arch/mips/configs/lemote2f_minimal_defconfig b/arch/mips/configs/lemote2f_minimal_defconfig
+new file mode 100644
+index 0000000..4f7e23e
+--- /dev/null
++++ b/arch/mips/configs/lemote2f_minimal_defconfig
+@@ -0,0 +1,1374 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.32
++# Thu Dec 10 17:01:59 2009
++#
++CONFIG_MIPS=y
++
++#
++# Machine selection
++#
++# CONFIG_MACH_ALCHEMY is not set
++# CONFIG_AR7 is not set
++# CONFIG_BASLER_EXCITE is not set
++# CONFIG_BCM47XX is not set
++# CONFIG_BCM63XX is not set
++# CONFIG_MIPS_COBALT is not set
++# CONFIG_MACH_DECSTATION is not set
++# CONFIG_MACH_JAZZ is not set
++# CONFIG_LASAT is not set
++CONFIG_MACH_LOONGSON=y
++# CONFIG_MIPS_MALTA is not set
++# CONFIG_MIPS_SIM is not set
++# CONFIG_NEC_MARKEINS is not set
++# CONFIG_MACH_VR41XX is not set
++# CONFIG_NXP_STB220 is not set
++# CONFIG_NXP_STB225 is not set
++# CONFIG_PNX8550_JBS is not set
++# CONFIG_PNX8550_STB810 is not set
++# CONFIG_PMC_MSP is not set
++# CONFIG_PMC_YOSEMITE is not set
++# CONFIG_POWERTV is not set
++# CONFIG_SGI_IP22 is not set
++# CONFIG_SGI_IP27 is not set
++# CONFIG_SGI_IP28 is not set
++# CONFIG_SGI_IP32 is not set
++# CONFIG_SIBYTE_CRHINE is not set
++# CONFIG_SIBYTE_CARMEL is not set
++# CONFIG_SIBYTE_CRHONE is not set
++# CONFIG_SIBYTE_RHONE is not set
++# CONFIG_SIBYTE_SWARM is not set
++# CONFIG_SIBYTE_LITTLESUR is not set
++# CONFIG_SIBYTE_SENTOSA is not set
++# CONFIG_SIBYTE_BIGSUR is not set
++# CONFIG_SNI_RM is not set
++# CONFIG_MACH_TX39XX is not set
++# CONFIG_MACH_TX49XX is not set
++# CONFIG_MIKROTIK_RB532 is not set
++# CONFIG_WR_PPMC is not set
++# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
++# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
++# CONFIG_ALCHEMY_GPIO_INDIRECT is not set
++CONFIG_ARCH_SPARSEMEM_ENABLE=y
++# CONFIG_LEMOTE_FULOONG2E is not set
++CONFIG_LEMOTE_MACH2F=y
++CONFIG_CS5536=y
++# CONFIG_CS5536_MFGPT is not set
++CONFIG_LOONGSON_UART_BASE=y
++
++#
++# Loongson Platform Specific Drivers
++#
++# CONFIG_LOONGSON_PLATFORM_DEVICES is not set
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_ARCH_SUPPORTS_OPROFILE=y
++CONFIG_GENERIC_FIND_NEXT_BIT=y
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_GENERIC_TIME=y
++CONFIG_GENERIC_CMOS_UPDATE=y
++CONFIG_SCHED_OMIT_FRAME_POINTER=y
++CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
++CONFIG_CEVT_R4K_LIB=y
++CONFIG_CEVT_R4K=y
++CONFIG_CSRC_R4K_LIB=y
++CONFIG_CSRC_R4K=y
++CONFIG_DMA_NONCOHERENT=y
++CONFIG_DMA_NEED_PCI_MAP_STATE=y
++CONFIG_EARLY_PRINTK=y
++CONFIG_SYS_HAS_EARLY_PRINTK=y
++CONFIG_I8259=y
++# CONFIG_NO_IOPORT is not set
++CONFIG_GENERIC_ISA_DMA=y
++CONFIG_GENERIC_ISA_DMA_SUPPORT_BROKEN=y
++# CONFIG_CPU_BIG_ENDIAN is not set
++CONFIG_CPU_LITTLE_ENDIAN=y
++CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
++CONFIG_IRQ_CPU=y
++CONFIG_BOOT_ELF32=y
++CONFIG_MIPS_L1_CACHE_SHIFT=5
++
++#
++# CPU selection
++#
++# CONFIG_CPU_LOONGSON2E is not set
++CONFIG_CPU_LOONGSON2F=y
++# CONFIG_CPU_MIPS32_R1 is not set
++# CONFIG_CPU_MIPS32_R2 is not set
++# CONFIG_CPU_MIPS64_R1 is not set
++# CONFIG_CPU_MIPS64_R2 is not set
++# CONFIG_CPU_R3000 is not set
++# CONFIG_CPU_TX39XX is not set
++# CONFIG_CPU_VR41XX is not set
++# CONFIG_CPU_R4300 is not set
++# CONFIG_CPU_R4X00 is not set
++# CONFIG_CPU_TX49XX is not set
++# CONFIG_CPU_R5000 is not set
++# CONFIG_CPU_R5432 is not set
++# CONFIG_CPU_R5500 is not set
++# CONFIG_CPU_R6000 is not set
++# CONFIG_CPU_NEVADA is not set
++# CONFIG_CPU_R8000 is not set
++# CONFIG_CPU_R10000 is not set
++# CONFIG_CPU_RM7000 is not set
++# CONFIG_CPU_RM9000 is not set
++# CONFIG_CPU_SB1 is not set
++# CONFIG_CPU_CAVIUM_OCTEON is not set
++CONFIG_SYS_SUPPORTS_ZBOOT=y
++CONFIG_SYS_SUPPORTS_ZBOOT_UART16550=y
++CONFIG_CPU_LOONGSON2=y
++CONFIG_SYS_HAS_CPU_LOONGSON2F=y
++CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
++CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
++CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
++CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
++CONFIG_CPU_SUPPORTS_CPUFREQ=y
++CONFIG_CPU_SUPPORTS_ADDRWINCFG=y
++CONFIG_CPU_SUPPORTS_UNCACHED_ACCELERATED=y
++
++#
++# Kernel type
++#
++# CONFIG_32BIT is not set
++CONFIG_64BIT=y
++# CONFIG_PAGE_SIZE_4KB is not set
++# CONFIG_PAGE_SIZE_8KB is not set
++CONFIG_PAGE_SIZE_16KB=y
++# CONFIG_PAGE_SIZE_32KB is not set
++# CONFIG_PAGE_SIZE_64KB is not set
++CONFIG_BOARD_SCACHE=y
++CONFIG_MIPS_MT_DISABLED=y
++# CONFIG_MIPS_MT_SMP is not set
++# CONFIG_MIPS_MT_SMTC is not set
++CONFIG_CPU_HAS_WB=y
++CONFIG_CPU_HAS_SYNC=y
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_CPU_SUPPORTS_HIGHMEM=y
++CONFIG_SYS_SUPPORTS_HIGHMEM=y
++CONFIG_ARCH_POPULATES_NODE_MAP=y
++CONFIG_SELECT_MEMORY_MODEL=y
++# CONFIG_FLATMEM_MANUAL is not set
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++CONFIG_SPARSEMEM_MANUAL=y
++CONFIG_SPARSEMEM=y
++CONFIG_HAVE_MEMORY_PRESENT=y
++CONFIG_SPARSEMEM_STATIC=y
++CONFIG_PAGEFLAGS_EXTENDED=y
++CONFIG_SPLIT_PTLOCK_CPUS=4
++CONFIG_PHYS_ADDR_T_64BIT=y
++CONFIG_ZONE_DMA_FLAG=0
++CONFIG_VIRT_TO_BUS=y
++CONFIG_HAVE_MLOCK=y
++CONFIG_HAVE_MLOCKED_PAGE_BIT=y
++# CONFIG_KSM is not set
++CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
++CONFIG_TICK_ONESHOT=y
++CONFIG_NO_HZ=y
++CONFIG_HIGH_RES_TIMERS=y
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++# CONFIG_HR_SCHED_CLOCK is not set
++# CONFIG_HZ_48 is not set
++# CONFIG_HZ_100 is not set
++# CONFIG_HZ_128 is not set
++CONFIG_HZ_250=y
++# CONFIG_HZ_256 is not set
++# CONFIG_HZ_1000 is not set
++# CONFIG_HZ_1024 is not set
++CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
++CONFIG_HZ=250
++# CONFIG_PREEMPT_NONE is not set
++# CONFIG_PREEMPT_VOLUNTARY is not set
++CONFIG_PREEMPT=y
++CONFIG_KEXEC=y
++# CONFIG_SECCOMP is not set
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++CONFIG_CONSTRUCTORS=y
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_LOCK_KERNEL=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++# CONFIG_LOCALVERSION_AUTO is not set
++CONFIG_HAVE_KERNEL_GZIP=y
++CONFIG_HAVE_KERNEL_BZIP2=y
++CONFIG_HAVE_KERNEL_LZMA=y
++CONFIG_HAVE_KERNEL_LZO=y
++CONFIG_KERNEL_GZIP=y
++# CONFIG_KERNEL_BZIP2 is not set
++# CONFIG_KERNEL_LZMA is not set
++# CONFIG_KERNEL_LZO is not set
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++# CONFIG_POSIX_MQUEUE is not set
++CONFIG_BSD_PROCESS_ACCT=y
++CONFIG_BSD_PROCESS_ACCT_V3=y
++# CONFIG_TASKSTATS is not set
++CONFIG_AUDIT=y
++
++#
++# RCU Subsystem
++#
++CONFIG_TREE_RCU=y
++# CONFIG_TREE_PREEMPT_RCU is not set
++# CONFIG_RCU_TRACE is not set
++CONFIG_RCU_FANOUT=64
++# CONFIG_RCU_FANOUT_EXACT is not set
++# CONFIG_TREE_RCU_TRACE is not set
++CONFIG_IKCONFIG=y
++CONFIG_IKCONFIG_PROC=y
++CONFIG_LOG_BUF_SHIFT=15
++# CONFIG_GROUP_SCHED is not set
++# CONFIG_CGROUPS is not set
++CONFIG_SYSFS_DEPRECATED=y
++CONFIG_SYSFS_DEPRECATED_V2=y
++# CONFIG_RELAY is not set
++# CONFIG_NAMESPACES is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE="./ramdisk.cpio.gz"
++CONFIG_INITRAMFS_ROOT_UID=0
++CONFIG_INITRAMFS_ROOT_GID=0
++CONFIG_RD_GZIP=y
++# CONFIG_RD_BZIP2 is not set
++# CONFIG_RD_LZMA is not set
++# CONFIG_INITRAMFS_COMPRESSION_NONE is not set
++CONFIG_INITRAMFS_COMPRESSION_GZIP=y
++# CONFIG_INITRAMFS_COMPRESSION_BZIP2 is not set
++# CONFIG_INITRAMFS_COMPRESSION_LZMA is not set
++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
++CONFIG_SYSCTL=y
++CONFIG_ANON_INODES=y
++CONFIG_EMBEDDED=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_ALL is not set
++# CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_PCSPKR_PLATFORM=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_AIO=y
++
++#
++# Kernel Performance Events And Counters
++#
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_PCI_QUIRKS=y
++CONFIG_SLUB_DEBUG=y
++CONFIG_COMPAT_BRK=y
++# CONFIG_SLAB is not set
++CONFIG_SLUB=y
++# CONFIG_SLOB is not set
++CONFIG_PROFILING=y
++# CONFIG_OPROFILE is not set
++CONFIG_HAVE_OPROFILE=y
++CONFIG_HAVE_SYSCALL_WRAPPERS=y
++
++#
++# GCOV-based kernel profiling
++#
++# CONFIG_SLOW_WORK is not set
++CONFIG_HAVE_GENERIC_DMA_COHERENT=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++CONFIG_BASE_SMALL=0
++# CONFIG_MODULES is not set
++CONFIG_BLOCK=y
++# CONFIG_BLK_DEV_BSG is not set
++# CONFIG_BLK_DEV_INTEGRITY is not set
++CONFIG_BLOCK_COMPAT=y
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++# CONFIG_IOSCHED_AS is not set
++# CONFIG_IOSCHED_DEADLINE is not set
++# CONFIG_IOSCHED_CFQ is not set
++# CONFIG_DEFAULT_AS is not set
++# CONFIG_DEFAULT_DEADLINE is not set
++# CONFIG_DEFAULT_CFQ is not set
++CONFIG_DEFAULT_NOOP=y
++CONFIG_DEFAULT_IOSCHED="noop"
++# CONFIG_FREEZER is not set
++
++#
++# Bus options (PCI, PCMCIA, EISA, ISA, TC)
++#
++CONFIG_HW_HAS_PCI=y
++CONFIG_PCI=y
++CONFIG_PCI_DOMAINS=y
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++# CONFIG_PCI_LEGACY is not set
++# CONFIG_PCI_DEBUG is not set
++# CONFIG_PCI_STUB is not set
++# CONFIG_PCI_IOV is not set
++CONFIG_ISA=y
++CONFIG_MMU=y
++# CONFIG_PCCARD is not set
++# CONFIG_HOTPLUG_PCI is not set
++
++#
++# Executable file formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++# CONFIG_HAVE_AOUT is not set
++# CONFIG_BINFMT_MISC is not set
++CONFIG_MIPS32_COMPAT=y
++CONFIG_COMPAT=y
++CONFIG_SYSVIPC_COMPAT=y
++CONFIG_MIPS32_O32=y
++CONFIG_MIPS32_N32=y
++CONFIG_BINFMT_ELF32=y
++
++#
++# Power management options
++#
++CONFIG_ARCH_HIBERNATION_POSSIBLE=y
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++# CONFIG_PM is not set
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++CONFIG_PACKET_MMAP=y
++CONFIG_UNIX=y
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++# CONFIG_IP_PNP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++# CONFIG_INET_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
++# CONFIG_INET_XFRM_MODE_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_BEET is not set
++# CONFIG_INET_LRO is not set
++# CONFIG_INET_DIAG is not set
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IPV6 is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_RDS is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_NET_DSA is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++# CONFIG_PHONET is not set
++# CONFIG_IEEE802154 is not set
++# CONFIG_NET_SCHED is not set
++# CONFIG_DCB is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++# CONFIG_WIRELESS is not set
++# CONFIG_WIMAX is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++# CONFIG_DEVTMPFS is not set
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++CONFIG_FW_LOADER=y
++CONFIG_FIRMWARE_IN_KERNEL=y
++CONFIG_EXTRA_FIRMWARE=""
++# CONFIG_DEBUG_DRIVER is not set
++# CONFIG_DEBUG_DEVRES is not set
++# CONFIG_SYS_HYPERVISOR is not set
++# CONFIG_CONNECTOR is not set
++# CONFIG_MTD is not set
++# CONFIG_PARPORT is not set
++# CONFIG_PNP is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_CPQ_DA is not set
++# CONFIG_BLK_CPQ_CISS_DA is not set
++# CONFIG_BLK_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_UMEM is not set
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_SX8 is not set
++# CONFIG_BLK_DEV_UB is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=16
++CONFIG_BLK_DEV_RAM_SIZE=8192
++# CONFIG_BLK_DEV_XIP is not set
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++# CONFIG_BLK_DEV_HD is not set
++# CONFIG_MISC_DEVICES is not set
++CONFIG_HAVE_IDE=y
++CONFIG_IDE=y
++
++#
++# Please see Documentation/ide/ide.txt for help/info on IDE drives
++#
++CONFIG_IDE_XFER_MODE=y
++CONFIG_IDE_TIMINGS=y
++# CONFIG_BLK_DEV_IDE_SATA is not set
++CONFIG_IDE_GD=y
++CONFIG_IDE_GD_ATA=y
++# CONFIG_IDE_GD_ATAPI is not set
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_IDE_TASK_IOCTL is not set
++# CONFIG_IDE_PROC_FS is not set
++
++#
++# IDE chipset support/bugfixes
++#
++# CONFIG_IDE_GENERIC is not set
++# CONFIG_BLK_DEV_PLATFORM is not set
++CONFIG_BLK_DEV_IDEDMA_SFF=y
++
++#
++# PCI IDE chipsets support
++#
++CONFIG_BLK_DEV_IDEPCI=y
++# CONFIG_IDEPCI_PCIBUS_ORDER is not set
++# CONFIG_BLK_DEV_GENERIC is not set
++# CONFIG_BLK_DEV_OPTI621 is not set
++CONFIG_BLK_DEV_IDEDMA_PCI=y
++# CONFIG_BLK_DEV_AEC62XX is not set
++# CONFIG_BLK_DEV_ALI15X3 is not set
++CONFIG_BLK_DEV_AMD74XX=y
++# CONFIG_BLK_DEV_CMD64X is not set
++# CONFIG_BLK_DEV_TRIFLEX is not set
++# CONFIG_BLK_DEV_CS5520 is not set
++# CONFIG_BLK_DEV_CS5530 is not set
++# CONFIG_BLK_DEV_HPT366 is not set
++# CONFIG_BLK_DEV_JMICRON is not set
++# CONFIG_BLK_DEV_SC1200 is not set
++# CONFIG_BLK_DEV_PIIX is not set
++# CONFIG_BLK_DEV_IT8172 is not set
++# CONFIG_BLK_DEV_IT8213 is not set
++# CONFIG_BLK_DEV_IT821X is not set
++# CONFIG_BLK_DEV_NS87415 is not set
++# CONFIG_BLK_DEV_PDC202XX_OLD is not set
++# CONFIG_BLK_DEV_PDC202XX_NEW is not set
++# CONFIG_BLK_DEV_SVWKS is not set
++# CONFIG_BLK_DEV_SIIMAGE is not set
++# CONFIG_BLK_DEV_SLC90E66 is not set
++# CONFIG_BLK_DEV_TRM290 is not set
++# CONFIG_BLK_DEV_VIA82CXXX is not set
++# CONFIG_BLK_DEV_TC86C001 is not set
++
++#
++# Other IDE chipsets support
++#
++
++#
++# Note: most of these also require special kernel boot parameters
++#
++# CONFIG_BLK_DEV_4DRIVES is not set
++# CONFIG_BLK_DEV_ALI14XX is not set
++# CONFIG_BLK_DEV_DTC2278 is not set
++# CONFIG_BLK_DEV_HT6560B is not set
++# CONFIG_BLK_DEV_QD65XX is not set
++# CONFIG_BLK_DEV_UMC8672 is not set
++CONFIG_BLK_DEV_IDEDMA=y
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++CONFIG_SCSI_DMA=y
++# CONFIG_SCSI_TGT is not set
++# CONFIG_SCSI_NETLINK is not set
++# CONFIG_SCSI_PROC_FS is not set
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++# CONFIG_CHR_DEV_SG is not set
++# CONFIG_CHR_DEV_SCH is not set
++# CONFIG_SCSI_MULTI_LUN is not set
++# CONFIG_SCSI_CONSTANTS is not set
++# CONFIG_SCSI_LOGGING is not set
++# CONFIG_SCSI_SCAN_ASYNC is not set
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++# CONFIG_SCSI_ISCSI_ATTRS is not set
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++# CONFIG_SCSI_LOWLEVEL is not set
++# CONFIG_SCSI_DH is not set
++# CONFIG_SCSI_OSD_INITIATOR is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++# CONFIG_FUSION is not set
++
++#
++# IEEE 1394 (FireWire) support
++#
++
++#
++# You can enable one or both FireWire driver stacks.
++#
++
++#
++# See the help texts for more information.
++#
++# CONFIG_FIREWIRE is not set
++# CONFIG_IEEE1394 is not set
++# CONFIG_I2O is not set
++CONFIG_NETDEVICES=y
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++# CONFIG_ARCNET is not set
++# CONFIG_PHYLIB is not set
++CONFIG_NET_ETHERNET=y
++CONFIG_MII=y
++# CONFIG_AX88796 is not set
++# CONFIG_HAPPYMEAL is not set
++# CONFIG_SUNGEM is not set
++# CONFIG_CASSINI is not set
++# CONFIG_NET_VENDOR_3COM is not set
++# CONFIG_NET_VENDOR_SMC is not set
++# CONFIG_SMC91X is not set
++# CONFIG_DM9000 is not set
++# CONFIG_ETHOC is not set
++# CONFIG_NET_VENDOR_RACAL is not set
++# CONFIG_DNET is not set
++# CONFIG_NET_TULIP is not set
++# CONFIG_AT1700 is not set
++# CONFIG_DEPCA is not set
++# CONFIG_HP100 is not set
++# CONFIG_NET_ISA is not set
++# CONFIG_IBM_NEW_EMAC_ZMII is not set
++# CONFIG_IBM_NEW_EMAC_RGMII is not set
++# CONFIG_IBM_NEW_EMAC_TAH is not set
++# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
++# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
++# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
++# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
++CONFIG_NET_PCI=y
++# CONFIG_PCNET32 is not set
++# CONFIG_AMD8111_ETH is not set
++# CONFIG_ADAPTEC_STARFIRE is not set
++# CONFIG_AC3200 is not set
++# CONFIG_APRICOT is not set
++# CONFIG_B44 is not set
++# CONFIG_FORCEDETH is not set
++# CONFIG_CS89x0 is not set
++# CONFIG_TC35815 is not set
++# CONFIG_E100 is not set
++# CONFIG_FEALNX is not set
++# CONFIG_NATSEMI is not set
++# CONFIG_NE2K_PCI is not set
++# CONFIG_8139CP is not set
++CONFIG_8139TOO=y
++CONFIG_8139TOO_PIO=y
++# CONFIG_8139TOO_TUNE_TWISTER is not set
++# CONFIG_8139TOO_8129 is not set
++# CONFIG_8139_OLD_RX_RESET is not set
++# CONFIG_R6040 is not set
++# CONFIG_SIS900 is not set
++# CONFIG_EPIC100 is not set
++# CONFIG_SMSC9420 is not set
++# CONFIG_SUNDANCE is not set
++# CONFIG_TLAN is not set
++# CONFIG_KS8842 is not set
++# CONFIG_KS8851_MLL is not set
++# CONFIG_VIA_RHINE is not set
++# CONFIG_SC92031 is not set
++# CONFIG_ATL2 is not set
++CONFIG_NETDEV_1000=y
++# CONFIG_ACENIC is not set
++# CONFIG_DL2K is not set
++# CONFIG_E1000 is not set
++# CONFIG_E1000E is not set
++# CONFIG_IP1000 is not set
++# CONFIG_IGB is not set
++# CONFIG_IGBVF is not set
++# CONFIG_NS83820 is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++CONFIG_R8169=y
++# CONFIG_SIS190 is not set
++# CONFIG_SKGE is not set
++# CONFIG_SKY2 is not set
++# CONFIG_VIA_VELOCITY is not set
++# CONFIG_TIGON3 is not set
++# CONFIG_BNX2 is not set
++# CONFIG_CNIC is not set
++# CONFIG_QLA3XXX is not set
++# CONFIG_ATL1 is not set
++# CONFIG_ATL1E is not set
++# CONFIG_ATL1C is not set
++# CONFIG_JME is not set
++# CONFIG_NETDEV_10000 is not set
++# CONFIG_TR is not set
++# CONFIG_WLAN is not set
++
++#
++# Enable WiMAX (Networking options) to see the WiMAX drivers
++#
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_WAN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_NET_FC is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++# CONFIG_PHONE is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_PSAUX=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_EVDEV is not set
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++CONFIG_KEYBOARD_ATKBD=y
++# CONFIG_KEYBOARD_LKKBD is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_OPENCORES is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++CONFIG_INPUT_MOUSE=y
++CONFIG_MOUSE_PS2=y
++# CONFIG_MOUSE_PS2_ALPS is not set
++# CONFIG_MOUSE_PS2_LOGIPS2PP is not set
++CONFIG_MOUSE_PS2_SYNAPTICS=y
++# CONFIG_MOUSE_PS2_TRACKPOINT is not set
++# CONFIG_MOUSE_PS2_ELANTECH is not set
++# CONFIG_MOUSE_PS2_SENTELIC is not set
++# CONFIG_MOUSE_PS2_TOUCHKIT is not set
++# CONFIG_MOUSE_SERIAL is not set
++# CONFIG_MOUSE_APPLETOUCH is not set
++# CONFIG_MOUSE_BCM5974 is not set
++# CONFIG_MOUSE_INPORT is not set
++# CONFIG_MOUSE_LOGIBM is not set
++# CONFIG_MOUSE_PC110PAD is not set
++# CONFIG_MOUSE_VSXXXAA is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++# CONFIG_INPUT_TOUCHSCREEN is not set
++# CONFIG_INPUT_MISC is not set
++
++#
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++CONFIG_SERIO_I8042=y
++# CONFIG_SERIO_SERPORT is not set
++# CONFIG_SERIO_PCIPS2 is not set
++CONFIG_SERIO_LIBPS2=y
++# CONFIG_SERIO_RAW is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_CONSOLE_TRANSLATIONS=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
++# CONFIG_DEVKMEM is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++# CONFIG_NOZOMI is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++# CONFIG_SERIAL_8250_PCI is not set
++CONFIG_SERIAL_8250_NR_UARTS=4
++CONFIG_SERIAL_8250_RUNTIME_UARTS=4
++# CONFIG_SERIAL_8250_EXTENDED is not set
++
++#
++# Non-8250 serial port support
++#
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++# CONFIG_SERIAL_JSM is not set
++CONFIG_UNIX98_PTYS=y
++# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=16
++# CONFIG_IPMI_HANDLER is not set
++# CONFIG_HW_RANDOM is not set
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_DEVPORT=y
++# CONFIG_I2C is not set
++# CONFIG_SPI is not set
++
++#
++# PPS support
++#
++# CONFIG_PPS is not set
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++# CONFIG_HWMON is not set
++# CONFIG_THERMAL is not set
++# CONFIG_WATCHDOG is not set
++CONFIG_SSB_POSSIBLE=y
++
++#
++# Sonics Silicon Backplane
++#
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_CORE is not set
++# CONFIG_MFD_SM501 is not set
++# CONFIG_HTC_PASIC3 is not set
++# CONFIG_MFD_TMIO is not set
++# CONFIG_REGULATOR is not set
++# CONFIG_MEDIA_SUPPORT is not set
++
++#
++# Graphics support
++#
++CONFIG_VGA_ARB=y
++# CONFIG_DRM is not set
++# CONFIG_VGASTATE is not set
++CONFIG_VIDEO_OUTPUT_CONTROL=y
++CONFIG_FB=y
++CONFIG_FIRMWARE_EDID=y
++# CONFIG_FB_DDC is not set
++CONFIG_FB_BOOT_VESA_SUPPORT=y
++CONFIG_FB_CFB_FILLRECT=y
++CONFIG_FB_CFB_COPYAREA=y
++CONFIG_FB_CFB_IMAGEBLIT=y
++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
++# CONFIG_FB_SYS_FILLRECT is not set
++# CONFIG_FB_SYS_COPYAREA is not set
++# CONFIG_FB_SYS_IMAGEBLIT is not set
++# CONFIG_FB_FOREIGN_ENDIAN is not set
++# CONFIG_FB_SYS_FOPS is not set
++# CONFIG_FB_SVGALIB is not set
++# CONFIG_FB_MACMODES is not set
++# CONFIG_FB_BACKLIGHT is not set
++CONFIG_FB_MODE_HELPERS=y
++CONFIG_FB_TILEBLITTING=y
++
++#
++# Frame buffer hardware drivers
++#
++# CONFIG_FB_CIRRUS is not set
++# CONFIG_FB_PM2 is not set
++# CONFIG_FB_CYBER2000 is not set
++# CONFIG_FB_ASILIANT is not set
++# CONFIG_FB_IMSTT is not set
++# CONFIG_FB_S1D13XXX is not set
++# CONFIG_FB_NVIDIA is not set
++# CONFIG_FB_RIVA is not set
++# CONFIG_FB_MATROX is not set
++# CONFIG_FB_RADEON is not set
++# CONFIG_FB_ATY128 is not set
++# CONFIG_FB_ATY is not set
++# CONFIG_FB_S3 is not set
++# CONFIG_FB_SAVAGE is not set
++CONFIG_FB_SIS=y
++CONFIG_FB_SIS_300=y
++CONFIG_FB_SIS_315=y
++# CONFIG_FB_VIA is not set
++# CONFIG_FB_NEOMAGIC is not set
++# CONFIG_FB_KYRO is not set
++# CONFIG_FB_3DFX is not set
++# CONFIG_FB_VOODOO1 is not set
++# CONFIG_FB_VT8623 is not set
++# CONFIG_FB_TRIDENT is not set
++# CONFIG_FB_ARK is not set
++# CONFIG_FB_PM3 is not set
++# CONFIG_FB_CARMINE is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FB_METRONOME is not set
++# CONFIG_FB_MB862XX is not set
++# CONFIG_FB_BROADSHEET is not set
++CONFIG_BACKLIGHT_LCD_SUPPORT=y
++# CONFIG_LCD_CLASS_DEVICE is not set
++CONFIG_BACKLIGHT_CLASS_DEVICE=y
++CONFIG_BACKLIGHT_GENERIC=y
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++# CONFIG_MDA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE=y
++# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
++CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
++CONFIG_FONTS=y
++CONFIG_FONT_8x8=y
++CONFIG_FONT_8x16=y
++CONFIG_FONT_6x11=y
++CONFIG_FONT_7x14=y
++CONFIG_FONT_PEARL_8x8=y
++CONFIG_FONT_ACORN_8x8=y
++CONFIG_FONT_MINI_4x6=y
++CONFIG_FONT_SUN8x16=y
++CONFIG_FONT_SUN12x22=y
++CONFIG_FONT_10x18=y
++CONFIG_LOGO=y
++# CONFIG_LOGO_LINUX_MONO is not set
++# CONFIG_LOGO_LINUX_VGA16 is not set
++CONFIG_LOGO_LINUX_CLUT224=y
++# CONFIG_SOUND is not set
++CONFIG_HID_SUPPORT=y
++CONFIG_HID=y
++CONFIG_HIDRAW=y
++
++#
++# USB Input Devices
++#
++CONFIG_USB_HID=y
++# CONFIG_HID_PID is not set
++CONFIG_USB_HIDDEV=y
++
++#
++# Special HID drivers
++#
++# CONFIG_HID_A4TECH is not set
++# CONFIG_HID_APPLE is not set
++# CONFIG_HID_BELKIN is not set
++# CONFIG_HID_CHERRY is not set
++# CONFIG_HID_CHICONY is not set
++# CONFIG_HID_CYPRESS is not set
++# CONFIG_HID_DRAGONRISE is not set
++# CONFIG_HID_EZKEY is not set
++# CONFIG_HID_KYE is not set
++# CONFIG_HID_GYRATION is not set
++# CONFIG_HID_TWINHAN is not set
++# CONFIG_HID_KENSINGTON is not set
++# CONFIG_HID_LOGITECH is not set
++# CONFIG_HID_MICROSOFT is not set
++# CONFIG_HID_MONTEREY is not set
++# CONFIG_HID_NTRIG is not set
++# CONFIG_HID_PANTHERLORD is not set
++# CONFIG_HID_PETALYNX is not set
++# CONFIG_HID_SAMSUNG is not set
++# CONFIG_HID_SONY is not set
++# CONFIG_HID_SUNPLUS is not set
++# CONFIG_HID_GREENASIA is not set
++# CONFIG_HID_SMARTJOYPLUS is not set
++# CONFIG_HID_TOPSEED is not set
++# CONFIG_HID_THRUSTMASTER is not set
++# CONFIG_HID_ZEROPLUS is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
++CONFIG_USB_ARCH_HAS_EHCI=y
++CONFIG_USB=y
++# CONFIG_USB_DEBUG is not set
++# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
++
++#
++# Miscellaneous USB options
++#
++# CONFIG_USB_DEVICEFS is not set
++# CONFIG_USB_DEVICE_CLASS is not set
++CONFIG_USB_DYNAMIC_MINORS=y
++# CONFIG_USB_OTG is not set
++CONFIG_USB_OTG_WHITELIST=y
++# CONFIG_USB_OTG_BLACKLIST_HUB is not set
++CONFIG_USB_MON=y
++# CONFIG_USB_WUSB is not set
++# CONFIG_USB_WUSB_CBAF is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_C67X00_HCD is not set
++# CONFIG_USB_XHCI_HCD is not set
++CONFIG_USB_EHCI_HCD=y
++CONFIG_USB_EHCI_ROOT_HUB_TT=y
++# CONFIG_USB_EHCI_TT_NEWSCHED is not set
++# CONFIG_USB_OXU210HP_HCD is not set
++# CONFIG_USB_ISP116X_HCD is not set
++# CONFIG_USB_ISP1760_HCD is not set
++# CONFIG_USB_ISP1362_HCD is not set
++CONFIG_USB_OHCI_HCD=y
++# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
++# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
++CONFIG_USB_OHCI_LITTLE_ENDIAN=y
++# CONFIG_USB_UHCI_HCD is not set
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++# CONFIG_USB_WHCI_HCD is not set
++# CONFIG_USB_HWA_HCD is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++# CONFIG_USB_WDM is not set
++# CONFIG_USB_TMC is not set
++
++#
++# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
++#
++
++#
++# also be needed; see USB_STORAGE Help for more info
++#
++CONFIG_USB_STORAGE=y
++# CONFIG_USB_STORAGE_DEBUG is not set
++# CONFIG_USB_STORAGE_DATAFAB is not set
++# CONFIG_USB_STORAGE_FREECOM is not set
++# CONFIG_USB_STORAGE_ISD200 is not set
++# CONFIG_USB_STORAGE_USBAT is not set
++# CONFIG_USB_STORAGE_SDDR09 is not set
++# CONFIG_USB_STORAGE_SDDR55 is not set
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_ONETOUCH is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
++CONFIG_USB_LIBUSUAL=y
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++
++#
++# USB port drivers
++#
++# CONFIG_USB_SERIAL is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_SEVSEG is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_BERRY_CHARGE is not set
++# CONFIG_USB_LED is not set
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_SISUSBVGA is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++# CONFIG_USB_IOWARRIOR is not set
++# CONFIG_USB_TEST is not set
++# CONFIG_USB_ISIGHTFW is not set
++# CONFIG_USB_VST is not set
++# CONFIG_USB_GADGET is not set
++
++#
++# OTG and related infrastructure
++#
++# CONFIG_NOP_USB_XCEIV is not set
++# CONFIG_UWB is not set
++# CONFIG_MMC is not set
++# CONFIG_MEMSTICK is not set
++# CONFIG_NEW_LEDS is not set
++# CONFIG_ACCESSIBILITY is not set
++# CONFIG_INFINIBAND is not set
++CONFIG_RTC_LIB=y
++CONFIG_RTC_CLASS=y
++CONFIG_RTC_HCTOSYS=y
++CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
++# CONFIG_RTC_DEBUG is not set
++
++#
++# RTC interfaces
++#
++CONFIG_RTC_INTF_SYSFS=y
++CONFIG_RTC_INTF_PROC=y
++CONFIG_RTC_INTF_DEV=y
++# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
++# CONFIG_RTC_DRV_TEST is not set
++
++#
++# SPI RTC drivers
++#
++
++#
++# Platform RTC drivers
++#
++CONFIG_RTC_DRV_CMOS=y
++# CONFIG_RTC_DRV_DS1286 is not set
++# CONFIG_RTC_DRV_DS1511 is not set
++# CONFIG_RTC_DRV_DS1553 is not set
++# CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
++# CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T35 is not set
++# CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_BQ4802 is not set
++# CONFIG_RTC_DRV_V3020 is not set
++
++#
++# on-CPU RTC drivers
++#
++# CONFIG_DMADEVICES is not set
++# CONFIG_AUXDISPLAY is not set
++# CONFIG_UIO is not set
++
++#
++# TI VLYNQ
++#
++CONFIG_STAGING=y
++# CONFIG_STAGING_EXCLUDE_BUILD is not set
++# CONFIG_ET131X is not set
++# CONFIG_USB_IP_COMMON is not set
++# CONFIG_ECHO is not set
++# CONFIG_ASUS_OLED is not set
++# CONFIG_ALTERA_PCIE_CHDMA is not set
++# CONFIG_INPUT_MIMIO is not set
++# CONFIG_TRANZPORT is not set
++
++#
++# Android
++#
++
++#
++# Qualcomm MSM Camera And Video
++#
++
++#
++# Camera Sensor Selection
++#
++# CONFIG_INPUT_GPIO is not set
++# CONFIG_POHMELFS is not set
++# CONFIG_B3DFG is not set
++# CONFIG_FB_UDL is not set
++# CONFIG_VME_BUS is not set
++
++#
++# RAR Register Driver
++#
++# CONFIG_RAR_REGISTER is not set
++# CONFIG_IIO is not set
++CONFIG_FB_SM7XX=y
++# CONFIG_FB_SM7XX_ACCEL is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++CONFIG_EXT2_FS_XATTR=y
++# CONFIG_EXT2_FS_POSIX_ACL is not set
++# CONFIG_EXT2_FS_SECURITY is not set
++# CONFIG_EXT2_FS_XIP is not set
++CONFIG_EXT3_FS=y
++# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
++CONFIG_EXT3_FS_XATTR=y
++# CONFIG_EXT3_FS_POSIX_ACL is not set
++# CONFIG_EXT3_FS_SECURITY is not set
++# CONFIG_EXT4_FS is not set
++CONFIG_JBD=y
++CONFIG_FS_MBCACHE=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_FS_POSIX_ACL is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++# CONFIG_BTRFS_FS is not set
++# CONFIG_NILFS2_FS is not set
++# CONFIG_FILE_LOCKING is not set
++CONFIG_FSNOTIFY=y
++CONFIG_DNOTIFY=y
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++
++#
++# Caches
++#
++# CONFIG_FSCACHE is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="utf-8"
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_KCORE=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++# CONFIG_TMPFS_POSIX_ACL is not set
++# CONFIG_HUGETLB_PAGE is not set
++# CONFIG_CONFIGFS_FS is not set
++# CONFIG_MISC_FILESYSTEMS is not set
++# CONFIG_NETWORK_FILESYSTEMS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="utf-8"
++CONFIG_NLS_CODEPAGE_437=y
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++# CONFIG_NLS_CODEPAGE_850 is not set
++# CONFIG_NLS_CODEPAGE_852 is not set
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++# CONFIG_NLS_CODEPAGE_936 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++CONFIG_NLS_ASCII=y
++# CONFIG_NLS_ISO8859_1 is not set
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_13 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++CONFIG_NLS_UTF8=y
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_PRINTK_TIME=y
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_FRAME_WARN=1024
++# CONFIG_MAGIC_SYSRQ is not set
++CONFIG_STRIP_ASM_SYMS=y
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SHIRQ is not set
++# CONFIG_DETECT_SOFTLOCKUP is not set
++# CONFIG_DETECT_HUNG_TASK is not set
++# CONFIG_SCHED_DEBUG is not set
++# CONFIG_SCHEDSTATS is not set
++# CONFIG_TIMER_STATS is not set
++# CONFIG_DEBUG_OBJECTS is not set
++# CONFIG_SLUB_DEBUG_ON is not set
++# CONFIG_SLUB_STATS is not set
++# CONFIG_DEBUG_PREEMPT is not set
++# CONFIG_DEBUG_RT_MUTEXES is not set
++# CONFIG_RT_MUTEX_TESTER is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_MUTEXES is not set
++# CONFIG_DEBUG_LOCK_ALLOC is not set
++# CONFIG_PROVE_LOCKING is not set
++# CONFIG_LOCK_STAT is not set
++# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
++# CONFIG_DEBUG_KOBJECT is not set
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_DEBUG_VM is not set
++# CONFIG_DEBUG_WRITECOUNT is not set
++# CONFIG_DEBUG_MEMORY_INIT is not set
++# CONFIG_DEBUG_LIST is not set
++# CONFIG_DEBUG_SG is not set
++# CONFIG_DEBUG_NOTIFIERS is not set
++# CONFIG_DEBUG_CREDENTIALS is not set
++# CONFIG_BOOT_PRINTK_DELAY is not set
++# CONFIG_RCU_TORTURE_TEST is not set
++# CONFIG_RCU_CPU_STALL_DETECTOR is not set
++# CONFIG_BACKTRACE_SELF_TEST is not set
++# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
++# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
++# CONFIG_FAULT_INJECTION is not set
++CONFIG_SYSCTL_SYSCALL_CHECK=y
++# CONFIG_PAGE_POISONING is not set
++CONFIG_HAVE_FUNCTION_TRACER=y
++CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
++CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
++CONFIG_HAVE_DYNAMIC_FTRACE=y
++CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
++CONFIG_TRACING_SUPPORT=y
++# CONFIG_FTRACE is not set
++# CONFIG_SAMPLES is not set
++CONFIG_HAVE_ARCH_KGDB=y
++# CONFIG_KGDB is not set
++CONFIG_CMDLINE=""
++# CONFIG_DEBUG_STACK_USAGE is not set
++# CONFIG_RUNTIME_DEBUG is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITYFS is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++# CONFIG_CRYPTO is not set
++# CONFIG_BINARY_PRINTF is not set
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++CONFIG_GENERIC_FIND_LAST_BIT=y
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_T10DIF is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_AUDIT_GENERIC=y
++CONFIG_ZLIB_INFLATE=y
++CONFIG_DECOMPRESS_GZIP=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
++CONFIG_NLATTR=y
+diff --git a/arch/mips/configs/powertv_defconfig b/arch/mips/configs/powertv_defconfig
+new file mode 100644
+index 0000000..3aff69a
+--- /dev/null
++++ b/arch/mips/configs/powertv_defconfig
+@@ -0,0 +1,1549 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.31-rc5
++# Fri Aug 28 14:49:33 2009
++#
++CONFIG_MIPS=y
++
++#
++# Machine selection
++#
++# CONFIG_MACH_ALCHEMY is not set
++# CONFIG_AR7 is not set
++# CONFIG_BASLER_EXCITE is not set
++# CONFIG_BCM47XX is not set
++# CONFIG_MIPS_COBALT is not set
++# CONFIG_MACH_DECSTATION is not set
++# CONFIG_MACH_JAZZ is not set
++# CONFIG_LASAT is not set
++# CONFIG_LEMOTE_FULONG is not set
++# CONFIG_MIPS_MALTA is not set
++# CONFIG_MIPS_SIM is not set
++# CONFIG_NEC_MARKEINS is not set
++# CONFIG_MACH_VR41XX is not set
++# CONFIG_NXP_STB220 is not set
++# CONFIG_NXP_STB225 is not set
++# CONFIG_PNX8550_JBS is not set
++# CONFIG_PNX8550_STB810 is not set
++# CONFIG_PMC_MSP is not set
++# CONFIG_PMC_YOSEMITE is not set
++CONFIG_POWERTV=y
++# CONFIG_SGI_IP22 is not set
++# CONFIG_SGI_IP27 is not set
++# CONFIG_SGI_IP28 is not set
++# CONFIG_SGI_IP32 is not set
++# CONFIG_SIBYTE_CRHINE is not set
++# CONFIG_SIBYTE_CARMEL is not set
++# CONFIG_SIBYTE_CRHONE is not set
++# CONFIG_SIBYTE_RHONE is not set
++# CONFIG_SIBYTE_SWARM is not set
++# CONFIG_SIBYTE_LITTLESUR is not set
++# CONFIG_SIBYTE_SENTOSA is not set
++# CONFIG_SIBYTE_BIGSUR is not set
++# CONFIG_SNI_RM is not set
++# CONFIG_MACH_TX39XX is not set
++# CONFIG_MACH_TX49XX is not set
++# CONFIG_MIKROTIK_RB532 is not set
++# CONFIG_WR_PPMC is not set
++# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
++# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
++# CONFIG_ALCHEMY_GPIO_INDIRECT is not set
++# CONFIG_MIN_RUNTIME_RESOURCES is not set
++# CONFIG_BOOTLOADER_DRIVER is not set
++CONFIG_BOOTLOADER_FAMILY="R2"
++CONFIG_CSRC_POWERTV=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_ARCH_SUPPORTS_OPROFILE=y
++CONFIG_GENERIC_FIND_NEXT_BIT=y
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_GENERIC_TIME=y
++CONFIG_GENERIC_CMOS_UPDATE=y
++CONFIG_SCHED_OMIT_FRAME_POINTER=y
++CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
++CONFIG_CEVT_R4K_LIB=y
++CONFIG_CEVT_R4K=y
++CONFIG_DMA_NONCOHERENT=y
++CONFIG_DMA_NEED_PCI_MAP_STATE=y
++# CONFIG_EARLY_PRINTK is not set
++CONFIG_SYS_HAS_EARLY_PRINTK=y
++# CONFIG_NO_IOPORT is not set
++CONFIG_CPU_BIG_ENDIAN=y
++# CONFIG_CPU_LITTLE_ENDIAN is not set
++CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
++CONFIG_BOOT_ELF32=y
++CONFIG_MIPS_L1_CACHE_SHIFT=5
++
++#
++# CPU selection
++#
++# CONFIG_CPU_LOONGSON2 is not set
++# CONFIG_CPU_MIPS32_R1 is not set
++CONFIG_CPU_MIPS32_R2=y
++# CONFIG_CPU_MIPS64_R1 is not set
++# CONFIG_CPU_MIPS64_R2 is not set
++# CONFIG_CPU_R3000 is not set
++# CONFIG_CPU_TX39XX is not set
++# CONFIG_CPU_VR41XX is not set
++# CONFIG_CPU_R4300 is not set
++# CONFIG_CPU_R4X00 is not set
++# CONFIG_CPU_TX49XX is not set
++# CONFIG_CPU_R5000 is not set
++# CONFIG_CPU_R5432 is not set
++# CONFIG_CPU_R5500 is not set
++# CONFIG_CPU_R6000 is not set
++# CONFIG_CPU_NEVADA is not set
++# CONFIG_CPU_R8000 is not set
++# CONFIG_CPU_R10000 is not set
++# CONFIG_CPU_RM7000 is not set
++# CONFIG_CPU_RM9000 is not set
++# CONFIG_CPU_SB1 is not set
++# CONFIG_CPU_CAVIUM_OCTEON is not set
++CONFIG_SYS_HAS_CPU_MIPS32_R2=y
++CONFIG_CPU_MIPS32=y
++CONFIG_CPU_MIPSR2=y
++CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
++CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
++CONFIG_HARDWARE_WATCHPOINTS=y
++
++#
++# Kernel type
++#
++CONFIG_32BIT=y
++# CONFIG_64BIT is not set
++CONFIG_PAGE_SIZE_4KB=y
++# CONFIG_PAGE_SIZE_8KB is not set
++# CONFIG_PAGE_SIZE_16KB is not set
++# CONFIG_PAGE_SIZE_32KB is not set
++# CONFIG_PAGE_SIZE_64KB is not set
++CONFIG_CPU_HAS_PREFETCH=y
++CONFIG_MIPS_MT_DISABLED=y
++# CONFIG_MIPS_MT_SMP is not set
++# CONFIG_MIPS_MT_SMTC is not set
++CONFIG_CPU_HAS_LLSC=y
++CONFIG_CPU_MIPSR2_IRQ_VI=y
++CONFIG_CPU_MIPSR2_IRQ_EI=y
++CONFIG_CPU_HAS_SYNC=y
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_GENERIC_IRQ_PROBE=y
++# CONFIG_HIGHMEM is not set
++CONFIG_CPU_SUPPORTS_HIGHMEM=y
++CONFIG_SYS_SUPPORTS_HIGHMEM=y
++CONFIG_ARCH_FLATMEM_ENABLE=y
++CONFIG_ARCH_POPULATES_NODE_MAP=y
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++CONFIG_PAGEFLAGS_EXTENDED=y
++CONFIG_SPLIT_PTLOCK_CPUS=4
++# CONFIG_PHYS_ADDR_T_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=0
++CONFIG_VIRT_TO_BUS=y
++CONFIG_HAVE_MLOCK=y
++CONFIG_HAVE_MLOCKED_PAGE_BIT=y
++CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
++CONFIG_TICK_ONESHOT=y
++CONFIG_NO_HZ=y
++CONFIG_HIGH_RES_TIMERS=y
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++# CONFIG_HZ_48 is not set
++# CONFIG_HZ_100 is not set
++# CONFIG_HZ_128 is not set
++# CONFIG_HZ_250 is not set
++# CONFIG_HZ_256 is not set
++CONFIG_HZ_1000=y
++# CONFIG_HZ_1024 is not set
++CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
++CONFIG_HZ=1000
++# CONFIG_PREEMPT_NONE is not set
++# CONFIG_PREEMPT_VOLUNTARY is not set
++CONFIG_PREEMPT=y
++# CONFIG_KEXEC is not set
++# CONFIG_SECCOMP is not set
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++CONFIG_CONSTRUCTORS=y
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_LOCK_KERNEL=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION_AUTO=y
++# CONFIG_SWAP is not set
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_AUDIT is not set
++
++#
++# RCU Subsystem
++#
++CONFIG_CLASSIC_RCU=y
++# CONFIG_TREE_RCU is not set
++# CONFIG_PREEMPT_RCU is not set
++# CONFIG_TREE_RCU_TRACE is not set
++# CONFIG_PREEMPT_RCU_TRACE is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_LOG_BUF_SHIFT=16
++CONFIG_GROUP_SCHED=y
++CONFIG_FAIR_GROUP_SCHED=y
++# CONFIG_RT_GROUP_SCHED is not set
++CONFIG_USER_SCHED=y
++# CONFIG_CGROUP_SCHED is not set
++# CONFIG_CGROUPS is not set
++# CONFIG_SYSFS_DEPRECATED_V2 is not set
++CONFIG_RELAY=y
++# CONFIG_NAMESPACES is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++# CONFIG_RD_GZIP is not set
++# CONFIG_RD_BZIP2 is not set
++# CONFIG_RD_LZMA is not set
++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
++CONFIG_SYSCTL=y
++CONFIG_ANON_INODES=y
++CONFIG_EMBEDDED=y
++# CONFIG_SYSCTL_SYSCALL is not set
++CONFIG_KALLSYMS=y
++CONFIG_KALLSYMS_ALL=y
++# CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++# CONFIG_PCSPKR_PLATFORM is not set
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++# CONFIG_EPOLL is not set
++# CONFIG_SIGNALFD is not set
++CONFIG_TIMERFD=y
++# CONFIG_EVENTFD is not set
++CONFIG_SHMEM=y
++CONFIG_AIO=y
++
++#
++# Performance Counters
++#
++# CONFIG_VM_EVENT_COUNTERS is not set
++CONFIG_PCI_QUIRKS=y
++# CONFIG_SLUB_DEBUG is not set
++# CONFIG_STRIP_ASM_SYMS is not set
++CONFIG_COMPAT_BRK=y
++# CONFIG_SLAB is not set
++CONFIG_SLUB=y
++# CONFIG_SLOB is not set
++# CONFIG_PROFILING is not set
++# CONFIG_MARKERS is not set
++CONFIG_HAVE_OPROFILE=y
++
++#
++# GCOV-based kernel profiling
++#
++# CONFIG_GCOV_KERNEL is not set
++# CONFIG_SLOW_WORK is not set
++# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
++CONFIG_RT_MUTEXES=y
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++# CONFIG_MODULE_FORCE_LOAD is not set
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++CONFIG_MODVERSIONS=y
++CONFIG_MODULE_SRCVERSION_ALL=y
++CONFIG_BLOCK=y
++CONFIG_LBDAF=y
++# CONFIG_BLK_DEV_BSG is not set
++# CONFIG_BLK_DEV_INTEGRITY is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++# CONFIG_IOSCHED_AS is not set
++# CONFIG_IOSCHED_DEADLINE is not set
++# CONFIG_IOSCHED_CFQ is not set
++# CONFIG_DEFAULT_AS is not set
++# CONFIG_DEFAULT_DEADLINE is not set
++# CONFIG_DEFAULT_CFQ is not set
++CONFIG_DEFAULT_NOOP=y
++CONFIG_DEFAULT_IOSCHED="noop"
++# CONFIG_PROBE_INITRD_HEADER is not set
++# CONFIG_FREEZER is not set
++
++#
++# Bus options (PCI, PCMCIA, EISA, ISA, TC)
++#
++CONFIG_HW_HAS_PCI=y
++CONFIG_PCI=y
++CONFIG_PCI_DOMAINS=y
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++# CONFIG_PCI_LEGACY is not set
++# CONFIG_PCI_DEBUG is not set
++# CONFIG_PCI_STUB is not set
++# CONFIG_PCI_IOV is not set
++CONFIG_MMU=y
++# CONFIG_PCCARD is not set
++# CONFIG_HOTPLUG_PCI is not set
++
++#
++# Executable file formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++# CONFIG_HAVE_AOUT is not set
++# CONFIG_BINFMT_MISC is not set
++CONFIG_TRAD_SIGNALS=y
++
++#
++# Power management options
++#
++CONFIG_ARCH_HIBERNATION_POSSIBLE=y
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++# CONFIG_PM is not set
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++CONFIG_PACKET_MMAP=y
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++# CONFIG_XFRM_USER is not set
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_XFRM_STATISTICS is not set
++CONFIG_XFRM_IPCOMP=y
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++CONFIG_IP_ADVANCED_ROUTER=y
++CONFIG_ASK_IP_FIB_HASH=y
++# CONFIG_IP_FIB_TRIE is not set
++CONFIG_IP_FIB_HASH=y
++# CONFIG_IP_MULTIPLE_TABLES is not set
++# CONFIG_IP_ROUTE_MULTIPATH is not set
++# CONFIG_IP_ROUTE_VERBOSE is not set
++CONFIG_IP_PNP=y
++# CONFIG_IP_PNP_DHCP is not set
++# CONFIG_IP_PNP_BOOTP is not set
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_IP_MROUTE is not set
++# CONFIG_ARPD is not set
++CONFIG_SYN_COOKIES=y
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++# CONFIG_INET_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
++# CONFIG_INET_XFRM_MODE_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_BEET is not set
++# CONFIG_INET_LRO is not set
++# CONFIG_INET_DIAG is not set
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++CONFIG_IPV6=y
++CONFIG_IPV6_PRIVACY=y
++# CONFIG_IPV6_ROUTER_PREF is not set
++# CONFIG_IPV6_OPTIMISTIC_DAD is not set
++CONFIG_INET6_AH=y
++CONFIG_INET6_ESP=y
++CONFIG_INET6_IPCOMP=y
++# CONFIG_IPV6_MIP6 is not set
++CONFIG_INET6_XFRM_TUNNEL=y
++CONFIG_INET6_TUNNEL=y
++# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
++# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
++# CONFIG_INET6_XFRM_MODE_BEET is not set
++# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
++# CONFIG_IPV6_SIT is not set
++CONFIG_IPV6_TUNNEL=y
++# CONFIG_IPV6_MULTIPLE_TABLES is not set
++# CONFIG_IPV6_MROUTE is not set
++# CONFIG_NETWORK_SECMARK is not set
++CONFIG_NETFILTER=y
++# CONFIG_NETFILTER_DEBUG is not set
++CONFIG_NETFILTER_ADVANCED=y
++# CONFIG_BRIDGE_NETFILTER is not set
++
++#
++# Core Netfilter Configuration
++#
++# CONFIG_NETFILTER_NETLINK_QUEUE is not set
++# CONFIG_NETFILTER_NETLINK_LOG is not set
++# CONFIG_NF_CONNTRACK is not set
++CONFIG_NETFILTER_XTABLES=y
++# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
++# CONFIG_NETFILTER_XT_TARGET_MARK is not set
++# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
++# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
++# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
++# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
++# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
++# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
++# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
++# CONFIG_NETFILTER_XT_MATCH_ESP is not set
++# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
++# CONFIG_NETFILTER_XT_MATCH_HL is not set
++# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
++# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
++# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
++# CONFIG_NETFILTER_XT_MATCH_MAC is not set
++# CONFIG_NETFILTER_XT_MATCH_MARK is not set
++CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
++# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
++# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
++# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
++# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
++# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set
++# CONFIG_NETFILTER_XT_MATCH_REALM is not set
++# CONFIG_NETFILTER_XT_MATCH_RECENT is not set
++# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
++# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
++# CONFIG_NETFILTER_XT_MATCH_STRING is not set
++# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
++# CONFIG_NETFILTER_XT_MATCH_TIME is not set
++# CONFIG_NETFILTER_XT_MATCH_U32 is not set
++# CONFIG_IP_VS is not set
++
++#
++# IP: Netfilter Configuration
++#
++# CONFIG_NF_DEFRAG_IPV4 is not set
++# CONFIG_IP_NF_QUEUE is not set
++CONFIG_IP_NF_IPTABLES=y
++# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
++# CONFIG_IP_NF_MATCH_AH is not set
++# CONFIG_IP_NF_MATCH_ECN is not set
++# CONFIG_IP_NF_MATCH_TTL is not set
++CONFIG_IP_NF_FILTER=y
++# CONFIG_IP_NF_TARGET_REJECT is not set
++# CONFIG_IP_NF_TARGET_LOG is not set
++# CONFIG_IP_NF_TARGET_ULOG is not set
++# CONFIG_IP_NF_MANGLE is not set
++# CONFIG_IP_NF_TARGET_TTL is not set
++# CONFIG_IP_NF_RAW is not set
++CONFIG_IP_NF_ARPTABLES=y
++CONFIG_IP_NF_ARPFILTER=y
++# CONFIG_IP_NF_ARP_MANGLE is not set
++
++#
++# IPv6: Netfilter Configuration
++#
++# CONFIG_IP6_NF_QUEUE is not set
++CONFIG_IP6_NF_IPTABLES=y
++# CONFIG_IP6_NF_MATCH_AH is not set
++# CONFIG_IP6_NF_MATCH_EUI64 is not set
++# CONFIG_IP6_NF_MATCH_FRAG is not set
++# CONFIG_IP6_NF_MATCH_OPTS is not set
++# CONFIG_IP6_NF_MATCH_HL is not set
++# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set
++# CONFIG_IP6_NF_MATCH_MH is not set
++# CONFIG_IP6_NF_MATCH_RT is not set
++# CONFIG_IP6_NF_TARGET_HL is not set
++# CONFIG_IP6_NF_TARGET_LOG is not set
++CONFIG_IP6_NF_FILTER=y
++# CONFIG_IP6_NF_TARGET_REJECT is not set
++# CONFIG_IP6_NF_MANGLE is not set
++# CONFIG_IP6_NF_RAW is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++CONFIG_STP=y
++CONFIG_BRIDGE=y
++# CONFIG_NET_DSA is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++CONFIG_LLC=y
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++# CONFIG_PHONET is not set
++# CONFIG_IEEE802154 is not set
++CONFIG_NET_SCHED=y
++
++#
++# Queueing/Scheduling
++#
++# CONFIG_NET_SCH_CBQ is not set
++# CONFIG_NET_SCH_HTB is not set
++# CONFIG_NET_SCH_HFSC is not set
++# CONFIG_NET_SCH_PRIO is not set
++# CONFIG_NET_SCH_MULTIQ is not set
++# CONFIG_NET_SCH_RED is not set
++# CONFIG_NET_SCH_SFQ is not set
++# CONFIG_NET_SCH_TEQL is not set
++CONFIG_NET_SCH_TBF=y
++# CONFIG_NET_SCH_GRED is not set
++# CONFIG_NET_SCH_DSMARK is not set
++# CONFIG_NET_SCH_NETEM is not set
++# CONFIG_NET_SCH_DRR is not set
++
++#
++# Classification
++#
++# CONFIG_NET_CLS_BASIC is not set
++# CONFIG_NET_CLS_TCINDEX is not set
++# CONFIG_NET_CLS_ROUTE4 is not set
++# CONFIG_NET_CLS_FW is not set
++# CONFIG_NET_CLS_U32 is not set
++# CONFIG_NET_CLS_RSVP is not set
++# CONFIG_NET_CLS_RSVP6 is not set
++# CONFIG_NET_CLS_FLOW is not set
++# CONFIG_NET_EMATCH is not set
++# CONFIG_NET_CLS_ACT is not set
++CONFIG_NET_SCH_FIFO=y
++# CONFIG_DCB is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++# CONFIG_WIRELESS is not set
++# CONFIG_WIMAX is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++CONFIG_FW_LOADER=y
++CONFIG_FIRMWARE_IN_KERNEL=y
++CONFIG_EXTRA_FIRMWARE=""
++# CONFIG_DEBUG_DRIVER is not set
++# CONFIG_DEBUG_DEVRES is not set
++# CONFIG_SYS_HYPERVISOR is not set
++# CONFIG_CONNECTOR is not set
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++# CONFIG_MTD_CONCAT is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_TESTS is not set
++# CONFIG_MTD_REDBOOT_PARTS is not set
++CONFIG_MTD_CMDLINE_PARTS=y
++# CONFIG_MTD_AR7_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLKDEVS=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_MTD_OOPS is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++# CONFIG_MTD_CFI is not set
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++# CONFIG_MTD_INTEL_VR_NOR is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
++CONFIG_MTD_NAND=y
++# CONFIG_MTD_NAND_VERIFY_WRITE is not set
++# CONFIG_MTD_NAND_ECC_SMC is not set
++# CONFIG_MTD_NAND_MUSEUM_IDS is not set
++CONFIG_MTD_NAND_IDS=y
++# CONFIG_MTD_NAND_DISKONCHIP is not set
++# CONFIG_MTD_NAND_CAFE is not set
++# CONFIG_MTD_NAND_NANDSIM is not set
++# CONFIG_MTD_NAND_PLATFORM is not set
++# CONFIG_MTD_ALAUDA is not set
++# CONFIG_MTD_ONENAND is not set
++
++#
++# LPDDR flash memory drivers
++#
++# CONFIG_MTD_LPDDR is not set
++
++#
++# UBI - Unsorted block images
++#
++# CONFIG_MTD_UBI is not set
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_CPQ_DA is not set
++# CONFIG_BLK_CPQ_CISS_DA is not set
++# CONFIG_BLK_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_UMEM is not set
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_SX8 is not set
++# CONFIG_BLK_DEV_UB is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=16
++CONFIG_BLK_DEV_RAM_SIZE=32768
++# CONFIG_BLK_DEV_XIP is not set
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++# CONFIG_BLK_DEV_HD is not set
++# CONFIG_MISC_DEVICES is not set
++CONFIG_HAVE_IDE=y
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++CONFIG_SCSI_DMA=y
++# CONFIG_SCSI_TGT is not set
++# CONFIG_SCSI_NETLINK is not set
++# CONFIG_SCSI_PROC_FS is not set
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++# CONFIG_CHR_DEV_SG is not set
++# CONFIG_CHR_DEV_SCH is not set
++# CONFIG_SCSI_MULTI_LUN is not set
++# CONFIG_SCSI_CONSTANTS is not set
++# CONFIG_SCSI_LOGGING is not set
++# CONFIG_SCSI_SCAN_ASYNC is not set
++CONFIG_SCSI_WAIT_SCAN=m
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++# CONFIG_SCSI_ISCSI_ATTRS is not set
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++# CONFIG_SCSI_LOWLEVEL is not set
++# CONFIG_SCSI_DH is not set
++# CONFIG_SCSI_OSD_INITIATOR is not set
++CONFIG_ATA=y
++# CONFIG_ATA_NONSTANDARD is not set
++CONFIG_SATA_PMP=y
++# CONFIG_SATA_AHCI is not set
++# CONFIG_SATA_SIL24 is not set
++CONFIG_ATA_SFF=y
++# CONFIG_SATA_SVW is not set
++# CONFIG_ATA_PIIX is not set
++# CONFIG_SATA_MV is not set
++# CONFIG_SATA_NV is not set
++# CONFIG_PDC_ADMA is not set
++# CONFIG_SATA_QSTOR is not set
++# CONFIG_SATA_PROMISE is not set
++# CONFIG_SATA_SX4 is not set
++# CONFIG_SATA_SIL is not set
++# CONFIG_SATA_SIS is not set
++# CONFIG_SATA_ULI is not set
++# CONFIG_SATA_VIA is not set
++# CONFIG_SATA_VITESSE is not set
++# CONFIG_SATA_INIC162X is not set
++# CONFIG_PATA_ALI is not set
++# CONFIG_PATA_AMD is not set
++# CONFIG_PATA_ARTOP is not set
++# CONFIG_PATA_ATIIXP is not set
++# CONFIG_PATA_CMD640_PCI is not set
++# CONFIG_PATA_CMD64X is not set
++# CONFIG_PATA_CS5520 is not set
++# CONFIG_PATA_CS5530 is not set
++# CONFIG_PATA_CYPRESS is not set
++# CONFIG_PATA_EFAR is not set
++# CONFIG_ATA_GENERIC is not set
++# CONFIG_PATA_HPT366 is not set
++# CONFIG_PATA_HPT37X is not set
++# CONFIG_PATA_HPT3X2N is not set
++# CONFIG_PATA_HPT3X3 is not set
++# CONFIG_PATA_IT821X is not set
++# CONFIG_PATA_IT8213 is not set
++# CONFIG_PATA_JMICRON is not set
++# CONFIG_PATA_TRIFLEX is not set
++# CONFIG_PATA_MARVELL is not set
++# CONFIG_PATA_MPIIX is not set
++# CONFIG_PATA_OLDPIIX is not set
++# CONFIG_PATA_NETCELL is not set
++# CONFIG_PATA_NINJA32 is not set
++# CONFIG_PATA_NS87410 is not set
++# CONFIG_PATA_NS87415 is not set
++# CONFIG_PATA_OPTI is not set
++# CONFIG_PATA_OPTIDMA is not set
++# CONFIG_PATA_PDC_OLD is not set
++# CONFIG_PATA_RADISYS is not set
++# CONFIG_PATA_RZ1000 is not set
++# CONFIG_PATA_SC1200 is not set
++# CONFIG_PATA_SERVERWORKS is not set
++# CONFIG_PATA_PDC2027X is not set
++# CONFIG_PATA_SIL680 is not set
++# CONFIG_PATA_SIS is not set
++# CONFIG_PATA_VIA is not set
++# CONFIG_PATA_WINBOND is not set
++# CONFIG_PATA_PLATFORM is not set
++# CONFIG_PATA_SCH is not set
++# CONFIG_MD is not set
++# CONFIG_FUSION is not set
++
++#
++# IEEE 1394 (FireWire) support
++#
++
++#
++# You can enable one or both FireWire driver stacks.
++#
++
++#
++# See the help texts for more information.
++#
++# CONFIG_FIREWIRE is not set
++# CONFIG_IEEE1394 is not set
++# CONFIG_I2O is not set
++CONFIG_NETDEVICES=y
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++# CONFIG_ARCNET is not set
++# CONFIG_PHYLIB is not set
++CONFIG_NET_ETHERNET=y
++CONFIG_MII=y
++# CONFIG_AX88796 is not set
++# CONFIG_HAPPYMEAL is not set
++# CONFIG_SUNGEM is not set
++# CONFIG_CASSINI is not set
++# CONFIG_NET_VENDOR_3COM is not set
++# CONFIG_SMC91X is not set
++# CONFIG_DM9000 is not set
++# CONFIG_ETHOC is not set
++# CONFIG_DNET is not set
++# CONFIG_NET_TULIP is not set
++# CONFIG_HP100 is not set
++# CONFIG_IBM_NEW_EMAC_ZMII is not set
++# CONFIG_IBM_NEW_EMAC_RGMII is not set
++# CONFIG_IBM_NEW_EMAC_TAH is not set
++# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
++# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
++# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
++# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
++# CONFIG_NET_PCI is not set
++# CONFIG_B44 is not set
++# CONFIG_KS8842 is not set
++# CONFIG_ATL2 is not set
++CONFIG_NETDEV_1000=y
++# CONFIG_ACENIC is not set
++# CONFIG_DL2K is not set
++# CONFIG_E1000 is not set
++# CONFIG_E1000E is not set
++# CONFIG_IP1000 is not set
++# CONFIG_IGB is not set
++# CONFIG_IGBVF is not set
++# CONFIG_NS83820 is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_R8169 is not set
++# CONFIG_SIS190 is not set
++# CONFIG_SKGE is not set
++# CONFIG_SKY2 is not set
++# CONFIG_VIA_VELOCITY is not set
++# CONFIG_TIGON3 is not set
++# CONFIG_BNX2 is not set
++# CONFIG_CNIC is not set
++# CONFIG_QLA3XXX is not set
++# CONFIG_ATL1 is not set
++# CONFIG_ATL1E is not set
++# CONFIG_ATL1C is not set
++# CONFIG_JME is not set
++CONFIG_NETDEV_10000=y
++# CONFIG_CHELSIO_T1 is not set
++CONFIG_CHELSIO_T3_DEPENDS=y
++# CONFIG_CHELSIO_T3 is not set
++# CONFIG_ENIC is not set
++# CONFIG_IXGBE is not set
++# CONFIG_IXGB is not set
++# CONFIG_S2IO is not set
++# CONFIG_VXGE is not set
++# CONFIG_MYRI10GE is not set
++# CONFIG_NETXEN_NIC is not set
++# CONFIG_NIU is not set
++# CONFIG_MLX4_EN is not set
++# CONFIG_MLX4_CORE is not set
++# CONFIG_TEHUTI is not set
++# CONFIG_BNX2X is not set
++# CONFIG_QLGE is not set
++# CONFIG_SFC is not set
++# CONFIG_BE2NET is not set
++# CONFIG_TR is not set
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++# CONFIG_WLAN_80211 is not set
++
++#
++# Enable WiMAX (Networking options) to see the WiMAX drivers
++#
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++CONFIG_USB_RTL8150=y
++# CONFIG_USB_USBNET is not set
++# CONFIG_WAN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_NET_FC is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++# CONFIG_PHONE is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++
++#
++# Userland interfaces
++#
++# CONFIG_INPUT_MOUSEDEV is not set
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++# CONFIG_INPUT_KEYBOARD is not set
++# CONFIG_INPUT_MOUSE is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++# CONFIG_INPUT_TOUCHSCREEN is not set
++# CONFIG_INPUT_MISC is not set
++
++#
++# Hardware I/O ports
++#
++# CONFIG_SERIO is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++# CONFIG_VT is not set
++# CONFIG_DEVKMEM is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++# CONFIG_NOZOMI is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_8250 is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_JSM is not set
++CONFIG_UNIX98_PTYS=y
++# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
++# CONFIG_LEGACY_PTYS is not set
++# CONFIG_IPMI_HANDLER is not set
++# CONFIG_HW_RANDOM is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_DEVPORT=y
++# CONFIG_I2C is not set
++# CONFIG_SPI is not set
++
++#
++# PPS support
++#
++# CONFIG_PPS is not set
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++# CONFIG_HWMON is not set
++# CONFIG_THERMAL is not set
++# CONFIG_THERMAL_HWMON is not set
++# CONFIG_WATCHDOG is not set
++CONFIG_SSB_POSSIBLE=y
++
++#
++# Sonics Silicon Backplane
++#
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_CORE is not set
++# CONFIG_MFD_SM501 is not set
++# CONFIG_HTC_PASIC3 is not set
++# CONFIG_MFD_TMIO is not set
++# CONFIG_REGULATOR is not set
++# CONFIG_MEDIA_SUPPORT is not set
++
++#
++# Graphics support
++#
++# CONFIG_DRM is not set
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++# CONFIG_FB is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++# CONFIG_SOUND is not set
++CONFIG_HID_SUPPORT=y
++CONFIG_HID=y
++# CONFIG_HID_DEBUG is not set
++# CONFIG_HIDRAW is not set
++
++#
++# USB Input Devices
++#
++CONFIG_USB_HID=y
++# CONFIG_HID_PID is not set
++CONFIG_USB_HIDDEV=y
++
++#
++# Special HID drivers
++#
++# CONFIG_HID_A4TECH is not set
++# CONFIG_HID_APPLE is not set
++# CONFIG_HID_BELKIN is not set
++# CONFIG_HID_CHERRY is not set
++# CONFIG_HID_CHICONY is not set
++# CONFIG_HID_CYPRESS is not set
++# CONFIG_HID_DRAGONRISE is not set
++# CONFIG_HID_EZKEY is not set
++# CONFIG_HID_KYE is not set
++# CONFIG_HID_GYRATION is not set
++# CONFIG_HID_KENSINGTON is not set
++# CONFIG_HID_LOGITECH is not set
++# CONFIG_HID_MICROSOFT is not set
++# CONFIG_HID_MONTEREY is not set
++# CONFIG_HID_NTRIG is not set
++# CONFIG_HID_PANTHERLORD is not set
++# CONFIG_HID_PETALYNX is not set
++# CONFIG_HID_SAMSUNG is not set
++# CONFIG_HID_SONY is not set
++# CONFIG_HID_SUNPLUS is not set
++# CONFIG_HID_GREENASIA is not set
++# CONFIG_HID_SMARTJOYPLUS is not set
++# CONFIG_HID_TOPSEED is not set
++# CONFIG_HID_THRUSTMASTER is not set
++# CONFIG_HID_ZEROPLUS is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
++CONFIG_USB_ARCH_HAS_EHCI=y
++CONFIG_USB=y
++# CONFIG_USB_DEBUG is not set
++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
++
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEVICEFS=y
++# CONFIG_USB_DEVICE_CLASS is not set
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_OTG is not set
++# CONFIG_USB_OTG_WHITELIST is not set
++# CONFIG_USB_OTG_BLACKLIST_HUB is not set
++# CONFIG_USB_MON is not set
++# CONFIG_USB_WUSB is not set
++# CONFIG_USB_WUSB_CBAF is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_C67X00_HCD is not set
++# CONFIG_USB_XHCI_HCD is not set
++CONFIG_USB_EHCI_HCD=y
++# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
++# CONFIG_USB_EHCI_TT_NEWSCHED is not set
++# CONFIG_USB_OXU210HP_HCD is not set
++# CONFIG_USB_ISP116X_HCD is not set
++# CONFIG_USB_ISP1760_HCD is not set
++CONFIG_USB_OHCI_HCD=y
++# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
++# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
++CONFIG_USB_OHCI_LITTLE_ENDIAN=y
++# CONFIG_USB_UHCI_HCD is not set
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++# CONFIG_USB_WHCI_HCD is not set
++# CONFIG_USB_HWA_HCD is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++# CONFIG_USB_WDM is not set
++# CONFIG_USB_TMC is not set
++
++#
++# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
++#
++
++#
++# also be needed; see USB_STORAGE Help for more info
++#
++CONFIG_USB_STORAGE=y
++# CONFIG_USB_STORAGE_DEBUG is not set
++# CONFIG_USB_STORAGE_DATAFAB is not set
++# CONFIG_USB_STORAGE_FREECOM is not set
++# CONFIG_USB_STORAGE_ISD200 is not set
++# CONFIG_USB_STORAGE_USBAT is not set
++# CONFIG_USB_STORAGE_SDDR09 is not set
++# CONFIG_USB_STORAGE_SDDR55 is not set
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_ONETOUCH is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
++# CONFIG_USB_LIBUSUAL is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++
++#
++# USB port drivers
++#
++CONFIG_USB_SERIAL=y
++CONFIG_USB_SERIAL_CONSOLE=y
++# CONFIG_USB_EZUSB is not set
++# CONFIG_USB_SERIAL_GENERIC is not set
++# CONFIG_USB_SERIAL_AIRCABLE is not set
++# CONFIG_USB_SERIAL_ARK3116 is not set
++# CONFIG_USB_SERIAL_BELKIN is not set
++# CONFIG_USB_SERIAL_CH341 is not set
++# CONFIG_USB_SERIAL_WHITEHEAT is not set
++# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
++CONFIG_USB_SERIAL_CP210X=y
++# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
++# CONFIG_USB_SERIAL_EMPEG is not set
++# CONFIG_USB_SERIAL_FTDI_SIO is not set
++# CONFIG_USB_SERIAL_FUNSOFT is not set
++# CONFIG_USB_SERIAL_VISOR is not set
++# CONFIG_USB_SERIAL_IPAQ is not set
++# CONFIG_USB_SERIAL_IR is not set
++# CONFIG_USB_SERIAL_EDGEPORT is not set
++# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
++# CONFIG_USB_SERIAL_GARMIN is not set
++# CONFIG_USB_SERIAL_IPW is not set
++# CONFIG_USB_SERIAL_IUU is not set
++# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
++# CONFIG_USB_SERIAL_KEYSPAN is not set
++# CONFIG_USB_SERIAL_KLSI is not set
++# CONFIG_USB_SERIAL_KOBIL_SCT is not set
++# CONFIG_USB_SERIAL_MCT_U232 is not set
++# CONFIG_USB_SERIAL_MOS7720 is not set
++# CONFIG_USB_SERIAL_MOS7840 is not set
++# CONFIG_USB_SERIAL_MOTOROLA is not set
++# CONFIG_USB_SERIAL_NAVMAN is not set
++# CONFIG_USB_SERIAL_PL2303 is not set
++# CONFIG_USB_SERIAL_OTI6858 is not set
++# CONFIG_USB_SERIAL_QUALCOMM is not set
++# CONFIG_USB_SERIAL_SPCP8X5 is not set
++# CONFIG_USB_SERIAL_HP4X is not set
++# CONFIG_USB_SERIAL_SAFE is not set
++# CONFIG_USB_SERIAL_SIEMENS_MPI is not set
++# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
++# CONFIG_USB_SERIAL_SYMBOL is not set
++# CONFIG_USB_SERIAL_TI is not set
++# CONFIG_USB_SERIAL_CYBERJACK is not set
++# CONFIG_USB_SERIAL_XIRCOM is not set
++# CONFIG_USB_SERIAL_OPTION is not set
++# CONFIG_USB_SERIAL_OMNINET is not set
++# CONFIG_USB_SERIAL_OPTICON is not set
++# CONFIG_USB_SERIAL_DEBUG is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_SEVSEG is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_BERRY_CHARGE is not set
++# CONFIG_USB_LED is not set
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_SISUSBVGA is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++# CONFIG_USB_IOWARRIOR is not set
++# CONFIG_USB_TEST is not set
++# CONFIG_USB_ISIGHTFW is not set
++# CONFIG_USB_VST is not set
++# CONFIG_USB_GADGET is not set
++
++#
++# OTG and related infrastructure
++#
++# CONFIG_NOP_USB_XCEIV is not set
++# CONFIG_UWB is not set
++# CONFIG_MMC is not set
++# CONFIG_MEMSTICK is not set
++# CONFIG_NEW_LEDS is not set
++# CONFIG_ACCESSIBILITY is not set
++# CONFIG_INFINIBAND is not set
++CONFIG_RTC_LIB=y
++# CONFIG_RTC_CLASS is not set
++# CONFIG_DMADEVICES is not set
++# CONFIG_AUXDISPLAY is not set
++# CONFIG_UIO is not set
++
++#
++# TI VLYNQ
++#
++# CONFIG_STAGING is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XIP is not set
++CONFIG_EXT3_FS=y
++# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT4_FS is not set
++CONFIG_JBD=y
++# CONFIG_JBD_DEBUG is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_FS_POSIX_ACL is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++# CONFIG_BTRFS_FS is not set
++CONFIG_FILE_LOCKING=y
++CONFIG_FSNOTIFY=y
++# CONFIG_DNOTIFY is not set
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++CONFIG_FUSE_FS=y
++# CONFIG_CUSE is not set
++
++#
++# Caches
++#
++# CONFIG_FSCACHE is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++# CONFIG_MSDOS_FS is not set
++# CONFIG_VFAT_FS is not set
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_KCORE=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++# CONFIG_TMPFS_POSIX_ACL is not set
++# CONFIG_HUGETLB_PAGE is not set
++# CONFIG_CONFIGFS_FS is not set
++CONFIG_MISC_FILESYSTEMS=y
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++CONFIG_JFFS2_FS_WRITEBUFFER=y
++# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
++# CONFIG_JFFS2_SUMMARY is not set
++# CONFIG_JFFS2_FS_XATTR is not set
++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
++CONFIG_JFFS2_ZLIB=y
++# CONFIG_JFFS2_LZO is not set
++CONFIG_JFFS2_RTIME=y
++# CONFIG_JFFS2_RUBIN is not set
++CONFIG_CRAMFS=y
++# CONFIG_SQUASHFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_OMFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_NILFS2_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=y
++CONFIG_NFS_V3=y
++# CONFIG_NFS_V3_ACL is not set
++# CONFIG_NFS_V4 is not set
++CONFIG_ROOT_NFS=y
++# CONFIG_NFSD is not set
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++# CONFIG_RPCSEC_GSS_KRB5 is not set
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_CIFS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="iso8859-1"
++# CONFIG_NLS_CODEPAGE_437 is not set
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++# CONFIG_NLS_CODEPAGE_850 is not set
++# CONFIG_NLS_CODEPAGE_852 is not set
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++# CONFIG_NLS_CODEPAGE_936 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++# CONFIG_NLS_ASCII is not set
++# CONFIG_NLS_ISO8859_1 is not set
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_13 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++# CONFIG_NLS_UTF8 is not set
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_PRINTK_TIME=y
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_FRAME_WARN=1024
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_UNUSED_SYMBOLS is not set
++CONFIG_DEBUG_FS=y
++# CONFIG_HEADERS_CHECK is not set
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SHIRQ is not set
++CONFIG_DETECT_SOFTLOCKUP=y
++# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
++CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
++CONFIG_DETECT_HUNG_TASK=y
++# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
++CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
++# CONFIG_SCHED_DEBUG is not set
++# CONFIG_SCHEDSTATS is not set
++# CONFIG_TIMER_STATS is not set
++# CONFIG_DEBUG_OBJECTS is not set
++# CONFIG_DEBUG_PREEMPT is not set
++# CONFIG_DEBUG_RT_MUTEXES is not set
++# CONFIG_RT_MUTEX_TESTER is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_MUTEXES is not set
++# CONFIG_DEBUG_LOCK_ALLOC is not set
++# CONFIG_PROVE_LOCKING is not set
++# CONFIG_LOCK_STAT is not set
++# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
++# CONFIG_DEBUG_KOBJECT is not set
++CONFIG_DEBUG_INFO=y
++# CONFIG_DEBUG_VM is not set
++# CONFIG_DEBUG_WRITECOUNT is not set
++# CONFIG_DEBUG_MEMORY_INIT is not set
++# CONFIG_DEBUG_LIST is not set
++# CONFIG_DEBUG_SG is not set
++# CONFIG_DEBUG_NOTIFIERS is not set
++# CONFIG_BOOT_PRINTK_DELAY is not set
++# CONFIG_RCU_TORTURE_TEST is not set
++# CONFIG_RCU_CPU_STALL_DETECTOR is not set
++# CONFIG_BACKTRACE_SELF_TEST is not set
++# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
++# CONFIG_FAULT_INJECTION is not set
++# CONFIG_PAGE_POISONING is not set
++CONFIG_TRACING_SUPPORT=y
++CONFIG_FTRACE=y
++# CONFIG_IRQSOFF_TRACER is not set
++# CONFIG_PREEMPT_TRACER is not set
++# CONFIG_SCHED_TRACER is not set
++# CONFIG_ENABLE_DEFAULT_TRACERS is not set
++# CONFIG_BOOT_TRACER is not set
++CONFIG_BRANCH_PROFILE_NONE=y
++# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
++# CONFIG_PROFILE_ALL_BRANCHES is not set
++# CONFIG_KMEMTRACE is not set
++# CONFIG_WORKQUEUE_TRACER is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_DYNAMIC_DEBUG is not set
++# CONFIG_SAMPLES is not set
++CONFIG_HAVE_ARCH_KGDB=y
++# CONFIG_KGDB is not set
++# CONFIG_KMEMCHECK is not set
++CONFIG_CMDLINE="rw dhash_entries=1024 ihash_entries=1024 ip=10.0.1.3:10.0.1.1:10.0.1.1:255.255.255.0:zeus:eth0: root=/dev/nfs nfsroot=/nfsroot/cramfs,wsize=512,rsize=512,tcp nokgdb console=ttyUSB0,115200 memsize=252M"
++# CONFIG_DEBUG_STACK_USAGE is not set
++# CONFIG_RUNTIME_DEBUG is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITYFS is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_CRYPTO=y
++
++#
++# Crypto core or helper
++#
++# CONFIG_CRYPTO_FIPS is not set
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_ALGAPI2=y
++CONFIG_CRYPTO_AEAD=y
++CONFIG_CRYPTO_AEAD2=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_BLKCIPHER2=y
++CONFIG_CRYPTO_HASH=y
++CONFIG_CRYPTO_HASH2=y
++CONFIG_CRYPTO_RNG2=y
++CONFIG_CRYPTO_PCOMP=y
++CONFIG_CRYPTO_MANAGER=y
++CONFIG_CRYPTO_MANAGER2=y
++# CONFIG_CRYPTO_GF128MUL is not set
++# CONFIG_CRYPTO_NULL is not set
++CONFIG_CRYPTO_WORKQUEUE=y
++# CONFIG_CRYPTO_CRYPTD is not set
++CONFIG_CRYPTO_AUTHENC=y
++# CONFIG_CRYPTO_TEST is not set
++
++#
++# Authenticated Encryption with Associated Data
++#
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_SEQIV is not set
++
++#
++# Block modes
++#
++CONFIG_CRYPTO_CBC=y
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_CTS is not set
++# CONFIG_CRYPTO_ECB is not set
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_XTS is not set
++
++#
++# Hash modes
++#
++CONFIG_CRYPTO_HMAC=y
++# CONFIG_CRYPTO_XCBC is not set
++
++#
++# Digest
++#
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_MD4 is not set
++CONFIG_CRYPTO_MD5=y
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_RMD128 is not set
++# CONFIG_CRYPTO_RMD160 is not set
++# CONFIG_CRYPTO_RMD256 is not set
++# CONFIG_CRYPTO_RMD320 is not set
++CONFIG_CRYPTO_SHA1=y
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_WP512 is not set
++
++#
++# Ciphers
++#
++# CONFIG_CRYPTO_AES is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_ARC4 is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++CONFIG_CRYPTO_DES=y
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++
++#
++# Compression
++#
++CONFIG_CRYPTO_DEFLATE=y
++# CONFIG_CRYPTO_ZLIB is not set
++# CONFIG_CRYPTO_LZO is not set
++
++#
++# Random Number Generation
++#
++# CONFIG_CRYPTO_ANSI_CPRNG is not set
++# CONFIG_CRYPTO_HW is not set
++# CONFIG_BINARY_PRINTF is not set
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++CONFIG_GENERIC_FIND_LAST_BIT=y
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_T10DIF is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
++CONFIG_NLATTR=y
+diff --git a/arch/mips/configs/rbtx49xx_defconfig b/arch/mips/configs/rbtx49xx_defconfig
+index 6c6a19a..4f3b970 100644
+--- a/arch/mips/configs/rbtx49xx_defconfig
++++ b/arch/mips/configs/rbtx49xx_defconfig
+@@ -284,7 +284,6 @@ CONFIG_DEFAULT_AS=y
+ # CONFIG_DEFAULT_CFQ is not set
+ # CONFIG_DEFAULT_NOOP is not set
+ CONFIG_DEFAULT_IOSCHED="anticipatory"
+-# CONFIG_PROBE_INITRD_HEADER is not set
+ # CONFIG_FREEZER is not set
+
+ #
+diff --git a/arch/mips/fw/arc/cmdline.c b/arch/mips/fw/arc/cmdline.c
+index 4ca4eef..5c8603c 100644
+--- a/arch/mips/fw/arc/cmdline.c
++++ b/arch/mips/fw/arc/cmdline.c
+@@ -16,11 +16,6 @@
+
+ #undef DEBUG_CMDLINE
+
+-char * __init prom_getcmdline(void)
+-{
+- return arcs_cmdline;
+-}
+-
+ static char *ignored[] = {
+ "ConsoleIn=",
+ "ConsoleOut=",
+diff --git a/arch/mips/include/asm/bootinfo.h b/arch/mips/include/asm/bootinfo.h
+index f5dfaf6..09eee09 100644
+--- a/arch/mips/include/asm/bootinfo.h
++++ b/arch/mips/include/asm/bootinfo.h
+@@ -67,9 +67,9 @@
+ #define MACH_LEMOTE_ML2F7 3
+ #define MACH_LEMOTE_YL2F89 4
+ #define MACH_DEXXON_GDIUM2F10 5
+-#define MACH_LOONGSON_END 6
+-
+-#define CL_SIZE COMMAND_LINE_SIZE
++#define MACH_LEMOTE_NAS 6
++#define MACH_LEMOTE_LL2F 7
++#define MACH_LOONGSON_END 8
+
+ extern char *system_type;
+ const char *get_system_type(void);
+@@ -107,7 +107,7 @@ extern void free_init_pages(const char *what,
+ /*
+ * Initial kernel command line, usually setup by prom_init()
+ */
+-extern char arcs_cmdline[CL_SIZE];
++extern char arcs_cmdline[COMMAND_LINE_SIZE];
+
+ /*
+ * Registers a0, a1, a3 and a4 as passed to the kernel entry by firmware
+diff --git a/arch/mips/include/asm/clock.h b/arch/mips/include/asm/clock.h
+new file mode 100644
+index 0000000..83894aa
+--- /dev/null
++++ b/arch/mips/include/asm/clock.h
+@@ -0,0 +1,64 @@
++#ifndef __ASM_MIPS_CLOCK_H
++#define __ASM_MIPS_CLOCK_H
++
++#include <linux/kref.h>
++#include <linux/list.h>
++#include <linux/seq_file.h>
++#include <linux/clk.h>
++
++extern void (*cpu_wait) (void);
++
++struct clk;
++
++struct clk_ops {
++ void (*init) (struct clk *clk);
++ void (*enable) (struct clk *clk);
++ void (*disable) (struct clk *clk);
++ void (*recalc) (struct clk *clk);
++ int (*set_rate) (struct clk *clk, unsigned long rate, int algo_id);
++ long (*round_rate) (struct clk *clk, unsigned long rate);
++};
++
++struct clk {
++ struct list_head node;
++ const char *name;
++ int id;
++ struct module *owner;
++
++ struct clk *parent;
++ struct clk_ops *ops;
++
++ struct kref kref;
++
++ unsigned long rate;
++ unsigned long flags;
++};
++
++#define CLK_ALWAYS_ENABLED (1 << 0)
++#define CLK_RATE_PROPAGATES (1 << 1)
++
++/* Should be defined by processor-specific code */
++void arch_init_clk_ops(struct clk_ops **, int type);
++
++int clk_init(void);
++
++int __clk_enable(struct clk *);
++void __clk_disable(struct clk *);
++
++void clk_recalc_rate(struct clk *);
++
++int clk_register(struct clk *);
++void clk_unregister(struct clk *);
++
++/* the exported API, in addition to clk_set_rate */
++/**
++ * clk_set_rate_ex - set the clock rate for a clock source, with additional parameter
++ * @clk: clock source
++ * @rate: desired clock rate in Hz
++ * @algo_id: algorithm id to be passed down to ops->set_rate
++ *
++ * Returns success (0) or negative errno.
++ */
++int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id);
++
++#endif /* __ASM_MIPS_CLOCK_H */
+diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h
+index 4b96d1a..cf373a9 100644
+--- a/arch/mips/include/asm/cpu.h
++++ b/arch/mips/include/asm/cpu.h
+@@ -154,6 +154,8 @@
+ #define PRID_REV_VR4181A 0x0070 /* Same as VR4122 */
+ #define PRID_REV_VR4130 0x0080
+ #define PRID_REV_34K_V1_0_2 0x0022
++#define PRID_REV_LOONGSON2E 0x0002
++#define PRID_REV_LOONGSON2F 0x0003
+
+ /*
+ * Older processors used to encode processor version and revision in two
+diff --git a/arch/mips/include/asm/fpu_emulator.h b/arch/mips/include/asm/fpu_emulator.h
+index e518957..aecada6 100644
+--- a/arch/mips/include/asm/fpu_emulator.h
++++ b/arch/mips/include/asm/fpu_emulator.h
+@@ -25,17 +25,27 @@
+
+ #include <asm/break.h>
+ #include <asm/inst.h>
++#include <asm/local.h>
++
++#ifdef CONFIG_DEBUG_FS
+
+ struct mips_fpu_emulator_stats {
+- unsigned int emulated;
+- unsigned int loads;
+- unsigned int stores;
+- unsigned int cp1ops;
+- unsigned int cp1xops;
+- unsigned int errors;
++ local_t emulated;
++ local_t loads;
++ local_t stores;
++ local_t cp1ops;
++ local_t cp1xops;
++ local_t errors;
+ };
+
+-extern struct mips_fpu_emulator_stats fpuemustats;
++DECLARE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats);
++
++#define MIPS_FPU_EMU_INC_STATS(M) \
++ cpu_local_wrap(__local_inc(&__get_cpu_var(fpuemustats).M))
++
++#else
++#define MIPS_FPU_EMU_INC_STATS(M) do { } while (0)
++#endif /* CONFIG_DEBUG_FS */
+
+ extern int mips_dsemul(struct pt_regs *regs, mips_instruction ir,
+ unsigned long cpc);
+diff --git a/arch/mips/include/asm/ftrace.h b/arch/mips/include/asm/ftrace.h
+index 40a8c17..3986cd8 100644
+--- a/arch/mips/include/asm/ftrace.h
++++ b/arch/mips/include/asm/ftrace.h
+@@ -1 +1,90 @@
+-/* empty */
++/*
++ * 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) 2009 DSLab, Lanzhou University, China
++ * Author: Wu Zhangjin <wuzj@lemote.com>
++ */
++
++#ifndef _ASM_MIPS_FTRACE_H
++#define _ASM_MIPS_FTRACE_H
++
++#ifdef CONFIG_FUNCTION_TRACER
++
++#define MCOUNT_ADDR ((unsigned long)(_mcount))
++#define MCOUNT_INSN_SIZE 4 /* sizeof mcount call */
++
++#ifndef __ASSEMBLY__
++extern void _mcount(void);
++#define mcount _mcount
++
++#define safe_load(load, src, dst, error) \
++do { \
++ asm volatile ( \
++ "1: " load " %[" STR(dst) "], 0(%[" STR(src) "])\n"\
++ " li %[" STR(error) "], 0\n" \
++ "2:\n" \
++ \
++ ".section .fixup, \"ax\"\n" \
++ "3: li %[" STR(error) "], 1\n" \
++ " j 2b\n" \
++ ".previous\n" \
++ \
++ ".section\t__ex_table,\"a\"\n\t" \
++ STR(PTR) "\t1b, 3b\n\t" \
++ ".previous\n" \
++ \
++ : [dst] "=&r" (dst), [error] "=r" (error)\
++ : [src] "r" (src) \
++ : "memory" \
++ ); \
++} while (0)
++
++#define safe_store(store, src, dst, error) \
++do { \
++ asm volatile ( \
++ "1: " store " %[" STR(src) "], 0(%[" STR(dst) "])\n"\
++ " li %[" STR(error) "], 0\n" \
++ "2:\n" \
++ \
++ ".section .fixup, \"ax\"\n" \
++ "3: li %[" STR(error) "], 1\n" \
++ " j 2b\n" \
++ ".previous\n" \
++ \
++ ".section\t__ex_table,\"a\"\n\t"\
++ STR(PTR) "\t1b, 3b\n\t" \
++ ".previous\n" \
++ \
++ : [error] "=r" (error) \
++ : [dst] "r" (dst), [src] "r" (src)\
++ : "memory" \
++ ); \
++} while (0)
++
++#define safe_load_code(dst, src, error) \
++ safe_load(STR(lw), src, dst, error)
++#define safe_store_code(src, dst, error) \
++ safe_store(STR(sw), src, dst, error)
++
++#define safe_load_stack(dst, src, error) \
++ safe_load(STR(PTR_L), src, dst, error)
++
++#define safe_store_stack(src, dst, error) \
++ safe_store(STR(PTR_S), src, dst, error)
++
++
++#ifdef CONFIG_DYNAMIC_FTRACE
++static inline unsigned long ftrace_call_adjust(unsigned long addr)
++{
++ return addr;
++}
++
++struct dyn_arch_ftrace {
++};
++
++#endif /* CONFIG_DYNAMIC_FTRACE */
++#endif /* __ASSEMBLY__ */
++#endif /* CONFIG_FUNCTION_TRACER */
++#endif /* _ASM_MIPS_FTRACE_H */
+diff --git a/arch/mips/include/asm/irq.h b/arch/mips/include/asm/irq.h
+index 09b08d0..0696036 100644
+--- a/arch/mips/include/asm/irq.h
++++ b/arch/mips/include/asm/irq.h
+@@ -113,36 +113,11 @@ do { \
+
+ #endif
+
+-/*
+- * do_IRQ handles all normal device IRQ's (the special
+- * SMP cross-CPU interrupts have their own specific
+- * handlers).
+- *
+- * Ideally there should be away to get this into kernel/irq/handle.c to
+- * avoid the overhead of a call for just a tiny function ...
+- */
+-#define do_IRQ(irq) \
+-do { \
+- irq_enter(); \
+- __DO_IRQ_SMTC_HOOK(irq); \
+- generic_handle_irq(irq); \
+- irq_exit(); \
+-} while (0)
++extern void do_IRQ(unsigned int irq);
+
+ #ifdef CONFIG_MIPS_MT_SMTC_IRQAFF
+-/*
+- * To avoid inefficient and in some cases pathological re-checking of
+- * IRQ affinity, we have this variant that skips the affinity check.
+- */
+-
+
+-#define do_IRQ_no_affinity(irq) \
+-do { \
+- irq_enter(); \
+- __NO_AFFINITY_IRQ_SMTC_HOOK(irq); \
+- generic_handle_irq(irq); \
+- irq_exit(); \
+-} while (0)
++extern void do_IRQ_no_affinity(unsigned int irq);
+
+ #endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */
+
+diff --git a/arch/mips/include/asm/mach-au1x00/au1000.h b/arch/mips/include/asm/mach-au1x00/au1000.h
+index 854e95f..e049d15 100644
+--- a/arch/mips/include/asm/mach-au1x00/au1000.h
++++ b/arch/mips/include/asm/mach-au1x00/au1000.h
+@@ -130,6 +130,55 @@ static inline int au1xxx_cpu_needs_config_od(void)
+ return 0;
+ }
+
++#define ALCHEMY_CPU_UNKNOWN -1
++#define ALCHEMY_CPU_AU1000 0
++#define ALCHEMY_CPU_AU1500 1
++#define ALCHEMY_CPU_AU1100 2
++#define ALCHEMY_CPU_AU1550 3
++#define ALCHEMY_CPU_AU1200 4
++
++static inline int alchemy_get_cputype(void)
++{
++ switch (read_c0_prid() & 0xffff0000) {
++ case 0x00030000:
++ return ALCHEMY_CPU_AU1000;
++ break;
++ case 0x01030000:
++ return ALCHEMY_CPU_AU1500;
++ break;
++ case 0x02030000:
++ return ALCHEMY_CPU_AU1100;
++ break;
++ case 0x03030000:
++ return ALCHEMY_CPU_AU1550;
++ break;
++ case 0x04030000:
++ return ALCHEMY_CPU_AU1200;
++ break;
++ }
++
++ return ALCHEMY_CPU_UNKNOWN;
++}
++
++static inline void alchemy_uart_putchar(u32 uart_phys, u8 c)
++{
++ void __iomem *base = (void __iomem *)KSEG1ADDR(uart_phys);
++ int timeout, i;
++
++ /* check LSR TX_EMPTY bit */
++ timeout = 0xffffff;
++ do {
++ if (__raw_readl(base + 0x1c) & 0x20)
++ break;
++ /* slow down */
++ for (i = 10000; i; i--)
++ asm volatile ("nop");
++ } while (--timeout);
++
++ __raw_writel(c, base + 0x04); /* tx */
++ wmb();
++}
++
+ /* arch/mips/au1000/common/clocks.c */
+ extern void set_au1x00_speed(unsigned int new_freq);
+ extern unsigned int get_au1x00_speed(void);
+@@ -143,20 +192,332 @@ void au_sleep(void);
+ void save_au1xxx_intctl(void);
+ void restore_au1xxx_intctl(void);
+
+-/*
+- * Every board describes its IRQ mapping with this table.
+- */
+-struct au1xxx_irqmap {
+- int im_irq;
+- int im_type;
+- int im_request;
++
++/* SOC Interrupt numbers */
++
++#define AU1000_INTC0_INT_BASE (MIPS_CPU_IRQ_BASE + 8)
++#define AU1000_INTC0_INT_LAST (AU1000_INTC0_INT_BASE + 31)
++#define AU1000_INTC1_INT_BASE (AU1000_INTC0_INT_LAST + 1)
++#define AU1000_INTC1_INT_LAST (AU1000_INTC1_INT_BASE + 31)
++#define AU1000_MAX_INTR AU1000_INTC1_INT_LAST
++
++enum soc_au1000_ints {
++ AU1000_FIRST_INT = AU1000_INTC0_INT_BASE,
++ AU1000_UART0_INT = AU1000_FIRST_INT,
++ AU1000_UART1_INT,
++ AU1000_UART2_INT,
++ AU1000_UART3_INT,
++ AU1000_SSI0_INT,
++ AU1000_SSI1_INT,
++ AU1000_DMA_INT_BASE,
++
++ AU1000_TOY_INT = AU1000_FIRST_INT + 14,
++ AU1000_TOY_MATCH0_INT,
++ AU1000_TOY_MATCH1_INT,
++ AU1000_TOY_MATCH2_INT,
++ AU1000_RTC_INT,
++ AU1000_RTC_MATCH0_INT,
++ AU1000_RTC_MATCH1_INT,
++ AU1000_RTC_MATCH2_INT,
++ AU1000_IRDA_TX_INT,
++ AU1000_IRDA_RX_INT,
++ AU1000_USB_DEV_REQ_INT,
++ AU1000_USB_DEV_SUS_INT,
++ AU1000_USB_HOST_INT,
++ AU1000_ACSYNC_INT,
++ AU1000_MAC0_DMA_INT,
++ AU1000_MAC1_DMA_INT,
++ AU1000_I2S_UO_INT,
++ AU1000_AC97C_INT,
++ AU1000_GPIO0_INT,
++ AU1000_GPIO1_INT,
++ AU1000_GPIO2_INT,
++ AU1000_GPIO3_INT,
++ AU1000_GPIO4_INT,
++ AU1000_GPIO5_INT,
++ AU1000_GPIO6_INT,
++ AU1000_GPIO7_INT,
++ AU1000_GPIO8_INT,
++ AU1000_GPIO9_INT,
++ AU1000_GPIO10_INT,
++ AU1000_GPIO11_INT,
++ AU1000_GPIO12_INT,
++ AU1000_GPIO13_INT,
++ AU1000_GPIO14_INT,
++ AU1000_GPIO15_INT,
++ AU1000_GPIO16_INT,
++ AU1000_GPIO17_INT,
++ AU1000_GPIO18_INT,
++ AU1000_GPIO19_INT,
++ AU1000_GPIO20_INT,
++ AU1000_GPIO21_INT,
++ AU1000_GPIO22_INT,
++ AU1000_GPIO23_INT,
++ AU1000_GPIO24_INT,
++ AU1000_GPIO25_INT,
++ AU1000_GPIO26_INT,
++ AU1000_GPIO27_INT,
++ AU1000_GPIO28_INT,
++ AU1000_GPIO29_INT,
++ AU1000_GPIO30_INT,
++ AU1000_GPIO31_INT,
+ };
+
+-/* core calls this function to let boards initialize other IRQ sources */
+-void board_init_irq(void);
++enum soc_au1100_ints {
++ AU1100_FIRST_INT = AU1000_INTC0_INT_BASE,
++ AU1100_UART0_INT = AU1100_FIRST_INT,
++ AU1100_UART1_INT,
++ AU1100_SD_INT,
++ AU1100_UART3_INT,
++ AU1100_SSI0_INT,
++ AU1100_SSI1_INT,
++ AU1100_DMA_INT_BASE,
++
++ AU1100_TOY_INT = AU1100_FIRST_INT + 14,
++ AU1100_TOY_MATCH0_INT,
++ AU1100_TOY_MATCH1_INT,
++ AU1100_TOY_MATCH2_INT,
++ AU1100_RTC_INT,
++ AU1100_RTC_MATCH0_INT,
++ AU1100_RTC_MATCH1_INT,
++ AU1100_RTC_MATCH2_INT,
++ AU1100_IRDA_TX_INT,
++ AU1100_IRDA_RX_INT,
++ AU1100_USB_DEV_REQ_INT,
++ AU1100_USB_DEV_SUS_INT,
++ AU1100_USB_HOST_INT,
++ AU1100_ACSYNC_INT,
++ AU1100_MAC0_DMA_INT,
++ AU1100_GPIO208_215_INT,
++ AU1100_LCD_INT,
++ AU1100_AC97C_INT,
++ AU1100_GPIO0_INT,
++ AU1100_GPIO1_INT,
++ AU1100_GPIO2_INT,
++ AU1100_GPIO3_INT,
++ AU1100_GPIO4_INT,
++ AU1100_GPIO5_INT,
++ AU1100_GPIO6_INT,
++ AU1100_GPIO7_INT,
++ AU1100_GPIO8_INT,
++ AU1100_GPIO9_INT,
++ AU1100_GPIO10_INT,
++ AU1100_GPIO11_INT,
++ AU1100_GPIO12_INT,
++ AU1100_GPIO13_INT,
++ AU1100_GPIO14_INT,
++ AU1100_GPIO15_INT,
++ AU1100_GPIO16_INT,
++ AU1100_GPIO17_INT,
++ AU1100_GPIO18_INT,
++ AU1100_GPIO19_INT,
++ AU1100_GPIO20_INT,
++ AU1100_GPIO21_INT,
++ AU1100_GPIO22_INT,
++ AU1100_GPIO23_INT,
++ AU1100_GPIO24_INT,
++ AU1100_GPIO25_INT,
++ AU1100_GPIO26_INT,
++ AU1100_GPIO27_INT,
++ AU1100_GPIO28_INT,
++ AU1100_GPIO29_INT,
++ AU1100_GPIO30_INT,
++ AU1100_GPIO31_INT,
++};
+
+-/* boards call this to register additional (GPIO) interrupts */
+-void au1xxx_setup_irqmap(struct au1xxx_irqmap *map, int count);
++enum soc_au1500_ints {
++ AU1500_FIRST_INT = AU1000_INTC0_INT_BASE,
++ AU1500_UART0_INT = AU1500_FIRST_INT,
++ AU1500_PCI_INTA,
++ AU1500_PCI_INTB,
++ AU1500_UART3_INT,
++ AU1500_PCI_INTC,
++ AU1500_PCI_INTD,
++ AU1500_DMA_INT_BASE,
++
++ AU1500_TOY_INT = AU1500_FIRST_INT + 14,
++ AU1500_TOY_MATCH0_INT,
++ AU1500_TOY_MATCH1_INT,
++ AU1500_TOY_MATCH2_INT,
++ AU1500_RTC_INT,
++ AU1500_RTC_MATCH0_INT,
++ AU1500_RTC_MATCH1_INT,
++ AU1500_RTC_MATCH2_INT,
++ AU1500_PCI_ERR_INT,
++ AU1500_RESERVED_INT,
++ AU1500_USB_DEV_REQ_INT,
++ AU1500_USB_DEV_SUS_INT,
++ AU1500_USB_HOST_INT,
++ AU1500_ACSYNC_INT,
++ AU1500_MAC0_DMA_INT,
++ AU1500_MAC1_DMA_INT,
++ AU1500_AC97C_INT = AU1500_FIRST_INT + 31,
++ AU1500_GPIO0_INT,
++ AU1500_GPIO1_INT,
++ AU1500_GPIO2_INT,
++ AU1500_GPIO3_INT,
++ AU1500_GPIO4_INT,
++ AU1500_GPIO5_INT,
++ AU1500_GPIO6_INT,
++ AU1500_GPIO7_INT,
++ AU1500_GPIO8_INT,
++ AU1500_GPIO9_INT,
++ AU1500_GPIO10_INT,
++ AU1500_GPIO11_INT,
++ AU1500_GPIO12_INT,
++ AU1500_GPIO13_INT,
++ AU1500_GPIO14_INT,
++ AU1500_GPIO15_INT,
++ AU1500_GPIO200_INT,
++ AU1500_GPIO201_INT,
++ AU1500_GPIO202_INT,
++ AU1500_GPIO203_INT,
++ AU1500_GPIO20_INT,
++ AU1500_GPIO204_INT,
++ AU1500_GPIO205_INT,
++ AU1500_GPIO23_INT,
++ AU1500_GPIO24_INT,
++ AU1500_GPIO25_INT,
++ AU1500_GPIO26_INT,
++ AU1500_GPIO27_INT,
++ AU1500_GPIO28_INT,
++ AU1500_GPIO206_INT,
++ AU1500_GPIO207_INT,
++ AU1500_GPIO208_215_INT,
++};
++
++enum soc_au1550_ints {
++ AU1550_FIRST_INT = AU1000_INTC0_INT_BASE,
++ AU1550_UART0_INT = AU1550_FIRST_INT,
++ AU1550_PCI_INTA,
++ AU1550_PCI_INTB,
++ AU1550_DDMA_INT,
++ AU1550_CRYPTO_INT,
++ AU1550_PCI_INTC,
++ AU1550_PCI_INTD,
++ AU1550_PCI_RST_INT,
++ AU1550_UART1_INT,
++ AU1550_UART3_INT,
++ AU1550_PSC0_INT,
++ AU1550_PSC1_INT,
++ AU1550_PSC2_INT,
++ AU1550_PSC3_INT,
++ AU1550_TOY_INT,
++ AU1550_TOY_MATCH0_INT,
++ AU1550_TOY_MATCH1_INT,
++ AU1550_TOY_MATCH2_INT,
++ AU1550_RTC_INT,
++ AU1550_RTC_MATCH0_INT,
++ AU1550_RTC_MATCH1_INT,
++ AU1550_RTC_MATCH2_INT,
++
++ AU1550_NAND_INT = AU1550_FIRST_INT + 23,
++ AU1550_USB_DEV_REQ_INT,
++ AU1550_USB_DEV_SUS_INT,
++ AU1550_USB_HOST_INT,
++ AU1550_MAC0_DMA_INT,
++ AU1550_MAC1_DMA_INT,
++ AU1550_GPIO0_INT = AU1550_FIRST_INT + 32,
++ AU1550_GPIO1_INT,
++ AU1550_GPIO2_INT,
++ AU1550_GPIO3_INT,
++ AU1550_GPIO4_INT,
++ AU1550_GPIO5_INT,
++ AU1550_GPIO6_INT,
++ AU1550_GPIO7_INT,
++ AU1550_GPIO8_INT,
++ AU1550_GPIO9_INT,
++ AU1550_GPIO10_INT,
++ AU1550_GPIO11_INT,
++ AU1550_GPIO12_INT,
++ AU1550_GPIO13_INT,
++ AU1550_GPIO14_INT,
++ AU1550_GPIO15_INT,
++ AU1550_GPIO200_INT,
++ AU1550_GPIO201_205_INT, /* Logical or of GPIO201:205 */
++ AU1550_GPIO16_INT,
++ AU1550_GPIO17_INT,
++ AU1550_GPIO20_INT,
++ AU1550_GPIO21_INT,
++ AU1550_GPIO22_INT,
++ AU1550_GPIO23_INT,
++ AU1550_GPIO24_INT,
++ AU1550_GPIO25_INT,
++ AU1550_GPIO26_INT,
++ AU1550_GPIO27_INT,
++ AU1550_GPIO28_INT,
++ AU1550_GPIO206_INT,
++ AU1550_GPIO207_INT,
++ AU1550_GPIO208_215_INT, /* Logical or of GPIO208:215 */
++};
++
++enum soc_au1200_ints {
++ AU1200_FIRST_INT = AU1000_INTC0_INT_BASE,
++ AU1200_UART0_INT = AU1200_FIRST_INT,
++ AU1200_SWT_INT,
++ AU1200_SD_INT,
++ AU1200_DDMA_INT,
++ AU1200_MAE_BE_INT,
++ AU1200_GPIO200_INT,
++ AU1200_GPIO201_INT,
++ AU1200_GPIO202_INT,
++ AU1200_UART1_INT,
++ AU1200_MAE_FE_INT,
++ AU1200_PSC0_INT,
++ AU1200_PSC1_INT,
++ AU1200_AES_INT,
++ AU1200_CAMERA_INT,
++ AU1200_TOY_INT,
++ AU1200_TOY_MATCH0_INT,
++ AU1200_TOY_MATCH1_INT,
++ AU1200_TOY_MATCH2_INT,
++ AU1200_RTC_INT,
++ AU1200_RTC_MATCH0_INT,
++ AU1200_RTC_MATCH1_INT,
++ AU1200_RTC_MATCH2_INT,
++ AU1200_GPIO203_INT,
++ AU1200_NAND_INT,
++ AU1200_GPIO204_INT,
++ AU1200_GPIO205_INT,
++ AU1200_GPIO206_INT,
++ AU1200_GPIO207_INT,
++ AU1200_GPIO208_215_INT, /* Logical OR of 208:215 */
++ AU1200_USB_INT,
++ AU1200_LCD_INT,
++ AU1200_MAE_BOTH_INT,
++ AU1200_GPIO0_INT,
++ AU1200_GPIO1_INT,
++ AU1200_GPIO2_INT,
++ AU1200_GPIO3_INT,
++ AU1200_GPIO4_INT,
++ AU1200_GPIO5_INT,
++ AU1200_GPIO6_INT,
++ AU1200_GPIO7_INT,
++ AU1200_GPIO8_INT,
++ AU1200_GPIO9_INT,
++ AU1200_GPIO10_INT,
++ AU1200_GPIO11_INT,
++ AU1200_GPIO12_INT,
++ AU1200_GPIO13_INT,
++ AU1200_GPIO14_INT,
++ AU1200_GPIO15_INT,
++ AU1200_GPIO16_INT,
++ AU1200_GPIO17_INT,
++ AU1200_GPIO18_INT,
++ AU1200_GPIO19_INT,
++ AU1200_GPIO20_INT,
++ AU1200_GPIO21_INT,
++ AU1200_GPIO22_INT,
++ AU1200_GPIO23_INT,
++ AU1200_GPIO24_INT,
++ AU1200_GPIO25_INT,
++ AU1200_GPIO26_INT,
++ AU1200_GPIO27_INT,
++ AU1200_GPIO28_INT,
++ AU1200_GPIO29_INT,
++ AU1200_GPIO30_INT,
++ AU1200_GPIO31_INT,
++};
+
+ #endif /* !defined (_LANGUAGE_ASSEMBLY) */
+
+@@ -549,78 +910,16 @@ void au1xxx_setup_irqmap(struct au1xxx_irqmap *map, int count);
+
+ #define IC1_TESTBIT 0xB1800080
+
+-/* Interrupt Numbers */
++
+ /* Au1000 */
+ #ifdef CONFIG_SOC_AU1000
+-enum soc_au1000_ints {
+- AU1000_FIRST_INT = MIPS_CPU_IRQ_BASE + 8,
+- AU1000_UART0_INT = AU1000_FIRST_INT,
+- AU1000_UART1_INT, /* au1000 */
+- AU1000_UART2_INT, /* au1000 */
+- AU1000_UART3_INT,
+- AU1000_SSI0_INT, /* au1000 */
+- AU1000_SSI1_INT, /* au1000 */
+- AU1000_DMA_INT_BASE,
+-
+- AU1000_TOY_INT = AU1000_FIRST_INT + 14,
+- AU1000_TOY_MATCH0_INT,
+- AU1000_TOY_MATCH1_INT,
+- AU1000_TOY_MATCH2_INT,
+- AU1000_RTC_INT,
+- AU1000_RTC_MATCH0_INT,
+- AU1000_RTC_MATCH1_INT,
+- AU1000_RTC_MATCH2_INT,
+- AU1000_IRDA_TX_INT, /* au1000 */
+- AU1000_IRDA_RX_INT, /* au1000 */
+- AU1000_USB_DEV_REQ_INT,
+- AU1000_USB_DEV_SUS_INT,
+- AU1000_USB_HOST_INT,
+- AU1000_ACSYNC_INT,
+- AU1000_MAC0_DMA_INT,
+- AU1000_MAC1_DMA_INT,
+- AU1000_I2S_UO_INT, /* au1000 */
+- AU1000_AC97C_INT,
+- AU1000_GPIO_0,
+- AU1000_GPIO_1,
+- AU1000_GPIO_2,
+- AU1000_GPIO_3,
+- AU1000_GPIO_4,
+- AU1000_GPIO_5,
+- AU1000_GPIO_6,
+- AU1000_GPIO_7,
+- AU1000_GPIO_8,
+- AU1000_GPIO_9,
+- AU1000_GPIO_10,
+- AU1000_GPIO_11,
+- AU1000_GPIO_12,
+- AU1000_GPIO_13,
+- AU1000_GPIO_14,
+- AU1000_GPIO_15,
+- AU1000_GPIO_16,
+- AU1000_GPIO_17,
+- AU1000_GPIO_18,
+- AU1000_GPIO_19,
+- AU1000_GPIO_20,
+- AU1000_GPIO_21,
+- AU1000_GPIO_22,
+- AU1000_GPIO_23,
+- AU1000_GPIO_24,
+- AU1000_GPIO_25,
+- AU1000_GPIO_26,
+- AU1000_GPIO_27,
+- AU1000_GPIO_28,
+- AU1000_GPIO_29,
+- AU1000_GPIO_30,
+- AU1000_GPIO_31,
+-};
+
+ #define UART0_ADDR 0xB1100000
+-#define UART1_ADDR 0xB1200000
+-#define UART2_ADDR 0xB1300000
+ #define UART3_ADDR 0xB1400000
+
+ #define USB_OHCI_BASE 0x10100000 /* phys addr for ioremap */
+ #define USB_HOST_CONFIG 0xB017FFFC
++#define FOR_PLATFORM_C_USB_HOST_INT AU1000_USB_HOST_INT
+
+ #define AU1000_ETH0_BASE 0xB0500000
+ #define AU1000_ETH1_BASE 0xB0510000
+@@ -631,78 +930,13 @@ enum soc_au1000_ints {
+
+ /* Au1500 */
+ #ifdef CONFIG_SOC_AU1500
+-enum soc_au1500_ints {
+- AU1500_FIRST_INT = MIPS_CPU_IRQ_BASE + 8,
+- AU1500_UART0_INT = AU1500_FIRST_INT,
+- AU1000_PCI_INTA, /* au1500 */
+- AU1000_PCI_INTB, /* au1500 */
+- AU1500_UART3_INT,
+- AU1000_PCI_INTC, /* au1500 */
+- AU1000_PCI_INTD, /* au1500 */
+- AU1000_DMA_INT_BASE,
+-
+- AU1000_TOY_INT = AU1500_FIRST_INT + 14,
+- AU1000_TOY_MATCH0_INT,
+- AU1000_TOY_MATCH1_INT,
+- AU1000_TOY_MATCH2_INT,
+- AU1000_RTC_INT,
+- AU1000_RTC_MATCH0_INT,
+- AU1000_RTC_MATCH1_INT,
+- AU1000_RTC_MATCH2_INT,
+- AU1500_PCI_ERR_INT,
+- AU1500_RESERVED_INT,
+- AU1000_USB_DEV_REQ_INT,
+- AU1000_USB_DEV_SUS_INT,
+- AU1000_USB_HOST_INT,
+- AU1000_ACSYNC_INT,
+- AU1500_MAC0_DMA_INT,
+- AU1500_MAC1_DMA_INT,
+- AU1000_AC97C_INT = AU1500_FIRST_INT + 31,
+- AU1000_GPIO_0,
+- AU1000_GPIO_1,
+- AU1000_GPIO_2,
+- AU1000_GPIO_3,
+- AU1000_GPIO_4,
+- AU1000_GPIO_5,
+- AU1000_GPIO_6,
+- AU1000_GPIO_7,
+- AU1000_GPIO_8,
+- AU1000_GPIO_9,
+- AU1000_GPIO_10,
+- AU1000_GPIO_11,
+- AU1000_GPIO_12,
+- AU1000_GPIO_13,
+- AU1000_GPIO_14,
+- AU1000_GPIO_15,
+- AU1500_GPIO_200,
+- AU1500_GPIO_201,
+- AU1500_GPIO_202,
+- AU1500_GPIO_203,
+- AU1500_GPIO_20,
+- AU1500_GPIO_204,
+- AU1500_GPIO_205,
+- AU1500_GPIO_23,
+- AU1500_GPIO_24,
+- AU1500_GPIO_25,
+- AU1500_GPIO_26,
+- AU1500_GPIO_27,
+- AU1500_GPIO_28,
+- AU1500_GPIO_206,
+- AU1500_GPIO_207,
+- AU1500_GPIO_208_215,
+-};
+-
+-/* shortcuts */
+-#define INTA AU1000_PCI_INTA
+-#define INTB AU1000_PCI_INTB
+-#define INTC AU1000_PCI_INTC
+-#define INTD AU1000_PCI_INTD
+
+ #define UART0_ADDR 0xB1100000
+ #define UART3_ADDR 0xB1400000
+
+ #define USB_OHCI_BASE 0x10100000 /* phys addr for ioremap */
+ #define USB_HOST_CONFIG 0xB017fffc
++#define FOR_PLATFORM_C_USB_HOST_INT AU1500_USB_HOST_INT
+
+ #define AU1500_ETH0_BASE 0xB1500000
+ #define AU1500_ETH1_BASE 0xB1510000
+@@ -713,74 +947,13 @@ enum soc_au1500_ints {
+
+ /* Au1100 */
+ #ifdef CONFIG_SOC_AU1100
+-enum soc_au1100_ints {
+- AU1100_FIRST_INT = MIPS_CPU_IRQ_BASE + 8,
+- AU1100_UART0_INT = AU1100_FIRST_INT,
+- AU1100_UART1_INT,
+- AU1100_SD_INT,
+- AU1100_UART3_INT,
+- AU1000_SSI0_INT,
+- AU1000_SSI1_INT,
+- AU1000_DMA_INT_BASE,
+-
+- AU1000_TOY_INT = AU1100_FIRST_INT + 14,
+- AU1000_TOY_MATCH0_INT,
+- AU1000_TOY_MATCH1_INT,
+- AU1000_TOY_MATCH2_INT,
+- AU1000_RTC_INT,
+- AU1000_RTC_MATCH0_INT,
+- AU1000_RTC_MATCH1_INT,
+- AU1000_RTC_MATCH2_INT,
+- AU1000_IRDA_TX_INT,
+- AU1000_IRDA_RX_INT,
+- AU1000_USB_DEV_REQ_INT,
+- AU1000_USB_DEV_SUS_INT,
+- AU1000_USB_HOST_INT,
+- AU1000_ACSYNC_INT,
+- AU1100_MAC0_DMA_INT,
+- AU1100_GPIO_208_215,
+- AU1100_LCD_INT,
+- AU1000_AC97C_INT,
+- AU1000_GPIO_0,
+- AU1000_GPIO_1,
+- AU1000_GPIO_2,
+- AU1000_GPIO_3,
+- AU1000_GPIO_4,
+- AU1000_GPIO_5,
+- AU1000_GPIO_6,
+- AU1000_GPIO_7,
+- AU1000_GPIO_8,
+- AU1000_GPIO_9,
+- AU1000_GPIO_10,
+- AU1000_GPIO_11,
+- AU1000_GPIO_12,
+- AU1000_GPIO_13,
+- AU1000_GPIO_14,
+- AU1000_GPIO_15,
+- AU1000_GPIO_16,
+- AU1000_GPIO_17,
+- AU1000_GPIO_18,
+- AU1000_GPIO_19,
+- AU1000_GPIO_20,
+- AU1000_GPIO_21,
+- AU1000_GPIO_22,
+- AU1000_GPIO_23,
+- AU1000_GPIO_24,
+- AU1000_GPIO_25,
+- AU1000_GPIO_26,
+- AU1000_GPIO_27,
+- AU1000_GPIO_28,
+- AU1000_GPIO_29,
+- AU1000_GPIO_30,
+- AU1000_GPIO_31,
+-};
+
+ #define UART0_ADDR 0xB1100000
+-#define UART1_ADDR 0xB1200000
+ #define UART3_ADDR 0xB1400000
+
+ #define USB_OHCI_BASE 0x10100000 /* phys addr for ioremap */
+ #define USB_HOST_CONFIG 0xB017FFFC
++#define FOR_PLATFORM_C_USB_HOST_INT AU1100_USB_HOST_INT
+
+ #define AU1100_ETH0_BASE 0xB0500000
+ #define AU1100_MAC0_ENABLE 0xB0520000
+@@ -788,87 +961,12 @@ enum soc_au1100_ints {
+ #endif /* CONFIG_SOC_AU1100 */
+
+ #ifdef CONFIG_SOC_AU1550
+-enum soc_au1550_ints {
+- AU1550_FIRST_INT = MIPS_CPU_IRQ_BASE + 8,
+- AU1550_UART0_INT = AU1550_FIRST_INT,
+- AU1550_PCI_INTA,
+- AU1550_PCI_INTB,
+- AU1550_DDMA_INT,
+- AU1550_CRYPTO_INT,
+- AU1550_PCI_INTC,
+- AU1550_PCI_INTD,
+- AU1550_PCI_RST_INT,
+- AU1550_UART1_INT,
+- AU1550_UART3_INT,
+- AU1550_PSC0_INT,
+- AU1550_PSC1_INT,
+- AU1550_PSC2_INT,
+- AU1550_PSC3_INT,
+- AU1000_TOY_INT,
+- AU1000_TOY_MATCH0_INT,
+- AU1000_TOY_MATCH1_INT,
+- AU1000_TOY_MATCH2_INT,
+- AU1000_RTC_INT,
+- AU1000_RTC_MATCH0_INT,
+- AU1000_RTC_MATCH1_INT,
+- AU1000_RTC_MATCH2_INT,
+-
+- AU1550_NAND_INT = AU1550_FIRST_INT + 23,
+- AU1550_USB_DEV_REQ_INT,
+- AU1000_USB_DEV_REQ_INT = AU1550_USB_DEV_REQ_INT,
+- AU1550_USB_DEV_SUS_INT,
+- AU1000_USB_DEV_SUS_INT = AU1550_USB_DEV_SUS_INT,
+- AU1550_USB_HOST_INT,
+- AU1000_USB_HOST_INT = AU1550_USB_HOST_INT,
+- AU1550_MAC0_DMA_INT,
+- AU1550_MAC1_DMA_INT,
+- AU1000_GPIO_0 = AU1550_FIRST_INT + 32,
+- AU1000_GPIO_1,
+- AU1000_GPIO_2,
+- AU1000_GPIO_3,
+- AU1000_GPIO_4,
+- AU1000_GPIO_5,
+- AU1000_GPIO_6,
+- AU1000_GPIO_7,
+- AU1000_GPIO_8,
+- AU1000_GPIO_9,
+- AU1000_GPIO_10,
+- AU1000_GPIO_11,
+- AU1000_GPIO_12,
+- AU1000_GPIO_13,
+- AU1000_GPIO_14,
+- AU1000_GPIO_15,
+- AU1550_GPIO_200,
+- AU1500_GPIO_201_205, /* Logical or of GPIO201:205 */
+- AU1500_GPIO_16,
+- AU1500_GPIO_17,
+- AU1500_GPIO_20,
+- AU1500_GPIO_21,
+- AU1500_GPIO_22,
+- AU1500_GPIO_23,
+- AU1500_GPIO_24,
+- AU1500_GPIO_25,
+- AU1500_GPIO_26,
+- AU1500_GPIO_27,
+- AU1500_GPIO_28,
+- AU1500_GPIO_206,
+- AU1500_GPIO_207,
+- AU1500_GPIO_208_218, /* Logical or of GPIO208:218 */
+-};
+-
+-/* shortcuts */
+-#define INTA AU1550_PCI_INTA
+-#define INTB AU1550_PCI_INTB
+-#define INTC AU1550_PCI_INTC
+-#define INTD AU1550_PCI_INTD
+-
+ #define UART0_ADDR 0xB1100000
+-#define UART1_ADDR 0xB1200000
+-#define UART3_ADDR 0xB1400000
+
+ #define USB_OHCI_BASE 0x14020000 /* phys addr for ioremap */
+ #define USB_OHCI_LEN 0x00060000
+ #define USB_HOST_CONFIG 0xB4027ffc
++#define FOR_PLATFORM_C_USB_HOST_INT AU1550_USB_HOST_INT
+
+ #define AU1550_ETH0_BASE 0xB0500000
+ #define AU1550_ETH1_BASE 0xB0510000
+@@ -877,78 +975,10 @@ enum soc_au1550_ints {
+ #define NUM_ETH_INTERFACES 2
+ #endif /* CONFIG_SOC_AU1550 */
+
++
+ #ifdef CONFIG_SOC_AU1200
+-enum soc_au1200_ints {
+- AU1200_FIRST_INT = MIPS_CPU_IRQ_BASE + 8,
+- AU1200_UART0_INT = AU1200_FIRST_INT,
+- AU1200_SWT_INT,
+- AU1200_SD_INT,
+- AU1200_DDMA_INT,
+- AU1200_MAE_BE_INT,
+- AU1200_GPIO_200,
+- AU1200_GPIO_201,
+- AU1200_GPIO_202,
+- AU1200_UART1_INT,
+- AU1200_MAE_FE_INT,
+- AU1200_PSC0_INT,
+- AU1200_PSC1_INT,
+- AU1200_AES_INT,
+- AU1200_CAMERA_INT,
+- AU1000_TOY_INT,
+- AU1000_TOY_MATCH0_INT,
+- AU1000_TOY_MATCH1_INT,
+- AU1000_TOY_MATCH2_INT,
+- AU1000_RTC_INT,
+- AU1000_RTC_MATCH0_INT,
+- AU1000_RTC_MATCH1_INT,
+- AU1000_RTC_MATCH2_INT,
+- AU1200_GPIO_203,
+- AU1200_NAND_INT,
+- AU1200_GPIO_204,
+- AU1200_GPIO_205,
+- AU1200_GPIO_206,
+- AU1200_GPIO_207,
+- AU1200_GPIO_208_215, /* Logical OR of 208:215 */
+- AU1200_USB_INT,
+- AU1000_USB_HOST_INT = AU1200_USB_INT,
+- AU1200_LCD_INT,
+- AU1200_MAE_BOTH_INT,
+- AU1000_GPIO_0,
+- AU1000_GPIO_1,
+- AU1000_GPIO_2,
+- AU1000_GPIO_3,
+- AU1000_GPIO_4,
+- AU1000_GPIO_5,
+- AU1000_GPIO_6,
+- AU1000_GPIO_7,
+- AU1000_GPIO_8,
+- AU1000_GPIO_9,
+- AU1000_GPIO_10,
+- AU1000_GPIO_11,
+- AU1000_GPIO_12,
+- AU1000_GPIO_13,
+- AU1000_GPIO_14,
+- AU1000_GPIO_15,
+- AU1000_GPIO_16,
+- AU1000_GPIO_17,
+- AU1000_GPIO_18,
+- AU1000_GPIO_19,
+- AU1000_GPIO_20,
+- AU1000_GPIO_21,
+- AU1000_GPIO_22,
+- AU1000_GPIO_23,
+- AU1000_GPIO_24,
+- AU1000_GPIO_25,
+- AU1000_GPIO_26,
+- AU1000_GPIO_27,
+- AU1000_GPIO_28,
+- AU1000_GPIO_29,
+- AU1000_GPIO_30,
+- AU1000_GPIO_31,
+-};
+
+ #define UART0_ADDR 0xB1100000
+-#define UART1_ADDR 0xB1200000
+
+ #define USB_UOC_BASE 0x14020020
+ #define USB_UOC_LEN 0x20
+@@ -974,15 +1004,9 @@ enum soc_au1200_ints {
+ #define USBMSRMCFG_RDCOMB 30
+ #define USBMSRMCFG_PFEN 31
+
+-#endif /* CONFIG_SOC_AU1200 */
+-
+-#define AU1000_INTC0_INT_BASE (MIPS_CPU_IRQ_BASE + 8)
+-#define AU1000_INTC0_INT_LAST (AU1000_INTC0_INT_BASE + 31)
+-#define AU1000_INTC1_INT_BASE (AU1000_INTC0_INT_BASE + 32)
+-#define AU1000_INTC1_INT_LAST (AU1000_INTC1_INT_BASE + 31)
++#define FOR_PLATFORM_C_USB_HOST_INT AU1200_USB_INT
+
+-#define AU1000_MAX_INTR AU1000_INTC1_INT_LAST
+-#define INTX 0xFF /* not valid */
++#endif /* CONFIG_SOC_AU1200 */
+
+ /* Programmable Counters 0 and 1 */
+ #define SYS_BASE 0xB1900000
+@@ -1231,14 +1255,6 @@ enum soc_au1200_ints {
+ #define MAC_RX_BUFF3_STATUS 0x30
+ #define MAC_RX_BUFF3_ADDR 0x34
+
+-/* UARTS 0-3 */
+-#define UART_BASE UART0_ADDR
+-#ifdef CONFIG_SOC_AU1200
+-#define UART_DEBUG_BASE UART1_ADDR
+-#else
+-#define UART_DEBUG_BASE UART3_ADDR
+-#endif
+-
+ #define UART_RX 0 /* Receive buffer */
+ #define UART_TX 4 /* Transmit buffer */
+ #define UART_IER 8 /* Interrupt Enable Register */
+@@ -1251,84 +1267,6 @@ enum soc_au1200_ints {
+ #define UART_CLK 0x28 /* Baud Rate Clock Divider */
+ #define UART_MOD_CNTRL 0x100 /* Module Control */
+
+-#define UART_FCR_ENABLE_FIFO 0x01 /* Enable the FIFO */
+-#define UART_FCR_CLEAR_RCVR 0x02 /* Clear the RCVR FIFO */
+-#define UART_FCR_CLEAR_XMIT 0x04 /* Clear the XMIT FIFO */
+-#define UART_FCR_DMA_SELECT 0x08 /* For DMA applications */
+-#define UART_FCR_TRIGGER_MASK 0xF0 /* Mask for the FIFO trigger range */
+-#define UART_FCR_R_TRIGGER_1 0x00 /* Mask for receive trigger set at 1 */
+-#define UART_FCR_R_TRIGGER_4 0x40 /* Mask for receive trigger set at 4 */
+-#define UART_FCR_R_TRIGGER_8 0x80 /* Mask for receive trigger set at 8 */
+-#define UART_FCR_R_TRIGGER_14 0xA0 /* Mask for receive trigger set at 14 */
+-#define UART_FCR_T_TRIGGER_0 0x00 /* Mask for transmit trigger set at 0 */
+-#define UART_FCR_T_TRIGGER_4 0x10 /* Mask for transmit trigger set at 4 */
+-#define UART_FCR_T_TRIGGER_8 0x20 /* Mask for transmit trigger set at 8 */
+-#define UART_FCR_T_TRIGGER_12 0x30 /* Mask for transmit trigger set at 12 */
+-
+-/*
+- * These are the definitions for the Line Control Register
+- */
+-#define UART_LCR_SBC 0x40 /* Set break control */
+-#define UART_LCR_SPAR 0x20 /* Stick parity (?) */
+-#define UART_LCR_EPAR 0x10 /* Even parity select */
+-#define UART_LCR_PARITY 0x08 /* Parity Enable */
+-#define UART_LCR_STOP 0x04 /* Stop bits: 0=1 stop bit, 1= 2 stop bits */
+-#define UART_LCR_WLEN5 0x00 /* Wordlength: 5 bits */
+-#define UART_LCR_WLEN6 0x01 /* Wordlength: 6 bits */
+-#define UART_LCR_WLEN7 0x02 /* Wordlength: 7 bits */
+-#define UART_LCR_WLEN8 0x03 /* Wordlength: 8 bits */
+-
+-/*
+- * These are the definitions for the Line Status Register
+- */
+-#define UART_LSR_TEMT 0x40 /* Transmitter empty */
+-#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */
+-#define UART_LSR_BI 0x10 /* Break interrupt indicator */
+-#define UART_LSR_FE 0x08 /* Frame error indicator */
+-#define UART_LSR_PE 0x04 /* Parity error indicator */
+-#define UART_LSR_OE 0x02 /* Overrun error indicator */
+-#define UART_LSR_DR 0x01 /* Receiver data ready */
+-
+-/*
+- * These are the definitions for the Interrupt Identification Register
+- */
+-#define UART_IIR_NO_INT 0x01 /* No interrupts pending */
+-#define UART_IIR_ID 0x06 /* Mask for the interrupt ID */
+-#define UART_IIR_MSI 0x00 /* Modem status interrupt */
+-#define UART_IIR_THRI 0x02 /* Transmitter holding register empty */
+-#define UART_IIR_RDI 0x04 /* Receiver data interrupt */
+-#define UART_IIR_RLSI 0x06 /* Receiver line status interrupt */
+-
+-/*
+- * These are the definitions for the Interrupt Enable Register
+- */
+-#define UART_IER_MSI 0x08 /* Enable Modem status interrupt */
+-#define UART_IER_RLSI 0x04 /* Enable receiver line status interrupt */
+-#define UART_IER_THRI 0x02 /* Enable Transmitter holding register int. */
+-#define UART_IER_RDI 0x01 /* Enable receiver data interrupt */
+-
+-/*
+- * These are the definitions for the Modem Control Register
+- */
+-#define UART_MCR_LOOP 0x10 /* Enable loopback test mode */
+-#define UART_MCR_OUT2 0x08 /* Out2 complement */
+-#define UART_MCR_OUT1 0x04 /* Out1 complement */
+-#define UART_MCR_RTS 0x02 /* RTS complement */
+-#define UART_MCR_DTR 0x01 /* DTR complement */
+-
+-/*
+- * These are the definitions for the Modem Status Register
+- */
+-#define UART_MSR_DCD 0x80 /* Data Carrier Detect */
+-#define UART_MSR_RI 0x40 /* Ring Indicator */
+-#define UART_MSR_DSR 0x20 /* Data Set Ready */
+-#define UART_MSR_CTS 0x10 /* Clear to Send */
+-#define UART_MSR_DDCD 0x08 /* Delta DCD */
+-#define UART_MSR_TERI 0x04 /* Trailing edge ring indicator */
+-#define UART_MSR_DDSR 0x02 /* Delta DSR */
+-#define UART_MSR_DCTS 0x01 /* Delta CTS */
+-#define UART_MSR_ANY_DELTA 0x0F /* Any of the delta bits! */
+-
+ /* SSIO */
+ #define SSI0_STATUS 0xB1600000
+ # define SSI_STATUS_BF (1 << 4)
+@@ -1739,53 +1677,18 @@ enum soc_au1200_ints {
+
+ #endif
+
+-#ifndef _LANGUAGE_ASSEMBLY
+-typedef volatile struct {
+- /* 0x0000 */ u32 toytrim;
+- /* 0x0004 */ u32 toywrite;
+- /* 0x0008 */ u32 toymatch0;
+- /* 0x000C */ u32 toymatch1;
+- /* 0x0010 */ u32 toymatch2;
+- /* 0x0014 */ u32 cntrctrl;
+- /* 0x0018 */ u32 scratch0;
+- /* 0x001C */ u32 scratch1;
+- /* 0x0020 */ u32 freqctrl0;
+- /* 0x0024 */ u32 freqctrl1;
+- /* 0x0028 */ u32 clksrc;
+- /* 0x002C */ u32 pinfunc;
+- /* 0x0030 */ u32 reserved0;
+- /* 0x0034 */ u32 wakemsk;
+- /* 0x0038 */ u32 endian;
+- /* 0x003C */ u32 powerctrl;
+- /* 0x0040 */ u32 toyread;
+- /* 0x0044 */ u32 rtctrim;
+- /* 0x0048 */ u32 rtcwrite;
+- /* 0x004C */ u32 rtcmatch0;
+- /* 0x0050 */ u32 rtcmatch1;
+- /* 0x0054 */ u32 rtcmatch2;
+- /* 0x0058 */ u32 rtcread;
+- /* 0x005C */ u32 wakesrc;
+- /* 0x0060 */ u32 cpupll;
+- /* 0x0064 */ u32 auxpll;
+- /* 0x0068 */ u32 reserved1;
+- /* 0x006C */ u32 reserved2;
+- /* 0x0070 */ u32 reserved3;
+- /* 0x0074 */ u32 reserved4;
+- /* 0x0078 */ u32 slppwr;
+- /* 0x007C */ u32 sleep;
+- /* 0x0080 */ u32 reserved5[32];
+- /* 0x0100 */ u32 trioutrd;
+-#define trioutclr trioutrd
+- /* 0x0104 */ u32 reserved6;
+- /* 0x0108 */ u32 outputrd;
+-#define outputset outputrd
+- /* 0x010C */ u32 outputclr;
+- /* 0x0110 */ u32 pinstaterd;
+-#define pininputen pinstaterd
+-} AU1X00_SYS;
+-
+-static AU1X00_SYS * const sys = (AU1X00_SYS *)SYS_BASE;
+-
+-#endif
++/*
++ * All Au1xx0 SOCs have a PCMCIA controller.
++ * We setup our 32-bit pseudo addresses to be equal to the
++ * 36-bit addr >> 4, to make it easier to check the address
++ * and fix it.
++ * The PCMCIA socket 0 physical attribute address is 0xF 4000 0000.
++ * The pseudo address we use is 0xF400 0000. Any address over
++ * 0xF400 0000 is a PCMCIA pseudo address.
++ */
++#define PCMCIA_IO_PSEUDO_PHYS (PCMCIA_IO_PHYS_ADDR >> 4)
++#define PCMCIA_ATTR_PSEUDO_PHYS (PCMCIA_ATTR_PHYS_ADDR >> 4)
++#define PCMCIA_MEM_PSEUDO_PHYS (PCMCIA_MEM_PHYS_ADDR >> 4)
++#define PCMCIA_PSEUDO_END (0xffffffff)
+
+ #endif
+diff --git a/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h b/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h
+index 06f68f4..c098b45 100644
+--- a/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h
++++ b/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h
+@@ -338,8 +338,8 @@ u32 au1xxx_dbdma_set_devwidth(u32 chanid, int bits);
+ u32 au1xxx_dbdma_ring_alloc(u32 chanid, int entries);
+
+ /* Put buffers on source/destination descriptors. */
+-u32 _au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags);
+-u32 _au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes, u32 flags);
++u32 au1xxx_dbdma_put_source(u32 chanid, dma_addr_t buf, int nbytes, u32 flags);
++u32 au1xxx_dbdma_put_dest(u32 chanid, dma_addr_t buf, int nbytes, u32 flags);
+
+ /* Get a buffer from the destination descriptor. */
+ u32 au1xxx_dbdma_get_dest(u32 chanid, void **buf, int *nbytes);
+@@ -362,25 +362,6 @@ void au1xxx_dbdma_suspend(void);
+ void au1xxx_dbdma_resume(void);
+ #endif
+
+-
+-/*
+- * Some compatibilty macros -- needed to make changes to API
+- * without breaking existing drivers.
+- */
+-#define au1xxx_dbdma_put_source(chanid, buf, nbytes) \
+- _au1xxx_dbdma_put_source(chanid, buf, nbytes, DDMA_FLAGS_IE)
+-#define au1xxx_dbdma_put_source_flags(chanid, buf, nbytes, flags) \
+- _au1xxx_dbdma_put_source(chanid, buf, nbytes, flags)
+-#define put_source_flags(chanid, buf, nbytes, flags) \
+- au1xxx_dbdma_put_source_flags(chanid, buf, nbytes, flags)
+-
+-#define au1xxx_dbdma_put_dest(chanid, buf, nbytes) \
+- _au1xxx_dbdma_put_dest(chanid, buf, nbytes, DDMA_FLAGS_IE)
+-#define au1xxx_dbdma_put_dest_flags(chanid, buf, nbytes, flags) \
+- _au1xxx_dbdma_put_dest(chanid, buf, nbytes, flags)
+-#define put_dest_flags(chanid, buf, nbytes, flags) \
+- au1xxx_dbdma_put_dest_flags(chanid, buf, nbytes, flags)
+-
+ /*
+ * Flags for the put_source/put_dest functions.
+ */
+diff --git a/arch/mips/include/asm/mach-au1x00/au1xxx_eth.h b/arch/mips/include/asm/mach-au1x00/au1xxx_eth.h
+new file mode 100644
+index 0000000..f30529e
+--- /dev/null
++++ b/arch/mips/include/asm/mach-au1x00/au1xxx_eth.h
+@@ -0,0 +1,18 @@
++#ifndef __AU1X00_ETH_DATA_H
++#define __AU1X00_ETH_DATA_H
++
++/* Platform specific PHY configuration passed to the MAC driver */
++struct au1000_eth_platform_data {
++ int phy_static_config;
++ int phy_search_highest_addr;
++ int phy1_search_mac0;
++ int phy_addr;
++ int phy_busid;
++ int phy_irq;
++};
++
++void __init au1xxx_override_eth_cfg(unsigned port,
++ struct au1000_eth_platform_data *eth_data);
++
++#endif /* __AU1X00_ETH_DATA_H */
++
+diff --git a/arch/mips/include/asm/mach-au1x00/gpio-au1000.h b/arch/mips/include/asm/mach-au1x00/gpio-au1000.h
+index 91595fa..9cf32d9 100644
+--- a/arch/mips/include/asm/mach-au1x00/gpio-au1000.h
++++ b/arch/mips/include/asm/mach-au1x00/gpio-au1000.h
+@@ -35,15 +35,13 @@ static inline int au1000_gpio2_to_irq(int gpio)
+ return -ENXIO;
+ }
+
+-#ifdef CONFIG_SOC_AU1000
+ static inline int au1000_irq_to_gpio(int irq)
+ {
+- if ((irq >= AU1000_GPIO_0) && (irq <= AU1000_GPIO_31))
+- return ALCHEMY_GPIO1_BASE + (irq - AU1000_GPIO_0) + 0;
++ if ((irq >= AU1000_GPIO0_INT) && (irq <= AU1000_GPIO31_INT))
++ return ALCHEMY_GPIO1_BASE + (irq - AU1000_GPIO0_INT) + 0;
+
+ return -ENXIO;
+ }
+-#endif
+
+ static inline int au1500_gpio1_to_irq(int gpio)
+ {
+@@ -71,27 +69,25 @@ static inline int au1500_gpio2_to_irq(int gpio)
+ return -ENXIO;
+ }
+
+-#ifdef CONFIG_SOC_AU1500
+ static inline int au1500_irq_to_gpio(int irq)
+ {
+ switch (irq) {
+- case AU1000_GPIO_0 ... AU1000_GPIO_15:
+- case AU1500_GPIO_20:
+- case AU1500_GPIO_23 ... AU1500_GPIO_28:
+- return ALCHEMY_GPIO1_BASE + (irq - AU1000_GPIO_0) + 0;
+- case AU1500_GPIO_200 ... AU1500_GPIO_203:
+- return ALCHEMY_GPIO2_BASE + (irq - AU1500_GPIO_200) + 0;
+- case AU1500_GPIO_204 ... AU1500_GPIO_205:
+- return ALCHEMY_GPIO2_BASE + (irq - AU1500_GPIO_204) + 4;
+- case AU1500_GPIO_206 ... AU1500_GPIO_207:
+- return ALCHEMY_GPIO2_BASE + (irq - AU1500_GPIO_206) + 6;
+- case AU1500_GPIO_208_215:
++ case AU1500_GPIO0_INT ... AU1500_GPIO15_INT:
++ case AU1500_GPIO20_INT:
++ case AU1500_GPIO23_INT ... AU1500_GPIO28_INT:
++ return ALCHEMY_GPIO1_BASE + (irq - AU1500_GPIO0_INT) + 0;
++ case AU1500_GPIO200_INT ... AU1500_GPIO203_INT:
++ return ALCHEMY_GPIO2_BASE + (irq - AU1500_GPIO200_INT) + 0;
++ case AU1500_GPIO204_INT ... AU1500_GPIO205_INT:
++ return ALCHEMY_GPIO2_BASE + (irq - AU1500_GPIO204_INT) + 4;
++ case AU1500_GPIO206_INT ... AU1500_GPIO207_INT:
++ return ALCHEMY_GPIO2_BASE + (irq - AU1500_GPIO206_INT) + 6;
++ case AU1500_GPIO208_215_INT:
+ return ALCHEMY_GPIO2_BASE + 8;
+ }
+
+ return -ENXIO;
+ }
+-#endif
+
+ static inline int au1100_gpio1_to_irq(int gpio)
+ {
+@@ -108,19 +104,17 @@ static inline int au1100_gpio2_to_irq(int gpio)
+ return -ENXIO;
+ }
+
+-#ifdef CONFIG_SOC_AU1100
+ static inline int au1100_irq_to_gpio(int irq)
+ {
+ switch (irq) {
+- case AU1000_GPIO_0 ... AU1000_GPIO_31:
+- return ALCHEMY_GPIO1_BASE + (irq - AU1000_GPIO_0) + 0;
+- case AU1100_GPIO_208_215:
++ case AU1100_GPIO0_INT ... AU1100_GPIO31_INT:
++ return ALCHEMY_GPIO1_BASE + (irq - AU1100_GPIO0_INT) + 0;
++ case AU1100_GPIO208_215_INT:
+ return ALCHEMY_GPIO2_BASE + 8;
+ }
+
+ return -ENXIO;
+ }
+-#endif
+
+ static inline int au1550_gpio1_to_irq(int gpio)
+ {
+@@ -149,24 +143,22 @@ static inline int au1550_gpio2_to_irq(int gpio)
+ return -ENXIO;
+ }
+
+-#ifdef CONFIG_SOC_AU1550
+ static inline int au1550_irq_to_gpio(int irq)
+ {
+ switch (irq) {
+- case AU1000_GPIO_0 ... AU1000_GPIO_15:
+- return ALCHEMY_GPIO1_BASE + (irq - AU1000_GPIO_0) + 0;
+- case AU1550_GPIO_200:
+- case AU1500_GPIO_201_205:
+- return ALCHEMY_GPIO2_BASE + (irq - AU1550_GPIO_200) + 0;
+- case AU1500_GPIO_16 ... AU1500_GPIO_28:
+- return ALCHEMY_GPIO1_BASE + (irq - AU1500_GPIO_16) + 16;
+- case AU1500_GPIO_206 ... AU1500_GPIO_208_218:
+- return ALCHEMY_GPIO2_BASE + (irq - AU1500_GPIO_206) + 6;
++ case AU1550_GPIO0_INT ... AU1550_GPIO15_INT:
++ return ALCHEMY_GPIO1_BASE + (irq - AU1550_GPIO0_INT) + 0;
++ case AU1550_GPIO200_INT:
++ case AU1550_GPIO201_205_INT:
++ return ALCHEMY_GPIO2_BASE + (irq - AU1550_GPIO200_INT) + 0;
++ case AU1550_GPIO16_INT ... AU1550_GPIO28_INT:
++ return ALCHEMY_GPIO1_BASE + (irq - AU1550_GPIO16_INT) + 16;
++ case AU1550_GPIO206_INT ... AU1550_GPIO208_215_INT:
++ return ALCHEMY_GPIO2_BASE + (irq - AU1550_GPIO206_INT) + 6;
+ }
+
+ return -ENXIO;
+ }
+-#endif
+
+ static inline int au1200_gpio1_to_irq(int gpio)
+ {
+@@ -187,23 +179,21 @@ static inline int au1200_gpio2_to_irq(int gpio)
+ return -ENXIO;
+ }
+
+-#ifdef CONFIG_SOC_AU1200
+ static inline int au1200_irq_to_gpio(int irq)
+ {
+ switch (irq) {
+- case AU1000_GPIO_0 ... AU1000_GPIO_31:
+- return ALCHEMY_GPIO1_BASE + (irq - AU1000_GPIO_0) + 0;
+- case AU1200_GPIO_200 ... AU1200_GPIO_202:
+- return ALCHEMY_GPIO2_BASE + (irq - AU1200_GPIO_200) + 0;
+- case AU1200_GPIO_203:
++ case AU1200_GPIO0_INT ... AU1200_GPIO31_INT:
++ return ALCHEMY_GPIO1_BASE + (irq - AU1200_GPIO0_INT) + 0;
++ case AU1200_GPIO200_INT ... AU1200_GPIO202_INT:
++ return ALCHEMY_GPIO2_BASE + (irq - AU1200_GPIO200_INT) + 0;
++ case AU1200_GPIO203_INT:
+ return ALCHEMY_GPIO2_BASE + 3;
+- case AU1200_GPIO_204 ... AU1200_GPIO_208_215:
+- return ALCHEMY_GPIO2_BASE + (irq - AU1200_GPIO_204) + 4;
++ case AU1200_GPIO204_INT ... AU1200_GPIO208_215_INT:
++ return ALCHEMY_GPIO2_BASE + (irq - AU1200_GPIO204_INT) + 4;
+ }
+
+ return -ENXIO;
+ }
+-#endif
+
+ /*
+ * GPIO1 block macros for common linux gpio functions.
+diff --git a/arch/mips/include/asm/mach-db1x00/bcsr.h b/arch/mips/include/asm/mach-db1x00/bcsr.h
+new file mode 100644
+index 0000000..618d2de
+--- /dev/null
++++ b/arch/mips/include/asm/mach-db1x00/bcsr.h
+@@ -0,0 +1,238 @@
++/*
++ * bcsr.h -- Db1xxx/Pb1xxx Devboard CPLD registers ("BCSR") abstraction.
++ *
++ * All Alchemy development boards (except, of course, the weird PB1000)
++ * have a few registers in a CPLD with standardised layout; they mostly
++ * only differ in base address and bit meanings in the RESETS and BOARD
++ * registers.
++ *
++ * All data taken from the official AMD board documentation sheets.
++ */
++
++#ifndef _DB1XXX_BCSR_H_
++#define _DB1XXX_BCSR_H_
++
++
++/* BCSR base addresses on various boards. BCSR base 2 refers to the
++ * physical address of the first HEXLEDS register, which is usually
++ * a variable offset from the WHOAMI register.
++ */
++
++/* DB1000, DB1100, DB1500, PB1100, PB1500 */
++#define DB1000_BCSR_PHYS_ADDR 0x0E000000
++#define DB1000_BCSR_HEXLED_OFS 0x01000000
++
++#define DB1550_BCSR_PHYS_ADDR 0x0F000000
++#define DB1550_BCSR_HEXLED_OFS 0x00400000
++
++#define PB1550_BCSR_PHYS_ADDR 0x0F000000
++#define PB1550_BCSR_HEXLED_OFS 0x00800000
++
++#define DB1200_BCSR_PHYS_ADDR 0x19800000
++#define DB1200_BCSR_HEXLED_OFS 0x00400000
++
++#define PB1200_BCSR_PHYS_ADDR 0x0D800000
++#define PB1200_BCSR_HEXLED_OFS 0x00400000
++
++
++enum bcsr_id {
++ /* BCSR base 1 */
++ BCSR_WHOAMI = 0,
++ BCSR_STATUS,
++ BCSR_SWITCHES,
++ BCSR_RESETS,
++ BCSR_PCMCIA,
++ BCSR_BOARD,
++ BCSR_LEDS,
++ BCSR_SYSTEM,
++ /* Au1200/1300 based boards */
++ BCSR_INTCLR,
++ BCSR_INTSET,
++ BCSR_MASKCLR,
++ BCSR_MASKSET,
++ BCSR_SIGSTAT,
++ BCSR_INTSTAT,
++
++ /* BCSR base 2 */
++ BCSR_HEXLEDS,
++ BCSR_RSVD1,
++ BCSR_HEXCLEAR,
++
++ BCSR_CNT,
++};
++
++/* register offsets, valid for all Db1xxx/Pb1xxx boards */
++#define BCSR_REG_WHOAMI 0x00
++#define BCSR_REG_STATUS 0x04
++#define BCSR_REG_SWITCHES 0x08
++#define BCSR_REG_RESETS 0x0c
++#define BCSR_REG_PCMCIA 0x10
++#define BCSR_REG_BOARD 0x14
++#define BCSR_REG_LEDS 0x18
++#define BCSR_REG_SYSTEM 0x1c
++/* Au1200/Au1300 based boards: CPLD IRQ muxer */
++#define BCSR_REG_INTCLR 0x20
++#define BCSR_REG_INTSET 0x24
++#define BCSR_REG_MASKCLR 0x28
++#define BCSR_REG_MASKSET 0x2c
++#define BCSR_REG_SIGSTAT 0x30
++#define BCSR_REG_INTSTAT 0x34
++
++/* hexled control, offset from BCSR base 2 */
++#define BCSR_REG_HEXLEDS 0x00
++#define BCSR_REG_HEXCLEAR 0x08
++
++/*
++ * Register Bits and Pieces.
++ */
++#define BCSR_WHOAMI_DCID(x) ((x) & 0xf)
++#define BCSR_WHOAMI_CPLD(x) (((x) >> 4) & 0xf)
++#define BCSR_WHOAMI_BOARD(x) (((x) >> 8) & 0xf)
++
++/* register "WHOAMI" bits 11:8 identify the board */
++enum bcsr_whoami_boards {
++ BCSR_WHOAMI_PB1500 = 1,
++ BCSR_WHOAMI_PB1500R2,
++ BCSR_WHOAMI_PB1100,
++ BCSR_WHOAMI_DB1000,
++ BCSR_WHOAMI_DB1100,
++ BCSR_WHOAMI_DB1500,
++ BCSR_WHOAMI_DB1550,
++ BCSR_WHOAMI_PB1550_DDR,
++ BCSR_WHOAMI_PB1550 = BCSR_WHOAMI_PB1550_DDR,
++ BCSR_WHOAMI_PB1550_SDR,
++ BCSR_WHOAMI_PB1200_DDR1,
++ BCSR_WHOAMI_PB1200 = BCSR_WHOAMI_PB1200_DDR1,
++ BCSR_WHOAMI_PB1200_DDR2,
++ BCSR_WHOAMI_DB1200,
++};
++
++/* STATUS reg. Unless otherwise noted, they're valid on all boards.
++ * PB1200 = DB1200.
++ */
++#define BCSR_STATUS_PC0VS 0x0003
++#define BCSR_STATUS_PC1VS 0x000C
++#define BCSR_STATUS_PC0FI 0x0010
++#define BCSR_STATUS_PC1FI 0x0020
++#define BCSR_STATUS_PB1550_SWAPBOOT 0x0040
++#define BCSR_STATUS_SRAMWIDTH 0x0080
++#define BCSR_STATUS_FLASHBUSY 0x0100
++#define BCSR_STATUS_ROMBUSY 0x0400
++#define BCSR_STATUS_SD0WP 0x0400 /* DB1200 */
++#define BCSR_STATUS_SD1WP 0x0800
++#define BCSR_STATUS_USBOTGID 0x0800 /* PB/DB1550 */
++#define BCSR_STATUS_DB1000_SWAPBOOT 0x2000
++#define BCSR_STATUS_DB1200_SWAPBOOT 0x0040 /* DB1200 */
++#define BCSR_STATUS_IDECBLID 0x0200 /* DB1200 */
++#define BCSR_STATUS_DB1200_U0RXD 0x1000 /* DB1200 */
++#define BCSR_STATUS_DB1200_U1RXD 0x2000 /* DB1200 */
++#define BCSR_STATUS_FLASHDEN 0xC000
++#define BCSR_STATUS_DB1550_U0RXD 0x1000 /* DB1550 */
++#define BCSR_STATUS_DB1550_U3RXD 0x2000 /* DB1550 */
++#define BCSR_STATUS_PB1550_U0RXD 0x1000 /* PB1550 */
++#define BCSR_STATUS_PB1550_U1RXD 0x2000 /* PB1550 */
++#define BCSR_STATUS_PB1550_U3RXD 0x8000 /* PB1550 */
++
++
++/* DB/PB1000,1100,1500,1550 */
++#define BCSR_RESETS_PHY0 0x0001
++#define BCSR_RESETS_PHY1 0x0002
++#define BCSR_RESETS_DC 0x0004
++#define BCSR_RESETS_FIR_SEL 0x2000
++#define BCSR_RESETS_IRDA_MODE_MASK 0xC000
++#define BCSR_RESETS_IRDA_MODE_FULL 0x0000
++#define BCSR_RESETS_PB1550_WSCFSM 0x2000
++#define BCSR_RESETS_IRDA_MODE_OFF 0x4000
++#define BCSR_RESETS_IRDA_MODE_2_3 0x8000
++#define BCSR_RESETS_IRDA_MODE_1_3 0xC000
++#define BCSR_RESETS_DMAREQ 0x8000 /* PB1550 */
++
++#define BCSR_BOARD_PCIM66EN 0x0001
++#define BCSR_BOARD_SD0PWR 0x0040
++#define BCSR_BOARD_SD1PWR 0x0080
++#define BCSR_BOARD_PCIM33 0x0100
++#define BCSR_BOARD_PCIEXTARB 0x0200
++#define BCSR_BOARD_GPIO200RST 0x0400
++#define BCSR_BOARD_PCICLKOUT 0x0800
++#define BCSR_BOARD_PCICFG 0x1000
++#define BCSR_BOARD_SPISEL 0x4000 /* PB/DB1550 */
++#define BCSR_BOARD_SD0WP 0x4000 /* DB1100 */
++#define BCSR_BOARD_SD1WP 0x8000 /* DB1100 */
++
++
++/* DB/PB1200 */
++#define BCSR_RESETS_ETH 0x0001
++#define BCSR_RESETS_CAMERA 0x0002
++#define BCSR_RESETS_DC 0x0004
++#define BCSR_RESETS_IDE 0x0008
++#define BCSR_RESETS_TV 0x0010 /* DB1200 */
++/* Not resets but in the same register */
++#define BCSR_RESETS_PWMR1MUX 0x0800 /* DB1200 */
++#define BCSR_RESETS_PB1200_WSCFSM 0x0800 /* PB1200 */
++#define BCSR_RESETS_PSC0MUX 0x1000
++#define BCSR_RESETS_PSC1MUX 0x2000
++#define BCSR_RESETS_SPISEL 0x4000
++#define BCSR_RESETS_SD1MUX 0x8000 /* PB1200 */
++
++#define BCSR_BOARD_LCDVEE 0x0001
++#define BCSR_BOARD_LCDVDD 0x0002
++#define BCSR_BOARD_LCDBL 0x0004
++#define BCSR_BOARD_CAMSNAP 0x0010
++#define BCSR_BOARD_CAMPWR 0x0020
++#define BCSR_BOARD_SD0PWR 0x0040
++
++
++#define BCSR_SWITCHES_DIP 0x00FF
++#define BCSR_SWITCHES_DIP_1 0x0080
++#define BCSR_SWITCHES_DIP_2 0x0040
++#define BCSR_SWITCHES_DIP_3 0x0020
++#define BCSR_SWITCHES_DIP_4 0x0010
++#define BCSR_SWITCHES_DIP_5 0x0008
++#define BCSR_SWITCHES_DIP_6 0x0004
++#define BCSR_SWITCHES_DIP_7 0x0002
++#define BCSR_SWITCHES_DIP_8 0x0001
++#define BCSR_SWITCHES_ROTARY 0x0F00
++
++
++#define BCSR_PCMCIA_PC0VPP 0x0003
++#define BCSR_PCMCIA_PC0VCC 0x000C
++#define BCSR_PCMCIA_PC0DRVEN 0x0010
++#define BCSR_PCMCIA_PC0RST 0x0080
++#define BCSR_PCMCIA_PC1VPP 0x0300
++#define BCSR_PCMCIA_PC1VCC 0x0C00
++#define BCSR_PCMCIA_PC1DRVEN 0x1000
++#define BCSR_PCMCIA_PC1RST 0x8000
++
++
++#define BCSR_LEDS_DECIMALS 0x0003
++#define BCSR_LEDS_LED0 0x0100
++#define BCSR_LEDS_LED1 0x0200
++#define BCSR_LEDS_LED2 0x0400
++#define BCSR_LEDS_LED3 0x0800
++
++
++#define BCSR_SYSTEM_RESET 0x8000 /* clear to reset */
++#define BCSR_SYSTEM_PWROFF 0x4000 /* set to power off */
++#define BCSR_SYSTEM_VDDI 0x001F /* PB1xxx boards */
++
++
++
++
++/* initialize BCSR for a board. Provide the PHYSICAL addresses of both
++ * BCSR spaces.
++ */
++void __init bcsr_init(unsigned long bcsr1_phys, unsigned long bcsr2_phys);
++
++/* read a board register */
++unsigned short bcsr_read(enum bcsr_id reg);
++
++/* write to a board register */
++void bcsr_write(enum bcsr_id reg, unsigned short val);
++
++/* modify a register. clear bits set in 'clr', set bits set in 'set' */
++void bcsr_mod(enum bcsr_id reg, unsigned short clr, unsigned short set);
++
++/* install CPLD IRQ demuxer (DB1200/PB1200) */
++void __init bcsr_init_irq(int csc_start, int csc_end, int hook_irq);
++
++#endif
+diff --git a/arch/mips/include/asm/mach-db1x00/db1200.h b/arch/mips/include/asm/mach-db1x00/db1200.h
+index 27f2610..3404248 100644
+--- a/arch/mips/include/asm/mach-db1x00/db1200.h
++++ b/arch/mips/include/asm/mach-db1x00/db1200.h
+@@ -25,133 +25,9 @@
+ #define __ASM_DB1200_H
+
+ #include <linux/types.h>
++#include <asm/mach-au1x00/au1000.h>
+ #include <asm/mach-au1x00/au1xxx_psc.h>
+
+-#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX
+-#define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX
+-#define DBDMA_I2S_TX_CHAN DSCR_CMD0_PSC1_TX
+-#define DBDMA_I2S_RX_CHAN DSCR_CMD0_PSC1_RX
+-
+-/*
+- * SPI and SMB are muxed on the DBAu1200 board.
+- * Refer to board documentation.
+- */
+-#define SPI_PSC_BASE PSC0_BASE_ADDR
+-#define SMBUS_PSC_BASE PSC0_BASE_ADDR
+-/*
+- * AC'97 and I2S are muxed on the DBAu1200 board.
+- * Refer to board documentation.
+- */
+-#define AC97_PSC_BASE PSC1_BASE_ADDR
+-#define I2S_PSC_BASE PSC1_BASE_ADDR
+-
+-#define BCSR_KSEG1_ADDR 0xB9800000
+-
+-typedef volatile struct
+-{
+- /*00*/ u16 whoami;
+- u16 reserved0;
+- /*04*/ u16 status;
+- u16 reserved1;
+- /*08*/ u16 switches;
+- u16 reserved2;
+- /*0C*/ u16 resets;
+- u16 reserved3;
+-
+- /*10*/ u16 pcmcia;
+- u16 reserved4;
+- /*14*/ u16 board;
+- u16 reserved5;
+- /*18*/ u16 disk_leds;
+- u16 reserved6;
+- /*1C*/ u16 system;
+- u16 reserved7;
+-
+- /*20*/ u16 intclr;
+- u16 reserved8;
+- /*24*/ u16 intset;
+- u16 reserved9;
+- /*28*/ u16 intclr_mask;
+- u16 reserved10;
+- /*2C*/ u16 intset_mask;
+- u16 reserved11;
+-
+- /*30*/ u16 sig_status;
+- u16 reserved12;
+- /*34*/ u16 int_status;
+- u16 reserved13;
+- /*38*/ u16 reserved14;
+- u16 reserved15;
+- /*3C*/ u16 reserved16;
+- u16 reserved17;
+-
+-} BCSR;
+-
+-static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
+-
+-/*
+- * Register bit definitions for the BCSRs
+- */
+-#define BCSR_WHOAMI_DCID 0x000F
+-#define BCSR_WHOAMI_CPLD 0x00F0
+-#define BCSR_WHOAMI_BOARD 0x0F00
+-
+-#define BCSR_STATUS_PCMCIA0VS 0x0003
+-#define BCSR_STATUS_PCMCIA1VS 0x000C
+-#define BCSR_STATUS_SWAPBOOT 0x0040
+-#define BCSR_STATUS_FLASHBUSY 0x0100
+-#define BCSR_STATUS_IDECBLID 0x0200
+-#define BCSR_STATUS_SD0WP 0x0400
+-#define BCSR_STATUS_U0RXD 0x1000
+-#define BCSR_STATUS_U1RXD 0x2000
+-
+-#define BCSR_SWITCHES_OCTAL 0x00FF
+-#define BCSR_SWITCHES_DIP_1 0x0080
+-#define BCSR_SWITCHES_DIP_2 0x0040
+-#define BCSR_SWITCHES_DIP_3 0x0020
+-#define BCSR_SWITCHES_DIP_4 0x0010
+-#define BCSR_SWITCHES_DIP_5 0x0008
+-#define BCSR_SWITCHES_DIP_6 0x0004
+-#define BCSR_SWITCHES_DIP_7 0x0002
+-#define BCSR_SWITCHES_DIP_8 0x0001
+-#define BCSR_SWITCHES_ROTARY 0x0F00
+-
+-#define BCSR_RESETS_ETH 0x0001
+-#define BCSR_RESETS_CAMERA 0x0002
+-#define BCSR_RESETS_DC 0x0004
+-#define BCSR_RESETS_IDE 0x0008
+-#define BCSR_RESETS_TV 0x0010
+-/* Not resets but in the same register */
+-#define BCSR_RESETS_PWMR1MUX 0x0800
+-#define BCSR_RESETS_PCS0MUX 0x1000
+-#define BCSR_RESETS_PCS1MUX 0x2000
+-#define BCSR_RESETS_SPISEL 0x4000
+-
+-#define BCSR_PCMCIA_PC0VPP 0x0003
+-#define BCSR_PCMCIA_PC0VCC 0x000C
+-#define BCSR_PCMCIA_PC0DRVEN 0x0010
+-#define BCSR_PCMCIA_PC0RST 0x0080
+-#define BCSR_PCMCIA_PC1VPP 0x0300
+-#define BCSR_PCMCIA_PC1VCC 0x0C00
+-#define BCSR_PCMCIA_PC1DRVEN 0x1000
+-#define BCSR_PCMCIA_PC1RST 0x8000
+-
+-#define BCSR_BOARD_LCDVEE 0x0001
+-#define BCSR_BOARD_LCDVDD 0x0002
+-#define BCSR_BOARD_LCDBL 0x0004
+-#define BCSR_BOARD_CAMSNAP 0x0010
+-#define BCSR_BOARD_CAMPWR 0x0020
+-#define BCSR_BOARD_SD0PWR 0x0040
+-
+-#define BCSR_LEDS_DECIMALS 0x0003
+-#define BCSR_LEDS_LED0 0x0100
+-#define BCSR_LEDS_LED1 0x0200
+-#define BCSR_LEDS_LED2 0x0400
+-#define BCSR_LEDS_LED3 0x0800
+-
+-#define BCSR_SYSTEM_POWEROFF 0x4000
+-#define BCSR_SYSTEM_RESET 0x8000
+-
+ /* Bit positions for the different interrupt sources */
+ #define BCSR_INT_IDE 0x0001
+ #define BCSR_INT_ETH 0x0002
+@@ -168,17 +44,15 @@ static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
+ #define BCSR_INT_SD0INSERT 0x1000
+ #define BCSR_INT_SD0EJECT 0x2000
+
+-#define SMC91C111_PHYS_ADDR 0x19000300
+-#define SMC91C111_INT DB1200_ETH_INT
+-
+ #define IDE_PHYS_ADDR 0x18800000
+ #define IDE_REG_SHIFT 5
+-#define IDE_PHYS_LEN (16 << IDE_REG_SHIFT)
+-#define IDE_INT DB1200_IDE_INT
+ #define IDE_DDMA_REQ DSCR_CMD0_DMA_REQ1
+ #define IDE_RQSIZE 128
+
+-#define NAND_PHYS_ADDR 0x20000000
++#define DB1200_IDE_PHYS_ADDR IDE_PHYS_ADDR
++#define DB1200_IDE_PHYS_LEN (16 << IDE_REG_SHIFT)
++#define DB1200_ETH_PHYS_ADDR 0x19000300
++#define DB1200_NAND_PHYS_ADDR 0x20000000
+
+ /*
+ * External Interrupts for DBAu1200 as of 8/6/2004.
+@@ -188,7 +62,7 @@ static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
+ * Example: IDE bis pos is = 64 - 64
+ * ETH bit pos is = 65 - 64
+ */
+-enum external_pb1200_ints {
++enum external_db1200_ints {
+ DB1200_INT_BEGIN = AU1000_MAX_INTR + 1,
+
+ DB1200_IDE_INT = DB1200_INT_BEGIN,
+@@ -209,22 +83,4 @@ enum external_pb1200_ints {
+ DB1200_INT_END = DB1200_INT_BEGIN + 15,
+ };
+
+-
+-/*
+- * DBAu1200 specific PCMCIA defines for drivers/pcmcia/au1000_db1x00.c
+- */
+-#define PCMCIA_MAX_SOCK 1
+-#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1)
+-
+-/* VPP/VCC */
+-#define SET_VCC_VPP(VCC, VPP, SLOT) \
+- ((((VCC) << 2) | ((VPP) << 0)) << ((SLOT) * 8))
+-
+-#define BOARD_PC0_INT DB1200_PC0_INT
+-#define BOARD_PC1_INT DB1200_PC1_INT
+-#define BOARD_CARD_INSERTED(SOCKET) bcsr->sig_status & (1 << (8 + (2 * SOCKET)))
+-
+-/* NAND chip select */
+-#define NAND_CS 1
+-
+ #endif /* __ASM_DB1200_H */
+diff --git a/arch/mips/include/asm/mach-db1x00/db1x00.h b/arch/mips/include/asm/mach-db1x00/db1x00.h
+index 1a515b8..a919dac 100644
+--- a/arch/mips/include/asm/mach-db1x00/db1x00.h
++++ b/arch/mips/include/asm/mach-db1x00/db1x00.h
+@@ -41,111 +41,11 @@
+ #define SMBUS_PSC_BASE PSC2_BASE_ADDR
+ #define I2S_PSC_BASE PSC3_BASE_ADDR
+
+-#define BCSR_KSEG1_ADDR 0xAF000000
+ #define NAND_PHYS_ADDR 0x20000000
+
+-#else
+-#define BCSR_KSEG1_ADDR 0xAE000000
+ #endif
+
+ /*
+- * Overlay data structure of the DBAu1x00 board registers.
+- * Registers are located at physical 0E0000xx, KSEG1 0xAE0000xx.
+- */
+-typedef volatile struct
+-{
+- /*00*/ unsigned short whoami;
+- unsigned short reserved0;
+- /*04*/ unsigned short status;
+- unsigned short reserved1;
+- /*08*/ unsigned short switches;
+- unsigned short reserved2;
+- /*0C*/ unsigned short resets;
+- unsigned short reserved3;
+- /*10*/ unsigned short pcmcia;
+- unsigned short reserved4;
+- /*14*/ unsigned short specific;
+- unsigned short reserved5;
+- /*18*/ unsigned short leds;
+- unsigned short reserved6;
+- /*1C*/ unsigned short swreset;
+- unsigned short reserved7;
+-
+-} BCSR;
+-
+-
+-/*
+- * Register/mask bit definitions for the BCSRs
+- */
+-#define BCSR_WHOAMI_DCID 0x000F
+-#define BCSR_WHOAMI_CPLD 0x00F0
+-#define BCSR_WHOAMI_BOARD 0x0F00
+-
+-#define BCSR_STATUS_PC0VS 0x0003
+-#define BCSR_STATUS_PC1VS 0x000C
+-#define BCSR_STATUS_PC0FI 0x0010
+-#define BCSR_STATUS_PC1FI 0x0020
+-#define BCSR_STATUS_FLASHBUSY 0x0100
+-#define BCSR_STATUS_ROMBUSY 0x0400
+-#define BCSR_STATUS_SWAPBOOT 0x2000
+-#define BCSR_STATUS_FLASHDEN 0xC000
+-
+-#define BCSR_SWITCHES_DIP 0x00FF
+-#define BCSR_SWITCHES_DIP_1 0x0080
+-#define BCSR_SWITCHES_DIP_2 0x0040
+-#define BCSR_SWITCHES_DIP_3 0x0020
+-#define BCSR_SWITCHES_DIP_4 0x0010
+-#define BCSR_SWITCHES_DIP_5 0x0008
+-#define BCSR_SWITCHES_DIP_6 0x0004
+-#define BCSR_SWITCHES_DIP_7 0x0002
+-#define BCSR_SWITCHES_DIP_8 0x0001
+-#define BCSR_SWITCHES_ROTARY 0x0F00
+-
+-#define BCSR_RESETS_PHY0 0x0001
+-#define BCSR_RESETS_PHY1 0x0002
+-#define BCSR_RESETS_DC 0x0004
+-#define BCSR_RESETS_FIR_SEL 0x2000
+-#define BCSR_RESETS_IRDA_MODE_MASK 0xC000
+-#define BCSR_RESETS_IRDA_MODE_FULL 0x0000
+-#define BCSR_RESETS_IRDA_MODE_OFF 0x4000
+-#define BCSR_RESETS_IRDA_MODE_2_3 0x8000
+-#define BCSR_RESETS_IRDA_MODE_1_3 0xC000
+-
+-#define BCSR_PCMCIA_PC0VPP 0x0003
+-#define BCSR_PCMCIA_PC0VCC 0x000C
+-#define BCSR_PCMCIA_PC0DRVEN 0x0010
+-#define BCSR_PCMCIA_PC0RST 0x0080
+-#define BCSR_PCMCIA_PC1VPP 0x0300
+-#define BCSR_PCMCIA_PC1VCC 0x0C00
+-#define BCSR_PCMCIA_PC1DRVEN 0x1000
+-#define BCSR_PCMCIA_PC1RST 0x8000
+-
+-#define BCSR_BOARD_PCIM66EN 0x0001
+-#define BCSR_BOARD_SD0_PWR 0x0040
+-#define BCSR_BOARD_SD1_PWR 0x0080
+-#define BCSR_BOARD_PCIM33 0x0100
+-#define BCSR_BOARD_GPIO200RST 0x0400
+-#define BCSR_BOARD_PCICFG 0x1000
+-#define BCSR_BOARD_SD0_WP 0x4000
+-#define BCSR_BOARD_SD1_WP 0x8000
+-
+-#define BCSR_LEDS_DECIMALS 0x0003
+-#define BCSR_LEDS_LED0 0x0100
+-#define BCSR_LEDS_LED1 0x0200
+-#define BCSR_LEDS_LED2 0x0400
+-#define BCSR_LEDS_LED3 0x0800
+-
+-#define BCSR_SWRESET_RESET 0x0080
+-
+-/* PCMCIA DBAu1x00 specific defines */
+-#define PCMCIA_MAX_SOCK 1
+-#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1)
+-
+-/* VPP/VCC */
+-#define SET_VCC_VPP(VCC, VPP, SLOT)\
+- ((((VCC) << 2) | ((VPP) << 0)) << ((SLOT) * 8))
+-
+-/*
+ * NAND defines
+ *
+ * Timing values as described in databook, * ns value stripped of the
+diff --git a/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h b/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h
+new file mode 100644
+index 0000000..1cf86f3
+--- /dev/null
++++ b/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h
+@@ -0,0 +1,340 @@
++/*
++ * The header file of cs5536 sourth bridge.
++ *
++ * Copyright (C) 2007 Lemote, Inc.
++ * Author : jlliu <liujl@lemote.com>
++ */
++
++#ifndef _CS5536_H
++#define _CS5536_H
++
++#include <linux/types.h>
++
++extern void _rdmsr(u32 msr, u32 *hi, u32 *lo);
++extern void _wrmsr(u32 msr, u32 hi, u32 lo);
++
++/*
++ * MSR module base
++ */
++#define CS5536_SB_MSR_BASE (0x00000000)
++#define CS5536_GLIU_MSR_BASE (0x10000000)
++#define CS5536_ILLEGAL_MSR_BASE (0x20000000)
++#define CS5536_USB_MSR_BASE (0x40000000)
++#define CS5536_IDE_MSR_BASE (0x60000000)
++#define CS5536_DIVIL_MSR_BASE (0x80000000)
++#define CS5536_ACC_MSR_BASE (0xa0000000)
++#define CS5536_UNUSED_MSR_BASE (0xc0000000)
++#define CS5536_GLCP_MSR_BASE (0xe0000000)
++
++#define SB_MSR_REG(offset) (CS5536_SB_MSR_BASE | (offset))
++#define GLIU_MSR_REG(offset) (CS5536_GLIU_MSR_BASE | (offset))
++#define ILLEGAL_MSR_REG(offset) (CS5536_ILLEGAL_MSR_BASE | (offset))
++#define USB_MSR_REG(offset) (CS5536_USB_MSR_BASE | (offset))
++#define IDE_MSR_REG(offset) (CS5536_IDE_MSR_BASE | (offset))
++#define DIVIL_MSR_REG(offset) (CS5536_DIVIL_MSR_BASE | (offset))
++#define ACC_MSR_REG(offset) (CS5536_ACC_MSR_BASE | (offset))
++#define UNUSED_MSR_REG(offset) (CS5536_UNUSED_MSR_BASE | (offset))
++#define GLCP_MSR_REG(offset) (CS5536_GLCP_MSR_BASE | (offset))
++
++/*
++ * BAR SPACE OF VIRTUAL PCI :
++ * range for pci probe use, length is the actual size.
++ */
++/* IO space for all DIVIL modules */
++#define CS5536_IRQ_RANGE 0xffffffe0 /* USERD FOR PCI PROBE */
++#define CS5536_IRQ_LENGTH 0x20 /* THE REGS ACTUAL LENGTH */
++#define CS5536_SMB_RANGE 0xfffffff8
++#define CS5536_SMB_LENGTH 0x08
++#define CS5536_GPIO_RANGE 0xffffff00
++#define CS5536_GPIO_LENGTH 0x100
++#define CS5536_MFGPT_RANGE 0xffffffc0
++#define CS5536_MFGPT_LENGTH 0x40
++#define CS5536_ACPI_RANGE 0xffffffe0
++#define CS5536_ACPI_LENGTH 0x20
++#define CS5536_PMS_RANGE 0xffffff80
++#define CS5536_PMS_LENGTH 0x80
++/* IO space for IDE */
++#define CS5536_IDE_RANGE 0xfffffff0
++#define CS5536_IDE_LENGTH 0x10
++/* IO space for ACC */
++#define CS5536_ACC_RANGE 0xffffff80
++#define CS5536_ACC_LENGTH 0x80
++/* MEM space for ALL USB modules */
++#define CS5536_OHCI_RANGE 0xfffff000
++#define CS5536_OHCI_LENGTH 0x1000
++#define CS5536_EHCI_RANGE 0xfffff000
++#define CS5536_EHCI_LENGTH 0x1000
++
++/*
++ * PCI MSR ACCESS
++ */
++#define PCI_MSR_CTRL 0xF0
++#define PCI_MSR_ADDR 0xF4
++#define PCI_MSR_DATA_LO 0xF8
++#define PCI_MSR_DATA_HI 0xFC
++
++/**************** MSR *****************************/
++
++/*
++ * GLIU STANDARD MSR
++ */
++#define GLIU_CAP 0x00
++#define GLIU_CONFIG 0x01
++#define GLIU_SMI 0x02
++#define GLIU_ERROR 0x03
++#define GLIU_PM 0x04
++#define GLIU_DIAG 0x05
++
++/*
++ * GLIU SPEC. MSR
++ */
++#define GLIU_P2D_BM0 0x20
++#define GLIU_P2D_BM1 0x21
++#define GLIU_P2D_BM2 0x22
++#define GLIU_P2D_BMK0 0x23
++#define GLIU_P2D_BMK1 0x24
++#define GLIU_P2D_BM3 0x25
++#define GLIU_P2D_BM4 0x26
++#define GLIU_COH 0x80
++#define GLIU_PAE 0x81
++#define GLIU_ARB 0x82
++#define GLIU_ASMI 0x83
++#define GLIU_AERR 0x84
++#define GLIU_DEBUG 0x85
++#define GLIU_PHY_CAP 0x86
++#define GLIU_NOUT_RESP 0x87
++#define GLIU_NOUT_WDATA 0x88
++#define GLIU_WHOAMI 0x8B
++#define GLIU_SLV_DIS 0x8C
++#define GLIU_IOD_BM0 0xE0
++#define GLIU_IOD_BM1 0xE1
++#define GLIU_IOD_BM2 0xE2
++#define GLIU_IOD_BM3 0xE3
++#define GLIU_IOD_BM4 0xE4
++#define GLIU_IOD_BM5 0xE5
++#define GLIU_IOD_BM6 0xE6
++#define GLIU_IOD_BM7 0xE7
++#define GLIU_IOD_BM8 0xE8
++#define GLIU_IOD_BM9 0xE9
++#define GLIU_IOD_SC0 0xEA
++#define GLIU_IOD_SC1 0xEB
++#define GLIU_IOD_SC2 0xEC
++#define GLIU_IOD_SC3 0xED
++#define GLIU_IOD_SC4 0xEE
++#define GLIU_IOD_SC5 0xEF
++#define GLIU_IOD_SC6 0xF0
++#define GLIU_IOD_SC7 0xF1
++
++/*
++ * SB STANDARD
++ */
++#define SB_CAP 0x00
++#define SB_CONFIG 0x01
++#define SB_SMI 0x02
++#define SB_ERROR 0x03
++#define SB_MAR_ERR_EN 0x00000001
++#define SB_TAR_ERR_EN 0x00000002
++#define SB_RSVD_BIT1 0x00000004
++#define SB_EXCEP_ERR_EN 0x00000008
++#define SB_SYSE_ERR_EN 0x00000010
++#define SB_PARE_ERR_EN 0x00000020
++#define SB_TAS_ERR_EN 0x00000040
++#define SB_MAR_ERR_FLAG 0x00010000
++#define SB_TAR_ERR_FLAG 0x00020000
++#define SB_RSVD_BIT2 0x00040000
++#define SB_EXCEP_ERR_FLAG 0x00080000
++#define SB_SYSE_ERR_FLAG 0x00100000
++#define SB_PARE_ERR_FLAG 0x00200000
++#define SB_TAS_ERR_FLAG 0x00400000
++#define SB_PM 0x04
++#define SB_DIAG 0x05
++
++/*
++ * SB SPEC.
++ */
++#define SB_CTRL 0x10
++#define SB_R0 0x20
++#define SB_R1 0x21
++#define SB_R2 0x22
++#define SB_R3 0x23
++#define SB_R4 0x24
++#define SB_R5 0x25
++#define SB_R6 0x26
++#define SB_R7 0x27
++#define SB_R8 0x28
++#define SB_R9 0x29
++#define SB_R10 0x2A
++#define SB_R11 0x2B
++#define SB_R12 0x2C
++#define SB_R13 0x2D
++#define SB_R14 0x2E
++#define SB_R15 0x2F
++
++/*
++ * GLCP STANDARD
++ */
++#define GLCP_CAP 0x00
++#define GLCP_CONFIG 0x01
++#define GLCP_SMI 0x02
++#define GLCP_ERROR 0x03
++#define GLCP_PM 0x04
++#define GLCP_DIAG 0x05
++
++/*
++ * GLCP SPEC.
++ */
++#define GLCP_CLK_DIS_DELAY 0x08
++#define GLCP_PM_CLK_DISABLE 0x09
++#define GLCP_GLB_PM 0x0B
++#define GLCP_DBG_OUT 0x0C
++#define GLCP_RSVD1 0x0D
++#define GLCP_SOFT_COM 0x0E
++#define SOFT_BAR_SMB_FLAG 0x00000001
++#define SOFT_BAR_GPIO_FLAG 0x00000002
++#define SOFT_BAR_MFGPT_FLAG 0x00000004
++#define SOFT_BAR_IRQ_FLAG 0x00000008
++#define SOFT_BAR_PMS_FLAG 0x00000010
++#define SOFT_BAR_ACPI_FLAG 0x00000020
++#define SOFT_BAR_IDE_FLAG 0x00000400
++#define SOFT_BAR_ACC_FLAG 0x00000800
++#define SOFT_BAR_OHCI_FLAG 0x00001000
++#define SOFT_BAR_EHCI_FLAG 0x00002000
++#define GLCP_RSVD2 0x0F
++#define GLCP_CLK_OFF 0x10
++#define GLCP_CLK_ACTIVE 0x11
++#define GLCP_CLK_DISABLE 0x12
++#define GLCP_CLK4ACK 0x13
++#define GLCP_SYS_RST 0x14
++#define GLCP_RSVD3 0x15
++#define GLCP_DBG_CLK_CTRL 0x16
++#define GLCP_CHIP_REV_ID 0x17
++
++/* PIC */
++#define PIC_YSEL_LOW 0x20
++#define PIC_YSEL_LOW_USB_SHIFT 8
++#define PIC_YSEL_LOW_ACC_SHIFT 16
++#define PIC_YSEL_LOW_FLASH_SHIFT 24
++#define PIC_YSEL_HIGH 0x21
++#define PIC_ZSEL_LOW 0x22
++#define PIC_ZSEL_HIGH 0x23
++#define PIC_IRQM_PRIM 0x24
++#define PIC_IRQM_LPC 0x25
++#define PIC_XIRR_STS_LOW 0x26
++#define PIC_XIRR_STS_HIGH 0x27
++#define PCI_SHDW 0x34
++
++/*
++ * DIVIL STANDARD
++ */
++#define DIVIL_CAP 0x00
++#define DIVIL_CONFIG 0x01
++#define DIVIL_SMI 0x02
++#define DIVIL_ERROR 0x03
++#define DIVIL_PM 0x04
++#define DIVIL_DIAG 0x05
++
++/*
++ * DIVIL SPEC.
++ */
++#define DIVIL_LBAR_IRQ 0x08
++#define DIVIL_LBAR_KEL 0x09
++#define DIVIL_LBAR_SMB 0x0B
++#define DIVIL_LBAR_GPIO 0x0C
++#define DIVIL_LBAR_MFGPT 0x0D
++#define DIVIL_LBAR_ACPI 0x0E
++#define DIVIL_LBAR_PMS 0x0F
++#define DIVIL_LEG_IO 0x14
++#define DIVIL_BALL_OPTS 0x15
++#define DIVIL_SOFT_IRQ 0x16
++#define DIVIL_SOFT_RESET 0x17
++
++/* MFGPT */
++#define MFGPT_IRQ 0x28
++
++/*
++ * IDE STANDARD
++ */
++#define IDE_CAP 0x00
++#define IDE_CONFIG 0x01
++#define IDE_SMI 0x02
++#define IDE_ERROR 0x03
++#define IDE_PM 0x04
++#define IDE_DIAG 0x05
++
++/*
++ * IDE SPEC.
++ */
++#define IDE_IO_BAR 0x08
++#define IDE_CFG 0x10
++#define IDE_DTC 0x12
++#define IDE_CAST 0x13
++#define IDE_ETC 0x14
++#define IDE_INTERNAL_PM 0x15
++
++/*
++ * ACC STANDARD
++ */
++#define ACC_CAP 0x00
++#define ACC_CONFIG 0x01
++#define ACC_SMI 0x02
++#define ACC_ERROR 0x03
++#define ACC_PM 0x04
++#define ACC_DIAG 0x05
++
++/*
++ * USB STANDARD
++ */
++#define USB_CAP 0x00
++#define USB_CONFIG 0x01
++#define USB_SMI 0x02
++#define USB_ERROR 0x03
++#define USB_PM 0x04
++#define USB_DIAG 0x05
++
++/*
++ * USB SPEC.
++ */
++#define USB_OHCI 0x08
++#define USB_EHCI 0x09
++
++/****************** NATIVE ***************************/
++/* GPIO : I/O SPACE; REG : 32BITS */
++#define GPIOL_OUT_VAL 0x00
++#define GPIOL_OUT_EN 0x04
++#define GPIOL_OUT_AUX1_SEL 0x10
++/* SMB : I/O SPACE, REG : 8BITS WIDTH */
++#define SMB_SDA 0x00
++#define SMB_STS 0x01
++#define SMB_STS_SLVSTP (1 << 7)
++#define SMB_STS_SDAST (1 << 6)
++#define SMB_STS_BER (1 << 5)
++#define SMB_STS_NEGACK (1 << 4)
++#define SMB_STS_STASTR (1 << 3)
++#define SMB_STS_NMATCH (1 << 2)
++#define SMB_STS_MASTER (1 << 1)
++#define SMB_STS_XMIT (1 << 0)
++#define SMB_CTRL_STS 0x02
++#define SMB_CSTS_TGSTL (1 << 5)
++#define SMB_CSTS_TSDA (1 << 4)
++#define SMB_CSTS_GCMTCH (1 << 3)
++#define SMB_CSTS_MATCH (1 << 2)
++#define SMB_CSTS_BB (1 << 1)
++#define SMB_CSTS_BUSY (1 << 0)
++#define SMB_CTRL1 0x03
++#define SMB_CTRL1_STASTRE (1 << 7)
++#define SMB_CTRL1_NMINTE (1 << 6)
++#define SMB_CTRL1_GCMEN (1 << 5)
++#define SMB_CTRL1_ACK (1 << 4)
++#define SMB_CTRL1_RSVD (1 << 3)
++#define SMB_CTRL1_INTEN (1 << 2)
++#define SMB_CTRL1_STOP (1 << 1)
++#define SMB_CTRL1_START (1 << 0)
++#define SMB_ADDR 0x04
++#define SMB_ADDR_SAEN (1 << 7)
++#define SMB_CONTROLLER_ADDR (0xef << 0)
++#define SMB_CTRL2 0x05
++#define SMB_FREQ (0x20 << 1)
++#define SMB_ENABLE (0x01 << 0)
++#define SMB_CTRL3 0x06
++
++#endif /* _CS5536_H */
+diff --git a/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h b/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h
+new file mode 100644
+index 0000000..cac04ee
+--- /dev/null
++++ b/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h
+@@ -0,0 +1,40 @@
++/*
++ * cs5536 mfgpt header file
++ */
++
++#ifndef _CS5536_MFGPT_H
++#define _CS5536_MFGPT_H
++
++#include <cs5536/cs5536.h>
++#include <cs5536/cs5536_pci.h>
++
++#ifdef CONFIG_CS5536_MFGPT
++extern void setup_mfgpt0_timer(void);
++extern void disable_mfgpt0_counter(void);
++extern void enable_mfgpt0_counter(void);
++#else
++static inline void __maybe_unused setup_mfgpt0_timer(void)
++{
++}
++static inline void __maybe_unused disable_mfgpt0_counter(void)
++{
++}
++static inline void __maybe_unused enable_mfgpt0_counter(void)
++{
++}
++#endif
++
++#define MFGPT_TICK_RATE 14318000
++#define COMPARE ((MFGPT_TICK_RATE + HZ/2) / HZ)
++
++#define MFGPT_BASE mfgpt_base
++#define MFGPT0_CMP2 (MFGPT_BASE + 2)
++#define MFGPT0_CNT (MFGPT_BASE + 4)
++#define MFGPT0_SETUP (MFGPT_BASE + 6)
++
++#define MFGPT2_CMP1 (MFGPT_BASE + 0x10)
++#define MFGPT2_CMP2 (MFGPT_BASE + 0x12)
++#define MFGPT2_CNT (MFGPT_BASE + 0x14)
++#define MFGPT2_SETUP (MFGPT_BASE + 0x16)
++
++#endif /*!_CS5536_MFGPT_H */
+diff --git a/arch/mips/include/asm/mach-loongson/cs5536/cs5536_pci.h b/arch/mips/include/asm/mach-loongson/cs5536/cs5536_pci.h
+new file mode 100644
+index 0000000..0dca9c8
+--- /dev/null
++++ b/arch/mips/include/asm/mach-loongson/cs5536/cs5536_pci.h
+@@ -0,0 +1,153 @@
++/*
++ * the definition file of cs5536 Virtual Support Module(VSM).
++ * pci configuration space can be accessed through the VSM, so
++ * there is no need of the MSR read/write now, except the spec.
++ * MSR registers which are not implemented yet.
++ *
++ * Copyright (C) 2007 Lemote Inc.
++ * Author : jlliu, liujl@lemote.com
++ */
++
++#ifndef _CS5536_PCI_H
++#define _CS5536_PCI_H
++
++#include <linux/types.h>
++#include <linux/pci_regs.h>
++
++extern void cs5536_pci_conf_write4(int function, int reg, u32 value);
++extern u32 cs5536_pci_conf_read4(int function, int reg);
++
++#define CS5536_ACC_INTR 9
++#define CS5536_IDE_INTR 14
++#define CS5536_USB_INTR 11
++#define CS5536_MFGPT_INTR 5
++#define CS5536_UART1_INTR 4
++#define CS5536_UART2_INTR 3
++
++/************** PCI BUS DEVICE FUNCTION ***************/
++
++/*
++ * PCI bus device function
++ */
++#define PCI_BUS_CS5536 0
++#define PCI_IDSEL_CS5536 14
++
++/********** STANDARD PCI-2.2 EXPANSION ****************/
++
++/*
++ * PCI configuration space
++ * we have to virtualize the PCI configure space head, so we should
++ * define the necessary IDs and some others.
++ */
++
++/* CONFIG of PCI VENDOR ID*/
++#define CFG_PCI_VENDOR_ID(mod_dev_id, sys_vendor_id) \
++ (((mod_dev_id) << 16) | (sys_vendor_id))
++
++/* VENDOR ID */
++#define CS5536_VENDOR_ID 0x1022
++
++/* DEVICE ID */
++#define CS5536_ISA_DEVICE_ID 0x2090
++#define CS5536_IDE_DEVICE_ID 0x209a
++#define CS5536_ACC_DEVICE_ID 0x2093
++#define CS5536_OHCI_DEVICE_ID 0x2094
++#define CS5536_EHCI_DEVICE_ID 0x2095
++
++/* CLASS CODE : CLASS SUB-CLASS INTERFACE */
++#define CS5536_ISA_CLASS_CODE 0x060100
++#define CS5536_IDE_CLASS_CODE 0x010180
++#define CS5536_ACC_CLASS_CODE 0x040100
++#define CS5536_OHCI_CLASS_CODE 0x0C0310
++#define CS5536_EHCI_CLASS_CODE 0x0C0320
++
++/* BHLC : BIST HEADER-TYPE LATENCY-TIMER CACHE-LINE-SIZE */
++
++#define CFG_PCI_CACHE_LINE_SIZE(header_type, latency_timer) \
++ ((PCI_NONE_BIST << 24) | ((header_type) << 16) \
++ | ((latency_timer) << 8) | PCI_NORMAL_CACHE_LINE_SIZE);
++
++#define PCI_NONE_BIST 0x00 /* RO not implemented yet. */
++#define PCI_BRIDGE_HEADER_TYPE 0x80 /* RO */
++#define PCI_NORMAL_HEADER_TYPE 0x00
++#define PCI_NORMAL_LATENCY_TIMER 0x00
++#define PCI_NORMAL_CACHE_LINE_SIZE 0x08 /* RW */
++
++/* BAR */
++#define PCI_BAR0_REG 0x10
++#define PCI_BAR1_REG 0x14
++#define PCI_BAR2_REG 0x18
++#define PCI_BAR3_REG 0x1c
++#define PCI_BAR4_REG 0x20
++#define PCI_BAR5_REG 0x24
++#define PCI_BAR_COUNT 6
++#define PCI_BAR_RANGE_MASK 0xFFFFFFFF
++
++/* CARDBUS CIS POINTER */
++#define PCI_CARDBUS_CIS_POINTER 0x00000000
++
++/* SUBSYSTEM VENDOR ID */
++#define CS5536_SUB_VENDOR_ID CS5536_VENDOR_ID
++
++/* SUBSYSTEM ID */
++#define CS5536_ISA_SUB_ID CS5536_ISA_DEVICE_ID
++#define CS5536_IDE_SUB_ID CS5536_IDE_DEVICE_ID
++#define CS5536_ACC_SUB_ID CS5536_ACC_DEVICE_ID
++#define CS5536_OHCI_SUB_ID CS5536_OHCI_DEVICE_ID
++#define CS5536_EHCI_SUB_ID CS5536_EHCI_DEVICE_ID
++
++/* EXPANSION ROM BAR */
++#define PCI_EXPANSION_ROM_BAR 0x00000000
++
++/* CAPABILITIES POINTER */
++#define PCI_CAPLIST_POINTER 0x00000000
++#define PCI_CAPLIST_USB_POINTER 0x40
++/* INTERRUPT */
++
++#define CFG_PCI_INTERRUPT_LINE(pin, mod_intr) \
++ ((PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) | \
++ ((pin) << 8) | (mod_intr))
++
++#define PCI_MAX_LATENCY 0x40
++#define PCI_MIN_GRANT 0x00
++#define PCI_DEFAULT_PIN 0x01
++
++/*********** EXPANSION PCI REG ************************/
++
++/*
++ * ISA EXPANSION
++ */
++#define PCI_UART1_INT_REG 0x50
++#define PCI_UART2_INT_REG 0x54
++#define PCI_ISA_FIXUP_REG 0x58
++
++/*
++ * IDE EXPANSION
++ */
++#define PCI_IDE_CFG_REG 0x40
++#define CS5536_IDE_FLASH_SIGNATURE 0xDEADBEEF
++#define PCI_IDE_DTC_REG 0x48
++#define PCI_IDE_CAST_REG 0x4C
++#define PCI_IDE_ETC_REG 0x50
++#define PCI_IDE_PM_REG 0x54
++#define PCI_IDE_INT_REG 0x60
++
++/*
++ * ACC EXPANSION
++ */
++#define PCI_ACC_INT_REG 0x50
++
++/*
++ * OHCI EXPANSION : INTTERUPT IS IMPLEMENTED BY THE OHCI
++ */
++#define PCI_OHCI_PM_REG 0x40
++#define PCI_OHCI_INT_REG 0x50
++
++/*
++ * EHCI EXPANSION
++ */
++#define PCI_EHCI_LEGSMIEN_REG 0x50
++#define PCI_EHCI_LEGSMISTS_REG 0x54
++#define PCI_EHCI_FLADJ_REG 0x60
++
++#endif /* _CS5536_PCI_H_ */
+diff --git a/arch/mips/include/asm/mach-loongson/cs5536/cs5536_vsm.h b/arch/mips/include/asm/mach-loongson/cs5536/cs5536_vsm.h
+new file mode 100644
+index 0000000..6305bea
+--- /dev/null
++++ b/arch/mips/include/asm/mach-loongson/cs5536/cs5536_vsm.h
+@@ -0,0 +1,31 @@
++/*
++ * the read/write interfaces for Virtual Support Module(VSM)
++ *
++ * Copyright (C) 2009 Lemote, Inc.
++ * Author: Wu Zhangjin <wuzj@lemote.com>
++ */
++
++#ifndef _CS5536_VSM_H
++#define _CS5536_VSM_H
++
++#include <linux/types.h>
++
++typedef void (*cs5536_pci_vsm_write)(int reg, u32 value);
++typedef u32 (*cs5536_pci_vsm_read)(int reg);
++
++#define DECLARE_CS5536_MODULE(name) \
++extern void pci_##name##_write_reg(int reg, u32 value); \
++extern u32 pci_##name##_read_reg(int reg);
++
++/* ide module */
++DECLARE_CS5536_MODULE(ide)
++/* acc module */
++DECLARE_CS5536_MODULE(acc)
++/* ohci module */
++DECLARE_CS5536_MODULE(ohci)
++/* isa module */
++DECLARE_CS5536_MODULE(isa)
++/* ehci module */
++DECLARE_CS5536_MODULE(ehci)
++
++#endif /* _CS5536_VSM_H */
+diff --git a/arch/mips/include/asm/mach-loongson/dbg.h b/arch/mips/include/asm/mach-loongson/dbg.h
+new file mode 100644
+index 0000000..96074d2
+--- /dev/null
++++ b/arch/mips/include/asm/mach-loongson/dbg.h
+@@ -0,0 +1,17 @@
++/*
++ * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
++ *
++ * 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 _ASM_MACH_LOONGSON_DBG_H_
++#define _ASM_MACH_LOONGSON_DBG_H_
++
++/* serial port print support */
++extern void prom_putchar(char c);
++extern void prom_printf(char *fmt, ...);
++
++#endif /* _ASM_MACH_LOONGSON_DBG_H_ */
+diff --git a/arch/mips/include/asm/mach-loongson/dma-coherence.h b/arch/mips/include/asm/mach-loongson/dma-coherence.h
+index 71a6851..981c75f 100644
+--- a/arch/mips/include/asm/mach-loongson/dma-coherence.h
++++ b/arch/mips/include/asm/mach-loongson/dma-coherence.h
+@@ -28,7 +28,11 @@ static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
+ static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
+ dma_addr_t dma_addr)
+ {
++#if defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT)
++ return (dma_addr > 0x8fffffff) ? dma_addr : (dma_addr & 0x0fffffff);
++#else
+ return dma_addr & 0x7fffffff;
++#endif
+ }
+
+ static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
+diff --git a/arch/mips/include/asm/mach-loongson/loongson.h b/arch/mips/include/asm/mach-loongson/loongson.h
+index da70bcf..ee8bc83 100644
+--- a/arch/mips/include/asm/mach-loongson/loongson.h
++++ b/arch/mips/include/asm/mach-loongson/loongson.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology
++ * Copyright (C) 2009 Lemote, Inc.
+ * Author: Wu Zhangjin <wuzj@lemote.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+@@ -15,9 +15,6 @@
+ #include <linux/io.h>
+ #include <linux/init.h>
+
+-/* there is an internal bonito64-compatiable northbridge in loongson2e/2f */
+-#include <asm/mips-boards/bonito64.h>
+-
+ /* loongson internal northbridge initialization */
+ extern void bonito_irq_init(void);
+
+@@ -32,7 +29,19 @@ extern unsigned long memsize, highmemsize;
+ /* loongson-specific command line, env and memory initialization */
+ extern void __init prom_init_memory(void);
+ extern void __init prom_init_cmdline(void);
++extern void __init prom_init_machtype(void);
+ extern void __init prom_init_env(void);
++#ifdef CONFIG_LOONGSON_UART_BASE
++extern unsigned long _loongson_uart_base, loongson_uart_base;
++extern void prom_init_loongson_uart_base(void);
++#endif
++
++static inline void prom_init_uart_base(void)
++{
++#ifdef CONFIG_LOONGSON_UART_BASE
++ prom_init_loongson_uart_base();
++#endif
++}
+
+ /* irq operation functions */
+ extern void bonito_irqdispatch(void);
+@@ -40,25 +49,276 @@ extern void __init bonito_irq_init(void);
+ extern void __init set_irq_trigger_mode(void);
+ extern void __init mach_init_irq(void);
+ extern void mach_irq_dispatch(unsigned int pending);
++extern int mach_i8259_irq(void);
++
++/* We need this in some places... */
++#define delay() ({ \
++ int x; \
++ for (x = 0; x < 100000; x++) \
++ __asm__ __volatile__(""); \
++})
++
++#define LOONGSON_REG(x) \
++ (*(volatile u32 *)((char *)CKSEG1ADDR(LOONGSON_REG_BASE) + (x)))
++
++#define LOONGSON_IRQ_BASE 32
++#define LOONGSON2_PERFCNT_IRQ (MIPS_CPU_IRQ_BASE + 6) /* cpu perf counter */
++
++#define LOONGSON_FLASH_BASE 0x1c000000
++#define LOONGSON_FLASH_SIZE 0x02000000 /* 32M */
++#define LOONGSON_FLASH_TOP (LOONGSON_FLASH_BASE+LOONGSON_FLASH_SIZE-1)
++
++#define LOONGSON_LIO0_BASE 0x1e000000
++#define LOONGSON_LIO0_SIZE 0x01C00000 /* 28M */
++#define LOONGSON_LIO0_TOP (LOONGSON_LIO0_BASE+LOONGSON_LIO0_SIZE-1)
++
++#define LOONGSON_BOOT_BASE 0x1fc00000
++#define LOONGSON_BOOT_SIZE 0x00100000 /* 1M */
++#define LOONGSON_BOOT_TOP (LOONGSON_BOOT_BASE+LOONGSON_BOOT_SIZE-1)
++#define LOONGSON_REG_BASE 0x1fe00000
++#define LOONGSON_REG_SIZE 0x00100000 /* 256Bytes + 256Bytes + ??? */
++#define LOONGSON_REG_TOP (LOONGSON_REG_BASE+LOONGSON_REG_SIZE-1)
++
++#define LOONGSON_LIO1_BASE 0x1ff00000
++#define LOONGSON_LIO1_SIZE 0x00100000 /* 1M */
++#define LOONGSON_LIO1_TOP (LOONGSON_LIO1_BASE+LOONGSON_LIO1_SIZE-1)
++
++#define LOONGSON_PCILO0_BASE 0x10000000
++#define LOONGSON_PCILO1_BASE 0x14000000
++#define LOONGSON_PCILO2_BASE 0x18000000
++#define LOONGSON_PCILO_BASE LOONGSON_PCILO0_BASE
++#define LOONGSON_PCILO_SIZE 0x0c000000 /* 64M * 3 */
++#define LOONGSON_PCILO_TOP (LOONGSON_PCILO0_BASE+LOONGSON_PCILO_SIZE-1)
++
++#define LOONGSON_PCICFG_BASE 0x1fe80000
++#define LOONGSON_PCICFG_SIZE 0x00000800 /* 2K */
++#define LOONGSON_PCICFG_TOP (LOONGSON_PCICFG_BASE+LOONGSON_PCICFG_SIZE-1)
++#define LOONGSON_PCIIO_BASE 0x1fd00000
++#define LOONGSON_PCIIO_SIZE 0x00100000 /* 1M */
++#define LOONGSON_PCIIO_TOP (LOONGSON_PCIIO_BASE+LOONGSON_PCIIO_SIZE-1)
++
++/* Loongson Register Bases */
++
++#define LOONGSON_PCICONFIGBASE 0x00
++#define LOONGSON_REGBASE 0x100
+
+ /* PCI Configuration Registers */
+-#define LOONGSON_PCI_ISR4C BONITO_PCI_REG(0x4c)
++
++#define LOONGSON_PCI_REG(x) LOONGSON_REG(LOONGSON_PCICONFIGBASE + (x))
++#define LOONGSON_PCIDID LOONGSON_PCI_REG(0x00)
++#define LOONGSON_PCICMD LOONGSON_PCI_REG(0x04)
++#define LOONGSON_PCICLASS LOONGSON_PCI_REG(0x08)
++#define LOONGSON_PCILTIMER LOONGSON_PCI_REG(0x0c)
++#define LOONGSON_PCIBASE0 LOONGSON_PCI_REG(0x10)
++#define LOONGSON_PCIBASE1 LOONGSON_PCI_REG(0x14)
++#define LOONGSON_PCIBASE2 LOONGSON_PCI_REG(0x18)
++#define LOONGSON_PCIBASE3 LOONGSON_PCI_REG(0x1c)
++#define LOONGSON_PCIBASE4 LOONGSON_PCI_REG(0x20)
++#define LOONGSON_PCIEXPRBASE LOONGSON_PCI_REG(0x30)
++#define LOONGSON_PCIINT LOONGSON_PCI_REG(0x3c)
++
++#define LOONGSON_PCI_ISR4C LOONGSON_PCI_REG(0x4c)
++
++#define LOONGSON_PCICMD_PERR_CLR 0x80000000
++#define LOONGSON_PCICMD_SERR_CLR 0x40000000
++#define LOONGSON_PCICMD_MABORT_CLR 0x20000000
++#define LOONGSON_PCICMD_MTABORT_CLR 0x10000000
++#define LOONGSON_PCICMD_TABORT_CLR 0x08000000
++#define LOONGSON_PCICMD_MPERR_CLR 0x01000000
++#define LOONGSON_PCICMD_PERRRESPEN 0x00000040
++#define LOONGSON_PCICMD_ASTEPEN 0x00000080
++#define LOONGSON_PCICMD_SERREN 0x00000100
++#define LOONGSON_PCILTIMER_BUSLATENCY 0x0000ff00
++#define LOONGSON_PCILTIMER_BUSLATENCY_SHIFT 8
++
++/* Loongson h/w Configuration */
++
++#define LOONGSON_GENCFG_OFFSET 0x4
++#define LOONGSON_GENCFG LOONGSON_REG(LOONGSON_REGBASE + LOONGSON_GENCFG_OFFSET)
++
++#define LOONGSON_GENCFG_DEBUGMODE 0x00000001
++#define LOONGSON_GENCFG_SNOOPEN 0x00000002
++#define LOONGSON_GENCFG_CPUSELFRESET 0x00000004
++
++#define LOONGSON_GENCFG_FORCE_IRQA 0x00000008
++#define LOONGSON_GENCFG_IRQA_ISOUT 0x00000010
++#define LOONGSON_GENCFG_IRQA_FROM_INT1 0x00000020
++#define LOONGSON_GENCFG_BYTESWAP 0x00000040
++
++#define LOONGSON_GENCFG_UNCACHED 0x00000080
++#define LOONGSON_GENCFG_PREFETCHEN 0x00000100
++#define LOONGSON_GENCFG_WBEHINDEN 0x00000200
++#define LOONGSON_GENCFG_CACHEALG 0x00000c00
++#define LOONGSON_GENCFG_CACHEALG_SHIFT 10
++#define LOONGSON_GENCFG_PCIQUEUE 0x00001000
++#define LOONGSON_GENCFG_CACHESTOP 0x00002000
++#define LOONGSON_GENCFG_MSTRBYTESWAP 0x00004000
++#define LOONGSON_GENCFG_BUSERREN 0x00008000
++#define LOONGSON_GENCFG_NORETRYTIMEOUT 0x00010000
++#define LOONGSON_GENCFG_SHORTCOPYTIMEOUT 0x00020000
++
++/* PCI address map control */
++
++#define LOONGSON_PCIMAP LOONGSON_REG(LOONGSON_REGBASE + 0x10)
++#define LOONGSON_PCIMEMBASECFG LOONGSON_REG(LOONGSON_REGBASE + 0x14)
++#define LOONGSON_PCIMAP_CFG LOONGSON_REG(LOONGSON_REGBASE + 0x18)
++
++/* GPIO Regs - r/w */
++
++#define LOONGSON_GPIODATA LOONGSON_REG(LOONGSON_REGBASE + 0x1c)
++#define LOONGSON_GPIOIE LOONGSON_REG(LOONGSON_REGBASE + 0x20)
++
++/* ICU Configuration Regs - r/w */
++
++#define LOONGSON_INTEDGE LOONGSON_REG(LOONGSON_REGBASE + 0x24)
++#define LOONGSON_INTSTEER LOONGSON_REG(LOONGSON_REGBASE + 0x28)
++#define LOONGSON_INTPOL LOONGSON_REG(LOONGSON_REGBASE + 0x2c)
++
++/* ICU Enable Regs - IntEn & IntISR are r/o. */
++
++#define LOONGSON_INTENSET LOONGSON_REG(LOONGSON_REGBASE + 0x30)
++#define LOONGSON_INTENCLR LOONGSON_REG(LOONGSON_REGBASE + 0x34)
++#define LOONGSON_INTEN LOONGSON_REG(LOONGSON_REGBASE + 0x38)
++#define LOONGSON_INTISR LOONGSON_REG(LOONGSON_REGBASE + 0x3c)
++
++/* ICU */
++#define LOONGSON_ICU_MBOXES 0x0000000f
++#define LOONGSON_ICU_MBOXES_SHIFT 0
++#define LOONGSON_ICU_DMARDY 0x00000010
++#define LOONGSON_ICU_DMAEMPTY 0x00000020
++#define LOONGSON_ICU_COPYRDY 0x00000040
++#define LOONGSON_ICU_COPYEMPTY 0x00000080
++#define LOONGSON_ICU_COPYERR 0x00000100
++#define LOONGSON_ICU_PCIIRQ 0x00000200
++#define LOONGSON_ICU_MASTERERR 0x00000400
++#define LOONGSON_ICU_SYSTEMERR 0x00000800
++#define LOONGSON_ICU_DRAMPERR 0x00001000
++#define LOONGSON_ICU_RETRYERR 0x00002000
++#define LOONGSON_ICU_GPIOS 0x01ff0000
++#define LOONGSON_ICU_GPIOS_SHIFT 16
++#define LOONGSON_ICU_GPINS 0x7e000000
++#define LOONGSON_ICU_GPINS_SHIFT 25
++#define LOONGSON_ICU_MBOX(N) (1<<(LOONGSON_ICU_MBOXES_SHIFT+(N)))
++#define LOONGSON_ICU_GPIO(N) (1<<(LOONGSON_ICU_GPIOS_SHIFT+(N)))
++#define LOONGSON_ICU_GPIN(N) (1<<(LOONGSON_ICU_GPINS_SHIFT+(N)))
++
++/* PCI prefetch window base & mask */
++
++#define LOONGSON_MEM_WIN_BASE_L LOONGSON_REG(LOONGSON_REGBASE + 0x40)
++#define LOONGSON_MEM_WIN_BASE_H LOONGSON_REG(LOONGSON_REGBASE + 0x44)
++#define LOONGSON_MEM_WIN_MASK_L LOONGSON_REG(LOONGSON_REGBASE + 0x48)
++#define LOONGSON_MEM_WIN_MASK_H LOONGSON_REG(LOONGSON_REGBASE + 0x4c)
+
+ /* PCI_Hit*_Sel_* */
+
+-#define LOONGSON_PCI_HIT0_SEL_L BONITO(BONITO_REGBASE + 0x50)
+-#define LOONGSON_PCI_HIT0_SEL_H BONITO(BONITO_REGBASE + 0x54)
+-#define LOONGSON_PCI_HIT1_SEL_L BONITO(BONITO_REGBASE + 0x58)
+-#define LOONGSON_PCI_HIT1_SEL_H BONITO(BONITO_REGBASE + 0x5c)
+-#define LOONGSON_PCI_HIT2_SEL_L BONITO(BONITO_REGBASE + 0x60)
+-#define LOONGSON_PCI_HIT2_SEL_H BONITO(BONITO_REGBASE + 0x64)
++#define LOONGSON_PCI_HIT0_SEL_L LOONGSON_REG(LOONGSON_REGBASE + 0x50)
++#define LOONGSON_PCI_HIT0_SEL_H LOONGSON_REG(LOONGSON_REGBASE + 0x54)
++#define LOONGSON_PCI_HIT1_SEL_L LOONGSON_REG(LOONGSON_REGBASE + 0x58)
++#define LOONGSON_PCI_HIT1_SEL_H LOONGSON_REG(LOONGSON_REGBASE + 0x5c)
++#define LOONGSON_PCI_HIT2_SEL_L LOONGSON_REG(LOONGSON_REGBASE + 0x60)
++#define LOONGSON_PCI_HIT2_SEL_H LOONGSON_REG(LOONGSON_REGBASE + 0x64)
+
+ /* PXArb Config & Status */
+
+-#define LOONGSON_PXARB_CFG BONITO(BONITO_REGBASE + 0x68)
+-#define LOONGSON_PXARB_STATUS BONITO(BONITO_REGBASE + 0x6c)
++#define LOONGSON_PXARB_CFG LOONGSON_REG(LOONGSON_REGBASE + 0x68)
++#define LOONGSON_PXARB_STATUS LOONGSON_REG(LOONGSON_REGBASE + 0x6c)
++
++/* pcimap */
++
++#define LOONGSON_PCIMAP_PCIMAP_LO0 0x0000003f
++#define LOONGSON_PCIMAP_PCIMAP_LO0_SHIFT 0
++#define LOONGSON_PCIMAP_PCIMAP_LO1 0x00000fc0
++#define LOONGSON_PCIMAP_PCIMAP_LO1_SHIFT 6
++#define LOONGSON_PCIMAP_PCIMAP_LO2 0x0003f000
++#define LOONGSON_PCIMAP_PCIMAP_LO2_SHIFT 12
++#define LOONGSON_PCIMAP_PCIMAP_2 0x00040000
++#define LOONGSON_PCIMAP_WIN(WIN, ADDR) \
++ ((((ADDR)>>26) & LOONGSON_PCIMAP_PCIMAP_LO0) << ((WIN)*6))
++
++#ifdef CONFIG_CPU_SUPPORTS_CPUFREQ
++#include <linux/cpufreq.h>
++extern void loongson2_cpu_wait(void);
++extern struct cpufreq_frequency_table loongson2_clockmod_table[];
++
++/* Chip Config */
++#define LOONGSON_CHIPCFG0 LOONGSON_REG(LOONGSON_REGBASE + 0x80)
++#endif
++
++/*
++ * address windows configuration module
++ *
++ * loongson2e do not have this module
++ */
++#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG
++
++/* address window config module base address */
++#define LOONGSON_ADDRWINCFG_BASE 0x3ff00000ul
++#define LOONGSON_ADDRWINCFG_SIZE 0x180
++
++extern unsigned long _loongson_addrwincfg_base;
++#define LOONGSON_ADDRWINCFG(offset) \
++ (*(volatile u64 *)(_loongson_addrwincfg_base + (offset)))
++
++#define CPU_WIN0_BASE LOONGSON_ADDRWINCFG(0x00)
++#define CPU_WIN1_BASE LOONGSON_ADDRWINCFG(0x08)
++#define CPU_WIN2_BASE LOONGSON_ADDRWINCFG(0x10)
++#define CPU_WIN3_BASE LOONGSON_ADDRWINCFG(0x18)
++
++#define CPU_WIN0_MASK LOONGSON_ADDRWINCFG(0x20)
++#define CPU_WIN1_MASK LOONGSON_ADDRWINCFG(0x28)
++#define CPU_WIN2_MASK LOONGSON_ADDRWINCFG(0x30)
++#define CPU_WIN3_MASK LOONGSON_ADDRWINCFG(0x38)
++
++#define CPU_WIN0_MMAP LOONGSON_ADDRWINCFG(0x40)
++#define CPU_WIN1_MMAP LOONGSON_ADDRWINCFG(0x48)
++#define CPU_WIN2_MMAP LOONGSON_ADDRWINCFG(0x50)
++#define CPU_WIN3_MMAP LOONGSON_ADDRWINCFG(0x58)
++
++#define PCIDMA_WIN0_BASE LOONGSON_ADDRWINCFG(0x60)
++#define PCIDMA_WIN1_BASE LOONGSON_ADDRWINCFG(0x68)
++#define PCIDMA_WIN2_BASE LOONGSON_ADDRWINCFG(0x70)
++#define PCIDMA_WIN3_BASE LOONGSON_ADDRWINCFG(0x78)
++
++#define PCIDMA_WIN0_MASK LOONGSON_ADDRWINCFG(0x80)
++#define PCIDMA_WIN1_MASK LOONGSON_ADDRWINCFG(0x88)
++#define PCIDMA_WIN2_MASK LOONGSON_ADDRWINCFG(0x90)
++#define PCIDMA_WIN3_MASK LOONGSON_ADDRWINCFG(0x98)
++
++#define PCIDMA_WIN0_MMAP LOONGSON_ADDRWINCFG(0xa0)
++#define PCIDMA_WIN1_MMAP LOONGSON_ADDRWINCFG(0xa8)
++#define PCIDMA_WIN2_MMAP LOONGSON_ADDRWINCFG(0xb0)
++#define PCIDMA_WIN3_MMAP LOONGSON_ADDRWINCFG(0xb8)
++
++#define ADDRWIN_WIN0 0
++#define ADDRWIN_WIN1 1
++#define ADDRWIN_WIN2 2
++#define ADDRWIN_WIN3 3
++
++#define ADDRWIN_MAP_DST_DDR 0
++#define ADDRWIN_MAP_DST_PCI 1
++#define ADDRWIN_MAP_DST_LIO 1
++
++/*
++ * s: CPU, PCIDMA
++ * d: DDR, PCI, LIO
++ * win: 0, 1, 2, 3
++ * src: map source
++ * dst: map destination
++ * size: ~mask + 1
++ */
++#define LOONGSON_ADDRWIN_CFG(s, d, w, src, dst, size) do {\
++ s##_WIN##w##_BASE = (src); \
++ s##_WIN##w##_MMAP = (src) | ADDRWIN_MAP_DST_##d; \
++ s##_WIN##w##_MASK = ~(size-1); \
++} while (0)
++
++#define LOONGSON_ADDRWIN_CPUTOPCI(win, src, dst, size) \
++ LOONGSON_ADDRWIN_CFG(CPU, PCI, win, src, dst, size)
++#define LOONGSON_ADDRWIN_CPUTODDR(win, src, dst, size) \
++ LOONGSON_ADDRWIN_CFG(CPU, DDR, win, src, dst, size)
++#define LOONGSON_ADDRWIN_PCITODDR(win, src, dst, size) \
++ LOONGSON_ADDRWIN_CFG(PCIDMA, DDR, win, src, dst, size)
+
+-/* loongson2-specific perf counter IRQ */
+-#define LOONGSON2_PERFCNT_IRQ (MIPS_CPU_IRQ_BASE + 6)
++#endif /* ! CONFIG_CPU_SUPPORTS_ADDRWINCFG */
+
+ #endif /* __ASM_MACH_LOONGSON_LOONGSON_H */
+diff --git a/arch/mips/include/asm/mach-loongson/machine.h b/arch/mips/include/asm/mach-loongson/machine.h
+index 206ea20..acf8359 100644
+--- a/arch/mips/include/asm/mach-loongson/machine.h
++++ b/arch/mips/include/asm/mach-loongson/machine.h
+@@ -13,10 +13,15 @@
+
+ #ifdef CONFIG_LEMOTE_FULOONG2E
+
+-#define LOONGSON_UART_BASE (BONITO_PCIIO_BASE + 0x3f8)
+-
+ #define LOONGSON_MACHTYPE MACH_LEMOTE_FL2E
+
+ #endif
+
++/* use fuloong2f as the default machine of LEMOTE_MACH2F */
++#ifdef CONFIG_LEMOTE_MACH2F
++
++#define LOONGSON_MACHTYPE MACH_LEMOTE_FL2F
++
++#endif
++
+ #endif /* __ASM_MACH_LOONGSON_MACHINE_H */
+diff --git a/arch/mips/include/asm/mach-loongson/mem.h b/arch/mips/include/asm/mach-loongson/mem.h
+index bd7b3cb..e9960f3 100644
+--- a/arch/mips/include/asm/mach-loongson/mem.h
++++ b/arch/mips/include/asm/mach-loongson/mem.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology
++ * Copyright (C) 2009 Lemote, Inc.
+ * Author: Wu Zhangjin <wuzj@lemote.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+@@ -12,19 +12,30 @@
+ #define __ASM_MACH_LOONGSON_MEM_H
+
+ /*
+- * On Lemote Loongson 2e
++ * high memory space
+ *
+- * the high memory space starts from 512M.
+- * the peripheral registers reside between 0x1000:0000 and 0x2000:0000.
++ * in loongson2e, starts from 512M
++ * in loongson2f, starts from 2G 256M
+ */
++#ifdef CONFIG_CPU_LOONGSON2E
++#define LOONGSON_HIGHMEM_START 0x20000000
++#else
++#define LOONGSON_HIGHMEM_START 0x90000000
++#endif
+
+-#ifdef CONFIG_LEMOTE_FULOONG2E
+-
+-#define LOONGSON_HIGHMEM_START 0x20000000
++/*
++ * the peripheral registers(MMIO):
++ *
++ * On the Lemote Loongson 2e system, reside between 0x1000:0000 and 0x2000:0000.
++ * On the Lemote Loongson 2f system, reside between 0x1000:0000 and 0x8000:0000.
++ */
+
+ #define LOONGSON_MMIO_MEM_START 0x10000000
+-#define LOONGSON_MMIO_MEM_END 0x20000000
+
++#ifdef CONFIG_CPU_LOONGSON2E
++#define LOONGSON_MMIO_MEM_END 0x20000000
++#else
++#define LOONGSON_MMIO_MEM_END 0x80000000
+ #endif
+
+ #endif /* __ASM_MACH_LOONGSON_MEM_H */
+diff --git a/arch/mips/include/asm/mach-loongson/pci.h b/arch/mips/include/asm/mach-loongson/pci.h
+index f1663ca..a199a4f 100644
+--- a/arch/mips/include/asm/mach-loongson/pci.h
++++ b/arch/mips/include/asm/mach-loongson/pci.h
+@@ -1,5 +1,6 @@
+ /*
+ * Copyright (c) 2008 Zhang Le <r0bertz@gentoo.org>
++ * Copyright (c) 2009 Wu Zhangjin <wuzj@lemote.com>
+ *
+ * This program is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General
+@@ -22,16 +23,39 @@
+ #ifndef __ASM_MACH_LOONGSON_PCI_H_
+ #define __ASM_MACH_LOONGSON_PCI_H_
+
+-extern struct pci_ops bonito64_pci_ops;
++extern struct pci_ops loongson_pci_ops;
+
+-#ifdef CONFIG_LEMOTE_FULOONG2E
++/* this is an offset from mips_io_port_base */
++#define LOONGSON_PCI_IO_START 0x00004000UL
++
++#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG
++
++/*
++ * we use address window2 to map cpu address space to pci space
++ * window2: cpu [1G, 2G] -> pci [1G, 2G]
++ * why not use window 0 & 1? because they are used by cpu when booting.
++ * window0: cpu [0, 256M] -> ddr [0, 256M]
++ * window1: cpu [256M, 512M] -> pci [256M, 512M]
++ */
++
++/* the smallest LOONGSON_CPU_MEM_SRC can be 512M */
++#define LOONGSON_CPU_MEM_SRC 0x40000000ul /* 1G */
++#define LOONGSON_PCI_MEM_DST LOONGSON_CPU_MEM_SRC
++
++#define LOONGSON_PCI_MEM_START LOONGSON_PCI_MEM_DST
++#define LOONGSON_PCI_MEM_END (0x80000000ul-1) /* 2G */
++
++#define MMAP_CPUTOPCI_SIZE (LOONGSON_PCI_MEM_END - \
++ LOONGSON_PCI_MEM_START + 1)
++
++#else /* loongson2f/32bit & loongson2e */
+
+ /* this pci memory space is mapped by pcimap in pci.c */
+-#define LOONGSON_PCI_MEM_START BONITO_PCILO1_BASE
+-#define LOONGSON_PCI_MEM_END (BONITO_PCILO1_BASE + 0x04000000 * 2)
++#define LOONGSON_PCI_MEM_START LOONGSON_PCILO1_BASE
++#define LOONGSON_PCI_MEM_END (LOONGSON_PCILO1_BASE + 0x04000000 * 2)
+ /* this is an offset from mips_io_port_base */
+ #define LOONGSON_PCI_IO_START 0x00004000UL
+
+-#endif
++#endif /* !CONFIG_CPU_SUPPORTS_ADDRWINCFG */
+
+ #endif /* !__ASM_MACH_LOONGSON_PCI_H_ */
+diff --git a/arch/mips/include/asm/mach-pb1x00/pb1100.h b/arch/mips/include/asm/mach-pb1x00/pb1100.h
+deleted file mode 100644
+index b1a60f1..0000000
+--- a/arch/mips/include/asm/mach-pb1x00/pb1100.h
++++ /dev/null
+@@ -1,85 +0,0 @@
+-/*
+- * Alchemy Semi Pb1100 Referrence Board
+- *
+- * Copyright 2001, 2008 MontaVista Software Inc.
+- * Author: MontaVista Software, Inc. <source@mvista.com>
+- *
+- * ########################################################################
+- *
+- * 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.
+- *
+- * ########################################################################
+- *
+- *
+- */
+-#ifndef __ASM_PB1100_H
+-#define __ASM_PB1100_H
+-
+-#define PB1100_IDENT 0xAE000000
+-#define BOARD_STATUS_REG 0xAE000004
+-# define PB1100_ROM_SEL (1 << 15)
+-# define PB1100_ROM_SIZ (1 << 14)
+-# define PB1100_SWAP_BOOT (1 << 13)
+-# define PB1100_FLASH_WP (1 << 12)
+-# define PB1100_ROM_H_STS (1 << 11)
+-# define PB1100_ROM_L_STS (1 << 10)
+-# define PB1100_FLASH_H_STS (1 << 9)
+-# define PB1100_FLASH_L_STS (1 << 8)
+-# define PB1100_SRAM_SIZ (1 << 7)
+-# define PB1100_TSC_BUSY (1 << 6)
+-# define PB1100_PCMCIA_VS_MASK (3 << 4)
+-# define PB1100_RS232_CD (1 << 3)
+-# define PB1100_RS232_CTS (1 << 2)
+-# define PB1100_RS232_DSR (1 << 1)
+-# define PB1100_RS232_RI (1 << 0)
+-
+-#define PB1100_IRDA_RS232 0xAE00000C
+-# define PB1100_IRDA_FULL (0 << 14) /* full power */
+-# define PB1100_IRDA_SHUTDOWN (1 << 14)
+-# define PB1100_IRDA_TT (2 << 14) /* 2/3 power */
+-# define PB1100_IRDA_OT (3 << 14) /* 1/3 power */
+-# define PB1100_IRDA_FIR (1 << 13)
+-
+-#define PCMCIA_BOARD_REG 0xAE000010
+-# define PB1100_SD_WP1_RO (1 << 15) /* read only */
+-# define PB1100_SD_WP0_RO (1 << 14) /* read only */
+-# define PB1100_SD_PWR1 (1 << 11) /* applies power to SD1 */
+-# define PB1100_SD_PWR0 (1 << 10) /* applies power to SD0 */
+-# define PB1100_SEL_SD_CONN1 (1 << 9)
+-# define PB1100_SEL_SD_CONN0 (1 << 8)
+-# define PC_DEASSERT_RST (1 << 7)
+-# define PC_DRV_EN (1 << 4)
+-
+-#define PB1100_G_CONTROL 0xAE000014 /* graphics control */
+-
+-#define PB1100_RST_VDDI 0xAE00001C
+-# define PB1100_SOFT_RESET (1 << 15) /* clear to reset the board */
+-# define PB1100_VDDI_MASK 0x1F
+-
+-#define PB1100_LEDS 0xAE000018
+-
+-/*
+- * 11:8 is 4 discreet LEDs. Clearing a bit illuminates the LED.
+- * 7:0 is the LED Display's decimal points.
+- */
+-#define PB1100_HEX_LED 0xAE000018
+-
+-/* PCMCIA Pb1100 specific defines */
+-#define PCMCIA_MAX_SOCK 0
+-#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1)
+-
+-/* VPP/VCC */
+-#define SET_VCC_VPP(VCC, VPP) (((VCC) << 2) | ((VPP) << 0))
+-
+-#endif /* __ASM_PB1100_H */
+diff --git a/arch/mips/include/asm/mach-pb1x00/pb1200.h b/arch/mips/include/asm/mach-pb1x00/pb1200.h
+index c8618df..962eb55 100644
+--- a/arch/mips/include/asm/mach-pb1x00/pb1200.h
++++ b/arch/mips/include/asm/mach-pb1x00/pb1200.h
+@@ -25,6 +25,7 @@
+ #define __ASM_PB1200_H
+
+ #include <linux/types.h>
++#include <asm/mach-au1x00/au1000.h>
+ #include <asm/mach-au1x00/au1xxx_psc.h>
+
+ #define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX
+@@ -43,113 +44,8 @@
+ * Refer to board documentation.
+ */
+ #define AC97_PSC_BASE PSC1_BASE_ADDR
+-#define I2S_PSC_BASE PSC1_BASE_ADDR
++#define I2S_PSC_BASE PSC1_BASE_ADDR
+
+-#define BCSR_KSEG1_ADDR 0xAD800000
+-
+-typedef volatile struct
+-{
+- /*00*/ u16 whoami;
+- u16 reserved0;
+- /*04*/ u16 status;
+- u16 reserved1;
+- /*08*/ u16 switches;
+- u16 reserved2;
+- /*0C*/ u16 resets;
+- u16 reserved3;
+-
+- /*10*/ u16 pcmcia;
+- u16 reserved4;
+- /*14*/ u16 board;
+- u16 reserved5;
+- /*18*/ u16 disk_leds;
+- u16 reserved6;
+- /*1C*/ u16 system;
+- u16 reserved7;
+-
+- /*20*/ u16 intclr;
+- u16 reserved8;
+- /*24*/ u16 intset;
+- u16 reserved9;
+- /*28*/ u16 intclr_mask;
+- u16 reserved10;
+- /*2C*/ u16 intset_mask;
+- u16 reserved11;
+-
+- /*30*/ u16 sig_status;
+- u16 reserved12;
+- /*34*/ u16 int_status;
+- u16 reserved13;
+- /*38*/ u16 reserved14;
+- u16 reserved15;
+- /*3C*/ u16 reserved16;
+- u16 reserved17;
+-
+-} BCSR;
+-
+-static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
+-
+-/*
+- * Register bit definitions for the BCSRs
+- */
+-#define BCSR_WHOAMI_DCID 0x000F
+-#define BCSR_WHOAMI_CPLD 0x00F0
+-#define BCSR_WHOAMI_BOARD 0x0F00
+-
+-#define BCSR_STATUS_PCMCIA0VS 0x0003
+-#define BCSR_STATUS_PCMCIA1VS 0x000C
+-#define BCSR_STATUS_SWAPBOOT 0x0040
+-#define BCSR_STATUS_FLASHBUSY 0x0100
+-#define BCSR_STATUS_IDECBLID 0x0200
+-#define BCSR_STATUS_SD0WP 0x0400
+-#define BCSR_STATUS_SD1WP 0x0800
+-#define BCSR_STATUS_U0RXD 0x1000
+-#define BCSR_STATUS_U1RXD 0x2000
+-
+-#define BCSR_SWITCHES_OCTAL 0x00FF
+-#define BCSR_SWITCHES_DIP_1 0x0080
+-#define BCSR_SWITCHES_DIP_2 0x0040
+-#define BCSR_SWITCHES_DIP_3 0x0020
+-#define BCSR_SWITCHES_DIP_4 0x0010
+-#define BCSR_SWITCHES_DIP_5 0x0008
+-#define BCSR_SWITCHES_DIP_6 0x0004
+-#define BCSR_SWITCHES_DIP_7 0x0002
+-#define BCSR_SWITCHES_DIP_8 0x0001
+-#define BCSR_SWITCHES_ROTARY 0x0F00
+-
+-#define BCSR_RESETS_ETH 0x0001
+-#define BCSR_RESETS_CAMERA 0x0002
+-#define BCSR_RESETS_DC 0x0004
+-#define BCSR_RESETS_IDE 0x0008
+-/* not resets but in the same register */
+-#define BCSR_RESETS_WSCFSM 0x0800
+-#define BCSR_RESETS_PCS0MUX 0x1000
+-#define BCSR_RESETS_PCS1MUX 0x2000
+-#define BCSR_RESETS_SPISEL 0x4000
+-#define BCSR_RESETS_SD1MUX 0x8000
+-
+-#define BCSR_PCMCIA_PC0VPP 0x0003
+-#define BCSR_PCMCIA_PC0VCC 0x000C
+-#define BCSR_PCMCIA_PC0DRVEN 0x0010
+-#define BCSR_PCMCIA_PC0RST 0x0080
+-#define BCSR_PCMCIA_PC1VPP 0x0300
+-#define BCSR_PCMCIA_PC1VCC 0x0C00
+-#define BCSR_PCMCIA_PC1DRVEN 0x1000
+-#define BCSR_PCMCIA_PC1RST 0x8000
+-
+-#define BCSR_BOARD_LCDVEE 0x0001
+-#define BCSR_BOARD_LCDVDD 0x0002
+-#define BCSR_BOARD_LCDBL 0x0004
+-#define BCSR_BOARD_CAMSNAP 0x0010
+-#define BCSR_BOARD_CAMPWR 0x0020
+-#define BCSR_BOARD_SD0PWR 0x0040
+-#define BCSR_BOARD_SD1PWR 0x0080
+-
+-#define BCSR_LEDS_DECIMALS 0x00FF
+-#define BCSR_LEDS_LED0 0x0100
+-#define BCSR_LEDS_LED1 0x0200
+-#define BCSR_LEDS_LED2 0x0400
+-#define BCSR_LEDS_LED3 0x0800
+
+ #define BCSR_SYSTEM_VDDI 0x001F
+ #define BCSR_SYSTEM_POWEROFF 0x4000
+@@ -239,20 +135,6 @@ enum external_pb1200_ints {
+ PB1200_INT_END = PB1200_INT_BEGIN + 15
+ };
+
+-/*
+- * Pb1200 specific PCMCIA defines for drivers/pcmcia/au1000_db1x00.c
+- */
+-#define PCMCIA_MAX_SOCK 1
+-#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1)
+-
+-/* VPP/VCC */
+-#define SET_VCC_VPP(VCC, VPP, SLOT) \
+- ((((VCC) << 2) | ((VPP) << 0)) << ((SLOT) * 8))
+-
+-#define BOARD_PC0_INT PB1200_PC0_INT
+-#define BOARD_PC1_INT PB1200_PC1_INT
+-#define BOARD_CARD_INSERTED(SOCKET) bcsr->sig_status & (1 << (8 + (2 * SOCKET)))
+-
+ /* NAND chip select */
+ #define NAND_CS 1
+
+diff --git a/arch/mips/include/asm/mach-pb1x00/pb1500.h b/arch/mips/include/asm/mach-pb1x00/pb1500.h
+deleted file mode 100644
+index da51a2e..0000000
+--- a/arch/mips/include/asm/mach-pb1x00/pb1500.h
++++ /dev/null
+@@ -1,49 +0,0 @@
+-/*
+- * Alchemy Semi Pb1500 Referrence Board
+- *
+- * Copyright 2001, 2008 MontaVista Software Inc.
+- * Author: MontaVista Software, Inc. <source@mvista.com>
+- *
+- * ########################################################################
+- *
+- * 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.
+- *
+- * ########################################################################
+- *
+- *
+- */
+-#ifndef __ASM_PB1500_H
+-#define __ASM_PB1500_H
+-
+-#define IDENT_BOARD_REG 0xAE000000
+-#define BOARD_STATUS_REG 0xAE000004
+-#define PCI_BOARD_REG 0xAE000010
+-#define PCMCIA_BOARD_REG 0xAE000010
+-# define PC_DEASSERT_RST 0x80
+-# define PC_DRV_EN 0x10
+-#define PB1500_G_CONTROL 0xAE000014
+-#define PB1500_RST_VDDI 0xAE00001C
+-#define PB1500_LEDS 0xAE000018
+-
+-#define PB1500_HEX_LED 0xAF000004
+-#define PB1500_HEX_LED_BLANK 0xAF000008
+-
+-/* PCMCIA Pb1500 specific defines */
+-#define PCMCIA_MAX_SOCK 0
+-#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1)
+-
+-/* VPP/VCC */
+-#define SET_VCC_VPP(VCC, VPP) (((VCC) << 2) | ((VPP) << 0))
+-
+-#endif /* __ASM_PB1500_H */
+diff --git a/arch/mips/include/asm/mach-pb1x00/pb1550.h b/arch/mips/include/asm/mach-pb1x00/pb1550.h
+index 6704a11..5879641 100644
+--- a/arch/mips/include/asm/mach-pb1x00/pb1550.h
++++ b/arch/mips/include/asm/mach-pb1x00/pb1550.h
+@@ -40,102 +40,6 @@
+ #define SMBUS_PSC_BASE PSC2_BASE_ADDR
+ #define I2S_PSC_BASE PSC3_BASE_ADDR
+
+-#define BCSR_PHYS_ADDR 0xAF000000
+-
+-typedef volatile struct
+-{
+- /*00*/ u16 whoami;
+- u16 reserved0;
+- /*04*/ u16 status;
+- u16 reserved1;
+- /*08*/ u16 switches;
+- u16 reserved2;
+- /*0C*/ u16 resets;
+- u16 reserved3;
+- /*10*/ u16 pcmcia;
+- u16 reserved4;
+- /*14*/ u16 pci;
+- u16 reserved5;
+- /*18*/ u16 leds;
+- u16 reserved6;
+- /*1C*/ u16 system;
+- u16 reserved7;
+-
+-} BCSR;
+-
+-static BCSR * const bcsr = (BCSR *)BCSR_PHYS_ADDR;
+-
+-/*
+- * Register bit definitions for the BCSRs
+- */
+-#define BCSR_WHOAMI_DCID 0x000F
+-#define BCSR_WHOAMI_CPLD 0x00F0
+-#define BCSR_WHOAMI_BOARD 0x0F00
+-
+-#define BCSR_STATUS_PCMCIA0VS 0x0003
+-#define BCSR_STATUS_PCMCIA1VS 0x000C
+-#define BCSR_STATUS_PCMCIA0FI 0x0010
+-#define BCSR_STATUS_PCMCIA1FI 0x0020
+-#define BCSR_STATUS_SWAPBOOT 0x0040
+-#define BCSR_STATUS_SRAMWIDTH 0x0080
+-#define BCSR_STATUS_FLASHBUSY 0x0100
+-#define BCSR_STATUS_ROMBUSY 0x0200
+-#define BCSR_STATUS_USBOTGID 0x0800
+-#define BCSR_STATUS_U0RXD 0x1000
+-#define BCSR_STATUS_U1RXD 0x2000
+-#define BCSR_STATUS_U3RXD 0x8000
+-
+-#define BCSR_SWITCHES_OCTAL 0x00FF
+-#define BCSR_SWITCHES_DIP_1 0x0080
+-#define BCSR_SWITCHES_DIP_2 0x0040
+-#define BCSR_SWITCHES_DIP_3 0x0020
+-#define BCSR_SWITCHES_DIP_4 0x0010
+-#define BCSR_SWITCHES_DIP_5 0x0008
+-#define BCSR_SWITCHES_DIP_6 0x0004
+-#define BCSR_SWITCHES_DIP_7 0x0002
+-#define BCSR_SWITCHES_DIP_8 0x0001
+-#define BCSR_SWITCHES_ROTARY 0x0F00
+-
+-#define BCSR_RESETS_PHY0 0x0001
+-#define BCSR_RESETS_PHY1 0x0002
+-#define BCSR_RESETS_DC 0x0004
+-#define BCSR_RESETS_WSC 0x2000
+-#define BCSR_RESETS_SPISEL 0x4000
+-#define BCSR_RESETS_DMAREQ 0x8000
+-
+-#define BCSR_PCMCIA_PC0VPP 0x0003
+-#define BCSR_PCMCIA_PC0VCC 0x000C
+-#define BCSR_PCMCIA_PC0DRVEN 0x0010
+-#define BCSR_PCMCIA_PC0RST 0x0080
+-#define BCSR_PCMCIA_PC1VPP 0x0300
+-#define BCSR_PCMCIA_PC1VCC 0x0C00
+-#define BCSR_PCMCIA_PC1DRVEN 0x1000
+-#define BCSR_PCMCIA_PC1RST 0x8000
+-
+-#define BCSR_PCI_M66EN 0x0001
+-#define BCSR_PCI_M33 0x0100
+-#define BCSR_PCI_EXTERNARB 0x0200
+-#define BCSR_PCI_GPIO200RST 0x0400
+-#define BCSR_PCI_CLKOUT 0x0800
+-#define BCSR_PCI_CFGHOST 0x1000
+-
+-#define BCSR_LEDS_DECIMALS 0x00FF
+-#define BCSR_LEDS_LED0 0x0100
+-#define BCSR_LEDS_LED1 0x0200
+-#define BCSR_LEDS_LED2 0x0400
+-#define BCSR_LEDS_LED3 0x0800
+-
+-#define BCSR_SYSTEM_VDDI 0x001F
+-#define BCSR_SYSTEM_POWEROFF 0x4000
+-#define BCSR_SYSTEM_RESET 0x8000
+-
+-#define PCMCIA_MAX_SOCK 1
+-#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1)
+-
+-/* VPP/VCC */
+-#define SET_VCC_VPP(VCC, VPP, SLOT) \
+- ((((VCC) << 2) | ((VPP) << 0)) << ((SLOT) * 8))
+-
+ #if defined(CONFIG_MTD_PB1550_BOOT) && defined(CONFIG_MTD_PB1550_USER)
+ #define PB1550_BOTH_BANKS
+ #elif defined(CONFIG_MTD_PB1550_BOOT) && !defined(CONFIG_MTD_PB1550_USER)
+diff --git a/arch/mips/include/asm/mach-powertv/asic.h b/arch/mips/include/asm/mach-powertv/asic.h
+new file mode 100644
+index 0000000..bcad43a
+--- /dev/null
++++ b/arch/mips/include/asm/mach-powertv/asic.h
+@@ -0,0 +1,107 @@
++/*
++ * Copyright (C) 2009 Cisco Systems, Inc.
++ *
++ * 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
++ */
++
++#ifndef _ASM_MACH_POWERTV_ASIC_H
++#define _ASM_MACH_POWERTV_ASIC_H
++
++#include <linux/ioport.h>
++#include <asm/mach-powertv/asic_regs.h>
++
++#define DVR_CAPABLE (1<<0)
++#define PCIE_CAPABLE (1<<1)
++#define FFS_CAPABLE (1<<2)
++#define DISPLAY_CAPABLE (1<<3)
++
++/* Platform Family types
++ * For compitability, the new value must be added in the end */
++enum family_type {
++ FAMILY_8500,
++ FAMILY_8500RNG,
++ FAMILY_4500,
++ FAMILY_1500,
++ FAMILY_8600,
++ FAMILY_4600,
++ FAMILY_4600VZA,
++ FAMILY_8600VZB,
++ FAMILY_1500VZE,
++ FAMILY_1500VZF,
++ FAMILIES
++};
++
++/* Register maps for each ASIC */
++extern const struct register_map calliope_register_map;
++extern const struct register_map cronus_register_map;
++extern const struct register_map zeus_register_map;
++
++extern struct resource dvr_cronus_resources[];
++extern struct resource dvr_zeus_resources[];
++extern struct resource non_dvr_calliope_resources[];
++extern struct resource non_dvr_cronus_resources[];
++extern struct resource non_dvr_cronuslite_resources[];
++extern struct resource non_dvr_vz_calliope_resources[];
++extern struct resource non_dvr_vze_calliope_resources[];
++extern struct resource non_dvr_vzf_calliope_resources[];
++extern struct resource non_dvr_zeus_resources[];
++
++extern void powertv_platform_init(void);
++extern void platform_alloc_bootmem(void);
++extern enum asic_type platform_get_asic(void);
++extern enum family_type platform_get_family(void);
++extern int platform_supports_dvr(void);
++extern int platform_supports_ffs(void);
++extern int platform_supports_pcie(void);
++extern int platform_supports_display(void);
++extern void configure_platform(void);
++extern void platform_configure_usb_ehci(void);
++extern void platform_unconfigure_usb_ehci(void);
++extern void platform_configure_usb_ohci(void);
++extern void platform_unconfigure_usb_ohci(void);
++
++/* Platform Resources */
++#define ASIC_RESOURCE_GET_EXISTS 1
++extern struct resource *asic_resource_get(const char *name);
++extern void platform_release_memory(void *baddr, int size);
++
++/* Reboot Cause */
++extern void set_reboot_cause(char code, unsigned int data, unsigned int data2);
++extern void set_locked_reboot_cause(char code, unsigned int data,
++ unsigned int data2);
++
++enum sys_reboot_type {
++ sys_unknown_reboot = 0x00, /* Unknown reboot cause */
++ sys_davic_change = 0x01, /* Reboot due to change in DAVIC
++ * mode */
++ sys_user_reboot = 0x02, /* Reboot initiated by user */
++ sys_system_reboot = 0x03, /* Reboot initiated by OS */
++ sys_trap_reboot = 0x04, /* Reboot due to a CPU trap */
++ sys_silent_reboot = 0x05, /* Silent reboot */
++ sys_boot_ldr_reboot = 0x06, /* Bootloader reboot */
++ sys_power_up_reboot = 0x07, /* Power on bootup. Older
++ * drivers may report as
++ * userReboot. */
++ sys_code_change = 0x08, /* Reboot to take code change.
++ * Older drivers may report as
++ * userReboot. */
++ sys_hardware_reset = 0x09, /* HW watchdog or front-panel
++ * reset button reset. Older
++ * drivers may report as
++ * userReboot. */
++ sys_watchdogInterrupt = 0x0A /* Pre-watchdog interrupt */
++};
++
++#endif /* _ASM_MACH_POWERTV_ASIC_H */
+diff --git a/arch/mips/include/asm/mach-powertv/asic_regs.h b/arch/mips/include/asm/mach-powertv/asic_regs.h
+new file mode 100644
+index 0000000..9a65c93
+--- /dev/null
++++ b/arch/mips/include/asm/mach-powertv/asic_regs.h
+@@ -0,0 +1,155 @@
++/*
++ * Copyright (C) 2009 Cisco Systems, Inc.
++ *
++ * 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
++ */
++
++#ifndef __ASM_MACH_POWERTV_ASIC_H_
++#define __ASM_MACH_POWERTV_ASIC_H_
++#include <linux/io.h>
++
++/* ASIC types */
++enum asic_type {
++ ASIC_UNKNOWN,
++ ASIC_ZEUS,
++ ASIC_CALLIOPE,
++ ASIC_CRONUS,
++ ASIC_CRONUSLITE,
++ ASICS
++};
++
++/* hardcoded values read from Chip Version registers */
++#define CRONUS_10 0x0B4C1C20
++#define CRONUS_11 0x0B4C1C21
++#define CRONUSLITE_10 0x0B4C1C40
++
++#define NAND_FLASH_BASE 0x03000000
++#define ZEUS_IO_BASE 0x09000000
++#define CALLIOPE_IO_BASE 0x08000000
++#define CRONUS_IO_BASE 0x09000000
++#define ASIC_IO_SIZE 0x01000000
++
++/* Definitions for backward compatibility */
++#define UART1_INTSTAT uart1_intstat
++#define UART1_INTEN uart1_inten
++#define UART1_CONFIG1 uart1_config1
++#define UART1_CONFIG2 uart1_config2
++#define UART1_DIVISORHI uart1_divisorhi
++#define UART1_DIVISORLO uart1_divisorlo
++#define UART1_DATA uart1_data
++#define UART1_STATUS uart1_status
++
++/* ASIC register enumeration */
++struct register_map {
++ u32 eic_slow0_strt_add;
++ u32 eic_cfg_bits;
++ u32 eic_ready_status;
++
++ u32 chipver3;
++ u32 chipver2;
++ u32 chipver1;
++ u32 chipver0;
++
++ u32 uart1_intstat;
++ u32 uart1_inten;
++ u32 uart1_config1;
++ u32 uart1_config2;
++ u32 uart1_divisorhi;
++ u32 uart1_divisorlo;
++ u32 uart1_data;
++ u32 uart1_status;
++
++ u32 int_stat_3;
++ u32 int_stat_2;
++ u32 int_stat_1;
++ u32 int_stat_0;
++ u32 int_config;
++ u32 int_int_scan;
++ u32 ien_int_3;
++ u32 ien_int_2;
++ u32 ien_int_1;
++ u32 ien_int_0;
++ u32 int_level_3_3;
++ u32 int_level_3_2;
++ u32 int_level_3_1;
++ u32 int_level_3_0;
++ u32 int_level_2_3;
++ u32 int_level_2_2;
++ u32 int_level_2_1;
++ u32 int_level_2_0;
++ u32 int_level_1_3;
++ u32 int_level_1_2;
++ u32 int_level_1_1;
++ u32 int_level_1_0;
++ u32 int_level_0_3;
++ u32 int_level_0_2;
++ u32 int_level_0_1;
++ u32 int_level_0_0;
++ u32 int_docsis_en;
++
++ u32 mips_pll_setup;
++ u32 usb_fs;
++ u32 test_bus;
++ u32 crt_spare;
++ u32 usb2_ohci_int_mask;
++ u32 usb2_strap;
++ u32 ehci_hcapbase;
++ u32 ohci_hc_revision;
++ u32 bcm1_bs_lmi_steer;
++ u32 usb2_control;
++ u32 usb2_stbus_obc;
++ u32 usb2_stbus_mess_size;
++ u32 usb2_stbus_chunk_size;
++
++ u32 pcie_regs;
++ u32 tim_ch;
++ u32 tim_cl;
++ u32 gpio_dout;
++ u32 gpio_din;
++ u32 gpio_dir;
++ u32 watchdog;
++ u32 front_panel;
++
++ u32 register_maps;
++};
++
++extern enum asic_type asic;
++extern const struct register_map *register_map;
++extern unsigned long asic_phy_base; /* Physical address of ASIC */
++extern unsigned long asic_base; /* Virtual address of ASIC */
++
++/*
++ * Macros to interface to registers through their ioremapped address
++ * asic_reg_offset Returns the offset of a given register from the start
++ * of the ASIC address space
++ * asic_reg_phys_addr Returns the physical address of the given register
++ * asic_reg_addr Returns the iomapped virtual address of the given
++ * register.
++ */
++#define asic_reg_offset(x) (register_map->x)
++#define asic_reg_phys_addr(x) (asic_phy_base + asic_reg_offset(x))
++#define asic_reg_addr(x) \
++ ((unsigned int *) (asic_base + asic_reg_offset(x)))
++
++/*
++ * The asic_reg macro is gone. It should be replaced by either asic_read or
++ * asic_write, as appropriate.
++ */
++
++#define asic_read(x) readl(asic_reg_addr(x))
++#define asic_write(v, x) writel(v, asic_reg_addr(x))
++
++extern void asic_irq_init(void);
++#endif
+diff --git a/arch/mips/include/asm/mach-powertv/dma-coherence.h b/arch/mips/include/asm/mach-powertv/dma-coherence.h
+new file mode 100644
+index 0000000..5b8d5eb
+--- /dev/null
++++ b/arch/mips/include/asm/mach-powertv/dma-coherence.h
+@@ -0,0 +1,119 @@
++/*
++ * 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.
++ *
++ * Version from mach-generic modified to support PowerTV port
++ * Portions Copyright (C) 2009 Cisco Systems, Inc.
++ * Copyright (C) 2006 Ralf Baechle <ralf@linux-mips.org>
++ *
++ */
++
++#ifndef __ASM_MACH_POWERTV_DMA_COHERENCE_H
++#define __ASM_MACH_POWERTV_DMA_COHERENCE_H
++
++#include <linux/sched.h>
++#include <linux/version.h>
++#include <linux/device.h>
++#include <asm/mach-powertv/asic.h>
++
++static inline bool is_kseg2(void *addr)
++{
++ return (unsigned long)addr >= KSEG2;
++}
++
++static inline unsigned long virt_to_phys_from_pte(void *addr)
++{
++ pgd_t *pgd;
++ pud_t *pud;
++ pmd_t *pmd;
++ pte_t *ptep, pte;
++
++ unsigned long virt_addr = (unsigned long)addr;
++ unsigned long phys_addr = 0UL;
++
++ /* get the page global directory. */
++ pgd = pgd_offset_k(virt_addr);
++
++ if (!pgd_none(*pgd)) {
++ /* get the page upper directory */
++ pud = pud_offset(pgd, virt_addr);
++ if (!pud_none(*pud)) {
++ /* get the page middle directory */
++ pmd = pmd_offset(pud, virt_addr);
++ if (!pmd_none(*pmd)) {
++ /* get a pointer to the page table entry */
++ ptep = pte_offset(pmd, virt_addr);
++ pte = *ptep;
++ /* check for a valid page */
++ if (pte_present(pte)) {
++ /* get the physical address the page is
++ * refering to */
++ phys_addr = (unsigned long)
++ page_to_phys(pte_page(pte));
++ /* add the offset within the page */
++ phys_addr |= (virt_addr & ~PAGE_MASK);
++ }
++ }
++ }
++ }
++
++ return phys_addr;
++}
++
++static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
++ size_t size)
++{
++ if (is_kseg2(addr))
++ return phys_to_bus(virt_to_phys_from_pte(addr));
++ else
++ return phys_to_bus(virt_to_phys(addr));
++}
++
++static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
++ struct page *page)
++{
++ return phys_to_bus(page_to_phys(page));
++}
++
++static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
++ dma_addr_t dma_addr)
++{
++ return bus_to_phys(dma_addr);
++}
++
++static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
++ size_t size, enum dma_data_direction direction)
++{
++}
++
++static inline int plat_dma_supported(struct device *dev, u64 mask)
++{
++ /*
++ * we fall back to GFP_DMA when the mask isn't all 1s,
++ * so we can't guarantee allocations that must be
++ * within a tighter range than GFP_DMA..
++ */
++ if (mask < DMA_BIT_MASK(24))
++ return 0;
++
++ return 1;
++}
++
++static inline void plat_extra_sync_for_device(struct device *dev)
++{
++ return;
++}
++
++static inline int plat_dma_mapping_error(struct device *dev,
++ dma_addr_t dma_addr)
++{
++ return 0;
++}
++
++static inline int plat_device_is_coherent(struct device *dev)
++{
++ return 0;
++}
++
++#endif /* __ASM_MACH_POWERTV_DMA_COHERENCE_H */
+diff --git a/arch/mips/include/asm/mach-powertv/interrupts.h b/arch/mips/include/asm/mach-powertv/interrupts.h
+new file mode 100644
+index 0000000..629a574
+--- /dev/null
++++ b/arch/mips/include/asm/mach-powertv/interrupts.h
+@@ -0,0 +1,254 @@
++/*
++ * Copyright (C) 2009 Cisco Systems, Inc.
++ *
++ * 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
++ */
++
++#ifndef _ASM_MACH_POWERTV_INTERRUPTS_H_
++#define _ASM_MACH_POWERTV_INTERRUPTS_H_
++
++/*
++ * Defines for all of the interrupt lines
++ */
++
++/* Definitions for backward compatibility */
++#define kIrq_Uart1 irq_uart1
++
++#define ibase 0
++
++/*------------- Register: int_stat_3 */
++/* 126 unused (bit 31) */
++#define irq_asc2video (ibase+126) /* ASC 2 Video Interrupt */
++#define irq_asc1video (ibase+125) /* ASC 1 Video Interrupt */
++#define irq_comms_block_wd (ibase+124) /* ASC 1 Video Interrupt */
++#define irq_fdma_mailbox (ibase+123) /* FDMA Mailbox Output */
++#define irq_fdma_gp (ibase+122) /* FDMA GP Output */
++#define irq_mips_pic (ibase+121) /* MIPS Performance Counter
++ * Interrupt */
++#define irq_mips_timer (ibase+120) /* MIPS Timer Interrupt */
++#define irq_memory_protect (ibase+119) /* Memory Protection Interrupt
++ * -- Ored by glue logic inside
++ * SPARC ILC (see
++ * INT_MEM_PROT_STAT, below,
++ * for individual interrupts)
++ */
++/* 118 unused (bit 22) */
++#define irq_sbag (ibase+117) /* SBAG Interrupt -- Ored by
++ * glue logic inside SPARC ILC
++ * (see INT_SBAG_STAT, below,
++ * for individual interrupts) */
++#define irq_qam_b_fec (ibase+116) /* QAM B FEC Interrupt */
++#define irq_qam_a_fec (ibase+115) /* QAM A FEC Interrupt */
++/* 114 unused (bit 18) */
++#define irq_mailbox (ibase+113) /* Mailbox Debug Interrupt --
++ * Ored by glue logic inside
++ * SPARC ILC (see
++ * INT_MAILBOX_STAT, below, for
++ * individual interrupts) */
++#define irq_fuse_stat1 (ibase+112) /* Fuse Status 1 */
++#define irq_fuse_stat2 (ibase+111) /* Fuse Status 2 */
++#define irq_fuse_stat3 (ibase+110) /* Blitter Interrupt / Fuse
++ * Status 3 */
++#define irq_blitter (ibase+110) /* Blitter Interrupt / Fuse
++ * Status 3 */
++#define irq_avc1_pp0 (ibase+109) /* AVC Decoder #1 PP0
++ * Interrupt */
++#define irq_avc1_pp1 (ibase+108) /* AVC Decoder #1 PP1
++ * Interrupt */
++#define irq_avc1_mbe (ibase+107) /* AVC Decoder #1 MBE
++ * Interrupt */
++#define irq_avc2_pp0 (ibase+106) /* AVC Decoder #2 PP0
++ * Interrupt */
++#define irq_avc2_pp1 (ibase+105) /* AVC Decoder #2 PP1
++ * Interrupt */
++#define irq_avc2_mbe (ibase+104) /* AVC Decoder #2 MBE
++ * Interrupt */
++#define irq_zbug_spi (ibase+103) /* Zbug SPI Slave Interrupt */
++#define irq_qam_mod2 (ibase+102) /* QAM Modulator 2 DMA
++ * Interrupt */
++#define irq_ir_rx (ibase+101) /* IR RX 2 Interrupt */
++#define irq_aud_dsp2 (ibase+100) /* Audio DSP #2 Interrupt */
++#define irq_aud_dsp1 (ibase+99) /* Audio DSP #1 Interrupt */
++#define irq_docsis (ibase+98) /* DOCSIS Debug Interrupt */
++#define irq_sd_dvp1 (ibase+97) /* SD DVP #1 Interrupt */
++#define irq_sd_dvp2 (ibase+96) /* SD DVP #2 Interrupt */
++/*------------- Register: int_stat_2 */
++#define irq_hd_dvp (ibase+95) /* HD DVP Interrupt */
++#define kIrq_Prewatchdog (ibase+94) /* watchdog Pre-Interrupt */
++#define irq_timer2 (ibase+93) /* Programmable Timer
++ * Interrupt 2 */
++#define irq_1394 (ibase+92) /* 1394 Firewire Interrupt */
++#define irq_usbohci (ibase+91) /* USB 2.0 OHCI Interrupt */
++#define irq_usbehci (ibase+90) /* USB 2.0 EHCI Interrupt */
++#define irq_pciexp (ibase+89) /* PCI Express 0 Interrupt */
++#define irq_pciexp0 (ibase+89) /* PCI Express 0 Interrupt */
++#define irq_afe1 (ibase+88) /* AFE 1 Interrupt */
++#define irq_sata (ibase+87) /* SATA 1 Interrupt */
++#define irq_sata1 (ibase+87) /* SATA 1 Interrupt */
++#define irq_dtcp (ibase+86) /* DTCP Interrupt */
++#define irq_pciexp1 (ibase+85) /* PCI Express 1 Interrupt */
++/* 84 unused (bit 20) */
++/* 83 unused (bit 19) */
++/* 82 unused (bit 18) */
++#define irq_sata2 (ibase+81) /* SATA2 Interrupt */
++#define irq_uart2 (ibase+80) /* UART2 Interrupt */
++#define irq_legacy_usb (ibase+79) /* Legacy USB Host ISR (1.1
++ * Host module) */
++#define irq_pod (ibase+78) /* POD Interrupt */
++#define irq_slave_usb (ibase+77) /* Slave USB */
++#define irq_denc1 (ibase+76) /* DENC #1 VTG Interrupt */
++#define irq_vbi_vtg (ibase+75) /* VBI VTG Interrupt */
++#define irq_afe2 (ibase+74) /* AFE 2 Interrupt */
++#define irq_denc2 (ibase+73) /* DENC #2 VTG Interrupt */
++#define irq_asc2 (ibase+72) /* ASC #2 Interrupt */
++#define irq_asc1 (ibase+71) /* ASC #1 Interrupt */
++#define irq_mod_dma (ibase+70) /* Modulator DMA Interrupt */
++#define irq_byte_eng1 (ibase+69) /* Byte Engine Interrupt [1] */
++#define irq_byte_eng0 (ibase+68) /* Byte Engine Interrupt [0] */
++/* 67 unused (bit 03) */
++/* 66 unused (bit 02) */
++/* 65 unused (bit 01) */
++/* 64 unused (bit 00) */
++/*------------- Register: int_stat_1 */
++/* 63 unused (bit 31) */
++/* 62 unused (bit 30) */
++/* 61 unused (bit 29) */
++/* 60 unused (bit 28) */
++/* 59 unused (bit 27) */
++/* 58 unused (bit 26) */
++/* 57 unused (bit 25) */
++/* 56 unused (bit 24) */
++#define irq_buf_dma_mem2mem (ibase+55) /* BufDMA Memory to Memory
++ * Interrupt */
++#define irq_buf_dma_usbtransmit (ibase+54) /* BufDMA USB Transmit
++ * Interrupt */
++#define irq_buf_dma_qpskpodtransmit (ibase+53) /* BufDMA QPSK/POD Tramsit
++ * Interrupt */
++#define irq_buf_dma_transmit_error (ibase+52) /* BufDMA Transmit Error
++ * Interrupt */
++#define irq_buf_dma_usbrecv (ibase+51) /* BufDMA USB Receive
++ * Interrupt */
++#define irq_buf_dma_qpskpodrecv (ibase+50) /* BufDMA QPSK/POD Receive
++ * Interrupt */
++#define irq_buf_dma_recv_error (ibase+49) /* BufDMA Receive Error
++ * Interrupt */
++#define irq_qamdma_transmit_play (ibase+48) /* QAMDMA Transmit/Play
++ * Interrupt */
++#define irq_qamdma_transmit_error (ibase+47) /* QAMDMA Transmit Error
++ * Interrupt */
++#define irq_qamdma_recv2high (ibase+46) /* QAMDMA Receive 2 High
++ * (Chans 63-32) */
++#define irq_qamdma_recv2low (ibase+45) /* QAMDMA Receive 2 Low
++ * (Chans 31-0) */
++#define irq_qamdma_recv1high (ibase+44) /* QAMDMA Receive 1 High
++ * (Chans 63-32) */
++#define irq_qamdma_recv1low (ibase+43) /* QAMDMA Receive 1 Low
++ * (Chans 31-0) */
++#define irq_qamdma_recv_error (ibase+42) /* QAMDMA Receive Error
++ * Interrupt */
++#define irq_mpegsplice (ibase+41) /* MPEG Splice Interrupt */
++#define irq_deinterlace_rdy (ibase+40) /* Deinterlacer Frame Ready
++ * Interrupt */
++#define irq_ext_in0 (ibase+39) /* External Interrupt irq_in0 */
++#define irq_gpio3 (ibase+38) /* GP I/O IRQ 3 - From GP I/O
++ * Module */
++#define irq_gpio2 (ibase+37) /* GP I/O IRQ 2 - From GP I/O
++ * Module (ABE_intN) */
++#define irq_pcrcmplt1 (ibase+36) /* PCR Capture Complete or
++ * Discontinuity 1 */
++#define irq_pcrcmplt2 (ibase+35) /* PCR Capture Complete or
++ * Discontinuity 2 */
++#define irq_parse_peierr (ibase+34) /* PID Parser Error Detect
++ * (PEI) */
++#define irq_parse_cont_err (ibase+33) /* PID Parser continuity error
++ * detect */
++#define irq_ds1framer (ibase+32) /* DS1 Framer Interrupt */
++/*------------- Register: int_stat_0 */
++#define irq_gpio1 (ibase+31) /* GP I/O IRQ 1 - From GP I/O
++ * Module */
++#define irq_gpio0 (ibase+30) /* GP I/O IRQ 0 - From GP I/O
++ * Module */
++#define irq_qpsk_out_aloha (ibase+29) /* QPSK Output Slotted Aloha
++ * (chan 3) Transmission
++ * Completed OK */
++#define irq_qpsk_out_tdma (ibase+28) /* QPSK Output TDMA (chan 2)
++ * Transmission Completed OK */
++#define irq_qpsk_out_reserve (ibase+27) /* QPSK Output Reservation
++ * (chan 1) Transmission
++ * Completed OK */
++#define irq_qpsk_out_aloha_err (ibase+26) /* QPSK Output Slotted Aloha
++ * (chan 3)Transmission
++ * completed with Errors. */
++#define irq_qpsk_out_tdma_err (ibase+25) /* QPSK Output TDMA (chan 2)
++ * Transmission completed with
++ * Errors. */
++#define irq_qpsk_out_rsrv_err (ibase+24) /* QPSK Output Reservation
++ * (chan 1) Transmission
++ * completed with Errors */
++#define irq_aloha_fail (ibase+23) /* Unsuccessful Resend of Aloha
++ * for N times. Aloha retry
++ * timeout for channel 3. */
++#define irq_timer1 (ibase+22) /* Programmable Timer
++ * Interrupt */
++#define irq_keyboard (ibase+21) /* Keyboard Module Interrupt */
++#define irq_i2c (ibase+20) /* I2C Module Interrupt */
++#define irq_spi (ibase+19) /* SPI Module Interrupt */
++#define irq_irblaster (ibase+18) /* IR Blaster Interrupt */
++#define irq_splice_detect (ibase+17) /* PID Key Change Interrupt or
++ * Splice Detect Interrupt */
++#define irq_se_micro (ibase+16) /* Secure Micro I/F Module
++ * Interrupt */
++#define irq_uart1 (ibase+15) /* UART Interrupt */
++#define irq_irrecv (ibase+14) /* IR Receiver Interrupt */
++#define irq_host_int1 (ibase+13) /* Host-to-Host Interrupt 1 */
++#define irq_host_int0 (ibase+12) /* Host-to-Host Interrupt 0 */
++#define irq_qpsk_hecerr (ibase+11) /* QPSK HEC Error Interrupt */
++#define irq_qpsk_crcerr (ibase+10) /* QPSK AAL-5 CRC Error
++ * Interrupt */
++/* 9 unused (bit 09) */
++/* 8 unused (bit 08) */
++#define irq_psicrcerr (ibase+7) /* QAM PSI CRC Error
++ * Interrupt */
++#define irq_psilength_err (ibase+6) /* QAM PSI Length Error
++ * Interrupt */
++#define irq_esfforward (ibase+5) /* ESF Interrupt Mark From
++ * Forward Path Reference -
++ * every 3ms when forward Mbits
++ * and forward slot control
++ * bytes are updated. */
++#define irq_esfreverse (ibase+4) /* ESF Interrupt Mark from
++ * Reverse Path Reference -
++ * delayed from forward mark by
++ * the ranging delay plus a
++ * fixed amount. When reverse
++ * Mbits and reverse slot
++ * control bytes are updated.
++ * Occurs every 3ms for 3.0M and
++ * 1.554 M upstream rates and
++ * every 6 ms for 256K upstream
++ * rate. */
++#define irq_aloha_timeout (ibase+3) /* Slotted-Aloha timeout on
++ * Channel 1. */
++#define irq_reservation (ibase+2) /* Partial (or Incremental)
++ * Reservation Message Completed
++ * or Slotted aloha verify for
++ * channel 1. */
++#define irq_aloha3 (ibase+1) /* Slotted-Aloha Message Verify
++ * Interrupt or Reservation
++ * increment completed for
++ * channel 3. */
++#define irq_mpeg_d (ibase+0) /* MPEG Decoder Interrupt */
++#endif /* _ASM_MACH_POWERTV_INTERRUPTS_H_ */
++
+diff --git a/arch/mips/include/asm/mach-powertv/ioremap.h b/arch/mips/include/asm/mach-powertv/ioremap.h
+new file mode 100644
+index 0000000..e6276d5
+--- /dev/null
++++ b/arch/mips/include/asm/mach-powertv/ioremap.h
+@@ -0,0 +1,90 @@
++/*
++ * 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.
++ *
++ * Portions Copyright (C) Cisco Systems, Inc.
++ */
++#ifndef __ASM_MACH_POWERTV_IOREMAP_H
++#define __ASM_MACH_POWERTV_IOREMAP_H
++
++#include <linux/types.h>
++
++#define LOW_MEM_BOUNDARY_PHYS 0x20000000
++#define LOW_MEM_BOUNDARY_MASK (~(LOW_MEM_BOUNDARY_PHYS - 1))
++
++/*
++ * The bus addresses are different than the physical addresses that
++ * the processor sees by an offset. This offset varies by ASIC
++ * version. Define a variable to hold the offset and some macros to
++ * make the conversion simpler. */
++extern unsigned long phys_to_bus_offset;
++
++#ifdef CONFIG_HIGHMEM
++#define MEM_GAP_PHYS 0x60000000
++/*
++ * TODO: We will use the hard code for conversion between physical and
++ * bus until the bootloader releases their device tree to us.
++ */
++#define phys_to_bus(x) (((x) < LOW_MEM_BOUNDARY_PHYS) ? \
++ ((x) + phys_to_bus_offset) : (x))
++#define bus_to_phys(x) (((x) < MEM_GAP_PHYS_ADDR) ? \
++ ((x) - phys_to_bus_offset) : (x))
++#else
++#define phys_to_bus(x) ((x) + phys_to_bus_offset)
++#define bus_to_phys(x) ((x) - phys_to_bus_offset)
++#endif
++
++/*
++ * Determine whether the address we are given is for an ASIC device
++ * Params: addr Address to check
++ * Returns: Zero if the address is not for ASIC devices, non-zero
++ * if it is.
++ */
++static inline int asic_is_device_addr(phys_t addr)
++{
++ return !((phys_t)addr & (phys_t) LOW_MEM_BOUNDARY_MASK);
++}
++
++/*
++ * Determine whether the address we are given is external RAM mappable
++ * into KSEG1.
++ * Params: addr Address to check
++ * Returns: Zero if the address is not for external RAM and
++ */
++static inline int asic_is_lowmem_ram_addr(phys_t addr)
++{
++ /*
++ * The RAM always starts at the following address in the processor's
++ * physical address space
++ */
++ static const phys_t phys_ram_base = 0x10000000;
++ phys_t bus_ram_base;
++
++ bus_ram_base = phys_to_bus_offset + phys_ram_base;
++
++ return addr >= bus_ram_base &&
++ addr < (bus_ram_base + (LOW_MEM_BOUNDARY_PHYS - phys_ram_base));
++}
++
++/*
++ * Allow physical addresses to be fixed up to help peripherals located
++ * outside the low 32-bit range -- generic pass-through version.
++ */
++static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size)
++{
++ return phys_addr;
++}
++
++static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size,
++ unsigned long flags)
++{
++ return NULL;
++}
++
++static inline int plat_iounmap(const volatile void __iomem *addr)
++{
++ return 0;
++}
++#endif /* __ASM_MACH_POWERTV_IOREMAP_H */
+diff --git a/arch/mips/include/asm/mach-powertv/irq.h b/arch/mips/include/asm/mach-powertv/irq.h
+new file mode 100644
+index 0000000..4bd5d0c
+--- /dev/null
++++ b/arch/mips/include/asm/mach-powertv/irq.h
+@@ -0,0 +1,25 @@
++/*
++ * Copyright (C) 2009 Cisco Systems, Inc.
++ *
++ * 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
++ */
++
++#ifndef _ASM_MACH_POWERTV_IRQ_H
++#define _ASM_MACH_POWERTV_IRQ_H
++#include <asm/mach-powertv/interrupts.h>
++
++#define MIPS_CPU_IRQ_BASE ibase
++#define NR_IRQS 127
++#endif
+diff --git a/arch/mips/include/asm/mach-powertv/powertv-clock.h b/arch/mips/include/asm/mach-powertv/powertv-clock.h
+new file mode 100644
+index 0000000..6f3e9a0
+--- /dev/null
++++ b/arch/mips/include/asm/mach-powertv/powertv-clock.h
+@@ -0,0 +1,29 @@
++/*
++ * Copyright (C) 2009 Cisco Systems, Inc.
++ *
++ * 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
++ */
++/*
++ * Local definitions for the powertv PCI code
++ */
++
++#ifndef _POWERTV_PCI_POWERTV_PCI_H_
++#define _POWERTV_PCI_POWERTV_PCI_H_
++extern int asic_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin);
++extern int asic_pcie_init(void);
++extern int asic_pcie_init(void);
++
++extern int log_level;
++#endif
+diff --git a/arch/mips/include/asm/mach-powertv/war.h b/arch/mips/include/asm/mach-powertv/war.h
+new file mode 100644
+index 0000000..7ac05ec
+--- /dev/null
++++ b/arch/mips/include/asm/mach-powertv/war.h
+@@ -0,0 +1,28 @@
++/*
++ * 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.
++ *
++ * This version for the PowerTV platform copied from the Malta version.
++ *
++ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
++ * Portions copyright (C) 2009 Cisco Systems, Inc.
++ */
++#ifndef __ASM_MACH_POWERTV_WAR_H
++#define __ASM_MACH_POWERTV_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 1
++#define MIPS_CACHE_SYNC_WAR 1
++#define TX49XX_ICACHE_INDEX_INV_WAR 0
++#define RM9000_CDEX_SMP_WAR 0
++#define ICACHE_REFILLS_WORKAROUND_WAR 1
++#define R10000_LLSC_WAR 0
++#define MIPS34K_MISSED_ITLB_WAR 0
++
++#endif /* __ASM_MACH_POWERTV_WAR_H */
+diff --git a/arch/mips/include/asm/mips-boards/bonito64.h b/arch/mips/include/asm/mips-boards/bonito64.h
+index a576ce0..d14e2ad 100644
+--- a/arch/mips/include/asm/mips-boards/bonito64.h
++++ b/arch/mips/include/asm/mips-boards/bonito64.h
+@@ -26,11 +26,6 @@
+ /* offsets from base register */
+ #define BONITO(x) (x)
+
+-#elif defined(CONFIG_LEMOTE_FULOONG2E)
+-
+-#define BONITO(x) (*(volatile u32 *)((char *)CKSEG1ADDR(BONITO_REG_BASE) + (x)))
+-#define BONITO_IRQ_BASE 32
+-
+ #else
+
+ /*
+diff --git a/arch/mips/include/asm/mmu_context.h b/arch/mips/include/asm/mmu_context.h
+index 6083db5..145bb81 100644
+--- a/arch/mips/include/asm/mmu_context.h
++++ b/arch/mips/include/asm/mmu_context.h
+@@ -24,6 +24,33 @@
+ #endif /* SMTC */
+ #include <asm-generic/mm_hooks.h>
+
++#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
++
++#define TLBMISS_HANDLER_SETUP_PGD(pgd) \
++ tlbmiss_handler_setup_pgd((unsigned long)(pgd))
++
++static inline void tlbmiss_handler_setup_pgd(unsigned long pgd)
++{
++ /* Check for swapper_pg_dir and convert to physical address. */
++ if ((pgd & CKSEG3) == CKSEG0)
++ pgd = CPHYSADDR(pgd);
++ write_c0_context(pgd << 11);
++}
++
++#define TLBMISS_HANDLER_SETUP() \
++ do { \
++ TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir); \
++ write_c0_xcontext((unsigned long) smp_processor_id() << 51); \
++ } while (0)
++
++
++static inline unsigned long get_current_pgd(void)
++{
++ return PHYS_TO_XKSEG_CACHED((read_c0_context() >> 11) & ~0xfffUL);
++}
++
++#else /* CONFIG_MIPS_PGD_C0_CONTEXT: using pgd_current*/
++
+ /*
+ * For the fast tlb miss handlers, we keep a per cpu array of pointers
+ * to the current pgd for each processor. Also, the proc. id is stuffed
+@@ -46,7 +73,7 @@ extern unsigned long pgd_current[];
+ back_to_back_c0_hazard(); \
+ TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
+ #endif
+-
++#endif /* CONFIG_MIPS_PGD_C0_CONTEXT*/
+ #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
+
+ #define ASID_INC 0x40
+diff --git a/arch/mips/include/asm/octeon/cvmx-agl-defs.h b/arch/mips/include/asm/octeon/cvmx-agl-defs.h
+new file mode 100644
+index 0000000..ec94b9a
+--- /dev/null
++++ b/arch/mips/include/asm/octeon/cvmx-agl-defs.h
+@@ -0,0 +1,1194 @@
++/***********************license start***************
++ * Author: Cavium Networks
++ *
++ * Contact: support@caviumnetworks.com
++ * This file is part of the OCTEON SDK
++ *
++ * Copyright (c) 2003-2008 Cavium Networks
++ *
++ * This file 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.
++ *
++ * This file is distributed in the hope that it will be useful, but
++ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
++ * NONINFRINGEMENT. See the GNU General Public License for more
++ * details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this file; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
++ * or visit http://www.gnu.org/licenses/.
++ *
++ * This file may also be available under a different license from Cavium.
++ * Contact Cavium Networks for more information
++ ***********************license end**************************************/
++
++#ifndef __CVMX_AGL_DEFS_H__
++#define __CVMX_AGL_DEFS_H__
++
++#define CVMX_AGL_GMX_BAD_REG \
++ CVMX_ADD_IO_SEG(0x00011800E0000518ull)
++#define CVMX_AGL_GMX_BIST \
++ CVMX_ADD_IO_SEG(0x00011800E0000400ull)
++#define CVMX_AGL_GMX_DRV_CTL \
++ CVMX_ADD_IO_SEG(0x00011800E00007F0ull)
++#define CVMX_AGL_GMX_INF_MODE \
++ CVMX_ADD_IO_SEG(0x00011800E00007F8ull)
++#define CVMX_AGL_GMX_PRTX_CFG(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E0000010ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_RXX_ADR_CAM0(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E0000180ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_RXX_ADR_CAM1(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E0000188ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_RXX_ADR_CAM2(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E0000190ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_RXX_ADR_CAM3(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E0000198ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_RXX_ADR_CAM4(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E00001A0ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_RXX_ADR_CAM5(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E00001A8ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_RXX_ADR_CAM_EN(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E0000108ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_RXX_ADR_CTL(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E0000100ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_RXX_DECISION(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E0000040ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_RXX_FRM_CHK(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E0000020ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_RXX_FRM_CTL(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E0000018ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_RXX_FRM_MAX(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E0000030ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_RXX_FRM_MIN(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E0000028ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_RXX_IFG(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E0000058ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_RXX_INT_EN(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E0000008ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_RXX_INT_REG(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E0000000ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_RXX_JABBER(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E0000038ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_RXX_PAUSE_DROP_TIME(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E0000068ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_RXX_STATS_CTL(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E0000050ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_RXX_STATS_OCTS(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E0000088ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_RXX_STATS_OCTS_CTL(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E0000098ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_RXX_STATS_OCTS_DMAC(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E00000A8ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_RXX_STATS_OCTS_DRP(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E00000B8ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_RXX_STATS_PKTS(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E0000080ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_RXX_STATS_PKTS_BAD(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E00000C0ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_RXX_STATS_PKTS_CTL(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E0000090ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_RXX_STATS_PKTS_DMAC(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E00000A0ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_RXX_STATS_PKTS_DRP(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E00000B0ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_RXX_UDD_SKP(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E0000048ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_RX_BP_DROPX(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E0000420ull + (((offset) & 1) * 8))
++#define CVMX_AGL_GMX_RX_BP_OFFX(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E0000460ull + (((offset) & 1) * 8))
++#define CVMX_AGL_GMX_RX_BP_ONX(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E0000440ull + (((offset) & 1) * 8))
++#define CVMX_AGL_GMX_RX_PRT_INFO \
++ CVMX_ADD_IO_SEG(0x00011800E00004E8ull)
++#define CVMX_AGL_GMX_RX_TX_STATUS \
++ CVMX_ADD_IO_SEG(0x00011800E00007E8ull)
++#define CVMX_AGL_GMX_SMACX(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E0000230ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_STAT_BP \
++ CVMX_ADD_IO_SEG(0x00011800E0000520ull)
++#define CVMX_AGL_GMX_TXX_APPEND(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E0000218ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_TXX_CTL(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E0000270ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_TXX_MIN_PKT(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E0000240ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_TXX_PAUSE_PKT_INTERVAL(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E0000248ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_TXX_PAUSE_PKT_TIME(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E0000238ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_TXX_PAUSE_TOGO(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E0000258ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_TXX_PAUSE_ZERO(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E0000260ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_TXX_SOFT_PAUSE(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E0000250ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_TXX_STAT0(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E0000280ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_TXX_STAT1(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E0000288ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_TXX_STAT2(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E0000290ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_TXX_STAT3(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E0000298ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_TXX_STAT4(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E00002A0ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_TXX_STAT5(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E00002A8ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_TXX_STAT6(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E00002B0ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_TXX_STAT7(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E00002B8ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_TXX_STAT8(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E00002C0ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_TXX_STAT9(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E00002C8ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_TXX_STATS_CTL(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E0000268ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_TXX_THRESH(offset) \
++ CVMX_ADD_IO_SEG(0x00011800E0000210ull + (((offset) & 1) * 2048))
++#define CVMX_AGL_GMX_TX_BP \
++ CVMX_ADD_IO_SEG(0x00011800E00004D0ull)
++#define CVMX_AGL_GMX_TX_COL_ATTEMPT \
++ CVMX_ADD_IO_SEG(0x00011800E0000498ull)
++#define CVMX_AGL_GMX_TX_IFG \
++ CVMX_ADD_IO_SEG(0x00011800E0000488ull)
++#define CVMX_AGL_GMX_TX_INT_EN \
++ CVMX_ADD_IO_SEG(0x00011800E0000508ull)
++#define CVMX_AGL_GMX_TX_INT_REG \
++ CVMX_ADD_IO_SEG(0x00011800E0000500ull)
++#define CVMX_AGL_GMX_TX_JAM \
++ CVMX_ADD_IO_SEG(0x00011800E0000490ull)
++#define CVMX_AGL_GMX_TX_LFSR \
++ CVMX_ADD_IO_SEG(0x00011800E00004F8ull)
++#define CVMX_AGL_GMX_TX_OVR_BP \
++ CVMX_ADD_IO_SEG(0x00011800E00004C8ull)
++#define CVMX_AGL_GMX_TX_PAUSE_PKT_DMAC \
++ CVMX_ADD_IO_SEG(0x00011800E00004A0ull)
++#define CVMX_AGL_GMX_TX_PAUSE_PKT_TYPE \
++ CVMX_ADD_IO_SEG(0x00011800E00004A8ull)
++
++union cvmx_agl_gmx_bad_reg {
++ uint64_t u64;
++ struct cvmx_agl_gmx_bad_reg_s {
++ uint64_t reserved_38_63:26;
++ uint64_t txpsh1:1;
++ uint64_t txpop1:1;
++ uint64_t ovrflw1:1;
++ uint64_t txpsh:1;
++ uint64_t txpop:1;
++ uint64_t ovrflw:1;
++ uint64_t reserved_27_31:5;
++ uint64_t statovr:1;
++ uint64_t reserved_23_25:3;
++ uint64_t loststat:1;
++ uint64_t reserved_4_21:18;
++ uint64_t out_ovr:2;
++ uint64_t reserved_0_1:2;
++ } s;
++ struct cvmx_agl_gmx_bad_reg_s cn52xx;
++ struct cvmx_agl_gmx_bad_reg_s cn52xxp1;
++ struct cvmx_agl_gmx_bad_reg_cn56xx {
++ uint64_t reserved_35_63:29;
++ uint64_t txpsh:1;
++ uint64_t txpop:1;
++ uint64_t ovrflw:1;
++ uint64_t reserved_27_31:5;
++ uint64_t statovr:1;
++ uint64_t reserved_23_25:3;
++ uint64_t loststat:1;
++ uint64_t reserved_3_21:19;
++ uint64_t out_ovr:1;
++ uint64_t reserved_0_1:2;
++ } cn56xx;
++ struct cvmx_agl_gmx_bad_reg_cn56xx cn56xxp1;
++};
++
++union cvmx_agl_gmx_bist {
++ uint64_t u64;
++ struct cvmx_agl_gmx_bist_s {
++ uint64_t reserved_10_63:54;
++ uint64_t status:10;
++ } s;
++ struct cvmx_agl_gmx_bist_s cn52xx;
++ struct cvmx_agl_gmx_bist_s cn52xxp1;
++ struct cvmx_agl_gmx_bist_s cn56xx;
++ struct cvmx_agl_gmx_bist_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_drv_ctl {
++ uint64_t u64;
++ struct cvmx_agl_gmx_drv_ctl_s {
++ uint64_t reserved_49_63:15;
++ uint64_t byp_en1:1;
++ uint64_t reserved_45_47:3;
++ uint64_t pctl1:5;
++ uint64_t reserved_37_39:3;
++ uint64_t nctl1:5;
++ uint64_t reserved_17_31:15;
++ uint64_t byp_en:1;
++ uint64_t reserved_13_15:3;
++ uint64_t pctl:5;
++ uint64_t reserved_5_7:3;
++ uint64_t nctl:5;
++ } s;
++ struct cvmx_agl_gmx_drv_ctl_s cn52xx;
++ struct cvmx_agl_gmx_drv_ctl_s cn52xxp1;
++ struct cvmx_agl_gmx_drv_ctl_cn56xx {
++ uint64_t reserved_17_63:47;
++ uint64_t byp_en:1;
++ uint64_t reserved_13_15:3;
++ uint64_t pctl:5;
++ uint64_t reserved_5_7:3;
++ uint64_t nctl:5;
++ } cn56xx;
++ struct cvmx_agl_gmx_drv_ctl_cn56xx cn56xxp1;
++};
++
++union cvmx_agl_gmx_inf_mode {
++ uint64_t u64;
++ struct cvmx_agl_gmx_inf_mode_s {
++ uint64_t reserved_2_63:62;
++ uint64_t en:1;
++ uint64_t reserved_0_0:1;
++ } s;
++ struct cvmx_agl_gmx_inf_mode_s cn52xx;
++ struct cvmx_agl_gmx_inf_mode_s cn52xxp1;
++ struct cvmx_agl_gmx_inf_mode_s cn56xx;
++ struct cvmx_agl_gmx_inf_mode_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_prtx_cfg {
++ uint64_t u64;
++ struct cvmx_agl_gmx_prtx_cfg_s {
++ uint64_t reserved_6_63:58;
++ uint64_t tx_en:1;
++ uint64_t rx_en:1;
++ uint64_t slottime:1;
++ uint64_t duplex:1;
++ uint64_t speed:1;
++ uint64_t en:1;
++ } s;
++ struct cvmx_agl_gmx_prtx_cfg_s cn52xx;
++ struct cvmx_agl_gmx_prtx_cfg_s cn52xxp1;
++ struct cvmx_agl_gmx_prtx_cfg_s cn56xx;
++ struct cvmx_agl_gmx_prtx_cfg_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_rxx_adr_cam0 {
++ uint64_t u64;
++ struct cvmx_agl_gmx_rxx_adr_cam0_s {
++ uint64_t adr:64;
++ } s;
++ struct cvmx_agl_gmx_rxx_adr_cam0_s cn52xx;
++ struct cvmx_agl_gmx_rxx_adr_cam0_s cn52xxp1;
++ struct cvmx_agl_gmx_rxx_adr_cam0_s cn56xx;
++ struct cvmx_agl_gmx_rxx_adr_cam0_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_rxx_adr_cam1 {
++ uint64_t u64;
++ struct cvmx_agl_gmx_rxx_adr_cam1_s {
++ uint64_t adr:64;
++ } s;
++ struct cvmx_agl_gmx_rxx_adr_cam1_s cn52xx;
++ struct cvmx_agl_gmx_rxx_adr_cam1_s cn52xxp1;
++ struct cvmx_agl_gmx_rxx_adr_cam1_s cn56xx;
++ struct cvmx_agl_gmx_rxx_adr_cam1_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_rxx_adr_cam2 {
++ uint64_t u64;
++ struct cvmx_agl_gmx_rxx_adr_cam2_s {
++ uint64_t adr:64;
++ } s;
++ struct cvmx_agl_gmx_rxx_adr_cam2_s cn52xx;
++ struct cvmx_agl_gmx_rxx_adr_cam2_s cn52xxp1;
++ struct cvmx_agl_gmx_rxx_adr_cam2_s cn56xx;
++ struct cvmx_agl_gmx_rxx_adr_cam2_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_rxx_adr_cam3 {
++ uint64_t u64;
++ struct cvmx_agl_gmx_rxx_adr_cam3_s {
++ uint64_t adr:64;
++ } s;
++ struct cvmx_agl_gmx_rxx_adr_cam3_s cn52xx;
++ struct cvmx_agl_gmx_rxx_adr_cam3_s cn52xxp1;
++ struct cvmx_agl_gmx_rxx_adr_cam3_s cn56xx;
++ struct cvmx_agl_gmx_rxx_adr_cam3_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_rxx_adr_cam4 {
++ uint64_t u64;
++ struct cvmx_agl_gmx_rxx_adr_cam4_s {
++ uint64_t adr:64;
++ } s;
++ struct cvmx_agl_gmx_rxx_adr_cam4_s cn52xx;
++ struct cvmx_agl_gmx_rxx_adr_cam4_s cn52xxp1;
++ struct cvmx_agl_gmx_rxx_adr_cam4_s cn56xx;
++ struct cvmx_agl_gmx_rxx_adr_cam4_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_rxx_adr_cam5 {
++ uint64_t u64;
++ struct cvmx_agl_gmx_rxx_adr_cam5_s {
++ uint64_t adr:64;
++ } s;
++ struct cvmx_agl_gmx_rxx_adr_cam5_s cn52xx;
++ struct cvmx_agl_gmx_rxx_adr_cam5_s cn52xxp1;
++ struct cvmx_agl_gmx_rxx_adr_cam5_s cn56xx;
++ struct cvmx_agl_gmx_rxx_adr_cam5_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_rxx_adr_cam_en {
++ uint64_t u64;
++ struct cvmx_agl_gmx_rxx_adr_cam_en_s {
++ uint64_t reserved_8_63:56;
++ uint64_t en:8;
++ } s;
++ struct cvmx_agl_gmx_rxx_adr_cam_en_s cn52xx;
++ struct cvmx_agl_gmx_rxx_adr_cam_en_s cn52xxp1;
++ struct cvmx_agl_gmx_rxx_adr_cam_en_s cn56xx;
++ struct cvmx_agl_gmx_rxx_adr_cam_en_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_rxx_adr_ctl {
++ uint64_t u64;
++ struct cvmx_agl_gmx_rxx_adr_ctl_s {
++ uint64_t reserved_4_63:60;
++ uint64_t cam_mode:1;
++ uint64_t mcst:2;
++ uint64_t bcst:1;
++ } s;
++ struct cvmx_agl_gmx_rxx_adr_ctl_s cn52xx;
++ struct cvmx_agl_gmx_rxx_adr_ctl_s cn52xxp1;
++ struct cvmx_agl_gmx_rxx_adr_ctl_s cn56xx;
++ struct cvmx_agl_gmx_rxx_adr_ctl_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_rxx_decision {
++ uint64_t u64;
++ struct cvmx_agl_gmx_rxx_decision_s {
++ uint64_t reserved_5_63:59;
++ uint64_t cnt:5;
++ } s;
++ struct cvmx_agl_gmx_rxx_decision_s cn52xx;
++ struct cvmx_agl_gmx_rxx_decision_s cn52xxp1;
++ struct cvmx_agl_gmx_rxx_decision_s cn56xx;
++ struct cvmx_agl_gmx_rxx_decision_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_rxx_frm_chk {
++ uint64_t u64;
++ struct cvmx_agl_gmx_rxx_frm_chk_s {
++ uint64_t reserved_9_63:55;
++ uint64_t skperr:1;
++ uint64_t rcverr:1;
++ uint64_t lenerr:1;
++ uint64_t alnerr:1;
++ uint64_t fcserr:1;
++ uint64_t jabber:1;
++ uint64_t maxerr:1;
++ uint64_t reserved_1_1:1;
++ uint64_t minerr:1;
++ } s;
++ struct cvmx_agl_gmx_rxx_frm_chk_s cn52xx;
++ struct cvmx_agl_gmx_rxx_frm_chk_s cn52xxp1;
++ struct cvmx_agl_gmx_rxx_frm_chk_s cn56xx;
++ struct cvmx_agl_gmx_rxx_frm_chk_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_rxx_frm_ctl {
++ uint64_t u64;
++ struct cvmx_agl_gmx_rxx_frm_ctl_s {
++ uint64_t reserved_10_63:54;
++ uint64_t pre_align:1;
++ uint64_t pad_len:1;
++ uint64_t vlan_len:1;
++ uint64_t pre_free:1;
++ uint64_t ctl_smac:1;
++ uint64_t ctl_mcst:1;
++ uint64_t ctl_bck:1;
++ uint64_t ctl_drp:1;
++ uint64_t pre_strp:1;
++ uint64_t pre_chk:1;
++ } s;
++ struct cvmx_agl_gmx_rxx_frm_ctl_s cn52xx;
++ struct cvmx_agl_gmx_rxx_frm_ctl_s cn52xxp1;
++ struct cvmx_agl_gmx_rxx_frm_ctl_s cn56xx;
++ struct cvmx_agl_gmx_rxx_frm_ctl_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_rxx_frm_max {
++ uint64_t u64;
++ struct cvmx_agl_gmx_rxx_frm_max_s {
++ uint64_t reserved_16_63:48;
++ uint64_t len:16;
++ } s;
++ struct cvmx_agl_gmx_rxx_frm_max_s cn52xx;
++ struct cvmx_agl_gmx_rxx_frm_max_s cn52xxp1;
++ struct cvmx_agl_gmx_rxx_frm_max_s cn56xx;
++ struct cvmx_agl_gmx_rxx_frm_max_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_rxx_frm_min {
++ uint64_t u64;
++ struct cvmx_agl_gmx_rxx_frm_min_s {
++ uint64_t reserved_16_63:48;
++ uint64_t len:16;
++ } s;
++ struct cvmx_agl_gmx_rxx_frm_min_s cn52xx;
++ struct cvmx_agl_gmx_rxx_frm_min_s cn52xxp1;
++ struct cvmx_agl_gmx_rxx_frm_min_s cn56xx;
++ struct cvmx_agl_gmx_rxx_frm_min_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_rxx_ifg {
++ uint64_t u64;
++ struct cvmx_agl_gmx_rxx_ifg_s {
++ uint64_t reserved_4_63:60;
++ uint64_t ifg:4;
++ } s;
++ struct cvmx_agl_gmx_rxx_ifg_s cn52xx;
++ struct cvmx_agl_gmx_rxx_ifg_s cn52xxp1;
++ struct cvmx_agl_gmx_rxx_ifg_s cn56xx;
++ struct cvmx_agl_gmx_rxx_ifg_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_rxx_int_en {
++ uint64_t u64;
++ struct cvmx_agl_gmx_rxx_int_en_s {
++ uint64_t reserved_20_63:44;
++ uint64_t pause_drp:1;
++ uint64_t reserved_16_18:3;
++ uint64_t ifgerr:1;
++ uint64_t coldet:1;
++ uint64_t falerr:1;
++ uint64_t rsverr:1;
++ uint64_t pcterr:1;
++ uint64_t ovrerr:1;
++ uint64_t reserved_9_9:1;
++ uint64_t skperr:1;
++ uint64_t rcverr:1;
++ uint64_t lenerr:1;
++ uint64_t alnerr:1;
++ uint64_t fcserr:1;
++ uint64_t jabber:1;
++ uint64_t maxerr:1;
++ uint64_t reserved_1_1:1;
++ uint64_t minerr:1;
++ } s;
++ struct cvmx_agl_gmx_rxx_int_en_s cn52xx;
++ struct cvmx_agl_gmx_rxx_int_en_s cn52xxp1;
++ struct cvmx_agl_gmx_rxx_int_en_s cn56xx;
++ struct cvmx_agl_gmx_rxx_int_en_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_rxx_int_reg {
++ uint64_t u64;
++ struct cvmx_agl_gmx_rxx_int_reg_s {
++ uint64_t reserved_20_63:44;
++ uint64_t pause_drp:1;
++ uint64_t reserved_16_18:3;
++ uint64_t ifgerr:1;
++ uint64_t coldet:1;
++ uint64_t falerr:1;
++ uint64_t rsverr:1;
++ uint64_t pcterr:1;
++ uint64_t ovrerr:1;
++ uint64_t reserved_9_9:1;
++ uint64_t skperr:1;
++ uint64_t rcverr:1;
++ uint64_t lenerr:1;
++ uint64_t alnerr:1;
++ uint64_t fcserr:1;
++ uint64_t jabber:1;
++ uint64_t maxerr:1;
++ uint64_t reserved_1_1:1;
++ uint64_t minerr:1;
++ } s;
++ struct cvmx_agl_gmx_rxx_int_reg_s cn52xx;
++ struct cvmx_agl_gmx_rxx_int_reg_s cn52xxp1;
++ struct cvmx_agl_gmx_rxx_int_reg_s cn56xx;
++ struct cvmx_agl_gmx_rxx_int_reg_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_rxx_jabber {
++ uint64_t u64;
++ struct cvmx_agl_gmx_rxx_jabber_s {
++ uint64_t reserved_16_63:48;
++ uint64_t cnt:16;
++ } s;
++ struct cvmx_agl_gmx_rxx_jabber_s cn52xx;
++ struct cvmx_agl_gmx_rxx_jabber_s cn52xxp1;
++ struct cvmx_agl_gmx_rxx_jabber_s cn56xx;
++ struct cvmx_agl_gmx_rxx_jabber_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_rxx_pause_drop_time {
++ uint64_t u64;
++ struct cvmx_agl_gmx_rxx_pause_drop_time_s {
++ uint64_t reserved_16_63:48;
++ uint64_t status:16;
++ } s;
++ struct cvmx_agl_gmx_rxx_pause_drop_time_s cn52xx;
++ struct cvmx_agl_gmx_rxx_pause_drop_time_s cn52xxp1;
++ struct cvmx_agl_gmx_rxx_pause_drop_time_s cn56xx;
++ struct cvmx_agl_gmx_rxx_pause_drop_time_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_rxx_stats_ctl {
++ uint64_t u64;
++ struct cvmx_agl_gmx_rxx_stats_ctl_s {
++ uint64_t reserved_1_63:63;
++ uint64_t rd_clr:1;
++ } s;
++ struct cvmx_agl_gmx_rxx_stats_ctl_s cn52xx;
++ struct cvmx_agl_gmx_rxx_stats_ctl_s cn52xxp1;
++ struct cvmx_agl_gmx_rxx_stats_ctl_s cn56xx;
++ struct cvmx_agl_gmx_rxx_stats_ctl_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_rxx_stats_octs {
++ uint64_t u64;
++ struct cvmx_agl_gmx_rxx_stats_octs_s {
++ uint64_t reserved_48_63:16;
++ uint64_t cnt:48;
++ } s;
++ struct cvmx_agl_gmx_rxx_stats_octs_s cn52xx;
++ struct cvmx_agl_gmx_rxx_stats_octs_s cn52xxp1;
++ struct cvmx_agl_gmx_rxx_stats_octs_s cn56xx;
++ struct cvmx_agl_gmx_rxx_stats_octs_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_rxx_stats_octs_ctl {
++ uint64_t u64;
++ struct cvmx_agl_gmx_rxx_stats_octs_ctl_s {
++ uint64_t reserved_48_63:16;
++ uint64_t cnt:48;
++ } s;
++ struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn52xx;
++ struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn52xxp1;
++ struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn56xx;
++ struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_rxx_stats_octs_dmac {
++ uint64_t u64;
++ struct cvmx_agl_gmx_rxx_stats_octs_dmac_s {
++ uint64_t reserved_48_63:16;
++ uint64_t cnt:48;
++ } s;
++ struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn52xx;
++ struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn52xxp1;
++ struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn56xx;
++ struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_rxx_stats_octs_drp {
++ uint64_t u64;
++ struct cvmx_agl_gmx_rxx_stats_octs_drp_s {
++ uint64_t reserved_48_63:16;
++ uint64_t cnt:48;
++ } s;
++ struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn52xx;
++ struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn52xxp1;
++ struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn56xx;
++ struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_rxx_stats_pkts {
++ uint64_t u64;
++ struct cvmx_agl_gmx_rxx_stats_pkts_s {
++ uint64_t reserved_32_63:32;
++ uint64_t cnt:32;
++ } s;
++ struct cvmx_agl_gmx_rxx_stats_pkts_s cn52xx;
++ struct cvmx_agl_gmx_rxx_stats_pkts_s cn52xxp1;
++ struct cvmx_agl_gmx_rxx_stats_pkts_s cn56xx;
++ struct cvmx_agl_gmx_rxx_stats_pkts_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_rxx_stats_pkts_bad {
++ uint64_t u64;
++ struct cvmx_agl_gmx_rxx_stats_pkts_bad_s {
++ uint64_t reserved_32_63:32;
++ uint64_t cnt:32;
++ } s;
++ struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn52xx;
++ struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn52xxp1;
++ struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn56xx;
++ struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_rxx_stats_pkts_ctl {
++ uint64_t u64;
++ struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s {
++ uint64_t reserved_32_63:32;
++ uint64_t cnt:32;
++ } s;
++ struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn52xx;
++ struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn52xxp1;
++ struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn56xx;
++ struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_rxx_stats_pkts_dmac {
++ uint64_t u64;
++ struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s {
++ uint64_t reserved_32_63:32;
++ uint64_t cnt:32;
++ } s;
++ struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn52xx;
++ struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn52xxp1;
++ struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn56xx;
++ struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_rxx_stats_pkts_drp {
++ uint64_t u64;
++ struct cvmx_agl_gmx_rxx_stats_pkts_drp_s {
++ uint64_t reserved_32_63:32;
++ uint64_t cnt:32;
++ } s;
++ struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn52xx;
++ struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn52xxp1;
++ struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn56xx;
++ struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_rxx_udd_skp {
++ uint64_t u64;
++ struct cvmx_agl_gmx_rxx_udd_skp_s {
++ uint64_t reserved_9_63:55;
++ uint64_t fcssel:1;
++ uint64_t reserved_7_7:1;
++ uint64_t len:7;
++ } s;
++ struct cvmx_agl_gmx_rxx_udd_skp_s cn52xx;
++ struct cvmx_agl_gmx_rxx_udd_skp_s cn52xxp1;
++ struct cvmx_agl_gmx_rxx_udd_skp_s cn56xx;
++ struct cvmx_agl_gmx_rxx_udd_skp_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_rx_bp_dropx {
++ uint64_t u64;
++ struct cvmx_agl_gmx_rx_bp_dropx_s {
++ uint64_t reserved_6_63:58;
++ uint64_t mark:6;
++ } s;
++ struct cvmx_agl_gmx_rx_bp_dropx_s cn52xx;
++ struct cvmx_agl_gmx_rx_bp_dropx_s cn52xxp1;
++ struct cvmx_agl_gmx_rx_bp_dropx_s cn56xx;
++ struct cvmx_agl_gmx_rx_bp_dropx_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_rx_bp_offx {
++ uint64_t u64;
++ struct cvmx_agl_gmx_rx_bp_offx_s {
++ uint64_t reserved_6_63:58;
++ uint64_t mark:6;
++ } s;
++ struct cvmx_agl_gmx_rx_bp_offx_s cn52xx;
++ struct cvmx_agl_gmx_rx_bp_offx_s cn52xxp1;
++ struct cvmx_agl_gmx_rx_bp_offx_s cn56xx;
++ struct cvmx_agl_gmx_rx_bp_offx_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_rx_bp_onx {
++ uint64_t u64;
++ struct cvmx_agl_gmx_rx_bp_onx_s {
++ uint64_t reserved_9_63:55;
++ uint64_t mark:9;
++ } s;
++ struct cvmx_agl_gmx_rx_bp_onx_s cn52xx;
++ struct cvmx_agl_gmx_rx_bp_onx_s cn52xxp1;
++ struct cvmx_agl_gmx_rx_bp_onx_s cn56xx;
++ struct cvmx_agl_gmx_rx_bp_onx_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_rx_prt_info {
++ uint64_t u64;
++ struct cvmx_agl_gmx_rx_prt_info_s {
++ uint64_t reserved_18_63:46;
++ uint64_t drop:2;
++ uint64_t reserved_2_15:14;
++ uint64_t commit:2;
++ } s;
++ struct cvmx_agl_gmx_rx_prt_info_s cn52xx;
++ struct cvmx_agl_gmx_rx_prt_info_s cn52xxp1;
++ struct cvmx_agl_gmx_rx_prt_info_cn56xx {
++ uint64_t reserved_17_63:47;
++ uint64_t drop:1;
++ uint64_t reserved_1_15:15;
++ uint64_t commit:1;
++ } cn56xx;
++ struct cvmx_agl_gmx_rx_prt_info_cn56xx cn56xxp1;
++};
++
++union cvmx_agl_gmx_rx_tx_status {
++ uint64_t u64;
++ struct cvmx_agl_gmx_rx_tx_status_s {
++ uint64_t reserved_6_63:58;
++ uint64_t tx:2;
++ uint64_t reserved_2_3:2;
++ uint64_t rx:2;
++ } s;
++ struct cvmx_agl_gmx_rx_tx_status_s cn52xx;
++ struct cvmx_agl_gmx_rx_tx_status_s cn52xxp1;
++ struct cvmx_agl_gmx_rx_tx_status_cn56xx {
++ uint64_t reserved_5_63:59;
++ uint64_t tx:1;
++ uint64_t reserved_1_3:3;
++ uint64_t rx:1;
++ } cn56xx;
++ struct cvmx_agl_gmx_rx_tx_status_cn56xx cn56xxp1;
++};
++
++union cvmx_agl_gmx_smacx {
++ uint64_t u64;
++ struct cvmx_agl_gmx_smacx_s {
++ uint64_t reserved_48_63:16;
++ uint64_t smac:48;
++ } s;
++ struct cvmx_agl_gmx_smacx_s cn52xx;
++ struct cvmx_agl_gmx_smacx_s cn52xxp1;
++ struct cvmx_agl_gmx_smacx_s cn56xx;
++ struct cvmx_agl_gmx_smacx_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_stat_bp {
++ uint64_t u64;
++ struct cvmx_agl_gmx_stat_bp_s {
++ uint64_t reserved_17_63:47;
++ uint64_t bp:1;
++ uint64_t cnt:16;
++ } s;
++ struct cvmx_agl_gmx_stat_bp_s cn52xx;
++ struct cvmx_agl_gmx_stat_bp_s cn52xxp1;
++ struct cvmx_agl_gmx_stat_bp_s cn56xx;
++ struct cvmx_agl_gmx_stat_bp_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_txx_append {
++ uint64_t u64;
++ struct cvmx_agl_gmx_txx_append_s {
++ uint64_t reserved_4_63:60;
++ uint64_t force_fcs:1;
++ uint64_t fcs:1;
++ uint64_t pad:1;
++ uint64_t preamble:1;
++ } s;
++ struct cvmx_agl_gmx_txx_append_s cn52xx;
++ struct cvmx_agl_gmx_txx_append_s cn52xxp1;
++ struct cvmx_agl_gmx_txx_append_s cn56xx;
++ struct cvmx_agl_gmx_txx_append_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_txx_ctl {
++ uint64_t u64;
++ struct cvmx_agl_gmx_txx_ctl_s {
++ uint64_t reserved_2_63:62;
++ uint64_t xsdef_en:1;
++ uint64_t xscol_en:1;
++ } s;
++ struct cvmx_agl_gmx_txx_ctl_s cn52xx;
++ struct cvmx_agl_gmx_txx_ctl_s cn52xxp1;
++ struct cvmx_agl_gmx_txx_ctl_s cn56xx;
++ struct cvmx_agl_gmx_txx_ctl_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_txx_min_pkt {
++ uint64_t u64;
++ struct cvmx_agl_gmx_txx_min_pkt_s {
++ uint64_t reserved_8_63:56;
++ uint64_t min_size:8;
++ } s;
++ struct cvmx_agl_gmx_txx_min_pkt_s cn52xx;
++ struct cvmx_agl_gmx_txx_min_pkt_s cn52xxp1;
++ struct cvmx_agl_gmx_txx_min_pkt_s cn56xx;
++ struct cvmx_agl_gmx_txx_min_pkt_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_txx_pause_pkt_interval {
++ uint64_t u64;
++ struct cvmx_agl_gmx_txx_pause_pkt_interval_s {
++ uint64_t reserved_16_63:48;
++ uint64_t interval:16;
++ } s;
++ struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn52xx;
++ struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn52xxp1;
++ struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn56xx;
++ struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_txx_pause_pkt_time {
++ uint64_t u64;
++ struct cvmx_agl_gmx_txx_pause_pkt_time_s {
++ uint64_t reserved_16_63:48;
++ uint64_t time:16;
++ } s;
++ struct cvmx_agl_gmx_txx_pause_pkt_time_s cn52xx;
++ struct cvmx_agl_gmx_txx_pause_pkt_time_s cn52xxp1;
++ struct cvmx_agl_gmx_txx_pause_pkt_time_s cn56xx;
++ struct cvmx_agl_gmx_txx_pause_pkt_time_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_txx_pause_togo {
++ uint64_t u64;
++ struct cvmx_agl_gmx_txx_pause_togo_s {
++ uint64_t reserved_16_63:48;
++ uint64_t time:16;
++ } s;
++ struct cvmx_agl_gmx_txx_pause_togo_s cn52xx;
++ struct cvmx_agl_gmx_txx_pause_togo_s cn52xxp1;
++ struct cvmx_agl_gmx_txx_pause_togo_s cn56xx;
++ struct cvmx_agl_gmx_txx_pause_togo_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_txx_pause_zero {
++ uint64_t u64;
++ struct cvmx_agl_gmx_txx_pause_zero_s {
++ uint64_t reserved_1_63:63;
++ uint64_t send:1;
++ } s;
++ struct cvmx_agl_gmx_txx_pause_zero_s cn52xx;
++ struct cvmx_agl_gmx_txx_pause_zero_s cn52xxp1;
++ struct cvmx_agl_gmx_txx_pause_zero_s cn56xx;
++ struct cvmx_agl_gmx_txx_pause_zero_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_txx_soft_pause {
++ uint64_t u64;
++ struct cvmx_agl_gmx_txx_soft_pause_s {
++ uint64_t reserved_16_63:48;
++ uint64_t time:16;
++ } s;
++ struct cvmx_agl_gmx_txx_soft_pause_s cn52xx;
++ struct cvmx_agl_gmx_txx_soft_pause_s cn52xxp1;
++ struct cvmx_agl_gmx_txx_soft_pause_s cn56xx;
++ struct cvmx_agl_gmx_txx_soft_pause_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_txx_stat0 {
++ uint64_t u64;
++ struct cvmx_agl_gmx_txx_stat0_s {
++ uint64_t xsdef:32;
++ uint64_t xscol:32;
++ } s;
++ struct cvmx_agl_gmx_txx_stat0_s cn52xx;
++ struct cvmx_agl_gmx_txx_stat0_s cn52xxp1;
++ struct cvmx_agl_gmx_txx_stat0_s cn56xx;
++ struct cvmx_agl_gmx_txx_stat0_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_txx_stat1 {
++ uint64_t u64;
++ struct cvmx_agl_gmx_txx_stat1_s {
++ uint64_t scol:32;
++ uint64_t mcol:32;
++ } s;
++ struct cvmx_agl_gmx_txx_stat1_s cn52xx;
++ struct cvmx_agl_gmx_txx_stat1_s cn52xxp1;
++ struct cvmx_agl_gmx_txx_stat1_s cn56xx;
++ struct cvmx_agl_gmx_txx_stat1_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_txx_stat2 {
++ uint64_t u64;
++ struct cvmx_agl_gmx_txx_stat2_s {
++ uint64_t reserved_48_63:16;
++ uint64_t octs:48;
++ } s;
++ struct cvmx_agl_gmx_txx_stat2_s cn52xx;
++ struct cvmx_agl_gmx_txx_stat2_s cn52xxp1;
++ struct cvmx_agl_gmx_txx_stat2_s cn56xx;
++ struct cvmx_agl_gmx_txx_stat2_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_txx_stat3 {
++ uint64_t u64;
++ struct cvmx_agl_gmx_txx_stat3_s {
++ uint64_t reserved_32_63:32;
++ uint64_t pkts:32;
++ } s;
++ struct cvmx_agl_gmx_txx_stat3_s cn52xx;
++ struct cvmx_agl_gmx_txx_stat3_s cn52xxp1;
++ struct cvmx_agl_gmx_txx_stat3_s cn56xx;
++ struct cvmx_agl_gmx_txx_stat3_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_txx_stat4 {
++ uint64_t u64;
++ struct cvmx_agl_gmx_txx_stat4_s {
++ uint64_t hist1:32;
++ uint64_t hist0:32;
++ } s;
++ struct cvmx_agl_gmx_txx_stat4_s cn52xx;
++ struct cvmx_agl_gmx_txx_stat4_s cn52xxp1;
++ struct cvmx_agl_gmx_txx_stat4_s cn56xx;
++ struct cvmx_agl_gmx_txx_stat4_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_txx_stat5 {
++ uint64_t u64;
++ struct cvmx_agl_gmx_txx_stat5_s {
++ uint64_t hist3:32;
++ uint64_t hist2:32;
++ } s;
++ struct cvmx_agl_gmx_txx_stat5_s cn52xx;
++ struct cvmx_agl_gmx_txx_stat5_s cn52xxp1;
++ struct cvmx_agl_gmx_txx_stat5_s cn56xx;
++ struct cvmx_agl_gmx_txx_stat5_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_txx_stat6 {
++ uint64_t u64;
++ struct cvmx_agl_gmx_txx_stat6_s {
++ uint64_t hist5:32;
++ uint64_t hist4:32;
++ } s;
++ struct cvmx_agl_gmx_txx_stat6_s cn52xx;
++ struct cvmx_agl_gmx_txx_stat6_s cn52xxp1;
++ struct cvmx_agl_gmx_txx_stat6_s cn56xx;
++ struct cvmx_agl_gmx_txx_stat6_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_txx_stat7 {
++ uint64_t u64;
++ struct cvmx_agl_gmx_txx_stat7_s {
++ uint64_t hist7:32;
++ uint64_t hist6:32;
++ } s;
++ struct cvmx_agl_gmx_txx_stat7_s cn52xx;
++ struct cvmx_agl_gmx_txx_stat7_s cn52xxp1;
++ struct cvmx_agl_gmx_txx_stat7_s cn56xx;
++ struct cvmx_agl_gmx_txx_stat7_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_txx_stat8 {
++ uint64_t u64;
++ struct cvmx_agl_gmx_txx_stat8_s {
++ uint64_t mcst:32;
++ uint64_t bcst:32;
++ } s;
++ struct cvmx_agl_gmx_txx_stat8_s cn52xx;
++ struct cvmx_agl_gmx_txx_stat8_s cn52xxp1;
++ struct cvmx_agl_gmx_txx_stat8_s cn56xx;
++ struct cvmx_agl_gmx_txx_stat8_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_txx_stat9 {
++ uint64_t u64;
++ struct cvmx_agl_gmx_txx_stat9_s {
++ uint64_t undflw:32;
++ uint64_t ctl:32;
++ } s;
++ struct cvmx_agl_gmx_txx_stat9_s cn52xx;
++ struct cvmx_agl_gmx_txx_stat9_s cn52xxp1;
++ struct cvmx_agl_gmx_txx_stat9_s cn56xx;
++ struct cvmx_agl_gmx_txx_stat9_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_txx_stats_ctl {
++ uint64_t u64;
++ struct cvmx_agl_gmx_txx_stats_ctl_s {
++ uint64_t reserved_1_63:63;
++ uint64_t rd_clr:1;
++ } s;
++ struct cvmx_agl_gmx_txx_stats_ctl_s cn52xx;
++ struct cvmx_agl_gmx_txx_stats_ctl_s cn52xxp1;
++ struct cvmx_agl_gmx_txx_stats_ctl_s cn56xx;
++ struct cvmx_agl_gmx_txx_stats_ctl_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_txx_thresh {
++ uint64_t u64;
++ struct cvmx_agl_gmx_txx_thresh_s {
++ uint64_t reserved_6_63:58;
++ uint64_t cnt:6;
++ } s;
++ struct cvmx_agl_gmx_txx_thresh_s cn52xx;
++ struct cvmx_agl_gmx_txx_thresh_s cn52xxp1;
++ struct cvmx_agl_gmx_txx_thresh_s cn56xx;
++ struct cvmx_agl_gmx_txx_thresh_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_tx_bp {
++ uint64_t u64;
++ struct cvmx_agl_gmx_tx_bp_s {
++ uint64_t reserved_2_63:62;
++ uint64_t bp:2;
++ } s;
++ struct cvmx_agl_gmx_tx_bp_s cn52xx;
++ struct cvmx_agl_gmx_tx_bp_s cn52xxp1;
++ struct cvmx_agl_gmx_tx_bp_cn56xx {
++ uint64_t reserved_1_63:63;
++ uint64_t bp:1;
++ } cn56xx;
++ struct cvmx_agl_gmx_tx_bp_cn56xx cn56xxp1;
++};
++
++union cvmx_agl_gmx_tx_col_attempt {
++ uint64_t u64;
++ struct cvmx_agl_gmx_tx_col_attempt_s {
++ uint64_t reserved_5_63:59;
++ uint64_t limit:5;
++ } s;
++ struct cvmx_agl_gmx_tx_col_attempt_s cn52xx;
++ struct cvmx_agl_gmx_tx_col_attempt_s cn52xxp1;
++ struct cvmx_agl_gmx_tx_col_attempt_s cn56xx;
++ struct cvmx_agl_gmx_tx_col_attempt_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_tx_ifg {
++ uint64_t u64;
++ struct cvmx_agl_gmx_tx_ifg_s {
++ uint64_t reserved_8_63:56;
++ uint64_t ifg2:4;
++ uint64_t ifg1:4;
++ } s;
++ struct cvmx_agl_gmx_tx_ifg_s cn52xx;
++ struct cvmx_agl_gmx_tx_ifg_s cn52xxp1;
++ struct cvmx_agl_gmx_tx_ifg_s cn56xx;
++ struct cvmx_agl_gmx_tx_ifg_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_tx_int_en {
++ uint64_t u64;
++ struct cvmx_agl_gmx_tx_int_en_s {
++ uint64_t reserved_18_63:46;
++ uint64_t late_col:2;
++ uint64_t reserved_14_15:2;
++ uint64_t xsdef:2;
++ uint64_t reserved_10_11:2;
++ uint64_t xscol:2;
++ uint64_t reserved_4_7:4;
++ uint64_t undflw:2;
++ uint64_t reserved_1_1:1;
++ uint64_t pko_nxa:1;
++ } s;
++ struct cvmx_agl_gmx_tx_int_en_s cn52xx;
++ struct cvmx_agl_gmx_tx_int_en_s cn52xxp1;
++ struct cvmx_agl_gmx_tx_int_en_cn56xx {
++ uint64_t reserved_17_63:47;
++ uint64_t late_col:1;
++ uint64_t reserved_13_15:3;
++ uint64_t xsdef:1;
++ uint64_t reserved_9_11:3;
++ uint64_t xscol:1;
++ uint64_t reserved_3_7:5;
++ uint64_t undflw:1;
++ uint64_t reserved_1_1:1;
++ uint64_t pko_nxa:1;
++ } cn56xx;
++ struct cvmx_agl_gmx_tx_int_en_cn56xx cn56xxp1;
++};
++
++union cvmx_agl_gmx_tx_int_reg {
++ uint64_t u64;
++ struct cvmx_agl_gmx_tx_int_reg_s {
++ uint64_t reserved_18_63:46;
++ uint64_t late_col:2;
++ uint64_t reserved_14_15:2;
++ uint64_t xsdef:2;
++ uint64_t reserved_10_11:2;
++ uint64_t xscol:2;
++ uint64_t reserved_4_7:4;
++ uint64_t undflw:2;
++ uint64_t reserved_1_1:1;
++ uint64_t pko_nxa:1;
++ } s;
++ struct cvmx_agl_gmx_tx_int_reg_s cn52xx;
++ struct cvmx_agl_gmx_tx_int_reg_s cn52xxp1;
++ struct cvmx_agl_gmx_tx_int_reg_cn56xx {
++ uint64_t reserved_17_63:47;
++ uint64_t late_col:1;
++ uint64_t reserved_13_15:3;
++ uint64_t xsdef:1;
++ uint64_t reserved_9_11:3;
++ uint64_t xscol:1;
++ uint64_t reserved_3_7:5;
++ uint64_t undflw:1;
++ uint64_t reserved_1_1:1;
++ uint64_t pko_nxa:1;
++ } cn56xx;
++ struct cvmx_agl_gmx_tx_int_reg_cn56xx cn56xxp1;
++};
++
++union cvmx_agl_gmx_tx_jam {
++ uint64_t u64;
++ struct cvmx_agl_gmx_tx_jam_s {
++ uint64_t reserved_8_63:56;
++ uint64_t jam:8;
++ } s;
++ struct cvmx_agl_gmx_tx_jam_s cn52xx;
++ struct cvmx_agl_gmx_tx_jam_s cn52xxp1;
++ struct cvmx_agl_gmx_tx_jam_s cn56xx;
++ struct cvmx_agl_gmx_tx_jam_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_tx_lfsr {
++ uint64_t u64;
++ struct cvmx_agl_gmx_tx_lfsr_s {
++ uint64_t reserved_16_63:48;
++ uint64_t lfsr:16;
++ } s;
++ struct cvmx_agl_gmx_tx_lfsr_s cn52xx;
++ struct cvmx_agl_gmx_tx_lfsr_s cn52xxp1;
++ struct cvmx_agl_gmx_tx_lfsr_s cn56xx;
++ struct cvmx_agl_gmx_tx_lfsr_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_tx_ovr_bp {
++ uint64_t u64;
++ struct cvmx_agl_gmx_tx_ovr_bp_s {
++ uint64_t reserved_10_63:54;
++ uint64_t en:2;
++ uint64_t reserved_6_7:2;
++ uint64_t bp:2;
++ uint64_t reserved_2_3:2;
++ uint64_t ign_full:2;
++ } s;
++ struct cvmx_agl_gmx_tx_ovr_bp_s cn52xx;
++ struct cvmx_agl_gmx_tx_ovr_bp_s cn52xxp1;
++ struct cvmx_agl_gmx_tx_ovr_bp_cn56xx {
++ uint64_t reserved_9_63:55;
++ uint64_t en:1;
++ uint64_t reserved_5_7:3;
++ uint64_t bp:1;
++ uint64_t reserved_1_3:3;
++ uint64_t ign_full:1;
++ } cn56xx;
++ struct cvmx_agl_gmx_tx_ovr_bp_cn56xx cn56xxp1;
++};
++
++union cvmx_agl_gmx_tx_pause_pkt_dmac {
++ uint64_t u64;
++ struct cvmx_agl_gmx_tx_pause_pkt_dmac_s {
++ uint64_t reserved_48_63:16;
++ uint64_t dmac:48;
++ } s;
++ struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn52xx;
++ struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn52xxp1;
++ struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn56xx;
++ struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn56xxp1;
++};
++
++union cvmx_agl_gmx_tx_pause_pkt_type {
++ uint64_t u64;
++ struct cvmx_agl_gmx_tx_pause_pkt_type_s {
++ uint64_t reserved_16_63:48;
++ uint64_t type:16;
++ } s;
++ struct cvmx_agl_gmx_tx_pause_pkt_type_s cn52xx;
++ struct cvmx_agl_gmx_tx_pause_pkt_type_s cn52xxp1;
++ struct cvmx_agl_gmx_tx_pause_pkt_type_s cn56xx;
++ struct cvmx_agl_gmx_tx_pause_pkt_type_s cn56xxp1;
++};
++
++#endif
+diff --git a/arch/mips/include/asm/octeon/cvmx-mixx-defs.h b/arch/mips/include/asm/octeon/cvmx-mixx-defs.h
+new file mode 100644
+index 0000000..dab6dca
+--- /dev/null
++++ b/arch/mips/include/asm/octeon/cvmx-mixx-defs.h
+@@ -0,0 +1,248 @@
++/***********************license start***************
++ * Author: Cavium Networks
++ *
++ * Contact: support@caviumnetworks.com
++ * This file is part of the OCTEON SDK
++ *
++ * Copyright (c) 2003-2008 Cavium Networks
++ *
++ * This file 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.
++ *
++ * This file is distributed in the hope that it will be useful, but
++ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
++ * NONINFRINGEMENT. See the GNU General Public License for more
++ * details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this file; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
++ * or visit http://www.gnu.org/licenses/.
++ *
++ * This file may also be available under a different license from Cavium.
++ * Contact Cavium Networks for more information
++ ***********************license end**************************************/
++
++#ifndef __CVMX_MIXX_DEFS_H__
++#define __CVMX_MIXX_DEFS_H__
++
++#define CVMX_MIXX_BIST(offset) \
++ CVMX_ADD_IO_SEG(0x0001070000100078ull + (((offset) & 1) * 2048))
++#define CVMX_MIXX_CTL(offset) \
++ CVMX_ADD_IO_SEG(0x0001070000100020ull + (((offset) & 1) * 2048))
++#define CVMX_MIXX_INTENA(offset) \
++ CVMX_ADD_IO_SEG(0x0001070000100050ull + (((offset) & 1) * 2048))
++#define CVMX_MIXX_IRCNT(offset) \
++ CVMX_ADD_IO_SEG(0x0001070000100030ull + (((offset) & 1) * 2048))
++#define CVMX_MIXX_IRHWM(offset) \
++ CVMX_ADD_IO_SEG(0x0001070000100028ull + (((offset) & 1) * 2048))
++#define CVMX_MIXX_IRING1(offset) \
++ CVMX_ADD_IO_SEG(0x0001070000100010ull + (((offset) & 1) * 2048))
++#define CVMX_MIXX_IRING2(offset) \
++ CVMX_ADD_IO_SEG(0x0001070000100018ull + (((offset) & 1) * 2048))
++#define CVMX_MIXX_ISR(offset) \
++ CVMX_ADD_IO_SEG(0x0001070000100048ull + (((offset) & 1) * 2048))
++#define CVMX_MIXX_ORCNT(offset) \
++ CVMX_ADD_IO_SEG(0x0001070000100040ull + (((offset) & 1) * 2048))
++#define CVMX_MIXX_ORHWM(offset) \
++ CVMX_ADD_IO_SEG(0x0001070000100038ull + (((offset) & 1) * 2048))
++#define CVMX_MIXX_ORING1(offset) \
++ CVMX_ADD_IO_SEG(0x0001070000100000ull + (((offset) & 1) * 2048))
++#define CVMX_MIXX_ORING2(offset) \
++ CVMX_ADD_IO_SEG(0x0001070000100008ull + (((offset) & 1) * 2048))
++#define CVMX_MIXX_REMCNT(offset) \
++ CVMX_ADD_IO_SEG(0x0001070000100058ull + (((offset) & 1) * 2048))
++
++union cvmx_mixx_bist {
++ uint64_t u64;
++ struct cvmx_mixx_bist_s {
++ uint64_t reserved_4_63:60;
++ uint64_t mrqdat:1;
++ uint64_t ipfdat:1;
++ uint64_t irfdat:1;
++ uint64_t orfdat:1;
++ } s;
++ struct cvmx_mixx_bist_s cn52xx;
++ struct cvmx_mixx_bist_s cn52xxp1;
++ struct cvmx_mixx_bist_s cn56xx;
++ struct cvmx_mixx_bist_s cn56xxp1;
++};
++
++union cvmx_mixx_ctl {
++ uint64_t u64;
++ struct cvmx_mixx_ctl_s {
++ uint64_t reserved_8_63:56;
++ uint64_t crc_strip:1;
++ uint64_t busy:1;
++ uint64_t en:1;
++ uint64_t reset:1;
++ uint64_t lendian:1;
++ uint64_t nbtarb:1;
++ uint64_t mrq_hwm:2;
++ } s;
++ struct cvmx_mixx_ctl_s cn52xx;
++ struct cvmx_mixx_ctl_s cn52xxp1;
++ struct cvmx_mixx_ctl_s cn56xx;
++ struct cvmx_mixx_ctl_s cn56xxp1;
++};
++
++union cvmx_mixx_intena {
++ uint64_t u64;
++ struct cvmx_mixx_intena_s {
++ uint64_t reserved_7_63:57;
++ uint64_t orunena:1;
++ uint64_t irunena:1;
++ uint64_t data_drpena:1;
++ uint64_t ithena:1;
++ uint64_t othena:1;
++ uint64_t ivfena:1;
++ uint64_t ovfena:1;
++ } s;
++ struct cvmx_mixx_intena_s cn52xx;
++ struct cvmx_mixx_intena_s cn52xxp1;
++ struct cvmx_mixx_intena_s cn56xx;
++ struct cvmx_mixx_intena_s cn56xxp1;
++};
++
++union cvmx_mixx_ircnt {
++ uint64_t u64;
++ struct cvmx_mixx_ircnt_s {
++ uint64_t reserved_20_63:44;
++ uint64_t ircnt:20;
++ } s;
++ struct cvmx_mixx_ircnt_s cn52xx;
++ struct cvmx_mixx_ircnt_s cn52xxp1;
++ struct cvmx_mixx_ircnt_s cn56xx;
++ struct cvmx_mixx_ircnt_s cn56xxp1;
++};
++
++union cvmx_mixx_irhwm {
++ uint64_t u64;
++ struct cvmx_mixx_irhwm_s {
++ uint64_t reserved_40_63:24;
++ uint64_t ibplwm:20;
++ uint64_t irhwm:20;
++ } s;
++ struct cvmx_mixx_irhwm_s cn52xx;
++ struct cvmx_mixx_irhwm_s cn52xxp1;
++ struct cvmx_mixx_irhwm_s cn56xx;
++ struct cvmx_mixx_irhwm_s cn56xxp1;
++};
++
++union cvmx_mixx_iring1 {
++ uint64_t u64;
++ struct cvmx_mixx_iring1_s {
++ uint64_t reserved_60_63:4;
++ uint64_t isize:20;
++ uint64_t reserved_36_39:4;
++ uint64_t ibase:33;
++ uint64_t reserved_0_2:3;
++ } s;
++ struct cvmx_mixx_iring1_s cn52xx;
++ struct cvmx_mixx_iring1_s cn52xxp1;
++ struct cvmx_mixx_iring1_s cn56xx;
++ struct cvmx_mixx_iring1_s cn56xxp1;
++};
++
++union cvmx_mixx_iring2 {
++ uint64_t u64;
++ struct cvmx_mixx_iring2_s {
++ uint64_t reserved_52_63:12;
++ uint64_t itlptr:20;
++ uint64_t reserved_20_31:12;
++ uint64_t idbell:20;
++ } s;
++ struct cvmx_mixx_iring2_s cn52xx;
++ struct cvmx_mixx_iring2_s cn52xxp1;
++ struct cvmx_mixx_iring2_s cn56xx;
++ struct cvmx_mixx_iring2_s cn56xxp1;
++};
++
++union cvmx_mixx_isr {
++ uint64_t u64;
++ struct cvmx_mixx_isr_s {
++ uint64_t reserved_7_63:57;
++ uint64_t orun:1;
++ uint64_t irun:1;
++ uint64_t data_drp:1;
++ uint64_t irthresh:1;
++ uint64_t orthresh:1;
++ uint64_t idblovf:1;
++ uint64_t odblovf:1;
++ } s;
++ struct cvmx_mixx_isr_s cn52xx;
++ struct cvmx_mixx_isr_s cn52xxp1;
++ struct cvmx_mixx_isr_s cn56xx;
++ struct cvmx_mixx_isr_s cn56xxp1;
++};
++
++union cvmx_mixx_orcnt {
++ uint64_t u64;
++ struct cvmx_mixx_orcnt_s {
++ uint64_t reserved_20_63:44;
++ uint64_t orcnt:20;
++ } s;
++ struct cvmx_mixx_orcnt_s cn52xx;
++ struct cvmx_mixx_orcnt_s cn52xxp1;
++ struct cvmx_mixx_orcnt_s cn56xx;
++ struct cvmx_mixx_orcnt_s cn56xxp1;
++};
++
++union cvmx_mixx_orhwm {
++ uint64_t u64;
++ struct cvmx_mixx_orhwm_s {
++ uint64_t reserved_20_63:44;
++ uint64_t orhwm:20;
++ } s;
++ struct cvmx_mixx_orhwm_s cn52xx;
++ struct cvmx_mixx_orhwm_s cn52xxp1;
++ struct cvmx_mixx_orhwm_s cn56xx;
++ struct cvmx_mixx_orhwm_s cn56xxp1;
++};
++
++union cvmx_mixx_oring1 {
++ uint64_t u64;
++ struct cvmx_mixx_oring1_s {
++ uint64_t reserved_60_63:4;
++ uint64_t osize:20;
++ uint64_t reserved_36_39:4;
++ uint64_t obase:33;
++ uint64_t reserved_0_2:3;
++ } s;
++ struct cvmx_mixx_oring1_s cn52xx;
++ struct cvmx_mixx_oring1_s cn52xxp1;
++ struct cvmx_mixx_oring1_s cn56xx;
++ struct cvmx_mixx_oring1_s cn56xxp1;
++};
++
++union cvmx_mixx_oring2 {
++ uint64_t u64;
++ struct cvmx_mixx_oring2_s {
++ uint64_t reserved_52_63:12;
++ uint64_t otlptr:20;
++ uint64_t reserved_20_31:12;
++ uint64_t odbell:20;
++ } s;
++ struct cvmx_mixx_oring2_s cn52xx;
++ struct cvmx_mixx_oring2_s cn52xxp1;
++ struct cvmx_mixx_oring2_s cn56xx;
++ struct cvmx_mixx_oring2_s cn56xxp1;
++};
++
++union cvmx_mixx_remcnt {
++ uint64_t u64;
++ struct cvmx_mixx_remcnt_s {
++ uint64_t reserved_52_63:12;
++ uint64_t iremcnt:20;
++ uint64_t reserved_20_31:12;
++ uint64_t oremcnt:20;
++ } s;
++ struct cvmx_mixx_remcnt_s cn52xx;
++ struct cvmx_mixx_remcnt_s cn52xxp1;
++ struct cvmx_mixx_remcnt_s cn56xx;
++ struct cvmx_mixx_remcnt_s cn56xxp1;
++};
++
++#endif
+diff --git a/arch/mips/include/asm/octeon/cvmx-smix-defs.h b/arch/mips/include/asm/octeon/cvmx-smix-defs.h
+new file mode 100644
+index 0000000..9ae45fc
+--- /dev/null
++++ b/arch/mips/include/asm/octeon/cvmx-smix-defs.h
+@@ -0,0 +1,178 @@
++/***********************license start***************
++ * Author: Cavium Networks
++ *
++ * Contact: support@caviumnetworks.com
++ * This file is part of the OCTEON SDK
++ *
++ * Copyright (c) 2003-2008 Cavium Networks
++ *
++ * This file 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.
++ *
++ * This file is distributed in the hope that it will be useful, but
++ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
++ * NONINFRINGEMENT. See the GNU General Public License for more
++ * details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this file; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
++ * or visit http://www.gnu.org/licenses/.
++ *
++ * This file may also be available under a different license from Cavium.
++ * Contact Cavium Networks for more information
++ ***********************license end**************************************/
++
++#ifndef __CVMX_SMIX_DEFS_H__
++#define __CVMX_SMIX_DEFS_H__
++
++#define CVMX_SMIX_CLK(offset) \
++ CVMX_ADD_IO_SEG(0x0001180000001818ull + (((offset) & 1) * 256))
++#define CVMX_SMIX_CMD(offset) \
++ CVMX_ADD_IO_SEG(0x0001180000001800ull + (((offset) & 1) * 256))
++#define CVMX_SMIX_EN(offset) \
++ CVMX_ADD_IO_SEG(0x0001180000001820ull + (((offset) & 1) * 256))
++#define CVMX_SMIX_RD_DAT(offset) \
++ CVMX_ADD_IO_SEG(0x0001180000001810ull + (((offset) & 1) * 256))
++#define CVMX_SMIX_WR_DAT(offset) \
++ CVMX_ADD_IO_SEG(0x0001180000001808ull + (((offset) & 1) * 256))
++
++union cvmx_smix_clk {
++ uint64_t u64;
++ struct cvmx_smix_clk_s {
++ uint64_t reserved_25_63:39;
++ uint64_t mode:1;
++ uint64_t reserved_21_23:3;
++ uint64_t sample_hi:5;
++ uint64_t sample_mode:1;
++ uint64_t reserved_14_14:1;
++ uint64_t clk_idle:1;
++ uint64_t preamble:1;
++ uint64_t sample:4;
++ uint64_t phase:8;
++ } s;
++ struct cvmx_smix_clk_cn30xx {
++ uint64_t reserved_21_63:43;
++ uint64_t sample_hi:5;
++ uint64_t reserved_14_15:2;
++ uint64_t clk_idle:1;
++ uint64_t preamble:1;
++ uint64_t sample:4;
++ uint64_t phase:8;
++ } cn30xx;
++ struct cvmx_smix_clk_cn30xx cn31xx;
++ struct cvmx_smix_clk_cn30xx cn38xx;
++ struct cvmx_smix_clk_cn30xx cn38xxp2;
++ struct cvmx_smix_clk_cn50xx {
++ uint64_t reserved_25_63:39;
++ uint64_t mode:1;
++ uint64_t reserved_21_23:3;
++ uint64_t sample_hi:5;
++ uint64_t reserved_14_15:2;
++ uint64_t clk_idle:1;
++ uint64_t preamble:1;
++ uint64_t sample:4;
++ uint64_t phase:8;
++ } cn50xx;
++ struct cvmx_smix_clk_s cn52xx;
++ struct cvmx_smix_clk_cn50xx cn52xxp1;
++ struct cvmx_smix_clk_s cn56xx;
++ struct cvmx_smix_clk_cn50xx cn56xxp1;
++ struct cvmx_smix_clk_cn30xx cn58xx;
++ struct cvmx_smix_clk_cn30xx cn58xxp1;
++};
++
++union cvmx_smix_cmd {
++ uint64_t u64;
++ struct cvmx_smix_cmd_s {
++ uint64_t reserved_18_63:46;
++ uint64_t phy_op:2;
++ uint64_t reserved_13_15:3;
++ uint64_t phy_adr:5;
++ uint64_t reserved_5_7:3;
++ uint64_t reg_adr:5;
++ } s;
++ struct cvmx_smix_cmd_cn30xx {
++ uint64_t reserved_17_63:47;
++ uint64_t phy_op:1;
++ uint64_t reserved_13_15:3;
++ uint64_t phy_adr:5;
++ uint64_t reserved_5_7:3;
++ uint64_t reg_adr:5;
++ } cn30xx;
++ struct cvmx_smix_cmd_cn30xx cn31xx;
++ struct cvmx_smix_cmd_cn30xx cn38xx;
++ struct cvmx_smix_cmd_cn30xx cn38xxp2;
++ struct cvmx_smix_cmd_s cn50xx;
++ struct cvmx_smix_cmd_s cn52xx;
++ struct cvmx_smix_cmd_s cn52xxp1;
++ struct cvmx_smix_cmd_s cn56xx;
++ struct cvmx_smix_cmd_s cn56xxp1;
++ struct cvmx_smix_cmd_cn30xx cn58xx;
++ struct cvmx_smix_cmd_cn30xx cn58xxp1;
++};
++
++union cvmx_smix_en {
++ uint64_t u64;
++ struct cvmx_smix_en_s {
++ uint64_t reserved_1_63:63;
++ uint64_t en:1;
++ } s;
++ struct cvmx_smix_en_s cn30xx;
++ struct cvmx_smix_en_s cn31xx;
++ struct cvmx_smix_en_s cn38xx;
++ struct cvmx_smix_en_s cn38xxp2;
++ struct cvmx_smix_en_s cn50xx;
++ struct cvmx_smix_en_s cn52xx;
++ struct cvmx_smix_en_s cn52xxp1;
++ struct cvmx_smix_en_s cn56xx;
++ struct cvmx_smix_en_s cn56xxp1;
++ struct cvmx_smix_en_s cn58xx;
++ struct cvmx_smix_en_s cn58xxp1;
++};
++
++union cvmx_smix_rd_dat {
++ uint64_t u64;
++ struct cvmx_smix_rd_dat_s {
++ uint64_t reserved_18_63:46;
++ uint64_t pending:1;
++ uint64_t val:1;
++ uint64_t dat:16;
++ } s;
++ struct cvmx_smix_rd_dat_s cn30xx;
++ struct cvmx_smix_rd_dat_s cn31xx;
++ struct cvmx_smix_rd_dat_s cn38xx;
++ struct cvmx_smix_rd_dat_s cn38xxp2;
++ struct cvmx_smix_rd_dat_s cn50xx;
++ struct cvmx_smix_rd_dat_s cn52xx;
++ struct cvmx_smix_rd_dat_s cn52xxp1;
++ struct cvmx_smix_rd_dat_s cn56xx;
++ struct cvmx_smix_rd_dat_s cn56xxp1;
++ struct cvmx_smix_rd_dat_s cn58xx;
++ struct cvmx_smix_rd_dat_s cn58xxp1;
++};
++
++union cvmx_smix_wr_dat {
++ uint64_t u64;
++ struct cvmx_smix_wr_dat_s {
++ uint64_t reserved_18_63:46;
++ uint64_t pending:1;
++ uint64_t val:1;
++ uint64_t dat:16;
++ } s;
++ struct cvmx_smix_wr_dat_s cn30xx;
++ struct cvmx_smix_wr_dat_s cn31xx;
++ struct cvmx_smix_wr_dat_s cn38xx;
++ struct cvmx_smix_wr_dat_s cn38xxp2;
++ struct cvmx_smix_wr_dat_s cn50xx;
++ struct cvmx_smix_wr_dat_s cn52xx;
++ struct cvmx_smix_wr_dat_s cn52xxp1;
++ struct cvmx_smix_wr_dat_s cn56xx;
++ struct cvmx_smix_wr_dat_s cn56xxp1;
++ struct cvmx_smix_wr_dat_s cn58xx;
++ struct cvmx_smix_wr_dat_s cn58xxp1;
++};
++
++#endif
+diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h
+index d6eb613..1854336 100644
+--- a/arch/mips/include/asm/pgtable.h
++++ b/arch/mips/include/asm/pgtable.h
+@@ -390,6 +390,19 @@ static inline int io_remap_pfn_range(struct vm_area_struct *vma,
+ #include <asm-generic/pgtable.h>
+
+ /*
++ * uncached accelerated TLB map for video memory access
++ */
++#ifdef CONFIG_CPU_SUPPORTS_UNCACHED_ACCELERATED
++#define __HAVE_PHYS_MEM_ACCESS_PROT
++
++struct file;
++pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
++ unsigned long size, pgprot_t vma_prot);
++int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn,
++ unsigned long size, pgprot_t *vma_prot);
++#endif
++
++/*
+ * We provide our own get_unmapped area to cope with the virtual aliasing
+ * constraints placed on us by the cache architecture.
+ */
+diff --git a/arch/mips/include/asm/sgialib.h b/arch/mips/include/asm/sgialib.h
+index bfce5c7..63741ca 100644
+--- a/arch/mips/include/asm/sgialib.h
++++ b/arch/mips/include/asm/sgialib.h
+@@ -85,8 +85,7 @@ extern void prom_identify_arch(void);
+ extern PCHAR ArcGetEnvironmentVariable(PCHAR name);
+ extern LONG ArcSetEnvironmentVariable(PCHAR name, PCHAR value);
+
+-/* ARCS command line acquisition and parsing. */
+-extern char *prom_getcmdline(void);
++/* ARCS command line parsing. */
+ extern void prom_init_cmdline(void);
+
+ /* Acquiring info about the current time, etc. */
+diff --git a/arch/mips/include/asm/stackframe.h b/arch/mips/include/asm/stackframe.h
+index db0fa7b..7b2eff0 100644
+--- a/arch/mips/include/asm/stackframe.h
++++ b/arch/mips/include/asm/stackframe.h
+@@ -51,9 +51,6 @@
+ LONG_S v1, PT_ACX(sp)
+ #else
+ mfhi v1
+- LONG_S v1, PT_HI(sp)
+- mflo v1
+- LONG_S v1, PT_LO(sp)
+ #endif
+ #ifdef CONFIG_32BIT
+ LONG_S $8, PT_R8(sp)
+@@ -62,10 +59,17 @@
+ LONG_S $10, PT_R10(sp)
+ LONG_S $11, PT_R11(sp)
+ LONG_S $12, PT_R12(sp)
++#ifndef CONFIG_CPU_HAS_SMARTMIPS
++ LONG_S v1, PT_HI(sp)
++ mflo v1
++#endif
+ LONG_S $13, PT_R13(sp)
+ LONG_S $14, PT_R14(sp)
+ LONG_S $15, PT_R15(sp)
+ LONG_S $24, PT_R24(sp)
++#ifndef CONFIG_CPU_HAS_SMARTMIPS
++ LONG_S v1, PT_LO(sp)
++#endif
+ .endm
+
+ .macro SAVE_STATIC
+@@ -83,15 +87,19 @@
+ #ifdef CONFIG_SMP
+ #ifdef CONFIG_MIPS_MT_SMTC
+ #define PTEBASE_SHIFT 19 /* TCBIND */
++#define CPU_ID_REG CP0_TCBIND
++#define CPU_ID_MFC0 mfc0
++#elif defined(CONFIG_MIPS_PGD_C0_CONTEXT)
++#define PTEBASE_SHIFT 48 /* XCONTEXT */
++#define CPU_ID_REG CP0_XCONTEXT
++#define CPU_ID_MFC0 MFC0
+ #else
+ #define PTEBASE_SHIFT 23 /* CONTEXT */
++#define CPU_ID_REG CP0_CONTEXT
++#define CPU_ID_MFC0 MFC0
+ #endif
+ .macro get_saved_sp /* SMP variation */
+-#ifdef CONFIG_MIPS_MT_SMTC
+- mfc0 k0, CP0_TCBIND
+-#else
+- MFC0 k0, CP0_CONTEXT
+-#endif
++ CPU_ID_MFC0 k0, CPU_ID_REG
+ #if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
+ lui k1, %hi(kernelsp)
+ #else
+@@ -107,16 +115,31 @@
+ .endm
+
+ .macro set_saved_sp stackp temp temp2
+-#ifdef CONFIG_MIPS_MT_SMTC
+- mfc0 \temp, CP0_TCBIND
+-#else
+- MFC0 \temp, CP0_CONTEXT
+-#endif
++ CPU_ID_MFC0 \temp, CPU_ID_REG
+ LONG_SRL \temp, PTEBASE_SHIFT
+ LONG_S \stackp, kernelsp(\temp)
+ .endm
+ #else
+ .macro get_saved_sp /* Uniprocessor variation */
++ /*
++ * clear BTB(branch target buffer), forbid RAS(row address
++ * strobe) to make cpu execute predictively via
++ * loongson2-specific 64bit diagnostic register
++ */
++#ifdef CONFIG_CPU_LOONGSON2F
++ move k0, ra
++ jal 1f
++ nop
++1: jal 1f
++ nop
++1: jal 1f
++ nop
++1: jal 1f
++ nop
++1: move ra, k0
++ li k0, 3
++ mtc0 k0, $22
++#endif
+ #if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
+ lui k1, %hi(kernelsp)
+ #else
+@@ -166,7 +189,6 @@
+ LONG_S $0, PT_R0(sp)
+ mfc0 v1, CP0_STATUS
+ LONG_S $2, PT_R2(sp)
+- LONG_S v1, PT_STATUS(sp)
+ #ifdef CONFIG_MIPS_MT_SMTC
+ /*
+ * Ideally, these instructions would be shuffled in
+@@ -178,20 +200,21 @@
+ LONG_S v1, PT_TCSTATUS(sp)
+ #endif /* CONFIG_MIPS_MT_SMTC */
+ LONG_S $4, PT_R4(sp)
+- mfc0 v1, CP0_CAUSE
+ LONG_S $5, PT_R5(sp)
+- LONG_S v1, PT_CAUSE(sp)
++ LONG_S v1, PT_STATUS(sp)
++ mfc0 v1, CP0_CAUSE
+ LONG_S $6, PT_R6(sp)
+- MFC0 v1, CP0_EPC
+ LONG_S $7, PT_R7(sp)
++ LONG_S v1, PT_CAUSE(sp)
++ MFC0 v1, CP0_EPC
+ #ifdef CONFIG_64BIT
+ LONG_S $8, PT_R8(sp)
+ LONG_S $9, PT_R9(sp)
+ #endif
+- LONG_S v1, PT_EPC(sp)
+ LONG_S $25, PT_R25(sp)
+ LONG_S $28, PT_R28(sp)
+ LONG_S $31, PT_R31(sp)
++ LONG_S v1, PT_EPC(sp)
+ ori $28, sp, _THREAD_MASK
+ xori $28, _THREAD_MASK
+ #ifdef CONFIG_CPU_CAVIUM_OCTEON
+diff --git a/arch/mips/include/asm/time.h b/arch/mips/include/asm/time.h
+index df6a430..a697f7d 100644
+--- a/arch/mips/include/asm/time.h
++++ b/arch/mips/include/asm/time.h
+@@ -84,6 +84,21 @@ static inline int init_mips_clocksource(void)
+ #endif
+ }
+
++/*
++ * Setup the high resolution sched_clock()
++ */
++#ifdef CONFIG_HR_SCHED_CLOCK
++extern void setup_r4k_sched_clock(struct clocksource cs, unsigned int clock);
++#endif
++
++static inline void setup_hres_sched_clock(struct clocksource cs,
++ unsigned int clock)
++{
++#ifdef CONFIG_HR_SCHED_CLOCK
++ setup_r4k_sched_clock(cs, clock);
++#endif
++}
++
+ extern void clocksource_set_clock(struct clocksource *cs, unsigned int clock);
+ extern void clockevent_set_clock(struct clock_event_device *cd,
+ unsigned int clock);
+diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
+index eecd2a9..a6e06c0 100644
+--- a/arch/mips/kernel/Makefile
++++ b/arch/mips/kernel/Makefile
+@@ -2,14 +2,17 @@
+ # Makefile for the Linux/MIPS kernel.
+ #
+
+-CPPFLAGS_vmlinux.lds := $(KBUILD_CFLAGS)
+-
+ extra-y := head.o init_task.o vmlinux.lds
+
+ obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \
+ ptrace.o reset.o setup.o signal.o syscall.o \
+ time.o topology.o traps.o unaligned.o watch.o
+
++ifdef CONFIG_FUNCTION_TRACER
++CFLAGS_REMOVE_ftrace.o = -pg
++CFLAGS_REMOVE_early_printk.o = -pg
++endif
++
+ obj-$(CONFIG_CEVT_BCM1480) += cevt-bcm1480.o
+ obj-$(CONFIG_CEVT_R4K_LIB) += cevt-r4k.o
+ obj-$(CONFIG_MIPS_MT_SMTC) += cevt-smtc.o
+@@ -19,13 +22,17 @@ obj-$(CONFIG_CEVT_SB1250) += cevt-sb1250.o
+ obj-$(CONFIG_CEVT_TXX9) += cevt-txx9.o
+ obj-$(CONFIG_CSRC_BCM1480) += csrc-bcm1480.o
+ obj-$(CONFIG_CSRC_IOASIC) += csrc-ioasic.o
++obj-$(CONFIG_CSRC_POWERTV) += csrc-powertv.o
+ obj-$(CONFIG_CSRC_R4K_LIB) += csrc-r4k.o
++obj-$(CONFIG_HR_SCHED_CLOCK) += csrc-r4k-hres.o
+ obj-$(CONFIG_CSRC_SB1250) += csrc-sb1250.o
+ obj-$(CONFIG_SYNC_R4K) += sync-r4k.o
+
+ obj-$(CONFIG_STACKTRACE) += stacktrace.o
+ obj-$(CONFIG_MODULES) += mips_ksyms.o module.o
+
++obj-$(CONFIG_FUNCTION_TRACER) += mcount.o ftrace.o
++
+ obj-$(CONFIG_CPU_LOONGSON2) += r4k_fpu.o r4k_switch.o
+ obj-$(CONFIG_CPU_MIPS32) += r4k_fpu.o r4k_switch.o
+ obj-$(CONFIG_CPU_MIPS64) += r4k_fpu.o r4k_switch.o
+@@ -92,4 +99,8 @@ CFLAGS_cpu-bugs64.o = $(shell if $(CC) $(KBUILD_CFLAGS) -Wa,-mdaddi -c -o /dev/n
+
+ obj-$(CONFIG_HAVE_STD_PC_SERIAL_PORT) += 8250-platform.o
+
++obj-$(CONFIG_MIPS_CPUFREQ) += cpufreq/
++
+ EXTRA_CFLAGS += -Werror
++
++CPPFLAGS_vmlinux.lds := $(KBUILD_CFLAGS)
+diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
+index 7a51866..80e202e 100644
+--- a/arch/mips/kernel/cpu-probe.c
++++ b/arch/mips/kernel/cpu-probe.c
+@@ -16,6 +16,7 @@
+ #include <linux/ptrace.h>
+ #include <linux/smp.h>
+ #include <linux/stddef.h>
++#include <linux/module.h>
+
+ #include <asm/bugs.h>
+ #include <asm/cpu.h>
+@@ -32,6 +33,7 @@
+ * the CPU very much.
+ */
+ void (*cpu_wait)(void);
++EXPORT_SYMBOL(cpu_wait);
+
+ static void r3081_wait(void)
+ {
+diff --git a/arch/mips/kernel/cpufreq/Kconfig b/arch/mips/kernel/cpufreq/Kconfig
+new file mode 100644
+index 0000000..58c601e
+--- /dev/null
++++ b/arch/mips/kernel/cpufreq/Kconfig
+@@ -0,0 +1,41 @@
++#
++# CPU Frequency scaling
++#
++
++config MIPS_EXTERNAL_TIMER
++ bool
++
++config MIPS_CPUFREQ
++ bool
++ default y
++ depends on CPU_SUPPORTS_CPUFREQ && MIPS_EXTERNAL_TIMER
++
++if MIPS_CPUFREQ
++
++menu "CPU Frequency scaling"
++
++source "drivers/cpufreq/Kconfig"
++
++if CPU_FREQ
++
++comment "CPUFreq processor drivers"
++
++config LOONGSON2_CPUFREQ
++ tristate "Loongson2 CPUFreq Driver"
++ select CPU_FREQ_TABLE
++ depends on MIPS_CPUFREQ
++ help
++ This option adds a CPUFreq driver for loongson processors which
++ support software configurable cpu frequency.
++
++ Loongson2F and it's successors support this feature.
++
++ For details, take a look at <file:Documentation/cpu-freq/>.
++
++ If in doubt, say N.
++
++endif # CPU_FREQ
++
++endmenu
++
++endif # MIPS_CPUFREQ
+diff --git a/arch/mips/kernel/cpufreq/Makefile b/arch/mips/kernel/cpufreq/Makefile
+new file mode 100644
+index 0000000..c3479a4
+--- /dev/null
++++ b/arch/mips/kernel/cpufreq/Makefile
+@@ -0,0 +1,5 @@
++#
++# Makefile for the Linux/MIPS cpufreq.
++#
++
++obj-$(CONFIG_LOONGSON2_CPUFREQ) += loongson2_cpufreq.o loongson2_clock.o
+diff --git a/arch/mips/kernel/cpufreq/loongson2_clock.c b/arch/mips/kernel/cpufreq/loongson2_clock.c
+new file mode 100644
+index 0000000..d7ca256
+--- /dev/null
++++ b/arch/mips/kernel/cpufreq/loongson2_clock.c
+@@ -0,0 +1,166 @@
++/*
++ * Copyright (C) 2006 - 2008 Lemote Inc. & Insititute of Computing Technology
++ * Author: Yanhua, yanh@lemote.com
++ *
++ * 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 <linux/cpufreq.h>
++#include <linux/platform_device.h>
++
++#include <asm/clock.h>
++
++#include <loongson.h>
++
++static LIST_HEAD(clock_list);
++static DEFINE_SPINLOCK(clock_lock);
++static DEFINE_MUTEX(clock_list_sem);
++
++/* Minimum CLK support */
++enum {
++ DC_ZERO, DC_25PT = 2, DC_37PT, DC_50PT, DC_62PT, DC_75PT,
++ DC_87PT, DC_DISABLE, DC_RESV
++};
++
++struct cpufreq_frequency_table loongson2_clockmod_table[] = {
++ {DC_RESV, CPUFREQ_ENTRY_INVALID},
++ {DC_ZERO, CPUFREQ_ENTRY_INVALID},
++ {DC_25PT, 0},
++ {DC_37PT, 0},
++ {DC_50PT, 0},
++ {DC_62PT, 0},
++ {DC_75PT, 0},
++ {DC_87PT, 0},
++ {DC_DISABLE, 0},
++ {DC_RESV, CPUFREQ_TABLE_END},
++};
++EXPORT_SYMBOL_GPL(loongson2_clockmod_table);
++
++static struct clk cpu_clk = {
++ .name = "cpu_clk",
++ .flags = CLK_ALWAYS_ENABLED | CLK_RATE_PROPAGATES,
++ .rate = 800000000,
++};
++
++struct clk *clk_get(struct device *dev, const char *id)
++{
++ return &cpu_clk;
++}
++EXPORT_SYMBOL(clk_get);
++
++static void propagate_rate(struct clk *clk)
++{
++ struct clk *clkp;
++
++ list_for_each_entry(clkp, &clock_list, node) {
++ if (likely(clkp->parent != clk))
++ continue;
++ if (likely(clkp->ops && clkp->ops->recalc))
++ clkp->ops->recalc(clkp);
++ if (unlikely(clkp->flags & CLK_RATE_PROPAGATES))
++ propagate_rate(clkp);
++ }
++}
++
++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 (unsigned long)clk->rate;
++}
++EXPORT_SYMBOL(clk_get_rate);
++
++void clk_put(struct clk *clk)
++{
++}
++EXPORT_SYMBOL(clk_put);
++
++int clk_set_rate(struct clk *clk, unsigned long rate)
++{
++ return clk_set_rate_ex(clk, rate, 0);
++}
++EXPORT_SYMBOL_GPL(clk_set_rate);
++
++int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id)
++{
++ int ret = 0;
++ int regval;
++ int i;
++
++ if (likely(clk->ops && clk->ops->set_rate)) {
++ unsigned long flags;
++
++ spin_lock_irqsave(&clock_lock, flags);
++ ret = clk->ops->set_rate(clk, rate, algo_id);
++ spin_unlock_irqrestore(&clock_lock, flags);
++ }
++
++ if (unlikely(clk->flags & CLK_RATE_PROPAGATES))
++ propagate_rate(clk);
++
++ for (i = 0; loongson2_clockmod_table[i].frequency != CPUFREQ_TABLE_END;
++ i++) {
++ if (loongson2_clockmod_table[i].frequency ==
++ CPUFREQ_ENTRY_INVALID)
++ continue;
++ if (rate == loongson2_clockmod_table[i].frequency)
++ break;
++ }
++ if (rate != loongson2_clockmod_table[i].frequency)
++ return -ENOTSUPP;
++
++ clk->rate = rate;
++
++ regval = LOONGSON_CHIPCFG0;
++ regval = (regval & ~0x7) | (loongson2_clockmod_table[i].index - 1);
++ LOONGSON_CHIPCFG0 = regval;
++
++ return ret;
++}
++EXPORT_SYMBOL_GPL(clk_set_rate_ex);
++
++long clk_round_rate(struct clk *clk, unsigned long rate)
++{
++ if (likely(clk->ops && clk->ops->round_rate)) {
++ unsigned long flags, rounded;
++
++ spin_lock_irqsave(&clock_lock, flags);
++ rounded = clk->ops->round_rate(clk, rate);
++ spin_unlock_irqrestore(&clock_lock, flags);
++
++ return rounded;
++ }
++
++ return rate;
++}
++EXPORT_SYMBOL_GPL(clk_round_rate);
++
++/*
++ * This is the simple version of Loongson-2 wait, Maybe we need do this in
++ * interrupt disabled content
++ */
++
++DEFINE_SPINLOCK(loongson2_wait_lock);
++void loongson2_cpu_wait(void)
++{
++ u32 cpu_freq;
++ unsigned long flags;
++
++ spin_lock_irqsave(&loongson2_wait_lock, flags);
++ cpu_freq = LOONGSON_CHIPCFG0;
++ LOONGSON_CHIPCFG0 &= ~0x7; /* Put CPU into wait mode */
++ LOONGSON_CHIPCFG0 = cpu_freq; /* Restore CPU state */
++ spin_unlock_irqrestore(&loongson2_wait_lock, flags);
++}
++EXPORT_SYMBOL_GPL(loongson2_cpu_wait);
+diff --git a/arch/mips/kernel/cpufreq/loongson2_cpufreq.c b/arch/mips/kernel/cpufreq/loongson2_cpufreq.c
+new file mode 100644
+index 0000000..2f6a0b1
+--- /dev/null
++++ b/arch/mips/kernel/cpufreq/loongson2_cpufreq.c
+@@ -0,0 +1,227 @@
++/*
++ * Cpufreq driver for the loongson-2 processors
++ *
++ * The 2E revision of loongson processor not support this feature.
++ *
++ * Copyright (C) 2006 - 2008 Lemote Inc. & Insititute of Computing Technology
++ * Author: Yanhua, yanh@lemote.com
++ *
++ * 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 <linux/cpufreq.h>
++#include <linux/module.h>
++#include <linux/err.h>
++#include <linux/sched.h> /* set_cpus_allowed() */
++#include <linux/delay.h>
++#include <linux/platform_device.h>
++
++#include <asm/clock.h>
++
++#include <loongson.h>
++
++static uint nowait;
++
++static struct clk *cpuclk;
++
++static void (*saved_cpu_wait) (void);
++
++static int loongson2_cpu_freq_notifier(struct notifier_block *nb,
++ unsigned long val, void *data);
++
++static struct notifier_block loongson2_cpufreq_notifier_block = {
++ .notifier_call = loongson2_cpu_freq_notifier
++};
++
++static int loongson2_cpu_freq_notifier(struct notifier_block *nb,
++ unsigned long val, void *data)
++{
++ if (val == CPUFREQ_POSTCHANGE)
++ current_cpu_data.udelay_val = loops_per_jiffy;
++
++ return 0;
++}
++
++static unsigned int loongson2_cpufreq_get(unsigned int cpu)
++{
++ return clk_get_rate(cpuclk);
++}
++
++/*
++ * Here we notify other drivers of the proposed change and the final change.
++ */
++static int loongson2_cpufreq_target(struct cpufreq_policy *policy,
++ unsigned int target_freq,
++ unsigned int relation)
++{
++ unsigned int cpu = policy->cpu;
++ unsigned int newstate = 0;
++ cpumask_t cpus_allowed;
++ struct cpufreq_freqs freqs;
++ unsigned int freq;
++
++ if (!cpu_online(cpu))
++ return -ENODEV;
++
++ cpus_allowed = current->cpus_allowed;
++ set_cpus_allowed(current, cpumask_of_cpu(cpu));
++
++ if (cpufreq_frequency_table_target
++ (policy, &loongson2_clockmod_table[0], target_freq, relation,
++ &newstate))
++ return -EINVAL;
++
++ freq =
++ ((cpu_clock_freq / 1000) *
++ loongson2_clockmod_table[newstate].index) / 8;
++ if (freq < policy->min || freq > policy->max)
++ return -EINVAL;
++
++ pr_debug("cpufreq: requested frequency %u Hz\n", target_freq * 1000);
++
++ freqs.cpu = cpu;
++ freqs.old = loongson2_cpufreq_get(cpu);
++ freqs.new = freq;
++ freqs.flags = 0;
++
++ if (freqs.new == freqs.old)
++ return 0;
++
++ /* notifiers */
++ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
++
++ set_cpus_allowed(current, cpus_allowed);
++
++ /* setting the cpu frequency */
++ clk_set_rate(cpuclk, freq);
++
++ /* notifiers */
++ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
++
++ pr_debug("cpufreq: set frequency %u kHz\n", freq);
++
++ return 0;
++}
++
++static int loongson2_cpufreq_cpu_init(struct cpufreq_policy *policy)
++{
++ int i;
++
++ if (!cpu_online(policy->cpu))
++ return -ENODEV;
++
++ cpuclk = clk_get(NULL, "cpu_clk");
++ if (IS_ERR(cpuclk)) {
++ printk(KERN_ERR "cpufreq: couldn't get CPU clk\n");
++ return PTR_ERR(cpuclk);
++ }
++
++ cpuclk->rate = cpu_clock_freq / 1000;
++ if (!cpuclk->rate)
++ return -EINVAL;
++
++ /* clock table init */
++ for (i = 2;
++ (loongson2_clockmod_table[i].frequency != CPUFREQ_TABLE_END);
++ i++)
++ loongson2_clockmod_table[i].frequency = (cpuclk->rate * i) / 8;
++
++ policy->cur = loongson2_cpufreq_get(policy->cpu);
++
++ cpufreq_frequency_table_get_attr(&loongson2_clockmod_table[0],
++ policy->cpu);
++
++ return cpufreq_frequency_table_cpuinfo(policy,
++ &loongson2_clockmod_table[0]);
++}
++
++static int loongson2_cpufreq_verify(struct cpufreq_policy *policy)
++{
++ return cpufreq_frequency_table_verify(policy,
++ &loongson2_clockmod_table[0]);
++}
++
++static int loongson2_cpufreq_exit(struct cpufreq_policy *policy)
++{
++ clk_put(cpuclk);
++ return 0;
++}
++
++static struct freq_attr *loongson2_table_attr[] = {
++ &cpufreq_freq_attr_scaling_available_freqs,
++ NULL,
++};
++
++static struct cpufreq_driver loongson2_cpufreq_driver = {
++ .owner = THIS_MODULE,
++ .name = "loongson2",
++ .init = loongson2_cpufreq_cpu_init,
++ .verify = loongson2_cpufreq_verify,
++ .target = loongson2_cpufreq_target,
++ .get = loongson2_cpufreq_get,
++ .exit = loongson2_cpufreq_exit,
++ .attr = loongson2_table_attr,
++};
++
++static struct platform_device_id platform_device_ids[] = {
++ {
++ .name = "loongson2_cpufreq",
++ },
++ {}
++};
++
++MODULE_DEVICE_TABLE(platform, platform_device_ids);
++
++static struct platform_driver platform_driver = {
++ .driver = {
++ .name = "loongson2_cpufreq",
++ .owner = THIS_MODULE,
++ },
++ .id_table = platform_device_ids,
++};
++
++static int __init cpufreq_init(void)
++{
++ int ret;
++
++ /* Register platform stuff */
++ ret = platform_driver_register(&platform_driver);
++ if (ret)
++ return ret;
++
++ pr_info("cpufreq: Loongson-2F CPU frequency driver.\n");
++
++ cpufreq_register_notifier(&loongson2_cpufreq_notifier_block,
++ CPUFREQ_TRANSITION_NOTIFIER);
++
++ ret = cpufreq_register_driver(&loongson2_cpufreq_driver);
++
++ if (!ret && !nowait) {
++ saved_cpu_wait = cpu_wait;
++ cpu_wait = loongson2_cpu_wait;
++ }
++
++ return ret;
++}
++
++static void __exit cpufreq_exit(void)
++{
++ if (!nowait && saved_cpu_wait)
++ cpu_wait = saved_cpu_wait;
++ cpufreq_unregister_driver(&loongson2_cpufreq_driver);
++ cpufreq_unregister_notifier(&loongson2_cpufreq_notifier_block,
++ CPUFREQ_TRANSITION_NOTIFIER);
++
++ platform_driver_unregister(&platform_driver);
++}
++
++module_init(cpufreq_init);
++module_exit(cpufreq_exit);
++
++module_param(nowait, uint, 0644);
++MODULE_PARM_DESC(nowait, "Disable Loongson-2F specific wait");
++
++MODULE_AUTHOR("Yanhua <yanh@lemote.com>");
++MODULE_DESCRIPTION("cpufreq driver for Loongson2F");
++MODULE_LICENSE("GPL");
+diff --git a/arch/mips/kernel/csrc-powertv.c b/arch/mips/kernel/csrc-powertv.c
+new file mode 100644
+index 0000000..a27c16c
+--- /dev/null
++++ b/arch/mips/kernel/csrc-powertv.c
+@@ -0,0 +1,180 @@
++/*
++ * Copyright (C) 2008 Scientific-Atlanta, Inc.
++ *
++ * 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 file comes from kernel/csrc-r4k.c
++ */
++#include <linux/clocksource.h>
++#include <linux/init.h>
++
++#include <asm/time.h> /* Not included in linux/time.h */
++
++#include <asm/mach-powertv/asic_regs.h>
++#include "powertv-clock.h"
++
++/* MIPS PLL Register Definitions */
++#define PLL_GET_M(x) (((x) >> 8) & 0x000000FF)
++#define PLL_GET_N(x) (((x) >> 16) & 0x000000FF)
++#define PLL_GET_P(x) (((x) >> 24) & 0x00000007)
++
++/*
++ * returns: Clock frequency in kHz
++ */
++unsigned int __init mips_get_pll_freq(void)
++{
++ unsigned int pll_reg, m, n, p;
++ unsigned int fin = 54000; /* Base frequency in kHz */
++ unsigned int fout;
++
++ /* Read PLL register setting */
++ pll_reg = asic_read(mips_pll_setup);
++ m = PLL_GET_M(pll_reg);
++ n = PLL_GET_N(pll_reg);
++ p = PLL_GET_P(pll_reg);
++ pr_info("MIPS PLL Register:0x%x M=%d N=%d P=%d\n", pll_reg, m, n, p);
++
++ /* Calculate clock frequency = (2 * N * 54MHz) / (M * (2**P)) */
++ fout = ((2 * n * fin) / (m * (0x01 << p)));
++
++ pr_info("MIPS Clock Freq=%d kHz\n", fout);
++
++ return fout;
++}
++
++static cycle_t c0_hpt_read(struct clocksource *cs)
++{
++ return read_c0_count();
++}
++
++static struct clocksource clocksource_mips = {
++ .name = "powertv-counter",
++ .read = c0_hpt_read,
++ .mask = CLOCKSOURCE_MASK(32),
++ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
++};
++
++static void __init powertv_c0_hpt_clocksource_init(void)
++{
++ unsigned int pll_freq = mips_get_pll_freq();
++
++ pr_info("CPU frequency %d.%02d MHz\n", pll_freq / 1000,
++ (pll_freq % 1000) * 100 / 1000);
++
++ mips_hpt_frequency = pll_freq / 2 * 1000;
++
++ clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000;
++
++ clocksource_set_clock(&clocksource_mips, mips_hpt_frequency);
++
++ clocksource_register(&clocksource_mips);
++}
++
++/**
++ * struct tim_c - free running counter
++ * @hi: High 16 bits of the counter
++ * @lo: Low 32 bits of the counter
++ *
++ * Lays out the structure of the free running counter in memory. This counter
++ * increments at a rate of 27 MHz/8 on all platforms.
++ */
++struct tim_c {
++ unsigned int hi;
++ unsigned int lo;
++};
++
++static struct tim_c *tim_c;
++
++static cycle_t tim_c_read(struct clocksource *cs)
++{
++ unsigned int hi;
++ unsigned int next_hi;
++ unsigned int lo;
++
++ hi = readl(&tim_c->hi);
++
++ for (;;) {
++ lo = readl(&tim_c->lo);
++ next_hi = readl(&tim_c->hi);
++ if (next_hi == hi)
++ break;
++ hi = next_hi;
++ }
++
++pr_crit("%s: read %llx\n", __func__, ((u64) hi << 32) | lo);
++ return ((u64) hi << 32) | lo;
++}
++
++#define TIM_C_SIZE 48 /* # bits in the timer */
++
++static struct clocksource clocksource_tim_c = {
++ .name = "powertv-tim_c",
++ .read = tim_c_read,
++ .mask = CLOCKSOURCE_MASK(TIM_C_SIZE),
++ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
++};
++
++/**
++ * powertv_tim_c_clocksource_init - set up a clock source for the TIM_C clock
++ *
++ * The hard part here is coming up with a constant k and shift s such that
++ * the 48-bit TIM_C value multiplied by k doesn't overflow and that value,
++ * when shifted right by s, yields the corresponding number of nanoseconds.
++ * We know that TIM_C counts at 27 MHz/8, so each cycle corresponds to
++ * 1 / (27,000,000/8) seconds. Multiply that by a billion and you get the
++ * number of nanoseconds. Since the TIM_C value has 48 bits and the math is
++ * done in 64 bits, avoiding an overflow means that k must be less than
++ * 64 - 48 = 16 bits.
++ */
++static void __init powertv_tim_c_clocksource_init(void)
++{
++ int prescale;
++ unsigned long dividend;
++ unsigned long k;
++ int s;
++ const int max_k_bits = (64 - 48) - 1;
++ const unsigned long billion = 1000000000;
++ const unsigned long counts_per_second = 27000000 / 8;
++
++ prescale = BITS_PER_LONG - ilog2(billion) - 1;
++ dividend = billion << prescale;
++ k = dividend / counts_per_second;
++ s = ilog2(k) - max_k_bits;
++
++ if (s < 0)
++ s = prescale;
++
++ else {
++ k >>= s;
++ s += prescale;
++ }
++
++ clocksource_tim_c.mult = k;
++ clocksource_tim_c.shift = s;
++ clocksource_tim_c.rating = 200;
++
++ clocksource_register(&clocksource_tim_c);
++ tim_c = (struct tim_c *) asic_reg_addr(tim_ch);
++}
++
++/**
++ powertv_clocksource_init - initialize all clocksources
++ */
++void __init powertv_clocksource_init(void)
++{
++ powertv_c0_hpt_clocksource_init();
++ powertv_tim_c_clocksource_init();
++}
+diff --git a/arch/mips/kernel/csrc-r4k-hres.c b/arch/mips/kernel/csrc-r4k-hres.c
+new file mode 100644
+index 0000000..2fe8be7
+--- /dev/null
++++ b/arch/mips/kernel/csrc-r4k-hres.c
+@@ -0,0 +1,54 @@
++/*
++ * MIPS sched_clock implementation.
++ *
++ * Copyright (C) 2009 Lemote Inc.
++ * Author: Wu Zhangjin, wuzj@lemote.com
++ *
++ * because cnt32_to_63() needs to be called at least once per half period to
++ * work properly, and some of the MIPS frequency is high, perhaps a kernel
++ * timer is needed to be set up to ensure this requirement is always met.
++ * Please refer to arch/arm/plat-orion/time.c and include/linux/cnt32_to_63.h
++ */
++
++#include <linux/clocksource.h>
++#include <linux/cnt32_to_63.h>
++#include <linux/init.h>
++#include <linux/timer.h>
++
++static unsigned long __read_mostly cycle2ns_scale;
++static unsigned long __read_mostly cycle2ns_scale_factor;
++
++unsigned long long notrace sched_clock(void)
++{
++ unsigned long long v = cnt32_to_63(read_c0_count());
++ return (v * cycle2ns_scale) >> cycle2ns_scale_factor;
++}
++
++static struct timer_list cnt32_to_63_keepwarm_timer;
++
++static void cnt32_to_63_keepwarm(unsigned long data)
++{
++ mod_timer(&cnt32_to_63_keepwarm_timer, round_jiffies(jiffies + data));
++ sched_clock();
++}
++
++void setup_r4k_sched_clock(struct clocksource cs, unsigned int clock)
++{
++ unsigned long long v;
++ unsigned long data;
++
++ v = cs.mult;
++ /*
++ * We want an even value to automatically clear the top bit
++ * returned by cnt32_to_63() without an additional run time
++ * instruction. So if the LSB is 1 then round it up.
++ */
++ if (v & 1)
++ v++;
++ cycle2ns_scale = v;
++ cycle2ns_scale_factor = cs.shift;
++
++ data = 0x80000000 / clock * HZ;
++ setup_timer(&cnt32_to_63_keepwarm_timer, cnt32_to_63_keepwarm, data);
++ mod_timer(&cnt32_to_63_keepwarm_timer, round_jiffies(jiffies + data));
++}
+diff --git a/arch/mips/kernel/csrc-r4k.c b/arch/mips/kernel/csrc-r4k.c
+index e95a3cd..3bd89bb 100644
+--- a/arch/mips/kernel/csrc-r4k.c
++++ b/arch/mips/kernel/csrc-r4k.c
+@@ -32,6 +32,8 @@ int __init init_r4k_clocksource(void)
+
+ clocksource_set_clock(&clocksource_mips, mips_hpt_frequency);
+
++ setup_hres_sched_clock(clocksource_mips, mips_hpt_frequency);
++
+ clocksource_register(&clocksource_mips);
+
+ return 0;
+diff --git a/arch/mips/kernel/ftrace.c b/arch/mips/kernel/ftrace.c
+new file mode 100644
+index 0000000..68b0670
+--- /dev/null
++++ b/arch/mips/kernel/ftrace.c
+@@ -0,0 +1,275 @@
++/*
++ * Code for replacing ftrace calls with jumps.
++ *
++ * Copyright (C) 2007-2008 Steven Rostedt <srostedt@redhat.com>
++ * Copyright (C) 2009 DSLab, Lanzhou University, China
++ * Author: Wu Zhangjin <wuzj@lemote.com>
++ *
++ * Thanks goes to Steven Rostedt for writing the original x86 version.
++ */
++
++#include <linux/uaccess.h>
++#include <linux/init.h>
++#include <linux/ftrace.h>
++
++#include <asm/cacheflush.h>
++#include <asm/asm.h>
++#include <asm/asm-offsets.h>
++
++#ifdef CONFIG_DYNAMIC_FTRACE
++
++#define JAL 0x0c000000 /* jump & link: ip --> ra, jump to target */
++#define ADDR_MASK 0x03ffffff /* op_code|addr : 31...26|25 ....0 */
++#define jump_insn_encode(op_code, addr) \
++ ((unsigned int)((op_code) | (((addr) >> 2) & ADDR_MASK)))
++
++static unsigned int ftrace_nop = 0x00000000;
++
++static int ftrace_modify_code(unsigned long ip, unsigned int new_code)
++{
++ int faulted;
++
++ /* *(unsigned int *)ip = new_code; */
++ safe_store_code(new_code, ip, faulted);
++
++ if (unlikely(faulted))
++ return -EFAULT;
++
++ flush_icache_range(ip, ip + 8);
++
++ return 0;
++}
++
++static int lui_v1;
++static int jal_mcount;
++
++int ftrace_make_nop(struct module *mod,
++ struct dyn_ftrace *rec, unsigned long addr)
++{
++ unsigned int new;
++ int faulted;
++ unsigned long ip = rec->ip;
++
++ /* We have compiled module with -mlong-calls, but compiled the kernel
++ * without it, we need to cope with them respectively. */
++ if (ip & 0x40000000) {
++ /* record it for ftrace_make_call */
++ if (lui_v1 == 0) {
++ /* lui_v1 = *(unsigned int *)ip; */
++ safe_load_code(lui_v1, ip, faulted);
++
++ if (unlikely(faulted))
++ return -EFAULT;
++ }
++
++ /* lui v1, hi_16bit_of_mcount --> b 1f (0x10000004)
++ * addiu v1, v1, low_16bit_of_mcount
++ * move at, ra
++ * jalr v1
++ * nop
++ * 1f: (ip + 12)
++ */
++ new = 0x10000004;
++ } else {
++ /* record/calculate it for ftrace_make_call */
++ if (jal_mcount == 0) {
++ /* We can record it directly like this:
++ * jal_mcount = *(unsigned int *)ip;
++ * Herein, jump over the first two nop instructions */
++ jal_mcount = jump_insn_encode(JAL, (MCOUNT_ADDR + 8));
++ }
++
++ /* move at, ra
++ * jalr v1 --> nop
++ */
++ new = ftrace_nop;
++ }
++ return ftrace_modify_code(ip, new);
++}
++
++static int modified; /* initialized as 0 by default */
++
++int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
++{
++ unsigned int new;
++ unsigned long ip = rec->ip;
++
++ /* We just need to remove the "b ftrace_stub" at the fist time! */
++ if (modified == 0) {
++ modified = 1;
++ ftrace_modify_code(addr, ftrace_nop);
++ }
++ /* ip, module: 0xc0000000, kernel: 0x80000000 */
++ new = (ip & 0x40000000) ? lui_v1 : jal_mcount;
++
++ return ftrace_modify_code(ip, new);
++}
++
++#define FTRACE_CALL_IP ((unsigned long)(&ftrace_call))
++
++int ftrace_update_ftrace_func(ftrace_func_t func)
++{
++ unsigned int new;
++
++ new = jump_insn_encode(JAL, (unsigned long)func);
++
++ return ftrace_modify_code(FTRACE_CALL_IP, new);
++}
++
++int __init ftrace_dyn_arch_init(void *data)
++{
++ /* The return code is retured via data */
++ *(unsigned long *)data = 0;
++
++ return 0;
++}
++#endif /* CONFIG_DYNAMIC_FTRACE */
++
++#ifdef CONFIG_FUNCTION_GRAPH_TRACER
++
++#ifdef CONFIG_DYNAMIC_FTRACE
++
++extern void ftrace_graph_call(void);
++#define JMP 0x08000000 /* jump to target directly */
++#define CALL_FTRACE_GRAPH_CALLER \
++ jump_insn_encode(JMP, (unsigned long)(&ftrace_graph_caller))
++#define FTRACE_GRAPH_CALL_IP ((unsigned long)(&ftrace_graph_call))
++
++int ftrace_enable_ftrace_graph_caller(void)
++{
++ return ftrace_modify_code(FTRACE_GRAPH_CALL_IP,
++ CALL_FTRACE_GRAPH_CALLER);
++}
++
++int ftrace_disable_ftrace_graph_caller(void)
++{
++ return ftrace_modify_code(FTRACE_GRAPH_CALL_IP, ftrace_nop);
++}
++
++#endif /* !CONFIG_DYNAMIC_FTRACE */
++
++#ifndef KBUILD_MCOUNT_RA_ADDRESS
++#define S_RA_SP (0xafbf << 16) /* s{d,w} ra, offset(sp) */
++#define S_R_SP (0xafb0 << 16) /* s{d,w} R, offset(sp) */
++#define OFFSET_MASK 0xffff /* stack offset range: 0 ~ PT_SIZE */
++
++unsigned long ftrace_get_parent_addr(unsigned long self_addr,
++ unsigned long parent,
++ unsigned long parent_addr,
++ unsigned long fp)
++{
++ unsigned long sp, ip, ra;
++ unsigned int code;
++ int faulted;
++
++ /* in module or kernel? */
++ if (self_addr & 0x40000000) {
++ /* module: move to the instruction "lui v1, HI_16BIT_OF_MCOUNT" */
++ ip = self_addr - 20;
++ } else {
++ /* kernel: move to the instruction "move ra, at" */
++ ip = self_addr - 12;
++ }
++
++ /* search the text until finding the non-store instruction or "s{d,w}
++ * ra, offset(sp)" instruction */
++ do {
++ ip -= 4;
++
++ /* get the code at "ip": code = *(unsigned int *)ip; */
++ safe_load_code(code, ip, faulted);
++
++ if (unlikely(faulted))
++ return 0;
++
++ /* If we hit the non-store instruction before finding where the
++ * ra is stored, then this is a leaf function and it does not
++ * store the ra on the stack. */
++ if ((code & S_R_SP) != S_R_SP)
++ return parent_addr;
++
++ } while (((code & S_RA_SP) != S_RA_SP));
++
++ sp = fp + (code & OFFSET_MASK);
++
++ /* ra = *(unsigned long *)sp; */
++ safe_load_stack(ra, sp, faulted);
++ if (unlikely(faulted))
++ return 0;
++
++ if (ra == parent)
++ return sp;
++ return 0;
++}
++
++#endif
++
++/*
++ * Hook the return address and push it in the stack of return addrs
++ * in current thread info.
++ */
++void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
++ unsigned long fp)
++{
++ unsigned long old;
++ struct ftrace_graph_ent trace;
++ unsigned long return_hooker = (unsigned long)
++ &return_to_handler;
++ int faulted;
++
++ if (unlikely(atomic_read(&current->tracing_graph_pause)))
++ return;
++
++ /* "parent" is the stack address saved the return address of the caller
++ * of _mcount.
++ *
++ * if the gcc < 4.5, a leaf function does not save the return address
++ * in the stack address, so, we "emulate" one in _mcount's stack space,
++ * and hijack it directly, but for a non-leaf function, it save the
++ * return address to the its own stack space, we can not hijack it
++ * directly, but need to find the real stack address,
++ * ftrace_get_parent_addr() does it!
++ *
++ * if gcc>= 4.5, with the new -mmcount-ra-address option, for a
++ * non-leaf function, the location of the return address will be saved
++ * to $12 for us, and for a leaf function, only put a zero into $12. we
++ * do it in ftrace_graph_caller of mcount.S.
++ */
++
++ /* old = *parent; */
++ safe_load_stack(old, parent, faulted);
++ if (unlikely(faulted))
++ goto out;
++#ifndef KBUILD_MCOUNT_RA_ADDRESS
++ parent = (unsigned long *)ftrace_get_parent_addr(self_addr, old,
++ (unsigned long)parent,
++ fp);
++ /* If fails when getting the stack address of the non-leaf function's
++ * ra, stop function graph tracer and return */
++ if (parent == 0)
++ goto out;
++#endif
++ /* *parent = return_hooker; */
++ safe_store_stack(return_hooker, parent, faulted);
++ if (unlikely(faulted))
++ goto out;
++
++ if (ftrace_push_return_trace(old, self_addr, &trace.depth, fp) ==
++ -EBUSY) {
++ *parent = old;
++ return;
++ }
++
++ trace.func = self_addr;
++
++ /* Only trace if the calling function expects to */
++ if (!ftrace_graph_entry(&trace)) {
++ current->curr_ret_stack--;
++ *parent = old;
++ }
++ return;
++out:
++ ftrace_graph_stop();
++ WARN_ON(1);
++}
++#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c
+index 7b845ba..dee8d5f 100644
+--- a/arch/mips/kernel/irq.c
++++ b/arch/mips/kernel/irq.c
+@@ -22,6 +22,7 @@
+ #include <linux/seq_file.h>
+ #include <linux/kallsyms.h>
+ #include <linux/kgdb.h>
++#include <linux/ftrace.h>
+
+ #include <asm/atomic.h>
+ #include <asm/system.h>
+@@ -150,3 +151,32 @@ void __init init_IRQ(void)
+ kgdb_early_setup = 1;
+ #endif
+ }
++
++/*
++ * do_IRQ handles all normal device IRQ's (the special
++ * SMP cross-CPU interrupts have their own specific
++ * handlers).
++ */
++void __irq_entry do_IRQ(unsigned int irq)
++{
++ irq_enter();
++ __DO_IRQ_SMTC_HOOK(irq);
++ generic_handle_irq(irq);
++ irq_exit();
++}
++
++#ifdef CONFIG_MIPS_MT_SMTC_IRQAFF
++/*
++ * To avoid inefficient and in some cases pathological re-checking of
++ * IRQ affinity, we have this variant that skips the affinity check.
++ */
++
++void __irq_entry do_IRQ_no_affinity(unsigned int irq)
++{
++ irq_enter();
++ __NO_AFFINITY_IRQ_SMTC_HOOK(irq);
++ generic_handle_irq(irq);
++ irq_exit();
++}
++
++#endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */
+diff --git a/arch/mips/kernel/mcount.S b/arch/mips/kernel/mcount.S
+new file mode 100644
+index 0000000..0a9cfdb
+--- /dev/null
++++ b/arch/mips/kernel/mcount.S
+@@ -0,0 +1,189 @@
++/*
++ * MIPS specific _mcount support
++ *
++ * 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) 2009 Lemote Inc. & DSLab, Lanzhou University, China
++ * Author: Wu Zhangjin <wuzj@lemote.com>
++ */
++
++#include <asm/regdef.h>
++#include <asm/stackframe.h>
++#include <asm/ftrace.h>
++
++ .text
++ .set noreorder
++ .set noat
++
++ .macro MCOUNT_SAVE_REGS
++ PTR_SUBU sp, PT_SIZE
++ PTR_S ra, PT_R31(sp)
++ PTR_S AT, PT_R1(sp)
++ PTR_S a0, PT_R4(sp)
++ PTR_S a1, PT_R5(sp)
++ PTR_S a2, PT_R6(sp)
++ PTR_S a3, PT_R7(sp)
++#ifdef CONFIG_64BIT
++ PTR_S a4, PT_R8(sp)
++ PTR_S a5, PT_R9(sp)
++ PTR_S a6, PT_R10(sp)
++ PTR_S a7, PT_R11(sp)
++#endif
++ .endm
++
++ .macro MCOUNT_RESTORE_REGS
++ PTR_L ra, PT_R31(sp)
++ PTR_L AT, PT_R1(sp)
++ PTR_L a0, PT_R4(sp)
++ PTR_L a1, PT_R5(sp)
++ PTR_L a2, PT_R6(sp)
++ PTR_L a3, PT_R7(sp)
++#ifdef CONFIG_64BIT
++ PTR_L a4, PT_R8(sp)
++ PTR_L a5, PT_R9(sp)
++ PTR_L a6, PT_R10(sp)
++ PTR_L a7, PT_R11(sp)
++#endif
++#ifdef CONFIG_64BIT
++ PTR_ADDIU sp, PT_SIZE
++#else
++ PTR_ADDIU sp, (PT_SIZE + 8)
++#endif
++.endm
++
++ .macro RETURN_BACK
++ jr ra
++ move ra, AT
++ .endm
++
++#ifdef CONFIG_DYNAMIC_FTRACE
++
++NESTED(ftrace_caller, PT_SIZE, ra)
++ .globl _mcount
++_mcount:
++ b ftrace_stub
++ nop
++ lw t1, function_trace_stop
++ bnez t1, ftrace_stub
++ nop
++
++ MCOUNT_SAVE_REGS
++#ifdef KBUILD_MCOUNT_RA_ADDRESS
++ PTR_S t0, PT_R12(sp) /* t0 saved the location of the return address(at) by -mmcount-ra-address */
++#endif
++
++ move a0, ra /* arg1: next ip, selfaddr */
++ .globl ftrace_call
++ftrace_call:
++ nop /* a placeholder for the call to a real tracing function */
++ move a1, AT /* arg2: the caller's next ip, parent */
++
++#ifdef CONFIG_FUNCTION_GRAPH_TRACER
++ .globl ftrace_graph_call
++ftrace_graph_call:
++ nop
++ nop
++#endif
++
++ MCOUNT_RESTORE_REGS
++ .globl ftrace_stub
++ftrace_stub:
++ RETURN_BACK
++ END(ftrace_caller)
++
++#else /* ! CONFIG_DYNAMIC_FTRACE */
++
++NESTED(_mcount, PT_SIZE, ra)
++ lw t1, function_trace_stop
++ bnez t1, ftrace_stub
++ nop
++ PTR_LA t1, ftrace_stub
++ PTR_L t2, ftrace_trace_function /* Prepare t2 for (1) */
++ bne t1, t2, static_trace
++ nop
++
++#ifdef CONFIG_FUNCTION_GRAPH_TRACER
++ PTR_L t3, ftrace_graph_return
++ bne t1, t3, ftrace_graph_caller
++ nop
++ PTR_LA t1, ftrace_graph_entry_stub
++ PTR_L t3, ftrace_graph_entry
++ bne t1, t3, ftrace_graph_caller
++ nop
++#endif
++ b ftrace_stub
++ nop
++
++static_trace:
++ MCOUNT_SAVE_REGS
++
++ move a0, ra /* arg1: next ip, selfaddr */
++ jalr t2 /* (1) call *ftrace_trace_function */
++ move a1, AT /* arg2: the caller's next ip, parent */
++
++ MCOUNT_RESTORE_REGS
++ .globl ftrace_stub
++ftrace_stub:
++ RETURN_BACK
++ END(_mcount)
++
++#endif /* ! CONFIG_DYNAMIC_FTRACE */
++
++#ifdef CONFIG_FUNCTION_GRAPH_TRACER
++
++NESTED(ftrace_graph_caller, PT_SIZE, ra)
++#ifdef CONFIG_DYNAMIC_FTRACE
++ PTR_L a1, PT_R31(sp) /* load the original ra from the stack */
++#ifdef KBUILD_MCOUNT_RA_ADDRESS
++ PTR_L t0, PT_R12(sp) /* load the original t0 from the stack */
++#endif
++#else
++ MCOUNT_SAVE_REGS
++ move a1, ra /* arg2: next ip, selfaddr */
++#endif
++
++#ifdef KBUILD_MCOUNT_RA_ADDRESS
++ bnez t0, 1f /* non-leaf func: t0 saved the location of the return address */
++ nop
++ PTR_LA t0, PT_R1(sp) /* leaf func: get the location of at(old ra) from our own stack */
++1: move a0, t0 /* arg1: the location of the return address */
++#else
++ PTR_LA a0, PT_R1(sp) /* arg1: &AT -> a0 */
++#endif
++ jal prepare_ftrace_return
++#ifdef CONFIG_FRAME_POINTER
++ move a2, fp /* arg3: frame pointer */
++#else
++#ifdef CONFIG_64BIT
++ PTR_LA a2, PT_SIZE(sp)
++#else
++ PTR_LA a2, (PT_SIZE+8)(sp)
++#endif
++#endif
++
++ MCOUNT_RESTORE_REGS
++ RETURN_BACK
++ END(ftrace_graph_caller)
++
++ .align 2
++ .globl return_to_handler
++return_to_handler:
++ PTR_SUBU sp, PT_SIZE
++ PTR_S v0, PT_R2(sp)
++
++ jal ftrace_return_to_handler
++ PTR_S v1, PT_R3(sp)
++
++ /* restore the real parent address: v0 -> ra */
++ move ra, v0
++
++ PTR_L v0, PT_R2(sp)
++ PTR_L v1, PT_R3(sp)
++ jr ra
++ PTR_ADDIU sp, PT_SIZE
++#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
++
++ .set at
++ .set reorder
+diff --git a/arch/mips/kernel/mips_ksyms.c b/arch/mips/kernel/mips_ksyms.c
+index 225755d..1d04807 100644
+--- a/arch/mips/kernel/mips_ksyms.c
++++ b/arch/mips/kernel/mips_ksyms.c
+@@ -13,6 +13,7 @@
+ #include <asm/checksum.h>
+ #include <asm/pgtable.h>
+ #include <asm/uaccess.h>
++#include <asm/ftrace.h>
+
+ extern void *__bzero(void *__s, size_t __count);
+ extern long __strncpy_from_user_nocheck_asm(char *__to,
+@@ -51,3 +52,7 @@ EXPORT_SYMBOL(csum_partial_copy_nocheck);
+ EXPORT_SYMBOL(__csum_partial_copy_user);
+
+ EXPORT_SYMBOL(invalid_pte_table);
++#ifdef CONFIG_FUNCTION_TRACER
++/* _mcount is defined in arch/mips/kernel/mcount.S */
++EXPORT_SYMBOL(_mcount);
++#endif
+diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
+index 2b290d7..b1e1272 100644
+--- a/arch/mips/kernel/setup.c
++++ b/arch/mips/kernel/setup.c
+@@ -58,8 +58,9 @@ EXPORT_SYMBOL(mips_machtype);
+
+ struct boot_mem_map boot_mem_map;
+
+-static char command_line[CL_SIZE];
+- char arcs_cmdline[CL_SIZE]=CONFIG_CMDLINE;
++static char command_line[COMMAND_LINE_SIZE];
++ char arcs_cmdline[COMMAND_LINE_SIZE] = CONFIG_CMDLINE;
++EXPORT_SYMBOL(arcs_cmdline);
+
+ /*
+ * mips_io_port_base is the begin of the address space to which x86 style
+@@ -166,26 +167,8 @@ static unsigned long __init init_initrd(void)
+ * already set up initrd_start and initrd_end. In these cases
+ * perfom sanity checks and use them if all looks good.
+ */
+- if (!initrd_start || initrd_end <= initrd_start) {
+-#ifdef CONFIG_PROBE_INITRD_HEADER
+- u32 *initrd_header;
+-
+- /*
+- * See if initrd has been added to the kernel image by
+- * arch/mips/boot/addinitrd.c. In that case a header is
+- * prepended to initrd and is made up by 8 bytes. The first
+- * word is a magic number and the second one is the size of
+- * initrd. Initrd start must be page aligned in any cases.
+- */
+- initrd_header = __va(PAGE_ALIGN(__pa_symbol(&_end) + 8)) - 8;
+- if (initrd_header[0] != 0x494E5244)
+- goto disable;
+- initrd_start = (unsigned long)(initrd_header + 2);
+- initrd_end = initrd_start + initrd_header[1];
+-#else
++ if (!initrd_start || initrd_end <= initrd_start)
+ goto disable;
+-#endif
+- }
+
+ if (initrd_start & ~PAGE_MASK) {
+ pr_err("initrd start must be page aligned\n");
+diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
+index e72e684..6cdca19 100644
+--- a/arch/mips/kernel/smp.c
++++ b/arch/mips/kernel/smp.c
+@@ -32,6 +32,7 @@
+ #include <linux/cpumask.h>
+ #include <linux/cpu.h>
+ #include <linux/err.h>
++#include <linux/ftrace.h>
+
+ #include <asm/atomic.h>
+ #include <asm/cpu.h>
+@@ -130,7 +131,7 @@ asmlinkage __cpuinit void start_secondary(void)
+ /*
+ * Call into both interrupt handlers, as we share the IPI for them
+ */
+-void smp_call_function_interrupt(void)
++void __irq_entry smp_call_function_interrupt(void)
+ {
+ irq_enter();
+ generic_smp_call_function_single_interrupt();
+diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c
+index 24630fd..75034a8 100644
+--- a/arch/mips/kernel/smtc.c
++++ b/arch/mips/kernel/smtc.c
+@@ -25,6 +25,7 @@
+ #include <linux/interrupt.h>
+ #include <linux/kernel_stat.h>
+ #include <linux/module.h>
++#include <linux/ftrace.h>
+
+ #include <asm/cpu.h>
+ #include <asm/processor.h>
+@@ -939,23 +940,29 @@ static void ipi_call_interrupt(void)
+
+ DECLARE_PER_CPU(struct clock_event_device, mips_clockevent_device);
+
+-void ipi_decode(struct smtc_ipi *pipi)
++static void __irq_entry smtc_clock_tick_interrupt(void)
+ {
+ unsigned int cpu = smp_processor_id();
+ struct clock_event_device *cd;
++ int irq = MIPS_CPU_IRQ_BASE + 1;
++
++ irq_enter();
++ kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq));
++ cd = &per_cpu(mips_clockevent_device, cpu);
++ cd->event_handler(cd);
++ irq_exit();
++}
++
++void ipi_decode(struct smtc_ipi *pipi)
++{
+ void *arg_copy = pipi->arg;
+ int type_copy = pipi->type;
+- int irq = MIPS_CPU_IRQ_BASE + 1;
+
+ smtc_ipi_nq(&freeIPIq, pipi);
+
+ switch (type_copy) {
+ case SMTC_CLOCK_TICK:
+- irq_enter();
+- kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq));
+- cd = &per_cpu(mips_clockevent_device, cpu);
+- cd->event_handler(cd);
+- irq_exit();
++ smtc_clock_tick_interrupt();
+ break;
+
+ case LINUX_SMP_IPI:
+diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S
+index 162b299..f25df73 100644
+--- a/arch/mips/kernel/vmlinux.lds.S
++++ b/arch/mips/kernel/vmlinux.lds.S
+@@ -46,6 +46,7 @@ SECTIONS
+ SCHED_TEXT
+ LOCK_TEXT
+ KPROBES_TEXT
++ IRQENTRY_TEXT
+ *(.text.*)
+ *(.fixup)
+ *(.gnu.warning)
+diff --git a/arch/mips/lasat/prom.c b/arch/mips/lasat/prom.c
+index 6acc6cb..20fde19 100644
+--- a/arch/mips/lasat/prom.c
++++ b/arch/mips/lasat/prom.c
+@@ -100,8 +100,8 @@ void __init prom_init(void)
+
+ /* Get the command line */
+ if (argc > 0) {
+- strncpy(arcs_cmdline, argv[0], CL_SIZE-1);
+- arcs_cmdline[CL_SIZE-1] = '\0';
++ strncpy(arcs_cmdline, argv[0], COMMAND_LINE_SIZE-1);
++ arcs_cmdline[COMMAND_LINE_SIZE-1] = '\0';
+ }
+
+ /* Set the I/O base address */
+diff --git a/arch/mips/loongson/Kconfig b/arch/mips/loongson/Kconfig
+index d450925..340ba03 100644
+--- a/arch/mips/loongson/Kconfig
++++ b/arch/mips/loongson/Kconfig
+@@ -1,31 +1,138 @@
+ choice
+- prompt "Machine Type"
+- depends on MACH_LOONGSON
++ prompt "Machine Type"
++ depends on MACH_LOONGSON
+
+ config LEMOTE_FULOONG2E
+- bool "Lemote Fuloong(2e) mini-PC"
+- select ARCH_SPARSEMEM_ENABLE
+- select CEVT_R4K
+- select CSRC_R4K
+- select SYS_HAS_CPU_LOONGSON2E
+- select DMA_NONCOHERENT
+- select BOOT_ELF32
+- select BOARD_SCACHE
+- select HW_HAS_PCI
+- select I8259
+- select ISA
+- select IRQ_CPU
+- select SYS_SUPPORTS_32BIT_KERNEL
+- select SYS_SUPPORTS_64BIT_KERNEL
+- select SYS_SUPPORTS_LITTLE_ENDIAN
+- select SYS_SUPPORTS_HIGHMEM
+- select SYS_HAS_EARLY_PRINTK
+- select GENERIC_HARDIRQS_NO__DO_IRQ
+- select GENERIC_ISA_DMA_SUPPORT_BROKEN
+- select CPU_HAS_WB
+- help
+- Lemote Fuloong(2e) mini-PC board based on the Chinese Loongson-2E CPU and
+- an FPGA northbridge
+-
+- Lemote Fuloong(2e) mini PC have a VIA686B south bridge.
++ bool "Lemote Fuloong(2e) mini-PC"
++ select ARCH_SPARSEMEM_ENABLE
++ select CEVT_R4K
++ select CSRC_R4K
++ select SYS_HAS_CPU_LOONGSON2E
++ select DMA_NONCOHERENT
++ select BOOT_ELF32
++ select BOARD_SCACHE
++ select HW_HAS_PCI
++ select I8259
++ select ISA
++ select IRQ_CPU
++ select SYS_SUPPORTS_32BIT_KERNEL
++ select SYS_SUPPORTS_64BIT_KERNEL
++ select SYS_SUPPORTS_LITTLE_ENDIAN
++ select SYS_SUPPORTS_HIGHMEM
++ select SYS_HAS_EARLY_PRINTK
++ select GENERIC_HARDIRQS_NO__DO_IRQ
++ select GENERIC_ISA_DMA_SUPPORT_BROKEN
++ select CPU_HAS_WB
++ help
++ Lemote Fuloong(2e) mini-PC board based on the Chinese Loongson-2E CPU and
++ an FPGA northbridge
++
++ Lemote Fuloong(2e) mini PC have a VIA686B south bridge.
++
++config LEMOTE_MACH2F
++ bool "Lemote Loongson 2F family machines"
++ select ARCH_SPARSEMEM_ENABLE
++ select BOARD_SCACHE
++ select BOOT_ELF32
++ select CEVT_R4K if ! MIPS_EXTERNAL_TIMER
++ select CPU_HAS_WB
++ select CS5536
++ select CSRC_R4K if ! MIPS_EXTERNAL_TIMER
++ select DMA_NONCOHERENT
++ select GENERIC_HARDIRQS_NO__DO_IRQ
++ select GENERIC_ISA_DMA_SUPPORT_BROKEN
++ select HW_HAS_PCI
++ select I8259
++ select IRQ_CPU
++ select ISA
++ select SYS_HAS_CPU_LOONGSON2F
++ select SYS_HAS_EARLY_PRINTK
++ select SYS_SUPPORTS_32BIT_KERNEL
++ select SYS_SUPPORTS_64BIT_KERNEL
++ select SYS_SUPPORTS_HIGHMEM
++ select SYS_SUPPORTS_LITTLE_ENDIAN
++ help
++ Lemote Loongson 2F family machines utilize the 2F revision of
++ Loongson processor and the AMD CS5536 south bridge.
++
++ These family machines include fuloong2f mini PC, yeeloong2f notebook,
++ LingLoong allinone PC and so forth.
+ endchoice
++
++config CS5536
++ bool
++
++config CS5536_MFGPT
++ bool "CS5536 MFGPT Timer"
++ depends on CS5536
++ select MIPS_EXTERNAL_TIMER
++ help
++ This option enables the mfgpt0 timer of AMD CS5536.
++
++ If you want to enable the Loongson2 CPUFreq Driver, Please enable
++ this option at first, otherwise, You will get wrong system time.
++
++ If unsure, say Yes.
++
++config LOONGSON_SUSPEND
++ bool
++ default y
++ depends on CPU_SUPPORTS_CPUFREQ && SUSPEND
++
++config LOONGSON_UART_BASE
++ bool
++ default y
++ depends on EARLY_PRINTK || SERIAL_8250
++
++#
++# Loongson Platform Specific Drivers
++#
++
++comment "Loongson Platform Specific Drivers"
++
++menuconfig LOONGSON_PLATFORM_DEVICES
++ bool "Loongson Platform Specific Drivers"
++ default y
++ ---help---
++ Say Y here to get to see options for device drivers for various
++ loongson platforms, including vendor-specific laptop/pc extension drivers.
++ This option alone does not add any kernel code.
++
++ If you say N, all options in this submenu will be skipped and disabled.
++
++if LOONGSON_PLATFORM_DEVICES
++
++config LEMOTE_LYNLOONG2F_PDEV
++ tristate "Lemote LynLoong(ALLINONE) Platform Specific Driver"
++ depends on LEMOTE_MACH2F
++ select THERMAL
++ select BACKLIGHT_CLASS_DEVICE
++ default m
++ help
++ LynLoong PC is an AllINONE machine made by Lemote, which is basically
++ compatible to FuLoong2F Mini PC, the only difference is that it has a
++ size-fixed screen: 1360x768 with sisfb video driver. and also, it has
++ its own specific suspend support.
++
++ This driver adds the lynloong specific backlight driver and platform
++ driver(mainly the suspend support).
++
++config LEMOTE_YEELOONG2F_PDEV
++ tristate "Lemote YeeLoong Platform Specific Driver"
++ depends on LEMOTE_MACH2F
++ default m
++ select INPUT_EVDEV
++ select HWMON
++ select VIDEO_OUTPUT_CONTROL
++ select THERMAL
++ select BACKLIGHT_CLASS_DEVICE
++ select SYS_SUPPORTS_APM_EMULATION
++ help
++ YeeLoong netbook is a mini laptop made by Lemote, which is basically
++ compatible to FuLoong2F mini PC, but It has an extra Embedded
++ Controller(kb3310b) for battery, hotkey, backlight, temperature and
++ fan management.
++
++ This driver adds the YeeLoong Platform Specific support.
++
++endif # LOONGSON_PLATFORM_DEVICES
+diff --git a/arch/mips/loongson/Makefile b/arch/mips/loongson/Makefile
+index 39048c4..2b76cb0 100644
+--- a/arch/mips/loongson/Makefile
++++ b/arch/mips/loongson/Makefile
+@@ -9,3 +9,9 @@ obj-$(CONFIG_MACH_LOONGSON) += common/
+ #
+
+ obj-$(CONFIG_LEMOTE_FULOONG2E) += fuloong-2e/
++
++#
++# Lemote loongson2f family machines
++#
++
++obj-$(CONFIG_LEMOTE_MACH2F) += lemote-2f/
+diff --git a/arch/mips/loongson/common/Makefile b/arch/mips/loongson/common/Makefile
+index 656b3cc..b8cb1bf 100644
+--- a/arch/mips/loongson/common/Makefile
++++ b/arch/mips/loongson/common/Makefile
+@@ -3,9 +3,29 @@
+ #
+
+ obj-y += setup.o init.o cmdline.o env.o time.o reset.o irq.o \
+- pci.o bonito-irq.o mem.o machtype.o
++ pci.o bonito-irq.o mem.o machtype.o platform.o
+
+ #
+-# Early printk support
++# Serial port support
+ #
+-obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
++obj-$(CONFIG_EARLY_PRINTK) += early_printk.o dbg.o
++obj-$(CONFIG_SERIAL_8250) += serial.o
++obj-$(CONFIG_LOONGSON_UART_BASE) += uart_base.o
++
++#
++# Enable CS5536 Virtual Support Module(VSM) to virtulize the PCI configure
++# space
++#
++obj-$(CONFIG_CS5536) += cs5536/
++
++#
++# Suspend Support
++#
++
++obj-$(CONFIG_LOONGSON_SUSPEND) += pm.o
++
++# Enable RTC Class support
++#
++# please enable CONFIG_RTC_DRV_CMOS
++#
++obj-$(CONFIG_RTC_DRV_CMOS) += rtc.o
+diff --git a/arch/mips/loongson/common/bonito-irq.c b/arch/mips/loongson/common/bonito-irq.c
+index 3e31e7a..2dc2a4c 100644
+--- a/arch/mips/loongson/common/bonito-irq.c
++++ b/arch/mips/loongson/common/bonito-irq.c
+@@ -12,18 +12,19 @@
+ * option) any later version.
+ */
+ #include <linux/interrupt.h>
++#include <linux/compiler.h>
+
+ #include <loongson.h>
+
+ static inline void bonito_irq_enable(unsigned int irq)
+ {
+- BONITO_INTENSET = (1 << (irq - BONITO_IRQ_BASE));
++ LOONGSON_INTENSET = (1 << (irq - LOONGSON_IRQ_BASE));
+ mmiowb();
+ }
+
+ static inline void bonito_irq_disable(unsigned int irq)
+ {
+- BONITO_INTENCLR = (1 << (irq - BONITO_IRQ_BASE));
++ LOONGSON_INTENCLR = (1 << (irq - LOONGSON_IRQ_BASE));
+ mmiowb();
+ }
+
+@@ -35,7 +36,7 @@ static struct irq_chip bonito_irq_type = {
+ .unmask = bonito_irq_enable,
+ };
+
+-static struct irqaction dma_timeout_irqaction = {
++static struct irqaction __maybe_unused dma_timeout_irqaction = {
+ .handler = no_action,
+ .name = "dma_timeout",
+ };
+@@ -44,8 +45,10 @@ void bonito_irq_init(void)
+ {
+ u32 i;
+
+- for (i = BONITO_IRQ_BASE; i < BONITO_IRQ_BASE + 32; i++)
++ for (i = LOONGSON_IRQ_BASE; i < LOONGSON_IRQ_BASE + 32; i++)
+ set_irq_chip_and_handler(i, &bonito_irq_type, handle_level_irq);
+
+- setup_irq(BONITO_IRQ_BASE + 10, &dma_timeout_irqaction);
++#ifdef CONFIG_CPU_LOONGSON2E
++ setup_irq(LOONGSON_IRQ_BASE + 10, &dma_timeout_irqaction);
++#endif
+ }
+diff --git a/arch/mips/loongson/common/cmdline.c b/arch/mips/loongson/common/cmdline.c
+index 75f1b24..62fb52e 100644
+--- a/arch/mips/loongson/common/cmdline.c
++++ b/arch/mips/loongson/common/cmdline.c
+@@ -9,7 +9,7 @@
+ * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ *
+- * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
++ * Copyright (C) 2009 Lemote Inc.
+ * Author: Wu Zhangjin, wuzj@lemote.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+@@ -49,4 +49,25 @@ void __init prom_init_cmdline(void)
+ strcat(arcs_cmdline, " console=ttyS0,115200");
+ if ((strstr(arcs_cmdline, "root=")) == NULL)
+ strcat(arcs_cmdline, " root=/dev/hda1");
++
++ prom_init_machtype();
++
++ /* append machine specific command line */
++ switch (mips_machtype) {
++ case MACH_LEMOTE_LL2F:
++ if ((strstr(arcs_cmdline, "video=")) == NULL)
++ strcat(arcs_cmdline, " video=sisfb:1360x768-16@60");
++ break;
++ case MACH_LEMOTE_FL2F:
++ if ((strstr(arcs_cmdline, "ide_core.ignore_cable=")) == NULL)
++ strcat(arcs_cmdline, " ide_core.ignore_cable=0");
++ break;
++ case MACH_LEMOTE_ML2F7:
++ /* Mengloong-2F has a 800x480 screen */
++ if ((strstr(arcs_cmdline, "vga=")) == NULL)
++ strcat(arcs_cmdline, " vga=0x313");
++ break;
++ default:
++ break;
++ }
+ }
+diff --git a/arch/mips/loongson/common/cs5536/Makefile b/arch/mips/loongson/common/cs5536/Makefile
+new file mode 100644
+index 0000000..510d4cd
+--- /dev/null
++++ b/arch/mips/loongson/common/cs5536/Makefile
+@@ -0,0 +1,13 @@
++#
++# Makefile for CS5536 support.
++#
++
++obj-$(CONFIG_CS5536) += cs5536_pci.o cs5536_ide.o cs5536_acc.o cs5536_ohci.o \
++ cs5536_isa.o cs5536_ehci.o
++
++#
++# Enable cs5536 mfgpt Timer
++#
++obj-$(CONFIG_CS5536_MFGPT) += cs5536_mfgpt.o
++
++EXTRA_CFLAGS += -Werror
+diff --git a/arch/mips/loongson/common/cs5536/cs5536_acc.c b/arch/mips/loongson/common/cs5536/cs5536_acc.c
+new file mode 100644
+index 0000000..b49485f
+--- /dev/null
++++ b/arch/mips/loongson/common/cs5536/cs5536_acc.c
+@@ -0,0 +1,140 @@
++/*
++ * the ACC Virtual Support Module of AMD CS5536
++ *
++ * Copyright (C) 2007 Lemote, Inc.
++ * Author : jlliu, liujl@lemote.com
++ *
++ * Copyright (C) 2009 Lemote, Inc.
++ * Author: Wu Zhangjin, wuzj@lemote.com
++ *
++ * 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 <cs5536/cs5536.h>
++#include <cs5536/cs5536_pci.h>
++
++void pci_acc_write_reg(int reg, u32 value)
++{
++ u32 hi = 0, lo = value;
++
++ switch (reg) {
++ case PCI_COMMAND:
++ _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo);
++ if (value & PCI_COMMAND_MASTER)
++ lo |= (0x03 << 8);
++ else
++ lo &= ~(0x03 << 8);
++ _wrmsr(GLIU_MSR_REG(GLIU_PAE), hi, lo);
++ break;
++ case PCI_STATUS:
++ if (value & PCI_STATUS_PARITY) {
++ _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
++ if (lo & SB_PARE_ERR_FLAG) {
++ lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG;
++ _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
++ }
++ }
++ break;
++ case PCI_BAR0_REG:
++ if (value == PCI_BAR_RANGE_MASK) {
++ _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
++ lo |= SOFT_BAR_ACC_FLAG;
++ _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
++ } else if (value & 0x01) {
++ value &= 0xfffffffc;
++ hi = 0xA0000000 | ((value & 0x000ff000) >> 12);
++ lo = 0x000fff80 | ((value & 0x00000fff) << 20);
++ _wrmsr(GLIU_MSR_REG(GLIU_IOD_BM1), hi, lo);
++ }
++ break;
++ case PCI_ACC_INT_REG:
++ _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo);
++ /* disable all the usb interrupt in PIC */
++ lo &= ~(0xf << PIC_YSEL_LOW_ACC_SHIFT);
++ if (value) /* enable all the acc interrupt in PIC */
++ lo |= (CS5536_ACC_INTR << PIC_YSEL_LOW_ACC_SHIFT);
++ _wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo);
++ break;
++ default:
++ break;
++ }
++}
++
++u32 pci_acc_read_reg(int reg)
++{
++ u32 hi, lo;
++ u32 conf_data = 0;
++
++ switch (reg) {
++ case PCI_VENDOR_ID:
++ conf_data =
++ CFG_PCI_VENDOR_ID(CS5536_ACC_DEVICE_ID, CS5536_VENDOR_ID);
++ break;
++ case PCI_COMMAND:
++ _rdmsr(GLIU_MSR_REG(GLIU_IOD_BM1), &hi, &lo);
++ if (((lo & 0xfff00000) || (hi & 0x000000ff))
++ && ((hi & 0xf0000000) == 0xa0000000))
++ conf_data |= PCI_COMMAND_IO;
++ _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo);
++ if ((lo & 0x300) == 0x300)
++ conf_data |= PCI_COMMAND_MASTER;
++ break;
++ case PCI_STATUS:
++ conf_data |= PCI_STATUS_66MHZ;
++ conf_data |= PCI_STATUS_FAST_BACK;
++ _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
++ if (lo & SB_PARE_ERR_FLAG)
++ conf_data |= PCI_STATUS_PARITY;
++ conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
++ break;
++ case PCI_CLASS_REVISION:
++ _rdmsr(ACC_MSR_REG(ACC_CAP), &hi, &lo);
++ conf_data = lo & 0x000000ff;
++ conf_data |= (CS5536_ACC_CLASS_CODE << 8);
++ break;
++ case PCI_CACHE_LINE_SIZE:
++ conf_data =
++ CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE,
++ PCI_NORMAL_LATENCY_TIMER);
++ break;
++ case PCI_BAR0_REG:
++ _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
++ if (lo & SOFT_BAR_ACC_FLAG) {
++ conf_data = CS5536_ACC_RANGE |
++ PCI_BASE_ADDRESS_SPACE_IO;
++ lo &= ~SOFT_BAR_ACC_FLAG;
++ _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
++ } else {
++ _rdmsr(GLIU_MSR_REG(GLIU_IOD_BM1), &hi, &lo);
++ conf_data = (hi & 0x000000ff) << 12;
++ conf_data |= (lo & 0xfff00000) >> 20;
++ conf_data |= 0x01;
++ conf_data &= ~0x02;
++ }
++ break;
++ case PCI_CARDBUS_CIS:
++ conf_data = PCI_CARDBUS_CIS_POINTER;
++ break;
++ case PCI_SUBSYSTEM_VENDOR_ID:
++ conf_data =
++ CFG_PCI_VENDOR_ID(CS5536_ACC_SUB_ID, CS5536_SUB_VENDOR_ID);
++ break;
++ case PCI_ROM_ADDRESS:
++ conf_data = PCI_EXPANSION_ROM_BAR;
++ break;
++ case PCI_CAPABILITY_LIST:
++ conf_data = PCI_CAPLIST_USB_POINTER;
++ break;
++ case PCI_INTERRUPT_LINE:
++ conf_data =
++ CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_ACC_INTR);
++ break;
++ default:
++ break;
++ }
++
++ return conf_data;
++}
+diff --git a/arch/mips/loongson/common/cs5536/cs5536_ehci.c b/arch/mips/loongson/common/cs5536/cs5536_ehci.c
+new file mode 100644
+index 0000000..74f9c59
+--- /dev/null
++++ b/arch/mips/loongson/common/cs5536/cs5536_ehci.c
+@@ -0,0 +1,158 @@
++/*
++ * the EHCI Virtual Support Module of AMD CS5536
++ *
++ * Copyright (C) 2007 Lemote, Inc.
++ * Author : jlliu, liujl@lemote.com
++ *
++ * Copyright (C) 2009 Lemote, Inc.
++ * Author: Wu Zhangjin, wuzj@lemote.com
++ *
++ * 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 <cs5536/cs5536.h>
++#include <cs5536/cs5536_pci.h>
++
++void pci_ehci_write_reg(int reg, u32 value)
++{
++ u32 hi = 0, lo = value;
++
++ switch (reg) {
++ case PCI_COMMAND:
++ _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
++ if (value & PCI_COMMAND_MASTER)
++ hi |= PCI_COMMAND_MASTER;
++ else
++ hi &= ~PCI_COMMAND_MASTER;
++
++ if (value & PCI_COMMAND_MEMORY)
++ hi |= PCI_COMMAND_MEMORY;
++ else
++ hi &= ~PCI_COMMAND_MEMORY;
++ _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo);
++ break;
++ case PCI_STATUS:
++ if (value & PCI_STATUS_PARITY) {
++ _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
++ if (lo & SB_PARE_ERR_FLAG) {
++ lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG;
++ _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
++ }
++ }
++ break;
++ case PCI_BAR0_REG:
++ if (value == PCI_BAR_RANGE_MASK) {
++ _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
++ lo |= SOFT_BAR_EHCI_FLAG;
++ _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
++ } else if ((value & 0x01) == 0x00) {
++ _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo);
++
++ value &= 0xfffffff0;
++ hi = 0x40000000 | ((value & 0xff000000) >> 24);
++ lo = 0x000fffff | ((value & 0x00fff000) << 8);
++ _wrmsr(GLIU_MSR_REG(GLIU_P2D_BM4), hi, lo);
++ }
++ break;
++ case PCI_EHCI_LEGSMIEN_REG:
++ _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
++ hi &= 0x003f0000;
++ hi |= (value & 0x3f) << 16;
++ _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo);
++ break;
++ case PCI_EHCI_FLADJ_REG:
++ _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
++ hi &= ~0x00003f00;
++ hi |= value & 0x00003f00;
++ _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo);
++ break;
++ default:
++ break;
++ }
++}
++
++u32 pci_ehci_read_reg(int reg)
++{
++ u32 conf_data = 0;
++ u32 hi, lo;
++
++ switch (reg) {
++ case PCI_VENDOR_ID:
++ conf_data =
++ CFG_PCI_VENDOR_ID(CS5536_EHCI_DEVICE_ID, CS5536_VENDOR_ID);
++ break;
++ case PCI_COMMAND:
++ _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
++ if (hi & PCI_COMMAND_MASTER)
++ conf_data |= PCI_COMMAND_MASTER;
++ if (hi & PCI_COMMAND_MEMORY)
++ conf_data |= PCI_COMMAND_MEMORY;
++ break;
++ case PCI_STATUS:
++ conf_data |= PCI_STATUS_66MHZ;
++ conf_data |= PCI_STATUS_FAST_BACK;
++ _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
++ if (lo & SB_PARE_ERR_FLAG)
++ conf_data |= PCI_STATUS_PARITY;
++ conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
++ break;
++ case PCI_CLASS_REVISION:
++ _rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo);
++ conf_data = lo & 0x000000ff;
++ conf_data |= (CS5536_EHCI_CLASS_CODE << 8);
++ break;
++ case PCI_CACHE_LINE_SIZE:
++ conf_data =
++ CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE,
++ PCI_NORMAL_LATENCY_TIMER);
++ break;
++ case PCI_BAR0_REG:
++ _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
++ if (lo & SOFT_BAR_EHCI_FLAG) {
++ conf_data = CS5536_EHCI_RANGE |
++ PCI_BASE_ADDRESS_SPACE_MEMORY;
++ lo &= ~SOFT_BAR_EHCI_FLAG;
++ _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
++ } else {
++ _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
++ conf_data = lo & 0xfffff000;
++ }
++ break;
++ case PCI_CARDBUS_CIS:
++ conf_data = PCI_CARDBUS_CIS_POINTER;
++ break;
++ case PCI_SUBSYSTEM_VENDOR_ID:
++ conf_data =
++ CFG_PCI_VENDOR_ID(CS5536_EHCI_SUB_ID, CS5536_SUB_VENDOR_ID);
++ break;
++ case PCI_ROM_ADDRESS:
++ conf_data = PCI_EXPANSION_ROM_BAR;
++ break;
++ case PCI_CAPABILITY_LIST:
++ conf_data = PCI_CAPLIST_USB_POINTER;
++ break;
++ case PCI_INTERRUPT_LINE:
++ conf_data =
++ CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_USB_INTR);
++ break;
++ case PCI_EHCI_LEGSMIEN_REG:
++ _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
++ conf_data = (hi & 0x003f0000) >> 16;
++ break;
++ case PCI_EHCI_LEGSMISTS_REG:
++ _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
++ conf_data = (hi & 0x3f000000) >> 24;
++ break;
++ case PCI_EHCI_FLADJ_REG:
++ _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
++ conf_data = hi & 0x00003f00;
++ break;
++ default:
++ break;
++ }
++
++ return conf_data;
++}
+diff --git a/arch/mips/loongson/common/cs5536/cs5536_ide.c b/arch/mips/loongson/common/cs5536/cs5536_ide.c
+new file mode 100644
+index 0000000..3f61594
+--- /dev/null
++++ b/arch/mips/loongson/common/cs5536/cs5536_ide.c
+@@ -0,0 +1,179 @@
++/*
++ * the IDE Virtual Support Module of AMD CS5536
++ *
++ * Copyright (C) 2007 Lemote, Inc.
++ * Author : jlliu, liujl@lemote.com
++ *
++ * Copyright (C) 2009 Lemote, Inc.
++ * Author: Wu Zhangjin, wuzj@lemote.com
++ *
++ * 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 <cs5536/cs5536.h>
++#include <cs5536/cs5536_pci.h>
++
++void pci_ide_write_reg(int reg, u32 value)
++{
++ u32 hi = 0, lo = value;
++
++ switch (reg) {
++ case PCI_COMMAND:
++ _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo);
++ if (value & PCI_COMMAND_MASTER)
++ lo |= (0x03 << 4);
++ else
++ lo &= ~(0x03 << 4);
++ _wrmsr(GLIU_MSR_REG(GLIU_PAE), hi, lo);
++ break;
++ case PCI_STATUS:
++ if (value & PCI_STATUS_PARITY) {
++ _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
++ if (lo & SB_PARE_ERR_FLAG) {
++ lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG;
++ _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
++ }
++ }
++ break;
++ case PCI_CACHE_LINE_SIZE:
++ value &= 0x0000ff00;
++ _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo);
++ hi &= 0xffffff00;
++ hi |= (value >> 8);
++ _wrmsr(SB_MSR_REG(SB_CTRL), hi, lo);
++ break;
++ case PCI_BAR4_REG:
++ if (value == PCI_BAR_RANGE_MASK) {
++ _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
++ lo |= SOFT_BAR_IDE_FLAG;
++ _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
++ } else if (value & 0x01) {
++ lo = (value & 0xfffffff0) | 0x1;
++ _wrmsr(IDE_MSR_REG(IDE_IO_BAR), hi, lo);
++
++ value &= 0xfffffffc;
++ hi = 0x60000000 | ((value & 0x000ff000) >> 12);
++ lo = 0x000ffff0 | ((value & 0x00000fff) << 20);
++ _wrmsr(GLIU_MSR_REG(GLIU_IOD_BM2), hi, lo);
++ }
++ break;
++ case PCI_IDE_CFG_REG:
++ if (value == CS5536_IDE_FLASH_SIGNATURE) {
++ _rdmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), &hi, &lo);
++ lo |= 0x01;
++ _wrmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), hi, lo);
++ } else
++ _wrmsr(IDE_MSR_REG(IDE_CFG), hi, lo);
++ break;
++ case PCI_IDE_DTC_REG:
++ _wrmsr(IDE_MSR_REG(IDE_DTC), hi, lo);
++ break;
++ case PCI_IDE_CAST_REG:
++ _wrmsr(IDE_MSR_REG(IDE_CAST), hi, lo);
++ break;
++ case PCI_IDE_ETC_REG:
++ _wrmsr(IDE_MSR_REG(IDE_ETC), hi, lo);
++ break;
++ case PCI_IDE_PM_REG:
++ _wrmsr(IDE_MSR_REG(IDE_INTERNAL_PM), hi, lo);
++ break;
++ default:
++ break;
++ }
++}
++
++u32 pci_ide_read_reg(int reg)
++{
++ u32 conf_data = 0;
++ u32 hi, lo;
++
++ switch (reg) {
++ case PCI_VENDOR_ID:
++ conf_data =
++ CFG_PCI_VENDOR_ID(CS5536_IDE_DEVICE_ID, CS5536_VENDOR_ID);
++ break;
++ case PCI_COMMAND:
++ _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo);
++ if (lo & 0xfffffff0)
++ conf_data |= PCI_COMMAND_IO;
++ _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo);
++ if ((lo & 0x30) == 0x30)
++ conf_data |= PCI_COMMAND_MASTER;
++ break;
++ case PCI_STATUS:
++ conf_data |= PCI_STATUS_66MHZ;
++ conf_data |= PCI_STATUS_FAST_BACK;
++ _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
++ if (lo & SB_PARE_ERR_FLAG)
++ conf_data |= PCI_STATUS_PARITY;
++ conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
++ break;
++ case PCI_CLASS_REVISION:
++ _rdmsr(IDE_MSR_REG(IDE_CAP), &hi, &lo);
++ conf_data = lo & 0x000000ff;
++ conf_data |= (CS5536_IDE_CLASS_CODE << 8);
++ break;
++ case PCI_CACHE_LINE_SIZE:
++ _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo);
++ hi &= 0x000000f8;
++ conf_data = CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE, hi);
++ break;
++ case PCI_BAR4_REG:
++ _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
++ if (lo & SOFT_BAR_IDE_FLAG) {
++ conf_data = CS5536_IDE_RANGE |
++ PCI_BASE_ADDRESS_SPACE_IO;
++ lo &= ~SOFT_BAR_IDE_FLAG;
++ _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
++ } else {
++ _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo);
++ conf_data = lo & 0xfffffff0;
++ conf_data |= 0x01;
++ conf_data &= ~0x02;
++ }
++ break;
++ case PCI_CARDBUS_CIS:
++ conf_data = PCI_CARDBUS_CIS_POINTER;
++ break;
++ case PCI_SUBSYSTEM_VENDOR_ID:
++ conf_data =
++ CFG_PCI_VENDOR_ID(CS5536_IDE_SUB_ID, CS5536_SUB_VENDOR_ID);
++ break;
++ case PCI_ROM_ADDRESS:
++ conf_data = PCI_EXPANSION_ROM_BAR;
++ break;
++ case PCI_CAPABILITY_LIST:
++ conf_data = PCI_CAPLIST_POINTER;
++ break;
++ case PCI_INTERRUPT_LINE:
++ conf_data =
++ CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_IDE_INTR);
++ break;
++ case PCI_IDE_CFG_REG:
++ _rdmsr(IDE_MSR_REG(IDE_CFG), &hi, &lo);
++ conf_data = lo;
++ break;
++ case PCI_IDE_DTC_REG:
++ _rdmsr(IDE_MSR_REG(IDE_DTC), &hi, &lo);
++ conf_data = lo;
++ break;
++ case PCI_IDE_CAST_REG:
++ _rdmsr(IDE_MSR_REG(IDE_CAST), &hi, &lo);
++ conf_data = lo;
++ break;
++ case PCI_IDE_ETC_REG:
++ _rdmsr(IDE_MSR_REG(IDE_ETC), &hi, &lo);
++ conf_data = lo;
++ case PCI_IDE_PM_REG:
++ _rdmsr(IDE_MSR_REG(IDE_INTERNAL_PM), &hi, &lo);
++ conf_data = lo;
++ break;
++ default:
++ break;
++ }
++
++ return conf_data;
++}
+diff --git a/arch/mips/loongson/common/cs5536/cs5536_isa.c b/arch/mips/loongson/common/cs5536/cs5536_isa.c
+new file mode 100644
+index 0000000..b6f17f5
+--- /dev/null
++++ b/arch/mips/loongson/common/cs5536/cs5536_isa.c
+@@ -0,0 +1,316 @@
++/*
++ * the ISA Virtual Support Module of AMD CS5536
++ *
++ * Copyright (C) 2007 Lemote, Inc.
++ * Author : jlliu, liujl@lemote.com
++ *
++ * Copyright (C) 2009 Lemote, Inc.
++ * Author: Wu Zhangjin, wuzj@lemote.com
++ *
++ * 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 <cs5536/cs5536.h>
++#include <cs5536/cs5536_pci.h>
++
++/* common variables for PCI_ISA_READ/WRITE_BAR */
++static const u32 divil_msr_reg[6] = {
++ DIVIL_MSR_REG(DIVIL_LBAR_SMB), DIVIL_MSR_REG(DIVIL_LBAR_GPIO),
++ DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), DIVIL_MSR_REG(DIVIL_LBAR_IRQ),
++ DIVIL_MSR_REG(DIVIL_LBAR_PMS), DIVIL_MSR_REG(DIVIL_LBAR_ACPI),
++};
++
++static const u32 soft_bar_flag[6] = {
++ SOFT_BAR_SMB_FLAG, SOFT_BAR_GPIO_FLAG, SOFT_BAR_MFGPT_FLAG,
++ SOFT_BAR_IRQ_FLAG, SOFT_BAR_PMS_FLAG, SOFT_BAR_ACPI_FLAG,
++};
++
++static const u32 sb_msr_reg[6] = {
++ SB_MSR_REG(SB_R0), SB_MSR_REG(SB_R1), SB_MSR_REG(SB_R2),
++ SB_MSR_REG(SB_R3), SB_MSR_REG(SB_R4), SB_MSR_REG(SB_R5),
++};
++
++static const u32 bar_space_range[6] = {
++ CS5536_SMB_RANGE, CS5536_GPIO_RANGE, CS5536_MFGPT_RANGE,
++ CS5536_IRQ_RANGE, CS5536_PMS_RANGE, CS5536_ACPI_RANGE,
++};
++
++static const int bar_space_len[6] = {
++ CS5536_SMB_LENGTH, CS5536_GPIO_LENGTH, CS5536_MFGPT_LENGTH,
++ CS5536_IRQ_LENGTH, CS5536_PMS_LENGTH, CS5536_ACPI_LENGTH,
++};
++
++/*
++ * enable the divil module bar space.
++ *
++ * For all the DIVIL module LBAR, you should control the DIVIL LBAR reg
++ * and the RCONFx(0~5) reg to use the modules.
++ */
++static void divil_lbar_enable(void)
++{
++ u32 hi, lo;
++ int offset;
++
++ /*
++ * The DIVIL IRQ is not used yet. and make the RCONF0 reserved.
++ */
++
++ for (offset = DIVIL_LBAR_SMB; offset <= DIVIL_LBAR_PMS; offset++) {
++ _rdmsr(DIVIL_MSR_REG(offset), &hi, &lo);
++ hi |= 0x01;
++ _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), hi, lo);
++ }
++}
++
++/*
++ * disable the divil module bar space.
++ */
++static void divil_lbar_disable(void)
++{
++ u32 hi, lo;
++ int offset;
++
++ for (offset = DIVIL_LBAR_SMB; offset <= DIVIL_LBAR_PMS; offset++) {
++ _rdmsr(DIVIL_MSR_REG(offset), &hi, &lo);
++ hi &= ~0x01;
++ _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), hi, lo);
++ }
++}
++
++/*
++ * BAR write: write value to the n BAR
++ */
++
++void pci_isa_write_bar(int n, u32 value)
++{
++ u32 hi = 0, lo = value;
++
++ if (value == PCI_BAR_RANGE_MASK) {
++ _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
++ lo |= soft_bar_flag[n];
++ _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
++ } else if (value & 0x01) {
++ /* NATIVE reg */
++ hi = 0x0000f001;
++ lo &= bar_space_range[n];
++ _wrmsr(divil_msr_reg[n], hi, lo);
++
++ /* RCONFx is 4bytes in units for I/O space */
++ hi = ((value & 0x000ffffc) << 12) |
++ ((bar_space_len[n] - 4) << 12) | 0x01;
++ lo = ((value & 0x000ffffc) << 12) | 0x01;
++ _wrmsr(sb_msr_reg[n], hi, lo);
++ }
++}
++
++/*
++ * BAR read: read the n BAR
++ */
++
++u32 pci_isa_read_bar(int n)
++{
++ u32 conf_data = 0;
++ u32 hi, lo;
++
++ _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
++ if (lo & soft_bar_flag[n]) {
++ conf_data = bar_space_range[n] | PCI_BASE_ADDRESS_SPACE_IO;
++ lo &= ~soft_bar_flag[n];
++ _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
++ } else {
++ _rdmsr(divil_msr_reg[n], &hi, &lo);
++ conf_data = lo & bar_space_range[n];
++ conf_data |= 0x01;
++ conf_data &= ~0x02;
++ }
++ return conf_data;
++}
++
++/*
++ * isa_write: ISA write transfer
++ *
++ * We assume that this is not a bus master transfer.
++ */
++void pci_isa_write_reg(int reg, u32 value)
++{
++ u32 hi = 0, lo = value;
++ u32 temp;
++
++ switch (reg) {
++ case PCI_COMMAND:
++ if (value & PCI_COMMAND_IO)
++ divil_lbar_enable();
++ else
++ divil_lbar_disable();
++ break;
++ case PCI_STATUS:
++ _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
++ temp = lo & 0x0000ffff;
++ if ((value & PCI_STATUS_SIG_TARGET_ABORT) &&
++ (lo & SB_TAS_ERR_EN))
++ temp |= SB_TAS_ERR_FLAG;
++
++ if ((value & PCI_STATUS_REC_TARGET_ABORT) &&
++ (lo & SB_TAR_ERR_EN))
++ temp |= SB_TAR_ERR_FLAG;
++
++ if ((value & PCI_STATUS_REC_MASTER_ABORT)
++ && (lo & SB_MAR_ERR_EN))
++ temp |= SB_MAR_ERR_FLAG;
++
++ if ((value & PCI_STATUS_DETECTED_PARITY)
++ && (lo & SB_PARE_ERR_EN))
++ temp |= SB_PARE_ERR_FLAG;
++
++ lo = temp;
++ _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
++ break;
++ case PCI_CACHE_LINE_SIZE:
++ value &= 0x0000ff00;
++ _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo);
++ hi &= 0xffffff00;
++ hi |= (value >> 8);
++ _wrmsr(SB_MSR_REG(SB_CTRL), hi, lo);
++ break;
++ case PCI_BAR0_REG:
++ pci_isa_write_bar(0, value);
++ break;
++ case PCI_BAR1_REG:
++ pci_isa_write_bar(1, value);
++ break;
++ case PCI_BAR2_REG:
++ pci_isa_write_bar(2, value);
++ break;
++ case PCI_BAR3_REG:
++ pci_isa_write_bar(3, value);
++ break;
++ case PCI_BAR4_REG:
++ pci_isa_write_bar(4, value);
++ break;
++ case PCI_BAR5_REG:
++ pci_isa_write_bar(5, value);
++ break;
++ case PCI_UART1_INT_REG:
++ _rdmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), &hi, &lo);
++ /* disable uart1 interrupt in PIC */
++ lo &= ~(0xf << 24);
++ if (value) /* enable uart1 interrupt in PIC */
++ lo |= (CS5536_UART1_INTR << 24);
++ _wrmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), hi, lo);
++ break;
++ case PCI_UART2_INT_REG:
++ _rdmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), &hi, &lo);
++ /* disable uart2 interrupt in PIC */
++ lo &= ~(0xf << 28);
++ if (value) /* enable uart2 interrupt in PIC */
++ lo |= (CS5536_UART2_INTR << 28);
++ _wrmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), hi, lo);
++ break;
++ case PCI_ISA_FIXUP_REG:
++ if (value) {
++ /* enable the TARGET ABORT/MASTER ABORT etc. */
++ _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
++ lo |= 0x00000063;
++ _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
++ }
++
++ default:
++ /* ALL OTHER PCI CONFIG SPACE HEADER IS NOT IMPLEMENTED. */
++ break;
++ }
++}
++
++/*
++ * isa_read: ISA read transfers
++ *
++ * We assume that this is not a bus master transfer.
++ */
++u32 pci_isa_read_reg(int reg)
++{
++ u32 conf_data = 0;
++ u32 hi, lo;
++
++ switch (reg) {
++ case PCI_VENDOR_ID:
++ conf_data =
++ CFG_PCI_VENDOR_ID(CS5536_ISA_DEVICE_ID, CS5536_VENDOR_ID);
++ break;
++ case PCI_COMMAND:
++ /* we just check the first LBAR for the IO enable bit, */
++ /* maybe we should changed later. */
++ _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), &hi, &lo);
++ if (hi & 0x01)
++ conf_data |= PCI_COMMAND_IO;
++ break;
++ case PCI_STATUS:
++ conf_data |= PCI_STATUS_66MHZ;
++ conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
++ conf_data |= PCI_STATUS_FAST_BACK;
++
++ _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
++ if (lo & SB_TAS_ERR_FLAG)
++ conf_data |= PCI_STATUS_SIG_TARGET_ABORT;
++ if (lo & SB_TAR_ERR_FLAG)
++ conf_data |= PCI_STATUS_REC_TARGET_ABORT;
++ if (lo & SB_MAR_ERR_FLAG)
++ conf_data |= PCI_STATUS_REC_MASTER_ABORT;
++ if (lo & SB_PARE_ERR_FLAG)
++ conf_data |= PCI_STATUS_DETECTED_PARITY;
++ break;
++ case PCI_CLASS_REVISION:
++ _rdmsr(GLCP_MSR_REG(GLCP_CHIP_REV_ID), &hi, &lo);
++ conf_data = lo & 0x000000ff;
++ conf_data |= (CS5536_ISA_CLASS_CODE << 8);
++ break;
++ case PCI_CACHE_LINE_SIZE:
++ _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo);
++ hi &= 0x000000f8;
++ conf_data = CFG_PCI_CACHE_LINE_SIZE(PCI_BRIDGE_HEADER_TYPE, hi);
++ break;
++ /*
++ * we only use the LBAR of DIVIL, no RCONF used.
++ * all of them are IO space.
++ */
++ case PCI_BAR0_REG:
++ return pci_isa_read_bar(0);
++ break;
++ case PCI_BAR1_REG:
++ return pci_isa_read_bar(1);
++ break;
++ case PCI_BAR2_REG:
++ return pci_isa_read_bar(2);
++ break;
++ case PCI_BAR3_REG:
++ break;
++ case PCI_BAR4_REG:
++ return pci_isa_read_bar(4);
++ break;
++ case PCI_BAR5_REG:
++ return pci_isa_read_bar(5);
++ break;
++ case PCI_CARDBUS_CIS:
++ conf_data = PCI_CARDBUS_CIS_POINTER;
++ break;
++ case PCI_SUBSYSTEM_VENDOR_ID:
++ conf_data =
++ CFG_PCI_VENDOR_ID(CS5536_ISA_SUB_ID, CS5536_SUB_VENDOR_ID);
++ break;
++ case PCI_ROM_ADDRESS:
++ conf_data = PCI_EXPANSION_ROM_BAR;
++ break;
++ case PCI_CAPABILITY_LIST:
++ conf_data = PCI_CAPLIST_POINTER;
++ break;
++ case PCI_INTERRUPT_LINE:
++ /* no interrupt used here */
++ conf_data = CFG_PCI_INTERRUPT_LINE(0x00, 0x00);
++ break;
++ default:
++ break;
++ }
++
++ return conf_data;
++}
+diff --git a/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c b/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c
+new file mode 100644
+index 0000000..6cb44db
+--- /dev/null
++++ b/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c
+@@ -0,0 +1,217 @@
++/*
++ * CS5536 General timer functions
++ *
++ * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
++ * Author: Yanhua, yanh@lemote.com
++ *
++ * Copyright (C) 2009 Lemote Inc.
++ * Author: Wu zhangjin, wuzj@lemote.com
++ *
++ * Reference: AMD Geode(TM) CS5536 Companion Device Data Book
++ *
++ * 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 <linux/io.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/jiffies.h>
++#include <linux/spinlock.h>
++#include <linux/interrupt.h>
++#include <linux/clockchips.h>
++
++#include <asm/time.h>
++
++#include <cs5536/cs5536_mfgpt.h>
++
++DEFINE_SPINLOCK(mfgpt_lock);
++EXPORT_SYMBOL(mfgpt_lock);
++
++static u32 mfgpt_base;
++
++/*
++ * Initialize the MFGPT timer.
++ *
++ * This is also called after resume to bring the MFGPT into operation again.
++ */
++
++/* disable counter */
++void disable_mfgpt0_counter(void)
++{
++ outw(inw(MFGPT0_SETUP) & 0x7fff, MFGPT0_SETUP);
++}
++EXPORT_SYMBOL(disable_mfgpt0_counter);
++
++/* enable counter, comparator2 to event mode, 14.318MHz clock */
++void enable_mfgpt0_counter(void)
++{
++ outw(0xe310, MFGPT0_SETUP);
++}
++EXPORT_SYMBOL(enable_mfgpt0_counter);
++
++static void init_mfgpt_timer(enum clock_event_mode mode,
++ struct clock_event_device *evt)
++{
++ spin_lock(&mfgpt_lock);
++
++ switch (mode) {
++ case CLOCK_EVT_MODE_PERIODIC:
++ outw(COMPARE, MFGPT0_CMP2); /* set comparator2 */
++ outw(0, MFGPT0_CNT); /* set counter to 0 */
++ enable_mfgpt0_counter();
++ break;
++
++ case CLOCK_EVT_MODE_SHUTDOWN:
++ case CLOCK_EVT_MODE_UNUSED:
++ if (evt->mode == CLOCK_EVT_MODE_PERIODIC ||
++ evt->mode == CLOCK_EVT_MODE_ONESHOT)
++ disable_mfgpt0_counter();
++ break;
++
++ case CLOCK_EVT_MODE_ONESHOT:
++ /* The oneshot mode have very high deviation, Not use it! */
++ break;
++
++ case CLOCK_EVT_MODE_RESUME:
++ /* Nothing to do here */
++ break;
++ }
++ spin_unlock(&mfgpt_lock);
++}
++
++static struct clock_event_device mfgpt_clockevent = {
++ .name = "mfgpt",
++ .features = CLOCK_EVT_FEAT_PERIODIC,
++ .set_mode = init_mfgpt_timer,
++ .irq = CS5536_MFGPT_INTR,
++};
++
++static irqreturn_t timer_interrupt(int irq, void *dev_id)
++{
++ u32 basehi;
++
++ /*
++ * get MFGPT base address
++ *
++ * NOTE: do not remove me, it's need for the value of mfgpt_base is
++ * variable
++ */
++ _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), &basehi, &mfgpt_base);
++
++ /* ack */
++ outw(inw(MFGPT0_SETUP) | 0x4000, MFGPT0_SETUP);
++
++ mfgpt_clockevent.event_handler(&mfgpt_clockevent);
++
++ return IRQ_HANDLED;
++}
++
++static struct irqaction irq5 = {
++ .handler = timer_interrupt,
++ .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_TIMER,
++ .name = "timer"
++};
++
++/*
++ * Initialize the conversion factor and the min/max deltas of the clock event
++ * structure and register the clock event source with the framework.
++ */
++void __init setup_mfgpt0_timer(void)
++{
++ u32 basehi;
++ struct clock_event_device *cd = &mfgpt_clockevent;
++ unsigned int cpu = smp_processor_id();
++
++ cd->cpumask = cpumask_of(cpu);
++ clockevent_set_clock(cd, MFGPT_TICK_RATE);
++ cd->max_delta_ns = clockevent_delta2ns(0xffff, cd);
++ cd->min_delta_ns = clockevent_delta2ns(0xf, cd);
++
++ /* Enable MFGPT0 Comparator 2 Output to the Interrupt Mapper */
++ _wrmsr(DIVIL_MSR_REG(MFGPT_IRQ), 0, 0x100);
++
++ /* Enable Interrupt Gate 5 */
++ _wrmsr(DIVIL_MSR_REG(PIC_ZSEL_LOW), 0, 0x50000);
++
++ /* get MFGPT base address */
++ _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), &basehi, &mfgpt_base);
++
++ clockevents_register_device(cd);
++
++ setup_irq(CS5536_MFGPT_INTR, &irq5);
++}
++
++/*
++ * Since the MFGPT overflows every tick, its not very useful
++ * to just read by itself. So use jiffies to emulate a free
++ * running counter:
++ */
++static cycle_t mfgpt_read(struct clocksource *cs)
++{
++ unsigned long flags;
++ int count;
++ u32 jifs;
++ static int old_count;
++ static u32 old_jifs;
++
++ spin_lock_irqsave(&mfgpt_lock, flags);
++ /*
++ * Although our caller may have the read side of xtime_lock,
++ * this is now a seqlock, and we are cheating in this routine
++ * by having side effects on state that we cannot undo if
++ * there is a collision on the seqlock and our caller has to
++ * retry. (Namely, old_jifs and old_count.) So we must treat
++ * jiffies as volatile despite the lock. We read jiffies
++ * before latching the timer count to guarantee that although
++ * the jiffies value might be older than the count (that is,
++ * the counter may underflow between the last point where
++ * jiffies was incremented and the point where we latch the
++ * count), it cannot be newer.
++ */
++ jifs = jiffies;
++ /* read the count */
++ count = inw(MFGPT0_CNT);
++
++ /*
++ * It's possible for count to appear to go the wrong way for this
++ * reason:
++ *
++ * The timer counter underflows, but we haven't handled the resulting
++ * interrupt and incremented jiffies yet.
++ *
++ * Previous attempts to handle these cases intelligently were buggy, so
++ * we just do the simple thing now.
++ */
++ if (count < old_count && jifs == old_jifs)
++ count = old_count;
++
++ old_count = count;
++ old_jifs = jifs;
++
++ spin_unlock_irqrestore(&mfgpt_lock, flags);
++
++ return (cycle_t) (jifs * COMPARE) + count;
++}
++
++static struct clocksource clocksource_mfgpt = {
++ .name = "mfgpt",
++ .rating = 120, /* Functional for real use, but not desired */
++ .read = mfgpt_read,
++ .mask = CLOCKSOURCE_MASK(32),
++ .mult = 0,
++ .shift = 22,
++};
++
++int __init init_mfgpt_clocksource(void)
++{
++ if (num_possible_cpus() > 1) /* MFGPT does not scale! */
++ return 0;
++
++ clocksource_mfgpt.mult = clocksource_hz2mult(MFGPT_TICK_RATE, 22);
++ return clocksource_register(&clocksource_mfgpt);
++}
++
++arch_initcall(init_mfgpt_clocksource);
+diff --git a/arch/mips/loongson/common/cs5536/cs5536_ohci.c b/arch/mips/loongson/common/cs5536/cs5536_ohci.c
+new file mode 100644
+index 0000000..8fdb02b
+--- /dev/null
++++ b/arch/mips/loongson/common/cs5536/cs5536_ohci.c
+@@ -0,0 +1,147 @@
++/*
++ * the OHCI Virtual Support Module of AMD CS5536
++ *
++ * Copyright (C) 2007 Lemote, Inc.
++ * Author : jlliu, liujl@lemote.com
++ *
++ * Copyright (C) 2009 Lemote, Inc.
++ * Author: Wu Zhangjin, wuzj@lemote.com
++ *
++ * 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 <cs5536/cs5536.h>
++#include <cs5536/cs5536_pci.h>
++
++void pci_ohci_write_reg(int reg, u32 value)
++{
++ u32 hi = 0, lo = value;
++
++ switch (reg) {
++ case PCI_COMMAND:
++ _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo);
++ if (value & PCI_COMMAND_MASTER)
++ hi |= PCI_COMMAND_MASTER;
++ else
++ hi &= ~PCI_COMMAND_MASTER;
++
++ if (value & PCI_COMMAND_MEMORY)
++ hi |= PCI_COMMAND_MEMORY;
++ else
++ hi &= ~PCI_COMMAND_MEMORY;
++ _wrmsr(USB_MSR_REG(USB_OHCI), hi, lo);
++ break;
++ case PCI_STATUS:
++ if (value & PCI_STATUS_PARITY) {
++ _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
++ if (lo & SB_PARE_ERR_FLAG) {
++ lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG;
++ _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
++ }
++ }
++ break;
++ case PCI_BAR0_REG:
++ if (value == PCI_BAR_RANGE_MASK) {
++ _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
++ lo |= SOFT_BAR_OHCI_FLAG;
++ _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
++ } else if ((value & 0x01) == 0x00) {
++ _wrmsr(USB_MSR_REG(USB_OHCI), hi, lo);
++
++ value &= 0xfffffff0;
++ hi = 0x40000000 | ((value & 0xff000000) >> 24);
++ lo = 0x000fffff | ((value & 0x00fff000) << 8);
++ _wrmsr(GLIU_MSR_REG(GLIU_P2D_BM3), hi, lo);
++ }
++ break;
++ case PCI_OHCI_INT_REG:
++ _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo);
++ lo &= ~(0xf << PIC_YSEL_LOW_USB_SHIFT);
++ if (value) /* enable all the usb interrupt in PIC */
++ lo |= (CS5536_USB_INTR << PIC_YSEL_LOW_USB_SHIFT);
++ _wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo);
++ break;
++ default:
++ break;
++ }
++}
++
++u32 pci_ohci_read_reg(int reg)
++{
++ u32 conf_data = 0;
++ u32 hi, lo;
++
++ switch (reg) {
++ case PCI_VENDOR_ID:
++ conf_data =
++ CFG_PCI_VENDOR_ID(CS5536_OHCI_DEVICE_ID, CS5536_VENDOR_ID);
++ break;
++ case PCI_COMMAND:
++ _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo);
++ if (hi & PCI_COMMAND_MASTER)
++ conf_data |= PCI_COMMAND_MASTER;
++ if (hi & PCI_COMMAND_MEMORY)
++ conf_data |= PCI_COMMAND_MEMORY;
++ break;
++ case PCI_STATUS:
++ conf_data |= PCI_STATUS_66MHZ;
++ conf_data |= PCI_STATUS_FAST_BACK;
++ _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
++ if (lo & SB_PARE_ERR_FLAG)
++ conf_data |= PCI_STATUS_PARITY;
++ conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
++ break;
++ case PCI_CLASS_REVISION:
++ _rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo);
++ conf_data = lo & 0x000000ff;
++ conf_data |= (CS5536_OHCI_CLASS_CODE << 8);
++ break;
++ case PCI_CACHE_LINE_SIZE:
++ conf_data =
++ CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE,
++ PCI_NORMAL_LATENCY_TIMER);
++ break;
++ case PCI_BAR0_REG:
++ _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
++ if (lo & SOFT_BAR_OHCI_FLAG) {
++ conf_data = CS5536_OHCI_RANGE |
++ PCI_BASE_ADDRESS_SPACE_MEMORY;
++ lo &= ~SOFT_BAR_OHCI_FLAG;
++ _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
++ } else {
++ _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo);
++ conf_data = lo & 0xffffff00;
++ conf_data &= ~0x0000000f; /* 32bit mem */
++ }
++ break;
++ case PCI_CARDBUS_CIS:
++ conf_data = PCI_CARDBUS_CIS_POINTER;
++ break;
++ case PCI_SUBSYSTEM_VENDOR_ID:
++ conf_data =
++ CFG_PCI_VENDOR_ID(CS5536_OHCI_SUB_ID, CS5536_SUB_VENDOR_ID);
++ break;
++ case PCI_ROM_ADDRESS:
++ conf_data = PCI_EXPANSION_ROM_BAR;
++ break;
++ case PCI_CAPABILITY_LIST:
++ conf_data = PCI_CAPLIST_USB_POINTER;
++ break;
++ case PCI_INTERRUPT_LINE:
++ conf_data =
++ CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_USB_INTR);
++ break;
++ case PCI_OHCI_INT_REG:
++ _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo);
++ if ((lo & 0x00000f00) == CS5536_USB_INTR)
++ conf_data = 1;
++ break;
++ default:
++ break;
++ }
++
++ return conf_data;
++}
+diff --git a/arch/mips/loongson/common/cs5536/cs5536_pci.c b/arch/mips/loongson/common/cs5536/cs5536_pci.c
+new file mode 100644
+index 0000000..e23f3d7
+--- /dev/null
++++ b/arch/mips/loongson/common/cs5536/cs5536_pci.c
+@@ -0,0 +1,87 @@
++/*
++ * read/write operation to the PCI config space of CS5536
++ *
++ * Copyright (C) 2007 Lemote, Inc.
++ * Author : jlliu, liujl@lemote.com
++ *
++ * Copyright (C) 2009 Lemote, Inc.
++ * Author: Wu Zhangjin, wuzj@lemote.com
++ *
++ * 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.
++ *
++ * the Virtual Support Module(VSM) for virtulizing the PCI
++ * configure space are defined in cs5536_modulename.c respectively,
++ *
++ * after this virtulizing, user can access the PCI configure space
++ * directly as a normal multi-function PCI device which follows
++ * the PCI-2.2 spec.
++ */
++
++#include <linux/types.h>
++#include <cs5536/cs5536_vsm.h>
++
++enum {
++ CS5536_FUNC_START = -1,
++ CS5536_ISA_FUNC,
++ reserved_func,
++ CS5536_IDE_FUNC,
++ CS5536_ACC_FUNC,
++ CS5536_OHCI_FUNC,
++ CS5536_EHCI_FUNC,
++ CS5536_FUNC_END,
++};
++
++static const cs5536_pci_vsm_write vsm_conf_write[] = {
++ [CS5536_ISA_FUNC] pci_isa_write_reg,
++ [reserved_func] NULL,
++ [CS5536_IDE_FUNC] pci_ide_write_reg,
++ [CS5536_ACC_FUNC] pci_acc_write_reg,
++ [CS5536_OHCI_FUNC] pci_ohci_write_reg,
++ [CS5536_EHCI_FUNC] pci_ehci_write_reg,
++};
++
++static const cs5536_pci_vsm_read vsm_conf_read[] = {
++ [CS5536_ISA_FUNC] pci_isa_read_reg,
++ [reserved_func] NULL,
++ [CS5536_IDE_FUNC] pci_ide_read_reg,
++ [CS5536_ACC_FUNC] pci_acc_read_reg,
++ [CS5536_OHCI_FUNC] pci_ohci_read_reg,
++ [CS5536_EHCI_FUNC] pci_ehci_read_reg,
++};
++
++/*
++ * write to PCI config space and transfer it to MSR write.
++ */
++void cs5536_pci_conf_write4(int function, int reg, u32 value)
++{
++ if ((function <= CS5536_FUNC_START) || (function >= CS5536_FUNC_END))
++ return;
++ if ((reg < 0) || (reg > 0x100) || ((reg & 0x03) != 0))
++ return;
++
++ if (vsm_conf_write[function] != NULL)
++ vsm_conf_write[function](reg, value);
++}
++
++/*
++ * read PCI config space and transfer it to MSR access.
++ */
++u32 cs5536_pci_conf_read4(int function, int reg)
++{
++ u32 data = 0;
++
++ if ((function <= CS5536_FUNC_START) || (function >= CS5536_FUNC_END))
++ return 0;
++ if ((reg < 0) || ((reg & 0x03) != 0))
++ return 0;
++ if (reg > 0x100)
++ return 0xffffffff;
++
++ if (vsm_conf_read[function] != NULL)
++ data = vsm_conf_read[function](reg);
++
++ return data;
++}
+diff --git a/arch/mips/loongson/common/dbg.c b/arch/mips/loongson/common/dbg.c
+new file mode 100644
+index 0000000..e68c947
+--- /dev/null
++++ b/arch/mips/loongson/common/dbg.c
+@@ -0,0 +1,34 @@
++/*
++ * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
++ *
++ * 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 <dbg.h>
++#include <loongson.h>
++
++#define PROM_PRINTF_BUF_LEN 1024
++
++void prom_printf(char *fmt, ...)
++{
++ static char buf[PROM_PRINTF_BUF_LEN];
++ va_list args;
++ char *ptr;
++
++
++ va_start(args, fmt);
++ vscnprintf(buf, sizeof(buf), fmt, args);
++
++ ptr = buf;
++
++ while (*ptr != 0) {
++ if (*ptr == '\n')
++ prom_putchar('\r');
++
++ prom_putchar(*ptr++);
++ }
++ va_end(args);
++}
+diff --git a/arch/mips/loongson/common/early_printk.c b/arch/mips/loongson/common/early_printk.c
+index bc73edc..23e7a8f 100644
+--- a/arch/mips/loongson/common/early_printk.c
++++ b/arch/mips/loongson/common/early_printk.c
+@@ -1,7 +1,7 @@
+ /* early printk support
+ *
+ * Copyright (c) 2009 Philippe Vachon <philippe@cowpig.ca>
+- * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
++ * Copyright (c) 2009 Lemote Inc.
+ * Author: Wu Zhangjin, wuzj@lemote.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+@@ -12,26 +12,29 @@
+ #include <linux/serial_reg.h>
+
+ #include <loongson.h>
+-#include <machine.h>
+
+ #define PORT(base, offset) (u8 *)(base + offset)
+
+-static inline unsigned int serial_in(phys_addr_t base, int offset)
++static inline unsigned int serial_in(unsigned char *base, int offset)
+ {
+ return readb(PORT(base, offset));
+ }
+
+-static inline void serial_out(phys_addr_t base, int offset, int value)
++static inline void serial_out(unsigned char *base, int offset, int value)
+ {
+ writeb(value, PORT(base, offset));
+ }
+
+ void prom_putchar(char c)
+ {
+- phys_addr_t uart_base =
+- (phys_addr_t) ioremap_nocache(LOONGSON_UART_BASE, 8);
++ int timeout;
++ unsigned char *uart_base;
+
+- while ((serial_in(uart_base, UART_LSR) & UART_LSR_THRE) == 0)
++ uart_base = (unsigned char *)_loongson_uart_base;
++ timeout = 1024;
++
++ while (((serial_in(uart_base, UART_LSR) & UART_LSR_THRE) == 0) &&
++ (timeout-- > 0))
+ ;
+
+ serial_out(uart_base, UART_TX, c);
+diff --git a/arch/mips/loongson/common/env.c b/arch/mips/loongson/common/env.c
+index b9ef503..196d947 100644
+--- a/arch/mips/loongson/common/env.c
++++ b/arch/mips/loongson/common/env.c
+@@ -17,11 +17,14 @@
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
++#include <linux/module.h>
++
+ #include <asm/bootinfo.h>
+
+ #include <loongson.h>
+
+ unsigned long bus_clock, cpu_clock_freq;
++EXPORT_SYMBOL(cpu_clock_freq);
+ unsigned long memsize, highmemsize;
+
+ /* pmon passes arguments in 32bit pointers */
+diff --git a/arch/mips/loongson/common/init.c b/arch/mips/loongson/common/init.c
+index 3abe927..a2abd93 100644
+--- a/arch/mips/loongson/common/init.c
++++ b/arch/mips/loongson/common/init.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
++ * Copyright (C) 2009 Lemote Inc.
+ * Author: Wu Zhangjin, wuzj@lemote.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+@@ -10,19 +10,28 @@
+
+ #include <linux/bootmem.h>
+
+-#include <asm/bootinfo.h>
+-
+ #include <loongson.h>
+
++/* Loongson CPU address windows config space base address */
++unsigned long __maybe_unused _loongson_addrwincfg_base;
++
+ void __init prom_init(void)
+ {
+- /* init base address of io space */
++ /* init base address of io space */
+ set_io_port_base((unsigned long)
+- ioremap(BONITO_PCIIO_BASE, BONITO_PCIIO_SIZE));
++ ioremap(LOONGSON_PCIIO_BASE, LOONGSON_PCIIO_SIZE));
++
++#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG
++ _loongson_addrwincfg_base = (unsigned long)
++ ioremap(LOONGSON_ADDRWINCFG_BASE, LOONGSON_ADDRWINCFG_SIZE);
++#endif
+
+ prom_init_cmdline();
+ prom_init_env();
+ prom_init_memory();
++
++ /*init the uart base address */
++ prom_init_uart_base();
+ }
+
+ void __init prom_free_prom_memory(void)
+diff --git a/arch/mips/loongson/common/irq.c b/arch/mips/loongson/common/irq.c
+index b32b4a3..20e7328 100644
+--- a/arch/mips/loongson/common/irq.c
++++ b/arch/mips/loongson/common/irq.c
+@@ -20,21 +20,21 @@ void bonito_irqdispatch(void)
+ int i;
+
+ /* workaround the IO dma problem: let cpu looping to allow DMA finish */
+- int_status = BONITO_INTISR;
++ int_status = LOONGSON_INTISR;
+ if (int_status & (1 << 10)) {
+ while (int_status & (1 << 10)) {
+ udelay(1);
+- int_status = BONITO_INTISR;
++ int_status = LOONGSON_INTISR;
+ }
+ }
+
+ /* Get pending sources, masked by current enables */
+- int_status = BONITO_INTISR & BONITO_INTEN;
++ int_status = LOONGSON_INTISR & LOONGSON_INTEN;
+
+ if (int_status != 0) {
+ i = __ffs(int_status);
+ int_status &= ~(1 << i);
+- do_IRQ(BONITO_IRQ_BASE + i);
++ do_IRQ(LOONGSON_IRQ_BASE + i);
+ }
+ }
+
+@@ -60,13 +60,13 @@ void __init arch_init_irq(void)
+ set_irq_trigger_mode();
+
+ /* no steer */
+- BONITO_INTSTEER = 0;
++ LOONGSON_INTSTEER = 0;
+
+ /*
+ * Mask out all interrupt by writing "1" to all bit position in
+ * the interrupt reset reg.
+ */
+- BONITO_INTENCLR = ~0;
++ LOONGSON_INTENCLR = ~0;
+
+ /* machine specific irq init */
+ mach_init_irq();
+diff --git a/arch/mips/loongson/common/machtype.c b/arch/mips/loongson/common/machtype.c
+index 7b34824..0ed52b3 100644
+--- a/arch/mips/loongson/common/machtype.c
++++ b/arch/mips/loongson/common/machtype.c
+@@ -15,6 +15,9 @@
+ #include <loongson.h>
+ #include <machine.h>
+
++/* please ensure the length of the machtype string is less than 50 */
++#define MACHTYPE_LEN 50
++
+ static const char *system_types[] = {
+ [MACH_LOONGSON_UNKNOWN] "unknown loongson machine",
+ [MACH_LEMOTE_FL2E] "lemote-fuloong-2e-box",
+@@ -22,29 +25,35 @@ static const char *system_types[] = {
+ [MACH_LEMOTE_ML2F7] "lemote-mengloong-2f-7inches",
+ [MACH_LEMOTE_YL2F89] "lemote-yeeloong-2f-8.9inches",
+ [MACH_DEXXON_GDIUM2F10] "dexxon-gidum-2f-10inches",
++ [MACH_LEMOTE_NAS] "lemote-nas-2f",
++ [MACH_LEMOTE_LL2F] "lemote-lynloong-2f",
+ [MACH_LOONGSON_END] NULL,
+ };
+
+ const char *get_system_type(void)
+ {
+- if (mips_machtype == MACH_UNKNOWN)
+- mips_machtype = LOONGSON_MACHTYPE;
+-
+ return system_types[mips_machtype];
+ }
+
+-static __init int machtype_setup(char *str)
++void __init prom_init_machtype(void)
+ {
++ char *p, str[MACHTYPE_LEN];
+ int machtype = MACH_LEMOTE_FL2E;
+
+- if (!str)
+- return -EINVAL;
++ mips_machtype = LOONGSON_MACHTYPE;
++
++ p = strstr(arcs_cmdline, "machtype=");
++ if (!p)
++ return;
++ p += strlen("machtype=");
++ strncpy(str, p, MACHTYPE_LEN);
++ p = strstr(str, " ");
++ if (p)
++ *p = '\0';
+
+ for (; system_types[machtype]; machtype++)
+ if (strstr(system_types[machtype], str)) {
+ mips_machtype = machtype;
+ break;
+ }
+- return 0;
+ }
+-__setup("machtype=", machtype_setup);
+diff --git a/arch/mips/loongson/common/mem.c b/arch/mips/loongson/common/mem.c
+index 7c92f79..f739317 100644
+--- a/arch/mips/loongson/common/mem.c
++++ b/arch/mips/loongson/common/mem.c
+@@ -12,15 +12,40 @@
+
+ #include <loongson.h>
+ #include <mem.h>
++#include <pci.h>
+
+ void __init prom_init_memory(void)
+ {
+ add_memory_region(0x0, (memsize << 20), BOOT_MEM_RAM);
++
++ add_memory_region(memsize << 20, LOONGSON_PCI_MEM_START - (memsize <<
++ 20), BOOT_MEM_RESERVED);
++#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG
++ {
++ int bit;
++
++ bit = fls(memsize + highmemsize);
++ if (bit != ffs(memsize + highmemsize))
++ bit += 20;
++ else
++ bit = bit + 20 - 1;
++
++ /* set cpu window3 to map CPU to DDR: 2G -> 2G */
++ LOONGSON_ADDRWIN_CPUTODDR(ADDRWIN_WIN3, 0x80000000ul,
++ 0x80000000ul, (1 << bit));
++ mmiowb();
++ }
++#endif /* !CONFIG_CPU_SUPPORTS_ADDRWINCFG */
++
+ #ifdef CONFIG_64BIT
+- if (highmemsize > 0)
+- add_memory_region(LOONGSON_HIGHMEM_START,
+- highmemsize << 20, BOOT_MEM_RAM);
+-#endif /* CONFIG_64BIT */
++ if (highmemsize > 0)
++ add_memory_region(LOONGSON_HIGHMEM_START,
++ highmemsize << 20, BOOT_MEM_RAM);
++
++ add_memory_region(LOONGSON_PCI_MEM_END + 1, LOONGSON_HIGHMEM_START -
++ LOONGSON_PCI_MEM_END - 1, BOOT_MEM_RESERVED);
++
++#endif /* !CONFIG_64BIT */
+ }
+
+ /* override of arch/mips/mm/cache.c: __uncached_access */
+@@ -33,3 +58,61 @@ int __uncached_access(struct file *file, unsigned long addr)
+ ((addr >= LOONGSON_MMIO_MEM_START) &&
+ (addr < LOONGSON_MMIO_MEM_END));
+ }
++
++#ifdef CONFIG_CPU_SUPPORTS_UNCACHED_ACCELERATED
++
++#include <linux/pci.h>
++#include <linux/sched.h>
++#include <asm/current.h>
++
++static unsigned long uca_start, uca_end;
++
++pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
++ unsigned long size, pgprot_t vma_prot)
++{
++ unsigned long offset = pfn << PAGE_SHIFT;
++ unsigned long end = offset + size;
++
++ if (__uncached_access(file, offset)) {
++ if (((uca_start && offset) >= uca_start) &&
++ (end <= uca_end))
++ return __pgprot((pgprot_val(vma_prot) &
++ ~_CACHE_MASK) |
++ _CACHE_UNCACHED_ACCELERATED);
++ else
++ return pgprot_noncached(vma_prot);
++ }
++ return vma_prot;
++}
++
++static int __init find_vga_mem_init(void)
++{
++ struct pci_dev *dev = 0;
++ struct resource *r;
++ int idx;
++
++ if (uca_start)
++ return 0;
++
++ for_each_pci_dev(dev) {
++ if ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA) {
++ for (idx = 0; idx < PCI_NUM_RESOURCES; idx++) {
++ r = &dev->resource[idx];
++ if (!r->start && r->end)
++ continue;
++ if (r->flags & IORESOURCE_IO)
++ continue;
++ if (r->flags & IORESOURCE_MEM) {
++ uca_start = r->start;
++ uca_end = r->end;
++ return 0;
++ }
++ }
++ }
++ }
++
++ return 0;
++}
++
++late_initcall(find_vga_mem_init);
++#endif /* !CONFIG_CPU_SUPPORTS_UNCACHED_ACCELERATED */
+diff --git a/arch/mips/loongson/common/mtd.c b/arch/mips/loongson/common/mtd.c
+new file mode 100644
+index 0000000..49a57a7
+--- /dev/null
++++ b/arch/mips/loongson/common/mtd.c
+@@ -0,0 +1,91 @@
++/*
++ * Driver for flushing/dumping ROM of PMON on loongson family machines
++ *
++ * Copyright (C) 2008-2009 Lemote Inc.
++ * Author: Yan Hua <yanh@lemote.com>
++ *
++ * 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 <linux/module.h>
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/map.h>
++#include <linux/mtd/partitions.h>
++
++#include <asm/io.h>
++
++#include <loongson.h>
++
++#define FLASH_PHYS_ADDR LOONGSON_BOOT_BASE
++#define FLASH_SIZE 0x080000
++
++#define FLASH_PARTITION0_ADDR 0x00000000
++#define FLASH_PARTITION0_SIZE 0x00080000
++
++struct map_info flash_map = {
++ .name = "flash device",
++ .size = FLASH_SIZE,
++ .bankwidth = 1,
++};
++
++struct mtd_partition flash_parts[] = {
++ {
++ .name = "Bootloader",
++ .offset = FLASH_PARTITION0_ADDR,
++ .size = FLASH_PARTITION0_SIZE},
++};
++
++#define PARTITION_COUNT ARRAY_SIZE(flash_parts)
++
++static struct mtd_info *mymtd;
++
++int __init init_flash(void)
++{
++ printk(KERN_NOTICE "flash device: %x at %x\n",
++ FLASH_SIZE, FLASH_PHYS_ADDR);
++
++ flash_map.phys = FLASH_PHYS_ADDR;
++ flash_map.virt = ioremap(FLASH_PHYS_ADDR, FLASH_SIZE);
++
++ if (!flash_map.virt) {
++ printk(KERN_NOTICE "Failed to ioremap\n");
++ return -EIO;
++ }
++
++ simple_map_init(&flash_map);
++
++ mymtd = do_map_probe("cfi_probe", &flash_map);
++ if (mymtd) {
++ add_mtd_partitions(mymtd, flash_parts, PARTITION_COUNT);
++ printk(KERN_NOTICE "pmon flash device initialized\n");
++ return 0;
++ }
++
++ iounmap((void *)flash_map.virt);
++ return -ENXIO;
++}
++
++static void __exit cleanup_flash(void)
++{
++ if (mymtd) {
++ del_mtd_partitions(mymtd);
++ map_destroy(mymtd);
++ }
++ if (flash_map.virt) {
++ iounmap((void *)flash_map.virt);
++ flash_map.virt = 0;
++ }
++}
++
++module_init(init_flash);
++module_exit(cleanup_flash);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Yanhua <yanh@lemote.com>");
++MODULE_DESCRIPTION("MTD driver for pmon flushing/dumping");
+diff --git a/arch/mips/loongson/common/pci.c b/arch/mips/loongson/common/pci.c
+index a3a4abf..31d8c5e 100644
+--- a/arch/mips/loongson/common/pci.c
++++ b/arch/mips/loongson/common/pci.c
+@@ -27,7 +27,7 @@ static struct resource loongson_pci_io_resource = {
+ };
+
+ static struct pci_controller loongson_pci_controller = {
+- .pci_ops = &bonito64_pci_ops,
++ .pci_ops = &loongson_pci_ops,
+ .io_resource = &loongson_pci_io_resource,
+ .mem_resource = &loongson_pci_mem_resource,
+ .mem_offset = 0x00000000UL,
+@@ -44,15 +44,15 @@ static void __init setup_pcimap(void)
+ * pcimap: PCI_MAP2 PCI_Mem_Lo2 PCI_Mem_Lo1 PCI_Mem_Lo0
+ * [<2G] [384M,448M] [320M,384M] [0M,64M]
+ */
+- BONITO_PCIMAP = BONITO_PCIMAP_PCIMAP_2 |
+- BONITO_PCIMAP_WIN(2, BONITO_PCILO2_BASE) |
+- BONITO_PCIMAP_WIN(1, BONITO_PCILO1_BASE) |
+- BONITO_PCIMAP_WIN(0, 0);
++ LOONGSON_PCIMAP = LOONGSON_PCIMAP_PCIMAP_2 |
++ LOONGSON_PCIMAP_WIN(2, LOONGSON_PCILO2_BASE) |
++ LOONGSON_PCIMAP_WIN(1, LOONGSON_PCILO1_BASE) |
++ LOONGSON_PCIMAP_WIN(0, 0);
+
+ /*
+ * PCI-DMA to local mapping: [2G,2G+256M] -> [0M,256M]
+ */
+- BONITO_PCIBASE0 = 0x80000000ul; /* base: 2G -> mmap: 0M */
++ LOONGSON_PCIBASE0 = 0x80000000ul; /* base: 2G -> mmap: 0M */
+ /* size: 256M, burst transmission, pre-fetch enable, 64bit */
+ LOONGSON_PCI_HIT0_SEL_L = 0xc000000cul;
+ LOONGSON_PCI_HIT0_SEL_H = 0xfffffffful;
+@@ -67,6 +67,14 @@ static void __init setup_pcimap(void)
+ /* can not change gnt to break pci transfer when device's gnt not
+ deassert for some broken device */
+ LOONGSON_PXARB_CFG = 0x00fe0105ul;
++
++#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG
++ /*
++ * set cpu addr window2 to map CPU address space to PCI address space
++ */
++ LOONGSON_ADDRWIN_CPUTOPCI(ADDRWIN_WIN2, LOONGSON_CPU_MEM_SRC,
++ LOONGSON_PCI_MEM_DST, MMAP_CPUTOPCI_SIZE);
++#endif
+ }
+
+ static int __init pcibios_init(void)
+diff --git a/arch/mips/loongson/common/platform.c b/arch/mips/loongson/common/platform.c
+new file mode 100644
+index 0000000..be81777
+--- /dev/null
++++ b/arch/mips/loongson/common/platform.c
+@@ -0,0 +1,30 @@
++/*
++ * Copyright (C) 2009 Lemote Inc.
++ * Author: Wu Zhangjin, wuzj@lemote.com
++ *
++ * 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 <linux/err.h>
++#include <linux/platform_device.h>
++
++static struct platform_device loongson2_cpufreq_device = {
++ .name = "loongson2_cpufreq",
++ .id = -1,
++};
++
++static int __init loongson2_cpufreq_init(void)
++{
++ struct cpuinfo_mips *c = &current_cpu_data;
++
++ /* Only 2F revision and it's successors support CPUFreq */
++ if ((c->processor_id & PRID_REV_MASK) >= PRID_REV_LOONGSON2F)
++ return platform_device_register(&loongson2_cpufreq_device);
++
++ return -ENODEV;
++}
++
++arch_initcall(loongson2_cpufreq_init);
+diff --git a/arch/mips/loongson/common/pm.c b/arch/mips/loongson/common/pm.c
+new file mode 100644
+index 0000000..5a42868
+--- /dev/null
++++ b/arch/mips/loongson/common/pm.c
+@@ -0,0 +1,165 @@
++/*
++ * loongson-specific suspend support
++ *
++ * Copyright (C) 2009 Lemote Inc.
++ * Author: Wu Zhangjin <wuzj@lemote.com>
++ *
++ * 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 <linux/suspend.h>
++#include <linux/interrupt.h>
++#include <linux/pm.h>
++
++#include <asm/i8259.h>
++#include <asm/mipsregs.h>
++
++#include <loongson.h>
++
++#include <cs5536/cs5536_mfgpt.h>
++
++static unsigned int __maybe_unused cached_master_mask; /* i8259A */
++static unsigned int __maybe_unused cached_slave_mask;
++static unsigned int __maybe_unused cached_bonito_irq_mask; /* bonito */
++
++void arch_suspend_disable_irqs(void)
++{
++ /* disable all mips events */
++ local_irq_disable();
++
++#ifdef CONFIG_I8259
++ /* disable all events of i8259A */
++ cached_slave_mask = inb(PIC_SLAVE_IMR);
++ cached_master_mask = inb(PIC_MASTER_IMR);
++
++ outb(0xff, PIC_SLAVE_IMR);
++ inb(PIC_SLAVE_IMR);
++ outb(0xff, PIC_MASTER_IMR);
++ inb(PIC_MASTER_IMR);
++#endif
++ /* disable all events of bonito */
++ cached_bonito_irq_mask = LOONGSON_INTEN;
++ LOONGSON_INTENCLR = 0xffff;
++ (void)LOONGSON_INTENCLR;
++}
++
++void arch_suspend_enable_irqs(void)
++{
++ /* enable all mips events */
++ local_irq_enable();
++#ifdef CONFIG_I8259
++ /* only enable the cached events of i8259A */
++ outb(cached_slave_mask, PIC_SLAVE_IMR);
++ outb(cached_master_mask, PIC_MASTER_IMR);
++#endif
++ /* enable all cached events of bonito */
++ LOONGSON_INTENSET = cached_bonito_irq_mask;
++ (void)LOONGSON_INTENSET;
++}
++
++/*
++ * Setup the board-specific events for waking up loongson from wait mode
++ */
++void __weak setup_wakeup_events(void)
++{
++}
++
++/*
++ * Check wakeup events
++ */
++int __weak wakeup_loongson(void)
++{
++ return 1;
++}
++
++/*
++ * If the events are really what we want to wakeup the CPU, wake it up
++ * otherwise put the CPU asleep again.
++ */
++static void wait_for_wakeup_events(void)
++{
++ while (!wakeup_loongson())
++ LOONGSON_CHIPCFG0 &= ~0x7;
++}
++
++/*
++ * Stop all perf counters
++ *
++ * $24 is the control register of Loongson perf counter
++ */
++static inline void stop_perf_counters(void)
++{
++ __write_64bit_c0_register($24, 0, 0);
++}
++
++
++static void loongson_suspend_enter(void)
++{
++ static unsigned int cached_cpu_freq;
++
++ /* setup wakeup events via enabling the IRQs */
++ setup_wakeup_events();
++
++ stop_perf_counters();
++
++ cached_cpu_freq = LOONGSON_CHIPCFG0;
++
++ /* Put CPU into wait mode */
++ LOONGSON_CHIPCFG0 &= ~0x7;
++
++ /* wait for the given events to wakeup cpu from wait mode */
++ wait_for_wakeup_events();
++
++ LOONGSON_CHIPCFG0 = cached_cpu_freq;
++ mmiowb();
++}
++
++void __weak mach_suspend(void)
++{
++ disable_mfgpt0_counter();
++}
++
++void __weak mach_resume(void)
++{
++ enable_mfgpt0_counter();
++}
++
++static int loongson_pm_enter(suspend_state_t state)
++{
++ mach_suspend();
++
++ /* processor specific suspend */
++ loongson_suspend_enter();
++
++ mach_resume();
++
++ return 0;
++}
++
++static int loongson_pm_valid_state(suspend_state_t state)
++{
++ switch (state) {
++ case PM_SUSPEND_ON:
++ case PM_SUSPEND_STANDBY:
++ case PM_SUSPEND_MEM:
++ return 1;
++
++ default:
++ return 0;
++ }
++}
++
++static struct platform_suspend_ops loongson_pm_ops = {
++ .valid = loongson_pm_valid_state,
++ .enter = loongson_pm_enter,
++};
++
++static int __init loongson_pm_init(void)
++{
++ suspend_set_ops(&loongson_pm_ops);
++
++ return 0;
++}
++arch_initcall(loongson_pm_init);
+diff --git a/arch/mips/loongson/common/reset.c b/arch/mips/loongson/common/reset.c
+index 97e9182..dbe62f6 100644
+--- a/arch/mips/loongson/common/reset.c
++++ b/arch/mips/loongson/common/reset.c
+@@ -21,8 +21,20 @@ static void loongson_restart(char *command)
+ /* do preparation for reboot */
+ mach_prepare_reboot();
+
+- /* reboot via jumping to boot base address */
+- ((void (*)(void))ioremap_nocache(BONITO_BOOT_BASE, 4)) ();
++ /* reboot via jumping to boot base address
++ *
++ * ".set noat" and ".set at" are used to ensure the address not
++ * polluted by the binutils patch. the patch will try to change the
++ * jumping address to "addr & 0xcfffffff" via the at register, which is
++ * really wrong for 0xbfc00000:
++ */
++
++ __asm__ __volatile__(".set noat\n"
++ ".long 0x3c02bfc0\n"
++ ".long 0x00400008\n"
++ ".set at\n"
++ :::"v0");
++
+ }
+
+ static void loongson_halt(void)
+diff --git a/arch/mips/loongson/common/rtc.c b/arch/mips/loongson/common/rtc.c
+new file mode 100644
+index 0000000..1f88791
+--- /dev/null
++++ b/arch/mips/loongson/common/rtc.c
+@@ -0,0 +1,43 @@
++/*
++ * Registration of Loongson RTC platform device.
++ *
++ * Copyright (C) 2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
++ * Copyright (C) 2009 Wu Zhangjin <wuzj@lemote.com>
++ *
++ * 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 <linux/init.h>
++#include <linux/ioport.h>
++#include <linux/mc146818rtc.h>
++#include <linux/platform_device.h>
++
++static struct resource rtc_cmos_resource[] = {
++ {
++ .start = RTC_PORT(0),
++ .end = RTC_PORT(1),
++ .flags = IORESOURCE_IO,
++ },
++ {
++ .start = RTC_IRQ,
++ .end = RTC_IRQ,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct platform_device rtc_cmos_device = {
++ .name = "rtc_cmos",
++ .id = -1,
++ .num_resources = ARRAY_SIZE(rtc_cmos_resource),
++ .resource = rtc_cmos_resource
++};
++
++static __init int rtc_cmos_init(void)
++{
++ return platform_device_register(&rtc_cmos_device);
++}
++
++device_initcall(rtc_cmos_init);
+diff --git a/arch/mips/loongson/common/serial.c b/arch/mips/loongson/common/serial.c
+new file mode 100644
+index 0000000..23b66a5
+--- /dev/null
++++ b/arch/mips/loongson/common/serial.c
+@@ -0,0 +1,76 @@
++/*
++ * 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) 2007 Ralf Baechle (ralf@linux-mips.org)
++ *
++ * Copyright (C) 2009 Lemote, Inc.
++ * Author: Yan hua (yanhua@lemote.com)
++ * Author: Wu Zhangjin (wuzj@lemote.com)
++ */
++
++#include <linux/io.h>
++#include <linux/init.h>
++#include <linux/serial_8250.h>
++
++#include <asm/bootinfo.h>
++
++#include <loongson.h>
++#include <machine.h>
++
++#define PORT(int) \
++{ \
++ .irq = int, \
++ .uartclk = 1843200, \
++ .iotype = UPIO_PORT, \
++ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, \
++ .regshift = 0, \
++}
++
++#define PORT_M(int) \
++{ \
++ .irq = MIPS_CPU_IRQ_BASE + (int), \
++ .uartclk = 3686400, \
++ .iotype = UPIO_MEM, \
++ .membase = (void __iomem *)NULL, \
++ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, \
++ .regshift = 0, \
++}
++
++static struct plat_serial8250_port uart8250_data[][2] = {
++ [MACH_LOONGSON_UNKNOWN] {},
++ [MACH_LEMOTE_FL2E] {PORT(4), {} },
++ [MACH_LEMOTE_FL2F] {PORT(3), {} },
++ [MACH_LEMOTE_ML2F7] {PORT_M(3), {} },
++ [MACH_LEMOTE_YL2F89] {PORT_M(3), {} },
++ [MACH_DEXXON_GDIUM2F10] {PORT_M(3), {} },
++ [MACH_LEMOTE_NAS] {PORT_M(3), {} },
++ [MACH_LEMOTE_LL2F] {PORT(3), {} },
++ [MACH_LOONGSON_END] {},
++};
++
++static struct platform_device uart8250_device = {
++ .name = "serial8250",
++ .id = PLAT8250_DEV_PLATFORM,
++};
++
++static int __init serial_init(void)
++{
++ unsigned char iotype;
++
++ iotype = uart8250_data[mips_machtype][0].iotype;
++
++ if (UPIO_MEM == iotype)
++ uart8250_data[mips_machtype][0].membase =
++ (void __iomem *)_loongson_uart_base;
++ else if (UPIO_PORT == iotype)
++ uart8250_data[mips_machtype][0].iobase =
++ loongson_uart_base - LOONGSON_PCIIO_BASE;
++
++ uart8250_device.dev.platform_data = uart8250_data[mips_machtype];
++
++ return platform_device_register(&uart8250_device);
++}
++
++device_initcall(serial_init);
+diff --git a/arch/mips/loongson/common/time.c b/arch/mips/loongson/common/time.c
+index 6e08c82..35f0b66 100644
+--- a/arch/mips/loongson/common/time.c
++++ b/arch/mips/loongson/common/time.c
+@@ -14,11 +14,14 @@
+ #include <asm/time.h>
+
+ #include <loongson.h>
++#include <cs5536/cs5536_mfgpt.h>
+
+ void __init plat_time_init(void)
+ {
+ /* setup mips r4k timer */
+ mips_hpt_frequency = cpu_clock_freq / 2;
++
++ setup_mfgpt0_timer();
+ }
+
+ void read_persistent_clock(struct timespec *ts)
+diff --git a/arch/mips/loongson/common/uart_base.c b/arch/mips/loongson/common/uart_base.c
+new file mode 100644
+index 0000000..78ff66a
+--- /dev/null
++++ b/arch/mips/loongson/common/uart_base.c
+@@ -0,0 +1,45 @@
++/*
++ * Copyright (C) 2009 Lemote Inc.
++ * Author: Wu Zhangjin, wuzj@lemote.com
++ *
++ * 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 <linux/module.h>
++#include <asm/bootinfo.h>
++
++#include <loongson.h>
++
++/* ioremapped */
++unsigned long _loongson_uart_base;
++EXPORT_SYMBOL(_loongson_uart_base);
++/* raw */
++unsigned long loongson_uart_base;
++EXPORT_SYMBOL(loongson_uart_base);
++
++void prom_init_loongson_uart_base(void)
++{
++ switch (mips_machtype) {
++ case MACH_LEMOTE_FL2E:
++ loongson_uart_base = LOONGSON_PCIIO_BASE + 0x3f8;
++ break;
++ case MACH_LEMOTE_FL2F:
++ case MACH_LEMOTE_LL2F:
++ loongson_uart_base = LOONGSON_PCIIO_BASE + 0x2f8;
++ break;
++ case MACH_LEMOTE_ML2F7:
++ case MACH_LEMOTE_YL2F89:
++ case MACH_DEXXON_GDIUM2F10:
++ case MACH_LEMOTE_NAS:
++ default:
++ /* The CPU provided serial port */
++ loongson_uart_base = LOONGSON_LIO1_BASE + 0x3f8;
++ break;
++ }
++
++ _loongson_uart_base =
++ (unsigned long)ioremap_nocache(loongson_uart_base, 8);
++}
+diff --git a/arch/mips/loongson/fuloong-2e/irq.c b/arch/mips/loongson/fuloong-2e/irq.c
+index 7888cf6..320e937 100644
+--- a/arch/mips/loongson/fuloong-2e/irq.c
++++ b/arch/mips/loongson/fuloong-2e/irq.c
+@@ -47,8 +47,8 @@ static struct irqaction cascade_irqaction = {
+ void __init set_irq_trigger_mode(void)
+ {
+ /* most bonito irq should be level triggered */
+- BONITO_INTEDGE = BONITO_ICU_SYSTEMERR | BONITO_ICU_MASTERERR |
+- BONITO_ICU_RETRYERR | BONITO_ICU_MBOXES;
++ LOONGSON_INTEDGE = LOONGSON_ICU_SYSTEMERR | LOONGSON_ICU_MASTERERR |
++ LOONGSON_ICU_RETRYERR | LOONGSON_ICU_MBOXES;
+ }
+
+ void __init mach_init_irq(void)
+diff --git a/arch/mips/loongson/fuloong-2e/reset.c b/arch/mips/loongson/fuloong-2e/reset.c
+index 677fe18..fc16c67 100644
+--- a/arch/mips/loongson/fuloong-2e/reset.c
++++ b/arch/mips/loongson/fuloong-2e/reset.c
+@@ -14,8 +14,8 @@
+
+ void mach_prepare_reboot(void)
+ {
+- BONITO_BONGENCFG &= ~(1 << 2);
+- BONITO_BONGENCFG |= (1 << 2);
++ LOONGSON_GENCFG &= ~(1 << 2);
++ LOONGSON_GENCFG |= (1 << 2);
+ }
+
+ void mach_prepare_shutdown(void)
+diff --git a/arch/mips/loongson/lemote-2f/Makefile b/arch/mips/loongson/lemote-2f/Makefile
+new file mode 100644
+index 0000000..0d7bee0
+--- /dev/null
++++ b/arch/mips/loongson/lemote-2f/Makefile
+@@ -0,0 +1,17 @@
++#
++# Makefile for lemote loongson2f family machines
++#
++
++obj-y += irq.o reset.o ec_kb3310b.o platform.o
++
++#
++# Suspend Support
++#
++
++obj-$(CONFIG_LOONGSON_SUSPEND) += pm.o
++
++#
++# Platform Drivers
++#
++obj-$(CONFIG_LEMOTE_LYNLOONG2F_PDEV) += lynloong_pc.o
++obj-$(CONFIG_LEMOTE_YEELOONG2F_PDEV) += yeeloong_laptop.o
+diff --git a/arch/mips/loongson/lemote-2f/ec_kb3310b.c b/arch/mips/loongson/lemote-2f/ec_kb3310b.c
+new file mode 100644
+index 0000000..1ca38a8
+--- /dev/null
++++ b/arch/mips/loongson/lemote-2f/ec_kb3310b.c
+@@ -0,0 +1,132 @@
++/*
++ * EC(Embedded Controller) KB3310B basic support for YeeLoong2F netbook
++ *
++ * Copyright (C) 2008 Lemote Inc.
++ * Author: liujl <liujl@lemote.com>, 2008-04-20
++ *
++ * 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 <linux/module.h>
++#include <linux/delay.h>
++
++#include "ec_kb3310b.h"
++
++/* this spinlock is dedicated for ec_read & ec_write function */
++DEFINE_SPINLOCK(index_access_lock);
++/* this spinlock is dedicated for 62&66 ports access */
++DEFINE_SPINLOCK(port_access_lock);
++
++/* read a byte from EC registers throught index-io */
++unsigned char ec_read(unsigned short addr)
++{
++ unsigned char value;
++ unsigned long flags;
++
++ spin_lock_irqsave(&index_access_lock, flags);
++ outb((addr & 0xff00) >> 8, EC_IO_PORT_HIGH);
++ outb((addr & 0x00ff), EC_IO_PORT_LOW);
++ value = inb(EC_IO_PORT_DATA);
++ spin_unlock_irqrestore(&index_access_lock, flags);
++
++ return value;
++}
++EXPORT_SYMBOL_GPL(ec_read);
++
++/* write a byte to EC registers throught index-io */
++void ec_write(unsigned short addr, unsigned char val)
++{
++ unsigned long flags;
++
++ spin_lock_irqsave(&index_access_lock, flags);
++ outb((addr & 0xff00) >> 8, EC_IO_PORT_HIGH);
++ outb((addr & 0x00ff), EC_IO_PORT_LOW);
++ outb(val, EC_IO_PORT_DATA);
++ /* flush the write action */
++ inb(EC_IO_PORT_DATA);
++ spin_unlock_irqrestore(&index_access_lock, flags);
++
++ return;
++}
++EXPORT_SYMBOL_GPL(ec_write);
++
++/*
++ * this function is used for ec command writing and corresponding status query
++ */
++int ec_query_seq(unsigned char cmd)
++{
++ int timeout;
++ unsigned char status;
++ unsigned long flags;
++ int ret = 0;
++
++ spin_lock_irqsave(&port_access_lock, flags);
++
++ /* make chip goto reset mode */
++ udelay(EC_REG_DELAY);
++ outb(cmd, EC_CMD_PORT);
++ udelay(EC_REG_DELAY);
++
++ /* check if the command is received by ec */
++ timeout = EC_CMD_TIMEOUT;
++ status = inb(EC_STS_PORT);
++ while (timeout-- && (status & (1 << 1))) {
++ status = inb(EC_STS_PORT);
++ udelay(EC_REG_DELAY);
++ }
++
++ if (timeout <= 0) {
++ printk(KERN_ERR "%s: deadable error : timeout...\n", __func__);
++ ret = -EINVAL;
++ } else
++ printk(KERN_INFO
++ "(%x/%d)ec issued command %d status : 0x%x\n",
++ timeout, EC_CMD_TIMEOUT - timeout, cmd, status);
++
++ spin_unlock_irqrestore(&port_access_lock, flags);
++
++ return ret;
++}
++EXPORT_SYMBOL_GPL(ec_query_seq);
++
++/*
++ * using query command to ec to get the proper event number
++ */
++int ec_query_event_num(void)
++{
++ return ec_query_seq(CMD_GET_EVENT_NUM);
++}
++EXPORT_SYMBOL(ec_query_event_num);
++
++/*
++ * get event number from ec
++ *
++ * NOTE : this routine must follow the query_event_num function in the
++ * interrupt
++ */
++int ec_get_event_num(void)
++{
++ int timeout = 100;
++ unsigned char value;
++ unsigned char status;
++
++ udelay(EC_REG_DELAY);
++ status = inb(EC_STS_PORT);
++ udelay(EC_REG_DELAY);
++ while (timeout-- && !(status & (1 << 0))) {
++ status = inb(EC_STS_PORT);
++ udelay(EC_REG_DELAY);
++ }
++ if (timeout <= 0) {
++ printk(KERN_INFO "%s: get event number timeout.\n", __func__);
++ return -EINVAL;
++ }
++ value = inb(EC_DAT_PORT);
++ udelay(EC_REG_DELAY);
++
++ return value;
++}
++EXPORT_SYMBOL(ec_get_event_num);
+diff --git a/arch/mips/loongson/lemote-2f/ec_kb3310b.h b/arch/mips/loongson/lemote-2f/ec_kb3310b.h
+new file mode 100644
+index 0000000..f7bb249
+--- /dev/null
++++ b/arch/mips/loongson/lemote-2f/ec_kb3310b.h
+@@ -0,0 +1,197 @@
++/*
++ * EC(Embedded Controller) KB3310B header file
++ *
++ * Copyright (C) 2008 Lemote Inc.
++ * Author: liujl <liujl@lemote.com>, 2008-03-14
++ *
++ * 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 _EC_KB3310B_H
++#define _EC_KB3310B_H
++
++extern unsigned char ec_read(unsigned short addr);
++extern void ec_write(unsigned short addr, unsigned char val);
++extern int ec_query_seq(unsigned char cmd);
++extern int ec_query_event_num(void);
++extern int ec_get_event_num(void);
++
++typedef int (*sci_handler) (int status);
++extern sci_handler yeeloong_report_lid_status;
++extern int yeeloong_install_sci_handler(int event, sci_handler handler);
++extern int yeeloong_uninstall_sci_handler(int event, sci_handler handler);
++
++#define SCI_IRQ_NUM 0x0A
++
++/*
++ * The following registers are determined by the EC index configuration.
++ * 1, fill the PORT_HIGH as EC register high part.
++ * 2, fill the PORT_LOW as EC register low part.
++ * 3, fill the PORT_DATA as EC register write data or get the data from it.
++ */
++#define EC_IO_PORT_HIGH 0x0381
++#define EC_IO_PORT_LOW 0x0382
++#define EC_IO_PORT_DATA 0x0383
++
++/* ec delay time 500us for register and status access */
++#define EC_REG_DELAY 500 /* unit : us */
++#define EC_CMD_TIMEOUT 0x1000
++
++/* EC access port for sci communication */
++#define EC_CMD_PORT 0x66
++#define EC_STS_PORT 0x66
++#define EC_DAT_PORT 0x62
++#define CMD_INIT_IDLE_MODE 0xdd
++#define CMD_EXIT_IDLE_MODE 0xdf
++#define CMD_INIT_RESET_MODE 0xd8
++#define CMD_REBOOT_SYSTEM 0x8c
++#define CMD_GET_EVENT_NUM 0x84
++#define CMD_PROGRAM_PIECE 0xda
++
++/* temperature & fan registers */
++#define REG_TEMPERATURE_VALUE 0xF458
++#define REG_FAN_AUTO_MAN_SWITCH 0xF459
++#define BIT_FAN_AUTO 0
++#define BIT_FAN_MANUAL 1
++#define REG_FAN_CONTROL 0xF4D2
++#define BIT_FAN_CONTROL_ON (1 << 0)
++#define BIT_FAN_CONTROL_OFF (0 << 0)
++#define REG_FAN_STATUS 0xF4DA
++#define BIT_FAN_STATUS_ON (1 << 0)
++#define BIT_FAN_STATUS_OFF (0 << 0)
++#define REG_FAN_SPEED_HIGH 0xFE22
++#define REG_FAN_SPEED_LOW 0xFE23
++#define REG_FAN_SPEED_LEVEL 0xF4CC
++/* fan speed divider */
++#define FAN_SPEED_DIVIDER 480000 /* (60*1000*1000/62.5/2)*/
++
++/* battery registers */
++#define REG_BAT_DESIGN_CAP_HIGH 0xF77D
++#define REG_BAT_DESIGN_CAP_LOW 0xF77E
++#define REG_BAT_FULLCHG_CAP_HIGH 0xF780
++#define REG_BAT_FULLCHG_CAP_LOW 0xF781
++#define REG_BAT_DESIGN_VOL_HIGH 0xF782
++#define REG_BAT_DESIGN_VOL_LOW 0xF783
++#define REG_BAT_CURRENT_HIGH 0xF784
++#define REG_BAT_CURRENT_LOW 0xF785
++#define REG_BAT_VOLTAGE_HIGH 0xF786
++#define REG_BAT_VOLTAGE_LOW 0xF787
++#define REG_BAT_TEMPERATURE_HIGH 0xF788
++#define REG_BAT_TEMPERATURE_LOW 0xF789
++#define REG_BAT_RELATIVE_CAP_HIGH 0xF492
++#define REG_BAT_RELATIVE_CAP_LOW 0xF493
++#define REG_BAT_VENDOR 0xF4C4
++#define FLAG_BAT_VENDOR_SANYO 0x01
++#define FLAG_BAT_VENDOR_SIMPLO 0x02
++#define REG_BAT_CELL_COUNT 0xF4C6
++#define FLAG_BAT_CELL_3S1P 0x03
++#define FLAG_BAT_CELL_3S2P 0x06
++#define REG_BAT_CHARGE 0xF4A2
++#define FLAG_BAT_CHARGE_DISCHARGE 0x01
++#define FLAG_BAT_CHARGE_CHARGE 0x02
++#define FLAG_BAT_CHARGE_ACPOWER 0x00
++#define REG_BAT_STATUS 0xF4B0
++#define BIT_BAT_STATUS_LOW (1 << 5)
++#define BIT_BAT_STATUS_DESTROY (1 << 2)
++#define BIT_BAT_STATUS_FULL (1 << 1)
++#define BIT_BAT_STATUS_IN (1 << 0)
++#define REG_BAT_CHARGE_STATUS 0xF4B1
++#define BIT_BAT_CHARGE_STATUS_OVERTEMP (1 << 2)
++#define BIT_BAT_CHARGE_STATUS_PRECHG (1 << 1)
++#define REG_BAT_STATE 0xF482
++#define BIT_BAT_STATE_CHARGING (1 << 1)
++#define BIT_BAT_STATE_DISCHARGING (1 << 0)
++#define REG_BAT_POWER 0xF440
++#define BIT_BAT_POWER_S3 (1 << 2)
++#define BIT_BAT_POWER_ON (1 << 1)
++#define BIT_BAT_POWER_ACIN (1 << 0)
++
++/* other registers */
++/* Audio: rd/wr */
++#define REG_AUDIO_VOLUME 0xF46C
++#define REG_AUDIO_MUTE 0xF4E7
++#define REG_AUDIO_BEEP 0xF4D0
++/* USB port power or not: rd/wr */
++#define REG_USB0_FLAG 0xF461
++#define REG_USB1_FLAG 0xF462
++#define REG_USB2_FLAG 0xF463
++#define BIT_USB_FLAG_ON 1
++#define BIT_USB_FLAG_OFF 0
++/* LID */
++#define REG_LID_DETECT 0xF4BD
++#define BIT_LID_DETECT_ON 1
++#define BIT_LID_DETECT_OFF 0
++/* CRT */
++#define REG_CRT_DETECT 0xF4AD
++#define BIT_CRT_DETECT_PLUG 1
++#define BIT_CRT_DETECT_UNPLUG 0
++/* LCD backlight brightness adjust: 9 levels */
++#define REG_DISPLAY_BRIGHTNESS 0xF4F5
++/* Black screen Status */
++#define BIT_DISPLAY_LCD_ON 1
++#define BIT_DISPLAY_LCD_OFF 0
++/* LCD backlight control: off/restore */
++#define REG_BACKLIGHT_CTRL 0xF7BD
++#define BIT_BACKLIGHT_ON 1
++#define BIT_BACKLIGHT_OFF 0
++/* Reset the machine auto-clear: rd/wr */
++#define REG_RESET 0xF4EC
++#define BIT_RESET_ON 1
++#define BIT_RESET_OFF 0
++/* Light the led: rd/wr */
++#define REG_LED 0xF4C8
++#define BIT_LED_RED_POWER (1 << 0)
++#define BIT_LED_ORANGE_POWER (1 << 1)
++#define BIT_LED_GREEN_CHARGE (1 << 2)
++#define BIT_LED_RED_CHARGE (1 << 3)
++#define BIT_LED_NUMLOCK (1 << 4)
++/* Test led mode, all led on/off */
++#define REG_LED_TEST 0xF4C2
++#define BIT_LED_TEST_IN 1
++#define BIT_LED_TEST_OUT 0
++/* Camera on/off */
++#define REG_CAMERA_STATUS 0xF46A
++#define BIT_CAMERA_STATUS_ON 1
++#define BIT_CAMERA_STATUS_OFF 0
++#define REG_CAMERA_CONTROL 0xF7B7
++#define BIT_CAMERA_CONTROL_OFF 0
++#define BIT_CAMERA_CONTROL_ON 1
++/* Wlan Status */
++#define REG_WLAN 0xF4FA
++#define BIT_WLAN_ON 1
++#define BIT_WLAN_OFF 0
++#define REG_DISPLAY_LCD 0xF79F
++
++/* SCI Event Number from EC */
++enum {
++ EVENT_LID = 0x23, /* LID open/close */
++ EVENT_DISPLAY_TOGGLE, /* Fn+F3 for display switch */
++ EVENT_SLEEP, /* Fn+F1 for entering sleep mode */
++ EVENT_OVERTEMP, /* Over-temperature happened */
++ EVENT_CRT_DETECT, /* CRT is connected */
++ EVENT_CAMERA, /* Camera on/off */
++ EVENT_USB_OC2, /* USB2 Over Current occurred */
++ EVENT_USB_OC0, /* USB0 Over Current occurred */
++ EVENT_BLACK_SCREEN, /* Black screen on/off */
++ EVENT_AUDIO_MUTE, /* Mute is on or off */
++ EVENT_DISPLAY_BRIGHTNESS,/* LCD backlight brightness adjust */
++ EVENT_AC_BAT, /* AC & Battery relative issue */
++ EVENT_AUDIO_VOLUME, /* Volume adjust */
++ EVENT_WLAN, /* Wlan on/off */
++ EVENT_END
++};
++
++enum {
++ BIT_AC_BAT_BAT_IN = 0,
++ BIT_AC_BAT_AC_IN,
++ BIT_AC_BAT_INIT_CAP,
++ BIT_AC_BAT_CHARGE_MODE,
++ BIT_AC_BAT_STOP_CHARGE,
++ BIT_AC_BAT_BAT_LOW,
++ BIT_AC_BAT_BAT_FULL
++};
++
++#endif /* !_EC_KB3310B_H */
+diff --git a/arch/mips/loongson/lemote-2f/irq.c b/arch/mips/loongson/lemote-2f/irq.c
+new file mode 100644
+index 0000000..77d32f9
+--- /dev/null
++++ b/arch/mips/loongson/lemote-2f/irq.c
+@@ -0,0 +1,134 @@
++/*
++ * Copyright (C) 2007 Lemote Inc.
++ * Author: Fuxin Zhang, zhangfx@lemote.com
++ *
++ * 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 <linux/interrupt.h>
++#include <linux/module.h>
++
++#include <asm/irq_cpu.h>
++#include <asm/i8259.h>
++#include <asm/mipsregs.h>
++
++#include <loongson.h>
++#include <machine.h>
++
++#define LOONGSON_TIMER_IRQ (MIPS_CPU_IRQ_BASE + 7) /* cpu timer */
++#define LOONGSON_PERFCNT_IRQ (MIPS_CPU_IRQ_BASE + 6) /* cpu perf counter */
++#define LOONGSON_NORTH_BRIDGE_IRQ (MIPS_CPU_IRQ_BASE + 6) /* bonito */
++#define LOONGSON_UART_IRQ (MIPS_CPU_IRQ_BASE + 3) /* cpu serial port */
++#define LOONGSON_SOUTH_BRIDGE_IRQ (MIPS_CPU_IRQ_BASE + 2) /* i8259 */
++
++#define LOONGSON_INT_BIT_INT0 (1 << 11)
++#define LOONGSON_INT_BIT_INT1 (1 << 12)
++
++/*
++ * The generic i8259_irq() make the kernel hang on booting. Since we cannot
++ * get the irq via the IRR directly, we access the ISR instead.
++ */
++int mach_i8259_irq(void)
++{
++ int irq, isr;
++
++ irq = -1;
++
++ if ((LOONGSON_INTISR & LOONGSON_INTEN) & LOONGSON_INT_BIT_INT0) {
++ spin_lock(&i8259A_lock);
++ isr = inb(PIC_MASTER_CMD) &
++ ~inb(PIC_MASTER_IMR) & ~(1 << PIC_CASCADE_IR);
++ if (!isr)
++ isr = (inb(PIC_SLAVE_CMD) & ~inb(PIC_SLAVE_IMR)) << 8;
++ irq = ffs(isr) - 1;
++ if (unlikely(irq == 7)) {
++ /*
++ * This may be a spurious interrupt.
++ *
++ * Read the interrupt status register (ISR). If the most
++ * significant bit is not set then there is no valid
++ * interrupt.
++ */
++ outb(0x0B, PIC_MASTER_ISR); /* ISR register */
++ if (~inb(PIC_MASTER_ISR) & 0x80)
++ irq = -1;
++ }
++ spin_unlock(&i8259A_lock);
++ }
++
++ return irq;
++}
++EXPORT_SYMBOL(mach_i8259_irq);
++
++static void i8259_irqdispatch(void)
++{
++ int irq;
++
++ irq = mach_i8259_irq();
++ if (irq >= 0)
++ do_IRQ(irq);
++ else
++ spurious_interrupt();
++}
++
++void mach_irq_dispatch(unsigned int pending)
++{
++ if (pending & CAUSEF_IP7)
++ do_IRQ(LOONGSON_TIMER_IRQ);
++ else if (pending & CAUSEF_IP6) { /* North Bridge, Perf counter */
++#ifdef CONFIG_OPROFILE
++ do_IRQ(LOONGSON2_PERFCNT_IRQ);
++#endif
++ bonito_irqdispatch();
++ } else if (pending & CAUSEF_IP3) /* CPU UART */
++ do_IRQ(LOONGSON_UART_IRQ);
++ else if (pending & CAUSEF_IP2) /* South Bridge */
++ i8259_irqdispatch();
++ else
++ spurious_interrupt();
++}
++
++void __init set_irq_trigger_mode(void)
++{
++ /* setup cs5536 as high level trigger */
++ LOONGSON_INTPOL = LOONGSON_INT_BIT_INT0 | LOONGSON_INT_BIT_INT1;
++ LOONGSON_INTEDGE &= ~(LOONGSON_INT_BIT_INT0 | LOONGSON_INT_BIT_INT1);
++}
++
++static irqreturn_t ip6_action(int cpl, void *dev_id)
++{
++ return IRQ_HANDLED;
++}
++
++struct irqaction ip6_irqaction = {
++ .handler = ip6_action,
++ .name = "cascade",
++ .flags = IRQF_SHARED,
++};
++
++struct irqaction cascade_irqaction = {
++ .handler = no_action,
++ .name = "cascade",
++};
++
++void __init mach_init_irq(void)
++{
++ /* init all controller
++ * 0-15 ------> i8259 interrupt
++ * 16-23 ------> mips cpu interrupt
++ * 32-63 ------> bonito irq
++ */
++
++ /* Sets the first-level interrupt dispatcher. */
++ mips_cpu_irq_init();
++ init_i8259_irqs();
++ bonito_irq_init();
++
++ /* setup north bridge irq (bonito) */
++ setup_irq(LOONGSON_NORTH_BRIDGE_IRQ, &ip6_irqaction);
++ /* setup source bridge irq (i8259) */
++ setup_irq(LOONGSON_SOUTH_BRIDGE_IRQ, &cascade_irqaction);
++}
+diff --git a/arch/mips/loongson/lemote-2f/lynloong_pc.c b/arch/mips/loongson/lemote-2f/lynloong_pc.c
+new file mode 100644
+index 0000000..a3f6ffc
+--- /dev/null
++++ b/arch/mips/loongson/lemote-2f/lynloong_pc.c
+@@ -0,0 +1,584 @@
++/*
++ * Driver for LynLoong pc extras
++ *
++ * Copyright (C) 2009 Lemote Inc.
++ * Author: Xiang Yu <xiangy@lemote.com>
++ * Wu Zhangjin <wuzj@lemote.com>
++ *
++ * 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 <linux/backlight.h>
++#include <linux/delay.h>
++#include <linux/fb.h>
++#include <linux/interrupt.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/pm.h>
++#include <linux/suspend.h>
++#include <linux/thermal.h>
++
++#include <asm/bootinfo.h>
++
++#include <loongson.h>
++
++#include <cs5536/cs5536.h>
++#include <cs5536/cs5536_pci.h>
++#include <cs5536/cs5536_mfgpt.h>
++
++static u32 gpio_base, smb_base, mfgpt_base;
++
++/* gpio operations */
++static void set_gpio_reg_high(int gpio, int reg)
++{
++ u32 val;
++
++ val = inl(gpio_base + reg);
++ val |= (1 << gpio);
++ val &= ~(1 << (16 + gpio));
++ outl(val, gpio_base + reg);
++ mmiowb();
++}
++
++static void set_gpio_reg_low(int gpio, int reg)
++{
++ u32 val;
++
++ val = inl(gpio_base + reg);
++ val |= (1 << (16 + gpio));
++ val &= ~(1 << gpio);
++ outl(val, gpio_base + reg);
++ mmiowb();
++}
++
++static void set_gpio_output_low(int gpio)
++{
++ set_gpio_reg_high(gpio, GPIOL_OUT_EN);
++ set_gpio_reg_low(gpio, GPIOL_OUT_VAL);
++}
++
++static void set_gpio_output_high(int gpio)
++{
++ set_gpio_reg_high(gpio, GPIOL_OUT_EN);
++ set_gpio_reg_high(gpio, GPIOL_OUT_VAL);
++}
++
++/* backlight subdriver */
++
++#define MAX_BRIGHTNESS 100
++#define DEFAULT_BRIGHTNESS 50
++#define MIN_BRIGHTNESS 0
++static uint level;
++
++/* tune the brightness */
++static void setup_mfgpt2(void)
++{
++ /* set MFGPT2 comparator 1,2 */
++ outw(MAX_BRIGHTNESS-level, MFGPT2_CMP1);
++ outw(MAX_BRIGHTNESS, MFGPT2_CMP2);
++ /* clear MFGPT2 UP COUNTER */
++ outw(0, MFGPT2_CNT);
++ /* enable counter, compare mode, 32k */
++ outw(0x8280, MFGPT2_SETUP);
++}
++
++static int lynloong_set_brightness(struct backlight_device *bd)
++{
++ uint i;
++
++ level = (bd->props.fb_blank == FB_BLANK_UNBLANK &&
++ bd->props.power == FB_BLANK_UNBLANK) ?
++ bd->props.brightness : 0;
++
++ if (level > MAX_BRIGHTNESS)
++ level = MAX_BRIGHTNESS;
++ else if (level < MIN_BRIGHTNESS)
++ level = MIN_BRIGHTNESS;
++
++ if (level == 0) {
++ /* turn off the backlight */
++ set_gpio_output_low(11);
++ for (i = 0; i < 0x500; i++)
++ delay();
++ /* turn off the LCD */
++ set_gpio_output_high(8);
++ } else {
++ /* turn on the LCD */
++ set_gpio_output_low(8);
++ for (i = 0; i < 0x500; i++)
++ delay();
++ /* turn on the backlight */
++ set_gpio_output_high(11);
++ }
++
++ setup_mfgpt2();
++
++ return 0;
++}
++
++static int lynloong_get_brightness(struct backlight_device *bd)
++{
++ return level;
++}
++
++static struct backlight_ops backlight_ops = {
++ .get_brightness = lynloong_get_brightness,
++ .update_status = lynloong_set_brightness,
++};
++
++static struct backlight_device *lynloong_backlight_dev;
++
++static void lynloong_backlight_exit(void)
++{
++ if (lynloong_backlight_dev) {
++ backlight_device_unregister(lynloong_backlight_dev);
++ lynloong_backlight_dev = NULL;
++ }
++ /* disable brightness controlling */
++ set_gpio_output_low(7);
++
++ printk(KERN_INFO "exit from LingLoong Backlight Driver");
++}
++
++static int __init lynloong_backlight_init(struct device *dev)
++{
++ int ret;
++
++ /* select for mfgpt */
++ set_gpio_reg_high(7, GPIOL_OUT_AUX1_SEL);
++ /* enable brightness controlling */
++ set_gpio_output_high(7);
++
++ lynloong_backlight_dev =
++ backlight_device_register("backlight0", dev, NULL,
++ &backlight_ops);
++
++ if (IS_ERR(lynloong_backlight_dev)) {
++ ret = PTR_ERR(lynloong_backlight_dev);
++ return ret;
++ }
++
++ lynloong_backlight_dev->props.max_brightness = MAX_BRIGHTNESS;
++ lynloong_backlight_dev->props.brightness = DEFAULT_BRIGHTNESS;
++ backlight_update_status(lynloong_backlight_dev);
++
++ return 0;
++}
++
++/* Thermal cooling devices subdriver */
++
++static int video_get_max_state(struct thermal_cooling_device *cdev, unsigned
++ long *state)
++{
++ *state = MAX_BRIGHTNESS;
++ return 0;
++}
++
++static int video_get_cur_state(struct thermal_cooling_device *cdev, unsigned
++ long *state)
++{
++ static struct backlight_device *bd;
++
++ bd = (struct backlight_device *)cdev->devdata;
++
++ *state = lynloong_get_brightness(bd);
++
++ return 0;
++}
++
++static int video_set_cur_state(struct thermal_cooling_device *cdev, unsigned
++ long state)
++{
++ static struct backlight_device *bd;
++
++ bd = (struct backlight_device *)cdev->devdata;
++
++ lynloong_backlight_dev->props.brightness = state;
++ backlight_update_status(bd);
++
++ return 0;
++}
++
++static struct thermal_cooling_device_ops video_cooling_ops = {
++ .get_max_state = video_get_max_state,
++ .get_cur_state = video_get_cur_state,
++ .set_cur_state = video_set_cur_state,
++};
++
++static struct thermal_cooling_device *lynloong_thermal_cdev;
++
++/* TODO: register cpu as the cooling device */
++static int lynloong_thermal_init(struct device *dev)
++{
++ int ret;
++
++ if (!dev)
++ return -1;
++
++ lynloong_thermal_cdev = thermal_cooling_device_register("LCD", dev,
++ &video_cooling_ops);
++
++ if (IS_ERR(lynloong_thermal_cdev)) {
++ ret = PTR_ERR(lynloong_thermal_cdev);
++ return ret;
++ }
++
++ ret = sysfs_create_link(&dev->kobj,
++ &lynloong_thermal_cdev->device.kobj,
++ "thermal_cooling");
++ if (ret) {
++ printk(KERN_ERR "Create sysfs link\n");
++ return ret;
++ }
++ ret = sysfs_create_link(&lynloong_thermal_cdev->device.kobj,
++ &dev->kobj, "device");
++ if (ret) {
++ printk(KERN_ERR "Create sysfs link\n");
++ return ret;
++ }
++
++ return 0;
++}
++
++static void lynloong_thermal_exit(struct device *dev)
++{
++ if (lynloong_thermal_cdev) {
++ if (dev)
++ sysfs_remove_link(&dev->kobj, "thermal_cooling");
++ sysfs_remove_link(&lynloong_thermal_cdev->device.kobj,
++ "device");
++ thermal_cooling_device_unregister(lynloong_thermal_cdev);
++ lynloong_thermal_cdev = NULL;
++ }
++}
++
++/* platform subdriver */
++
++/* I2C operations */
++
++static int i2c_wait(void)
++{
++ char c;
++ int i;
++
++ udelay(1000);
++ for (i = 0; i < 20; i++) {
++ c = inb(smb_base | SMB_STS);
++ if (c & (SMB_STS_BER | SMB_STS_NEGACK))
++ return -1;
++ if (c & SMB_STS_SDAST)
++ return 0;
++ udelay(100);
++ }
++ return -2;
++}
++
++static void i2c_read_single(int addr, int regNo, char *value)
++{
++ unsigned char c;
++
++ /* Start condition */
++ c = inb(smb_base | SMB_CTRL1);
++ outb(c | SMB_CTRL1_START, smb_base | SMB_CTRL1);
++ i2c_wait();
++
++ /* Send slave address */
++ outb(addr & 0xfe, smb_base | SMB_SDA);
++ i2c_wait();
++
++ /* Acknowledge smbus */
++ c = inb(smb_base | SMB_CTRL1);
++ outb(c | SMB_CTRL1_ACK, smb_base | SMB_CTRL1);
++
++ /* Send register index */
++ outb(regNo, smb_base | SMB_SDA);
++ i2c_wait();
++
++ /* Acknowledge smbus */
++ c = inb(smb_base | SMB_CTRL1);
++ outb(c | SMB_CTRL1_ACK, smb_base | SMB_CTRL1);
++
++ /* Start condition again */
++ c = inb(smb_base | SMB_CTRL1);
++ outb(c | SMB_CTRL1_START, smb_base | SMB_CTRL1);
++ i2c_wait();
++
++ /* Send salve address again */
++ outb(1 | addr, smb_base | SMB_SDA);
++ i2c_wait();
++
++ /* Acknowledge smbus */
++ c = inb(smb_base | SMB_CTRL1);
++ outb(c | SMB_CTRL1_ACK, smb_base | SMB_CTRL1);
++
++ /* Read data */
++ *value = inb(smb_base | SMB_SDA);
++
++ /* Stop condition */
++ outb(SMB_CTRL1_STOP, smb_base | SMB_CTRL1);
++ i2c_wait();
++}
++
++static void i2c_write_single(int addr, int regNo, char value)
++{
++ unsigned char c;
++
++ /* Start condition */
++ c = inb(smb_base | SMB_CTRL1);
++ outb(c | SMB_CTRL1_START, smb_base | SMB_CTRL1);
++ i2c_wait();
++ /* Send slave address */
++ outb(addr & 0xfe, smb_base | SMB_SDA);
++ i2c_wait();;
++
++ /* Send register index */
++ outb(regNo, smb_base | SMB_SDA);
++ i2c_wait();
++
++ /* Write data */
++ outb(value, smb_base | SMB_SDA);
++ i2c_wait();
++ /* Stop condition */
++ outb(SMB_CTRL1_STOP, smb_base | SMB_CTRL1);
++ i2c_wait();
++}
++
++static void stop_clock(int clk_reg, int clk_sel)
++{
++ u8 value;
++
++ i2c_read_single(0xd3, clk_reg, &value);
++ value &= ~(1 << clk_sel);
++ i2c_write_single(0xd2, clk_reg, value);
++}
++
++static void enable_clock(int clk_reg, int clk_sel)
++{
++ u8 value;
++
++ i2c_read_single(0xd3, clk_reg, &value);
++ value |= (1 << clk_sel);
++ i2c_write_single(0xd2, clk_reg, value);
++}
++
++static char cached_clk_freq;
++static char cached_pci_fixed_freq;
++
++static void decrease_clk_freq(void)
++{
++ char value;
++
++ i2c_read_single(0xd3, 1, &value);
++ cached_clk_freq = value;
++
++ /* select frequency by software */
++ value |= (1 << 1);
++ /* CPU, 3V66, PCI : 100, 66, 33(1) */
++ value |= (1 << 2);
++ i2c_write_single(0xd2, 1, value);
++
++ /* cache the pci frequency */
++ i2c_read_single(0xd3, 14, &value);
++ cached_pci_fixed_freq = value;
++
++ /* enable PCI fix mode */
++ value |= (1 << 5);
++ /* 3V66, PCI : 64MHz, 32MHz */
++ value |= (1 << 3);
++ i2c_write_single(0xd2, 14, value);
++
++}
++
++static void resume_clk_freq(void)
++{
++ i2c_write_single(0xd2, 1, cached_clk_freq);
++ i2c_write_single(0xd2, 14, cached_pci_fixed_freq);
++}
++
++static void stop_clocks(void)
++{
++ /* CPU Clock Register */
++ stop_clock(2, 5); /* not used */
++ stop_clock(2, 6); /* not used */
++ stop_clock(2, 7); /* not used */
++
++ /* PCI Clock Register */
++ stop_clock(3, 1); /* 8100 */
++ stop_clock(3, 5); /* SIS */
++ stop_clock(3, 0); /* not used */
++ stop_clock(3, 6); /* not used */
++
++ /* PCI 48M Clock Register */
++ stop_clock(4, 6); /* USB grounding */
++ stop_clock(4, 5); /* REF(5536_14M) */
++
++ /* 3V66 Control Register */
++ stop_clock(5, 0); /* VCH_CLK..., grounding */
++}
++static void enable_clocks(void)
++{
++ enable_clock(3, 1); /* 8100 */
++ enable_clock(3, 5); /* SIS */
++
++ enable_clock(4, 6);
++ enable_clock(4, 5); /* REF(5536_14M) */
++
++ enable_clock(5, 0); /* VCH_CLOCK, grounding */
++}
++
++static struct platform_device *lynloong_pdev;
++
++static int __maybe_unused lynloong_suspend(struct platform_device *pdev,
++ pm_message_t state)
++{
++ int i;
++
++ printk(KERN_INFO "lynloong specific suspend\n");
++
++ /* disable AMP */
++ set_gpio_output_high(6);
++ /* disable the brightness control */
++ set_gpio_output_low(7);
++ /* disable the backlight output */
++ set_gpio_output_low(11);
++
++ /* stop the clocks of some devices */
++ stop_clocks();
++
++ /* decrease the external clock frequency */
++ decrease_clk_freq();
++
++ /* turn off the LCD */
++ for (i = 0; i < 0x600; i++)
++ delay();
++ set_gpio_output_high(8);
++
++ return 0;
++}
++
++static int __maybe_unused lynloong_resume(struct platform_device *pdev)
++{
++ int i;
++
++ printk(KERN_INFO "lynloong specific resume\n");
++
++ /* turn on the LCD */
++ set_gpio_output_low(8);
++ for (i = 0; i < 0x1000; i++)
++ delay();
++
++ /* resume clock frequency, enable the relative clocks */
++ resume_clk_freq();
++ enable_clocks();
++
++ /* enable the backlight output */
++ set_gpio_output_high(11);
++ /* enable the brightness control */
++ set_gpio_output_high(7);
++ /* enable AMP */
++ set_gpio_output_low(6);
++
++ return 0;
++}
++
++static struct platform_device *lynloong_pdev;
++
++static struct platform_device_id platform_device_ids[] = {
++ {
++ .name = "lynloong_pc",
++ },
++ {}
++};
++
++MODULE_DEVICE_TABLE(platform, platform_device_ids);
++
++static struct platform_driver platform_driver = {
++ .driver = {
++ .name = "lynloong_pc",
++ .owner = THIS_MODULE,
++ },
++ .id_table = platform_device_ids,
++#ifdef CONFIG_PM
++ .suspend = lynloong_suspend,
++ .resume = lynloong_resume,
++#endif
++};
++
++static int lynloong_pdev_init(void)
++{
++ int ret;
++
++ /* Register platform stuff */
++ ret = platform_driver_register(&platform_driver);
++ if (ret)
++ return ret;
++
++ return 0;
++}
++
++static void lynloong_pdev_exit(void)
++{
++ platform_driver_unregister(&platform_driver);
++}
++
++static int __init lynloong_init(void)
++{
++ int ret;
++ u32 hi;
++
++ if (mips_machtype != MACH_LEMOTE_LL2F) {
++ printk(KERN_INFO "This Driver is for LynLoong(Allinone) PC, You"
++ " can not use it on the other Machines\n");
++ return -EFAULT;
++ }
++
++ printk(KERN_INFO "Load LynLoong Platform Driver\n");
++
++ /* get mfgpt_base */
++ _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), &hi, &mfgpt_base);
++ /* get gpio_base */
++ _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &gpio_base);
++ /* get smb base */
++ _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), &hi, &smb_base);
++
++ ret = lynloong_pdev_init();
++ if (ret) {
++ lynloong_pdev_exit();
++ printk(KERN_INFO "init lynloong platform driver failure\n");
++ return ret;
++ }
++
++ ret = lynloong_backlight_init(&lynloong_pdev->dev);
++ if (ret) {
++ lynloong_backlight_exit();
++ printk(KERN_INFO "init lynloong backlight driver failure\n");
++ return ret;
++ }
++ ret = lynloong_thermal_init(&lynloong_backlight_dev->dev);
++ if (ret) {
++ lynloong_thermal_exit(&lynloong_backlight_dev->dev);
++ printk(KERN_INFO
++ "init lynloong thermal cooling device failure\n");
++ return ret;
++ }
++
++ return 0;
++}
++
++static void __exit lynloong_exit(void)
++{
++ lynloong_pdev_exit();
++ lynloong_thermal_exit(&lynloong_backlight_dev->dev);
++ lynloong_backlight_exit();
++
++ printk(KERN_INFO "Unload LynLoong Platform Driver\n");
++}
++
++module_init(lynloong_init);
++module_exit(lynloong_exit);
++
++MODULE_AUTHOR("Xiang Yu <xiangy@lemote.com>; Wu Zhangjin <wuzj@lemote.com>");
++MODULE_DESCRIPTION("LynLoong Platform Specific Driver");
++MODULE_LICENSE("GPL");
+diff --git a/arch/mips/loongson/lemote-2f/platform.c b/arch/mips/loongson/lemote-2f/platform.c
+new file mode 100644
+index 0000000..e0de8c2
+--- /dev/null
++++ b/arch/mips/loongson/lemote-2f/platform.c
+@@ -0,0 +1,50 @@
++/*
++ * Copyright (C) 2009 Lemote Inc.
++ * Author: Wu Zhangjin, wuzj@lemote.com
++ *
++ * 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 <linux/err.h>
++#include <linux/platform_device.h>
++
++#include <asm/bootinfo.h>
++
++static struct platform_device yeeloong_dev = {
++ .name = "yeeloong_laptop",
++ .id = -1,
++};
++
++static struct platform_device lynloong_dev = {
++ .name = "lynloong_pc",
++ .id = -1,
++};
++
++static int __init lemote2f_init(void)
++{
++ struct platform_device *pdev;
++
++ pdev = NULL;
++
++ switch (mips_machtype) {
++ case MACH_LEMOTE_LL2F:
++ pdev = &lynloong_dev;
++ break;
++ case MACH_LEMOTE_YL2F89:
++ pdev = &yeeloong_dev;
++ break;
++ default:
++ break;
++
++ }
++
++ if (pdev != NULL)
++ return platform_device_register(pdev);
++
++ return -ENODEV;
++}
++
++arch_initcall(lemote2f_init);
+diff --git a/arch/mips/loongson/lemote-2f/pm.c b/arch/mips/loongson/lemote-2f/pm.c
+new file mode 100644
+index 0000000..3072583
+--- /dev/null
++++ b/arch/mips/loongson/lemote-2f/pm.c
+@@ -0,0 +1,138 @@
++/*
++ * Lemote loongson2f family machines' specific suspend support
++ *
++ * Copyright (C) 2009 Lemote Inc.
++ * Author: Wu Zhangjin <wuzj@lemote.com>
++ *
++ * 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 <linux/suspend.h>
++#include <linux/interrupt.h>
++#include <linux/pm.h>
++#include <linux/i8042.h>
++#include <linux/module.h>
++
++#include <asm/i8259.h>
++#include <asm/mipsregs.h>
++#include <asm/bootinfo.h>
++
++#include <loongson.h>
++
++#include "ec_kb3310b.h"
++
++#define I8042_KBD_IRQ 1
++#define I8042_CTR_KBDINT 0x01
++#define I8042_CTR_KBDDIS 0x10
++
++static unsigned char i8042_ctr;
++
++static int i8042_enable_kbd_port(void)
++{
++ if (i8042_command(&i8042_ctr, I8042_CMD_CTL_RCTR)) {
++ pr_err("i8042.c: Can't read CTR while enabling i8042 kbd port."
++ "\n");
++ return -EIO;
++ }
++
++ i8042_ctr &= ~I8042_CTR_KBDDIS;
++ i8042_ctr |= I8042_CTR_KBDINT;
++
++ if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
++ i8042_ctr &= ~I8042_CTR_KBDINT;
++ i8042_ctr |= I8042_CTR_KBDDIS;
++ pr_err("i8042.c: Failed to enable KBD port.\n");
++
++ return -EIO;
++ }
++
++ return 0;
++}
++
++void setup_wakeup_events(void)
++{
++ int irq_mask;
++
++ switch (mips_machtype) {
++ case MACH_LEMOTE_ML2F7:
++ case MACH_LEMOTE_YL2F89:
++ /* open the keyboard irq in i8259A */
++ outb((0xff & ~(1 << I8042_KBD_IRQ)), PIC_MASTER_IMR);
++ irq_mask = inb(PIC_MASTER_IMR);
++
++ /* enable keyboard port */
++ i8042_enable_kbd_port();
++
++ /* wakeup cpu via SCI with relative lid openning event */
++ outb(irq_mask & ~(1 << PIC_CASCADE_IR), PIC_MASTER_IMR);
++ inb(PIC_MASTER_IMR);
++ outb(0xff & ~(1 << (SCI_IRQ_NUM - 8)), PIC_SLAVE_IMR);
++ inb(PIC_SLAVE_IMR);
++
++ break;
++
++ default:
++ break;
++ }
++}
++
++static struct delayed_work lid_task;
++static int initialized;
++/* yeeloong_report_lid_status will be implemented in yeeloong_laptop.c */
++sci_handler yeeloong_report_lid_status;
++EXPORT_SYMBOL(yeeloong_report_lid_status);
++static void yeeloong_lid_update_task(struct work_struct *work)
++{
++ if (yeeloong_report_lid_status)
++ yeeloong_report_lid_status(BIT_LID_DETECT_ON);
++}
++
++int wakeup_loongson(void)
++{
++ int irq;
++
++ /* query the interrupt number */
++ irq = mach_i8259_irq();
++ if (irq < 0)
++ return 0;
++
++ printk(KERN_INFO "%s: irq = %d\n", __func__, irq);
++
++ if (irq == I8042_KBD_IRQ)
++ return 1;
++ else if (irq == SCI_IRQ_NUM) {
++ int ret, sci_event;
++ /* query the event number */
++ ret = ec_query_seq(CMD_GET_EVENT_NUM);
++ if (ret < 0)
++ return 0;
++ sci_event = ec_get_event_num();
++ if (sci_event < 0)
++ return 0;
++ if (sci_event == EVENT_LID) {
++ int lid_status;
++ /* check the LID status */
++ lid_status = ec_read(REG_LID_DETECT);
++ /* wakeup cpu when people open the LID */
++ if (lid_status == BIT_LID_DETECT_ON) {
++ /* If we call it directly here, the WARNING
++ * will be sent out by getnstimeofday
++ * via "WARN_ON(timekeeping_suspended);"
++ * because we can not schedule in suspend mode.
++ */
++ if (initialized == 0) {
++ INIT_DELAYED_WORK(&lid_task,
++ yeeloong_lid_update_task);
++ initialized = 1;
++ }
++ schedule_delayed_work(&lid_task, 1);
++ return 1;
++ }
++ }
++ }
++
++ return 0;
++}
+diff --git a/arch/mips/loongson/lemote-2f/reset.c b/arch/mips/loongson/lemote-2f/reset.c
+new file mode 100644
+index 0000000..51d1a60
+--- /dev/null
++++ b/arch/mips/loongson/lemote-2f/reset.c
+@@ -0,0 +1,159 @@
++/* Board-specific reboot/shutdown routines
++ *
++ * Copyright (c) 2009 Philippe Vachon <philippe@cowpig.ca>
++ *
++ * Copyright (C) 2009 Lemote Inc.
++ * Author: Wu Zhangjin, wuzj@lemote.com
++ *
++ * 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 <linux/io.h>
++#include <linux/delay.h>
++#include <linux/types.h>
++
++#include <asm/bootinfo.h>
++
++#include <loongson.h>
++
++#include <cs5536/cs5536.h>
++#include "ec_kb3310b.h"
++
++static void reset_cpu(void)
++{
++ /*
++ * reset cpu to full speed, this is needed when enabling cpu frequency
++ * scalling
++ */
++ LOONGSON_CHIPCFG0 |= 0x7;
++}
++
++/* reset support for fuloong2f */
++
++static void fl2f_reboot(void)
++{
++ reset_cpu();
++
++ /* send a reset signal to south bridge.
++ *
++ * NOTE: if enable "Power Management" in kernel, rtl8169 will not reset
++ * normally with this reset operation and it will not work in PMON, but
++ * you can type halt command and then reboot, seems the hardware reset
++ * logic not work normally.
++ */
++ {
++ u32 hi, lo;
++ _rdmsr(DIVIL_MSR_REG(DIVIL_SOFT_RESET), &hi, &lo);
++ lo |= 0x00000001;
++ _wrmsr(DIVIL_MSR_REG(DIVIL_SOFT_RESET), hi, lo);
++ }
++}
++
++static void fl2f_shutdown(void)
++{
++ u32 hi, lo, val;
++ int gpio_base;
++
++ /* get gpio base */
++ _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &lo);
++ gpio_base = lo & 0xff00;
++
++ /* make cs5536 gpio13 output enable */
++ val = inl(gpio_base + GPIOL_OUT_EN);
++ val &= ~(1 << (16 + 13));
++ val |= (1 << 13);
++ outl(val, gpio_base + GPIOL_OUT_EN);
++ mmiowb();
++ /* make cs5536 gpio13 output low level voltage. */
++ val = inl(gpio_base + GPIOL_OUT_VAL) & ~(1 << (13));
++ val |= (1 << (16 + 13));
++ outl(val, gpio_base + GPIOL_OUT_VAL);
++ mmiowb();
++}
++
++/* reset support for yeeloong2f and mengloong2f notebook */
++
++void ml2f_reboot(void)
++{
++ reset_cpu();
++
++ /* sending an reset signal to EC(embedded controller) */
++ ec_write(REG_RESET, BIT_RESET_ON);
++}
++
++#define yl2f89_reboot ml2f_reboot
++
++/* menglong(7inches) laptop has different shutdown logic from 8.9inches */
++#define EC_SHUTDOWN_IO_PORT_HIGH 0xff2d
++#define EC_SHUTDOWN_IO_PORT_LOW 0xff2e
++#define EC_SHUTDOWN_IO_PORT_DATA 0xff2f
++#define REG_SHUTDOWN_HIGH 0xFC
++#define REG_SHUTDOWN_LOW 0x29
++#define BIT_SHUTDOWN_ON (1 << 1)
++
++static void ml2f_shutdown(void)
++{
++ u8 val;
++ u64 i;
++
++ outb(REG_SHUTDOWN_HIGH, EC_SHUTDOWN_IO_PORT_HIGH);
++ outb(REG_SHUTDOWN_LOW, EC_SHUTDOWN_IO_PORT_LOW);
++ mmiowb();
++ val = inb(EC_SHUTDOWN_IO_PORT_DATA);
++ outb(val & (~BIT_SHUTDOWN_ON), EC_SHUTDOWN_IO_PORT_DATA);
++ mmiowb();
++ /* need enough wait here... how many microseconds needs? */
++ for (i = 0; i < 0x10000; i++)
++ delay();
++ outb(val | BIT_SHUTDOWN_ON, EC_SHUTDOWN_IO_PORT_DATA);
++ mmiowb();
++}
++
++static void yl2f89_shutdown(void)
++{
++ /* cpu-gpio0 output low */
++ LOONGSON_GPIODATA &= ~0x00000001;
++ /* cpu-gpio0 as output */
++ LOONGSON_GPIOIE &= ~0x00000001;
++}
++
++void mach_prepare_reboot(void)
++{
++ switch (mips_machtype) {
++ case MACH_LEMOTE_FL2F:
++ case MACH_LEMOTE_NAS:
++ case MACH_LEMOTE_LL2F:
++ fl2f_reboot();
++ break;
++ case MACH_LEMOTE_ML2F7:
++ ml2f_reboot();
++ break;
++ case MACH_LEMOTE_YL2F89:
++ yl2f89_reboot();
++ break;
++ default:
++ break;
++ }
++}
++
++void mach_prepare_shutdown(void)
++{
++ switch (mips_machtype) {
++ case MACH_LEMOTE_FL2F:
++ case MACH_LEMOTE_NAS:
++ case MACH_LEMOTE_LL2F:
++ fl2f_shutdown();
++ break;
++ case MACH_LEMOTE_ML2F7:
++ ml2f_shutdown();
++ break;
++ case MACH_LEMOTE_YL2F89:
++ yl2f89_shutdown();
++ break;
++ default:
++ break;
++ }
++}
+diff --git a/arch/mips/loongson/lemote-2f/yeeloong_ecrom.c b/arch/mips/loongson/lemote-2f/yeeloong_ecrom.c
+new file mode 100644
+index 0000000..1acaca2
+--- /dev/null
++++ b/arch/mips/loongson/lemote-2f/yeeloong_ecrom.c
+@@ -0,0 +1,943 @@
++/*
++ * Driver for flushing/dumping ROM of EC on YeeLoong laptop
++ *
++ * Copyright (C) 2009 Lemote Inc.
++ * Author: liujl <liujl@lemote.com>
++ *
++ * NOTE :
++ * The EC resources accessing and programming are supported.
++ */
++
++#include <linux/proc_fs.h>
++#include <linux/miscdevice.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++
++#include <ec/kb3310b.h>
++
++#define EC_MISC_DEV "ec_misc"
++#define EC_IOC_MAGIC 'E'
++
++/* ec registers range */
++#define EC_MAX_REGADDR 0xFFFF
++#define EC_MIN_REGADDR 0xF000
++#define EC_RAM_ADDR 0xF800
++
++/* version burned address */
++#define VER_ADDR 0xf7a1
++#define VER_MAX_SIZE 7
++#define EC_ROM_MAX_SIZE 0x10000
++
++/* ec internal register */
++#define REG_POWER_MODE 0xF710
++#define FLAG_NORMAL_MODE 0x00
++#define FLAG_IDLE_MODE 0x01
++#define FLAG_RESET_MODE 0x02
++
++/* ec update program flag */
++#define PROGRAM_FLAG_NONE 0x00
++#define PROGRAM_FLAG_IE 0x01
++#define PROGRAM_FLAG_ROM 0x02
++
++/* XBI relative registers */
++#define REG_XBISEG0 0xFEA0
++#define REG_XBISEG1 0xFEA1
++#define REG_XBIRSV2 0xFEA2
++#define REG_XBIRSV3 0xFEA3
++#define REG_XBIRSV4 0xFEA4
++#define REG_XBICFG 0xFEA5
++#define REG_XBICS 0xFEA6
++#define REG_XBIWE 0xFEA7
++#define REG_XBISPIA0 0xFEA8
++#define REG_XBISPIA1 0xFEA9
++#define REG_XBISPIA2 0xFEAA
++#define REG_XBISPIDAT 0xFEAB
++#define REG_XBISPICMD 0xFEAC
++#define REG_XBISPICFG 0xFEAD
++#define REG_XBISPIDATR 0xFEAE
++#define REG_XBISPICFG2 0xFEAF
++
++/* commands definition for REG_XBISPICMD */
++#define SPICMD_WRITE_STATUS 0x01
++#define SPICMD_BYTE_PROGRAM 0x02
++#define SPICMD_READ_BYTE 0x03
++#define SPICMD_WRITE_DISABLE 0x04
++#define SPICMD_READ_STATUS 0x05
++#define SPICMD_WRITE_ENABLE 0x06
++#define SPICMD_HIGH_SPEED_READ 0x0B
++#define SPICMD_POWER_DOWN 0xB9
++#define SPICMD_SST_EWSR 0x50
++#define SPICMD_SST_SEC_ERASE 0x20
++#define SPICMD_SST_BLK_ERASE 0x52
++#define SPICMD_SST_CHIP_ERASE 0x60
++#define SPICMD_FRDO 0x3B
++#define SPICMD_SEC_ERASE 0xD7
++#define SPICMD_BLK_ERASE 0xD8
++#define SPICMD_CHIP_ERASE 0xC7
++
++/* bits definition for REG_XBISPICFG */
++#define SPICFG_AUTO_CHECK 0x01
++#define SPICFG_SPI_BUSY 0x02
++#define SPICFG_DUMMY_READ 0x04
++#define SPICFG_EN_SPICMD 0x08
++#define SPICFG_LOW_SPICS 0x10
++#define SPICFG_EN_SHORT_READ 0x20
++#define SPICFG_EN_OFFSET_READ 0x40
++#define SPICFG_EN_FAST_READ 0x80
++
++/* watchdog timer registers */
++#define REG_WDTCFG 0xfe80
++#define REG_WDTPF 0xfe81
++#define REG_WDT 0xfe82
++
++/* lpc configure register */
++#define REG_LPCCFG 0xfe95
++
++/* 8051 reg */
++#define REG_PXCFG 0xff14
++
++/* Fan register in KB3310 */
++#define REG_ECFAN_SPEED_LEVEL 0xf4e4
++#define REG_ECFAN_SWITCH 0xf4d2
++
++/* the ec flash rom id number */
++#define EC_ROM_PRODUCT_ID_SPANSION 0x01
++#define EC_ROM_PRODUCT_ID_MXIC 0xC2
++#define EC_ROM_PRODUCT_ID_AMIC 0x37
++#define EC_ROM_PRODUCT_ID_EONIC 0x1C
++
++/* misc ioctl operations */
++#define IOCTL_RDREG _IOR(EC_IOC_MAGIC, 1, int)
++#define IOCTL_WRREG _IOW(EC_IOC_MAGIC, 2, int)
++#define IOCTL_READ_EC _IOR(EC_IOC_MAGIC, 3, int)
++#define IOCTL_PROGRAM_IE _IOW(EC_IOC_MAGIC, 4, int)
++#define IOCTL_PROGRAM_EC _IOW(EC_IOC_MAGIC, 5, int)
++
++/* start address for programming of EC content or IE */
++/* ec running code start address */
++#define EC_START_ADDR 0x00000000
++/* ec information element storing address */
++#define IE_START_ADDR 0x00020000
++
++/* EC state */
++#define EC_STATE_IDLE 0x00 /* ec in idle state */
++#define EC_STATE_BUSY 0x01 /* ec in busy state */
++
++/* timeout value for programming */
++#define EC_FLASH_TIMEOUT 0x1000 /* ec program timeout */
++/* command checkout timeout including cmd to port or state flag check */
++#define EC_CMD_TIMEOUT 0x1000
++#define EC_SPICMD_STANDARD_TIMEOUT (4 * 1000) /* unit : us */
++#define EC_MAX_DELAY_UNIT (10) /* every time for polling */
++#define SPI_FINISH_WAIT_TIME 10
++/* EC content max size */
++#define EC_CONTENT_MAX_SIZE (64 * 1024)
++#define IE_CONTENT_MAX_SIZE (0x100000 - IE_START_ADDR)
++
++/* the register operation access struct */
++struct ec_reg {
++ u32 addr; /* the address of kb3310 registers */
++ u8 val; /* the register value */
++};
++
++struct ec_info {
++ u32 start_addr;
++ u32 size;
++ u8 *buf;
++};
++
++/* open for using rom protection action */
++#define EC_ROM_PROTECTION
++
++/* enable the chip reset mode */
++static int ec_init_reset_mode(void)
++{
++ int timeout;
++ unsigned char status = 0;
++ int ret = 0;
++
++ /* make chip goto reset mode */
++ ret = ec_query_seq(CMD_INIT_RESET_MODE);
++ if (ret < 0) {
++ printk(KERN_ERR "ec init reset mode failed.\n");
++ goto out;
++ }
++
++ /* make the action take active */
++ timeout = EC_CMD_TIMEOUT;
++ status = ec_read(REG_POWER_MODE) & FLAG_RESET_MODE;
++ while (timeout--) {
++ if (status) {
++ udelay(EC_REG_DELAY);
++ break;
++ }
++ status = ec_read(REG_POWER_MODE) & FLAG_RESET_MODE;
++ udelay(EC_REG_DELAY);
++ }
++ if (timeout <= 0) {
++ printk(KERN_ERR "ec rom fixup : can't check reset status.\n");
++ ret = -EINVAL;
++ } else
++ printk(KERN_INFO "(%d/%d)reset 0xf710 : 0x%x\n", timeout,
++ EC_CMD_TIMEOUT - timeout, status);
++
++ /* set MCU to reset mode */
++ udelay(EC_REG_DELAY);
++ status = ec_read(REG_PXCFG);
++ status |= (1 << 0);
++ ec_write(REG_PXCFG, status);
++ udelay(EC_REG_DELAY);
++
++ /* disable FWH/LPC */
++ udelay(EC_REG_DELAY);
++ status = ec_read(REG_LPCCFG);
++ status &= ~(1 << 7);
++ ec_write(REG_LPCCFG, status);
++ udelay(EC_REG_DELAY);
++
++ printk(KERN_INFO "entering reset mode ok..............\n");
++
++ out:
++ return ret;
++}
++
++/* make ec exit from reset mode */
++static void ec_exit_reset_mode(void)
++{
++ unsigned char regval;
++
++ udelay(EC_REG_DELAY);
++ regval = ec_read(REG_LPCCFG);
++ regval |= (1 << 7);
++ ec_write(REG_LPCCFG, regval);
++ regval = ec_read(REG_PXCFG);
++ regval &= ~(1 << 0);
++ ec_write(REG_PXCFG, regval);
++ printk(KERN_INFO "exit reset mode ok..................\n");
++
++ return;
++}
++
++/* make ec disable WDD */
++static void ec_disable_WDD(void)
++{
++ unsigned char status;
++
++ udelay(EC_REG_DELAY);
++ status = ec_read(REG_WDTCFG);
++ ec_write(REG_WDTPF, 0x03);
++ ec_write(REG_WDTCFG, (status & 0x80) | 0x48);
++ printk(KERN_INFO "Disable WDD ok..................\n");
++
++ return;
++}
++
++/* make ec enable WDD */
++static void ec_enable_WDD(void)
++{
++ unsigned char status;
++
++ udelay(EC_REG_DELAY);
++ status = ec_read(REG_WDTCFG);
++ ec_write(REG_WDT, 0x28); /* set WDT 5sec(0x28) */
++ ec_write(REG_WDTCFG, (status & 0x80) | 0x03);
++ printk(KERN_INFO "Enable WDD ok..................\n");
++
++ return;
++}
++
++/* make ec goto idle mode */
++static int ec_init_idle_mode(void)
++{
++ int timeout;
++ unsigned char status = 0;
++ int ret = 0;
++
++ ec_query_seq(CMD_INIT_IDLE_MODE);
++
++ /* make the action take active */
++ timeout = EC_CMD_TIMEOUT;
++ status = ec_read(REG_POWER_MODE) & FLAG_IDLE_MODE;
++ while (timeout--) {
++ if (status) {
++ udelay(EC_REG_DELAY);
++ break;
++ }
++ status = ec_read(REG_POWER_MODE) & FLAG_IDLE_MODE;
++ udelay(EC_REG_DELAY);
++ }
++ if (timeout <= 0) {
++ printk(KERN_ERR "ec rom fixup : can't check out the status.\n");
++ ret = -EINVAL;
++ } else
++ printk(KERN_INFO "(%d/%d)0xf710 : 0x%x\n", timeout,
++ EC_CMD_TIMEOUT - timeout, ec_read(REG_POWER_MODE));
++
++ printk(KERN_INFO "entering idle mode ok...................\n");
++
++ return ret;
++}
++
++/* make ec exit from idle mode */
++static int ec_exit_idle_mode(void)
++{
++
++ ec_query_seq(CMD_EXIT_IDLE_MODE);
++
++ printk(KERN_INFO "exit idle mode ok...................\n");
++
++ return 0;
++}
++
++static int ec_instruction_cycle(void)
++{
++ unsigned long timeout;
++ int ret = 0;
++
++ timeout = EC_FLASH_TIMEOUT;
++ while (timeout-- >= 0) {
++ if (!(ec_read(REG_XBISPICFG) & SPICFG_SPI_BUSY))
++ break;
++ }
++ if (timeout <= 0) {
++ printk(KERN_ERR
++ "EC_INSTRUCTION_CYCLE : timeout for check flag.\n");
++ ret = -EINVAL;
++ goto out;
++ }
++
++ out:
++ return ret;
++}
++
++/* To see if the ec is in busy state or not. */
++static inline int ec_flash_busy(unsigned long timeout)
++{
++ /* assurance the first command be going to rom */
++ if (ec_instruction_cycle() < 0)
++ return EC_STATE_BUSY;
++#if 1
++ timeout = timeout / EC_MAX_DELAY_UNIT;
++ while (timeout-- > 0) {
++ /* check the rom's status of busy flag */
++ ec_write(REG_XBISPICMD, SPICMD_READ_STATUS);
++ if (ec_instruction_cycle() < 0)
++ return EC_STATE_BUSY;
++ if ((ec_read(REG_XBISPIDAT) & 0x01) == 0x00)
++ return EC_STATE_IDLE;
++ udelay(EC_MAX_DELAY_UNIT);
++ }
++ if (timeout <= 0) {
++ printk(KERN_ERR
++ "EC_FLASH_BUSY : timeout for check rom flag.\n");
++ return EC_STATE_BUSY;
++ }
++#else
++ /* check the rom's status of busy flag */
++ ec_write(REG_XBISPICMD, SPICMD_READ_STATUS);
++ if (ec_instruction_cycle() < 0)
++ return EC_STATE_BUSY;
++
++ timeout = timeout / EC_MAX_DELAY_UNIT;
++ while (timeout-- > 0) {
++ if ((ec_read(REG_XBISPIDAT) & 0x01) == 0x00)
++ return EC_STATE_IDLE;
++ udelay(EC_MAX_DELAY_UNIT);
++ }
++ if (timeout <= 0) {
++ printk(KERN_ERR
++ "EC_FLASH_BUSY : timeout for check rom flag.\n");
++ return EC_STATE_BUSY;
++ }
++#endif
++
++ return EC_STATE_IDLE;
++}
++
++static int rom_instruction_cycle(unsigned char cmd)
++{
++ unsigned long timeout = 0;
++
++ switch (cmd) {
++ case SPICMD_READ_STATUS:
++ case SPICMD_WRITE_ENABLE:
++ case SPICMD_WRITE_DISABLE:
++ case SPICMD_READ_BYTE:
++ case SPICMD_HIGH_SPEED_READ:
++ timeout = 0;
++ break;
++ case SPICMD_WRITE_STATUS:
++ timeout = 300 * 1000;
++ break;
++ case SPICMD_BYTE_PROGRAM:
++ timeout = 5 * 1000;
++ break;
++ case SPICMD_SST_SEC_ERASE:
++ case SPICMD_SEC_ERASE:
++ timeout = 1000 * 1000;
++ break;
++ case SPICMD_SST_BLK_ERASE:
++ case SPICMD_BLK_ERASE:
++ timeout = 3 * 1000 * 1000;
++ break;
++ case SPICMD_SST_CHIP_ERASE:
++ case SPICMD_CHIP_ERASE:
++ timeout = 20 * 1000 * 1000;
++ break;
++ default:
++ timeout = EC_SPICMD_STANDARD_TIMEOUT;
++ }
++ if (timeout == 0)
++ return ec_instruction_cycle();
++ if (timeout < EC_SPICMD_STANDARD_TIMEOUT)
++ timeout = EC_SPICMD_STANDARD_TIMEOUT;
++
++ return ec_flash_busy(timeout);
++}
++
++/* delay for start/stop action */
++static void delay_spi(int n)
++{
++ while (n--)
++ inb(EC_IO_PORT_HIGH);
++}
++
++/* start the action to spi rom function */
++static void ec_start_spi(void)
++{
++ unsigned char val;
++
++ delay_spi(SPI_FINISH_WAIT_TIME);
++ val = ec_read(REG_XBISPICFG) | SPICFG_EN_SPICMD | SPICFG_AUTO_CHECK;
++ ec_write(REG_XBISPICFG, val);
++ delay_spi(SPI_FINISH_WAIT_TIME);
++}
++
++/* stop the action to spi rom function */
++static void ec_stop_spi(void)
++{
++ unsigned char val;
++
++ delay_spi(SPI_FINISH_WAIT_TIME);
++ val =
++ ec_read(REG_XBISPICFG) & (~(SPICFG_EN_SPICMD | SPICFG_AUTO_CHECK));
++ ec_write(REG_XBISPICFG, val);
++ delay_spi(SPI_FINISH_WAIT_TIME);
++}
++
++/* read one byte from xbi interface */
++static int ec_read_byte(unsigned int addr, unsigned char *byte)
++{
++ int ret = 0;
++
++ /* enable spicmd writing. */
++ ec_start_spi();
++
++ /* enable write spi flash */
++ ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE);
++ if (rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY) {
++ printk(KERN_ERR "EC_READ_BYTE : SPICMD_WRITE_ENABLE failed.\n");
++ ret = -EINVAL;
++ goto out;
++ }
++
++ /* write the address */
++ ec_write(REG_XBISPIA2, (addr & 0xff0000) >> 16);
++ ec_write(REG_XBISPIA1, (addr & 0x00ff00) >> 8);
++ ec_write(REG_XBISPIA0, (addr & 0x0000ff) >> 0);
++ /* start action */
++ ec_write(REG_XBISPICMD, SPICMD_HIGH_SPEED_READ);
++ if (rom_instruction_cycle(SPICMD_HIGH_SPEED_READ) == EC_STATE_BUSY) {
++ printk(KERN_ERR
++ "EC_READ_BYTE : SPICMD_HIGH_SPEED_READ failed.\n");
++ ret = -EINVAL;
++ goto out;
++ }
++
++ *byte = ec_read(REG_XBISPIDAT);
++
++ out:
++ /* disable spicmd writing. */
++ ec_stop_spi();
++
++ return ret;
++}
++
++/* write one byte to ec rom */
++static int ec_write_byte(unsigned int addr, unsigned char byte)
++{
++ int ret = 0;
++
++ /* enable spicmd writing. */
++ ec_start_spi();
++
++ /* enable write spi flash */
++ ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE);
++ if (rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY) {
++ printk(KERN_ERR
++ "EC_WRITE_BYTE : SPICMD_WRITE_ENABLE failed.\n");
++ ret = -EINVAL;
++ goto out;
++ }
++
++ /* write the address */
++ ec_write(REG_XBISPIA2, (addr & 0xff0000) >> 16);
++ ec_write(REG_XBISPIA1, (addr & 0x00ff00) >> 8);
++ ec_write(REG_XBISPIA0, (addr & 0x0000ff) >> 0);
++ ec_write(REG_XBISPIDAT, byte);
++ /* start action */
++ ec_write(REG_XBISPICMD, SPICMD_BYTE_PROGRAM);
++ if (rom_instruction_cycle(SPICMD_BYTE_PROGRAM) == EC_STATE_BUSY) {
++ printk(KERN_ERR
++ "EC_WRITE_BYTE : SPICMD_BYTE_PROGRAM failed.\n");
++ ret = -EINVAL;
++ goto out;
++ }
++
++ out:
++ /* disable spicmd writing. */
++ ec_stop_spi();
++
++ return ret;
++}
++
++/* unprotect SPI ROM */
++/* EC_ROM_unprotect function code */
++static int EC_ROM_unprotect(void)
++{
++ unsigned char status;
++
++ /* enable write spi flash */
++ ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE);
++ if (rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY) {
++ printk(KERN_ERR
++ "EC_UNIT_ERASE : SPICMD_WRITE_ENABLE failed.\n");
++ return 1;
++ }
++
++ /* unprotect the status register of rom */
++ ec_write(REG_XBISPICMD, SPICMD_READ_STATUS);
++ if (rom_instruction_cycle(SPICMD_READ_STATUS) == EC_STATE_BUSY) {
++ printk(KERN_ERR "EC_UNIT_ERASE : SPICMD_READ_STATUS failed.\n");
++ return 1;
++ }
++ status = ec_read(REG_XBISPIDAT);
++ ec_write(REG_XBISPIDAT, status & 0x02);
++ if (ec_instruction_cycle() < 0) {
++ printk(KERN_ERR "EC_UNIT_ERASE : write status value failed.\n");
++ return 1;
++ }
++
++ ec_write(REG_XBISPICMD, SPICMD_WRITE_STATUS);
++ if (rom_instruction_cycle(SPICMD_WRITE_STATUS) == EC_STATE_BUSY) {
++ printk(KERN_ERR
++ "EC_UNIT_ERASE : SPICMD_WRITE_STATUS failed.\n");
++ return 1;
++ }
++
++ /* enable write spi flash */
++ ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE);
++ if (rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY) {
++ printk(KERN_ERR
++ "EC_UNIT_ERASE : SPICMD_WRITE_ENABLE failed.\n");
++ return 1;
++ }
++
++ return 0;
++}
++
++/* erase one block or chip or sector as needed */
++static int ec_unit_erase(unsigned char erase_cmd, unsigned int addr)
++{
++ unsigned char status;
++ int ret = 0, i = 0;
++ int unprotect_count = 3;
++ int check_flag = 0;
++
++ /* enable spicmd writing. */
++ ec_start_spi();
++
++#ifdef EC_ROM_PROTECTION
++ /* added for re-check SPICMD_READ_STATUS */
++ while (unprotect_count-- > 0) {
++ if (EC_ROM_unprotect()) {
++ ret = -EINVAL;
++ goto out;
++ }
++
++ /* first time:500ms --> 5.5sec -->10.5sec */
++ for (i = 0; i < ((2 - unprotect_count) * 100 + 10); i++)
++ udelay(50000);
++ ec_write(REG_XBISPICMD, SPICMD_READ_STATUS);
++ if (rom_instruction_cycle(SPICMD_READ_STATUS)
++ == EC_STATE_BUSY) {
++ printk(KERN_ERR
++ "EC_PROGRAM_ROM : SPICMD_READ_STATUS failed.\n");
++ } else {
++ status = ec_read(REG_XBISPIDAT);
++ printk(KERN_INFO "Read unprotect status : 0x%x\n",
++ status);
++ if ((status & 0x1C) == 0x00) {
++ printk(KERN_INFO
++ "Read unprotect status OK1 : 0x%x\n",
++ status & 0x1C);
++ check_flag = 1;
++ break;
++ }
++ }
++ }
++
++ if (!check_flag) {
++ printk(KERN_INFO "SPI ROM unprotect fail.\n");
++ return 1;
++ }
++#endif
++
++ /* block address fill */
++ if (erase_cmd == SPICMD_BLK_ERASE) {
++ ec_write(REG_XBISPIA2, (addr & 0x00ff0000) >> 16);
++ ec_write(REG_XBISPIA1, (addr & 0x0000ff00) >> 8);
++ ec_write(REG_XBISPIA0, (addr & 0x000000ff) >> 0);
++ }
++
++ /* erase the whole chip first */
++ ec_write(REG_XBISPICMD, erase_cmd);
++ if (rom_instruction_cycle(erase_cmd) == EC_STATE_BUSY) {
++ printk(KERN_ERR "EC_UNIT_ERASE : erase failed.\n");
++ ret = -EINVAL;
++ goto out;
++ }
++
++ out:
++ /* disable spicmd writing. */
++ ec_stop_spi();
++
++ return ret;
++}
++
++/* update the whole rom content with H/W mode
++ * PLEASE USING ec_unit_erase() FIRSTLY
++ */
++static int ec_program_rom(struct ec_info *info, int flag)
++{
++ unsigned int addr = 0;
++ unsigned long size = 0;
++ unsigned char *ptr = NULL;
++ unsigned char data;
++ unsigned char val = 0;
++ int ret = 0;
++ int i, j;
++ unsigned char status;
++
++ /* modify for program serial No.
++ * set IE_START_ADDR & use idle mode,
++ * disable WDD
++ */
++ if (flag == PROGRAM_FLAG_ROM) {
++ ret = ec_init_reset_mode();
++ addr = info->start_addr + EC_START_ADDR;
++ printk(KERN_INFO "PROGRAM_FLAG_ROM..............\n");
++ } else if (flag == PROGRAM_FLAG_IE) {
++ ret = ec_init_idle_mode();
++ ec_disable_WDD();
++ addr = info->start_addr + IE_START_ADDR;
++ printk(KERN_INFO "PROGRAM_FLAG_IE..............\n");
++ } else {
++ return 0;
++ }
++
++ if (ret < 0) {
++ if (flag == PROGRAM_FLAG_IE)
++ ec_enable_WDD();
++ return ret;
++ }
++
++ size = info->size;
++ ptr = info->buf;
++ printk(KERN_INFO "starting update ec ROM..............\n");
++
++ ret = ec_unit_erase(SPICMD_BLK_ERASE, addr);
++ if (ret) {
++ printk(KERN_ERR "program ec : erase block failed.\n");
++ goto out;
++ }
++ printk(KERN_ERR "program ec : erase block OK.\n");
++
++ i = 0;
++ while (i < size) {
++ data = *(ptr + i);
++ ec_write_byte(addr, data);
++ ec_read_byte(addr, &val);
++ if (val != data) {
++ ec_write_byte(addr, data);
++ ec_read_byte(addr, &val);
++ if (val != data) {
++ printk(KERN_INFO
++ "EC : Second flash program failed at:\t");
++ printk(KERN_INFO
++ "addr : 0x%x, source : 0x%x, dest: 0x%x\n",
++ addr, data, val);
++ printk(KERN_INFO "This should not happen... STOP\n");
++ break;
++ }
++ }
++ i++;
++ addr++;
++ }
++
++#ifdef EC_ROM_PROTECTION
++ /* we should start spi access firstly */
++ ec_start_spi();
++
++ /* enable write spi flash */
++ ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE);
++ if (rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY) {
++ printk(KERN_ERR
++ "EC_PROGRAM_ROM : SPICMD_WRITE_ENABLE failed.\n");
++ goto out1;
++ }
++
++ /* protect the status register of rom */
++ ec_write(REG_XBISPICMD, SPICMD_READ_STATUS);
++ if (rom_instruction_cycle(SPICMD_READ_STATUS) == EC_STATE_BUSY) {
++ printk(KERN_ERR
++ "EC_PROGRAM_ROM : SPICMD_READ_STATUS failed.\n");
++ goto out1;
++ }
++ status = ec_read(REG_XBISPIDAT);
++
++ ec_write(REG_XBISPIDAT, status | 0x1C);
++ if (ec_instruction_cycle() < 0) {
++ printk(KERN_ERR
++ "EC_PROGRAM_ROM : write status value failed.\n");
++ goto out1;
++ }
++
++ ec_write(REG_XBISPICMD, SPICMD_WRITE_STATUS);
++ if (rom_instruction_cycle(SPICMD_WRITE_STATUS) == EC_STATE_BUSY) {
++ printk(KERN_ERR
++ "EC_PROGRAM_ROM : SPICMD_WRITE_STATUS failed.\n");
++ goto out1;
++ }
++#endif
++
++ /* disable the write action to spi rom */
++ ec_write(REG_XBISPICMD, SPICMD_WRITE_DISABLE);
++ if (rom_instruction_cycle(SPICMD_WRITE_DISABLE) == EC_STATE_BUSY) {
++ printk(KERN_ERR
++ "EC_PROGRAM_ROM : SPICMD_WRITE_DISABLE failed.\n");
++ goto out1;
++ }
++
++ out1:
++ /* we should stop spi access firstly */
++ ec_stop_spi();
++ out:
++ /* for security */
++ for (j = 0; j < 2000; j++)
++ udelay(1000);
++
++ /* modify for program serial No.
++ * after program No exit idle mode
++ * and enable WDD
++ */
++ if (flag == PROGRAM_FLAG_ROM) {
++ /* exit from the reset mode */
++ ec_exit_reset_mode();
++ } else {
++ /* ec exit from idle mode */
++ ret = ec_exit_idle_mode();
++ ec_enable_WDD();
++ if (ret < 0)
++ return ret;
++ }
++
++ return 0;
++}
++
++/* ioctl */
++static int misc_ioctl(struct inode *inode, struct file *filp, u_int cmd,
++ u_long arg)
++{
++ struct ec_info ecinfo;
++ void __user *ptr = (void __user *)arg;
++ struct ec_reg *ecreg = (struct ec_reg *)(filp->private_data);
++ int ret = 0;
++
++ switch (cmd) {
++ case IOCTL_RDREG:
++ ret = copy_from_user(ecreg, ptr, sizeof(struct ec_reg));
++ if (ret) {
++ printk(KERN_ERR "reg read : copy from user error.\n");
++ return -EFAULT;
++ }
++ if ((ecreg->addr > EC_MAX_REGADDR)
++ || (ecreg->addr < EC_MIN_REGADDR)) {
++ printk(KERN_ERR
++ "reg read : out of register address range.\n");
++ return -EINVAL;
++ }
++ ecreg->val = ec_read(ecreg->addr);
++ ret = copy_to_user(ptr, ecreg, sizeof(struct ec_reg));
++ if (ret) {
++ printk(KERN_ERR "reg read : copy to user error.\n");
++ return -EFAULT;
++ }
++ break;
++ case IOCTL_WRREG:
++ ret = copy_from_user(ecreg, ptr, sizeof(struct ec_reg));
++ if (ret) {
++ printk(KERN_ERR "reg write : copy from user error.\n");
++ return -EFAULT;
++ }
++ if ((ecreg->addr > EC_MAX_REGADDR)
++ || (ecreg->addr < EC_MIN_REGADDR)) {
++ printk(KERN_ERR
++ "reg write : out of register address range.\n");
++ return -EINVAL;
++ }
++ ec_write(ecreg->addr, ecreg->val);
++ break;
++ case IOCTL_READ_EC:
++ ret = copy_from_user(ecreg, ptr, sizeof(struct ec_reg));
++ if (ret) {
++ printk(KERN_ERR "spi read : copy from user error.\n");
++ return -EFAULT;
++ }
++ if ((ecreg->addr > EC_RAM_ADDR)
++ && (ecreg->addr < EC_MAX_REGADDR)) {
++ printk(KERN_ERR
++ "spi read : out of register address range.\n");
++ return -EINVAL;
++ }
++ ec_read_byte(ecreg->addr, &(ecreg->val));
++ ret = copy_to_user(ptr, ecreg, sizeof(struct ec_reg));
++ if (ret) {
++ printk(KERN_ERR "spi read : copy to user error.\n");
++ return -EFAULT;
++ }
++ break;
++ case IOCTL_PROGRAM_IE:
++ ecinfo.start_addr = EC_START_ADDR;
++ ecinfo.size = EC_CONTENT_MAX_SIZE;
++ ecinfo.buf = (u8 *) kmalloc(ecinfo.size, GFP_KERNEL);
++ if (ecinfo.buf == NULL) {
++ printk(KERN_ERR "program ie : kmalloc failed.\n");
++ return -ENOMEM;
++ }
++ ret = copy_from_user(ecinfo.buf, (u8 *) ptr, ecinfo.size);
++ if (ret) {
++ printk(KERN_ERR "program ie : copy from user error.\n");
++ kfree(ecinfo.buf);
++ ecinfo.buf = NULL;
++ return -EFAULT;
++ }
++
++ /* use ec_program_rom to write serial No */
++ ec_program_rom(&ecinfo, PROGRAM_FLAG_IE);
++
++ kfree(ecinfo.buf);
++ ecinfo.buf = NULL;
++ break;
++ case IOCTL_PROGRAM_EC:
++ ecinfo.start_addr = EC_START_ADDR;
++ if (get_user((ecinfo.size), (u32 *) ptr)) {
++ printk(KERN_ERR "program ec : get user error.\n");
++ return -EFAULT;
++ }
++ if ((ecinfo.size) > EC_CONTENT_MAX_SIZE) {
++ printk(KERN_ERR "program ec : size out of limited.\n");
++ return -EINVAL;
++ }
++ ecinfo.buf = (u8 *) kmalloc(ecinfo.size, GFP_KERNEL);
++ if (ecinfo.buf == NULL) {
++ printk(KERN_ERR "program ec : kmalloc failed.\n");
++ return -ENOMEM;
++ }
++ ret = copy_from_user(ecinfo.buf, ((u8 *) ptr + 4), ecinfo.size);
++ if (ret) {
++ printk(KERN_ERR "program ec : copy from user error.\n");
++ kfree(ecinfo.buf);
++ ecinfo.buf = NULL;
++ return -EFAULT;
++ }
++
++ ec_program_rom(&ecinfo, PROGRAM_FLAG_ROM);
++
++ kfree(ecinfo.buf);
++ ecinfo.buf = NULL;
++ break;
++
++ default:
++ break;
++ }
++
++ return 0;
++}
++
++static long misc_compat_ioctl(struct file *file, unsigned int cmd,
++ unsigned long arg)
++{
++ return misc_ioctl(file->f_dentry->d_inode, file, cmd, arg);
++}
++
++static int misc_open(struct inode *inode, struct file *filp)
++{
++ struct ec_reg *ecreg = NULL;
++ ecreg = kmalloc(sizeof(struct ec_reg), GFP_KERNEL);
++ if (ecreg)
++ filp->private_data = ecreg;
++
++ return ecreg ? 0 : -ENOMEM;
++}
++
++static int misc_release(struct inode *inode, struct file *filp)
++{
++ struct ec_reg *ecreg = (struct ec_reg *)(filp->private_data);
++
++ filp->private_data = NULL;
++ kfree(ecreg);
++
++ return 0;
++}
++
++static const struct file_operations ecmisc_fops = {
++ .open = misc_open,
++ .release = misc_release,
++ .read = NULL,
++ .write = NULL,
++#ifdef CONFIG_64BIT
++ .compat_ioctl = misc_compat_ioctl,
++#else
++ .ioctl = misc_ioctl,
++#endif
++};
++
++static struct miscdevice ecmisc_device = {
++ .minor = MISC_DYNAMIC_MINOR,
++ .name = EC_MISC_DEV,
++ .fops = &ecmisc_fops
++};
++
++static int __init ecmisc_init(void)
++{
++ int ret;
++
++ printk(KERN_INFO "EC misc device init.\n");
++ ret = misc_register(&ecmisc_device);
++
++ return ret;
++}
++
++static void __exit ecmisc_exit(void)
++{
++ printk(KERN_INFO "EC misc device exit.\n");
++ misc_deregister(&ecmisc_device);
++}
++
++module_init(ecmisc_init);
++module_exit(ecmisc_exit);
++
++MODULE_AUTHOR("liujl <liujl@lemote.com>");
++MODULE_DESCRIPTION("Driver for flushing/dumping ROM of EC on YeeLoong laptop");
++MODULE_LICENSE("GPL");
+diff --git a/arch/mips/loongson/lemote-2f/yeeloong_laptop.c b/arch/mips/loongson/lemote-2f/yeeloong_laptop.c
+new file mode 100644
+index 0000000..24e9acc
+--- /dev/null
++++ b/arch/mips/loongson/lemote-2f/yeeloong_laptop.c
+@@ -0,0 +1,1285 @@
++/*
++ * Driver for YeeLoong laptop extras
++ *
++ * Copyright (C) 2009 Lemote Inc.
++ * Author: Wu Zhangjin <wuzj@lemote.com>
++ *
++ * 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 <linux/apm-emulation.h>
++#include <linux/backlight.h>
++#include <linux/delay.h>
++#include <linux/err.h>
++#include <linux/fb.h>
++#include <linux/hwmon.h>
++#include <linux/hwmon-sysfs.h>
++#include <linux/input.h>
++#include <linux/interrupt.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/thermal.h>
++#include <linux/video_output.h>
++
++#include <asm/bootinfo.h> /* for arcs_cmdline */
++
++#include <loongson.h>
++
++#include <cs5536/cs5536.h>
++#include "ec_kb3310b.h"
++
++#define DRIVER_VERSION "0.1"
++
++/* backlight subdriver */
++#define MAX_BRIGHTNESS 8
++
++static int yeeloong_set_brightness(struct backlight_device *bd)
++{
++ unsigned int level, current_level;
++ static unsigned int old_level;
++
++ level = (bd->props.fb_blank == FB_BLANK_UNBLANK &&
++ bd->props.power == FB_BLANK_UNBLANK) ?
++ bd->props.brightness : 0;
++
++ if (level > MAX_BRIGHTNESS)
++ level = MAX_BRIGHTNESS;
++ else if (level < 0)
++ level = 0;
++
++ /* avoid to modify the brightness when EC is tuning it */
++ current_level = ec_read(REG_DISPLAY_BRIGHTNESS);
++ if ((old_level == current_level) && (old_level != level))
++ ec_write(REG_DISPLAY_BRIGHTNESS, level);
++ old_level = level;
++
++ return 0;
++}
++
++static int yeeloong_get_brightness(struct backlight_device *bd)
++{
++ return (int)ec_read(REG_DISPLAY_BRIGHTNESS);
++}
++
++static struct backlight_ops backlight_ops = {
++ .get_brightness = yeeloong_get_brightness,
++ .update_status = yeeloong_set_brightness,
++};
++
++static struct backlight_device *yeeloong_backlight_dev;
++
++static int yeeloong_backlight_init(struct device *dev)
++{
++ int ret;
++
++ yeeloong_backlight_dev = backlight_device_register("backlight0", dev,
++ NULL, &backlight_ops);
++
++ if (IS_ERR(yeeloong_backlight_dev)) {
++ ret = PTR_ERR(yeeloong_backlight_dev);
++ yeeloong_backlight_dev = NULL;
++ return ret;
++ }
++
++ yeeloong_backlight_dev->props.max_brightness = MAX_BRIGHTNESS;
++ yeeloong_backlight_dev->props.brightness =
++ yeeloong_get_brightness(yeeloong_backlight_dev);
++ backlight_update_status(yeeloong_backlight_dev);
++
++ return 0;
++}
++
++static void yeeloong_backlight_exit(void)
++{
++ if (yeeloong_backlight_dev) {
++ backlight_device_unregister(yeeloong_backlight_dev);
++ yeeloong_backlight_dev = NULL;
++ }
++}
++
++/* hwmon subdriver */
++
++/* pwm(auto/manual) enable or not */
++static int get_fan_pwm_enable(void)
++{
++ /* get the fan control method: auto or manual */
++ return ec_read(REG_FAN_AUTO_MAN_SWITCH);
++}
++
++static void set_fan_pwm_enable(int manual)
++{
++ ec_write(REG_FAN_AUTO_MAN_SWITCH, !!manual);
++}
++
++static int get_fan_pwm(void)
++{
++ return ec_read(REG_FAN_SPEED_LEVEL);
++}
++
++static void set_fan_pwm(int value)
++{
++ int status;
++
++ value = SENSORS_LIMIT(value, 0, 3);
++
++ /* If value is not ZERO, We should ensure it is on */
++ if (value != 0) {
++ status = ec_read(REG_FAN_STATUS);
++ if (status == 0)
++ ec_write(REG_FAN_CONTROL, BIT_FAN_CONTROL_ON);
++ }
++ ec_write(REG_FAN_SPEED_LEVEL, value);
++}
++
++static int get_fan_rpm(void)
++{
++ int value = 0;
++
++ value = FAN_SPEED_DIVIDER /
++ (((ec_read(REG_FAN_SPEED_HIGH) & 0x0f) << 8) |
++ ec_read(REG_FAN_SPEED_LOW));
++
++ return value;
++}
++
++static int get_cpu_temp(void)
++{
++ int value;
++
++ value = ec_read(REG_TEMPERATURE_VALUE);
++
++ if (value & (1 << 7))
++ value = (value & 0x7f) - 128;
++ else
++ value = value & 0xff;
++
++ return value * 1000;
++}
++
++static int get_battery_temp(void)
++{
++ int value;
++
++ value = (ec_read(REG_BAT_TEMPERATURE_HIGH) << 8) |
++ (ec_read(REG_BAT_TEMPERATURE_LOW));
++
++ return value * 1000;
++}
++
++static int get_battery_current(void)
++{
++ int value;
++
++ value = (ec_read(REG_BAT_CURRENT_HIGH) << 8) |
++ (ec_read(REG_BAT_CURRENT_LOW));
++
++ if (value & 0x8000)
++ value = 0xffff - value;
++
++ return value;
++}
++
++static int get_battery_voltage(void)
++{
++ int value;
++
++ value = (ec_read(REG_BAT_VOLTAGE_HIGH) << 8) |
++ (ec_read(REG_BAT_VOLTAGE_LOW));
++
++ return value;
++}
++
++
++static int parse_arg(const char *buf, unsigned long count, int *val)
++{
++ if (!count)
++ return 0;
++ if (sscanf(buf, "%i", val) != 1)
++ return -EINVAL;
++ return count;
++}
++
++static ssize_t store_sys_hwmon(void (*set) (int), const char *buf, size_t count)
++{
++ int rv, value;
++
++ rv = parse_arg(buf, count, &value);
++ if (rv > 0)
++ set(value);
++ return rv;
++}
++
++static ssize_t show_sys_hwmon(int (*get) (void), char *buf)
++{
++ return sprintf(buf, "%d\n", get());
++}
++
++#define CREATE_SENSOR_ATTR(_name, _mode, _set, _get) \
++ static ssize_t show_##_name(struct device *dev, \
++ struct device_attribute *attr, \
++ char *buf) \
++ { \
++ return show_sys_hwmon(_set, buf); \
++ } \
++ static ssize_t store_##_name(struct device *dev, \
++ struct device_attribute *attr, \
++ const char *buf, size_t count) \
++ { \
++ return store_sys_hwmon(_get, buf, count); \
++ } \
++ static SENSOR_DEVICE_ATTR(_name, _mode, show_##_name, store_##_name, 0);
++
++CREATE_SENSOR_ATTR(fan1_input, S_IRUGO, get_fan_rpm, NULL);
++CREATE_SENSOR_ATTR(pwm1, S_IRUGO | S_IWUSR, get_fan_pwm, set_fan_pwm);
++CREATE_SENSOR_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, get_fan_pwm_enable,
++ set_fan_pwm_enable);
++CREATE_SENSOR_ATTR(temp1_input, S_IRUGO, get_cpu_temp, NULL);
++CREATE_SENSOR_ATTR(temp2_input, S_IRUGO, get_battery_temp, NULL);
++CREATE_SENSOR_ATTR(curr1_input, S_IRUGO, get_battery_current, NULL);
++CREATE_SENSOR_ATTR(in1_input, S_IRUGO, get_battery_voltage, NULL);
++
++static ssize_t
++show_name(struct device *dev, struct device_attribute *attr, char *buf)
++{
++ return sprintf(buf, "yeeloong\n");
++}
++
++static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0);
++
++static struct attribute *hwmon_attributes[] = {
++ &sensor_dev_attr_pwm1.dev_attr.attr,
++ &sensor_dev_attr_pwm1_enable.dev_attr.attr,
++ &sensor_dev_attr_fan1_input.dev_attr.attr,
++ &sensor_dev_attr_temp1_input.dev_attr.attr,
++ &sensor_dev_attr_temp2_input.dev_attr.attr,
++ &sensor_dev_attr_curr1_input.dev_attr.attr,
++ &sensor_dev_attr_in1_input.dev_attr.attr,
++ &sensor_dev_attr_name.dev_attr.attr,
++ NULL
++};
++
++static struct attribute_group hwmon_attribute_group = {
++ .attrs = hwmon_attributes
++};
++
++struct device *yeeloong_hwmon_dev;
++
++static int yeeloong_hwmon_init(struct device *dev)
++{
++ int ret;
++
++ yeeloong_hwmon_dev = hwmon_device_register(dev);
++ if (IS_ERR(yeeloong_hwmon_dev)) {
++ printk(KERN_INFO "unable to register yeeloong hwmon device\n");
++ yeeloong_hwmon_dev = NULL;
++ return PTR_ERR(yeeloong_hwmon_dev);
++ }
++ ret = sysfs_create_group(&yeeloong_hwmon_dev->kobj,
++ &hwmon_attribute_group);
++ if (ret) {
++ sysfs_remove_group(&yeeloong_hwmon_dev->kobj,
++ &hwmon_attribute_group);
++ hwmon_device_unregister(yeeloong_hwmon_dev);
++ yeeloong_hwmon_dev = NULL;
++ }
++ /* ensure fan is set to auto mode */
++ set_fan_pwm_enable(BIT_FAN_AUTO);
++
++ return 0;
++}
++
++static void yeeloong_hwmon_exit(void)
++{
++ if (yeeloong_hwmon_dev) {
++ sysfs_remove_group(&yeeloong_hwmon_dev->kobj,
++ &hwmon_attribute_group);
++ hwmon_device_unregister(yeeloong_hwmon_dev);
++ yeeloong_hwmon_dev = NULL;
++ }
++}
++
++/* video output subdriver */
++
++static int lcd_video_output_get(struct output_device *od)
++{
++ return ec_read(REG_DISPLAY_LCD);
++}
++
++static int lcd_video_output_set(struct output_device *od)
++{
++ unsigned long status = od->request_state;
++ int value;
++
++ if (status == BIT_DISPLAY_LCD_ON) {
++ /* open LCD */
++ outb(0x31, 0x3c4);
++ value = inb(0x3c5);
++ value = (value & 0xf8) | 0x03;
++ outb(0x31, 0x3c4);
++ outb(value, 0x3c5);
++ /* open backlight */
++ ec_write(REG_BACKLIGHT_CTRL, BIT_BACKLIGHT_ON);
++ } else {
++ /* close backlight */
++ ec_write(REG_BACKLIGHT_CTRL, BIT_BACKLIGHT_OFF);
++ /* close LCD */
++ outb(0x31, 0x3c4);
++ value = inb(0x3c5);
++ value = (value & 0xf8) | 0x02;
++ outb(0x31, 0x3c4);
++ outb(value, 0x3c5);
++ }
++
++ return 0;
++}
++
++static struct output_properties lcd_output_properties = {
++ .set_state = lcd_video_output_set,
++ .get_status = lcd_video_output_get,
++};
++
++static int crt_video_output_get(struct output_device *od)
++{
++ return ec_read(REG_CRT_DETECT);
++}
++
++static int crt_video_output_set(struct output_device *od)
++{
++ unsigned long status = od->request_state;
++ int value;
++
++ if (status == BIT_CRT_DETECT_PLUG) {
++ if (ec_read(REG_CRT_DETECT) == BIT_CRT_DETECT_PLUG) {
++ /* open CRT */
++ outb(0x21, 0x3c4);
++ value = inb(0x3c5);
++ value &= ~(1 << 7);
++ outb(0x21, 0x3c4);
++ outb(value, 0x3c5);
++ }
++ } else {
++ /* close CRT */
++ outb(0x21, 0x3c4);
++ value = inb(0x3c5);
++ value |= (1 << 7);
++ outb(0x21, 0x3c4);
++ outb(value, 0x3c5);
++ }
++
++ return 0;
++}
++
++static struct output_properties crt_output_properties = {
++ .set_state = crt_video_output_set,
++ .get_status = crt_video_output_get,
++};
++
++struct output_device *lcd_output_dev, *crt_output_dev;
++
++static void lcd_vo_set(int status)
++{
++ lcd_output_dev->request_state = status;
++ lcd_video_output_set(lcd_output_dev);
++}
++
++static void crt_vo_set(int status)
++{
++ crt_output_dev->request_state = status;
++ crt_video_output_set(crt_output_dev);
++}
++
++static int crt_detect_handler(int status)
++{
++ if (status == BIT_CRT_DETECT_PLUG) {
++ crt_vo_set(BIT_CRT_DETECT_PLUG);
++ lcd_vo_set(BIT_DISPLAY_LCD_OFF);
++ } else {
++ lcd_vo_set(BIT_DISPLAY_LCD_ON);
++ crt_vo_set(BIT_CRT_DETECT_UNPLUG);
++ }
++ return status;
++}
++
++#define EC_VER_LEN 64
++
++static int black_screen_handler(int status)
++{
++ char *p, ec_ver[EC_VER_LEN];
++
++ p = strstr(arcs_cmdline, "EC_VER=");
++ if (!p)
++ memset(ec_ver, 0, EC_VER_LEN);
++ else {
++ strncpy(ec_ver, p, EC_VER_LEN);
++ p = strstr(ec_ver, " ");
++ if (p)
++ *p = '\0';
++ }
++
++ /* Seems EC(>=PQ1D26) does this job for us, we can not do it again,
++ * otherwise, the brightness will not resume to the normal level! */
++ if (strncasecmp(ec_ver, "EC_VER=PQ1D26", 64) < 0)
++ lcd_vo_set(status);
++
++ return status;
++}
++
++static int display_toggle_handler(int status)
++{
++ static int video_output_status;
++
++ /* only enable switch video output button
++ * when CRT is connected */
++ if (ec_read(REG_CRT_DETECT) == BIT_CRT_DETECT_UNPLUG)
++ return 0;
++ /* 0. no CRT connected: LCD on, CRT off
++ * 1. BOTH on
++ * 2. LCD off, CRT on
++ * 3. BOTH off
++ * 4. LCD on, CRT off
++ */
++ video_output_status++;
++ if (video_output_status > 4)
++ video_output_status = 1;
++
++ switch (video_output_status) {
++ case 1:
++ lcd_vo_set(BIT_DISPLAY_LCD_ON);
++ crt_vo_set(BIT_CRT_DETECT_PLUG);
++ break;
++ case 2:
++ lcd_vo_set(BIT_DISPLAY_LCD_OFF);
++ crt_vo_set(BIT_CRT_DETECT_PLUG);
++ break;
++ case 3:
++ lcd_vo_set(BIT_DISPLAY_LCD_OFF);
++ crt_vo_set(BIT_CRT_DETECT_UNPLUG);
++ break;
++ case 4:
++ lcd_vo_set(BIT_DISPLAY_LCD_ON);
++ crt_vo_set(BIT_CRT_DETECT_UNPLUG);
++ break;
++ default:
++ /* ensure LCD is on */
++ lcd_vo_set(BIT_DISPLAY_LCD_ON);
++ break;
++ }
++ return video_output_status;
++}
++
++static int yeeloong_vo_init(struct device *dev)
++{
++ int ret;
++
++ /* register video output device: lcd, crt */
++ lcd_output_dev = video_output_register("LCD", dev, NULL,
++ &lcd_output_properties);
++
++ if (IS_ERR(lcd_output_dev)) {
++ ret = PTR_ERR(lcd_output_dev);
++ lcd_output_dev = NULL;
++ return ret;
++ }
++ /* ensure LCD is on by default */
++ lcd_vo_set(1);
++
++ crt_output_dev = video_output_register("CRT", dev, NULL,
++ &crt_output_properties);
++
++ if (IS_ERR(crt_output_dev)) {
++ ret = PTR_ERR(crt_output_dev);
++ crt_output_dev = NULL;
++ return ret;
++ }
++ /* close CRT by default, and will be enabled
++ * when the CRT connectting event reported by SCI */
++ crt_vo_set(0);
++
++ /* install event handlers */
++ yeeloong_install_sci_handler(EVENT_CRT_DETECT, crt_detect_handler);
++ yeeloong_install_sci_handler(EVENT_BLACK_SCREEN, black_screen_handler);
++ yeeloong_install_sci_handler(EVENT_DISPLAY_TOGGLE,
++ display_toggle_handler);
++ return 0;
++}
++
++static void yeeloong_vo_exit(void)
++{
++ /* uninstall event handlers */
++ yeeloong_uninstall_sci_handler(EVENT_CRT_DETECT, crt_detect_handler);
++ yeeloong_uninstall_sci_handler(EVENT_BLACK_SCREEN,
++ black_screen_handler);
++ yeeloong_uninstall_sci_handler(EVENT_DISPLAY_TOGGLE,
++ display_toggle_handler);
++
++ if (lcd_output_dev) {
++ video_output_unregister(lcd_output_dev);
++ lcd_output_dev = NULL;
++ }
++ if (crt_output_dev) {
++ video_output_unregister(crt_output_dev);
++ crt_output_dev = NULL;
++ }
++}
++
++/* Thermal cooling devices subdriver */
++
++static int video_get_max_state(struct thermal_cooling_device *cdev, unsigned
++ long *state)
++{
++ *state = MAX_BRIGHTNESS;
++ return 0;
++}
++
++static int video_get_cur_state(struct thermal_cooling_device *cdev, unsigned
++ long *state)
++{
++ static struct backlight_device *bd;
++
++ bd = (struct backlight_device *)cdev->devdata;
++
++ *state = yeeloong_get_brightness(bd);
++
++ return 0;
++}
++
++static int video_set_cur_state(struct thermal_cooling_device *cdev, unsigned
++ long state)
++{
++ static struct backlight_device *bd;
++
++ bd = (struct backlight_device *)cdev->devdata;
++
++ yeeloong_backlight_dev->props.brightness = state;
++ backlight_update_status(bd);
++
++ return 0;
++}
++
++static struct thermal_cooling_device_ops video_cooling_ops = {
++ .get_max_state = video_get_max_state,
++ .get_cur_state = video_get_cur_state,
++ .set_cur_state = video_set_cur_state,
++};
++
++static struct thermal_cooling_device *yeeloong_thermal_cdev;
++
++/* TODO: register fan, cpu as the cooling devices */
++static int yeeloong_thermal_init(struct device *dev)
++{
++ int ret;
++
++ if (!dev)
++ return -1;
++
++ yeeloong_thermal_cdev = thermal_cooling_device_register("LCD", dev,
++ &video_cooling_ops);
++
++ if (IS_ERR(yeeloong_thermal_cdev)) {
++ ret = PTR_ERR(yeeloong_thermal_cdev);
++ return ret;
++ }
++
++ ret = sysfs_create_link(&dev->kobj,
++ &yeeloong_thermal_cdev->device.kobj,
++ "thermal_cooling");
++ if (ret) {
++ printk(KERN_ERR "Create sysfs link\n");
++ return ret;
++ }
++ ret = sysfs_create_link(&yeeloong_thermal_cdev->device.kobj,
++ &dev->kobj, "device");
++ if (ret) {
++ printk(KERN_ERR "Create sysfs link\n");
++ return ret;
++ }
++
++ return 0;
++}
++
++static void yeeloong_thermal_exit(struct device *dev)
++{
++ if (yeeloong_thermal_cdev) {
++ if (dev)
++ sysfs_remove_link(&dev->kobj, "thermal_cooling");
++ sysfs_remove_link(&yeeloong_thermal_cdev->device.kobj,
++ "device");
++ thermal_cooling_device_unregister(yeeloong_thermal_cdev);
++ yeeloong_thermal_cdev = NULL;
++ }
++}
++
++/* hotkey input subdriver */
++
++static struct input_dev *yeeloong_hotkey_dev;
++static int event, status;
++
++struct key_entry {
++ char type; /* See KE_* below */
++ int event; /* event from SCI */
++ u16 keycode; /* KEY_* or SW_* */
++};
++
++enum { KE_KEY, KE_SW, KE_END };
++
++static struct key_entry yeeloong_keymap[] = {
++ {KE_SW, EVENT_LID, SW_LID},
++ /*{KE_KEY, EVENT_AC_BAT, KEY_BATTERY},*/
++ {KE_KEY, EVENT_CAMERA, KEY_CAMERA}, /* Fn + ESC */
++ {KE_KEY, EVENT_SLEEP, KEY_SLEEP}, /* Fn + F1 */
++ {KE_KEY, EVENT_DISPLAY_TOGGLE, KEY_SWITCHVIDEOMODE}, /* Fn + F3 */
++ {KE_KEY, EVENT_AUDIO_MUTE, KEY_MUTE}, /* Fn + F4 */
++ {KE_KEY, EVENT_WLAN, KEY_WLAN}, /* Fn + F5 */
++ {KE_KEY, EVENT_DISPLAY_BRIGHTNESS, KEY_BRIGHTNESSUP}, /* Fn + up */
++ {KE_KEY, EVENT_DISPLAY_BRIGHTNESS, KEY_BRIGHTNESSDOWN}, /* Fn + down */
++ {KE_KEY, EVENT_AUDIO_VOLUME, KEY_VOLUMEUP}, /* Fn + right */
++ {KE_KEY, EVENT_AUDIO_VOLUME, KEY_VOLUMEDOWN}, /* Fn + left */
++ {KE_END, 0, KEY_UNKNOWN}
++};
++
++static int yeeloong_lid_update_status(int status)
++{
++ input_report_switch(yeeloong_hotkey_dev, SW_LID, !status);
++ input_sync(yeeloong_hotkey_dev);
++
++ return status;
++}
++
++static void yeeloong_hotkey_update_status(int key)
++{
++ input_report_key(yeeloong_hotkey_dev, key, 1);
++ input_sync(yeeloong_hotkey_dev);
++ input_report_key(yeeloong_hotkey_dev, key, 0);
++ input_sync(yeeloong_hotkey_dev);
++}
++
++static int get_event_keycode(void)
++{
++ struct key_entry *key;
++
++ for (key = yeeloong_keymap; key->type != KE_END; key++) {
++ if (key->event != event)
++ continue;
++ else {
++ if (EVENT_DISPLAY_BRIGHTNESS == event) {
++ static int old_brightness_status = -1;
++ /* current status > old one, means up */
++ if ((status < old_brightness_status)
++ || (0 == status))
++ key++;
++ old_brightness_status = status;
++ } else if (EVENT_AUDIO_VOLUME == event) {
++ static int old_volume_status = -1;
++ if ((status < old_volume_status)
++ || (0 == status))
++ key++;
++ old_volume_status = status;
++ }
++ break;
++ }
++ }
++ return key->keycode;
++}
++
++void yeeloong_report_key(void)
++{
++ int keycode;
++
++ keycode = get_event_keycode();
++ if (keycode == KEY_UNKNOWN)
++ return;
++
++ if (keycode == SW_LID)
++ yeeloong_lid_update_status(status);
++ else
++ yeeloong_hotkey_update_status(keycode);
++}
++
++enum { NO_REG, MUL_REG, REG_END };
++
++int event_reg[15] = {
++ REG_LID_DETECT, /* LID open/close */
++ NO_REG, /* Fn+F3 for display switch */
++ NO_REG, /* Fn+F1 for entering sleep mode */
++ MUL_REG, /* Over-temperature happened */
++ REG_CRT_DETECT, /* CRT is connected */
++ REG_CAMERA_STATUS, /* Camera on/off */
++ REG_USB2_FLAG, /* USB2 Over Current occurred */
++ REG_USB0_FLAG, /* USB0 Over Current occurred */
++ REG_DISPLAY_LCD, /* Black screen on/off */
++ REG_AUDIO_MUTE, /* Mute on/off */
++ REG_DISPLAY_BRIGHTNESS, /* LCD backlight brightness adjust */
++ NO_REG, /* AC & Battery relative issue */
++ REG_AUDIO_VOLUME, /* Volume adjust */
++ REG_WLAN, /* Wlan on/off */
++ REG_END
++};
++
++static int ec_get_event_status(void)
++{
++ int reg;
++
++ reg = event_reg[event - EVENT_LID];
++
++ if (reg == NO_REG)
++ return 1;
++ else if (reg == MUL_REG) {
++ if (event == EVENT_OVERTEMP) {
++ return (ec_read(REG_BAT_CHARGE_STATUS) &
++ BIT_BAT_CHARGE_STATUS_OVERTEMP) >> 2;
++ }
++ } else if (reg != REG_END)
++ return ec_read(reg);
++
++ return -1;
++}
++
++static sci_handler event_handler[15];
++
++int yeeloong_install_sci_handler(int event, sci_handler handler)
++{
++ if (event_handler[event - EVENT_LID] != NULL) {
++ printk(KERN_INFO "There is a handler installed for event: %d\n",
++ event);
++ return -1;
++ }
++ event_handler[event - EVENT_LID] = handler;
++
++ return 0;
++}
++EXPORT_SYMBOL(yeeloong_install_sci_handler);
++
++int yeeloong_uninstall_sci_handler(int event, sci_handler handler)
++{
++ if (event_handler[event - EVENT_LID] == NULL) {
++ printk(KERN_INFO "There is no handler installed for event: %d\n",
++ event);
++ return -1;
++ }
++ if (event_handler[event - EVENT_LID] != handler) {
++ printk(KERN_INFO "You can not uninstall the handler installed by others\n");
++ return -1;
++ }
++ event_handler[event - EVENT_LID] = NULL;
++
++ return 0;
++}
++EXPORT_SYMBOL(yeeloong_uninstall_sci_handler);
++
++static void yeeloong_event_action(void)
++{
++ sci_handler handler;
++
++ handler = event_handler[event - EVENT_LID];
++
++ if (handler == NULL)
++ return;
++
++ if (event == EVENT_CAMERA)
++ status = handler(3);
++ else
++ status = handler(status);
++}
++
++/*
++ * SCI(system control interrupt) main interrupt routine
++ *
++ * we will do the query and get event number together so the interrupt routine
++ * should be longer than 120us now at least 3ms elpase for it.
++ */
++static irqreturn_t sci_irq_handler(int irq, void *dev_id)
++{
++ int ret;
++
++ if (SCI_IRQ_NUM != irq) {
++ printk(KERN_ERR "%s: spurious irq.\n", __func__);
++ return IRQ_NONE;
++ }
++
++ /* query the event number */
++ ret = ec_query_event_num();
++ if (ret < 0) {
++ printk(KERN_ERR "%s: return: %d\n", __func__, ret);
++ return IRQ_NONE;
++ }
++
++ event = ec_get_event_num();
++ if (event < 0) {
++ printk(KERN_ERR "%s: return: %d\n", __func__, event);
++ return IRQ_NONE;
++ }
++
++ if ((event != 0x00) && (event != 0xff)) {
++ /* get status of current event */
++ status = ec_get_event_status();
++ printk(KERN_INFO "%s: event: %d, status: %d\n", __func__,
++ event, status);
++ if (status == -1)
++ return IRQ_NONE;
++ /* execute corresponding actions */
++ yeeloong_event_action();
++ /* report current key */
++ yeeloong_report_key();
++ }
++ return IRQ_HANDLED;
++}
++
++/*
++ * config and init some msr and gpio register properly.
++ */
++static int sci_irq_init(void)
++{
++ u32 hi, lo;
++ u32 gpio_base;
++ int ret = 0;
++ unsigned long flags;
++
++ /* get gpio base */
++ _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &lo);
++ gpio_base = lo & 0xff00;
++
++ /* filter the former kb3310 interrupt for security */
++ ret = ec_query_event_num();
++ if (ret) {
++ printk(KERN_ERR "%s: failed.\n", __func__);
++ return ret;
++ }
++
++ /* for filtering next number interrupt */
++ udelay(10000);
++
++ /* set gpio native registers and msrs for GPIO27 SCI EVENT PIN
++ * gpio :
++ * input, pull-up, no-invert, event-count and value 0,
++ * no-filter, no edge mode
++ * gpio27 map to Virtual gpio0
++ * msr :
++ * no primary and lpc
++ * Unrestricted Z input to IG10 from Virtual gpio 0.
++ */
++ local_irq_save(flags);
++ _rdmsr(0x80000024, &hi, &lo);
++ lo &= ~(1 << 10);
++ _wrmsr(0x80000024, hi, lo);
++ _rdmsr(0x80000025, &hi, &lo);
++ lo &= ~(1 << 10);
++ _wrmsr(0x80000025, hi, lo);
++ _rdmsr(0x80000023, &hi, &lo);
++ lo |= (0x0a << 0);
++ _wrmsr(0x80000023, hi, lo);
++ local_irq_restore(flags);
++
++ /* set gpio27 as sci interrupt
++ *
++ * input, pull-up, no-fliter, no-negedge, invert
++ * the sci event is just about 120us
++ */
++ asm(".set noreorder\n");
++ /* input enable */
++ outl(0x00000800, (gpio_base | 0xA0));
++ /* revert the input */
++ outl(0x00000800, (gpio_base | 0xA4));
++ /* event-int enable */
++ outl(0x00000800, (gpio_base | 0xB8));
++ asm(".set reorder\n");
++
++ return 0;
++}
++
++struct irqaction sci_irqaction = {
++ .handler = sci_irq_handler,
++ .name = "sci",
++ .flags = IRQF_SHARED,
++};
++
++static int setup_sci(void)
++{
++ sci_irq_init();
++
++ setup_irq(SCI_IRQ_NUM, &sci_irqaction);
++
++ return 0;
++}
++
++static int camera_set(int status)
++{
++ int value;
++ static int camera_status;
++
++ if (status == 2)
++ /* resume the old camera status */
++ camera_set(camera_status);
++ else if (status == 3) {
++ /* revert the camera status */
++ value = ec_read(REG_CAMERA_CONTROL);
++ ec_write(REG_CAMERA_CONTROL, value | (1 << 1));
++ } else {/* status == 0 or status == 1 */
++ status = !!status;
++ camera_status = ec_read(REG_CAMERA_STATUS);
++ if (status != camera_status)
++ camera_set(3);
++ }
++ return ec_read(REG_CAMERA_STATUS);
++}
++
++static void yeeloong_hotkey_exit(void)
++{
++ /* free irq */
++ remove_irq(SCI_IRQ_NUM, &sci_irqaction);
++
++#ifdef CONFIG_SUSPEND
++ /* uninstall the real yeeloong_report_lid_status for pm.c */
++ yeeloong_report_lid_status = NULL;
++#endif
++ /* uninstall event handler */
++ yeeloong_uninstall_sci_handler(EVENT_CAMERA, camera_set);
++
++ if (yeeloong_hotkey_dev) {
++ input_unregister_device(yeeloong_hotkey_dev);
++ yeeloong_hotkey_dev = NULL;
++ }
++}
++
++static int yeeloong_hotkey_init(struct device *dev)
++{
++ int ret;
++ struct key_entry *key;
++
++ /* setup the system control interface */
++ ret = setup_sci();
++ if (ret)
++ return -EFAULT;
++
++ yeeloong_hotkey_dev = input_allocate_device();
++
++ if (!yeeloong_hotkey_dev) {
++ yeeloong_hotkey_exit();
++ return -ENOMEM;
++ }
++
++ yeeloong_hotkey_dev->name = "HotKeys";
++ yeeloong_hotkey_dev->phys = "button/input0";
++ yeeloong_hotkey_dev->id.bustype = BUS_HOST;
++ yeeloong_hotkey_dev->dev.parent = dev;
++
++ for (key = yeeloong_keymap; key->type != KE_END; key++) {
++ switch (key->type) {
++ case KE_KEY:
++ set_bit(EV_KEY, yeeloong_hotkey_dev->evbit);
++ set_bit(key->keycode, yeeloong_hotkey_dev->keybit);
++ break;
++ case KE_SW:
++ set_bit(EV_SW, yeeloong_hotkey_dev->evbit);
++ set_bit(key->keycode, yeeloong_hotkey_dev->swbit);
++ break;
++ }
++ }
++
++ ret = input_register_device(yeeloong_hotkey_dev);
++ if (ret) {
++ input_free_device(yeeloong_hotkey_dev);
++ return ret;
++ }
++
++ if (ret) {
++ input_unregister_device(yeeloong_hotkey_dev);
++ yeeloong_hotkey_dev = NULL;
++ }
++ /* update the current status of lid */
++ yeeloong_lid_update_status(BIT_LID_DETECT_ON);
++
++#ifdef CONFIG_SUSPEND
++ /* install the real yeeloong_report_lid_status for pm.c */
++ yeeloong_report_lid_status = yeeloong_lid_update_status;
++#endif
++ /* install event handler */
++ yeeloong_install_sci_handler(EVENT_CAMERA, camera_set);
++
++ return 0;
++}
++
++/* battery subdriver: APM emulated support */
++
++static void get_fixed_battery_info(void)
++{
++ int design_cap, full_charged_cap, design_vol, vendor, cell_count;
++
++ design_cap = (ec_read(REG_BAT_DESIGN_CAP_HIGH) << 8)
++ | ec_read(REG_BAT_DESIGN_CAP_LOW);
++ full_charged_cap = (ec_read(REG_BAT_FULLCHG_CAP_HIGH) << 8)
++ | ec_read(REG_BAT_FULLCHG_CAP_LOW);
++ design_vol = (ec_read(REG_BAT_DESIGN_VOL_HIGH) << 8)
++ | ec_read(REG_BAT_DESIGN_VOL_LOW);
++ vendor = ec_read(REG_BAT_VENDOR);
++ cell_count = ec_read(REG_BAT_CELL_COUNT);
++
++ if (vendor != 0) {
++ printk(KERN_INFO
++ "battery vendor(%s), cells count(%d), "
++ "with designed capacity(%d),designed voltage(%d),"
++ " full charged capacity(%d)\n",
++ (vendor ==
++ FLAG_BAT_VENDOR_SANYO) ? "SANYO" : "SIMPLO",
++ (cell_count == FLAG_BAT_CELL_3S1P) ? 3 : 6,
++ design_cap, design_vol,
++ full_charged_cap);
++ }
++}
++
++#define APM_CRITICAL 5
++
++static void __maybe_unused yeeloong_apm_get_power_status(struct apm_power_info
++ *info)
++{
++ unsigned char bat_status;
++
++ info->battery_status = APM_BATTERY_STATUS_UNKNOWN;
++ info->battery_flag = APM_BATTERY_FLAG_UNKNOWN;
++ info->units = APM_UNITS_MINS;
++
++ info->battery_life = (ec_read(REG_BAT_RELATIVE_CAP_HIGH) << 8) |
++ (ec_read(REG_BAT_RELATIVE_CAP_LOW));
++
++ info->ac_line_status = (ec_read(REG_BAT_POWER) & BIT_BAT_POWER_ACIN) ?
++ APM_AC_ONLINE : APM_AC_OFFLINE;
++
++ bat_status = ec_read(REG_BAT_STATUS);
++
++ if (!(bat_status & BIT_BAT_STATUS_IN)) {
++ /* no battery inserted */
++ info->battery_status = APM_BATTERY_STATUS_NOT_PRESENT;
++ info->battery_flag = APM_BATTERY_FLAG_NOT_PRESENT;
++ info->time = 0x00;
++ return;
++ }
++
++ /* adapter inserted */
++ if (info->ac_line_status == APM_AC_ONLINE) {
++ if (!(bat_status & BIT_BAT_STATUS_FULL)) {
++ /* battery is not fully charged */
++ info->battery_status = APM_BATTERY_STATUS_CHARGING;
++ info->battery_flag = APM_BATTERY_FLAG_CHARGING;
++ } else {
++ /* battery is fully charged */
++ info->battery_status = APM_BATTERY_STATUS_HIGH;
++ info->battery_flag = APM_BATTERY_FLAG_HIGH;
++ info->battery_life = 100;
++ }
++ } else {
++ /* battery is too low */
++ if (bat_status & BIT_BAT_STATUS_LOW) {
++ info->battery_status = APM_BATTERY_STATUS_LOW;
++ info->battery_flag = APM_BATTERY_FLAG_LOW;
++ if (info->battery_life <= APM_CRITICAL) {
++ /* we should power off the system now */
++ info->battery_status =
++ APM_BATTERY_STATUS_CRITICAL;
++ info->battery_flag = APM_BATTERY_FLAG_CRITICAL;
++ }
++ } else {
++ /* assume the battery is high enough. */
++ info->battery_status = APM_BATTERY_STATUS_HIGH;
++ info->battery_flag = APM_BATTERY_FLAG_HIGH;
++ }
++ }
++ info->time = ((info->battery_life - 3) * 54 + 142) / 60;
++}
++
++static int yeeloong_apm_init(void)
++{
++ /* print fixed information of battery */
++ get_fixed_battery_info();
++
++#ifdef CONFIG_APM_EMULATION
++ apm_get_power_status = yeeloong_apm_get_power_status;
++#endif
++ return 0;
++}
++
++static void yeeloong_apm_exit(void)
++{
++#ifdef CONFIG_APM_EMULATION
++ if (apm_get_power_status == yeeloong_apm_get_power_status)
++ apm_get_power_status = NULL;
++#endif
++}
++
++/* platform subdriver */
++static void __maybe_unused usb_ports_set(int status)
++{
++ status = !!status;
++
++ ec_write(REG_USB0_FLAG, status);
++ ec_write(REG_USB1_FLAG, status);
++ ec_write(REG_USB2_FLAG, status);
++}
++
++static int __maybe_unused yeeloong_suspend(struct platform_device *pdev,
++ pm_message_t state)
++{
++ printk(KERN_INFO "yeeloong specific suspend\n");
++
++ /* close LCD */
++ lcd_vo_set(BIT_DISPLAY_LCD_OFF);
++ /* close CRT */
++ crt_vo_set(BIT_CRT_DETECT_UNPLUG);
++ /* power off camera */
++ camera_set(BIT_CAMERA_CONTROL_OFF);
++ /* poweroff three usb ports */
++ usb_ports_set(BIT_USB_FLAG_OFF);
++ /* minimize the speed of FAN */
++ set_fan_pwm_enable(BIT_FAN_MANUAL);
++ set_fan_pwm(1);
++
++ return 0;
++}
++
++static int __maybe_unused yeeloong_resume(struct platform_device *pdev)
++{
++ printk(KERN_INFO "yeeloong specific resume\n");
++
++ /* resume the status of lcd & crt */
++ lcd_vo_set(BIT_DISPLAY_LCD_ON);
++ crt_vo_set(BIT_CRT_DETECT_PLUG);
++
++ /* power on three usb ports */
++ usb_ports_set(BIT_USB_FLAG_ON);
++
++ /* resume the camera status */
++ camera_set(2);
++
++ /* resume fan to auto mode */
++ set_fan_pwm_enable(BIT_FAN_AUTO);
++
++ return 0;
++}
++
++static struct platform_device *yeeloong_pdev;
++
++static int __devinit yeeloong_probe(struct platform_device *dev)
++{
++ yeeloong_pdev = dev;
++
++ return 0;
++}
++
++static struct platform_device_id platform_device_ids[] = {
++ {
++ .name = "yeeloong_laptop",
++ },
++ {}
++};
++
++MODULE_DEVICE_TABLE(platform, platform_device_ids);
++
++static struct platform_driver platform_driver = {
++ .probe = yeeloong_probe,
++ .driver = {
++ .name = "yeeloong_laptop",
++ .owner = THIS_MODULE,
++ },
++ .id_table = platform_device_ids,
++#ifdef CONFIG_PM
++ .suspend = yeeloong_suspend,
++ .resume = yeeloong_resume,
++#endif
++};
++
++static int yeeloong_pdev_init(void)
++{
++ int ret;
++
++ /* Register platform stuff */
++ ret = platform_driver_register(&platform_driver);
++ if (ret)
++ return ret;
++
++ return 0;
++}
++
++static void yeeloong_pdev_exit(void)
++{
++ platform_driver_unregister(&platform_driver);
++}
++
++static int __init yeeloong_init(void)
++{
++ int ret;
++
++ if (mips_machtype != MACH_LEMOTE_YL2F89) {
++ printk(KERN_INFO "This Driver is for YeeLoong netbook, You"
++ " can not use it on the other Machines\n");
++ return -EFAULT;
++ }
++
++ printk(KERN_INFO "Load YeeLoong Platform Driver %s.\n",
++ DRIVER_VERSION);
++
++ ret = yeeloong_pdev_init();
++ if (ret) {
++ yeeloong_pdev_exit();
++ printk(KERN_INFO "Fail to init yeeloong platform driver.\n");
++ return ret;
++ }
++ ret = yeeloong_hotkey_init(&yeeloong_pdev->dev);
++ if (ret) {
++ yeeloong_hotkey_exit();
++ printk(KERN_INFO "Fail init yeeloong hotkey driver.\n");
++ return ret;
++ }
++ ret = yeeloong_apm_init();
++ if (ret) {
++ yeeloong_apm_exit();
++ printk(KERN_INFO "Fail to init yeeloong apm driver.\n");
++ return ret;
++ }
++ ret = yeeloong_backlight_init(&yeeloong_pdev->dev);
++ if (ret) {
++ yeeloong_backlight_exit();
++ printk(KERN_INFO "Fail to init yeeloong backlight driver.\n");
++ return ret;
++ }
++ ret = yeeloong_thermal_init(&yeeloong_backlight_dev->dev);
++ if (ret) {
++ yeeloong_thermal_exit(&yeeloong_backlight_dev->dev);
++ printk(KERN_INFO
++ "Fail to init yeeloong thermal cooling device.\n");
++ return ret;
++ }
++ ret = yeeloong_hwmon_init(&yeeloong_pdev->dev);
++ if (ret) {
++ yeeloong_hwmon_exit();
++ printk(KERN_INFO "Fail to init yeeloong hwmon driver.\n");
++ return ret;
++ }
++ ret = yeeloong_vo_init(&yeeloong_pdev->dev);
++ if (ret) {
++ yeeloong_vo_exit();
++ printk(KERN_INFO "Fail to init yeeloong video output driver.\n");
++ return ret;
++ }
++ return 0;
++}
++
++static void __exit yeeloong_exit(void)
++{
++ yeeloong_vo_exit();
++ yeeloong_hwmon_exit();
++ yeeloong_thermal_exit(&yeeloong_backlight_dev->dev);
++ yeeloong_backlight_exit();
++ yeeloong_apm_exit();
++ yeeloong_hotkey_exit();
++ yeeloong_pdev_exit();
++
++ printk(KERN_INFO "Unload YeeLoong Platform Driver %s\n",
++ DRIVER_VERSION);
++}
++
++module_init(yeeloong_init);
++module_exit(yeeloong_exit);
++
++MODULE_AUTHOR("Wu Zhangjin <wuzj@lemote.com>");
++MODULE_DESCRIPTION("YeeLoong laptop driver");
++MODULE_LICENSE("GPL");
+diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c
+index 454b539..8f2f8e9 100644
+--- a/arch/mips/math-emu/cp1emu.c
++++ b/arch/mips/math-emu/cp1emu.c
+@@ -35,6 +35,7 @@
+ * better performance by compiling with -msoft-float!
+ */
+ #include <linux/sched.h>
++#include <linux/module.h>
+ #include <linux/debugfs.h>
+
+ #include <asm/inst.h>
+@@ -68,7 +69,9 @@ static int fpux_emu(struct pt_regs *,
+
+ /* Further private data for which no space exists in mips_fpu_struct */
+
+-struct mips_fpu_emulator_stats fpuemustats;
++#ifdef CONFIG_DEBUG_FS
++DEFINE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats);
++#endif
+
+ /* Control registers */
+
+@@ -209,7 +212,7 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
+ unsigned int cond;
+
+ if (get_user(ir, (mips_instruction __user *) xcp->cp0_epc)) {
+- fpuemustats.errors++;
++ MIPS_FPU_EMU_INC_STATS(errors);
+ return SIGBUS;
+ }
+
+@@ -240,7 +243,7 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
+ return SIGILL;
+ }
+ if (get_user(ir, (mips_instruction __user *) emulpc)) {
+- fpuemustats.errors++;
++ MIPS_FPU_EMU_INC_STATS(errors);
+ return SIGBUS;
+ }
+ /* __compute_return_epc() will have updated cp0_epc */
+@@ -253,16 +256,16 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
+ }
+
+ emul:
+- fpuemustats.emulated++;
++ MIPS_FPU_EMU_INC_STATS(emulated);
+ switch (MIPSInst_OPCODE(ir)) {
+ case ldc1_op:{
+ u64 __user *va = (u64 __user *) (xcp->regs[MIPSInst_RS(ir)] +
+ MIPSInst_SIMM(ir));
+ u64 val;
+
+- fpuemustats.loads++;
++ MIPS_FPU_EMU_INC_STATS(loads);
+ if (get_user(val, va)) {
+- fpuemustats.errors++;
++ MIPS_FPU_EMU_INC_STATS(errors);
+ return SIGBUS;
+ }
+ DITOREG(val, MIPSInst_RT(ir));
+@@ -274,10 +277,10 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
+ MIPSInst_SIMM(ir));
+ u64 val;
+
+- fpuemustats.stores++;
++ MIPS_FPU_EMU_INC_STATS(stores);
+ DIFROMREG(val, MIPSInst_RT(ir));
+ if (put_user(val, va)) {
+- fpuemustats.errors++;
++ MIPS_FPU_EMU_INC_STATS(errors);
+ return SIGBUS;
+ }
+ break;
+@@ -288,9 +291,9 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
+ MIPSInst_SIMM(ir));
+ u32 val;
+
+- fpuemustats.loads++;
++ MIPS_FPU_EMU_INC_STATS(loads);
+ if (get_user(val, va)) {
+- fpuemustats.errors++;
++ MIPS_FPU_EMU_INC_STATS(errors);
+ return SIGBUS;
+ }
+ SITOREG(val, MIPSInst_RT(ir));
+@@ -302,10 +305,10 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
+ MIPSInst_SIMM(ir));
+ u32 val;
+
+- fpuemustats.stores++;
++ MIPS_FPU_EMU_INC_STATS(stores);
+ SIFROMREG(val, MIPSInst_RT(ir));
+ if (put_user(val, va)) {
+- fpuemustats.errors++;
++ MIPS_FPU_EMU_INC_STATS(errors);
+ return SIGBUS;
+ }
+ break;
+@@ -429,7 +432,7 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
+
+ if (get_user(ir,
+ (mips_instruction __user *) xcp->cp0_epc)) {
+- fpuemustats.errors++;
++ MIPS_FPU_EMU_INC_STATS(errors);
+ return SIGBUS;
+ }
+
+@@ -595,7 +598,7 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
+ {
+ unsigned rcsr = 0; /* resulting csr */
+
+- fpuemustats.cp1xops++;
++ MIPS_FPU_EMU_INC_STATS(cp1xops);
+
+ switch (MIPSInst_FMA_FFMT(ir)) {
+ case s_fmt:{ /* 0 */
+@@ -610,9 +613,9 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
+ va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
+ xcp->regs[MIPSInst_FT(ir)]);
+
+- fpuemustats.loads++;
++ MIPS_FPU_EMU_INC_STATS(loads);
+ if (get_user(val, va)) {
+- fpuemustats.errors++;
++ MIPS_FPU_EMU_INC_STATS(errors);
+ return SIGBUS;
+ }
+ SITOREG(val, MIPSInst_FD(ir));
+@@ -622,11 +625,11 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
+ va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
+ xcp->regs[MIPSInst_FT(ir)]);
+
+- fpuemustats.stores++;
++ MIPS_FPU_EMU_INC_STATS(stores);
+
+ SIFROMREG(val, MIPSInst_FS(ir));
+ if (put_user(val, va)) {
+- fpuemustats.errors++;
++ MIPS_FPU_EMU_INC_STATS(errors);
+ return SIGBUS;
+ }
+ break;
+@@ -687,9 +690,9 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
+ va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
+ xcp->regs[MIPSInst_FT(ir)]);
+
+- fpuemustats.loads++;
++ MIPS_FPU_EMU_INC_STATS(loads);
+ if (get_user(val, va)) {
+- fpuemustats.errors++;
++ MIPS_FPU_EMU_INC_STATS(errors);
+ return SIGBUS;
+ }
+ DITOREG(val, MIPSInst_FD(ir));
+@@ -699,10 +702,10 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
+ va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
+ xcp->regs[MIPSInst_FT(ir)]);
+
+- fpuemustats.stores++;
++ MIPS_FPU_EMU_INC_STATS(stores);
+ DIFROMREG(val, MIPSInst_FS(ir));
+ if (put_user(val, va)) {
+- fpuemustats.errors++;
++ MIPS_FPU_EMU_INC_STATS(errors);
+ return SIGBUS;
+ }
+ break;
+@@ -769,7 +772,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
+ #endif
+ } rv; /* resulting value */
+
+- fpuemustats.cp1ops++;
++ MIPS_FPU_EMU_INC_STATS(cp1ops);
+ switch (rfmt = (MIPSInst_FFMT(ir) & 0xf)) {
+ case s_fmt:{ /* 0 */
+ union {
+@@ -1240,7 +1243,7 @@ int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
+ prevepc = xcp->cp0_epc;
+
+ if (get_user(insn, (mips_instruction __user *) xcp->cp0_epc)) {
+- fpuemustats.errors++;
++ MIPS_FPU_EMU_INC_STATS(errors);
+ return SIGBUS;
+ }
+ if (insn == 0)
+@@ -1276,33 +1279,50 @@ int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
+ }
+
+ #ifdef CONFIG_DEBUG_FS
++
++static int fpuemu_stat_get(void *data, u64 *val)
++{
++ int cpu;
++ unsigned long sum = 0;
++ for_each_online_cpu(cpu) {
++ struct mips_fpu_emulator_stats *ps;
++ local_t *pv;
++ ps = &per_cpu(fpuemustats, cpu);
++ pv = (void *)ps + (unsigned long)data;
++ sum += local_read(pv);
++ }
++ *val = sum;
++ return 0;
++}
++DEFINE_SIMPLE_ATTRIBUTE(fops_fpuemu_stat, fpuemu_stat_get, NULL, "%llu\n");
++
+ extern struct dentry *mips_debugfs_dir;
+ static int __init debugfs_fpuemu(void)
+ {
+ struct dentry *d, *dir;
+- int i;
+- static struct {
+- const char *name;
+- unsigned int *v;
+- } vars[] __initdata = {
+- { "emulated", &fpuemustats.emulated },
+- { "loads", &fpuemustats.loads },
+- { "stores", &fpuemustats.stores },
+- { "cp1ops", &fpuemustats.cp1ops },
+- { "cp1xops", &fpuemustats.cp1xops },
+- { "errors", &fpuemustats.errors },
+- };
+
+ if (!mips_debugfs_dir)
+ return -ENODEV;
+ dir = debugfs_create_dir("fpuemustats", mips_debugfs_dir);
+ if (!dir)
+ return -ENOMEM;
+- for (i = 0; i < ARRAY_SIZE(vars); i++) {
+- d = debugfs_create_u32(vars[i].name, S_IRUGO, dir, vars[i].v);
+- if (!d)
+- return -ENOMEM;
+- }
++
++#define FPU_STAT_CREATE(M) \
++ do { \
++ d = debugfs_create_file(#M , S_IRUGO, dir, \
++ (void *)offsetof(struct mips_fpu_emulator_stats, M), \
++ &fops_fpuemu_stat); \
++ if (!d) \
++ return -ENOMEM; \
++ } while (0)
++
++ FPU_STAT_CREATE(emulated);
++ FPU_STAT_CREATE(loads);
++ FPU_STAT_CREATE(stores);
++ FPU_STAT_CREATE(cp1ops);
++ FPU_STAT_CREATE(cp1xops);
++ FPU_STAT_CREATE(errors);
++
+ return 0;
+ }
+ __initcall(debugfs_fpuemu);
+diff --git a/arch/mips/math-emu/dsemul.c b/arch/mips/math-emu/dsemul.c
+index df7b9d9..36d975a 100644
+--- a/arch/mips/math-emu/dsemul.c
++++ b/arch/mips/math-emu/dsemul.c
+@@ -98,7 +98,7 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc)
+ err |= __put_user(cpc, &fr->epc);
+
+ if (unlikely(err)) {
+- fpuemustats.errors++;
++ MIPS_FPU_EMU_INC_STATS(errors);
+ return SIGBUS;
+ }
+
+@@ -136,7 +136,7 @@ int do_dsemulret(struct pt_regs *xcp)
+ err |= __get_user(cookie, &fr->cookie);
+
+ if (unlikely(err || (insn != BREAK_MATH) || (cookie != BD_COOKIE))) {
+- fpuemustats.errors++;
++ MIPS_FPU_EMU_INC_STATS(errors);
+ return 0;
+ }
+
+diff --git a/arch/mips/mipssim/sim_cmdline.c b/arch/mips/mipssim/sim_cmdline.c
+deleted file mode 100644
+index 74240e1..0000000
+--- a/arch/mips/mipssim/sim_cmdline.c
++++ /dev/null
+@@ -1,32 +0,0 @@
+-/*
+- * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
+- *
+- * This program is free software; you can distribute it and/or modify it
+- * under the terms of the GNU General Public License (Version 2) as
+- * published by the Free Software Foundation.
+- *
+- * This program is distributed in the hope it will be useful, but WITHOUT
+- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+- * for more details.
+- *
+- * You should have received a copy of the GNU General Public License along
+- * with this program; if not, write to the Free Software Foundation, Inc.,
+- * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+- *
+- */
+-#include <linux/init.h>
+-#include <linux/string.h>
+-#include <asm/bootinfo.h>
+-
+-extern char arcs_cmdline[];
+-
+-char * __init prom_getcmdline(void)
+-{
+- return arcs_cmdline;
+-}
+-
+-void __init prom_init_cmdline(void)
+-{
+- /* XXX: Get boot line from environment? */
+-}
+diff --git a/arch/mips/mipssim/sim_setup.c b/arch/mips/mipssim/sim_setup.c
+index 2877675..0824f6a 100644
+--- a/arch/mips/mipssim/sim_setup.c
++++ b/arch/mips/mipssim/sim_setup.c
+@@ -61,7 +61,6 @@ void __init prom_init(void)
+ set_io_port_base(0xbfd00000);
+
+ pr_info("\nLINUX started...\n");
+- prom_init_cmdline();
+ prom_meminit();
+
+ #ifdef CONFIG_MIPS_MT_SMP
+diff --git a/arch/mips/mm/cerr-sb1.c b/arch/mips/mm/cerr-sb1.c
+index 1bd1f18..3571090 100644
+--- a/arch/mips/mm/cerr-sb1.c
++++ b/arch/mips/mm/cerr-sb1.c
+@@ -567,13 +567,10 @@ static uint32_t extract_dc(unsigned short addr, int data)
+ datalo = ((unsigned long long)datalohi << 32) | datalolo;
+ ecc = dc_ecc(datalo);
+ if (ecc != datahi) {
+- int bits = 0;
++ int bits;
+ bad_ecc |= 1 << (3-offset);
+ ecc ^= datahi;
+- while (ecc) {
+- if (ecc & 1) bits++;
+- ecc >>= 1;
+- }
++ bits = hweight8(ecc);
+ res |= (bits == 1) ? CP0_CERRD_DATA_SBE : CP0_CERRD_DATA_DBE;
+ }
+ printk(" %02X-%016llX", datahi, datalo);
+diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
+index 8d1f4f3..9e8d003 100644
+--- a/arch/mips/mm/init.c
++++ b/arch/mips/mm/init.c
+@@ -462,7 +462,9 @@ void __init_refok free_initmem(void)
+ __pa_symbol(&__init_end));
+ }
+
++#ifndef CONFIG_MIPS_PGD_C0_CONTEXT
+ unsigned long pgd_current[NR_CPUS];
++#endif
+ /*
+ * On 64-bit we've got three-level pagetables with a slightly
+ * different layout ...
+diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
+index bb1719a..3d0baa4 100644
+--- a/arch/mips/mm/tlbex.c
++++ b/arch/mips/mm/tlbex.c
+@@ -160,6 +160,12 @@ static u32 tlb_handler[128] __cpuinitdata;
+ static struct uasm_label labels[128] __cpuinitdata;
+ static struct uasm_reloc relocs[128] __cpuinitdata;
+
++#ifndef CONFIG_MIPS_PGD_C0_CONTEXT
++/*
++ * CONFIG_MIPS_PGD_C0_CONTEXT implies 64 bit and lack of pgd_current,
++ * we cannot do r3000 under these circumstances.
++ */
++
+ /*
+ * The R3000 TLB handler is simple.
+ */
+@@ -199,6 +205,7 @@ static void __cpuinit build_r3000_tlb_refill_handler(void)
+
+ dump_handler((u32 *)ebase, 32);
+ }
++#endif /* CONFIG_MIPS_PGD_C0_CONTEXT */
+
+ /*
+ * The R4000 TLB handler is much more complicated. We have two
+@@ -497,8 +504,9 @@ static void __cpuinit
+ build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
+ unsigned int tmp, unsigned int ptr)
+ {
++#ifndef CONFIG_MIPS_PGD_C0_CONTEXT
+ long pgdc = (long)pgd_current;
+-
++#endif
+ /*
+ * The vmalloc handling is not in the hotpath.
+ */
+@@ -506,7 +514,15 @@ build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
+ uasm_il_bltz(p, r, tmp, label_vmalloc);
+ /* No uasm_i_nop needed here, since the next insn doesn't touch TMP. */
+
+-#ifdef CONFIG_SMP
++#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
++ /*
++ * &pgd << 11 stored in CONTEXT [23..63].
++ */
++ UASM_i_MFC0(p, ptr, C0_CONTEXT);
++ uasm_i_dins(p, ptr, 0, 0, 23); /* Clear lower 23 bits of context. */
++ uasm_i_ori(p, ptr, ptr, 0x540); /* 1 0 1 0 1 << 6 xkphys cached */
++ uasm_i_drotr(p, ptr, ptr, 11);
++#elif defined(CONFIG_SMP)
+ # ifdef CONFIG_MIPS_MT_SMTC
+ /*
+ * SMTC uses TCBind value as "CPU" index
+@@ -520,7 +536,7 @@ build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
+ */
+ uasm_i_dmfc0(p, ptr, C0_CONTEXT);
+ uasm_i_dsrl(p, ptr, ptr, 23);
+-#endif
++# endif
+ UASM_i_LA_mostly(p, tmp, pgdc);
+ uasm_i_daddu(p, ptr, ptr, tmp);
+ uasm_i_dmfc0(p, tmp, C0_BADVADDR);
+@@ -1033,6 +1049,7 @@ build_pte_modifiable(u32 **p, struct uasm_reloc **r,
+ iPTE_LW(p, pte, ptr);
+ }
+
++#ifndef CONFIG_MIPS_PGD_C0_CONTEXT
+ /*
+ * R3000 style TLB load/store/modify handlers.
+ */
+@@ -1184,6 +1201,7 @@ static void __cpuinit build_r3000_tlb_modify_handler(void)
+
+ dump_handler(handle_tlbm, ARRAY_SIZE(handle_tlbm));
+ }
++#endif /* CONFIG_MIPS_PGD_C0_CONTEXT */
+
+ /*
+ * R4000 style TLB load/store/modify handlers.
+@@ -1400,6 +1418,7 @@ void __cpuinit build_tlb_refill_handler(void)
+ case CPU_TX3912:
+ case CPU_TX3922:
+ case CPU_TX3927:
++#ifndef CONFIG_MIPS_PGD_C0_CONTEXT
+ build_r3000_tlb_refill_handler();
+ if (!run_once) {
+ build_r3000_tlb_load_handler();
+@@ -1407,6 +1426,9 @@ void __cpuinit build_tlb_refill_handler(void)
+ build_r3000_tlb_modify_handler();
+ run_once++;
+ }
++#else
++ panic("No R3000 TLB refill handler");
++#endif
+ break;
+
+ case CPU_R6000:
+diff --git a/arch/mips/mm/uasm.c b/arch/mips/mm/uasm.c
+index f467199..0a165c5 100644
+--- a/arch/mips/mm/uasm.c
++++ b/arch/mips/mm/uasm.c
+@@ -60,11 +60,11 @@ enum opcode {
+ insn_beql, insn_bgez, insn_bgezl, insn_bltz, insn_bltzl,
+ insn_bne, insn_cache, insn_daddu, insn_daddiu, insn_dmfc0,
+ insn_dmtc0, insn_dsll, insn_dsll32, insn_dsra, insn_dsrl,
+- insn_dsrl32, insn_dsubu, insn_eret, insn_j, insn_jal, insn_jr,
+- insn_ld, insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0,
++ insn_dsrl32, insn_drotr, insn_dsubu, insn_eret, insn_j, insn_jal,
++ insn_jr, insn_ld, insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0,
+ insn_mtc0, insn_ori, insn_pref, insn_rfe, insn_sc, insn_scd,
+ insn_sd, insn_sll, insn_sra, insn_srl, insn_subu, insn_sw,
+- insn_tlbp, insn_tlbwi, insn_tlbwr, insn_xor, insn_xori
++ insn_tlbp, insn_tlbwi, insn_tlbwr, insn_xor, insn_xori, insn_dins
+ };
+
+ struct insn {
+@@ -104,6 +104,7 @@ static struct insn insn_table[] __cpuinitdata = {
+ { insn_dsra, M(spec_op, 0, 0, 0, 0, dsra_op), RT | RD | RE },
+ { insn_dsrl, M(spec_op, 0, 0, 0, 0, dsrl_op), RT | RD | RE },
+ { insn_dsrl32, M(spec_op, 0, 0, 0, 0, dsrl32_op), RT | RD | RE },
++ { insn_drotr, M(spec_op, 1, 0, 0, 0, dsrl_op), RT | RD | RE },
+ { insn_dsubu, M(spec_op, 0, 0, 0, 0, dsubu_op), RS | RT | RD },
+ { insn_eret, M(cop0_op, cop_op, 0, 0, 0, eret_op), 0 },
+ { insn_j, M(j_op, 0, 0, 0, 0, 0), JIMM },
+@@ -132,6 +133,7 @@ static struct insn insn_table[] __cpuinitdata = {
+ { insn_tlbwr, M(cop0_op, cop_op, 0, 0, 0, tlbwr_op), 0 },
+ { insn_xor, M(spec_op, 0, 0, 0, 0, xor_op), RS | RT | RD },
+ { insn_xori, M(xori_op, 0, 0, 0, 0, 0), RS | RT | UIMM },
++ { insn_dins, M(spec3_op, 0, 0, 0, 0, dins_op), RS | RT | RD | RE },
+ { insn_invalid, 0, 0 }
+ };
+
+@@ -304,6 +306,12 @@ Ip_u2u1s3(op) \
+ build_insn(buf, insn##op, b, a, c); \
+ }
+
++#define I_u2u1msbu3(op) \
++Ip_u2u1msbu3(op) \
++{ \
++ build_insn(buf, insn##op, b, a, c+d-1, c); \
++}
++
+ #define I_u1u2(op) \
+ Ip_u1u2(op) \
+ { \
+@@ -349,6 +357,7 @@ I_u2u1u3(_dsll32)
+ I_u2u1u3(_dsra)
+ I_u2u1u3(_dsrl)
+ I_u2u1u3(_dsrl32)
++I_u2u1u3(_drotr)
+ I_u3u1u2(_dsubu)
+ I_0(_eret)
+ I_u1(_j)
+@@ -377,6 +386,7 @@ I_0(_tlbwi)
+ I_0(_tlbwr)
+ I_u3u1u2(_xor)
+ I_u2u1u3(_xori)
++I_u2u1msbu3(_dins);
+
+ /* Handle labels. */
+ void __cpuinit uasm_build_label(struct uasm_label **lab, u32 *addr, int lid)
+diff --git a/arch/mips/mm/uasm.h b/arch/mips/mm/uasm.h
+index c6d1e3d..3d153ed 100644
+--- a/arch/mips/mm/uasm.h
++++ b/arch/mips/mm/uasm.h
+@@ -34,6 +34,11 @@ uasm_i##op(u32 **buf, unsigned int a, signed int b, unsigned int c)
+ void __cpuinit \
+ uasm_i##op(u32 **buf, unsigned int a, unsigned int b, signed int c)
+
++#define Ip_u2u1msbu3(op) \
++void __cpuinit \
++uasm_i##op(u32 **buf, unsigned int a, unsigned int b, unsigned int c, \
++ unsigned int d)
++
+ #define Ip_u1u2(op) \
+ void __cpuinit uasm_i##op(u32 **buf, unsigned int a, unsigned int b)
+
+@@ -65,6 +70,7 @@ Ip_u2u1u3(_dsll32);
+ Ip_u2u1u3(_dsra);
+ Ip_u2u1u3(_dsrl);
+ Ip_u2u1u3(_dsrl32);
++Ip_u2u1u3(_drotr);
+ Ip_u3u1u2(_dsubu);
+ Ip_0(_eret);
+ Ip_u1(_j);
+@@ -93,6 +99,7 @@ Ip_0(_tlbwi);
+ Ip_0(_tlbwr);
+ Ip_u3u1u2(_xor);
+ Ip_u2u1u3(_xori);
++Ip_u2u1msbu3(_dins);
+
+ /* Handle labels. */
+ struct uasm_label {
+diff --git a/arch/mips/mti-malta/malta-memory.c b/arch/mips/mti-malta/malta-memory.c
+index 9035c64..b27419c 100644
+--- a/arch/mips/mti-malta/malta-memory.c
++++ b/arch/mips/mti-malta/malta-memory.c
+@@ -55,7 +55,7 @@ static struct prom_pmemblock * __init prom_getmdesc(void)
+ char *memsize_str;
+ unsigned int memsize;
+ char *ptr;
+- static char cmdline[CL_SIZE] __initdata;
++ static char cmdline[COMMAND_LINE_SIZE] __initdata;
+
+ /* otherwise look in the environment */
+ memsize_str = prom_getenv("memsize");
+diff --git a/arch/mips/nxp/pnx833x/common/interrupts.c b/arch/mips/nxp/pnx833x/common/interrupts.c
+index 30533ba..3a467c0 100644
+--- a/arch/mips/nxp/pnx833x/common/interrupts.c
++++ b/arch/mips/nxp/pnx833x/common/interrupts.c
+@@ -295,7 +295,7 @@ static int pnx833x_set_type_gpio_irq(unsigned int irq, unsigned int flow_type)
+ }
+
+ static struct irq_chip pnx833x_pic_irq_type = {
+- .typename = "PNX-PIC",
++ .name = "PNX-PIC",
+ .startup = pnx833x_startup_pic_irq,
+ .shutdown = pnx833x_shutdown_pic_irq,
+ .enable = pnx833x_enable_pic_irq,
+@@ -305,7 +305,7 @@ static struct irq_chip pnx833x_pic_irq_type = {
+ };
+
+ static struct irq_chip pnx833x_gpio_irq_type = {
+- .typename = "PNX-GPIO",
++ .name = "PNX-GPIO",
+ .startup = pnx833x_startup_gpio_irq,
+ .shutdown = pnx833x_disable_gpio_irq,
+ .enable = pnx833x_enable_gpio_irq,
+diff --git a/arch/mips/oprofile/op_model_loongson2.c b/arch/mips/oprofile/op_model_loongson2.c
+index 575cd14..475ff46 100644
+--- a/arch/mips/oprofile/op_model_loongson2.c
++++ b/arch/mips/oprofile/op_model_loongson2.c
+@@ -1,7 +1,7 @@
+ /*
+ * Loongson2 performance counter driver for oprofile
+ *
+- * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
++ * Copyright (C) 2009 Lemote Inc.
+ * Author: Yanhua <yanh@lemote.com>
+ * Author: Wu Zhangjin <wuzj@lemote.com>
+ *
+@@ -125,6 +125,9 @@ static irqreturn_t loongson2_perfcount_handler(int irq, void *dev_id)
+ */
+
+ /* Check whether the irq belongs to me */
++ enabled = read_c0_perfcnt() & LOONGSON2_PERFCNT_INT_EN;
++ if (!enabled)
++ return IRQ_NONE;
+ enabled = reg.cnt1_enabled | reg.cnt2_enabled;
+ if (!enabled)
+ return IRQ_NONE;
+diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile
+index 91bfe73..c9a0dc1 100644
+--- a/arch/mips/pci/Makefile
++++ b/arch/mips/pci/Makefile
+@@ -28,7 +28,8 @@ obj-$(CONFIG_MIPS_COBALT) += fixup-cobalt.o
+ obj-$(CONFIG_SOC_AU1500) += fixup-au1000.o ops-au1000.o
+ obj-$(CONFIG_SOC_AU1550) += fixup-au1000.o ops-au1000.o
+ obj-$(CONFIG_SOC_PNX8550) += fixup-pnx8550.o ops-pnx8550.o
+-obj-$(CONFIG_LEMOTE_FULOONG2E) += fixup-fuloong2e.o ops-bonito64.o
++obj-$(CONFIG_LEMOTE_FULOONG2E) += fixup-fuloong2e.o ops-loongson2.o
++obj-$(CONFIG_LEMOTE_MACH2F) += fixup-lemote2f.o ops-loongson2.o
+ obj-$(CONFIG_MIPS_MALTA) += fixup-malta.o
+ obj-$(CONFIG_PMC_MSP7120_GW) += fixup-pmcmsp.o ops-pmcmsp.o
+ obj-$(CONFIG_PMC_MSP7120_EVAL) += fixup-pmcmsp.o ops-pmcmsp.o
+diff --git a/arch/mips/pci/fixup-fuloong2e.c b/arch/mips/pci/fixup-fuloong2e.c
+index 0c4c7a8..4f6d8da 100644
+--- a/arch/mips/pci/fixup-fuloong2e.c
++++ b/arch/mips/pci/fixup-fuloong2e.c
+@@ -13,7 +13,8 @@
+ */
+ #include <linux/init.h>
+ #include <linux/pci.h>
+-#include <asm/mips-boards/bonito64.h>
++
++#include <loongson.h>
+
+ /* South bridge slot number is set by the pci probe process */
+ static u8 sb_slot = 5;
+@@ -35,7 +36,7 @@ int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+ break;
+ }
+ } else {
+- irq = BONITO_IRQ_BASE + 25 + pin;
++ irq = LOONGSON_IRQ_BASE + 25 + pin;
+ }
+ return irq;
+
+diff --git a/arch/mips/pci/fixup-lemote2f.c b/arch/mips/pci/fixup-lemote2f.c
+new file mode 100644
+index 0000000..caf2ede
+--- /dev/null
++++ b/arch/mips/pci/fixup-lemote2f.c
+@@ -0,0 +1,160 @@
++/*
++ * Copyright (C) 2008 Lemote Technology
++ * Copyright (C) 2004 ICT CAS
++ * Author: Li xiaoyu, lixy@ict.ac.cn
++ *
++ * Copyright (C) 2007 Lemote, Inc.
++ * Author: Fuxin Zhang, zhangfx@lemote.com
++ *
++ * 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 <linux/init.h>
++#include <linux/pci.h>
++
++#include <loongson.h>
++#include <cs5536/cs5536.h>
++#include <cs5536/cs5536_pci.h>
++
++/* PCI interrupt pins
++ *
++ * These should not be changed, or you should consider loongson2f interrupt
++ * register and your pci card dispatch
++ */
++
++#define PCIA 4
++#define PCIB 5
++#define PCIC 6
++#define PCID 7
++
++/* all the pci device has the PCIA pin, check the datasheet. */
++static char irq_tab[][5] __initdata = {
++ /* INTA INTB INTC INTD */
++ {0, 0, 0, 0, 0}, /* 11: Unused */
++ {0, 0, 0, 0, 0}, /* 12: Unused */
++ {0, 0, 0, 0, 0}, /* 13: Unused */
++ {0, 0, 0, 0, 0}, /* 14: Unused */
++ {0, 0, 0, 0, 0}, /* 15: Unused */
++ {0, 0, 0, 0, 0}, /* 16: Unused */
++ {0, PCIA, 0, 0, 0}, /* 17: RTL8110-0 */
++ {0, PCIB, 0, 0, 0}, /* 18: RTL8110-1 */
++ {0, PCIC, 0, 0, 0}, /* 19: SiI3114 */
++ {0, PCID, 0, 0, 0}, /* 20: 3-ports nec usb */
++ {0, PCIA, PCIB, PCIC, PCID}, /* 21: PCI-SLOT */
++ {0, 0, 0, 0, 0}, /* 22: Unused */
++ {0, 0, 0, 0, 0}, /* 23: Unused */
++ {0, 0, 0, 0, 0}, /* 24: Unused */
++ {0, 0, 0, 0, 0}, /* 25: Unused */
++ {0, 0, 0, 0, 0}, /* 26: Unused */
++ {0, 0, 0, 0, 0}, /* 27: Unused */
++};
++
++int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
++{
++ int virq;
++
++ if ((PCI_SLOT(dev->devfn) != PCI_IDSEL_CS5536)
++ && (PCI_SLOT(dev->devfn) < 32)) {
++ virq = irq_tab[slot][pin];
++ printk(KERN_INFO "slot: %d, pin: %d, irq: %d\n", slot, pin,
++ virq + LOONGSON_IRQ_BASE);
++ if (virq != 0)
++ return LOONGSON_IRQ_BASE + virq;
++ else
++ return 0;
++ } else if (PCI_SLOT(dev->devfn) == PCI_IDSEL_CS5536) { /* cs5536 */
++ switch (PCI_FUNC(dev->devfn)) {
++ case 2:
++ pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
++ CS5536_IDE_INTR);
++ return CS5536_IDE_INTR; /* for IDE */
++ case 3:
++ pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
++ CS5536_ACC_INTR);
++ return CS5536_ACC_INTR; /* for AUDIO */
++ case 4: /* for OHCI */
++ case 5: /* for EHCI */
++ case 6: /* for UDC */
++ case 7: /* for OTG */
++ pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
++ CS5536_USB_INTR);
++ return CS5536_USB_INTR;
++ }
++ return dev->irq;
++ } else {
++ printk(KERN_INFO " strange pci slot number.\n");
++ return 0;
++ }
++}
++
++/* Do platform specific device initialization at pci_enable_device() time */
++int pcibios_plat_dev_init(struct pci_dev *dev)
++{
++ return 0;
++}
++
++/* CS5536 SPEC. fixup */
++static void __init loongson_cs5536_isa_fixup(struct pci_dev *pdev)
++{
++ /* the uart1 and uart2 interrupt in PIC is enabled as default */
++ pci_write_config_dword(pdev, PCI_UART1_INT_REG, 1);
++ pci_write_config_dword(pdev, PCI_UART2_INT_REG, 1);
++}
++
++static void __init loongson_cs5536_ide_fixup(struct pci_dev *pdev)
++{
++ /* setting the mutex pin as IDE function */
++ pci_write_config_dword(pdev, PCI_IDE_CFG_REG,
++ CS5536_IDE_FLASH_SIGNATURE);
++}
++
++static void __init loongson_cs5536_acc_fixup(struct pci_dev *pdev)
++{
++ /* enable the AUDIO interrupt in PIC */
++ pci_write_config_dword(pdev, PCI_ACC_INT_REG, 1);
++
++ pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xc0);
++}
++
++static void __init loongson_cs5536_ohci_fixup(struct pci_dev *pdev)
++{
++ /* enable the OHCI interrupt in PIC */
++ /* THE OHCI, EHCI, UDC, OTG are shared with interrupt in PIC */
++ pci_write_config_dword(pdev, PCI_OHCI_INT_REG, 1);
++}
++
++static void __init loongson_cs5536_ehci_fixup(struct pci_dev *pdev)
++{
++ u32 hi, lo;
++
++ /* Serial short detect enable */
++ _rdmsr(USB_MSR_REG(USB_CONFIG), &hi, &lo);
++ _wrmsr(USB_MSR_REG(USB_CONFIG), (1 << 1) | (1 << 2) | (1 << 3), lo);
++
++ /* setting the USB2.0 micro frame length */
++ pci_write_config_dword(pdev, PCI_EHCI_FLADJ_REG, 0x2000);
++}
++
++static void __init loongson_nec_fixup(struct pci_dev *pdev)
++{
++ unsigned int val;
++
++ pci_read_config_dword(pdev, 0xe0, &val);
++ /* Only 2 port be used */
++ pci_write_config_dword(pdev, 0xe0, (val & ~3) | 0x2);
++}
++
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA,
++ loongson_cs5536_isa_fixup);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_OHC,
++ loongson_cs5536_ohci_fixup);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_EHC,
++ loongson_cs5536_ehci_fixup);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_AUDIO,
++ loongson_cs5536_acc_fixup);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_IDE,
++ loongson_cs5536_ide_fixup);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB,
++ loongson_nec_fixup);
+diff --git a/arch/mips/pci/ops-bonito64.c b/arch/mips/pci/ops-bonito64.c
+index 54e55e7..1b3e03f 100644
+--- a/arch/mips/pci/ops-bonito64.c
++++ b/arch/mips/pci/ops-bonito64.c
+@@ -29,13 +29,8 @@
+ #define PCI_ACCESS_READ 0
+ #define PCI_ACCESS_WRITE 1
+
+-#ifdef CONFIG_LEMOTE_FULOONG2E
+-#define CFG_SPACE_REG(offset) (void *)CKSEG1ADDR(BONITO_PCICFG_BASE | (offset))
+-#define ID_SEL_BEGIN 11
+-#else
+ #define CFG_SPACE_REG(offset) (void *)CKSEG1ADDR(_pcictrl_bonito_pcicfg + (offset))
+ #define ID_SEL_BEGIN 10
+-#endif
+ #define MAX_DEV_NUM (31 - ID_SEL_BEGIN)
+
+
+@@ -77,10 +72,8 @@ static int bonito64_pcibios_config_access(unsigned char access_type,
+ addrp = CFG_SPACE_REG(addr & 0xffff);
+ if (access_type == PCI_ACCESS_WRITE) {
+ writel(cpu_to_le32(*data), addrp);
+-#ifndef CONFIG_LEMOTE_FULOONG2E
+ /* Wait till done */
+ while (BONITO_PCIMSTAT & 0xF);
+-#endif
+ } else {
+ *data = le32_to_cpu(readl(addrp));
+ }
+diff --git a/arch/mips/pci/ops-loongson2.c b/arch/mips/pci/ops-loongson2.c
+new file mode 100644
+index 0000000..aa5d3da
+--- /dev/null
++++ b/arch/mips/pci/ops-loongson2.c
+@@ -0,0 +1,208 @@
++/*
++ * fuloong2e specific PCI support.
++ *
++ * Copyright (C) 1999, 2000, 2004 MIPS Technologies, Inc.
++ * All rights reserved.
++ * Authors: Carsten Langgaard <carstenl@mips.com>
++ * Maciej W. Rozycki <macro@mips.com>
++ *
++ * Copyright (C) 2009 Lemote Inc.
++ * Author: Wu Zhangjin <wuzj@lemote.com>
++ *
++ * 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.
++ */
++#include <linux/types.h>
++#include <linux/pci.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++
++#include <loongson.h>
++
++#ifdef CONFIG_CS5536
++#include <cs5536/cs5536_pci.h>
++#include <cs5536/cs5536.h>
++#endif
++
++#define PCI_ACCESS_READ 0
++#define PCI_ACCESS_WRITE 1
++
++#define CFG_SPACE_REG(offset) \
++ (void *)CKSEG1ADDR(LOONGSON_PCICFG_BASE | (offset))
++#define ID_SEL_BEGIN 11
++#define MAX_DEV_NUM (31 - ID_SEL_BEGIN)
++
++
++static int loongson_pcibios_config_access(unsigned char access_type,
++ struct pci_bus *bus,
++ unsigned int devfn, int where,
++ u32 *data)
++{
++ u32 busnum = bus->number;
++ u32 addr, type;
++ u32 dummy;
++ void *addrp;
++ int device = PCI_SLOT(devfn);
++ int function = PCI_FUNC(devfn);
++ int reg = where & ~3;
++
++ if (busnum == 0) {
++ /* board-specific part,currently,only fuloong2f,yeeloong2f
++ * use CS5536, fuloong2e use via686b, gdium has no
++ * south bridge
++ */
++#ifdef CONFIG_CS5536
++ /* cs5536_pci_conf_read4/write4() will call _rdmsr/_wrmsr() to
++ * access the regsters PCI_MSR_ADDR, PCI_MSR_DATA_LO,
++ * PCI_MSR_DATA_HI, which is bigger than PCI_MSR_CTRL, so, it
++ * will not go this branch, but the others. so, no calling dead
++ * loop here.
++ */
++ if ((PCI_IDSEL_CS5536 == device) && (reg < PCI_MSR_CTRL)) {
++ switch (access_type) {
++ case PCI_ACCESS_READ:
++ *data = cs5536_pci_conf_read4(function, reg);
++ break;
++ case PCI_ACCESS_WRITE:
++ cs5536_pci_conf_write4(function, reg, *data);
++ break;
++ }
++ return 0;
++ }
++#endif
++ /* Type 0 configuration for onboard PCI bus */
++ if (device > MAX_DEV_NUM)
++ return -1;
++
++ addr = (1 << (device + ID_SEL_BEGIN)) | (function << 8) | reg;
++ type = 0;
++ } else {
++ /* Type 1 configuration for offboard PCI bus */
++ addr = (busnum << 16) | (device << 11) | (function << 8) | reg;
++ type = 0x10000;
++ }
++
++ /* Clear aborts */
++ LOONGSON_PCICMD |= LOONGSON_PCICMD_MABORT_CLR | \
++ LOONGSON_PCICMD_MTABORT_CLR;
++
++ LOONGSON_PCIMAP_CFG = (addr >> 16) | type;
++
++ /* Flush Bonito register block */
++ dummy = LOONGSON_PCIMAP_CFG;
++ mmiowb();
++
++ addrp = CFG_SPACE_REG(addr & 0xffff);
++ if (access_type == PCI_ACCESS_WRITE)
++ writel(cpu_to_le32(*data), addrp);
++ else
++ *data = le32_to_cpu(readl(addrp));
++
++ /* Detect Master/Target abort */
++ if (LOONGSON_PCICMD & (LOONGSON_PCICMD_MABORT_CLR |
++ LOONGSON_PCICMD_MTABORT_CLR)) {
++ /* Error occurred */
++
++ /* Clear bits */
++ LOONGSON_PCICMD |= (LOONGSON_PCICMD_MABORT_CLR |
++ LOONGSON_PCICMD_MTABORT_CLR);
++
++ return -1;
++ }
++
++ return 0;
++
++}
++
++
++/*
++ * We can't address 8 and 16 bit words directly. Instead we have to
++ * read/write a 32bit word and mask/modify the data we actually want.
++ */
++static int loongson_pcibios_read(struct pci_bus *bus, unsigned int devfn,
++ int where, int size, u32 *val)
++{
++ u32 data = 0;
++
++ if ((size == 2) && (where & 1))
++ return PCIBIOS_BAD_REGISTER_NUMBER;
++ else if ((size == 4) && (where & 3))
++ return PCIBIOS_BAD_REGISTER_NUMBER;
++
++ if (loongson_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where,
++ &data))
++ return -1;
++
++ if (size == 1)
++ *val = (data >> ((where & 3) << 3)) & 0xff;
++ else if (size == 2)
++ *val = (data >> ((where & 3) << 3)) & 0xffff;
++ else
++ *val = data;
++
++ return PCIBIOS_SUCCESSFUL;
++}
++
++static int loongson_pcibios_write(struct pci_bus *bus, unsigned int devfn,
++ int where, int size, u32 val)
++{
++ u32 data = 0;
++
++ if ((size == 2) && (where & 1))
++ return PCIBIOS_BAD_REGISTER_NUMBER;
++ else if ((size == 4) && (where & 3))
++ return PCIBIOS_BAD_REGISTER_NUMBER;
++
++ if (size == 4)
++ data = val;
++ else {
++ if (loongson_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
++ where, &data))
++ return -1;
++
++ 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 (loongson_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn, where,
++ &data))
++ return -1;
++
++ return PCIBIOS_SUCCESSFUL;
++}
++
++struct pci_ops loongson_pci_ops = {
++ .read = loongson_pcibios_read,
++ .write = loongson_pcibios_write
++};
++
++#ifdef CONFIG_CS5536
++void _rdmsr(u32 msr, u32 *hi, u32 *lo)
++{
++ struct pci_bus bus = {
++ .number = PCI_BUS_CS5536
++ };
++ u32 devfn = PCI_DEVFN(PCI_IDSEL_CS5536, 0);
++ loongson_pcibios_write(&bus, devfn, PCI_MSR_ADDR, 4, msr);
++ loongson_pcibios_read(&bus, devfn, PCI_MSR_DATA_LO, 4, lo);
++ loongson_pcibios_read(&bus, devfn, PCI_MSR_DATA_HI, 4, hi);
++}
++EXPORT_SYMBOL(_rdmsr);
++
++void _wrmsr(u32 msr, u32 hi, u32 lo)
++{
++ struct pci_bus bus = {
++ .number = PCI_BUS_CS5536
++ };
++ u32 devfn = PCI_DEVFN(PCI_IDSEL_CS5536, 0);
++ loongson_pcibios_write(&bus, devfn, PCI_MSR_ADDR, 4, msr);
++ loongson_pcibios_write(&bus, devfn, PCI_MSR_DATA_LO, 4, lo);
++ loongson_pcibios_write(&bus, devfn, PCI_MSR_DATA_HI, 4, hi);
++}
++EXPORT_SYMBOL(_wrmsr);
++#endif
+diff --git a/arch/mips/powertv/Kconfig b/arch/mips/powertv/Kconfig
+new file mode 100644
+index 0000000..ff0e7e3
+--- /dev/null
++++ b/arch/mips/powertv/Kconfig
+@@ -0,0 +1,21 @@
++source "arch/mips/powertv/asic/Kconfig"
++
++config BOOTLOADER_DRIVER
++ bool "PowerTV Bootloader Driver Support"
++ default n
++ depends on POWERTV
++ help
++ Use this option if you want to load bootloader driver.
++
++config BOOTLOADER_FAMILY
++ string "POWERTV Bootloader Family string"
++ default "85"
++ depends on POWERTV && !BOOTLOADER_DRIVER
++ help
++ This value should be specified when the bootloader driver is disabled
++ and must be exactly two characters long. Families supported are:
++ R1 - RNG-100 R2 - RNG-200
++ A1 - Class A B1 - Class B
++ E1 - Class E F1 - Class F
++ 44 - 45xx 46 - 46xx
++ 85 - 85xx 86 - 86xx
+diff --git a/arch/mips/powertv/Makefile b/arch/mips/powertv/Makefile
+new file mode 100644
+index 0000000..2c51671
+--- /dev/null
++++ b/arch/mips/powertv/Makefile
+@@ -0,0 +1,28 @@
++#
++# Carsten Langgaard, carstenl@mips.com
++# Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
++#
++# Carsten Langgaard, carstenl@mips.com
++# Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
++# Portions copyright (C) 2009 Cisco Systems, Inc.
++#
++# 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.
++#
++# Makefile for the Cisco PowerTV-specific kernel interface routines
++# under Linux.
++#
++
++obj-y += cmdline.o init.o memory.o reset.o time.o powertv_setup.o asic/ pci/
++
++EXTRA_CFLAGS += -Wall -Werror
+diff --git a/arch/mips/powertv/asic/Kconfig b/arch/mips/powertv/asic/Kconfig
+new file mode 100644
+index 0000000..2016bfe
+--- /dev/null
++++ b/arch/mips/powertv/asic/Kconfig
+@@ -0,0 +1,28 @@
++config MIN_RUNTIME_RESOURCES
++ bool "Support for minimum runtime resources"
++ default n
++ depends on POWERTV
++ help
++ Enables support for minimizing the number of (SA asic) runtime
++ resources that are preallocated by the kernel.
++
++config MIN_RUNTIME_DOCSIS
++ bool "Support for minimum DOCSIS resource"
++ default y
++ depends on MIN_RUNTIME_RESOURCES
++ help
++ Enables support for the preallocated DOCSIS resource.
++
++config MIN_RUNTIME_PMEM
++ bool "Support for minimum PMEM resource"
++ default y
++ depends on MIN_RUNTIME_RESOURCES
++ help
++ Enables support for the preallocated Memory resource.
++
++config MIN_RUNTIME_TFTP
++ bool "Support for minimum TFTP resource"
++ default y
++ depends on MIN_RUNTIME_RESOURCES
++ help
++ Enables support for the preallocated TFTP resource.
+diff --git a/arch/mips/powertv/asic/Makefile b/arch/mips/powertv/asic/Makefile
+new file mode 100644
+index 0000000..bebfdcf
+--- /dev/null
++++ b/arch/mips/powertv/asic/Makefile
+@@ -0,0 +1,23 @@
++#
++# Copyright (C) 2009 Scientific-Atlanta, Inc.
++#
++# 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
++#
++
++obj-y += asic-calliope.o asic-cronus.o asic-zeus.o asic_devices.o asic_int.o \
++ irq_asic.o prealloc-calliope.o prealloc-cronus.o \
++ prealloc-cronuslite.o prealloc-zeus.o
++
++EXTRA_CFLAGS += -Wall -Werror
+diff --git a/arch/mips/powertv/asic/asic-calliope.c b/arch/mips/powertv/asic/asic-calliope.c
+new file mode 100644
+index 0000000..03d3884
+--- /dev/null
++++ b/arch/mips/powertv/asic/asic-calliope.c
+@@ -0,0 +1,98 @@
++/*
++ * Locations of devices in the Calliope ASIC.
++ *
++ * Copyright (C) 2005-2009 Scientific-Atlanta, Inc.
++ *
++ * 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
++ *
++ * Author: Ken Eppinett
++ * David Schleef <ds@schleef.org>
++ *
++ * Description: Defines the platform resources for the SA settop.
++ */
++
++#include <asm/mach-powertv/asic.h>
++
++const struct register_map calliope_register_map = {
++ .eic_slow0_strt_add = 0x800000,
++ .eic_cfg_bits = 0x800038,
++ .eic_ready_status = 0x80004c,
++
++ .chipver3 = 0xA00800,
++ .chipver2 = 0xA00804,
++ .chipver1 = 0xA00808,
++ .chipver0 = 0xA0080c,
++
++ /* The registers of IRBlaster */
++ .uart1_intstat = 0xA01800,
++ .uart1_inten = 0xA01804,
++ .uart1_config1 = 0xA01808,
++ .uart1_config2 = 0xA0180C,
++ .uart1_divisorhi = 0xA01810,
++ .uart1_divisorlo = 0xA01814,
++ .uart1_data = 0xA01818,
++ .uart1_status = 0xA0181C,
++
++ .int_stat_3 = 0xA02800,
++ .int_stat_2 = 0xA02804,
++ .int_stat_1 = 0xA02808,
++ .int_stat_0 = 0xA0280c,
++ .int_config = 0xA02810,
++ .int_int_scan = 0xA02818,
++ .ien_int_3 = 0xA02830,
++ .ien_int_2 = 0xA02834,
++ .ien_int_1 = 0xA02838,
++ .ien_int_0 = 0xA0283c,
++ .int_level_3_3 = 0xA02880,
++ .int_level_3_2 = 0xA02884,
++ .int_level_3_1 = 0xA02888,
++ .int_level_3_0 = 0xA0288c,
++ .int_level_2_3 = 0xA02890,
++ .int_level_2_2 = 0xA02894,
++ .int_level_2_1 = 0xA02898,
++ .int_level_2_0 = 0xA0289c,
++ .int_level_1_3 = 0xA028a0,
++ .int_level_1_2 = 0xA028a4,
++ .int_level_1_1 = 0xA028a8,
++ .int_level_1_0 = 0xA028ac,
++ .int_level_0_3 = 0xA028b0,
++ .int_level_0_2 = 0xA028b4,
++ .int_level_0_1 = 0xA028b8,
++ .int_level_0_0 = 0xA028bc,
++ .int_docsis_en = 0xA028F4,
++
++ .mips_pll_setup = 0x980000,
++ .usb_fs = 0x980030, /* -default 72800028- */
++ .test_bus = 0x9800CC,
++ .crt_spare = 0x9800d4,
++ .usb2_ohci_int_mask = 0x9A000c,
++ .usb2_strap = 0x9A0014,
++ .ehci_hcapbase = 0x9BFE00,
++ .ohci_hc_revision = 0x9BFC00,
++ .bcm1_bs_lmi_steer = 0x9E0004,
++ .usb2_control = 0x9E0054,
++ .usb2_stbus_obc = 0x9BFF00,
++ .usb2_stbus_mess_size = 0x9BFF04,
++ .usb2_stbus_chunk_size = 0x9BFF08,
++
++ .pcie_regs = 0x000000, /* -doesn't exist- */
++ .tim_ch = 0xA02C10,
++ .tim_cl = 0xA02C14,
++ .gpio_dout = 0xA02c20,
++ .gpio_din = 0xA02c24,
++ .gpio_dir = 0xA02c2C,
++ .watchdog = 0xA02c30,
++ .front_panel = 0x000000, /* -not used- */
++};
+diff --git a/arch/mips/powertv/asic/asic-cronus.c b/arch/mips/powertv/asic/asic-cronus.c
+new file mode 100644
+index 0000000..5f4589c
+--- /dev/null
++++ b/arch/mips/powertv/asic/asic-cronus.c
+@@ -0,0 +1,98 @@
++/*
++ * Locations of devices in the Cronus ASIC
++ *
++ * Copyright (C) 2005-2009 Scientific-Atlanta, Inc.
++ *
++ * 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
++ *
++ * Author: Ken Eppinett
++ * David Schleef <ds@schleef.org>
++ *
++ * Description: Defines the platform resources for the SA settop.
++ */
++
++#include <asm/mach-powertv/asic.h>
++
++const struct register_map cronus_register_map = {
++ .eic_slow0_strt_add = 0x000000,
++ .eic_cfg_bits = 0x000038,
++ .eic_ready_status = 0x00004C,
++
++ .chipver3 = 0x2A0800,
++ .chipver2 = 0x2A0804,
++ .chipver1 = 0x2A0808,
++ .chipver0 = 0x2A080C,
++
++ /* The registers of IRBlaster */
++ .uart1_intstat = 0x2A1800,
++ .uart1_inten = 0x2A1804,
++ .uart1_config1 = 0x2A1808,
++ .uart1_config2 = 0x2A180C,
++ .uart1_divisorhi = 0x2A1810,
++ .uart1_divisorlo = 0x2A1814,
++ .uart1_data = 0x2A1818,
++ .uart1_status = 0x2A181C,
++
++ .int_stat_3 = 0x2A2800,
++ .int_stat_2 = 0x2A2804,
++ .int_stat_1 = 0x2A2808,
++ .int_stat_0 = 0x2A280C,
++ .int_config = 0x2A2810,
++ .int_int_scan = 0x2A2818,
++ .ien_int_3 = 0x2A2830,
++ .ien_int_2 = 0x2A2834,
++ .ien_int_1 = 0x2A2838,
++ .ien_int_0 = 0x2A283C,
++ .int_level_3_3 = 0x2A2880,
++ .int_level_3_2 = 0x2A2884,
++ .int_level_3_1 = 0x2A2888,
++ .int_level_3_0 = 0x2A288C,
++ .int_level_2_3 = 0x2A2890,
++ .int_level_2_2 = 0x2A2894,
++ .int_level_2_1 = 0x2A2898,
++ .int_level_2_0 = 0x2A289C,
++ .int_level_1_3 = 0x2A28A0,
++ .int_level_1_2 = 0x2A28A4,
++ .int_level_1_1 = 0x2A28A8,
++ .int_level_1_0 = 0x2A28AC,
++ .int_level_0_3 = 0x2A28B0,
++ .int_level_0_2 = 0x2A28B4,
++ .int_level_0_1 = 0x2A28B8,
++ .int_level_0_0 = 0x2A28BC,
++ .int_docsis_en = 0x2A28F4,
++
++ .mips_pll_setup = 0x1C0000,
++ .usb_fs = 0x1C0018,
++ .test_bus = 0x1C00CC,
++ .crt_spare = 0x1c00d4,
++ .usb2_ohci_int_mask = 0x20000C,
++ .usb2_strap = 0x200014,
++ .ehci_hcapbase = 0x21FE00,
++ .ohci_hc_revision = 0x1E0000,
++ .bcm1_bs_lmi_steer = 0x2E0008,
++ .usb2_control = 0x2E004C,
++ .usb2_stbus_obc = 0x21FF00,
++ .usb2_stbus_mess_size = 0x21FF04,
++ .usb2_stbus_chunk_size = 0x21FF08,
++
++ .pcie_regs = 0x220000,
++ .tim_ch = 0x2A2C10,
++ .tim_cl = 0x2A2C14,
++ .gpio_dout = 0x2A2C20,
++ .gpio_din = 0x2A2C24,
++ .gpio_dir = 0x2A2C2C,
++ .watchdog = 0x2A2C30,
++ .front_panel = 0x2A3800,
++};
+diff --git a/arch/mips/powertv/asic/asic-zeus.c b/arch/mips/powertv/asic/asic-zeus.c
+new file mode 100644
+index 0000000..1469daa
+--- /dev/null
++++ b/arch/mips/powertv/asic/asic-zeus.c
+@@ -0,0 +1,98 @@
++/*
++ * Locations of devices in the Zeus ASIC
++ *
++ * Copyright (C) 2005-2009 Scientific-Atlanta, Inc.
++ *
++ * 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
++ *
++ * Author: Ken Eppinett
++ * David Schleef <ds@schleef.org>
++ *
++ * Description: Defines the platform resources for the SA settop.
++ */
++
++#include <asm/mach-powertv/asic.h>
++
++const struct register_map zeus_register_map = {
++ .eic_slow0_strt_add = 0x000000,
++ .eic_cfg_bits = 0x000038,
++ .eic_ready_status = 0x00004c,
++
++ .chipver3 = 0x280800,
++ .chipver2 = 0x280804,
++ .chipver1 = 0x280808,
++ .chipver0 = 0x28080c,
++
++ /* The registers of IRBlaster */
++ .uart1_intstat = 0x281800,
++ .uart1_inten = 0x281804,
++ .uart1_config1 = 0x281808,
++ .uart1_config2 = 0x28180C,
++ .uart1_divisorhi = 0x281810,
++ .uart1_divisorlo = 0x281814,
++ .uart1_data = 0x281818,
++ .uart1_status = 0x28181C,
++
++ .int_stat_3 = 0x282800,
++ .int_stat_2 = 0x282804,
++ .int_stat_1 = 0x282808,
++ .int_stat_0 = 0x28280c,
++ .int_config = 0x282810,
++ .int_int_scan = 0x282818,
++ .ien_int_3 = 0x282830,
++ .ien_int_2 = 0x282834,
++ .ien_int_1 = 0x282838,
++ .ien_int_0 = 0x28283c,
++ .int_level_3_3 = 0x282880,
++ .int_level_3_2 = 0x282884,
++ .int_level_3_1 = 0x282888,
++ .int_level_3_0 = 0x28288c,
++ .int_level_2_3 = 0x282890,
++ .int_level_2_2 = 0x282894,
++ .int_level_2_1 = 0x282898,
++ .int_level_2_0 = 0x28289c,
++ .int_level_1_3 = 0x2828a0,
++ .int_level_1_2 = 0x2828a4,
++ .int_level_1_1 = 0x2828a8,
++ .int_level_1_0 = 0x2828ac,
++ .int_level_0_3 = 0x2828b0,
++ .int_level_0_2 = 0x2828b4,
++ .int_level_0_1 = 0x2828b8,
++ .int_level_0_0 = 0x2828bc,
++ .int_docsis_en = 0x2828F4,
++
++ .mips_pll_setup = 0x1a0000,
++ .usb_fs = 0x1a0018,
++ .test_bus = 0x1a0238,
++ .crt_spare = 0x1a0090,
++ .usb2_ohci_int_mask = 0x1e000c,
++ .usb2_strap = 0x1e0014,
++ .ehci_hcapbase = 0x1FFE00,
++ .ohci_hc_revision = 0x1FFC00,
++ .bcm1_bs_lmi_steer = 0x2C0008,
++ .usb2_control = 0x2c01a0,
++ .usb2_stbus_obc = 0x1FFF00,
++ .usb2_stbus_mess_size = 0x1FFF04,
++ .usb2_stbus_chunk_size = 0x1FFF08,
++
++ .pcie_regs = 0x200000,
++ .tim_ch = 0x282C10,
++ .tim_cl = 0x282C14,
++ .gpio_dout = 0x282c20,
++ .gpio_din = 0x282c24,
++ .gpio_dir = 0x282c2C,
++ .watchdog = 0x282c30,
++ .front_panel = 0x283800,
++};
+diff --git a/arch/mips/powertv/asic/asic_devices.c b/arch/mips/powertv/asic/asic_devices.c
+new file mode 100644
+index 0000000..5f20cee
+--- /dev/null
++++ b/arch/mips/powertv/asic/asic_devices.c
+@@ -0,0 +1,787 @@
++/*
++ * ASIC Device List Intialization
++ *
++ * Description: Defines the platform resources for the SA settop.
++ *
++ * Copyright (C) 2005-2009 Scientific-Atlanta, Inc.
++ *
++ * 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
++ *
++ * Author: Ken Eppinett
++ * David Schleef <ds@schleef.org>
++ *
++ * Description: Defines the platform resources for the SA settop.
++ *
++ * NOTE: The bootloader allocates persistent memory at an address which is
++ * 16 MiB below the end of the highest address in KSEG0. All fixed
++ * address memory reservations must avoid this region.
++ */
++
++#include <linux/device.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/resource.h>
++#include <linux/serial_reg.h>
++#include <linux/io.h>
++#include <linux/bootmem.h>
++#include <linux/mm.h>
++#include <linux/platform_device.h>
++#include <linux/module.h>
++#include <asm/page.h>
++#include <linux/swap.h>
++#include <linux/highmem.h>
++#include <linux/dma-mapping.h>
++
++#include <asm/mach-powertv/asic.h>
++#include <asm/mach-powertv/asic_regs.h>
++#include <asm/mach-powertv/interrupts.h>
++
++#ifdef CONFIG_BOOTLOADER_DRIVER
++#include <asm/mach-powertv/kbldr.h>
++#endif
++#include <asm/bootinfo.h>
++
++#define BOOTLDRFAMILY(byte1, byte0) (((byte1) << 8) | (byte0))
++
++/*
++ * Forward Prototypes
++ */
++static void pmem_setup_resource(void);
++
++/*
++ * Global Variables
++ */
++enum asic_type asic;
++
++unsigned int platform_features;
++unsigned int platform_family;
++const struct register_map *register_map;
++EXPORT_SYMBOL(register_map); /* Exported for testing */
++unsigned long asic_phy_base;
++unsigned long asic_base;
++EXPORT_SYMBOL(asic_base); /* Exported for testing */
++struct resource *gp_resources;
++static bool usb_configured;
++
++/*
++ * Don't recommend to use it directly, it is usually used by kernel internally.
++ * Portable code should be using interfaces such as ioremp, dma_map_single, etc.
++ */
++unsigned long phys_to_bus_offset;
++EXPORT_SYMBOL(phys_to_bus_offset);
++
++/*
++ *
++ * IO Resource Definition
++ *
++ */
++
++struct resource asic_resource = {
++ .name = "ASIC Resource",
++ .start = 0,
++ .end = ASIC_IO_SIZE,
++ .flags = IORESOURCE_MEM,
++};
++
++/*
++ *
++ * USB Host Resource Definition
++ *
++ */
++
++static struct resource ehci_resources[] = {
++ {
++ .parent = &asic_resource,
++ .start = 0,
++ .end = 0xff,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .start = irq_usbehci,
++ .end = irq_usbehci,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static u64 ehci_dmamask = DMA_BIT_MASK(32);
++
++static struct platform_device ehci_device = {
++ .name = "powertv-ehci",
++ .id = 0,
++ .num_resources = 2,
++ .resource = ehci_resources,
++ .dev = {
++ .dma_mask = &ehci_dmamask,
++ .coherent_dma_mask = DMA_BIT_MASK(32),
++ },
++};
++
++static struct resource ohci_resources[] = {
++ {
++ .parent = &asic_resource,
++ .start = 0,
++ .end = 0xff,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .start = irq_usbohci,
++ .end = irq_usbohci,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static u64 ohci_dmamask = DMA_BIT_MASK(32);
++
++static struct platform_device ohci_device = {
++ .name = "powertv-ohci",
++ .id = 0,
++ .num_resources = 2,
++ .resource = ohci_resources,
++ .dev = {
++ .dma_mask = &ohci_dmamask,
++ .coherent_dma_mask = DMA_BIT_MASK(32),
++ },
++};
++
++static struct platform_device *platform_devices[] = {
++ &ehci_device,
++ &ohci_device,
++};
++
++/*
++ *
++ * Platform Configuration and Device Initialization
++ *
++ */
++static void __init fs_update(int pe, int md, int sdiv, int disable_div_by_3)
++{
++ int en_prg, byp, pwr, nsb, val;
++ int sout;
++
++ sout = 1;
++ en_prg = 1;
++ byp = 0;
++ nsb = 1;
++ pwr = 1;
++
++ val = ((sdiv << 29) | (md << 24) | (pe<<8) | (sout<<3) | (byp<<2) |
++ (nsb<<1) | (disable_div_by_3<<5));
++
++ asic_write(val, usb_fs);
++ asic_write(val | (en_prg<<4), usb_fs);
++ asic_write(val | (en_prg<<4) | pwr, usb_fs);
++}
++
++/*
++ * Allow override of bootloader-specified model
++ */
++static char __initdata cmdline[CL_SIZE];
++
++#define FORCEFAMILY_PARAM "forcefamily"
++
++static __init int check_forcefamily(unsigned char forced_family[2])
++{
++ const char *p;
++
++ forced_family[0] = '\0';
++ forced_family[1] = '\0';
++
++ /* Check the command line for a forcefamily directive */
++ strncpy(cmdline, arcs_cmdline, CL_SIZE - 1);
++ p = strstr(cmdline, FORCEFAMILY_PARAM);
++ if (p && (p != cmdline) && (*(p - 1) != ' '))
++ p = strstr(p, " " FORCEFAMILY_PARAM "=");
++
++ if (p) {
++ p += strlen(FORCEFAMILY_PARAM "=");
++
++ if (*p == '\0' || *(p + 1) == '\0' ||
++ (*(p + 2) != '\0' && *(p + 2) != ' '))
++ pr_err(FORCEFAMILY_PARAM " must be exactly two "
++ "characters long, ignoring value\n");
++
++ else {
++ forced_family[0] = *p;
++ forced_family[1] = *(p + 1);
++ }
++ }
++
++ return 0;
++}
++
++/*
++ * platform_set_family - determine major platform family type.
++ *
++ * Returns family type; -1 if none
++ * Returns the family type; -1 if none
++ *
++ */
++static __init noinline void platform_set_family(void)
++{
++#define BOOTLDRFAMILY(byte1, byte0) (((byte1) << 8) | (byte0))
++
++ unsigned char forced_family[2];
++ unsigned short bootldr_family;
++
++ check_forcefamily(forced_family);
++
++ if (forced_family[0] != '\0' && forced_family[1] != '\0')
++ bootldr_family = BOOTLDRFAMILY(forced_family[0],
++ forced_family[1]);
++ else {
++
++#ifdef CONFIG_BOOTLOADER_DRIVER
++ bootldr_family = (unsigned short) kbldr_GetSWFamily();
++#else
++#if defined(CONFIG_BOOTLOADER_FAMILY)
++ bootldr_family = (unsigned short) BOOTLDRFAMILY(
++ CONFIG_BOOTLOADER_FAMILY[0],
++ CONFIG_BOOTLOADER_FAMILY[1]);
++#else
++#error "Unknown Bootloader Family"
++#endif
++#endif
++ }
++
++ pr_info("Bootloader Family = 0x%04X\n", bootldr_family);
++
++ switch (bootldr_family) {
++ case BOOTLDRFAMILY('R', '1'):
++ platform_family = FAMILY_1500;
++ break;
++ case BOOTLDRFAMILY('4', '4'):
++ platform_family = FAMILY_4500;
++ break;
++ case BOOTLDRFAMILY('4', '6'):
++ platform_family = FAMILY_4600;
++ break;
++ case BOOTLDRFAMILY('A', '1'):
++ platform_family = FAMILY_4600VZA;
++ break;
++ case BOOTLDRFAMILY('8', '5'):
++ platform_family = FAMILY_8500;
++ break;
++ case BOOTLDRFAMILY('R', '2'):
++ platform_family = FAMILY_8500RNG;
++ break;
++ case BOOTLDRFAMILY('8', '6'):
++ platform_family = FAMILY_8600;
++ break;
++ case BOOTLDRFAMILY('B', '1'):
++ platform_family = FAMILY_8600VZB;
++ break;
++ case BOOTLDRFAMILY('E', '1'):
++ platform_family = FAMILY_1500VZE;
++ break;
++ case BOOTLDRFAMILY('F', '1'):
++ platform_family = FAMILY_1500VZF;
++ break;
++ default:
++ platform_family = -1;
++ }
++}
++
++unsigned int platform_get_family(void)
++{
++ return platform_family;
++}
++EXPORT_SYMBOL(platform_get_family);
++
++/*
++ * \brief usb_eye_configure() for optimizing the USB eye on Calliope.
++ *
++ * \param unsigned int value saved to the register.
++ *
++ * \return none
++ *
++ */
++static void __init usb_eye_configure(unsigned int value)
++{
++ asic_write(asic_read(crt_spare) | value, crt_spare);
++}
++
++/*
++ * platform_get_asic - determine the ASIC type.
++ *
++ * \param none
++ *
++ * \return ASIC type; ASIC_UNKNOWN if none
++ *
++ */
++enum asic_type platform_get_asic(void)
++{
++ return asic;
++}
++EXPORT_SYMBOL(platform_get_asic);
++
++/*
++ * platform_configure_usb - usb configuration based on platform type.
++ * @bcm1_usb2_ctl: value for the BCM1_USB2_CTL register, which is
++ * quirky
++ */
++static void __init platform_configure_usb(void)
++{
++ u32 bcm1_usb2_ctl;
++
++ if (usb_configured)
++ return;
++
++ switch (asic) {
++ case ASIC_ZEUS:
++ fs_update(0x0000, 0x11, 0x02, 0);
++ bcm1_usb2_ctl = 0x803;
++ break;
++
++ case ASIC_CRONUS:
++ case ASIC_CRONUSLITE:
++ fs_update(0x0000, 0x11, 0x02, 0);
++ bcm1_usb2_ctl = 0x803;
++ break;
++
++ case ASIC_CALLIOPE:
++ fs_update(0x0000, 0x11, 0x02, 1);
++
++ switch (platform_family) {
++ case FAMILY_1500VZE:
++ break;
++
++ case FAMILY_1500VZF:
++ usb_eye_configure(0x003c0000);
++ break;
++
++ default:
++ usb_eye_configure(0x00300000);
++ break;
++ }
++
++ bcm1_usb2_ctl = 0x803;
++ break;
++
++ default:
++ pr_err("Unknown ASIC type: %d\n", asic);
++ break;
++ }
++
++ /* turn on USB power */
++ asic_write(0, usb2_strap);
++ /* Enable all OHCI interrupts */
++ asic_write(bcm1_usb2_ctl, usb2_control);
++ /* USB2_STBUS_OBC store32/load32 */
++ asic_write(3, usb2_stbus_obc);
++ /* USB2_STBUS_MESS_SIZE 2 packets */
++ asic_write(1, usb2_stbus_mess_size);
++ /* USB2_STBUS_CHUNK_SIZE 2 packets */
++ asic_write(1, usb2_stbus_chunk_size);
++
++ usb_configured = true;
++}
++
++/*
++ * Set up the USB EHCI interface
++ */
++void platform_configure_usb_ehci()
++{
++ platform_configure_usb();
++}
++
++/*
++ * Set up the USB OHCI interface
++ */
++void platform_configure_usb_ohci()
++{
++ platform_configure_usb();
++}
++
++/*
++ * Shut the USB EHCI interface down--currently a NOP
++ */
++void platform_unconfigure_usb_ehci()
++{
++}
++
++/*
++ * Shut the USB OHCI interface down--currently a NOP
++ */
++void platform_unconfigure_usb_ohci()
++{
++}
++
++/**
++ * configure_platform - configuration based on platform type.
++ */
++void __init configure_platform(void)
++{
++ platform_set_family();
++
++ switch (platform_family) {
++ case FAMILY_1500:
++ case FAMILY_1500VZE:
++ case FAMILY_1500VZF:
++ platform_features = FFS_CAPABLE;
++ asic = ASIC_CALLIOPE;
++ asic_phy_base = CALLIOPE_IO_BASE;
++ register_map = &calliope_register_map;
++ asic_base = (unsigned long)ioremap_nocache(asic_phy_base,
++ ASIC_IO_SIZE);
++
++ if (platform_family == FAMILY_1500VZE) {
++ gp_resources = non_dvr_vze_calliope_resources;
++ pr_info("Platform: 1500/Vz Class E - "
++ "CALLIOPE, NON_DVR_CAPABLE\n");
++ } else if (platform_family == FAMILY_1500VZF) {
++ gp_resources = non_dvr_vzf_calliope_resources;
++ pr_info("Platform: 1500/Vz Class F - "
++ "CALLIOPE, NON_DVR_CAPABLE\n");
++ } else {
++ gp_resources = non_dvr_calliope_resources;
++ pr_info("Platform: 1500/RNG100 - CALLIOPE, "
++ "NON_DVR_CAPABLE\n");
++ }
++ break;
++
++ case FAMILY_4500:
++ platform_features = FFS_CAPABLE | PCIE_CAPABLE |
++ DISPLAY_CAPABLE;
++ asic = ASIC_ZEUS;
++ asic_phy_base = ZEUS_IO_BASE;
++ register_map = &zeus_register_map;
++ asic_base = (unsigned long)ioremap_nocache(asic_phy_base,
++ ASIC_IO_SIZE);
++ gp_resources = non_dvr_zeus_resources;
++
++ pr_info("Platform: 4500 - ZEUS, NON_DVR_CAPABLE\n");
++ break;
++
++ case FAMILY_4600:
++ {
++ unsigned int chipversion = 0;
++
++ /* The settop has PCIE but it isn't used, so don't advertise
++ * it*/
++ platform_features = FFS_CAPABLE | DISPLAY_CAPABLE;
++ asic_phy_base = CRONUS_IO_BASE; /* same as Cronus */
++ register_map = &cronus_register_map; /* same as Cronus */
++ asic_base = (unsigned long)ioremap_nocache(asic_phy_base,
++ ASIC_IO_SIZE);
++ gp_resources = non_dvr_cronuslite_resources;
++
++ /* ASIC version will determine if this is a real CronusLite or
++ * Castrati(Cronus) */
++ chipversion = asic_read(chipver3) << 24;
++ chipversion |= asic_read(chipver2) << 16;
++ chipversion |= asic_read(chipver1) << 8;
++ chipversion |= asic_read(chipver0);
++
++ if ((chipversion == CRONUS_10) || (chipversion == CRONUS_11))
++ asic = ASIC_CRONUS;
++ else
++ asic = ASIC_CRONUSLITE;
++
++ pr_info("Platform: 4600 - %s, NON_DVR_CAPABLE, "
++ "chipversion=0x%08X\n",
++ (asic == ASIC_CRONUS) ? "CRONUS" : "CRONUS LITE",
++ chipversion);
++ break;
++ }
++ case FAMILY_4600VZA:
++ platform_features = FFS_CAPABLE | DISPLAY_CAPABLE;
++ asic = ASIC_CRONUS;
++ asic_phy_base = CRONUS_IO_BASE;
++ register_map = &cronus_register_map;
++ asic_base = (unsigned long)ioremap_nocache(asic_phy_base,
++ ASIC_IO_SIZE);
++ gp_resources = non_dvr_cronus_resources;
++
++ pr_info("Platform: Vz Class A - CRONUS, NON_DVR_CAPABLE\n");
++ break;
++
++ case FAMILY_8500:
++ case FAMILY_8500RNG:
++ platform_features = DVR_CAPABLE | PCIE_CAPABLE |
++ DISPLAY_CAPABLE;
++ asic = ASIC_ZEUS;
++ asic_phy_base = ZEUS_IO_BASE;
++ register_map = &zeus_register_map;
++ asic_base = (unsigned long)ioremap_nocache(asic_phy_base,
++ ASIC_IO_SIZE);
++ gp_resources = dvr_zeus_resources;
++
++ pr_info("Platform: 8500/RNG200 - ZEUS, DVR_CAPABLE\n");
++ break;
++
++ case FAMILY_8600:
++ case FAMILY_8600VZB:
++ platform_features = DVR_CAPABLE | PCIE_CAPABLE |
++ DISPLAY_CAPABLE;
++ asic = ASIC_CRONUS;
++ asic_phy_base = CRONUS_IO_BASE;
++ register_map = &cronus_register_map;
++ asic_base = (unsigned long)ioremap_nocache(asic_phy_base,
++ ASIC_IO_SIZE);
++ gp_resources = dvr_cronus_resources;
++
++ pr_info("Platform: 8600/Vz Class B - CRONUS, "
++ "DVR_CAPABLE\n");
++ break;
++
++ default:
++ pr_crit("Platform: UNKNOWN PLATFORM\n");
++ break;
++ }
++
++ switch (asic) {
++ case ASIC_ZEUS:
++ phys_to_bus_offset = 0x30000000;
++ break;
++ case ASIC_CALLIOPE:
++ phys_to_bus_offset = 0x10000000;
++ break;
++ case ASIC_CRONUSLITE:
++ /* Fall through */
++ case ASIC_CRONUS:
++ /*
++ * TODO: We suppose 0x10000000 aliases into 0x20000000-
++ * 0x2XXXXXXX. If 0x10000000 aliases into 0x60000000-
++ * 0x6XXXXXXX, the offset should be 0x50000000, not 0x10000000.
++ */
++ phys_to_bus_offset = 0x10000000;
++ break;
++ default:
++ phys_to_bus_offset = 0x00000000;
++ break;
++ }
++}
++
++/**
++ * platform_devices_init - sets up USB device resourse.
++ */
++static int __init platform_devices_init(void)
++{
++ pr_notice("%s: ----- Initializing USB resources -----\n", __func__);
++
++ asic_resource.start = asic_phy_base;
++ asic_resource.end += asic_resource.start;
++
++ ehci_resources[0].start = asic_reg_phys_addr(ehci_hcapbase);
++ ehci_resources[0].end += ehci_resources[0].start;
++
++ ohci_resources[0].start = asic_reg_phys_addr(ohci_hc_revision);
++ ohci_resources[0].end += ohci_resources[0].start;
++
++ set_io_port_base(0);
++
++ platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
++
++ return 0;
++}
++
++arch_initcall(platform_devices_init);
++
++/*
++ *
++ * BOOTMEM ALLOCATION
++ *
++ */
++/*
++ * Allocates/reserves the Platform memory resources early in the boot process.
++ * This ignores any resources that are designated IORESOURCE_IO
++ */
++void __init platform_alloc_bootmem(void)
++{
++ int i;
++ int total = 0;
++
++ /* Get persistent memory data from command line before allocating
++ * resources. This need to happen before normal command line parsing
++ * has been done */
++ pmem_setup_resource();
++
++ /* Loop through looking for resources that want a particular address */
++ for (i = 0; gp_resources[i].flags != 0; i++) {
++ int size = gp_resources[i].end - gp_resources[i].start + 1;
++ if ((gp_resources[i].start != 0) &&
++ ((gp_resources[i].flags & IORESOURCE_MEM) != 0)) {
++ reserve_bootmem(bus_to_phys(gp_resources[i].start),
++ size, 0);
++ total += gp_resources[i].end -
++ gp_resources[i].start + 1;
++ pr_info("reserve resource %s at %08x (%u bytes)\n",
++ gp_resources[i].name, gp_resources[i].start,
++ gp_resources[i].end -
++ gp_resources[i].start + 1);
++ }
++ }
++
++ /* Loop through assigning addresses for those that are left */
++ for (i = 0; gp_resources[i].flags != 0; i++) {
++ int size = gp_resources[i].end - gp_resources[i].start + 1;
++ if ((gp_resources[i].start == 0) &&
++ ((gp_resources[i].flags & IORESOURCE_MEM) != 0)) {
++ void *mem = alloc_bootmem_pages(size);
++
++ if (mem == NULL)
++ pr_err("Unable to allocate bootmem pages "
++ "for %s\n", gp_resources[i].name);
++
++ else {
++ gp_resources[i].start =
++ phys_to_bus(virt_to_phys(mem));
++ gp_resources[i].end =
++ gp_resources[i].start + size - 1;
++ total += size;
++ pr_info("allocate resource %s at %08x "
++ "(%u bytes)\n",
++ gp_resources[i].name,
++ gp_resources[i].start, size);
++ }
++ }
++ }
++
++ pr_info("Total Platform driver memory allocation: 0x%08x\n", total);
++
++ /* indicate resources that are platform I/O related */
++ for (i = 0; gp_resources[i].flags != 0; i++) {
++ if ((gp_resources[i].start != 0) &&
++ ((gp_resources[i].flags & IORESOURCE_IO) != 0)) {
++ pr_info("reserved platform resource %s at %08x\n",
++ gp_resources[i].name, gp_resources[i].start);
++ }
++ }
++}
++
++/*
++ *
++ * PERSISTENT MEMORY (PMEM) CONFIGURATION
++ *
++ */
++static unsigned long pmemaddr __initdata;
++
++static int __init early_param_pmemaddr(char *p)
++{
++ pmemaddr = (unsigned long)simple_strtoul(p, NULL, 0);
++ return 0;
++}
++early_param("pmemaddr", early_param_pmemaddr);
++
++static long pmemlen __initdata;
++
++static int __init early_param_pmemlen(char *p)
++{
++/* TODO: we can use this code when and if the bootloader ever changes this */
++#if 0
++ pmemlen = (unsigned long)simple_strtoul(p, NULL, 0);
++#else
++ pmemlen = 0x20000;
++#endif
++ return 0;
++}
++early_param("pmemlen", early_param_pmemlen);
++
++/*
++ * Set up persistent memory. If we were given values, we patch the array of
++ * resources. Otherwise, persistent memory may be allocated anywhere at all.
++ */
++static void __init pmem_setup_resource(void)
++{
++ struct resource *resource;
++ resource = asic_resource_get("DiagPersistentMemory");
++
++ if (resource && pmemaddr && pmemlen) {
++ /* The address provided by bootloader is in kseg0. Convert to
++ * a bus address. */
++ resource->start = phys_to_bus(pmemaddr - 0x80000000);
++ resource->end = resource->start + pmemlen - 1;
++
++ pr_info("persistent memory: start=0x%x end=0x%x\n",
++ resource->start, resource->end);
++ }
++}
++
++/*
++ *
++ * RESOURCE ACCESS FUNCTIONS
++ *
++ */
++
++/**
++ * asic_resource_get - retrieves parameters for a platform resource.
++ * @name: string to match resource
++ *
++ * Returns a pointer to a struct resource corresponding to the given name.
++ *
++ * CANNOT BE NAMED platform_resource_get, which would be the obvious choice,
++ * as this function name is already declared
++ */
++struct resource *asic_resource_get(const char *name)
++{
++ int i;
++
++ for (i = 0; gp_resources[i].flags != 0; i++) {
++ if (strcmp(gp_resources[i].name, name) == 0)
++ return &gp_resources[i];
++ }
++
++ return NULL;
++}
++EXPORT_SYMBOL(asic_resource_get);
++
++/**
++ * platform_release_memory - release pre-allocated memory
++ * @ptr: pointer to memory to release
++ * @size: size of resource
++ *
++ * This must only be called for memory allocated or reserved via the boot
++ * memory allocator.
++ */
++void platform_release_memory(void *ptr, int size)
++{
++ unsigned long addr;
++ unsigned long end;
++
++ addr = ((unsigned long)ptr + (PAGE_SIZE - 1)) & PAGE_MASK;
++ end = ((unsigned long)ptr + size) & PAGE_MASK;
++
++ for (; addr < end; addr += PAGE_SIZE) {
++ ClearPageReserved(virt_to_page(__va(addr)));
++ init_page_count(virt_to_page(__va(addr)));
++ free_page((unsigned long)__va(addr));
++ }
++}
++EXPORT_SYMBOL(platform_release_memory);
++
++/*
++ *
++ * FEATURE AVAILABILITY FUNCTIONS
++ *
++ */
++int platform_supports_dvr(void)
++{
++ return (platform_features & DVR_CAPABLE) != 0;
++}
++
++int platform_supports_ffs(void)
++{
++ return (platform_features & FFS_CAPABLE) != 0;
++}
++
++int platform_supports_pcie(void)
++{
++ return (platform_features & PCIE_CAPABLE) != 0;
++}
++
++int platform_supports_display(void)
++{
++ return (platform_features & DISPLAY_CAPABLE) != 0;
++}
+diff --git a/arch/mips/powertv/asic/asic_int.c b/arch/mips/powertv/asic/asic_int.c
+new file mode 100644
+index 0000000..80b2eed
+--- /dev/null
++++ b/arch/mips/powertv/asic/asic_int.c
+@@ -0,0 +1,125 @@
++/*
++ * Carsten Langgaard, carstenl@mips.com
++ * Copyright (C) 2000, 2001, 2004 MIPS Technologies, Inc.
++ * Copyright (C) 2001 Ralf Baechle
++ * Portions copyright (C) 2009 Cisco Systems, Inc.
++ *
++ * 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 PowerTV
++ * platform.
++ *
++ * The interrupt controller is located in the South Bridge a PIIX4 device
++ * with two internal 82C95 interrupt controllers.
++ */
++#include <linux/init.h>
++#include <linux/irq.h>
++#include <linux/sched.h>
++#include <linux/slab.h>
++#include <linux/interrupt.h>
++#include <linux/kernel_stat.h>
++#include <linux/kernel.h>
++#include <linux/random.h>
++
++#include <asm/irq_cpu.h>
++#include <linux/io.h>
++#include <asm/irq_regs.h>
++#include <asm/mips-boards/generic.h>
++
++#include <asm/mach-powertv/asic_regs.h>
++
++static DEFINE_SPINLOCK(asic_irq_lock);
++
++static inline int get_int(void)
++{
++ unsigned long flags;
++ int irq;
++
++ spin_lock_irqsave(&asic_irq_lock, flags);
++
++ irq = (asic_read(int_int_scan) >> 4) - 1;
++
++ if (irq == 0 || irq >= NR_IRQS)
++ irq = -1;
++
++ spin_unlock_irqrestore(&asic_irq_lock, flags);
++
++ return irq;
++}
++
++static void asic_irqdispatch(void)
++{
++ int irq;
++
++ irq = get_int();
++ if (irq < 0)
++ return; /* interrupt has already been cleared */
++
++ do_IRQ(irq);
++}
++
++static inline int clz(unsigned long x)
++{
++ __asm__(
++ " .set push \n"
++ " .set mips32 \n"
++ " clz %0, %1 \n"
++ " .set pop \n"
++ : "=r" (x)
++ : "r" (x));
++
++ return x;
++}
++
++/*
++ * Version of ffs that only looks at bits 12..15.
++ */
++static inline unsigned int irq_ffs(unsigned int pending)
++{
++ return fls(pending) - 1 + CAUSEB_IP;
++}
++
++/*
++ * TODO: check how it works under EIC mode.
++ */
++asmlinkage void plat_irq_dispatch(void)
++{
++ unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
++ int irq;
++
++ irq = irq_ffs(pending);
++
++ if (irq == CAUSEF_IP3)
++ asic_irqdispatch();
++ else if (irq >= 0)
++ do_IRQ(irq);
++ else
++ spurious_interrupt();
++}
++
++void __init arch_init_irq(void)
++{
++ int i;
++
++ asic_irq_init();
++
++ /*
++ * Initialize interrupt exception vectors.
++ */
++ if (cpu_has_veic || cpu_has_vint) {
++ int nvec = cpu_has_veic ? 64 : 8;
++ for (i = 0; i < nvec; i++)
++ set_vi_handler(i, asic_irqdispatch);
++ }
++}
+diff --git a/arch/mips/powertv/asic/irq_asic.c b/arch/mips/powertv/asic/irq_asic.c
+new file mode 100644
+index 0000000..b54d244
+--- /dev/null
++++ b/arch/mips/powertv/asic/irq_asic.c
+@@ -0,0 +1,116 @@
++/*
++ * Portions copyright (C) 2005-2009 Scientific Atlanta
++ * Portions copyright (C) 2009 Cisco Systems, Inc.
++ *
++ * Modified from arch/mips/kernel/irq-rm7000.c:
++ * Copyright (C) 2003 Ralf Baechle
++ *
++ * 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 <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/kernel.h>
++
++#include <asm/irq_cpu.h>
++#include <asm/mipsregs.h>
++#include <asm/system.h>
++
++#include <asm/mach-powertv/asic_regs.h>
++
++static inline void unmask_asic_irq(unsigned int irq)
++{
++ unsigned long enable_bit;
++
++ enable_bit = (1 << (irq & 0x1f));
++
++ switch (irq >> 5) {
++ case 0:
++ asic_write(asic_read(ien_int_0) | enable_bit, ien_int_0);
++ break;
++ case 1:
++ asic_write(asic_read(ien_int_1) | enable_bit, ien_int_1);
++ break;
++ case 2:
++ asic_write(asic_read(ien_int_2) | enable_bit, ien_int_2);
++ break;
++ case 3:
++ asic_write(asic_read(ien_int_3) | enable_bit, ien_int_3);
++ break;
++ default:
++ BUG();
++ }
++}
++
++static inline void mask_asic_irq(unsigned int irq)
++{
++ unsigned long disable_mask;
++
++ disable_mask = ~(1 << (irq & 0x1f));
++
++ switch (irq >> 5) {
++ case 0:
++ asic_write(asic_read(ien_int_0) & disable_mask, ien_int_0);
++ break;
++ case 1:
++ asic_write(asic_read(ien_int_1) & disable_mask, ien_int_1);
++ break;
++ case 2:
++ asic_write(asic_read(ien_int_2) & disable_mask, ien_int_2);
++ break;
++ case 3:
++ asic_write(asic_read(ien_int_3) & disable_mask, ien_int_3);
++ break;
++ default:
++ BUG();
++ }
++}
++
++static struct irq_chip asic_irq_chip = {
++ .name = "ASIC Level",
++ .ack = mask_asic_irq,
++ .mask = mask_asic_irq,
++ .mask_ack = mask_asic_irq,
++ .unmask = unmask_asic_irq,
++ .eoi = unmask_asic_irq,
++};
++
++void __init asic_irq_init(void)
++{
++ int i;
++
++ /* set priority to 0 */
++ write_c0_status(read_c0_status() & ~(0x0000fc00));
++
++ asic_write(0, ien_int_0);
++ asic_write(0, ien_int_1);
++ asic_write(0, ien_int_2);
++ asic_write(0, ien_int_3);
++
++ asic_write(0x0fffffff, int_level_3_3);
++ asic_write(0xffffffff, int_level_3_2);
++ asic_write(0xffffffff, int_level_3_1);
++ asic_write(0xffffffff, int_level_3_0);
++ asic_write(0xffffffff, int_level_2_3);
++ asic_write(0xffffffff, int_level_2_2);
++ asic_write(0xffffffff, int_level_2_1);
++ asic_write(0xffffffff, int_level_2_0);
++ asic_write(0xffffffff, int_level_1_3);
++ asic_write(0xffffffff, int_level_1_2);
++ asic_write(0xffffffff, int_level_1_1);
++ asic_write(0xffffffff, int_level_1_0);
++ asic_write(0xffffffff, int_level_0_3);
++ asic_write(0xffffffff, int_level_0_2);
++ asic_write(0xffffffff, int_level_0_1);
++ asic_write(0xffffffff, int_level_0_0);
++
++ asic_write(0xf, int_int_scan);
++
++ /*
++ * Initialize interrupt handlers.
++ */
++ for (i = 0; i < NR_IRQS; i++)
++ set_irq_chip_and_handler(i, &asic_irq_chip, handle_level_irq);
++}
+diff --git a/arch/mips/powertv/asic/prealloc-calliope.c b/arch/mips/powertv/asic/prealloc-calliope.c
+new file mode 100644
+index 0000000..cd5b76a
+--- /dev/null
++++ b/arch/mips/powertv/asic/prealloc-calliope.c
+@@ -0,0 +1,620 @@
++/*
++ * Memory pre-allocations for Calliope boxes.
++ *
++ * Copyright (C) 2005-2009 Scientific-Atlanta, Inc.
++ *
++ * 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
++ *
++ * Author: Ken Eppinett
++ * David Schleef <ds@schleef.org>
++ */
++
++#include <linux/init.h>
++#include <asm/mach-powertv/asic.h>
++
++/*
++ * NON_DVR_CAPABLE CALLIOPE RESOURCES
++ */
++struct resource non_dvr_calliope_resources[] __initdata =
++{
++ /*
++ * VIDEO / LX1
++ */
++ {
++ .name = "ST231aImage", /* Delta-Mu 1 image and ram */
++ .start = 0x24000000,
++ .end = 0x24200000 - 1, /*2MiB */
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "ST231aMonitor", /*8KiB block ST231a monitor */
++ .start = 0x24200000,
++ .end = 0x24202000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "MediaMemory1",
++ .start = 0x24202000,
++ .end = 0x26700000 - 1, /*~36.9MiB (32MiB - (2MiB + 8KiB)) */
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * Sysaudio Driver
++ */
++ {
++ .name = "DSP_Image_Buff",
++ .start = 0x00000000,
++ .end = 0x000FFFFF,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "ADSC_CPU_PCM_Buff",
++ .start = 0x00000000,
++ .end = 0x00009FFF,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "ADSC_AUX_Buff",
++ .start = 0x00000000,
++ .end = 0x00003FFF,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "ADSC_Main_Buff",
++ .start = 0x00000000,
++ .end = 0x00003FFF,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * STAVEM driver/STAPI
++ */
++ {
++ .name = "AVMEMPartition0",
++ .start = 0x00000000,
++ .end = 0x00600000 - 1, /* 6 MB total */
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * DOCSIS Subsystem
++ */
++ {
++ .name = "Docsis",
++ .start = 0x22000000,
++ .end = 0x22700000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * GHW HAL Driver
++ */
++ {
++ .name = "GraphicsHeap",
++ .start = 0x22700000,
++ .end = 0x23500000 - 1, /* 14 MB total */
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * multi com buffer area
++ */
++ {
++ .name = "MulticomSHM",
++ .start = 0x23700000,
++ .end = 0x23720000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * DMA Ring buffer (don't need recording buffers)
++ */
++ {
++ .name = "BMM_Buffer",
++ .start = 0x00000000,
++ .end = 0x000AA000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * Display bins buffer for unit0
++ */
++ {
++ .name = "DisplayBins0",
++ .start = 0x00000000,
++ .end = 0x00000FFF, /* 4 KB total */
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ *
++ * AVFS: player HAL memory
++ *
++ *
++ */
++ {
++ .name = "AvfsDmaMem",
++ .start = 0x00000000,
++ .end = 0x002c4c00 - 1, /* 945K * 3 for playback */
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * PMEM
++ */
++ {
++ .name = "DiagPersistentMemory",
++ .start = 0x00000000,
++ .end = 0x10000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * Smartcard
++ */
++ {
++ .name = "SmartCardInfo",
++ .start = 0x00000000,
++ .end = 0x2800 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * NAND Flash
++ */
++ {
++ .name = "NandFlash",
++ .start = NAND_FLASH_BASE,
++ .end = NAND_FLASH_BASE + 0x400 - 1,
++ .flags = IORESOURCE_IO,
++ },
++ /*
++ * Synopsys GMAC Memory Region
++ */
++ {
++ .name = "GMAC",
++ .start = 0x00000000,
++ .end = 0x00010000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * Add other resources here
++ *
++ */
++ { },
++};
++
++struct resource non_dvr_vz_calliope_resources[] __initdata =
++{
++ /*
++ * VIDEO / LX1
++ */
++ {
++ .name = "ST231aImage", /* Delta-Mu 1 image and ram */
++ .start = 0x24000000,
++ .end = 0x24200000 - 1, /*2 Meg */
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "ST231aMonitor", /* 8k block ST231a monitor */
++ .start = 0x24200000,
++ .end = 0x24202000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "MediaMemory1",
++ .start = 0x22202000,
++ .end = 0x22C20B85 - 1, /* 10.12 Meg */
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * Sysaudio Driver
++ */
++ {
++ .name = "DSP_Image_Buff",
++ .start = 0x00000000,
++ .end = 0x000FFFFF,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "ADSC_CPU_PCM_Buff",
++ .start = 0x00000000,
++ .end = 0x00009FFF,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "ADSC_AUX_Buff",
++ .start = 0x00000000,
++ .end = 0x00003FFF,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "ADSC_Main_Buff",
++ .start = 0x00000000,
++ .end = 0x00003FFF,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * STAVEM driver/STAPI
++ */
++ {
++ .name = "AVMEMPartition0",
++ .start = 0x20300000,
++ .end = 0x20620000-1, /*3.125 MB total */
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * GHW HAL Driver
++ */
++ {
++ .name = "GraphicsHeap",
++ .start = 0x20100000,
++ .end = 0x20300000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * multi com buffer area
++ */
++ {
++ .name = "MulticomSHM",
++ .start = 0x23900000,
++ .end = 0x23920000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * DMA Ring buffer
++ */
++ {
++ .name = "BMM_Buffer",
++ .start = 0x00000000,
++ .end = 0x000AA000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * Display bins buffer for unit0
++ */
++ {
++ .name = "DisplayBins0",
++ .start = 0x00000000,
++ .end = 0x00000FFF,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * PMEM
++ */
++ {
++ .name = "DiagPersistentMemory",
++ .start = 0x00000000,
++ .end = 0x10000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * Smartcard
++ */
++ {
++ .name = "SmartCardInfo",
++ .start = 0x00000000,
++ .end = 0x2800 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * NAND Flash
++ */
++ {
++ .name = "NandFlash",
++ .start = NAND_FLASH_BASE,
++ .end = NAND_FLASH_BASE+0x400 - 1,
++ .flags = IORESOURCE_IO,
++ },
++ /*
++ * Synopsys GMAC Memory Region
++ */
++ {
++ .name = "GMAC",
++ .start = 0x00000000,
++ .end = 0x00010000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * Add other resources here
++ */
++ { },
++};
++
++struct resource non_dvr_vze_calliope_resources[] __initdata =
++{
++ /*
++ * VIDEO / LX1
++ */
++ {
++ .name = "ST231aImage", /* Delta-Mu 1 image and ram */
++ .start = 0x22000000,
++ .end = 0x22200000 - 1, /*2 Meg */
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "ST231aMonitor", /* 8k block ST231a monitor */
++ .start = 0x22200000,
++ .end = 0x22202000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "MediaMemory1",
++ .start = 0x22202000,
++ .end = 0x22C20B85 - 1, /* 10.12 Meg */
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * Sysaudio Driver
++ */
++ {
++ .name = "DSP_Image_Buff",
++ .start = 0x00000000,
++ .end = 0x000FFFFF,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "ADSC_CPU_PCM_Buff",
++ .start = 0x00000000,
++ .end = 0x00009FFF,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "ADSC_AUX_Buff",
++ .start = 0x00000000,
++ .end = 0x00003FFF,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "ADSC_Main_Buff",
++ .start = 0x00000000,
++ .end = 0x00003FFF,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * STAVEM driver/STAPI
++ */
++ {
++ .name = "AVMEMPartition0",
++ .start = 0x20396000,
++ .end = 0x206B6000 - 1, /* 3.125 MB total */
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * GHW HAL Driver
++ */
++ {
++ .name = "GraphicsHeap",
++ .start = 0x20100000,
++ .end = 0x20396000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * multi com buffer area
++ */
++ {
++ .name = "MulticomSHM",
++ .start = 0x206B6000,
++ .end = 0x206D6000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * DMA Ring buffer
++ */
++ {
++ .name = "BMM_Buffer",
++ .start = 0x00000000,
++ .end = 0x000AA000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * Display bins buffer for unit0
++ */
++ {
++ .name = "DisplayBins0",
++ .start = 0x00000000,
++ .end = 0x00000FFF,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * PMEM
++ */
++ {
++ .name = "DiagPersistentMemory",
++ .start = 0x00000000,
++ .end = 0x10000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * Smartcard
++ */
++ {
++ .name = "SmartCardInfo",
++ .start = 0x00000000,
++ .end = 0x2800 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * NAND Flash
++ */
++ {
++ .name = "NandFlash",
++ .start = NAND_FLASH_BASE,
++ .end = NAND_FLASH_BASE+0x400 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * Synopsys GMAC Memory Region
++ */
++ {
++ .name = "GMAC",
++ .start = 0x00000000,
++ .end = 0x00010000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * Add other resources here
++ */
++ { },
++};
++
++struct resource non_dvr_vzf_calliope_resources[] __initdata =
++{
++ /*
++ * VIDEO / LX1
++ */
++ {
++ .name = "ST231aImage", /*Delta-Mu 1 image and ram */
++ .start = 0x24000000,
++ .end = 0x24200000 - 1, /*2MiB */
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "ST231aMonitor", /*8KiB block ST231a monitor */
++ .start = 0x24200000,
++ .end = 0x24202000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "MediaMemory1",
++ .start = 0x24202000,
++ /* ~19.4 (21.5MiB - (2MiB + 8KiB)) */
++ .end = 0x25580000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * Sysaudio Driver
++ */
++ {
++ .name = "DSP_Image_Buff",
++ .start = 0x00000000,
++ .end = 0x000FFFFF,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "ADSC_CPU_PCM_Buff",
++ .start = 0x00000000,
++ .end = 0x00009FFF,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "ADSC_AUX_Buff",
++ .start = 0x00000000,
++ .end = 0x00003FFF,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "ADSC_Main_Buff",
++ .start = 0x00000000,
++ .end = 0x00003FFF,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * STAVEM driver/STAPI
++ */
++ {
++ .name = "AVMEMPartition0",
++ .start = 0x00000000,
++ .end = 0x00480000 - 1, /* 4.5 MB total */
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * GHW HAL Driver
++ */
++ {
++ .name = "GraphicsHeap",
++ .start = 0x22700000,
++ .end = 0x23500000 - 1, /* 14 MB total */
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * multi com buffer area
++ */
++ {
++ .name = "MulticomSHM",
++ .start = 0x23700000,
++ .end = 0x23720000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * DMA Ring buffer (don't need recording buffers)
++ */
++ {
++ .name = "BMM_Buffer",
++ .start = 0x00000000,
++ .end = 0x000AA000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * Display bins buffer for unit0
++ */
++ {
++ .name = "DisplayBins0",
++ .start = 0x00000000,
++ .end = 0x00000FFF, /* 4 KB total */
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * Display bins buffer for unit1
++ */
++ {
++ .name = "DisplayBins1",
++ .start = 0x00000000,
++ .end = 0x00000FFF, /* 4 KB total */
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ *
++ * AVFS: player HAL memory
++ *
++ *
++ */
++ {
++ .name = "AvfsDmaMem",
++ .start = 0x00000000,
++ .end = 0x002c4c00 - 1, /* 945K * 3 for playback */
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * PMEM
++ */
++ {
++ .name = "DiagPersistentMemory",
++ .start = 0x00000000,
++ .end = 0x10000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * Smartcard
++ */
++ {
++ .name = "SmartCardInfo",
++ .start = 0x00000000,
++ .end = 0x2800 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * NAND Flash
++ */
++ {
++ .name = "NandFlash",
++ .start = NAND_FLASH_BASE,
++ .end = NAND_FLASH_BASE + 0x400 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * Synopsys GMAC Memory Region
++ */
++ {
++ .name = "GMAC",
++ .start = 0x00000000,
++ .end = 0x00010000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * Add other resources here
++ */
++ { },
++};
+diff --git a/arch/mips/powertv/asic/prealloc-cronus.c b/arch/mips/powertv/asic/prealloc-cronus.c
+new file mode 100644
+index 0000000..45a5c3e
+--- /dev/null
++++ b/arch/mips/powertv/asic/prealloc-cronus.c
+@@ -0,0 +1,608 @@
++/*
++ * Memory pre-allocations for Cronus boxes.
++ *
++ * Copyright (C) 2005-2009 Scientific-Atlanta, Inc.
++ *
++ * 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
++ *
++ * Author: Ken Eppinett
++ * David Schleef <ds@schleef.org>
++ */
++
++#include <linux/init.h>
++#include <asm/mach-powertv/asic.h>
++
++/*
++ * DVR_CAPABLE CRONUS RESOURCES
++ */
++struct resource dvr_cronus_resources[] __initdata =
++{
++ /*
++ *
++ * VIDEO1 / LX1
++ *
++ */
++ {
++ .name = "ST231aImage", /* Delta-Mu 1 image and ram */
++ .start = 0x24000000,
++ .end = 0x241FFFFF, /* 2MiB */
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "ST231aMonitor", /* 8KiB block ST231a monitor */
++ .start = 0x24200000,
++ .end = 0x24201FFF,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "MediaMemory1",
++ .start = 0x24202000,
++ .end = 0x25FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ *
++ * VIDEO2 / LX2
++ *
++ */
++ {
++ .name = "ST231bImage", /* Delta-Mu 2 image and ram */
++ .start = 0x60000000,
++ .end = 0x601FFFFF, /* 2MiB */
++ .flags = IORESOURCE_IO,
++ },
++ {
++ .name = "ST231bMonitor", /* 8KiB block ST231b monitor */
++ .start = 0x60200000,
++ .end = 0x60201FFF,
++ .flags = IORESOURCE_IO,
++ },
++ {
++ .name = "MediaMemory2",
++ .start = 0x60202000,
++ .end = 0x61FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */
++ .flags = IORESOURCE_IO,
++ },
++ /*
++ *
++ * Sysaudio Driver
++ *
++ * This driver requires:
++ *
++ * Arbitrary Based Buffers:
++ * DSP_Image_Buff - DSP code and data images (1MB)
++ * ADSC_CPU_PCM_Buff - ADSC CPU PCM buffer (40KB)
++ * ADSC_AUX_Buff - ADSC AUX buffer (16KB)
++ * ADSC_Main_Buff - ADSC Main buffer (16KB)
++ *
++ */
++ {
++ .name = "DSP_Image_Buff",
++ .start = 0x00000000,
++ .end = 0x000FFFFF,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "ADSC_CPU_PCM_Buff",
++ .start = 0x00000000,
++ .end = 0x00009FFF,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "ADSC_AUX_Buff",
++ .start = 0x00000000,
++ .end = 0x00003FFF,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "ADSC_Main_Buff",
++ .start = 0x00000000,
++ .end = 0x00003FFF,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ *
++ * STAVEM driver/STAPI
++ *
++ * This driver requires:
++ *
++ * Arbitrary Based Buffers:
++ * This memory area is used for allocating buffers for Video decoding
++ * purposes. Allocation/De-allocation within this buffer is managed
++ * by the STAVMEM driver of the STAPI. They could be Decimated
++ * Picture Buffers, Intermediate Buffers, as deemed necessary for
++ * video decoding purposes, for any video decoders on Zeus.
++ *
++ */
++ {
++ .name = "AVMEMPartition0",
++ .start = 0x63580000,
++ .end = 0x64180000 - 1, /* 12 MB total */
++ .flags = IORESOURCE_IO,
++ },
++ /*
++ *
++ * DOCSIS Subsystem
++ *
++ * This driver requires:
++ *
++ * Arbitrary Based Buffers:
++ * Docsis -
++ *
++ */
++ {
++ .name = "Docsis",
++ .start = 0x62000000,
++ .end = 0x62700000 - 1, /* 7 MB total */
++ .flags = IORESOURCE_IO,
++ },
++ /*
++ *
++ * GHW HAL Driver
++ *
++ * This driver requires:
++ *
++ * Arbitrary Based Buffers:
++ * GraphicsHeap - PowerTV Graphics Heap
++ *
++ */
++ {
++ .name = "GraphicsHeap",
++ .start = 0x62700000,
++ .end = 0x63500000 - 1, /* 14 MB total */
++ .flags = IORESOURCE_IO,
++ },
++ /*
++ *
++ * multi com buffer area
++ *
++ * This driver requires:
++ *
++ * Arbitrary Based Buffers:
++ * Docsis -
++ *
++ */
++ {
++ .name = "MulticomSHM",
++ .start = 0x26000000,
++ .end = 0x26020000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ *
++ * DMA Ring buffer
++ *
++ * This driver requires:
++ *
++ * Arbitrary Based Buffers:
++ * Docsis -
++ *
++ */
++ {
++ .name = "BMM_Buffer",
++ .start = 0x00000000,
++ .end = 0x00280000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ *
++ * Display bins buffer for unit0
++ *
++ * This driver requires:
++ *
++ * Arbitrary Based Buffers:
++ * Display Bins for unit0
++ *
++ */
++ {
++ .name = "DisplayBins0",
++ .start = 0x00000000,
++ .end = 0x00000FFF, /* 4 KB total */
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ *
++ * Display bins buffer
++ *
++ * This driver requires:
++ *
++ * Arbitrary Based Buffers:
++ * Display Bins for unit1
++ *
++ */
++ {
++ .name = "DisplayBins1",
++ .start = 0x64AD4000,
++ .end = 0x64AD5000 - 1, /* 4 KB total */
++ .flags = IORESOURCE_IO,
++ },
++ /*
++ *
++ * ITFS
++ *
++ * This driver requires:
++ *
++ * Arbitrary Based Buffers:
++ * Docsis -
++ *
++ */
++ {
++ .name = "ITFS",
++ .start = 0x64180000,
++ /* 815,104 bytes each for 2 ITFS partitions. */
++ .end = 0x6430DFFF,
++ .flags = IORESOURCE_IO,
++ },
++ /*
++ *
++ * AVFS
++ *
++ * This driver requires:
++ *
++ * Arbitrary Based Buffers:
++ * Docsis -
++ *
++ */
++ {
++ .name = "AvfsDmaMem",
++ .start = 0x6430E000,
++ /* (945K * 8) = (128K *3) 5 playbacks / 3 server */
++ .end = 0x64AD0000 - 1,
++ .flags = IORESOURCE_IO,
++ },
++ {
++ .name = "AvfsFileSys",
++ .start = 0x64AD0000,
++ .end = 0x64AD1000 - 1, /* 4K */
++ .flags = IORESOURCE_IO,
++ },
++ /*
++ *
++ * PMEM
++ *
++ * This driver requires:
++ *
++ * Arbitrary Based Buffers:
++ * Persistent memory for diagnostics.
++ *
++ */
++ {
++ .name = "DiagPersistentMemory",
++ .start = 0x00000000,
++ .end = 0x10000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ *
++ * Smartcard
++ *
++ * This driver requires:
++ *
++ * Arbitrary Based Buffers:
++ * Read and write buffers for Internal/External cards
++ *
++ */
++ {
++ .name = "SmartCardInfo",
++ .start = 0x64AD1000,
++ .end = 0x64AD3800 - 1,
++ .flags = IORESOURCE_IO,
++ },
++ /*
++ *
++ * KAVNET
++ * NP Reset Vector - must be of the form xxCxxxxx
++ * NP Image - must be video bank 1
++ * NP IPC - must be video bank 2
++ */
++ {
++ .name = "NP_Reset_Vector",
++ .start = 0x27c00000,
++ .end = 0x27c01000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "NP_Image",
++ .start = 0x27020000,
++ .end = 0x27060000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "NP_IPC",
++ .start = 0x63500000,
++ .end = 0x63580000 - 1,
++ .flags = IORESOURCE_IO,
++ },
++ /*
++ * Add other resources here
++ */
++ { },
++};
++
++/*
++ * NON_DVR_CAPABLE CRONUS RESOURCES
++ */
++struct resource non_dvr_cronus_resources[] __initdata =
++{
++ /*
++ *
++ * VIDEO1 / LX1
++ *
++ */
++ {
++ .name = "ST231aImage", /* Delta-Mu 1 image and ram */
++ .start = 0x24000000,
++ .end = 0x241FFFFF, /* 2MiB */
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "ST231aMonitor", /* 8KiB block ST231a monitor */
++ .start = 0x24200000,
++ .end = 0x24201FFF,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "MediaMemory1",
++ .start = 0x24202000,
++ .end = 0x25FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ *
++ * VIDEO2 / LX2
++ *
++ */
++ {
++ .name = "ST231bImage", /* Delta-Mu 2 image and ram */
++ .start = 0x60000000,
++ .end = 0x601FFFFF, /* 2MiB */
++ .flags = IORESOURCE_IO,
++ },
++ {
++ .name = "ST231bMonitor", /* 8KiB block ST231b monitor */
++ .start = 0x60200000,
++ .end = 0x60201FFF,
++ .flags = IORESOURCE_IO,
++ },
++ {
++ .name = "MediaMemory2",
++ .start = 0x60202000,
++ .end = 0x61FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */
++ .flags = IORESOURCE_IO,
++ },
++ /*
++ *
++ * Sysaudio Driver
++ *
++ * This driver requires:
++ *
++ * Arbitrary Based Buffers:
++ * DSP_Image_Buff - DSP code and data images (1MB)
++ * ADSC_CPU_PCM_Buff - ADSC CPU PCM buffer (40KB)
++ * ADSC_AUX_Buff - ADSC AUX buffer (16KB)
++ * ADSC_Main_Buff - ADSC Main buffer (16KB)
++ *
++ */
++ {
++ .name = "DSP_Image_Buff",
++ .start = 0x00000000,
++ .end = 0x000FFFFF,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "ADSC_CPU_PCM_Buff",
++ .start = 0x00000000,
++ .end = 0x00009FFF,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "ADSC_AUX_Buff",
++ .start = 0x00000000,
++ .end = 0x00003FFF,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "ADSC_Main_Buff",
++ .start = 0x00000000,
++ .end = 0x00003FFF,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ *
++ * STAVEM driver/STAPI
++ *
++ * This driver requires:
++ *
++ * Arbitrary Based Buffers:
++ * This memory area is used for allocating buffers for Video decoding
++ * purposes. Allocation/De-allocation within this buffer is managed
++ * by the STAVMEM driver of the STAPI. They could be Decimated
++ * Picture Buffers, Intermediate Buffers, as deemed necessary for
++ * video decoding purposes, for any video decoders on Zeus.
++ *
++ */
++ {
++ .name = "AVMEMPartition0",
++ .start = 0x63580000,
++ .end = 0x64180000 - 1, /* 12 MB total */
++ .flags = IORESOURCE_IO,
++ },
++ /*
++ *
++ * DOCSIS Subsystem
++ *
++ * This driver requires:
++ *
++ * Arbitrary Based Buffers:
++ * Docsis -
++ *
++ */
++ {
++ .name = "Docsis",
++ .start = 0x62000000,
++ .end = 0x62700000 - 1, /* 7 MB total */
++ .flags = IORESOURCE_IO,
++ },
++ /*
++ *
++ * GHW HAL Driver
++ *
++ * This driver requires:
++ *
++ * Arbitrary Based Buffers:
++ * GraphicsHeap - PowerTV Graphics Heap
++ *
++ */
++ {
++ .name = "GraphicsHeap",
++ .start = 0x62700000,
++ .end = 0x63500000 - 1, /* 14 MB total */
++ .flags = IORESOURCE_IO,
++ },
++ /*
++ *
++ * multi com buffer area
++ *
++ * This driver requires:
++ *
++ * Arbitrary Based Buffers:
++ * Docsis -
++ *
++ */
++ {
++ .name = "MulticomSHM",
++ .start = 0x26000000,
++ .end = 0x26020000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ *
++ * DMA Ring buffer
++ *
++ * This driver requires:
++ *
++ * Arbitrary Based Buffers:
++ * Docsis -
++ *
++ */
++ {
++ .name = "BMM_Buffer",
++ .start = 0x00000000,
++ .end = 0x000AA000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ *
++ * Display bins buffer for unit0
++ *
++ * This driver requires:
++ *
++ * Arbitrary Based Buffers:
++ * Display Bins for unit0
++ *
++ */
++ {
++ .name = "DisplayBins0",
++ .start = 0x00000000,
++ .end = 0x00000FFF, /* 4 KB total */
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ *
++ * Display bins buffer
++ *
++ * This driver requires:
++ *
++ * Arbitrary Based Buffers:
++ * Display Bins for unit1
++ *
++ */
++ {
++ .name = "DisplayBins1",
++ .start = 0x64AD4000,
++ .end = 0x64AD5000 - 1, /* 4 KB total */
++ .flags = IORESOURCE_IO,
++ },
++ /*
++ *
++ * AVFS: player HAL memory
++ *
++ *
++ */
++ {
++ .name = "AvfsDmaMem",
++ .start = 0x6430E000,
++ .end = 0x645D2C00 - 1, /* 945K * 3 for playback */
++ .flags = IORESOURCE_IO,
++ },
++ /*
++ *
++ * PMEM
++ *
++ * This driver requires:
++ *
++ * Arbitrary Based Buffers:
++ * Persistent memory for diagnostics.
++ *
++ */
++ {
++ .name = "DiagPersistentMemory",
++ .start = 0x00000000,
++ .end = 0x10000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ *
++ * Smartcard
++ *
++ * This driver requires:
++ *
++ * Arbitrary Based Buffers:
++ * Read and write buffers for Internal/External cards
++ *
++ */
++ {
++ .name = "SmartCardInfo",
++ .start = 0x64AD1000,
++ .end = 0x64AD3800 - 1,
++ .flags = IORESOURCE_IO,
++ },
++ /*
++ *
++ * KAVNET
++ * NP Reset Vector - must be of the form xxCxxxxx
++ * NP Image - must be video bank 1
++ * NP IPC - must be video bank 2
++ */
++ {
++ .name = "NP_Reset_Vector",
++ .start = 0x27c00000,
++ .end = 0x27c01000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "NP_Image",
++ .start = 0x27020000,
++ .end = 0x27060000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "NP_IPC",
++ .start = 0x63500000,
++ .end = 0x63580000 - 1,
++ .flags = IORESOURCE_IO,
++ },
++ { },
++};
+diff --git a/arch/mips/powertv/asic/prealloc-cronuslite.c b/arch/mips/powertv/asic/prealloc-cronuslite.c
+new file mode 100644
+index 0000000..23a9056
+--- /dev/null
++++ b/arch/mips/powertv/asic/prealloc-cronuslite.c
+@@ -0,0 +1,290 @@
++/*
++ * Memory pre-allocations for Cronus Lite boxes.
++ *
++ * Copyright (C) 2005-2009 Scientific-Atlanta, Inc.
++ *
++ * 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
++ *
++ * Author: Ken Eppinett
++ * David Schleef <ds@schleef.org>
++ */
++
++#include <linux/init.h>
++#include <asm/mach-powertv/asic.h>
++
++/*
++ * NON_DVR_CAPABLE CRONUSLITE RESOURCES
++ */
++struct resource non_dvr_cronuslite_resources[] __initdata =
++{
++ /*
++ *
++ * VIDEO2 / LX2
++ *
++ */
++ {
++ .name = "ST231aImage", /* Delta-Mu 2 image and ram */
++ .start = 0x60000000,
++ .end = 0x601FFFFF, /* 2MiB */
++ .flags = IORESOURCE_IO,
++ },
++ {
++ .name = "ST231aMonitor", /* 8KiB block ST231b monitor */
++ .start = 0x60200000,
++ .end = 0x60201FFF,
++ .flags = IORESOURCE_IO,
++ },
++ {
++ .name = "MediaMemory1",
++ .start = 0x60202000,
++ .end = 0x61FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */
++ .flags = IORESOURCE_IO,
++ },
++ /*
++ *
++ * Sysaudio Driver
++ *
++ * This driver requires:
++ *
++ * Arbitrary Based Buffers:
++ * DSP_Image_Buff - DSP code and data images (1MB)
++ * ADSC_CPU_PCM_Buff - ADSC CPU PCM buffer (40KB)
++ * ADSC_AUX_Buff - ADSC AUX buffer (16KB)
++ * ADSC_Main_Buff - ADSC Main buffer (16KB)
++ *
++ */
++ {
++ .name = "DSP_Image_Buff",
++ .start = 0x00000000,
++ .end = 0x000FFFFF,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "ADSC_CPU_PCM_Buff",
++ .start = 0x00000000,
++ .end = 0x00009FFF,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "ADSC_AUX_Buff",
++ .start = 0x00000000,
++ .end = 0x00003FFF,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "ADSC_Main_Buff",
++ .start = 0x00000000,
++ .end = 0x00003FFF,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ *
++ * STAVEM driver/STAPI
++ *
++ * This driver requires:
++ *
++ * Arbitrary Based Buffers:
++ * This memory area is used for allocating buffers for Video decoding
++ * purposes. Allocation/De-allocation within this buffer is managed
++ * by the STAVMEM driver of the STAPI. They could be Decimated
++ * Picture Buffers, Intermediate Buffers, as deemed necessary for
++ * video decoding purposes, for any video decoders on Zeus.
++ *
++ */
++ {
++ .name = "AVMEMPartition0",
++ .start = 0x63580000,
++ .end = 0x63B80000 - 1, /* 6 MB total */
++ .flags = IORESOURCE_IO,
++ },
++ /*
++ *
++ * DOCSIS Subsystem
++ *
++ * This driver requires:
++ *
++ * Arbitrary Based Buffers:
++ * Docsis -
++ *
++ */
++ {
++ .name = "Docsis",
++ .start = 0x62000000,
++ .end = 0x62700000 - 1, /* 7 MB total */
++ .flags = IORESOURCE_IO,
++ },
++ /*
++ *
++ * GHW HAL Driver
++ *
++ * This driver requires:
++ *
++ * Arbitrary Based Buffers:
++ * GraphicsHeap - PowerTV Graphics Heap
++ *
++ */
++ {
++ .name = "GraphicsHeap",
++ .start = 0x62700000,
++ .end = 0x63500000 - 1, /* 14 MB total */
++ .flags = IORESOURCE_IO,
++ },
++ /*
++ *
++ * multi com buffer area
++ *
++ * This driver requires:
++ *
++ * Arbitrary Based Buffers:
++ * Docsis -
++ *
++ */
++ {
++ .name = "MulticomSHM",
++ .start = 0x26000000,
++ .end = 0x26020000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ *
++ * DMA Ring buffer
++ *
++ * This driver requires:
++ *
++ * Arbitrary Based Buffers:
++ * Docsis -
++ *
++ */
++ {
++ .name = "BMM_Buffer",
++ .start = 0x00000000,
++ .end = 0x000AA000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ *
++ * Display bins buffer for unit0
++ *
++ * This driver requires:
++ *
++ * Arbitrary Based Buffers:
++ * Display Bins for unit0
++ *
++ */
++ {
++ .name = "DisplayBins0",
++ .start = 0x00000000,
++ .end = 0x00000FFF, /* 4 KB total */
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ *
++ * Display bins buffer
++ *
++ * This driver requires:
++ *
++ * Arbitrary Based Buffers:
++ * Display Bins for unit1
++ *
++ */
++ {
++ .name = "DisplayBins1",
++ .start = 0x63B83000,
++ .end = 0x63B84000 - 1, /* 4 KB total */
++ .flags = IORESOURCE_IO,
++ },
++ /*
++ *
++ * AVFS: player HAL memory
++ *
++ *
++ */
++ {
++ .name = "AvfsDmaMem",
++ .start = 0x63B84000,
++ .end = 0x63E48C00 - 1, /* 945K * 3 for playback */
++ .flags = IORESOURCE_IO,
++ },
++ /*
++ *
++ * PMEM
++ *
++ * This driver requires:
++ *
++ * Arbitrary Based Buffers:
++ * Persistent memory for diagnostics.
++ *
++ */
++ {
++ .name = "DiagPersistentMemory",
++ .start = 0x00000000,
++ .end = 0x10000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ *
++ * Smartcard
++ *
++ * This driver requires:
++ *
++ * Arbitrary Based Buffers:
++ * Read and write buffers for Internal/External cards
++ *
++ */
++ {
++ .name = "SmartCardInfo",
++ .start = 0x63B80000,
++ .end = 0x63B82800 - 1,
++ .flags = IORESOURCE_IO,
++ },
++ /*
++ *
++ * KAVNET
++ * NP Reset Vector - must be of the form xxCxxxxx
++ * NP Image - must be video bank 1
++ * NP IPC - must be video bank 2
++ */
++ {
++ .name = "NP_Reset_Vector",
++ .start = 0x27c00000,
++ .end = 0x27c01000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "NP_Image",
++ .start = 0x27020000,
++ .end = 0x27060000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "NP_IPC",
++ .start = 0x63500000,
++ .end = 0x63580000 - 1,
++ .flags = IORESOURCE_IO,
++ },
++ /*
++ * NAND Flash
++ */
++ {
++ .name = "NandFlash",
++ .start = NAND_FLASH_BASE,
++ .end = NAND_FLASH_BASE + 0x400 - 1,
++ .flags = IORESOURCE_IO,
++ },
++ /*
++ * Add other resources here
++ */
++ { },
++};
+diff --git a/arch/mips/powertv/asic/prealloc-zeus.c b/arch/mips/powertv/asic/prealloc-zeus.c
+new file mode 100644
+index 0000000..018d451
+--- /dev/null
++++ b/arch/mips/powertv/asic/prealloc-zeus.c
+@@ -0,0 +1,459 @@
++/*
++ * Memory pre-allocations for Zeus boxes.
++ *
++ * Copyright (C) 2005-2009 Scientific-Atlanta, Inc.
++ *
++ * 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
++ *
++ * Author: Ken Eppinett
++ * David Schleef <ds@schleef.org>
++ */
++
++#include <linux/init.h>
++#include <asm/mach-powertv/asic.h>
++
++/*
++ * DVR_CAPABLE RESOURCES
++ */
++struct resource dvr_zeus_resources[] __initdata =
++{
++ /*
++ *
++ * VIDEO1 / LX1
++ *
++ */
++ {
++ .name = "ST231aImage", /* Delta-Mu 1 image and ram */
++ .start = 0x20000000,
++ .end = 0x201FFFFF, /* 2MiB */
++ .flags = IORESOURCE_IO,
++ },
++ {
++ .name = "ST231aMonitor", /* 8KiB block ST231a monitor */
++ .start = 0x20200000,
++ .end = 0x20201FFF,
++ .flags = IORESOURCE_IO,
++ },
++ {
++ .name = "MediaMemory1",
++ .start = 0x20202000,
++ .end = 0x21FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */
++ .flags = IORESOURCE_IO,
++ },
++ /*
++ *
++ * VIDEO2 / LX2
++ *
++ */
++ {
++ .name = "ST231bImage", /* Delta-Mu 2 image and ram */
++ .start = 0x30000000,
++ .end = 0x301FFFFF, /* 2MiB */
++ .flags = IORESOURCE_IO,
++ },
++ {
++ .name = "ST231bMonitor", /* 8KiB block ST231b monitor */
++ .start = 0x30200000,
++ .end = 0x30201FFF,
++ .flags = IORESOURCE_IO,
++ },
++ {
++ .name = "MediaMemory2",
++ .start = 0x30202000,
++ .end = 0x31FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */
++ .flags = IORESOURCE_IO,
++ },
++ /*
++ *
++ * Sysaudio Driver
++ *
++ * This driver requires:
++ *
++ * Arbitrary Based Buffers:
++ * DSP_Image_Buff - DSP code and data images (1MB)
++ * ADSC_CPU_PCM_Buff - ADSC CPU PCM buffer (40KB)
++ * ADSC_AUX_Buff - ADSC AUX buffer (16KB)
++ * ADSC_Main_Buff - ADSC Main buffer (16KB)
++ *
++ */
++ {
++ .name = "DSP_Image_Buff",
++ .start = 0x00000000,
++ .end = 0x000FFFFF,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "ADSC_CPU_PCM_Buff",
++ .start = 0x00000000,
++ .end = 0x00009FFF,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "ADSC_AUX_Buff",
++ .start = 0x00000000,
++ .end = 0x00003FFF,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "ADSC_Main_Buff",
++ .start = 0x00000000,
++ .end = 0x00003FFF,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ *
++ * STAVEM driver/STAPI
++ *
++ * This driver requires:
++ *
++ * Arbitrary Based Buffers:
++ * This memory area is used for allocating buffers for Video decoding
++ * purposes. Allocation/De-allocation within this buffer is managed
++ * by the STAVMEM driver of the STAPI. They could be Decimated
++ * Picture Buffers, Intermediate Buffers, as deemed necessary for
++ * video decoding purposes, for any video decoders on Zeus.
++ *
++ */
++ {
++ .name = "AVMEMPartition0",
++ .start = 0x00000000,
++ .end = 0x00c00000 - 1, /* 12 MB total */
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ *
++ * DOCSIS Subsystem
++ *
++ * This driver requires:
++ *
++ * Arbitrary Based Buffers:
++ * Docsis -
++ *
++ */
++ {
++ .name = "Docsis",
++ .start = 0x40100000,
++ .end = 0x407fffff,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ *
++ * GHW HAL Driver
++ *
++ * This driver requires:
++ *
++ * Arbitrary Based Buffers:
++ * GraphicsHeap - PowerTV Graphics Heap
++ *
++ */
++ {
++ .name = "GraphicsHeap",
++ .start = 0x46900000,
++ .end = 0x47700000 - 1, /* 14 MB total */
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ *
++ * multi com buffer area
++ *
++ * This driver requires:
++ *
++ * Arbitrary Based Buffers:
++ * Docsis -
++ *
++ */
++ {
++ .name = "MulticomSHM",
++ .start = 0x47900000,
++ .end = 0x47920000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ *
++ * DMA Ring buffer
++ *
++ * This driver requires:
++ *
++ * Arbitrary Based Buffers:
++ * Docsis -
++ *
++ */
++ {
++ .name = "BMM_Buffer",
++ .start = 0x00000000,
++ .end = 0x00280000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ *
++ * Display bins buffer for unit0
++ *
++ * This driver requires:
++ *
++ * Arbitrary Based Buffers:
++ * Display Bins for unit0
++ *
++ */
++ {
++ .name = "DisplayBins0",
++ .start = 0x00000000,
++ .end = 0x00000FFF, /* 4 KB total */
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ *
++ * Display bins buffer
++ *
++ * This driver requires:
++ *
++ * Arbitrary Based Buffers:
++ * Display Bins for unit1
++ *
++ */
++ {
++ .name = "DisplayBins1",
++ .start = 0x00000000,
++ .end = 0x00000FFF, /* 4 KB total */
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ *
++ * ITFS
++ *
++ * This driver requires:
++ *
++ * Arbitrary Based Buffers:
++ * Docsis -
++ *
++ */
++ {
++ .name = "ITFS",
++ .start = 0x00000000,
++ /* 815,104 bytes each for 2 ITFS partitions. */
++ .end = 0x0018DFFF,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ *
++ * AVFS
++ *
++ * This driver requires:
++ *
++ * Arbitrary Based Buffers:
++ * Docsis -
++ *
++ */
++ {
++ .name = "AvfsDmaMem",
++ .start = 0x00000000,
++ /* (945K * 8) = (128K * 3) 5 playbacks / 3 server */
++ .end = 0x007c2000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "AvfsFileSys",
++ .start = 0x00000000,
++ .end = 0x00001000 - 1, /* 4K */
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ *
++ * PMEM
++ *
++ * This driver requires:
++ *
++ * Arbitrary Based Buffers:
++ * Persistent memory for diagnostics.
++ *
++ */
++ {
++ .name = "DiagPersistentMemory",
++ .start = 0x00000000,
++ .end = 0x10000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ *
++ * Smartcard
++ *
++ * This driver requires:
++ *
++ * Arbitrary Based Buffers:
++ * Read and write buffers for Internal/External cards
++ *
++ */
++ {
++ .name = "SmartCardInfo",
++ .start = 0x00000000,
++ .end = 0x2800 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * Add other resources here
++ */
++ { },
++};
++
++/*
++ * NON_DVR_CAPABLE ZEUS RESOURCES
++ */
++struct resource non_dvr_zeus_resources[] __initdata =
++{
++ /*
++ * VIDEO1 / LX1
++ */
++ {
++ .name = "ST231aImage", /* Delta-Mu 1 image and ram */
++ .start = 0x20000000,
++ .end = 0x201FFFFF, /* 2MiB */
++ .flags = IORESOURCE_IO,
++ },
++ {
++ .name = "ST231aMonitor", /* 8KiB block ST231a monitor */
++ .start = 0x20200000,
++ .end = 0x20201FFF,
++ .flags = IORESOURCE_IO,
++ },
++ {
++ .name = "MediaMemory1",
++ .start = 0x20202000,
++ .end = 0x21FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */
++ .flags = IORESOURCE_IO,
++ },
++ /*
++ * Sysaudio Driver
++ */
++ {
++ .name = "DSP_Image_Buff",
++ .start = 0x00000000,
++ .end = 0x000FFFFF,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "ADSC_CPU_PCM_Buff",
++ .start = 0x00000000,
++ .end = 0x00009FFF,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "ADSC_AUX_Buff",
++ .start = 0x00000000,
++ .end = 0x00003FFF,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "ADSC_Main_Buff",
++ .start = 0x00000000,
++ .end = 0x00003FFF,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * STAVEM driver/STAPI
++ */
++ {
++ .name = "AVMEMPartition0",
++ .start = 0x00000000,
++ .end = 0x00600000 - 1, /* 6 MB total */
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * DOCSIS Subsystem
++ */
++ {
++ .name = "Docsis",
++ .start = 0x40100000,
++ .end = 0x407fffff,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * GHW HAL Driver
++ */
++ {
++ .name = "GraphicsHeap",
++ .start = 0x46900000,
++ .end = 0x47700000 - 1, /* 14 MB total */
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * multi com buffer area
++ */
++ {
++ .name = "MulticomSHM",
++ .start = 0x47900000,
++ .end = 0x47920000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * DMA Ring buffer
++ */
++ {
++ .name = "BMM_Buffer",
++ .start = 0x00000000,
++ .end = 0x00280000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * Display bins buffer for unit0
++ */
++ {
++ .name = "DisplayBins0",
++ .start = 0x00000000,
++ .end = 0x00000FFF, /* 4 KB total */
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ *
++ * AVFS: player HAL memory
++ *
++ *
++ */
++ {
++ .name = "AvfsDmaMem",
++ .start = 0x00000000,
++ .end = 0x002c4c00 - 1, /* 945K * 3 for playback */
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * PMEM
++ */
++ {
++ .name = "DiagPersistentMemory",
++ .start = 0x00000000,
++ .end = 0x10000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * Smartcard
++ */
++ {
++ .name = "SmartCardInfo",
++ .start = 0x00000000,
++ .end = 0x2800 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * NAND Flash
++ */
++ {
++ .name = "NandFlash",
++ .start = NAND_FLASH_BASE,
++ .end = NAND_FLASH_BASE + 0x400 - 1,
++ .flags = IORESOURCE_IO,
++ },
++ /*
++ * Add other resources here
++ */
++ { },
++};
+diff --git a/arch/mips/powertv/cmdline.c b/arch/mips/powertv/cmdline.c
+new file mode 100644
+index 0000000..3bc4334
+--- /dev/null
++++ b/arch/mips/powertv/cmdline.c
+@@ -0,0 +1,52 @@
++/*
++ * Carsten Langgaard, carstenl@mips.com
++ * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
++ * Portions copyright (C) 2009 Cisco Systems, Inc.
++ *
++ * 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.
++ *
++ * Kernel command line creation using the prom monitor (YAMON) argc/argv.
++ */
++#include <linux/init.h>
++#include <linux/string.h>
++
++#include <asm/bootinfo.h>
++
++#include "init.h"
++
++/*
++ * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer.
++ * This macro take care of sign extension.
++ */
++#define prom_argv(index) ((char *)(long)_prom_argv[(index)])
++
++char * __init prom_getcmdline(void)
++{
++ return &(arcs_cmdline[0]);
++}
++
++void __init prom_init_cmdline(void)
++{
++ int len;
++
++ if (prom_argc != 1)
++ return;
++
++ len = strlen(arcs_cmdline);
++
++ arcs_cmdline[len] = ' ';
++
++ strlcpy(arcs_cmdline + len + 1, (char *)_prom_argv,
++ CL_SIZE - len - 1);
++}
+diff --git a/arch/mips/powertv/init.c b/arch/mips/powertv/init.c
+new file mode 100644
+index 0000000..5f4e4c3
+--- /dev/null
++++ b/arch/mips/powertv/init.c
+@@ -0,0 +1,128 @@
++/*
++ * Copyright (C) 1999, 2000, 2004, 2005 MIPS Technologies, Inc.
++ * All rights reserved.
++ * Authors: Carsten Langgaard <carstenl@mips.com>
++ * Maciej W. Rozycki <macro@mips.com>
++ * Portions copyright (C) 2009 Cisco Systems, Inc.
++ *
++ * 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.
++ *
++ * PROM library initialisation code.
++ */
++#include <linux/init.h>
++#include <linux/string.h>
++#include <linux/kernel.h>
++
++#include <asm/bootinfo.h>
++#include <linux/io.h>
++#include <asm/system.h>
++#include <asm/cacheflush.h>
++#include <asm/traps.h>
++
++#include <asm/mips-boards/prom.h>
++#include <asm/mips-boards/generic.h>
++#include <asm/mach-powertv/asic.h>
++
++#include "init.h"
++
++int prom_argc;
++int *_prom_argv, *_prom_envp;
++unsigned long _prom_memsize;
++
++/*
++ * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer.
++ * This macro take care of sign extension, if running in 64-bit mode.
++ */
++#define prom_envp(index) ((char *)(long)_prom_envp[(index)])
++
++char *prom_getenv(char *envname)
++{
++ char *result = NULL;
++
++ if (_prom_envp != NULL) {
++ /*
++ * Return a pointer to the given environment variable.
++ * In 64-bit mode: we're using 64-bit pointers, but all pointers
++ * in the PROM structures are only 32-bit, so we need some
++ * workarounds, if we are running in 64-bit mode.
++ */
++ int i, index = 0;
++
++ i = strlen(envname);
++
++ while (prom_envp(index)) {
++ if (strncmp(envname, prom_envp(index), i) == 0) {
++ result = prom_envp(index + 1);
++ break;
++ }
++ index += 2;
++ }
++ }
++
++ return result;
++}
++
++/* TODO: Verify on linux-mips mailing list that the following two */
++/* functions are correct */
++/* TODO: Copy NMI and EJTAG exception vectors to memory from the */
++/* BootROM exception vectors. Flush their cache entries. test it. */
++
++static void __init mips_nmi_setup(void)
++{
++ void *base;
++#if defined(CONFIG_CPU_MIPS32_R1)
++ base = cpu_has_veic ?
++ (void *)(CAC_BASE + 0xa80) :
++ (void *)(CAC_BASE + 0x380);
++#elif defined(CONFIG_CPU_MIPS32_R2)
++ base = (void *)0xbfc00000;
++#else
++#error NMI exception handler address not defined
++#endif
++}
++
++static void __init mips_ejtag_setup(void)
++{
++ void *base;
++
++#if defined(CONFIG_CPU_MIPS32_R1)
++ base = cpu_has_veic ?
++ (void *)(CAC_BASE + 0xa00) :
++ (void *)(CAC_BASE + 0x300);
++#elif defined(CONFIG_CPU_MIPS32_R2)
++ base = (void *)0xbfc00480;
++#else
++#error EJTAG exception handler address not defined
++#endif
++}
++
++void __init prom_init(void)
++{
++ prom_argc = fw_arg0;
++ _prom_argv = (int *) fw_arg1;
++ _prom_envp = (int *) fw_arg2;
++ _prom_memsize = (unsigned long) fw_arg3;
++
++ board_nmi_handler_setup = mips_nmi_setup;
++ board_ejtag_handler_setup = mips_ejtag_setup;
++
++ pr_info("\nLINUX started...\n");
++ prom_init_cmdline();
++ configure_platform();
++ prom_meminit();
++
++#ifndef CONFIG_BOOTLOADER_DRIVER
++ pr_info("\nBootloader driver isn't loaded...\n");
++#endif
++}
+diff --git a/arch/mips/powertv/init.h b/arch/mips/powertv/init.h
+new file mode 100644
+index 0000000..7af6bf2
+--- /dev/null
++++ b/arch/mips/powertv/init.h
+@@ -0,0 +1,28 @@
++/*
++ * Definitions from powertv init.c file
++ *
++ * Copyright (C) 2009 Cisco Systems, Inc.
++ *
++ * 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
++ *
++ * Author: David VomLehn
++ */
++
++#ifndef _POWERTV_INIT_H
++#define _POWERTV_INIT_H
++extern int prom_argc;
++extern int *_prom_argv;
++extern unsigned long _prom_memsize;
++#endif
+diff --git a/arch/mips/powertv/memory.c b/arch/mips/powertv/memory.c
+new file mode 100644
+index 0000000..c63620a
+--- /dev/null
++++ b/arch/mips/powertv/memory.c
+@@ -0,0 +1,186 @@
++/*
++ * Carsten Langgaard, carstenl@mips.com
++ * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
++ * Portions copyright (C) 2009 Cisco Systems, Inc.
++ *
++ * 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.
++ *
++ * Apparently originally from arch/mips/malta-memory.c. Modified to work
++ * with the PowerTV bootloader.
++ */
++#include <linux/init.h>
++#include <linux/mm.h>
++#include <linux/bootmem.h>
++#include <linux/pfn.h>
++#include <linux/string.h>
++
++#include <asm/bootinfo.h>
++#include <asm/page.h>
++#include <asm/sections.h>
++
++#include <asm/mips-boards/prom.h>
++
++#include "init.h"
++
++/* Memory constants */
++#define KIBIBYTE(n) ((n) * 1024) /* Number of kibibytes */
++#define MEBIBYTE(n) ((n) * KIBIBYTE(1024)) /* Number of mebibytes */
++#define DEFAULT_MEMSIZE MEBIBYTE(256) /* If no memsize provided */
++#define LOW_MEM_MAX MEBIBYTE(252) /* Max usable low mem */
++#define RES_BOOTLDR_MEMSIZE MEBIBYTE(1) /* Memory reserved for bldr */
++#define BOOT_MEM_SIZE KIBIBYTE(256) /* Memory reserved for bldr */
++#define PHYS_MEM_START 0x10000000 /* Start of physical memory */
++
++unsigned long ptv_memsize;
++
++char __initdata cmdline[CL_SIZE];
++
++void __init prom_meminit(void)
++{
++ char *memsize_str;
++ unsigned long memsize = 0;
++ unsigned int physend;
++ char *ptr;
++ int low_mem;
++ int high_mem;
++
++ /* Check the command line first for a memsize directive */
++ strcpy(cmdline, arcs_cmdline);
++ ptr = strstr(cmdline, "memsize=");
++ if (ptr && (ptr != cmdline) && (*(ptr - 1) != ' '))
++ ptr = strstr(ptr, " memsize=");
++
++ if (ptr) {
++ memsize = memparse(ptr + 8, &ptr);
++ } else {
++ /* otherwise look in the environment */
++ memsize_str = prom_getenv("memsize");
++
++ if (memsize_str != NULL) {
++ pr_info("prom memsize = %s\n", memsize_str);
++ memsize = simple_strtol(memsize_str, NULL, 0);
++ }
++
++ if (memsize == 0) {
++ if (_prom_memsize != 0) {
++ memsize = _prom_memsize;
++ pr_info("_prom_memsize = 0x%lx\n", memsize);
++ /* add in memory that the bootloader doesn't
++ * report */
++ memsize += BOOT_MEM_SIZE;
++ } else {
++ memsize = DEFAULT_MEMSIZE;
++ pr_info("Memsize not passed by bootloader, "
++ "defaulting to 0x%lx\n", memsize);
++ }
++ }
++ }
++
++ /* Store memsize for diagnostic purposes */
++ ptv_memsize = memsize;
++
++ physend = PFN_ALIGN(&_end) - 0x80000000;
++ if (memsize > LOW_MEM_MAX) {
++ low_mem = LOW_MEM_MAX;
++ high_mem = memsize - low_mem;
++ } else {
++ low_mem = memsize;
++ high_mem = 0;
++ }
++
++/*
++ * TODO: We will use the hard code for memory configuration until
++ * the bootloader releases their device tree to us.
++ */
++ /*
++ * Add the memory reserved for use by the bootloader to the
++ * memory map.
++ */
++ add_memory_region(PHYS_MEM_START, RES_BOOTLDR_MEMSIZE,
++ BOOT_MEM_RESERVED);
++#ifdef CONFIG_HIGHMEM_256_128
++ /*
++ * Add memory in low for general use by the kernel and its friends
++ * (like drivers, applications, etc).
++ */
++ add_memory_region(PHYS_MEM_START + RES_BOOTLDR_MEMSIZE,
++ LOW_MEM_MAX - RES_BOOTLDR_MEMSIZE, BOOT_MEM_RAM);
++ /*
++ * Add the memory reserved for reset vector.
++ */
++ add_memory_region(0x1fc00000, MEBIBYTE(4), BOOT_MEM_RESERVED);
++ /*
++ * Add the memory reserved.
++ */
++ add_memory_region(0x20000000, MEBIBYTE(1024 + 75), BOOT_MEM_RESERVED);
++ /*
++ * Add memory in high for general use by the kernel and its friends
++ * (like drivers, applications, etc).
++ *
++ * 75MB is reserved for devices which are using the memory in high.
++ */
++ add_memory_region(0x60000000 + MEBIBYTE(75), MEBIBYTE(128 - 75),
++ BOOT_MEM_RAM);
++#elif defined CONFIG_HIGHMEM_128_128
++ /*
++ * Add memory in low for general use by the kernel and its friends
++ * (like drivers, applications, etc).
++ */
++ add_memory_region(PHYS_MEM_START + RES_BOOTLDR_MEMSIZE,
++ MEBIBYTE(128) - RES_BOOTLDR_MEMSIZE, BOOT_MEM_RAM);
++ /*
++ * Add the memory reserved.
++ */
++ add_memory_region(PHYS_MEM_START + MEBIBYTE(128),
++ MEBIBYTE(128 + 1024 + 75), BOOT_MEM_RESERVED);
++ /*
++ * Add memory in high for general use by the kernel and its friends
++ * (like drivers, applications, etc).
++ *
++ * 75MB is reserved for devices which are using the memory in high.
++ */
++ add_memory_region(0x60000000 + MEBIBYTE(75), MEBIBYTE(128 - 75),
++ BOOT_MEM_RAM);
++#else
++ /* Add low memory regions for either:
++ * - no-highmemory configuration case -OR-
++ * - highmemory "HIGHMEM_LOWBANK_ONLY" case
++ */
++ /*
++ * Add memory for general use by the kernel and its friends
++ * (like drivers, applications, etc).
++ */
++ add_memory_region(PHYS_MEM_START + RES_BOOTLDR_MEMSIZE,
++ low_mem - RES_BOOTLDR_MEMSIZE, BOOT_MEM_RAM);
++ /*
++ * Add the memory reserved for reset vector.
++ */
++ add_memory_region(0x1fc00000, MEBIBYTE(4), BOOT_MEM_RESERVED);
++#endif
++}
++
++void __init prom_free_prom_memory(void)
++{
++ unsigned long addr;
++ int i;
++
++ for (i = 0; i < boot_mem_map.nr_map; i++) {
++ if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
++ continue;
++
++ addr = boot_mem_map.map[i].addr;
++ free_init_pages("prom memory",
++ addr, addr + boot_mem_map.map[i].size);
++ }
++}
+diff --git a/arch/mips/powertv/pci/Makefile b/arch/mips/powertv/pci/Makefile
+new file mode 100644
+index 0000000..f5c6246
+--- /dev/null
++++ b/arch/mips/powertv/pci/Makefile
+@@ -0,0 +1,21 @@
++#
++# Copyright (C) 2009 Scientific-Atlanta, Inc.
++#
++# 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
++#
++
++obj-$(CONFIG_PCI) += fixup-powertv.o
++
++EXTRA_CFLAGS += -Wall -Werror
+diff --git a/arch/mips/powertv/pci/fixup-powertv.c b/arch/mips/powertv/pci/fixup-powertv.c
+new file mode 100644
+index 0000000..726bc2e
+--- /dev/null
++++ b/arch/mips/powertv/pci/fixup-powertv.c
+@@ -0,0 +1,36 @@
++#include <linux/init.h>
++#include <linux/pci.h>
++#include <asm/mach-powertv/interrupts.h>
++#include "powertv-pci.h"
++
++int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
++{
++ return asic_pcie_map_irq(dev, slot, pin);
++}
++
++/* Do platform specific device initialization at pci_enable_device() time */
++int pcibios_plat_dev_init(struct pci_dev *dev)
++{
++ return 0;
++}
++
++/*
++ * asic_pcie_map_irq
++ *
++ * Parameters:
++ * *dev - pointer to a pci_dev structure (not used)
++ * slot - slot number (not used)
++ * pin - pin number (not used)
++ *
++ * Return Value:
++ * Returns: IRQ number (always the PCI Express IRQ number)
++ *
++ * Description:
++ * asic_pcie_map_irq will return the IRQ number of the PCI Express interrupt.
++ *
++ */
++int asic_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
++{
++ return irq_pciexp;
++}
++EXPORT_SYMBOL(asic_pcie_map_irq);
+diff --git a/arch/mips/powertv/pci/powertv-pci.h b/arch/mips/powertv/pci/powertv-pci.h
+new file mode 100644
+index 0000000..1b5886b
+--- /dev/null
++++ b/arch/mips/powertv/pci/powertv-pci.h
+@@ -0,0 +1,31 @@
++/*
++ * powertv-pci.c
++ *
++ * Copyright (C) 2009 Cisco Systems, Inc.
++ *
++ * 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
++ */
++/*
++ * Local definitions for the powertv PCI code
++ */
++
++#ifndef _POWERTV_PCI_POWERTV_PCI_H_
++#define _POWERTV_PCI_POWERTV_PCI_H_
++extern int asic_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin);
++extern int asic_pcie_init(void);
++extern int asic_pcie_init(void);
++
++extern int log_level;
++#endif
+diff --git a/arch/mips/powertv/powertv-clock.h b/arch/mips/powertv/powertv-clock.h
+new file mode 100644
+index 0000000..d94c543
+--- /dev/null
++++ b/arch/mips/powertv/powertv-clock.h
+@@ -0,0 +1,26 @@
++/*
++ * Copyright (C) 2009 Cisco Systems, Inc.
++ *
++ * 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
++ *
++ * Author: David VomLehn
++ */
++
++#ifndef _POWERTV_POWERTV_CLOCK_H
++#define _POWERTV_POWERTV_CLOCK_H
++extern int powertv_clockevent_init(void);
++extern void powertv_clocksource_init(void);
++extern unsigned int mips_get_pll_freq(void);
++#endif
+diff --git a/arch/mips/powertv/powertv_setup.c b/arch/mips/powertv/powertv_setup.c
+new file mode 100644
+index 0000000..bd8ebf1
+--- /dev/null
++++ b/arch/mips/powertv/powertv_setup.c
+@@ -0,0 +1,351 @@
++/*
++ * Carsten Langgaard, carstenl@mips.com
++ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
++ * Portions copyright (C) 2009 Cisco Systems, Inc.
++ *
++ * This program is free software; you can distribute it and/or modify it
++ * under the terms of the GNU General Public License (Version 2) as
++ * published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * for more details.
++ *
++ * You should have received a copy of the GNU General Public License along
++ * with this program; if not, write to the Free Software Foundation, Inc.,
++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
++ */
++#include <linux/init.h>
++#include <linux/sched.h>
++#include <linux/ioport.h>
++#include <linux/pci.h>
++#include <linux/screen_info.h>
++#include <linux/notifier.h>
++#include <linux/etherdevice.h>
++#include <linux/if_ether.h>
++#include <linux/ctype.h>
++
++#include <linux/cpu.h>
++#include <asm/bootinfo.h>
++#include <asm/irq.h>
++#include <asm/mips-boards/generic.h>
++#include <asm/mips-boards/prom.h>
++#include <asm/dma.h>
++#include <linux/time.h>
++#include <asm/traps.h>
++#include <asm/asm-offsets.h>
++#include "reset.h"
++
++#define VAL(n) STR(n)
++
++/*
++ * Macros for loading addresses and storing registers:
++ * PTR_LA Load the address into a register
++ * LONG_S Store the full width of the given register.
++ * LONG_L Load the full width of the given register
++ * PTR_ADDIU Add a constant value to a register used as a pointer
++ * REG_SIZE Number of 8-bit bytes in a full width register
++ */
++#ifdef CONFIG_64BIT
++#warning TODO: 64-bit code needs to be verified
++#define PTR_LA "dla "
++#define LONG_S "sd "
++#define LONG_L "ld "
++#define PTR_ADDIU "daddiu "
++#define REG_SIZE "8" /* In bytes */
++#endif
++
++#ifdef CONFIG_32BIT
++#define PTR_LA "la "
++#define LONG_S "sw "
++#define LONG_L "lw "
++#define PTR_ADDIU "addiu "
++#define REG_SIZE "4" /* In bytes */
++#endif
++
++static struct pt_regs die_regs;
++static bool have_die_regs;
++
++static void register_panic_notifier(void);
++static int panic_handler(struct notifier_block *notifier_block,
++ unsigned long event, void *cause_string);
++
++const char *get_system_type(void)
++{
++ return "PowerTV";
++}
++
++void __init plat_mem_setup(void)
++{
++ panic_on_oops = 1;
++ register_panic_notifier();
++
++#if 0
++ mips_pcibios_init();
++#endif
++ mips_reboot_setup();
++}
++
++/*
++ * Install a panic notifier for platform-specific diagnostics
++ */
++static void register_panic_notifier()
++{
++ static struct notifier_block panic_notifier = {
++ .notifier_call = panic_handler,
++ .next = NULL,
++ .priority = INT_MAX
++ };
++ atomic_notifier_chain_register(&panic_notifier_list, &panic_notifier);
++}
++
++static int panic_handler(struct notifier_block *notifier_block,
++ unsigned long event, void *cause_string)
++{
++ struct pt_regs my_regs;
++
++ /* Save all of the registers */
++ {
++ unsigned long at, v0, v1; /* Must be on the stack */
++
++ /* Start by saving $at and v0 on the stack. We use $at
++ * ourselves, but it looks like the compiler may use v0 or v1
++ * to load the address of the pt_regs structure. We'll come
++ * back later to store the registers in the pt_regs
++ * structure. */
++ __asm__ __volatile__ (
++ ".set noat\n"
++ LONG_S "$at, %[at]\n"
++ LONG_S "$2, %[v0]\n"
++ LONG_S "$3, %[v1]\n"
++ :
++ [at] "=m" (at),
++ [v0] "=m" (v0),
++ [v1] "=m" (v1)
++ :
++ : "at"
++ );
++
++ __asm__ __volatile__ (
++ ".set noat\n"
++ "move $at, %[pt_regs]\n"
++
++ /* Argument registers */
++ LONG_S "$4, " VAL(PT_R4) "($at)\n"
++ LONG_S "$5, " VAL(PT_R5) "($at)\n"
++ LONG_S "$6, " VAL(PT_R6) "($at)\n"
++ LONG_S "$7, " VAL(PT_R7) "($at)\n"
++
++ /* Temporary regs */
++ LONG_S "$8, " VAL(PT_R8) "($at)\n"
++ LONG_S "$9, " VAL(PT_R9) "($at)\n"
++ LONG_S "$10, " VAL(PT_R10) "($at)\n"
++ LONG_S "$11, " VAL(PT_R11) "($at)\n"
++ LONG_S "$12, " VAL(PT_R12) "($at)\n"
++ LONG_S "$13, " VAL(PT_R13) "($at)\n"
++ LONG_S "$14, " VAL(PT_R14) "($at)\n"
++ LONG_S "$15, " VAL(PT_R15) "($at)\n"
++
++ /* "Saved" registers */
++ LONG_S "$16, " VAL(PT_R16) "($at)\n"
++ LONG_S "$17, " VAL(PT_R17) "($at)\n"
++ LONG_S "$18, " VAL(PT_R18) "($at)\n"
++ LONG_S "$19, " VAL(PT_R19) "($at)\n"
++ LONG_S "$20, " VAL(PT_R20) "($at)\n"
++ LONG_S "$21, " VAL(PT_R21) "($at)\n"
++ LONG_S "$22, " VAL(PT_R22) "($at)\n"
++ LONG_S "$23, " VAL(PT_R23) "($at)\n"
++
++ /* Add'l temp regs */
++ LONG_S "$24, " VAL(PT_R24) "($at)\n"
++ LONG_S "$25, " VAL(PT_R25) "($at)\n"
++
++ /* Kernel temp regs */
++ LONG_S "$26, " VAL(PT_R26) "($at)\n"
++ LONG_S "$27, " VAL(PT_R27) "($at)\n"
++
++ /* Global pointer, stack pointer, frame pointer and
++ * return address */
++ LONG_S "$gp, " VAL(PT_R28) "($at)\n"
++ LONG_S "$sp, " VAL(PT_R29) "($at)\n"
++ LONG_S "$fp, " VAL(PT_R30) "($at)\n"
++ LONG_S "$ra, " VAL(PT_R31) "($at)\n"
++
++ /* Now we can get the $at and v0 registers back and
++ * store them */
++ LONG_L "$8, %[at]\n"
++ LONG_S "$8, " VAL(PT_R1) "($at)\n"
++ LONG_L "$8, %[v0]\n"
++ LONG_S "$8, " VAL(PT_R2) "($at)\n"
++ LONG_L "$8, %[v1]\n"
++ LONG_S "$8, " VAL(PT_R3) "($at)\n"
++ :
++ :
++ [at] "m" (at),
++ [v0] "m" (v0),
++ [v1] "m" (v1),
++ [pt_regs] "r" (&my_regs)
++ : "at", "t0"
++ );
++
++ /* Set the current EPC value to be the current location in this
++ * function */
++ __asm__ __volatile__ (
++ ".set noat\n"
++ "1:\n"
++ PTR_LA "$at, 1b\n"
++ LONG_S "$at, %[cp0_epc]\n"
++ :
++ [cp0_epc] "=m" (my_regs.cp0_epc)
++ :
++ : "at"
++ );
++
++ my_regs.cp0_cause = read_c0_cause();
++ my_regs.cp0_status = read_c0_status();
++ }
++
++#ifdef CONFIG_DIAGNOSTICS
++ failure_report((char *) cause_string,
++ have_die_regs ? &die_regs : &my_regs);
++ have_die_regs = false;
++#else
++ pr_crit("I'm feeling a bit sleepy. hmmmmm... perhaps a nap would... "
++ "zzzz... \n");
++#endif
++
++ return NOTIFY_DONE;
++}
++
++/**
++ * Platform-specific handling of oops
++ * @str: Pointer to the oops string
++ * @regs: Pointer to the oops registers
++ * All we do here is to save the registers for subsequent printing through
++ * the panic notifier.
++ */
++void platform_die(const char *str, const struct pt_regs *regs)
++{
++ /* If we already have saved registers, don't overwrite them as they
++ * they apply to the initial fault */
++
++ if (!have_die_regs) {
++ have_die_regs = true;
++ die_regs = *regs;
++ }
++}
++
++/* Information about the RF MAC address, if one was supplied on the
++ * command line. */
++static bool have_rfmac;
++static u8 rfmac[ETH_ALEN];
++
++static int rfmac_param(char *p)
++{
++ u8 *q;
++ bool is_high_nibble;
++ int c;
++
++ /* Skip a leading "0x", if present */
++ if (*p == '0' && *(p+1) == 'x')
++ p += 2;
++
++ q = rfmac;
++ is_high_nibble = true;
++
++ for (c = (unsigned char) *p++;
++ isxdigit(c) && q - rfmac < ETH_ALEN;
++ c = (unsigned char) *p++) {
++ int nibble;
++
++ nibble = (isdigit(c) ? (c - '0') :
++ (isupper(c) ? c - 'A' + 10 : c - 'a' + 10));
++
++ if (is_high_nibble)
++ *q = nibble << 4;
++ else
++ *q++ |= nibble;
++
++ is_high_nibble = !is_high_nibble;
++ }
++
++ /* If we parsed all the way to the end of the parameter value and
++ * parsed all ETH_ALEN bytes, we have a usable RF MAC address */
++ have_rfmac = (c == '\0' && q - rfmac == ETH_ALEN);
++
++ return 0;
++}
++
++early_param("rfmac", rfmac_param);
++
++/*
++ * Generate an Ethernet MAC address that has a good chance of being unique.
++ * @addr: Pointer to six-byte array containing the Ethernet address
++ * Generates an Ethernet MAC address that is highly likely to be unique for
++ * this particular system on a network with other systems of the same type.
++ *
++ * The problem we are solving is that, when random_ether_addr() is used to
++ * generate MAC addresses at startup, there isn't much entropy for the random
++ * number generator to use and the addresses it produces are fairly likely to
++ * be the same as those of other identical systems on the same local network.
++ * This is true even for relatively small numbers of systems (for the reason
++ * why, see the Wikipedia entry for "Birthday problem" at:
++ * http://en.wikipedia.org/wiki/Birthday_problem
++ *
++ * The good news is that we already have a MAC address known to be unique, the
++ * RF MAC address. The bad news is that this address is already in use on the
++ * RF interface. Worse, the obvious trick, taking the RF MAC address and
++ * turning on the locally managed bit, has already been used for other devices.
++ * Still, this does give us something to work with.
++ *
++ * The approach we take is:
++ * 1. If we can't get the RF MAC Address, just call random_ether_addr.
++ * 2. Use the 24-bit NIC-specific bits of the RF MAC address as the last 24
++ * bits of the new address. This is very likely to be unique, except for
++ * the current box.
++ * 3. To avoid using addresses already on the current box, we set the top
++ * six bits of the address with a value different from any currently
++ * registered Scientific Atlanta organizationally unique identifyer
++ * (OUI). This avoids duplication with any addresses on the system that
++ * were generated from valid Scientific Atlanta-registered address by
++ * simply flipping the locally managed bit.
++ * 4. We aren't generating a multicast address, so we leave the multicast
++ * bit off. Since we aren't using a registered address, we have to set
++ * the locally managed bit.
++ * 5. We then randomly generate the remaining 16-bits. This does two
++ * things:
++ * a. It allows us to call this function for more than one device
++ * in this system
++ * b. It ensures that things will probably still work even if
++ * some device on the device network has a locally managed
++ * address that matches the top six bits from step 2.
++ */
++void platform_random_ether_addr(u8 addr[ETH_ALEN])
++{
++ const int num_random_bytes = 2;
++ const unsigned char non_sciatl_oui_bits = 0xc0u;
++ const unsigned char mac_addr_locally_managed = (1 << 1);
++
++ if (!have_rfmac) {
++ pr_warning("rfmac not available on command line; "
++ "generating random MAC address\n");
++ random_ether_addr(addr);
++ }
++
++ else {
++ int i;
++
++ /* Set the first byte to something that won't match a Scientific
++ * Atlanta OUI, is locally managed, and isn't a multicast
++ * address */
++ addr[0] = non_sciatl_oui_bits | mac_addr_locally_managed;
++
++ /* Get some bytes of random address information */
++ get_random_bytes(&addr[1], num_random_bytes);
++
++ /* Copy over the NIC-specific bits of the RF MAC address */
++ for (i = 1 + num_random_bytes; i < ETH_ALEN; i++)
++ addr[i] = rfmac[i];
++ }
++}
+diff --git a/arch/mips/powertv/reset.c b/arch/mips/powertv/reset.c
+new file mode 100644
+index 0000000..494c652
+--- /dev/null
++++ b/arch/mips/powertv/reset.c
+@@ -0,0 +1,65 @@
++/*
++ * Carsten Langgaard, carstenl@mips.com
++ * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
++ * Portions copyright (C) 2009 Cisco Systems, Inc.
++ *
++ * This program is free software; you can distribute it and/or modify it
++ * under the terms of the GNU General Public License (Version 2) as
++ * published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * for more details.
++ *
++ * You should have received a copy of the GNU General Public License along
++ * with this program; if not, write to the Free Software Foundation, Inc.,
++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
++ */
++#include <linux/pm.h>
++
++#include <linux/io.h>
++#include <asm/reboot.h> /* Not included by linux/reboot.h */
++
++#ifdef CONFIG_BOOTLOADER_DRIVER
++#include <asm/mach-powertv/kbldr.h>
++#endif
++
++#include <asm/mach-powertv/asic_regs.h>
++#include "reset.h"
++
++static void mips_machine_restart(char *command);
++static void mips_machine_halt(void);
++
++static void mips_machine_restart(char *command)
++{
++#ifdef CONFIG_BOOTLOADER_DRIVER
++ /*
++ * Call the bootloader's reset function to ensure
++ * that persistent data is flushed before hard reset
++ */
++ kbldr_SetCauseAndReset();
++#else
++ writel(0x1, asic_reg_addr(watchdog));
++#endif
++}
++
++static void mips_machine_halt(void)
++{
++#ifdef CONFIG_BOOTLOADER_DRIVER
++ /*
++ * Call the bootloader's reset function to ensure
++ * that persistent data is flushed before hard reset
++ */
++ kbldr_SetCauseAndReset();
++#else
++ writel(0x1, asic_reg_addr(watchdog));
++#endif
++}
++
++void mips_reboot_setup(void)
++{
++ _machine_restart = mips_machine_restart;
++ _machine_halt = mips_machine_halt;
++ pm_power_off = mips_machine_halt;
++}
+diff --git a/arch/mips/powertv/reset.h b/arch/mips/powertv/reset.h
+new file mode 100644
+index 0000000..888fd09
+--- /dev/null
++++ b/arch/mips/powertv/reset.h
+@@ -0,0 +1,26 @@
++/*
++ * Definitions from powertv reset.c file
++ *
++ * Copyright (C) 2009 Cisco Systems, Inc.
++ *
++ * 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
++ *
++ * Author: David VomLehn
++ */
++
++#ifndef _POWERTV_POWERTV_RESET_H
++#define _POWERTV_POWERTV_RESET_H
++extern void mips_reboot_setup(void);
++#endif
+diff --git a/arch/mips/powertv/time.c b/arch/mips/powertv/time.c
+new file mode 100644
+index 0000000..1e0a5ef
+--- /dev/null
++++ b/arch/mips/powertv/time.c
+@@ -0,0 +1,37 @@
++/*
++ * Carsten Langgaard, carstenl@mips.com
++ * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
++ * Portions copyright (C) 2009 Cisco Systems, Inc.
++ *
++ * 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.
++ *
++ * Setting up the clock on the MIPS boards.
++ */
++
++#include <linux/init.h>
++#include <asm/mach-powertv/interrupts.h>
++#include <asm/time.h>
++
++#include "powertv-clock.h"
++
++unsigned int __cpuinit get_c0_compare_int(void)
++{
++ return irq_mips_timer;
++}
++
++void __init plat_time_init(void)
++{
++ powertv_clocksource_init();
++ r4k_clockevent_init();
++}
+diff --git a/arch/mips/rb532/prom.c b/arch/mips/rb532/prom.c
+index ad5bd10..f4f3f2e 100644
+--- a/arch/mips/rb532/prom.c
++++ b/arch/mips/rb532/prom.c
+@@ -115,7 +115,7 @@ void __init prom_setup_cmdline(void)
+ strcpy(cp, arcs_cmdline);
+ cp += strlen(arcs_cmdline);
+ }
+- cmd_line[CL_SIZE-1] = '\0';
++ cmd_line[COMMAND_LINE_SIZE-1] = '\0';
+
+ strcpy(arcs_cmdline, cmd_line);
+ }
+diff --git a/arch/mips/sgi-ip22/ip22-int.c b/arch/mips/sgi-ip22/ip22-int.c
+index 0ecd5fe..383f11d 100644
+--- a/arch/mips/sgi-ip22/ip22-int.c
++++ b/arch/mips/sgi-ip22/ip22-int.c
+@@ -13,6 +13,7 @@
+ #include <linux/init.h>
+ #include <linux/kernel_stat.h>
+ #include <linux/interrupt.h>
++#include <linux/ftrace.h>
+
+ #include <asm/irq_cpu.h>
+ #include <asm/sgi/hpc3.h>
+@@ -150,7 +151,7 @@ static void indy_local1_irqdispatch(void)
+
+ extern void ip22_be_interrupt(int irq);
+
+-static void indy_buserror_irq(void)
++static void __irq_entry indy_buserror_irq(void)
+ {
+ int irq = SGI_BUSERR_IRQ;
+
+diff --git a/arch/mips/sgi-ip22/ip22-time.c b/arch/mips/sgi-ip22/ip22-time.c
+index c8f7d23..603fc91 100644
+--- a/arch/mips/sgi-ip22/ip22-time.c
++++ b/arch/mips/sgi-ip22/ip22-time.c
+@@ -16,6 +16,7 @@
+ #include <linux/interrupt.h>
+ #include <linux/kernel_stat.h>
+ #include <linux/time.h>
++#include <linux/ftrace.h>
+
+ #include <asm/cpu.h>
+ #include <asm/mipsregs.h>
+@@ -115,7 +116,7 @@ __init void plat_time_init(void)
+ }
+
+ /* Generic SGI handler for (spurious) 8254 interrupts */
+-void indy_8254timer_irq(void)
++void __irq_entry indy_8254timer_irq(void)
+ {
+ int irq = SGI_8254_0_IRQ;
+ ULONG cnt;
+diff --git a/arch/mips/sibyte/common/cfe.c b/arch/mips/sibyte/common/cfe.c
+index eb5396c..6343011 100644
+--- a/arch/mips/sibyte/common/cfe.c
++++ b/arch/mips/sibyte/common/cfe.c
+@@ -287,7 +287,7 @@ void __init prom_init(void)
+ * boot console
+ */
+ cfe_cons_handle = cfe_getstdhandle(CFE_STDHANDLE_CONSOLE);
+- if (cfe_getenv("LINUX_CMDLINE", arcs_cmdline, CL_SIZE) < 0) {
++ if (cfe_getenv("LINUX_CMDLINE", arcs_cmdline, COMMAND_LINE_SIZE) < 0) {
+ if (argc >= 0) {
+ /* The loader should have set the command line */
+ /* too early for panic to do any good */
+@@ -318,7 +318,7 @@ void __init prom_init(void)
+ #endif /* CONFIG_BLK_DEV_INITRD */
+
+ /* Not sure this is needed, but it's the safe way. */
+- arcs_cmdline[CL_SIZE-1] = 0;
++ arcs_cmdline[COMMAND_LINE_SIZE-1] = 0;
+
+ prom_meminit();
+
+diff --git a/arch/mips/sni/a20r.c b/arch/mips/sni/a20r.c
+index 7dd76fb..e698089 100644
+--- a/arch/mips/sni/a20r.c
++++ b/arch/mips/sni/a20r.c
+@@ -188,7 +188,7 @@ static void end_a20r_irq(unsigned int irq)
+ }
+
+ static struct irq_chip a20r_irq_type = {
+- .typename = "A20R",
++ .name = "A20R",
+ .ack = mask_a20r_irq,
+ .mask = mask_a20r_irq,
+ .mask_ack = mask_a20r_irq,
+diff --git a/arch/mips/sni/pcimt.c b/arch/mips/sni/pcimt.c
+index 74e6c67..51e62bb 100644
+--- a/arch/mips/sni/pcimt.c
++++ b/arch/mips/sni/pcimt.c
+@@ -214,7 +214,7 @@ static void end_pcimt_irq(unsigned int irq)
+ }
+
+ static struct irq_chip pcimt_irq_type = {
+- .typename = "PCIMT",
++ .name = "PCIMT",
+ .ack = disable_pcimt_irq,
+ .mask = disable_pcimt_irq,
+ .mask_ack = disable_pcimt_irq,
+diff --git a/arch/mips/sni/pcit.c b/arch/mips/sni/pcit.c
+index 071a957..f4699d3 100644
+--- a/arch/mips/sni/pcit.c
++++ b/arch/mips/sni/pcit.c
+@@ -176,7 +176,7 @@ void end_pcit_irq(unsigned int irq)
+ }
+
+ static struct irq_chip pcit_irq_type = {
+- .typename = "PCIT",
++ .name = "PCIT",
+ .ack = disable_pcit_irq,
+ .mask = disable_pcit_irq,
+ .mask_ack = disable_pcit_irq,
+diff --git a/arch/mips/sni/rm200.c b/arch/mips/sni/rm200.c
+index 5e68781..46f0069 100644
+--- a/arch/mips/sni/rm200.c
++++ b/arch/mips/sni/rm200.c
+@@ -449,7 +449,7 @@ void end_rm200_irq(unsigned int irq)
+ }
+
+ static struct irq_chip rm200_irq_type = {
+- .typename = "RM200",
++ .name = "RM200",
+ .ack = disable_rm200_irq,
+ .mask = disable_rm200_irq,
+ .mask_ack = disable_rm200_irq,
+diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c
+index d66802e..06e801c 100644
+--- a/arch/mips/txx9/generic/setup.c
++++ b/arch/mips/txx9/generic/setup.c
+@@ -160,7 +160,7 @@ static void __init prom_init_cmdline(void)
+ int argc;
+ int *argv32;
+ int i; /* Always ignore the "-c" at argv[0] */
+- static char builtin[CL_SIZE] __initdata;
++ static char builtin[COMMAND_LINE_SIZE] __initdata;
+
+ if (fw_arg0 >= CKSEG0 || fw_arg1 < CKSEG0) {
+ /*
+@@ -315,7 +315,7 @@ static inline void txx9_cache_fixup(void)
+
+ static void __init preprocess_cmdline(void)
+ {
+- static char cmdline[CL_SIZE] __initdata;
++ static char cmdline[COMMAND_LINE_SIZE] __initdata;
+ char *s;
+
+ strcpy(cmdline, arcs_cmdline);
+diff --git a/drivers/ide/au1xxx-ide.c b/drivers/ide/au1xxx-ide.c
+index 58121bd..bcf4176 100644
+--- a/drivers/ide/au1xxx-ide.c
++++ b/drivers/ide/au1xxx-ide.c
+@@ -56,8 +56,8 @@ static inline void auide_insw(unsigned long port, void *addr, u32 count)
+ chan_tab_t *ctp;
+ au1x_ddma_desc_t *dp;
+
+- if(!put_dest_flags(ahwif->rx_chan, (void*)addr, count << 1,
+- DDMA_FLAGS_NOIE)) {
++ if (!au1xxx_dbdma_put_dest(ahwif->rx_chan, virt_to_phys(addr),
++ count << 1, DDMA_FLAGS_NOIE)) {
+ printk(KERN_ERR "%s failed %d\n", __func__, __LINE__);
+ return;
+ }
+@@ -74,8 +74,8 @@ static inline void auide_outsw(unsigned long port, void *addr, u32 count)
+ chan_tab_t *ctp;
+ au1x_ddma_desc_t *dp;
+
+- if(!put_source_flags(ahwif->tx_chan, (void*)addr,
+- count << 1, DDMA_FLAGS_NOIE)) {
++ if (!au1xxx_dbdma_put_source(ahwif->tx_chan, virt_to_phys(addr),
++ count << 1, DDMA_FLAGS_NOIE)) {
+ printk(KERN_ERR "%s failed %d\n", __func__, __LINE__);
+ return;
+ }
+@@ -246,17 +246,14 @@ static int auide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
+ flags = DDMA_FLAGS_NOIE;
+
+ if (iswrite) {
+- if(!put_source_flags(ahwif->tx_chan,
+- (void*) sg_virt(sg),
+- tc, flags)) {
++ if (!au1xxx_dbdma_put_source(ahwif->tx_chan,
++ sg_phys(sg), tc, flags)) {
+ printk(KERN_ERR "%s failed %d\n",
+ __func__, __LINE__);
+ }
+- } else
+- {
+- if(!put_dest_flags(ahwif->rx_chan,
+- (void*) sg_virt(sg),
+- tc, flags)) {
++ } else {
++ if (!au1xxx_dbdma_put_dest(ahwif->rx_chan,
++ sg_phys(sg), tc, flags)) {
+ printk(KERN_ERR "%s failed %d\n",
+ __func__, __LINE__);
+ }
+diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
+index 222c1ef..c8a4456 100644
+--- a/drivers/ide/ide-iops.c
++++ b/drivers/ide/ide-iops.c
+@@ -27,6 +27,8 @@
+ #include <asm/uaccess.h>
+ #include <asm/io.h>
+
++#include <asm/bootinfo.h>
++
+ void SELECT_MASK(ide_drive_t *drive, int mask)
+ {
+ const struct ide_port_ops *port_ops = drive->hwif->port_ops;
+@@ -300,6 +302,9 @@ void ide_check_nien_quirk_list(ide_drive_t *drive)
+ {
+ const char **list, *m = (char *)&drive->id[ATA_ID_PROD];
+
++ if (mips_machtype != MACH_LEMOTE_YL2F89)
++ return;
++
+ for (list = nien_quirk_list; *list != NULL; list++)
+ if (strstr(m, *list) != NULL) {
+ drive->dev_flags |= IDE_DFLAG_NIEN_QUIRK;
+diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c
+index d3f5561..c8649df 100644
+--- a/drivers/mmc/host/au1xmmc.c
++++ b/drivers/mmc/host/au1xmmc.c
+@@ -650,11 +650,11 @@ static int au1xmmc_prepare_data(struct au1xmmc_host *host,
+ flags = DDMA_FLAGS_IE;
+
+ if (host->flags & HOST_F_XMIT) {
+- ret = au1xxx_dbdma_put_source_flags(channel,
+- (void *)sg_virt(sg), len, flags);
++ ret = au1xxx_dbdma_put_source(channel,
++ sg_phys(sg), len, flags);
+ } else {
+- ret = au1xxx_dbdma_put_dest_flags(channel,
+- (void *)sg_virt(sg), len, flags);
++ ret = au1xxx_dbdma_put_dest(channel,
++ sg_phys(sg), len, flags);
+ }
+
+ if (!ret)
+diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
+index 14be075..e992b83 100644
+--- a/drivers/mtd/maps/Kconfig
++++ b/drivers/mtd/maps/Kconfig
+@@ -253,12 +253,6 @@ config MTD_NETtel
+ help
+ Support for flash chips on NETtel/SecureEdge/SnapGear boards.
+
+-config MTD_ALCHEMY
+- tristate "AMD Alchemy Pb1xxx/Db1xxx/RDK MTD support"
+- depends on SOC_AU1X00 && MTD_PARTITIONS && MTD_CFI
+- help
+- Flash memory access on AMD Alchemy Pb/Db/RDK Reference Boards
+-
+ config MTD_DILNETPC
+ tristate "CFI Flash device mapped on DIL/Net PC"
+ depends on X86 && MTD_CONCAT && MTD_PARTITIONS && MTD_CFI_INTELEXT && BROKEN
+diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
+index ae2f6db..74226d9 100644
+--- a/drivers/mtd/maps/Makefile
++++ b/drivers/mtd/maps/Makefile
+@@ -40,7 +40,6 @@ obj-$(CONFIG_MTD_SCx200_DOCFLASH)+= scx200_docflash.o
+ obj-$(CONFIG_MTD_DBOX2) += dbox2-flash.o
+ obj-$(CONFIG_MTD_SOLUTIONENGINE)+= solutionengine.o
+ obj-$(CONFIG_MTD_PCI) += pci.o
+-obj-$(CONFIG_MTD_ALCHEMY) += alchemy-flash.o
+ obj-$(CONFIG_MTD_AUTCPU12) += autcpu12-nvram.o
+ obj-$(CONFIG_MTD_EDB7312) += edb7312.o
+ obj-$(CONFIG_MTD_IMPA7) += impa7.o
+diff --git a/drivers/mtd/maps/alchemy-flash.c b/drivers/mtd/maps/alchemy-flash.c
+deleted file mode 100644
+index 845ad4f..0000000
+--- a/drivers/mtd/maps/alchemy-flash.c
++++ /dev/null
+@@ -1,166 +0,0 @@
+-/*
+- * Flash memory access on AMD Alchemy evaluation boards
+- *
+- * (C) 2003, 2004 Pete Popov <ppopov@embeddedalley.com>
+- */
+-
+-#include <linux/init.h>
+-#include <linux/module.h>
+-#include <linux/types.h>
+-#include <linux/kernel.h>
+-
+-#include <linux/mtd/mtd.h>
+-#include <linux/mtd/map.h>
+-#include <linux/mtd/partitions.h>
+-
+-#include <asm/io.h>
+-
+-#ifdef CONFIG_MIPS_PB1000
+-#define BOARD_MAP_NAME "Pb1000 Flash"
+-#define BOARD_FLASH_SIZE 0x00800000 /* 8MB */
+-#define BOARD_FLASH_WIDTH 4 /* 32-bits */
+-#endif
+-
+-#ifdef CONFIG_MIPS_PB1500
+-#define BOARD_MAP_NAME "Pb1500 Flash"
+-#define BOARD_FLASH_SIZE 0x04000000 /* 64MB */
+-#define BOARD_FLASH_WIDTH 4 /* 32-bits */
+-#endif
+-
+-#ifdef CONFIG_MIPS_PB1100
+-#define BOARD_MAP_NAME "Pb1100 Flash"
+-#define BOARD_FLASH_SIZE 0x04000000 /* 64MB */
+-#define BOARD_FLASH_WIDTH 4 /* 32-bits */
+-#endif
+-
+-#ifdef CONFIG_MIPS_PB1550
+-#define BOARD_MAP_NAME "Pb1550 Flash"
+-#define BOARD_FLASH_SIZE 0x08000000 /* 128MB */
+-#define BOARD_FLASH_WIDTH 4 /* 32-bits */
+-#endif
+-
+-#ifdef CONFIG_MIPS_PB1200
+-#define BOARD_MAP_NAME "Pb1200 Flash"
+-#define BOARD_FLASH_SIZE 0x08000000 /* 128MB */
+-#define BOARD_FLASH_WIDTH 2 /* 16-bits */
+-#endif
+-
+-#ifdef CONFIG_MIPS_DB1000
+-#define BOARD_MAP_NAME "Db1000 Flash"
+-#define BOARD_FLASH_SIZE 0x02000000 /* 32MB */
+-#define BOARD_FLASH_WIDTH 4 /* 32-bits */
+-#endif
+-
+-#ifdef CONFIG_MIPS_DB1500
+-#define BOARD_MAP_NAME "Db1500 Flash"
+-#define BOARD_FLASH_SIZE 0x02000000 /* 32MB */
+-#define BOARD_FLASH_WIDTH 4 /* 32-bits */
+-#endif
+-
+-#ifdef CONFIG_MIPS_DB1100
+-#define BOARD_MAP_NAME "Db1100 Flash"
+-#define BOARD_FLASH_SIZE 0x02000000 /* 32MB */
+-#define BOARD_FLASH_WIDTH 4 /* 32-bits */
+-#endif
+-
+-#ifdef CONFIG_MIPS_DB1550
+-#define BOARD_MAP_NAME "Db1550 Flash"
+-#define BOARD_FLASH_SIZE 0x08000000 /* 128MB */
+-#define BOARD_FLASH_WIDTH 4 /* 32-bits */
+-#endif
+-
+-#ifdef CONFIG_MIPS_DB1200
+-#define BOARD_MAP_NAME "Db1200 Flash"
+-#define BOARD_FLASH_SIZE 0x04000000 /* 64MB */
+-#define BOARD_FLASH_WIDTH 2 /* 16-bits */
+-#endif
+-
+-#ifdef CONFIG_MIPS_BOSPORUS
+-#define BOARD_MAP_NAME "Bosporus Flash"
+-#define BOARD_FLASH_SIZE 0x01000000 /* 16MB */
+-#define BOARD_FLASH_WIDTH 2 /* 16-bits */
+-#endif
+-
+-#ifdef CONFIG_MIPS_MIRAGE
+-#define BOARD_MAP_NAME "Mirage Flash"
+-#define BOARD_FLASH_SIZE 0x04000000 /* 64MB */
+-#define BOARD_FLASH_WIDTH 4 /* 32-bits */
+-#define USE_LOCAL_ACCESSORS /* why? */
+-#endif
+-
+-static struct map_info alchemy_map = {
+- .name = BOARD_MAP_NAME,
+-};
+-
+-static struct mtd_partition alchemy_partitions[] = {
+- {
+- .name = "User FS",
+- .size = BOARD_FLASH_SIZE - 0x00400000,
+- .offset = 0x0000000
+- },{
+- .name = "YAMON",
+- .size = 0x0100000,
+- .offset = MTDPART_OFS_APPEND,
+- .mask_flags = MTD_WRITEABLE
+- },{
+- .name = "raw kernel",
+- .size = (0x300000 - 0x40000), /* last 256KB is yamon env */
+- .offset = MTDPART_OFS_APPEND,
+- }
+-};
+-
+-static struct mtd_info *mymtd;
+-
+-static int __init alchemy_mtd_init(void)
+-{
+- struct mtd_partition *parts;
+- int nb_parts = 0;
+- unsigned long window_addr;
+- unsigned long window_size;
+-
+- /* Default flash buswidth */
+- alchemy_map.bankwidth = BOARD_FLASH_WIDTH;
+-
+- window_addr = 0x20000000 - BOARD_FLASH_SIZE;
+- window_size = BOARD_FLASH_SIZE;
+-
+- /*
+- * Static partition definition selection
+- */
+- parts = alchemy_partitions;
+- nb_parts = ARRAY_SIZE(alchemy_partitions);
+- alchemy_map.size = window_size;
+-
+- /*
+- * Now let's probe for the actual flash. Do it here since
+- * specific machine settings might have been set above.
+- */
+- printk(KERN_NOTICE BOARD_MAP_NAME ": probing %d-bit flash bus\n",
+- alchemy_map.bankwidth*8);
+- alchemy_map.virt = ioremap(window_addr, window_size);
+- mymtd = do_map_probe("cfi_probe", &alchemy_map);
+- if (!mymtd) {
+- iounmap(alchemy_map.virt);
+- return -ENXIO;
+- }
+- mymtd->owner = THIS_MODULE;
+-
+- add_mtd_partitions(mymtd, parts, nb_parts);
+- return 0;
+-}
+-
+-static void __exit alchemy_mtd_cleanup(void)
+-{
+- if (mymtd) {
+- del_mtd_partitions(mymtd);
+- map_destroy(mymtd);
+- iounmap(alchemy_map.virt);
+- }
+-}
+-
+-module_init(alchemy_mtd_init);
+-module_exit(alchemy_mtd_cleanup);
+-
+-MODULE_AUTHOR("Embedded Alley Solutions, Inc");
+-MODULE_DESCRIPTION(BOARD_MAP_NAME " MTD driver");
+-MODULE_LICENSE("GPL");
+diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c
+index 92c334f..43d46e4 100644
+--- a/drivers/mtd/nand/au1550nd.c
++++ b/drivers/mtd/nand/au1550nd.c
+@@ -19,6 +19,7 @@
+ #include <asm/io.h>
+
+ #include <asm/mach-au1x00/au1xxx.h>
++#include <asm/mach-db1x00/bcsr.h>
+
+ /*
+ * MTD structure for NAND controller
+@@ -475,7 +476,8 @@ static int __init au1xxx_nand_init(void)
+ /* set gpio206 high */
+ au_writel(au_readl(GPIO2_DIR) & ~(1 << 6), GPIO2_DIR);
+
+- boot_swapboot = (au_readl(MEM_STSTAT) & (0x7 << 1)) | ((bcsr->status >> 6) & 0x1);
++ boot_swapboot = (au_readl(MEM_STSTAT) & (0x7 << 1)) | ((bcsr_read(BCSR_STATUS) >> 6) & 0x1);
++
+ switch (boot_swapboot) {
+ case 0:
+ case 2:
+diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
+index b2f71f7..357b569 100644
+--- a/drivers/net/Kconfig
++++ b/drivers/net/Kconfig
+@@ -1953,6 +1953,8 @@ config BCM63XX_ENET
+
+ source "drivers/net/fs_enet/Kconfig"
+
++source "drivers/net/octeon/Kconfig"
++
+ endif # NET_ETHERNET
+
+ #
+@@ -2409,6 +2411,13 @@ config MV643XX_ETH
+ Some boards that use the Discovery chipset are the Momenco
+ Ocelot C and Jaguar ATX and Pegasos II.
+
++config TITAN_GE
++ bool "PMC-Sierra TITAN Gigabit Ethernet Support"
++ depends on PMC_YOSEMITE
++ help
++ This enables support for the the integrated ethernet of
++ PMC-Sierra's Titan SoC.
++
+ config XILINX_LL_TEMAC
+ tristate "Xilinx LL TEMAC (LocalLink Tri-mode Ethernet MAC) driver"
+ select PHYLIB
+diff --git a/drivers/net/Makefile b/drivers/net/Makefile
+index 246323d..657ccc3 100644
+--- a/drivers/net/Makefile
++++ b/drivers/net/Makefile
+@@ -150,6 +150,8 @@ obj-$(CONFIG_XILINX_EMACLITE) += xilinx_emaclite.o
+ obj-$(CONFIG_QLA3XXX) += qla3xxx.o
+ obj-$(CONFIG_QLGE) += qlge/
+
++obj-$(CONFIG_TITAN_GE) += titan_mdio.o titan_ge.o
++
+ obj-$(CONFIG_PPP) += ppp_generic.o
+ obj-$(CONFIG_PPP_ASYNC) += ppp_async.o
+ obj-$(CONFIG_PPP_SYNC_TTY) += ppp_synctty.o
+@@ -285,3 +287,5 @@ obj-$(CONFIG_VIRTIO_NET) += virtio_net.o
+ obj-$(CONFIG_SFC) += sfc/
+
+ obj-$(CONFIG_WIMAX) += wimax/
++
++obj-$(CONFIG_OCTEON_MGMT_ETHERNET) += octeon/
+diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
+index 3f4b430..bb2f67f 100644
+--- a/drivers/net/au1000_eth.c
++++ b/drivers/net/au1000_eth.c
+@@ -55,6 +55,7 @@
+ #include <linux/delay.h>
+ #include <linux/crc32.h>
+ #include <linux/phy.h>
++#include <linux/platform_device.h>
+
+ #include <asm/cpu.h>
+ #include <asm/mipsregs.h>
+@@ -63,6 +64,7 @@
+ #include <asm/processor.h>
+
+ #include <au1000.h>
++#include <au1xxx_eth.h>
+ #include <prom.h>
+
+ #include "au1000_eth.h"
+@@ -112,15 +114,15 @@ struct au1000_private *au_macs[NUM_ETH_INTERFACES];
+ *
+ * PHY detection algorithm
+ *
+- * If AU1XXX_PHY_STATIC_CONFIG is undefined, the PHY setup is
++ * If phy_static_config is undefined, the PHY setup is
+ * autodetected:
+ *
+ * mii_probe() first searches the current MAC's MII bus for a PHY,
+- * selecting the first (or last, if AU1XXX_PHY_SEARCH_HIGHEST_ADDR is
++ * selecting the first (or last, if phy_search_highest_addr is
+ * defined) PHY address not already claimed by another netdev.
+ *
+ * If nothing was found that way when searching for the 2nd ethernet
+- * controller's PHY and AU1XXX_PHY1_SEARCH_ON_MAC0 is defined, then
++ * controller's PHY and phy1_search_mac0 is defined, then
+ * the first MII bus is searched as well for an unclaimed PHY; this is
+ * needed in case of a dual-PHY accessible only through the MAC0's MII
+ * bus.
+@@ -129,9 +131,7 @@ struct au1000_private *au_macs[NUM_ETH_INTERFACES];
+ * controller is not registered to the network subsystem.
+ */
+
+-/* autodetection defaults */
+-#undef AU1XXX_PHY_SEARCH_HIGHEST_ADDR
+-#define AU1XXX_PHY1_SEARCH_ON_MAC0
++/* autodetection defaults: phy1_search_mac0 */
+
+ /* static PHY setup
+ *
+@@ -148,29 +148,6 @@ struct au1000_private *au_macs[NUM_ETH_INTERFACES];
+ * specific irq-map
+ */
+
+-#if defined(CONFIG_MIPS_BOSPORUS)
+-/*
+- * Micrel/Kendin 5 port switch attached to MAC0,
+- * MAC0 is associated with PHY address 5 (== WAN port)
+- * MAC1 is not associated with any PHY, since it's connected directly
+- * to the switch.
+- * no interrupts are used
+- */
+-# define AU1XXX_PHY_STATIC_CONFIG
+-
+-# define AU1XXX_PHY0_ADDR 5
+-# define AU1XXX_PHY0_BUSID 0
+-# undef AU1XXX_PHY0_IRQ
+-
+-# undef AU1XXX_PHY1_ADDR
+-# undef AU1XXX_PHY1_BUSID
+-# undef AU1XXX_PHY1_IRQ
+-#endif
+-
+-#if defined(AU1XXX_PHY0_BUSID) && (AU1XXX_PHY0_BUSID > 0)
+-# error MAC0-associated PHY attached 2nd MACs MII bus not supported yet
+-#endif
+-
+ static void enable_mac(struct net_device *dev, int force_reset)
+ {
+ unsigned long flags;
+@@ -390,67 +367,54 @@ static int mii_probe (struct net_device *dev)
+ struct au1000_private *const aup = netdev_priv(dev);
+ struct phy_device *phydev = NULL;
+
+-#if defined(AU1XXX_PHY_STATIC_CONFIG)
+- BUG_ON(aup->mac_id < 0 || aup->mac_id > 1);
++ if (aup->phy_static_config) {
++ BUG_ON(aup->mac_id < 0 || aup->mac_id > 1);
+
+- if(aup->mac_id == 0) { /* get PHY0 */
+-# if defined(AU1XXX_PHY0_ADDR)
+- phydev = au_macs[AU1XXX_PHY0_BUSID]->mii_bus->phy_map[AU1XXX_PHY0_ADDR];
+-# else
+- printk (KERN_INFO DRV_NAME ":%s: using PHY-less setup\n",
+- dev->name);
+- return 0;
+-# endif /* defined(AU1XXX_PHY0_ADDR) */
+- } else if (aup->mac_id == 1) { /* get PHY1 */
+-# if defined(AU1XXX_PHY1_ADDR)
+- phydev = au_macs[AU1XXX_PHY1_BUSID]->mii_bus->phy_map[AU1XXX_PHY1_ADDR];
+-# else
+- printk (KERN_INFO DRV_NAME ":%s: using PHY-less setup\n",
+- dev->name);
++ if (aup->phy_addr)
++ phydev = aup->mii_bus->phy_map[aup->phy_addr];
++ else
++ printk (KERN_INFO DRV_NAME ":%s: using PHY-less setup\n",
++ dev->name);
+ return 0;
+-# endif /* defined(AU1XXX_PHY1_ADDR) */
+- }
+-
+-#else /* defined(AU1XXX_PHY_STATIC_CONFIG) */
+- int phy_addr;
+-
+- /* find the first (lowest address) PHY on the current MAC's MII bus */
+- for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++)
+- if (aup->mii_bus->phy_map[phy_addr]) {
+- phydev = aup->mii_bus->phy_map[phy_addr];
+-# if !defined(AU1XXX_PHY_SEARCH_HIGHEST_ADDR)
+- break; /* break out with first one found */
+-# endif
+- }
+-
+-# if defined(AU1XXX_PHY1_SEARCH_ON_MAC0)
+- /* try harder to find a PHY */
+- if (!phydev && (aup->mac_id == 1)) {
+- /* no PHY found, maybe we have a dual PHY? */
+- printk (KERN_INFO DRV_NAME ": no PHY found on MAC1, "
+- "let's see if it's attached to MAC0...\n");
+-
+- BUG_ON(!au_macs[0]);
+-
+- /* find the first (lowest address) non-attached PHY on
+- * the MAC0 MII bus */
+- for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
+- struct phy_device *const tmp_phydev =
+- au_macs[0]->mii_bus->phy_map[phy_addr];
+-
+- if (!tmp_phydev)
+- continue; /* no PHY here... */
+-
+- if (tmp_phydev->attached_dev)
+- continue; /* already claimed by MAC0 */
++ } else {
++ int phy_addr;
++
++ /* find the first (lowest address) PHY on the current MAC's MII bus */
++ for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++)
++ if (aup->mii_bus->phy_map[phy_addr]) {
++ phydev = aup->mii_bus->phy_map[phy_addr];
++ if (!aup->phy_search_highest_addr)
++ break; /* break out with first one found */
++ }
+
+- phydev = tmp_phydev;
+- break; /* found it */
++ if (aup->phy1_search_mac0) {
++ /* try harder to find a PHY */
++ if (!phydev && (aup->mac_id == 1)) {
++ /* no PHY found, maybe we have a dual PHY? */
++ printk (KERN_INFO DRV_NAME ": no PHY found on MAC1, "
++ "let's see if it's attached to MAC0...\n");
++
++ /* find the first (lowest address) non-attached PHY on
++ * the MAC0 MII bus */
++ for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
++ if (aup->mac_id == 1)
++ break;
++ struct phy_device *const tmp_phydev =
++ aup->mii_bus->phy_map[phy_addr];
++
++ if (!tmp_phydev)
++ continue; /* no PHY here... */
++
++ if (tmp_phydev->attached_dev)
++ continue; /* already claimed by MAC0 */
++
++ phydev = tmp_phydev;
++ break; /* found it */
++ }
++ }
+ }
+ }
+-# endif /* defined(AU1XXX_PHY1_SEARCH_OTHER_BUS) */
+
+-#endif /* defined(AU1XXX_PHY_STATIC_CONFIG) */
+ if (!phydev) {
+ printk (KERN_ERR DRV_NAME ":%s: no PHY found\n", dev->name);
+ return -1;
+@@ -578,31 +542,6 @@ setup_hw_rings(struct au1000_private *aup, u32 rx_base, u32 tx_base)
+ }
+ }
+
+-static struct {
+- u32 base_addr;
+- u32 macen_addr;
+- int irq;
+- struct net_device *dev;
+-} iflist[2] = {
+-#ifdef CONFIG_SOC_AU1000
+- {AU1000_ETH0_BASE, AU1000_MAC0_ENABLE, AU1000_MAC0_DMA_INT},
+- {AU1000_ETH1_BASE, AU1000_MAC1_ENABLE, AU1000_MAC1_DMA_INT}
+-#endif
+-#ifdef CONFIG_SOC_AU1100
+- {AU1100_ETH0_BASE, AU1100_MAC0_ENABLE, AU1100_MAC0_DMA_INT}
+-#endif
+-#ifdef CONFIG_SOC_AU1500
+- {AU1500_ETH0_BASE, AU1500_MAC0_ENABLE, AU1500_MAC0_DMA_INT},
+- {AU1500_ETH1_BASE, AU1500_MAC1_ENABLE, AU1500_MAC1_DMA_INT}
+-#endif
+-#ifdef CONFIG_SOC_AU1550
+- {AU1550_ETH0_BASE, AU1550_MAC0_ENABLE, AU1550_MAC0_DMA_INT},
+- {AU1550_ETH1_BASE, AU1550_MAC1_ENABLE, AU1550_MAC1_DMA_INT}
+-#endif
+-};
+-
+-static int num_ifs;
+-
+ /*
+ * ethtool operations
+ */
+@@ -1058,34 +997,55 @@ static const struct net_device_ops au1000_netdev_ops = {
+ .ndo_change_mtu = eth_change_mtu,
+ };
+
+-static struct net_device * au1000_probe(int port_num)
++static int __devinit au1000_probe(struct platform_device *pdev)
+ {
+ static unsigned version_printed = 0;
+ struct au1000_private *aup = NULL;
++ struct au1000_eth_platform_data *pd;
+ struct net_device *dev = NULL;
+ db_dest_t *pDB, *pDBfree;
+- char ethaddr[6];
+- int irq, i, err;
+- u32 base, macen;
++ int irq, i, err = 0;
++ struct resource *base, *macen;
++ DECLARE_MAC_BUF(ethaddr);
++
++ base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (!base) {
++ printk(KERN_ERR DRV_NAME ": failed to retrieve base register\n");
++ err = -ENODEV;
++ goto out;
++ }
+
+- if (port_num >= NUM_ETH_INTERFACES)
+- return NULL;
++ macen = platform_get_resource(pdev, IORESOURCE_MEM, 1);
++ if (!macen) {
++ printk(KERN_ERR DRV_NAME ": failed to retrieve MAC Enable register\n");
++ err = -ENODEV;
++ goto out;
++ }
+
+- base = CPHYSADDR(iflist[port_num].base_addr );
+- macen = CPHYSADDR(iflist[port_num].macen_addr);
+- irq = iflist[port_num].irq;
++ irq = platform_get_irq(pdev, 0);
++ if (irq < 0) {
++ printk(KERN_ERR DRV_NAME ": failed to retrieve IRQ\n");
++ err = -ENODEV;
++ goto out;
++ }
+
+- if (!request_mem_region( base, MAC_IOSIZE, "Au1x00 ENET") ||
+- !request_mem_region(macen, 4, "Au1x00 ENET"))
+- return NULL;
++ if (!request_mem_region(base->start, resource_size(base), pdev->name)) {
++ printk(KERN_ERR DRV_NAME ": failed to request memory region for base registers\n");
++ err = -ENXIO;
++ goto out;
++ }
+
+- if (version_printed++ == 0)
+- printk("%s version %s %s\n", DRV_NAME, DRV_VERSION, DRV_AUTHOR);
++ if (!request_mem_region(macen->start, resource_size(macen), pdev->name)) {
++ printk(KERN_ERR DRV_NAME ": failed to request memory region for MAC enable register\n");
++ err = -ENXIO;
++ goto err_request;
++ }
+
+ dev = alloc_etherdev(sizeof(struct au1000_private));
+ if (!dev) {
+ printk(KERN_ERR "%s: alloc_etherdev failed\n", DRV_NAME);
+- return NULL;
++ err = -ENOMEM;
++ goto err_alloc;
+ }
+
+ dev->base_addr = base;
+@@ -1115,21 +1075,29 @@ static struct net_device * au1000_probe(int port_num)
+ (NUM_TX_BUFFS + NUM_RX_BUFFS),
+ &aup->dma_addr, 0);
+ if (!aup->vaddr) {
+- free_netdev(dev);
+- release_mem_region( base, MAC_IOSIZE);
+- release_mem_region(macen, 4);
+- return NULL;
++ printk(KERN_ERR DRV_NAME ": failed to allocate data buffers\n");
++ err = -ENOMEM;
++ goto err_vaddr;
+ }
+
+ /* aup->mac is the base address of the MAC's registers */
+- aup->mac = (volatile mac_reg_t *)iflist[port_num].base_addr;
++ aup->mac = (volatile mac_reg_t *)ioremap_nocache(base->start, resource_size(base));
++ if (!aup->mac) {
++ printk(KERN_ERR DRV_NAME ": failed to ioremap MAC registers\n");
++ err = -ENXIO;
++ goto err_remap1;
++ }
+
+- /* Setup some variables for quick register address access */
+- aup->enable = (volatile u32 *)iflist[port_num].macen_addr;
+- aup->mac_id = port_num;
+- au_macs[port_num] = aup;
++ /* Setup some variables for quick register address access */
++ aup->enable = (volatile u32 *)ioremap_nocache(macen->start, resource_size(macen));
++ if (!aup->enable) {
++ printk(KERN_ERR DRV_NAME ": failed to ioremap MAC enable register\n");
++ err = -ENXIO;
++ goto err_remap2;
++ }
++ aup->mac_id = pdev->id;
+
+- if (port_num == 0) {
++ if (pdev->id == 0) {
+ if (prom_get_ethernet_addr(ethaddr) == 0)
+ memcpy(au1000_mac_addr, ethaddr, sizeof(au1000_mac_addr));
+ else {
+@@ -1139,7 +1107,7 @@ static struct net_device * au1000_probe(int port_num)
+ }
+
+ setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR);
+- } else if (port_num == 1)
++ } else if (pdev->id == 1)
+ setup_hw_rings(aup, MAC1_RX_DMA_ADDR, MAC1_TX_DMA_ADDR);
+
+ /*
+@@ -1147,14 +1115,37 @@ static struct net_device * au1000_probe(int port_num)
+ * to match those that are printed on their stickers
+ */
+ memcpy(dev->dev_addr, au1000_mac_addr, sizeof(au1000_mac_addr));
+- dev->dev_addr[5] += port_num;
++ dev->dev_addr[5] += pdev->id;
+
+ *aup->enable = 0;
+ aup->mac_enabled = 0;
+
++ pd = pdev->dev.platform_data;
++ if (!pd) {
++ printk(KERN_INFO DRV_NAME ": no platform_data passed, PHY search on MAC0\n");
++ aup->phy1_search_mac0 = 1;
++ } else {
++ aup->phy_static_config = pd->phy_static_config;
++ aup->phy_search_highest_addr = pd->phy_search_highest_addr;
++ aup->phy1_search_mac0 = pd->phy1_search_mac0;
++ aup->phy_addr = pd->phy_addr;
++ aup->phy_busid = pd->phy_busid;
++ aup->phy_irq = pd->phy_irq;
++ }
++
++ if (aup->phy_busid && aup->phy_busid > 0) {
++ printk(KERN_ERR DRV_NAME ": MAC0-associated PHY attached 2nd MACs MII"
++ "bus not supported yet\n");
++ err = -ENODEV;
++ goto err_mdiobus_alloc;
++ }
++
+ aup->mii_bus = mdiobus_alloc();
+- if (aup->mii_bus == NULL)
+- goto err_out;
++ if (aup->mii_bus == NULL) {
++ printk(KERN_ERR DRV_NAME ": failed to allocate mdiobus structure\n");
++ err = -ENOMEM;
++ goto err_mdiobus_alloc;
++ }
+
+ aup->mii_bus->priv = dev;
+ aup->mii_bus->read = au1000_mdiobus_read;
+@@ -1168,23 +1159,19 @@ static struct net_device * au1000_probe(int port_num)
+
+ for(i = 0; i < PHY_MAX_ADDR; ++i)
+ aup->mii_bus->irq[i] = PHY_POLL;
+-
+ /* if known, set corresponding PHY IRQs */
+-#if defined(AU1XXX_PHY_STATIC_CONFIG)
+-# if defined(AU1XXX_PHY0_IRQ)
+- if (AU1XXX_PHY0_BUSID == aup->mac_id)
+- aup->mii_bus->irq[AU1XXX_PHY0_ADDR] = AU1XXX_PHY0_IRQ;
+-# endif
+-# if defined(AU1XXX_PHY1_IRQ)
+- if (AU1XXX_PHY1_BUSID == aup->mac_id)
+- aup->mii_bus->irq[AU1XXX_PHY1_ADDR] = AU1XXX_PHY1_IRQ;
+-# endif
+-#endif
+- mdiobus_register(aup->mii_bus);
++ if (aup->phy_static_config)
++ if (aup->phy_irq && aup->phy_busid == aup->mac_id)
++ aup->mii_bus->irq[aup->phy_addr] = aup->phy_irq;
++
++ err = mdiobus_register(aup->mii_bus);
++ if (err) {
++ printk(KERN_ERR DRV_NAME " failed to register MDIO bus\n");
++ goto err_mdiobus_reg;
++ }
+
+- if (mii_probe(dev) != 0) {
++ if (mii_probe(dev) != 0)
+ goto err_out;
+- }
+
+ pDBfree = NULL;
+ /* setup the data buffer descriptors and attach a buffer to each one */
+@@ -1216,19 +1203,35 @@ static struct net_device * au1000_probe(int port_num)
+ aup->tx_db_inuse[i] = pDB;
+ }
+
++ dev->base_addr = base->start;
++ dev->irq = irq;
++ dev->netdev_ops = &au1000_netdev_ops;
++ SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops);
++ dev->watchdog_timeo = ETH_TX_TIMEOUT;
++
+ /*
+ * The boot code uses the ethernet controller, so reset it to start
+ * fresh. au1000_init() expects that the device is in reset state.
+ */
+ reset_mac(dev);
+
+- return dev;
++ err = register_netdev(dev);
++ if (err) {
++ printk(KERN_ERR DRV_NAME "%s: Cannot register net device, aborting.\n",
++ dev->name);
++ goto err_out;
++ }
++
++ printk("%s: Au1xx0 Ethernet found at 0x%x, irq %d\n",
++ dev->name, base->start, irq);
++ if (version_printed++ == 0)
++ printk("%s version %s %s\n", DRV_NAME, DRV_VERSION, DRV_AUTHOR);
++
++ return 0;
+
+ err_out:
+- if (aup->mii_bus != NULL) {
++ if (aup->mii_bus != NULL)
+ mdiobus_unregister(aup->mii_bus);
+- mdiobus_free(aup->mii_bus);
+- }
+
+ /* here we should have a valid dev plus aup-> register addresses
+ * so we can reset the mac properly.*/
+@@ -1242,67 +1245,84 @@ err_out:
+ if (aup->tx_db_inuse[i])
+ ReleaseDB(aup, aup->tx_db_inuse[i]);
+ }
++err_mdiobus_reg:
++ mdiobus_free(aup->mii_bus);
++err_mdiobus_alloc:
++ iounmap(aup->enable);
++err_remap2:
++ iounmap(aup->mac);
++err_remap1:
+ dma_free_noncoherent(NULL, MAX_BUF_SIZE * (NUM_TX_BUFFS + NUM_RX_BUFFS),
+ (void *)aup->vaddr, aup->dma_addr);
+- unregister_netdev(dev);
++err_vaddr:
+ free_netdev(dev);
+- release_mem_region( base, MAC_IOSIZE);
+- release_mem_region(macen, 4);
+- return NULL;
++err_alloc:
++ release_mem_region(macen->start, resource_size(macen));
++err_request:
++ release_mem_region(base->start, resource_size(base));
++out:
++ return err;
+ }
+
+-/*
+- * Setup the base address and interrupt of the Au1xxx ethernet macs
+- * based on cpu type and whether the interface is enabled in sys_pinfunc
+- * register. The last interface is enabled if SYS_PF_NI2 (bit 4) is 0.
+- */
+-static int __init au1000_init_module(void)
++static int __devexit au1000_remove(struct platform_device *pdev)
+ {
+- int ni = (int)((au_readl(SYS_PINFUNC) & (u32)(SYS_PF_NI2)) >> 4);
+- struct net_device *dev;
+- int i, found_one = 0;
++ struct net_device *dev = platform_get_drvdata(pdev);
++ struct au1000_private *aup = netdev_priv(dev);
++ int i;
++ struct resource *base, *macen;
+
+- num_ifs = NUM_ETH_INTERFACES - ni;
++ platform_set_drvdata(pdev, NULL);
++
++ unregister_netdev(dev);
++ mdiobus_unregister(aup->mii_bus);
++ mdiobus_free(aup->mii_bus);
++
++ for (i = 0; i < NUM_RX_DMA; i++)
++ if (aup->rx_db_inuse[i])
++ ReleaseDB(aup, aup->rx_db_inuse[i]);
++
++ for (i = 0; i < NUM_TX_DMA; i++)
++ if (aup->tx_db_inuse[i])
++ ReleaseDB(aup, aup->tx_db_inuse[i]);
++
++ dma_free_noncoherent(NULL, MAX_BUF_SIZE *
++ (NUM_TX_BUFFS + NUM_RX_BUFFS),
++ (void *)aup->vaddr, aup->dma_addr);
++
++ iounmap(aup->mac);
++ iounmap(aup->enable);
++
++ base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ release_mem_region(base->start, resource_size(base));
++
++ macen = platform_get_resource(pdev, IORESOURCE_MEM, 1);
++ release_mem_region(macen->start, resource_size(macen));
++
++ free_netdev(dev);
+
+- for(i = 0; i < num_ifs; i++) {
+- dev = au1000_probe(i);
+- iflist[i].dev = dev;
+- if (dev)
+- found_one++;
+- }
+- if (!found_one)
+- return -ENODEV;
+ return 0;
+ }
+
+-static void __exit au1000_cleanup_module(void)
++static struct platform_driver au1000_eth_driver = {
++ .probe = au1000_probe,
++ .remove = __devexit_p(au1000_remove),
++ .driver = {
++ .name = "au1000-eth",
++ .owner = THIS_MODULE,
++ },
++};
++MODULE_ALIAS("platform:au1000-eth");
++
++
++static int __init au1000_init_module(void)
++{
++ return platform_driver_register(&au1000_eth_driver);
++}
++
++static void __exit au1000_exit_module(void)
+ {
+- int i, j;
+- struct net_device *dev;
+- struct au1000_private *aup;
+-
+- for (i = 0; i < num_ifs; i++) {
+- dev = iflist[i].dev;
+- if (dev) {
+- aup = netdev_priv(dev);
+- unregister_netdev(dev);
+- mdiobus_unregister(aup->mii_bus);
+- mdiobus_free(aup->mii_bus);
+- for (j = 0; j < NUM_RX_DMA; j++)
+- if (aup->rx_db_inuse[j])
+- ReleaseDB(aup, aup->rx_db_inuse[j]);
+- for (j = 0; j < NUM_TX_DMA; j++)
+- if (aup->tx_db_inuse[j])
+- ReleaseDB(aup, aup->tx_db_inuse[j]);
+- dma_free_noncoherent(NULL, MAX_BUF_SIZE *
+- (NUM_TX_BUFFS + NUM_RX_BUFFS),
+- (void *)aup->vaddr, aup->dma_addr);
+- release_mem_region(dev->base_addr, MAC_IOSIZE);
+- release_mem_region(CPHYSADDR(iflist[i].macen_addr), 4);
+- free_netdev(dev);
+- }
+- }
++ platform_driver_unregister(&au1000_eth_driver);
+ }
+
+ module_init(au1000_init_module);
+-module_exit(au1000_cleanup_module);
++module_exit(au1000_exit_module);
+diff --git a/drivers/net/au1000_eth.h b/drivers/net/au1000_eth.h
+index 824ecd5..f9d29a2 100644
+--- a/drivers/net/au1000_eth.h
++++ b/drivers/net/au1000_eth.h
+@@ -108,6 +108,15 @@ struct au1000_private {
+ struct phy_device *phy_dev;
+ struct mii_bus *mii_bus;
+
++ /* PHY configuration */
++ int phy_static_config;
++ int phy_search_highest_addr;
++ int phy1_search_mac0;
++
++ int phy_addr;
++ int phy_busid;
++ int phy_irq;
++
+ /* These variables are just for quick access to certain regs addresses. */
+ volatile mac_reg_t *mac; /* mac registers */
+ volatile u32 *enable; /* address of MAC Enable Register */
+diff --git a/drivers/net/irda/au1k_ir.c b/drivers/net/irda/au1k_ir.c
+index eb42468..955f04e 100644
+--- a/drivers/net/irda/au1k_ir.c
++++ b/drivers/net/irda/au1k_ir.c
+@@ -36,6 +36,7 @@
+ #include <asm/pb1000.h>
+ #elif defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100)
+ #include <asm/db1x00.h>
++#include <asm/mach-db1x00/bcsr.h>
+ #else
+ #error au1k_ir: unsupported board
+ #endif
+@@ -66,10 +67,6 @@ static char version[] __devinitdata =
+
+ #define RUN_AT(x) (jiffies + (x))
+
+-#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100)
+-static BCSR * const bcsr = (BCSR *)0xAE000000;
+-#endif
+-
+ static DEFINE_SPINLOCK(ir_lock);
+
+ /*
+@@ -282,9 +279,8 @@ static int au1k_irda_net_init(struct net_device *dev)
+
+ #if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100)
+ /* power on */
+- bcsr->resets &= ~BCSR_RESETS_IRDA_MODE_MASK;
+- bcsr->resets |= BCSR_RESETS_IRDA_MODE_FULL;
+- au_sync();
++ bcsr_mod(BCSR_RESETS, BCSR_RESETS_IRDA_MODE_MASK,
++ BCSR_RESETS_IRDA_MODE_FULL);
+ #endif
+
+ return 0;
+@@ -720,14 +716,14 @@ au1k_irda_set_speed(struct net_device *dev, int speed)
+
+ if (speed == 4000000) {
+ #if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100)
+- bcsr->resets |= BCSR_RESETS_FIR_SEL;
++ bcsr_mod(BCSR_RESETS, 0, BCSR_RESETS_FIR_SEL);
+ #else /* Pb1000 and Pb1100 */
+ writel(1<<13, CPLD_AUX1);
+ #endif
+ }
+ else {
+ #if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100)
+- bcsr->resets &= ~BCSR_RESETS_FIR_SEL;
++ bcsr_mod(BCSR_RESETS, BCSR_RESETS_FIR_SEL, 0);
+ #else /* Pb1000 and Pb1100 */
+ writel(readl(CPLD_AUX1) & ~(1<<13), CPLD_AUX1);
+ #endif
+diff --git a/drivers/net/octeon/Kconfig b/drivers/net/octeon/Kconfig
+new file mode 100644
+index 0000000..1e56bbf
+--- /dev/null
++++ b/drivers/net/octeon/Kconfig
+@@ -0,0 +1,10 @@
++config OCTEON_MGMT_ETHERNET
++ tristate "Octeon Management port ethernet driver (CN5XXX, CN6XXX)"
++ depends on CPU_CAVIUM_OCTEON
++ select PHYLIB
++ select MDIO_OCTEON
++ default y
++ help
++ This option enables the ethernet driver for the management
++ port on Cavium Networks' Octeon CN57XX, CN56XX, CN55XX,
++ CN54XX, CN52XX, and CN6XXX chips.
+diff --git a/drivers/net/octeon/Makefile b/drivers/net/octeon/Makefile
+new file mode 100644
+index 0000000..906edec
+--- /dev/null
++++ b/drivers/net/octeon/Makefile
+@@ -0,0 +1,2 @@
++
++obj-$(CONFIG_OCTEON_MGMT_ETHERNET) += octeon_mgmt.o
+diff --git a/drivers/net/octeon/octeon_mgmt.c b/drivers/net/octeon/octeon_mgmt.c
+new file mode 100644
+index 0000000..050538b
+--- /dev/null
++++ b/drivers/net/octeon/octeon_mgmt.c
+@@ -0,0 +1,1176 @@
++/*
++ * 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) 2009 Cavium Networks
++ */
++
++#include <linux/capability.h>
++#include <linux/dma-mapping.h>
++#include <linux/init.h>
++#include <linux/platform_device.h>
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/if_vlan.h>
++#include <linux/phy.h>
++#include <linux/spinlock.h>
++
++#include <asm/octeon/octeon.h>
++#include <asm/octeon/cvmx-mixx-defs.h>
++#include <asm/octeon/cvmx-agl-defs.h>
++
++#define DRV_NAME "octeon_mgmt"
++#define DRV_VERSION "2.0"
++#define DRV_DESCRIPTION \
++ "Cavium Networks Octeon MII (management) port Network Driver"
++
++#define OCTEON_MGMT_NAPI_WEIGHT 16
++
++/*
++ * Ring sizes that are powers of two allow for more efficient modulo
++ * opertions.
++ */
++#define OCTEON_MGMT_RX_RING_SIZE 512
++#define OCTEON_MGMT_TX_RING_SIZE 128
++
++/* Allow 8 bytes for vlan and FCS. */
++#define OCTEON_MGMT_RX_HEADROOM (ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN)
++
++union mgmt_port_ring_entry {
++ u64 d64;
++ struct {
++ u64 reserved_62_63:2;
++ /* Length of the buffer/packet in bytes */
++ u64 len:14;
++ /* For TX, signals that the packet should be timestamped */
++ u64 tstamp:1;
++ /* The RX error code */
++ u64 code:7;
++#define RING_ENTRY_CODE_DONE 0xf
++#define RING_ENTRY_CODE_MORE 0x10
++ /* Physical address of the buffer */
++ u64 addr:40;
++ } s;
++};
++
++struct octeon_mgmt {
++ struct net_device *netdev;
++ int port;
++ int irq;
++ u64 *tx_ring;
++ dma_addr_t tx_ring_handle;
++ unsigned int tx_next;
++ unsigned int tx_next_clean;
++ unsigned int tx_current_fill;
++ /* The tx_list lock also protects the ring related variables */
++ struct sk_buff_head tx_list;
++
++ /* RX variables only touched in napi_poll. No locking necessary. */
++ u64 *rx_ring;
++ dma_addr_t rx_ring_handle;
++ unsigned int rx_next;
++ unsigned int rx_next_fill;
++ unsigned int rx_current_fill;
++ struct sk_buff_head rx_list;
++
++ spinlock_t lock;
++ unsigned int last_duplex;
++ unsigned int last_link;
++ struct device *dev;
++ struct napi_struct napi;
++ struct tasklet_struct tx_clean_tasklet;
++ struct phy_device *phydev;
++};
++
++static void octeon_mgmt_set_rx_irq(struct octeon_mgmt *p, int enable)
++{
++ int port = p->port;
++ union cvmx_mixx_intena mix_intena;
++ unsigned long flags;
++
++ spin_lock_irqsave(&p->lock, flags);
++ mix_intena.u64 = cvmx_read_csr(CVMX_MIXX_INTENA(port));
++ mix_intena.s.ithena = enable ? 1 : 0;
++ cvmx_write_csr(CVMX_MIXX_INTENA(port), mix_intena.u64);
++ spin_unlock_irqrestore(&p->lock, flags);
++}
++
++static void octeon_mgmt_set_tx_irq(struct octeon_mgmt *p, int enable)
++{
++ int port = p->port;
++ union cvmx_mixx_intena mix_intena;
++ unsigned long flags;
++
++ spin_lock_irqsave(&p->lock, flags);
++ mix_intena.u64 = cvmx_read_csr(CVMX_MIXX_INTENA(port));
++ mix_intena.s.othena = enable ? 1 : 0;
++ cvmx_write_csr(CVMX_MIXX_INTENA(port), mix_intena.u64);
++ spin_unlock_irqrestore(&p->lock, flags);
++}
++
++static inline void octeon_mgmt_enable_rx_irq(struct octeon_mgmt *p)
++{
++ octeon_mgmt_set_rx_irq(p, 1);
++}
++
++static inline void octeon_mgmt_disable_rx_irq(struct octeon_mgmt *p)
++{
++ octeon_mgmt_set_rx_irq(p, 0);
++}
++
++static inline void octeon_mgmt_enable_tx_irq(struct octeon_mgmt *p)
++{
++ octeon_mgmt_set_tx_irq(p, 1);
++}
++
++static inline void octeon_mgmt_disable_tx_irq(struct octeon_mgmt *p)
++{
++ octeon_mgmt_set_tx_irq(p, 0);
++}
++
++static unsigned int ring_max_fill(unsigned int ring_size)
++{
++ return ring_size - 8;
++}
++
++static unsigned int ring_size_to_bytes(unsigned int ring_size)
++{
++ return ring_size * sizeof(union mgmt_port_ring_entry);
++}
++
++static void octeon_mgmt_rx_fill_ring(struct net_device *netdev)
++{
++ struct octeon_mgmt *p = netdev_priv(netdev);
++ int port = p->port;
++
++ while (p->rx_current_fill < ring_max_fill(OCTEON_MGMT_RX_RING_SIZE)) {
++ unsigned int size;
++ union mgmt_port_ring_entry re;
++ struct sk_buff *skb;
++
++ /* CN56XX pass 1 needs 8 bytes of padding. */
++ size = netdev->mtu + OCTEON_MGMT_RX_HEADROOM + 8 + NET_IP_ALIGN;
++
++ skb = netdev_alloc_skb(netdev, size);
++ if (!skb)
++ break;
++ skb_reserve(skb, NET_IP_ALIGN);
++ __skb_queue_tail(&p->rx_list, skb);
++
++ re.d64 = 0;
++ re.s.len = size;
++ re.s.addr = dma_map_single(p->dev, skb->data,
++ size,
++ DMA_FROM_DEVICE);
++
++ /* Put it in the ring. */
++ p->rx_ring[p->rx_next_fill] = re.d64;
++ dma_sync_single_for_device(p->dev, p->rx_ring_handle,
++ ring_size_to_bytes(OCTEON_MGMT_RX_RING_SIZE),
++ DMA_BIDIRECTIONAL);
++ p->rx_next_fill =
++ (p->rx_next_fill + 1) % OCTEON_MGMT_RX_RING_SIZE;
++ p->rx_current_fill++;
++ /* Ring the bell. */
++ cvmx_write_csr(CVMX_MIXX_IRING2(port), 1);
++ }
++}
++
++static void octeon_mgmt_clean_tx_buffers(struct octeon_mgmt *p)
++{
++ int port = p->port;
++ union cvmx_mixx_orcnt mix_orcnt;
++ union mgmt_port_ring_entry re;
++ struct sk_buff *skb;
++ int cleaned = 0;
++ unsigned long flags;
++
++ mix_orcnt.u64 = cvmx_read_csr(CVMX_MIXX_ORCNT(port));
++ while (mix_orcnt.s.orcnt) {
++ dma_sync_single_for_cpu(p->dev, p->tx_ring_handle,
++ ring_size_to_bytes(OCTEON_MGMT_TX_RING_SIZE),
++ DMA_BIDIRECTIONAL);
++
++ spin_lock_irqsave(&p->tx_list.lock, flags);
++
++ re.d64 = p->tx_ring[p->tx_next_clean];
++ p->tx_next_clean =
++ (p->tx_next_clean + 1) % OCTEON_MGMT_TX_RING_SIZE;
++ skb = __skb_dequeue(&p->tx_list);
++
++ mix_orcnt.u64 = 0;
++ mix_orcnt.s.orcnt = 1;
++
++ /* Acknowledge to hardware that we have the buffer. */
++ cvmx_write_csr(CVMX_MIXX_ORCNT(port), mix_orcnt.u64);
++ p->tx_current_fill--;
++
++ spin_unlock_irqrestore(&p->tx_list.lock, flags);
++
++ dma_unmap_single(p->dev, re.s.addr, re.s.len,
++ DMA_TO_DEVICE);
++ dev_kfree_skb_any(skb);
++ cleaned++;
++
++ mix_orcnt.u64 = cvmx_read_csr(CVMX_MIXX_ORCNT(port));
++ }
++
++ if (cleaned && netif_queue_stopped(p->netdev))
++ netif_wake_queue(p->netdev);
++}
++
++static void octeon_mgmt_clean_tx_tasklet(unsigned long arg)
++{
++ struct octeon_mgmt *p = (struct octeon_mgmt *)arg;
++ octeon_mgmt_clean_tx_buffers(p);
++ octeon_mgmt_enable_tx_irq(p);
++}
++
++static void octeon_mgmt_update_rx_stats(struct net_device *netdev)
++{
++ struct octeon_mgmt *p = netdev_priv(netdev);
++ int port = p->port;
++ unsigned long flags;
++ u64 drop, bad;
++
++ /* These reads also clear the count registers. */
++ drop = cvmx_read_csr(CVMX_AGL_GMX_RXX_STATS_PKTS_DRP(port));
++ bad = cvmx_read_csr(CVMX_AGL_GMX_RXX_STATS_PKTS_BAD(port));
++
++ if (drop || bad) {
++ /* Do an atomic update. */
++ spin_lock_irqsave(&p->lock, flags);
++ netdev->stats.rx_errors += bad;
++ netdev->stats.rx_dropped += drop;
++ spin_unlock_irqrestore(&p->lock, flags);
++ }
++}
++
++static void octeon_mgmt_update_tx_stats(struct net_device *netdev)
++{
++ struct octeon_mgmt *p = netdev_priv(netdev);
++ int port = p->port;
++ unsigned long flags;
++
++ union cvmx_agl_gmx_txx_stat0 s0;
++ union cvmx_agl_gmx_txx_stat1 s1;
++
++ /* These reads also clear the count registers. */
++ s0.u64 = cvmx_read_csr(CVMX_AGL_GMX_TXX_STAT0(port));
++ s1.u64 = cvmx_read_csr(CVMX_AGL_GMX_TXX_STAT1(port));
++
++ if (s0.s.xsdef || s0.s.xscol || s1.s.scol || s1.s.mcol) {
++ /* Do an atomic update. */
++ spin_lock_irqsave(&p->lock, flags);
++ netdev->stats.tx_errors += s0.s.xsdef + s0.s.xscol;
++ netdev->stats.collisions += s1.s.scol + s1.s.mcol;
++ spin_unlock_irqrestore(&p->lock, flags);
++ }
++}
++
++/*
++ * Dequeue a receive skb and its corresponding ring entry. The ring
++ * entry is returned, *pskb is updated to point to the skb.
++ */
++static u64 octeon_mgmt_dequeue_rx_buffer(struct octeon_mgmt *p,
++ struct sk_buff **pskb)
++{
++ union mgmt_port_ring_entry re;
++
++ dma_sync_single_for_cpu(p->dev, p->rx_ring_handle,
++ ring_size_to_bytes(OCTEON_MGMT_RX_RING_SIZE),
++ DMA_BIDIRECTIONAL);
++
++ re.d64 = p->rx_ring[p->rx_next];
++ p->rx_next = (p->rx_next + 1) % OCTEON_MGMT_RX_RING_SIZE;
++ p->rx_current_fill--;
++ *pskb = __skb_dequeue(&p->rx_list);
++
++ dma_unmap_single(p->dev, re.s.addr,
++ ETH_FRAME_LEN + OCTEON_MGMT_RX_HEADROOM,
++ DMA_FROM_DEVICE);
++
++ return re.d64;
++}
++
++
++static int octeon_mgmt_receive_one(struct octeon_mgmt *p)
++{
++ int port = p->port;
++ struct net_device *netdev = p->netdev;
++ union cvmx_mixx_ircnt mix_ircnt;
++ union mgmt_port_ring_entry re;
++ struct sk_buff *skb;
++ struct sk_buff *skb2;
++ struct sk_buff *skb_new;
++ union mgmt_port_ring_entry re2;
++ int rc = 1;
++
++
++ re.d64 = octeon_mgmt_dequeue_rx_buffer(p, &skb);
++ if (likely(re.s.code == RING_ENTRY_CODE_DONE)) {
++ /* A good packet, send it up. */
++ skb_put(skb, re.s.len);
++good:
++ skb->protocol = eth_type_trans(skb, netdev);
++ netdev->stats.rx_packets++;
++ netdev->stats.rx_bytes += skb->len;
++ netdev->last_rx = jiffies;
++ netif_receive_skb(skb);
++ rc = 0;
++ } else if (re.s.code == RING_ENTRY_CODE_MORE) {
++ /*
++ * Packet split across skbs. This can happen if we
++ * increase the MTU. Buffers that are already in the
++ * rx ring can then end up being too small. As the rx
++ * ring is refilled, buffers sized for the new MTU
++ * will be used and we should go back to the normal
++ * non-split case.
++ */
++ skb_put(skb, re.s.len);
++ do {
++ re2.d64 = octeon_mgmt_dequeue_rx_buffer(p, &skb2);
++ if (re2.s.code != RING_ENTRY_CODE_MORE
++ && re2.s.code != RING_ENTRY_CODE_DONE)
++ goto split_error;
++ skb_put(skb2, re2.s.len);
++ skb_new = skb_copy_expand(skb, 0, skb2->len,
++ GFP_ATOMIC);
++ if (!skb_new)
++ goto split_error;
++ if (skb_copy_bits(skb2, 0, skb_tail_pointer(skb_new),
++ skb2->len))
++ goto split_error;
++ skb_put(skb_new, skb2->len);
++ dev_kfree_skb_any(skb);
++ dev_kfree_skb_any(skb2);
++ skb = skb_new;
++ } while (re2.s.code == RING_ENTRY_CODE_MORE);
++ goto good;
++ } else {
++ /* Some other error, discard it. */
++ dev_kfree_skb_any(skb);
++ /*
++ * Error statistics are accumulated in
++ * octeon_mgmt_update_rx_stats.
++ */
++ }
++ goto done;
++split_error:
++ /* Discard the whole mess. */
++ dev_kfree_skb_any(skb);
++ dev_kfree_skb_any(skb2);
++ while (re2.s.code == RING_ENTRY_CODE_MORE) {
++ re2.d64 = octeon_mgmt_dequeue_rx_buffer(p, &skb2);
++ dev_kfree_skb_any(skb2);
++ }
++ netdev->stats.rx_errors++;
++
++done:
++ /* Tell the hardware we processed a packet. */
++ mix_ircnt.u64 = 0;
++ mix_ircnt.s.ircnt = 1;
++ cvmx_write_csr(CVMX_MIXX_IRCNT(port), mix_ircnt.u64);
++ return rc;
++
++}
++
++static int octeon_mgmt_receive_packets(struct octeon_mgmt *p, int budget)
++{
++ int port = p->port;
++ unsigned int work_done = 0;
++ union cvmx_mixx_ircnt mix_ircnt;
++ int rc;
++
++
++ mix_ircnt.u64 = cvmx_read_csr(CVMX_MIXX_IRCNT(port));
++ while (work_done < budget && mix_ircnt.s.ircnt) {
++
++ rc = octeon_mgmt_receive_one(p);
++ if (!rc)
++ work_done++;
++
++ /* Check for more packets. */
++ mix_ircnt.u64 = cvmx_read_csr(CVMX_MIXX_IRCNT(port));
++ }
++
++ octeon_mgmt_rx_fill_ring(p->netdev);
++
++ return work_done;
++}
++
++static int octeon_mgmt_napi_poll(struct napi_struct *napi, int budget)
++{
++ struct octeon_mgmt *p = container_of(napi, struct octeon_mgmt, napi);
++ struct net_device *netdev = p->netdev;
++ unsigned int work_done = 0;
++
++ work_done = octeon_mgmt_receive_packets(p, budget);
++
++ if (work_done < budget) {
++ /* We stopped because no more packets were available. */
++ napi_complete(napi);
++ octeon_mgmt_enable_rx_irq(p);
++ }
++ octeon_mgmt_update_rx_stats(netdev);
++
++ return work_done;
++}
++
++/* Reset the hardware to clean state. */
++static void octeon_mgmt_reset_hw(struct octeon_mgmt *p)
++{
++ union cvmx_mixx_ctl mix_ctl;
++ union cvmx_mixx_bist mix_bist;
++ union cvmx_agl_gmx_bist agl_gmx_bist;
++
++ mix_ctl.u64 = 0;
++ cvmx_write_csr(CVMX_MIXX_CTL(p->port), mix_ctl.u64);
++ do {
++ mix_ctl.u64 = cvmx_read_csr(CVMX_MIXX_CTL(p->port));
++ } while (mix_ctl.s.busy);
++ mix_ctl.s.reset = 1;
++ cvmx_write_csr(CVMX_MIXX_CTL(p->port), mix_ctl.u64);
++ cvmx_read_csr(CVMX_MIXX_CTL(p->port));
++ cvmx_wait(64);
++
++ mix_bist.u64 = cvmx_read_csr(CVMX_MIXX_BIST(p->port));
++ if (mix_bist.u64)
++ dev_warn(p->dev, "MIX failed BIST (0x%016llx)\n",
++ (unsigned long long)mix_bist.u64);
++
++ agl_gmx_bist.u64 = cvmx_read_csr(CVMX_AGL_GMX_BIST);
++ if (agl_gmx_bist.u64)
++ dev_warn(p->dev, "AGL failed BIST (0x%016llx)\n",
++ (unsigned long long)agl_gmx_bist.u64);
++}
++
++struct octeon_mgmt_cam_state {
++ u64 cam[6];
++ u64 cam_mask;
++ int cam_index;
++};
++
++static void octeon_mgmt_cam_state_add(struct octeon_mgmt_cam_state *cs,
++ unsigned char *addr)
++{
++ int i;
++
++ for (i = 0; i < 6; i++)
++ cs->cam[i] |= (u64)addr[i] << (8 * (cs->cam_index));
++ cs->cam_mask |= (1ULL << cs->cam_index);
++ cs->cam_index++;
++}
++
++static void octeon_mgmt_set_rx_filtering(struct net_device *netdev)
++{
++ struct octeon_mgmt *p = netdev_priv(netdev);
++ int port = p->port;
++ int i;
++ union cvmx_agl_gmx_rxx_adr_ctl adr_ctl;
++ union cvmx_agl_gmx_prtx_cfg agl_gmx_prtx;
++ unsigned long flags;
++ unsigned int prev_packet_enable;
++ unsigned int cam_mode = 1; /* 1 - Accept on CAM match */
++ unsigned int multicast_mode = 1; /* 1 - Reject all multicast. */
++ struct octeon_mgmt_cam_state cam_state;
++ struct dev_addr_list *list;
++ struct list_head *pos;
++ int available_cam_entries;
++
++ memset(&cam_state, 0, sizeof(cam_state));
++
++ if ((netdev->flags & IFF_PROMISC) || netdev->dev_addrs.count > 7) {
++ cam_mode = 0;
++ available_cam_entries = 8;
++ } else {
++ /*
++ * One CAM entry for the primary address, leaves seven
++ * for the secondary addresses.
++ */
++ available_cam_entries = 7 - netdev->dev_addrs.count;
++ }
++
++ if (netdev->flags & IFF_MULTICAST) {
++ if (cam_mode == 0 || (netdev->flags & IFF_ALLMULTI)
++ || netdev->mc_count > available_cam_entries)
++ multicast_mode = 2; /* 1 - Accept all multicast. */
++ else
++ multicast_mode = 0; /* 0 - Use CAM. */
++ }
++
++ if (cam_mode == 1) {
++ /* Add primary address. */
++ octeon_mgmt_cam_state_add(&cam_state, netdev->dev_addr);
++ list_for_each(pos, &netdev->dev_addrs.list) {
++ struct netdev_hw_addr *hw_addr;
++ hw_addr = list_entry(pos, struct netdev_hw_addr, list);
++ octeon_mgmt_cam_state_add(&cam_state, hw_addr->addr);
++ list = list->next;
++ }
++ }
++ if (multicast_mode == 0) {
++ i = netdev->mc_count;
++ list = netdev->mc_list;
++ while (i--) {
++ octeon_mgmt_cam_state_add(&cam_state, list->da_addr);
++ list = list->next;
++ }
++ }
++
++
++ spin_lock_irqsave(&p->lock, flags);
++
++ /* Disable packet I/O. */
++ agl_gmx_prtx.u64 = cvmx_read_csr(CVMX_AGL_GMX_PRTX_CFG(port));
++ prev_packet_enable = agl_gmx_prtx.s.en;
++ agl_gmx_prtx.s.en = 0;
++ cvmx_write_csr(CVMX_AGL_GMX_PRTX_CFG(port), agl_gmx_prtx.u64);
++
++
++ adr_ctl.u64 = 0;
++ adr_ctl.s.cam_mode = cam_mode;
++ adr_ctl.s.mcst = multicast_mode;
++ adr_ctl.s.bcst = 1; /* Allow broadcast */
++
++ cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CTL(port), adr_ctl.u64);
++
++ cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM0(port), cam_state.cam[0]);
++ cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM1(port), cam_state.cam[1]);
++ cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM2(port), cam_state.cam[2]);
++ cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM3(port), cam_state.cam[3]);
++ cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM4(port), cam_state.cam[4]);
++ cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM5(port), cam_state.cam[5]);
++ cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM_EN(port), cam_state.cam_mask);
++
++ /* Restore packet I/O. */
++ agl_gmx_prtx.s.en = prev_packet_enable;
++ cvmx_write_csr(CVMX_AGL_GMX_PRTX_CFG(port), agl_gmx_prtx.u64);
++
++ spin_unlock_irqrestore(&p->lock, flags);
++}
++
++static int octeon_mgmt_set_mac_address(struct net_device *netdev, void *addr)
++{
++ struct sockaddr *sa = addr;
++
++ if (!is_valid_ether_addr(sa->sa_data))
++ return -EADDRNOTAVAIL;
++
++ memcpy(netdev->dev_addr, sa->sa_data, ETH_ALEN);
++
++ octeon_mgmt_set_rx_filtering(netdev);
++
++ return 0;
++}
++
++static int octeon_mgmt_change_mtu(struct net_device *netdev, int new_mtu)
++{
++ struct octeon_mgmt *p = netdev_priv(netdev);
++ int port = p->port;
++ int size_without_fcs = new_mtu + OCTEON_MGMT_RX_HEADROOM;
++
++ /*
++ * Limit the MTU to make sure the ethernet packets are between
++ * 64 bytes and 16383 bytes.
++ */
++ if (size_without_fcs < 64 || size_without_fcs > 16383) {
++ dev_warn(p->dev, "MTU must be between %d and %d.\n",
++ 64 - OCTEON_MGMT_RX_HEADROOM,
++ 16383 - OCTEON_MGMT_RX_HEADROOM);
++ return -EINVAL;
++ }
++
++ netdev->mtu = new_mtu;
++
++ cvmx_write_csr(CVMX_AGL_GMX_RXX_FRM_MAX(port), size_without_fcs);
++ cvmx_write_csr(CVMX_AGL_GMX_RXX_JABBER(port),
++ (size_without_fcs + 7) & 0xfff8);
++
++ return 0;
++}
++
++static irqreturn_t octeon_mgmt_interrupt(int cpl, void *dev_id)
++{
++ struct net_device *netdev = dev_id;
++ struct octeon_mgmt *p = netdev_priv(netdev);
++ int port = p->port;
++ union cvmx_mixx_isr mixx_isr;
++
++ mixx_isr.u64 = cvmx_read_csr(CVMX_MIXX_ISR(port));
++
++ /* Clear any pending interrupts */
++ cvmx_write_csr(CVMX_MIXX_ISR(port),
++ cvmx_read_csr(CVMX_MIXX_ISR(port)));
++ cvmx_read_csr(CVMX_MIXX_ISR(port));
++
++ if (mixx_isr.s.irthresh) {
++ octeon_mgmt_disable_rx_irq(p);
++ napi_schedule(&p->napi);
++ }
++ if (mixx_isr.s.orthresh) {
++ octeon_mgmt_disable_tx_irq(p);
++ tasklet_schedule(&p->tx_clean_tasklet);
++ }
++
++ return IRQ_HANDLED;
++}
++
++static int octeon_mgmt_ioctl(struct net_device *netdev,
++ struct ifreq *rq, int cmd)
++{
++ struct octeon_mgmt *p = netdev_priv(netdev);
++
++ if (!netif_running(netdev))
++ return -EINVAL;
++
++ if (!p->phydev)
++ return -EINVAL;
++
++ return phy_mii_ioctl(p->phydev, if_mii(rq), cmd);
++}
++
++static void octeon_mgmt_adjust_link(struct net_device *netdev)
++{
++ struct octeon_mgmt *p = netdev_priv(netdev);
++ int port = p->port;
++ union cvmx_agl_gmx_prtx_cfg prtx_cfg;
++ unsigned long flags;
++ int link_changed = 0;
++
++ spin_lock_irqsave(&p->lock, flags);
++ if (p->phydev->link) {
++ if (!p->last_link)
++ link_changed = 1;
++ if (p->last_duplex != p->phydev->duplex) {
++ p->last_duplex = p->phydev->duplex;
++ prtx_cfg.u64 =
++ cvmx_read_csr(CVMX_AGL_GMX_PRTX_CFG(port));
++ prtx_cfg.s.duplex = p->phydev->duplex;
++ cvmx_write_csr(CVMX_AGL_GMX_PRTX_CFG(port),
++ prtx_cfg.u64);
++ }
++ } else {
++ if (p->last_link)
++ link_changed = -1;
++ }
++ p->last_link = p->phydev->link;
++ spin_unlock_irqrestore(&p->lock, flags);
++
++ if (link_changed != 0) {
++ if (link_changed > 0) {
++ netif_carrier_on(netdev);
++ pr_info("%s: Link is up - %d/%s\n", netdev->name,
++ p->phydev->speed,
++ DUPLEX_FULL == p->phydev->duplex ?
++ "Full" : "Half");
++ } else {
++ netif_carrier_off(netdev);
++ pr_info("%s: Link is down\n", netdev->name);
++ }
++ }
++}
++
++static int octeon_mgmt_init_phy(struct net_device *netdev)
++{
++ struct octeon_mgmt *p = netdev_priv(netdev);
++ char phy_id[20];
++
++ if (octeon_is_simulation()) {
++ /* No PHYs in the simulator. */
++ netif_carrier_on(netdev);
++ return 0;
++ }
++
++ snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT, "0", p->port);
++
++ p->phydev = phy_connect(netdev, phy_id, octeon_mgmt_adjust_link, 0,
++ PHY_INTERFACE_MODE_MII);
++
++ if (IS_ERR(p->phydev)) {
++ p->phydev = NULL;
++ return -1;
++ }
++
++ phy_start_aneg(p->phydev);
++
++ return 0;
++}
++
++static int octeon_mgmt_open(struct net_device *netdev)
++{
++ struct octeon_mgmt *p = netdev_priv(netdev);
++ int port = p->port;
++ union cvmx_mixx_ctl mix_ctl;
++ union cvmx_agl_gmx_inf_mode agl_gmx_inf_mode;
++ union cvmx_mixx_oring1 oring1;
++ union cvmx_mixx_iring1 iring1;
++ union cvmx_agl_gmx_prtx_cfg prtx_cfg;
++ union cvmx_agl_gmx_rxx_frm_ctl rxx_frm_ctl;
++ union cvmx_mixx_irhwm mix_irhwm;
++ union cvmx_mixx_orhwm mix_orhwm;
++ union cvmx_mixx_intena mix_intena;
++ struct sockaddr sa;
++
++ /* Allocate ring buffers. */
++ p->tx_ring = kzalloc(ring_size_to_bytes(OCTEON_MGMT_TX_RING_SIZE),
++ GFP_KERNEL);
++ if (!p->tx_ring)
++ return -ENOMEM;
++ p->tx_ring_handle =
++ dma_map_single(p->dev, p->tx_ring,
++ ring_size_to_bytes(OCTEON_MGMT_TX_RING_SIZE),
++ DMA_BIDIRECTIONAL);
++ p->tx_next = 0;
++ p->tx_next_clean = 0;
++ p->tx_current_fill = 0;
++
++
++ p->rx_ring = kzalloc(ring_size_to_bytes(OCTEON_MGMT_RX_RING_SIZE),
++ GFP_KERNEL);
++ if (!p->rx_ring)
++ goto err_nomem;
++ p->rx_ring_handle =
++ dma_map_single(p->dev, p->rx_ring,
++ ring_size_to_bytes(OCTEON_MGMT_RX_RING_SIZE),
++ DMA_BIDIRECTIONAL);
++
++ p->rx_next = 0;
++ p->rx_next_fill = 0;
++ p->rx_current_fill = 0;
++
++ octeon_mgmt_reset_hw(p);
++
++ mix_ctl.u64 = cvmx_read_csr(CVMX_MIXX_CTL(port));
++
++ /* Bring it out of reset if needed. */
++ if (mix_ctl.s.reset) {
++ mix_ctl.s.reset = 0;
++ cvmx_write_csr(CVMX_MIXX_CTL(port), mix_ctl.u64);
++ do {
++ mix_ctl.u64 = cvmx_read_csr(CVMX_MIXX_CTL(port));
++ } while (mix_ctl.s.reset);
++ }
++
++ agl_gmx_inf_mode.u64 = 0;
++ agl_gmx_inf_mode.s.en = 1;
++ cvmx_write_csr(CVMX_AGL_GMX_INF_MODE, agl_gmx_inf_mode.u64);
++
++ oring1.u64 = 0;
++ oring1.s.obase = p->tx_ring_handle >> 3;
++ oring1.s.osize = OCTEON_MGMT_TX_RING_SIZE;
++ cvmx_write_csr(CVMX_MIXX_ORING1(port), oring1.u64);
++
++ iring1.u64 = 0;
++ iring1.s.ibase = p->rx_ring_handle >> 3;
++ iring1.s.isize = OCTEON_MGMT_RX_RING_SIZE;
++ cvmx_write_csr(CVMX_MIXX_IRING1(port), iring1.u64);
++
++ /* Disable packet I/O. */
++ prtx_cfg.u64 = cvmx_read_csr(CVMX_AGL_GMX_PRTX_CFG(port));
++ prtx_cfg.s.en = 0;
++ cvmx_write_csr(CVMX_AGL_GMX_PRTX_CFG(port), prtx_cfg.u64);
++
++ memcpy(sa.sa_data, netdev->dev_addr, ETH_ALEN);
++ octeon_mgmt_set_mac_address(netdev, &sa);
++
++ octeon_mgmt_change_mtu(netdev, netdev->mtu);
++
++ /*
++ * Enable the port HW. Packets are not allowed until
++ * cvmx_mgmt_port_enable() is called.
++ */
++ mix_ctl.u64 = 0;
++ mix_ctl.s.crc_strip = 1; /* Strip the ending CRC */
++ mix_ctl.s.en = 1; /* Enable the port */
++ mix_ctl.s.nbtarb = 0; /* Arbitration mode */
++ /* MII CB-request FIFO programmable high watermark */
++ mix_ctl.s.mrq_hwm = 1;
++ cvmx_write_csr(CVMX_MIXX_CTL(port), mix_ctl.u64);
++
++ if (OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X)
++ || OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X)) {
++ /*
++ * Force compensation values, as they are not
++ * determined properly by HW
++ */
++ union cvmx_agl_gmx_drv_ctl drv_ctl;
++
++ drv_ctl.u64 = cvmx_read_csr(CVMX_AGL_GMX_DRV_CTL);
++ if (port) {
++ drv_ctl.s.byp_en1 = 1;
++ drv_ctl.s.nctl1 = 6;
++ drv_ctl.s.pctl1 = 6;
++ } else {
++ drv_ctl.s.byp_en = 1;
++ drv_ctl.s.nctl = 6;
++ drv_ctl.s.pctl = 6;
++ }
++ cvmx_write_csr(CVMX_AGL_GMX_DRV_CTL, drv_ctl.u64);
++ }
++
++ octeon_mgmt_rx_fill_ring(netdev);
++
++ /* Clear statistics. */
++ /* Clear on read. */
++ cvmx_write_csr(CVMX_AGL_GMX_RXX_STATS_CTL(port), 1);
++ cvmx_write_csr(CVMX_AGL_GMX_RXX_STATS_PKTS_DRP(port), 0);
++ cvmx_write_csr(CVMX_AGL_GMX_RXX_STATS_PKTS_BAD(port), 0);
++
++ cvmx_write_csr(CVMX_AGL_GMX_TXX_STATS_CTL(port), 1);
++ cvmx_write_csr(CVMX_AGL_GMX_TXX_STAT0(port), 0);
++ cvmx_write_csr(CVMX_AGL_GMX_TXX_STAT1(port), 0);
++
++ /* Clear any pending interrupts */
++ cvmx_write_csr(CVMX_MIXX_ISR(port), cvmx_read_csr(CVMX_MIXX_ISR(port)));
++
++ if (request_irq(p->irq, octeon_mgmt_interrupt, 0, netdev->name,
++ netdev)) {
++ dev_err(p->dev, "request_irq(%d) failed.\n", p->irq);
++ goto err_noirq;
++ }
++
++ /* Interrupt every single RX packet */
++ mix_irhwm.u64 = 0;
++ mix_irhwm.s.irhwm = 0;
++ cvmx_write_csr(CVMX_MIXX_IRHWM(port), mix_irhwm.u64);
++
++ /* Interrupt when we have 5 or more packets to clean. */
++ mix_orhwm.u64 = 0;
++ mix_orhwm.s.orhwm = 5;
++ cvmx_write_csr(CVMX_MIXX_ORHWM(port), mix_orhwm.u64);
++
++ /* Enable receive and transmit interrupts */
++ mix_intena.u64 = 0;
++ mix_intena.s.ithena = 1;
++ mix_intena.s.othena = 1;
++ cvmx_write_csr(CVMX_MIXX_INTENA(port), mix_intena.u64);
++
++
++ /* Enable packet I/O. */
++
++ rxx_frm_ctl.u64 = 0;
++ rxx_frm_ctl.s.pre_align = 1;
++ /*
++ * When set, disables the length check for non-min sized pkts
++ * with padding in the client data.
++ */
++ rxx_frm_ctl.s.pad_len = 1;
++ /* When set, disables the length check for VLAN pkts */
++ rxx_frm_ctl.s.vlan_len = 1;
++ /* When set, PREAMBLE checking is less strict */
++ rxx_frm_ctl.s.pre_free = 1;
++ /* Control Pause Frames can match station SMAC */
++ rxx_frm_ctl.s.ctl_smac = 0;
++ /* Control Pause Frames can match globally assign Multicast address */
++ rxx_frm_ctl.s.ctl_mcst = 1;
++ /* Forward pause information to TX block */
++ rxx_frm_ctl.s.ctl_bck = 1;
++ /* Drop Control Pause Frames */
++ rxx_frm_ctl.s.ctl_drp = 1;
++ /* Strip off the preamble */
++ rxx_frm_ctl.s.pre_strp = 1;
++ /*
++ * This port is configured to send PREAMBLE+SFD to begin every
++ * frame. GMX checks that the PREAMBLE is sent correctly.
++ */
++ rxx_frm_ctl.s.pre_chk = 1;
++ cvmx_write_csr(CVMX_AGL_GMX_RXX_FRM_CTL(port), rxx_frm_ctl.u64);
++
++ /* Enable the AGL block */
++ agl_gmx_inf_mode.u64 = 0;
++ agl_gmx_inf_mode.s.en = 1;
++ cvmx_write_csr(CVMX_AGL_GMX_INF_MODE, agl_gmx_inf_mode.u64);
++
++ /* Configure the port duplex and enables */
++ prtx_cfg.u64 = cvmx_read_csr(CVMX_AGL_GMX_PRTX_CFG(port));
++ prtx_cfg.s.tx_en = 1;
++ prtx_cfg.s.rx_en = 1;
++ prtx_cfg.s.en = 1;
++ p->last_duplex = 1;
++ prtx_cfg.s.duplex = p->last_duplex;
++ cvmx_write_csr(CVMX_AGL_GMX_PRTX_CFG(port), prtx_cfg.u64);
++
++ p->last_link = 0;
++ netif_carrier_off(netdev);
++
++ if (octeon_mgmt_init_phy(netdev)) {
++ dev_err(p->dev, "Cannot initialize PHY.\n");
++ goto err_noirq;
++ }
++
++ netif_wake_queue(netdev);
++ napi_enable(&p->napi);
++
++ return 0;
++err_noirq:
++ octeon_mgmt_reset_hw(p);
++ dma_unmap_single(p->dev, p->rx_ring_handle,
++ ring_size_to_bytes(OCTEON_MGMT_RX_RING_SIZE),
++ DMA_BIDIRECTIONAL);
++ kfree(p->rx_ring);
++err_nomem:
++ dma_unmap_single(p->dev, p->tx_ring_handle,
++ ring_size_to_bytes(OCTEON_MGMT_TX_RING_SIZE),
++ DMA_BIDIRECTIONAL);
++ kfree(p->tx_ring);
++ return -ENOMEM;
++}
++
++static int octeon_mgmt_stop(struct net_device *netdev)
++{
++ struct octeon_mgmt *p = netdev_priv(netdev);
++
++ napi_disable(&p->napi);
++ netif_stop_queue(netdev);
++
++ if (p->phydev)
++ phy_disconnect(p->phydev);
++
++ netif_carrier_off(netdev);
++
++ octeon_mgmt_reset_hw(p);
++
++
++ free_irq(p->irq, netdev);
++
++ /* dma_unmap is a nop on Octeon, so just free everything. */
++ skb_queue_purge(&p->tx_list);
++ skb_queue_purge(&p->rx_list);
++
++ dma_unmap_single(p->dev, p->rx_ring_handle,
++ ring_size_to_bytes(OCTEON_MGMT_RX_RING_SIZE),
++ DMA_BIDIRECTIONAL);
++ kfree(p->rx_ring);
++
++ dma_unmap_single(p->dev, p->tx_ring_handle,
++ ring_size_to_bytes(OCTEON_MGMT_TX_RING_SIZE),
++ DMA_BIDIRECTIONAL);
++ kfree(p->tx_ring);
++
++
++ return 0;
++}
++
++static int octeon_mgmt_xmit(struct sk_buff *skb, struct net_device *netdev)
++{
++ struct octeon_mgmt *p = netdev_priv(netdev);
++ int port = p->port;
++ union mgmt_port_ring_entry re;
++ unsigned long flags;
++
++ re.d64 = 0;
++ re.s.len = skb->len;
++ re.s.addr = dma_map_single(p->dev, skb->data,
++ skb->len,
++ DMA_TO_DEVICE);
++
++ spin_lock_irqsave(&p->tx_list.lock, flags);
++
++ if (unlikely(p->tx_current_fill >=
++ ring_max_fill(OCTEON_MGMT_TX_RING_SIZE))) {
++ spin_unlock_irqrestore(&p->tx_list.lock, flags);
++
++ dma_unmap_single(p->dev, re.s.addr, re.s.len,
++ DMA_TO_DEVICE);
++
++ netif_stop_queue(netdev);
++ return NETDEV_TX_BUSY;
++ }
++
++ __skb_queue_tail(&p->tx_list, skb);
++
++ /* Put it in the ring. */
++ p->tx_ring[p->tx_next] = re.d64;
++ p->tx_next = (p->tx_next + 1) % OCTEON_MGMT_TX_RING_SIZE;
++ p->tx_current_fill++;
++
++ spin_unlock_irqrestore(&p->tx_list.lock, flags);
++
++ dma_sync_single_for_device(p->dev, p->tx_ring_handle,
++ ring_size_to_bytes(OCTEON_MGMT_TX_RING_SIZE),
++ DMA_BIDIRECTIONAL);
++
++ netdev->stats.tx_packets++;
++ netdev->stats.tx_bytes += skb->len;
++
++ /* Ring the bell. */
++ cvmx_write_csr(CVMX_MIXX_ORING2(port), 1);
++
++ netdev->trans_start = jiffies;
++ octeon_mgmt_clean_tx_buffers(p);
++ octeon_mgmt_update_tx_stats(netdev);
++ return NETDEV_TX_OK;
++}
++
++#ifdef CONFIG_NET_POLL_CONTROLLER
++static void octeon_mgmt_poll_controller(struct net_device *netdev)
++{
++ struct octeon_mgmt *p = netdev_priv(netdev);
++
++ octeon_mgmt_receive_packets(p, 16);
++ octeon_mgmt_update_rx_stats(netdev);
++ return;
++}
++#endif
++
++static void octeon_mgmt_get_drvinfo(struct net_device *netdev,
++ struct ethtool_drvinfo *info)
++{
++ strncpy(info->driver, DRV_NAME, sizeof(info->driver));
++ strncpy(info->version, DRV_VERSION, sizeof(info->version));
++ strncpy(info->fw_version, "N/A", sizeof(info->fw_version));
++ strncpy(info->bus_info, "N/A", sizeof(info->bus_info));
++ info->n_stats = 0;
++ info->testinfo_len = 0;
++ info->regdump_len = 0;
++ info->eedump_len = 0;
++}
++
++static int octeon_mgmt_get_settings(struct net_device *netdev,
++ struct ethtool_cmd *cmd)
++{
++ struct octeon_mgmt *p = netdev_priv(netdev);
++
++ if (p->phydev)
++ return phy_ethtool_gset(p->phydev, cmd);
++
++ return -EINVAL;
++}
++
++static int octeon_mgmt_set_settings(struct net_device *netdev,
++ struct ethtool_cmd *cmd)
++{
++ struct octeon_mgmt *p = netdev_priv(netdev);
++
++ if (!capable(CAP_NET_ADMIN))
++ return -EPERM;
++
++ if (p->phydev)
++ return phy_ethtool_sset(p->phydev, cmd);
++
++ return -EINVAL;
++}
++
++static const struct ethtool_ops octeon_mgmt_ethtool_ops = {
++ .get_drvinfo = octeon_mgmt_get_drvinfo,
++ .get_link = ethtool_op_get_link,
++ .get_settings = octeon_mgmt_get_settings,
++ .set_settings = octeon_mgmt_set_settings
++};
++
++static const struct net_device_ops octeon_mgmt_ops = {
++ .ndo_open = octeon_mgmt_open,
++ .ndo_stop = octeon_mgmt_stop,
++ .ndo_start_xmit = octeon_mgmt_xmit,
++ .ndo_set_rx_mode = octeon_mgmt_set_rx_filtering,
++ .ndo_set_multicast_list = octeon_mgmt_set_rx_filtering,
++ .ndo_set_mac_address = octeon_mgmt_set_mac_address,
++ .ndo_do_ioctl = octeon_mgmt_ioctl,
++ .ndo_change_mtu = octeon_mgmt_change_mtu,
++#ifdef CONFIG_NET_POLL_CONTROLLER
++ .ndo_poll_controller = octeon_mgmt_poll_controller,
++#endif
++};
++
++static int __init octeon_mgmt_probe(struct platform_device *pdev)
++{
++ struct resource *res_irq;
++ struct net_device *netdev;
++ struct octeon_mgmt *p;
++ int i;
++
++ netdev = alloc_etherdev(sizeof(struct octeon_mgmt));
++ if (netdev == NULL)
++ return -ENOMEM;
++
++ dev_set_drvdata(&pdev->dev, netdev);
++ p = netdev_priv(netdev);
++ netif_napi_add(netdev, &p->napi, octeon_mgmt_napi_poll,
++ OCTEON_MGMT_NAPI_WEIGHT);
++
++ p->netdev = netdev;
++ p->dev = &pdev->dev;
++
++ p->port = pdev->id;
++ snprintf(netdev->name, IFNAMSIZ, "mgmt%d", p->port);
++
++ res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
++ if (!res_irq)
++ goto err;
++
++ p->irq = res_irq->start;
++ spin_lock_init(&p->lock);
++
++ skb_queue_head_init(&p->tx_list);
++ skb_queue_head_init(&p->rx_list);
++ tasklet_init(&p->tx_clean_tasklet,
++ octeon_mgmt_clean_tx_tasklet, (unsigned long)p);
++
++ netdev->netdev_ops = &octeon_mgmt_ops;
++ netdev->ethtool_ops = &octeon_mgmt_ethtool_ops;
++
++
++ /* The mgmt ports get the first N MACs. */
++ for (i = 0; i < 6; i++)
++ netdev->dev_addr[i] = octeon_bootinfo->mac_addr_base[i];
++ netdev->dev_addr[5] += p->port;
++
++ if (p->port >= octeon_bootinfo->mac_addr_count)
++ dev_err(&pdev->dev,
++ "Error %s: Using MAC outside of the assigned range: "
++ "%02x:%02x:%02x:%02x:%02x:%02x\n", netdev->name,
++ netdev->dev_addr[0], netdev->dev_addr[1],
++ netdev->dev_addr[2], netdev->dev_addr[3],
++ netdev->dev_addr[4], netdev->dev_addr[5]);
++
++ if (register_netdev(netdev))
++ goto err;
++
++ dev_info(&pdev->dev, "Version " DRV_VERSION "\n");
++ return 0;
++err:
++ free_netdev(netdev);
++ return -ENOENT;
++}
++
++static int __exit octeon_mgmt_remove(struct platform_device *pdev)
++{
++ struct net_device *netdev = dev_get_drvdata(&pdev->dev);
++
++ unregister_netdev(netdev);
++ free_netdev(netdev);
++ return 0;
++}
++
++static struct platform_driver octeon_mgmt_driver = {
++ .driver = {
++ .name = "octeon_mgmt",
++ .owner = THIS_MODULE,
++ },
++ .probe = octeon_mgmt_probe,
++ .remove = __exit_p(octeon_mgmt_remove),
++};
++
++extern void octeon_mdiobus_force_mod_depencency(void);
++
++static int __init octeon_mgmt_mod_init(void)
++{
++ /* Force our mdiobus driver module to be loaded first. */
++ octeon_mdiobus_force_mod_depencency();
++ return platform_driver_register(&octeon_mgmt_driver);
++}
++
++static void __exit octeon_mgmt_mod_exit(void)
++{
++ platform_driver_unregister(&octeon_mgmt_driver);
++}
++
++module_init(octeon_mgmt_mod_init);
++module_exit(octeon_mgmt_mod_exit);
++
++MODULE_DESCRIPTION(DRV_DESCRIPTION);
++MODULE_AUTHOR("David Daney");
++MODULE_LICENSE("GPL");
++MODULE_VERSION(DRV_VERSION);
+diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
+index d5d8e1c..fc5938b 100644
+--- a/drivers/net/phy/Kconfig
++++ b/drivers/net/phy/Kconfig
+@@ -115,4 +115,15 @@ config MDIO_GPIO
+ To compile this driver as a module, choose M here: the module
+ will be called mdio-gpio.
+
++config MDIO_OCTEON
++ tristate "Support for MDIO buses on Octeon SOCs"
++ depends on CPU_CAVIUM_OCTEON
++ default y
++ help
++
++ This module provides a driver for the Octeon MDIO busses.
++ It is required by the Octeon Ethernet device drivers.
++
++ If in doubt, say Y.
++
+ endif # PHYLIB
+diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
+index edfaac4..1342585 100644
+--- a/drivers/net/phy/Makefile
++++ b/drivers/net/phy/Makefile
+@@ -20,3 +20,4 @@ obj-$(CONFIG_MDIO_BITBANG) += mdio-bitbang.o
+ obj-$(CONFIG_MDIO_GPIO) += mdio-gpio.o
+ obj-$(CONFIG_NATIONAL_PHY) += national.o
+ obj-$(CONFIG_STE10XP) += ste10Xp.o
++obj-$(CONFIG_MDIO_OCTEON) += mdio-octeon.o
+diff --git a/drivers/net/phy/mdio-octeon.c b/drivers/net/phy/mdio-octeon.c
+new file mode 100644
+index 0000000..61a4461
+--- /dev/null
++++ b/drivers/net/phy/mdio-octeon.c
+@@ -0,0 +1,180 @@
++/*
++ * 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) 2009 Cavium Networks
++ */
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/phy.h>
++
++#include <asm/octeon/octeon.h>
++#include <asm/octeon/cvmx-smix-defs.h>
++
++#define DRV_VERSION "1.0"
++#define DRV_DESCRIPTION "Cavium Networks Octeon SMI/MDIO driver"
++
++struct octeon_mdiobus {
++ struct mii_bus *mii_bus;
++ int unit;
++ int phy_irq[PHY_MAX_ADDR];
++};
++
++static int octeon_mdiobus_read(struct mii_bus *bus, int phy_id, int regnum)
++{
++ struct octeon_mdiobus *p = bus->priv;
++ union cvmx_smix_cmd smi_cmd;
++ union cvmx_smix_rd_dat smi_rd;
++ int timeout = 1000;
++
++ smi_cmd.u64 = 0;
++ smi_cmd.s.phy_op = 1; /* MDIO_CLAUSE_22_READ */
++ smi_cmd.s.phy_adr = phy_id;
++ smi_cmd.s.reg_adr = regnum;
++ cvmx_write_csr(CVMX_SMIX_CMD(p->unit), smi_cmd.u64);
++
++ do {
++ /*
++ * Wait 1000 clocks so we don't saturate the RSL bus
++ * doing reads.
++ */
++ cvmx_wait(1000);
++ smi_rd.u64 = cvmx_read_csr(CVMX_SMIX_RD_DAT(p->unit));
++ } while (smi_rd.s.pending && --timeout);
++
++ if (smi_rd.s.val)
++ return smi_rd.s.dat;
++ else
++ return -EIO;
++}
++
++static int octeon_mdiobus_write(struct mii_bus *bus, int phy_id,
++ int regnum, u16 val)
++{
++ struct octeon_mdiobus *p = bus->priv;
++ union cvmx_smix_cmd smi_cmd;
++ union cvmx_smix_wr_dat smi_wr;
++ int timeout = 1000;
++
++ smi_wr.u64 = 0;
++ smi_wr.s.dat = val;
++ cvmx_write_csr(CVMX_SMIX_WR_DAT(p->unit), smi_wr.u64);
++
++ smi_cmd.u64 = 0;
++ smi_cmd.s.phy_op = 0; /* MDIO_CLAUSE_22_WRITE */
++ smi_cmd.s.phy_adr = phy_id;
++ smi_cmd.s.reg_adr = regnum;
++ cvmx_write_csr(CVMX_SMIX_CMD(p->unit), smi_cmd.u64);
++
++ do {
++ /*
++ * Wait 1000 clocks so we don't saturate the RSL bus
++ * doing reads.
++ */
++ cvmx_wait(1000);
++ smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(p->unit));
++ } while (smi_wr.s.pending && --timeout);
++
++ if (timeout <= 0)
++ return -EIO;
++
++ return 0;
++}
++
++static int __init octeon_mdiobus_probe(struct platform_device *pdev)
++{
++ struct octeon_mdiobus *bus;
++ int i;
++ int err = -ENOENT;
++
++ bus = devm_kzalloc(&pdev->dev, sizeof(*bus), GFP_KERNEL);
++ if (!bus)
++ return -ENOMEM;
++
++ /* The platform_device id is our unit number. */
++ bus->unit = pdev->id;
++
++ bus->mii_bus = mdiobus_alloc();
++
++ if (!bus->mii_bus)
++ goto err;
++
++ /*
++ * Standard Octeon evaluation boards don't support phy
++ * interrupts, we need to poll.
++ */
++ for (i = 0; i < PHY_MAX_ADDR; i++)
++ bus->phy_irq[i] = PHY_POLL;
++
++ bus->mii_bus->priv = bus;
++ bus->mii_bus->irq = bus->phy_irq;
++ bus->mii_bus->name = "mdio-octeon";
++ snprintf(bus->mii_bus->id, MII_BUS_ID_SIZE, "%x", bus->unit);
++ bus->mii_bus->parent = &pdev->dev;
++
++ bus->mii_bus->read = octeon_mdiobus_read;
++ bus->mii_bus->write = octeon_mdiobus_write;
++
++ dev_set_drvdata(&pdev->dev, bus);
++
++ err = mdiobus_register(bus->mii_bus);
++ if (err)
++ goto err_register;
++
++ dev_info(&pdev->dev, "Version " DRV_VERSION "\n");
++
++ return 0;
++err_register:
++ mdiobus_free(bus->mii_bus);
++
++err:
++ devm_kfree(&pdev->dev, bus);
++ return err;
++}
++
++static int __exit octeon_mdiobus_remove(struct platform_device *pdev)
++{
++ struct octeon_mdiobus *bus;
++
++ bus = dev_get_drvdata(&pdev->dev);
++
++ mdiobus_unregister(bus->mii_bus);
++ mdiobus_free(bus->mii_bus);
++ return 0;
++}
++
++static struct platform_driver octeon_mdiobus_driver = {
++ .driver = {
++ .name = "mdio-octeon",
++ .owner = THIS_MODULE,
++ },
++ .probe = octeon_mdiobus_probe,
++ .remove = __exit_p(octeon_mdiobus_remove),
++};
++
++void octeon_mdiobus_force_mod_depencency(void)
++{
++ /* Let ethernet drivers force us to be loaded. */
++}
++EXPORT_SYMBOL(octeon_mdiobus_force_mod_depencency);
++
++static int __init octeon_mdiobus_mod_init(void)
++{
++ return platform_driver_register(&octeon_mdiobus_driver);
++}
++
++static void __exit octeon_mdiobus_mod_exit(void)
++{
++ platform_driver_unregister(&octeon_mdiobus_driver);
++}
++
++module_init(octeon_mdiobus_mod_init);
++module_exit(octeon_mdiobus_mod_exit);
++
++MODULE_DESCRIPTION(DRV_DESCRIPTION);
++MODULE_VERSION(DRV_VERSION);
++MODULE_AUTHOR("David Daney");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/net/titan_ge.c b/drivers/net/titan_ge.c
+new file mode 100644
+index 0000000..dc137bf
+--- /dev/null
++++ b/drivers/net/titan_ge.c
+@@ -0,0 +1,2069 @@
++/*
++ * drivers/net/titan_ge.c - Driver for Titan ethernet ports
++ *
++ * Copyright (C) 2003 PMC-Sierra Inc.
++ * Author : Manish Lachwani (lachwani@pmc-sierra.com)
++ *
++ * 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 MAC unit of the Titan consists of the following:
++ *
++ * -> XDMA Engine to move data to from the memory to the MAC packet FIFO
++ * -> FIFO is where the incoming and outgoing data is placed
++ * -> TRTG is the unit that pulls the data from the FIFO for Tx and pushes
++ * the data into the FIFO for Rx
++ * -> TMAC is the outgoing MAC interface and RMAC is the incoming.
++ * -> AFX is the address filtering block
++ * -> GMII block to communicate with the PHY
++ *
++ * Rx will look like the following:
++ * GMII --> RMAC --> AFX --> TRTG --> Rx FIFO --> XDMA --> CPU memory
++ *
++ * Tx will look like the following:
++ * CPU memory --> XDMA --> Tx FIFO --> TRTG --> TMAC --> GMII
++ *
++ * The Titan driver has support for the following performance features:
++ * -> Rx side checksumming
++ * -> Jumbo Frames
++ * -> Interrupt Coalscing
++ * -> Rx NAPI
++ * -> SKB Recycling
++ * -> Transmit/Receive descriptors in SRAM
++ * -> Fast routing for IP forwarding
++ */
++
++#include <linux/dma-mapping.h>
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/ioport.h>
++#include <linux/interrupt.h>
++#include <linux/slab.h>
++#include <linux/string.h>
++#include <linux/errno.h>
++#include <linux/ip.h>
++#include <linux/init.h>
++#include <linux/in.h>
++#include <linux/platform_device.h>
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/skbuff.h>
++#include <linux/mii.h>
++#include <linux/delay.h>
++#include <linux/skbuff.h>
++#include <linux/prefetch.h>
++
++/* For MII specifc registers, titan_mdio.h should be included */
++#include <net/ip.h>
++
++#include <asm/bitops.h>
++#include <asm/io.h>
++#include <asm/types.h>
++#include <asm/pgtable.h>
++#include <asm/system.h>
++#include <asm/titan_dep.h>
++
++#include "titan_ge.h"
++#include "titan_mdio.h"
++
++/* Static Function Declarations */
++static int titan_ge_eth_open(struct net_device *);
++static void titan_ge_eth_stop(struct net_device *);
++static struct net_device_stats *titan_ge_get_stats(struct net_device *);
++static int titan_ge_init_rx_desc_ring(titan_ge_port_info *, int, int,
++ unsigned long, unsigned long,
++ unsigned long);
++static int titan_ge_init_tx_desc_ring(titan_ge_port_info *, int,
++ unsigned long, unsigned long);
++
++static int titan_ge_open(struct net_device *);
++static int titan_ge_start_xmit(struct sk_buff *, struct net_device *);
++static int titan_ge_stop(struct net_device *);
++
++static unsigned long titan_ge_tx_coal(unsigned long, int);
++
++static void titan_ge_port_reset(unsigned int);
++static int titan_ge_free_tx_queue(titan_ge_port_info *);
++static int titan_ge_rx_task(struct net_device *, titan_ge_port_info *);
++static int titan_ge_port_start(struct net_device *, titan_ge_port_info *);
++
++static int titan_ge_return_tx_desc(titan_ge_port_info *, int);
++
++/*
++ * Some configuration for the FIFO and the XDMA channel needs
++ * to be done only once for all the ports. This flag controls
++ * that
++ */
++static unsigned long config_done;
++
++/*
++ * One time out of memory flag
++ */
++static unsigned int oom_flag;
++
++static int titan_ge_poll(struct net_device *netdev, int *budget);
++
++static int titan_ge_receive_queue(struct net_device *, unsigned int);
++
++static struct platform_device *titan_ge_device[3];
++
++/* MAC Address */
++extern unsigned char titan_ge_mac_addr_base[6];
++
++unsigned long titan_ge_base;
++static unsigned long titan_ge_sram;
++
++static char titan_string[] = "titan";
++
++/*
++ * The Titan GE has two alignment requirements:
++ * -> skb->data to be cacheline aligned (32 byte)
++ * -> IP header alignment to 16 bytes
++ *
++ * The latter is not implemented. So, that results in an extra copy on
++ * the Rx. This is a big performance hog. For the former case, the
++ * dev_alloc_skb() has been replaced with titan_ge_alloc_skb(). The size
++ * requested is calculated:
++ *
++ * Ethernet Frame Size : 1518
++ * Ethernet Header : 14
++ * Future Titan change for IP header alignment : 2
++ *
++ * Hence, we allocate (1518 + 14 + 2+ 64) = 1580 bytes. For IP header
++ * alignment, we use skb_reserve().
++ */
++
++#define ALIGNED_RX_SKB_ADDR(addr) \
++ ((((unsigned long)(addr) + (64UL - 1UL)) \
++ & ~(64UL - 1UL)) - (unsigned long)(addr))
++
++#define titan_ge_alloc_skb(__length, __gfp_flags) \
++({ struct sk_buff *__skb; \
++ __skb = alloc_skb((__length) + 64, (__gfp_flags)); \
++ if(__skb) { \
++ int __offset = (int) ALIGNED_RX_SKB_ADDR(__skb->data); \
++ if(__offset) \
++ skb_reserve(__skb, __offset); \
++ } \
++ __skb; \
++})
++
++/*
++ * Configure the GMII block of the Titan based on what the PHY tells us
++ */
++static void titan_ge_gmii_config(int port_num)
++{
++ unsigned int reg_data = 0, phy_reg;
++ int err;
++
++ err = titan_ge_mdio_read(port_num, TITAN_GE_MDIO_PHY_STATUS, &phy_reg);
++
++ if (err == TITAN_GE_MDIO_ERROR) {
++ printk(KERN_ERR
++ "Could not read PHY control register 0x11 \n");
++ printk(KERN_ERR
++ "Setting speed to 1000 Mbps and Duplex to Full \n");
++
++ return;
++ }
++
++ err = titan_ge_mdio_write(port_num, TITAN_GE_MDIO_PHY_IE, 0);
++
++ if (phy_reg & 0x8000) {
++ if (phy_reg & 0x2000) {
++ /* Full Duplex and 1000 Mbps */
++ TITAN_GE_WRITE((TITAN_GE_GMII_CONFIG_MODE +
++ (port_num << 12)), 0x201);
++ } else {
++ /* Half Duplex and 1000 Mbps */
++ TITAN_GE_WRITE((TITAN_GE_GMII_CONFIG_MODE +
++ (port_num << 12)), 0x2201);
++ }
++ }
++ if (phy_reg & 0x4000) {
++ if (phy_reg & 0x2000) {
++ /* Full Duplex and 100 Mbps */
++ TITAN_GE_WRITE((TITAN_GE_GMII_CONFIG_MODE +
++ (port_num << 12)), 0x100);
++ } else {
++ /* Half Duplex and 100 Mbps */
++ TITAN_GE_WRITE((TITAN_GE_GMII_CONFIG_MODE +
++ (port_num << 12)), 0x2100);
++ }
++ }
++ reg_data = TITAN_GE_READ(TITAN_GE_GMII_CONFIG_GENERAL +
++ (port_num << 12));
++ reg_data |= 0x3;
++ TITAN_GE_WRITE((TITAN_GE_GMII_CONFIG_GENERAL +
++ (port_num << 12)), reg_data);
++}
++
++/*
++ * Enable the TMAC if it is not
++ */
++static void titan_ge_enable_tx(unsigned int port_num)
++{
++ unsigned long reg_data;
++
++ reg_data = TITAN_GE_READ(TITAN_GE_TMAC_CONFIG_1 + (port_num << 12));
++ if (!(reg_data & 0x8000)) {
++ printk("TMAC disabled for port %d!! \n", port_num);
++
++ reg_data |= 0x0001; /* Enable TMAC */
++ reg_data |= 0x4000; /* CRC Check Enable */
++ reg_data |= 0x2000; /* Padding enable */
++ reg_data |= 0x0800; /* CRC Add enable */
++ reg_data |= 0x0080; /* PAUSE frame */
++
++ TITAN_GE_WRITE((TITAN_GE_TMAC_CONFIG_1 +
++ (port_num << 12)), reg_data);
++ }
++}
++
++/*
++ * Tx Timeout function
++ */
++static void titan_ge_tx_timeout(struct net_device *netdev)
++{
++ titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
++
++ printk(KERN_INFO "%s: TX timeout ", netdev->name);
++ printk(KERN_INFO "Resetting card \n");
++
++ /* Do the reset outside of interrupt context */
++ schedule_work(&titan_ge_eth->tx_timeout_task);
++}
++
++/*
++ * Update the AFX tables for UC and MC for slice 0 only
++ */
++static void titan_ge_update_afx(titan_ge_port_info * titan_ge_eth)
++{
++ int port = titan_ge_eth->port_num;
++ unsigned int i;
++ volatile unsigned long reg_data = 0;
++ u8 p_addr[6];
++
++ memcpy(p_addr, titan_ge_eth->port_mac_addr, 6);
++
++ /* Set the MAC address here for TMAC and RMAC */
++ TITAN_GE_WRITE((TITAN_GE_TMAC_STATION_HI + (port << 12)),
++ ((p_addr[5] << 8) | p_addr[4]));
++ TITAN_GE_WRITE((TITAN_GE_TMAC_STATION_MID + (port << 12)),
++ ((p_addr[3] << 8) | p_addr[2]));
++ TITAN_GE_WRITE((TITAN_GE_TMAC_STATION_LOW + (port << 12)),
++ ((p_addr[1] << 8) | p_addr[0]));
++
++ TITAN_GE_WRITE((TITAN_GE_RMAC_STATION_HI + (port << 12)),
++ ((p_addr[5] << 8) | p_addr[4]));
++ TITAN_GE_WRITE((TITAN_GE_RMAC_STATION_MID + (port << 12)),
++ ((p_addr[3] << 8) | p_addr[2]));
++ TITAN_GE_WRITE((TITAN_GE_RMAC_STATION_LOW + (port << 12)),
++ ((p_addr[1] << 8) | p_addr[0]));
++
++ TITAN_GE_WRITE((0x112c | (port << 12)), 0x1);
++ /* Configure the eight address filters */
++ for (i = 0; i < 8; i++) {
++ /* Select each of the eight filters */
++ TITAN_GE_WRITE((TITAN_GE_AFX_ADDRS_FILTER_CTRL_2 +
++ (port << 12)), i);
++
++ /* Configure the match */
++ reg_data = 0x9; /* Forward Enable Bit */
++ TITAN_GE_WRITE((TITAN_GE_AFX_ADDRS_FILTER_CTRL_0 +
++ (port << 12)), reg_data);
++
++ /* Finally, AFX Exact Match Address Registers */
++ TITAN_GE_WRITE((TITAN_GE_AFX_EXACT_MATCH_LOW + (port << 12)),
++ ((p_addr[1] << 8) | p_addr[0]));
++ TITAN_GE_WRITE((TITAN_GE_AFX_EXACT_MATCH_MID + (port << 12)),
++ ((p_addr[3] << 8) | p_addr[2]));
++ TITAN_GE_WRITE((TITAN_GE_AFX_EXACT_MATCH_HIGH + (port << 12)),
++ ((p_addr[5] << 8) | p_addr[4]));
++
++ /* VLAN id set to 0 */
++ TITAN_GE_WRITE((TITAN_GE_AFX_EXACT_MATCH_VID +
++ (port << 12)), 0);
++ }
++}
++
++/*
++ * Actual Routine to reset the adapter when the timeout occurred
++ */
++static void titan_ge_tx_timeout_task(struct net_device *netdev)
++{
++ titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
++ int port = titan_ge_eth->port_num;
++
++ printk("Titan GE: Transmit timed out. Resetting ... \n");
++
++ /* Dump debug info */
++ printk(KERN_ERR "TRTG cause : %x \n",
++ TITAN_GE_READ(0x100c + (port << 12)));
++
++ /* Fix this for the other ports */
++ printk(KERN_ERR "FIFO cause : %x \n", TITAN_GE_READ(0x482c));
++ printk(KERN_ERR "IE cause : %x \n", TITAN_GE_READ(0x0040));
++ printk(KERN_ERR "XDMA GDI ERROR : %x \n",
++ TITAN_GE_READ(0x5008 + (port << 8)));
++ printk(KERN_ERR "CHANNEL ERROR: %x \n",
++ TITAN_GE_READ(TITAN_GE_CHANNEL0_INTERRUPT
++ + (port << 8)));
++
++ netif_device_detach(netdev);
++ titan_ge_port_reset(titan_ge_eth->port_num);
++ titan_ge_port_start(netdev, titan_ge_eth);
++ netif_device_attach(netdev);
++}
++
++/*
++ * Change the MTU of the Ethernet Device
++ */
++static int titan_ge_change_mtu(struct net_device *netdev, int new_mtu)
++{
++ titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
++ unsigned long flags;
++
++ if ((new_mtu > 9500) || (new_mtu < 64))
++ return -EINVAL;
++
++ spin_lock_irqsave(&titan_ge_eth->lock, flags);
++
++ netdev->mtu = new_mtu;
++
++ /* Now we have to reopen the interface so that SKBs with the new
++ * size will be allocated */
++
++ if (netif_running(netdev)) {
++ titan_ge_eth_stop(netdev);
++
++ if (titan_ge_eth_open(netdev) != TITAN_OK) {
++ printk(KERN_ERR
++ "%s: Fatal error on opening device\n",
++ netdev->name);
++ spin_unlock_irqrestore(&titan_ge_eth->lock, flags);
++ return -1;
++ }
++ }
++
++ spin_unlock_irqrestore(&titan_ge_eth->lock, flags);
++ return 0;
++}
++
++/*
++ * Titan Gbe Interrupt Handler. All the three ports send interrupt to one line
++ * only. Once an interrupt is triggered, figure out the port and then check
++ * the channel.
++ */
++static irqreturn_t titan_ge_int_handler(int irq, void *dev_id)
++{
++ struct net_device *netdev = (struct net_device *) dev_id;
++ titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
++ unsigned int port_num = titan_ge_eth->port_num;
++ unsigned int reg_data;
++ unsigned int eth_int_cause_error = 0, is;
++ unsigned long eth_int_cause1;
++ int err = 0;
++#ifdef CONFIG_SMP
++ unsigned long eth_int_cause2;
++#endif
++
++ /* Ack the CPU interrupt */
++ switch (port_num) {
++ case 0:
++ is = OCD_READ(RM9000x2_OCD_INTP0STATUS1);
++ OCD_WRITE(RM9000x2_OCD_INTP0CLEAR1, is);
++
++#ifdef CONFIG_SMP
++ is = OCD_READ(RM9000x2_OCD_INTP1STATUS1);
++ OCD_WRITE(RM9000x2_OCD_INTP1CLEAR1, is);
++#endif
++ break;
++
++ case 1:
++ is = OCD_READ(RM9000x2_OCD_INTP0STATUS0);
++ OCD_WRITE(RM9000x2_OCD_INTP0CLEAR0, is);
++
++#ifdef CONFIG_SMP
++ is = OCD_READ(RM9000x2_OCD_INTP1STATUS0);
++ OCD_WRITE(RM9000x2_OCD_INTP1CLEAR0, is);
++#endif
++ break;
++
++ case 2:
++ is = OCD_READ(RM9000x2_OCD_INTP0STATUS4);
++ OCD_WRITE(RM9000x2_OCD_INTP0CLEAR4, is);
++
++#ifdef CONFIG_SMP
++ is = OCD_READ(RM9000x2_OCD_INTP1STATUS4);
++ OCD_WRITE(RM9000x2_OCD_INTP1CLEAR4, is);
++#endif
++ }
++
++ eth_int_cause1 = TITAN_GE_READ(TITAN_GE_INTR_XDMA_CORE_A);
++#ifdef CONFIG_SMP
++ eth_int_cause2 = TITAN_GE_READ(TITAN_GE_INTR_XDMA_CORE_B);
++#endif
++
++ /* Spurious interrupt */
++#ifdef CONFIG_SMP
++ if ( (eth_int_cause1 == 0) && (eth_int_cause2 == 0)) {
++#else
++ if (eth_int_cause1 == 0) {
++#endif
++ eth_int_cause_error = TITAN_GE_READ(TITAN_GE_CHANNEL0_INTERRUPT +
++ (port_num << 8));
++
++ if (eth_int_cause_error == 0)
++ return IRQ_NONE;
++ }
++
++ /* Handle Tx first. No need to ack interrupts */
++#ifdef CONFIG_SMP
++ if ( (eth_int_cause1 & 0x20202) ||
++ (eth_int_cause2 & 0x20202) )
++#else
++ if (eth_int_cause1 & 0x20202)
++#endif
++ titan_ge_free_tx_queue(titan_ge_eth);
++
++ /* Handle the Rx next */
++#ifdef CONFIG_SMP
++ if ( (eth_int_cause1 & 0x10101) ||
++ (eth_int_cause2 & 0x10101)) {
++#else
++ if (eth_int_cause1 & 0x10101) {
++#endif
++ if (netif_rx_schedule_prep(netdev)) {
++ unsigned int ack;
++
++ ack = TITAN_GE_READ(TITAN_GE_INTR_XDMA_IE);
++ /* Disable Tx and Rx both */
++ if (port_num == 0)
++ ack &= ~(0x3);
++ if (port_num == 1)
++ ack &= ~(0x300);
++
++ if (port_num == 2)
++ ack &= ~(0x30000);
++
++ /* Interrupts have been disabled */
++ TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_IE, ack);
++
++ __netif_rx_schedule(netdev);
++ }
++ }
++
++ /* Handle error interrupts */
++ if (eth_int_cause_error && (eth_int_cause_error != 0x2)) {
++ printk(KERN_ERR
++ "XDMA Channel Error : %x on port %d\n",
++ eth_int_cause_error, port_num);
++
++ printk(KERN_ERR
++ "XDMA GDI Hardware error : %x on port %d\n",
++ TITAN_GE_READ(0x5008 + (port_num << 8)), port_num);
++
++ printk(KERN_ERR
++ "XDMA currently has %d Rx descriptors \n",
++ TITAN_GE_READ(0x5048 + (port_num << 8)));
++
++ printk(KERN_ERR
++ "XDMA currently has prefetcted %d Rx descriptors \n",
++ TITAN_GE_READ(0x505c + (port_num << 8)));
++
++ TITAN_GE_WRITE((TITAN_GE_CHANNEL0_INTERRUPT +
++ (port_num << 8)), eth_int_cause_error);
++ }
++
++ /*
++ * PHY interrupt to inform abt the changes. Reading the
++ * PHY Status register will clear the interrupt
++ */
++ if ((!(eth_int_cause1 & 0x30303)) &&
++ (eth_int_cause_error == 0)) {
++ err =
++ titan_ge_mdio_read(port_num,
++ TITAN_GE_MDIO_PHY_IS, &reg_data);
++
++ if (reg_data & 0x0400) {
++ /* Link status change */
++ titan_ge_mdio_read(port_num,
++ TITAN_GE_MDIO_PHY_STATUS, &reg_data);
++ if (!(reg_data & 0x0400)) {
++ /* Link is down */
++ netif_carrier_off(netdev);
++ netif_stop_queue(netdev);
++ } else {
++ /* Link is up */
++ netif_carrier_on(netdev);
++ netif_wake_queue(netdev);
++
++ /* Enable the queue */
++ titan_ge_enable_tx(port_num);
++ }
++ }
++ }
++
++ return IRQ_HANDLED;
++}
++
++/*
++ * Multicast and Promiscuous mode set. The
++ * set_multi entry point is called whenever the
++ * multicast address list or the network interface
++ * flags are updated.
++ */
++static void titan_ge_set_multi(struct net_device *netdev)
++{
++ titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
++ unsigned int port_num = titan_ge_eth->port_num;
++ unsigned long reg_data;
++
++ reg_data = TITAN_GE_READ(TITAN_GE_AFX_ADDRS_FILTER_CTRL_1 +
++ (port_num << 12));
++
++ if (netdev->flags & IFF_PROMISC) {
++ reg_data |= 0x2;
++ }
++ else if (netdev->flags & IFF_ALLMULTI) {
++ reg_data |= 0x01;
++ reg_data |= 0x400; /* Use the 64-bit Multicast Hash bin */
++ }
++ else {
++ reg_data = 0x2;
++ }
++
++ TITAN_GE_WRITE((TITAN_GE_AFX_ADDRS_FILTER_CTRL_1 +
++ (port_num << 12)), reg_data);
++ if (reg_data & 0x01) {
++ TITAN_GE_WRITE((TITAN_GE_AFX_MULTICAST_HASH_LOW +
++ (port_num << 12)), 0xffff);
++ TITAN_GE_WRITE((TITAN_GE_AFX_MULTICAST_HASH_MIDLOW +
++ (port_num << 12)), 0xffff);
++ TITAN_GE_WRITE((TITAN_GE_AFX_MULTICAST_HASH_MIDHI +
++ (port_num << 12)), 0xffff);
++ TITAN_GE_WRITE((TITAN_GE_AFX_MULTICAST_HASH_HI +
++ (port_num << 12)), 0xffff);
++ }
++}
++
++/*
++ * Open the network device
++ */
++static int titan_ge_open(struct net_device *netdev)
++{
++ titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
++ unsigned int port_num = titan_ge_eth->port_num;
++ unsigned int irq = TITAN_ETH_PORT_IRQ - port_num;
++ int retval;
++
++ retval = request_irq(irq, titan_ge_int_handler,
++ SA_INTERRUPT | SA_SAMPLE_RANDOM , netdev->name, netdev);
++
++ if (retval != 0) {
++ printk(KERN_ERR "Cannot assign IRQ number to TITAN GE \n");
++ return -1;
++ }
++
++ netdev->irq = irq;
++ printk(KERN_INFO "Assigned IRQ %d to port %d\n", irq, port_num);
++
++ spin_lock_irq(&(titan_ge_eth->lock));
++
++ if (titan_ge_eth_open(netdev) != TITAN_OK) {
++ spin_unlock_irq(&(titan_ge_eth->lock));
++ printk("%s: Error opening interface \n", netdev->name);
++ free_irq(netdev->irq, netdev);
++ return -EBUSY;
++ }
++
++ spin_unlock_irq(&(titan_ge_eth->lock));
++
++ return 0;
++}
++
++/*
++ * Allocate the SKBs for the Rx ring. Also used
++ * for refilling the queue
++ */
++static int titan_ge_rx_task(struct net_device *netdev,
++ titan_ge_port_info *titan_ge_port)
++{
++ struct device *device = &titan_ge_device[titan_ge_port->port_num]->dev;
++ volatile titan_ge_rx_desc *rx_desc;
++ struct sk_buff *skb;
++ int rx_used_desc;
++ int count = 0;
++
++ while (titan_ge_port->rx_ring_skbs < titan_ge_port->rx_ring_size) {
++
++ /* First try to get the skb from the recycler */
++#ifdef TITAN_GE_JUMBO_FRAMES
++ skb = titan_ge_alloc_skb(TITAN_GE_JUMBO_BUFSIZE, GFP_ATOMIC);
++#else
++ skb = titan_ge_alloc_skb(TITAN_GE_STD_BUFSIZE, GFP_ATOMIC);
++#endif
++ if (unlikely(!skb)) {
++ /* OOM, set the flag */
++ printk("OOM \n");
++ oom_flag = 1;
++ break;
++ }
++ count++;
++ skb->dev = netdev;
++
++ titan_ge_port->rx_ring_skbs++;
++
++ rx_used_desc = titan_ge_port->rx_used_desc_q;
++ rx_desc = &(titan_ge_port->rx_desc_area[rx_used_desc]);
++
++#ifdef TITAN_GE_JUMBO_FRAMES
++ rx_desc->buffer_addr = dma_map_single(device, skb->data,
++ TITAN_GE_JUMBO_BUFSIZE - 2, DMA_FROM_DEVICE);
++#else
++ rx_desc->buffer_addr = dma_map_single(device, skb->data,
++ TITAN_GE_STD_BUFSIZE - 2, DMA_FROM_DEVICE);
++#endif
++
++ titan_ge_port->rx_skb[rx_used_desc] = skb;
++ rx_desc->cmd_sts = TITAN_GE_RX_BUFFER_OWNED;
++
++ titan_ge_port->rx_used_desc_q =
++ (rx_used_desc + 1) % TITAN_GE_RX_QUEUE;
++ }
++
++ return count;
++}
++
++/*
++ * Actual init of the Tital GE port. There is one register for
++ * the channel configuration
++ */
++static void titan_port_init(struct net_device *netdev,
++ titan_ge_port_info * titan_ge_eth)
++{
++ unsigned long reg_data;
++
++ titan_ge_port_reset(titan_ge_eth->port_num);
++
++ /* First reset the TMAC */
++ reg_data = TITAN_GE_READ(TITAN_GE_CHANNEL0_CONFIG);
++ reg_data |= 0x80000000;
++ TITAN_GE_WRITE(TITAN_GE_CHANNEL0_CONFIG, reg_data);
++
++ udelay(30);
++
++ reg_data = TITAN_GE_READ(TITAN_GE_CHANNEL0_CONFIG);
++ reg_data &= ~(0xc0000000);
++ TITAN_GE_WRITE(TITAN_GE_CHANNEL0_CONFIG, reg_data);
++
++ /* Now reset the RMAC */
++ reg_data = TITAN_GE_READ(TITAN_GE_CHANNEL0_CONFIG);
++ reg_data |= 0x00080000;
++ TITAN_GE_WRITE(TITAN_GE_CHANNEL0_CONFIG, reg_data);
++
++ udelay(30);
++
++ reg_data = TITAN_GE_READ(TITAN_GE_CHANNEL0_CONFIG);
++ reg_data &= ~(0x000c0000);
++ TITAN_GE_WRITE(TITAN_GE_CHANNEL0_CONFIG, reg_data);
++}
++
++/*
++ * Start the port. All the hardware specific configuration
++ * for the XDMA, Tx FIFO, Rx FIFO, TMAC, RMAC, TRTG and AFX
++ * go here
++ */
++static int titan_ge_port_start(struct net_device *netdev,
++ titan_ge_port_info * titan_port)
++{
++ volatile unsigned long reg_data, reg_data1;
++ int port_num = titan_port->port_num;
++ int count = 0;
++ unsigned long reg_data_1;
++
++ if (config_done == 0) {
++ reg_data = TITAN_GE_READ(0x0004);
++ reg_data |= 0x100;
++ TITAN_GE_WRITE(0x0004, reg_data);
++
++ reg_data &= ~(0x100);
++ TITAN_GE_WRITE(0x0004, reg_data);
++
++ /* Turn on GMII/MII mode and turn off TBI mode */
++ reg_data = TITAN_GE_READ(TITAN_GE_TSB_CTRL_1);
++ reg_data |= 0x00000700;
++ reg_data &= ~(0x00800000); /* Fencing */
++
++ TITAN_GE_WRITE(0x000c, 0x00001100);
++
++ TITAN_GE_WRITE(TITAN_GE_TSB_CTRL_1, reg_data);
++
++ /* Set the CPU Resource Limit register */
++ TITAN_GE_WRITE(0x00f8, 0x8);
++
++ /* Be conservative when using the BIU buffers */
++ TITAN_GE_WRITE(0x0068, 0x4);
++ }
++
++ titan_port->tx_threshold = 0;
++ titan_port->rx_threshold = 0;
++
++ /* We need to write the descriptors for Tx and Rx */
++ TITAN_GE_WRITE((TITAN_GE_CHANNEL0_TX_DESC + (port_num << 8)),
++ (unsigned long) titan_port->tx_dma);
++ TITAN_GE_WRITE((TITAN_GE_CHANNEL0_RX_DESC + (port_num << 8)),
++ (unsigned long) titan_port->rx_dma);
++
++ if (config_done == 0) {
++ /* Step 1: XDMA config */
++ reg_data = TITAN_GE_READ(TITAN_GE_XDMA_CONFIG);
++ reg_data &= ~(0x80000000); /* clear reset */
++ reg_data |= 0x1 << 29; /* sparse tx descriptor spacing */
++ reg_data |= 0x1 << 28; /* sparse rx descriptor spacing */
++ reg_data |= (0x1 << 23) | (0x1 << 24); /* Descriptor Coherency */
++ reg_data |= (0x1 << 21) | (0x1 << 22); /* Data Coherency */
++ TITAN_GE_WRITE(TITAN_GE_XDMA_CONFIG, reg_data);
++ }
++
++ /* IR register for the XDMA */
++ reg_data = TITAN_GE_READ(TITAN_GE_GDI_INTERRUPT_ENABLE + (port_num << 8));
++ reg_data |= 0x80068000; /* No Rx_OOD */
++ TITAN_GE_WRITE((TITAN_GE_GDI_INTERRUPT_ENABLE + (port_num << 8)), reg_data);
++
++ /* Start the Tx and Rx XDMA controller */
++ reg_data = TITAN_GE_READ(TITAN_GE_CHANNEL0_CONFIG + (port_num << 8));
++ reg_data &= 0x4fffffff; /* Clear tx reset */
++ reg_data &= 0xfff4ffff; /* Clear rx reset */
++
++#ifdef TITAN_GE_JUMBO_FRAMES
++ reg_data |= 0xa0 | 0x30030000;
++#else
++ reg_data |= 0x40 | 0x20030000;
++#endif
++
++#ifndef CONFIG_SMP
++ reg_data &= ~(0x10);
++ reg_data |= 0x0f; /* All of the packet */
++#endif
++
++ TITAN_GE_WRITE((TITAN_GE_CHANNEL0_CONFIG + (port_num << 8)), reg_data);
++
++ /* Rx desc count */
++ count = titan_ge_rx_task(netdev, titan_port);
++ TITAN_GE_WRITE((0x5048 + (port_num << 8)), count);
++ count = TITAN_GE_READ(0x5048 + (port_num << 8));
++
++ udelay(30);
++
++ /*
++ * Step 2: Configure the SDQPF, i.e. FIFO
++ */
++ if (config_done == 0) {
++ reg_data = TITAN_GE_READ(TITAN_GE_SDQPF_RXFIFO_CTL);
++ reg_data = 0x1;
++ TITAN_GE_WRITE(TITAN_GE_SDQPF_RXFIFO_CTL, reg_data);
++ reg_data &= ~(0x1);
++ TITAN_GE_WRITE(TITAN_GE_SDQPF_RXFIFO_CTL, reg_data);
++ reg_data = TITAN_GE_READ(TITAN_GE_SDQPF_RXFIFO_CTL);
++ TITAN_GE_WRITE(TITAN_GE_SDQPF_RXFIFO_CTL, reg_data);
++
++ reg_data = TITAN_GE_READ(TITAN_GE_SDQPF_TXFIFO_CTL);
++ reg_data = 0x1;
++ TITAN_GE_WRITE(TITAN_GE_SDQPF_TXFIFO_CTL, reg_data);
++ reg_data &= ~(0x1);
++ TITAN_GE_WRITE(TITAN_GE_SDQPF_TXFIFO_CTL, reg_data);
++ reg_data = TITAN_GE_READ(TITAN_GE_SDQPF_TXFIFO_CTL);
++ TITAN_GE_WRITE(TITAN_GE_SDQPF_TXFIFO_CTL, reg_data);
++ }
++ /*
++ * Enable RX FIFO 0, 4 and 8
++ */
++ if (port_num == 0) {
++ reg_data = TITAN_GE_READ(TITAN_GE_SDQPF_RXFIFO_0);
++
++ reg_data |= 0x100000;
++ reg_data |= (0xff << 10);
++
++ TITAN_GE_WRITE(TITAN_GE_SDQPF_RXFIFO_0, reg_data);
++ /*
++ * BAV2,BAV and DAV settings for the Rx FIFO
++ */
++ reg_data1 = TITAN_GE_READ(0x4844);
++ reg_data1 |= ( (0x10 << 20) | (0x10 << 10) | 0x1);
++ TITAN_GE_WRITE(0x4844, reg_data1);
++
++ reg_data &= ~(0x00100000);
++ reg_data |= 0x200000;
++
++ TITAN_GE_WRITE(TITAN_GE_SDQPF_RXFIFO_0, reg_data);
++
++ reg_data = TITAN_GE_READ(TITAN_GE_SDQPF_TXFIFO_0);
++ reg_data |= 0x100000;
++
++ TITAN_GE_WRITE(TITAN_GE_SDQPF_TXFIFO_0, reg_data);
++
++ reg_data |= (0xff << 10);
++
++ TITAN_GE_WRITE(TITAN_GE_SDQPF_TXFIFO_0, reg_data);
++
++ /*
++ * BAV2, BAV and DAV settings for the Tx FIFO
++ */
++ reg_data1 = TITAN_GE_READ(0x4944);
++ reg_data1 = ( (0x1 << 20) | (0x1 << 10) | 0x10);
++
++ TITAN_GE_WRITE(0x4944, reg_data1);
++
++ reg_data &= ~(0x00100000);
++ reg_data |= 0x200000;
++
++ TITAN_GE_WRITE(TITAN_GE_SDQPF_TXFIFO_0, reg_data);
++
++ }
++
++ if (port_num == 1) {
++ reg_data = TITAN_GE_READ(0x4870);
++
++ reg_data |= 0x100000;
++ reg_data |= (0xff << 10) | (0xff + 1);
++
++ TITAN_GE_WRITE(0x4870, reg_data);
++ /*
++ * BAV2,BAV and DAV settings for the Rx FIFO
++ */
++ reg_data1 = TITAN_GE_READ(0x4874);
++ reg_data1 |= ( (0x10 << 20) | (0x10 << 10) | 0x1);
++ TITAN_GE_WRITE(0x4874, reg_data1);
++
++ reg_data &= ~(0x00100000);
++ reg_data |= 0x200000;
++
++ TITAN_GE_WRITE(0x4870, reg_data);
++
++ reg_data = TITAN_GE_READ(0x494c);
++ reg_data |= 0x100000;
++
++ TITAN_GE_WRITE(0x494c, reg_data);
++ reg_data |= (0xff << 10) | (0xff + 1);
++ TITAN_GE_WRITE(0x494c, reg_data);
++
++ /*
++ * BAV2, BAV and DAV settings for the Tx FIFO
++ */
++ reg_data1 = TITAN_GE_READ(0x4950);
++ reg_data1 = ( (0x1 << 20) | (0x1 << 10) | 0x10);
++
++ TITAN_GE_WRITE(0x4950, reg_data1);
++
++ reg_data &= ~(0x00100000);
++ reg_data |= 0x200000;
++
++ TITAN_GE_WRITE(0x494c, reg_data);
++ }
++
++ /*
++ * Titan 1.2 revision does support port #2
++ */
++ if (port_num == 2) {
++ /*
++ * Put the descriptors in the SRAM
++ */
++ reg_data = TITAN_GE_READ(0x48a0);
++
++ reg_data |= 0x100000;
++ reg_data |= (0xff << 10) | (2*(0xff + 1));
++
++ TITAN_GE_WRITE(0x48a0, reg_data);
++ /*
++ * BAV2,BAV and DAV settings for the Rx FIFO
++ */
++ reg_data1 = TITAN_GE_READ(0x48a4);
++ reg_data1 |= ( (0x10 << 20) | (0x10 << 10) | 0x1);
++ TITAN_GE_WRITE(0x48a4, reg_data1);
++
++ reg_data &= ~(0x00100000);
++ reg_data |= 0x200000;
++
++ TITAN_GE_WRITE(0x48a0, reg_data);
++
++ reg_data = TITAN_GE_READ(0x4958);
++ reg_data |= 0x100000;
++
++ TITAN_GE_WRITE(0x4958, reg_data);
++ reg_data |= (0xff << 10) | (2*(0xff + 1));
++ TITAN_GE_WRITE(0x4958, reg_data);
++
++ /*
++ * BAV2, BAV and DAV settings for the Tx FIFO
++ */
++ reg_data1 = TITAN_GE_READ(0x495c);
++ reg_data1 = ( (0x1 << 20) | (0x1 << 10) | 0x10);
++
++ TITAN_GE_WRITE(0x495c, reg_data1);
++
++ reg_data &= ~(0x00100000);
++ reg_data |= 0x200000;
++
++ TITAN_GE_WRITE(0x4958, reg_data);
++ }
++
++ if (port_num == 2) {
++ reg_data = TITAN_GE_READ(0x48a0);
++
++ reg_data |= 0x100000;
++ reg_data |= (0xff << 10) | (2*(0xff + 1));
++
++ TITAN_GE_WRITE(0x48a0, reg_data);
++ /*
++ * BAV2,BAV and DAV settings for the Rx FIFO
++ */
++ reg_data1 = TITAN_GE_READ(0x48a4);
++ reg_data1 |= ( (0x10 << 20) | (0x10 << 10) | 0x1);
++ TITAN_GE_WRITE(0x48a4, reg_data1);
++
++ reg_data &= ~(0x00100000);
++ reg_data |= 0x200000;
++
++ TITAN_GE_WRITE(0x48a0, reg_data);
++
++ reg_data = TITAN_GE_READ(0x4958);
++ reg_data |= 0x100000;
++
++ TITAN_GE_WRITE(0x4958, reg_data);
++ reg_data |= (0xff << 10) | (2*(0xff + 1));
++ TITAN_GE_WRITE(0x4958, reg_data);
++
++ /*
++ * BAV2, BAV and DAV settings for the Tx FIFO
++ */
++ reg_data1 = TITAN_GE_READ(0x495c);
++ reg_data1 = ( (0x1 << 20) | (0x1 << 10) | 0x10);
++
++ TITAN_GE_WRITE(0x495c, reg_data1);
++
++ reg_data &= ~(0x00100000);
++ reg_data |= 0x200000;
++
++ TITAN_GE_WRITE(0x4958, reg_data);
++ }
++
++ /*
++ * Step 3: TRTG block enable
++ */
++ reg_data = TITAN_GE_READ(TITAN_GE_TRTG_CONFIG + (port_num << 12));
++
++ /*
++ * This is the 1.2 revision of the chip. It has fix for the
++ * IP header alignment. Now, the IP header begins at an
++ * aligned address and this wont need an extra copy in the
++ * driver. This performance drawback existed in the previous
++ * versions of the silicon
++ */
++ reg_data_1 = TITAN_GE_READ(0x103c + (port_num << 12));
++ reg_data_1 |= 0x40000000;
++ TITAN_GE_WRITE((0x103c + (port_num << 12)), reg_data_1);
++
++ reg_data_1 |= 0x04000000;
++ TITAN_GE_WRITE((0x103c + (port_num << 12)), reg_data_1);
++
++ mdelay(5);
++
++ reg_data_1 &= ~(0x04000000);
++ TITAN_GE_WRITE((0x103c + (port_num << 12)), reg_data_1);
++
++ mdelay(5);
++
++ reg_data |= 0x0001;
++ TITAN_GE_WRITE((TITAN_GE_TRTG_CONFIG + (port_num << 12)), reg_data);
++
++ /*
++ * Step 4: Start the Tx activity
++ */
++ TITAN_GE_WRITE((TITAN_GE_TMAC_CONFIG_2 + (port_num << 12)), 0xe197);
++#ifdef TITAN_GE_JUMBO_FRAMES
++ TITAN_GE_WRITE((0x1258 + (port_num << 12)), 0x4000);
++#endif
++ reg_data = TITAN_GE_READ(TITAN_GE_TMAC_CONFIG_1 + (port_num << 12));
++ reg_data |= 0x0001; /* Enable TMAC */
++ reg_data |= 0x6c70; /* PAUSE also set */
++
++ TITAN_GE_WRITE((TITAN_GE_TMAC_CONFIG_1 + (port_num << 12)), reg_data);
++
++ udelay(30);
++
++ /* Destination Address drop bit */
++ reg_data = TITAN_GE_READ(TITAN_GE_RMAC_CONFIG_2 + (port_num << 12));
++ reg_data |= 0x218; /* DA_DROP bit and pause */
++ TITAN_GE_WRITE((TITAN_GE_RMAC_CONFIG_2 + (port_num << 12)), reg_data);
++
++ TITAN_GE_WRITE((0x1218 + (port_num << 12)), 0x3);
++
++#ifdef TITAN_GE_JUMBO_FRAMES
++ TITAN_GE_WRITE((0x1208 + (port_num << 12)), 0x4000);
++#endif
++ /* Start the Rx activity */
++ reg_data = TITAN_GE_READ(TITAN_GE_RMAC_CONFIG_1 + (port_num << 12));
++ reg_data |= 0x0001; /* RMAC Enable */
++ reg_data |= 0x0010; /* CRC Check enable */
++ reg_data |= 0x0040; /* Min Frame check enable */
++ reg_data |= 0x4400; /* Max Frame check enable */
++
++ TITAN_GE_WRITE((TITAN_GE_RMAC_CONFIG_1 + (port_num << 12)), reg_data);
++
++ udelay(30);
++
++ /*
++ * Enable the Interrupts for Tx and Rx
++ */
++ reg_data1 = TITAN_GE_READ(TITAN_GE_INTR_XDMA_IE);
++
++ if (port_num == 0) {
++ reg_data1 |= 0x3;
++#ifdef CONFIG_SMP
++ TITAN_GE_WRITE(0x0038, 0x003);
++#else
++ TITAN_GE_WRITE(0x0038, 0x303);
++#endif
++ }
++
++ if (port_num == 1) {
++ reg_data1 |= 0x300;
++ }
++
++ if (port_num == 2)
++ reg_data1 |= 0x30000;
++
++ TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_IE, reg_data1);
++ TITAN_GE_WRITE(0x003c, 0x300);
++
++ if (config_done == 0) {
++ TITAN_GE_WRITE(0x0024, 0x04000024); /* IRQ vector */
++ TITAN_GE_WRITE(0x0020, 0x000fb000); /* INTMSG base */
++ }
++
++ /* Priority */
++ reg_data = TITAN_GE_READ(0x1038 + (port_num << 12));
++ reg_data &= ~(0x00f00000);
++ TITAN_GE_WRITE((0x1038 + (port_num << 12)), reg_data);
++
++ /* Step 5: GMII config */
++ titan_ge_gmii_config(port_num);
++
++ if (config_done == 0) {
++ TITAN_GE_WRITE(0x1a80, 0);
++ config_done = 1;
++ }
++
++ return TITAN_OK;
++}
++
++/*
++ * Function to queue the packet for the Ethernet device
++ */
++static void titan_ge_tx_queue(titan_ge_port_info * titan_ge_eth,
++ struct sk_buff * skb)
++{
++ struct device *device = &titan_ge_device[titan_ge_eth->port_num]->dev;
++ unsigned int curr_desc = titan_ge_eth->tx_curr_desc_q;
++ volatile titan_ge_tx_desc *tx_curr;
++ int port_num = titan_ge_eth->port_num;
++
++ tx_curr = &(titan_ge_eth->tx_desc_area[curr_desc]);
++ tx_curr->buffer_addr =
++ dma_map_single(device, skb->data, skb_headlen(skb),
++ DMA_TO_DEVICE);
++
++ titan_ge_eth->tx_skb[curr_desc] = (struct sk_buff *) skb;
++ tx_curr->buffer_len = skb_headlen(skb);
++
++ /* Last descriptor enables interrupt and changes ownership */
++ tx_curr->cmd_sts = 0x1 | (1 << 15) | (1 << 5);
++
++ /* Kick the XDMA to start the transfer from memory to the FIFO */
++ TITAN_GE_WRITE((0x5044 + (port_num << 8)), 0x1);
++
++ /* Current descriptor updated */
++ titan_ge_eth->tx_curr_desc_q = (curr_desc + 1) % TITAN_GE_TX_QUEUE;
++
++ /* Prefetch the next descriptor */
++ prefetch((const void *)
++ &titan_ge_eth->tx_desc_area[titan_ge_eth->tx_curr_desc_q]);
++}
++
++/*
++ * Actually does the open of the Ethernet device
++ */
++static int titan_ge_eth_open(struct net_device *netdev)
++{
++ titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
++ unsigned int port_num = titan_ge_eth->port_num;
++ struct device *device = &titan_ge_device[port_num]->dev;
++ unsigned long reg_data;
++ unsigned int phy_reg;
++ int err = 0;
++
++ /* Stop the Rx activity */
++ reg_data = TITAN_GE_READ(TITAN_GE_RMAC_CONFIG_1 + (port_num << 12));
++ reg_data &= ~(0x00000001);
++ TITAN_GE_WRITE((TITAN_GE_RMAC_CONFIG_1 + (port_num << 12)), reg_data);
++
++ /* Clear the port interrupts */
++ TITAN_GE_WRITE((TITAN_GE_CHANNEL0_INTERRUPT + (port_num << 8)), 0x0);
++
++ if (config_done == 0) {
++ TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_CORE_A, 0);
++ TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_CORE_B, 0);
++ }
++
++ /* Set the MAC Address */
++ memcpy(titan_ge_eth->port_mac_addr, netdev->dev_addr, 6);
++
++ if (config_done == 0)
++ titan_port_init(netdev, titan_ge_eth);
++
++ titan_ge_update_afx(titan_ge_eth);
++
++ /* Allocate the Tx ring now */
++ titan_ge_eth->tx_ring_skbs = 0;
++ titan_ge_eth->tx_ring_size = TITAN_GE_TX_QUEUE;
++
++ /* Allocate space in the SRAM for the descriptors */
++ titan_ge_eth->tx_desc_area = (titan_ge_tx_desc *)
++ (titan_ge_sram + TITAN_TX_RING_BYTES * port_num);
++ titan_ge_eth->tx_dma = TITAN_SRAM_BASE + TITAN_TX_RING_BYTES * port_num;
++
++ if (!titan_ge_eth->tx_desc_area) {
++ printk(KERN_ERR
++ "%s: Cannot allocate Tx Ring (size %d bytes) for port %d\n",
++ netdev->name, TITAN_TX_RING_BYTES, port_num);
++ return -ENOMEM;
++ }
++
++ memset(titan_ge_eth->tx_desc_area, 0, titan_ge_eth->tx_desc_area_size);
++
++ /* Now initialize the Tx descriptor ring */
++ titan_ge_init_tx_desc_ring(titan_ge_eth,
++ titan_ge_eth->tx_ring_size,
++ (unsigned long) titan_ge_eth->tx_desc_area,
++ (unsigned long) titan_ge_eth->tx_dma);
++
++ /* Allocate the Rx ring now */
++ titan_ge_eth->rx_ring_size = TITAN_GE_RX_QUEUE;
++ titan_ge_eth->rx_ring_skbs = 0;
++
++ titan_ge_eth->rx_desc_area =
++ (titan_ge_rx_desc *)(titan_ge_sram + 0x1000 + TITAN_RX_RING_BYTES * port_num);
++
++ titan_ge_eth->rx_dma = TITAN_SRAM_BASE + 0x1000 + TITAN_RX_RING_BYTES * port_num;
++
++ if (!titan_ge_eth->rx_desc_area) {
++ printk(KERN_ERR "%s: Cannot allocate Rx Ring (size %d bytes)\n",
++ netdev->name, TITAN_RX_RING_BYTES);
++
++ printk(KERN_ERR "%s: Freeing previously allocated TX queues...",
++ netdev->name);
++
++ dma_free_coherent(device, titan_ge_eth->tx_desc_area_size,
++ (void *) titan_ge_eth->tx_desc_area,
++ titan_ge_eth->tx_dma);
++
++ return -ENOMEM;
++ }
++
++ memset(titan_ge_eth->rx_desc_area, 0, titan_ge_eth->rx_desc_area_size);
++
++ /* Now initialize the Rx ring */
++#ifdef TITAN_GE_JUMBO_FRAMES
++ if ((titan_ge_init_rx_desc_ring
++ (titan_ge_eth, titan_ge_eth->rx_ring_size, TITAN_GE_JUMBO_BUFSIZE,
++ (unsigned long) titan_ge_eth->rx_desc_area, 0,
++ (unsigned long) titan_ge_eth->rx_dma)) == 0)
++#else
++ if ((titan_ge_init_rx_desc_ring
++ (titan_ge_eth, titan_ge_eth->rx_ring_size, TITAN_GE_STD_BUFSIZE,
++ (unsigned long) titan_ge_eth->rx_desc_area, 0,
++ (unsigned long) titan_ge_eth->rx_dma)) == 0)
++#endif
++ panic("%s: Error initializing RX Ring\n", netdev->name);
++
++ /* Fill the Rx ring with the SKBs */
++ titan_ge_port_start(netdev, titan_ge_eth);
++
++ /*
++ * Check if Interrupt Coalscing needs to be turned on. The
++ * values specified in the register is multiplied by
++ * (8 x 64 nanoseconds) to determine when an interrupt should
++ * be sent to the CPU.
++ */
++
++ if (TITAN_GE_TX_COAL) {
++ titan_ge_eth->tx_int_coal =
++ titan_ge_tx_coal(TITAN_GE_TX_COAL, port_num);
++ }
++
++ err = titan_ge_mdio_read(port_num, TITAN_GE_MDIO_PHY_STATUS, &phy_reg);
++ if (err == TITAN_GE_MDIO_ERROR) {
++ printk(KERN_ERR
++ "Could not read PHY control register 0x11 \n");
++ return TITAN_ERROR;
++ }
++ if (!(phy_reg & 0x0400)) {
++ netif_carrier_off(netdev);
++ netif_stop_queue(netdev);
++ return TITAN_ERROR;
++ } else {
++ netif_carrier_on(netdev);
++ netif_start_queue(netdev);
++ }
++
++ return TITAN_OK;
++}
++
++/*
++ * Queue the packet for Tx. Currently no support for zero copy,
++ * checksum offload and Scatter Gather. The chip does support
++ * Scatter Gather only. But, that wont help here since zero copy
++ * requires support for Tx checksumming also.
++ */
++int titan_ge_start_xmit(struct sk_buff *skb, struct net_device *netdev)
++{
++ titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
++ unsigned long flags;
++ struct net_device_stats *stats;
++//printk("titan_ge_start_xmit\n");
++
++ stats = &titan_ge_eth->stats;
++ spin_lock_irqsave(&titan_ge_eth->lock, flags);
++
++ if ((TITAN_GE_TX_QUEUE - titan_ge_eth->tx_ring_skbs) <=
++ (skb_shinfo(skb)->nr_frags + 1)) {
++ netif_stop_queue(netdev);
++ spin_unlock_irqrestore(&titan_ge_eth->lock, flags);
++ printk(KERN_ERR "Tx OOD \n");
++ return 1;
++ }
++
++ titan_ge_tx_queue(titan_ge_eth, skb);
++ titan_ge_eth->tx_ring_skbs++;
++
++ if (TITAN_GE_TX_QUEUE <= (titan_ge_eth->tx_ring_skbs + 4)) {
++ spin_unlock_irqrestore(&titan_ge_eth->lock, flags);
++ titan_ge_free_tx_queue(titan_ge_eth);
++ spin_lock_irqsave(&titan_ge_eth->lock, flags);
++ }
++
++ stats->tx_bytes += skb->len;
++ stats->tx_packets++;
++
++ spin_unlock_irqrestore(&titan_ge_eth->lock, flags);
++
++ netdev->trans_start = jiffies;
++
++ return 0;
++}
++
++/*
++ * Actually does the Rx. Rx side checksumming supported.
++ */
++static int titan_ge_rx(struct net_device *netdev, int port_num,
++ titan_ge_port_info * titan_ge_port,
++ titan_ge_packet * packet)
++{
++ int rx_curr_desc, rx_used_desc;
++ volatile titan_ge_rx_desc *rx_desc;
++
++ rx_curr_desc = titan_ge_port->rx_curr_desc_q;
++ rx_used_desc = titan_ge_port->rx_used_desc_q;
++
++ if (((rx_curr_desc + 1) % TITAN_GE_RX_QUEUE) == rx_used_desc)
++ return TITAN_ERROR;
++
++ rx_desc = &(titan_ge_port->rx_desc_area[rx_curr_desc]);
++
++ if (rx_desc->cmd_sts & TITAN_GE_RX_BUFFER_OWNED)
++ return TITAN_ERROR;
++
++ packet->skb = titan_ge_port->rx_skb[rx_curr_desc];
++ packet->len = (rx_desc->cmd_sts & 0x7fff);
++
++ /*
++ * At this point, we dont know if the checksumming
++ * actually helps relieve CPU. So, keep it for
++ * port 0 only
++ */
++ packet->checksum = ntohs((rx_desc->buffer & 0xffff0000) >> 16);
++ packet->cmd_sts = rx_desc->cmd_sts;
++
++ titan_ge_port->rx_curr_desc_q = (rx_curr_desc + 1) % TITAN_GE_RX_QUEUE;
++
++ /* Prefetch the next descriptor */
++ prefetch((const void *)
++ &titan_ge_port->rx_desc_area[titan_ge_port->rx_curr_desc_q + 1]);
++
++ return TITAN_OK;
++}
++
++/*
++ * Free the Tx queue of the used SKBs
++ */
++static int titan_ge_free_tx_queue(titan_ge_port_info *titan_ge_eth)
++{
++ unsigned long flags;
++
++ /* Take the lock */
++ spin_lock_irqsave(&(titan_ge_eth->lock), flags);
++
++ while (titan_ge_return_tx_desc(titan_ge_eth, titan_ge_eth->port_num) == 0)
++ if (titan_ge_eth->tx_ring_skbs != 1)
++ titan_ge_eth->tx_ring_skbs--;
++
++ spin_unlock_irqrestore(&titan_ge_eth->lock, flags);
++
++ return TITAN_OK;
++}
++
++/*
++ * Threshold beyond which we do the cleaning of
++ * Tx queue and new allocation for the Rx
++ * queue
++ */
++#define TX_THRESHOLD 4
++#define RX_THRESHOLD 10
++
++/*
++ * Receive the packets and send it to the kernel.
++ */
++static int titan_ge_receive_queue(struct net_device *netdev, unsigned int max)
++{
++ titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
++ unsigned int port_num = titan_ge_eth->port_num;
++ titan_ge_packet packet;
++ struct net_device_stats *stats;
++ struct sk_buff *skb;
++ unsigned long received_packets = 0;
++ unsigned int ack;
++
++ stats = &titan_ge_eth->stats;
++
++ while ((--max)
++ && (titan_ge_rx(netdev, port_num, titan_ge_eth, &packet) == TITAN_OK)) {
++ skb = (struct sk_buff *) packet.skb;
++
++ titan_ge_eth->rx_ring_skbs--;
++
++ if (--titan_ge_eth->rx_work_limit < 0)
++ break;
++ received_packets++;
++
++ stats->rx_packets++;
++ stats->rx_bytes += packet.len;
++
++ if ((packet.cmd_sts & TITAN_GE_RX_PERR) ||
++ (packet.cmd_sts & TITAN_GE_RX_OVERFLOW_ERROR) ||
++ (packet.cmd_sts & TITAN_GE_RX_TRUNC) ||
++ (packet.cmd_sts & TITAN_GE_RX_CRC_ERROR)) {
++ stats->rx_dropped++;
++ dev_kfree_skb_any(skb);
++
++ continue;
++ }
++ /*
++ * Either support fast path or slow path. Decision
++ * making can really slow down the performance. The
++ * idea is to cut down the number of checks and improve
++ * the fastpath.
++ */
++
++ skb_put(skb, packet.len - 2);
++
++ /*
++ * Increment data pointer by two since thats where
++ * the MAC starts
++ */
++ skb_reserve(skb, 2);
++ skb->protocol = eth_type_trans(skb, netdev);
++ netif_receive_skb(skb);
++
++ if (titan_ge_eth->rx_threshold > RX_THRESHOLD) {
++ ack = titan_ge_rx_task(netdev, titan_ge_eth);
++ TITAN_GE_WRITE((0x5048 + (port_num << 8)), ack);
++ titan_ge_eth->rx_threshold = 0;
++ } else
++ titan_ge_eth->rx_threshold++;
++
++ if (titan_ge_eth->tx_threshold > TX_THRESHOLD) {
++ titan_ge_eth->tx_threshold = 0;
++ titan_ge_free_tx_queue(titan_ge_eth);
++ }
++ else
++ titan_ge_eth->tx_threshold++;
++
++ }
++ return received_packets;
++}
++
++
++/*
++ * Enable the Rx side interrupts
++ */
++static void titan_ge_enable_int(unsigned int port_num,
++ titan_ge_port_info *titan_ge_eth,
++ struct net_device *netdev)
++{
++ unsigned long reg_data = TITAN_GE_READ(TITAN_GE_INTR_XDMA_IE);
++
++ if (port_num == 0)
++ reg_data |= 0x3;
++ if (port_num == 1)
++ reg_data |= 0x300;
++ if (port_num == 2)
++ reg_data |= 0x30000;
++
++ /* Re-enable interrupts */
++ TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_IE, reg_data);
++}
++
++/*
++ * Main function to handle the polling for Rx side NAPI.
++ * Receive interrupts have been disabled at this point.
++ * The poll schedules the transmit followed by receive.
++ */
++static int titan_ge_poll(struct net_device *netdev, int *budget)
++{
++ titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
++ int port_num = titan_ge_eth->port_num;
++ int work_done = 0;
++ unsigned long flags, status;
++
++ titan_ge_eth->rx_work_limit = *budget;
++ if (titan_ge_eth->rx_work_limit > netdev->quota)
++ titan_ge_eth->rx_work_limit = netdev->quota;
++
++ do {
++ /* Do the transmit cleaning work here */
++ titan_ge_free_tx_queue(titan_ge_eth);
++
++ /* Ack the Rx interrupts */
++ if (port_num == 0)
++ TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_CORE_A, 0x3);
++ if (port_num == 1)
++ TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_CORE_A, 0x300);
++ if (port_num == 2)
++ TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_CORE_A, 0x30000);
++
++ work_done += titan_ge_receive_queue(netdev, 0);
++
++ /* Out of quota and there is work to be done */
++ if (titan_ge_eth->rx_work_limit < 0)
++ goto not_done;
++
++ /* Receive alloc_skb could lead to OOM */
++ if (oom_flag == 1) {
++ oom_flag = 0;
++ goto oom;
++ }
++
++ status = TITAN_GE_READ(TITAN_GE_INTR_XDMA_CORE_A);
++ } while (status & 0x30300);
++
++ /* If we are here, then no more interrupts to process */
++ goto done;
++
++not_done:
++ *budget -= work_done;
++ netdev->quota -= work_done;
++ return 1;
++
++oom:
++ printk(KERN_ERR "OOM \n");
++ netif_rx_complete(netdev);
++ return 0;
++
++done:
++ /*
++ * No more packets on the poll list. Turn the interrupts
++ * back on and we should be able to catch the new
++ * packets in the interrupt handler
++ */
++ if (!work_done)
++ work_done = 1;
++
++ *budget -= work_done;
++ netdev->quota -= work_done;
++
++ spin_lock_irqsave(&titan_ge_eth->lock, flags);
++
++ /* Remove us from the poll list */
++ netif_rx_complete(netdev);
++
++ /* Re-enable interrupts */
++ titan_ge_enable_int(port_num, titan_ge_eth, netdev);
++
++ spin_unlock_irqrestore(&titan_ge_eth->lock, flags);
++
++ return 0;
++}
++
++/*
++ * Close the network device
++ */
++int titan_ge_stop(struct net_device *netdev)
++{
++ titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
++
++ spin_lock_irq(&(titan_ge_eth->lock));
++ titan_ge_eth_stop(netdev);
++ free_irq(netdev->irq, netdev);
++ spin_unlock_irq(&titan_ge_eth->lock);
++
++ return TITAN_OK;
++}
++
++/*
++ * Free the Tx ring
++ */
++static void titan_ge_free_tx_rings(struct net_device *netdev)
++{
++ titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
++ unsigned int port_num = titan_ge_eth->port_num;
++ unsigned int curr;
++ unsigned long reg_data;
++
++ /* Stop the Tx DMA */
++ reg_data = TITAN_GE_READ(TITAN_GE_CHANNEL0_CONFIG +
++ (port_num << 8));
++ reg_data |= 0xc0000000;
++ TITAN_GE_WRITE((TITAN_GE_CHANNEL0_CONFIG +
++ (port_num << 8)), reg_data);
++
++ /* Disable the TMAC */
++ reg_data = TITAN_GE_READ(TITAN_GE_TMAC_CONFIG_1 +
++ (port_num << 12));
++ reg_data &= ~(0x00000001);
++ TITAN_GE_WRITE((TITAN_GE_TMAC_CONFIG_1 +
++ (port_num << 12)), reg_data);
++
++ for (curr = 0;
++ (titan_ge_eth->tx_ring_skbs) && (curr < TITAN_GE_TX_QUEUE);
++ curr++) {
++ if (titan_ge_eth->tx_skb[curr]) {
++ dev_kfree_skb(titan_ge_eth->tx_skb[curr]);
++ titan_ge_eth->tx_ring_skbs--;
++ }
++ }
++
++ if (titan_ge_eth->tx_ring_skbs != 0)
++ printk
++ ("%s: Error on Tx descriptor free - could not free %d"
++ " descriptors\n", netdev->name,
++ titan_ge_eth->tx_ring_skbs);
++
++#ifndef TITAN_RX_RING_IN_SRAM
++ dma_free_coherent(&titan_ge_device[port_num]->dev,
++ titan_ge_eth->tx_desc_area_size,
++ (void *) titan_ge_eth->tx_desc_area,
++ titan_ge_eth->tx_dma);
++#endif
++}
++
++/*
++ * Free the Rx ring
++ */
++static void titan_ge_free_rx_rings(struct net_device *netdev)
++{
++ titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
++ unsigned int port_num = titan_ge_eth->port_num;
++ unsigned int curr;
++ unsigned long reg_data;
++
++ /* Stop the Rx DMA */
++ reg_data = TITAN_GE_READ(TITAN_GE_CHANNEL0_CONFIG +
++ (port_num << 8));
++ reg_data |= 0x000c0000;
++ TITAN_GE_WRITE((TITAN_GE_CHANNEL0_CONFIG +
++ (port_num << 8)), reg_data);
++
++ /* Disable the RMAC */
++ reg_data = TITAN_GE_READ(TITAN_GE_RMAC_CONFIG_1 +
++ (port_num << 12));
++ reg_data &= ~(0x00000001);
++ TITAN_GE_WRITE((TITAN_GE_RMAC_CONFIG_1 +
++ (port_num << 12)), reg_data);
++
++ for (curr = 0;
++ titan_ge_eth->rx_ring_skbs && (curr < TITAN_GE_RX_QUEUE);
++ curr++) {
++ if (titan_ge_eth->rx_skb[curr]) {
++ dev_kfree_skb(titan_ge_eth->rx_skb[curr]);
++ titan_ge_eth->rx_ring_skbs--;
++ }
++ }
++
++ if (titan_ge_eth->rx_ring_skbs != 0)
++ printk(KERN_ERR
++ "%s: Error in freeing Rx Ring. %d skb's still"
++ " stuck in RX Ring - ignoring them\n", netdev->name,
++ titan_ge_eth->rx_ring_skbs);
++
++#ifndef TITAN_RX_RING_IN_SRAM
++ dma_free_coherent(&titan_ge_device[port_num]->dev,
++ titan_ge_eth->rx_desc_area_size,
++ (void *) titan_ge_eth->rx_desc_area,
++ titan_ge_eth->rx_dma);
++#endif
++}
++
++/*
++ * Actually does the stop of the Ethernet device
++ */
++static void titan_ge_eth_stop(struct net_device *netdev)
++{
++ titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
++
++ netif_stop_queue(netdev);
++
++ titan_ge_port_reset(titan_ge_eth->port_num);
++
++ titan_ge_free_tx_rings(netdev);
++ titan_ge_free_rx_rings(netdev);
++
++ /* Disable the Tx and Rx Interrupts for all channels */
++ TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_IE, 0x0);
++}
++
++/*
++ * Update the MAC address. Note that we have to write the
++ * address in three station registers, 16 bits each. And this
++ * has to be done for TMAC and RMAC
++ */
++static void titan_ge_update_mac_address(struct net_device *netdev)
++{
++ titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
++ unsigned int port_num = titan_ge_eth->port_num;
++ u8 p_addr[6];
++
++ memcpy(titan_ge_eth->port_mac_addr, netdev->dev_addr, 6);
++ memcpy(p_addr, netdev->dev_addr, 6);
++
++ /* Update the Address Filtering Match tables */
++ titan_ge_update_afx(titan_ge_eth);
++
++ printk("Station MAC : %d %d %d %d %d %d \n",
++ p_addr[5], p_addr[4], p_addr[3],
++ p_addr[2], p_addr[1], p_addr[0]);
++
++ /* Set the MAC address here for TMAC and RMAC */
++ TITAN_GE_WRITE((TITAN_GE_TMAC_STATION_HI + (port_num << 12)),
++ ((p_addr[5] << 8) | p_addr[4]));
++ TITAN_GE_WRITE((TITAN_GE_TMAC_STATION_MID + (port_num << 12)),
++ ((p_addr[3] << 8) | p_addr[2]));
++ TITAN_GE_WRITE((TITAN_GE_TMAC_STATION_LOW + (port_num << 12)),
++ ((p_addr[1] << 8) | p_addr[0]));
++
++ TITAN_GE_WRITE((TITAN_GE_RMAC_STATION_HI + (port_num << 12)),
++ ((p_addr[5] << 8) | p_addr[4]));
++ TITAN_GE_WRITE((TITAN_GE_RMAC_STATION_MID + (port_num << 12)),
++ ((p_addr[3] << 8) | p_addr[2]));
++ TITAN_GE_WRITE((TITAN_GE_RMAC_STATION_LOW + (port_num << 12)),
++ ((p_addr[1] << 8) | p_addr[0]));
++}
++
++/*
++ * Set the MAC address of the Ethernet device
++ */
++static int titan_ge_set_mac_address(struct net_device *dev, void *addr)
++{
++ titan_ge_port_info *tp = netdev_priv(dev);
++ struct sockaddr *sa = addr;
++
++ memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
++
++ spin_lock_irq(&tp->lock);
++ titan_ge_update_mac_address(dev);
++ spin_unlock_irq(&tp->lock);
++
++ return 0;
++}
++
++/*
++ * Get the Ethernet device stats
++ */
++static struct net_device_stats *titan_ge_get_stats(struct net_device *netdev)
++{
++ titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
++
++ return &titan_ge_eth->stats;
++}
++
++/*
++ * Initialize the Rx descriptor ring for the Titan Ge
++ */
++static int titan_ge_init_rx_desc_ring(titan_ge_port_info * titan_eth_port,
++ int rx_desc_num,
++ int rx_buff_size,
++ unsigned long rx_desc_base_addr,
++ unsigned long rx_buff_base_addr,
++ unsigned long rx_dma)
++{
++ volatile titan_ge_rx_desc *rx_desc;
++ unsigned long buffer_addr;
++ int index;
++ unsigned long titan_ge_rx_desc_bus = rx_dma;
++
++ buffer_addr = rx_buff_base_addr;
++ rx_desc = (titan_ge_rx_desc *) rx_desc_base_addr;
++
++ /* Check alignment */
++ if (rx_buff_base_addr & 0xF)
++ return 0;
++
++ /* Check Rx buffer size */
++ if ((rx_buff_size < 8) || (rx_buff_size > TITAN_GE_MAX_RX_BUFFER))
++ return 0;
++
++ /* 64-bit alignment
++ if ((rx_buff_base_addr + rx_buff_size) & 0x7)
++ return 0; */
++
++ /* Initialize the Rx desc ring */
++ for (index = 0; index < rx_desc_num; index++) {
++ titan_ge_rx_desc_bus += sizeof(titan_ge_rx_desc);
++ rx_desc[index].cmd_sts = 0;
++ rx_desc[index].buffer_addr = buffer_addr;
++ titan_eth_port->rx_skb[index] = NULL;
++ buffer_addr += rx_buff_size;
++ }
++
++ titan_eth_port->rx_curr_desc_q = 0;
++ titan_eth_port->rx_used_desc_q = 0;
++
++ titan_eth_port->rx_desc_area = (titan_ge_rx_desc *) rx_desc_base_addr;
++ titan_eth_port->rx_desc_area_size =
++ rx_desc_num * sizeof(titan_ge_rx_desc);
++
++ titan_eth_port->rx_dma = rx_dma;
++
++ return TITAN_OK;
++}
++
++/*
++ * Initialize the Tx descriptor ring. Descriptors in the SRAM
++ */
++static int titan_ge_init_tx_desc_ring(titan_ge_port_info * titan_ge_port,
++ int tx_desc_num,
++ unsigned long tx_desc_base_addr,
++ unsigned long tx_dma)
++{
++ titan_ge_tx_desc *tx_desc;
++ int index;
++ unsigned long titan_ge_tx_desc_bus = tx_dma;
++
++ if (tx_desc_base_addr & 0xF)
++ return 0;
++
++ tx_desc = (titan_ge_tx_desc *) tx_desc_base_addr;
++
++ for (index = 0; index < tx_desc_num; index++) {
++ titan_ge_port->tx_dma_array[index] =
++ (dma_addr_t) titan_ge_tx_desc_bus;
++ titan_ge_tx_desc_bus += sizeof(titan_ge_tx_desc);
++ tx_desc[index].cmd_sts = 0x0000;
++ tx_desc[index].buffer_len = 0;
++ tx_desc[index].buffer_addr = 0x00000000;
++ titan_ge_port->tx_skb[index] = NULL;
++ }
++
++ titan_ge_port->tx_curr_desc_q = 0;
++ titan_ge_port->tx_used_desc_q = 0;
++
++ titan_ge_port->tx_desc_area = (titan_ge_tx_desc *) tx_desc_base_addr;
++ titan_ge_port->tx_desc_area_size =
++ tx_desc_num * sizeof(titan_ge_tx_desc);
++
++ titan_ge_port->tx_dma = tx_dma;
++ return TITAN_OK;
++}
++
++/*
++ * Initialize the device as an Ethernet device
++ */
++static int __init titan_ge_probe(struct device *device)
++{
++ titan_ge_port_info *titan_ge_eth;
++ struct net_device *netdev;
++ int port = to_platform_device(device)->id;
++ int err;
++
++ netdev = alloc_etherdev(sizeof(titan_ge_port_info));
++ if (!netdev) {
++ err = -ENODEV;
++ goto out;
++ }
++
++ netdev->open = titan_ge_open;
++ netdev->stop = titan_ge_stop;
++ netdev->hard_start_xmit = titan_ge_start_xmit;
++ netdev->get_stats = titan_ge_get_stats;
++ netdev->set_multicast_list = titan_ge_set_multi;
++ netdev->set_mac_address = titan_ge_set_mac_address;
++
++ /* Tx timeout */
++ netdev->tx_timeout = titan_ge_tx_timeout;
++ netdev->watchdog_timeo = 2 * HZ;
++
++ /* Set these to very high values */
++ netdev->poll = titan_ge_poll;
++ netdev->weight = 64;
++
++ netdev->tx_queue_len = TITAN_GE_TX_QUEUE;
++ netif_carrier_off(netdev);
++ netdev->base_addr = 0;
++
++ netdev->change_mtu = titan_ge_change_mtu;
++
++ titan_ge_eth = netdev_priv(netdev);
++ /* Allocation of memory for the driver structures */
++
++ titan_ge_eth->port_num = port;
++
++ /* Configure the Tx timeout handler */
++ INIT_WORK(&titan_ge_eth->tx_timeout_task,
++ (void (*)(void *)) titan_ge_tx_timeout_task, netdev);
++
++ spin_lock_init(&titan_ge_eth->lock);
++
++ /* set MAC addresses */
++ memcpy(netdev->dev_addr, titan_ge_mac_addr_base, 6);
++ netdev->dev_addr[5] += port;
++
++ err = register_netdev(netdev);
++
++ if (err)
++ goto out_free_netdev;
++
++ printk(KERN_NOTICE
++ "%s: port %d with MAC address %02x:%02x:%02x:%02x:%02x:%02x\n",
++ netdev->name, port, netdev->dev_addr[0],
++ netdev->dev_addr[1], netdev->dev_addr[2],
++ netdev->dev_addr[3], netdev->dev_addr[4],
++ netdev->dev_addr[5]);
++
++ printk(KERN_NOTICE "Rx NAPI supported, Tx Coalescing ON \n");
++
++ return 0;
++
++out_free_netdev:
++ kfree(netdev);
++
++out:
++ return err;
++}
++
++static void __devexit titan_device_remove(struct device *device)
++{
++}
++
++/*
++ * Reset the Ethernet port
++ */
++static void titan_ge_port_reset(unsigned int port_num)
++{
++ unsigned int reg_data;
++
++ /* Stop the Tx port activity */
++ reg_data = TITAN_GE_READ(TITAN_GE_TMAC_CONFIG_1 +
++ (port_num << 12));
++ reg_data &= ~(0x0001);
++ TITAN_GE_WRITE((TITAN_GE_TMAC_CONFIG_1 +
++ (port_num << 12)), reg_data);
++
++ /* Stop the Rx port activity */
++ reg_data = TITAN_GE_READ(TITAN_GE_RMAC_CONFIG_1 +
++ (port_num << 12));
++ reg_data &= ~(0x0001);
++ TITAN_GE_WRITE((TITAN_GE_RMAC_CONFIG_1 +
++ (port_num << 12)), reg_data);
++
++ return;
++}
++
++/*
++ * Return the Tx desc after use by the XDMA
++ */
++static int titan_ge_return_tx_desc(titan_ge_port_info * titan_ge_eth, int port)
++{
++ int tx_desc_used;
++ struct sk_buff *skb;
++
++ tx_desc_used = titan_ge_eth->tx_used_desc_q;
++
++ /* return right away */
++ if (tx_desc_used == titan_ge_eth->tx_curr_desc_q)
++ return TITAN_ERROR;
++
++ /* Now the critical stuff */
++ skb = titan_ge_eth->tx_skb[tx_desc_used];
++
++ dev_kfree_skb_any(skb);
++
++ titan_ge_eth->tx_skb[tx_desc_used] = NULL;
++ titan_ge_eth->tx_used_desc_q =
++ (tx_desc_used + 1) % TITAN_GE_TX_QUEUE;
++
++ return 0;
++}
++
++/*
++ * Coalescing for the Tx path
++ */
++static unsigned long titan_ge_tx_coal(unsigned long delay, int port)
++{
++ unsigned long rx_delay;
++
++ rx_delay = TITAN_GE_READ(TITAN_GE_INT_COALESCING);
++ delay = (delay << 16) | rx_delay;
++
++ TITAN_GE_WRITE(TITAN_GE_INT_COALESCING, delay);
++ TITAN_GE_WRITE(0x5038, delay);
++
++ return delay;
++}
++
++static struct device_driver titan_soc_driver = {
++ .name = titan_string,
++ .bus = &platform_bus_type,
++ .probe = titan_ge_probe,
++ .remove = __devexit_p(titan_device_remove),
++};
++
++static void titan_platform_release (struct device *device)
++{
++ struct platform_device *pldev;
++
++ /* free device */
++ pldev = to_platform_device (device);
++ kfree (pldev);
++}
++
++/*
++ * Register the Titan GE with the kernel
++ */
++static int __init titan_ge_init_module(void)
++{
++ struct platform_device *pldev;
++ unsigned int version, device;
++ int i;
++
++ printk(KERN_NOTICE
++ "PMC-Sierra TITAN 10/100/1000 Ethernet Driver \n");
++
++ titan_ge_base = (unsigned long) ioremap(TITAN_GE_BASE, TITAN_GE_SIZE);
++ if (!titan_ge_base) {
++ printk("Mapping Titan GE failed\n");
++ goto out;
++ }
++
++ device = TITAN_GE_READ(TITAN_GE_DEVICE_ID);
++ version = (device & 0x000f0000) >> 16;
++ device &= 0x0000ffff;
++
++ printk(KERN_NOTICE "Device Id : %x, Version : %x \n", device, version);
++
++#ifdef TITAN_RX_RING_IN_SRAM
++ titan_ge_sram = (unsigned long) ioremap(TITAN_SRAM_BASE,
++ TITAN_SRAM_SIZE);
++ if (!titan_ge_sram) {
++ printk("Mapping Titan SRAM failed\n");
++ goto out_unmap_ge;
++ }
++#endif
++
++ if (driver_register(&titan_soc_driver)) {
++ printk(KERN_ERR "Driver registration failed\n");
++ goto out_unmap_sram;
++ }
++
++ for (i = 0; i < 3; i++) {
++ titan_ge_device[i] = NULL;
++
++ if (!(pldev = kmalloc (sizeof (*pldev), GFP_KERNEL)))
++ continue;
++
++ memset (pldev, 0, sizeof (*pldev));
++ pldev->name = titan_string;
++ pldev->id = i;
++ pldev->dev.release = titan_platform_release;
++ titan_ge_device[i] = pldev;
++
++ if (platform_device_register (pldev)) {
++ kfree (pldev);
++ titan_ge_device[i] = NULL;
++ continue;
++ }
++
++ if (!pldev->dev.driver) {
++ /*
++ * The driver was not bound to this device, there was
++ * no hardware at this address. Unregister it, as the
++ * release fuction will take care of freeing the
++ * allocated structure
++ */
++ titan_ge_device[i] = NULL;
++ platform_device_unregister (pldev);
++ }
++ }
++
++ return 0;
++
++out_unmap_sram:
++ iounmap((void *)titan_ge_sram);
++
++out_unmap_ge:
++ iounmap((void *)titan_ge_base);
++
++out:
++ return -ENOMEM;
++}
++
++/*
++ * Unregister the Titan GE from the kernel
++ */
++static void __exit titan_ge_cleanup_module(void)
++{
++ int i;
++
++ driver_unregister(&titan_soc_driver);
++
++ for (i = 0; i < 3; i++) {
++ if (titan_ge_device[i]) {
++ platform_device_unregister (titan_ge_device[i]);
++ titan_ge_device[i] = NULL;
++ }
++ }
++
++ iounmap((void *)titan_ge_sram);
++ iounmap((void *)titan_ge_base);
++}
++
++MODULE_AUTHOR("Manish Lachwani <lachwani@pmc-sierra.com>");
++MODULE_DESCRIPTION("Titan GE Ethernet driver");
++MODULE_LICENSE("GPL");
++
++module_init(titan_ge_init_module);
++module_exit(titan_ge_cleanup_module);
+diff --git a/drivers/net/titan_ge.h b/drivers/net/titan_ge.h
+new file mode 100644
+index 0000000..3719f78
+--- /dev/null
++++ b/drivers/net/titan_ge.h
+@@ -0,0 +1,415 @@
++#ifndef _TITAN_GE_H_
++#define _TITAN_GE_H_
++
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/spinlock.h>
++#include <asm/byteorder.h>
++
++/*
++ * These functions should be later moved to a more generic location since there
++ * will be others accessing it also
++ */
++
++/*
++ * This is the way it works: LKB5 Base is at 0x0128. TITAN_BASE is defined in
++ * include/asm/titan_dep.h. TITAN_GE_BASE is the value in the TITAN_GE_LKB5
++ * register.
++ */
++
++#define TITAN_GE_BASE 0xfe000000UL
++#define TITAN_GE_SIZE 0x10000UL
++
++extern unsigned long titan_ge_base;
++
++#define TITAN_GE_WRITE(offset, data) \
++ *(volatile u32 *)(titan_ge_base + (offset)) = (data)
++
++#define TITAN_GE_READ(offset) *(volatile u32 *)(titan_ge_base + (offset))
++
++#ifndef msec_delay
++#define msec_delay(x) do { if(in_interrupt()) { \
++ /* Don't mdelay in interrupt context! */ \
++ BUG(); \
++ } else { \
++ set_current_state(TASK_UNINTERRUPTIBLE); \
++ schedule_timeout((x * HZ)/1000); \
++ } } while(0)
++#endif
++
++#define TITAN_GE_PORT_0
++
++#define TITAN_SRAM_BASE ((OCD_READ(RM9000x2_OCD_LKB13) & ~1) << 4)
++#define TITAN_SRAM_SIZE 0x2000UL
++
++/*
++ * We may need these constants
++ */
++#define TITAN_BIT0 0x00000001
++#define TITAN_BIT1 0x00000002
++#define TITAN_BIT2 0x00000004
++#define TITAN_BIT3 0x00000008
++#define TITAN_BIT4 0x00000010
++#define TITAN_BIT5 0x00000020
++#define TITAN_BIT6 0x00000040
++#define TITAN_BIT7 0x00000080
++#define TITAN_BIT8 0x00000100
++#define TITAN_BIT9 0x00000200
++#define TITAN_BIT10 0x00000400
++#define TITAN_BIT11 0x00000800
++#define TITAN_BIT12 0x00001000
++#define TITAN_BIT13 0x00002000
++#define TITAN_BIT14 0x00004000
++#define TITAN_BIT15 0x00008000
++#define TITAN_BIT16 0x00010000
++#define TITAN_BIT17 0x00020000
++#define TITAN_BIT18 0x00040000
++#define TITAN_BIT19 0x00080000
++#define TITAN_BIT20 0x00100000
++#define TITAN_BIT21 0x00200000
++#define TITAN_BIT22 0x00400000
++#define TITAN_BIT23 0x00800000
++#define TITAN_BIT24 0x01000000
++#define TITAN_BIT25 0x02000000
++#define TITAN_BIT26 0x04000000
++#define TITAN_BIT27 0x08000000
++#define TITAN_BIT28 0x10000000
++#define TITAN_BIT29 0x20000000
++#define TITAN_BIT30 0x40000000
++#define TITAN_BIT31 0x80000000
++
++/* Flow Control */
++#define TITAN_GE_FC_NONE 0x0
++#define TITAN_GE_FC_FULL 0x1
++#define TITAN_GE_FC_TX_PAUSE 0x2
++#define TITAN_GE_FC_RX_PAUSE 0x3
++
++/* Duplex Settings */
++#define TITAN_GE_FULL_DUPLEX 0x1
++#define TITAN_GE_HALF_DUPLEX 0x2
++
++/* Speed settings */
++#define TITAN_GE_SPEED_1000 0x1
++#define TITAN_GE_SPEED_100 0x2
++#define TITAN_GE_SPEED_10 0x3
++
++/* Debugging info only */
++#undef TITAN_DEBUG
++
++/* Keep the rings in the Titan's SSRAM */
++#define TITAN_RX_RING_IN_SRAM
++
++#ifdef CONFIG_64BIT
++#define TITAN_GE_IE_MASK 0xfffffffffb001b64
++#define TITAN_GE_IE_STATUS 0xfffffffffb001b60
++#else
++#define TITAN_GE_IE_MASK 0xfb001b64
++#define TITAN_GE_IE_STATUS 0xfb001b60
++#endif
++
++/* Support for Jumbo Frames */
++#undef TITAN_GE_JUMBO_FRAMES
++
++/* Rx buffer size */
++#ifdef TITAN_GE_JUMBO_FRAMES
++#define TITAN_GE_JUMBO_BUFSIZE 9080
++#else
++#define TITAN_GE_STD_BUFSIZE 1580
++#endif
++
++/*
++ * Tx and Rx Interrupt Coalescing parameter. These values are
++ * for 1 Ghz processor. Rx coalescing can be taken care of
++ * by NAPI. NAPI is adaptive and hence useful. Tx coalescing
++ * is not adaptive. Hence, these values need to be adjusted
++ * based on load, CPU speed etc.
++ */
++#define TITAN_GE_RX_COAL 150
++#define TITAN_GE_TX_COAL 300
++
++#if defined(__BIG_ENDIAN)
++
++/* Define the Rx descriptor */
++typedef struct eth_rx_desc {
++ u32 reserved; /* Unused */
++ u32 buffer_addr; /* CPU buffer address */
++ u32 cmd_sts; /* Command and Status */
++ u32 buffer; /* XDMA buffer address */
++} titan_ge_rx_desc;
++
++/* Define the Tx descriptor */
++typedef struct eth_tx_desc {
++ u16 cmd_sts; /* Command, Status and Buffer count */
++ u16 buffer_len; /* Length of the buffer */
++ u32 buffer_addr; /* Physical address of the buffer */
++} titan_ge_tx_desc;
++
++#elif defined(__LITTLE_ENDIAN)
++
++/* Define the Rx descriptor */
++typedef struct eth_rx_desc {
++ u32 buffer_addr; /* CPU buffer address */
++ u32 reserved; /* Unused */
++ u32 buffer; /* XDMA buffer address */
++ u32 cmd_sts; /* Command and Status */
++} titan_ge_rx_desc;
++
++/* Define the Tx descriptor */
++typedef struct eth_tx_desc {
++ u32 buffer_addr; /* Physical address of the buffer */
++ u16 buffer_len; /* Length of the buffer */
++ u16 cmd_sts; /* Command, Status and Buffer count */
++} titan_ge_tx_desc;
++#endif
++
++/* Default Tx Queue Size */
++#define TITAN_GE_TX_QUEUE 128
++#define TITAN_TX_RING_BYTES (TITAN_GE_TX_QUEUE * sizeof(struct eth_tx_desc))
++
++/* Default Rx Queue Size */
++#define TITAN_GE_RX_QUEUE 64
++#define TITAN_RX_RING_BYTES (TITAN_GE_RX_QUEUE * sizeof(struct eth_rx_desc))
++
++/* Packet Structure */
++typedef struct _pkt_info {
++ unsigned int len;
++ unsigned int cmd_sts;
++ unsigned int buffer;
++ struct sk_buff *skb;
++ unsigned int checksum;
++} titan_ge_packet;
++
++
++#define PHYS_CNT 3
++
++/* Titan Port specific data structure */
++typedef struct _eth_port_ctrl {
++ unsigned int port_num;
++ u8 port_mac_addr[6];
++
++ /* Rx descriptor pointers */
++ int rx_curr_desc_q, rx_used_desc_q;
++
++ /* Tx descriptor pointers */
++ int tx_curr_desc_q, tx_used_desc_q;
++
++ /* Rx descriptor area */
++ volatile titan_ge_rx_desc *rx_desc_area;
++ unsigned int rx_desc_area_size;
++ struct sk_buff* rx_skb[TITAN_GE_RX_QUEUE];
++
++ /* Tx Descriptor area */
++ volatile titan_ge_tx_desc *tx_desc_area;
++ unsigned int tx_desc_area_size;
++ struct sk_buff* tx_skb[TITAN_GE_TX_QUEUE];
++
++ /* Timeout task */
++ struct work_struct tx_timeout_task;
++
++ /* DMA structures and handles */
++ dma_addr_t tx_dma;
++ dma_addr_t rx_dma;
++ dma_addr_t tx_dma_array[TITAN_GE_TX_QUEUE];
++
++ /* Device lock */
++ spinlock_t lock;
++
++ unsigned int tx_ring_skbs;
++ unsigned int rx_ring_size;
++ unsigned int tx_ring_size;
++ unsigned int rx_ring_skbs;
++
++ struct net_device_stats stats;
++
++ /* Tx and Rx coalescing */
++ unsigned long rx_int_coal;
++ unsigned long tx_int_coal;
++
++ /* Threshold for replenishing the Rx and Tx rings */
++ unsigned int tx_threshold;
++ unsigned int rx_threshold;
++
++ /* NAPI work limit */
++ unsigned int rx_work_limit;
++} titan_ge_port_info;
++
++/* Titan specific constants */
++#define TITAN_ETH_PORT_IRQ 3
++
++/* Max Rx buffer */
++#define TITAN_GE_MAX_RX_BUFFER 65536
++
++/* Tx and Rx Error */
++#define TITAN_GE_ERROR
++
++/* Rx Descriptor Command and Status */
++
++#define TITAN_GE_RX_CRC_ERROR TITAN_BIT27 /* crc error */
++#define TITAN_GE_RX_OVERFLOW_ERROR TITAN_BIT15 /* overflow */
++#define TITAN_GE_RX_BUFFER_OWNED TITAN_BIT21 /* buffer ownership */
++#define TITAN_GE_RX_STP TITAN_BIT31 /* start of packet */
++#define TITAN_GE_RX_BAM TITAN_BIT30 /* broadcast address match */
++#define TITAN_GE_RX_PAM TITAN_BIT28 /* physical address match */
++#define TITAN_GE_RX_LAFM TITAN_BIT29 /* logical address filter match */
++#define TITAN_GE_RX_VLAN TITAN_BIT26 /* virtual lans */
++#define TITAN_GE_RX_PERR TITAN_BIT19 /* packet error */
++#define TITAN_GE_RX_TRUNC TITAN_BIT20 /* packet size greater than 32 buffers */
++
++/* Tx Descriptor Command */
++#define TITAN_GE_TX_BUFFER_OWNED TITAN_BIT5 /* buffer ownership */
++#define TITAN_GE_TX_ENABLE_INTERRUPT TITAN_BIT15 /* Interrupt Enable */
++
++/* Return Status */
++#define TITAN_OK 0x1 /* Good Status */
++#define TITAN_ERROR 0x2 /* Error Status */
++
++/* MIB specific register offset */
++#define TITAN_GE_MSTATX_STATS_BASE_LOW 0x0800 /* MSTATX COUNTL[15:0] */
++#define TITAN_GE_MSTATX_STATS_BASE_MID 0x0804 /* MSTATX COUNTM[15:0] */
++#define TITAN_GE_MSTATX_STATS_BASE_HI 0x0808 /* MSTATX COUNTH[7:0] */
++#define TITAN_GE_MSTATX_CONTROL 0x0828 /* MSTATX Control */
++#define TITAN_GE_MSTATX_VARIABLE_SELECT 0x082C /* MSTATX Variable Select */
++
++/* MIB counter offsets, add to the TITAN_GE_MSTATX_STATS_BASE_XXX */
++#define TITAN_GE_MSTATX_RXFRAMESOK 0x0040
++#define TITAN_GE_MSTATX_RXOCTETSOK 0x0050
++#define TITAN_GE_MSTATX_RXFRAMES 0x0060
++#define TITAN_GE_MSTATX_RXOCTETS 0x0070
++#define TITAN_GE_MSTATX_RXUNICASTFRAMESOK 0x0080
++#define TITAN_GE_MSTATX_RXBROADCASTFRAMESOK 0x0090
++#define TITAN_GE_MSTATX_RXMULTICASTFRAMESOK 0x00A0
++#define TITAN_GE_MSTATX_RXTAGGEDFRAMESOK 0x00B0
++#define TITAN_GE_MSTATX_RXMACPAUSECONTROLFRAMESOK 0x00C0
++#define TITAN_GE_MSTATX_RXMACCONTROLFRAMESOK 0x00D0
++#define TITAN_GE_MSTATX_RXFCSERROR 0x00E0
++#define TITAN_GE_MSTATX_RXALIGNMENTERROR 0x00F0
++#define TITAN_GE_MSTATX_RXSYMBOLERROR 0x0100
++#define TITAN_GE_MSTATX_RXLAYER1ERROR 0x0110
++#define TITAN_GE_MSTATX_RXINRANGELENGTHERROR 0x0120
++#define TITAN_GE_MSTATX_RXLONGLENGTHERROR 0x0130
++#define TITAN_GE_MSTATX_RXLONGLENGTHCRCERROR 0x0140
++#define TITAN_GE_MSTATX_RXSHORTLENGTHERROR 0x0150
++#define TITAN_GE_MSTATX_RXSHORTLLENGTHCRCERROR 0x0160
++#define TITAN_GE_MSTATX_RXFRAMES64OCTETS 0x0170
++#define TITAN_GE_MSTATX_RXFRAMES65TO127OCTETS 0x0180
++#define TITAN_GE_MSTATX_RXFRAMES128TO255OCTETS 0x0190
++#define TITAN_GE_MSTATX_RXFRAMES256TO511OCTETS 0x01A0
++#define TITAN_GE_MSTATX_RXFRAMES512TO1023OCTETS 0x01B0
++#define TITAN_GE_MSTATX_RXFRAMES1024TO1518OCTETS 0x01C0
++#define TITAN_GE_MSTATX_RXFRAMES1519TOMAXSIZE 0x01D0
++#define TITAN_GE_MSTATX_RXSTATIONADDRESSFILTERED 0x01E0
++#define TITAN_GE_MSTATX_RXVARIABLE 0x01F0
++#define TITAN_GE_MSTATX_GENERICADDRESSFILTERED 0x0200
++#define TITAN_GE_MSTATX_UNICASTFILTERED 0x0210
++#define TITAN_GE_MSTATX_MULTICASTFILTERED 0x0220
++#define TITAN_GE_MSTATX_BROADCASTFILTERED 0x0230
++#define TITAN_GE_MSTATX_HASHFILTERED 0x0240
++#define TITAN_GE_MSTATX_TXFRAMESOK 0x0250
++#define TITAN_GE_MSTATX_TXOCTETSOK 0x0260
++#define TITAN_GE_MSTATX_TXOCTETS 0x0270
++#define TITAN_GE_MSTATX_TXTAGGEDFRAMESOK 0x0280
++#define TITAN_GE_MSTATX_TXMACPAUSECONTROLFRAMESOK 0x0290
++#define TITAN_GE_MSTATX_TXFCSERROR 0x02A0
++#define TITAN_GE_MSTATX_TXSHORTLENGTHERROR 0x02B0
++#define TITAN_GE_MSTATX_TXLONGLENGTHERROR 0x02C0
++#define TITAN_GE_MSTATX_TXSYSTEMERROR 0x02D0
++#define TITAN_GE_MSTATX_TXMACERROR 0x02E0
++#define TITAN_GE_MSTATX_TXCARRIERSENSEERROR 0x02F0
++#define TITAN_GE_MSTATX_TXSQETESTERROR 0x0300
++#define TITAN_GE_MSTATX_TXUNICASTFRAMESOK 0x0310
++#define TITAN_GE_MSTATX_TXBROADCASTFRAMESOK 0x0320
++#define TITAN_GE_MSTATX_TXMULTICASTFRAMESOK 0x0330
++#define TITAN_GE_MSTATX_TXUNICASTFRAMESATTEMPTED 0x0340
++#define TITAN_GE_MSTATX_TXBROADCASTFRAMESATTEMPTED 0x0350
++#define TITAN_GE_MSTATX_TXMULTICASTFRAMESATTEMPTED 0x0360
++#define TITAN_GE_MSTATX_TXFRAMES64OCTETS 0x0370
++#define TITAN_GE_MSTATX_TXFRAMES65TO127OCTETS 0x0380
++#define TITAN_GE_MSTATX_TXFRAMES128TO255OCTETS 0x0390
++#define TITAN_GE_MSTATX_TXFRAMES256TO511OCTETS 0x03A0
++#define TITAN_GE_MSTATX_TXFRAMES512TO1023OCTETS 0x03B0
++#define TITAN_GE_MSTATX_TXFRAMES1024TO1518OCTETS 0x03C0
++#define TITAN_GE_MSTATX_TXFRAMES1519TOMAXSIZE 0x03D0
++#define TITAN_GE_MSTATX_TXVARIABLE 0x03E0
++#define TITAN_GE_MSTATX_RXSYSTEMERROR 0x03F0
++#define TITAN_GE_MSTATX_SINGLECOLLISION 0x0400
++#define TITAN_GE_MSTATX_MULTIPLECOLLISION 0x0410
++#define TITAN_GE_MSTATX_DEFERREDXMISSIONS 0x0420
++#define TITAN_GE_MSTATX_LATECOLLISIONS 0x0430
++#define TITAN_GE_MSTATX_ABORTEDDUETOXSCOLLS 0x0440
++
++/* Interrupt specific defines */
++#define TITAN_GE_DEVICE_ID 0x0000 /* Device ID */
++#define TITAN_GE_RESET 0x0004 /* Reset reg */
++#define TITAN_GE_TSB_CTRL_0 0x000C /* TSB Control reg 0 */
++#define TITAN_GE_TSB_CTRL_1 0x0010 /* TSB Control reg 1 */
++#define TITAN_GE_INTR_GRP0_STATUS 0x0040 /* General Interrupt Group 0 Status */
++#define TITAN_GE_INTR_XDMA_CORE_A 0x0048 /* XDMA Channel Interrupt Status, Core A*/
++#define TITAN_GE_INTR_XDMA_CORE_B 0x004C /* XDMA Channel Interrupt Status, Core B*/
++#define TITAN_GE_INTR_XDMA_IE 0x0058 /* XDMA Channel Interrupt Enable */
++#define TITAN_GE_SDQPF_ECC_INTR 0x480C /* SDQPF ECC Interrupt Status */
++#define TITAN_GE_SDQPF_RXFIFO_CTL 0x4828 /* SDQPF RxFifo Control and Interrupt Enb*/
++#define TITAN_GE_SDQPF_RXFIFO_INTR 0x482C /* SDQPF RxFifo Interrupt Status */
++#define TITAN_GE_SDQPF_TXFIFO_CTL 0x4928 /* SDQPF TxFifo Control and Interrupt Enb*/
++#define TITAN_GE_SDQPF_TXFIFO_INTR 0x492C /* SDQPF TxFifo Interrupt Status */
++#define TITAN_GE_SDQPF_RXFIFO_0 0x4840 /* SDQPF RxFIFO Enable */
++#define TITAN_GE_SDQPF_TXFIFO_0 0x4940 /* SDQPF TxFIFO Enable */
++#define TITAN_GE_XDMA_CONFIG 0x5000 /* XDMA Global Configuration */
++#define TITAN_GE_XDMA_INTR_SUMMARY 0x5010 /* XDMA Interrupt Summary */
++#define TITAN_GE_XDMA_BUFADDRPRE 0x5018 /* XDMA Buffer Address Prefix */
++#define TITAN_GE_XDMA_DESCADDRPRE 0x501C /* XDMA Descriptor Address Prefix */
++#define TITAN_GE_XDMA_PORTWEIGHT 0x502C /* XDMA Port Weight Configuration */
++
++/* Rx MAC defines */
++#define TITAN_GE_RMAC_CONFIG_1 0x1200 /* RMAC Configuration 1 */
++#define TITAN_GE_RMAC_CONFIG_2 0x1204 /* RMAC Configuration 2 */
++#define TITAN_GE_RMAC_MAX_FRAME_LEN 0x1208 /* RMAC Max Frame Length */
++#define TITAN_GE_RMAC_STATION_HI 0x120C /* Rx Station Address High */
++#define TITAN_GE_RMAC_STATION_MID 0x1210 /* Rx Station Address Middle */
++#define TITAN_GE_RMAC_STATION_LOW 0x1214 /* Rx Station Address Low */
++#define TITAN_GE_RMAC_LINK_CONFIG 0x1218 /* RMAC Link Configuration */
++
++/* Tx MAC defines */
++#define TITAN_GE_TMAC_CONFIG_1 0x1240 /* TMAC Configuration 1 */
++#define TITAN_GE_TMAC_CONFIG_2 0x1244 /* TMAC Configuration 2 */
++#define TITAN_GE_TMAC_IPG 0x1248 /* TMAC Inter-Packet Gap */
++#define TITAN_GE_TMAC_STATION_HI 0x124C /* Tx Station Address High */
++#define TITAN_GE_TMAC_STATION_MID 0x1250 /* Tx Station Address Middle */
++#define TITAN_GE_TMAC_STATION_LOW 0x1254 /* Tx Station Address Low */
++#define TITAN_GE_TMAC_MAX_FRAME_LEN 0x1258 /* TMAC Max Frame Length */
++#define TITAN_GE_TMAC_MIN_FRAME_LEN 0x125C /* TMAC Min Frame Length */
++#define TITAN_GE_TMAC_PAUSE_FRAME_TIME 0x1260 /* TMAC Pause Frame Time */
++#define TITAN_GE_TMAC_PAUSE_FRAME_INTERVAL 0x1264 /* TMAC Pause Frame Interval */
++
++/* GMII register */
++#define TITAN_GE_GMII_INTERRUPT_STATUS 0x1348 /* GMII Interrupt Status */
++#define TITAN_GE_GMII_CONFIG_GENERAL 0x134C /* GMII Configuration General */
++#define TITAN_GE_GMII_CONFIG_MODE 0x1350 /* GMII Configuration Mode */
++
++/* Tx and Rx XDMA defines */
++#define TITAN_GE_INT_COALESCING 0x5030 /* Interrupt Coalescing */
++#define TITAN_GE_CHANNEL0_CONFIG 0x5040 /* Channel 0 XDMA config */
++#define TITAN_GE_CHANNEL0_INTERRUPT 0x504c /* Channel 0 Interrupt Status */
++#define TITAN_GE_GDI_INTERRUPT_ENABLE 0x5050 /* IE for the GDI Errors */
++#define TITAN_GE_CHANNEL0_PACKET 0x5060 /* Channel 0 Packet count */
++#define TITAN_GE_CHANNEL0_BYTE 0x5064 /* Channel 0 Byte count */
++#define TITAN_GE_CHANNEL0_TX_DESC 0x5054 /* Channel 0 Tx first desc */
++#define TITAN_GE_CHANNEL0_RX_DESC 0x5058 /* Channel 0 Rx first desc */
++
++/* AFX (Address Filter Exact) register offsets for Slice 0 */
++#define TITAN_GE_AFX_EXACT_MATCH_LOW 0x1100 /* AFX Exact Match Address Low*/
++#define TITAN_GE_AFX_EXACT_MATCH_MID 0x1104 /* AFX Exact Match Address Mid*/
++#define TITAN_GE_AFX_EXACT_MATCH_HIGH 0x1108 /* AFX Exact Match Address Hi */
++#define TITAN_GE_AFX_EXACT_MATCH_VID 0x110C /* AFX Exact Match VID */
++#define TITAN_GE_AFX_MULTICAST_HASH_LOW 0x1110 /* AFX Multicast HASH Low */
++#define TITAN_GE_AFX_MULTICAST_HASH_MIDLOW 0x1114 /* AFX Multicast HASH MidLow */
++#define TITAN_GE_AFX_MULTICAST_HASH_MIDHI 0x1118 /* AFX Multicast HASH MidHi */
++#define TITAN_GE_AFX_MULTICAST_HASH_HI 0x111C /* AFX Multicast HASH Hi */
++#define TITAN_GE_AFX_ADDRS_FILTER_CTRL_0 0x1120 /* AFX Address Filter Ctrl 0 */
++#define TITAN_GE_AFX_ADDRS_FILTER_CTRL_1 0x1124 /* AFX Address Filter Ctrl 1 */
++#define TITAN_GE_AFX_ADDRS_FILTER_CTRL_2 0x1128 /* AFX Address Filter Ctrl 2 */
++
++/* Traffic Groomer block */
++#define TITAN_GE_TRTG_CONFIG 0x1000 /* TRTG Config */
++
++#endif /* _TITAN_GE_H_ */
++
+diff --git a/drivers/net/titan_mdio.c b/drivers/net/titan_mdio.c
+new file mode 100644
+index 0000000..8a8785b
+--- /dev/null
++++ b/drivers/net/titan_mdio.c
+@@ -0,0 +1,217 @@
++/*
++ * drivers/net/titan_mdio.c - Driver for Titan ethernet ports
++ *
++ * Copyright (C) 2003 PMC-Sierra Inc.
++ * Author : Manish Lachwani (lachwani@pmc-sierra.com)
++ *
++ * 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.
++ *
++ * Management Data IO (MDIO) driver for the Titan GMII. Interacts with the Marvel PHY
++ * on the Titan. No support for the TBI as yet.
++ *
++ */
++
++#include "titan_mdio.h"
++
++#define MDIO_DEBUG
++
++/*
++ * Local constants
++ */
++#define MAX_CLKA 1023
++#define MAX_PHY_DEV 31
++#define MAX_PHY_REG 31
++#define WRITEADDRS_OPCODE 0x0
++#define READ_OPCODE 0x2
++#define WRITE_OPCODE 0x1
++#define MAX_MDIO_POLL 100
++
++/*
++ * Titan MDIO and SCMB registers
++ */
++#define TITAN_GE_SCMB_CONTROL 0x01c0 /* SCMB Control */
++#define TITAN_GE_SCMB_CLKA 0x01c4 /* SCMB Clock A */
++#define TITAN_GE_MDIO_COMMAND 0x01d0 /* MDIO Command */
++#define TITAN_GE_MDIO_DEVICE_PORT_ADDRESS 0x01d4 /* MDIO Device and Port addrs */
++#define TITAN_GE_MDIO_DATA 0x01d8 /* MDIO Data */
++#define TITAN_GE_MDIO_INTERRUPTS 0x01dC /* MDIO Interrupts */
++
++/*
++ * Function to poll the MDIO
++ */
++static int titan_ge_mdio_poll(void)
++{
++ int i, val;
++
++ for (i = 0; i < MAX_MDIO_POLL; i++) {
++ val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_COMMAND);
++
++ if (!(val & 0x8000))
++ return TITAN_GE_MDIO_GOOD;
++ }
++
++ return TITAN_GE_MDIO_ERROR;
++}
++
++
++/*
++ * Initialize and configure the MDIO
++ */
++int titan_ge_mdio_setup(titan_ge_mdio_config *titan_mdio)
++{
++ unsigned long val;
++
++ /* Reset the SCMB and program into MDIO mode*/
++ TITAN_GE_MDIO_WRITE(TITAN_GE_SCMB_CONTROL, 0x9000);
++ TITAN_GE_MDIO_WRITE(TITAN_GE_SCMB_CONTROL, 0x1000);
++
++ /* CLK A */
++ val = TITAN_GE_MDIO_READ(TITAN_GE_SCMB_CLKA);
++ val = ( (val & ~(0x03ff)) | (titan_mdio->clka & 0x03ff));
++ TITAN_GE_MDIO_WRITE(TITAN_GE_SCMB_CLKA, val);
++
++ /* Preamble Suppresion */
++ val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_COMMAND);
++ val = ( (val & ~(0x0001)) | (titan_mdio->mdio_spre & 0x0001));
++ TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_COMMAND, val);
++
++ /* MDIO mode */
++ val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS);
++ val = ( (val & ~(0x4000)) | (titan_mdio->mdio_mode & 0x4000));
++ TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS, val);
++
++ return TITAN_GE_MDIO_GOOD;
++}
++
++/*
++ * Set the PHY address in indirect mode
++ */
++int titan_ge_mdio_inaddrs(int dev_addr, int reg_addr)
++{
++ volatile unsigned long val;
++
++ /* Setup the PHY device */
++ val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS);
++ val = ( (val & ~(0x1f00)) | ( (dev_addr << 8) & 0x1f00));
++ val = ( (val & ~(0x001f)) | ( reg_addr & 0x001f));
++ TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS, val);
++
++ /* Write the new address */
++ val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_COMMAND);
++ val = ( (val & ~(0x0300)) | ( (WRITEADDRS_OPCODE << 8) & 0x0300));
++ TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_COMMAND, val);
++
++ return TITAN_GE_MDIO_GOOD;
++}
++
++/*
++ * Read the MDIO register. This is what the individual parametes mean:
++ *
++ * dev_addr : PHY ID
++ * reg_addr : register offset
++ *
++ * See the spec for the Titan MAC. We operate in the Direct Mode.
++ */
++
++#define MAX_RETRIES 2
++
++int titan_ge_mdio_read(int dev_addr, int reg_addr, unsigned int *pdata)
++{
++ volatile unsigned long val;
++ int retries = 0;
++
++ /* Setup the PHY device */
++
++again:
++ val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS);
++ val = ( (val & ~(0x1f00)) | ( (dev_addr << 8) & 0x1f00));
++ val = ( (val & ~(0x001f)) | ( reg_addr & 0x001f));
++ val |= 0x4000;
++ TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS, val);
++
++ udelay(30);
++
++ /* Issue the read command */
++ val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_COMMAND);
++ val = ( (val & ~(0x0300)) | ( (READ_OPCODE << 8) & 0x0300));
++ TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_COMMAND, val);
++
++ udelay(30);
++
++ if (titan_ge_mdio_poll() != TITAN_GE_MDIO_GOOD)
++ return TITAN_GE_MDIO_ERROR;
++
++ *pdata = (unsigned int)TITAN_GE_MDIO_READ(TITAN_GE_MDIO_DATA);
++ val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_INTERRUPTS);
++
++ udelay(30);
++
++ if (val & 0x2) {
++ if (retries == MAX_RETRIES)
++ return TITAN_GE_MDIO_ERROR;
++ else {
++ retries++;
++ goto again;
++ }
++ }
++
++ return TITAN_GE_MDIO_GOOD;
++}
++
++/*
++ * Write to the MDIO register
++ *
++ * dev_addr : PHY ID
++ * reg_addr : register that needs to be written to
++ *
++ */
++int titan_ge_mdio_write(int dev_addr, int reg_addr, unsigned int data)
++{
++ volatile unsigned long val;
++
++ if (titan_ge_mdio_poll() != TITAN_GE_MDIO_GOOD)
++ return TITAN_GE_MDIO_ERROR;
++
++ /* Setup the PHY device */
++ val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS);
++ val = ( (val & ~(0x1f00)) | ( (dev_addr << 8) & 0x1f00));
++ val = ( (val & ~(0x001f)) | ( reg_addr & 0x001f));
++ val |= 0x4000;
++ TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS, val);
++
++ udelay(30);
++
++ /* Setup the data to write */
++ TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_DATA, data);
++
++ udelay(30);
++
++ /* Issue the write command */
++ val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_COMMAND);
++ val = ( (val & ~(0x0300)) | ( (WRITE_OPCODE << 8) & 0x0300));
++ TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_COMMAND, val);
++
++ udelay(30);
++
++ if (titan_ge_mdio_poll() != TITAN_GE_MDIO_GOOD)
++ return TITAN_GE_MDIO_ERROR;
++
++ val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_INTERRUPTS);
++ if (val & 0x2)
++ return TITAN_GE_MDIO_ERROR;
++
++ return TITAN_GE_MDIO_GOOD;
++}
++
+diff --git a/drivers/net/titan_mdio.h b/drivers/net/titan_mdio.h
+new file mode 100644
+index 0000000..5d23344
+--- /dev/null
++++ b/drivers/net/titan_mdio.h
+@@ -0,0 +1,56 @@
++/*
++ * MDIO used to interact with the PHY when using GMII/MII
++ */
++#ifndef _TITAN_MDIO_H
++#define _TITAN_MDIO_H
++
++#include <linux/netdevice.h>
++#include <linux/workqueue.h>
++#include <linux/delay.h>
++#include "titan_ge.h"
++
++
++#define TITAN_GE_MDIO_ERROR (-9000)
++#define TITAN_GE_MDIO_GOOD 0
++
++#define TITAN_GE_MDIO_BASE titan_ge_base
++
++#define TITAN_GE_MDIO_READ(offset) \
++ *(volatile u32 *)(titan_ge_base + (offset))
++
++#define TITAN_GE_MDIO_WRITE(offset, data) \
++ *(volatile u32 *)(titan_ge_base + (offset)) = (data)
++
++
++/* GMII specific registers */
++#define TITAN_GE_MARVEL_PHY_ID 0x00
++#define TITAN_PHY_AUTONEG_ADV 0x04
++#define TITAN_PHY_LP_ABILITY 0x05
++#define TITAN_GE_MDIO_MII_CTRL 0x09
++#define TITAN_GE_MDIO_MII_EXTENDED 0x0f
++#define TITAN_GE_MDIO_PHY_CTRL 0x10
++#define TITAN_GE_MDIO_PHY_STATUS 0x11
++#define TITAN_GE_MDIO_PHY_IE 0x12
++#define TITAN_GE_MDIO_PHY_IS 0x13
++#define TITAN_GE_MDIO_PHY_LED 0x18
++#define TITAN_GE_MDIO_PHY_LED_OVER 0x19
++#define PHY_ANEG_TIME_WAIT 45 /* 45 seconds wait time */
++
++/*
++ * MDIO Config Structure
++ */
++typedef struct {
++ unsigned int clka;
++ int mdio_spre;
++ int mdio_mode;
++} titan_ge_mdio_config;
++
++/*
++ * Function Prototypes
++ */
++int titan_ge_mdio_setup(titan_ge_mdio_config *);
++int titan_ge_mdio_inaddrs(int, int);
++int titan_ge_mdio_read(int, int, unsigned int *);
++int titan_ge_mdio_write(int, int, unsigned int);
++
++#endif /* _TITAN_MDIO_H */
+diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
+index d7a764a..75b6899 100644
+--- a/drivers/net/wireless/Kconfig
++++ b/drivers/net/wireless/Kconfig
+@@ -400,7 +400,7 @@ config RTL8180
+
+ config RTL8187
+ tristate "Realtek 8187 and 8187B USB support"
+- depends on MAC80211 && USB && WLAN_80211
++ depends on MAC80211 && USB && WLAN_80211 && !LEMOTE_MACH2F
+ select EEPROM_93CX6
+ ---help---
+ This is a driver for RTL8187 and RTL8187B based cards.
+@@ -427,6 +427,19 @@ config RTL8187_LEDS
+ depends on RTL8187 && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = RTL8187)
+ default y
+
++config RTL8187B
++ tristate "Realtek 8187B wifi support for yeeloong2f laptop"
++ depends on USB && WLAN_80211 && LEMOTE_MACH2F
++ depends on LEMOTE_YEELOONG2F_PDEV || !LEMOTE_YEELOONG2F_PDEV
++ depends on RFKILL || !RFKILL
++ select EEPROM_93CX6
++ select CRYPTO
++ ---help---
++ This is a driver for RTL8187B based cards, this driver is especially
++ for yeeloon2f laptop.
++
++ Thanks to Realtek for their support!
++
+ config ADM8211
+ tristate "ADMtek ADM8211 support"
+ depends on MAC80211 && PCI && WLAN_80211 && EXPERIMENTAL
+diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
+index 7a4647e..5b1eb08 100644
+--- a/drivers/net/wireless/Makefile
++++ b/drivers/net/wireless/Makefile
+@@ -34,6 +34,7 @@ obj-$(CONFIG_B43LEGACY) += b43legacy/
+ obj-$(CONFIG_ZD1211RW) += zd1211rw/
+ obj-$(CONFIG_RTL8180) += rtl818x/
+ obj-$(CONFIG_RTL8187) += rtl818x/
++obj-$(CONFIG_RTL8187B) += rtl8187b/
+
+ # 16-bit wireless PCMCIA client drivers
+ obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o
+diff --git a/drivers/net/wireless/rtl8187b/Makefile b/drivers/net/wireless/rtl8187b/Makefile
+new file mode 100644
+index 0000000..c28a4aa
+--- /dev/null
++++ b/drivers/net/wireless/rtl8187b/Makefile
+@@ -0,0 +1,41 @@
++obj-$(CONFIG_RTL8187B) += rtl8187b.o
++
++rtl8187b-objs := r8187_core.o \
++ r8180_93cx6.o \
++ r8180_wx.o \
++ r8180_rtl8225.o \
++ r8180_rtl8225z2.o \
++ r8180_pm.o \
++ r8180_dm.o \
++ r8187_led.o \
++ r8187_rfkill.o \
++ ieee80211/dot11d.o \
++ ieee80211/ieee80211_softmac.o \
++ ieee80211/ieee80211_rx.o \
++ ieee80211/ieee80211_tx.o \
++ ieee80211/ieee80211_wx.o \
++ ieee80211/ieee80211_module.o \
++ ieee80211/ieee80211_softmac_wx.o \
++ ieee80211/ieee80211_crypt.o \
++ ieee80211/ieee80211_crypt_tkip.o \
++ ieee80211/ieee80211_crypt_ccmp.o \
++ ieee80211/ieee80211_crypt_wep.o
++
++EXTRA_CFLAGS += -DCONFIG_RTL8180_PM
++EXTRA_CFLAGS += -DJACKSON_NEW_8187 -DJACKSON_NEW_RX
++EXTRA_CFLAGS += -DTHOMAS_BEACON -DTHOMAS_TASKLET -DTHOMAS_SKB -DTHOMAS_TURBO
++EXTRA_CFLAGS += -DJOHN_IOCTL
++EXTRA_CFLAGS += -DLED
++#EXTRA_CFLAGS += -DLED_SHIN
++#EXTRA_CFLAGS += -DSW_ANTE_DIVERSITY
++EXTRA_CFLAGS += -DCPU_64BIT
++EXTRA_CFLAGS += -DCONFIG_IPS
++#CFLAGS += -DJOHN_HWSEC -DJOHN_TKIP
++#CFLAGS += -DJOHN_DUMP_TX
++#EXTRA_CFLAGS += -DJOHN_DUMP_TXPKT
++
++#Radio On/Off debug
++EXTRA_CFLAGS += -DCONFIG_RADIO_DEBUG
++
++#for dot11d
++EXTRA_CFLAGS += -DENABLE_DOT11D
+diff --git a/drivers/net/wireless/rtl8187b/dot11d.h b/drivers/net/wireless/rtl8187b/dot11d.h
+new file mode 100644
+index 0000000..99010be
+--- /dev/null
++++ b/drivers/net/wireless/rtl8187b/dot11d.h
+@@ -0,0 +1,102 @@
++#ifndef __INC_DOT11D_H
++#define __INC_DOT11D_H
++
++#include "ieee80211/ieee80211.h"
++
++//#define ENABLE_DOT11D
++
++//#define DOT11D_MAX_CHNL_NUM 83
++
++typedef struct _CHNL_TXPOWER_TRIPLE {
++ u8 FirstChnl;
++ u8 NumChnls;
++ u8 MaxTxPowerInDbm;
++}CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;
++
++typedef enum _DOT11D_STATE {
++ DOT11D_STATE_NONE = 0,
++ DOT11D_STATE_LEARNED,
++ DOT11D_STATE_DONE,
++}DOT11D_STATE;
++
++typedef struct _RT_DOT11D_INFO {
++ //DECLARE_RT_OBJECT(RT_DOT11D_INFO);
++
++ bool bEnabled; // dot11MultiDomainCapabilityEnabled
++
++ u16 CountryIeLen; // > 0 if CountryIeBuf[] contains valid country information element.
++ u8 CountryIeBuf[MAX_IE_LEN];
++ u8 CountryIeSrcAddr[6]; // Source AP of the country IE.
++ u8 CountryIeWatchdog;
++
++ u8 channel_map[MAX_CHANNEL_NUMBER+1]; //!!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan)
++ //u8 ChnlListLen; // #Bytes valid in ChnlList[].
++ //u8 ChnlList[DOT11D_MAX_CHNL_NUM];
++ u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];
++
++ DOT11D_STATE State;
++}RT_DOT11D_INFO, *PRT_DOT11D_INFO;
++#define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 )
++#define cpMacAddr(des,src) ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3],(des)[4]=(src)[4],(des)[5]=(src)[5])
++#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo))
++
++#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled
++#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0)
++
++#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
++#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
++
++#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \
++ (((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \
++ FALSE : \
++ (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length)))
++
++#define CIE_WATCHDOG_TH 1
++#define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog
++#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0
++#define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev)
++
++#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)
++
++
++void
++Dot11d_Init(
++ struct ieee80211_device *dev
++ );
++
++void
++Dot11d_Reset(
++ struct ieee80211_device *dev
++ );
++
++void
++Dot11d_UpdateCountryIe(
++ struct ieee80211_device *dev,
++ u8 * pTaddr,
++ u16 CoutryIeLen,
++ u8 * pCoutryIe
++ );
++
++u8
++DOT11D_GetMaxTxPwrInDbm(
++ struct ieee80211_device *dev,
++ u8 Channel
++ );
++
++void
++DOT11D_ScanComplete(
++ struct ieee80211_device * dev
++ );
++
++int IsLegalChannel(
++ struct ieee80211_device * dev,
++ u8 channel
++);
++
++int ToLegalChannel(
++ struct ieee80211_device * dev,
++ u8 channel
++);
++
++void dump_chnl_map(u8 * channel_map);
++#endif // #ifndef __INC_DOT11D_H
+diff --git a/drivers/net/wireless/rtl8187b/ieee80211/arc4.c b/drivers/net/wireless/rtl8187b/ieee80211/arc4.c
+new file mode 100644
+index 0000000..e93e5e2
+--- /dev/null
++++ b/drivers/net/wireless/rtl8187b/ieee80211/arc4.c
+@@ -0,0 +1,103 @@
++/*
++ * Cryptographic API
++ *
++ * ARC4 Cipher Algorithm
++ *
++ * Jon Oberheide <jon@oberheide.org>
++ *
++ * 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 <linux/module.h>
++#include <linux/init.h>
++#include "rtl_crypto.h"
++
++#define ARC4_MIN_KEY_SIZE 1
++#define ARC4_MAX_KEY_SIZE 256
++#define ARC4_BLOCK_SIZE 1
++
++struct arc4_ctx {
++ u8 S[256];
++ u8 x, y;
++};
++
++static int arc4_set_key(void *ctx_arg, const u8 *in_key, unsigned int key_len, u32 *flags)
++{
++ struct arc4_ctx *ctx = ctx_arg;
++ int i, j = 0, k = 0;
++
++ ctx->x = 1;
++ ctx->y = 0;
++
++ for(i = 0; i < 256; i++)
++ ctx->S[i] = i;
++
++ for(i = 0; i < 256; i++)
++ {
++ u8 a = ctx->S[i];
++ j = (j + in_key[k] + a) & 0xff;
++ ctx->S[i] = ctx->S[j];
++ ctx->S[j] = a;
++ if(++k >= key_len)
++ k = 0;
++ }
++
++ return 0;
++}
++
++static void arc4_crypt(void *ctx_arg, u8 *out, const u8 *in)
++{
++ struct arc4_ctx *ctx = ctx_arg;
++
++ u8 *const S = ctx->S;
++ u8 x = ctx->x;
++ u8 y = ctx->y;
++ u8 a, b;
++
++ a = S[x];
++ y = (y + a) & 0xff;
++ b = S[y];
++ S[x] = b;
++ S[y] = a;
++ x = (x + 1) & 0xff;
++ *out++ = *in ^ S[(a + b) & 0xff];
++
++ ctx->x = x;
++ ctx->y = y;
++}
++
++static struct crypto_alg arc4_alg = {
++ .cra_name = "arc4",
++ .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
++ .cra_blocksize = ARC4_BLOCK_SIZE,
++ .cra_ctxsize = sizeof(struct arc4_ctx),
++ .cra_module = THIS_MODULE,
++ .cra_list = LIST_HEAD_INIT(arc4_alg.cra_list),
++ .cra_u = { .cipher = {
++ .cia_min_keysize = ARC4_MIN_KEY_SIZE,
++ .cia_max_keysize = ARC4_MAX_KEY_SIZE,
++ .cia_setkey = arc4_set_key,
++ .cia_encrypt = arc4_crypt,
++ .cia_decrypt = arc4_crypt } }
++};
++
++static int __init arc4_init(void)
++{
++ return crypto_register_alg(&arc4_alg);
++}
++
++
++static void __exit arc4_exit(void)
++{
++ crypto_unregister_alg(&arc4_alg);
++}
++
++module_init(arc4_init);
++module_exit(arc4_exit);
++
++MODULE_LICENSE("GPL");
++MODULE_DESCRIPTION("ARC4 Cipher Algorithm");
++MODULE_AUTHOR("Jon Oberheide <jon@oberheide.org>");
+diff --git a/drivers/net/wireless/rtl8187b/ieee80211/dot11d.c b/drivers/net/wireless/rtl8187b/ieee80211/dot11d.c
+new file mode 100644
+index 0000000..8d662b5
+--- /dev/null
++++ b/drivers/net/wireless/rtl8187b/ieee80211/dot11d.c
+@@ -0,0 +1,244 @@
++#ifdef ENABLE_DOT11D
++//-----------------------------------------------------------------------------
++// File:
++// Dot11d.c
++//
++// Description:
++// Implement 802.11d.
++//
++//-----------------------------------------------------------------------------
++
++#include "dot11d.h"
++
++void
++Dot11d_Init(struct ieee80211_device *ieee)
++{
++ PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);
++
++ pDot11dInfo->bEnabled = 0;
++
++ pDot11dInfo->State = DOT11D_STATE_NONE;
++ pDot11dInfo->CountryIeLen = 0;
++ memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
++ memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
++ RESET_CIE_WATCHDOG(ieee);
++
++ //printk("Dot11d_Init()\n");
++}
++
++//
++// Description:
++// Reset to the state as we are just entering a regulatory domain.
++//
++void
++Dot11d_Reset(struct ieee80211_device *ieee)
++{
++ u32 i;
++ PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);
++
++ // Clear old channel map
++ memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
++ memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
++ // Set new channel map
++ for (i=1; i<=11; i++) {
++ (pDot11dInfo->channel_map)[i] = 1;
++ }
++ for (i=12; i<=14; i++) {
++ (pDot11dInfo->channel_map)[i] = 2;
++ }
++
++ pDot11dInfo->State = DOT11D_STATE_NONE;
++ pDot11dInfo->CountryIeLen = 0;
++ RESET_CIE_WATCHDOG(ieee);
++
++ //printk("Dot11d_Reset()\n");
++}
++
++//
++// Description:
++// Update country IE from Beacon or Probe Resopnse
++// and configure PHY for operation in the regulatory domain.
++//
++// TODO:
++// Configure Tx power.
++//
++// Assumption:
++// 1. IS_DOT11D_ENABLE() is TRUE.
++// 2. Input IE is an valid one.
++//
++void
++Dot11d_UpdateCountryIe(
++ struct ieee80211_device *dev,
++ u8 * pTaddr,
++ u16 CoutryIeLen,
++ u8 * pCoutryIe
++ )
++{
++ PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
++ u8 i, j, NumTriples, MaxChnlNum;
++ PCHNL_TXPOWER_TRIPLE pTriple;
++
++ if((CoutryIeLen - 3)%3 != 0)
++ {
++ printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
++ Dot11d_Reset(dev);
++ return;
++ }
++
++ memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
++ memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
++ MaxChnlNum = 0;
++ NumTriples = (CoutryIeLen - 3) / 3; // skip 3-byte country string.
++ pTriple = (PCHNL_TXPOWER_TRIPLE)(pCoutryIe + 3);
++ for(i = 0; i < NumTriples; i++)
++ {
++ if(MaxChnlNum >= pTriple->FirstChnl)
++ { // It is not in a monotonically increasing order, so stop processing.
++ printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
++ Dot11d_Reset(dev);
++ return;
++ }
++ if(MAX_CHANNEL_NUMBER < (pTriple->FirstChnl + pTriple->NumChnls))
++ { // It is not a valid set of channel id, so stop processing.
++ printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........2\n");
++ Dot11d_Reset(dev);
++ return;
++ }
++
++ for(j = 0 ; j < pTriple->NumChnls; j++)
++ {
++ pDot11dInfo->channel_map[pTriple->FirstChnl + j] = 1;
++ pDot11dInfo->MaxTxPwrDbmList[pTriple->FirstChnl + j] = pTriple->MaxTxPowerInDbm;
++ MaxChnlNum = pTriple->FirstChnl + j;
++ }
++
++ pTriple = (PCHNL_TXPOWER_TRIPLE)((u8*)pTriple + 3);
++ }
++#if 1
++ //printk("Dot11d_UpdateCountryIe(): Channel List:\n");
++ printk("Channel List:");
++ for(i=1; i<= MAX_CHANNEL_NUMBER; i++)
++ if(pDot11dInfo->channel_map[i] > 0)
++ printk(" %d", i);
++ printk("\n");
++#endif
++
++ UPDATE_CIE_SRC(dev, pTaddr);
++
++ pDot11dInfo->CountryIeLen = CoutryIeLen;
++ memcpy(pDot11dInfo->CountryIeBuf, pCoutryIe,CoutryIeLen);
++ pDot11dInfo->State = DOT11D_STATE_LEARNED;
++}
++
++void dump_chnl_map(u8 * channel_map)
++{
++ int i;
++ printk("Channel List:");
++ for(i=1; i<= MAX_CHANNEL_NUMBER; i++)
++ if(channel_map[i] > 0)
++ printk(" %d(%d)", i, channel_map[i]);
++ printk("\n");
++}
++
++u8
++DOT11D_GetMaxTxPwrInDbm(
++ struct ieee80211_device *dev,
++ u8 Channel
++ )
++{
++ PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
++ u8 MaxTxPwrInDbm = 255;
++
++ if(MAX_CHANNEL_NUMBER < Channel)
++ {
++ printk("DOT11D_GetMaxTxPwrInDbm(): Invalid Channel\n");
++ return MaxTxPwrInDbm;
++ }
++ if(pDot11dInfo->channel_map[Channel])
++ {
++ MaxTxPwrInDbm = pDot11dInfo->MaxTxPwrDbmList[Channel];
++ }
++
++ return MaxTxPwrInDbm;
++}
++
++
++void
++DOT11D_ScanComplete(
++ struct ieee80211_device * dev
++ )
++{
++ PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
++
++ switch(pDot11dInfo->State)
++ {
++ case DOT11D_STATE_LEARNED:
++ pDot11dInfo->State = DOT11D_STATE_DONE;
++ break;
++
++ case DOT11D_STATE_DONE:
++ if( GET_CIE_WATCHDOG(dev) == 0 )
++ { // Reset country IE if previous one is gone.
++ Dot11d_Reset(dev);
++ }
++ break;
++ case DOT11D_STATE_NONE:
++ break;
++ }
++}
++
++int IsLegalChannel(
++ struct ieee80211_device * dev,
++ u8 channel
++)
++{
++ PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
++
++ if(MAX_CHANNEL_NUMBER < channel)
++ {
++ printk("IsLegalChannel(): Invalid Channel\n");
++ return 0;
++ }
++ if(pDot11dInfo->channel_map[channel] > 0)
++ return 1;
++ return 0;
++}
++
++int ToLegalChannel(
++ struct ieee80211_device * dev,
++ u8 channel
++)
++{
++ PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
++ u8 default_chn = 0;
++ u32 i = 0;
++
++ for (i=1; i<= MAX_CHANNEL_NUMBER; i++)
++ {
++ if(pDot11dInfo->channel_map[i] > 0)
++ {
++ default_chn = i;
++ break;
++ }
++ }
++
++ if(MAX_CHANNEL_NUMBER < channel)
++ {
++ printk("IsLegalChannel(): Invalid Channel\n");
++ return default_chn;
++ }
++
++ if(pDot11dInfo->channel_map[channel] > 0)
++ return channel;
++
++ return default_chn;
++}
++
++EXPORT_SYMBOL(Dot11d_Init);
++EXPORT_SYMBOL(Dot11d_Reset);
++EXPORT_SYMBOL(Dot11d_UpdateCountryIe);
++EXPORT_SYMBOL(DOT11D_GetMaxTxPwrInDbm);
++EXPORT_SYMBOL(DOT11D_ScanComplete);
++EXPORT_SYMBOL(IsLegalChannel);
++EXPORT_SYMBOL(ToLegalChannel);
++#endif
+diff --git a/drivers/net/wireless/rtl8187b/ieee80211/dot11d.h b/drivers/net/wireless/rtl8187b/ieee80211/dot11d.h
+new file mode 100644
+index 0000000..64bcf15
+--- /dev/null
++++ b/drivers/net/wireless/rtl8187b/ieee80211/dot11d.h
+@@ -0,0 +1,102 @@
++#ifndef __INC_DOT11D_H
++#define __INC_DOT11D_H
++
++#include "ieee80211.h"
++
++//#define ENABLE_DOT11D
++
++//#define DOT11D_MAX_CHNL_NUM 83
++
++typedef struct _CHNL_TXPOWER_TRIPLE {
++ u8 FirstChnl;
++ u8 NumChnls;
++ u8 MaxTxPowerInDbm;
++}CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;
++
++typedef enum _DOT11D_STATE {
++ DOT11D_STATE_NONE = 0,
++ DOT11D_STATE_LEARNED,
++ DOT11D_STATE_DONE,
++}DOT11D_STATE;
++
++typedef struct _RT_DOT11D_INFO {
++ //DECLARE_RT_OBJECT(RT_DOT11D_INFO);
++
++ bool bEnabled; // dot11MultiDomainCapabilityEnabled
++
++ u16 CountryIeLen; // > 0 if CountryIeBuf[] contains valid country information element.
++ u8 CountryIeBuf[MAX_IE_LEN];
++ u8 CountryIeSrcAddr[6]; // Source AP of the country IE.
++ u8 CountryIeWatchdog;
++
++ u8 channel_map[MAX_CHANNEL_NUMBER+1]; //!!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan)
++ //u8 ChnlListLen; // #Bytes valid in ChnlList[].
++ //u8 ChnlList[DOT11D_MAX_CHNL_NUM];
++ u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];
++
++ DOT11D_STATE State;
++}RT_DOT11D_INFO, *PRT_DOT11D_INFO;
++#define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 )
++#define cpMacAddr(des,src) ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3],(des)[4]=(src)[4],(des)[5]=(src)[5])
++#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo))
++
++#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled
++#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0)
++
++#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
++#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
++
++#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \
++ (((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \
++ FALSE : \
++ (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length)))
++
++#define CIE_WATCHDOG_TH 1
++#define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog
++#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0
++#define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev)
++
++#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)
++
++
++void
++Dot11d_Init(
++ struct ieee80211_device *dev
++ );
++
++void
++Dot11d_Reset(
++ struct ieee80211_device *dev
++ );
++
++void
++Dot11d_UpdateCountryIe(
++ struct ieee80211_device *dev,
++ u8 * pTaddr,
++ u16 CoutryIeLen,
++ u8 * pCoutryIe
++ );
++
++u8
++DOT11D_GetMaxTxPwrInDbm(
++ struct ieee80211_device *dev,
++ u8 Channel
++ );
++
++void
++DOT11D_ScanComplete(
++ struct ieee80211_device * dev
++ );
++
++int IsLegalChannel(
++ struct ieee80211_device * dev,
++ u8 channel
++);
++
++int ToLegalChannel(
++ struct ieee80211_device * dev,
++ u8 channel
++);
++
++void dump_chnl_map(u8 * channel_map);
++#endif // #ifndef __INC_DOT11D_H
+diff --git a/drivers/net/wireless/rtl8187b/ieee80211/ieee80211.h b/drivers/net/wireless/rtl8187b/ieee80211/ieee80211.h
+new file mode 100644
+index 0000000..01f707a
+--- /dev/null
++++ b/drivers/net/wireless/rtl8187b/ieee80211/ieee80211.h
+@@ -0,0 +1,1903 @@
++/*
++ * Merged with mainline ieee80211.h in Aug 2004. Original ieee802_11
++ * remains copyright by the original authors
++ *
++ * Portions of the merged code are based on Host AP (software wireless
++ * LAN access point) driver for Intersil Prism2/2.5/3.
++ *
++ * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
++ * <jkmaline@cc.hut.fi>
++ * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
++ *
++ * Adaption to a generic IEEE 802.11 stack by James Ketrenos
++ * <jketreno@linux.intel.com>
++ * Copyright (c) 2004, Intel Corporation
++ *
++ * Modified for Realtek's wi-fi cards by Andrea Merello
++ * <andreamrl@tiscali.it>
++ *
++ * 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. See README and COPYING for
++ * more details.
++ */
++#ifndef IEEE80211_H
++#define IEEE80211_H
++#include <linux/if_ether.h> /* ETH_ALEN */
++#include <linux/kernel.h> /* ARRAY_SIZE */
++#include <linux/version.h>
++#include <linux/module.h>
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
++#include <linux/jiffies.h>
++#else
++#include <linux/jffs.h>
++#include <linux/tqueue.h>
++#endif
++#include <linux/timer.h>
++#include <linux/sched.h>
++
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13))
++#include <linux/wireless.h>
++#endif
++/*
++#ifndef bool
++#define bool int
++#endif
++
++#ifndef true
++#define true 1
++#endif
++
++#ifndef false
++#define false 0
++#endif
++*/
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
++#ifndef bool
++typedef enum{false = 0, true} bool;
++#endif
++#endif
++//#ifdef JOHN_HWSEC
++#define KEY_TYPE_NA 0x0
++#define KEY_TYPE_WEP40 0x1
++#define KEY_TYPE_TKIP 0x2
++#define KEY_TYPE_CCMP 0x4
++#define KEY_TYPE_WEP104 0x5
++//#endif
++
++
++#define aSifsTime 10
++
++#define MGMT_QUEUE_NUM 5
++
++
++#define IEEE_CMD_SET_WPA_PARAM 1
++#define IEEE_CMD_SET_WPA_IE 2
++#define IEEE_CMD_SET_ENCRYPTION 3
++#define IEEE_CMD_MLME 4
++
++#define IEEE_PARAM_WPA_ENABLED 1
++#define IEEE_PARAM_TKIP_COUNTERMEASURES 2
++#define IEEE_PARAM_DROP_UNENCRYPTED 3
++#define IEEE_PARAM_PRIVACY_INVOKED 4
++#define IEEE_PARAM_AUTH_ALGS 5
++#define IEEE_PARAM_IEEE_802_1X 6
++//It should consistent with the driver_XXX.c
++// David, 2006.9.26
++#define IEEE_PARAM_WPAX_SELECT 7
++//Added for notify the encryption type selection
++// David, 2006.9.26
++#define IEEE_PROTO_WPA 1
++#define IEEE_PROTO_RSN 2
++//Added for notify the encryption type selection
++// David, 2006.9.26
++#define IEEE_WPAX_USEGROUP 0
++#define IEEE_WPAX_WEP40 1
++#define IEEE_WPAX_TKIP 2
++#define IEEE_WPAX_WRAP 3
++#define IEEE_WPAX_CCMP 4
++#define IEEE_WPAX_WEP104 5
++
++#define IEEE_KEY_MGMT_IEEE8021X 1
++#define IEEE_KEY_MGMT_PSK 2
++
++
++
++#define IEEE_MLME_STA_DEAUTH 1
++#define IEEE_MLME_STA_DISASSOC 2
++
++
++#define IEEE_CRYPT_ERR_UNKNOWN_ALG 2
++#define IEEE_CRYPT_ERR_UNKNOWN_ADDR 3
++#define IEEE_CRYPT_ERR_CRYPT_INIT_FAILED 4
++#define IEEE_CRYPT_ERR_KEY_SET_FAILED 5
++#define IEEE_CRYPT_ERR_TX_KEY_SET_FAILED 6
++#define IEEE_CRYPT_ERR_CARD_CONF_FAILED 7
++
++
++#define IEEE_CRYPT_ALG_NAME_LEN 16
++
++//#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,10))
++#define ieee80211_wx_get_scan ieee80211_wx_get_scan_rtl
++#define ieee80211_wx_set_encode ieee80211_wx_set_encode_rtl
++#define ieee80211_wx_get_encode ieee80211_wx_get_encode_rtl
++////////////////////////////////
++// added for kernel conflict under FC5
++#define ieee80211_wx_get_name ieee80211_wx_get_name_rtl
++#define free_ieee80211 free_ieee80211_rtl
++#define alloc_ieee80211 alloc_ieee80211_rtl
++///////////////////////////////
++//#endif
++#define ieee80211_rx ieee80211_rx_rtl
++#define ieee80211_wake_queue ieee80211_wake_queue_rtl
++#define ieee80211_stop_queue ieee80211_stop_queue_rtl
++#define ieee80211_wx_set_auth ieee80211_wx_set_auth_rtl
++#define ieee80211_get_crypto_ops ieee80211_get_crypto_ops_rtl
++#define ieee80211_crypt_delayed_deinit ieee80211_crypt_delayed_deinit_rtl
++
++#define ieee80211_start_scan ieee80211_start_scan_rtl
++#define ieee80211_register_crypto_ops ieee80211_register_crypto_ops_rtl
++#define ieee80211_unregister_crypto_ops ieee80211_unregister_crypto_ops_rtl
++#define ieee80211_crypt_deinit_entries ieee80211_crypt_deinit_entries_rtl
++#define ieee80211_crypt_deinit_handler ieee80211_crypt_deinit_handler_rtl
++typedef struct ieee_param {
++ u32 cmd;
++ u8 sta_addr[ETH_ALEN];
++ union {
++ struct {
++ u8 name;
++ u32 value;
++ } wpa_param;
++ struct {
++ u32 len;
++ u8 reserved[32];
++ u8 data[0];
++ } wpa_ie;
++ struct{
++ int command;
++ int reason_code;
++ } mlme;
++ struct {
++ u8 alg[IEEE_CRYPT_ALG_NAME_LEN];
++ u8 set_tx;
++ u32 err;
++ u8 idx;
++ u8 seq[8]; /* sequence counter (set: RX, get: TX) */
++ u16 key_len;
++ u8 key[0];
++ } crypt;
++
++ } u;
++}ieee_param;
++
++
++#if WIRELESS_EXT < 17
++#define IW_QUAL_QUAL_INVALID 0x10
++#define IW_QUAL_LEVEL_INVALID 0x20
++#define IW_QUAL_NOISE_INVALID 0x40
++#define IW_QUAL_QUAL_UPDATED 0x1
++#define IW_QUAL_LEVEL_UPDATED 0x2
++#define IW_QUAL_NOISE_UPDATED 0x4
++#endif
++
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
++static inline void tq_init(struct tq_struct * task, void(*func)(void *), void *data)
++{
++ task->routine = func;
++ task->data = data;
++ //task->next = NULL;
++ INIT_LIST_HEAD(&task->list);
++ task->sync = 0;
++}
++#endif
++
++// linux under 2.6.9 release may not support it, so modify it for common use
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9))
++//#define MSECS(t) (1000 * ((t) / HZ) + 1000 * ((t) % HZ) / HZ)
++#define MSECS(t) (HZ * ((t) / 1000) + (HZ * ((t) % 1000)) / 1000)
++static inline unsigned long msleep_interruptible_rtl(unsigned int msecs)
++{
++ unsigned long timeout = MSECS(msecs) + 1;
++
++ while (timeout) {
++ set_current_state(TASK_UNINTERRUPTIBLE);
++ timeout = schedule_timeout(timeout);
++ }
++ return timeout;
++}
++#else
++#define MSECS(t) msecs_to_jiffies(t)
++#define msleep_interruptible_rtl msleep_interruptible
++#endif
++
++#define IEEE80211_DATA_LEN 2304
++/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
++ 6.2.1.1.2.
++
++ The figure in section 7.1.2 suggests a body size of up to 2312
++ bytes is allowed, which is a bit confusing, I suspect this
++ represents the 2304 bytes of real data, plus a possible 8 bytes of
++ WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */
++
++
++#define IEEE80211_HLEN 30
++#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN)
++
++/* this is stolen and modified from the madwifi driver*/
++#define IEEE80211_FC0_TYPE_MASK 0x0c
++#define IEEE80211_FC0_TYPE_DATA 0x08
++#define IEEE80211_FC0_SUBTYPE_MASK 0xB0
++#define IEEE80211_FC0_SUBTYPE_QOS 0x80
++
++#define IEEE80211_QOS_HAS_SEQ(fc) \
++ (((fc) & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == \
++ (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS))
++
++/* this is stolen from ipw2200 driver */
++#define IEEE_IBSS_MAC_HASH_SIZE 31
++#define IEEE_MESH_MAC_HASH_SIZE 31
++struct ieee_ibss_seq {
++ u8 mac[ETH_ALEN];
++ u16 seq_num[17];
++ u16 frag_num[17];
++ unsigned long packet_time[17];
++ struct list_head list;
++};
++
++struct ieee_mesh_seq {
++ u8 mac[ETH_ALEN];
++ u16 seq_num;
++ u16 frag_num;
++ unsigned long packet_time;
++ struct list_head list;
++};
++
++struct ieee80211_hdr {
++ u16 frame_ctl;
++ u16 duration_id;
++ u8 addr1[ETH_ALEN];
++ u8 addr2[ETH_ALEN];
++ u8 addr3[ETH_ALEN];
++ u16 seq_ctl;
++ u8 addr4[ETH_ALEN];
++} __attribute__ ((packed));
++
++struct ieee80211_hdr_QOS {
++ u16 frame_ctl;
++ u16 duration_id;
++ u8 addr1[ETH_ALEN];
++ u8 addr2[ETH_ALEN];
++ u8 addr3[ETH_ALEN];
++ u16 seq_ctl;
++ u8 addr4[ETH_ALEN];
++ u16 QOS_ctl;
++} __attribute__ ((packed));
++
++struct ieee80211_hdr_3addr {
++ u16 frame_ctl;
++ u16 duration_id;
++ u8 addr1[ETH_ALEN];
++ u8 addr2[ETH_ALEN];
++ u8 addr3[ETH_ALEN];
++ u16 seq_ctl;
++} __attribute__ ((packed));
++
++struct ieee80211_hdr_3addr_QOS {
++ u16 frame_ctl;
++ u16 duration_id;
++ u8 addr1[ETH_ALEN];
++ u8 addr2[ETH_ALEN];
++ u8 addr3[ETH_ALEN];
++ u16 seq_ctl;
++ u16 QOS_ctl;
++} __attribute__ ((packed));
++
++enum eap_type {
++ EAP_PACKET = 0,
++ EAPOL_START,
++ EAPOL_LOGOFF,
++ EAPOL_KEY,
++ EAPOL_ENCAP_ASF_ALERT
++};
++
++//by lizhaoming for LED 2008.6.23 from r8187_led.h
++#ifdef LED
++typedef enum _LED_CTL_MODE {
++ LED_CTL_POWER_ON,
++ LED_CTL_POWER_OFF,
++ LED_CTL_LINK,
++ LED_CTL_NO_LINK,
++ LED_CTL_TX,
++ LED_CTL_RX,
++ LED_CTL_SITE_SURVEY,
++} LED_CTL_MODE;
++#endif
++
++static const char *eap_types[] = {
++ [EAP_PACKET] = "EAP-Packet",
++ [EAPOL_START] = "EAPOL-Start",
++ [EAPOL_LOGOFF] = "EAPOL-Logoff",
++ [EAPOL_KEY] = "EAPOL-Key",
++ [EAPOL_ENCAP_ASF_ALERT] = "EAPOL-Encap-ASF-Alert"
++};
++
++static inline const char *eap_get_type(int type)
++{
++ return (type >= ARRAY_SIZE(eap_types)) ? "Unknown" : eap_types[type];
++}
++
++struct eapol {
++ u8 snap[6];
++ u16 ethertype;
++ u8 version;
++ u8 type;
++ u16 length;
++} __attribute__ ((packed));
++
++#define IEEE80211_3ADDR_LEN 24
++#define IEEE80211_4ADDR_LEN 30
++#define IEEE80211_FCS_LEN 4
++
++#define MIN_FRAG_THRESHOLD 256U
++#define MAX_FRAG_THRESHOLD 2346U
++
++/* Frame control field constants */
++#define IEEE80211_FCTL_VERS 0x0002
++#define IEEE80211_FCTL_FTYPE 0x000c
++#define IEEE80211_FCTL_STYPE 0x00f0
++#define IEEE80211_FCTL_TODS 0x0100
++#define IEEE80211_FCTL_FROMDS 0x0200
++#define IEEE80211_FCTL_DSTODS 0x0300 //added by david
++#define IEEE80211_FCTL_MOREFRAGS 0x0400
++#define IEEE80211_FCTL_RETRY 0x0800
++#define IEEE80211_FCTL_PM 0x1000
++#define IEEE80211_FCTL_MOREDATA 0x2000
++#define IEEE80211_FCTL_WEP 0x4000
++#define IEEE80211_FCTL_ORDER 0x8000
++
++#define IEEE80211_FTYPE_MGMT 0x0000
++#define IEEE80211_FTYPE_CTL 0x0004
++#define IEEE80211_FTYPE_DATA 0x0008
++
++/* management */
++#define IEEE80211_STYPE_ASSOC_REQ 0x0000
++#define IEEE80211_STYPE_ASSOC_RESP 0x0010
++#define IEEE80211_STYPE_REASSOC_REQ 0x0020
++#define IEEE80211_STYPE_REASSOC_RESP 0x0030
++#define IEEE80211_STYPE_PROBE_REQ 0x0040
++#define IEEE80211_STYPE_PROBE_RESP 0x0050
++#define IEEE80211_STYPE_BEACON 0x0080
++#define IEEE80211_STYPE_ATIM 0x0090
++#define IEEE80211_STYPE_DISASSOC 0x00A0
++#define IEEE80211_STYPE_AUTH 0x00B0
++#define IEEE80211_STYPE_DEAUTH 0x00C0
++#define IEEE80211_STYPE_MANAGE_ACT 0x00D0
++
++/* control */
++#define IEEE80211_STYPE_PSPOLL 0x00A0
++#define IEEE80211_STYPE_RTS 0x00B0
++#define IEEE80211_STYPE_CTS 0x00C0
++#define IEEE80211_STYPE_ACK 0x00D0
++#define IEEE80211_STYPE_CFEND 0x00E0
++#define IEEE80211_STYPE_CFENDACK 0x00F0
++
++/* data */
++#define IEEE80211_STYPE_DATA 0x0000
++#define IEEE80211_STYPE_DATA_CFACK 0x0010
++#define IEEE80211_STYPE_DATA_CFPOLL 0x0020
++#define IEEE80211_STYPE_DATA_CFACKPOLL 0x0030
++#define IEEE80211_STYPE_NULLFUNC 0x0040
++#define IEEE80211_STYPE_CFACK 0x0050
++#define IEEE80211_STYPE_CFPOLL 0x0060
++#define IEEE80211_STYPE_CFACKPOLL 0x0070
++#define IEEE80211_STYPE_QOS_DATA 0x0080 //added for WMM 2006/8/2
++#define IEEE80211_STYPE_QOS_NULL 0x00C0
++
++
++#define IEEE80211_SCTL_FRAG 0x000F
++#define IEEE80211_SCTL_SEQ 0xFFF0
++
++
++/* debug macros */
++
++#ifdef CONFIG_IEEE80211_DEBUG
++extern u32 ieee80211_debug_level;
++#define IEEE80211_DEBUG(level, fmt, args...) \
++do { if (ieee80211_debug_level & (level)) \
++ printk(KERN_DEBUG "ieee80211: %c %s " fmt, \
++ in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0)
++#else
++#define IEEE80211_DEBUG(level, fmt, args...) do {} while (0)
++#endif /* CONFIG_IEEE80211_DEBUG */
++
++/*
++ * To use the debug system;
++ *
++ * If you are defining a new debug classification, simply add it to the #define
++ * list here in the form of:
++ *
++ * #define IEEE80211_DL_xxxx VALUE
++ *
++ * shifting value to the left one bit from the previous entry. xxxx should be
++ * the name of the classification (for example, WEP)
++ *
++ * You then need to either add a IEEE80211_xxxx_DEBUG() macro definition for your
++ * classification, or use IEEE80211_DEBUG(IEEE80211_DL_xxxx, ...) whenever you want
++ * to send output to that classification.
++ *
++ * To add your debug level to the list of levels seen when you perform
++ *
++ * % cat /proc/net/ipw/debug_level
++ *
++ * you simply need to add your entry to the ipw_debug_levels array.
++ *
++ * If you do not see debug_level in /proc/net/ipw then you do not have
++ * CONFIG_IEEE80211_DEBUG defined in your kernel configuration
++ *
++ */
++
++#define IEEE80211_DL_INFO (1<<0)
++#define IEEE80211_DL_WX (1<<1)
++#define IEEE80211_DL_SCAN (1<<2)
++#define IEEE80211_DL_STATE (1<<3)
++#define IEEE80211_DL_MGMT (1<<4)
++#define IEEE80211_DL_FRAG (1<<5)
++#define IEEE80211_DL_EAP (1<<6)
++#define IEEE80211_DL_DROP (1<<7)
++
++#define IEEE80211_DL_TX (1<<8)
++#define IEEE80211_DL_RX (1<<9)
++
++#define IEEE80211_ERROR(f, a...) printk(KERN_ERR "ieee80211: " f, ## a)
++#define IEEE80211_WARNING(f, a...) printk(KERN_WARNING "ieee80211: " f, ## a)
++#define IEEE80211_DEBUG_INFO(f, a...) IEEE80211_DEBUG(IEEE80211_DL_INFO, f, ## a)
++
++#define IEEE80211_DEBUG_WX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_WX, f, ## a)
++#define IEEE80211_DEBUG_SCAN(f, a...) IEEE80211_DEBUG(IEEE80211_DL_SCAN, f, ## a)
++#define IEEE80211_DEBUG_STATE(f, a...) IEEE80211_DEBUG(IEEE80211_DL_STATE, f, ## a)
++#define IEEE80211_DEBUG_MGMT(f, a...) IEEE80211_DEBUG(IEEE80211_DL_MGMT, f, ## a)
++#define IEEE80211_DEBUG_FRAG(f, a...) IEEE80211_DEBUG(IEEE80211_DL_FRAG, f, ## a)
++#define IEEE80211_DEBUG_EAP(f, a...) IEEE80211_DEBUG(IEEE80211_DL_EAP, f, ## a)
++#define IEEE80211_DEBUG_DROP(f, a...) IEEE80211_DEBUG(IEEE80211_DL_DROP, f, ## a)
++#define IEEE80211_DEBUG_TX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_TX, f, ## a)
++#define IEEE80211_DEBUG_RX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_RX, f, ## a)
++#include <linux/netdevice.h>
++#include <linux/wireless.h>
++#include <linux/if_arp.h> /* ARPHRD_ETHER */
++
++#ifndef WIRELESS_SPY
++#define WIRELESS_SPY // enable iwspy support
++#endif
++#include <net/iw_handler.h> // new driver API
++
++#ifndef ETH_P_PAE
++#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
++#endif /* ETH_P_PAE */
++
++#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */
++
++#ifndef ETH_P_80211_RAW
++#define ETH_P_80211_RAW (ETH_P_ECONET + 1)
++#endif
++
++/* IEEE 802.11 defines */
++
++#define P80211_OUI_LEN 3
++
++struct ieee80211_snap_hdr {
++
++ u8 dsap; /* always 0xAA */
++ u8 ssap; /* always 0xAA */
++ u8 ctrl; /* always 0x03 */
++ u8 oui[P80211_OUI_LEN]; /* organizational universal id */
++
++} __attribute__ ((packed));
++
++#define SNAP_SIZE sizeof(struct ieee80211_snap_hdr)
++
++#define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE)
++#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE)
++
++#define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG)
++#define WLAN_GET_SEQ_SEQ(seq) ((seq) & IEEE80211_SCTL_SEQ)
++
++/* Authentication algorithms */
++#define WLAN_AUTH_OPEN 0
++#define WLAN_AUTH_SHARED_KEY 1
++
++#define WLAN_AUTH_CHALLENGE_LEN 128
++
++#define WLAN_CAPABILITY_BSS (1<<0)
++#define WLAN_CAPABILITY_IBSS (1<<1)
++#define WLAN_CAPABILITY_CF_POLLABLE (1<<2)
++#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3)
++#define WLAN_CAPABILITY_PRIVACY (1<<4)
++#define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5)
++#define WLAN_CAPABILITY_PBCC (1<<6)
++#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7)
++#define WLAN_CAPABILITY_SHORT_SLOT (1<<10)
++
++/* Status codes */
++#define WLAN_STATUS_SUCCESS 0
++#define WLAN_STATUS_UNSPECIFIED_FAILURE 1
++#define WLAN_STATUS_CAPS_UNSUPPORTED 10
++#define WLAN_STATUS_REASSOC_NO_ASSOC 11
++#define WLAN_STATUS_ASSOC_DENIED_UNSPEC 12
++#define WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG 13
++#define WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION 14
++#define WLAN_STATUS_CHALLENGE_FAIL 15
++#define WLAN_STATUS_AUTH_TIMEOUT 16
++#define WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA 17
++#define WLAN_STATUS_ASSOC_DENIED_RATES 18
++/* 802.11b */
++#define WLAN_STATUS_ASSOC_DENIED_NOSHORT 19
++#define WLAN_STATUS_ASSOC_DENIED_NOPBCC 20
++#define WLAN_STATUS_ASSOC_DENIED_NOAGILITY 21
++
++/* Reason codes */
++#define WLAN_REASON_UNSPECIFIED 1
++#define WLAN_REASON_PREV_AUTH_NOT_VALID 2
++#define WLAN_REASON_DEAUTH_LEAVING 3
++#define WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY 4
++#define WLAN_REASON_DISASSOC_AP_BUSY 5
++#define WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA 6
++#define WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA 7
++#define WLAN_REASON_DISASSOC_STA_HAS_LEFT 8
++#define WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH 9
++
++
++/* Information Element IDs */
++#define WLAN_EID_SSID 0
++#define WLAN_EID_SUPP_RATES 1
++#define WLAN_EID_FH_PARAMS 2
++#define WLAN_EID_DS_PARAMS 3
++#define WLAN_EID_CF_PARAMS 4
++#define WLAN_EID_TIM 5
++#define WLAN_EID_IBSS_PARAMS 6
++#define WLAN_EID_CHALLENGE 16
++#define WLAN_EID_RSN 48
++#define WLAN_EID_GENERIC 221
++
++#define IEEE80211_MGMT_HDR_LEN 24
++#define IEEE80211_DATA_HDR3_LEN 24
++#define IEEE80211_DATA_HDR4_LEN 30
++
++
++#define IEEE80211_STATMASK_SIGNAL (1<<0)
++#define IEEE80211_STATMASK_RSSI (1<<1)
++#define IEEE80211_STATMASK_NOISE (1<<2)
++#define IEEE80211_STATMASK_RATE (1<<3)
++#define IEEE80211_STATMASK_WEMASK 0x7
++
++
++#define IEEE80211_CCK_MODULATION (1<<0)
++#define IEEE80211_OFDM_MODULATION (1<<1)
++
++#define IEEE80211_24GHZ_BAND (1<<0)
++#define IEEE80211_52GHZ_BAND (1<<1)
++
++#define IEEE80211_CCK_RATE_LEN 4
++#define IEEE80211_CCK_RATE_1MB 0x02
++#define IEEE80211_CCK_RATE_2MB 0x04
++#define IEEE80211_CCK_RATE_5MB 0x0B
++#define IEEE80211_CCK_RATE_11MB 0x16
++#define IEEE80211_OFDM_RATE_LEN 8
++#define IEEE80211_OFDM_RATE_6MB 0x0C
++#define IEEE80211_OFDM_RATE_9MB 0x12
++#define IEEE80211_OFDM_RATE_12MB 0x18
++#define IEEE80211_OFDM_RATE_18MB 0x24
++#define IEEE80211_OFDM_RATE_24MB 0x30
++#define IEEE80211_OFDM_RATE_36MB 0x48
++#define IEEE80211_OFDM_RATE_48MB 0x60
++#define IEEE80211_OFDM_RATE_54MB 0x6C
++#define IEEE80211_BASIC_RATE_MASK 0x80
++
++#define IEEE80211_CCK_RATE_1MB_MASK (1<<0)
++#define IEEE80211_CCK_RATE_2MB_MASK (1<<1)
++#define IEEE80211_CCK_RATE_5MB_MASK (1<<2)
++#define IEEE80211_CCK_RATE_11MB_MASK (1<<3)
++#define IEEE80211_OFDM_RATE_6MB_MASK (1<<4)
++#define IEEE80211_OFDM_RATE_9MB_MASK (1<<5)
++#define IEEE80211_OFDM_RATE_12MB_MASK (1<<6)
++#define IEEE80211_OFDM_RATE_18MB_MASK (1<<7)
++#define IEEE80211_OFDM_RATE_24MB_MASK (1<<8)
++#define IEEE80211_OFDM_RATE_36MB_MASK (1<<9)
++#define IEEE80211_OFDM_RATE_48MB_MASK (1<<10)
++#define IEEE80211_OFDM_RATE_54MB_MASK (1<<11)
++
++#define IEEE80211_CCK_RATES_MASK 0x0000000F
++#define IEEE80211_CCK_BASIC_RATES_MASK (IEEE80211_CCK_RATE_1MB_MASK | \
++ IEEE80211_CCK_RATE_2MB_MASK)
++#define IEEE80211_CCK_DEFAULT_RATES_MASK (IEEE80211_CCK_BASIC_RATES_MASK | \
++ IEEE80211_CCK_RATE_5MB_MASK | \
++ IEEE80211_CCK_RATE_11MB_MASK)
++
++#define IEEE80211_OFDM_RATES_MASK 0x00000FF0
++#define IEEE80211_OFDM_BASIC_RATES_MASK (IEEE80211_OFDM_RATE_6MB_MASK | \
++ IEEE80211_OFDM_RATE_12MB_MASK | \
++ IEEE80211_OFDM_RATE_24MB_MASK)
++#define IEEE80211_OFDM_DEFAULT_RATES_MASK (IEEE80211_OFDM_BASIC_RATES_MASK | \
++ IEEE80211_OFDM_RATE_9MB_MASK | \
++ IEEE80211_OFDM_RATE_18MB_MASK | \
++ IEEE80211_OFDM_RATE_36MB_MASK | \
++ IEEE80211_OFDM_RATE_48MB_MASK | \
++ IEEE80211_OFDM_RATE_54MB_MASK)
++#define IEEE80211_DEFAULT_RATES_MASK (IEEE80211_OFDM_DEFAULT_RATES_MASK | \
++ IEEE80211_CCK_DEFAULT_RATES_MASK)
++
++#define IEEE80211_NUM_OFDM_RATES 8
++#define IEEE80211_NUM_CCK_RATES 4
++#define IEEE80211_OFDM_SHIFT_MASK_A 4
++
++
++
++
++/* NOTE: This data is for statistical purposes; not all hardware provides this
++ * information for frames received. Not setting these will not cause
++ * any adverse affects. */
++struct ieee80211_rx_stats {
++ u32 mac_time[2];
++ u8 signalstrength;
++ s8 rssi;
++ u8 signal;
++ u8 noise;
++ u16 rate; /* in 100 kbps */
++ u8 received_channel;
++ u8 control;
++ u8 mask;
++ u8 freq;
++ u16 len;
++ u8 nic_type;
++};
++
++/* IEEE 802.11 requires that STA supports concurrent reception of at least
++ * three fragmented frames. This define can be increased to support more
++ * concurrent frames, but it should be noted that each entry can consume about
++ * 2 kB of RAM and increasing cache size will slow down frame reassembly. */
++#define IEEE80211_FRAG_CACHE_LEN 4
++
++struct ieee80211_frag_entry {
++ unsigned long first_frag_time;
++ unsigned int seq;
++ unsigned int last_frag;
++ struct sk_buff *skb;
++ u8 src_addr[ETH_ALEN];
++ u8 dst_addr[ETH_ALEN];
++};
++
++struct ieee80211_stats {
++ unsigned int tx_unicast_frames;
++ unsigned int tx_multicast_frames;
++ unsigned int tx_fragments;
++ unsigned int tx_unicast_octets;
++ unsigned int tx_multicast_octets;
++ unsigned int tx_deferred_transmissions;
++ unsigned int tx_single_retry_frames;
++ unsigned int tx_multiple_retry_frames;
++ unsigned int tx_retry_limit_exceeded;
++ unsigned int tx_discards;
++ unsigned int rx_unicast_frames;
++ unsigned int rx_multicast_frames;
++ unsigned int rx_fragments;
++ unsigned int rx_unicast_octets;
++ unsigned int rx_multicast_octets;
++ unsigned int rx_fcs_errors;
++ unsigned int rx_discards_no_buffer;
++ unsigned int tx_discards_wrong_sa;
++ unsigned int rx_discards_undecryptable;
++ unsigned int rx_message_in_msg_fragments;
++ unsigned int rx_message_in_bad_msg_fragments;
++};
++
++struct ieee80211_softmac_stats{
++ unsigned int rx_ass_ok;
++ unsigned int rx_ass_err;
++ unsigned int rx_probe_rq;
++ unsigned int tx_probe_rs;
++ unsigned int tx_beacons;
++ unsigned int rx_auth_rq;
++ unsigned int rx_auth_rs_ok;
++ unsigned int rx_auth_rs_err;
++ unsigned int tx_auth_rq;
++ unsigned int no_auth_rs;
++ unsigned int no_ass_rs;
++ unsigned int tx_ass_rq;
++ unsigned int rx_ass_rq;
++ unsigned int tx_probe_rq;
++ unsigned int reassoc;
++ unsigned int swtxstop;
++ unsigned int swtxawake;
++};
++
++struct ieee80211_device;
++
++#include "ieee80211_crypt.h"
++
++#define SEC_KEY_1 (1<<0)
++#define SEC_KEY_2 (1<<1)
++#define SEC_KEY_3 (1<<2)
++#define SEC_KEY_4 (1<<3)
++#define SEC_ACTIVE_KEY (1<<4)
++#define SEC_AUTH_MODE (1<<5)
++#define SEC_UNICAST_GROUP (1<<6)
++#define SEC_LEVEL (1<<7)
++#define SEC_ENABLED (1<<8)
++
++#define SEC_LEVEL_0 0 /* None */
++#define SEC_LEVEL_1 1 /* WEP 40 and 104 bit */
++#define SEC_LEVEL_2 2 /* Level 1 + TKIP */
++#define SEC_LEVEL_2_CKIP 3 /* Level 1 + CKIP */
++#define SEC_LEVEL_3 4 /* Level 2 + CCMP */
++
++#define WEP_KEYS 4
++#define WEP_KEY_LEN 13
++#define ALG_KEY_LEN 32
++
++#ifdef _RTL8187_EXT_PATCH_
++#define MAX_MP 16
++#endif
++struct ieee80211_security {
++ u16 active_key:2,
++ enabled:1,
++ auth_mode:2,
++ auth_algo:4,
++ unicast_uses_group:1;
++ u8 key_sizes[WEP_KEYS];
++ u8 keys[WEP_KEYS][ALG_KEY_LEN];
++ u8 level;
++ u16 flags;
++} __attribute__ ((packed));
++
++
++/*
++
++ 802.11 data frame from AP
++
++ ,-------------------------------------------------------------------.
++Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 |
++ |------|------|---------|---------|---------|------|---------|------|
++Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | frame | fcs |
++ | | tion | (BSSID) | | | ence | data | |
++ `-------------------------------------------------------------------'
++
++Total: 28-2340 bytes
++
++*/
++
++struct ieee80211_header_data {
++ u16 frame_ctl;
++ u16 duration_id;
++ u8 addr1[6];
++ u8 addr2[6];
++ u8 addr3[6];
++ u16 seq_ctrl;
++};
++
++#define BEACON_PROBE_SSID_ID_POSITION 12
++
++/* Management Frame Information Element Types */
++#define MFIE_TYPE_SSID 0
++#define MFIE_TYPE_RATES 1
++#define MFIE_TYPE_FH_SET 2
++#define MFIE_TYPE_DS_SET 3
++#define MFIE_TYPE_CF_SET 4
++#define MFIE_TYPE_TIM 5
++#define MFIE_TYPE_IBSS_SET 6
++#define MFIE_TYPE_COUNTRY 7
++#define MFIE_TYPE_CHALLENGE 16
++#define MFIE_TYPE_ERP 42
++#define MFIE_TYPE_RSN 48
++#define MFIE_TYPE_RATES_EX 50
++#define MFIE_TYPE_GENERIC 221
++
++#ifdef ENABLE_DOT11D
++typedef enum
++{
++ COUNTRY_CODE_FCC = 0,
++ COUNTRY_CODE_IC = 1,
++ COUNTRY_CODE_ETSI = 2,
++ COUNTRY_CODE_SPAIN = 3,
++ COUNTRY_CODE_FRANCE = 4,
++ COUNTRY_CODE_MKK = 5,
++ COUNTRY_CODE_MKK1 = 6,
++ COUNTRY_CODE_ISRAEL = 7,
++ COUNTRY_CODE_TELEC = 8,
++ COUNTRY_CODE_GLOBAL_DOMAIN = 9,
++ COUNTRY_CODE_WORLD_WIDE_13_INDEX = 10
++}country_code_type_t;
++#endif
++
++
++struct ieee80211_info_element_hdr {
++ u8 id;
++ u8 len;
++} __attribute__ ((packed));
++
++struct ieee80211_info_element {
++ u8 id;
++ u8 len;
++ u8 data[0];
++} __attribute__ ((packed));
++
++/*
++ * These are the data types that can make up management packets
++ *
++ u16 auth_algorithm;
++ u16 auth_sequence;
++ u16 beacon_interval;
++ u16 capability;
++ u8 current_ap[ETH_ALEN];
++ u16 listen_interval;
++ struct {
++ u16 association_id:14, reserved:2;
++ } __attribute__ ((packed));
++ u32 time_stamp[2];
++ u16 reason;
++ u16 status;
++*/
++
++#define IEEE80211_DEFAULT_TX_ESSID "Penguin"
++#define IEEE80211_DEFAULT_BASIC_RATE 10
++#define IEEE80211_DEFAULT_MESHID "802.11s"
++#define IEEE80211_DEFAULT_MESH_CHAN 1
++
++struct ieee80211_authentication {
++ struct ieee80211_header_data header;
++ u16 algorithm;
++ u16 transaction;
++ u16 status;
++ //struct ieee80211_info_element_hdr info_element;
++} __attribute__ ((packed));
++
++
++struct ieee80211_probe_response {
++ struct ieee80211_header_data header;
++ u32 time_stamp[2];
++ u16 beacon_interval;
++ u16 capability;
++ struct ieee80211_info_element info_element;
++} __attribute__ ((packed));
++
++struct ieee80211_probe_request {
++ struct ieee80211_header_data header;
++ /*struct ieee80211_info_element info_element;*/
++} __attribute__ ((packed));
++
++struct ieee80211_assoc_request_frame {
++ struct ieee80211_hdr_3addr header;
++ u16 capability;
++ u16 listen_interval;
++ //u8 current_ap[ETH_ALEN];
++ struct ieee80211_info_element_hdr info_element;
++} __attribute__ ((packed));
++
++struct ieee80211_assoc_response_frame {
++ struct ieee80211_hdr_3addr header;
++ u16 capability;
++ u16 status;
++ u16 aid;
++ struct ieee80211_info_element info_element; /* supported rates */
++} __attribute__ ((packed));
++
++
++struct ieee80211_txb {
++ u8 nr_frags;
++ u8 encrypted;
++ u16 reserved;
++ u16 frag_size;
++ u16 payload_size;
++ struct sk_buff *fragments[0];
++};
++
++struct ieee80211_wmm_ac_param {
++ u8 ac_aci_acm_aifsn;
++ u8 ac_ecwmin_ecwmax;
++ u16 ac_txop_limit;
++};
++
++struct ieee80211_wmm_ts_info {
++ u8 ac_dir_tid;
++ u8 ac_up_psb;
++ u8 reserved;
++} __attribute__ ((packed));
++
++struct ieee80211_wmm_tspec_elem {
++ struct ieee80211_wmm_ts_info ts_info;
++ u16 norm_msdu_size;
++ u16 max_msdu_size;
++ u32 min_serv_inter;
++ u32 max_serv_inter;
++ u32 inact_inter;
++ u32 suspen_inter;
++ u32 serv_start_time;
++ u32 min_data_rate;
++ u32 mean_data_rate;
++ u32 peak_data_rate;
++ u32 max_burst_size;
++ u32 delay_bound;
++ u32 min_phy_rate;
++ u16 surp_band_allow;
++ u16 medium_time;
++}__attribute__((packed));
++
++enum {WMM_all_frame, WMM_two_frame, WMM_four_frame, WMM_six_frame};
++#define MAX_SP_Len (WMM_all_frame << 4)
++#define IEEE80211_QOS_TID 0x0f
++#define QOS_CTL_NOTCONTAIN_ACK (0x01 << 5)
++
++/* SWEEP TABLE ENTRIES NUMBER*/
++#define MAX_SWEEP_TAB_ENTRIES 42
++#define MAX_SWEEP_TAB_ENTRIES_PER_PACKET 7
++/* MAX_RATES_LENGTH needs to be 12. The spec says 8, and many APs
++ * only use 8, and then use extended rates for the remaining supported
++ * rates. Other APs, however, stick all of their supported rates on the
++ * main rates information element... */
++#define MAX_RATES_LENGTH ((u8)12)
++#define MAX_RATES_EX_LENGTH ((u8)16)
++#define MAX_NETWORK_COUNT 128
++#ifdef ENABLE_DOT11D
++#define MAX_CHANNEL_NUMBER 165 //YJ,modified,080625
++#define MAX_IE_LEN 0xFF //+YJ,080625
++#else
++#define MAX_CHANNEL_NUMBER 161
++#endif
++
++//#define IEEE80211_SOFTMAC_SCAN_TIME 400
++#define IEEE80211_SOFTMAC_SCAN_TIME 100//lzm mod 081209
++//(HZ / 2)
++#define IEEE80211_SOFTMAC_ASSOC_RETRY_TIME (HZ * 2)
++
++#define CRC_LENGTH 4U
++
++#define MAX_WPA_IE_LEN 64
++
++#define NETWORK_EMPTY_ESSID (1<<0)
++#define NETWORK_HAS_OFDM (1<<1)
++#define NETWORK_HAS_CCK (1<<2)
++
++#define IEEE80211_DTIM_MBCAST 4
++#define IEEE80211_DTIM_UCAST 2
++#define IEEE80211_DTIM_VALID 1
++#define IEEE80211_DTIM_INVALID 0
++
++#define IEEE80211_PS_DISABLED 0
++#define IEEE80211_PS_UNICAST IEEE80211_DTIM_UCAST
++#define IEEE80211_PS_MBCAST IEEE80211_DTIM_MBCAST
++
++//added by David for QoS 2006/6/30
++//#define WMM_Hang_8187
++#ifdef WMM_Hang_8187
++#undef WMM_Hang_8187
++#endif
++
++#define WME_AC_BE 0x00
++#define WME_AC_BK 0x01
++#define WME_AC_VI 0x02
++#define WME_AC_VO 0x03
++#define WME_ACI_MASK 0x03
++#define WME_AIFSN_MASK 0x03
++#define WME_AC_PRAM_LEN 16
++
++//UP Mapping to AC, using in MgntQuery_SequenceNumber() and maybe for DSCP
++//#define UP2AC(up) ((up<3) ? ((up==0)?1:0) : (up>>1))
++#define UP2AC(up) ( \
++ ((up) < 1) ? WME_AC_BE : \
++ ((up) < 3) ? WME_AC_BK : \
++ ((up) < 4) ? WME_AC_BE : \
++ ((up) < 6) ? WME_AC_VI : \
++ WME_AC_VO)
++//AC Mapping to UP, using in Tx part for selecting the corresponding TX queue
++#define AC2UP(_ac) ( \
++ ((_ac) == WME_AC_VO) ? 6 : \
++ ((_ac) == WME_AC_VI) ? 5 : \
++ ((_ac) == WME_AC_BK) ? 1 : \
++ 0)
++
++#define ETHER_ADDR_LEN 6 /* length of an Ethernet address */
++struct ether_header {
++ u8 ether_dhost[ETHER_ADDR_LEN];
++ u8 ether_shost[ETHER_ADDR_LEN];
++ u16 ether_type;
++} __attribute__((packed));
++
++#ifndef ETHERTYPE_PAE
++#define ETHERTYPE_PAE 0x888e /* EAPOL PAE/802.1x */
++#endif
++#ifndef ETHERTYPE_IP
++#define ETHERTYPE_IP 0x0800 /* IP protocol */
++#endif
++
++struct ieee80211_network {
++ /* These entries are used to identify a unique network */
++ u8 bssid[ETH_ALEN];
++ u8 channel;
++ /* Ensure null-terminated for any debug msgs */
++ u8 ssid[IW_ESSID_MAX_SIZE + 1];
++ u8 ssid_len;
++
++ /* These are network statistics */
++ struct ieee80211_rx_stats stats;
++ u16 capability;
++ u8 rates[MAX_RATES_LENGTH];
++ u8 rates_len;
++ u8 rates_ex[MAX_RATES_EX_LENGTH];
++ u8 rates_ex_len;
++ unsigned long last_scanned;
++ u8 mode;
++ u8 flags;
++ u32 last_associate;
++ u32 time_stamp[2];
++ u16 beacon_interval;
++ u16 listen_interval;
++ u16 atim_window;
++ u8 wpa_ie[MAX_WPA_IE_LEN];
++ size_t wpa_ie_len;
++ u8 rsn_ie[MAX_WPA_IE_LEN];
++ size_t rsn_ie_len;
++ u8 dtim_period;
++ u8 dtim_data;
++ u32 last_dtim_sta_time[2];
++#ifdef _RTL8187_EXT_PATCH_
++ void *ext_entry;
++#endif
++ struct list_head list;
++ //appeded for QoS
++ u8 wmm_info;
++ struct ieee80211_wmm_ac_param wmm_param[4];
++ u8 QoS_Enable;
++ u8 SignalStrength;
++#ifdef THOMAS_TURBO
++ u8 Turbo_Enable;//enable turbo mode, added by thomas
++#endif
++
++#ifdef ENABLE_DOT11D
++ u16 CountryIeLen;
++ u8 CountryIeBuf[MAX_IE_LEN];
++#endif
++
++};
++
++enum ieee80211_state {
++
++ /* the card is not linked at all */
++ IEEE80211_NOLINK = 0,
++
++ /* IEEE80211_ASSOCIATING* are for BSS client mode
++ * the driver shall not perform RX filtering unless
++ * the state is LINKED.
++ * The driver shall just check for the state LINKED and
++ * defaults to NOLINK for ALL the other states (including
++ * LINKED_SCANNING)
++ */
++
++ /* the association procedure will start (wq scheduling)*/
++ IEEE80211_ASSOCIATING,
++ IEEE80211_ASSOCIATING_RETRY,
++
++ /* the association procedure is sending AUTH request*/
++ IEEE80211_ASSOCIATING_AUTHENTICATING,
++
++ /* the association procedure has successfully authentcated
++ * and is sending association request
++ */
++ IEEE80211_ASSOCIATING_AUTHENTICATED,
++
++ /* the link is ok. the card associated to a BSS or linked
++ * to a ibss cell or acting as an AP and creating the bss
++ */
++ IEEE80211_LINKED,
++
++ /* same as LINKED, but the driver shall apply RX filter
++ * rules as we are in NO_LINK mode. As the card is still
++ * logically linked, but it is doing a syncro site survey
++ * then it will be back to LINKED state.
++ */
++ IEEE80211_LINKED_SCANNING,
++//by amy for mesh
++ IEEE80211_MESH_SCANNING,
++ IEEE80211_MESH_LINKED,
++//by amy for mesh
++
++};
++
++#define DEFAULT_MAX_SCAN_AGE (15 * HZ)
++#define DEFAULT_FTS 2346
++#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
++#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
++
++
++#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,11))
++extern inline int is_multicast_ether_addr(const u8 *addr)
++{
++ return ((addr[0] != 0xff) && (0x01 & addr[0]));
++}
++#endif
++
++#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,13))
++extern inline int is_broadcast_ether_addr(const u8 *addr)
++{
++ return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) && \
++ (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
++}
++#endif
++
++#define CFG_IEEE80211_RESERVE_FCS (1<<0)
++#define CFG_IEEE80211_COMPUTE_FCS (1<<1)
++
++typedef struct tx_pending_t{
++ int frag;
++ struct ieee80211_txb *txb;
++}tx_pending_t;
++
++#ifdef _RTL8187_EXT_PATCH_
++struct ieee80211_crypt_data_list{
++ u8 used;
++ u8 mac_addr[ETH_ALEN]; //record mac_add
++ struct ieee80211_crypt_data *crypt[WEP_KEYS];
++}__attribute__((packed));
++
++#endif
++
++struct ieee80211_device {
++ struct net_device *dev;
++
++ /* Bookkeeping structures */
++ struct net_device_stats stats;
++ struct ieee80211_stats ieee_stats;
++ struct ieee80211_softmac_stats softmac_stats;
++
++ /* Probe / Beacon management */
++ struct list_head network_free_list;
++ struct list_head network_list;
++ struct ieee80211_network *networks;
++ int scans;
++ int scan_age;
++
++ int iw_mode; /* operating mode (IW_MODE_*) */
++#ifdef _RTL8187_EXT_PATCH_
++ int iw_ext_mode; // if iw_mode == iw_ext_mode, do ext_patch_**();
++#endif
++
++ spinlock_t lock;
++ spinlock_t wpax_suitlist_lock;
++
++ int tx_headroom; /* Set to size of any additional room needed at front
++ * of allocated Tx SKBs */
++ u32 config;
++
++ /* WEP and other encryption related settings at the device level */
++ int open_wep; /* Set to 1 to allow unencrypted frames */
++
++ int reset_on_keychange; /* Set to 1 if the HW needs to be reset on
++ * WEP key changes */
++
++ /* If the host performs {en,de}cryption, then set to 1 */
++ int host_encrypt;
++ int host_decrypt;
++ int ieee802_1x; /* is IEEE 802.1X used */
++
++ /* WPA data */
++ int wpa_enabled;
++ int drop_unencrypted;
++ int tkip_countermeasures;
++ int privacy_invoked;
++ size_t wpa_ie_len;
++ u8 *wpa_ie;
++
++//#ifdef JOHN_TKIP
++ u8 ap_mac_addr[6];
++ u16 pairwise_key_type;
++ u16 broadcast_key_type;
++//#endif
++ struct list_head crypt_deinit_list;
++#ifdef _RTL8187_EXT_PATCH_
++ struct ieee80211_crypt_data_list* cryptlist[MAX_MP];
++#else
++ struct ieee80211_crypt_data *crypt[WEP_KEYS];
++#endif
++ int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */
++ struct timer_list crypt_deinit_timer;
++
++ int bcrx_sta_key; /* use individual keys to override default keys even
++ * with RX of broad/multicast frames */
++
++ /* Fragmentation structures */
++ // each streaming contain a entry
++ struct ieee80211_frag_entry frag_cache[17][IEEE80211_FRAG_CACHE_LEN];
++ unsigned int frag_next_idx[17];
++ u16 fts; /* Fragmentation Threshold */
++
++ /* This stores infos for the current network.
++ * Either the network we are associated in INFRASTRUCTURE
++ * or the network that we are creating in MASTER mode.
++ * ad-hoc is a mixture ;-).
++ * Note that in infrastructure mode, even when not associated,
++ * fields bssid and essid may be valid (if wpa_set and essid_set
++ * are true) as thy carry the value set by the user via iwconfig
++ */
++ struct ieee80211_network current_network;
++
++
++ enum ieee80211_state state;
++
++ int short_slot;
++ int mode; /* A, B, G */
++ int modulation; /* CCK, OFDM */
++ int freq_band; /* 2.4Ghz, 5.2Ghz, Mixed */
++ int abg_true; /* ABG flag */
++
++ /* used for forcing the ibss workqueue to terminate
++ * without wait for the syncro scan to terminate
++ */
++ short sync_scan_hurryup;
++
++#ifdef ENABLE_DOT11D
++ void * pDot11dInfo;
++ bool bGlobalDomain;
++ bool bWorldWide13;//lzm add 20081205
++
++ // For Liteon Ch12~13 passive scan
++ u8 MinPassiveChnlNum;
++ u8 IbssStartChnl;
++#else
++ /* map of allowed channels. 0 is dummy */
++ // FIXME: remeber to default to a basic channel plan depending of the PHY type
++ int channel_map[MAX_CHANNEL_NUMBER+1];
++#endif
++
++ int rate; /* current rate */
++ int basic_rate;
++ //FIXME: pleace callback, see if redundant with softmac_features
++ short active_scan;
++
++#ifdef _RTL8187_EXT_PATCH_
++// short ch_lock;
++ short meshScanMode;
++#endif
++ /* this contains flags for selectively enable softmac support */
++ u16 softmac_features;
++
++ /* if the sequence control field is not filled by HW */
++ u16 seq_ctrl[5];
++
++ /* association procedure transaction sequence number */
++ u16 associate_seq;
++
++ /* AID for RTXed association responses */
++ u16 assoc_id;
++
++ /* power save mode related*/
++ short ps;
++ short sta_sleep;
++ int ps_timeout;
++ struct tasklet_struct ps_task;
++ u32 ps_th;
++ u32 ps_tl;
++
++ short raw_tx;
++ /* used if IEEE_SOFTMAC_TX_QUEUE is set */
++ short queue_stop;
++ short scanning;
++ short scan_watchdog;//lzm add 081215 for roaming
++ short proto_started;
++
++ struct semaphore wx_sem;
++ struct semaphore scan_sem;
++ struct semaphore ips_sem;
++ spinlock_t mgmt_tx_lock;
++ spinlock_t beacon_lock;
++ spinlock_t beaconflag_lock;
++ short beacon_txing;
++
++ short wap_set;
++ short ssid_set;
++
++ u8 wpax_type_set; //{added by David, 2006.9.28}
++ u32 wpax_type_notify; //{added by David, 2006.9.26}
++
++ /* QoS related flag */
++ char init_wmmparam_flag;
++
++ /* for discarding duplicated packets in IBSS */
++ struct list_head ibss_mac_hash[IEEE_IBSS_MAC_HASH_SIZE];
++
++ /* for discarding duplicated packets in Mesh */ //added by david 2008.2.28/
++ struct list_head mesh_mac_hash[IEEE_MESH_MAC_HASH_SIZE];
++
++ /* for discarding duplicated packets in BSS */
++ u16 last_rxseq_num[17]; /* rx seq previous per-tid */
++ u16 last_rxfrag_num[17];/* tx frag previous per-tid */
++ unsigned long last_packet_time[17];
++
++ /* for PS mode */
++ unsigned long last_rx_ps_time;
++
++ /* used if IEEE_SOFTMAC_SINGLE_QUEUE is set */
++ struct sk_buff *mgmt_queue_ring[MGMT_QUEUE_NUM];
++ int mgmt_queue_head;
++ int mgmt_queue_tail;
++//by amy for ps
++ bool bInactivePs;
++ bool actscanning;
++ u16 ListenInterval;
++ u32 NumRxData;
++ unsigned long NumRxDataInPeriod; //YJ,add,080828
++ unsigned long NumRxBcnInPeriod; //YJ,add,080828
++//by amy for ps
++ short meshid_set;
++ /* used if IEEE_SOFTMAC_TX_QUEUE is set */
++ struct tx_pending_t tx_pending;
++
++ /* used if IEEE_SOFTMAC_ASSOCIATE is set */
++ struct timer_list associate_timer;
++
++ /* used if IEEE_SOFTMAC_BEACONS is set */
++ struct timer_list beacon_timer;
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
++ struct work_struct associate_complete_wq;
++// struct work_struct associate_retry_wq;
++// struct work_struct start_ibss_wq;
++ struct work_struct associate_procedure_wq;
++ struct work_struct ips_leave_wq; //YJ,add,081230,for IPS
++ bool bHwRadioOff;//by lizhaoming
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
++ struct delayed_work softmac_scan_wq;
++ struct delayed_work start_ibss_wq;
++ struct delayed_work associate_retry_wq;
++//by amy for rate adaptive
++ struct delayed_work rate_adapter_wq;
++//by amy for rate adaptive
++ struct delayed_work watch_dog_wq;
++ struct delayed_work hw_dig_wq;
++ struct delayed_work tx_pw_wq;
++
++#ifdef SW_ANTE_DIVERSITY
++ struct delayed_work SwAntennaWorkItem;
++#endif
++
++#else
++ struct work_struct softmac_scan_wq;
++ struct work_struct start_ibss_wq;
++ struct work_struct associate_retry_wq;
++//by amy for rate adaptive
++ struct work_struct rate_adapter_wq;
++//by amy for rate adaptive
++ struct work_struct watch_dog_wq;
++ struct work_struct hw_dig_wq;
++ struct work_struct tx_pw_wq;
++
++#ifdef SW_ANTE_DIVERSITY
++ struct work_struct SwAntennaWorkItem;
++#endif
++
++#endif
++
++//struct work_struct softmac_scan_wq;
++ struct work_struct wx_sync_scan_wq;
++ struct work_struct wmm_param_update_wq;
++#ifdef _RTL8187_EXT_PATCH_
++ struct work_struct ext_stop_scan_wq;
++ struct work_struct ext_send_beacon_wq;
++#endif
++ struct workqueue_struct *wq;
++#else
++ /* used for periodly scan */
++ struct timer_list scan_timer;
++
++ struct tq_struct associate_complete_wq;
++ struct tq_struct associate_retry_wq;
++ struct tq_struct start_ibss_wq;
++ struct tq_struct associate_procedure_wq;
++ struct tq_struct ips_leave_wq; //YJ,add,081230,for IPS
++ struct tq_struct softmac_scan_wq;
++ struct tq_struct wx_sync_scan_wq;
++ struct tq_struct wmm_param_update_wq;
++#ifdef _RTL8187_EXT_PATCH_
++ struct tq_struct ext_stop_scan_wq;
++ struct tq_struct ext_send_beacon_wq;
++#endif
++#endif
++
++ /* Callback functions */
++ void (*set_security)(struct net_device *dev,
++ struct ieee80211_security *sec);
++
++ /* Used to TX data frame by using txb structs.
++ * this is not used if in the softmac_features
++ * is set the flag IEEE_SOFTMAC_TX_QUEUE
++ */
++ int (*hard_start_xmit)(struct ieee80211_txb *txb,
++ struct net_device *dev);
++
++ int (*reset_port)(struct net_device *dev);
++
++ /* Softmac-generated frames (mamagement) are TXed via this
++ * callback if the flag IEEE_SOFTMAC_SINGLE_QUEUE is
++ * not set. As some cards may have different HW queues that
++ * one might want to use for data and management frames
++ * the option to have two callbacks might be useful.
++ * This fucntion can't sleep.
++ */
++ int (*softmac_hard_start_xmit)(struct sk_buff *skb,
++ struct net_device *dev);
++
++ /* used instead of hard_start_xmit (not softmac_hard_start_xmit)
++ * if the IEEE_SOFTMAC_TX_QUEUE feature is used to TX data
++ * frames. I the option IEEE_SOFTMAC_SINGLE_QUEUE is also set
++ * then also management frames are sent via this callback.
++ * This function can't sleep.
++ */
++ void (*softmac_data_hard_start_xmit)(struct sk_buff *skb,
++ struct net_device *dev,int rate);
++
++ /* stops the HW queue for DATA frames. Useful to avoid
++ * waste time to TX data frame when we are reassociating
++ * This function can sleep.
++ */
++ void (*data_hard_stop)(struct net_device *dev);
++
++ /* OK this is complementar to data_poll_hard_stop */
++ void (*data_hard_resume)(struct net_device *dev);
++
++ /* ask to the driver to retune the radio .
++ * This function can sleep. the driver should ensure
++ * the radio has been swithced before return.
++ */
++ void (*set_chan)(struct net_device *dev,short ch);
++
++ /* These are not used if the ieee stack takes care of
++ * scanning (IEEE_SOFTMAC_SCAN feature set).
++ * In this case only the set_chan is used.
++ *
++ * The syncro version is similar to the start_scan but
++ * does not return until all channels has been scanned.
++ * this is called in user context and should sleep,
++ * it is called in a work_queue when swithcing to ad-hoc mode
++ * or in behalf of iwlist scan when the card is associated
++ * and root user ask for a scan.
++ * the fucntion stop_scan should stop both the syncro and
++ * background scanning and can sleep.
++ * The fucntion start_scan should initiate the background
++ * scanning and can't sleep.
++ */
++ void (*scan_syncro)(struct net_device *dev);
++ void (*start_scan)(struct net_device *dev);
++ void (*stop_scan)(struct net_device *dev);
++
++ /* indicate the driver that the link state is changed
++ * for example it may indicate the card is associated now.
++ * Driver might be interested in this to apply RX filter
++ * rules or simply light the LINK led
++ */
++ void (*link_change)(struct net_device *dev);
++
++ /* these two function indicates to the HW when to start
++ * and stop to send beacons. This is used when the
++ * IEEE_SOFTMAC_BEACONS is not set. For now the
++ * stop_send_bacons is NOT guaranteed to be called only
++ * after start_send_beacons.
++ */
++ void (*start_send_beacons) (struct net_device *dev);
++ void (*stop_send_beacons) (struct net_device *dev);
++
++ /* power save mode related */
++ void (*sta_wake_up) (struct net_device *dev);
++ void (*ps_request_tx_ack) (struct net_device *dev);
++ void (*enter_sleep_state) (struct net_device *dev, u32 th, u32 tl);
++ short (*ps_is_queue_empty) (struct net_device *dev);
++
++//by lizhaoming for LED 2008.6.23
++#ifdef LED
++ void (*ieee80211_led_contorl) (struct net_device *dev, LED_CTL_MODE LedAction);
++#endif
++#ifdef CONFIG_IPS
++ void (*ieee80211_ips_leave) (struct net_device *dev);
++#endif
++ /* QoS related */
++ //void (*wmm_param_update) (struct net_device *dev, u8 *ac_param);
++ //void (*wmm_param_update) (struct ieee80211_device *ieee);
++
++
++#ifdef _RTL8187_EXT_PATCH_
++
++ /// ieee80211_softmac.c
++ int (*ext_patch_ieee80211_start_protocol) (struct ieee80211_device *ieee); // start special mode
++
++ short (*ext_patch_ieee80211_probe_req_1) (struct ieee80211_device *ieee); // return = 0: no more phases, >0: another phase
++ u8* (*ext_patch_ieee80211_probe_req_2) (struct ieee80211_device *ieee, struct sk_buff *skb, u8 *tag); // return tag
++
++ void (*ext_patch_ieee80211_stop_protocol) (struct ieee80211_device *ieee); // stop timer
++
++ void (*ext_patch_ieee80211_association_req_1) (struct ieee80211_assoc_request_frame *hdr);
++ u8* (*ext_patch_ieee80211_association_req_2) (struct ieee80211_device *ieee, struct ieee80211_network *pstat, struct sk_buff *skb);
++
++ int (*ext_patch_ieee80211_rx_frame_softmac_on_assoc_req) (struct ieee80211_device *ieee, struct sk_buff *skb);
++ int (*ext_patch_ieee80211_rx_frame_softmac_on_assoc_rsp) (struct ieee80211_device *ieee, struct sk_buff *skb);
++
++ void (*ext_patch_ieee80211_assoc_resp_by_net_1) (struct ieee80211_assoc_response_frame *assoc);
++ u8* (*ext_patch_ieee80211_assoc_resp_by_net_2) (struct ieee80211_device *ieee, struct ieee80211_network *pstat, int pkt_type, struct sk_buff *skb);
++
++ int (*ext_patch_ieee80211_ext_stop_scan_wq_set_channel) (struct ieee80211_device *ieee);
++
++ int (*ext_patch_ieee80211_softmac_xmit_get_rate) (struct ieee80211_device *ieee, struct sk_buff *skb);
++
++ int (*ext_patch_ieee80211_rx_frame_softmac_on_auth)(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats);
++ int (*ext_patch_ieee80211_rx_frame_softmac_on_deauth)(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats);
++//by amy for mesh
++ void (*ext_patch_ieee80211_start_mesh)(struct ieee80211_device *ieee);
++//by amy for mesh
++ // ieee80211_rx.c
++ // rz
++ void (*ext_patch_ieee80211_rx_mgt_on_probe_req) ( struct ieee80211_device *ieee, struct ieee80211_probe_request *beacon, struct ieee80211_rx_stats *stats);
++ unsigned int(*ext_patch_ieee80211_process_probe_response_1)(struct ieee80211_device *ieee, struct ieee80211_probe_response *beacon, struct ieee80211_rx_stats *stats);
++
++ void (*ext_patch_ieee80211_rx_mgt_update_expire) ( struct ieee80211_device *ieee, struct sk_buff *skb);
++ struct sk_buff* (*ext_patch_get_beacon_get_probersp)(struct ieee80211_device *ieee, u8 *dest, struct ieee80211_network *net);
++
++ // success(return 0) is responsible to free skb
++ int (*ext_patch_ieee80211_rx_on_rx) (struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats, u16 type, u16 stype);
++
++ int (*ext_patch_ieee80211_rx_frame_get_hdrlen) (struct ieee80211_device *ieee, struct sk_buff *skb);
++
++ // Check whether or not accept the incoming frame. return 0: not accept, >0: accept
++ int (*ext_patch_ieee80211_rx_is_valid_framectl) (struct ieee80211_device *ieee, u16 fc, u16 type, u16 stype);
++
++ // return > 0 is success. 0 when failed
++ // success(return >0) is responsible to free skb
++ int (*ext_patch_ieee80211_rx_process_dataframe) (struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats);
++
++ /* added by david for setting acl dynamically */
++ u8 (*ext_patch_ieee80211_acl_query) (struct ieee80211_device *ieee, u8 *sa);
++
++ // int (*ext_patch_is_duplicate_packet) (struct ieee80211_device *ieee, struct ieee80211_hdr *header, u16 type, u16 stype);
++
++ // ieee80211_tx.c
++
++ // locked by ieee->lock. Call ieee80211_softmac_xmit afterward
++ struct ieee80211_txb* (*ext_patch_ieee80211_xmit) (struct sk_buff *skb, struct net_device *dev);
++
++
++#endif // _RTL8187_EXT_PATCH_
++
++ /* This must be the last item so that it points to the data
++ * allocated beyond this structure by alloc_ieee80211 */
++ u8 priv[0];
++};
++
++#define IEEE_A (1<<0)
++#define IEEE_B (1<<1)
++#define IEEE_G (1<<2)
++#define IEEE_MODE_MASK (IEEE_A|IEEE_B|IEEE_G)
++
++/* Generate a 802.11 header */
++
++/* Uses the channel change callback directly
++ * instead of [start/stop] scan callbacks
++ */
++#define IEEE_SOFTMAC_SCAN (1<<2)
++
++/* Perform authentication and association handshake */
++#define IEEE_SOFTMAC_ASSOCIATE (1<<3)
++
++/* Generate probe requests */
++#define IEEE_SOFTMAC_PROBERQ (1<<4)
++
++/* Generate respones to probe requests */
++#define IEEE_SOFTMAC_PROBERS (1<<5)
++
++/* The ieee802.11 stack will manages the netif queue
++ * wake/stop for the driver, taking care of 802.11
++ * fragmentation. See softmac.c for details. */
++#define IEEE_SOFTMAC_TX_QUEUE (1<<7)
++
++/* Uses only the softmac_data_hard_start_xmit
++ * even for TX management frames.
++ */
++#define IEEE_SOFTMAC_SINGLE_QUEUE (1<<8)
++
++/* Generate beacons. The stack will enqueue beacons
++ * to the card
++ */
++#define IEEE_SOFTMAC_BEACONS (1<<6)
++#ifdef _RTL8187_EXT_PATCH_
++extern inline int ieee80211_find_MP(struct ieee80211_device* ieee, const u8* addr, u8 set)
++{
++ int i=0;
++ for (i=1; i<MAX_MP; i++)
++ {
++ if ((ieee->cryptlist[i]->used == 0)&&set)
++ {//entry is empty
++ memcpy(ieee->cryptlist[i]->mac_addr, addr, ETH_ALEN);
++ ieee->cryptlist[i]->used = 1;
++ return i;
++ }
++ else if (0 == memcmp(ieee->cryptlist[i]->mac_addr, addr, ETH_ALEN)) //find matched entry
++ {
++ return i;
++ }
++ }
++ return -1;
++}
++#endif
++
++
++
++static inline void *ieee80211_priv(struct net_device *dev)
++{
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
++ return ((struct ieee80211_device *)netdev_priv(dev))->priv;
++#else
++ return ((struct ieee80211_device *)dev->priv)->priv;
++#endif
++}
++
++extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
++{
++ /* Single white space is for Linksys APs */
++ if (essid_len == 1 && essid[0] == ' ')
++ return 1;
++
++ /* Otherwise, if the entire essid is 0, we assume it is hidden */
++ while (essid_len) {
++ essid_len--;
++ if (essid[essid_len] != '\0')
++ return 0;
++ }
++
++ return 1;
++}
++
++extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode)
++{
++ /*
++ * It is possible for both access points and our device to support
++ * combinations of modes, so as long as there is one valid combination
++ * of ap/device supported modes, then return success
++ *
++ */
++ if ((mode & IEEE_A) &&
++ (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
++ (ieee->freq_band & IEEE80211_52GHZ_BAND))
++ return 1;
++
++ if ((mode & IEEE_G) &&
++ (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
++ (ieee->freq_band & IEEE80211_24GHZ_BAND))
++ return 1;
++
++ if ((mode & IEEE_B) &&
++ (ieee->modulation & IEEE80211_CCK_MODULATION) &&
++ (ieee->freq_band & IEEE80211_24GHZ_BAND))
++ return 1;
++
++ return 0;
++}
++
++extern inline int ieee80211_get_hdrlen(u16 fc)
++{
++ int hdrlen = 24;
++
++ switch (WLAN_FC_GET_TYPE(fc)) {
++ case IEEE80211_FTYPE_DATA:
++ if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
++ hdrlen = 30; /* Addr4 */
++ if(IEEE80211_QOS_HAS_SEQ(fc))
++ hdrlen += 2; /* QOS ctrl*/
++ break;
++ case IEEE80211_FTYPE_CTL:
++ switch (WLAN_FC_GET_STYPE(fc)) {
++ case IEEE80211_STYPE_CTS:
++ case IEEE80211_STYPE_ACK:
++ hdrlen = 10;
++ break;
++ default:
++ hdrlen = 16;
++ break;
++ }
++ break;
++ }
++
++ return hdrlen;
++}
++
++
++
++/* ieee80211.c */
++extern void free_ieee80211(struct net_device *dev);
++extern struct net_device *alloc_ieee80211(int sizeof_priv);
++
++extern int ieee80211_set_encryption(struct ieee80211_device *ieee);
++
++/* ieee80211_tx.c */
++
++extern int ieee80211_encrypt_fragment(
++ struct ieee80211_device *ieee,
++ struct sk_buff *frag,
++ int hdr_len);
++
++extern int ieee80211_xmit(struct sk_buff *skb,
++ struct net_device *dev);
++extern void ieee80211_txb_free(struct ieee80211_txb *);
++
++
++/* ieee80211_rx.c */
++extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
++ struct ieee80211_rx_stats *rx_stats);
++extern void ieee80211_rx_mgt(struct ieee80211_device *ieee,
++ struct ieee80211_hdr *header,
++ struct ieee80211_rx_stats *stats);
++
++/* ieee80211_wx.c */
++extern int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *key);
++extern int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *key);
++extern int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *key);
++extern int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
++ struct iw_request_info *info,
++ union iwreq_data* wrqu, char *extra);
++int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
++ struct iw_request_info *info,
++ struct iw_param *data, char *extra);
++int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra);
++
++int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len);
++/* ieee80211_softmac.c */
++extern short ieee80211_is_54g(struct ieee80211_network net);
++extern short ieee80211_is_shortslot(struct ieee80211_network net);
++extern int ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
++ struct ieee80211_rx_stats *rx_stats, u16 type,
++ u16 stype);
++extern void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net);
++
++extern void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee);
++extern void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee);
++extern void ieee80211_start_bss(struct ieee80211_device *ieee);
++extern void ieee80211_start_master_bss(struct ieee80211_device *ieee);
++extern void ieee80211_start_ibss(struct ieee80211_device *ieee);
++extern void ieee80211_softmac_init(struct ieee80211_device *ieee);
++extern void ieee80211_softmac_free(struct ieee80211_device *ieee);
++extern void ieee80211_associate_abort(struct ieee80211_device *ieee);
++extern void ieee80211_disassociate(struct ieee80211_device *ieee);
++extern void ieee80211_stop_scan(struct ieee80211_device *ieee);
++extern void ieee80211_start_scan_syncro(struct ieee80211_device *ieee);
++extern void ieee80211_check_all_nets(struct ieee80211_device *ieee);
++extern void ieee80211_start_protocol(struct ieee80211_device *ieee);
++extern void ieee80211_stop_protocol(struct ieee80211_device *ieee);
++extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee);
++extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee);
++extern void ieee80211_reset_queue(struct ieee80211_device *ieee);
++extern void ieee80211_wake_queue(struct ieee80211_device *ieee);
++extern void ieee80211_stop_queue(struct ieee80211_device *ieee);
++extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee);
++extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee);
++extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee);
++extern int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p);
++extern void notify_wx_assoc_event(struct ieee80211_device *ieee);
++extern void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success);
++extern void ieee80211_start_scan(struct ieee80211_device *ieee);
++
++#ifdef _RTL8187_EXT_PATCH_
++extern void ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb);
++extern void ieee80211_ext_issue_assoc_req(struct ieee80211_device *ieee, struct ieee80211_network *pstat);
++extern void ieee80211_associate_step1(struct ieee80211_device *ieee);
++extern void ieee80211_ext_issue_disassoc(struct ieee80211_device *ieee, struct ieee80211_network *pstat, int reason, unsigned char extReason);
++extern void ieee80211_ext_issue_assoc_rsp(struct ieee80211_device *ieee, u8 *dest, unsigned short status, struct ieee80211_network *pstat, int pkt_type);
++extern void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee);
++extern struct sk_buff* ieee80211_ext_probe_resp_by_net(struct ieee80211_device *ieee, u8 *dest, struct ieee80211_network *net);
++extern int ieee80211_network_init(struct ieee80211_device *ieee, struct ieee80211_probe_response *beacon, struct ieee80211_network *network, struct ieee80211_rx_stats *stats);
++extern struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size, int gfp_mask);
++extern void ieee80211_ext_send_11s_beacon(struct ieee80211_device *ieee);
++extern struct ieee80211_txb *ieee80211_ext_alloc_txb(struct sk_buff *skb, struct net_device *dev, struct ieee80211_hdr_3addr *header, int hdr_len, u8 isQoS, u16 *pQOS_ctl, int isEncrypt, struct ieee80211_crypt_data* crypt);
++extern struct ieee80211_txb *ieee80211_ext_reuse_txb(struct sk_buff *skb, struct net_device *dev, struct ieee80211_hdr_3addr *header, int hdr_len, u8 isQoS, u16 *pQOS_ctl, int isEncrypt, struct ieee80211_crypt_data* crypt);
++extern int ieee_ext_skb_p80211_to_ether(struct sk_buff *skb, int hdrlen, u8 *dst, u8 *src);
++#endif
++
++/* ieee80211_crypt_ccmp&tkip&wep.c */
++extern void ieee80211_tkip_null(void);
++extern void ieee80211_wep_null(void);
++extern void ieee80211_ccmp_null(void);
++/* ieee80211_softmac_wx.c */
++
++extern int ieee80211_wx_get_wap(struct ieee80211_device *ieee,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *ext);
++
++extern int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
++ struct iw_request_info *info,
++ union iwreq_data *awrq,
++ char *extra);
++
++extern int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b);
++
++extern int ieee80211_wx_set_rate(struct ieee80211_device *ieee,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra);
++
++extern int ieee80211_wx_get_rate(struct ieee80211_device *ieee,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra);
++
++extern int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
++ union iwreq_data *wrqu, char *b);
++
++extern int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a,
++ union iwreq_data *wrqu, char *b);
++
++extern int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
++ struct iw_request_info *a,
++ union iwreq_data *wrqu, char *extra);
++
++extern int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
++ union iwreq_data *wrqu, char *b);
++
++extern int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
++ union iwreq_data *wrqu, char *b);
++
++extern int ieee80211_wx_get_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
++ union iwreq_data *wrqu, char *b);
++
++//extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee);
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
++extern void ieee80211_wx_sync_scan_wq(struct work_struct *work);
++#else
++ extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee);
++#endif
++extern int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra);
++
++extern int ieee80211_wx_get_name(struct ieee80211_device *ieee,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra);
++
++extern int ieee80211_wx_set_power(struct ieee80211_device *ieee,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra);
++
++extern int ieee80211_wx_get_power(struct ieee80211_device *ieee,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra);
++
++extern const long ieee80211_wlan_frequencies[];
++
++extern inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
++{
++ ieee->scans++;
++}
++
++extern inline int ieee80211_get_scans(struct ieee80211_device *ieee)
++{
++ return ieee->scans;
++}
++
++static inline const char *escape_essid(const char *essid, u8 essid_len) {
++ static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
++ const char *s = essid;
++ char *d = escaped;
++
++ if (ieee80211_is_empty_essid(essid, essid_len)) {
++ memcpy(escaped, "<hidden>", sizeof("<hidden>"));
++ return escaped;
++ }
++
++ essid_len = min(essid_len, (u8)IW_ESSID_MAX_SIZE);
++ while (essid_len--) {
++ if (*s == '\0') {
++ *d++ = '\\';
++ *d++ = '0';
++ s++;
++ } else {
++ *d++ = *s++;
++ }
++ }
++ *d = '\0';
++ return escaped;
++}
++#endif /* IEEE80211_H */
+diff --git a/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt.c b/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt.c
+new file mode 100644
+index 0000000..57a6696
+--- /dev/null
++++ b/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt.c
+@@ -0,0 +1,275 @@
++/*
++ * Host AP crypto routines
++ *
++ * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
++ * Portions Copyright (C) 2004, Intel Corporation <jketreno@linux.intel.com>
++ *
++ * 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. See README and COPYING for
++ * more details.
++ *
++ */
++
++//#include <linux/config.h>
++#include <linux/version.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <asm/string.h>
++#include <asm/errno.h>
++
++#include "ieee80211.h"
++
++MODULE_AUTHOR("Jouni Malinen");
++MODULE_DESCRIPTION("HostAP crypto");
++MODULE_LICENSE("GPL");
++
++struct ieee80211_crypto_alg {
++ struct list_head list;
++ struct ieee80211_crypto_ops *ops;
++};
++
++
++struct ieee80211_crypto {
++ struct list_head algs;
++ spinlock_t lock;
++};
++
++static struct ieee80211_crypto *hcrypt;
++
++void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee,
++ int force)
++{
++ struct list_head *ptr, *n;
++ struct ieee80211_crypt_data *entry;
++
++ for (ptr = ieee->crypt_deinit_list.next, n = ptr->next;
++ ptr != &ieee->crypt_deinit_list; ptr = n, n = ptr->next) {
++ entry = list_entry(ptr, struct ieee80211_crypt_data, list);
++
++ if (atomic_read(&entry->refcnt) != 0 && !force)
++ continue;
++
++ list_del(ptr);
++
++ if (entry->ops) {
++ entry->ops->deinit(entry->priv);
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
++ module_put(entry->ops->owner);
++#else
++ __MOD_DEC_USE_COUNT(entry->ops->owner);
++#endif
++ }
++ kfree(entry);
++ }
++}
++
++void ieee80211_crypt_deinit_handler(unsigned long data)
++{
++ struct ieee80211_device *ieee = (struct ieee80211_device *)data;
++ unsigned long flags;
++
++ spin_lock_irqsave(&ieee->lock, flags);
++ ieee80211_crypt_deinit_entries(ieee, 0);
++ if (!list_empty(&ieee->crypt_deinit_list)) {
++ printk(KERN_DEBUG "%s: entries remaining in delayed crypt "
++ "deletion list\n", ieee->dev->name);
++ ieee->crypt_deinit_timer.expires = jiffies + HZ;
++ add_timer(&ieee->crypt_deinit_timer);
++ }
++ spin_unlock_irqrestore(&ieee->lock, flags);
++
++}
++
++void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
++ struct ieee80211_crypt_data **crypt)
++{
++ struct ieee80211_crypt_data *tmp;
++ unsigned long flags;
++
++ if (*crypt == NULL)
++ return;
++
++ tmp = *crypt;
++ *crypt = NULL;
++
++ /* must not run ops->deinit() while there may be pending encrypt or
++ * decrypt operations. Use a list of delayed deinits to avoid needing
++ * locking. */
++
++ spin_lock_irqsave(&ieee->lock, flags);
++ list_add(&tmp->list, &ieee->crypt_deinit_list);
++ if (!timer_pending(&ieee->crypt_deinit_timer)) {
++ ieee->crypt_deinit_timer.expires = jiffies + HZ;
++ add_timer(&ieee->crypt_deinit_timer);
++ }
++ spin_unlock_irqrestore(&ieee->lock, flags);
++}
++
++int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops)
++{
++ unsigned long flags;
++ struct ieee80211_crypto_alg *alg;
++
++ if (hcrypt == NULL)
++ return -1;
++
++ alg = kmalloc(sizeof(*alg), GFP_KERNEL);
++ if (alg == NULL)
++ return -ENOMEM;
++
++ memset(alg, 0, sizeof(*alg));
++ alg->ops = ops;
++
++ spin_lock_irqsave(&hcrypt->lock, flags);
++ list_add(&alg->list, &hcrypt->algs);
++ spin_unlock_irqrestore(&hcrypt->lock, flags);
++
++ printk(KERN_DEBUG "ieee80211_crypt: registered algorithm '%s'\n",
++ ops->name);
++
++ return 0;
++}
++
++int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops)
++{
++ unsigned long flags;
++ struct list_head *ptr;
++ struct ieee80211_crypto_alg *del_alg = NULL;
++
++ if (hcrypt == NULL)
++ return -1;
++
++ spin_lock_irqsave(&hcrypt->lock, flags);
++ for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
++ struct ieee80211_crypto_alg *alg =
++ (struct ieee80211_crypto_alg *) ptr;
++ if (alg->ops == ops) {
++ list_del(&alg->list);
++ del_alg = alg;
++ break;
++ }
++ }
++ spin_unlock_irqrestore(&hcrypt->lock, flags);
++
++ if (del_alg) {
++ printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
++ "'%s'\n", ops->name);
++ kfree(del_alg);
++ }
++
++ return del_alg ? 0 : -1;
++}
++
++
++struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name)
++{
++ unsigned long flags;
++ struct list_head *ptr;
++ struct ieee80211_crypto_alg *found_alg = NULL;
++
++ if (hcrypt == NULL)
++ return NULL;
++
++ spin_lock_irqsave(&hcrypt->lock, flags);
++ for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
++ struct ieee80211_crypto_alg *alg =
++ (struct ieee80211_crypto_alg *) ptr;
++ if (strcmp(alg->ops->name, name) == 0) {
++ found_alg = alg;
++ break;
++ }
++ }
++ spin_unlock_irqrestore(&hcrypt->lock, flags);
++
++ if (found_alg)
++ return found_alg->ops;
++ else
++ return NULL;
++}
++
++
++static void * ieee80211_crypt_null_init(int keyidx) { return (void *) 1; }
++static void ieee80211_crypt_null_deinit(void *priv) {}
++
++static struct ieee80211_crypto_ops ieee80211_crypt_null = {
++ .name = "NULL",
++ .init = ieee80211_crypt_null_init,
++ .deinit = ieee80211_crypt_null_deinit,
++ .encrypt_mpdu = NULL,
++ .decrypt_mpdu = NULL,
++ .encrypt_msdu = NULL,
++ .decrypt_msdu = NULL,
++ .set_key = NULL,
++ .get_key = NULL,
++ .extra_prefix_len = 0,
++ .extra_postfix_len = 0,
++ .owner = THIS_MODULE,
++};
++
++
++int __init ieee80211_crypto_init(void)
++{
++ int ret = -ENOMEM;
++
++ hcrypt = kmalloc(sizeof(*hcrypt), GFP_KERNEL);
++ if (!hcrypt)
++ goto out;
++
++ memset(hcrypt, 0, sizeof(*hcrypt));
++ INIT_LIST_HEAD(&hcrypt->algs);
++ spin_lock_init(&hcrypt->lock);
++
++ ret = ieee80211_register_crypto_ops(&ieee80211_crypt_null);
++ if (ret < 0) {
++ kfree(hcrypt);
++ hcrypt = NULL;
++ }
++out:
++ return ret;
++}
++
++
++void __exit ieee80211_crypto_deinit(void)
++{
++ struct list_head *ptr, *n;
++
++ if (hcrypt == NULL)
++ return;
++
++ for (ptr = hcrypt->algs.next, n = ptr->next; ptr != &hcrypt->algs;
++ ptr = n, n = ptr->next) {
++ struct ieee80211_crypto_alg *alg =
++ (struct ieee80211_crypto_alg *) ptr;
++ list_del(ptr);
++ printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
++ "'%s' (deinit)\n", alg->ops->name);
++ kfree(alg);
++ }
++
++ kfree(hcrypt);
++}
++
++#if 0
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
++EXPORT_SYMBOL(ieee80211_crypt_deinit_entries);
++EXPORT_SYMBOL(ieee80211_crypt_deinit_handler);
++EXPORT_SYMBOL(ieee80211_crypt_delayed_deinit);
++
++EXPORT_SYMBOL(ieee80211_register_crypto_ops);
++EXPORT_SYMBOL(ieee80211_unregister_crypto_ops);
++EXPORT_SYMBOL(ieee80211_get_crypto_ops);
++#else
++EXPORT_SYMBOL_NOVERS(ieee80211_crypt_deinit_entries);
++EXPORT_SYMBOL_NOVERS(ieee80211_crypt_deinit_handler);
++EXPORT_SYMBOL_NOVERS(ieee80211_crypt_delayed_deinit);
++
++EXPORT_SYMBOL_NOVERS(ieee80211_register_crypto_ops);
++EXPORT_SYMBOL_NOVERS(ieee80211_unregister_crypto_ops);
++EXPORT_SYMBOL_NOVERS(ieee80211_get_crypto_ops);
++#endif
++
++module_init(ieee80211_crypto_init);
++module_exit(ieee80211_crypto_deinit);
++#endif
+diff --git a/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt.h b/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt.h
+new file mode 100644
+index 0000000..5fa8764
+--- /dev/null
++++ b/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt.h
+@@ -0,0 +1,91 @@
++/*
++ * Original code based on Host AP (software wireless LAN access point) driver
++ * for Intersil Prism2/2.5/3.
++ *
++ * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
++ * <jkmaline@cc.hut.fi>
++ * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
++ *
++ * Adaption to a generic IEEE 802.11 stack by James Ketrenos
++ * <jketreno@linux.intel.com>
++ *
++ * Copyright (c) 2004, Intel Corporation
++ *
++ * 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. See README and COPYING for
++ * more details.
++ */
++
++/*
++ * This file defines the interface to the ieee80211 crypto module.
++ */
++#ifndef IEEE80211_CRYPT_H
++#define IEEE80211_CRYPT_H
++
++#include <linux/skbuff.h>
++
++struct ieee80211_crypto_ops {
++ const char *name;
++
++ /* init new crypto context (e.g., allocate private data space,
++ * select IV, etc.); returns NULL on failure or pointer to allocated
++ * private data on success */
++ void * (*init)(int keyidx);
++
++ /* deinitialize crypto context and free allocated private data */
++ void (*deinit)(void *priv);
++
++ /* encrypt/decrypt return < 0 on error or >= 0 on success. The return
++ * value from decrypt_mpdu is passed as the keyidx value for
++ * decrypt_msdu. skb must have enough head and tail room for the
++ * encryption; if not, error will be returned; these functions are
++ * called for all MPDUs (i.e., fragments).
++ */
++ int (*encrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
++ int (*decrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
++
++ /* These functions are called for full MSDUs, i.e. full frames.
++ * These can be NULL if full MSDU operations are not needed. */
++ int (*encrypt_msdu)(struct sk_buff *skb, int hdr_len, void *priv);
++ int (*decrypt_msdu)(struct sk_buff *skb, int keyidx, int hdr_len,
++ void *priv);
++
++ int (*set_key)(void *key, int len, u8 *seq, void *priv);
++ int (*get_key)(void *key, int len, u8 *seq, void *priv);
++
++ /* procfs handler for printing out key information and possible
++ * statistics */
++ char * (*print_stats)(char *p, void *priv);
++
++ /* maximum number of bytes added by encryption; encrypt buf is
++ * allocated with extra_prefix_len bytes, copy of in_buf, and
++ * extra_postfix_len; encrypt need not use all this space, but
++ * the result must start at the beginning of the buffer and correct
++ * length must be returned */
++ int extra_prefix_len, extra_postfix_len;
++
++ struct module *owner;
++};
++
++struct ieee80211_crypt_data {
++ struct list_head list; /* delayed deletion list */
++ struct ieee80211_crypto_ops *ops;
++ void *priv;
++ atomic_t refcnt;
++};
++
++int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops);
++int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops);
++struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name);
++void ieee80211_crypt_deinit_entries(struct ieee80211_device *, int);
++void ieee80211_crypt_deinit_handler(unsigned long);
++void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
++ struct ieee80211_crypt_data **crypt);
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
++#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK)
++#define crypto_alloc_tfm crypto_alloc_tfm_rtl
++#define crypto_free_tfm crypto_free_tfm_rtl
++#endif
++
++#endif
+diff --git a/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_ccmp.c b/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_ccmp.c
+new file mode 100644
+index 0000000..37f4259
+--- /dev/null
++++ b/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_ccmp.c
+@@ -0,0 +1,524 @@
++/*
++ * Host AP crypt: host-based CCMP encryption implementation for Host AP driver
++ *
++ * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
++ *
++ * 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. See README and COPYING for
++ * more details.
++ */
++
++//#include <linux/config.h>
++#include <linux/version.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/random.h>
++#include <linux/skbuff.h>
++#include <linux/netdevice.h>
++#include <linux/if_ether.h>
++#include <linux/if_arp.h>
++#include <asm/string.h>
++#include <linux/wireless.h>
++
++#include "ieee80211.h"
++
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
++#include "rtl_crypto.h"
++#else
++#include <linux/crypto.h>
++#endif
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
++ #include <asm/scatterlist.h>
++#else
++ #include <linux/scatterlist.h>
++#endif
++
++//#include <asm/scatterlist.h>
++
++MODULE_AUTHOR("Jouni Malinen");
++MODULE_DESCRIPTION("Host AP crypt: CCMP");
++MODULE_LICENSE("GPL");
++
++#define AES_BLOCK_LEN 16
++#define CCMP_HDR_LEN 8
++#define CCMP_MIC_LEN 8
++#define CCMP_TK_LEN 16
++#define CCMP_PN_LEN 6
++
++struct ieee80211_ccmp_data {
++ u8 key[CCMP_TK_LEN];
++ int key_set;
++
++ u8 tx_pn[CCMP_PN_LEN];
++ u8 rx_pn[CCMP_PN_LEN];
++
++ u32 dot11RSNAStatsCCMPFormatErrors;
++ u32 dot11RSNAStatsCCMPReplays;
++ u32 dot11RSNAStatsCCMPDecryptErrors;
++
++ int key_idx;
++
++ struct crypto_tfm *tfm;
++
++ /* scratch buffers for virt_to_page() (crypto API) */
++ u8 tx_b0[AES_BLOCK_LEN], tx_b[AES_BLOCK_LEN],
++ tx_e[AES_BLOCK_LEN], tx_s0[AES_BLOCK_LEN];
++ u8 rx_b0[AES_BLOCK_LEN], rx_b[AES_BLOCK_LEN], rx_a[AES_BLOCK_LEN];
++};
++
++void ieee80211_ccmp_aes_encrypt(struct crypto_tfm *tfm,
++ const u8 pt[16], u8 ct[16])
++{
++ #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
++ struct scatterlist src, dst;
++
++ src.page = virt_to_page(pt);
++ src.offset = offset_in_page(pt);
++ src.length = AES_BLOCK_LEN;
++
++ dst.page = virt_to_page(ct);
++ dst.offset = offset_in_page(ct);
++ dst.length = AES_BLOCK_LEN;
++
++ crypto_cipher_encrypt(tfm, &dst, &src, AES_BLOCK_LEN);
++ #else
++ crypto_cipher_encrypt_one((void*)tfm, ct, pt);
++ #endif
++}
++
++static void * ieee80211_ccmp_init(int key_idx)
++{
++ struct ieee80211_ccmp_data *priv;
++
++ priv = kmalloc(sizeof(*priv), GFP_ATOMIC);
++ if (priv == NULL)
++ goto fail;
++ memset(priv, 0, sizeof(*priv));
++ priv->key_idx = key_idx;
++
++ #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
++ priv->tfm = crypto_alloc_tfm("aes", 0);
++ if (priv->tfm == NULL) {
++ printk(KERN_DEBUG "ieee80211_crypt_ccmp: could not allocate "
++ "crypto API aes\n");
++ goto fail;
++ }
++ #else
++ priv->tfm = (void*)crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
++ if (IS_ERR(priv->tfm)) {
++ printk(KERN_DEBUG "ieee80211_crypt_ccmp: could not allocate "
++ "crypto API aes\n");
++ priv->tfm = NULL;
++ goto fail;
++ }
++ #endif
++ return priv;
++
++fail:
++ if (priv) {
++ if (priv->tfm)
++ #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
++ crypto_free_tfm(priv->tfm);
++ #else
++ crypto_free_cipher((void*)priv->tfm);
++ #endif
++ kfree(priv);
++ }
++
++ return NULL;
++}
++
++
++static void ieee80211_ccmp_deinit(void *priv)
++{
++ struct ieee80211_ccmp_data *_priv = priv;
++ if (_priv && _priv->tfm)
++ #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
++ crypto_free_tfm(_priv->tfm);
++ #else
++ crypto_free_cipher((void*)_priv->tfm);
++ #endif
++ kfree(priv);
++}
++
++
++static inline void xor_block(u8 *b, u8 *a, size_t len)
++{
++ int i;
++ for (i = 0; i < len; i++)
++ b[i] ^= a[i];
++}
++
++#ifndef JOHN_CCMP
++static void ccmp_init_blocks(struct crypto_tfm *tfm,
++ struct ieee80211_hdr *hdr,
++ u8 *pn, size_t dlen, u8 *b0, u8 *auth,
++ u8 *s0)
++{
++ u8 *pos, qc = 0;
++ size_t aad_len;
++ u16 fc;
++ int a4_included, qc_included;
++ u8 aad[2 * AES_BLOCK_LEN];
++
++ fc = le16_to_cpu(hdr->frame_ctl);
++ a4_included = ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
++ (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS));
++ /*
++ qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) &&
++ (WLAN_FC_GET_STYPE(fc) & 0x08));
++ */
++ // fixed by David :2006.9.6
++ qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) &&
++ (WLAN_FC_GET_STYPE(fc) & 0x80));
++ aad_len = 22;
++ if (a4_included)
++ aad_len += 6;
++ if (qc_included) {
++ pos = (u8 *) &hdr->addr4;
++ if (a4_included)
++ pos += 6;
++ qc = *pos & 0x0f;
++ aad_len += 2;
++ }
++ /* CCM Initial Block:
++ * Flag (Include authentication header, M=3 (8-octet MIC),
++ * L=1 (2-octet Dlen))
++ * Nonce: 0x00 | A2 | PN
++ * Dlen */
++ b0[0] = 0x59;
++ b0[1] = qc;
++ memcpy(b0 + 2, hdr->addr2, ETH_ALEN);
++ memcpy(b0 + 8, pn, CCMP_PN_LEN);
++ b0[14] = (dlen >> 8) & 0xff;
++ b0[15] = dlen & 0xff;
++
++ /* AAD:
++ * FC with bits 4..6 and 11..13 masked to zero; 14 is always one
++ * A1 | A2 | A3
++ * SC with bits 4..15 (seq#) masked to zero
++ * A4 (if present)
++ * QC (if present)
++ */
++ pos = (u8 *) hdr;
++ aad[0] = 0; /* aad_len >> 8 */
++ aad[1] = aad_len & 0xff;
++ aad[2] = pos[0] & 0x8f;
++ aad[3] = pos[1] & 0xc7;
++ memcpy(aad + 4, hdr->addr1, 3 * ETH_ALEN);
++ pos = (u8 *) &hdr->seq_ctl;
++ aad[22] = pos[0] & 0x0f;
++ aad[23] = 0; /* all bits masked */
++ memset(aad + 24, 0, 8);
++ if (a4_included)
++ memcpy(aad + 24, hdr->addr4, ETH_ALEN);
++ if (qc_included) {
++ aad[a4_included ? 30 : 24] = qc;
++ /* rest of QC masked */
++ }
++
++ /* Start with the first block and AAD */
++ ieee80211_ccmp_aes_encrypt(tfm, b0, auth);
++ xor_block(auth, aad, AES_BLOCK_LEN);
++ ieee80211_ccmp_aes_encrypt(tfm, auth, auth);
++ xor_block(auth, &aad[AES_BLOCK_LEN], AES_BLOCK_LEN);
++ ieee80211_ccmp_aes_encrypt(tfm, auth, auth);
++ b0[0] &= 0x07;
++ b0[14] = b0[15] = 0;
++ ieee80211_ccmp_aes_encrypt(tfm, b0, s0);
++}
++#endif
++
++static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
++{
++ struct ieee80211_ccmp_data *key = priv;
++ int data_len, i;
++ u8 *pos;
++ struct ieee80211_hdr *hdr;
++#ifndef JOHN_CCMP
++ int blocks, last, len;
++ u8 *mic;
++ u8 *b0 = key->tx_b0;
++ u8 *b = key->tx_b;
++ u8 *e = key->tx_e;
++ u8 *s0 = key->tx_s0;
++#endif
++ if (skb_headroom(skb) < CCMP_HDR_LEN ||
++ skb_tailroom(skb) < CCMP_MIC_LEN ||
++ skb->len < hdr_len)
++ return -1;
++
++ data_len = skb->len - hdr_len;
++ pos = skb_push(skb, CCMP_HDR_LEN);
++ memmove(pos, pos + CCMP_HDR_LEN, hdr_len);
++ pos += hdr_len;
++// mic = skb_put(skb, CCMP_MIC_LEN);
++
++ i = CCMP_PN_LEN - 1;
++ while (i >= 0) {
++ key->tx_pn[i]++;
++ if (key->tx_pn[i] != 0)
++ break;
++ i--;
++ }
++
++ *pos++ = key->tx_pn[5];
++ *pos++ = key->tx_pn[4];
++ *pos++ = 0;
++ *pos++ = (key->key_idx << 6) | (1 << 5) /* Ext IV included */;
++ *pos++ = key->tx_pn[3];
++ *pos++ = key->tx_pn[2];
++ *pos++ = key->tx_pn[1];
++ *pos++ = key->tx_pn[0];
++
++ hdr = (struct ieee80211_hdr *) skb->data;
++#ifndef JOHN_CCMP
++ //mic is moved to here by john
++ mic = skb_put(skb, CCMP_MIC_LEN);
++
++ ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0);
++
++ blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
++ last = data_len % AES_BLOCK_LEN;
++
++ for (i = 1; i <= blocks; i++) {
++ len = (i == blocks && last) ? last : AES_BLOCK_LEN;
++ /* Authentication */
++ xor_block(b, pos, len);
++ ieee80211_ccmp_aes_encrypt(key->tfm, b, b);
++ /* Encryption, with counter */
++ b0[14] = (i >> 8) & 0xff;
++ b0[15] = i & 0xff;
++ ieee80211_ccmp_aes_encrypt(key->tfm, b0, e);
++ xor_block(pos, e, len);
++ pos += len;
++ }
++
++ for (i = 0; i < CCMP_MIC_LEN; i++)
++ mic[i] = b[i] ^ s0[i];
++#endif
++ return 0;
++}
++
++
++static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
++{
++ struct ieee80211_ccmp_data *key = priv;
++ u8 keyidx, *pos;
++ struct ieee80211_hdr *hdr;
++ u8 pn[6];
++#ifndef JOHN_CCMP
++ size_t data_len = skb->len - hdr_len - CCMP_HDR_LEN - CCMP_MIC_LEN;
++ u8 *mic = skb->data + skb->len - CCMP_MIC_LEN;
++ u8 *b0 = key->rx_b0;
++ u8 *b = key->rx_b;
++ u8 *a = key->rx_a;
++ int i, blocks, last, len;
++#endif
++ if (skb->len < hdr_len + CCMP_HDR_LEN + CCMP_MIC_LEN) {
++ key->dot11RSNAStatsCCMPFormatErrors++;
++ return -1;
++ }
++
++ hdr = (struct ieee80211_hdr *) skb->data;
++ pos = skb->data + hdr_len;
++ keyidx = pos[3];
++ if (!(keyidx & (1 << 5))) {
++ if (net_ratelimit()) {
++ printk(KERN_DEBUG "CCMP: received packet without ExtIV"
++ " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2));
++ }
++ key->dot11RSNAStatsCCMPFormatErrors++;
++ return -2;
++ }
++ keyidx >>= 6;
++ if (key->key_idx != keyidx) {
++ printk(KERN_DEBUG "CCMP: RX tkey->key_idx=%d frame "
++ "keyidx=%d priv=%p\n", key->key_idx, keyidx, priv);
++ return -6;
++ }
++ if (!key->key_set) {
++ if (net_ratelimit()) {
++ printk(KERN_DEBUG "CCMP: received packet from " MAC_FMT
++ " with keyid=%d that does not have a configured"
++ " key\n", MAC_ARG(hdr->addr2), keyidx);
++ }
++ return -3;
++ }
++
++ pn[0] = pos[7];
++ pn[1] = pos[6];
++ pn[2] = pos[5];
++ pn[3] = pos[4];
++ pn[4] = pos[1];
++ pn[5] = pos[0];
++ pos += 8;
++#if 0
++ if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) {
++ if (net_ratelimit()) {
++ printk(KERN_DEBUG "CCMP: replay detected: STA=" MAC_FMT
++ " previous PN %02x%02x%02x%02x%02x%02x "
++ "received PN %02x%02x%02x%02x%02x%02x\n",
++ MAC_ARG(hdr->addr2), MAC_ARG(key->rx_pn),
++ MAC_ARG(pn));
++ }
++ key->dot11RSNAStatsCCMPReplays++;
++ return -4;
++ }
++#endif
++#ifndef JOHN_CCMP
++ ccmp_init_blocks(key->tfm, hdr, pn, data_len, b0, a, b);
++ xor_block(mic, b, CCMP_MIC_LEN);
++
++ blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
++ last = data_len % AES_BLOCK_LEN;
++
++ for (i = 1; i <= blocks; i++) {
++ len = (i == blocks && last) ? last : AES_BLOCK_LEN;
++ /* Decrypt, with counter */
++ b0[14] = (i >> 8) & 0xff;
++ b0[15] = i & 0xff;
++ ieee80211_ccmp_aes_encrypt(key->tfm, b0, b);
++ xor_block(pos, b, len);
++ /* Authentication */
++ xor_block(a, pos, len);
++ ieee80211_ccmp_aes_encrypt(key->tfm, a, a);
++ pos += len;
++ }
++
++ if (memcmp(mic, a, CCMP_MIC_LEN) != 0) {
++ if (net_ratelimit()) {
++ printk(KERN_DEBUG "CCMP: decrypt failed: STA="
++ MAC_FMT "\n", MAC_ARG(hdr->addr2));
++ }
++ key->dot11RSNAStatsCCMPDecryptErrors++;
++ return -5;
++ }
++
++ memcpy(key->rx_pn, pn, CCMP_PN_LEN);
++
++#endif
++ /* Remove hdr and MIC */
++ memmove(skb->data + CCMP_HDR_LEN, skb->data, hdr_len);
++ skb_pull(skb, CCMP_HDR_LEN);
++ skb_trim(skb, skb->len - CCMP_MIC_LEN);
++
++ return keyidx;
++}
++
++
++static int ieee80211_ccmp_set_key(void *key, int len, u8 *seq, void *priv)
++{
++ struct ieee80211_ccmp_data *data = priv;
++ int keyidx;
++ struct crypto_tfm *tfm = data->tfm;
++
++ keyidx = data->key_idx;
++ memset(data, 0, sizeof(*data));
++ data->key_idx = keyidx;
++ data->tfm = tfm;
++ if (len == CCMP_TK_LEN) {
++ memcpy(data->key, key, CCMP_TK_LEN);
++ data->key_set = 1;
++ if (seq) {
++ data->rx_pn[0] = seq[5];
++ data->rx_pn[1] = seq[4];
++ data->rx_pn[2] = seq[3];
++ data->rx_pn[3] = seq[2];
++ data->rx_pn[4] = seq[1];
++ data->rx_pn[5] = seq[0];
++ }
++ crypto_cipher_setkey((void*)data->tfm, data->key, CCMP_TK_LEN);
++ } else if (len == 0)
++ data->key_set = 0;
++ else
++ return -1;
++
++ return 0;
++}
++
++
++static int ieee80211_ccmp_get_key(void *key, int len, u8 *seq, void *priv)
++{
++ struct ieee80211_ccmp_data *data = priv;
++
++ if (len < CCMP_TK_LEN)
++ return -1;
++
++ if (!data->key_set)
++ return 0;
++ memcpy(key, data->key, CCMP_TK_LEN);
++
++ if (seq) {
++ seq[0] = data->tx_pn[5];
++ seq[1] = data->tx_pn[4];
++ seq[2] = data->tx_pn[3];
++ seq[3] = data->tx_pn[2];
++ seq[4] = data->tx_pn[1];
++ seq[5] = data->tx_pn[0];
++ }
++
++ return CCMP_TK_LEN;
++}
++
++
++static char * ieee80211_ccmp_print_stats(char *p, void *priv)
++{
++ struct ieee80211_ccmp_data *ccmp = priv;
++ p += sprintf(p, "key[%d] alg=CCMP key_set=%d "
++ "tx_pn=%02x%02x%02x%02x%02x%02x "
++ "rx_pn=%02x%02x%02x%02x%02x%02x "
++ "format_errors=%d replays=%d decrypt_errors=%d\n",
++ ccmp->key_idx, ccmp->key_set,
++ MAC_ARG(ccmp->tx_pn), MAC_ARG(ccmp->rx_pn),
++ ccmp->dot11RSNAStatsCCMPFormatErrors,
++ ccmp->dot11RSNAStatsCCMPReplays,
++ ccmp->dot11RSNAStatsCCMPDecryptErrors);
++
++ return p;
++}
++
++void ieee80211_ccmp_null(void)
++{
++ // printk("============>%s()\n", __FUNCTION__);
++ return;
++}
++static struct ieee80211_crypto_ops ieee80211_crypt_ccmp = {
++ .name = "CCMP",
++ .init = ieee80211_ccmp_init,
++ .deinit = ieee80211_ccmp_deinit,
++ .encrypt_mpdu = ieee80211_ccmp_encrypt,
++ .decrypt_mpdu = ieee80211_ccmp_decrypt,
++ .encrypt_msdu = NULL,
++ .decrypt_msdu = NULL,
++ .set_key = ieee80211_ccmp_set_key,
++ .get_key = ieee80211_ccmp_get_key,
++ .print_stats = ieee80211_ccmp_print_stats,
++ .extra_prefix_len = CCMP_HDR_LEN,
++ .extra_postfix_len = CCMP_MIC_LEN,
++ .owner = THIS_MODULE,
++};
++
++
++int __init ieee80211_crypto_ccmp_init(void)
++{
++ return ieee80211_register_crypto_ops(&ieee80211_crypt_ccmp);
++}
++
++
++void __exit ieee80211_crypto_ccmp_exit(void)
++{
++ ieee80211_unregister_crypto_ops(&ieee80211_crypt_ccmp);
++}
++#if 0
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
++EXPORT_SYMBOL(ieee80211_ccmp_null);
++#else
++EXPORT_SYMBOL_NOVERS(ieee80211_ccmp_null);
++#endif
++
++module_init(ieee80211_crypto_ccmp_init);
++module_exit(ieee80211_crypto_ccmp_exit);
++#endif
+diff --git a/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_tkip.c b/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_tkip.c
+new file mode 100644
+index 0000000..92a6e93
+--- /dev/null
++++ b/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_tkip.c
+@@ -0,0 +1,996 @@
++/*
++ * Host AP crypt: host-based TKIP encryption implementation for Host AP driver
++ *
++ * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
++ *
++ * 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. See README and COPYING for
++ * more details.
++ */
++
++//#include <linux/config.h>
++#include <linux/version.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/random.h>
++#include <linux/skbuff.h>
++#include <linux/netdevice.h>
++#include <linux/if_ether.h>
++#include <linux/if_arp.h>
++#include <asm/string.h>
++
++#include "ieee80211.h"
++
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
++#include "rtl_crypto.h"
++#else
++#include <linux/crypto.h>
++#endif
++//#include <asm/scatterlist.h>
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
++ #include <asm/scatterlist.h>
++#else
++ #include <linux/scatterlist.h>
++#endif
++
++#include <linux/crc32.h>
++
++MODULE_AUTHOR("Jouni Malinen");
++MODULE_DESCRIPTION("Host AP crypt: TKIP");
++MODULE_LICENSE("GPL");
++
++struct ieee80211_tkip_data {
++#define TKIP_KEY_LEN 32
++ u8 key[TKIP_KEY_LEN];
++ int key_set;
++
++ u32 tx_iv32;
++ u16 tx_iv16;
++ u16 tx_ttak[5];
++ int tx_phase1_done;
++
++ u32 rx_iv32;
++ u16 rx_iv16;
++ u16 rx_ttak[5];
++ int rx_phase1_done;
++ u32 rx_iv32_new;
++ u16 rx_iv16_new;
++
++ u32 dot11RSNAStatsTKIPReplays;
++ u32 dot11RSNAStatsTKIPICVErrors;
++ u32 dot11RSNAStatsTKIPLocalMICFailures;
++
++ int key_idx;
++
++ #if(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))
++ struct crypto_blkcipher *rx_tfm_arc4;
++ struct crypto_hash *rx_tfm_michael;
++ struct crypto_blkcipher *tx_tfm_arc4;
++ struct crypto_hash *tx_tfm_michael;
++ #endif
++
++ struct crypto_tfm *tfm_arc4;
++ struct crypto_tfm *tfm_michael;
++
++ /* scratch buffers for virt_to_page() (crypto API) */
++ u8 rx_hdr[16], tx_hdr[16];
++};
++
++static void * ieee80211_tkip_init(int key_idx)
++{
++ struct ieee80211_tkip_data *priv;
++
++ priv = kmalloc(sizeof(*priv), GFP_ATOMIC);
++ if (priv == NULL)
++ goto fail;
++ memset(priv, 0, sizeof(*priv));
++ priv->key_idx = key_idx;
++
++ #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
++ priv->tfm_arc4 = crypto_alloc_tfm("arc4", 0);
++ if (priv->tfm_arc4 == NULL) {
++ printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
++ "crypto API arc4\n");
++ goto fail;
++ }
++
++ priv->tfm_michael = crypto_alloc_tfm("michael_mic", 0);
++ if (priv->tfm_michael == NULL) {
++ printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
++ "crypto API michael_mic\n");
++ goto fail;
++ }
++
++ #else
++ priv->tx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
++ CRYPTO_ALG_ASYNC);
++ if (IS_ERR(priv->tx_tfm_arc4)) {
++ printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
++ "crypto API arc4\n");
++ priv->tx_tfm_arc4 = NULL;
++ goto fail;
++ }
++
++ priv->tx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
++ CRYPTO_ALG_ASYNC);
++ if (IS_ERR(priv->tx_tfm_michael)) {
++ printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
++ "crypto API michael_mic\n");
++ priv->tx_tfm_michael = NULL;
++ goto fail;
++ }
++
++ priv->rx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
++ CRYPTO_ALG_ASYNC);
++ if (IS_ERR(priv->rx_tfm_arc4)) {
++ printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
++ "crypto API arc4\n");
++ priv->rx_tfm_arc4 = NULL;
++ goto fail;
++ }
++
++ priv->rx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
++ CRYPTO_ALG_ASYNC);
++ if (IS_ERR(priv->rx_tfm_michael)) {
++ printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
++ "crypto API michael_mic\n");
++ priv->rx_tfm_michael = NULL;
++ goto fail;
++ }
++ #endif
++ return priv;
++
++fail:
++ if (priv) {
++ #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
++ if (priv->tfm_michael)
++ crypto_free_tfm(priv->tfm_michael);
++ if (priv->tfm_arc4)
++ crypto_free_tfm(priv->tfm_arc4);
++ #else
++ if (priv->tx_tfm_michael)
++ crypto_free_hash(priv->tx_tfm_michael);
++ if (priv->tx_tfm_arc4)
++ crypto_free_blkcipher(priv->tx_tfm_arc4);
++ if (priv->rx_tfm_michael)
++ crypto_free_hash(priv->rx_tfm_michael);
++ if (priv->rx_tfm_arc4)
++ crypto_free_blkcipher(priv->rx_tfm_arc4);
++ #endif
++ kfree(priv);
++ }
++
++ return NULL;
++}
++
++
++static void ieee80211_tkip_deinit(void *priv)
++{
++ struct ieee80211_tkip_data *_priv = priv;
++ #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
++ if (_priv && _priv->tfm_michael)
++ crypto_free_tfm(_priv->tfm_michael);
++ if (_priv && _priv->tfm_arc4)
++ crypto_free_tfm(_priv->tfm_arc4);
++ #else
++ if (_priv) {
++ if (_priv->tx_tfm_michael)
++ crypto_free_hash(_priv->tx_tfm_michael);
++ if (_priv->tx_tfm_arc4)
++ crypto_free_blkcipher(_priv->tx_tfm_arc4);
++ if (_priv->rx_tfm_michael)
++ crypto_free_hash(_priv->rx_tfm_michael);
++ if (_priv->rx_tfm_arc4)
++ crypto_free_blkcipher(_priv->rx_tfm_arc4);
++ }
++ #endif
++ kfree(priv);
++}
++
++
++static inline u16 RotR1(u16 val)
++{
++ return (val >> 1) | (val << 15);
++}
++
++
++static inline u8 Lo8(u16 val)
++{
++ return val & 0xff;
++}
++
++
++static inline u8 Hi8(u16 val)
++{
++ return val >> 8;
++}
++
++
++static inline u16 Lo16(u32 val)
++{
++ return val & 0xffff;
++}
++
++
++static inline u16 Hi16(u32 val)
++{
++ return val >> 16;
++}
++
++
++static inline u16 Mk16(u8 hi, u8 lo)
++{
++ return lo | (((u16) hi) << 8);
++}
++
++
++static inline u16 Mk16_le(u16 *v)
++{
++ return le16_to_cpu(*v);
++}
++
++
++static const u16 Sbox[256] =
++{
++ 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
++ 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
++ 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
++ 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
++ 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
++ 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
++ 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
++ 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
++ 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
++ 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
++ 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
++ 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
++ 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
++ 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
++ 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
++ 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
++ 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
++ 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
++ 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
++ 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
++ 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
++ 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
++ 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
++ 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
++ 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
++ 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
++ 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
++ 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
++ 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
++ 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
++ 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
++ 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
++};
++
++
++static inline u16 _S_(u16 v)
++{
++ u16 t = Sbox[Hi8(v)];
++ return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8));
++}
++
++#ifndef JOHN_TKIP
++#define PHASE1_LOOP_COUNT 8
++
++static void tkip_mixing_phase1(u16 *TTAK, const u8 *TK, const u8 *TA, u32 IV32)
++{
++ int i, j;
++
++ /* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */
++ TTAK[0] = Lo16(IV32);
++ TTAK[1] = Hi16(IV32);
++ TTAK[2] = Mk16(TA[1], TA[0]);
++ TTAK[3] = Mk16(TA[3], TA[2]);
++ TTAK[4] = Mk16(TA[5], TA[4]);
++
++ for (i = 0; i < PHASE1_LOOP_COUNT; i++) {
++ j = 2 * (i & 1);
++ TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j]));
++ TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j]));
++ TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j]));
++ TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j]));
++ TTAK[4] += _S_(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j])) + i;
++ }
++}
++
++
++static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK,
++ u16 IV16)
++{
++ /* Make temporary area overlap WEP seed so that the final copy can be
++ * avoided on little endian hosts. */
++ u16 *PPK = (u16 *) &WEPSeed[4];
++
++ /* Step 1 - make copy of TTAK and bring in TSC */
++ PPK[0] = TTAK[0];
++ PPK[1] = TTAK[1];
++ PPK[2] = TTAK[2];
++ PPK[3] = TTAK[3];
++ PPK[4] = TTAK[4];
++ PPK[5] = TTAK[4] + IV16;
++
++ /* Step 2 - 96-bit bijective mixing using S-box */
++ PPK[0] += _S_(PPK[5] ^ Mk16_le((u16 *) &TK[0]));
++ PPK[1] += _S_(PPK[0] ^ Mk16_le((u16 *) &TK[2]));
++ PPK[2] += _S_(PPK[1] ^ Mk16_le((u16 *) &TK[4]));
++ PPK[3] += _S_(PPK[2] ^ Mk16_le((u16 *) &TK[6]));
++ PPK[4] += _S_(PPK[3] ^ Mk16_le((u16 *) &TK[8]));
++ PPK[5] += _S_(PPK[4] ^ Mk16_le((u16 *) &TK[10]));
++
++ PPK[0] += RotR1(PPK[5] ^ Mk16_le((u16 *) &TK[12]));
++ PPK[1] += RotR1(PPK[0] ^ Mk16_le((u16 *) &TK[14]));
++ PPK[2] += RotR1(PPK[1]);
++ PPK[3] += RotR1(PPK[2]);
++ PPK[4] += RotR1(PPK[3]);
++ PPK[5] += RotR1(PPK[4]);
++
++ /* Step 3 - bring in last of TK bits, assign 24-bit WEP IV value
++ * WEPSeed[0..2] is transmitted as WEP IV */
++ WEPSeed[0] = Hi8(IV16);
++ WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F;
++ WEPSeed[2] = Lo8(IV16);
++ WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((u16 *) &TK[0])) >> 1);
++
++#ifdef __BIG_ENDIAN
++ {
++ int i;
++ for (i = 0; i < 6; i++)
++ PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8);
++ }
++#endif
++}
++#endif
++static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
++{
++ struct ieee80211_tkip_data *tkey = priv;
++ #if(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))
++ struct blkcipher_desc desc = {.tfm = tkey->tx_tfm_arc4};
++ #endif
++ int len;
++ u8 *pos;
++ struct ieee80211_hdr *hdr;
++#ifndef JOHN_TKIP
++ u8 rc4key[16],*icv;
++ u32 crc;
++ struct scatterlist sg;
++#endif
++ #if(LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,21))
++ int ret;
++ #endif
++
++ if (skb_headroom(skb) < 8 || skb_tailroom(skb) < 4 ||
++ skb->len < hdr_len)
++ return -1;
++
++ hdr = (struct ieee80211_hdr *) skb->data;
++#if 0
++printk("@@ tkey\n");
++printk("%x|", ((u32*)tkey->key)[0]);
++printk("%x|", ((u32*)tkey->key)[1]);
++printk("%x|", ((u32*)tkey->key)[2]);
++printk("%x|", ((u32*)tkey->key)[3]);
++printk("%x|", ((u32*)tkey->key)[4]);
++printk("%x|", ((u32*)tkey->key)[5]);
++printk("%x|", ((u32*)tkey->key)[6]);
++printk("%x\n", ((u32*)tkey->key)[7]);
++#endif
++
++#ifndef JOHN_TKIP
++ if (!tkey->tx_phase1_done) {
++ tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2,
++ tkey->tx_iv32);
++ tkey->tx_phase1_done = 1;
++ }
++ tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16);
++
++#else
++ tkey->tx_phase1_done = 1;
++#endif /*JOHN_TKIP*/
++
++ len = skb->len - hdr_len;
++ pos = skb_push(skb, 8);
++ memmove(pos, pos + 8, hdr_len);
++ pos += hdr_len;
++
++#ifdef JOHN_TKIP
++ *pos++ = Hi8(tkey->tx_iv16);
++ *pos++ = (Hi8(tkey->tx_iv16) | 0x20) & 0x7F;
++ *pos++ = Lo8(tkey->tx_iv16);
++#else
++ *pos++ = rc4key[0];
++ *pos++ = rc4key[1];
++ *pos++ = rc4key[2];
++#endif
++ *pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */;
++ *pos++ = tkey->tx_iv32 & 0xff;
++ *pos++ = (tkey->tx_iv32 >> 8) & 0xff;
++ *pos++ = (tkey->tx_iv32 >> 16) & 0xff;
++ *pos++ = (tkey->tx_iv32 >> 24) & 0xff;
++#ifndef JOHN_TKIP
++ icv = skb_put(skb, 4);
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
++ crc = ~crc32_le(~0, pos, len);
++#else
++ crc = ~ether_crc_le(len, pos);
++#endif
++ icv[0] = crc;
++ icv[1] = crc >> 8;
++ icv[2] = crc >> 16;
++ icv[3] = crc >> 24;
++ #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
++ crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16);
++ sg.page = virt_to_page(pos);
++ sg.offset = offset_in_page(pos);
++ sg.length = len + 4;
++ crypto_cipher_encrypt(tkey->tfm_arc4, &sg, &sg, len + 4);
++ #else
++ crypto_blkcipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
++ #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
++ sg.page = virt_to_page(pos);
++ sg.offset = offset_in_page(pos);
++ sg.length = len + 4;
++ #else
++ sg_init_one(&sg, pos, len + 4);
++ #endif
++ ret= crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
++ #endif
++#endif
++ tkey->tx_iv16++;
++ if (tkey->tx_iv16 == 0) {
++ tkey->tx_phase1_done = 0;
++ tkey->tx_iv32++;
++ }
++#ifndef JOHN_TKIP
++ #if(LINUX_VERSION_CODE <KERNEL_VERSION(2,6,21))
++ return 0;
++ #else
++ return ret;
++ #endif
++#else
++ return 0;
++#endif
++}
++
++static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
++{
++ struct ieee80211_tkip_data *tkey = priv;
++ #if(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))
++ struct blkcipher_desc desc = {.tfm = tkey->rx_tfm_arc4};
++ #endif
++ u8 keyidx, *pos;
++ u32 iv32;
++ u16 iv16;
++ struct ieee80211_hdr *hdr;
++#ifndef JOHN_TKIP
++ u8 icv[4];
++ u32 crc;
++ struct scatterlist sg;
++ u8 rc4key[16];
++ int plen;
++#endif
++ if (skb->len < hdr_len + 8 + 4)
++ return -1;
++
++ hdr = (struct ieee80211_hdr *) skb->data;
++ pos = skb->data + hdr_len;
++ keyidx = pos[3];
++ if (!(keyidx & (1 << 5))) {
++ if (net_ratelimit()) {
++ printk(KERN_DEBUG "TKIP: received packet without ExtIV"
++ " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2));
++ }
++ return -2;
++ }
++ keyidx >>= 6;
++ if (tkey->key_idx != keyidx) {
++ printk(KERN_DEBUG "TKIP: RX tkey->key_idx=%d frame "
++ "keyidx=%d priv=%p\n", tkey->key_idx, keyidx, priv);
++ return -6;
++ }
++ if (!tkey->key_set) {
++ if (net_ratelimit()) {
++ printk(KERN_DEBUG "TKIP: received packet from " MAC_FMT
++ " with keyid=%d that does not have a configured"
++ " key\n", MAC_ARG(hdr->addr2), keyidx);
++ }
++ return -3;
++ }
++ iv16 = (pos[0] << 8) | pos[2];
++ iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24);
++ pos += 8;
++#ifndef JOHN_TKIP
++#if 0
++ if (iv32 < tkey->rx_iv32 ||
++ (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) {
++ if (net_ratelimit()) {
++ printk(KERN_DEBUG "TKIP: replay detected: STA=" MAC_FMT
++ " previous TSC %08x%04x received TSC "
++ "%08x%04x\n", MAC_ARG(hdr->addr2),
++ tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
++ }
++ tkey->dot11RSNAStatsTKIPReplays++;
++ return -4;
++ }
++#endif
++ if (iv32 != tkey->rx_iv32 || !tkey->rx_phase1_done) {
++ tkip_mixing_phase1(tkey->rx_ttak, tkey->key, hdr->addr2, iv32);
++ tkey->rx_phase1_done = 1;
++ }
++ tkip_mixing_phase2(rc4key, tkey->key, tkey->rx_ttak, iv16);
++
++ plen = skb->len - hdr_len - 12;
++ #if(LINUX_VERSION_CODE <KERNEL_VERSION(2,6,21))
++ crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16);
++ sg.page = virt_to_page(pos);
++ sg.offset = offset_in_page(pos);
++ sg.length = plen + 4;
++ crypto_cipher_decrypt(tkey->tfm_arc4, &sg, &sg, plen + 4);
++ #else
++ crypto_blkcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
++ #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24))
++ sg.page = virt_to_page(pos);
++ sg.offset = offset_in_page(pos);
++ sg.length = plen + 4;
++ #else
++ sg_init_one(&sg, pos, plen + 4);
++ #endif
++ if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
++ if (net_ratelimit()) {
++ printk(KERN_DEBUG ": TKIP: failed to decrypt "
++ "received packet from " MAC_FMT "\n",
++ MAC_ARG(hdr->addr2));
++ }
++ return -7;
++ }
++ #endif
++
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
++ crc = ~crc32_le(~0, pos, plen);
++#else
++ crc = ~ether_crc_le(plen, pos);
++#endif
++ icv[0] = crc;
++ icv[1] = crc >> 8;
++ icv[2] = crc >> 16;
++ icv[3] = crc >> 24;
++ if (memcmp(icv, pos + plen, 4) != 0) {
++ if (iv32 != tkey->rx_iv32) {
++ /* Previously cached Phase1 result was already lost, so
++ * it needs to be recalculated for the next packet. */
++ tkey->rx_phase1_done = 0;
++ }
++ if (net_ratelimit()) {
++ printk(KERN_DEBUG "TKIP: ICV error detected: STA="
++ MAC_FMT "\n", MAC_ARG(hdr->addr2));
++ }
++ tkey->dot11RSNAStatsTKIPICVErrors++;
++ return -5;
++ }
++
++#endif /* JOHN_TKIP */
++
++ /* Update real counters only after Michael MIC verification has
++ * completed */
++ tkey->rx_iv32_new = iv32;
++ tkey->rx_iv16_new = iv16;
++
++ /* Remove IV and ICV */
++ memmove(skb->data + 8, skb->data, hdr_len);
++ skb_pull(skb, 8);
++ skb_trim(skb, skb->len - 4);
++
++//john's test
++#ifdef JOHN_DUMP
++if( ((u16*)skb->data)[0] & 0x4000){
++ printk("@@ rx decrypted skb->data");
++ int i;
++ for(i=0;i<skb->len;i++){
++ if( (i%24)==0 ) printk("\n");
++ printk("%2x ", ((u8*)skb->data)[i]);
++ }
++ printk("\n");
++}
++#endif /*JOHN_DUMP*/
++ return keyidx;
++}
++
++#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
++static int michael_mic(struct ieee80211_tkip_data *tkey, u8 *key, u8 *hdr,
++ u8 *data, size_t data_len, u8 *mic)
++{
++ struct scatterlist sg[2];
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
++ struct hash_desc desc;
++ int ret=0;
++#endif
++ if (tkey->tfm_michael == NULL) {
++ printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
++ return -1;
++ }
++ sg[0].page = virt_to_page(hdr);
++ sg[0].offset = offset_in_page(hdr);
++ sg[0].length = 16;
++
++ sg[1].page = virt_to_page(data);
++ sg[1].offset = offset_in_page(data);
++ sg[1].length = data_len;
++
++ //crypto_digest_init(tkey->tfm_michael);
++ //crypto_digest_setkey(tkey->tfm_michael, key, 8);
++ //crypto_digest_update(tkey->tfm_michael, sg, 2);
++ //crypto_digest_final(tkey->tfm_michael, mic);
++
++ //return 0;
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
++ crypto_digest_init(tkey->tfm_michael);
++ crypto_digest_setkey(tkey->tfm_michael, key, 8);
++ crypto_digest_update(tkey->tfm_michael, sg, 2);
++ crypto_digest_final(tkey->tfm_michael, mic);
++
++ return 0;
++#else
++if (crypto_hash_setkey(tkey->tfm_michael, key, 8))
++ return -1;
++
++// return 0;
++ desc.tfm = tkey->tfm_michael;
++ desc.flags = 0;
++ ret = crypto_hash_digest(&desc, sg, data_len + 16, mic);
++ return ret;
++#endif
++}
++#else
++static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
++ u8 * data, size_t data_len, u8 * mic)
++{
++ struct hash_desc desc;
++ struct scatterlist sg[2];
++
++ if (tfm_michael == NULL) {
++ printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
++ return -1;
++ }
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
++ sg[0].page = virt_to_page(hdr);
++ sg[0].offset = offset_in_page(hdr);
++ sg[0].length = 16;
++
++ sg[1].page = virt_to_page(data);
++ sg[1].offset = offset_in_page(data);
++ sg[1].length = data_len;
++#else
++ sg_init_table(sg, 2);
++ sg_set_buf(&sg[0], hdr, 16);
++ sg_set_buf(&sg[1], data, data_len);
++#endif
++ if (crypto_hash_setkey(tfm_michael, key, 8))
++ return -1;
++
++ desc.tfm = tfm_michael;
++ desc.flags = 0;
++ return crypto_hash_digest(&desc, sg, data_len + 16, mic);
++}
++#endif
++
++
++
++static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr)
++{
++ struct ieee80211_hdr *hdr11;
++
++ hdr11 = (struct ieee80211_hdr *) skb->data;
++ switch (le16_to_cpu(hdr11->frame_ctl) &
++ (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
++ case IEEE80211_FCTL_TODS:
++ memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
++ memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
++ break;
++ case IEEE80211_FCTL_FROMDS:
++ memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
++ memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */
++ break;
++ case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
++ memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
++ memcpy(hdr + ETH_ALEN, hdr11->addr4, ETH_ALEN); /* SA */
++ break;
++ case 0:
++ memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
++ memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
++ break;
++ }
++
++ hdr[12] = 0; /* priority */
++
++ hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */
++}
++
++
++static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv)
++{
++ struct ieee80211_tkip_data *tkey = priv;
++ u8 *pos;
++ struct ieee80211_hdr *hdr;
++
++ hdr = (struct ieee80211_hdr *) skb->data;
++
++ if (skb_tailroom(skb) < 8 || skb->len < hdr_len) {
++ printk(KERN_DEBUG "Invalid packet for Michael MIC add "
++ "(tailroom=%d hdr_len=%d skb->len=%d)\n",
++ skb_tailroom(skb), hdr_len, skb->len);
++ return -1;
++ }
++
++ michael_mic_hdr(skb, tkey->tx_hdr);
++
++ // { david, 2006.9.1
++ // fix the wpa process with wmm enabled.
++ if(IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) {
++ tkey->tx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
++ }
++ // }
++ pos = skb_put(skb, 8);
++ #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
++ if (michael_mic(tkey, &tkey->key[16], tkey->tx_hdr,
++ skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
++ #else
++ if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr,
++ skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
++ #endif
++ return -1;
++
++ return 0;
++}
++
++
++#if WIRELESS_EXT >= 18
++static void ieee80211_michael_mic_failure(struct net_device *dev,
++ struct ieee80211_hdr *hdr,
++ int keyidx)
++{
++ union iwreq_data wrqu;
++ struct iw_michaelmicfailure ev;
++
++ /* TODO: needed parameters: count, keyid, key type, TSC */
++ memset(&ev, 0, sizeof(ev));
++ ev.flags = keyidx & IW_MICFAILURE_KEY_ID;
++ if (hdr->addr1[0] & 0x01)
++ ev.flags |= IW_MICFAILURE_GROUP;
++ else
++ ev.flags |= IW_MICFAILURE_PAIRWISE;
++ ev.src_addr.sa_family = ARPHRD_ETHER;
++ memcpy(ev.src_addr.sa_data, hdr->addr2, ETH_ALEN);
++ memset(&wrqu, 0, sizeof(wrqu));
++ wrqu.data.length = sizeof(ev);
++ wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *) &ev);
++}
++#elif WIRELESS_EXT >= 15
++static void ieee80211_michael_mic_failure(struct net_device *dev,
++ struct ieee80211_hdr *hdr,
++ int keyidx)
++{
++ union iwreq_data wrqu;
++ char buf[128];
++
++ /* TODO: needed parameters: count, keyid, key type, TSC */
++ sprintf(buf, "MLME-MICHAELMICFAILURE.indication(keyid=%d %scast addr="
++ MAC_FMT ")", keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni",
++ MAC_ARG(hdr->addr2));
++ memset(&wrqu, 0, sizeof(wrqu));
++ wrqu.data.length = strlen(buf);
++ wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
++}
++#else /* WIRELESS_EXT >= 15 */
++static inline void ieee80211_michael_mic_failure(struct net_device *dev,
++ struct ieee80211_hdr *hdr,
++ int keyidx)
++{
++}
++#endif /* WIRELESS_EXT >= 15 */
++
++
++static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
++ int hdr_len, void *priv)
++{
++ struct ieee80211_tkip_data *tkey = priv;
++ u8 mic[8];
++ struct ieee80211_hdr *hdr;
++
++ hdr = (struct ieee80211_hdr *) skb->data;
++
++ if (!tkey->key_set)
++ return -1;
++
++ michael_mic_hdr(skb, tkey->rx_hdr);
++ // { david, 2006.9.1
++ // fix the wpa process with wmm enabled.
++ if(IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) {
++ tkey->rx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
++ }
++ // }
++ #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
++ if (michael_mic(tkey, &tkey->key[24], tkey->rx_hdr,
++ skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
++ #else
++ if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr,
++ skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
++ #endif
++ return -1;
++ if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
++ struct ieee80211_hdr *hdr;
++ hdr = (struct ieee80211_hdr *) skb->data;
++ printk(KERN_DEBUG "%s: Michael MIC verification failed for "
++ "MSDU from " MAC_FMT " keyidx=%d\n",
++ skb->dev ? skb->dev->name : "N/A", MAC_ARG(hdr->addr2),
++ keyidx);
++ if (skb->dev)
++ ieee80211_michael_mic_failure(skb->dev, hdr, keyidx);
++ tkey->dot11RSNAStatsTKIPLocalMICFailures++;
++ return -1;
++ }
++
++ /* Update TSC counters for RX now that the packet verification has
++ * completed. */
++ tkey->rx_iv32 = tkey->rx_iv32_new;
++ tkey->rx_iv16 = tkey->rx_iv16_new;
++
++ skb_trim(skb, skb->len - 8);
++
++ return 0;
++}
++
++
++static int ieee80211_tkip_set_key(void *key, int len, u8 *seq, void *priv)
++{
++ struct ieee80211_tkip_data *tkey = priv;
++ int keyidx;
++ #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
++ struct crypto_tfm *tfm = tkey->tfm_michael;
++ struct crypto_tfm *tfm2 = tkey->tfm_arc4;
++ #else
++ struct crypto_hash *tfm = tkey->tx_tfm_michael;
++ struct crypto_blkcipher *tfm2 = tkey->tx_tfm_arc4;
++ struct crypto_hash *tfm3 = tkey->rx_tfm_michael;
++ struct crypto_blkcipher *tfm4 = tkey->rx_tfm_arc4;
++ #endif
++
++ keyidx = tkey->key_idx;
++ memset(tkey, 0, sizeof(*tkey));
++ tkey->key_idx = keyidx;
++
++ #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
++ tkey->tfm_michael = tfm;
++ tkey->tfm_arc4 = tfm2;
++ #else
++ tkey->tx_tfm_michael = tfm;
++ tkey->tx_tfm_arc4 = tfm2;
++ tkey->rx_tfm_michael = tfm3;
++ tkey->rx_tfm_arc4 = tfm4;
++ #endif
++
++ if (len == TKIP_KEY_LEN) {
++ memcpy(tkey->key, key, TKIP_KEY_LEN);
++ tkey->key_set = 1;
++ tkey->tx_iv16 = 1; /* TSC is initialized to 1 */
++ if (seq) {
++ tkey->rx_iv32 = (seq[5] << 24) | (seq[4] << 16) |
++ (seq[3] << 8) | seq[2];
++ tkey->rx_iv16 = (seq[1] << 8) | seq[0];
++ }
++ } else if (len == 0)
++ tkey->key_set = 0;
++ else
++ return -1;
++
++ return 0;
++}
++
++
++static int ieee80211_tkip_get_key(void *key, int len, u8 *seq, void *priv)
++{
++ struct ieee80211_tkip_data *tkey = priv;
++
++ if (len < TKIP_KEY_LEN)
++ return -1;
++
++ if (!tkey->key_set)
++ return 0;
++ memcpy(key, tkey->key, TKIP_KEY_LEN);
++
++ if (seq) {
++ /* Return the sequence number of the last transmitted frame. */
++ u16 iv16 = tkey->tx_iv16;
++ u32 iv32 = tkey->tx_iv32;
++ if (iv16 == 0)
++ iv32--;
++ iv16--;
++ seq[0] = tkey->tx_iv16;
++ seq[1] = tkey->tx_iv16 >> 8;
++ seq[2] = tkey->tx_iv32;
++ seq[3] = tkey->tx_iv32 >> 8;
++ seq[4] = tkey->tx_iv32 >> 16;
++ seq[5] = tkey->tx_iv32 >> 24;
++ }
++
++ return TKIP_KEY_LEN;
++}
++
++
++static char * ieee80211_tkip_print_stats(char *p, void *priv)
++{
++ struct ieee80211_tkip_data *tkip = priv;
++ p += sprintf(p, "key[%d] alg=TKIP key_set=%d "
++ "tx_pn=%02x%02x%02x%02x%02x%02x "
++ "rx_pn=%02x%02x%02x%02x%02x%02x "
++ "replays=%d icv_errors=%d local_mic_failures=%d\n",
++ tkip->key_idx, tkip->key_set,
++ (tkip->tx_iv32 >> 24) & 0xff,
++ (tkip->tx_iv32 >> 16) & 0xff,
++ (tkip->tx_iv32 >> 8) & 0xff,
++ tkip->tx_iv32 & 0xff,
++ (tkip->tx_iv16 >> 8) & 0xff,
++ tkip->tx_iv16 & 0xff,
++ (tkip->rx_iv32 >> 24) & 0xff,
++ (tkip->rx_iv32 >> 16) & 0xff,
++ (tkip->rx_iv32 >> 8) & 0xff,
++ tkip->rx_iv32 & 0xff,
++ (tkip->rx_iv16 >> 8) & 0xff,
++ tkip->rx_iv16 & 0xff,
++ tkip->dot11RSNAStatsTKIPReplays,
++ tkip->dot11RSNAStatsTKIPICVErrors,
++ tkip->dot11RSNAStatsTKIPLocalMICFailures);
++ return p;
++}
++
++
++static struct ieee80211_crypto_ops ieee80211_crypt_tkip = {
++ .name = "TKIP",
++ .init = ieee80211_tkip_init,
++ .deinit = ieee80211_tkip_deinit,
++ .encrypt_mpdu = ieee80211_tkip_encrypt,
++ .decrypt_mpdu = ieee80211_tkip_decrypt,
++ .encrypt_msdu = ieee80211_michael_mic_add,
++ .decrypt_msdu = ieee80211_michael_mic_verify,
++ .set_key = ieee80211_tkip_set_key,
++ .get_key = ieee80211_tkip_get_key,
++ .print_stats = ieee80211_tkip_print_stats,
++ .extra_prefix_len = 4 + 4, /* IV + ExtIV */
++ .extra_postfix_len = 8 + 4, /* MIC + ICV */
++ .owner = THIS_MODULE,
++};
++
++
++int __init ieee80211_crypto_tkip_init(void)
++{
++ return ieee80211_register_crypto_ops(&ieee80211_crypt_tkip);
++}
++
++
++void __exit ieee80211_crypto_tkip_exit(void)
++{
++ ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip);
++}
++
++
++void ieee80211_tkip_null(void)
++{
++// printk("============>%s()\n", __FUNCTION__);
++ return;
++}
++
++#if 0
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
++EXPORT_SYMBOL(ieee80211_tkip_null);
++#else
++EXPORT_SYMBOL_NOVERS(ieee80211_tkip_null);
++#endif
++
++
++module_init(ieee80211_crypto_tkip_init);
++module_exit(ieee80211_crypto_tkip_exit);
++#endif
+diff --git a/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_wep.c b/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_wep.c
+new file mode 100644
+index 0000000..d97b637
+--- /dev/null
++++ b/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_wep.c
+@@ -0,0 +1,383 @@
++/*
++ * Host AP crypt: host-based WEP encryption implementation for Host AP driver
++ *
++ * Copyright (c) 2002-2004, Jouni Malinen <jkmaline@cc.hut.fi>
++ *
++ * 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. See README and COPYING for
++ * more details.
++ */
++
++//#include <linux/config.h>
++#include <linux/version.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/random.h>
++#include <linux/skbuff.h>
++#include <asm/string.h>
++
++#include "ieee80211.h"
++
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
++#include "rtl_crypto.h"
++#else
++#include <linux/crypto.h>
++#endif
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
++ #include <asm/scatterlist.h>
++#else
++ #include <linux/scatterlist.h>
++#endif
++//#include <asm/scatterlist.h>
++#include <linux/crc32.h>
++
++MODULE_AUTHOR("Jouni Malinen");
++MODULE_DESCRIPTION("Host AP crypt: WEP");
++MODULE_LICENSE("GPL");
++
++
++struct prism2_wep_data {
++ u32 iv;
++#define WEP_KEY_LEN 13
++ u8 key[WEP_KEY_LEN + 1];
++ u8 key_len;
++ u8 key_idx;
++ #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
++ struct crypto_tfm *tfm;
++ #else
++ struct crypto_blkcipher *tx_tfm;
++ struct crypto_blkcipher *rx_tfm;
++ #endif
++};
++
++
++static void * prism2_wep_init(int keyidx)
++{
++ struct prism2_wep_data *priv;
++
++ priv = kmalloc(sizeof(*priv), GFP_ATOMIC);
++ if (priv == NULL)
++ goto fail;
++ memset(priv, 0, sizeof(*priv));
++ priv->key_idx = keyidx;
++ #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
++ priv->tfm = crypto_alloc_tfm("arc4", 0);
++ if (priv->tfm == NULL) {
++ printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
++ "crypto API arc4\n");
++ goto fail;
++ }
++ #else
++ priv->tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
++ if (IS_ERR(priv->tx_tfm)) {
++ printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
++ "crypto API arc4\n");
++ priv->tx_tfm = NULL;
++ goto fail;
++ }
++ priv->rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
++ if (IS_ERR(priv->rx_tfm)) {
++ printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
++ "crypto API arc4\n");
++ priv->rx_tfm = NULL;
++ goto fail;
++ }
++ #endif
++
++ /* start WEP IV from a random value */
++ get_random_bytes(&priv->iv, 4);
++
++ return priv;
++
++fail:
++ #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
++ if (priv) {
++ if (priv->tfm)
++ crypto_free_tfm(priv->tfm);
++ kfree(priv);
++ }
++ #else
++ if (priv) {
++ if (priv->tx_tfm)
++ crypto_free_blkcipher(priv->tx_tfm);
++ if (priv->rx_tfm)
++ crypto_free_blkcipher(priv->rx_tfm);
++ kfree(priv);
++ }
++ #endif
++ return NULL;
++}
++
++
++static void prism2_wep_deinit(void *priv)
++{
++ struct prism2_wep_data *_priv = priv;
++ #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
++ if (_priv && _priv->tfm)
++ crypto_free_tfm(_priv->tfm);
++ #else
++ if (_priv) {
++ if (_priv->tx_tfm)
++ crypto_free_blkcipher(_priv->tx_tfm);
++ if (_priv->rx_tfm)
++ crypto_free_blkcipher(_priv->rx_tfm);
++ }
++ #endif
++ kfree(priv);
++}
++
++
++/* Perform WEP encryption on given skb that has at least 4 bytes of headroom
++ * for IV and 4 bytes of tailroom for ICV. Both IV and ICV will be transmitted,
++ * so the payload length increases with 8 bytes.
++ *
++ * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data))
++ */
++static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
++{
++ struct prism2_wep_data *wep = priv;
++#if(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))
++ struct blkcipher_desc desc = {.tfm = wep->tx_tfm};
++#endif
++ u32 klen, len;
++ u8 key[WEP_KEY_LEN + 3];
++ u8 *pos;
++#ifndef JOHN_HWSEC
++ u32 crc;
++ u8 *icv;
++ struct scatterlist sg;
++#endif
++ if (skb_headroom(skb) < 4 || skb_tailroom(skb) < 4 ||
++ skb->len < hdr_len)
++ return -1;
++
++ len = skb->len - hdr_len;
++ pos = skb_push(skb, 4);
++ memmove(pos, pos + 4, hdr_len);
++ pos += hdr_len;
++
++ klen = 3 + wep->key_len;
++
++ wep->iv++;
++
++ /* Fluhrer, Mantin, and Shamir have reported weaknesses in the key
++ * scheduling algorithm of RC4. At least IVs (KeyByte + 3, 0xff, N)
++ * can be used to speedup attacks, so avoid using them. */
++ if ((wep->iv & 0xff00) == 0xff00) {
++ u8 B = (wep->iv >> 16) & 0xff;
++ if (B >= 3 && B < klen)
++ wep->iv += 0x0100;
++ }
++
++ /* Prepend 24-bit IV to RC4 key and TX frame */
++ *pos++ = key[0] = (wep->iv >> 16) & 0xff;
++ *pos++ = key[1] = (wep->iv >> 8) & 0xff;
++ *pos++ = key[2] = wep->iv & 0xff;
++ *pos++ = wep->key_idx << 6;
++
++ /* Copy rest of the WEP key (the secret part) */
++ memcpy(key + 3, wep->key, wep->key_len);
++
++#ifndef JOHN_HWSEC
++ /* Append little-endian CRC32 and encrypt it to produce ICV */
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
++ crc = ~crc32_le(~0, pos, len);
++#else
++ crc = ~ether_crc_le(len, pos);
++#endif
++ icv = skb_put(skb, 4);
++ icv[0] = crc;
++ icv[1] = crc >> 8;
++ icv[2] = crc >> 16;
++ icv[3] = crc >> 24;
++
++ #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
++ crypto_cipher_setkey(wep->tfm, key, klen);
++ sg.page = virt_to_page(pos);
++ sg.offset = offset_in_page(pos);
++ sg.length = len + 4;
++ crypto_cipher_encrypt(wep->tfm, &sg, &sg, len + 4);
++
++ return 0;
++ #else
++ crypto_blkcipher_setkey(wep->tx_tfm, key, klen);
++ #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24))
++ sg.page = virt_to_page(pos);
++ sg.offset = offset_in_page(pos);
++ sg.length = len + 4;
++ #else
++ sg_init_one(&sg, pos, len + 4);
++ #endif
++ return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
++ #endif
++#endif /* JOHN_HWSEC */
++ return 0;
++}
++
++
++/* Perform WEP decryption on given buffer. Buffer includes whole WEP part of
++ * the frame: IV (4 bytes), encrypted payload (including SNAP header),
++ * ICV (4 bytes). len includes both IV and ICV.
++ *
++ * Returns 0 if frame was decrypted successfully and ICV was correct and -1 on
++ * failure. If frame is OK, IV and ICV will be removed.
++ */
++static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
++{
++ struct prism2_wep_data *wep = priv;
++ #if(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))
++ struct blkcipher_desc desc = {.tfm = wep->rx_tfm};
++ #endif
++ u32 klen, plen;
++ u8 key[WEP_KEY_LEN + 3];
++ u8 keyidx, *pos;
++#ifndef JOHN_HWSEC
++ u32 crc;
++ u8 icv[4];
++ struct scatterlist sg;
++#endif
++ if (skb->len < hdr_len + 8)
++ return -1;
++
++ pos = skb->data + hdr_len;
++ key[0] = *pos++;
++ key[1] = *pos++;
++ key[2] = *pos++;
++ keyidx = *pos++ >> 6;
++ if (keyidx != wep->key_idx)
++ return -1;
++
++ klen = 3 + wep->key_len;
++
++ /* Copy rest of the WEP key (the secret part) */
++ memcpy(key + 3, wep->key, wep->key_len);
++
++ /* Apply RC4 to data and compute CRC32 over decrypted data */
++ plen = skb->len - hdr_len - 8;
++#ifndef JOHN_HWSEC
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
++ crypto_cipher_setkey(wep->tfm, key, klen);
++ sg.page = virt_to_page(pos);
++ sg.offset = offset_in_page(pos);
++ sg.length = plen + 4;
++ crypto_cipher_decrypt(wep->tfm, &sg, &sg, plen + 4);
++#else
++ crypto_blkcipher_setkey(wep->rx_tfm, key, klen);
++ #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
++ sg.page = virt_to_page(pos);
++ sg.offset = offset_in_page(pos);
++ sg.length = plen + 4;
++ #else
++ sg_init_one(&sg, pos, plen + 4);
++ #endif
++ if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4))
++ return -7;
++#endif
++
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
++ crc = ~crc32_le(~0, pos, plen);
++#else
++ crc = ~ether_crc_le(plen, pos);
++#endif
++ icv[0] = crc;
++ icv[1] = crc >> 8;
++ icv[2] = crc >> 16;
++ icv[3] = crc >> 24;
++
++ if (memcmp(icv, pos + plen, 4) != 0) {
++ /* ICV mismatch - drop frame */
++ return -2;
++ }
++#endif /* JOHN_HWSEC */
++
++ /* Remove IV and ICV */
++ memmove(skb->data + 4, skb->data, hdr_len);
++ skb_pull(skb, 4);
++ skb_trim(skb, skb->len - 4);
++ return 0;
++}
++
++
++static int prism2_wep_set_key(void *key, int len, u8 *seq, void *priv)
++{
++ struct prism2_wep_data *wep = priv;
++
++ if (len < 0 || len > WEP_KEY_LEN)
++ return -1;
++
++ memcpy(wep->key, key, len);
++ wep->key_len = len;
++
++ return 0;
++}
++
++
++static int prism2_wep_get_key(void *key, int len, u8 *seq, void *priv)
++{
++ struct prism2_wep_data *wep = priv;
++
++ if (len < wep->key_len)
++ return -1;
++
++ memcpy(key, wep->key, wep->key_len);
++
++ return wep->key_len;
++}
++
++
++static char * prism2_wep_print_stats(char *p, void *priv)
++{
++ struct prism2_wep_data *wep = priv;
++ p += sprintf(p, "key[%d] alg=WEP len=%d\n",
++ wep->key_idx, wep->key_len);
++ return p;
++}
++
++
++static struct ieee80211_crypto_ops ieee80211_crypt_wep = {
++ .name = "WEP",
++ .init = prism2_wep_init,
++ .deinit = prism2_wep_deinit,
++ .encrypt_mpdu = prism2_wep_encrypt,
++ .decrypt_mpdu = prism2_wep_decrypt,
++ .encrypt_msdu = NULL,
++ .decrypt_msdu = NULL,
++ .set_key = prism2_wep_set_key,
++ .get_key = prism2_wep_get_key,
++ .print_stats = prism2_wep_print_stats,
++ .extra_prefix_len = 4, /* IV */
++ .extra_postfix_len = 4, /* ICV */
++ .owner = THIS_MODULE,
++};
++
++
++int __init ieee80211_crypto_wep_init(void)
++{
++ return ieee80211_register_crypto_ops(&ieee80211_crypt_wep);
++}
++
++
++void __exit ieee80211_crypto_wep_exit(void)
++{
++ ieee80211_unregister_crypto_ops(&ieee80211_crypt_wep);
++}
++
++
++void ieee80211_wep_null(void)
++{
++// printk("============>%s()\n", __FUNCTION__);
++ return;
++}
++#if 0
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
++EXPORT_SYMBOL(ieee80211_wep_null);
++#else
++EXPORT_SYMBOL_NOVERS(ieee80211_wep_null);
++#endif
++
++module_init(ieee80211_crypto_wep_init);
++module_exit(ieee80211_crypto_wep_exit);
++#endif
+diff --git a/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_module.c b/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_module.c
+new file mode 100644
+index 0000000..b85f6dd
+--- /dev/null
++++ b/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_module.c
+@@ -0,0 +1,385 @@
++/*******************************************************************************
++
++ Copyright(c) 2004 Intel Corporation. All rights reserved.
++
++ Portions of this file are based on the WEP enablement code provided by the
++ Host AP project hostap-drivers v0.1.3
++ Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
++ <jkmaline@cc.hut.fi>
++ Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
++
++ This program is free software; you can redistribute it and/or modify it
++ under the terms of version 2 of the GNU General Public License as
++ published by the Free Software Foundation.
++
++ 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 full GNU General Public License is included in this distribution in the
++ file called LICENSE.
++
++ Contact Information:
++ James P. Ketrenos <ipw2100-admin@linux.intel.com>
++ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
++
++*******************************************************************************/
++
++#include <linux/compiler.h>
++//#include <linux/config.h>
++#include <linux/errno.h>
++#include <linux/if_arp.h>
++#include <linux/in6.h>
++#include <linux/in.h>
++#include <linux/ip.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/netdevice.h>
++#include <linux/pci.h>
++#include <linux/proc_fs.h>
++#include <linux/skbuff.h>
++#include <linux/slab.h>
++#include <linux/tcp.h>
++#include <linux/types.h>
++#include <linux/version.h>
++#include <linux/wireless.h>
++#include <linux/etherdevice.h>
++#include <asm/uaccess.h>
++#include <net/arp.h>
++
++#include "ieee80211.h"
++
++MODULE_DESCRIPTION("802.11 data/management/control stack");
++MODULE_AUTHOR("Copyright (C) 2004 Intel Corporation <jketreno@linux.intel.com>");
++MODULE_LICENSE("GPL");
++
++#define DRV_NAME "ieee80211"
++
++static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee)
++{
++ if (ieee->networks)
++ return 0;
++
++ ieee->networks = kmalloc(
++ MAX_NETWORK_COUNT * sizeof(struct ieee80211_network),
++ GFP_KERNEL);
++ if (!ieee->networks) {
++ printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
++ ieee->dev->name);
++ return -ENOMEM;
++ }
++
++ memset(ieee->networks, 0,
++ MAX_NETWORK_COUNT * sizeof(struct ieee80211_network));
++
++ return 0;
++}
++
++static inline void ieee80211_networks_free(struct ieee80211_device *ieee)
++{
++ if (!ieee->networks)
++ return;
++ kfree(ieee->networks);
++ ieee->networks = NULL;
++}
++
++static inline void ieee80211_networks_initialize(struct ieee80211_device *ieee)
++{
++ int i;
++
++ INIT_LIST_HEAD(&ieee->network_free_list);
++ INIT_LIST_HEAD(&ieee->network_list);
++ for (i = 0; i < MAX_NETWORK_COUNT; i++)
++ list_add_tail(&ieee->networks[i].list, &ieee->network_free_list);
++}
++
++
++struct net_device *alloc_ieee80211(int sizeof_priv)
++{
++ struct ieee80211_device *ieee;
++ struct net_device *dev;
++ int i,err;
++
++ IEEE80211_DEBUG_INFO("Initializing...\n");
++
++ dev = alloc_etherdev(sizeof(struct ieee80211_device) + sizeof_priv);
++ if (!dev) {
++ IEEE80211_ERROR("Unable to network device.\n");
++ goto failed;
++ }
++
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
++ ieee = netdev_priv(dev);
++#else
++ ieee = (struct ieee80211_device *)dev->priv;
++#endif
++
++ ieee->dev = dev;
++
++ err = ieee80211_networks_allocate(ieee);
++ if (err) {
++ IEEE80211_ERROR("Unable to allocate beacon storage: %d\n",
++ err);
++ goto failed;
++ }
++ ieee80211_networks_initialize(ieee);
++
++ /* Default fragmentation threshold is maximum payload size */
++ ieee->fts = DEFAULT_FTS;
++ ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
++ ieee->open_wep = 1;
++
++ /* Default to enabling full open WEP with host based encrypt/decrypt */
++ ieee->host_encrypt = 1;
++ ieee->host_decrypt = 1;
++ ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
++
++ INIT_LIST_HEAD(&ieee->crypt_deinit_list);
++ init_timer(&ieee->crypt_deinit_timer);
++ ieee->crypt_deinit_timer.data = (unsigned long)ieee;
++ ieee->crypt_deinit_timer.function = ieee80211_crypt_deinit_handler;
++
++ spin_lock_init(&ieee->lock);
++ spin_lock_init(&ieee->wpax_suitlist_lock);
++
++ ieee->wpax_type_set = 0;
++ ieee->wpa_enabled = 0;
++ ieee->tkip_countermeasures = 0;
++ ieee->drop_unencrypted = 0;
++ ieee->privacy_invoked = 0;
++ ieee->ieee802_1x = 1;
++ ieee->raw_tx = 0;
++#ifdef _RTL8187_EXT_PATCH_
++ for (i=0; i<MAX_MP; i++)
++ {
++ ieee->cryptlist[i] = (struct ieee80211_crypt_data_list*) kmalloc(sizeof(struct ieee80211_crypt_data_list), GFP_KERNEL);
++ if (NULL == ieee->cryptlist[i])
++ {
++ printk("error kmalloc cryptlist\n");
++ goto failed;
++ }
++ memset(ieee->cryptlist[i], 0, sizeof(struct ieee80211_crypt_data_list));
++
++ }
++#endif
++ ieee80211_softmac_init(ieee);
++
++ for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++)
++ INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]);
++
++ for (i = 0; i < IEEE_MESH_MAC_HASH_SIZE; i++)
++ INIT_LIST_HEAD(&ieee->mesh_mac_hash[i]);
++
++ for (i = 0; i < 17; i++) {
++ ieee->last_rxseq_num[i] = -1;
++ ieee->last_rxfrag_num[i] = -1;
++ ieee->last_packet_time[i] = 0;
++ }
++#if 1 //added these to autoload encryption module. WB
++ ieee80211_tkip_null();
++ ieee80211_wep_null();
++ ieee80211_ccmp_null();
++#endif
++ return dev;
++
++ failed:
++#ifdef _RTL8187_EXT_PATCH_
++ for (i=0; i<MAX_MP; i++)
++ {
++ if (ieee->cryptlist[i]==NULL){
++ continue;
++ }
++ kfree(ieee->cryptlist[i]);
++ ieee->cryptlist[i] = NULL;
++
++ }
++#endif
++ if (dev)
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
++ free_netdev(dev);
++#else
++ kfree(dev);
++#endif
++ return NULL;
++}
++
++
++void free_ieee80211(struct net_device *dev)
++{
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
++ struct ieee80211_device *ieee = netdev_priv(dev);
++#else
++ struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv;
++#endif
++ int i;//,j;
++ struct list_head *p, *q;
++
++
++ ieee80211_softmac_free(ieee);
++ del_timer_sync(&ieee->crypt_deinit_timer);
++ ieee80211_crypt_deinit_entries(ieee, 1);
++#if 1
++ ieee80211_tkip_null();
++ ieee80211_wep_null();
++ ieee80211_ccmp_null();
++#endif
++ for (i = 0; i < WEP_KEYS; i++) {
++#ifdef _RTL8187_EXT_PATCH_
++{
++ // int j;
++ for (j=0;j<MAX_MP; j++){
++ if (ieee->cryptlist[j] == NULL)
++ continue;
++ struct ieee80211_crypt_data *crypt = ieee->cryptlist[j]->crypt[i];
++#else
++ struct ieee80211_crypt_data *crypt = ieee->crypt[i];
++#endif
++ if (crypt) {
++ if (crypt->ops) {
++ crypt->ops->deinit(crypt->priv);
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
++ module_put(crypt->ops->owner);
++#else
++ __MOD_DEC_USE_COUNT(crypt->ops->owner);
++#endif
++ }
++ kfree(crypt);
++#ifdef _RTL8187_EXT_PATCH_
++ ieee->cryptlist[j]->crypt[i] = NULL;
++ //kfree(ieee->cryptlist[j]);
++ //ieee->cryptlist[j] = NULL;
++#else
++ ieee->crypt[i] = NULL;
++#endif
++ }
++#ifdef _RTL8187_EXT_PATCH_
++ }
++ }
++#endif
++}
++#ifdef _RTL8187_EXT_PATCH_
++for(j=0;j<MAX_MP;j++)
++ {
++ if (ieee->cryptlist[j])
++ {
++ kfree(ieee->cryptlist[j]);
++ ieee->cryptlist[j] = NULL;
++ }
++ }
++
++ for (i = 0; i < IEEE_MESH_MAC_HASH_SIZE; i++) {
++ list_for_each_safe(p, q, &ieee->mesh_mac_hash[i]) {
++ kfree(list_entry(p, struct ieee_mesh_seq, list));
++ list_del(p);
++ }
++ }
++#endif
++ ieee80211_networks_free(ieee);
++
++ for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++) {
++ list_for_each_safe(p, q, &ieee->ibss_mac_hash[i]) {
++ kfree(list_entry(p, struct ieee_ibss_seq, list));
++ list_del(p);
++ }
++ }
++
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
++ free_netdev(dev);
++#else
++ kfree(dev);
++#endif
++}
++
++#ifdef CONFIG_IEEE80211_DEBUG
++
++static int debug = 0;
++u32 ieee80211_debug_level = 0;
++struct proc_dir_entry *ieee80211_proc = NULL;
++
++static int show_debug_level(char *page, char **start, off_t offset,
++ int count, int *eof, void *data)
++{
++ return snprintf(page, count, "0x%08X\n", ieee80211_debug_level);
++}
++
++static int store_debug_level(struct file *file, const char *buffer,
++ unsigned long count, void *data)
++{
++ char buf[] = "0x00000000";
++ unsigned long len = min(sizeof(buf) - 1, (u32)count);
++ char *p = (char *)buf;
++ unsigned long val;
++
++ if (copy_from_user(buf, buffer, len))
++ return count;
++ buf[len] = 0;
++ if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
++ p++;
++ if (p[0] == 'x' || p[0] == 'X')
++ p++;
++ val = simple_strtoul(p, &p, 16);
++ } else
++ val = simple_strtoul(p, &p, 10);
++ if (p == buf)
++ printk(KERN_INFO DRV_NAME
++ ": %s is not in hex or decimal form.\n", buf);
++ else
++ ieee80211_debug_level = val;
++
++ return strnlen(buf, count);
++}
++
++static int __init ieee80211_init(void)
++{
++ struct proc_dir_entry *e;
++
++ ieee80211_debug_level = debug;
++ ieee80211_proc = create_proc_entry(DRV_NAME, S_IFDIR, proc_net);
++ if (ieee80211_proc == NULL) {
++ IEEE80211_ERROR("Unable to create " DRV_NAME
++ " proc directory\n");
++ return -EIO;
++ }
++ e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
++ ieee80211_proc);
++ if (!e) {
++ remove_proc_entry(DRV_NAME, proc_net);
++ ieee80211_proc = NULL;
++ return -EIO;
++ }
++ e->read_proc = show_debug_level;
++ e->write_proc = store_debug_level;
++ e->data = NULL;
++
++ return 0;
++}
++
++static void __exit ieee80211_exit(void)
++{
++ if (ieee80211_proc) {
++ remove_proc_entry("debug_level", ieee80211_proc);
++ remove_proc_entry(DRV_NAME, proc_net);
++ ieee80211_proc = NULL;
++ }
++}
++
++#include <linux/moduleparam.h>
++module_param(debug, int, 0444);
++MODULE_PARM_DESC(debug, "debug output mask");
++
++
++module_exit(ieee80211_exit);
++module_init(ieee80211_init);
++#endif
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
++EXPORT_SYMBOL(alloc_ieee80211);
++EXPORT_SYMBOL(free_ieee80211);
++#else
++EXPORT_SYMBOL_NOVERS(alloc_ieee80211);
++EXPORT_SYMBOL_NOVERS(free_ieee80211);
++#endif
+diff --git a/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_rx.c b/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_rx.c
+new file mode 100644
+index 0000000..769203c
+--- /dev/null
++++ b/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_rx.c
+@@ -0,0 +1,2074 @@
++/*
++ * Original code based Host AP (software wireless LAN access point) driver
++ * for Intersil Prism2/2.5/3 - hostap.o module, common routines
++ *
++ * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
++ * <jkmaline@cc.hut.fi>
++ * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
++ * Copyright (c) 2004, Intel Corporation
++ *
++ * 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. See README and COPYING for
++ * more details.
++ ******************************************************************************
++
++ Few modifications for Realtek's Wi-Fi drivers by
++ Andrea Merello <andreamrl@tiscali.it>
++
++ A special thanks goes to Realtek for their support !
++
++******************************************************************************/
++
++
++#include <linux/compiler.h>
++//#include <linux/config.h>
++#include <linux/errno.h>
++#include <linux/if_arp.h>
++#include <linux/in6.h>
++#include <linux/in.h>
++#include <linux/ip.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/netdevice.h>
++#include <linux/pci.h>
++#include <linux/proc_fs.h>
++#include <linux/skbuff.h>
++#include <linux/slab.h>
++#include <linux/tcp.h>
++#include <linux/types.h>
++#include <linux/version.h>
++#include <linux/wireless.h>
++#include <linux/etherdevice.h>
++#include <asm/uaccess.h>
++#include <linux/ctype.h>
++
++#include "ieee80211.h"
++#ifdef ENABLE_DOT11D
++#include "dot11d.h"
++#endif
++
++static inline void ieee80211_monitor_rx(struct ieee80211_device *ieee,
++ struct sk_buff *skb,
++ struct ieee80211_rx_stats *rx_stats)
++{
++ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
++ u16 fc = le16_to_cpu(hdr->frame_ctl);
++
++ skb->dev = ieee->dev;
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
++ skb_reset_mac_header(skb);
++#else
++ skb->mac.raw = skb->data;
++#endif
++
++ //skb->mac.raw = skb->data;
++ skb_pull(skb, ieee80211_get_hdrlen(fc));
++ skb->pkt_type = PACKET_OTHERHOST;
++ skb->protocol = __constant_htons(ETH_P_80211_RAW);
++ memset(skb->cb, 0, sizeof(skb->cb));
++ netif_rx(skb);
++}
++
++
++/* Called only as a tasklet (software IRQ) */
++static struct ieee80211_frag_entry *
++ieee80211_frag_cache_find(struct ieee80211_device *ieee, unsigned int seq,
++ unsigned int frag, u8 tid,u8 *src, u8 *dst)
++{
++ struct ieee80211_frag_entry *entry;
++ int i;
++
++ for (i = 0; i < IEEE80211_FRAG_CACHE_LEN; i++) {
++ entry = &ieee->frag_cache[tid][i];
++ if (entry->skb != NULL &&
++ time_after(jiffies, entry->first_frag_time + 2 * HZ)) {
++ IEEE80211_DEBUG_FRAG(
++ "expiring fragment cache entry "
++ "seq=%u last_frag=%u\n",
++ entry->seq, entry->last_frag);
++ dev_kfree_skb_any(entry->skb);
++ entry->skb = NULL;
++ }
++
++ if (entry->skb != NULL && entry->seq == seq &&
++ (entry->last_frag + 1 == frag || frag == -1) &&
++ memcmp(entry->src_addr, src, ETH_ALEN) == 0 &&
++ memcmp(entry->dst_addr, dst, ETH_ALEN) == 0)
++ return entry;
++ }
++
++ return NULL;
++}
++
++/* Called only as a tasklet (software IRQ) */
++static struct sk_buff *
++ieee80211_frag_cache_get(struct ieee80211_device *ieee,
++ struct ieee80211_hdr *hdr)
++{
++ struct sk_buff *skb = NULL;
++ u16 fc = le16_to_cpu(hdr->frame_ctl);
++ u16 sc = le16_to_cpu(hdr->seq_ctl);
++ unsigned int frag = WLAN_GET_SEQ_FRAG(sc);
++ unsigned int seq = WLAN_GET_SEQ_SEQ(sc);
++ struct ieee80211_frag_entry *entry;
++ struct ieee80211_hdr_3addr_QOS *hdr_3addr_QoS;
++ struct ieee80211_hdr_QOS *hdr_4addr_QoS;
++ u8 tid;
++
++#ifdef _RTL8187_EXT_PATCH_
++ if(ieee->iw_mode == ieee->iw_ext_mode)
++ {
++ tid = (hdr->addr2[ETH_ALEN-2] ^ hdr->addr2[ETH_ALEN-1]) & IEEE80211_QOS_TID;
++ }
++ else
++#endif
++ if (((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) {
++ hdr_4addr_QoS = (struct ieee80211_hdr_QOS *)hdr;
++ tid = le16_to_cpu(hdr_4addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
++ tid = UP2AC(tid);
++ tid ++;
++ } else if (IEEE80211_QOS_HAS_SEQ(fc)) {
++ hdr_3addr_QoS = (struct ieee80211_hdr_3addr_QOS *)hdr;
++ tid = le16_to_cpu(hdr_3addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
++ tid = UP2AC(tid);
++ tid ++;
++ } else {
++ tid = 0;
++ }
++
++ if (frag == 0) {
++ /* Reserve enough space to fit maximum frame length */
++ skb = dev_alloc_skb(ieee->dev->mtu +
++ sizeof(struct ieee80211_hdr) +
++ 8 /* LLC */ +
++ 2 /* alignment */ +
++ 8 /* WEP */ +
++ ETH_ALEN /* WDS */ +
++ (IEEE80211_QOS_HAS_SEQ(fc)?2:0) /* QOS Control */);
++ if (skb == NULL)
++ return NULL;
++
++ entry = &ieee->frag_cache[tid][ieee->frag_next_idx[tid]];
++ ieee->frag_next_idx[tid]++;
++ if (ieee->frag_next_idx[tid] >= IEEE80211_FRAG_CACHE_LEN)
++ ieee->frag_next_idx[tid] = 0;
++
++ if (entry->skb != NULL)
++ dev_kfree_skb_any(entry->skb);
++
++ entry->first_frag_time = jiffies;
++ entry->seq = seq;
++ entry->last_frag = frag;
++ entry->skb = skb;
++ memcpy(entry->src_addr, hdr->addr2, ETH_ALEN);
++ memcpy(entry->dst_addr, hdr->addr1, ETH_ALEN);
++ } else {
++ /* received a fragment of a frame for which the head fragment
++ * should have already been received */
++ entry = ieee80211_frag_cache_find(ieee, seq, frag, tid,hdr->addr2,
++ hdr->addr1);
++ if (entry != NULL) {
++ entry->last_frag = frag;
++ skb = entry->skb;
++ }
++ }
++
++ return skb;
++}
++
++
++/* Called only as a tasklet (software IRQ) */
++static int ieee80211_frag_cache_invalidate(struct ieee80211_device *ieee,
++ struct ieee80211_hdr *hdr)
++{
++ u16 fc = le16_to_cpu(hdr->frame_ctl);
++ u16 sc = le16_to_cpu(hdr->seq_ctl);
++ unsigned int seq = WLAN_GET_SEQ_SEQ(sc);
++ struct ieee80211_frag_entry *entry;
++ struct ieee80211_hdr_3addr_QOS *hdr_3addr_QoS;
++ struct ieee80211_hdr_QOS *hdr_4addr_QoS;
++ u8 tid;
++
++#ifdef _RTL8187_EXT_PATCH_
++ if(ieee->iw_mode == ieee->iw_ext_mode)
++ {
++ tid = (hdr->addr2[ETH_ALEN-2] ^ hdr->addr2[ETH_ALEN-1]) & IEEE80211_QOS_TID;
++ }
++ else
++#endif
++ if(((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) {
++ hdr_4addr_QoS = (struct ieee80211_hdr_QOS *)hdr;
++ tid = le16_to_cpu(hdr_4addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
++ tid = UP2AC(tid);
++ tid ++;
++ } else if (IEEE80211_QOS_HAS_SEQ(fc)) {
++ hdr_3addr_QoS = (struct ieee80211_hdr_3addr_QOS *)hdr;
++ tid = le16_to_cpu(hdr_3addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
++ tid = UP2AC(tid);
++ tid ++;
++ } else {
++ tid = 0;
++ }
++
++ entry = ieee80211_frag_cache_find(ieee, seq, -1, tid,hdr->addr2,
++ hdr->addr1);
++
++ if (entry == NULL) {
++ IEEE80211_DEBUG_FRAG(
++ "could not invalidate fragment cache "
++ "entry (seq=%u)\n", seq);
++ return -1;
++ }
++
++ entry->skb = NULL;
++ return 0;
++}
++
++
++
++/* ieee80211_rx_frame_mgtmt
++ *
++ * Responsible for handling management control frames
++ *
++ * Called by ieee80211_rx */
++static inline int
++ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb,
++ struct ieee80211_rx_stats *rx_stats, u16 type,
++ u16 stype)
++{
++ /* On the struct stats definition there is written that
++ * this is not mandatory.... but seems that the probe
++ * response parser uses it
++ */
++ struct ieee80211_hdr * hdr = (struct ieee80211_hdr*)skb->data;
++ rx_stats->len = skb->len;
++ ieee80211_rx_mgt(ieee,(struct ieee80211_hdr *)skb->data,rx_stats);
++
++ if ((ieee->state == IEEE80211_LINKED) && (memcmp(hdr->addr3, ieee->current_network.bssid, ETH_ALEN)))
++ {
++ dev_kfree_skb_any(skb);
++ return 0;
++ }
++
++ ieee80211_rx_frame_softmac(ieee, skb, rx_stats, type, stype);
++
++ dev_kfree_skb_any(skb);
++
++ return 0;
++
++ #ifdef NOT_YET
++ if (ieee->iw_mode == IW_MODE_MASTER) {
++ printk(KERN_DEBUG "%s: Master mode not yet suppported.\n",
++ ieee->dev->name);
++ return 0;
++/*
++ hostap_update_sta_ps(ieee, (struct hostap_ieee80211_hdr *)
++ skb->data);*/
++ }
++
++ if (ieee->hostapd && type == IEEE80211_TYPE_MGMT) {
++ if (stype == WLAN_FC_STYPE_BEACON &&
++ ieee->iw_mode == IW_MODE_MASTER) {
++ struct sk_buff *skb2;
++ /* Process beacon frames also in kernel driver to
++ * update STA(AP) table statistics */
++ skb2 = skb_clone(skb, GFP_ATOMIC);
++ if (skb2)
++ hostap_rx(skb2->dev, skb2, rx_stats);
++ }
++
++ /* send management frames to the user space daemon for
++ * processing */
++ ieee->apdevstats.rx_packets++;
++ ieee->apdevstats.rx_bytes += skb->len;
++ prism2_rx_80211(ieee->apdev, skb, rx_stats, PRISM2_RX_MGMT);
++ return 0;
++ }
++
++ if (ieee->iw_mode == IW_MODE_MASTER) {
++ if (type != WLAN_FC_TYPE_MGMT && type != WLAN_FC_TYPE_CTRL) {
++ printk(KERN_DEBUG "%s: unknown management frame "
++ "(type=0x%02x, stype=0x%02x) dropped\n",
++ skb->dev->name, type, stype);
++ return -1;
++ }
++
++ hostap_rx(skb->dev, skb, rx_stats);
++ return 0;
++ }
++
++ printk(KERN_DEBUG "%s: hostap_rx_frame_mgmt: management frame "
++ "received in non-Host AP mode\n", skb->dev->name);
++ return -1;
++ #endif
++}
++
++
++
++/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
++/* Ethernet-II snap header (RFC1042 for most EtherTypes) */
++static unsigned char rfc1042_header[] =
++{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
++/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
++static unsigned char bridge_tunnel_header[] =
++{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
++/* No encapsulation header if EtherType < 0x600 (=length) */
++
++/* Called by ieee80211_rx_frame_decrypt */
++static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee,
++ struct sk_buff *skb, size_t hdrlen)
++{
++ struct net_device *dev = ieee->dev;
++ u16 fc, ethertype;
++ struct ieee80211_hdr *hdr;
++ u8 *pos;
++
++ if (skb->len < 24)
++ return 0;
++
++ hdr = (struct ieee80211_hdr *) skb->data;
++ fc = le16_to_cpu(hdr->frame_ctl);
++
++ /* check that the frame is unicast frame to us */
++ if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
++ IEEE80211_FCTL_TODS &&
++ memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0 &&
++ memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) {
++ /* ToDS frame with own addr BSSID and DA */
++ } else if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
++ IEEE80211_FCTL_FROMDS &&
++ memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) {
++ /* FromDS frame with own addr as DA */
++ } else
++ return 0;
++
++ if (skb->len < 24 + 8)
++ return 0;
++
++ /* check for port access entity Ethernet type */
++// pos = skb->data + 24;
++ pos = skb->data + hdrlen;
++ ethertype = (pos[6] << 8) | pos[7];
++ if (ethertype == ETH_P_PAE)
++ return 1;
++
++ return 0;
++}
++
++/* Called only as a tasklet (software IRQ), by ieee80211_rx */
++static inline int
++ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb,
++ struct ieee80211_crypt_data *crypt)
++{
++ struct ieee80211_hdr *hdr;
++ int res, hdrlen;
++
++ if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
++ return 0;
++
++ hdr = (struct ieee80211_hdr *) skb->data;
++#ifdef _RTL8187_EXT_PATCH_
++ if((ieee->iw_mode == ieee->iw_ext_mode) && (ieee->ext_patch_ieee80211_rx_frame_get_hdrlen))
++ {
++ hdrlen = ieee->ext_patch_ieee80211_rx_frame_get_hdrlen(ieee, skb);
++ }
++ else
++#endif
++ hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
++
++#ifdef CONFIG_IEEE80211_CRYPT_TKIP
++ if (ieee->tkip_countermeasures &&
++ strcmp(crypt->ops->name, "TKIP") == 0) {
++ if (net_ratelimit()) {
++ printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
++ "received packet from " MAC_FMT "\n",
++ ieee->dev->name, MAC_ARG(hdr->addr2));
++ }
++ return -1;
++ }
++#endif
++
++ atomic_inc(&crypt->refcnt);
++ res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv);
++ atomic_dec(&crypt->refcnt);
++ if (res < 0) {
++ IEEE80211_DEBUG_DROP(
++ "decryption failed (SA=" MAC_FMT
++ ") res=%d\n", MAC_ARG(hdr->addr2), res);
++ if (res == -2)
++ IEEE80211_DEBUG_DROP("Decryption failed ICV "
++ "mismatch (key %d)\n",
++ skb->data[hdrlen + 3] >> 6);
++ ieee->ieee_stats.rx_discards_undecryptable++;
++ return -1;
++ }
++
++ return res;
++}
++
++
++/* Called only as a tasklet (software IRQ), by ieee80211_rx */
++static inline int
++ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device* ieee, struct sk_buff *skb,
++ int keyidx, struct ieee80211_crypt_data *crypt)
++{
++ struct ieee80211_hdr *hdr;
++ int res, hdrlen;
++
++ if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
++ return 0;
++
++ hdr = (struct ieee80211_hdr *) skb->data;
++#ifdef _RTL8187_EXT_PATCH_
++ if((ieee->iw_mode == ieee->iw_ext_mode) && (ieee->ext_patch_ieee80211_rx_frame_get_hdrlen))
++ {
++ hdrlen = ieee->ext_patch_ieee80211_rx_frame_get_hdrlen(ieee, skb);
++ }
++ else
++#endif
++ hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
++
++ atomic_inc(&crypt->refcnt);
++ res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv);
++ atomic_dec(&crypt->refcnt);
++ if (res < 0) {
++ printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
++ " (SA=" MAC_FMT " keyidx=%d)\n",
++ ieee->dev->name, MAC_ARG(hdr->addr2), keyidx);
++ return -1;
++ }
++
++ return 0;
++}
++
++
++/* this function is stolen from ipw2200 driver*/
++#define IEEE_PACKET_RETRY_TIME (5*HZ)
++static int is_duplicate_packet(struct ieee80211_device *ieee,
++ struct ieee80211_hdr *header)
++{
++ u16 fc = le16_to_cpu(header->frame_ctl);
++ u16 sc = le16_to_cpu(header->seq_ctl);
++ u16 seq = WLAN_GET_SEQ_SEQ(sc);
++ u16 frag = WLAN_GET_SEQ_FRAG(sc);
++ u16 *last_seq, *last_frag;
++ unsigned long *last_time;
++ struct ieee80211_hdr_3addr_QOS *hdr_3addr_QoS;
++ struct ieee80211_hdr_QOS *hdr_4addr_QoS;
++ u8 tid;
++
++#ifdef _RTL8187_EXT_PATCH_
++ if(ieee->iw_mode == ieee->iw_ext_mode)
++ {
++ tid = (header->addr2[ETH_ALEN-2] ^ header->addr2[ETH_ALEN-1]) & IEEE80211_QOS_TID;
++ }
++ else
++#endif
++ //TO2DS and QoS
++ if(((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) {
++ hdr_4addr_QoS = (struct ieee80211_hdr_QOS *)header;
++ tid = le16_to_cpu(hdr_4addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
++ tid = UP2AC(tid);
++ tid ++;
++ } else if(IEEE80211_QOS_HAS_SEQ(fc)) { //QoS
++ hdr_3addr_QoS = (struct ieee80211_hdr_3addr_QOS*)header;
++ tid = le16_to_cpu(hdr_3addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
++ tid = UP2AC(tid);
++ tid ++;
++ } else { // no QoS
++ tid = 0;
++ }
++
++ switch (ieee->iw_mode) {
++ case IW_MODE_ADHOC:
++ {
++ struct list_head *p;
++ struct ieee_ibss_seq *entry = NULL;
++ u8 *mac = header->addr2;
++ int index = mac[5] % IEEE_IBSS_MAC_HASH_SIZE;
++ //for (pos = (head)->next; pos != (head); pos = pos->next)
++ __list_for_each(p, &ieee->ibss_mac_hash[index]) {
++ entry = list_entry(p, struct ieee_ibss_seq, list);
++ if (!memcmp(entry->mac, mac, ETH_ALEN))
++ break;
++ }
++ // if (memcmp(entry->mac, mac, ETH_ALEN)){
++ if (p == &ieee->ibss_mac_hash[index]) {
++ entry = kmalloc(sizeof(struct ieee_ibss_seq), GFP_ATOMIC);
++ if (!entry) {
++ printk(KERN_WARNING "Cannot malloc new mac entry\n");
++ return 0;
++ }
++ memcpy(entry->mac, mac, ETH_ALEN);
++ entry->seq_num[tid] = seq;
++ entry->frag_num[tid] = frag;
++ entry->packet_time[tid] = jiffies;
++ list_add(&entry->list, &ieee->ibss_mac_hash[index]);
++ return 0;
++ }
++ last_seq = &entry->seq_num[tid];
++ last_frag = &entry->frag_num[tid];
++ last_time = &entry->packet_time[tid];
++ break;
++ }
++
++ case IW_MODE_INFRA:
++ last_seq = &ieee->last_rxseq_num[tid];
++ last_frag = &ieee->last_rxfrag_num[tid];
++ last_time = &ieee->last_packet_time[tid];
++
++ break;
++ default:
++#ifdef _RTL8187_EXT_PATCH_
++ if(ieee->iw_mode == ieee->iw_ext_mode)
++ {
++#if 0
++ printk("==============> tid = %d\n", tid);
++ last_seq = &ieee->last_rxseq_num[tid];
++ last_frag = &ieee->last_rxfrag_num[tid];
++ last_time = &ieee->last_packet_time[tid];
++#else
++ struct list_head *p;
++ struct ieee_mesh_seq *entry = NULL;
++ u8 *mac = header->addr2;
++ int index = mac[5] % IEEE_IBSS_MAC_HASH_SIZE;
++
++ __list_for_each(p, &ieee->mesh_mac_hash[index]) {
++ entry = list_entry(p, struct ieee_mesh_seq, list);
++ if (!memcmp(entry->mac, mac, ETH_ALEN))
++ break;
++ }
++ if (p == &ieee->mesh_mac_hash[index]) {
++ entry = kmalloc(sizeof(struct ieee_mesh_seq), GFP_ATOMIC);
++ if (!entry) {
++ printk(KERN_WARNING "Cannot malloc new mac entry for mesh\n");
++ return 0;
++ }
++ memcpy(entry->mac, mac, ETH_ALEN);
++ entry->seq_num = seq;
++ entry->frag_num = frag;
++ entry->packet_time = jiffies;
++ list_add(&entry->list, &ieee->mesh_mac_hash[index]);
++ return 0;
++ }
++ last_seq = &entry->seq_num;
++ last_frag = &entry->frag_num;
++ last_time = &entry->packet_time;
++#endif
++ break;
++ }
++ else
++#endif
++ return 0;
++ }
++
++// if(tid != 0) {
++// printk(KERN_WARNING ":)))))))))))%x %x %x, fc(%x)\n", tid, *last_seq, seq, header->frame_ctl);
++// }
++ if ((*last_seq == seq) &&
++ time_after(*last_time + IEEE_PACKET_RETRY_TIME, jiffies)) {
++ if (*last_frag == frag){
++ //printk(KERN_WARNING "[1] go drop!\n");
++ goto drop;
++
++ }
++ if (*last_frag + 1 != frag)
++ /* out-of-order fragment */
++ //printk(KERN_WARNING "[2] go drop!\n");
++ goto drop;
++ } else
++ *last_seq = seq;
++
++ *last_frag = frag;
++ *last_time = jiffies;
++ return 0;
++
++drop:
++// BUG_ON(!(fc & IEEE80211_FCTL_RETRY));
++// printk("DUP\n");
++
++ return 1;
++}
++#ifdef JUST_FOR_87SEMESH
++#define ActionHeadLen 30
++#define WIFI_MESH_TYPE IEEE80211_FTYPE_DATA
++#define WIFI_11S_MESH_ACTION 0x00A0
++#endif
++
++/* All received frames are sent to this function. @skb contains the frame in
++ * IEEE 802.11 format, i.e., in the format it was sent over air.
++ * This function is called only as a tasklet (software IRQ). */
++int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
++ struct ieee80211_rx_stats *rx_stats)
++{
++ struct net_device *dev = ieee->dev;
++ struct ieee80211_hdr *hdr;
++ //struct ieee80211_hdr_3addr_QOS *hdr;
++
++ size_t hdrlen;
++ u16 fc, type, stype, sc;
++ struct net_device_stats *stats;
++ unsigned int frag;
++ u8 *payload;
++ u16 ethertype;
++#ifdef NOT_YET
++ struct net_device *wds = NULL;
++ struct sk_buff *skb2 = NULL;
++ struct net_device *wds = NULL;
++ int frame_authorized = 0;
++ int from_assoc_ap = 0;
++ void *sta = NULL;
++#endif
++// u16 QOS_ctl = 0;
++ u8 dst[ETH_ALEN];
++ u8 src[ETH_ALEN];
++ u8 bssid[ETH_ALEN];
++ struct ieee80211_crypt_data *crypt = NULL;
++ int keyidx = 0;
++
++ //Added for mesh by Lawrence.
++ //u8 status;
++ //u32 flags;
++
++ // cheat the the hdr type
++ hdr = (struct ieee80211_hdr *)skb->data;
++ stats = &ieee->stats;
++
++ if (skb->len < 10) {
++ printk(KERN_INFO "%s: SKB length < 10\n",
++ dev->name);
++ goto rx_dropped;
++ }
++#if 0
++//{added by david for filter the packet listed in the filter table
++#ifdef _RTL8187_EXT_PATCH_
++ if((ieee->iw_mode == ieee->iw_ext_mode) && (ieee->ext_patch_ieee80211_acl_query))
++ {
++ if(!ieee->ext_patch_ieee80211_acl_query(ieee, hdr->addr2))
++ goto rx_dropped;
++ }
++#endif
++//}
++#endif
++ fc = le16_to_cpu(hdr->frame_ctl);
++ type = WLAN_FC_GET_TYPE(fc);
++ stype = WLAN_FC_GET_STYPE(fc);
++
++ //Because 87se's bad feature,do more handle.
++#ifdef JUST_FOR_87SEMESH
++
++u8 tmphead[ActionHeadLen];
++ if(type ==WIFI_MESH_TYPE && stype== WIFI_11S_MESH_ACTION )
++ //head=sizeof(struct ieee80211_hdr)=30
++ {
++ memset(tmphead,0,ActionHeadLen);
++ memcpy(tmphead,skb->data,ActionHeadLen);
++
++ skb_pull(skb,ActionHeadLen+2);
++ memcpy(skb_push(skb,ActionHeadLen),tmphead,ActionHeadLen);
++ hdr = (struct ieee80211_hdr *)skb->data;
++ }
++
++#endif
++ sc = le16_to_cpu(hdr->seq_ctl);
++
++ frag = WLAN_GET_SEQ_FRAG(sc);
++#ifdef _RTL8187_EXT_PATCH_
++ if((ieee->iw_mode == ieee->iw_ext_mode) && (ieee->ext_patch_ieee80211_rx_frame_get_hdrlen))
++ {
++ hdrlen = ieee->ext_patch_ieee80211_rx_frame_get_hdrlen(ieee, skb);
++ if(skb->len < hdrlen)
++ goto rx_dropped;
++ }
++ else
++#endif
++ hdrlen = ieee80211_get_hdrlen(fc);
++
++#ifdef NOT_YET
++#if WIRELESS_EXT > 15
++ /* Put this code here so that we avoid duplicating it in all
++ * Rx paths. - Jean II */
++#ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */
++ /* If spy monitoring on */
++ if (iface->spy_data.spy_number > 0) {
++ struct iw_quality wstats;
++ wstats.level = rx_stats->signal;
++ wstats.noise = rx_stats->noise;
++ wstats.updated = 6; /* No qual value */
++ /* Update spy records */
++ wireless_spy_update(dev, hdr->addr2, &wstats);
++ }
++#endif /* IW_WIRELESS_SPY */
++#endif /* WIRELESS_EXT > 15 */
++ hostap_update_rx_stats(local->ap, hdr, rx_stats);
++#endif
++
++#if WIRELESS_EXT > 15
++ if (ieee->iw_mode == IW_MODE_MONITOR) {
++ ieee80211_monitor_rx(ieee, skb, rx_stats);
++ stats->rx_packets++;
++ stats->rx_bytes += skb->len;
++ return 1;
++ }
++#endif
++ if (ieee->host_decrypt) {
++ int idx = 0;
++ if (skb->len >= hdrlen + 3)
++ idx = skb->data[hdrlen + 3] >> 6;
++#ifdef _RTL8187_EXT_PATCH_
++
++ crypt = ieee->cryptlist[0]->crypt[idx];
++#if 0
++ {
++ int i = ieee80211_find_MP(ieee, ((struct ieee80211_hdr*)skb->data)->addr2);
++ if (i == -1)
++ {
++ printk("error find entry in entry list\n");
++ goto rx_dropped;
++ }
++ //printk("%s():"MAC_FMT", find in index:%d", __FUNCTION__, MAC_ARG(((struct ieee80211_hdr*)skb->data)->addr2), i);
++ crypt = ieee->cryptlist[i]->crypt[idx];
++ }
++#endif
++#else
++ crypt = ieee->crypt[idx];
++#endif
++
++#ifdef NOT_YET
++ sta = NULL;
++
++ /* Use station specific key to override default keys if the
++ * receiver address is a unicast address ("individual RA"). If
++ * bcrx_sta_key parameter is set, station specific key is used
++ * even with broad/multicast targets (this is against IEEE
++ * 802.11, but makes it easier to use different keys with
++ * stations that do not support WEP key mapping). */
++
++ if (!(hdr->addr1[0] & 0x01) || local->bcrx_sta_key)
++ (void) hostap_handle_sta_crypto(local, hdr, &crypt,
++ &sta);
++#endif
++
++ /* allow NULL decrypt to indicate an station specific override
++ * for default encryption */
++ if (crypt && (crypt->ops == NULL ||
++ crypt->ops->decrypt_mpdu == NULL))
++ crypt = NULL;
++
++ if (!crypt && (fc & IEEE80211_FCTL_WEP)) {
++ /* This seems to be triggered by some (multicast?)
++ * frames from other than current BSS, so just drop the
++ * frames silently instead of filling system log with
++ * these reports. */
++ IEEE80211_DEBUG_DROP("Decryption failed (not set)"
++ " (SA=" MAC_FMT ")\n",
++ MAC_ARG(hdr->addr2));
++ ieee->ieee_stats.rx_discards_undecryptable++;
++ goto rx_dropped;
++ }
++ }
++
++ if (skb->len < IEEE80211_DATA_HDR3_LEN)
++ goto rx_dropped;
++
++ // if QoS enabled, should check the sequence for each of the AC
++ if (is_duplicate_packet(ieee, hdr))
++ goto rx_dropped;
++
++#ifdef _RTL8187_EXT_PATCH_
++ if( ieee->iw_mode == ieee->iw_ext_mode && ieee->ext_patch_ieee80211_rx_mgt_update_expire )
++ ieee->ext_patch_ieee80211_rx_mgt_update_expire( ieee, skb );
++#endif
++
++ if (type == IEEE80211_FTYPE_MGMT) {
++
++ #if 0
++ if ( stype == IEEE80211_STYPE_AUTH &&
++ fc & IEEE80211_FCTL_WEP && ieee->host_decrypt &&
++ (keyidx = hostap_rx_frame_decrypt(ieee, skb, crypt)) < 0)
++ {
++ printk(KERN_DEBUG "%s: failed to decrypt mgmt::auth "
++ "from " MAC_FMT "\n", dev->name,
++ MAC_ARG(hdr->addr2));
++ /* TODO: could inform hostapd about this so that it
++ * could send auth failure report */
++ goto rx_dropped;
++ }
++ #endif
++
++
++ if (ieee80211_rx_frame_mgmt(ieee, skb, rx_stats, type, stype))
++ goto rx_dropped;
++ else
++ goto rx_exit;
++ }
++
++#ifdef _RTL8187_EXT_PATCH_
++ if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_on_rx)
++ {
++ if(ieee->ext_patch_ieee80211_rx_on_rx(ieee, skb, rx_stats, type, stype)==0)
++ {
++ goto rx_exit;
++ }
++ }
++#endif
++
++ /* Data frame - extract src/dst addresses */
++ switch (fc & (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
++ case IEEE80211_FCTL_FROMDS:
++ memcpy(dst, hdr->addr1, ETH_ALEN);
++ memcpy(src, hdr->addr3, ETH_ALEN);
++ memcpy(bssid, hdr->addr2, ETH_ALEN);
++ break;
++ case IEEE80211_FCTL_TODS:
++ memcpy(dst, hdr->addr3, ETH_ALEN);
++ memcpy(src, hdr->addr2, ETH_ALEN);
++ memcpy(bssid, hdr->addr1, ETH_ALEN);
++ break;
++ case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
++ if (skb->len < IEEE80211_DATA_HDR4_LEN)
++ goto rx_dropped;
++ memcpy(dst, hdr->addr3, ETH_ALEN);
++ memcpy(src, hdr->addr4, ETH_ALEN);
++ memcpy(bssid, ieee->current_network.bssid, ETH_ALEN);
++ break;
++ case 0:
++ memcpy(dst, hdr->addr1, ETH_ALEN);
++ memcpy(src, hdr->addr2, ETH_ALEN);
++ memcpy(bssid, hdr->addr3, ETH_ALEN);
++ break;
++ }
++
++#ifdef NOT_YET
++ if (hostap_rx_frame_wds(ieee, hdr, fc, &wds))
++ goto rx_dropped;
++ if (wds) {
++ skb->dev = dev = wds;
++ stats = hostap_get_stats(dev);
++ }
++
++ if (ieee->iw_mode == IW_MODE_MASTER && !wds &&
++ (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == IEEE80211_FCTL_FROMDS &&
++ ieee->stadev &&
++ memcmp(hdr->addr2, ieee->assoc_ap_addr, ETH_ALEN) == 0) {
++ /* Frame from BSSID of the AP for which we are a client */
++ skb->dev = dev = ieee->stadev;
++ stats = hostap_get_stats(dev);
++ from_assoc_ap = 1;
++ }
++#endif
++
++ dev->last_rx = jiffies;
++
++#ifdef NOT_YET
++ if ((ieee->iw_mode == IW_MODE_MASTER ||
++ ieee->iw_mode == IW_MODE_REPEAT) &&
++ !from_assoc_ap) {
++ switch (hostap_handle_sta_rx(ieee, dev, skb, rx_stats,
++ wds != NULL)) {
++ case AP_RX_CONTINUE_NOT_AUTHORIZED:
++ frame_authorized = 0;
++ break;
++ case AP_RX_CONTINUE:
++ frame_authorized = 1;
++ break;
++ case AP_RX_DROP:
++ goto rx_dropped;
++ case AP_RX_EXIT:
++ goto rx_exit;
++ }
++ }
++#endif
++
++#ifdef _RTL8187_EXT_PATCH_
++ if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_is_valid_framectl)
++ {
++ if(ieee->ext_patch_ieee80211_rx_is_valid_framectl(ieee, fc, type, stype)==0)
++ goto rx_dropped;
++ }
++ else
++#endif
++ /* Nullfunc frames may have PS-bit set, so they must be passed to
++ * hostap_handle_sta_rx() before being dropped here. */
++ if (stype != IEEE80211_STYPE_DATA &&
++ stype != IEEE80211_STYPE_DATA_CFACK &&
++ stype != IEEE80211_STYPE_DATA_CFPOLL &&
++ stype != IEEE80211_STYPE_DATA_CFACKPOLL&&
++ stype != IEEE80211_STYPE_QOS_DATA//add by David,2006.8.4
++ ) {
++ if (stype != IEEE80211_STYPE_NULLFUNC)
++ IEEE80211_DEBUG_DROP(
++ "RX: dropped data frame "
++ "with no data (type=0x%02x, "
++ "subtype=0x%02x, len=%d)\n",
++ type, stype, skb->len);
++ goto rx_dropped;
++ }
++
++ if (memcmp(bssid, ieee->current_network.bssid, ETH_ALEN))
++ goto rx_dropped;
++
++ /* skb: hdr + (possibly fragmented, possibly encrypted) payload */
++#ifdef _RTL8187_EXT_PATCH_
++ if (ieee->host_decrypt && crypt) {
++ int idx = 0;
++ if (skb->len >= hdrlen + 3)
++ idx = skb->data[hdrlen + 3] >> 6;
++ if (ieee->iw_ext_mode == ieee->iw_mode) //if in mesh mode
++ {
++ int i = ieee80211_find_MP(ieee, ((struct ieee80211_hdr*)skb->data)->addr2, 0);
++ if (i == -1)
++ {
++ printk("error find entry in entry list\n");
++ goto rx_dropped;
++ }
++ // printk("%s():"MAC_FMT", find in index:%d\n", __FUNCTION__, MAC_ARG(((struct ieee80211_hdr*)skb->data)->addr2), i);
++ if (ieee->cryptlist[i]&&ieee->cryptlist[i]->crypt[idx])
++ crypt = ieee->cryptlist[i]->crypt[idx];
++
++ else
++ crypt = NULL;
++ }
++ else
++ crypt = ieee->cryptlist[0]->crypt[idx];
++ }
++#endif
++
++ if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
++ (keyidx = ieee80211_rx_frame_decrypt(ieee, skb, crypt)) < 0)
++ goto rx_dropped;
++
++ hdr = (struct ieee80211_hdr *) skb->data;
++
++ /* skb: hdr + (possibly fragmented) plaintext payload */
++ // PR: FIXME: hostap has additional conditions in the "if" below:
++ // ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
++ if ((frag != 0 || (fc & IEEE80211_FCTL_MOREFRAGS))) {
++ int flen;
++ struct sk_buff *frag_skb = ieee80211_frag_cache_get(ieee, hdr);
++ IEEE80211_DEBUG_FRAG("Rx Fragment received (%u)\n", frag);
++
++ if (!frag_skb) {
++ IEEE80211_DEBUG(IEEE80211_DL_RX | IEEE80211_DL_FRAG,
++ "Rx cannot get skb from fragment "
++ "cache (morefrag=%d seq=%u frag=%u)\n",
++ (fc & IEEE80211_FCTL_MOREFRAGS) != 0,
++ WLAN_GET_SEQ_SEQ(sc), frag);
++ goto rx_dropped;
++ }
++ flen = skb->len;
++ if (frag != 0)
++ flen -= hdrlen;
++
++ if (frag_skb->tail + flen > frag_skb->end) {
++ printk(KERN_WARNING "%s: host decrypted and "
++ "reassembled frame did not fit skb\n",
++ dev->name);
++ ieee80211_frag_cache_invalidate(ieee, hdr);
++ goto rx_dropped;
++ }
++
++ if (frag == 0) {
++ /* copy first fragment (including full headers) into
++ * beginning of the fragment cache skb */
++ memcpy(skb_put(frag_skb, flen), skb->data, flen);
++ } else {
++ /* append frame payload to the end of the fragment
++ * cache skb */
++ memcpy(skb_put(frag_skb, flen), skb->data + hdrlen,
++ flen);
++ }
++ dev_kfree_skb_any(skb);
++ skb = NULL;
++
++ if (fc & IEEE80211_FCTL_MOREFRAGS) {
++ /* more fragments expected - leave the skb in fragment
++ * cache for now; it will be delivered to upper layers
++ * after all fragments have been received */
++ goto rx_exit;
++ }
++
++ /* this was the last fragment and the frame will be
++ * delivered, so remove skb from fragment cache */
++ skb = frag_skb;
++ hdr = (struct ieee80211_hdr *) skb->data;
++ ieee80211_frag_cache_invalidate(ieee, hdr);
++ }
++
++ /* skb: hdr + (possible reassembled) full MSDU payload; possibly still
++ * encrypted/authenticated */
++ if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
++ ieee80211_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt))
++ goto rx_dropped;
++
++ hdr = (struct ieee80211_hdr *) skb->data;
++ if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep) {
++ if (/*ieee->ieee802_1x &&*/
++ ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
++
++#ifdef CONFIG_IEEE80211_DEBUG
++ /* pass unencrypted EAPOL frames even if encryption is
++ * configured */
++ struct eapol *eap = (struct eapol *)(skb->data +
++ 24);
++ IEEE80211_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n",
++ eap_get_type(eap->type));
++#endif
++ } else {
++ IEEE80211_DEBUG_DROP(
++ "encryption configured, but RX "
++ "frame not encrypted (SA=" MAC_FMT ")\n",
++ MAC_ARG(hdr->addr2));
++ goto rx_dropped;
++ }
++ }
++
++#ifdef CONFIG_IEEE80211_DEBUG
++ if (crypt && !(fc & IEEE80211_FCTL_WEP) &&
++ ieee80211_is_eapol_frame(ieee, skb)) {
++ struct eapol *eap = (struct eapol *)(skb->data +
++ 24);
++ IEEE80211_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n",
++ eap_get_type(eap->type));
++ }
++#endif
++
++ if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep &&
++ !ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
++ IEEE80211_DEBUG_DROP(
++ "dropped unencrypted RX data "
++ "frame from " MAC_FMT
++ " (drop_unencrypted=1)\n",
++ MAC_ARG(hdr->addr2));
++ goto rx_dropped;
++ }
++/*
++ if(ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
++ printk(KERN_WARNING "RX: IEEE802.1X EPAOL frame!\n");
++ }
++*/
++ /* skb: hdr + (possible reassembled) full plaintext payload */
++ payload = skb->data + hdrlen;
++ ethertype = (payload[6] << 8) | payload[7];
++
++#ifdef NOT_YET
++ /* If IEEE 802.1X is used, check whether the port is authorized to send
++ * the received frame. */
++ if (ieee->ieee802_1x && ieee->iw_mode == IW_MODE_MASTER) {
++ if (ethertype == ETH_P_PAE) {
++ printk(KERN_DEBUG "%s: RX: IEEE 802.1X frame\n",
++ dev->name);
++ if (ieee->hostapd && ieee->apdev) {
++ /* Send IEEE 802.1X frames to the user
++ * space daemon for processing */
++ prism2_rx_80211(ieee->apdev, skb, rx_stats,
++ PRISM2_RX_MGMT);
++ ieee->apdevstats.rx_packets++;
++ ieee->apdevstats.rx_bytes += skb->len;
++ goto rx_exit;
++ }
++ } else if (!frame_authorized) {
++ printk(KERN_DEBUG "%s: dropped frame from "
++ "unauthorized port (IEEE 802.1X): "
++ "ethertype=0x%04x\n",
++ dev->name, ethertype);
++ goto rx_dropped;
++ }
++ }
++#endif
++
++#ifdef _RTL8187_EXT_PATCH_
++ if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_process_dataframe)
++ {
++ if(ieee->ext_patch_ieee80211_rx_process_dataframe(ieee, skb, rx_stats))
++ {
++ stats->rx_packets++;
++ stats->rx_bytes += skb->len;
++ goto rx_exit;
++ }
++ else
++ goto rx_dropped;
++ }
++#endif
++ ieee->NumRxDataInPeriod++;
++// ieee->NumRxOkTotal++;
++ /* convert hdr + possible LLC headers into Ethernet header */
++ if (skb->len - hdrlen >= 8 &&
++ ((memcmp(payload, rfc1042_header, SNAP_SIZE) == 0 &&
++ ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
++ memcmp(payload, bridge_tunnel_header, SNAP_SIZE) == 0)) {
++ /* remove RFC1042 or Bridge-Tunnel encapsulation and
++ * replace EtherType */
++ skb_pull(skb, hdrlen + SNAP_SIZE);
++ memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
++ memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
++ } else {
++ u16 len;
++ /* Leave Ethernet header part of hdr and full payload */
++ skb_pull(skb, hdrlen);
++ len = htons(skb->len);
++ memcpy(skb_push(skb, 2), &len, 2);
++ memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
++ memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
++ }
++
++#ifdef NOT_YET
++ if (wds && ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
++ IEEE80211_FCTL_TODS) &&
++ skb->len >= ETH_HLEN + ETH_ALEN) {
++ /* Non-standard frame: get addr4 from its bogus location after
++ * the payload */
++ memcpy(skb->data + ETH_ALEN,
++ skb->data + skb->len - ETH_ALEN, ETH_ALEN);
++ skb_trim(skb, skb->len - ETH_ALEN);
++ }
++#endif
++
++ stats->rx_packets++;
++ stats->rx_bytes += skb->len;
++
++#ifdef NOT_YET
++ if (ieee->iw_mode == IW_MODE_MASTER && !wds &&
++ ieee->ap->bridge_packets) {
++ if (dst[0] & 0x01) {
++ /* copy multicast frame both to the higher layers and
++ * to the wireless media */
++ ieee->ap->bridged_multicast++;
++ skb2 = skb_clone(skb, GFP_ATOMIC);
++ if (skb2 == NULL)
++ printk(KERN_DEBUG "%s: skb_clone failed for "
++ "multicast frame\n", dev->name);
++ } else if (hostap_is_sta_assoc(ieee->ap, dst)) {
++ /* send frame directly to the associated STA using
++ * wireless media and not passing to higher layers */
++ ieee->ap->bridged_unicast++;
++ skb2 = skb;
++ skb = NULL;
++ }
++ }
++
++ if (skb2 != NULL) {
++ /* send to wireless media */
++ skb2->protocol = __constant_htons(ETH_P_802_3);
++ skb2->mac.raw = skb2->nh.raw = skb2->data;
++ /* skb2->nh.raw = skb2->data + ETH_HLEN; */
++ skb2->dev = dev;
++ dev_queue_xmit(skb2);
++ }
++
++#endif
++ if (skb) {
++ //printk("0skb_len(%d)\n", skb->len);
++ skb->protocol = eth_type_trans(skb, dev);
++ memset(skb->cb, 0, sizeof(skb->cb));
++ skb->dev = dev;
++ skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */
++ //skb->ip_summed = CHECKSUM_UNNECESSARY; /* 802.11 crc not sufficient */
++ ieee->last_rx_ps_time = jiffies;
++ //printk("1skb_len(%d)\n", skb->len);
++ netif_rx(skb);
++ }
++
++//by lizhaoming for LED_RX 2008.6.23
++#ifdef LED_SHIN
++// printk("==================>data rcvd\n");
++ ieee->ieee80211_led_contorl(dev,LED_CTL_RX);
++#endif
++
++ rx_exit:
++#ifdef NOT_YET
++ if (sta)
++ hostap_handle_sta_release(sta);
++#endif
++ return 1;
++
++ rx_dropped:
++ stats->rx_dropped++;
++#if 0
++ int i;
++ printk("======>dropped: %s():addr2:"MAC_FMT",addr1:"MAC_FMT",skb->len:%d, hdrlen:%d\n", __FUNCTION__, MAC_ARG(((struct ieee80211_hdr*)skb->data)->addr2), MAC_ARG(((struct ieee80211_hdr*)skb->data)->addr1), skb->len, hdrlen);
++ for (i = 0; i < skb->len; i++) {
++ if (i % 16 == 0) printk("\n\t");
++ printk("%2x ", *(skb->data+i));
++ }
++
++ printk("\n");
++#endif
++ /* Returning 0 indicates to caller that we have not handled the SKB--
++ * so it is still allocated and can be used again by underlying
++ * hardware as a DMA target */
++ return 0;
++}
++
++#ifdef _RTL8187_EXT_PATCH_
++int ieee_ext_skb_p80211_to_ether(struct sk_buff *skb, int hdrlen, u8 *dst, u8 *src)
++{
++ u8 *payload;
++ u16 ethertype;
++
++ /* skb: hdr + (possible reassembled) full plaintext payload */
++ payload = skb->data + hdrlen;
++ ethertype = (payload[6] << 8) | payload[7];
++
++ /* convert hdr + possible LLC headers into Ethernet header */
++ if (skb->len - hdrlen >= 8 &&
++ ((memcmp(payload, rfc1042_header, SNAP_SIZE) == 0 &&
++ ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
++ memcmp(payload, bridge_tunnel_header, SNAP_SIZE) == 0)) {
++ /* remove RFC1042 or Bridge-Tunnel encapsulation and
++ * replace EtherType */
++ skb_pull(skb, hdrlen + SNAP_SIZE);
++ memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
++ memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
++ } else {
++ u16 len;
++ /* Leave Ethernet header part of hdr and full payload */
++ skb_pull(skb, hdrlen);
++ len = htons(skb->len);
++ memcpy(skb_push(skb, 2), &len, 2);
++ memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
++ memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
++ }
++
++ return 1;
++}
++#endif // _RTL8187_EXT_PATCH_
++
++
++#define MGMT_FRAME_FIXED_PART_LENGTH 0x24
++
++static inline int ieee80211_is_ofdm_rate(u8 rate)
++{
++ switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
++ case IEEE80211_OFDM_RATE_6MB:
++ case IEEE80211_OFDM_RATE_9MB:
++ case IEEE80211_OFDM_RATE_12MB:
++ case IEEE80211_OFDM_RATE_18MB:
++ case IEEE80211_OFDM_RATE_24MB:
++ case IEEE80211_OFDM_RATE_36MB:
++ case IEEE80211_OFDM_RATE_48MB:
++ case IEEE80211_OFDM_RATE_54MB:
++ return 1;
++ }
++ return 0;
++}
++
++
++//
++// Description:
++// Translate 0-100 signal strength index into dBm.
++//
++int
++TranslateToDbm8187(
++ unsigned char SignalStrengthIndex // 0-100 index.
++ )
++{
++ unsigned char SignalPower; // in dBm.
++
++ // Translate to dBm (x=0.5y-95).
++ //SignalPower = (int)((SignalStrengthIndex + 1) >> 1);
++ SignalPower = (int)SignalStrengthIndex * 7 / 10;
++ SignalPower -= 95;
++// printk("==>SignalPower:%d\n", SignalPower);
++ return SignalPower;
++}
++
++static inline int ieee80211_SignalStrengthTranslate(
++ int CurrSS
++ )
++{
++ int RetSS;
++
++ // Step 1. Scale mapping.
++ if(CurrSS >= 71 && CurrSS <= 100)
++ {
++ RetSS = 95 + (((CurrSS - 70) / 6 == 5) ? 5 : ((CurrSS - 70) / 6 + 1));
++ }
++ else if(CurrSS >= 41 && CurrSS <= 70)
++ {
++ RetSS = 83 + ((CurrSS - 40) / 3);
++ }
++ else if(CurrSS >= 31 && CurrSS <= 40)
++ {
++ RetSS = 71 + (CurrSS - 30);
++ }
++ else if(CurrSS >= 21 && CurrSS <= 30)
++ {
++ RetSS = 59 + (CurrSS - 20);
++ }
++ else if(CurrSS >= 5 && CurrSS <= 20)
++ {
++ RetSS = 47 + (((CurrSS - 5) * 2) / 3);
++ }
++ else if(CurrSS == 4)
++ {
++ RetSS = 37;
++ }
++ else if(CurrSS == 3)
++ {
++ RetSS = 27;
++ }
++ else if(CurrSS == 2)
++ {
++ RetSS = 18;
++ }
++ else if(CurrSS == 1)
++ {
++ RetSS = 9;
++ }
++ else
++ {
++ RetSS = CurrSS;
++ }
++ //RT_TRACE(COMP_DBG, DBG_LOUD, ("##### After Mapping: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
++
++ // Step 2. Smoothing.
++
++ //RT_TRACE(COMP_DBG, DBG_LOUD, ("$$$$$ After Smoothing: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
++
++ return RetSS;
++}
++
++#ifdef ENABLE_DOT11D
++static inline void ieee80211_extract_country_ie(
++ struct ieee80211_device *ieee,
++ struct ieee80211_info_element *info_element,
++ struct ieee80211_network *network,
++ u8 * addr2
++)
++{
++#if 0
++ u32 i = 0;
++ u8 * p = (u8*)info_element->data;
++ printk("-----------------------\n");
++ printk("%s Country IE:", network->ssid);
++ for(i=0; i<info_element->len; i++)
++ printk("\t%2.2x", *(p+i));
++ printk("\n-----------------------\n");
++#endif
++ if(IS_DOT11D_ENABLE(ieee))
++ {
++ if(info_element->len!= 0)
++ {
++ memcpy(network->CountryIeBuf, info_element->data, info_element->len);
++ network->CountryIeLen = info_element->len;
++
++ if(!IS_COUNTRY_IE_VALID(ieee))
++ {
++ Dot11d_UpdateCountryIe(ieee, addr2, info_element->len, info_element->data);
++ }
++ }
++
++ //
++ // 070305, rcnjko: I update country IE watch dog here because
++ // some AP (e.g. Cisco 1242) don't include country IE in their
++ // probe response frame.
++ //
++ if(IS_EQUAL_CIE_SRC(ieee, addr2) )
++ {
++ UPDATE_CIE_WATCHDOG(ieee);
++ }
++ }
++
++}
++#endif
++
++
++ inline int ieee80211_network_init(
++ struct ieee80211_device *ieee,
++ struct ieee80211_probe_response *beacon,
++ struct ieee80211_network *network,
++ struct ieee80211_rx_stats *stats)
++{
++#ifdef CONFIG_IEEE80211_DEBUG
++ char rates_str[64];
++ char *p;
++#endif
++ struct ieee80211_info_element *info_element;
++ u16 left;
++ u8 i;
++ short offset;
++
++ /* Pull out fixed field data */
++ memcpy(network->bssid, beacon->header.addr3, ETH_ALEN);
++ network->capability = beacon->capability;
++ network->last_scanned = jiffies;
++ network->time_stamp[0] = beacon->time_stamp[0];
++ network->time_stamp[1] = beacon->time_stamp[1];
++ network->beacon_interval = beacon->beacon_interval;
++ /* Where to pull this? beacon->listen_interval;*/
++ network->listen_interval = 0x0A;
++ network->rates_len = network->rates_ex_len = 0;
++ network->last_associate = 0;
++ network->ssid_len = 0;
++ network->flags = 0;
++ network->atim_window = 0;
++ network->QoS_Enable = 0;
++#ifdef THOMAS_TURBO
++ network->Turbo_Enable = 0;
++#endif
++#ifdef ENABLE_DOT11D
++ network->CountryIeLen = 0;
++ memset(network->CountryIeBuf, 0, MAX_IE_LEN);
++#endif
++
++ if (stats->freq == IEEE80211_52GHZ_BAND) {
++ /* for A band (No DS info) */
++ network->channel = stats->received_channel;
++ } else
++ network->flags |= NETWORK_HAS_CCK;
++
++ network->wpa_ie_len = 0;
++ network->rsn_ie_len = 0;
++
++ info_element = &beacon->info_element;
++ left = stats->len - ((void *)info_element - (void *)beacon);
++ while (left >= sizeof(struct ieee80211_info_element_hdr)) {
++ if (sizeof(struct ieee80211_info_element_hdr) + info_element->len > left) {
++ IEEE80211_DEBUG_SCAN("SCAN: parse failed: info_element->len + 2 > left : info_element->len+2=%d left=%d.\n",
++ info_element->len + sizeof(struct ieee80211_info_element),
++ left);
++ return 1;
++ }
++
++ switch (info_element->id) {
++ case MFIE_TYPE_SSID:
++ if (ieee80211_is_empty_essid(info_element->data,
++ info_element->len)) {
++ network->flags |= NETWORK_EMPTY_ESSID;
++ break;
++ }
++
++ network->ssid_len = min(info_element->len,
++ (u8)IW_ESSID_MAX_SIZE);
++ memcpy(network->ssid, info_element->data, network->ssid_len);
++ if (network->ssid_len < IW_ESSID_MAX_SIZE)
++ memset(network->ssid + network->ssid_len, 0,
++ IW_ESSID_MAX_SIZE - network->ssid_len);
++
++ IEEE80211_DEBUG_SCAN("MFIE_TYPE_SSID: '%s' len=%d.\n",
++ network->ssid, network->ssid_len);
++ break;
++
++ case MFIE_TYPE_RATES:
++#ifdef CONFIG_IEEE80211_DEBUG
++ p = rates_str;
++#endif
++ network->rates_len = min(info_element->len, MAX_RATES_LENGTH);
++ for (i = 0; i < network->rates_len; i++) {
++ network->rates[i] = info_element->data[i];
++#ifdef CONFIG_IEEE80211_DEBUG
++ p += snprintf(p, sizeof(rates_str) - (p - rates_str), "%02X ", network->rates[i]);
++#endif
++ if (ieee80211_is_ofdm_rate(info_element->data[i])) {
++ network->flags |= NETWORK_HAS_OFDM;
++ if (info_element->data[i] &
++ IEEE80211_BASIC_RATE_MASK)
++ network->flags &=
++ ~NETWORK_HAS_CCK;
++ }
++ }
++
++ IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES: '%s' (%d)\n",
++ rates_str, network->rates_len);
++ break;
++
++ case MFIE_TYPE_RATES_EX:
++#ifdef CONFIG_IEEE80211_DEBUG
++ p = rates_str;
++#endif
++ network->rates_ex_len = min(info_element->len, MAX_RATES_EX_LENGTH);
++ for (i = 0; i < network->rates_ex_len; i++) {
++ network->rates_ex[i] = info_element->data[i];
++#ifdef CONFIG_IEEE80211_DEBUG
++ p += snprintf(p, sizeof(rates_str) - (p - rates_str), "%02X ", network->rates[i]);
++#endif
++ if (ieee80211_is_ofdm_rate(info_element->data[i])) {
++ network->flags |= NETWORK_HAS_OFDM;
++ if (info_element->data[i] &
++ IEEE80211_BASIC_RATE_MASK)
++ network->flags &=
++ ~NETWORK_HAS_CCK;
++ }
++ }
++
++ IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES_EX: '%s' (%d)\n",
++ rates_str, network->rates_ex_len);
++ break;
++
++ case MFIE_TYPE_DS_SET:
++ IEEE80211_DEBUG_SCAN("MFIE_TYPE_DS_SET: %d\n",
++ info_element->data[0]);
++ if (stats->freq == IEEE80211_24GHZ_BAND)
++ network->channel = info_element->data[0];
++ break;
++
++ case MFIE_TYPE_FH_SET:
++ IEEE80211_DEBUG_SCAN("MFIE_TYPE_FH_SET: ignored\n");
++ break;
++
++ case MFIE_TYPE_CF_SET:
++ IEEE80211_DEBUG_SCAN("MFIE_TYPE_CF_SET: ignored\n");
++ break;
++
++ case MFIE_TYPE_TIM:
++
++ if(info_element->len < 4)
++ break;
++
++ network->dtim_period = info_element->data[1];
++
++ if(ieee->state != IEEE80211_LINKED)
++ break;
++
++ network->last_dtim_sta_time[0] = stats->mac_time[0];
++ network->last_dtim_sta_time[1] = stats->mac_time[1];
++
++ network->dtim_data = IEEE80211_DTIM_VALID;
++
++ if(info_element->data[0] != 0)
++ break;
++
++ if(info_element->data[2] & 1)
++ network->dtim_data |= IEEE80211_DTIM_MBCAST;
++
++ offset = (info_element->data[2] >> 1)*2;
++
++ //printk("offset1:%x aid:%x\n",offset, ieee->assoc_id);
++
++ if(ieee->assoc_id < offset ||
++ ieee->assoc_id > 8*(offset + info_element->len -3))
++
++ break;
++
++
++ offset = offset + ieee->assoc_id / 8;// + ((aid % 8)? 0 : 1) ;
++
++ // printk("offset:%x data:%x, ucast:%d\n", offset,
++ // info_element->data[3+offset] ,
++ // info_element->data[3+offset] & (1<<(ieee->assoc_id%8)));
++
++ if(info_element->data[3+offset] & (1<<(ieee->assoc_id%8)))
++ network->dtim_data |= IEEE80211_DTIM_UCAST;
++
++ break;
++
++ case MFIE_TYPE_IBSS_SET:
++ IEEE80211_DEBUG_SCAN("MFIE_TYPE_IBSS_SET: ignored\n");
++ break;
++
++ case MFIE_TYPE_CHALLENGE:
++ IEEE80211_DEBUG_SCAN("MFIE_TYPE_CHALLENGE: ignored\n");
++ break;
++
++ case MFIE_TYPE_GENERIC:
++ //nic is 87B
++ IEEE80211_DEBUG_SCAN("MFIE_TYPE_GENERIC: %d bytes\n",
++ info_element->len);
++ if (info_element->len >= 4 &&
++ info_element->data[0] == 0x00 &&
++ info_element->data[1] == 0x50 &&
++ info_element->data[2] == 0xf2 &&
++ info_element->data[3] == 0x01) {
++ network->wpa_ie_len = min(info_element->len + 2,
++ MAX_WPA_IE_LEN);
++ memcpy(network->wpa_ie, info_element,
++ network->wpa_ie_len);
++ }
++
++#ifdef THOMAS_TURBO
++ if (info_element->len == 7 &&
++ info_element->data[0] == 0x00 &&
++ info_element->data[1] == 0xe0 &&
++ info_element->data[2] == 0x4c &&
++ info_element->data[3] == 0x01 &&
++ info_element->data[4] == 0x02) {
++ network->Turbo_Enable = 1;
++ }
++#endif
++ if (1 == stats->nic_type) {//nic 87
++ break;
++ }
++
++ if (info_element->len >= 5 &&
++ info_element->data[0] == 0x00 &&
++ info_element->data[1] == 0x50 &&
++ info_element->data[2] == 0xf2 &&
++ info_element->data[3] == 0x02 &&
++ info_element->data[4] == 0x00) {
++ //printk(KERN_WARNING "wmm info updated: %x\n", info_element->data[6]);
++ //WMM Information Element
++ network->wmm_info = info_element->data[6];
++ network->QoS_Enable = 1;
++ }
++
++ if (info_element->len >= 8 &&
++ info_element->data[0] == 0x00 &&
++ info_element->data[1] == 0x50 &&
++ info_element->data[2] == 0xf2 &&
++ info_element->data[3] == 0x02 &&
++ info_element->data[4] == 0x01) {
++ // Not care about version at present.
++ //WMM Information Element
++ //printk(KERN_WARNING "wmm info&param updated: %x\n", info_element->data[6]);
++ network->wmm_info = info_element->data[6];
++ //WMM Parameter Element
++ memcpy(network->wmm_param, (u8 *)(info_element->data + 8),(info_element->len - 8));
++ network->QoS_Enable = 1;
++ }
++ break;
++
++ case MFIE_TYPE_RSN:
++ IEEE80211_DEBUG_SCAN("MFIE_TYPE_RSN: %d bytes\n",
++ info_element->len);
++ network->rsn_ie_len = min(info_element->len + 2,
++ MAX_WPA_IE_LEN);
++ memcpy(network->rsn_ie, info_element,
++ network->rsn_ie_len);
++ break;
++
++#ifdef ENABLE_DOT11D
++ case MFIE_TYPE_COUNTRY:
++ IEEE80211_DEBUG_SCAN("MFIE_TYPE_COUNTRY: %d bytes\n",
++ info_element->len);
++// printk("=====>Receive <%s> Country IE\n",network->ssid);
++ ieee80211_extract_country_ie(ieee, info_element, network, beacon->header.addr2);
++ break;
++#endif
++
++ default:
++ IEEE80211_DEBUG_SCAN("unsupported IE %d\n",
++ info_element->id);
++ break;
++ }
++
++ left -= sizeof(struct ieee80211_info_element_hdr) +
++ info_element->len;
++ info_element = (struct ieee80211_info_element *)
++ &info_element->data[info_element->len];
++ }
++
++ network->mode = 0;
++ if (stats->freq == IEEE80211_52GHZ_BAND)
++ network->mode = IEEE_A;
++ else {
++ if (network->flags & NETWORK_HAS_OFDM)
++ network->mode |= IEEE_G;
++ if (network->flags & NETWORK_HAS_CCK)
++ network->mode |= IEEE_B;
++ }
++
++ if (network->mode == 0) {
++ IEEE80211_DEBUG_SCAN("Filtered out '%s (" MAC_FMT ")' "
++ "network.\n",
++ escape_essid(network->ssid,
++ network->ssid_len),
++ MAC_ARG(network->bssid));
++ return 1;
++ }
++
++ if (ieee80211_is_empty_essid(network->ssid, network->ssid_len))
++ network->flags |= NETWORK_EMPTY_ESSID;
++
++#if 1
++ //if(strcmp(network->ssid, "linksys_lzm000") == 0)
++ // printk("----signalstrength = %d ", stats->signalstrength);
++ stats->signal = TranslateToDbm8187(stats->signalstrength);
++ //stats->noise = stats->signal - stats->noise;
++ stats->noise = TranslateToDbm8187(100 - stats->signalstrength) - 25;
++#endif
++ memcpy(&network->stats, stats, sizeof(network->stats));
++
++ //YJ,test,080611
++ //if(strcmp(network->ssid, "ZyXEL") == 0)
++ // IEEE_NET_DUMP(network);
++
++ return 0;
++}
++
++static inline int is_same_network(struct ieee80211_network *src,
++ struct ieee80211_network *dst,
++ struct ieee80211_device * ieee)
++{
++ /* A network is only a duplicate if the channel, BSSID, ESSID
++ * and the capability field (in particular IBSS and BSS) all match.
++ * We treat all <hidden> with the same BSSID and channel
++ * as one network */
++ return (((src->ssid_len == dst->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && //YJ,mod,080819,for hidden ap
++ //((src->ssid_len == dst->ssid_len) &&
++ (src->channel == dst->channel) &&
++ !memcmp(src->bssid, dst->bssid, ETH_ALEN) &&
++ (!memcmp(src->ssid, dst->ssid, src->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && //YJ,mod,080819,for hidden ap
++ //!memcmp(src->ssid, dst->ssid, src->ssid_len) &&
++ ((src->capability & WLAN_CAPABILITY_IBSS) ==
++ (dst->capability & WLAN_CAPABILITY_IBSS)) &&
++ ((src->capability & WLAN_CAPABILITY_BSS) ==
++ (dst->capability & WLAN_CAPABILITY_BSS)));
++}
++
++inline void update_network(struct ieee80211_network *dst,
++ struct ieee80211_network *src)
++{
++ unsigned char quality = src->stats.signalstrength;
++ unsigned char signal = 0;
++ unsigned char noise = 0;
++ if(dst->stats.signalstrength > 0) {
++ quality = (dst->stats.signalstrength * 5 + src->stats.signalstrength + 5)/6;
++ }
++ signal = TranslateToDbm8187(quality);
++ //noise = signal - src->stats.noise;
++ if(dst->stats.noise > 0)
++ noise = (dst->stats.noise * 5 + src->stats.noise)/6;
++ //if(strcmp(dst->ssid, "linksys_lzm000") == 0)
++// printk("ssid:%s, quality:%d, signal:%d\n", dst->ssid, quality, signal);
++ memcpy(&dst->stats, &src->stats, sizeof(struct ieee80211_rx_stats));
++ dst->stats.signalstrength = quality;
++ dst->stats.signal = signal;
++ dst->stats.noise = noise;
++ dst->capability = src->capability;
++ memcpy(dst->rates, src->rates, src->rates_len);
++ dst->rates_len = src->rates_len;
++ memcpy(dst->rates_ex, src->rates_ex, src->rates_ex_len);
++ dst->rates_ex_len = src->rates_ex_len;
++
++ //YJ,add,080819,for hidden ap
++ if(src->ssid_len > 0)
++ {
++ //if(src->ssid_len == 13)
++ // printk("=====================>>>>>>>> Dst ssid: %s Src ssid: %s\n", dst->ssid, src->ssid);
++ memset(dst->ssid, 0, dst->ssid_len);
++ dst->ssid_len = src->ssid_len;
++ memcpy(dst->ssid, src->ssid, src->ssid_len);
++ }
++ //YJ,add,080819,for hidden ap,end
++ dst->channel = src->channel;
++ dst->mode = src->mode;
++ dst->flags = src->flags;
++ dst->time_stamp[0] = src->time_stamp[0];
++ dst->time_stamp[1] = src->time_stamp[1];
++
++ dst->beacon_interval = src->beacon_interval;
++ dst->listen_interval = src->listen_interval;
++ dst->atim_window = src->atim_window;
++ dst->dtim_period = src->dtim_period;
++ dst->dtim_data = src->dtim_data;
++ dst->last_dtim_sta_time[0] = src->last_dtim_sta_time[0];
++ dst->last_dtim_sta_time[1] = src->last_dtim_sta_time[1];
++
++ memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len);
++ dst->wpa_ie_len = src->wpa_ie_len;
++ memcpy(dst->rsn_ie, src->rsn_ie, src->rsn_ie_len);
++ dst->rsn_ie_len = src->rsn_ie_len;
++
++ dst->last_scanned = jiffies;
++ /* dst->last_associate is not overwritten */
++#if 1
++ dst->wmm_info = src->wmm_info; //sure to exist in beacon or probe response frame.
++/*
++ if((dst->wmm_info^src->wmm_info)&0x0f) {//Param Set Count change, update Parameter
++ memcpy(dst->wmm_param, src->wmm_param, IEEE80211_AC_PRAM_LEN);
++ }
++*/
++ if(src->wmm_param[0].ac_aci_acm_aifsn|| \
++ src->wmm_param[1].ac_aci_acm_aifsn|| \
++ src->wmm_param[2].ac_aci_acm_aifsn|| \
++ src->wmm_param[1].ac_aci_acm_aifsn) {
++ memcpy(dst->wmm_param, src->wmm_param, WME_AC_PRAM_LEN);
++ }
++ dst->QoS_Enable = src->QoS_Enable;
++#else
++ dst->QoS_Enable = 1;//for Rtl8187 simulation
++#endif
++ dst->SignalStrength = src->SignalStrength;
++#ifdef THOMAS_TURBO
++ dst->Turbo_Enable = src->Turbo_Enable;
++#endif
++#ifdef ENABLE_DOT11D
++ dst->CountryIeLen = src->CountryIeLen;
++ memcpy(dst->CountryIeBuf, src->CountryIeBuf, src->CountryIeLen);
++#endif
++
++}
++
++inline void ieee80211_process_probe_response(
++ struct ieee80211_device *ieee,
++ struct ieee80211_probe_response *beacon,
++ struct ieee80211_rx_stats *stats)
++{
++ struct ieee80211_network network;
++ struct ieee80211_network *target;
++ struct ieee80211_network *oldest = NULL;
++#ifdef CONFIG_IEEE80211_DEBUG
++ struct ieee80211_info_element *info_element = &beacon->info_element;
++#endif
++ unsigned long flags;
++ short renew;
++ u8 wmm_info;
++ u8 is_beacon = (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_BEACON)? 1:0;
++
++ memset(&network, 0, sizeof(struct ieee80211_network));
++//rz
++#ifdef _RTL8187_EXT_PATCH_
++ if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_process_probe_response_1) {
++ ieee->ext_patch_ieee80211_process_probe_response_1(ieee, beacon, stats);
++ return;
++ }
++#endif
++ IEEE80211_DEBUG_SCAN(
++ "'%s' (" MAC_FMT "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
++ escape_essid(info_element->data, info_element->len),
++ MAC_ARG(beacon->header.addr3),
++ (beacon->capability & (1<<0xf)) ? '1' : '0',
++ (beacon->capability & (1<<0xe)) ? '1' : '0',
++ (beacon->capability & (1<<0xd)) ? '1' : '0',
++ (beacon->capability & (1<<0xc)) ? '1' : '0',
++ (beacon->capability & (1<<0xb)) ? '1' : '0',
++ (beacon->capability & (1<<0xa)) ? '1' : '0',
++ (beacon->capability & (1<<0x9)) ? '1' : '0',
++ (beacon->capability & (1<<0x8)) ? '1' : '0',
++ (beacon->capability & (1<<0x7)) ? '1' : '0',
++ (beacon->capability & (1<<0x6)) ? '1' : '0',
++ (beacon->capability & (1<<0x5)) ? '1' : '0',
++ (beacon->capability & (1<<0x4)) ? '1' : '0',
++ (beacon->capability & (1<<0x3)) ? '1' : '0',
++ (beacon->capability & (1<<0x2)) ? '1' : '0',
++ (beacon->capability & (1<<0x1)) ? '1' : '0',
++ (beacon->capability & (1<<0x0)) ? '1' : '0');
++
++ if (ieee80211_network_init(ieee, beacon, &network, stats)) {
++ IEEE80211_DEBUG_SCAN("Dropped '%s' (" MAC_FMT ") via %s.\n",
++ escape_essid(info_element->data,
++ info_element->len),
++ MAC_ARG(beacon->header.addr3),
++ WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
++ IEEE80211_STYPE_PROBE_RESP ?
++ "PROBE RESPONSE" : "BEACON");
++ return;
++ }
++
++#ifdef ENABLE_DOT11D
++ // For Asus EeePc request,
++ // (1) if wireless adapter receive get any 802.11d country code in AP beacon,
++ // wireless adapter should follow the country code.
++ // (2) If there is no any country code in beacon,
++ // then wireless adapter should do active scan from ch1~11 and
++ // passive scan from ch12~14
++ if(ieee->bGlobalDomain)
++ {
++ if (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_PROBE_RESP)
++ {
++ // Case 1: Country code
++ if(IS_COUNTRY_IE_VALID(ieee) )
++ {
++ if( !IsLegalChannel(ieee, network.channel) )
++ {
++ printk("GetScanInfo(): For Country code, filter probe response at channel(%d).\n", network.channel);
++ return;
++ }
++ }
++ // Case 2: No any country code.
++ else
++ {
++ // Filter over channel ch12~14
++ if(network.channel > 11)
++ {
++ printk("GetScanInfo(): For Global Domain, filter probe response at channel(%d).\n", network.channel);
++ return;
++ }
++ }
++ }
++ else
++ {
++ // Case 1: Country code
++ if(IS_COUNTRY_IE_VALID(ieee) )
++ {
++ if( !IsLegalChannel(ieee, network.channel) )
++ {
++ printk("GetScanInfo(): For Country code, filter beacon at channel(%d).\n",network.channel);
++ return;
++ }
++ }
++ // Case 2: No any country code.
++ else
++ {
++ // Filter over channel ch12~14
++ if(network.channel > 14)
++ {
++ printk("GetScanInfo(): For Global Domain, filter beacon at channel(%d).\n",network.channel);
++ return;
++ }
++ }
++ }
++ }
++
++ //lzm add 081205
++ // for Toshiba request, we use channel_plan COUNTRY_CODE_WORLD_WIDE_13_INDEX,
++ // For Liteon "World Wide 13" Domain name:ch1~11 active scan & ch12~13 passive scan
++ // So we shoud only rcv beacon in 12-13, and filter probe resp in 12-13.
++ if(ieee->MinPassiveChnlNum != MAX_CHANNEL_NUMBER+1)
++ {
++ if (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_PROBE_RESP)
++ {
++ // Filter over channel ch12~13
++ if(network.channel >= ieee->MinPassiveChnlNum)
++ {
++ printk("GetScanInfo(): passive scan, filter probe resp at channel(%d).\n", network.channel);
++ return;
++ }
++ }
++ }
++#endif
++
++
++ /* The network parsed correctly -- so now we scan our known networks
++ * to see if we can find it in our list.
++ *
++ * NOTE: This search is definitely not optimized. Once its doing
++ * the "right thing" we'll optimize it for efficiency if
++ * necessary */
++
++ /* Search for this entry in the list and update it if it is
++ * already there. */
++
++ spin_lock_irqsave(&ieee->lock, flags);
++
++ if(is_same_network(&ieee->current_network, &network, ieee)) {
++ //YJ,add,080819,for hidden ap
++ if(is_beacon == 0)
++ network.flags = (~NETWORK_EMPTY_ESSID & network.flags)|(NETWORK_EMPTY_ESSID & ieee->current_network.flags);
++ if ((ieee->state == IEEE80211_LINKED) && is_beacon)
++ ieee->NumRxBcnInPeriod++;
++ wmm_info = ieee->current_network.wmm_info;
++ update_network(&ieee->current_network, &network);
++ }
++
++ list_for_each_entry(target, &ieee->network_list, list) {
++ if (is_same_network(target, &network, ieee))
++ break;
++ if ((oldest == NULL) ||
++ (target->last_scanned < oldest->last_scanned))
++ oldest = target;
++ }
++
++ /* If we didn't find a match, then get a new network slot to initialize
++ * with this beacon's information */
++ if (&target->list == &ieee->network_list) {
++ if (list_empty(&ieee->network_free_list)) {
++ /* If there are no more slots, expire the oldest */
++ list_del(&oldest->list);
++ target = oldest;
++ IEEE80211_DEBUG_SCAN("Expired '%s' (" MAC_FMT ") from "
++ "network list.\n",
++ escape_essid(target->ssid,
++ target->ssid_len),
++ MAC_ARG(target->bssid));
++ } else {
++ /* Otherwise just pull from the free list */
++ target = list_entry(ieee->network_free_list.next,
++ struct ieee80211_network, list);
++ list_del(ieee->network_free_list.next);
++ }
++
++
++#ifdef CONFIG_IEEE80211_DEBUG
++ IEEE80211_DEBUG_SCAN("Adding '%s' (" MAC_FMT ") via %s.\n",
++ escape_essid(network.ssid,
++ network.ssid_len),
++ MAC_ARG(network.bssid),
++ WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
++ IEEE80211_STYPE_PROBE_RESP ?
++ "PROBE RESPONSE" : "BEACON");
++#endif
++
++#ifdef _RTL8187_EXT_PATCH_
++ network.ext_entry = target->ext_entry;
++#endif
++ memcpy(target, &network, sizeof(*target));
++ list_add_tail(&target->list, &ieee->network_list);
++ if(ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE)
++ ieee80211_softmac_new_net(ieee,&network);
++ } else {
++ IEEE80211_DEBUG_SCAN("Updating '%s' (" MAC_FMT ") via %s.\n",
++ escape_essid(target->ssid,
++ target->ssid_len),
++ MAC_ARG(target->bssid),
++ WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
++ IEEE80211_STYPE_PROBE_RESP ?
++ "PROBE RESPONSE" : "BEACON");
++
++ /* we have an entry and we are going to update it. But this entry may
++ * be already expired. In this case we do the same as we found a new
++ * net and call the new_net handler
++ */
++ renew = !time_after(target->last_scanned + ieee->scan_age, jiffies);
++ //YJ,add,080819,for hidden ap
++ if(is_beacon == 0)
++ network.flags = (~NETWORK_EMPTY_ESSID & network.flags)|(NETWORK_EMPTY_ESSID & target->flags);
++ //if(strncmp(network.ssid, "linksys-c",9) == 0)
++ // printk("====>2 network.ssid=%s FLAG=%d target.ssid=%s FLAG=%d\n", network.ssid, network.flags, target->ssid, target->flags);
++ if(((network.flags & NETWORK_EMPTY_ESSID) == NETWORK_EMPTY_ESSID) \
++ && (((network.ssid_len > 0) && (strncmp(target->ssid, network.ssid, network.ssid_len)))\
++ ||((ieee->current_network.ssid_len == network.ssid_len)&&(strncmp(ieee->current_network.ssid, network.ssid, network.ssid_len) == 0)&&(ieee->state == IEEE80211_NOLINK))))
++ renew = 1;
++ //YJ,add,080819,for hidden ap,end
++ update_network(target, &network);
++ if(renew && (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE))
++ ieee80211_softmac_new_net(ieee,&network);
++ }
++
++ spin_unlock_irqrestore(&ieee->lock, flags);
++}
++
++void ieee80211_rx_mgt(struct ieee80211_device *ieee,
++ struct ieee80211_hdr *header,
++ struct ieee80211_rx_stats *stats)
++{
++ switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
++
++ case IEEE80211_STYPE_BEACON:
++ IEEE80211_DEBUG_MGMT("received BEACON (%d)\n",
++ WLAN_FC_GET_STYPE(header->frame_ctl));
++ IEEE80211_DEBUG_SCAN("Beacon\n");
++ ieee80211_process_probe_response(
++ ieee, (struct ieee80211_probe_response *)header, stats);
++ break;
++
++ case IEEE80211_STYPE_PROBE_RESP:
++ IEEE80211_DEBUG_MGMT("received PROBE RESPONSE (%d)\n",
++ WLAN_FC_GET_STYPE(header->frame_ctl));
++ IEEE80211_DEBUG_SCAN("Probe response\n");
++ ieee80211_process_probe_response(
++ ieee, (struct ieee80211_probe_response *)header, stats);
++ break;
++//rz
++#ifdef _RTL8187_EXT_PATCH_
++ case IEEE80211_STYPE_PROBE_REQ:
++ IEEE80211_DEBUG_MGMT("received PROBE REQUEST (%d)\n",
++ WLAN_FC_GET_STYPE(header->frame_ctl));
++ IEEE80211_DEBUG_SCAN("Probe request\n");
++ ///
++ //printk("Probe request\n");
++ if( ieee->iw_mode == ieee->iw_ext_mode && ieee->ext_patch_ieee80211_rx_mgt_on_probe_req )
++ ieee->ext_patch_ieee80211_rx_mgt_on_probe_req( ieee, (struct ieee80211_probe_request *)header, stats);
++ break;
++#endif // _RTL8187_EXT_PATCH_
++
++ }
++}
++
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
++EXPORT_SYMBOL(ieee80211_rx_mgt);
++EXPORT_SYMBOL(ieee80211_rx);
++EXPORT_SYMBOL(ieee80211_network_init);
++#ifdef _RTL8187_EXT_PATCH_
++EXPORT_SYMBOL(ieee_ext_skb_p80211_to_ether);
++#endif
++#else
++EXPORT_SYMBOL_NOVERS(ieee80211_rx_mgt);
++EXPORT_SYMBOL_NOVERS(ieee80211_rx);
++EXPORT_SYMBOL_NOVERS(ieee80211_network_init);
++#ifdef _RTL8187_EXT_PATCH_
++EXPORT_SYMBOL_NOVERS(ieee_ext_skb_p80211_to_ether);
++#endif
++#endif
+diff --git a/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_softmac.c b/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_softmac.c
+new file mode 100644
+index 0000000..c4b8629
+--- /dev/null
++++ b/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_softmac.c
+@@ -0,0 +1,4083 @@
++/* IEEE 802.11 SoftMAC layer
++ * Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
++ *
++ * Mostly extracted from the rtl8180-sa2400 driver for the
++ * in-kernel generic ieee802.11 stack.
++ *
++ * Few lines might be stolen from other part of the ieee80211
++ * stack. Copyright who own it's copyright
++ *
++ * WPA code stolen from the ipw2200 driver.
++ * Copyright who own it's copyright.
++ *
++ * released under the GPL
++ */
++
++
++#include "ieee80211.h"
++
++#include <linux/random.h>
++#include <linux/delay.h>
++#include <linux/version.h>
++#include <asm/uaccess.h>
++
++#ifdef ENABLE_DOT11D
++#include "dot11d.h"
++#endif
++
++
++u8 rsn_authen_cipher_suite[16][4] = {
++ {0x00,0x0F,0xAC,0x00}, //Use group key, //Reserved
++ {0x00,0x0F,0xAC,0x01}, //WEP-40 //RSNA default
++ {0x00,0x0F,0xAC,0x02}, //TKIP //NONE //{used just as default}
++ {0x00,0x0F,0xAC,0x03}, //WRAP-historical
++ {0x00,0x0F,0xAC,0x04}, //CCMP
++ {0x00,0x0F,0xAC,0x05}, //WEP-104
++};
++
++short ieee80211_is_54g(struct ieee80211_network net)
++{
++ return ((net.rates_ex_len > 0) || (net.rates_len > 4));
++}
++
++short ieee80211_is_shortslot(struct ieee80211_network net)
++{
++ return (net.capability & WLAN_CAPABILITY_SHORT_SLOT);
++}
++
++/* returns the total length needed for pleacing the RATE MFIE
++ * tag and the EXTENDED RATE MFIE tag if needed.
++ * It encludes two bytes per tag for the tag itself and its len
++ */
++unsigned int ieee80211_MFIE_rate_len(struct ieee80211_device *ieee)
++{
++ unsigned int rate_len = 0;
++
++ if (ieee->modulation & IEEE80211_CCK_MODULATION)
++ rate_len = IEEE80211_CCK_RATE_LEN + 2;
++
++ if (ieee->modulation & IEEE80211_OFDM_MODULATION)
++
++ rate_len += IEEE80211_OFDM_RATE_LEN + 2;
++
++ return rate_len;
++}
++
++/* pleace the MFIE rate, tag to the memory (double) poined.
++ * Then it updates the pointer so that
++ * it points after the new MFIE tag added.
++ */
++void ieee80211_MFIE_Brate(struct ieee80211_device *ieee, u8 **tag_p)
++{
++ u8 *tag = *tag_p;
++
++ if (ieee->modulation & IEEE80211_CCK_MODULATION){
++ *tag++ = MFIE_TYPE_RATES;
++ *tag++ = 7;
++ *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
++ *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
++ *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
++ *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
++ //added for basic rate set
++ *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
++ *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
++ *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
++ }
++
++ /* We may add an option for custom rates that specific HW might support */
++ *tag_p = tag;
++}
++
++void ieee80211_MFIE_Grate(struct ieee80211_device *ieee, u8 **tag_p)
++{
++ u8 *tag = *tag_p;
++
++ if (ieee->modulation & IEEE80211_OFDM_MODULATION){
++
++ *tag++ = MFIE_TYPE_RATES_EX;
++ *tag++ = 5;
++ *tag++ = IEEE80211_OFDM_RATE_9MB;
++ *tag++ = IEEE80211_OFDM_RATE_18MB;
++ *tag++ = IEEE80211_OFDM_RATE_36MB;
++ *tag++ = IEEE80211_OFDM_RATE_48MB;
++ *tag++ = IEEE80211_OFDM_RATE_54MB;
++
++ }
++
++ /* We may add an option for custom rates that specific HW might support */
++ *tag_p = tag;
++}
++
++
++void ieee80211_WMM_Info(struct ieee80211_device *ieee, u8 **tag_p) {
++ u8 *tag = *tag_p;
++
++ *tag++ = MFIE_TYPE_GENERIC; //0
++ *tag++ = 7;
++ *tag++ = 0x00;
++ *tag++ = 0x50;
++ *tag++ = 0xf2;
++ *tag++ = 0x02;//5
++ *tag++ = 0x00;
++ *tag++ = 0x01;
++#ifdef SUPPORT_USPD
++ if(ieee->current_network.wmm_info & 0x80) {
++ *tag++ = 0x0f|MAX_SP_Len;
++ } else {
++ *tag++ = MAX_SP_Len;
++ }
++#else
++ *tag++ = MAX_SP_Len;
++#endif
++ *tag_p = tag;
++}
++
++#ifdef THOMAS_TURBO
++void ieee80211_TURBO_Info(struct ieee80211_device *ieee, u8 **tag_p) {
++ u8 *tag = *tag_p;
++
++ *tag++ = MFIE_TYPE_GENERIC; //0
++ *tag++ = 7;
++ *tag++ = 0x00;
++ *tag++ = 0xe0;
++ *tag++ = 0x4c;
++ *tag++ = 0x01;//5
++ *tag++ = 0x02;
++ *tag++ = 0x11;
++ *tag++ = 0x00;
++
++ *tag_p = tag;
++ printk(KERN_ALERT "This is enable turbo mode IE process\n");
++}
++#endif
++
++void enqueue_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb)
++{
++ int nh;
++ nh = (ieee->mgmt_queue_head +1) % MGMT_QUEUE_NUM;
++
++/*
++ * if the queue is full but we have newer frames then
++ * just overwrites the oldest.
++ *
++ * if (nh == ieee->mgmt_queue_tail)
++ * return -1;
++ */
++ ieee->mgmt_queue_head = nh;
++ ieee->mgmt_queue_ring[nh] = skb;
++
++ //return 0;
++}
++
++struct sk_buff *dequeue_mgmt(struct ieee80211_device *ieee)
++{
++ struct sk_buff *ret;
++
++ if(ieee->mgmt_queue_tail == ieee->mgmt_queue_head)
++ return NULL;
++
++ ret = ieee->mgmt_queue_ring[ieee->mgmt_queue_tail];
++
++ ieee->mgmt_queue_tail =
++ (ieee->mgmt_queue_tail+1) % MGMT_QUEUE_NUM;
++
++ return ret;
++}
++
++void init_mgmt_queue(struct ieee80211_device *ieee)
++{
++ ieee->mgmt_queue_tail = ieee->mgmt_queue_head = 0;
++}
++
++
++void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl);
++
++inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
++{
++ unsigned long flags;
++ short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
++ struct ieee80211_hdr_3addr *header=
++ (struct ieee80211_hdr_3addr *) skb->data;
++
++
++ spin_lock_irqsave(&ieee->lock, flags);
++
++ /* called with 2nd param 0, no mgmt lock required */
++ ieee80211_sta_wakeup(ieee,0);
++
++ if(single){
++ if(ieee->queue_stop){
++
++ enqueue_mgmt(ieee,skb);
++ }else{
++ header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4);
++
++ if (ieee->seq_ctrl[0] == 0xFFF)
++ ieee->seq_ctrl[0] = 0;
++ else
++ ieee->seq_ctrl[0]++;
++
++ /* avoid watchdog triggers */
++ ieee->dev->trans_start = jiffies;
++ ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
++// dev_kfree_skb_any(skb);//edit by thomas //'cause this function will cause Oops called in interrupt context in old version 101907
++#endif
++ }
++
++ spin_unlock_irqrestore(&ieee->lock, flags);
++ }else{
++ spin_unlock_irqrestore(&ieee->lock, flags);
++ spin_lock_irqsave(&ieee->mgmt_tx_lock, flags);
++
++ header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
++
++ if (ieee->seq_ctrl[0] == 0xFFF)
++ ieee->seq_ctrl[0] = 0;
++ else
++ ieee->seq_ctrl[0]++;
++
++ ieee->softmac_hard_start_xmit(skb,ieee->dev);
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
++// dev_kfree_skb_any(skb);//edit by thomas
++#endif
++ spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags);
++ }
++}
++
++
++inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
++{
++
++ short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
++ struct ieee80211_hdr_3addr *header =
++ (struct ieee80211_hdr_3addr *) skb->data;
++
++
++ if(single){
++
++ header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
++
++ if (ieee->seq_ctrl[0] == 0xFFF)
++ ieee->seq_ctrl[0] = 0;
++ else
++ ieee->seq_ctrl[0]++;
++
++ /* avoid watchdog triggers */
++ ieee->dev->trans_start = jiffies;
++ ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
++
++ }else{
++
++ header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
++
++ if (ieee->seq_ctrl[0] == 0xFFF)
++ ieee->seq_ctrl[0] = 0;
++ else
++ ieee->seq_ctrl[0]++;
++
++ ieee->softmac_hard_start_xmit(skb,ieee->dev);
++
++ }
++ dev_kfree_skb_any(skb);//edit by thomas
++}
++
++inline struct sk_buff *ieee80211_probe_req(struct ieee80211_device *ieee)
++{
++ unsigned int len,rate_len;
++ u8 *tag;
++ struct sk_buff *skb;
++ struct ieee80211_probe_request *req;
++
++#ifdef _RTL8187_EXT_PATCH_
++ short extMore = 0;
++ if(ieee->ext_patch_ieee80211_probe_req_1)
++ extMore = ieee->ext_patch_ieee80211_probe_req_1(ieee);
++#endif
++
++ len = ieee->current_network.ssid_len;
++
++ rate_len = ieee80211_MFIE_rate_len(ieee);
++
++#ifdef _RTL8187_EXT_PATCH_
++ if(!extMore)
++#endif
++ skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
++ 2 + len + rate_len);
++#ifdef _RTL8187_EXT_PATCH_
++ else
++ skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
++ 2 + len + rate_len+128); // MESHID + CAP
++#endif
++
++ if (!skb)
++ return NULL;
++
++ req = (struct ieee80211_probe_request *) skb_put(skb,sizeof(struct ieee80211_probe_request));
++ req->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
++ req->header.duration_id = 0; //FIXME: is this OK ?
++
++ memset(req->header.addr1, 0xff, ETH_ALEN);
++ memcpy(req->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
++ memset(req->header.addr3, 0xff, ETH_ALEN);
++
++ tag = (u8 *) skb_put(skb,len+2+rate_len);
++
++ *tag++ = MFIE_TYPE_SSID;
++ *tag++ = len;
++ memcpy(tag, ieee->current_network.ssid, len);
++ tag += len;
++
++ ieee80211_MFIE_Brate(ieee,&tag);
++ ieee80211_MFIE_Grate(ieee,&tag);
++
++#ifdef _RTL8187_EXT_PATCH_
++ if(extMore)
++ ieee->ext_patch_ieee80211_probe_req_2(ieee, skb, tag);
++#endif
++ return skb;
++}
++
++struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee);
++
++#ifdef _RTL8187_EXT_PATCH_
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
++void ext_ieee80211_send_beacon_wq(struct work_struct *work)
++{
++ struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, ext_send_beacon_wq);
++#else
++void ext_ieee80211_send_beacon_wq(struct ieee80211_device *ieee)
++{
++#endif
++
++ struct sk_buff *skb;
++
++ //unsigned long flags;
++// printk("=========>%s()\n", __FUNCTION__);
++ skb = ieee80211_get_beacon_(ieee);
++
++ if (skb){
++ softmac_mgmt_xmit(skb, ieee);
++ ieee->softmac_stats.tx_beacons++;
++ dev_kfree_skb_any(skb);//edit by thomas
++ }
++
++
++ //printk(KERN_WARNING "[1] beacon sending!\n");
++// ieee->beacon_timer.expires = jiffies +
++// (MSECS( ieee->current_network.beacon_interval -5));
++
++ //spin_lock_irqsave(&ieee->beacon_lock,flags);
++// if(ieee->beacon_txing)
++// add_timer(&ieee->beacon_timer);
++ //spin_unlock_irqrestore(&ieee->beacon_lock,flags);
++}
++#endif
++
++void ieee80211_send_beacon(struct ieee80211_device *ieee)
++{
++ struct sk_buff *skb;
++
++ //unsigned long flags;
++// printk("=========>%s()\n", __FUNCTION__);
++ skb = ieee80211_get_beacon_(ieee);
++
++ if (skb){
++ softmac_mgmt_xmit(skb, ieee);
++ ieee->softmac_stats.tx_beacons++;
++ dev_kfree_skb_any(skb);//edit by thomas
++ }
++
++
++ //printk(KERN_WARNING "[1] beacon sending!\n");
++ ieee->beacon_timer.expires = jiffies +
++ (MSECS( ieee->current_network.beacon_interval -5));
++
++ //spin_lock_irqsave(&ieee->beacon_lock,flags);
++ if(ieee->beacon_txing)
++ add_timer(&ieee->beacon_timer);
++ //spin_unlock_irqrestore(&ieee->beacon_lock,flags);
++}
++
++
++void ieee80211_send_beacon_cb(unsigned long _ieee)
++{
++ struct ieee80211_device *ieee =
++ (struct ieee80211_device *) _ieee;
++ unsigned long flags;
++
++ spin_lock_irqsave(&ieee->beacon_lock, flags);
++ ieee80211_send_beacon(ieee);
++ spin_unlock_irqrestore(&ieee->beacon_lock, flags);
++}
++
++#ifdef _RTL8187_EXT_PATCH_
++
++inline struct sk_buff *ieee80211_probe_req_with_SSID(struct ieee80211_device *ieee, char *ssid, int len_ssid)
++{
++ unsigned int len,rate_len;
++ u8 *tag;
++ struct sk_buff *skb;
++ struct ieee80211_probe_request *req;
++
++#ifdef _RTL8187_EXT_PATCH_
++ short extMore = 0;
++ if(ieee->ext_patch_ieee80211_probe_req_1)
++ extMore = ieee->ext_patch_ieee80211_probe_req_1(ieee);
++#endif
++
++ len = len_ssid;
++
++ rate_len = ieee80211_MFIE_rate_len(ieee);
++
++#ifdef _RTL8187_EXT_PATCH_
++ if(!extMore)
++#endif
++ skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
++ 2 + len + rate_len);
++#ifdef _RTL8187_EXT_PATCH_
++ else
++ skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
++ 2 + len + rate_len+128); // MESHID + CAP
++#endif
++
++ if (!skb)
++ return NULL;
++
++ req = (struct ieee80211_probe_request *) skb_put(skb,sizeof(struct ieee80211_probe_request));
++ req->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
++ req->header.duration_id = 0; //FIXME: is this OK ?
++
++ memset(req->header.addr1, 0xff, ETH_ALEN);
++ memcpy(req->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
++ memset(req->header.addr3, 0xff, ETH_ALEN);
++
++ tag = (u8 *) skb_put(skb,len+2+rate_len);
++
++ *tag++ = MFIE_TYPE_SSID;
++ *tag++ = len;
++ if(len)
++ {
++ memcpy(tag, ssid, len);
++ tag += len;
++ }
++
++ ieee80211_MFIE_Brate(ieee,&tag);
++ ieee80211_MFIE_Grate(ieee,&tag);
++
++#ifdef _RTL8187_EXT_PATCH_
++ if(extMore)
++ ieee->ext_patch_ieee80211_probe_req_2(ieee, skb, tag);
++#endif
++ return skb;
++}
++
++#endif // _RTL8187_EXT_PATCH_
++
++
++void ieee80211_send_probe(struct ieee80211_device *ieee)
++{
++ struct sk_buff *skb;
++
++#ifdef _RTL8187_EXT_PATCH_
++ if(ieee->iw_mode == ieee->iw_ext_mode)
++ skb = ieee80211_probe_req_with_SSID(ieee, NULL, 0);
++ else
++#endif
++ skb = ieee80211_probe_req(ieee);
++ if (skb){
++ softmac_mgmt_xmit(skb, ieee);
++ ieee->softmac_stats.tx_probe_rq++;
++ dev_kfree_skb_any(skb);//edit by thomas
++ }
++}
++
++void ieee80211_send_probe_requests(struct ieee80211_device *ieee)
++{
++ if (ieee->active_scan && (ieee->softmac_features & IEEE_SOFTMAC_PROBERQ)){
++ ieee80211_send_probe(ieee);
++ ieee80211_send_probe(ieee);
++ }
++}
++
++/* this performs syncro scan blocking the caller until all channels
++ * in the allowed channel map has been checked.
++ */
++void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee)
++{
++ short ch = 0;
++#ifdef ENABLE_DOT11D
++ u8 channel_map[MAX_CHANNEL_NUMBER+1];
++ memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
++#endif
++
++
++ down(&ieee->scan_sem);
++
++ while(1)
++ {
++
++ do{
++ ch++;
++ if (ch > MAX_CHANNEL_NUMBER)
++ goto out; /* scan completed */
++
++#ifdef ENABLE_DOT11D
++ }while(!channel_map[ch]);
++#else
++ }while(!ieee->channel_map[ch]);
++#endif
++
++ //printk("=>current channel is %d\n",ch);
++
++ /* this fuction can be called in two situations
++ * 1- We have switched to ad-hoc mode and we are
++ * performing a complete syncro scan before conclude
++ * there are no interesting cell and to create a
++ * new one. In this case the link state is
++ * IEEE80211_NOLINK until we found an interesting cell.
++ * If so the ieee8021_new_net, called by the RX path
++ * will set the state to IEEE80211_LINKED, so we stop
++ * scanning
++ * 2- We are linked and the root uses run iwlist scan.
++ * So we switch to IEEE80211_LINKED_SCANNING to remember
++ * that we are still logically linked (not interested in
++ * new network events, despite for updating the net list,
++ * but we are temporarly 'unlinked' as the driver shall
++ * not filter RX frames and the channel is changing.
++ * So the only situation in witch are interested is to check
++ * if the state become LINKED because of the #1 situation
++ */
++
++ if (ieee->state == IEEE80211_LINKED)
++ goto out;
++
++ //printk("---->%s: chan %d\n", __func__, ch);
++ ieee->set_chan(ieee->dev, ch);
++#ifdef ENABLE_DOT11D
++ if(channel_map[ch] == 1)
++#endif
++ {
++ ieee80211_send_probe_requests(ieee);
++ }
++
++ /* this prevent excessive time wait when we
++ * need to wait for a syncro scan to end..
++ */
++ if (ieee->sync_scan_hurryup)
++ goto out;
++
++
++ msleep_interruptible_rtl(IEEE80211_SOFTMAC_SCAN_TIME);
++
++ }
++out:
++ ieee->sync_scan_hurryup = 0;
++ up(&ieee->scan_sem);
++#ifdef ENABLE_DOT11D
++ if(IS_DOT11D_ENABLE(ieee))
++ DOT11D_ScanComplete(ieee);
++#endif
++
++}
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++/* called both by wq with ieee->lock held */
++void ieee80211_softmac_scan(struct ieee80211_device *ieee)
++{
++#if 0
++ short watchdog = 0;
++ do{
++ ieee->current_network.channel =
++ (ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER;
++ if (watchdog++ > MAX_CHANNEL_NUMBER)
++ return; /* no good chans */
++
++ }while(!ieee->channel_map[ieee->current_network.channel]);
++#endif
++
++ schedule_task(&ieee->softmac_scan_wq);
++}
++#endif
++
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
++void ieee80211_softmac_scan_wq(struct work_struct *work)
++{
++ struct delayed_work *dwork = container_of(work, struct delayed_work, work);
++ struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, softmac_scan_wq);
++#else
++void ieee80211_softmac_scan_wq(struct ieee80211_device *ieee)
++{
++#endif
++ //static short watchdog = 0;
++ //short watchdog = 0;//lzm move into ieee->scan_watchdog 081215 for roaming
++ u8 channel_bak = ieee->current_network.channel;//lzm for channel+1
++#ifdef ENABLE_DOT11D
++ u8 channel_map[MAX_CHANNEL_NUMBER+1];
++ memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
++#endif
++ down(&ieee->scan_sem);
++
++ do{
++ ieee->current_network.channel =
++ (ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER;
++ if (ieee->scan_watchdog++ > MAX_CHANNEL_NUMBER)
++ goto out; /* no good chans */
++#ifdef ENABLE_DOT11D
++ }while(!channel_map[ieee->current_network.channel]);
++#else
++ }while(!ieee->channel_map[ieee->current_network.channel]);
++#endif
++
++ if (ieee->scanning == 0 )
++ goto out;
++
++ //printk("current channel is %d\n",ieee->current_network.channel);
++ ieee->set_chan(ieee->dev, ieee->current_network.channel);
++#ifdef ENABLE_DOT11D
++ if(channel_map[ieee->current_network.channel] == 1)
++#endif
++ {
++ ieee80211_send_probe_requests(ieee);
++ }
++
++
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
++ queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, IEEE80211_SOFTMAC_SCAN_TIME);
++#else
++ ieee->scan_timer.expires = jiffies + (IEEE80211_SOFTMAC_SCAN_TIME);
++ if (ieee->scanning == 1)
++ add_timer(&ieee->scan_timer);
++#endif
++
++ up(&ieee->scan_sem);
++ return;
++out:
++ //printk("%s():Stop scan now\n",__FUNCTION__);
++ ieee->actscanning = false;
++ ieee->scan_watchdog = 0;
++ ieee->scanning = 0;
++ ieee->current_network.channel = channel_bak;
++ up(&ieee->scan_sem);
++#ifdef ENABLE_DOT11D
++ if(IS_DOT11D_ENABLE(ieee))
++ DOT11D_ScanComplete(ieee);
++#endif
++
++ return;
++}
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++void ieee80211_softmac_scan_cb(unsigned long _dev)
++{
++ unsigned long flags;
++ struct ieee80211_device *ieee = (struct ieee80211_device *)_dev;
++
++ spin_lock_irqsave(&ieee->lock, flags);
++ ieee80211_softmac_scan(ieee);
++ spin_unlock_irqrestore(&ieee->lock, flags);
++}
++#endif
++
++
++void ieee80211_beacons_start(struct ieee80211_device *ieee)
++{
++ unsigned long flags;
++
++ spin_lock_irqsave(&ieee->beacon_lock,flags);
++
++ ieee->beacon_txing = 1;
++ ieee80211_send_beacon(ieee);
++
++ spin_unlock_irqrestore(&ieee->beacon_lock,flags);
++}
++
++void ieee80211_beacons_stop(struct ieee80211_device *ieee)
++{
++ unsigned long flags;
++
++ spin_lock_irqsave(&ieee->beacon_lock,flags);
++
++ ieee->beacon_txing = 0;
++ del_timer_sync(&ieee->beacon_timer);
++
++ spin_unlock_irqrestore(&ieee->beacon_lock,flags);
++
++}
++
++
++void ieee80211_stop_send_beacons(struct ieee80211_device *ieee)
++{
++ if(ieee->stop_send_beacons)
++ ieee->stop_send_beacons(ieee->dev);
++ if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
++ ieee80211_beacons_stop(ieee);
++}
++
++
++void ieee80211_start_send_beacons(struct ieee80211_device *ieee)
++{
++ if(ieee->start_send_beacons)
++ ieee->start_send_beacons(ieee->dev);
++ if(ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
++ ieee80211_beacons_start(ieee);
++}
++
++
++void ieee80211_softmac_stop_scan(struct ieee80211_device *ieee)
++{
++// unsigned long flags;
++
++ ieee->sync_scan_hurryup = 1;
++
++ down(&ieee->scan_sem);
++// spin_lock_irqsave(&ieee->lock, flags);
++
++ if (ieee->scanning == 1){
++ //printk("%s():Stop scan now\n",__FUNCTION__);
++ ieee->scanning = 0;
++ //lzm add for softmac_scan_wq can't return from out
++ //example: rcv probe_response
++ ieee->scan_watchdog = 0;//lzm add 081215 for roaming
++ ieee->actscanning = false;
++
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
++ cancel_delayed_work(&ieee->softmac_scan_wq);
++#else
++ del_timer_sync(&ieee->scan_timer);
++#endif
++ }
++
++// spin_unlock_irqrestore(&ieee->lock, flags);
++ up(&ieee->scan_sem);
++}
++
++void ieee80211_stop_scan(struct ieee80211_device *ieee)
++{
++ if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
++ ieee80211_softmac_stop_scan(ieee);
++ else
++ ieee->stop_scan(ieee->dev);
++}
++
++/* called with ieee->lock held */
++void ieee80211_start_scan(struct ieee80211_device *ieee)
++{
++ ieee->actscanning = true;
++#ifdef CONFIG_IPS
++ ieee->ieee80211_ips_leave(ieee->dev);
++#endif
++
++#ifdef ENABLE_DOT11D
++ if(IS_DOT11D_ENABLE(ieee) )
++ {
++ if(IS_COUNTRY_IE_VALID(ieee))
++ {
++ RESET_CIE_WATCHDOG(ieee);
++ }
++ }
++#endif
++
++ if (ieee->softmac_features & IEEE_SOFTMAC_SCAN){
++ if (ieee->scanning == 0){
++ ieee->scanning = 1;
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
++ queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq,0);
++#else
++ ieee80211_softmac_scan(ieee);
++#endif
++ }
++ }else
++ ieee->start_scan(ieee->dev);
++
++}
++
++/* called with wx_sem held */
++void ieee80211_start_scan_syncro(struct ieee80211_device *ieee)
++{
++ //printk("====>%s()\n", __func__);
++#ifdef CONFIG_IPS
++ ieee->ieee80211_ips_leave(ieee->dev);
++#endif
++ ieee->actscanning = true;
++
++#ifdef ENABLE_DOT11D
++ if(IS_DOT11D_ENABLE(ieee) )
++ {
++ if(IS_COUNTRY_IE_VALID(ieee))
++ {
++ RESET_CIE_WATCHDOG(ieee);
++ }
++ }
++#endif
++
++ ieee->sync_scan_hurryup = 0;
++
++ if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
++ ieee80211_softmac_scan_syncro(ieee);
++ else
++ ieee->scan_syncro(ieee->dev);
++
++ ieee->actscanning = false;
++ //printk("<====%s()\n", __func__);
++}
++
++inline struct sk_buff *ieee80211_authentication_req(struct ieee80211_network *beacon,
++ struct ieee80211_device *ieee, int challengelen)
++{
++ struct sk_buff *skb;
++ struct ieee80211_authentication *auth;
++
++ skb = dev_alloc_skb(sizeof(struct ieee80211_authentication) + challengelen);
++
++ if (!skb) return NULL;
++
++ auth = (struct ieee80211_authentication *)
++ skb_put(skb, sizeof(struct ieee80211_authentication));
++
++ auth->header.frame_ctl = IEEE80211_STYPE_AUTH;
++ if (challengelen) auth->header.frame_ctl |= IEEE80211_FCTL_WEP;
++
++ auth->header.duration_id = 0x013a; //FIXME
++
++ memcpy(auth->header.addr1, beacon->bssid, ETH_ALEN);
++ memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
++ memcpy(auth->header.addr3, beacon->bssid, ETH_ALEN);
++
++ auth->algorithm = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
++
++ auth->transaction = cpu_to_le16(ieee->associate_seq);
++ ieee->associate_seq++;
++
++ auth->status = cpu_to_le16(WLAN_STATUS_SUCCESS);
++
++ return skb;
++
++}
++
++u8 WPA_OUI[3] = {0x00, 0x50, 0xf2};
++
++static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *dest)
++{
++ u8 *tag;
++ int beacon_size;
++ struct ieee80211_probe_response *beacon_buf;
++ struct sk_buff *skb;
++ int encrypt;
++ int atim_len,erp_len;
++ struct ieee80211_crypt_data* crypt;
++
++ char *ssid = ieee->current_network.ssid;
++ int ssid_len = ieee->current_network.ssid_len;
++ int rate_len = ieee->current_network.rates_len+2;
++ int rate_ex_len = ieee->current_network.rates_ex_len;
++
++ int wpa_ie_len = 0, wpa_type=0;
++ if(rate_ex_len > 0) rate_ex_len+=2;
++
++ if(ieee->current_network.capability & WLAN_CAPABILITY_IBSS)
++ atim_len = 4;
++ else
++ atim_len = 0;
++
++ if(ieee80211_is_54g(ieee->current_network))
++ erp_len = 3;
++ else
++ erp_len = 0;
++ if (ieee->wpa_enabled)
++ {
++ // printk("hoho wpa_enalbe\n");
++ wpa_ie_len = ieee->wpa_ie_len; //24-2
++ }
++ beacon_size = sizeof(struct ieee80211_probe_response)+
++ ssid_len
++ +3 //channel
++ +rate_len
++ +rate_ex_len
++ +atim_len
++ +erp_len
++ +wpa_ie_len;
++
++ skb = dev_alloc_skb(beacon_size);
++
++ if (!skb)
++ return NULL;
++
++ beacon_buf = (struct ieee80211_probe_response*) skb_put(skb, beacon_size);
++
++ memcpy (beacon_buf->header.addr1, dest,ETH_ALEN);
++ memcpy (beacon_buf->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
++ memcpy (beacon_buf->header.addr3, ieee->current_network.bssid, ETH_ALEN);
++
++ beacon_buf->header.duration_id = 0; //FIXME
++ beacon_buf->beacon_interval =
++ cpu_to_le16(ieee->current_network.beacon_interval);
++ beacon_buf->capability =
++ cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_IBSS);
++
++ if(ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT))
++ cpu_to_le16((beacon_buf->capability |= WLAN_CAPABILITY_SHORT_SLOT));
++#ifdef _RTL8187_EXT_PATCH_
++{
++/* struct ieee80211_crypt_data_list* cryptlist = ieee->cryptlist[1];
++ u8 i = cryptlist->used;
++ crypt = cryptlist ->crypt[ieee->tx_keyidx];
++*/
++ crypt = ieee->cryptlist[0]->crypt[ieee->tx_keyidx];
++}
++#else
++
++ crypt = ieee->crypt[ieee->tx_keyidx];
++#endif
++ if (crypt)
++ wpa_type = strcmp(crypt->ops->name, "TKIP");
++
++
++ encrypt = ieee->host_encrypt && crypt && crypt->ops &&
++ ((0 == strcmp(crypt->ops->name, "WEP")||wpa_ie_len));
++
++ if (encrypt)
++ beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
++
++
++ beacon_buf->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_RESP);
++
++ beacon_buf->info_element.id = MFIE_TYPE_SSID;
++ beacon_buf->info_element.len = ssid_len;
++
++ tag = (u8*) beacon_buf->info_element.data;
++
++ memcpy(tag, ssid, ssid_len);
++
++ tag += ssid_len;
++
++ *(tag++) = MFIE_TYPE_RATES;
++ *(tag++) = rate_len-2;
++ memcpy(tag,ieee->current_network.rates,rate_len-2);
++ tag+=rate_len-2;
++
++ *(tag++) = MFIE_TYPE_DS_SET;
++ *(tag++) = 1;
++ *(tag++) = ieee->current_network.channel;
++
++ if(atim_len){
++ u16 val16;
++ *(tag++) = MFIE_TYPE_IBSS_SET;
++ *(tag++) = 2;
++ val16 = cpu_to_le16(ieee->current_network.atim_window);
++ //*((u16*)(tag)) = cpu_to_le16(ieee->current_network.atim_window);
++ memcpy((u8 *)tag,(u8 *)&val16,2);
++ tag+=2;
++ }
++
++ if(erp_len){
++ *(tag++) = MFIE_TYPE_ERP;
++ *(tag++) = 1;
++ *(tag++) = 0;
++ }
++
++ if(rate_ex_len){
++ *(tag++) = MFIE_TYPE_RATES_EX;
++ *(tag++) = rate_ex_len-2;
++ memcpy(tag,ieee->current_network.rates_ex,rate_ex_len-2);
++ tag+=rate_ex_len-2;
++ }
++ if (wpa_ie_len)
++ {
++#if 0
++ *(tag++) = 0xdd;
++ *(tag++) = wpa_ie_len-2;
++ memcpy(tag, WPA_OUI, 3);
++ tag += 3;
++ *(tag++) = 1;
++ *(tag++) = 1;
++ *(tag++) = 0;
++
++ memcpy(tag, WPA_OUI, 3);
++ tag += 3;
++ *(tag++) = wpa_type ? 4:2;
++ *(tag++) = 1;
++ *(tag++) = 0;
++
++
++ memcpy(tag, WPA_OUI, 3);
++ tag += 3;
++ *(tag++) = wpa_type ? 4:0;
++ *(tag++) = 1;
++ *(tag++) = 0;
++
++ memcpy(tag, WPA_OUI, 3);
++ tag += 3;
++ *(tag++) = 0;
++#else
++ if (ieee->iw_mode == IW_MODE_ADHOC)
++ {//as Windows will set pairwise key same as the group key which is not allowed in Linux, so set this for IOT issue. WB 2008.07.07
++ memcpy(&ieee->wpa_ie[14], &ieee->wpa_ie[8], 4);
++ }
++
++ memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
++
++#endif
++ }
++
++
++ skb->dev = ieee->dev;
++ return skb;
++}
++
++
++#ifdef _RTL8187_EXT_PATCH_
++struct sk_buff* ieee80211_ext_probe_resp_by_net(struct ieee80211_device *ieee, u8 *dest, struct ieee80211_network *net)
++{
++ u8 *tag;
++ int beacon_size;
++ struct ieee80211_probe_response *beacon_buf;
++ struct sk_buff *skb;
++ int encrypt;
++ int atim_len,erp_len;
++ struct ieee80211_crypt_data* crypt;
++ u8 broadcast_addr[] = {0xff,0xff,0xff,0xff,0xff,0xff};
++
++ char *ssid = net->ssid;
++ int ssid_len = net->ssid_len;
++
++ int rate_len = ieee->current_network.rates_len+2;
++ int rate_ex_len = ieee->current_network.rates_ex_len;
++ int wpa_ie_len = 0, wpa_type=0;
++ if(rate_ex_len > 0) rate_ex_len+=2;
++
++ if( ieee->meshScanMode&4)
++ ieee->current_network.channel = ieee->ext_patch_ieee80211_ext_stop_scan_wq_set_channel(ieee);
++ if( ieee->meshScanMode&6)
++ {
++
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
++ queue_work(ieee->wq, &ieee->ext_stop_scan_wq);
++#else
++ schedule_task(&ieee->ext_stop_scan_wq);
++#endif
++ }
++ if(ieee->current_network.capability & WLAN_CAPABILITY_IBSS) // use current_network here
++ atim_len = 4;
++ else
++ atim_len = 0;
++
++ if(ieee80211_is_54g(*net))
++ erp_len = 3;
++ else
++ erp_len = 0;
++
++ if (ieee->wpa_enabled &&(ieee->iw_ext_mode==ieee->iw_mode))
++ {
++// printk("hoho wpa_enalbe\n");
++ wpa_ie_len = ieee->wpa_ie_len; //24-2
++ }
++
++ beacon_size = sizeof(struct ieee80211_probe_response)+
++ ssid_len
++ +3 //channel
++ +rate_len
++ +rate_ex_len
++ +atim_len
++ +erp_len
++ +wpa_ie_len;
++//b
++ skb = dev_alloc_skb(beacon_size+196);
++
++ if (!skb)
++ return NULL;
++
++ beacon_buf = (struct ieee80211_probe_response*) skb_put(skb, beacon_size);
++
++ memcpy (beacon_buf->header.addr1, dest,ETH_ALEN);
++ memcpy (beacon_buf->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
++ memcpy (beacon_buf->header.addr3, ieee->current_network.bssid, ETH_ALEN);
++
++ beacon_buf->header.duration_id = 0; //FIXME
++
++ beacon_buf->beacon_interval =
++ cpu_to_le16(ieee->current_network.beacon_interval); // use current_network here
++ beacon_buf->capability =
++ cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_IBSS);
++
++ if(ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT))
++ cpu_to_le16((beacon_buf->capability |= WLAN_CAPABILITY_SHORT_SLOT));
++#ifdef _RTL8187_EXT_PATCH_
++
++ crypt = ieee->cryptlist[0]->crypt[ieee->tx_keyidx];
++#else
++
++ crypt = ieee->crypt[ieee->tx_keyidx];
++#endif
++
++// crypt = ieee->crypt[ieee->tx_keyidx];
++ if (crypt)
++ wpa_type = strcmp(crypt->ops->name, "TKIP");
++
++ encrypt = ieee->host_encrypt && crypt && crypt->ops &&
++ ((0 == strcmp(crypt->ops->name, "WEP")||wpa_ie_len));
++
++ if (encrypt)
++ beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
++
++
++ beacon_buf->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_RESP);
++
++ beacon_buf->info_element.id = MFIE_TYPE_SSID;
++ beacon_buf->info_element.len = ssid_len;
++
++ tag = (u8*) beacon_buf->info_element.data;
++
++ // brocad cast / probe rsp
++ if(memcmp(dest, broadcast_addr, ETH_ALEN ))
++ memcpy(tag, ssid, ssid_len);
++ else
++ ssid_len=0;
++
++ tag += ssid_len;
++
++//get_bssrate_set(priv, _SUPPORTEDRATES_IE_, &pbssrate, &bssrate_len);
++//pbuf = set_ie(pbuf, _SUPPORTEDRATES_IE_, bssrate_len, pbssrate, &frlen);
++
++ *(tag++) = MFIE_TYPE_RATES;
++ *(tag++) = rate_len-2;
++ memcpy(tag,ieee->current_network.rates,rate_len-2);
++ tag+=rate_len-2;
++
++ *(tag++) = MFIE_TYPE_DS_SET;
++ *(tag++) = 1;
++ *(tag++) = ieee->current_network.channel; // use current_network here
++
++
++ if(atim_len){
++ *(tag++) = MFIE_TYPE_IBSS_SET;
++ *(tag++) = 2;
++ *((u16*)(tag)) = cpu_to_le16(ieee->current_network.atim_window); // use current_network here
++ tag+=2;
++ }
++
++ if(erp_len){
++ *(tag++) = MFIE_TYPE_ERP;
++ *(tag++) = 1;
++ *(tag++) = 0;
++ }
++
++ if(rate_ex_len){
++ *(tag++) = MFIE_TYPE_RATES_EX;
++ *(tag++) = rate_ex_len-2;
++ memcpy(tag,ieee->current_network.rates_ex,rate_ex_len-2);
++ tag+=rate_ex_len-2;
++ }
++
++ if (wpa_ie_len)
++ {
++#if 0
++ *(tag++) = 0xdd;
++ *(tag++) = wpa_ie_len-2;
++ memcpy(tag, WPA_OUI, 3);
++ tag += 3;
++ *(tag++) = 1;
++ *(tag++) = 1;
++ *(tag++) = 0;
++
++ memcpy(tag, WPA_OUI, 3);
++ tag += 3;
++ *(tag++) = wpa_type ? 4:2;
++ *(tag++) = 1;
++ *(tag++) = 0;
++
++
++ memcpy(tag, WPA_OUI, 3);
++ tag += 3;
++ *(tag++) = wpa_type ? 4:0;
++ *(tag++) = 1;
++ *(tag++) = 0;
++
++ memcpy(tag, WPA_OUI, 3);
++ tag += 3;
++ *(tag++) = 0;
++#else
++ memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
++#endif
++ }
++
++
++ skb->dev = ieee->dev;
++ return skb;
++}
++#endif // _RTL8187_EXT_PATCH_
++
++
++struct sk_buff* ieee80211_assoc_resp(struct ieee80211_device *ieee, u8 *dest)
++{
++ struct sk_buff *skb;
++ u8* tag;
++
++ struct ieee80211_crypt_data* crypt;
++ struct ieee80211_assoc_response_frame *assoc;
++ short encrypt;
++
++ unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
++ int len = sizeof(struct ieee80211_assoc_response_frame) + rate_len;
++
++ skb = dev_alloc_skb(len);
++
++ if (!skb)
++ return NULL;
++
++ assoc = (struct ieee80211_assoc_response_frame *)
++ skb_put(skb,sizeof(struct ieee80211_assoc_response_frame));
++
++ assoc->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP);
++ memcpy(assoc->header.addr1, dest,ETH_ALEN);
++ memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
++ memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
++ assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ?
++ WLAN_CAPABILITY_BSS : WLAN_CAPABILITY_IBSS);
++
++
++ if(ieee->short_slot)
++ assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
++
++ if (ieee->host_encrypt){
++#ifdef _RTL8187_EXT_PATCH_
++ crypt = ieee->cryptlist[0]->crypt[ieee->tx_keyidx];
++#else
++ crypt = ieee->crypt[ieee->tx_keyidx];
++#endif
++ }
++ else crypt = NULL;
++
++ encrypt = ( crypt && crypt->ops);
++
++ if (encrypt)
++ assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
++
++ assoc->status = 0;
++ assoc->aid = cpu_to_le16(ieee->assoc_id);
++ if (ieee->assoc_id == 0x2007) ieee->assoc_id=0;
++ else ieee->assoc_id++;
++
++ tag = (u8*) skb_put(skb, rate_len);
++
++ ieee80211_MFIE_Brate(ieee, &tag);
++ ieee80211_MFIE_Grate(ieee, &tag);
++
++ return skb;
++}
++
++struct sk_buff* ieee80211_auth_resp(struct ieee80211_device *ieee,int status, u8 *dest)
++{
++ struct sk_buff *skb;
++ struct ieee80211_authentication *auth;
++
++ skb = dev_alloc_skb(sizeof(struct ieee80211_authentication)+1);
++
++ if (!skb)
++ return NULL;
++
++ skb->len = sizeof(struct ieee80211_authentication);
++
++ auth = (struct ieee80211_authentication *)skb->data;
++
++ auth->status = cpu_to_le16(status);
++ auth->transaction = cpu_to_le16(2);
++ auth->algorithm = cpu_to_le16(WLAN_AUTH_OPEN);
++
++#ifdef _RTL8187_EXT_PATCH_
++ if(ieee->iw_mode == ieee->iw_ext_mode)
++ memcpy(auth->header.addr3, dest, ETH_ALEN);
++#else
++ memcpy(auth->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
++#endif
++ memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
++ memcpy(auth->header.addr1, dest, ETH_ALEN);
++ auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH);
++ return skb;
++
++
++}
++
++struct sk_buff* ieee80211_null_func(struct ieee80211_device *ieee,short pwr)
++{
++ struct sk_buff *skb;
++ struct ieee80211_hdr_3addr* hdr;
++
++ skb = dev_alloc_skb(sizeof(struct ieee80211_hdr_3addr));
++
++ if (!skb)
++ return NULL;
++
++ hdr = (struct ieee80211_hdr_3addr*)skb_put(skb,sizeof(struct ieee80211_hdr_3addr));
++
++ memcpy(hdr->addr1, ieee->current_network.bssid, ETH_ALEN);
++ memcpy(hdr->addr2, ieee->dev->dev_addr, ETH_ALEN);
++ memcpy(hdr->addr3, ieee->current_network.bssid, ETH_ALEN);
++
++ hdr->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA |
++ IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS |
++ (pwr ? IEEE80211_FCTL_PM:0));
++
++ return skb;
++
++
++}
++
++
++void ieee80211_resp_to_assoc_rq(struct ieee80211_device *ieee, u8* dest)
++{
++ struct sk_buff *buf = ieee80211_assoc_resp(ieee, dest);
++
++ if (buf){
++ softmac_mgmt_xmit(buf, ieee);
++ dev_kfree_skb_any(buf);//edit by thomas
++ }
++}
++
++
++void ieee80211_resp_to_auth(struct ieee80211_device *ieee, int s, u8* dest)
++{
++ struct sk_buff *buf = ieee80211_auth_resp(ieee, s, dest);
++
++ if (buf){
++ softmac_mgmt_xmit(buf, ieee);
++ dev_kfree_skb_any(buf);//edit by thomas
++ }
++}
++
++
++void ieee80211_resp_to_probe(struct ieee80211_device *ieee, u8 *dest)
++{
++
++ struct sk_buff *buf = ieee80211_probe_resp(ieee, dest);
++
++ if (buf) {
++ softmac_mgmt_xmit(buf, ieee);
++ dev_kfree_skb_any(buf);//edit by thomas
++ }
++}
++
++
++inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beacon,struct ieee80211_device *ieee)
++{
++ struct sk_buff *skb;
++
++ struct ieee80211_assoc_request_frame *hdr;
++ u8 *tag;
++ //int i;
++ unsigned int wpa_len = beacon->wpa_ie_len;
++#if 1
++ // for testing purpose
++ unsigned int rsn_len = beacon->rsn_ie_len;
++#else
++ unsigned int rsn_len = beacon->rsn_ie_len - 4;
++#endif
++ unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
++ unsigned int wmm_info_len = beacon->QoS_Enable?9:0;
++#ifdef THOMAS_TURBO
++ unsigned int turbo_info_len = beacon->Turbo_Enable?9:0;
++#endif
++
++ u8 encry_proto = ieee->wpax_type_notify & 0xff;
++
++
++ int len = 0;
++
++ //[0] Notify type of encryption: WPA/WPA2
++ //[1] pair wise type
++ //[2] authen type
++ if(ieee->wpax_type_set) {
++ if (IEEE_PROTO_WPA == encry_proto) {
++ rsn_len = 0;
++ } else if (IEEE_PROTO_RSN == encry_proto) {
++ wpa_len = 0;
++ }
++ }
++#ifdef THOMAS_TURBO
++ len = sizeof(struct ieee80211_assoc_request_frame)+
++ + beacon->ssid_len//essid tagged val
++ + rate_len//rates tagged val
++ + wpa_len
++ + rsn_len
++ + wmm_info_len
++ + turbo_info_len;
++#else
++ len = sizeof(struct ieee80211_assoc_request_frame)+
++ + beacon->ssid_len//essid tagged val
++ + rate_len//rates tagged val
++ + wpa_len
++ + rsn_len
++ + wmm_info_len;
++#endif
++
++#ifdef _RTL8187_EXT_PATCH_
++ if(ieee->iw_mode == ieee->iw_ext_mode)
++ skb = dev_alloc_skb(len+256); // stanley
++ else
++#endif
++ skb = dev_alloc_skb(len);
++
++ if (!skb)
++ return NULL;
++
++ hdr = (struct ieee80211_assoc_request_frame *)
++ skb_put(skb, sizeof(struct ieee80211_assoc_request_frame));
++
++
++ hdr->header.frame_ctl = IEEE80211_STYPE_ASSOC_REQ;
++ hdr->header.duration_id= 37; //FIXME
++ memcpy(hdr->header.addr1, beacon->bssid, ETH_ALEN);
++ memcpy(hdr->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
++ memcpy(hdr->header.addr3, beacon->bssid, ETH_ALEN);
++ memcpy(ieee->ap_mac_addr, beacon->bssid, ETH_ALEN);//for HW security, John
++
++ hdr->capability = cpu_to_le16(WLAN_CAPABILITY_BSS);
++ if (beacon->capability & WLAN_CAPABILITY_PRIVACY )
++ hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
++
++ if (beacon->capability & WLAN_CAPABILITY_SHORT_PREAMBLE )
++ hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE);
++
++ if(ieee->short_slot)
++ hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
++
++#ifdef _RTL8187_EXT_PATCH_
++ if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_association_req_1)
++ ieee->ext_patch_ieee80211_association_req_1(hdr);
++#endif
++
++ hdr->listen_interval = 0xa; //FIXME
++
++ hdr->info_element.id = MFIE_TYPE_SSID;
++
++ hdr->info_element.len = beacon->ssid_len;
++ tag = skb_put(skb, beacon->ssid_len);
++ memcpy(tag, beacon->ssid, beacon->ssid_len);
++
++ tag = skb_put(skb, rate_len);
++
++ ieee80211_MFIE_Brate(ieee, &tag);
++ ieee80211_MFIE_Grate(ieee, &tag);
++
++ //add rsn==0 condition for ap's mix security mode(wpa+wpa2), john2007.8.9
++ //choose AES encryption as default algorithm while using mixed mode
++#if 0
++ if(rsn_len == 0){
++
++ tag = skb_put(skb,wpa_len);
++
++ if(wpa_len) {
++
++
++ //{add by david. 2006.8.31
++ //fix linksys compatibility bug
++ //}
++ if(wpa_len > 24) {//22+2, mean include the capability
++ beacon->wpa_ie[wpa_len - 2] = 0;
++ }
++ //multicast cipher OUI
++ if( beacon->wpa_ie[11]==0x2 ){ //0x0050f202 is the oui of tkip
++ ieee->broadcast_key_type = KEY_TYPE_TKIP;
++ }
++ else if( beacon->wpa_ie[11]==0x4 ){//0x0050f204 is the oui of ccmp
++ ieee->broadcast_key_type = KEY_TYPE_CCMP;
++ }
++ //unicast cipher OUI
++ if( beacon->wpa_ie[14]==0
++ && beacon->wpa_ie[15]==0x50
++ && beacon->wpa_ie[16]==0xf2
++ && beacon->wpa_ie[17]==0x2 ){ //0x0050f202 is the oui of tkip
++ ieee->pairwise_key_type = KEY_TYPE_TKIP;
++ }
++
++ else if( beacon->wpa_ie[14]==0
++ && beacon->wpa_ie[15]==0x50
++ && beacon->wpa_ie[16]==0xf2
++ && beacon->wpa_ie[17]==0x4 ){//0x0050f204 is the oui of ccmp
++ ieee->pairwise_key_type = KEY_TYPE_CCMP;
++ }
++ //indicate the wpa_ie content to WPA_SUPPLICANT
++ buff = kmalloc(IW_CUSTOM_MAX, GFP_ATOMIC);
++ memset(buff, 0, IW_CUSTOM_MAX);
++ p=buff;
++ p += sprintf(p, "ASSOCINFO(ReqIEs=");
++ for(i=0;i<wpa_len;i++){
++ p += sprintf(p, "%02x", beacon->wpa_ie[i]);
++ }
++ p += sprintf(p, ")");
++ memset(&wrqu, 0, sizeof(wrqu) );
++ wrqu.data.length = p - buff;
++
++ wireless_send_event(dev, IWEVCUSTOM, &wrqu, buff);
++ memcpy(tag,beacon->wpa_ie,wpa_len);
++ }
++
++ }
++
++ if(rsn_len > 22) {
++
++ if( beacon->rsn_ie[4]==0x0 &&
++ beacon->rsn_ie[5]==0xf &&
++ beacon->rsn_ie[6]==0xac){
++
++ switch(beacon->rsn_ie[7]){
++ case 0x1:
++ ieee->broadcast_key_type = KEY_TYPE_WEP40;
++ break;
++ case 0x2:
++ ieee->broadcast_key_type = KEY_TYPE_TKIP;
++ break;
++ case 0x4:
++ ieee->broadcast_key_type = KEY_TYPE_CCMP;
++ break;
++ case 0x5:
++ ieee->broadcast_key_type = KEY_TYPE_WEP104;
++ break;
++ default:
++ printk("fault suite type in RSN broadcast key\n");
++ break;
++ }
++ }
++
++ if( beacon->rsn_ie[10]==0x0 &&
++ beacon->rsn_ie[11]==0xf &&
++ beacon->rsn_ie[12]==0xac){
++ if(beacon->rsn_ie[8]==1){//not mixed mode
++ switch(beacon->rsn_ie[13]){
++ case 0x2:
++ ieee->pairwise_key_type = KEY_TYPE_TKIP;
++ break;
++ case 0x4:
++ ieee->pairwise_key_type = KEY_TYPE_CCMP;
++ break;
++ default:
++ printk("fault suite type in RSN pairwise key\n");
++ break;
++ }
++ }
++ else if(beacon->rsn_ie[8]==2){//mixed mode
++ ieee->pairwise_key_type = KEY_TYPE_CCMP;
++ }
++ }
++
++
++
++ tag = skb_put(skb,22);
++ memcpy(tag,(beacon->rsn_ie + info_addr),8);
++ tag[1] = 20;
++ tag += 8;
++ info_addr += 8;
++
++ spin_lock_irqsave(&ieee->wpax_suitlist_lock,flags);
++ for (i = 0; i < 2; i++) {
++ tag[0] = 1;
++ tag[1] = 0;
++ tag += 2;
++ suite_count = beacon->rsn_ie[info_addr] + \
++ (beacon->rsn_ie[info_addr + 1] << 8);
++ info_addr += 2;
++ if(1 == suite_count) {
++ memcpy(tag,(beacon->rsn_ie + info_addr),4);
++ info_addr += 4;
++ } else {
++ // if the wpax_type_notify has been set by the application,
++ // just use it, otherwise just use the default one.
++ if(ieee->wpax_type_set) {
++ suit_select = ((0 == i) ? pairwise_type:authen_type)&0x0f ;
++ memcpy(tag,rsn_authen_cipher_suite[suit_select],4);
++ } else {
++ //default set as ccmp, or none authentication
++ if(i == 0) {
++ memcpy(tag,rsn_authen_cipher_suite[4],4);
++ } else {
++ memcpy(tag,rsn_authen_cipher_suite[2],4);
++ }
++
++ }
++
++ info_addr += (suite_count * 4);
++ }
++ tag += 4;
++ }
++ spin_unlock_irqrestore(&ieee->wpax_suitlist_lock,flags);
++
++ tag[0] = 0;
++ tag[1] = beacon->rsn_ie[info_addr+1];
++
++
++
++ } else {
++ tag = skb_put(skb,rsn_len);
++ if(rsn_len) {
++
++
++ if( beacon->rsn_ie[4]==0x0 &&
++ beacon->rsn_ie[5]==0xf &&
++ beacon->rsn_ie[6]==0xac){
++ switch(beacon->rsn_ie[7]){
++ case 0x1:
++ ieee->broadcast_key_type = KEY_TYPE_WEP40;
++ break;
++ case 0x2:
++ ieee->broadcast_key_type = KEY_TYPE_TKIP;
++ break;
++ case 0x4:
++ ieee->broadcast_key_type = KEY_TYPE_CCMP;
++ break;
++ case 0x5:
++ ieee->broadcast_key_type = KEY_TYPE_WEP104;
++ break;
++ default:
++ printk("fault suite type in RSN broadcast key\n");
++ break;
++ }
++ }
++ if( beacon->rsn_ie[10]==0x0 &&
++ beacon->rsn_ie[11]==0xf &&
++ beacon->rsn_ie[12]==0xac){
++ if(beacon->rsn_ie[8]==1){//not mixed mode
++ switch(beacon->rsn_ie[13]){
++ case 0x2:
++ ieee->pairwise_key_type = KEY_TYPE_TKIP;
++ break;
++ case 0x4:
++ ieee->pairwise_key_type = KEY_TYPE_CCMP;
++ break;
++ default:
++ printk("fault suite type in RSN pairwise key\n");
++ break;
++ }
++
++ }
++ else if(beacon->rsn_ie[8]==2){//mixed mode
++ ieee->pairwise_key_type = KEY_TYPE_CCMP;
++ }
++ }
++
++
++ beacon->rsn_ie[rsn_len - 2] = 0;
++ memcpy(tag,beacon->rsn_ie,rsn_len);
++ }
++ }
++#else
++ if (ieee->wpa_ie){
++ tag = skb_put(skb,ieee->wpa_ie_len);
++ memcpy(tag,ieee->wpa_ie,ieee->wpa_ie_len);
++ }
++#endif
++ tag = skb_put(skb,wmm_info_len);
++ if(wmm_info_len) {
++ ieee80211_WMM_Info(ieee, &tag);
++ }
++#ifdef THOMAS_TURBO
++ tag = skb_put(skb,turbo_info_len);
++ if(turbo_info_len) {
++ ieee80211_TURBO_Info(ieee, &tag);
++ }
++#endif
++
++#ifdef _RTL8187_EXT_PATCH_
++ if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_association_req_2)
++ ieee->ext_patch_ieee80211_association_req_2(ieee, beacon, skb);
++#endif
++
++ return skb;
++}
++
++void ieee80211_associate_abort(struct ieee80211_device *ieee)
++{
++
++ unsigned long flags;
++ spin_lock_irqsave(&ieee->lock, flags);
++
++ ieee->associate_seq++;
++
++ /* don't scan, and avoid to have the RX path possibily
++ * try again to associate. Even do not react to AUTH or
++ * ASSOC response. Just wait for the retry wq to be scheduled.
++ * Here we will check if there are good nets to associate
++ * with, so we retry or just get back to NO_LINK and scanning
++ */
++ if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING){
++ IEEE80211_DEBUG_MGMT("Authentication failed\n");
++ ieee->softmac_stats.no_auth_rs++;
++ }else{
++ IEEE80211_DEBUG_MGMT("Association failed\n");
++ ieee->softmac_stats.no_ass_rs++;
++ }
++
++ ieee->state = IEEE80211_ASSOCIATING_RETRY;
++
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
++ queue_delayed_work(ieee->wq, &ieee->associate_retry_wq, \
++ IEEE80211_SOFTMAC_ASSOC_RETRY_TIME);
++#else
++ schedule_task(&ieee->associate_retry_wq);
++#endif
++
++ spin_unlock_irqrestore(&ieee->lock, flags);
++}
++
++void ieee80211_associate_abort_cb(unsigned long dev)
++{
++ ieee80211_associate_abort((struct ieee80211_device *) dev);
++}
++
++
++void ieee80211_associate_step1(struct ieee80211_device *ieee)
++{
++ struct ieee80211_network *beacon = &ieee->current_network;
++ struct sk_buff *skb;
++
++ IEEE80211_DEBUG_MGMT("Stopping scan\n");
++
++ ieee->softmac_stats.tx_auth_rq++;
++ skb=ieee80211_authentication_req(beacon, ieee, 0);
++
++#ifdef _RTL8187_EXT_PATCH_
++ if(ieee->iw_mode == ieee->iw_ext_mode ) {
++ if(skb)
++ softmac_mgmt_xmit(skb, ieee);
++ return;
++ }else
++#endif
++ if (!skb)
++ ieee80211_associate_abort(ieee);
++ else{
++ ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATING ;
++ IEEE80211_DEBUG_MGMT("Sending authentication request\n");
++ //printk(KERN_WARNING "Sending authentication request\n");
++ softmac_mgmt_xmit(skb, ieee);
++ //BUGON when you try to add_timer twice, using mod_timer may be better, john0709
++ if(!timer_pending(&ieee->associate_timer)){
++ ieee->associate_timer.expires = jiffies + (HZ / 2);
++ add_timer(&ieee->associate_timer);
++ }
++ dev_kfree_skb_any(skb);//edit by thomas
++ }
++}
++
++void ieee80211_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int chlen)
++{
++ u8 *c;
++ struct sk_buff *skb;
++ struct ieee80211_network *beacon = &ieee->current_network;
++// int hlen = sizeof(struct ieee80211_authentication);
++
++ ieee->associate_seq++;
++ ieee->softmac_stats.tx_auth_rq++;
++
++ skb = ieee80211_authentication_req(beacon, ieee, chlen+2);
++ if (!skb)
++ ieee80211_associate_abort(ieee);
++ else{
++ c = skb_put(skb, chlen+2);
++ *(c++) = MFIE_TYPE_CHALLENGE;
++ *(c++) = chlen;
++ memcpy(c, challenge, chlen);
++
++ IEEE80211_DEBUG_MGMT("Sending authentication challenge response\n");
++
++ ieee80211_encrypt_fragment(ieee, skb, sizeof(struct ieee80211_hdr_3addr ));
++
++ softmac_mgmt_xmit(skb, ieee);
++
++ if(!timer_pending(&ieee->associate_timer)){
++ ieee->associate_timer.expires = jiffies + (HZ / 2);
++ add_timer(&ieee->associate_timer);
++ }
++ dev_kfree_skb_any(skb);//edit by thomas
++ }
++ kfree(challenge);
++}
++
++#ifdef _RTL8187_EXT_PATCH_
++
++// based on ieee80211_assoc_resp
++struct sk_buff* ieee80211_assoc_resp_by_net(struct ieee80211_device *ieee, u8 *dest, unsigned short status, struct ieee80211_network *pstat, int pkt_type)
++{
++ struct sk_buff *skb;
++ u8* tag;
++
++ struct ieee80211_crypt_data* crypt;
++ struct ieee80211_assoc_response_frame *assoc;
++ short encrypt;
++
++ unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
++ int len = sizeof(struct ieee80211_assoc_response_frame) + rate_len;
++
++ if(ieee->iw_mode == ieee->iw_ext_mode)
++ skb = dev_alloc_skb(len+256); // stanley
++ else
++ skb = dev_alloc_skb(len);
++
++ if (!skb)
++ return NULL;
++
++ assoc = (struct ieee80211_assoc_response_frame *)
++ skb_put(skb,sizeof(struct ieee80211_assoc_response_frame));
++
++ assoc->header.frame_ctl = cpu_to_le16(pkt_type);
++
++ memcpy(assoc->header.addr1, dest,ETH_ALEN);
++ memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
++ memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
++ assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ?
++ WLAN_CAPABILITY_BSS : WLAN_CAPABILITY_IBSS);
++
++ if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_assoc_resp_by_net_1)
++ ieee->ext_patch_ieee80211_assoc_resp_by_net_1(assoc);
++
++ if(ieee->short_slot)
++ assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
++
++ if (ieee->host_encrypt)
++#ifdef _RTL8187_EXT_PATCH_
++ crypt = ieee->cryptlist[0]->crypt[ieee->tx_keyidx];
++#else
++ crypt = ieee->crypt[ieee->tx_keyidx];
++#endif
++
++ else crypt = NULL;
++
++ encrypt = ( crypt && crypt->ops);
++
++ if (encrypt)
++ assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
++
++ assoc->status = 0;
++ assoc->aid = cpu_to_le16(ieee->assoc_id);
++ if (ieee->assoc_id == 0x2007) ieee->assoc_id=0;
++ else ieee->assoc_id++;
++
++ assoc->info_element.id = 230; // Stanley, an unused id (just a hot fix)
++ assoc->info_element.len = 0;
++
++ tag = (u8*) skb_put(skb, rate_len);
++
++ ieee80211_MFIE_Brate(ieee, &tag);
++ ieee80211_MFIE_Grate(ieee, &tag);
++
++ if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_assoc_resp_by_net_2)
++ ieee->ext_patch_ieee80211_assoc_resp_by_net_2(ieee, pstat, pkt_type, skb);
++
++ return skb;
++}
++
++// based on ieee80211_resp_to_assoc_rq
++void ieee80211_ext_issue_assoc_rsp(struct ieee80211_device *ieee, u8 *dest, unsigned short status, struct ieee80211_network *pstat, int pkt_type)
++{
++ struct sk_buff *buf = ieee80211_assoc_resp_by_net(ieee, dest, status, pstat, pkt_type);
++
++ if (buf)
++ softmac_mgmt_xmit(buf, ieee);
++}
++
++// based on ieee80211_associate_step2
++void ieee80211_ext_issue_assoc_req(struct ieee80211_device *ieee, struct ieee80211_network *pstat)
++{
++
++ struct sk_buff* skb;
++
++ // printk("@@@@@ ieee80211_ext_issue_assoc_req on channel: %d\n", ieee->current_network.channel);
++
++ ieee->softmac_stats.tx_ass_rq++;
++ skb=ieee80211_association_req(pstat, ieee);
++ if (skb)
++ softmac_mgmt_xmit(skb, ieee);
++}
++
++void ieee80211_ext_issue_disassoc(struct ieee80211_device *ieee, struct ieee80211_network *pstat, int reason, unsigned char extReason)
++{
++ // do nothing
++ // printk("@@@@@ ieee80211_ext_issue_disassoc\n");
++ return;
++}
++#endif // _RTL8187_EXT_PATCH_
++
++void ieee80211_associate_step2(struct ieee80211_device *ieee)
++{
++ struct sk_buff* skb;
++ struct ieee80211_network *beacon = &ieee->current_network;
++
++// del_timer_sync(&ieee->associate_timer);
++
++ IEEE80211_DEBUG_MGMT("Sending association request\n");
++
++ ieee->softmac_stats.tx_ass_rq++;
++ skb=ieee80211_association_req(beacon, ieee);
++ if (!skb)
++ ieee80211_associate_abort(ieee);
++ else{
++ softmac_mgmt_xmit(skb, ieee);
++ if(!timer_pending(&ieee->associate_timer)){
++ ieee->associate_timer.expires = jiffies + (HZ / 2);
++ add_timer(&ieee->associate_timer);
++ }
++ dev_kfree_skb_any(skb);//edit by thomas
++ }
++}
++
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
++void ieee80211_associate_complete_wq(struct work_struct *work)
++{
++ struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_complete_wq);
++#else
++void ieee80211_associate_complete_wq(struct ieee80211_device *ieee)
++{
++#endif
++ printk(KERN_INFO "Associated successfully\n");
++ if(ieee80211_is_54g(ieee->current_network) &&
++ (ieee->modulation & IEEE80211_OFDM_MODULATION)){
++
++ ieee->rate = 540;
++ printk(KERN_INFO"Using G rates\n");
++ }else{
++ ieee->rate = 110;
++ printk(KERN_INFO"Using B rates\n");
++ }
++
++//by lizhaoming for LED LINK
++#ifdef LED_SHIN
++ {
++ struct net_device *dev = ieee->dev;
++ ieee->ieee80211_led_contorl(dev, LED_CTL_LINK);
++ }
++#endif
++
++ ieee->link_change(ieee->dev);
++ notify_wx_assoc_event(ieee);
++ if (ieee->data_hard_resume)
++ ieee->data_hard_resume(ieee->dev);
++ netif_carrier_on(ieee->dev);
++}
++
++void ieee80211_associate_complete(struct ieee80211_device *ieee)
++{
++ int i;
++// struct net_device *dev = ieee->dev;
++ del_timer_sync(&ieee->associate_timer);
++
++ for(i = 0; i < 6; i++) {
++// ieee->seq_ctrl[i] = 0;
++ }
++ ieee->state = IEEE80211_LINKED;
++ IEEE80211_DEBUG_MGMT("Successfully associated\n");
++
++ //by lizhaoming for LED LINK
++ //ieee->ieee80211_led_contorl(dev, LED_CTL_LINK);
++
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
++ queue_work(ieee->wq, &ieee->associate_complete_wq);
++#else
++ schedule_task(&ieee->associate_complete_wq);
++#endif
++}
++
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
++void ieee80211_associate_procedure_wq(struct work_struct *work)
++{
++ struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_procedure_wq);
++#else
++void ieee80211_associate_procedure_wq(struct ieee80211_device *ieee)
++{
++#endif
++ ieee->sync_scan_hurryup = 1;
++ down(&ieee->wx_sem);
++
++ if (ieee->data_hard_stop)
++ ieee->data_hard_stop(ieee->dev);
++
++ ieee80211_stop_scan(ieee);
++ //printk("=======>%s set chan:%d\n", __func__, ieee->current_network.channel);
++ ieee->set_chan(ieee->dev, ieee->current_network.channel);
++
++ ieee->associate_seq = 1;
++ ieee80211_associate_step1(ieee);
++
++ up(&ieee->wx_sem);
++}
++#ifdef _RTL8187_EXT_PATCH_
++// based on ieee80211_associate_procedure_wq
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
++void ieee80211_ext_stop_scan_wq(struct work_struct *work)
++{
++ struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, ext_stop_scan_wq);
++#else
++void ieee80211_ext_stop_scan_wq(struct ieee80211_device *ieee)
++{
++#endif
++/*
++ if (ieee->scanning == 0)
++ {
++ if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_ext_stop_scan_wq_set_channel
++ && ( ieee->current_network.channel == ieee->ext_patch_ieee80211_ext_stop_scan_wq_set_channel(ieee) ) )
++ return;
++ }
++*/
++ ieee->sync_scan_hurryup = 1;
++
++ down(&ieee->wx_sem);
++
++ // printk("@@@@@@@@@@ ieee80211_ext_stop_scan_wq\n");
++ if (ieee->data_hard_stop)
++ ieee->data_hard_stop(ieee->dev);
++
++ ieee80211_stop_scan(ieee);
++
++ // set channel
++ if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_ext_stop_scan_wq_set_channel)
++ {
++ int ch = ieee->ext_patch_ieee80211_ext_stop_scan_wq_set_channel(ieee);
++ ieee->current_network.channel = ch;
++ ieee->set_chan(ieee->dev, ch);
++ }
++ else
++ {
++ ieee->set_chan(ieee->dev, ieee->current_network.channel);
++ }
++ //
++ up(&ieee->wx_sem);
++}
++
++
++void ieee80211_ext_send_11s_beacon(struct ieee80211_device *ieee)
++{
++ #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
++ queue_work(ieee->wq, &ieee->ext_send_beacon_wq);
++ #else
++ schedule_task(&ieee->ext_send_beacon_wq);
++ #endif
++
++}
++
++#endif // _RTL8187_EXT_PATCH_
++
++inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net)
++{
++ u8 tmp_ssid[IW_ESSID_MAX_SIZE+1];
++ int tmp_ssid_len = 0;
++
++ short apset,ssidset,ssidbroad,apmatch,ssidmatch;
++// printk("===============>%s()\n",__FUNCTION__);
++ /* we are interested in new new only if we are not associated
++ * and we are not associating / authenticating
++ */
++ if (ieee->state != IEEE80211_NOLINK)
++ return;
++
++ if ((ieee->iw_mode == IW_MODE_INFRA) && !(net->capability & WLAN_CAPABILITY_BSS))
++ return;
++
++ if ((ieee->iw_mode == IW_MODE_ADHOC) && !(net->capability & WLAN_CAPABILITY_IBSS))
++ return;
++
++
++ if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC){
++ /* if the user specified the AP MAC, we need also the essid
++ * This could be obtained by beacons or, if the network does not
++ * broadcast it, it can be put manually.
++ */
++ apset = ieee->wap_set;//(memcmp(ieee->current_network.bssid, zero,ETH_ALEN)!=0 );
++ ssidset = ieee->ssid_set;//ieee->current_network.ssid[0] != '\0';
++ ssidbroad = !(net->ssid_len == 0 || net->ssid[0]== '\0');
++ apmatch = (memcmp(ieee->current_network.bssid, net->bssid, ETH_ALEN)==0);
++ if(ieee->current_network.ssid_len != net->ssid_len)
++ ssidmatch = 0;
++ else
++ ssidmatch = (0==strncmp(ieee->current_network.ssid, net->ssid, net->ssid_len));
++
++
++
++ if ( /* if the user set the AP check if match.
++ * if the network does not broadcast essid we check the user supplyed ANY essid
++ * if the network does broadcast and the user does not set essid it is OK
++ * if the network does broadcast and the user did set essid chech if essid match
++ */
++ ( apset && apmatch &&
++ //((ssidset && ssidbroad && ssidmatch) || (ssidbroad && !ssidset) || (!ssidbroad && ssidset)) ) ||
++ ((ssidset && ssidbroad && ssidmatch) || (!ssidbroad && ssidset)) ) ||
++ /* if the ap is not set, check that the user set the bssid
++ * and the network does bradcast and that those two bssid matches
++ */
++ (!apset && ssidset && ssidbroad && ssidmatch)
++ ){
++ /* if the essid is hidden replace it with the
++ * essid provided by the user.
++ */
++ if (!ssidbroad){
++ strncpy(tmp_ssid, ieee->current_network.ssid, IW_ESSID_MAX_SIZE);
++ tmp_ssid_len = ieee->current_network.ssid_len;
++ }
++ memcpy(&ieee->current_network, net, sizeof(struct ieee80211_network));
++
++ if (!ssidbroad){
++ strncpy(ieee->current_network.ssid, tmp_ssid, IW_ESSID_MAX_SIZE);
++ ieee->current_network.ssid_len = tmp_ssid_len;
++ }
++ printk(KERN_INFO"Linking with %s, channel:%d\n",ieee->current_network.ssid, ieee->current_network.channel);
++
++#ifdef CONFIG_IPS
++ ieee->ieee80211_ips_leave(ieee->dev);
++#endif
++
++ if (ieee->iw_mode == IW_MODE_INFRA){
++ ieee->state = IEEE80211_ASSOCIATING;
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
++ queue_work(ieee->wq, &ieee->associate_procedure_wq);
++#else
++ schedule_task(&ieee->associate_procedure_wq);
++#endif
++ }else{
++ ieee->state = IEEE80211_LINKED;
++ if(ieee80211_is_54g(ieee->current_network) &&
++ (ieee->modulation & IEEE80211_OFDM_MODULATION)){
++ ieee->rate = 540;
++ printk(KERN_INFO"Using G rates\n");
++ }else{
++ ieee->rate = 110;
++ printk(KERN_INFO"Using B rates\n");
++ }
++ }
++
++ }
++ }
++
++}
++
++void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee)
++{
++ unsigned long flags;
++ struct ieee80211_network *target;
++
++ spin_lock_irqsave(&ieee->lock, flags);
++#if 0
++ list_for_each_entry(target, &ieee->network_list, list) {
++ printk(KERN_INFO"check network list SSID: %s, channel: %d\n",target->ssid,target->channel);
++ }
++#endif
++ list_for_each_entry(target, &ieee->network_list, list) {
++
++ /* if the state become different that NOLINK means
++ * we had found what we are searching for
++ */
++
++ if (ieee->state != IEEE80211_NOLINK)
++ break;
++
++ if (ieee->scan_age == 0 || time_after(target->last_scanned + ieee->scan_age, jiffies))
++ ieee80211_softmac_new_net(ieee, target);
++ }
++
++ spin_unlock_irqrestore(&ieee->lock, flags);
++
++ //printk("<=====%s\n", __func__);
++}
++
++
++static inline u16 auth_parse(struct sk_buff *skb, u8** challenge, int *chlen)
++{
++ struct ieee80211_authentication *a;
++ u8 *t;
++ if (skb->len < (sizeof(struct ieee80211_authentication)-sizeof(struct ieee80211_info_element))){
++ IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n",skb->len);
++ return 0xcafe;
++ }
++ *challenge = NULL;
++ a = (struct ieee80211_authentication*) skb->data;
++ if(skb->len > (sizeof(struct ieee80211_authentication) +3)){
++ t = skb->data + sizeof(struct ieee80211_authentication);
++
++ if(*(t++) == MFIE_TYPE_CHALLENGE){
++ *chlen = *(t++);
++ *challenge = (u8*)kmalloc(*chlen, GFP_ATOMIC);
++ memcpy(*challenge, t, *chlen);
++ }
++ }
++
++ return cpu_to_le16(a->status);
++
++}
++
++
++int auth_rq_parse(struct sk_buff *skb,u8* dest)
++{
++ struct ieee80211_authentication *a;
++
++ if (skb->len < (sizeof(struct ieee80211_authentication)-sizeof(struct ieee80211_info_element))){
++ IEEE80211_DEBUG_MGMT("invalid len in auth request: %d\n",skb->len);
++ return -1;
++ }
++ a = (struct ieee80211_authentication*) skb->data;
++
++ memcpy(dest,a->header.addr2, ETH_ALEN);
++
++ if (le16_to_cpu(a->algorithm) != WLAN_AUTH_OPEN)
++ return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
++
++ return WLAN_STATUS_SUCCESS;
++}
++
++static short probe_rq_parse(struct ieee80211_device *ieee, struct sk_buff *skb, u8 *src)
++{
++ u8 *tag;
++ u8 *skbend;
++ u8 *ssid=NULL;
++ u8 ssidlen = 0;
++
++ struct ieee80211_hdr_3addr *header =
++ (struct ieee80211_hdr_3addr *) skb->data;
++
++ if (skb->len < sizeof (struct ieee80211_hdr_3addr ))
++ return -1; /* corrupted */
++
++ memcpy(src,header->addr2, ETH_ALEN);
++
++ skbend = (u8*)skb->data + skb->len;
++
++ tag = skb->data + sizeof (struct ieee80211_hdr_3addr );
++
++ while (tag+1 < skbend){
++ if (*tag == 0){
++ ssid = tag+2;
++ ssidlen = *(tag+1);
++ break;
++ }
++ tag++; /* point to the len field */
++ tag = tag + *(tag); /* point to the last data byte of the tag */
++ tag++; /* point to the next tag */
++ }
++
++ //IEEE80211DMESG("Card MAC address is "MACSTR, MAC2STR(src));
++ if (ssidlen == 0) return 1;
++
++ if (!ssid) return 1; /* ssid not found in tagged param */
++ return (!strncmp(ssid, ieee->current_network.ssid, ssidlen));
++
++}
++
++int assoc_rq_parse(struct sk_buff *skb,u8* dest)
++{
++ struct ieee80211_assoc_request_frame *a;
++
++ if (skb->len < (sizeof(struct ieee80211_assoc_request_frame) -
++ sizeof(struct ieee80211_info_element))) {
++
++ IEEE80211_DEBUG_MGMT("invalid len in auth request:%d \n", skb->len);
++ return -1;
++ }
++
++ a = (struct ieee80211_assoc_request_frame*) skb->data;
++
++ memcpy(dest,a->header.addr2,ETH_ALEN);
++
++ return 0;
++}
++
++static inline u16 assoc_parse(struct sk_buff *skb, int *aid)
++{
++ struct ieee80211_assoc_response_frame *a;
++ if (skb->len < sizeof(struct ieee80211_assoc_response_frame)){
++ IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len);
++ return 0xcafe;
++ }
++
++ a = (struct ieee80211_assoc_response_frame*) skb->data;
++ *aid = le16_to_cpu(a->aid) & 0x3fff;
++ return le16_to_cpu(a->status);
++}
++
++static inline void
++ieee80211_rx_probe_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
++{
++ u8 dest[ETH_ALEN];
++
++ //IEEE80211DMESG("Rx probe");
++ ieee->softmac_stats.rx_probe_rq++;
++ //DMESG("Dest is "MACSTR, MAC2STR(dest));
++ if (probe_rq_parse(ieee, skb, dest)){
++ //IEEE80211DMESG("Was for me!");
++ ieee->softmac_stats.tx_probe_rs++;
++ ieee80211_resp_to_probe(ieee, dest);
++ }
++}
++
++//static inline void
++inline void ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
++{
++ u8 dest[ETH_ALEN];
++ int status;
++ //IEEE80211DMESG("Rx probe");
++ ieee->softmac_stats.rx_auth_rq++;
++
++ if ((status = auth_rq_parse(skb, dest))!= -1){
++ ieee80211_resp_to_auth(ieee, status, dest);
++ }
++ //DMESG("Dest is "MACSTR, MAC2STR(dest));
++
++}
++
++//static inline void
++inline void
++ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
++{
++
++ u8 dest[ETH_ALEN];
++ //unsigned long flags;
++
++ ieee->softmac_stats.rx_ass_rq++;
++ if (assoc_rq_parse(skb,dest) != -1){
++ ieee80211_resp_to_assoc_rq(ieee, dest);
++ }
++
++ printk(KERN_INFO"New client associated: "MAC_FMT"\n", MAC_ARG(dest));
++ //FIXME
++ #if 0
++ spin_lock_irqsave(&ieee->lock,flags);
++ add_associate(ieee,dest);
++ spin_unlock_irqrestore(&ieee->lock,flags);
++ #endif
++}
++
++
++
++void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr)
++{
++
++ struct sk_buff *buf = ieee80211_null_func(ieee, pwr);
++
++ printk(KERN_ALERT "ieee80211_sta_ps_send_null_frame \n");
++ if (buf)
++ softmac_ps_mgmt_xmit(buf, ieee);
++
++}
++
++
++short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, u32 *time_l)
++{
++ int timeout = ieee->ps_timeout;
++ u8 dtim;
++ /*if(ieee->ps == IEEE80211_PS_DISABLED ||
++ ieee->iw_mode != IW_MODE_INFRA ||
++ ieee->state != IEEE80211_LINKED)
++
++ return 0;
++ */
++ dtim = ieee->current_network.dtim_data;
++ //printk("DTIM\n");
++ if(!(dtim & IEEE80211_DTIM_VALID))
++ return 0;
++ //printk("VALID\n");
++ ieee->current_network.dtim_data = IEEE80211_DTIM_INVALID;
++
++ if(dtim & ((IEEE80211_DTIM_UCAST | IEEE80211_DTIM_MBCAST)& ieee->ps))
++ return 2;
++
++ if(!time_after(jiffies, ieee->dev->trans_start + MSECS(timeout)))
++ return 0;
++
++ if(!time_after(jiffies, ieee->last_rx_ps_time + MSECS(timeout)))
++ return 0;
++
++ if((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE ) &&
++ (ieee->mgmt_queue_tail != ieee->mgmt_queue_head))
++ return 0;
++
++ if(time_l){
++ *time_l = ieee->current_network.last_dtim_sta_time[0]
++ + (ieee->current_network.beacon_interval
++ * ieee->current_network.dtim_period) * 1000;
++ }
++
++ if(time_h){
++ *time_h = ieee->current_network.last_dtim_sta_time[1];
++ if(time_l && *time_l < ieee->current_network.last_dtim_sta_time[0])
++ *time_h += 1;
++ }
++
++ return 1;
++
++
++}
++
++inline void ieee80211_sta_ps(struct ieee80211_device *ieee)
++{
++
++ u32 th,tl;
++ short sleep;
++
++ unsigned long flags,flags2;
++
++ spin_lock_irqsave(&ieee->lock, flags);
++
++ if((ieee->ps == IEEE80211_PS_DISABLED ||
++ ieee->iw_mode != IW_MODE_INFRA ||
++ ieee->state != IEEE80211_LINKED)){
++
++ // #warning CHECK_LOCK_HERE
++ spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
++
++ ieee80211_sta_wakeup(ieee, 1);
++
++ spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
++ }
++
++ sleep = ieee80211_sta_ps_sleep(ieee,&th, &tl);
++ /* 2 wake, 1 sleep, 0 do nothing */
++ if(sleep == 0)
++ goto out;
++
++ if(sleep == 1){
++
++ if(ieee->sta_sleep == 1)
++ ieee->enter_sleep_state(ieee->dev,th,tl);
++
++ else if(ieee->sta_sleep == 0){
++ // printk("send null 1\n");
++ spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
++
++ if(ieee->ps_is_queue_empty(ieee->dev)){
++
++
++ ieee->sta_sleep = 2;
++
++ ieee->ps_request_tx_ack(ieee->dev);
++
++ ieee80211_sta_ps_send_null_frame(ieee,1);
++
++ ieee->ps_th = th;
++ ieee->ps_tl = tl;
++ }
++ spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
++
++ }
++
++
++ }else if(sleep == 2){
++//#warning CHECK_LOCK_HERE
++ spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
++
++ ieee80211_sta_wakeup(ieee,1);
++
++ spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
++ }
++
++out:
++ spin_unlock_irqrestore(&ieee->lock, flags);
++
++}
++
++void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl)
++{
++ if(ieee->sta_sleep == 0){
++ if(nl){
++ printk("Warning: driver is probably failing to report TX ps error\n");
++ ieee->ps_request_tx_ack(ieee->dev);
++ ieee80211_sta_ps_send_null_frame(ieee, 0);
++ }
++ return;
++
++ }
++
++ if(ieee->sta_sleep == 1)
++ ieee->sta_wake_up(ieee->dev);
++
++ ieee->sta_sleep = 0;
++
++ if(nl){
++ ieee->ps_request_tx_ack(ieee->dev);
++ ieee80211_sta_ps_send_null_frame(ieee, 0);
++ }
++}
++
++void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success)
++{
++ unsigned long flags,flags2;
++
++ spin_lock_irqsave(&ieee->lock, flags);
++
++ if(ieee->sta_sleep == 2){
++ /* Null frame with PS bit set */
++ if(success){
++ ieee->sta_sleep = 1;
++ ieee->enter_sleep_state(ieee->dev,ieee->ps_th,ieee->ps_tl);
++ }
++ /* if the card report not success we can't be sure the AP
++ * has not RXed so we can't assume the AP believe us awake
++ */
++ }
++ /* 21112005 - tx again null without PS bit if lost */
++ else {
++
++ if((ieee->sta_sleep == 0) && !success){
++ spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
++ ieee80211_sta_ps_send_null_frame(ieee, 0);
++ spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
++ }
++ }
++ spin_unlock_irqrestore(&ieee->lock, flags);
++}
++
++inline int
++ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
++ struct ieee80211_rx_stats *rx_stats, u16 type,
++ u16 stype)
++{
++ struct ieee80211_hdr_3addr *header = (struct ieee80211_hdr_3addr *) skb->data;
++ u16 errcode;
++ u8* challenge=NULL;
++ int chlen=0;
++ int aid=0;
++ struct ieee80211_assoc_response_frame *assoc_resp;
++ struct ieee80211_info_element *info_element;
++
++ if(!ieee->proto_started)
++ return 0;
++
++ if(ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED &&
++ ieee->iw_mode == IW_MODE_INFRA &&
++ ieee->state == IEEE80211_LINKED))
++
++ tasklet_schedule(&ieee->ps_task);
++
++ if(WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_PROBE_RESP &&
++ WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_BEACON)
++ ieee->last_rx_ps_time = jiffies;
++
++ switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
++ case IEEE80211_STYPE_ASSOC_RESP:
++ case IEEE80211_STYPE_REASSOC_RESP:
++
++ IEEE80211_DEBUG_MGMT("received [RE]ASSOCIATION RESPONSE (%d)\n",
++ WLAN_FC_GET_STYPE(header->frame_ctl));
++ //printk(KERN_WARNING "Received association response\n");
++ if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
++ ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATED &&
++ ieee->iw_mode == IW_MODE_INFRA){
++ if (0 == (errcode=assoc_parse(skb, &aid))){
++ u16 left;
++
++ ieee->state=IEEE80211_LINKED;
++ ieee->assoc_id = aid;
++ ieee->softmac_stats.rx_ass_ok++;
++
++ //printk(KERN_WARNING "nic_type = %s", (rx_stats->nic_type == 1)?"rtl8187":"rtl8187B");
++ if(1 == rx_stats->nic_type) //card type is 8187
++ {
++ goto associate_complete;
++ }
++ assoc_resp = (struct ieee80211_assoc_response_frame*)skb->data;
++ info_element = &assoc_resp->info_element;
++ left = skb->len - ((void*)info_element - (void*)assoc_resp);
++
++ while (left >= sizeof(struct ieee80211_info_element_hdr)) {
++ if (sizeof(struct ieee80211_info_element_hdr) + info_element->len > left) {
++ printk(KERN_WARNING "[re]associate reeponse error!");
++ return 1;
++ }
++ switch (info_element->id) {
++ case MFIE_TYPE_GENERIC:
++ IEEE80211_DEBUG_SCAN("MFIE_TYPE_GENERIC: %d bytes\n", info_element->len);
++ if (info_element->len >= 8 &&
++ info_element->data[0] == 0x00 &&
++ info_element->data[1] == 0x50 &&
++ info_element->data[2] == 0xf2 &&
++ info_element->data[3] == 0x02 &&
++ info_element->data[4] == 0x01) {
++ // Not care about version at present.
++ //WMM Parameter Element
++ memcpy(ieee->current_network.wmm_param,(u8*)(info_element->data\
++ + 8),(info_element->len - 8));
++
++ if (((ieee->current_network.wmm_info^info_element->data[6])& \
++ 0x0f)||(!ieee->init_wmmparam_flag)) {
++ //refresh paramete element for current network
++ // update the register parameter for hardware
++ ieee->init_wmmparam_flag = 1;
++ //ieee->wmm_param_update(ieee);
++ //schedule_work(&ieee->wmm_param_update_wq);
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
++ queue_work(ieee->wq, &ieee->wmm_param_update_wq);
++#else
++ schedule_task(&ieee->wmm_param_update_wq);
++#endif
++
++ }
++ //update info_element for current network
++ ieee->current_network.wmm_info = info_element->data[6];
++ }
++ break;
++ default:
++ //nothing to do at present!!!
++ break;
++ }
++
++ left -= sizeof(struct ieee80211_info_element_hdr) +
++ info_element->len;
++ info_element = (struct ieee80211_info_element *)
++ &info_element->data[info_element->len];
++ }
++ if(!ieee->init_wmmparam_flag) //legacy AP, reset the AC_xx_param register
++ {
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
++ queue_work(ieee->wq,&ieee->wmm_param_update_wq);
++#else
++ schedule_task(&ieee->wmm_param_update_wq);
++#endif
++ ieee->init_wmmparam_flag = 1;//indicate AC_xx_param upated since last associate
++ }
++associate_complete:
++ ieee80211_associate_complete(ieee);
++ }else{
++ ieee->softmac_stats.rx_ass_err++;
++ IEEE80211_DEBUG_MGMT(
++ "Association response status code 0x%x\n",
++ errcode);
++ printk(KERN_WARNING "Association response status code 0x%x\n",
++ errcode);
++ ieee80211_associate_abort(ieee);
++ }
++ }
++#ifdef _RTL8187_EXT_PATCH_
++ else if ((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_frame_softmac_on_assoc_rsp)
++ {
++ ieee->ext_patch_ieee80211_rx_frame_softmac_on_assoc_rsp(ieee, skb);
++ }
++#endif
++ break;
++
++ case IEEE80211_STYPE_ASSOC_REQ:
++ case IEEE80211_STYPE_REASSOC_REQ:
++ //printk("Received IEEE80211_STYPE_ASSOC_REQ\n");
++
++ if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
++ ieee->iw_mode == IW_MODE_MASTER)
++
++ ieee80211_rx_assoc_rq(ieee, skb);
++#ifdef _RTL8187_EXT_PATCH_
++ else if ((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_frame_softmac_on_assoc_req)
++ {
++ ieee->ext_patch_ieee80211_rx_frame_softmac_on_assoc_req(ieee, skb);
++ }
++#endif
++ break;
++
++ case IEEE80211_STYPE_AUTH:
++ //printk("Received authentication response\n");
++
++#ifdef _RTL8187_EXT_PATCH_
++//printk("IEEE80211_STYPE_AUTH\n");
++ if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_frame_softmac_on_auth)
++ if( ieee->ext_patch_ieee80211_rx_frame_softmac_on_auth(ieee, skb, rx_stats) );
++#endif
++ if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE){
++ if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING &&
++ ieee->iw_mode == IW_MODE_INFRA){
++
++ IEEE80211_DEBUG_MGMT("Received authentication response");
++
++ if (0 == (errcode=auth_parse(skb, &challenge, &chlen))){
++ if(ieee->open_wep || !challenge){
++ ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATED;
++ ieee->softmac_stats.rx_auth_rs_ok++;
++
++ ieee80211_associate_step2(ieee);
++ }else{
++ ieee80211_auth_challenge(ieee, challenge, chlen);
++ }
++ }else{
++ ieee->softmac_stats.rx_auth_rs_err++;
++ IEEE80211_DEBUG_MGMT("Authentication respose status code 0x%x",errcode);
++ ieee80211_associate_abort(ieee);
++ }
++
++ }else if (ieee->iw_mode == IW_MODE_MASTER){
++ ieee80211_rx_auth_rq(ieee, skb);
++ }
++ }
++ break;
++
++ case IEEE80211_STYPE_PROBE_REQ:
++ //printk("Received IEEE80211_STYPE_PROBE_REQ\n");
++
++ if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) &&
++ ((ieee->iw_mode == IW_MODE_ADHOC ||
++ ieee->iw_mode == IW_MODE_MASTER) &&
++ ieee->state == IEEE80211_LINKED))
++
++ ieee80211_rx_probe_rq(ieee, skb);
++ break;
++
++ case IEEE80211_STYPE_DISASSOC:
++ case IEEE80211_STYPE_DEAUTH:
++ //printk("Received IEEE80211_STYPE_DISASSOC\n");
++#ifdef _RTL8187_EXT_PATCH_
++//printk("IEEE80211_STYPE_DEAUTH\n");
++ if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_frame_softmac_on_deauth)
++ if( ieee->ext_patch_ieee80211_rx_frame_softmac_on_deauth(ieee, skb, rx_stats) ) ;
++#endif
++ /* FIXME for now repeat all the association procedure
++ * both for disassociation and deauthentication
++ */
++ if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
++ ieee->state == IEEE80211_LINKED &&
++ ieee->iw_mode == IW_MODE_INFRA){
++
++ ieee->state = IEEE80211_ASSOCIATING;
++ ieee->softmac_stats.reassoc++;
++
++ notify_wx_assoc_event(ieee);
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
++ queue_work(ieee->wq, &ieee->associate_procedure_wq);
++#else
++ schedule_task(&ieee->associate_procedure_wq);
++#endif
++ }
++
++ break;
++
++ default:
++ return -1;
++ break;
++ }
++
++ //dev_kfree_skb_any(skb);
++ return 0;
++}
++
++
++
++/* following are for a simplier TX queue management.
++ * Instead of using netif_[stop/wake]_queue the driver
++ * will uses these two function (plus a reset one), that
++ * will internally uses the kernel netif_* and takes
++ * care of the ieee802.11 fragmentation.
++ * So the driver receives a fragment per time and might
++ * call the stop function when it want without take care
++ * to have enought room to TX an entire packet.
++ * This might be useful if each fragment need it's own
++ * descriptor, thus just keep a total free memory > than
++ * the max fragmentation treshold is not enought.. If the
++ * ieee802.11 stack passed a TXB struct then you needed
++ * to keep N free descriptors where
++ * N = MAX_PACKET_SIZE / MIN_FRAG_TRESHOLD
++ * In this way you need just one and the 802.11 stack
++ * will take care of buffering fragments and pass them to
++ * to the driver later, when it wakes the queue.
++ */
++
++void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee)
++{
++
++
++ unsigned long flags;
++ int i;
++#ifdef _RTL8187_EXT_PATCH_
++ int rate = ieee->rate;
++#endif
++
++ spin_lock_irqsave(&ieee->lock,flags);
++ #if 0
++ if(ieee->queue_stop){
++ IEEE80211DMESG("EE: IEEE hard_start_xmit invoked when kernel queue should be stopped");
++ netif_stop_queue(ieee->dev);
++ ieee->ieee_stats.swtxstop++;
++ //dev_kfree_skb_any(skb);
++ err = 1;
++ goto exit;
++ }
++
++ ieee->stats.tx_bytes+=skb->len;
++
++
++ txb=ieee80211_skb_to_txb(ieee,skb);
++
++
++ if(txb==NULL){
++ IEEE80211DMESG("WW: IEEE stack failed to provide txb");
++ //dev_kfree_skb_any(skb);
++ err = 1;
++ goto exit;
++ }
++ #endif
++
++#ifdef _RTL8187_EXT_PATCH_
++ if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_softmac_xmit_get_rate && txb->nr_frags)
++ {
++ rate = ieee->ext_patch_ieee80211_softmac_xmit_get_rate(ieee, txb->fragments[0]);
++ }
++#endif
++ /* called with 2nd parm 0, no tx mgmt lock required */
++ ieee80211_sta_wakeup(ieee,0);
++
++ for(i = 0; i < txb->nr_frags; i++) {
++
++ if (ieee->queue_stop){
++ ieee->tx_pending.txb = txb;
++ ieee->tx_pending.frag = i;
++ goto exit;
++ }else{
++ ieee->softmac_data_hard_start_xmit(
++ txb->fragments[i],
++#ifdef _RTL8187_EXT_PATCH_
++ ieee->dev, rate);
++#else
++ ieee->dev,ieee->rate);
++#endif
++ //(i+1)<txb->nr_frags);
++ ieee->stats.tx_packets++;
++ ieee->stats.tx_bytes += txb->fragments[i]->len;
++ ieee->dev->trans_start = jiffies;
++ }
++ }
++
++ ieee80211_txb_free(txb);
++
++ exit:
++ spin_unlock_irqrestore(&ieee->lock,flags);
++
++}
++
++/* called with ieee->lock acquired */
++void ieee80211_resume_tx(struct ieee80211_device *ieee)
++{
++ int i;
++ for(i = ieee->tx_pending.frag; i < ieee->tx_pending.txb->nr_frags; i++) {
++
++ if (ieee->queue_stop){
++ ieee->tx_pending.frag = i;
++ return;
++ }else{
++
++ ieee->softmac_data_hard_start_xmit(
++ ieee->tx_pending.txb->fragments[i],
++ ieee->dev,ieee->rate);
++ //(i+1)<ieee->tx_pending.txb->nr_frags);
++ ieee->stats.tx_packets++;
++ ieee->dev->trans_start = jiffies;
++ }
++ }
++
++
++ ieee80211_txb_free(ieee->tx_pending.txb);
++ ieee->tx_pending.txb = NULL;
++}
++
++
++void ieee80211_reset_queue(struct ieee80211_device *ieee)
++{
++ unsigned long flags;
++
++ spin_lock_irqsave(&ieee->lock,flags);
++ init_mgmt_queue(ieee);
++ if (ieee->tx_pending.txb){
++ ieee80211_txb_free(ieee->tx_pending.txb);
++ ieee->tx_pending.txb = NULL;
++ }
++ ieee->queue_stop = 0;
++ spin_unlock_irqrestore(&ieee->lock,flags);
++
++}
++
++void ieee80211_wake_queue(struct ieee80211_device *ieee)
++{
++
++ unsigned long flags;
++ struct sk_buff *skb;
++ struct ieee80211_hdr_3addr *header;
++
++ spin_lock_irqsave(&ieee->lock,flags);
++ if (! ieee->queue_stop) goto exit;
++
++ ieee->queue_stop = 0;
++
++ if(ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE){
++ while (!ieee->queue_stop && (skb = dequeue_mgmt(ieee))){
++
++ header = (struct ieee80211_hdr_3addr *) skb->data;
++
++ header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
++
++ if (ieee->seq_ctrl[0] == 0xFFF)
++ ieee->seq_ctrl[0] = 0;
++ else
++ ieee->seq_ctrl[0]++;
++
++ printk(KERN_ALERT "ieee80211_wake_queue \n");
++ ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
++ dev_kfree_skb_any(skb);//edit by thomas
++ }
++ }
++ if (!ieee->queue_stop && ieee->tx_pending.txb)
++ ieee80211_resume_tx(ieee);
++
++ if (!ieee->queue_stop && netif_queue_stopped(ieee->dev)){
++ ieee->softmac_stats.swtxawake++;
++ netif_wake_queue(ieee->dev);
++ }
++
++exit :
++ spin_unlock_irqrestore(&ieee->lock,flags);
++}
++
++
++void ieee80211_stop_queue(struct ieee80211_device *ieee)
++{
++ //unsigned long flags;
++ //spin_lock_irqsave(&ieee->lock,flags);
++
++ if (! netif_queue_stopped(ieee->dev)){
++ netif_stop_queue(ieee->dev);
++ ieee->softmac_stats.swtxstop++;
++ }
++ ieee->queue_stop = 1;
++ //spin_unlock_irqrestore(&ieee->lock,flags);
++
++}
++
++
++inline void ieee80211_randomize_cell(struct ieee80211_device *ieee)
++{
++
++ get_random_bytes(ieee->current_network.bssid, ETH_ALEN);
++
++ /* an IBSS cell address must have the two less significant
++ * bits of the first byte = 2
++ */
++ ieee->current_network.bssid[0] &= ~0x01;
++ ieee->current_network.bssid[0] |= 0x02;
++}
++
++/* called in user context only */
++void ieee80211_start_master_bss(struct ieee80211_device *ieee)
++{
++ ieee->assoc_id = 1;
++
++ if (ieee->current_network.ssid_len == 0){
++ strncpy(ieee->current_network.ssid,
++ IEEE80211_DEFAULT_TX_ESSID,
++ IW_ESSID_MAX_SIZE);
++
++ ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
++ ieee->ssid_set = 1;
++ }
++
++ memcpy(ieee->current_network.bssid, ieee->dev->dev_addr, ETH_ALEN);
++
++ ieee->set_chan(ieee->dev, ieee->current_network.channel);
++ ieee->state = IEEE80211_LINKED;
++
++//by lizhaoming for LED LINK
++#ifdef LED_SHIN
++ {
++ struct net_device *dev = ieee->dev;
++ ieee->ieee80211_led_contorl(dev, LED_CTL_LINK);
++ }
++#endif
++ ieee->link_change(ieee->dev);
++ notify_wx_assoc_event(ieee);
++
++ if (ieee->data_hard_resume)
++ ieee->data_hard_resume(ieee->dev);
++
++ netif_carrier_on(ieee->dev);
++}
++
++void ieee80211_start_monitor_mode(struct ieee80211_device *ieee)
++{
++ if(ieee->raw_tx){
++
++ if (ieee->data_hard_resume)
++ ieee->data_hard_resume(ieee->dev);
++
++ netif_carrier_on(ieee->dev);
++ }
++}
++
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
++void ieee80211_start_ibss_wq(struct work_struct *work)
++{
++ struct delayed_work *dwork = container_of(work, struct delayed_work, work);
++ struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, start_ibss_wq);
++#else
++void ieee80211_start_ibss_wq(struct ieee80211_device *ieee)
++{
++#endif
++
++ /* iwconfig mode ad-hoc will schedule this and return
++ * on the other hand this will block further iwconfig SET
++ * operations because of the wx_sem hold.
++ * Anyway some most set operations set a flag to speed-up
++ * (abort) this wq (when syncro scanning) before sleeping
++ * on the semaphore
++ */
++
++ down(&ieee->wx_sem);
++
++ if (ieee->current_network.ssid_len == 0){
++ strcpy(ieee->current_network.ssid,IEEE80211_DEFAULT_TX_ESSID);
++ ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
++ ieee->ssid_set = 1;
++ }
++
++//by lizhaoming for LED BLINK 2008.6.23
++#ifdef LED_SHIN
++ {
++ struct net_device *dev = ieee->dev;
++ ieee->ieee80211_led_contorl(dev, LED_CTL_SITE_SURVEY);
++ }
++#endif
++
++ /* check if we have this cell in our network list */
++ ieee80211_softmac_check_all_nets(ieee);
++
++#ifdef ENABLE_DOT11D
++ //[World wide 13]:
++ // Adhoc:
++ // (1) active scan from ch1~11 and passive scan from ch12~13
++ // (2) IBSS can join ch1~13 adhoc, but only start at ch10.
++ if(ieee->state == IEEE80211_NOLINK)
++ if(ieee->IbssStartChnl != 0)
++ ieee->current_network.channel = ieee->IbssStartChnl;//chan 10
++#endif
++
++ /* if not then the state is not linked. Maybe the user swithced to
++ * ad-hoc mode just after being in monitor mode, or just after
++ * being very few time in managed mode (so the card have had no
++ * time to scan all the chans..) or we have just run up the iface
++ * after setting ad-hoc mode. So we have to give another try..
++ * Here, in ibss mode, should be safe to do this without extra care
++ * (in bss mode we had to make sure no-one tryed to associate when
++ * we had just checked the ieee->state and we was going to start the
++ * scan) beacause in ibss mode the ieee80211_new_net function, when
++ * finds a good net, just set the ieee->state to IEEE80211_LINKED,
++ * so, at worst, we waste a bit of time to initiate an unneeded syncro
++ * scan, that will stop at the first round because it sees the state
++ * associated.
++ */
++ if (ieee->state == IEEE80211_NOLINK){
++ ieee80211_start_scan_syncro(ieee);
++ }
++
++ /* the network definitively is not here.. create a new cell */
++ if (ieee->state == IEEE80211_NOLINK){
++ printk("creating new IBSS cell\n");
++ ieee->state = IEEE80211_LINKED;
++ if(!ieee->wap_set)
++ ieee80211_randomize_cell(ieee);
++
++ if(ieee->modulation & IEEE80211_CCK_MODULATION){
++
++ ieee->current_network.rates_len = 4;
++
++ ieee->current_network.rates[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
++ ieee->current_network.rates[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
++ ieee->current_network.rates[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
++ ieee->current_network.rates[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
++
++ }else
++ ieee->current_network.rates_len = 0;
++
++ if(ieee->modulation & IEEE80211_OFDM_MODULATION){
++ ieee->current_network.rates_ex_len = 8;
++
++ ieee->current_network.rates_ex[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
++ ieee->current_network.rates_ex[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
++ ieee->current_network.rates_ex[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
++ ieee->current_network.rates_ex[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
++ ieee->current_network.rates_ex[4] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
++ ieee->current_network.rates_ex[5] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
++ ieee->current_network.rates_ex[6] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
++ ieee->current_network.rates_ex[7] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
++
++ ieee->rate = 540;
++ }else{
++ ieee->current_network.rates_ex_len = 0;
++ ieee->rate = 110;
++ }
++
++ // By default, WMM function will be disabled in IBSS mode
++ ieee->current_network.QoS_Enable = 0;
++
++ ieee->current_network.atim_window = 0;
++ ieee->current_network.capability = WLAN_CAPABILITY_IBSS;
++ if(ieee->short_slot)
++ ieee->current_network.capability |= WLAN_CAPABILITY_SHORT_SLOT;
++
++ }
++
++ ieee->state = IEEE80211_LINKED;
++
++//by lizhaoming for LED LINK
++#ifdef LED_SHIN
++ {
++ struct net_device *dev = ieee->dev;
++ ieee->ieee80211_led_contorl(dev, LED_CTL_LINK);
++ }
++#endif
++
++ ieee->set_chan(ieee->dev, ieee->current_network.channel);
++ ieee->link_change(ieee->dev);
++
++ notify_wx_assoc_event(ieee);
++
++ ieee80211_start_send_beacons(ieee);
++ printk(KERN_WARNING "after sending beacon packet!\n");
++
++ if (ieee->data_hard_resume)
++ ieee->data_hard_resume(ieee->dev);
++
++ netif_carrier_on(ieee->dev);
++
++ up(&ieee->wx_sem);
++}
++
++inline void ieee80211_start_ibss(struct ieee80211_device *ieee)
++{
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
++ queue_delayed_work(ieee->wq, &ieee->start_ibss_wq, 150); //change to delayed work, delayed time is need to check
++#else
++ schedule_task(&ieee->start_ibss_wq);
++#endif
++}
++
++/* this is called only in user context, with wx_sem held */
++void ieee80211_start_bss(struct ieee80211_device *ieee)
++{
++ unsigned long flags;
++ /* check if we have already found the net we
++ * are interested in (if any).
++ * if not (we are disassociated and we are not
++ * in associating / authenticating phase) start the background scanning.
++ */
++
++//by lizhaoming for LED BLINK 2008.6.23
++#ifdef LED_SHIN
++ {
++ struct net_device *dev = ieee->dev;
++ ieee->ieee80211_led_contorl(dev, LED_CTL_SITE_SURVEY);
++ }
++#endif
++
++#ifdef ENABLE_DOT11D
++ //
++ // Ref: 802.11d 11.1.3.3
++ // STA shall not start a BSS unless properly formed Beacon frame including a Country IE.
++ //
++ if(IS_DOT11D_ENABLE(ieee) && !IS_COUNTRY_IE_VALID(ieee))
++ {
++ if(! ieee->bGlobalDomain)
++ {
++ return;
++ }
++ }
++#endif
++ //printk("======>%s()\n",__FUNCTION__);
++ ieee80211_softmac_check_all_nets(ieee);
++
++ /* ensure no-one start an associating process (thus setting
++ * the ieee->state to ieee80211_ASSOCIATING) while we
++ * have just cheked it and we are going to enable scan.
++ * The ieee80211_new_net function is always called with
++ * lock held (from both ieee80211_softmac_check_all_nets and
++ * the rx path), so we cannot be in the middle of such function
++ */
++
++ spin_lock_irqsave(&ieee->lock, flags);
++ if (ieee->state == IEEE80211_NOLINK){
++ //printk("Not find SSID in network list scan now\n");
++ ieee80211_start_scan(ieee);
++ }
++ spin_unlock_irqrestore(&ieee->lock, flags);
++
++}
++
++/* called only in userspace context */
++void ieee80211_disassociate(struct ieee80211_device *ieee)
++{
++ netif_carrier_off(ieee->dev);
++
++ if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)
++ ieee80211_reset_queue(ieee);
++
++ if (ieee->data_hard_stop)
++ ieee->data_hard_stop(ieee->dev);
++
++#ifdef ENABLE_DOT11D
++ if(IS_DOT11D_ENABLE(ieee))
++ Dot11d_Reset(ieee);
++#endif
++
++ ieee->state = IEEE80211_NOLINK;
++ ieee->link_change(ieee->dev);
++ notify_wx_assoc_event(ieee);
++
++}
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
++void ieee80211_associate_retry_wq(struct work_struct *work)
++{
++ struct delayed_work *dwork = container_of(work, struct delayed_work, work);
++ struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, associate_retry_wq);
++#else
++void ieee80211_associate_retry_wq(struct ieee80211_device *ieee)
++{
++#endif
++ unsigned long flags;
++
++ down(&ieee->wx_sem);
++ if(!ieee->proto_started)
++ goto exit;
++
++ if(ieee->state != IEEE80211_ASSOCIATING_RETRY)
++ goto exit;
++
++ /* until we do not set the state to IEEE80211_NOLINK
++ * there are no possibility to have someone else trying
++ * to start an association procdure (we get here with
++ * ieee->state = IEEE80211_ASSOCIATING).
++ * When we set the state to IEEE80211_NOLINK it is possible
++ * that the RX path run an attempt to associate, but
++ * both ieee80211_softmac_check_all_nets and the
++ * RX path works with ieee->lock held so there are no
++ * problems. If we are still disassociated then start a scan.
++ * the lock here is necessary to ensure no one try to start
++ * an association procedure when we have just checked the
++ * state and we are going to start the scan.
++ */
++ ieee->state = IEEE80211_NOLINK;
++
++ ieee80211_softmac_check_all_nets(ieee);
++
++ spin_lock_irqsave(&ieee->lock, flags);
++ if(ieee->state == IEEE80211_NOLINK)
++ {
++ printk("%s():Not find SSID:%s[ch=%d, mode=%s] in network list scan now\n", __FUNCTION__,
++ ieee->current_network.ssid,ieee->current_network.channel,
++ (ieee->iw_mode == IW_MODE_INFRA) ? "BSS" : "IBSS");
++
++ ieee80211_start_scan(ieee);
++ }
++
++ spin_unlock_irqrestore(&ieee->lock, flags);
++
++exit:
++ up(&ieee->wx_sem);
++}
++
++struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee)
++{
++ u8 broadcast_addr[] = {0xff,0xff,0xff,0xff,0xff,0xff};
++
++ struct sk_buff *skb = NULL;
++ struct ieee80211_probe_response *b;
++
++//rz
++#ifdef _RTL8187_EXT_PATCH_
++ if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_get_beacon_get_probersp )
++ skb = ieee->ext_patch_get_beacon_get_probersp(ieee, broadcast_addr, &(ieee->current_network));
++ else
++ skb = ieee80211_probe_resp(ieee, broadcast_addr);
++#else
++ skb = ieee80211_probe_resp(ieee, broadcast_addr);
++#endif
++//
++ if (!skb)
++ return NULL;
++
++ b = (struct ieee80211_probe_response *) skb->data;
++ b->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_BEACON);
++
++ return skb;
++
++}
++
++struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee)
++{
++ struct sk_buff *skb;
++ struct ieee80211_probe_response *b;
++// printk("=========>%s()\n", __FUNCTION__);
++ skb = ieee80211_get_beacon_(ieee);
++ if(!skb)
++ return NULL;
++
++ b = (struct ieee80211_probe_response *) skb->data;
++ b->header.seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
++
++ if (ieee->seq_ctrl[0] == 0xFFF)
++ ieee->seq_ctrl[0] = 0;
++ else
++ ieee->seq_ctrl[0]++;
++
++ return skb;
++}
++
++void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee)
++{
++ ieee->sync_scan_hurryup = 1;
++ down(&ieee->wx_sem);
++ ieee80211_stop_protocol(ieee);
++ up(&ieee->wx_sem);
++}
++
++
++void ieee80211_stop_protocol(struct ieee80211_device *ieee)
++{
++ if (!ieee->proto_started)
++ return;
++
++ ieee->proto_started = 0;
++ //printk("=====>%s\n", __func__);
++
++#ifdef _RTL8187_EXT_PATCH_
++ if(ieee->ext_patch_ieee80211_stop_protocol)
++ ieee->ext_patch_ieee80211_stop_protocol(ieee);
++//if call queue_delayed_work,can call this,or do nothing..
++//edit by lawrence,20071118
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
++// cancel_delayed_work(&ieee->ext_stop_scan_wq);
++// cancel_delayed_work(&ieee->ext_send_beacon_wq);
++#endif
++#endif // _RTL8187_EXT_PATCH_
++
++ ieee80211_stop_send_beacons(ieee);
++
++ del_timer_sync(&ieee->associate_timer);
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
++ cancel_delayed_work(&ieee->associate_retry_wq);
++ cancel_delayed_work(&ieee->start_ibss_wq); //cancel ibss start workqueue when stop protocol
++#endif
++ ieee80211_stop_scan(ieee);
++
++ ieee80211_disassociate(ieee);
++ //printk("<=====%s\n", __func__);
++
++}
++
++void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee)
++{
++ ieee->sync_scan_hurryup = 0;
++ down(&ieee->wx_sem);
++ ieee80211_start_protocol(ieee);
++ up(&ieee->wx_sem);
++}
++
++void ieee80211_start_protocol(struct ieee80211_device *ieee)
++{
++ short ch = 0;
++ int i = 0;
++
++ if (ieee->proto_started)
++ return;
++
++ //printk("=====>%s\n", __func__);
++
++ ieee->proto_started = 1;
++
++ if (ieee->current_network.channel == 0){
++ do{
++ ch++;
++ if (ch > MAX_CHANNEL_NUMBER)
++ return; /* no channel found */
++#ifdef ENABLE_DOT11D
++ }while(!GET_DOT11D_INFO(ieee)->channel_map[ch]);
++#else
++ }while(!ieee->channel_map[ch]);
++#endif
++ ieee->current_network.channel = ch;
++ }
++
++ if (ieee->current_network.beacon_interval == 0)
++ ieee->current_network.beacon_interval = 100;
++
++ ieee->set_chan(ieee->dev,ieee->current_network.channel);
++ mdelay(10);//must or link change will fail lzm
++
++ for(i = 0; i < 17; i++) {
++ ieee->last_rxseq_num[i] = -1;
++ ieee->last_rxfrag_num[i] = -1;
++ ieee->last_packet_time[i] = 0;
++ }
++
++ ieee->init_wmmparam_flag = 0;//reinitialize AC_xx_PARAM registers.
++
++
++ /* if the user set the MAC of the ad-hoc cell and then
++ * switch to managed mode, shall we make sure that association
++ * attempts does not fail just because the user provide the essid
++ * and the nic is still checking for the AP MAC ??
++ */
++
++ if (ieee->iw_mode == IW_MODE_INFRA){
++ ieee80211_start_bss(ieee);
++ // printk("==========> IW_MODE_INFRA\n");
++ }
++ else if (ieee->iw_mode == IW_MODE_ADHOC){
++ // printk("==========> IW_MODE_ADHOC\n");
++ ieee80211_start_ibss(ieee);
++ }
++ else if (ieee->iw_mode == IW_MODE_MASTER){
++ ieee80211_start_master_bss(ieee);
++// printk("==========> IW_MODE_MASTER\n");
++ }
++ else if(ieee->iw_mode == IW_MODE_MONITOR){
++ ieee80211_start_monitor_mode(ieee);
++// printk("==========> IW_MODE_MONITOR\n");
++ }
++
++#ifdef _RTL8187_EXT_PATCH_
++// else if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_start_protocol && ieee->ext_patch_ieee80211_start_protocol(ieee))
++ else if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_start_protocol)
++ {
++ ieee->ext_patch_ieee80211_start_mesh(ieee);
++ }
++#endif
++}
++
++
++#define DRV_NAME "Ieee80211"
++void ieee80211_softmac_init(struct ieee80211_device *ieee)
++{
++ int i;
++ memset(&ieee->current_network, 0, sizeof(struct ieee80211_network));
++
++ ieee->state = IEEE80211_NOLINK;
++ ieee->sync_scan_hurryup = 0;
++ for(i = 0; i < 5; i++) {
++ ieee->seq_ctrl[i] = 0;
++ }
++
++ ieee->assoc_id = 0;
++ ieee->queue_stop = 0;
++ ieee->scanning = 0;
++ ieee->scan_watchdog = 0;//lzm add 081215 for roaming
++ ieee->softmac_features = 0; //so IEEE2100-like driver are happy
++ ieee->wap_set = 0;
++ ieee->ssid_set = 0;
++ ieee->proto_started = 0;
++ ieee->basic_rate = IEEE80211_DEFAULT_BASIC_RATE;
++ ieee->rate = 3;
++ ieee->ps = IEEE80211_PS_DISABLED;
++ ieee->sta_sleep = 0;
++//by amy
++ ieee->bInactivePs = false;
++ ieee->actscanning = false;
++ ieee->ListenInterval = 2;
++ ieee->NumRxData = 0;
++ ieee->NumRxDataInPeriod = 0; //YJ,add,080828
++ ieee->NumRxBcnInPeriod = 0; //YJ,add,080828
++ ieee->bHwRadioOff = false;//by lizhaoming
++//by amy
++#ifdef _RTL8187_EXT_PATCH_
++ ieee->iw_ext_mode = 999;
++#endif
++
++ init_mgmt_queue(ieee);
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++ init_timer(&ieee->scan_timer);
++ ieee->scan_timer.data = (unsigned long)ieee;
++ ieee->scan_timer.function = ieee80211_softmac_scan_cb;
++#endif
++ ieee->tx_pending.txb = NULL;
++
++ init_timer(&ieee->associate_timer);
++ ieee->associate_timer.data = (unsigned long)ieee;
++ ieee->associate_timer.function = ieee80211_associate_abort_cb;
++
++ init_timer(&ieee->beacon_timer);
++ ieee->beacon_timer.data = (unsigned long) ieee;
++ ieee->beacon_timer.function = ieee80211_send_beacon_cb;
++
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
++#ifdef PF_SYNCTHREAD
++ ieee->wq = create_workqueue(DRV_NAME,0);
++#else
++ ieee->wq = create_workqueue(DRV_NAME);
++#endif
++#endif
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)//added by lawrence,070702
++ INIT_DELAYED_WORK(&ieee->start_ibss_wq, ieee80211_start_ibss_wq);
++ INIT_WORK(&ieee->associate_complete_wq, ieee80211_associate_complete_wq);
++ INIT_WORK(&ieee->associate_procedure_wq, ieee80211_associate_procedure_wq);
++ INIT_DELAYED_WORK(&ieee->softmac_scan_wq, ieee80211_softmac_scan_wq);
++ INIT_DELAYED_WORK(&ieee->associate_retry_wq, ieee80211_associate_retry_wq);
++ INIT_WORK(&ieee->wx_sync_scan_wq, ieee80211_wx_sync_scan_wq);
++//added by lawrence,20071118
++#ifdef _RTL8187_EXT_PATCH_
++ INIT_WORK(&ieee->ext_stop_scan_wq, ieee80211_ext_stop_scan_wq);
++ //INIT_WORK(&ieee->ext_send_beacon_wq, ieee80211_beacons_start,ieee);
++ INIT_WORK(&ieee->ext_send_beacon_wq, ext_ieee80211_send_beacon_wq);
++#endif //_RTL8187_EXT_PATCH_
++#else
++ INIT_WORK(&ieee->start_ibss_wq,(void(*)(void*)) ieee80211_start_ibss_wq,ieee);
++ INIT_WORK(&ieee->associate_retry_wq,(void(*)(void*)) ieee80211_associate_retry_wq,ieee);
++ INIT_WORK(&ieee->associate_complete_wq,(void(*)(void*)) ieee80211_associate_complete_wq,ieee);
++ INIT_WORK(&ieee->associate_procedure_wq,(void(*)(void*)) ieee80211_associate_procedure_wq,ieee);
++ INIT_WORK(&ieee->softmac_scan_wq,(void(*)(void*)) ieee80211_softmac_scan_wq,ieee);
++ INIT_WORK(&ieee->wx_sync_scan_wq,(void(*)(void*)) ieee80211_wx_sync_scan_wq,ieee);
++#ifdef _RTL8187_EXT_PATCH_
++ INIT_WORK(&ieee->ext_stop_scan_wq,(void(*)(void*)) ieee80211_ext_stop_scan_wq,ieee);
++ //INIT_WORK(&ieee->ext_send_beacon_wq,(void(*)(void*)) ieee80211_beacons_start,ieee);
++ INIT_WORK(&ieee->ext_send_beacon_wq,(void(*)(void*)) ext_ieee80211_send_beacon_wq,ieee);
++#endif
++#endif
++#else
++ tq_init(&ieee->start_ibss_wq,(void(*)(void*)) ieee80211_start_ibss_wq,ieee);
++ tq_init(&ieee->associate_retry_wq,(void(*)(void*)) ieee80211_associate_retry_wq,ieee);
++ tq_init(&ieee->associate_complete_wq,(void(*)(void*)) ieee80211_associate_complete_wq,ieee);
++ tq_init(&ieee->associate_procedure_wq,(void(*)(void*)) ieee80211_associate_procedure_wq,ieee);
++ tq_init(&ieee->softmac_scan_wq,(void(*)(void*)) ieee80211_softmac_scan_wq,ieee);
++ tq_init(&ieee->wx_sync_scan_wq,(void(*)(void*)) ieee80211_wx_sync_scan_wq,ieee);
++#ifdef _RTL8187_EXT_PATCH_
++ tq_init(&ieee->ext_stop_scan_wq,(void(*)(void*)) ieee80211_ext_stop_scan_wq,ieee);
++ //tq_init(&ieee->ext_send_beacon_wq,(void(*)(void*)) ieee80211_beacons_start,ieee);
++ tq_init(&ieee->ext_send_beacon_wq,(void(*)(void*)) ext_ieee80211_send_beacon_wq,ieee);
++#endif
++#endif
++ sema_init(&ieee->wx_sem, 1);
++ sema_init(&ieee->scan_sem, 1);
++ sema_init(&ieee->ips_sem,1);
++ spin_lock_init(&ieee->mgmt_tx_lock);
++ spin_lock_init(&ieee->beacon_lock);
++ spin_lock_init(&ieee->beaconflag_lock);
++ tasklet_init(&ieee->ps_task,
++ (void(*)(unsigned long)) ieee80211_sta_ps,
++ (unsigned long)ieee);
++#ifdef ENABLE_DOT11D
++ ieee->pDot11dInfo = kmalloc(sizeof(RT_DOT11D_INFO), GFP_ATOMIC);
++#endif
++
++}
++
++void ieee80211_softmac_free(struct ieee80211_device *ieee)
++{
++ down(&ieee->wx_sem);
++
++ del_timer_sync(&ieee->associate_timer);
++
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
++ cancel_delayed_work(&ieee->associate_retry_wq);
++
++
++
++#ifdef _RTL8187_EXT_PATCH_
++ //When kernel>2.6.20,crash....
++// cancel_delayed_work(&ieee->ext_stop_scan_wq);
++// cancel_delayed_work(&ieee->ext_send_beacon_wq);
++#endif
++ destroy_workqueue(ieee->wq);
++#endif
++
++#ifdef ENABLE_DOT11D
++ if(NULL != ieee->pDot11dInfo)
++ kfree(ieee->pDot11dInfo);
++#endif
++
++ up(&ieee->wx_sem);
++}
++
++/********************************************************
++ * Start of WPA code. *
++ * this is stolen from the ipw2200 driver *
++ ********************************************************/
++
++
++static int ieee80211_wpa_enable(struct ieee80211_device *ieee, int value)
++{
++ /* This is called when wpa_supplicant loads and closes the driver
++ * interface. */
++ printk("%s WPA\n",value ? "enabling" : "disabling");
++ ieee->wpa_enabled = value;
++ return 0;
++}
++
++
++void ieee80211_wpa_assoc_frame(struct ieee80211_device *ieee, char *wpa_ie, int wpa_ie_len)
++{
++ /* make sure WPA is enabled */
++ ieee80211_wpa_enable(ieee, 1);
++
++ ieee80211_disassociate(ieee);
++}
++
++
++static int ieee80211_wpa_mlme(struct ieee80211_device *ieee, int command, int reason)
++{
++
++ int ret = 0;
++
++ switch (command) {
++ case IEEE_MLME_STA_DEAUTH:
++ // silently ignore
++ break;
++
++ case IEEE_MLME_STA_DISASSOC:
++ ieee80211_disassociate(ieee);
++ break;
++
++ default:
++ printk("Unknown MLME request: %d\n", command);
++ ret = -EOPNOTSUPP;
++ }
++
++ return ret;
++}
++
++
++static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device *ieee,
++ struct ieee_param *param, int plen)
++{
++ u8 *buf;
++
++ if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
++ (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL))
++ return -EINVAL;
++
++ if (param->u.wpa_ie.len) {
++ buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL);
++ if (buf == NULL)
++ return -ENOMEM;
++
++ memcpy(buf, param->u.wpa_ie.data, param->u.wpa_ie.len);
++ kfree(ieee->wpa_ie);
++ ieee->wpa_ie = buf;
++ ieee->wpa_ie_len = param->u.wpa_ie.len;
++ } else {
++ kfree(ieee->wpa_ie);
++ ieee->wpa_ie = NULL;
++ ieee->wpa_ie_len = 0;
++ }
++
++ ieee80211_wpa_assoc_frame(ieee, ieee->wpa_ie, ieee->wpa_ie_len);
++ return 0;
++}
++
++#define AUTH_ALG_OPEN_SYSTEM 0x1
++#define AUTH_ALG_SHARED_KEY 0x2
++
++static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value)
++{
++
++ struct ieee80211_security sec = {
++ .flags = SEC_AUTH_MODE,
++ };
++ int ret = 0;
++
++ if (value & AUTH_ALG_SHARED_KEY) {
++ sec.auth_mode = WLAN_AUTH_SHARED_KEY;
++ ieee->open_wep = 0;
++ } else {
++ sec.auth_mode = WLAN_AUTH_OPEN;
++ ieee->open_wep = 1;
++ }
++
++ if (ieee->set_security)
++ ieee->set_security(ieee->dev, &sec);
++ else
++ ret = -EOPNOTSUPP;
++
++ return ret;
++}
++
++static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 value)
++{
++ int ret=0;
++ unsigned long flags;
++
++ switch (name) {
++ case IEEE_PARAM_WPA_ENABLED:
++ ret = ieee80211_wpa_enable(ieee, value);
++ break;
++
++ case IEEE_PARAM_TKIP_COUNTERMEASURES:
++ ieee->tkip_countermeasures=value;
++ break;
++
++ case IEEE_PARAM_DROP_UNENCRYPTED: {
++ /* HACK:
++ *
++ * wpa_supplicant calls set_wpa_enabled when the driver
++ * is loaded and unloaded, regardless of if WPA is being
++ * used. No other calls are made which can be used to
++ * determine if encryption will be used or not prior to
++ * association being expected. If encryption is not being
++ * used, drop_unencrypted is set to false, else true -- we
++ * can use this to determine if the CAP_PRIVACY_ON bit should
++ * be set.
++ */
++ struct ieee80211_security sec = {
++ .flags = SEC_ENABLED,
++ .enabled = value,
++ };
++ ieee->drop_unencrypted = value;
++ /* We only change SEC_LEVEL for open mode. Others
++ * are set by ipw_wpa_set_encryption.
++ */
++ if (!value) {
++ sec.flags |= SEC_LEVEL;
++ sec.level = SEC_LEVEL_0;
++ }
++ else {
++ sec.flags |= SEC_LEVEL;
++ sec.level = SEC_LEVEL_1;
++ }
++ if (ieee->set_security)
++ ieee->set_security(ieee->dev, &sec);
++ break;
++ }
++
++ case IEEE_PARAM_PRIVACY_INVOKED:
++ ieee->privacy_invoked=value;
++ break;
++
++ case IEEE_PARAM_AUTH_ALGS:
++ ret = ieee80211_wpa_set_auth_algs(ieee, value);
++ break;
++
++ case IEEE_PARAM_IEEE_802_1X:
++ ieee->ieee802_1x=value;
++ break;
++ case IEEE_PARAM_WPAX_SELECT:
++ // added for WPA2 mixed mode
++ //printk(KERN_WARNING "------------------------>wpax value = %x\n", value);
++ spin_lock_irqsave(&ieee->wpax_suitlist_lock,flags);
++ ieee->wpax_type_set = 1;
++ ieee->wpax_type_notify = value;
++ spin_unlock_irqrestore(&ieee->wpax_suitlist_lock,flags);
++ break;
++
++ default:
++ printk("Unknown WPA param: %d\n",name);
++ ret = -EOPNOTSUPP;
++ }
++
++ return ret;
++}
++
++/* implementation borrowed from hostap driver */
++
++static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
++ struct ieee_param *param, int param_len)
++{
++ int ret = 0;
++
++ struct ieee80211_crypto_ops *ops;
++ struct ieee80211_crypt_data **crypt;
++
++ struct ieee80211_security sec = {
++ .flags = 0,
++ };
++
++ param->u.crypt.err = 0;
++ param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
++
++ if (param_len !=
++ (int) ((char *) param->u.crypt.key - (char *) param) +
++ param->u.crypt.key_len) {
++ printk("Len mismatch %d, %d\n", param_len,
++ param->u.crypt.key_len);
++ return -EINVAL;
++ }
++ if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
++ param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
++ param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
++ if (param->u.crypt.idx >= WEP_KEYS)
++ return -EINVAL;
++#ifdef _RTL8187_EXT_PATCH_
++ crypt = &ieee->cryptlist[0]->crypt[param->u.crypt.idx];
++#else
++ crypt = &ieee->crypt[param->u.crypt.idx];
++#endif
++
++ } else {
++ return -EINVAL;
++ }
++
++ if (strcmp(param->u.crypt.alg, "none") == 0) {
++ if (crypt) {
++ sec.enabled = 0;
++ // FIXME FIXME
++ //sec.encrypt = 0;
++ sec.level = SEC_LEVEL_0;
++ sec.flags |= SEC_ENABLED | SEC_LEVEL;
++ ieee80211_crypt_delayed_deinit(ieee, crypt);
++ }
++ goto done;
++ }
++ sec.enabled = 1;
++// FIXME FIXME
++// sec.encrypt = 1;
++ sec.flags |= SEC_ENABLED;
++
++ /* IPW HW cannot build TKIP MIC, host decryption still needed. */
++ if (!(ieee->host_encrypt || ieee->host_decrypt) &&
++ strcmp(param->u.crypt.alg, "TKIP"))
++ goto skip_host_crypt;
++
++ ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
++ if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
++ request_module("ieee80211_crypt_wep");
++ ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
++ } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
++ request_module("ieee80211_crypt_tkip");
++ ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
++ } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
++ request_module("ieee80211_crypt_ccmp");
++ ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
++ }
++ if (ops == NULL) {
++ printk("unknown crypto alg '%s'\n", param->u.crypt.alg);
++ param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG;
++ ret = -EINVAL;
++ goto done;
++ }
++
++#ifdef _RTL8187_EXT_PATCH_
++ u8 i;
++ for (i=0; i<MAX_MP; i++){
++ crypt = &ieee->cryptlist[i]->crypt[param->u.crypt.idx];
++// if (crypt != NULL) printk("crypt not null\n", crypt);
++
++ *crypt = ieee->cryptlist[i]->crypt[param->u.crypt.idx];
++#endif
++ if (*crypt == NULL || (*crypt)->ops != ops) {
++ struct ieee80211_crypt_data *new_crypt;
++
++ ieee80211_crypt_delayed_deinit(ieee, crypt);
++
++ new_crypt = (struct ieee80211_crypt_data *)
++ kmalloc(sizeof(*new_crypt), GFP_KERNEL);
++ if (new_crypt == NULL) {
++ ret = -ENOMEM;
++ goto done;
++ }
++ memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
++ new_crypt->ops = ops;
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
++ if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
++#else
++ if (new_crypt->ops && try_inc_mod_count(new_crypt->ops->owner))
++#endif
++ new_crypt->priv =
++ new_crypt->ops->init(param->u.crypt.idx);
++
++ if (new_crypt->priv == NULL) {
++ kfree(new_crypt);
++ param->u.crypt.err = IEEE_CRYPT_ERR_CRYPT_INIT_FAILED;
++ ret = -EINVAL;
++ goto done;
++ }
++
++ *crypt = new_crypt;
++ }
++
++ if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key &&
++ (*crypt)->ops->set_key(param->u.crypt.key,
++ param->u.crypt.key_len, param->u.crypt.seq,
++ (*crypt)->priv) < 0) {
++ printk("key setting failed\n");
++ param->u.crypt.err = IEEE_CRYPT_ERR_KEY_SET_FAILED;
++ ret = -EINVAL;
++ goto done;
++ }
++#ifdef _RTL8187_EXT_PATCH_
++ }
++#endif
++ skip_host_crypt:
++ if (param->u.crypt.set_tx) {
++ ieee->tx_keyidx = param->u.crypt.idx;
++ sec.active_key = param->u.crypt.idx;
++ sec.flags |= SEC_ACTIVE_KEY;
++ } else
++ sec.flags &= ~SEC_ACTIVE_KEY;
++
++ if (param->u.crypt.alg != NULL) {
++ memcpy(sec.keys[param->u.crypt.idx],
++ param->u.crypt.key,
++ param->u.crypt.key_len);
++ sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len;
++ sec.flags |= (1 << param->u.crypt.idx);
++
++ if (strcmp(param->u.crypt.alg, "WEP") == 0) {
++ sec.flags |= SEC_LEVEL;
++ sec.level = SEC_LEVEL_1;
++ } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
++ sec.flags |= SEC_LEVEL;
++ sec.level = SEC_LEVEL_2;
++ } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
++ sec.flags |= SEC_LEVEL;
++ sec.level = SEC_LEVEL_3;
++ }
++ }
++ done:
++ if (ieee->set_security)
++ ieee->set_security(ieee->dev, &sec);
++#if 1
++#ifdef _RTL8187_EXT_PATCH_
++ if (ret != 0)//error out
++ {
++ for (i=0; i<MAX_MP; i++)
++ {
++ if (ieee->cryptlist[i]->crypt[param->u.crypt.idx]==NULL){
++ break;
++ }
++ else{
++ //if (ieee->cryptlist[i]->crypt[param->u.crypt.idx] != NULL)
++ // {
++ kfree(ieee->cryptlist[i]->crypt[param->u.crypt.idx]);
++ ieee->cryptlist[i]->crypt[param->u.crypt.idx] = NULL;
++ // }
++ // kfree(ieee->cryptlist[i]);
++ // ieee->cryptlist[i] = NULL;
++ }
++ }
++ }
++#endif
++#endif
++ /* Do not reset port if card is in Managed mode since resetting will
++ * generate new IEEE 802.11 authentication which may end up in looping
++ * with IEEE 802.1X. If your hardware requires a reset after WEP
++ * configuration (for example... Prism2), implement the reset_port in
++ * the callbacks structures used to initialize the 802.11 stack. */
++ if (ieee->reset_on_keychange &&
++ ieee->iw_mode != IW_MODE_INFRA &&
++ ieee->reset_port &&
++ ieee->reset_port(ieee->dev)) {
++ printk("reset_port failed\n");
++ param->u.crypt.err = IEEE_CRYPT_ERR_CARD_CONF_FAILED;
++ return -EINVAL;
++ }
++
++ return ret;
++}
++
++int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p)
++{
++ struct ieee_param *param;
++ int ret=0;
++
++ down(&ieee->wx_sem);
++ //IEEE_DEBUG_INFO("wpa_supplicant: len=%d\n", p->length);
++
++ if (p->length < sizeof(struct ieee_param) || !p->pointer){
++ ret = -EINVAL;
++ goto out;
++ }
++
++ param = (struct ieee_param *)kmalloc(p->length, GFP_KERNEL);
++ if (param == NULL){
++ ret = -ENOMEM;
++ goto out;
++ }
++ if (copy_from_user(param, p->pointer, p->length)) {
++ kfree(param);
++ ret = -EFAULT;
++ goto out;
++ }
++
++ switch (param->cmd) {
++
++ case IEEE_CMD_SET_WPA_PARAM:
++ ret = ieee80211_wpa_set_param(ieee, param->u.wpa_param.name,
++ param->u.wpa_param.value);
++ break;
++
++ case IEEE_CMD_SET_WPA_IE:
++ ret = ieee80211_wpa_set_wpa_ie(ieee, param, p->length);
++ break;
++
++ case IEEE_CMD_SET_ENCRYPTION:
++ ret = ieee80211_wpa_set_encryption(ieee, param, p->length);
++ break;
++
++ case IEEE_CMD_MLME:
++ ret = ieee80211_wpa_mlme(ieee, param->u.mlme.command,
++ param->u.mlme.reason_code);
++ break;
++
++ default:
++ printk("Unknown WPA supplicant request: %d\n",param->cmd);
++ ret = -EOPNOTSUPP;
++ break;
++ }
++
++ if (ret == 0 && copy_to_user(p->pointer, param, p->length))
++ ret = -EFAULT;
++
++ kfree(param);
++out:
++ up(&ieee->wx_sem);
++
++ return ret;
++}
++
++void notify_wx_assoc_event(struct ieee80211_device *ieee)
++{
++ union iwreq_data wrqu;
++ wrqu.ap_addr.sa_family = ARPHRD_ETHER;
++ if (ieee->state == IEEE80211_LINKED)
++ memcpy(wrqu.ap_addr.sa_data, ieee->current_network.bssid, ETH_ALEN);
++ else
++ memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
++ wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL);
++}
++
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
++EXPORT_SYMBOL(ieee80211_get_beacon);
++EXPORT_SYMBOL(ieee80211_wake_queue);
++EXPORT_SYMBOL(ieee80211_stop_queue);
++EXPORT_SYMBOL(ieee80211_reset_queue);
++EXPORT_SYMBOL(ieee80211_softmac_stop_protocol);
++EXPORT_SYMBOL(ieee80211_softmac_start_protocol);
++EXPORT_SYMBOL(ieee80211_is_shortslot);
++EXPORT_SYMBOL(ieee80211_is_54g);
++EXPORT_SYMBOL(ieee80211_wpa_supplicant_ioctl);
++EXPORT_SYMBOL(ieee80211_ps_tx_ack);
++EXPORT_SYMBOL(notify_wx_assoc_event);
++EXPORT_SYMBOL(ieee80211_stop_send_beacons);
++EXPORT_SYMBOL(ieee80211_start_send_beacons);
++EXPORT_SYMBOL(ieee80211_start_scan_syncro);
++EXPORT_SYMBOL(ieee80211_start_protocol);
++EXPORT_SYMBOL(ieee80211_stop_protocol);
++EXPORT_SYMBOL(ieee80211_start_scan);
++EXPORT_SYMBOL(ieee80211_stop_scan);
++#ifdef _RTL8187_EXT_PATCH_
++EXPORT_SYMBOL(ieee80211_ext_issue_assoc_req);
++EXPORT_SYMBOL(ieee80211_ext_issue_disassoc);
++EXPORT_SYMBOL(ieee80211_ext_issue_assoc_rsp);
++EXPORT_SYMBOL(softmac_mgmt_xmit);
++EXPORT_SYMBOL(ieee80211_ext_probe_resp_by_net);
++EXPORT_SYMBOL(ieee80211_stop_scan);
++EXPORT_SYMBOL(ieee80211_ext_send_11s_beacon);
++EXPORT_SYMBOL(ieee80211_rx_auth_rq);
++EXPORT_SYMBOL(ieee80211_associate_step1);
++#endif // _RTL8187_EXT_PATCH_
++#else
++EXPORT_SYMBOL_NOVERS(ieee80211_get_beacon);
++EXPORT_SYMBOL_NOVERS(ieee80211_wake_queue);
++EXPORT_SYMBOL_NOVERS(ieee80211_stop_queue);
++EXPORT_SYMBOL_NOVERS(ieee80211_reset_queue);
++EXPORT_SYMBOL_NOVERS(ieee80211_softmac_stop_protocol);
++EXPORT_SYMBOL_NOVERS(ieee80211_softmac_start_protocol);
++EXPORT_SYMBOL_NOVERS(ieee80211_is_shortslot);
++EXPORT_SYMBOL_NOVERS(ieee80211_is_54g);
++EXPORT_SYMBOL_NOVERS(ieee80211_wpa_supplicant_ioctl);
++EXPORT_SYMBOL_NOVERS(ieee80211_ps_tx_ack);
++EXPORT_SYMBOL_NOVERS(ieee80211_start_scan);
++EXPORT_SYMBOL_NOVERS(ieee80211_stop_scan);
++#ifdef _RTL8187_EXT_PATCH_
++EXPORT_SYMBOL_NOVERS(ieee80211_ext_issue_assoc_req);
++EXPORT_SYMBOL_NOVERS(ieee80211_ext_issue_disassoc);
++EXPORT_SYMBOL_NOVERS(ieee80211_ext_issue_assoc_rsp);
++EXPORT_SYMBOL_NOVERS(softmac_mgmt_xmit);
++EXPORT_SYMBOL_NOVERS(ieee80211_ext_probe_resp_by_net);
++EXPORT_SYMBOL_NOVERS(ieee80211_stop_scan);
++EXPORT_SYMBOL_NOVERS(ieee80211_ext_send_11s_beacon);
++EXPORT_SYMBOL_NOVERS(ieee80211_rx_auth_rq);
++EXPORT_SYMBOL(ieee80211_associate_step1);
++#endif // _RTL8187_EXT_PATCH_
++
++#endif
++//EXPORT_SYMBOL(ieee80211_sta_ps_send_null_frame);
+diff --git a/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_softmac_wx.c b/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_softmac_wx.c
+new file mode 100644
+index 0000000..a23b9d0
+--- /dev/null
++++ b/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_softmac_wx.c
+@@ -0,0 +1,629 @@
++/* IEEE 802.11 SoftMAC layer
++ * Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
++ *
++ * Mostly extracted from the rtl8180-sa2400 driver for the
++ * in-kernel generic ieee802.11 stack.
++ *
++ * Some pieces of code might be stolen from ipw2100 driver
++ * copyright of who own it's copyright ;-)
++ *
++ * PS wx handler mostly stolen from hostap, copyright who
++ * own it's copyright ;-)
++ *
++ * released under the GPL
++ */
++
++
++#include "ieee80211.h"
++#ifdef ENABLE_DOT11D
++#include "dot11d.h"
++#endif
++
++/* FIXME: add A freqs */
++
++const long ieee80211_wlan_frequencies[] = {
++ 2412, 2417, 2422, 2427,
++ 2432, 2437, 2442, 2447,
++ 2452, 2457, 2462, 2467,
++ 2472, 2484
++};
++
++
++int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
++ union iwreq_data *wrqu, char *b)
++{
++ int ret;
++ struct iw_freq *fwrq = & wrqu->freq;
++
++ down(&ieee->wx_sem);
++
++ if(ieee->iw_mode == IW_MODE_INFRA){
++ ret = -EOPNOTSUPP;
++ goto out;
++ }
++
++ /* if setting by freq convert to channel */
++ if (fwrq->e == 1) {
++ if ((fwrq->m >= (int) 2.412e8 &&
++ fwrq->m <= (int) 2.487e8)) {
++ int f = fwrq->m / 100000;
++ int c = 0;
++
++ while ((c < 14) && (f != ieee80211_wlan_frequencies[c]))
++ c++;
++
++ /* hack to fall through */
++ fwrq->e = 0;
++ fwrq->m = c + 1;
++ }
++ }
++
++ if (fwrq->e > 0 || fwrq->m > 14 || fwrq->m < 1 ){
++ ret = -EOPNOTSUPP;
++ goto out;
++
++ }else { /* Set the channel */
++
++#ifdef ENABLE_DOT11D
++ if(!IsLegalChannel(ieee, fwrq->m) )
++ {
++ printk("channel(%d). is invalide\n", fwrq->m);
++ ret = -EOPNOTSUPP;
++ goto out;
++ }
++ else
++ {
++ if(ieee->iw_mode == IW_MODE_ADHOC)
++ {
++ if(ieee->MinPassiveChnlNum != MAX_CHANNEL_NUMBER+1)
++ {
++ if(fwrq->m >= ieee->MinPassiveChnlNum)
++ {
++ ret = -EOPNOTSUPP;
++ goto out;
++ }
++ }
++ }
++ }
++#endif
++ ieee->current_network.channel = fwrq->m;
++ ieee->set_chan(ieee->dev, ieee->current_network.channel);
++
++ if(ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER)
++ if(ieee->state == IEEE80211_LINKED){
++
++ ieee80211_stop_send_beacons(ieee);
++ ieee80211_start_send_beacons(ieee);
++ }
++ }
++
++ ret = 0;
++out:
++ up(&ieee->wx_sem);
++ return ret;
++}
++
++
++int ieee80211_wx_get_freq(struct ieee80211_device *ieee,
++ struct iw_request_info *a,
++ union iwreq_data *wrqu, char *b)
++{
++ struct iw_freq *fwrq = & wrqu->freq;
++
++ if (ieee->current_network.channel == 0)
++ return -1;
++
++ fwrq->m = ieee->current_network.channel;
++ fwrq->e = 0;
++
++ return 0;
++}
++
++int ieee80211_wx_get_wap(struct ieee80211_device *ieee,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ unsigned long flags;
++
++ wrqu->ap_addr.sa_family = ARPHRD_ETHER;
++
++ if (ieee->iw_mode == IW_MODE_MONITOR)
++ return -1;
++
++ /* We want avoid to give to the user inconsistent infos*/
++ spin_lock_irqsave(&ieee->lock, flags);
++
++ if (ieee->state != IEEE80211_LINKED &&
++ ieee->state != IEEE80211_LINKED_SCANNING &&
++ ieee->wap_set == 0)
++
++ memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
++ else
++ memcpy(wrqu->ap_addr.sa_data,
++ ieee->current_network.bssid, ETH_ALEN);
++
++ spin_unlock_irqrestore(&ieee->lock, flags);
++
++ return 0;
++}
++
++
++int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
++ struct iw_request_info *info,
++ union iwreq_data *awrq,
++ char *extra)
++{
++
++ int ret = 0;
++ u8 zero[] = {0,0,0,0,0,0};
++ unsigned long flags;
++
++ short ifup = ieee->proto_started;//dev->flags & IFF_UP;
++ struct sockaddr *temp = (struct sockaddr *)awrq;
++
++ ieee->sync_scan_hurryup = 1;
++
++ down(&ieee->wx_sem);
++ /* use ifconfig hw ether */
++ if (ieee->iw_mode == IW_MODE_MASTER){
++ ret = -1;
++ goto out;
++ }
++
++ if (temp->sa_family != ARPHRD_ETHER){
++ ret = -EINVAL;
++ goto out;
++ }
++
++ if (ifup)
++ ieee80211_stop_protocol(ieee);
++
++ /* just to avoid to give inconsistent infos in the
++ * get wx method. not really needed otherwise
++ */
++ spin_lock_irqsave(&ieee->lock, flags);
++
++ memcpy(ieee->current_network.bssid, temp->sa_data, ETH_ALEN);
++ ieee->wap_set = memcmp(temp->sa_data, zero,ETH_ALEN)!=0;
++
++ spin_unlock_irqrestore(&ieee->lock, flags);
++
++ if (ifup)
++ ieee80211_start_protocol(ieee);
++
++out:
++ up(&ieee->wx_sem);
++ return ret;
++}
++
++ int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b)
++{
++ int len,ret = 0;
++ unsigned long flags;
++
++ if (ieee->iw_mode == IW_MODE_MONITOR)
++ return -1;
++
++ /* We want avoid to give to the user inconsistent infos*/
++ spin_lock_irqsave(&ieee->lock, flags);
++
++ if (ieee->current_network.ssid[0] == '\0' ||
++ ieee->current_network.ssid_len == 0){
++ ret = -1;
++ goto out;
++ }
++
++ if (ieee->state != IEEE80211_LINKED &&
++ ieee->state != IEEE80211_LINKED_SCANNING &&
++ ieee->ssid_set == 0){
++ ret = -1;
++ goto out;
++ }
++ len = ieee->current_network.ssid_len;
++ wrqu->essid.length = len;
++ strncpy(b,ieee->current_network.ssid,len);
++ wrqu->essid.flags = 1;
++
++out:
++ spin_unlock_irqrestore(&ieee->lock, flags);
++
++ return ret;
++
++}
++
++int ieee80211_wx_set_rate(struct ieee80211_device *ieee,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++
++ u32 target_rate = wrqu->bitrate.value;
++
++ ieee->rate = target_rate/100000;
++ //FIXME: we might want to limit rate also in management protocols.
++ return 0;
++}
++
++
++
++int ieee80211_wx_get_rate(struct ieee80211_device *ieee,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++
++ wrqu->bitrate.value = ieee->rate * 100000;
++
++ return 0;
++}
++
++int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
++ union iwreq_data *wrqu, char *b)
++{
++
++ ieee->sync_scan_hurryup = 1;
++
++ down(&ieee->wx_sem);
++ //printk("=======>%s\n", __func__);
++
++ if (wrqu->mode == ieee->iw_mode)
++ goto out;
++
++ if (wrqu->mode == IW_MODE_MONITOR){
++
++ ieee->dev->type = ARPHRD_IEEE80211;
++ }else{
++ ieee->dev->type = ARPHRD_ETHER;
++ }
++
++ if (!ieee->proto_started){
++ ieee->iw_mode = wrqu->mode;
++ }else{
++ ieee80211_stop_protocol(ieee);
++ ieee->iw_mode = wrqu->mode;
++ ieee80211_start_protocol(ieee);
++ }
++
++out:
++ up(&ieee->wx_sem);
++ return 0;
++}
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
++void ieee80211_wx_sync_scan_wq(struct work_struct *work)
++{
++ struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, wx_sync_scan_wq);
++#else
++void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee)
++{
++#endif
++ short chan;
++
++ chan = ieee->current_network.channel;
++
++ netif_carrier_off(ieee->dev);
++
++ if (ieee->data_hard_stop)
++ ieee->data_hard_stop(ieee->dev);
++
++ ieee80211_stop_send_beacons(ieee);
++
++ ieee->state = IEEE80211_LINKED_SCANNING;
++ ieee->link_change(ieee->dev);
++
++ ieee80211_start_scan_syncro(ieee);
++
++ ieee->set_chan(ieee->dev, chan);
++
++ ieee->state = IEEE80211_LINKED;
++ ieee->link_change(ieee->dev);
++
++ if (ieee->data_hard_resume)
++ ieee->data_hard_resume(ieee->dev);
++
++ if(ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER)
++ ieee80211_start_send_beacons(ieee);
++
++ netif_carrier_on(ieee->dev);
++
++ up(&ieee->wx_sem);
++
++}
++
++int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a,
++ union iwreq_data *wrqu, char *b)
++{
++ int ret = 0;
++
++ down(&ieee->wx_sem);
++
++ if (ieee->iw_mode == IW_MODE_MONITOR || !(ieee->proto_started)){
++ ret = -1;
++ goto out;
++ }
++
++ if ( ieee->state == IEEE80211_LINKED){
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
++ queue_work(ieee->wq, &ieee->wx_sync_scan_wq);
++#else
++ schedule_task(&ieee->wx_sync_scan_wq);
++#endif
++ /* intentionally forget to up sem */
++ return 0;
++ }
++
++out:
++ up(&ieee->wx_sem);
++ return ret;
++}
++
++int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
++ struct iw_request_info *a,
++ union iwreq_data *wrqu, char *extra)
++{
++
++ int ret=0,len;
++ short proto_started;
++ unsigned long flags;
++
++ ieee->sync_scan_hurryup = 1;
++
++ down(&ieee->wx_sem);
++
++ //printk("=======>%s\n", __func__);
++ proto_started = ieee->proto_started;
++
++ if (wrqu->essid.length > IW_ESSID_MAX_SIZE){
++ ret= -E2BIG;
++ goto out;
++ }
++
++ if (ieee->iw_mode == IW_MODE_MONITOR){
++ ret= -1;
++ goto out;
++ }
++
++ if(proto_started){
++ ieee80211_stop_protocol(ieee);
++ }
++
++ /* this is just to be sure that the GET wx callback
++ * has consisten infos. not needed otherwise
++ */
++ spin_lock_irqsave(&ieee->lock, flags);
++
++ if (wrqu->essid.flags && wrqu->essid.length) {
++ len = ((wrqu->essid.length-1) < IW_ESSID_MAX_SIZE) ? (wrqu->essid.length-1) : IW_ESSID_MAX_SIZE;
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
++ strncpy(ieee->current_network.ssid, extra, len);
++ ieee->current_network.ssid_len = len;
++#else
++ strncpy(ieee->current_network.ssid, extra, len+1);
++ ieee->current_network.ssid_len = len+1;
++#endif
++ ieee->ssid_set = 1;
++ //YJ,add,080819,for hidden ap
++ if(len == 0){
++ memset(ieee->current_network.bssid, 0, ETH_ALEN);
++ ieee->current_network.capability = 0;
++ }
++ //YJ,add,080819,for hidden ap,end
++ }
++ else{
++ ieee->ssid_set = 0;
++ ieee->current_network.ssid[0] = '\0';
++ ieee->current_network.ssid_len = 0;
++ }
++
++ spin_unlock_irqrestore(&ieee->lock, flags);
++
++ if (proto_started){
++ ieee80211_start_protocol(ieee);
++ }
++out:
++ up(&ieee->wx_sem);
++ return ret;
++}
++
++ int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
++ union iwreq_data *wrqu, char *b)
++{
++
++ wrqu->mode = ieee->iw_mode;
++ return 0;
++}
++
++ int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++
++ int *parms = (int *)extra;
++ int enable = (parms[0] > 0);
++ short prev = ieee->raw_tx;
++
++ down(&ieee->wx_sem);
++
++ if(enable)
++ ieee->raw_tx = 1;
++ else
++ ieee->raw_tx = 0;
++
++ printk(KERN_INFO"raw TX is %s\n",
++ ieee->raw_tx ? "enabled" : "disabled");
++
++ if(ieee->iw_mode == IW_MODE_MONITOR)
++ {
++ if(prev == 0 && ieee->raw_tx){
++ if (ieee->data_hard_resume)
++ ieee->data_hard_resume(ieee->dev);
++
++ netif_carrier_on(ieee->dev);
++ }
++
++ if(prev && ieee->raw_tx == 1)
++ netif_carrier_off(ieee->dev);
++ }
++
++ up(&ieee->wx_sem);
++
++ return 0;
++}
++
++int ieee80211_wx_get_name(struct ieee80211_device *ieee,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ strcpy(wrqu->name, "802.11");
++ if(ieee->modulation & IEEE80211_CCK_MODULATION){
++ strcat(wrqu->name, "b");
++ if(ieee->modulation & IEEE80211_OFDM_MODULATION)
++ strcat(wrqu->name, "/g");
++ }else if(ieee->modulation & IEEE80211_OFDM_MODULATION)
++ strcat(wrqu->name, "g");
++
++ if((ieee->state == IEEE80211_LINKED) ||
++ (ieee->state == IEEE80211_LINKED_SCANNING))
++ strcat(wrqu->name," linked");
++ else if(ieee->state != IEEE80211_NOLINK)
++ strcat(wrqu->name," link..");
++
++
++ return 0;
++}
++
++
++/* this is mostly stolen from hostap */
++int ieee80211_wx_set_power(struct ieee80211_device *ieee,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ int ret = 0;
++
++ if(
++ (!ieee->sta_wake_up) ||
++ (!ieee->ps_request_tx_ack) ||
++ (!ieee->enter_sleep_state) ||
++ (!ieee->ps_is_queue_empty)){
++
++ printk("ERROR. PS mode is tryied to be use but\
++driver missed a callback\n\n");
++
++ return -1;
++ }
++
++ down(&ieee->wx_sem);
++
++ if (wrqu->power.disabled){
++ ieee->ps = IEEE80211_PS_DISABLED;
++
++ goto exit;
++ }
++ switch (wrqu->power.flags & IW_POWER_MODE) {
++ case IW_POWER_UNICAST_R:
++ ieee->ps = IEEE80211_PS_UNICAST;
++
++ break;
++ case IW_POWER_ALL_R:
++ ieee->ps = IEEE80211_PS_UNICAST | IEEE80211_PS_MBCAST;
++ break;
++
++ case IW_POWER_ON:
++ ieee->ps = IEEE80211_PS_DISABLED;
++ break;
++
++ default:
++ ret = -EINVAL;
++ goto exit;
++ }
++
++ if (wrqu->power.flags & IW_POWER_TIMEOUT) {
++
++ ieee->ps_timeout = wrqu->power.value / 1000;
++ printk("Timeout %d\n",ieee->ps_timeout);
++ }
++
++ if (wrqu->power.flags & IW_POWER_PERIOD) {
++
++ ret = -EOPNOTSUPP;
++ goto exit;
++ //wrq->value / 1024;
++
++ }
++exit:
++ up(&ieee->wx_sem);
++ return ret;
++
++}
++
++/* this is stolen from hostap */
++int ieee80211_wx_get_power(struct ieee80211_device *ieee,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ int ret =0;
++
++ down(&ieee->wx_sem);
++
++ if(ieee->ps == IEEE80211_PS_DISABLED){
++ wrqu->power.disabled = 1;
++ goto exit;
++ }
++
++ wrqu->power.disabled = 0;
++
++// if ((wrqu->power.flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
++ wrqu->power.flags = IW_POWER_TIMEOUT;
++ wrqu->power.value = ieee->ps_timeout * 1000;
++// } else {
++// ret = -EOPNOTSUPP;
++// goto exit;
++ //wrqu->power.flags = IW_POWER_PERIOD;
++ //wrqu->power.value = ieee->current_network.dtim_period *
++ // ieee->current_network.beacon_interval * 1024;
++// }
++
++
++ if (ieee->ps & IEEE80211_PS_MBCAST)
++ wrqu->power.flags |= IW_POWER_ALL_R;
++ else
++ wrqu->power.flags |= IW_POWER_UNICAST_R;
++
++exit:
++ up(&ieee->wx_sem);
++ return ret;
++
++}
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
++EXPORT_SYMBOL(ieee80211_wx_get_essid);
++EXPORT_SYMBOL(ieee80211_wx_set_essid);
++EXPORT_SYMBOL(ieee80211_wx_set_rate);
++EXPORT_SYMBOL(ieee80211_wx_get_rate);
++EXPORT_SYMBOL(ieee80211_wx_set_wap);
++EXPORT_SYMBOL(ieee80211_wx_get_wap);
++EXPORT_SYMBOL(ieee80211_wx_set_mode);
++EXPORT_SYMBOL(ieee80211_wx_get_mode);
++EXPORT_SYMBOL(ieee80211_wx_set_scan);
++EXPORT_SYMBOL(ieee80211_wx_get_freq);
++EXPORT_SYMBOL(ieee80211_wx_set_freq);
++EXPORT_SYMBOL(ieee80211_wx_set_rawtx);
++EXPORT_SYMBOL(ieee80211_wx_get_name);
++EXPORT_SYMBOL(ieee80211_wx_set_power);
++EXPORT_SYMBOL(ieee80211_wx_get_power);
++EXPORT_SYMBOL(ieee80211_wlan_frequencies);
++#else
++EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_essid);
++EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_essid);
++EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_rate);
++EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_rate);
++EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_wap);
++EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_wap);
++EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_mode);
++EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_mode);
++EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_scan);
++EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_freq);
++EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_freq);
++EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_rawtx);
++EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_name);
++EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_power);
++EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_power);
++EXPORT_SYMBOL_NOVERS(ieee80211_wlan_frequencies);
++#endif
+diff --git a/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_tx.c b/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_tx.c
+new file mode 100644
+index 0000000..cad850f
+--- /dev/null
++++ b/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_tx.c
+@@ -0,0 +1,876 @@
++/******************************************************************************
++
++ Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
++
++ This program is free software; you can redistribute it and/or modify it
++ under the terms of version 2 of the GNU General Public License as
++ published by the Free Software Foundation.
++
++ 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 full GNU General Public License is included in this distribution in the
++ file called LICENSE.
++
++ Contact Information:
++ James P. Ketrenos <ipw2100-admin@linux.intel.com>
++ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
++
++******************************************************************************
++
++ Few modifications for Realtek's Wi-Fi drivers by
++ Andrea Merello <andreamrl@tiscali.it>
++
++ A special thanks goes to Realtek for their support !
++
++******************************************************************************/
++
++#include <linux/compiler.h>
++//#include <linux/config.h>
++#include <linux/errno.h>
++#include <linux/if_arp.h>
++#include <linux/in6.h>
++#include <linux/in.h>
++#include <linux/ip.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/netdevice.h>
++#include <linux/pci.h>
++#include <linux/proc_fs.h>
++#include <linux/skbuff.h>
++#include <linux/slab.h>
++#include <linux/tcp.h>
++#include <linux/types.h>
++#include <linux/version.h>
++#include <linux/wireless.h>
++#include <linux/etherdevice.h>
++#include <asm/uaccess.h>
++#include <linux/if_vlan.h>
++
++#include "ieee80211.h"
++
++
++/*
++
++
++802.11 Data Frame
++
++
++802.11 frame_contorl for data frames - 2 bytes
++ ,-----------------------------------------------------------------------------------------.
++bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e |
++ |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
++val | 0 | 0 | 0 | 1 | x | 0 | 0 | 0 | 1 | 0 | x | x | x | x | x |
++ |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
++desc | ^-ver-^ | ^type-^ | ^-----subtype-----^ | to |from |more |retry| pwr |more |wep |
++ | | | x=0 data,x=1 data+ack | DS | DS |frag | | mgm |data | |
++ '-----------------------------------------------------------------------------------------'
++ /\
++ |
++802.11 Data Frame |
++ ,--------- 'ctrl' expands to >-----------'
++ |
++ ,--'---,-------------------------------------------------------------.
++Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 |
++ |------|------|---------|---------|---------|------|---------|------|
++Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | Frame | fcs |
++ | | tion | (BSSID) | | | ence | data | |
++ `--------------------------------------------------| |------'
++Total: 28 non-data bytes `----.----'
++ |
++ .- 'Frame data' expands to <---------------------------'
++ |
++ V
++ ,---------------------------------------------------.
++Bytes | 1 | 1 | 1 | 3 | 2 | 0-2304 |
++ |------|------|---------|----------|------|---------|
++Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP |
++ | DSAP | SSAP | | | | Packet |
++ | 0xAA | 0xAA |0x03 (UI)|0x00-00-F8| | |
++ `-----------------------------------------| |
++Total: 8 non-data bytes `----.----'
++ |
++ .- 'IP Packet' expands, if WEP enabled, to <--'
++ |
++ V
++ ,-----------------------.
++Bytes | 4 | 0-2296 | 4 |
++ |-----|-----------|-----|
++Desc. | IV | Encrypted | ICV |
++ | | IP Packet | |
++ `-----------------------'
++Total: 8 non-data bytes
++
++
++802.3 Ethernet Data Frame
++
++ ,-----------------------------------------.
++Bytes | 6 | 6 | 2 | Variable | 4 |
++ |-------|-------|------|-----------|------|
++Desc. | Dest. | Source| Type | IP Packet | fcs |
++ | MAC | MAC | | | |
++ `-----------------------------------------'
++Total: 18 non-data bytes
++
++In the event that fragmentation is required, the incoming payload is split into
++N parts of size ieee->fts. The first fragment contains the SNAP header and the
++remaining packets are just data.
++
++If encryption is enabled, each fragment payload size is reduced by enough space
++to add the prefix and postfix (IV and ICV totalling 8 bytes in the case of WEP)
++So if you have 1500 bytes of payload with ieee->fts set to 500 without
++encryption it will take 3 frames. With WEP it will take 4 frames as the
++payload of each frame is reduced to 492 bytes.
++
++* SKB visualization
++*
++* ,- skb->data
++* |
++* | ETHERNET HEADER ,-<-- PAYLOAD
++* | | 14 bytes from skb->data
++* | 2 bytes for Type --> ,T. | (sizeof ethhdr)
++* | | | |
++* |,-Dest.--. ,--Src.---. | | |
++* | 6 bytes| | 6 bytes | | | |
++* v | | | | | |
++* 0 | v 1 | v | v 2
++* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
++* ^ | ^ | ^ |
++* | | | | | |
++* | | | | `T' <---- 2 bytes for Type
++* | | | |
++* | | '---SNAP--' <-------- 6 bytes for SNAP
++* | |
++* `-IV--' <-------------------- 4 bytes for IV (WEP)
++*
++* SNAP HEADER
++*
++*/
++
++static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
++static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
++
++static inline int ieee80211_put_snap(u8 *data, u16 h_proto)
++{
++ struct ieee80211_snap_hdr *snap;
++ u8 *oui;
++
++ snap = (struct ieee80211_snap_hdr *)data;
++ snap->dsap = 0xaa;
++ snap->ssap = 0xaa;
++ snap->ctrl = 0x03;
++
++ if (h_proto == 0x8137 || h_proto == 0x80f3)
++ oui = P802_1H_OUI;
++ else
++ oui = RFC1042_OUI;
++ snap->oui[0] = oui[0];
++ snap->oui[1] = oui[1];
++ snap->oui[2] = oui[2];
++
++ *(u16 *)(data + SNAP_SIZE) = htons(h_proto);
++
++ return SNAP_SIZE + sizeof(u16);
++}
++
++int ieee80211_encrypt_fragment(
++ struct ieee80211_device *ieee,
++ struct sk_buff *frag,
++ int hdr_len)
++{
++ struct ieee80211_crypt_data* crypt = NULL;//ieee->crypt[ieee->tx_keyidx];
++ int res;//, i;
++// printk("====>wwwwww%s():ieee:%x, hdr_len:%d\n", __FUNCTION__, ieee, hdr_len);
++/* printk("\n%s(), hdr_len:%d\n", __FUNCTION__, hdr_len);
++ for (i = 0; i < 48; i++) {
++ if (i % 16 == 0) printk("\n\t");
++ printk("%2x ", *(frag->data+i));
++ }
++*/
++
++#ifdef _RTL8187_EXT_PATCH_
++#if 0
++ i = ieee80211_find_MP(ieee, ((struct ieee80211_hdr*) frag->data)->addr1);
++ if (i== -1){
++ printk("error find MP entry in %s()\n", __FUNCTION__);
++ return i;
++ }
++ // printk("%s():"MAC_FMT", find in index:%d\n", __FUNCTION__, MAC_ARG(((struct ieee80211_hdr*)frag->data)->addr1), i);
++#endif
++// crypt = ieee->cryptlist[MAX_MP-1]->crypt[ieee->tx_keyidx];
++ crypt = ieee->cryptlist[0]->crypt[ieee->tx_keyidx];
++#else
++ crypt = ieee->crypt[ieee->tx_keyidx];
++#endif
++ /*added to care about null crypt condition, to solve that system hangs when shared keys error*/
++ if (!crypt || !crypt->ops)
++ return -1;
++
++#ifdef CONFIG_IEEE80211_CRYPT_TKIP
++ struct ieee80211_hdr *header;
++
++ if (ieee->tkip_countermeasures &&
++ crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
++ header = (struct ieee80211_hdr *) frag->data;
++ if (net_ratelimit()) {
++ printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
++ "TX packet to " MAC_FMT "\n",
++ ieee->dev->name, MAC_ARG(header->addr1));
++ }
++ return -1;
++ }
++#endif
++ /* To encrypt, frame format is:
++ * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */
++
++ // PR: FIXME: Copied from hostap. Check fragmentation/MSDU/MPDU encryption.
++ /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
++ * call both MSDU and MPDU encryption functions from here. */
++ atomic_inc(&crypt->refcnt);
++ res = 0;
++ if (crypt->ops->encrypt_msdu)
++ res = crypt->ops->encrypt_msdu(frag, hdr_len, crypt->priv);
++ if (res == 0 && crypt->ops->encrypt_mpdu)
++ res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv);
++ atomic_dec(&crypt->refcnt);
++ if (res < 0) {
++ printk(KERN_INFO "%s: Encryption failed: len=%d.\n",
++ ieee->dev->name, frag->len);
++ ieee->ieee_stats.tx_discards++;
++ return -1;
++ }
++
++ return 0;
++}
++
++
++void ieee80211_txb_free(struct ieee80211_txb *txb) {
++ int i;
++ if (unlikely(!txb))
++ return;
++ for (i = 0; i < txb->nr_frags; i++)
++ if (txb->fragments[i])
++ dev_kfree_skb_any(txb->fragments[i]);
++ kfree(txb);
++}
++
++struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
++ int gfp_mask)
++{
++ struct ieee80211_txb *txb;
++ int i;
++ txb = kmalloc(
++ sizeof(struct ieee80211_txb) + (sizeof(u8*) * nr_frags),
++ gfp_mask);
++ if (!txb)
++ return NULL;
++
++ memset(txb, 0, sizeof(struct ieee80211_txb));
++ txb->nr_frags = nr_frags;
++ txb->frag_size = txb_size;
++
++ for (i = 0; i < nr_frags; i++) {
++ txb->fragments[i] = dev_alloc_skb(txb_size);
++ if (unlikely(!txb->fragments[i])) {
++ i--;
++ break;
++ }
++ }
++ if (unlikely(i != nr_frags)) {
++ while (i >= 0)
++ dev_kfree_skb_any(txb->fragments[i--]);
++ kfree(txb);
++ return NULL;
++ }
++ return txb;
++}
++
++// Classify the to-be send data packet
++// Need to acquire the sent queue index.
++static int
++ieee80211_classify(struct sk_buff *skb, struct ieee80211_network *network)
++{
++ struct ether_header *eh = (struct ether_header*)skb->data;
++ unsigned int wme_UP = 0;
++
++ if(!network->QoS_Enable) {
++ skb->priority = 0;
++ return(wme_UP);
++ }
++
++ if(eh->ether_type == __constant_htons(ETHERTYPE_IP)) {
++ const struct iphdr *ih = (struct iphdr*)(skb->data + \
++ sizeof(struct ether_header));
++ wme_UP = (ih->tos >> 5)&0x07;
++ } else if (vlan_tx_tag_present(skb)) {//vtag packet
++#ifndef VLAN_PRI_SHIFT
++#define VLAN_PRI_SHIFT 13 /* Shift to find VLAN user priority */
++#define VLAN_PRI_MASK 7 /* Mask for user priority bits in VLAN */
++#endif
++ u32 tag = vlan_tx_tag_get(skb);
++ wme_UP = (tag >> VLAN_PRI_SHIFT) & VLAN_PRI_MASK;
++ } else if(ETH_P_PAE == ntohs(((struct ethhdr *)skb->data)->h_proto)) {
++ //printk(KERN_WARNING "type = normal packet\n");
++ wme_UP = 7;
++ }
++ skb->priority = wme_UP;
++/*
++ if (network->QoS_Enable) {
++ skb->priority = wme_UP;
++ }else {
++ skb->priority = 0;
++ }
++*/
++ return(wme_UP);
++}
++
++#ifdef _RTL8187_EXT_PATCH_
++// based on part of ieee80211_xmit. Mainly allocate txb. ieee->lock is held
++struct ieee80211_txb *ieee80211_ext_alloc_txb(struct sk_buff *skb, struct net_device *dev, struct ieee80211_hdr_3addr *header, int hdr_len, u8 isQoS, u16 *pQOS_ctl, int isEncrypt, struct ieee80211_crypt_data* crypt)
++{
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
++ struct ieee80211_device *ieee = netdev_priv(dev);
++#else
++ struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv;
++#endif
++ struct ieee80211_txb *txb = NULL;
++ struct ieee80211_hdr_3addr *frag_hdr;
++ int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
++ int ether_type;
++ int bytes, QOS_ctl;
++ struct sk_buff *skb_frag;
++
++ ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
++
++ /* Advance the SKB to the start of the payload */
++ skb_pull(skb, sizeof(struct ethhdr));
++
++ /* Determine total amount of storage required for TXB packets */
++ bytes = skb->len + SNAP_SIZE + sizeof(u16);
++
++ /* Determine fragmentation size based on destination (multicast
++ * and broadcast are not fragmented) */
++ // if (is_multicast_ether_addr(dest) ||
++ // is_broadcast_ether_addr(dest)) {
++ if (is_multicast_ether_addr(header->addr1) ||
++ is_broadcast_ether_addr(header->addr1)) {
++ frag_size = MAX_FRAG_THRESHOLD;
++ QOS_ctl = QOS_CTL_NOTCONTAIN_ACK;
++ }
++ else {
++ //printk(KERN_WARNING "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&frag_size = %d\n", frag_size);
++ frag_size = ieee->fts;//default:392
++ QOS_ctl = 0;
++ }
++
++ if(isQoS) {
++ QOS_ctl |= skb->priority; //set in the ieee80211_classify
++ *pQOS_ctl = cpu_to_le16(QOS_ctl);
++ }
++ //printk(KERN_WARNING "header size = %d, QOS_ctl = %x\n", hdr_len,QOS_ctl);
++ /* Determine amount of payload per fragment. Regardless of if
++ * this stack is providing the full 802.11 header, one will
++ * eventually be affixed to this fragment -- so we must account for
++ * it when determining the amount of payload space. */
++ //bytes_per_frag = frag_size - (IEEE80211_3ADDR_LEN + (ieee->current_network->QoS_Enable ? 2:0));
++ bytes_per_frag = frag_size - hdr_len;
++ if (ieee->config &
++ (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
++ bytes_per_frag -= IEEE80211_FCS_LEN;
++
++ /* Each fragment may need to have room for encryptiong pre/postfix */
++ if (isEncrypt)
++ bytes_per_frag -= crypt->ops->extra_prefix_len +
++ crypt->ops->extra_postfix_len;
++
++ /* Number of fragments is the total bytes_per_frag /
++ * payload_per_fragment */
++ nr_frags = bytes / bytes_per_frag;
++ bytes_last_frag = bytes % bytes_per_frag;
++ if (bytes_last_frag)
++ nr_frags++;
++ else
++ bytes_last_frag = bytes_per_frag;
++
++ /* When we allocate the TXB we allocate enough space for the reserve
++ * and full fragment bytes (bytes_per_frag doesn't include prefix,
++ * postfix, header, FCS, etc.) */
++ txb = ieee80211_alloc_txb(nr_frags, frag_size, GFP_ATOMIC);
++ if (unlikely(!txb)) {
++ printk(KERN_WARNING "%s: Could not allocate TXB\n",
++ ieee->dev->name);
++ return NULL;
++ }
++ txb->encrypted = isEncrypt;
++ txb->payload_size = bytes;
++
++ for (i = 0; i < nr_frags; i++) {
++ skb_frag = txb->fragments[i];
++ skb_frag->priority = UP2AC(skb->priority);
++ if (isEncrypt)
++ skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
++
++ frag_hdr = (struct ieee80211_hdr_3addr *)skb_put(skb_frag, hdr_len);
++ memcpy(frag_hdr, (void *)header, hdr_len);
++
++ /* If this is not the last fragment, then add the MOREFRAGS
++ * bit to the frame control */
++ if (i != nr_frags - 1) {
++ frag_hdr->frame_ctl = cpu_to_le16(
++ header->frame_ctl | IEEE80211_FCTL_MOREFRAGS);
++ bytes = bytes_per_frag;
++
++ } else {
++ /* The last fragment takes the remaining length */
++ bytes = bytes_last_frag;
++ }
++
++ frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | i);
++ //frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl<<4 | i);
++ //
++
++ /* Put a SNAP header on the first fragment */
++ if (i == 0) {
++ ieee80211_put_snap(
++ skb_put(skb_frag, SNAP_SIZE + sizeof(u16)), ether_type);
++ bytes -= SNAP_SIZE + sizeof(u16);
++ }
++
++ memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
++
++ /* Advance the SKB... */
++ skb_pull(skb, bytes);
++
++ /* Encryption routine will move the header forward in order
++ * to insert the IV between the header and the payload */
++ if (isEncrypt)
++ ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
++ if (ieee->config &
++ (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
++ skb_put(skb_frag, 4);
++ }
++ // Advance sequence number in data frame.
++ //printk(KERN_WARNING "QoS Enalbed? %s\n", ieee->current_network.QoS_Enable?"Y":"N");
++ if (ieee->seq_ctrl[0] == 0xFFF)
++ ieee->seq_ctrl[0] = 0;
++ else
++ ieee->seq_ctrl[0]++;
++ // stanley, just for debug
++/*
++{
++ int j=0;
++ for(j=0;j<nr_frags;j++)
++ {
++ int i;
++ struct sk_buff *skb = txb->fragments[j];
++ printk("send(%d): ", j);
++ for (i=0;i<skb->len;i++)
++ printk("%02X ", skb->data[i]&0xff);
++ printk("\n");
++ }
++}
++*/
++
++ return txb;
++}
++
++
++// based on part of ieee80211_xmit. Mainly allocate txb. ieee->lock is held
++// Assume no encryption, no FCS computing
++struct ieee80211_txb *ieee80211_ext_reuse_txb(struct sk_buff *skb, struct net_device *dev, struct ieee80211_hdr_3addr *header, int hdr_len, u8 isQoS, u16 *pQOS_ctl, int isEncrypt, struct ieee80211_crypt_data* crypt)
++{
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
++ struct ieee80211_device *ieee = netdev_priv(dev);
++#else
++ struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv;
++#endif
++ struct ieee80211_txb *txb = NULL;
++ struct ieee80211_hdr_3addr *frag_hdr;
++ int ether_type;
++ int bytes, QOS_ctl;
++
++ ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
++
++ /* Advance the SKB to the start of the payload */
++ skb_pull(skb, sizeof(struct ethhdr));
++
++ /* Determine total amount of storage required for TXB packets */
++ bytes = skb->len + SNAP_SIZE + sizeof(u16);
++
++ if (is_multicast_ether_addr(header->addr1) ||
++ is_broadcast_ether_addr(header->addr1)) {
++ QOS_ctl = QOS_CTL_NOTCONTAIN_ACK;
++ }
++ else {
++ QOS_ctl = 0;
++ }
++
++ if(isQoS) {
++ QOS_ctl |= skb->priority; //set in the ieee80211_classify
++ *pQOS_ctl = cpu_to_le16(QOS_ctl);
++ }
++
++ txb = kmalloc( sizeof(struct ieee80211_txb) + sizeof(u8*), GFP_ATOMIC );
++ if (unlikely(!txb)) {
++ printk(KERN_WARNING "%s: Could not allocate TXB\n",
++ ieee->dev->name);
++ return NULL;
++ }
++
++ txb->nr_frags = 1;
++ txb->frag_size = bytes;
++ txb->encrypted = isEncrypt;
++ txb->payload_size = bytes;
++
++ txb->fragments[0] = skb;
++ ieee80211_put_snap(
++ skb_push(skb, SNAP_SIZE + sizeof(u16)), ether_type);
++ frag_hdr = (struct ieee80211_hdr_3addr *)skb_push(skb, hdr_len);
++ memcpy(frag_hdr, (void *)header, hdr_len);
++ frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | 0);
++ skb->priority = UP2AC(skb->priority);
++ if(isEncrypt)
++ ieee80211_encrypt_fragment(ieee,skb,hdr_len);
++
++ // Advance sequence number in data frame.
++ //printk(KERN_WARNING "QoS Enalbed? %s\n", ieee->current_network.QoS_Enable?"Y":"N");
++ if (ieee->seq_ctrl[0] == 0xFFF)
++ ieee->seq_ctrl[0] = 0;
++ else
++ ieee->seq_ctrl[0]++;
++
++ return txb;
++}
++
++#endif // _RTL8187_EXT_PATCH_
++
++/* SKBs are added to the ieee->tx_queue. */
++int ieee80211_xmit(struct sk_buff *skb,
++ struct net_device *dev)
++{
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
++ struct ieee80211_device *ieee = netdev_priv(dev);
++#else
++ struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv;
++#endif
++ struct ieee80211_txb *txb = NULL;
++ struct ieee80211_hdr_3addr_QOS *frag_hdr;
++ int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
++ unsigned long flags;
++ struct net_device_stats *stats = &ieee->stats;
++ int ether_type, encrypt;
++ int bytes, fc, QOS_ctl, hdr_len;
++ struct sk_buff *skb_frag;
++ //struct ieee80211_hdr header = { /* Ensure zero initialized */
++ // .duration_id = 0,
++ // .seq_ctl = 0
++ //};
++ struct ieee80211_hdr_3addr_QOS header = { /* Ensure zero initialized */
++ .duration_id = 0,
++ .seq_ctl = 0,
++ .QOS_ctl = 0
++ };
++ u8 dest[ETH_ALEN], src[ETH_ALEN];
++
++ struct ieee80211_crypt_data* crypt;
++
++ //printk(KERN_WARNING "upper layer packet!\n");
++ spin_lock_irqsave(&ieee->lock, flags);
++
++ /* If there is no driver handler to take the TXB, dont' bother
++ * creating it... */
++ if ((!ieee->hard_start_xmit && !(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE))||
++ ((!ieee->softmac_data_hard_start_xmit && (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) {
++ printk(KERN_WARNING "%s: No xmit handler.\n",
++ ieee->dev->name);
++ goto success;
++ }
++
++ ieee80211_classify(skb,&ieee->current_network);
++ if(likely(ieee->raw_tx == 0)){
++
++ if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
++ printk(KERN_WARNING "%s: skb too small (%d).\n",
++ ieee->dev->name, skb->len);
++ goto success;
++ }
++
++
++#ifdef _RTL8187_EXT_PATCH_
++ // note, skb->priority which was set by ieee80211_classify, and used by physical tx
++ if((ieee->iw_mode == ieee->iw_ext_mode) && (ieee->ext_patch_ieee80211_xmit))
++ {
++ txb = ieee->ext_patch_ieee80211_xmit(skb, dev);
++ goto success;
++ }
++#endif
++
++ ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
++#ifdef _RTL8187_EXT_PATCH_
++ crypt = ieee->cryptlist[0]->crypt[ieee->tx_keyidx];
++#else
++ crypt = ieee->crypt[ieee->tx_keyidx];
++#endif
++ encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
++ ieee->host_encrypt && crypt && crypt->ops;
++
++ if (!encrypt && ieee->ieee802_1x &&
++ ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
++ stats->tx_dropped++;
++ goto success;
++ }
++
++ #ifdef CONFIG_IEEE80211_DEBUG
++ if (crypt && !encrypt && ether_type == ETH_P_PAE) {
++ struct eapol *eap = (struct eapol *)(skb->data +
++ sizeof(struct ethhdr) - SNAP_SIZE - sizeof(u16));
++ IEEE80211_DEBUG_EAP("TX: IEEE 802.11 EAPOL frame: %s\n",
++ eap_get_type(eap->type));
++ }
++ #endif
++
++ /* Save source and destination addresses */
++ memcpy(&dest, skb->data, ETH_ALEN);
++ memcpy(&src, skb->data+ETH_ALEN, ETH_ALEN);
++
++ /* Advance the SKB to the start of the payload */
++ skb_pull(skb, sizeof(struct ethhdr));
++
++ /* Determine total amount of storage required for TXB packets */
++ bytes = skb->len + SNAP_SIZE + sizeof(u16);
++
++ if(ieee->current_network.QoS_Enable) {
++ if (encrypt)
++ fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA |
++ IEEE80211_FCTL_WEP;
++ else
++ fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA;
++
++ } else {
++ if (encrypt)
++ fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA |
++ IEEE80211_FCTL_WEP;
++ else
++ fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA;
++ }
++
++ if (ieee->iw_mode == IW_MODE_INFRA) {
++ fc |= IEEE80211_FCTL_TODS;
++ /* To DS: Addr1 = BSSID, Addr2 = SA,
++ Addr3 = DA */
++ memcpy(&header.addr1, ieee->current_network.bssid, ETH_ALEN);
++ memcpy(&header.addr2, &src, ETH_ALEN);
++ memcpy(&header.addr3, &dest, ETH_ALEN);
++ } else if (ieee->iw_mode == IW_MODE_ADHOC) {
++ /* not From/To DS: Addr1 = DA, Addr2 = SA,
++ Addr3 = BSSID */
++ memcpy(&header.addr1, dest, ETH_ALEN);
++ memcpy(&header.addr2, src, ETH_ALEN);
++ memcpy(&header.addr3, ieee->current_network.bssid, ETH_ALEN);
++ }
++ // printk(KERN_WARNING "essid MAC address is "MAC_FMT, MAC_ARG(&header.addr1));
++ header.frame_ctl = cpu_to_le16(fc);
++ //hdr_len = IEEE80211_3ADDR_LEN;
++
++ /* Determine fragmentation size based on destination (multicast
++ * and broadcast are not fragmented) */
++// if (is_multicast_ether_addr(dest) ||
++// is_broadcast_ether_addr(dest)) {
++ if (is_multicast_ether_addr(header.addr1) ||
++ is_broadcast_ether_addr(header.addr1)) {
++ frag_size = MAX_FRAG_THRESHOLD;
++ QOS_ctl = QOS_CTL_NOTCONTAIN_ACK;
++ }
++ else {
++ //printk(KERN_WARNING "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&frag_size = %d\n", frag_size);
++ frag_size = ieee->fts;//default:392
++ QOS_ctl = 0;
++ }
++
++ if (ieee->current_network.QoS_Enable) {
++ hdr_len = IEEE80211_3ADDR_LEN + 2;
++ QOS_ctl |= skb->priority; //set in the ieee80211_classify
++ header.QOS_ctl = cpu_to_le16(QOS_ctl);
++ } else {
++ hdr_len = IEEE80211_3ADDR_LEN;
++ }
++ //printk(KERN_WARNING "header size = %d, QOS_ctl = %x\n", hdr_len,QOS_ctl);
++ /* Determine amount of payload per fragment. Regardless of if
++ * this stack is providing the full 802.11 header, one will
++ * eventually be affixed to this fragment -- so we must account for
++ * it when determining the amount of payload space. */
++ //bytes_per_frag = frag_size - (IEEE80211_3ADDR_LEN + (ieee->current_network->QoS_Enable ? 2:0));
++ bytes_per_frag = frag_size - hdr_len;
++ if (ieee->config &
++ (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
++ bytes_per_frag -= IEEE80211_FCS_LEN;
++
++ /* Each fragment may need to have room for encryptiong pre/postfix */
++ if (encrypt)
++ bytes_per_frag -= crypt->ops->extra_prefix_len +
++ crypt->ops->extra_postfix_len;
++
++ /* Number of fragments is the total bytes_per_frag /
++ * payload_per_fragment */
++ nr_frags = bytes / bytes_per_frag;
++ bytes_last_frag = bytes % bytes_per_frag;
++ if (bytes_last_frag)
++ nr_frags++;
++ else
++ bytes_last_frag = bytes_per_frag;
++
++ /* When we allocate the TXB we allocate enough space for the reserve
++ * and full fragment bytes (bytes_per_frag doesn't include prefix,
++ * postfix, header, FCS, etc.) */
++ txb = ieee80211_alloc_txb(nr_frags, frag_size, GFP_ATOMIC);
++ if (unlikely(!txb)) {
++ printk(KERN_WARNING "%s: Could not allocate TXB\n",
++ ieee->dev->name);
++ goto failed;
++ }
++ txb->encrypted = encrypt;
++ txb->payload_size = bytes;
++
++ for (i = 0; i < nr_frags; i++) {
++ skb_frag = txb->fragments[i];
++ skb_frag->priority = UP2AC(skb->priority);
++ if (encrypt)
++ skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
++
++ frag_hdr = (struct ieee80211_hdr_3addr_QOS *)skb_put(skb_frag, hdr_len);
++ memcpy(frag_hdr, &header, hdr_len);
++
++ /* If this is not the last fragment, then add the MOREFRAGS
++ * bit to the frame control */
++ if (i != nr_frags - 1) {
++ frag_hdr->frame_ctl = cpu_to_le16(
++ fc | IEEE80211_FCTL_MOREFRAGS);
++ bytes = bytes_per_frag;
++
++ } else {
++ /* The last fragment takes the remaining length */
++ bytes = bytes_last_frag;
++ }
++ if(ieee->current_network.QoS_Enable) {
++ // add 1 only indicate to corresponding seq number control 2006/7/12
++ frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[UP2AC(skb->priority)+1]<<4 | i);
++ //printk(KERN_WARNING "skb->priority = %d,", skb->priority);
++ //printk(KERN_WARNING "type:%d: seq = %d\n",UP2AC(skb->priority),ieee->seq_ctrl[UP2AC(skb->priority)+1]);
++ } else {
++ frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | i);
++ }
++ //frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl<<4 | i);
++ //
++
++ /* Put a SNAP header on the first fragment */
++ if (i == 0) {
++ ieee80211_put_snap(
++ skb_put(skb_frag, SNAP_SIZE + sizeof(u16)),
++ ether_type);
++ bytes -= SNAP_SIZE + sizeof(u16);
++ }
++
++ memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
++
++ /* Advance the SKB... */
++ skb_pull(skb, bytes);
++
++ /* Encryption routine will move the header forward in order
++ * to insert the IV between the header and the payload */
++ if (encrypt)
++ ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
++ if (ieee->config &
++ (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
++ skb_put(skb_frag, 4);
++ }
++ // Advance sequence number in data frame.
++ //printk(KERN_WARNING "QoS Enalbed? %s\n", ieee->current_network.QoS_Enable?"Y":"N");
++ if (ieee->current_network.QoS_Enable) {
++ if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF)
++ ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0;
++ else
++ ieee->seq_ctrl[UP2AC(skb->priority) + 1]++;
++ } else {
++ if (ieee->seq_ctrl[0] == 0xFFF)
++ ieee->seq_ctrl[0] = 0;
++ else
++ ieee->seq_ctrl[0]++;
++ }
++ //---
++ }else{
++ if (unlikely(skb->len < sizeof(struct ieee80211_hdr_3addr))) {
++ printk(KERN_WARNING "%s: skb too small (%d).\n",
++ ieee->dev->name, skb->len);
++ goto success;
++ }
++
++ txb = ieee80211_alloc_txb(1, skb->len, GFP_ATOMIC);
++ if(!txb){
++ printk(KERN_WARNING "%s: Could not allocate TXB\n",
++ ieee->dev->name);
++ goto failed;
++ }
++
++ txb->encrypted = 0;
++ txb->payload_size = skb->len;
++ memcpy(skb_put(txb->fragments[0],skb->len), skb->data, skb->len);
++ }
++
++ success:
++ spin_unlock_irqrestore(&ieee->lock, flags);
++#ifdef _RTL8187_EXT_PATCH_
++ // Sometimes, extension mode can reuse skb (by txb->fragments[0])
++ if( ! ((ieee->iw_mode == ieee->iw_ext_mode) && txb && (txb->fragments[0] == skb)) )
++#endif
++ dev_kfree_skb_any(skb);
++ if (txb) {
++ if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE){
++ ieee80211_softmac_xmit(txb, ieee);
++ }else{
++ if ((*ieee->hard_start_xmit)(txb, dev) == 0) {
++ stats->tx_packets++;
++ stats->tx_bytes += txb->payload_size;
++ return 0;
++ }
++ ieee80211_txb_free(txb);
++ }
++ }
++
++ return 0;
++
++ failed:
++ spin_unlock_irqrestore(&ieee->lock, flags);
++ netif_stop_queue(dev);
++ printk("netif_stop_queue in ieee80211_xmit \n");
++ stats->tx_errors++;
++ return 1;
++
++}
++
++
++
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
++EXPORT_SYMBOL(ieee80211_txb_free);
++#ifdef _RTL8187_EXT_PATCH_
++EXPORT_SYMBOL(ieee80211_alloc_txb);
++EXPORT_SYMBOL(ieee80211_ext_alloc_txb);
++EXPORT_SYMBOL(ieee80211_ext_reuse_txb);
++
++EXPORT_SYMBOL(ieee80211_encrypt_fragment);
++#endif // _RTL8187_EXT_PATCH_
++#else
++EXPORT_SYMBOL_NOVERS(ieee80211_txb_free);
++#ifdef _RTL8187_EXT_PATCH_
++EXPORT_SYMBOL_NOVERS(ieee80211_alloc_txb);
++EXPORT_SYMBOL_NOVERS(ieee80211_ext_reuse_txb);
++
++EXPORT_SYMBOL_NOVERS(ieee80211_encrypt_fragment);
++#endif // _RTL8187_EXT_PATCH_
++#endif
++
+diff --git a/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_wx.c b/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_wx.c
+new file mode 100644
+index 0000000..40fe532
+--- /dev/null
++++ b/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_wx.c
+@@ -0,0 +1,926 @@
++/******************************************************************************
++
++ Copyright(c) 2004 Intel Corporation. All rights reserved.
++
++ Portions of this file are based on the WEP enablement code provided by the
++ Host AP project hostap-drivers v0.1.3
++ Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
++ <jkmaline@cc.hut.fi>
++ Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
++
++ This program is free software; you can redistribute it and/or modify it
++ under the terms of version 2 of the GNU General Public License as
++ published by the Free Software Foundation.
++
++ 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 full GNU General Public License is included in this distribution in the
++ file called LICENSE.
++
++ Contact Information:
++ James P. Ketrenos <ipw2100-admin@linux.intel.com>
++ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
++
++******************************************************************************/
++#include <linux/wireless.h>
++#include <linux/version.h>
++#include <linux/kmod.h>
++#include <linux/module.h>
++
++#include "ieee80211.h"
++static const char *ieee80211_modes[] = {
++ "?", "a", "b", "ab", "g", "ag", "bg", "abg"
++};
++
++#define MAX_CUSTOM_LEN 64
++static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
++ char *start, char *stop,
++ struct ieee80211_network *network,
++ struct iw_request_info *info)
++{
++ char custom[MAX_CUSTOM_LEN];
++ char *p;
++ struct iw_event iwe;
++ int i, j;
++ u8 max_rate, rate;
++
++ /* First entry *MUST* be the AP MAC address */
++ iwe.cmd = SIOCGIWAP;
++ iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
++ memcpy(iwe.u.ap_addr.sa_data, network->bssid, ETH_ALEN);
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
++ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
++#else
++ start = iwe_stream_add_event(start, stop, &iwe, IW_EV_ADDR_LEN);
++#endif
++ /* Remaining entries will be displayed in the order we provide them */
++
++ /* Add the ESSID */
++ iwe.cmd = SIOCGIWESSID;
++ iwe.u.data.flags = 1;
++ //YJ,modified,080903,for hidden ap
++ //if (network->flags & NETWORK_EMPTY_ESSID) {
++ if (network->ssid_len == 0) {
++ iwe.u.data.length = sizeof("<hidden>");
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
++ start = iwe_stream_add_point(info, start, stop, &iwe, "<hidden>");
++#else
++ start = iwe_stream_add_point(start, stop, &iwe, "<hidden>");
++#endif
++ } else {
++ iwe.u.data.length = min(network->ssid_len, (u8)32);
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
++ start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
++#else
++ start = iwe_stream_add_point(start, stop, &iwe, network->ssid);
++#endif
++ }
++
++ /* Add the protocol name */
++ iwe.cmd = SIOCGIWNAME;
++ snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11%s", ieee80211_modes[network->mode]);
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
++ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
++#else
++ start = iwe_stream_add_event(start, stop, &iwe, IW_EV_CHAR_LEN);
++#endif
++ /* Add mode */
++ iwe.cmd = SIOCGIWMODE;
++ if (network->capability &
++ (WLAN_CAPABILITY_BSS | WLAN_CAPABILITY_IBSS)) {
++ if (network->capability & WLAN_CAPABILITY_BSS)
++ iwe.u.mode = IW_MODE_MASTER;
++ else
++ iwe.u.mode = IW_MODE_ADHOC;
++
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
++ start = iwe_stream_add_event(info, start, stop, &iwe,
++ IW_EV_UINT_LEN);
++#else
++ start = iwe_stream_add_event(start, stop, &iwe,
++ IW_EV_UINT_LEN);
++#endif
++ }
++
++ /* Add frequency/channel */
++ iwe.cmd = SIOCGIWFREQ;
++/* iwe.u.freq.m = ieee80211_frequency(network->channel, network->mode);
++ iwe.u.freq.e = 3; */
++ iwe.u.freq.m = network->channel;
++ iwe.u.freq.e = 0;
++ iwe.u.freq.i = 0;
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
++ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN);
++#else
++ start = iwe_stream_add_event(start, stop, &iwe, IW_EV_FREQ_LEN);
++#endif
++ /* Add encryption capability */
++ iwe.cmd = SIOCGIWENCODE;
++ if (network->capability & WLAN_CAPABILITY_PRIVACY)
++ iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
++ else
++ iwe.u.data.flags = IW_ENCODE_DISABLED;
++ iwe.u.data.length = 0;
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
++ start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
++#else
++ start = iwe_stream_add_point(start, stop, &iwe, network->ssid);
++#endif
++ /* Add basic and extended rates */
++ max_rate = 0;
++ p = custom;
++ p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
++ for (i = 0, j = 0; i < network->rates_len; ) {
++ if (j < network->rates_ex_len &&
++ ((network->rates_ex[j] & 0x7F) <
++ (network->rates[i] & 0x7F)))
++ rate = network->rates_ex[j++] & 0x7F;
++ else
++ rate = network->rates[i++] & 0x7F;
++ if (rate > max_rate)
++ max_rate = rate;
++ p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
++ "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
++ }
++ for (; j < network->rates_ex_len; j++) {
++ rate = network->rates_ex[j] & 0x7F;
++ p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
++ "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
++ if (rate > max_rate)
++ max_rate = rate;
++ }
++
++ iwe.cmd = SIOCGIWRATE;
++ iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
++ iwe.u.bitrate.value = max_rate * 500000;
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
++ start = iwe_stream_add_event(info, start, stop, &iwe,IW_EV_PARAM_LEN);
++#else
++ start = iwe_stream_add_event(start, stop, &iwe,IW_EV_PARAM_LEN);
++#endif
++ iwe.cmd = IWEVCUSTOM;
++ iwe.u.data.length = p - custom;
++ if (iwe.u.data.length)
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
++ start = iwe_stream_add_point(info, start, stop, &iwe, custom);
++#else
++ start = iwe_stream_add_point(start, stop, &iwe, custom);
++#endif
++ /* Add quality statistics */
++ /* TODO: Fix these values... */
++ iwe.cmd = IWEVQUAL;
++ iwe.u.qual.qual = network->stats.signalstrength;//network->stats.signal;
++ iwe.u.qual.level = network->stats.signal;//network->stats.rssi;
++ iwe.u.qual.noise = network->stats.noise;
++#if 0
++ iwe.u.qual.updated = network->stats.mask & IEEE80211_STATMASK_WEMASK;
++ if (!(network->stats.mask & IEEE80211_STATMASK_RSSI))
++ iwe.u.qual.updated |= IW_QUAL_LEVEL_INVALID;
++ if (!(network->stats.mask & IEEE80211_STATMASK_NOISE))
++ iwe.u.qual.updated |= IW_QUAL_NOISE_INVALID;
++ if (!(network->stats.mask & IEEE80211_STATMASK_SIGNAL))
++ iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID;
++#endif
++
++ iwe.u.qual.updated = 0x7;//network->stats.mask & IEEE80211_STATMASK_WEMASK;
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
++ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
++#else
++ start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN);
++#endif
++ iwe.cmd = IWEVCUSTOM;
++ p = custom;
++
++ iwe.u.data.length = p - custom;
++ if (iwe.u.data.length)
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
++ start = iwe_stream_add_point(info, start, stop, &iwe, custom);
++#else
++ start = iwe_stream_add_point(start, stop, &iwe, custom);
++#endif
++#if 0
++ if (ieee->wpa_enabled && network->wpa_ie_len){
++ char buf[MAX_WPA_IE_LEN * 2 + 30];
++ // printk("WPA IE\n");
++ u8 *p = buf;
++ p += sprintf(p, "wpa_ie=");
++ for (i = 0; i < network->wpa_ie_len; i++) {
++ p += sprintf(p, "%02x", network->wpa_ie[i]);
++ }
++
++ memset(&iwe, 0, sizeof(iwe));
++ iwe.cmd = IWEVCUSTOM;
++ iwe.u.data.length = strlen(buf);
++ start = iwe_stream_add_point(start, stop, &iwe, buf);
++ }
++
++ if (ieee->wpa_enabled && network->rsn_ie_len){
++ char buf[MAX_WPA_IE_LEN * 2 + 30];
++
++ u8 *p = buf;
++ p += sprintf(p, "rsn_ie=");
++ for (i = 0; i < network->rsn_ie_len; i++) {
++ p += sprintf(p, "%02x", network->rsn_ie[i]);
++ }
++
++
++#else
++ memset(&iwe, 0, sizeof(iwe));
++ if (network->wpa_ie_len) {
++ //printk("wpa_ie_len:%d\n", network->wpa_ie_len);
++ char buf[MAX_WPA_IE_LEN];
++ memcpy(buf, network->wpa_ie, network->wpa_ie_len);
++ iwe.cmd = IWEVGENIE;
++ iwe.u.data.length = network->wpa_ie_len;
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
++ start = iwe_stream_add_point(info, start, stop, &iwe, buf);
++#else
++ start = iwe_stream_add_point(start, stop, &iwe, buf);
++#endif
++ }
++
++ memset(&iwe, 0, sizeof(iwe));
++ if (network->rsn_ie_len) {
++ //printk("=====>rsn_ie_len:\n", network->rsn_ie_len);
++ #if 0
++ {
++ int i;
++ for (i=0; i<network->rsn_ie_len; i++);
++ printk("%2x ", network->rsn_ie[i]);
++ printk("\n");
++ }
++ #endif
++ char buf[MAX_WPA_IE_LEN];
++ memcpy(buf, network->rsn_ie, network->rsn_ie_len);
++ iwe.cmd = IWEVGENIE;
++ iwe.u.data.length = network->rsn_ie_len;
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
++ start = iwe_stream_add_point(info, start, stop, &iwe, buf);
++#else
++ start = iwe_stream_add_point(start, stop, &iwe, buf);
++#endif
++ }
++
++#endif
++
++ /* Add EXTRA: Age to display seconds since last beacon/probe response
++ * for given network. */
++ iwe.cmd = IWEVCUSTOM;
++ p = custom;
++ p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
++ " Last beacon: %lums ago", (jiffies - network->last_scanned) / (HZ / 100));
++ iwe.u.data.length = p - custom;
++ if (iwe.u.data.length)
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
++ start = iwe_stream_add_point(info, start, stop, &iwe, custom);
++#else
++ start = iwe_stream_add_point(start, stop, &iwe, custom);
++#endif
++
++ return start;
++}
++
++int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ struct ieee80211_network *network;
++ unsigned long flags;
++ int err = 0;
++ char *ev = extra;
++ char *stop = ev + wrqu->data.length;//IW_SCAN_MAX_DATA;
++ //char *stop = ev + IW_SCAN_MAX_DATA;
++ int i = 0;
++
++ IEEE80211_DEBUG_WX("Getting scan\n");
++ down(&ieee->wx_sem);
++ spin_lock_irqsave(&ieee->lock, flags);
++
++ if(!ieee->bHwRadioOff)
++ {
++ list_for_each_entry(network, &ieee->network_list, list) {
++ i++;
++
++ if((stop-ev)<200)
++ {
++ err = -E2BIG;
++ break;
++ }
++
++ if (ieee->scan_age == 0 ||
++ time_after(network->last_scanned + ieee->scan_age, jiffies))
++ {
++ ev = rtl819x_translate_scan(ieee, ev, stop, network, info);
++ }
++ else
++ IEEE80211_DEBUG_SCAN(
++ "Not showing network '%s ("
++ MAC_FMT ")' due to age (%lums).\n",
++ escape_essid(network->ssid,
++ network->ssid_len),
++ MAC_ARG(network->bssid),
++ (jiffies - network->last_scanned) / (HZ / 100));
++ }
++ }
++ spin_unlock_irqrestore(&ieee->lock, flags);
++ up(&ieee->wx_sem);
++ wrqu->data.length = ev - extra;
++ wrqu->data.flags = 0;
++
++ IEEE80211_DEBUG_WX("exit: %d networks returned.\n", i);
++
++ return err;
++}
++
++int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *keybuf)
++{
++ struct iw_point *erq = &(wrqu->encoding);
++ struct net_device *dev = ieee->dev;
++ struct ieee80211_security sec = {
++ .flags = 0
++ };
++ int i, key, key_provided, len;
++ struct ieee80211_crypt_data **crypt;
++
++ IEEE80211_DEBUG_WX("SET_ENCODE\n");
++
++ key = erq->flags & IW_ENCODE_INDEX;
++ if (key) {
++ if (key > WEP_KEYS)
++ return -EINVAL;
++ key--;
++ key_provided = 1;
++ } else {
++ key_provided = 0;
++ key = ieee->tx_keyidx;
++ }
++
++ IEEE80211_DEBUG_WX("Key: %d [%s]\n", key, key_provided ?
++ "provided" : "default");
++#ifdef _RTL8187_EXT_PATCH_
++#if 0
++{
++ int j;
++ for(j=0; j<MAX_MP; j++){
++ crypt = &ieee->cryptlist[j]->crypt[key];
++#else
++ crypt = &ieee->cryptlist[0]->crypt[key];
++#endif
++#else
++ crypt = &ieee->crypt[key];
++#endif
++ if (erq->flags & IW_ENCODE_DISABLED) {
++ if (key_provided && *crypt) {
++ IEEE80211_DEBUG_WX("Disabling encryption on key %d.\n",
++ key);
++ ieee80211_crypt_delayed_deinit(ieee, crypt);
++ } else
++ IEEE80211_DEBUG_WX("Disabling encryption.\n");
++
++ /* Check all the keys to see if any are still configured,
++ * and if no key index was provided, de-init them all */
++ for (i = 0; i < WEP_KEYS; i++) {
++#ifdef _RTL8187_EXT_PATCH_
++
++ if (ieee->cryptlist[0]->crypt[i] != NULL){
++#else
++
++ if (ieee->crypt[i] != NULL) {
++#endif
++ if (key_provided)
++ break;
++ ieee80211_crypt_delayed_deinit(
++#ifdef _RTL8187_EXT_PATCH_
++ ieee, &ieee->cryptlist[0]->crypt[i]);
++#else
++ ieee, &ieee->crypt[i]);
++#endif
++ }
++ }
++
++ if (i == WEP_KEYS) {
++ sec.enabled = 0;
++ sec.level = SEC_LEVEL_0;
++ sec.flags |= SEC_ENABLED | SEC_LEVEL;
++ }
++
++ goto done;
++ }
++
++
++
++ sec.enabled = 1;
++ sec.flags |= SEC_ENABLED;
++
++ if (*crypt != NULL && (*crypt)->ops != NULL &&
++ strcmp((*crypt)->ops->name, "WEP") != 0) {
++ /* changing to use WEP; deinit previously used algorithm
++ * on this key */
++ ieee80211_crypt_delayed_deinit(ieee, crypt);
++ }
++
++ if (*crypt == NULL) {
++ struct ieee80211_crypt_data *new_crypt;
++
++ /* take WEP into use */
++ new_crypt = kmalloc(sizeof(struct ieee80211_crypt_data),
++ GFP_KERNEL);
++ if (new_crypt == NULL)
++ return -ENOMEM;
++ memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
++ new_crypt->ops = ieee80211_get_crypto_ops("WEP");
++ if (!new_crypt->ops) {
++ request_module("ieee80211_crypt_wep");
++ new_crypt->ops = ieee80211_get_crypto_ops("WEP");
++ }
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
++ if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
++#else
++ if (new_crypt->ops && try_inc_mod_count(new_crypt->ops->owner))
++#endif
++ new_crypt->priv = new_crypt->ops->init(key);
++
++ if (!new_crypt->ops || !new_crypt->priv) {
++ kfree(new_crypt);
++ new_crypt = NULL;
++
++ printk(KERN_WARNING "%s: could not initialize WEP: "
++ "load module ieee80211_crypt_wep\n",
++ dev->name);
++ return -EOPNOTSUPP;
++ }
++ *crypt = new_crypt;
++ }
++
++ /* If a new key was provided, set it up */
++ if (erq->length > 0) {
++ len = erq->length <= 5 ? 5 : 13;
++ memcpy(sec.keys[key], keybuf, erq->length);
++ if (len > erq->length)
++ memset(sec.keys[key] + erq->length, 0,
++ len - erq->length);
++ IEEE80211_DEBUG_WX("Setting key %d to '%s' (%d:%d bytes)\n",
++ key, escape_essid(sec.keys[key], len),
++ erq->length, len);
++ sec.key_sizes[key] = len;
++ (*crypt)->ops->set_key(sec.keys[key], len, NULL,
++ (*crypt)->priv);
++ sec.flags |= (1 << key);
++ /* This ensures a key will be activated if no key is
++ * explicitely set */
++ if (key == sec.active_key)
++ sec.flags |= SEC_ACTIVE_KEY;
++
++ ieee->tx_keyidx = key; //we need it to support multi_key setting. added by wb 2008_2_22
++ } else {
++ len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN,
++ NULL, (*crypt)->priv);
++ if (len == 0) {
++ /* Set a default key of all 0 */
++ IEEE80211_DEBUG_WX("Setting key %d to all zero.\n",
++ key);
++ memset(sec.keys[key], 0, 13);
++ (*crypt)->ops->set_key(sec.keys[key], 13, NULL,
++ (*crypt)->priv);
++ sec.key_sizes[key] = 13;
++ sec.flags |= (1 << key);
++ }
++
++ /* No key data - just set the default TX key index */
++ if (key_provided) {
++ IEEE80211_DEBUG_WX(
++ "Setting key %d to default Tx key.\n", key);
++ ieee->tx_keyidx = key;
++ sec.active_key = key;
++ sec.flags |= SEC_ACTIVE_KEY;
++ }
++ }
++#ifdef _RTL8187_EXT_PATCH_
++#if 0
++}
++}
++#endif
++#endif
++ done:
++ ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED);
++ sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
++ sec.flags |= SEC_AUTH_MODE;
++ IEEE80211_DEBUG_WX("Auth: %s\n", sec.auth_mode == WLAN_AUTH_OPEN ?
++ "OPEN" : "SHARED KEY");
++
++ /* For now we just support WEP, so only set that security level...
++ * TODO: When WPA is added this is one place that needs to change */
++ sec.flags |= SEC_LEVEL;
++ sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */
++
++ if (ieee->set_security)
++ ieee->set_security(dev, &sec);
++
++ /* Do not reset port if card is in Managed mode since resetting will
++ * generate new IEEE 802.11 authentication which may end up in looping
++ * with IEEE 802.1X. If your hardware requires a reset after WEP
++ * configuration (for example... Prism2), implement the reset_port in
++ * the callbacks structures used to initialize the 802.11 stack. */
++ if (ieee->reset_on_keychange &&
++ ieee->iw_mode != IW_MODE_INFRA &&
++ ieee->reset_port && ieee->reset_port(dev)) {
++ printk(KERN_DEBUG "%s: reset_port failed\n", dev->name);
++ return -EINVAL;
++ }
++ return 0;
++}
++
++int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *keybuf)
++{
++ struct iw_point *erq = &(wrqu->encoding);
++ int len, key;
++ struct ieee80211_crypt_data *crypt;
++
++ IEEE80211_DEBUG_WX("GET_ENCODE\n");
++
++ if(ieee->iw_mode == IW_MODE_MONITOR)
++ return -1;
++
++ key = erq->flags & IW_ENCODE_INDEX;
++ if (key) {
++ if (key > WEP_KEYS)
++ return -EINVAL;
++ key--;
++ } else
++ key = ieee->tx_keyidx;
++#ifdef _RTL8187_EXT_PATCH_
++ crypt = ieee->cryptlist[0]->crypt[key];
++#else
++ crypt = ieee->crypt[key];
++#endif
++ erq->flags = key + 1;
++
++ if (crypt == NULL || crypt->ops == NULL) {
++ erq->length = 0;
++ erq->flags |= IW_ENCODE_DISABLED;
++ return 0;
++ }
++
++ if (strcmp(crypt->ops->name, "WEP") != 0) {
++ /* only WEP is supported with wireless extensions, so just
++ * report that encryption is used */
++ erq->length = 0;
++ erq->flags |= IW_ENCODE_ENABLED;
++ return 0;
++ }
++
++ len = crypt->ops->get_key(keybuf, WEP_KEY_LEN, NULL, crypt->priv);
++ erq->length = (len >= 0 ? len : 0);
++
++ erq->flags |= IW_ENCODE_ENABLED;
++
++ if (ieee->open_wep)
++ erq->flags |= IW_ENCODE_OPEN;
++ else
++ erq->flags |= IW_ENCODE_RESTRICTED;
++
++ return 0;
++}
++
++int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ struct net_device *dev = ieee->dev;
++ struct iw_point *encoding = &wrqu->encoding;
++ struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
++ int i, idx, ret = 0;
++ int group_key = 0;
++ const char *alg, *module;
++ struct ieee80211_crypto_ops *ops;
++ struct ieee80211_crypt_data **crypt;
++
++ struct ieee80211_security sec = {
++ .flags = 0,
++ };
++ //printk("======>encoding flag:%x,ext flag:%x, ext alg:%d\n", encoding->flags,ext->ext_flags, ext->alg);
++ idx = encoding->flags & IW_ENCODE_INDEX;
++ if (idx) {
++ if (idx < 1 || idx > WEP_KEYS)
++ return -EINVAL;
++ idx--;
++ } else
++ idx = ieee->tx_keyidx;
++
++ if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
++#ifdef _RTL8187_EXT_PATCH_
++ crypt = &ieee->cryptlist[0]->crypt[idx];
++#else
++ crypt = &ieee->crypt[idx];
++#endif
++ group_key = 1;
++ } else {
++ /* some Cisco APs use idx>0 for unicast in dynamic WEP */
++ //printk("not group key, flags:%x, ext->alg:%d\n", ext->ext_flags, ext->alg);
++ if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP)
++ return -EINVAL;
++ if (ieee->iw_mode == IW_MODE_INFRA)
++#ifdef _RTL8187_EXT_PATCH_
++ crypt = &ieee->cryptlist[0]->crypt[idx];
++#else
++ crypt = &ieee->crypt[idx];
++#endif
++ else
++ return -EINVAL;
++ }
++
++ sec.flags |= SEC_ENABLED;// | SEC_ENCRYPT;
++ if ((encoding->flags & IW_ENCODE_DISABLED) ||
++ ext->alg == IW_ENCODE_ALG_NONE) {
++ if (*crypt)
++ ieee80211_crypt_delayed_deinit(ieee, crypt);
++
++ for (i = 0; i < WEP_KEYS; i++)
++#ifdef _RTL8187_EXT_PATCH_
++ if (ieee->cryptlist[0]->crypt[i] != NULL)
++#else
++ if (ieee->crypt[i] != NULL)
++#endif
++ break;
++
++ if (i == WEP_KEYS) {
++ sec.enabled = 0;
++ // sec.encrypt = 0;
++ sec.level = SEC_LEVEL_0;
++ sec.flags |= SEC_LEVEL;
++ }
++ //printk("disabled: flag:%x\n", encoding->flags);
++ goto done;
++ }
++
++ sec.enabled = 1;
++ // sec.encrypt = 1;
++#if 0
++ if (group_key ? !ieee->host_mc_decrypt :
++ !(ieee->host_encrypt || ieee->host_decrypt ||
++ ieee->host_encrypt_msdu))
++ goto skip_host_crypt;
++#endif
++ switch (ext->alg) {
++ case IW_ENCODE_ALG_WEP:
++ alg = "WEP";
++ module = "ieee80211_crypt_wep";
++ break;
++ case IW_ENCODE_ALG_TKIP:
++ alg = "TKIP";
++ module = "ieee80211_crypt_tkip";
++ break;
++ case IW_ENCODE_ALG_CCMP:
++ alg = "CCMP";
++ module = "ieee80211_crypt_ccmp";
++ break;
++ default:
++ IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
++ dev->name, ext->alg);
++ ret = -EINVAL;
++ goto done;
++ }
++ printk("alg name:%s\n",alg);
++
++ ops = ieee80211_get_crypto_ops(alg);
++ if (ops == NULL) {
++ request_module(module);
++ ops = ieee80211_get_crypto_ops(alg);
++ }
++ if (ops == NULL) {
++ IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
++ dev->name, ext->alg);
++ printk("========>unknown crypto alg %d\n", ext->alg);
++ ret = -EINVAL;
++ goto done;
++ }
++
++ if (*crypt == NULL || (*crypt)->ops != ops) {
++ struct ieee80211_crypt_data *new_crypt;
++
++ ieee80211_crypt_delayed_deinit(ieee, crypt);
++
++ new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
++ if (new_crypt == NULL) {
++ ret = -ENOMEM;
++ goto done;
++ }
++ new_crypt->ops = ops;
++ if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
++ new_crypt->priv = new_crypt->ops->init(idx);
++ if (new_crypt->priv == NULL) {
++ kfree(new_crypt);
++ ret = -EINVAL;
++ goto done;
++ }
++ *crypt = new_crypt;
++
++ }
++ //I need to deinit other crypt here in mesh mode instead deinit them while use them to tx&rx.
++#ifdef _RTL8187_EXT_PATCH_
++ if (ieee->iw_mode == ieee->iw_ext_mode)
++ {
++ int j;
++ for (j=1; j<MAX_MP; j++)
++ {
++ struct ieee80211_crypt_data ** crypttmp = &ieee->cryptlist[j]->crypt[idx];
++ if (*crypttmp == NULL)
++ break;
++ if (*crypttmp && (*crypttmp)->ops != ops)
++ ieee80211_crypt_delayed_deinit(ieee, crypttmp);
++ }
++ }
++#endif
++ if (ext->key_len > 0 && (*crypt)->ops->set_key &&
++ (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq,
++ (*crypt)->priv) < 0) {
++ IEEE80211_DEBUG_WX("%s: key setting failed\n", dev->name);
++ printk("key setting failed\n");
++ ret = -EINVAL;
++ goto done;
++ }
++#if 1
++// skip_host_crypt:
++ //printk("skip_host_crypt:ext_flags:%x\n", ext->ext_flags);
++ if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
++ ieee->tx_keyidx = idx;
++ sec.active_key = idx;
++ sec.flags |= SEC_ACTIVE_KEY;
++ }
++
++ if (ext->alg != IW_ENCODE_ALG_NONE) {
++ memcpy(sec.keys[idx], ext->key, ext->key_len);
++ sec.key_sizes[idx] = ext->key_len;
++ sec.flags |= (1 << idx);
++ if (ext->alg == IW_ENCODE_ALG_WEP) {
++ // sec.encode_alg[idx] = SEC_ALG_WEP;
++ sec.flags |= SEC_LEVEL;
++ sec.level = SEC_LEVEL_1;
++ } else if (ext->alg == IW_ENCODE_ALG_TKIP) {
++ // sec.encode_alg[idx] = SEC_ALG_TKIP;
++ sec.flags |= SEC_LEVEL;
++ sec.level = SEC_LEVEL_2;
++ } else if (ext->alg == IW_ENCODE_ALG_CCMP) {
++ // sec.encode_alg[idx] = SEC_ALG_CCMP;
++ sec.flags |= SEC_LEVEL;
++ sec.level = SEC_LEVEL_3;
++ }
++ /* Don't set sec level for group keys. */
++ if (group_key)
++ sec.flags &= ~SEC_LEVEL;
++ }
++#endif
++done:
++ if (ieee->set_security)
++ ieee->set_security(ieee->dev, &sec);
++
++ if (ieee->reset_on_keychange &&
++ ieee->iw_mode != IW_MODE_INFRA &&
++ ieee->reset_port && ieee->reset_port(dev)) {
++ IEEE80211_DEBUG_WX("%s: reset_port failed\n", dev->name);
++ return -EINVAL;
++ }
++
++ return ret;
++}
++int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ struct iw_mlme *mlme = (struct iw_mlme *) extra;
++// printk("\ndkgadfslkdjgalskdf===============>%s(), cmd:%x\n", __FUNCTION__, mlme->cmd);
++#if 1
++ switch (mlme->cmd) {
++ case IW_MLME_DEAUTH:
++ case IW_MLME_DISASSOC:
++ // printk("disassoc now\n");
++ ieee80211_disassociate(ieee);
++ break;
++ default:
++ return -EOPNOTSUPP;
++ }
++#endif
++ return 0;
++}
++
++int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
++ struct iw_request_info *info,
++ struct iw_param *data, char *extra)
++{
++/*
++ struct ieee80211_security sec = {
++ .flags = SEC_AUTH_MODE,
++ }
++*/
++ //printk("set auth:flag:%x, data value:%x\n", data->flags, data->value);
++ switch (data->flags & IW_AUTH_INDEX) {
++ case IW_AUTH_WPA_VERSION:
++ /*need to support wpa2 here*/
++ //printk("wpa version:%x\n", data->value);
++ break;
++ case IW_AUTH_CIPHER_PAIRWISE:
++ case IW_AUTH_CIPHER_GROUP:
++ case IW_AUTH_KEY_MGMT:
++ /*
++ * * Host AP driver does not use these parameters and allows
++ * * wpa_supplicant to control them internally.
++ * */
++ break;
++ case IW_AUTH_TKIP_COUNTERMEASURES:
++ ieee->tkip_countermeasures = data->value;
++ break;
++ case IW_AUTH_DROP_UNENCRYPTED:
++ ieee->drop_unencrypted = data->value;
++ break;
++
++ case IW_AUTH_80211_AUTH_ALG:
++ ieee->open_wep = (data->value&IW_AUTH_ALG_OPEN_SYSTEM)?1:0;
++ //printk("open_wep:%d\n", ieee->open_wep);
++ break;
++
++#if 1
++ case IW_AUTH_WPA_ENABLED:
++ ieee->wpa_enabled = (data->value)?1:0;
++ //printk("enalbe wpa:%d\n", ieee->wpa_enabled);
++ break;
++
++#endif
++ case IW_AUTH_RX_UNENCRYPTED_EAPOL:
++ ieee->ieee802_1x = data->value;
++ break;
++ case IW_AUTH_PRIVACY_INVOKED:
++ ieee->privacy_invoked = data->value;
++ break;
++ default:
++ return -EOPNOTSUPP;
++ }
++ return 0;
++}
++
++#if 1
++int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len)
++{
++#if 0
++ printk("====>%s()\n", __FUNCTION__);
++ {
++ int i;
++ for (i=0; i<len; i++)
++ printk("%2x ", ie[i]&0xff);
++ printk("\n");
++ }
++#endif
++ u8 *buf = NULL;
++
++ if (len>MAX_WPA_IE_LEN || (len && ie == NULL))
++ {
++ // printk("return error out, len:%d\n", len);
++ return -EINVAL;
++ }
++ if (len)
++ {
++
++ if (len != ie[1]+2) printk("len:%d, ie:%d\n", (int)len, ie[1]);
++ buf = kmalloc(len, GFP_KERNEL);
++ if (buf == NULL)
++ return -ENOMEM;
++ memcpy(buf, ie, len);
++ kfree(ieee->wpa_ie);
++ ieee->wpa_ie = buf;
++ ieee->wpa_ie_len = len;
++ }
++ else{
++ if (ieee->wpa_ie)
++ kfree(ieee->wpa_ie);
++ ieee->wpa_ie = NULL;
++ ieee->wpa_ie_len = 0;
++ }
++// printk("<=====out %s()\n", __FUNCTION__);
++
++ return 0;
++
++}
++#endif
++
++EXPORT_SYMBOL(ieee80211_wx_set_gen_ie);
++EXPORT_SYMBOL(ieee80211_wx_set_mlme);
++EXPORT_SYMBOL(ieee80211_wx_set_auth);
++EXPORT_SYMBOL(ieee80211_wx_set_encode_ext);
++EXPORT_SYMBOL(ieee80211_wx_get_scan);
++EXPORT_SYMBOL(ieee80211_wx_set_encode);
++EXPORT_SYMBOL(ieee80211_wx_get_encode);
++#if 0
++EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_scan);
++EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_encode);
++EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_encode);
++#endif
+diff --git a/drivers/net/wireless/rtl8187b/ieee80211/internal.h b/drivers/net/wireless/rtl8187b/ieee80211/internal.h
+new file mode 100644
+index 0000000..189f285
+--- /dev/null
++++ b/drivers/net/wireless/rtl8187b/ieee80211/internal.h
+@@ -0,0 +1,115 @@
++/*
++ * Cryptographic API.
++ *
++ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
++ *
++ * 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 _CRYPTO_INTERNAL_H
++#define _CRYPTO_INTERNAL_H
++
++
++//#include <linux/crypto.h>
++#include "rtl_crypto.h"
++#include <linux/mm.h>
++#include <linux/highmem.h>
++#include <linux/init.h>
++#include <asm/hardirq.h>
++#include <asm/softirq.h>
++#include <asm/kmap_types.h>
++
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,20))
++#define list_for_each_entry(pos, head, member) \
++ for (pos = list_entry((head)->next, typeof(*pos), member), \
++ prefetch(pos->member.next); \
++ &pos->member != (head); \
++ pos = list_entry(pos->member.next, typeof(*pos), member), \
++ prefetch(pos->member.next))
++
++static inline void cond_resched(void)
++{
++ if (need_resched()) {
++ set_current_state(TASK_RUNNING);
++ schedule();
++ }
++}
++#endif
++
++extern enum km_type crypto_km_types[];
++
++static inline enum km_type crypto_kmap_type(int out)
++{
++ return crypto_km_types[(in_softirq() ? 2 : 0) + out];
++}
++
++static inline void *crypto_kmap(struct page *page, int out)
++{
++ return kmap_atomic(page, crypto_kmap_type(out));
++}
++
++static inline void crypto_kunmap(void *vaddr, int out)
++{
++ kunmap_atomic(vaddr, crypto_kmap_type(out));
++}
++
++static inline void crypto_yield(struct crypto_tfm *tfm)
++{
++ if (!in_softirq())
++ cond_resched();
++}
++
++static inline void *crypto_tfm_ctx(struct crypto_tfm *tfm)
++{
++ return (void *)&tfm[1];
++}
++
++struct crypto_alg *crypto_alg_lookup(const char *name);
++
++#ifdef CONFIG_KMOD
++void crypto_alg_autoload(const char *name);
++struct crypto_alg *crypto_alg_mod_lookup(const char *name);
++#else
++static inline struct crypto_alg *crypto_alg_mod_lookup(const char *name)
++{
++ return crypto_alg_lookup(name);
++}
++#endif
++
++#ifdef CONFIG_CRYPTO_HMAC
++int crypto_alloc_hmac_block(struct crypto_tfm *tfm);
++void crypto_free_hmac_block(struct crypto_tfm *tfm);
++#else
++static inline int crypto_alloc_hmac_block(struct crypto_tfm *tfm)
++{
++ return 0;
++}
++
++static inline void crypto_free_hmac_block(struct crypto_tfm *tfm)
++{ }
++#endif
++
++#ifdef CONFIG_PROC_FS
++void __init crypto_init_proc(void);
++#else
++static inline void crypto_init_proc(void)
++{ }
++#endif
++
++int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags);
++int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags);
++int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags);
++
++int crypto_init_digest_ops(struct crypto_tfm *tfm);
++int crypto_init_cipher_ops(struct crypto_tfm *tfm);
++int crypto_init_compress_ops(struct crypto_tfm *tfm);
++
++void crypto_exit_digest_ops(struct crypto_tfm *tfm);
++void crypto_exit_cipher_ops(struct crypto_tfm *tfm);
++void crypto_exit_compress_ops(struct crypto_tfm *tfm);
++
++#endif /* _CRYPTO_INTERNAL_H */
++
+diff --git a/drivers/net/wireless/rtl8187b/ieee80211/kmap_types.h b/drivers/net/wireless/rtl8187b/ieee80211/kmap_types.h
+new file mode 100644
+index 0000000..de67bb0
+--- /dev/null
++++ b/drivers/net/wireless/rtl8187b/ieee80211/kmap_types.h
+@@ -0,0 +1,20 @@
++#ifndef __KMAP_TYPES_H
++
++#define __KMAP_TYPES_H
++
++
++enum km_type {
++ KM_BOUNCE_READ,
++ KM_SKB_SUNRPC_DATA,
++ KM_SKB_DATA_SOFTIRQ,
++ KM_USER0,
++ KM_USER1,
++ KM_BH_IRQ,
++ KM_SOFTIRQ0,
++ KM_SOFTIRQ1,
++ KM_TYPE_NR
++};
++
++#define _ASM_KMAP_TYPES_H
++
++#endif
+diff --git a/drivers/net/wireless/rtl8187b/ieee80211/readme b/drivers/net/wireless/rtl8187b/ieee80211/readme
+new file mode 100644
+index 0000000..bc04ffb
+--- /dev/null
++++ b/drivers/net/wireless/rtl8187b/ieee80211/readme
+@@ -0,0 +1,162 @@
++What this layer should do
++
++- It mantain the old mechanism as alternative, so the
++ ipw2100 driver works with really few changes.
++- Encapsulate / Decapsulate ieee80211 packet
++- Handle fragmentation
++- Optionally provide an alterantive mechanism for netif queue stop/wake,
++ so that the ieee80211 layer will pass one fragment per time instead of
++ one txb struct per time. so the driver can stop the queue in the middle
++ of a packet.
++- Provide two different TX interfaces for cards that can handle management
++ frames on one HW queue, and data on another, and for cards that have only
++ one HW queue (the latter untested and very, very rough).
++- Optionally provide the logic for handling IBSS/MASTER/MONITOR/BSS modes
++ and for the channel, essid and wap get/set wireless extension requests.
++ so that the driver has only to change channel when the ieee stack tell it.
++- Optionally provide a scanning mechanism so that the driver has not to
++ worry about this, just implement the set channel calback and pass
++ frames to the upper layer
++- Optionally provide the bss client protocol handshaking (just with open
++ authentication)
++- Optionally provide the probe request send mechanism
++- Optionally provide the bss master mode logic to handle association
++ protocol (only open authentication) and probe responses.
++- SW wep encryption (with open authentication)
++- It collects some stats
++- It provides beacons to the card when it ask for them
++
++What this layer doesn't do (yet)
++- Perform shared authentication
++- Have full support for master mode (the AP should loop back in the air
++ frames from an associated client to another. This could be done easily
++ with few lines of code, and it is done in my previous version of the
++ stach, but a table of association must be keept and a disassociation
++ policy must be decided and implemented.
++- Handle cleanly the full ieee 802.11 protocol. In AP mode it never
++ disassociate clients, and it is really prone to always allow access.
++ In bss client mode it is a bit rough with AP deauth and disassoc requests.
++- It has not any entry point to view the collected stats.
++- Altought it takes care of the card supported rates in the management frame
++ it sends, support for rate changing on TXed packet is not complete.
++- Give up once associated in bss client mode (it never detect a
++ signal loss condition to disassociate and restart scanning)
++- Provide a mechanism for enabling the TX in monitor mode, so
++ userspace programs can TX raw packets.
++- Provide a mechanism for cards that need that the SW take care of beacon
++ TX completely, in sense that the SW has to enqueue by itself beacons
++ to the card so it TX them (if any...)
++APIs
++
++Callback functions in the original stack has been mantained.
++following has been added (from ieee80211.h)
++
++ /* Softmac-generated frames (mamagement) are TXed via this
++ * callback if the flag IEEE_SOFTMAC_SINGLE_QUEUE is
++ * not set. As some cards may have different HW queues that
++ * one might want to use for data and management frames
++ * the option to have two callbacks might be useful.
++ * This fucntion can't sleep.
++ */
++ int (*softmac_hard_start_xmit)(struct sk_buff *skb,
++ struct net_device *dev);
++
++ /* used instead of hard_start_xmit (not softmac_hard_start_xmit)
++ * if the IEEE_SOFTMAC_TX_QUEUE feature is used to TX data
++ * frames. I the option IEEE_SOFTMAC_SINGLE_QUEUE is also set
++ * then also management frames are sent via this callback.
++ * This function can't sleep.
++ */
++ void (*softmac_data_hard_start_xmit)(struct sk_buff *skb,
++ struct net_device *dev);
++
++ /* stops the HW queue for DATA frames. Useful to avoid
++ * waste time to TX data frame when we are reassociating
++ * This function can sleep.
++ */
++ void (*data_hard_stop)(struct net_device *dev);
++
++ /* OK this is complementar to data_poll_hard_stop */
++ void (*data_hard_resume)(struct net_device *dev);
++
++ /* ask to the driver to retune the radio .
++ * This function can sleep. the driver should ensure
++ * the radio has been swithced before return.
++ */
++ void (*set_chan)(struct net_device *dev,short ch);
++
++ /* These are not used if the ieee stack takes care of
++ * scanning (IEEE_SOFTMAC_SCAN feature set).
++ * In this case only the set_chan is used.
++ *
++ * The syncro version is similar to the start_scan but
++ * does not return until all channels has been scanned.
++ * this is called in user context and should sleep,
++ * it is called in a work_queue when swithcing to ad-hoc mode
++ * or in behalf of iwlist scan when the card is associated
++ * and root user ask for a scan.
++ * the fucntion stop_scan should stop both the syncro and
++ * background scanning and can sleep.
++ * The fucntion start_scan should initiate the background
++ * scanning and can't sleep.
++ */
++ void (*scan_syncro)(struct net_device *dev);
++ void (*start_scan)(struct net_device *dev);
++ void (*stop_scan)(struct net_device *dev);
++
++ /* indicate the driver that the link state is changed
++ * for example it may indicate the card is associated now.
++ * Driver might be interested in this to apply RX filter
++ * rules or simply light the LINK led
++ */
++ void (*link_change)(struct net_device *dev);
++
++Functions hard_data_[resume/stop] are optional and should not be used
++if the driver decides to uses data+management frames enqueue in a
++single HQ queue (thus using just the softmac_hard_data_start_xmit
++callback).
++
++Function that the driver can use are:
++
++ieee80211_get_beacon - this is called by the driver when
++ the HW needs a beacon.
++ieee80211_softmac_start_protocol - this should normally be called in the
++ driver open function
++ieee80211_softmac_stop_protocol - the opposite of the above
++ieee80211_wake_queue - this is similar to netif_wake_queue
++ieee80211_reset_queue - this throw away fragments pending(if any)
++ieee80211_stop_queue - this is similar to netif_stop_queue
++
++
++known BUGS:
++- When performing syncro scan (possiblily when swithcing to ad-hoc mode
++ and when running iwlist scan when associated) there is still an odd
++ behaviour.. I have not looked in this more accurately (yet).
++
++locking:
++locking is done by means of three structures.
++1- ieee->lock (by means of spin_[un]lock_irq[save/restore]
++2- ieee->wx_sem
++3- ieee->scan_sem
++
++the lock 1 is what protect most of the critical sections in the ieee stack.
++the lock 2 is used to avoid that more than one of the SET wireless extension
++handlers (as well as start/stop protocol function) are running at the same time.
++the lock 1 is used when we need to modify or read the shared data in the wx handlers.
++In other words the lock 2 will prevent one SET action will run across another SET
++action (by make sleep the 2nd one) but allow GET actions, while the lock 1
++make atomic those little shared data access in both GET and SET operation.
++So get operation will be never be delayed really: they will never sleep..
++Furthermore in the top of some SET operations a flag is set before acquiring
++the lock. This is an help to make the previous running SET operation to
++finish faster if needed (just in case the second one will totally undo the
++first, so there is not need to complete the 1st really.. ).
++The background scanning mechaninsm is protected by the lock 1 except for the
++workqueue. this wq is here just to let the set_chan callback sleep (I thinked it
++might be appreciated by USB network card driver developer). In this case the lock 3
++take its turn.
++Thus the stop function needs both the locks.
++Funny in the syncro scan the lock 2 play its role (as both the syncro_scan
++function and the stop scan function are called with this semaphore held).
++
++
+diff --git a/drivers/net/wireless/rtl8187b/ieee80211/rtl8187_mesh.h b/drivers/net/wireless/rtl8187b/ieee80211/rtl8187_mesh.h
+new file mode 100644
+index 0000000..80f23ea
+--- /dev/null
++++ b/drivers/net/wireless/rtl8187b/ieee80211/rtl8187_mesh.h
+@@ -0,0 +1,282 @@
++#ifndef _RTL8187_MESH_H_
++#define _RTL8187_MESH_H_
++
++#include "msh_class.h" // struct mshclass
++#include "mesh.h" // struct MESH-Neighbor-Entry
++#include "ieee80211.h" // struct ieee80211-network
++#include "mesh_8185_util.h" // DOT11-QUEUE
++#include "hash_table.h" // hash-table
++#include "8185s_pathsel.h"
++#include <linux/list.h>
++
++#define GET_MESH_PRIV(x) ((struct mshclass_priv *)(x->priv))
++
++struct ieee80211_hdr_mesh {
++ u16 frame_ctl;
++ u16 duration_id;
++ u8 addr1[ETH_ALEN];
++ u8 addr2[ETH_ALEN];
++ u8 addr3[ETH_ALEN];
++ u16 seq_ctl;
++ u8 addr4[ETH_ALEN];
++ unsigned char mesh_flag;
++ INT8 TTL;
++ UINT16 segNum;
++ unsigned char DestMACAddr[ETH_ALEN]; // modify for 6 address
++ unsigned char SrcMACAddr[ETH_ALEN];
++} __attribute__ ((packed));
++
++struct myMeshIDNode {
++ struct list_head list;
++ char id[MESH_ID_LEN+1];
++ short popEN;
++ char tried;
++ unsigned long expire;
++ struct ieee80211_network mesh_network;
++};
++
++struct ieee80211_hdr_mesh_QOS {
++ u16 frame_ctl;
++ u16 duration_id;
++ u8 addr1[ETH_ALEN];
++ u8 addr2[ETH_ALEN];
++ u8 addr3[ETH_ALEN];
++ u16 seq_ctl;
++ u8 addr4[ETH_ALEN];
++ u16 QOS_ctl;
++ unsigned char mesh_flag;
++ INT8 TTL;
++ UINT16 segNum;
++ unsigned char DestMACAddr[ETH_ALEN]; // modify for 6 address
++ unsigned char SrcMACAddr[ETH_ALEN];
++} __attribute__ ((packed));
++
++
++struct mesh_PeerEntry {
++ // based on 8185ag.h
++ struct list_head hash_list;
++ unsigned int used; ///< used == TRUE => has been allocated, \n used == FALSE => can be allocated
++ unsigned char hwaddr[MACADDRLEN]; ///< hardware address
++
++ // struct list_head mesh_unEstablish_ptr; // ©|¥¼(©Î±q¤w³s½u -> ¥¼³s½u) ¤§ MP list
++ struct list_head mesh_mp_ptr; // MP list
++
++ /*mesh_neighbor:
++ * Inited by "Neighbor Discovering"
++ * cleaned by "Disassociation" or "Expired"
++ */
++ struct MESH_Neighbor_Entry mesh_neighbor_TBL;
++
++ struct ieee80211_network * pstat; // a backward pointer
++
++ // 802.11 seq checking
++ u16 last_rxseq; /* rx seq previous per-tid */
++ u16 last_rxfrag;/* tx frag previous per-tid */
++ unsigned long last_time;
++ //
++};
++
++
++struct mshclass_priv {
++
++ struct mesh_PeerEntry *meshEntries; // 1-to-1 for priv->ieee80211->networks
++
++ spinlock_t lock_stainfo; // lock for accessing the data structure of stat info
++ spinlock_t lock_queue; // lock for DOT11_EnQueue2/DOT11_DeQueue2/enque/dequeue
++ spinlock_t lock_Rreq; // lock for rreq_retry. Some function like aodv_expire/tx use lock_queue simultaneously
++// spinlock_t lock_meshlist;
++
++ // struct _DOT11_QUEUE *pevent_queue; ///< 802.11 QUEUEµ²ºc
++ // struct hash_table *pathsel_table; // GANTOE
++ //tsananiu
++ struct _DOT11_QUEUE *pathsel_queue; ///< 802.11 QUEUEµ²ºc
++
++ //tsananiu end
++
++ //add by shlu 20070518
++ unsigned char RreqMAC[AODV_RREQ_TABLE_SIZE][6];
++ unsigned int RreqBegin;
++ unsigned int RreqEnd;
++
++#if defined(MESH_ROLE_ROOT) || defined(MESH_ROLE_PORTAL)
++#define MAX_SZ_BAD_MAC 3
++ unsigned char BadMac[MAX_SZ_BAD_MAC][MACADDRLEN];
++ int idx_BadMac;
++#endif // MESH_ROLE_ROOT || MESH_ROLE_PORTAL
++
++ //-------------
++ unsigned char root_mac[MACADDRLEN];
++ struct mesh_info dot11MeshInfo; // extrated from wifi_mib (ieee802_mib.h)
++ struct hash_table *proxy_table, *mesh_rreq_retry_queue; //GANTOE //GANTOE
++ struct hash_table *pathsel_table; // add by chuangch 2007.09.13
++ // add by Jason
++ struct mpp_tb *pann_mpp_tb;
++
++ struct timer_list expire_timer; // 1sec timer
++
++ struct timer_list beacon_timer; // 1sec timer
++ struct list_head stat_hash[MAX_NETWORK_COUNT]; // sta_info hash table (aid_obj)
++
++ struct list_head meshList[MAX_CHANNEL_NUMBER];
++ int scanMode;
++
++ struct {
++ struct ieee80211_network *pstat;
++ unsigned char hwaddr[MACADDRLEN];
++ } stainfo_cache;
++
++ // The following elements are used by 802.11s.
++ // For copyright-pretection, we use an independent (binary) module.
++ // Note that it can also be put either under r8180_priv or ieee80211_device. The adv of put under
++ // r8180_priv is to get "higher encapsulation". On the other hand, r8180_priv was originally designed
++ // for "hardward specific."
++ char mesh_mac_filter_allow[8][13];
++ char mesh_mac_filter_deny[8][13];
++
++ struct MESH_Share meshare; // mesh share data
++
++ struct {
++
++ int prev_iw_mode; // Save this->iw_mode for r8180_wx->r8180_wx_enable_mesh. No init requirement
++
++ struct MESH_Profile mesh_profile; // contains MESHID
++
++ struct mesh_info dot11MeshInfo; // contains meshMaxAssocNum
++
++ struct net_device_stats mesh_stats;
++
++ UINT8 mesh_Version; // ¨Ï¥Îªºª©¥»
++ // WLAN Mesh Capability
++ INT16 mesh_PeerCAP_cap; // peer capability-Cap number (¦³¸¹¼Æ)
++ UINT8 mesh_PeerCAP_flags; // peer capability-flags
++ UINT8 mesh_PowerSaveCAP; // Power Save capability
++ UINT8 mesh_SyncCAP; // Synchronization capability
++ UINT8 mesh_MDA_CAP; // MDA capability
++ UINT32 mesh_ChannelPrecedence; // Channel Precedence
++
++ // neighbor -> candidate neighbor, if mesh_available_peerlink > 0, page 56, D0.02
++ UINT8 mesh_AvailablePeerLink; // ¦¹¬O§_¦³»Ý­n?(¦]¥¦µ¥¦P©ó mesh_PeerCAP)=>¼È ®É«O ¯d
++
++ UINT8 mesh_HeaderFlags; // mesh header ¤ºªº mesh flags field
++
++ // MKD domain element [MKDDIE]
++ UINT8 mesh_MKD_DomainID[6];
++ UINT8 mesh_MKDDIE_SecurityConfiguration;
++
++ // EMSA Handshake element [EMSAIE]
++ UINT8 mesh_EMSAIE_ANonce[32];
++ UINT8 mesh_EMSAIE_SNonce[32];
++ UINT8 mesh_EMSAIE_MA_ID[6];
++ UINT16 mesh_EMSAIE_MIC_Control;
++ UINT8 mesh_EMSAIE_MIC[16];
++
++ struct timer_list mesh_peer_link_timer; ///< ¹ï©|¥¼³s ½u(»P³s½u°h¦Ü¥¼³s½u) MP mesh_unEstablish_hdr §@ peer link time out
++
++// struct timer_list mesh_beacon_timer;
++ // mesh_unEstablish_hdr:
++ // It is a list structure, only stores unEstablish (or Establish -> unEstablish [MP_HOLDING])MP entry
++ // Each entry is a pointer pointing to an entry in "stat_info->mesh_mp_ptr"
++ // and removed by successful "Peer link setup" or "Expired"
++ struct list_head mesh_unEstablish_hdr;
++
++ // mesh_mp_hdr:
++ // It is a list of MP/MAP/MPP who has already passed "Peer link setup"
++ // Each entry is a pointer pointing to an entry in "stat_info->mesh_mp_ptr"
++ // Every entry is inserted by "successful peer link setup"
++ // and removed by "Expired"
++ struct list_head mesh_mp_hdr;
++
++ } mesh;
++
++ int iCurChannel; // remember the working channel
++};
++
++// Stanley, 04/23/07
++// The following mode is used by ieee80211_device->iw_mode
++// Although it is better to put the definition under linux/wireless.h (or wireless_copy.h), it is a system file
++// that we shouldn't modify directly.
++#define IW_MODE_MESH 11 /* 802.11s mesh mode */
++
++// Default MESHID
++#define IEEE80211S_DEFAULT_MESHID "802.11s"
++
++// callback for 802.11s
++extern short rtl8187_patch_ieee80211_probe_req_1 (struct ieee80211_device *ieee);
++extern u8* rtl8187_patch_ieee80211_probe_req_2 (struct ieee80211_device *ieee, struct sk_buff *skb, u8 *tag);
++
++// wx
++extern int rtl8187_patch_r8180_wx_get_meshinfo(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
++extern int rtl8187_patch_r8180_wx_enable_mesh(struct net_device *dev);
++extern int rtl8187_patch_r8180_wx_disable_mesh(struct net_device *dev);
++extern int rtl8187_patch_r8180_wx_wx_set_meshID(struct net_device *dev, char *ext,unsigned char channel);
++extern void rtl8187_patch_r8180_wx_set_channel (struct ieee80211_device *ieee, int ch);
++extern int rtl8187_patch_r8180_wx_set_add_mac_allow(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
++extern int rtl8187_patch_r8180_wx_set_del_mac_allow(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
++extern int rtl8187_patch_r8180_wx_set_add_mac_deny(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
++extern int rtl8187_patch_r8180_wx_set_del_mac_deny(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
++extern int rtl8187_patch_r8180_wx_get_mac_allow(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
++extern int rtl8187_patch_r8180_wx_get_mac_deny(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
++
++extern int rtl8187_patch_r8180_wx_get_mesh_list(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
++extern int rtl8187_patch_r8180_wx_mesh_scan(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
++extern int rtl8187_patch_r8180_wx_get_selected_mesh(struct net_device *dev, int en, char *cho, char* id);
++//by amy for networkmanager UI
++extern int rtl8187_patch_r8180_wx_get_selected_mesh_channel(struct net_device *dev, char *extmeshid, char *cho);
++//by amy for networkmanager UI
++// osdep
++extern int rtl8187_patch_ieee80211_start_protocol (struct ieee80211_device *ieee);
++extern u8 rtl8187_patch_rtl8180_up(struct mshclass *priv);
++extern void rtl8187_patch_ieee80211_stop_protocol(struct ieee80211_device *ieee);
++
++// issue_assocreq_MP
++extern void rtl8187_patch_ieee80211_association_req_1 (struct ieee80211_assoc_request_frame *hdr);
++extern u8* rtl8187_patch_ieee80211_association_req_2 (struct ieee80211_device *ieee, struct ieee80211_network *pstat, struct sk_buff *skb);
++
++// OnAssocReq_MP
++extern int rtl8187_patch_ieee80211_rx_frame_softmac_on_assoc_req (struct ieee80211_device *ieee, struct sk_buff *skb);
++
++// issue_assocrsp_MP
++extern void rtl8187_patch_ieee80211_assoc_resp_by_net_1 (struct ieee80211_assoc_response_frame *assoc);
++u8* rtl8187_patch_ieee80211_assoc_resp_by_net_2 (struct ieee80211_device *ieee, struct ieee80211_network *pstat, int pkt_type, struct sk_buff *skb);
++
++// OnAssocRsp_MP
++extern int rtl8187_patch_ieee80211_rx_frame_softmac_on_assoc_rsp (struct ieee80211_device *ieee, struct sk_buff *skb);
++
++
++extern int rtl8187_patch_ieee80211_rx_frame_softmac_on_auth(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats);
++extern int rtl8187_patch_ieee80211_rx_frame_softmac_on_deauth(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats);
++extern unsigned int rtl8187_patch_ieee80211_process_probe_response_1( struct ieee80211_device *ieee, struct ieee80211_probe_response *beacon, struct ieee80211_rx_stats *stats);
++extern void rtl8187_patch_ieee80211_rx_mgt_on_probe_req( struct ieee80211_device *ieee, struct ieee80211_probe_request *beacon, struct ieee80211_rx_stats *stats);
++extern void rtl8187_patch_ieee80211_rx_mgt_update_expire ( struct ieee80211_device *ieee, struct sk_buff *skb);
++
++// set channel
++extern int rtl8187_patch_ieee80211_ext_stop_scan_wq_set_channel (struct ieee80211_device *ieee);
++
++// on rx (rx isr)
++extern int rtl8187_patch_ieee80211_rx_on_rx (struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats, u16 type, u16 stype);
++
++// r8187_core
++// handle ioctl
++extern int rtl8187_patch_rtl8180_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
++// create proc
++extern void rtl8187_patch_create_proc(struct r8180_priv *priv);
++extern void rtl8187_patch_remove_proc(struct r8180_priv *priv);
++
++// tx, xmit
++// locked by ieee->lock. Call ieee80211_softmac_xmit afterward
++extern struct ieee80211_txb* rtl8187_patch_ieee80211_xmit (struct sk_buff *skb, struct net_device *dev);
++
++// given a skb, output header's length
++extern int rtl8187_patch_ieee80211_rx_frame_get_hdrlen (struct ieee80211_device *ieee, struct sk_buff *skb);
++
++// check the frame control field, return 0: not accept, 1: accept
++extern int rtl8187_patch_ieee80211_rx_is_valid_framectl (struct ieee80211_device *ieee, u16 fc, u16 type, u16 stype);
++
++// process_dataframe
++extern int rtl8187_patch_ieee80211_rx_process_dataframe (struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats);
++
++extern int rtl8187_patch_is_duplicate_packet (struct ieee80211_device *ieee, struct ieee80211_hdr *header, u16 type, u16 stype);
++
++extern int rtl8187_patch_ieee80211_softmac_xmit_get_rate (struct ieee80211_device *ieee, struct sk_buff *skb);
++extern void ieee80211_start_mesh(struct ieee80211_device *ieee);
++#endif // _RTL8187_MESH_H_
+diff --git a/drivers/net/wireless/rtl8187b/ieee80211/rtl_crypto.h b/drivers/net/wireless/rtl8187b/ieee80211/rtl_crypto.h
+new file mode 100644
+index 0000000..82fa2b7
+--- /dev/null
++++ b/drivers/net/wireless/rtl8187b/ieee80211/rtl_crypto.h
+@@ -0,0 +1,399 @@
++/*
++ * Scatterlist Cryptographic API.
++ *
++ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
++ * Copyright (c) 2002 David S. Miller (davem@redhat.com)
++ *
++ * Portions derived from Cryptoapi, by Alexander Kjeldaas <astor@fast.no>
++ * and Nettle, by Niels Mé°ˆler.
++ *
++ * 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 _LINUX_CRYPTO_H
++#define _LINUX_CRYPTO_H
++
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/types.h>
++#include <linux/list.h>
++#include <linux/string.h>
++#include <asm/page.h>
++#include <asm/errno.h>
++
++#define crypto_register_alg crypto_register_alg_rtl
++#define crypto_unregister_alg crypto_unregister_alg_rtl
++#define crypto_alloc_tfm crypto_alloc_tfm_rtl
++#define crypto_free_tfm crypto_free_tfm_rtl
++#define crypto_alg_available crypto_alg_available_rtl
++
++/*
++ * Algorithm masks and types.
++ */
++#define CRYPTO_ALG_TYPE_MASK 0x000000ff
++#define CRYPTO_ALG_TYPE_CIPHER 0x00000001
++#define CRYPTO_ALG_TYPE_DIGEST 0x00000002
++#define CRYPTO_ALG_TYPE_COMPRESS 0x00000004
++
++/*
++ * Transform masks and values (for crt_flags).
++ */
++#define CRYPTO_TFM_MODE_MASK 0x000000ff
++#define CRYPTO_TFM_REQ_MASK 0x000fff00
++#define CRYPTO_TFM_RES_MASK 0xfff00000
++
++#define CRYPTO_TFM_MODE_ECB 0x00000001
++#define CRYPTO_TFM_MODE_CBC 0x00000002
++#define CRYPTO_TFM_MODE_CFB 0x00000004
++#define CRYPTO_TFM_MODE_CTR 0x00000008
++
++#define CRYPTO_TFM_REQ_WEAK_KEY 0x00000100
++#define CRYPTO_TFM_RES_WEAK_KEY 0x00100000
++#define CRYPTO_TFM_RES_BAD_KEY_LEN 0x00200000
++#define CRYPTO_TFM_RES_BAD_KEY_SCHED 0x00400000
++#define CRYPTO_TFM_RES_BAD_BLOCK_LEN 0x00800000
++#define CRYPTO_TFM_RES_BAD_FLAGS 0x01000000
++
++/*
++ * Miscellaneous stuff.
++ */
++#define CRYPTO_UNSPEC 0
++#define CRYPTO_MAX_ALG_NAME 64
++
++struct scatterlist;
++
++/*
++ * Algorithms: modular crypto algorithm implementations, managed
++ * via crypto_register_alg() and crypto_unregister_alg().
++ */
++struct cipher_alg {
++ unsigned int cia_min_keysize;
++ unsigned int cia_max_keysize;
++ int (*cia_setkey)(void *ctx, const u8 *key,
++ unsigned int keylen, u32 *flags);
++ void (*cia_encrypt)(void *ctx, u8 *dst, const u8 *src);
++ void (*cia_decrypt)(void *ctx, u8 *dst, const u8 *src);
++};
++
++struct digest_alg {
++ unsigned int dia_digestsize;
++ void (*dia_init)(void *ctx);
++ void (*dia_update)(void *ctx, const u8 *data, unsigned int len);
++ void (*dia_final)(void *ctx, u8 *out);
++ int (*dia_setkey)(void *ctx, const u8 *key,
++ unsigned int keylen, u32 *flags);
++};
++
++struct compress_alg {
++ int (*coa_init)(void *ctx);
++ void (*coa_exit)(void *ctx);
++ int (*coa_compress)(void *ctx, const u8 *src, unsigned int slen,
++ u8 *dst, unsigned int *dlen);
++ int (*coa_decompress)(void *ctx, const u8 *src, unsigned int slen,
++ u8 *dst, unsigned int *dlen);
++};
++
++#define cra_cipher cra_u.cipher
++#define cra_digest cra_u.digest
++#define cra_compress cra_u.compress
++
++struct crypto_alg {
++ struct list_head cra_list;
++ u32 cra_flags;
++ unsigned int cra_blocksize;
++ unsigned int cra_ctxsize;
++ const char cra_name[CRYPTO_MAX_ALG_NAME];
++
++ union {
++ struct cipher_alg cipher;
++ struct digest_alg digest;
++ struct compress_alg compress;
++ } cra_u;
++
++ struct module *cra_module;
++};
++
++/*
++ * Algorithm registration interface.
++ */
++int crypto_register_alg(struct crypto_alg *alg);
++int crypto_unregister_alg(struct crypto_alg *alg);
++
++/*
++ * Algorithm query interface.
++ */
++int crypto_alg_available(const char *name, u32 flags);
++
++/*
++ * Transforms: user-instantiated objects which encapsulate algorithms
++ * and core processing logic. Managed via crypto_alloc_tfm() and
++ * crypto_free_tfm(), as well as the various helpers below.
++ */
++struct crypto_tfm;
++
++struct cipher_tfm {
++ void *cit_iv;
++ unsigned int cit_ivsize;
++ u32 cit_mode;
++ int (*cit_setkey)(struct crypto_tfm *tfm,
++ const u8 *key, unsigned int keylen);
++ int (*cit_encrypt)(struct crypto_tfm *tfm,
++ struct scatterlist *dst,
++ struct scatterlist *src,
++ unsigned int nbytes);
++ int (*cit_encrypt_iv)(struct crypto_tfm *tfm,
++ struct scatterlist *dst,
++ struct scatterlist *src,
++ unsigned int nbytes, u8 *iv);
++ int (*cit_decrypt)(struct crypto_tfm *tfm,
++ struct scatterlist *dst,
++ struct scatterlist *src,
++ unsigned int nbytes);
++ int (*cit_decrypt_iv)(struct crypto_tfm *tfm,
++ struct scatterlist *dst,
++ struct scatterlist *src,
++ unsigned int nbytes, u8 *iv);
++ void (*cit_xor_block)(u8 *dst, const u8 *src);
++};
++
++struct digest_tfm {
++ void (*dit_init)(struct crypto_tfm *tfm);
++ void (*dit_update)(struct crypto_tfm *tfm,
++ struct scatterlist *sg, unsigned int nsg);
++ void (*dit_final)(struct crypto_tfm *tfm, u8 *out);
++ void (*dit_digest)(struct crypto_tfm *tfm, struct scatterlist *sg,
++ unsigned int nsg, u8 *out);
++ int (*dit_setkey)(struct crypto_tfm *tfm,
++ const u8 *key, unsigned int keylen);
++#ifdef CONFIG_CRYPTO_HMAC
++ void *dit_hmac_block;
++#endif
++};
++
++struct compress_tfm {
++ int (*cot_compress)(struct crypto_tfm *tfm,
++ const u8 *src, unsigned int slen,
++ u8 *dst, unsigned int *dlen);
++ int (*cot_decompress)(struct crypto_tfm *tfm,
++ const u8 *src, unsigned int slen,
++ u8 *dst, unsigned int *dlen);
++};
++
++#define crt_cipher crt_u.cipher
++#define crt_digest crt_u.digest
++#define crt_compress crt_u.compress
++
++struct crypto_tfm {
++
++ u32 crt_flags;
++
++ union {
++ struct cipher_tfm cipher;
++ struct digest_tfm digest;
++ struct compress_tfm compress;
++ } crt_u;
++
++ struct crypto_alg *__crt_alg;
++};
++
++/*
++ * Transform user interface.
++ */
++
++/*
++ * crypto_alloc_tfm() will first attempt to locate an already loaded algorithm.
++ * If that fails and the kernel supports dynamically loadable modules, it
++ * will then attempt to load a module of the same name or alias. A refcount
++ * is grabbed on the algorithm which is then associated with the new transform.
++ *
++ * crypto_free_tfm() frees up the transform and any associated resources,
++ * then drops the refcount on the associated algorithm.
++ */
++struct crypto_tfm *crypto_alloc_tfm(const char *alg_name, u32 tfm_flags);
++void crypto_free_tfm(struct crypto_tfm *tfm);
++
++/*
++ * Transform helpers which query the underlying algorithm.
++ */
++static inline const char *crypto_tfm_alg_name(struct crypto_tfm *tfm)
++{
++ return tfm->__crt_alg->cra_name;
++}
++
++static inline const char *crypto_tfm_alg_modname(struct crypto_tfm *tfm)
++{
++ struct crypto_alg *alg = tfm->__crt_alg;
++
++ if (alg->cra_module)
++ return alg->cra_module->name;
++ else
++ return NULL;
++}
++
++static inline u32 crypto_tfm_alg_type(struct crypto_tfm *tfm)
++{
++ return tfm->__crt_alg->cra_flags & CRYPTO_ALG_TYPE_MASK;
++}
++
++static inline unsigned int crypto_tfm_alg_min_keysize(struct crypto_tfm *tfm)
++{
++ BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
++ return tfm->__crt_alg->cra_cipher.cia_min_keysize;
++}
++
++static inline unsigned int crypto_tfm_alg_max_keysize(struct crypto_tfm *tfm)
++{
++ BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
++ return tfm->__crt_alg->cra_cipher.cia_max_keysize;
++}
++
++static inline unsigned int crypto_tfm_alg_ivsize(struct crypto_tfm *tfm)
++{
++ BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
++ return tfm->crt_cipher.cit_ivsize;
++}
++
++static inline unsigned int crypto_tfm_alg_blocksize(struct crypto_tfm *tfm)
++{
++ return tfm->__crt_alg->cra_blocksize;
++}
++
++static inline unsigned int crypto_tfm_alg_digestsize(struct crypto_tfm *tfm)
++{
++ BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
++ return tfm->__crt_alg->cra_digest.dia_digestsize;
++}
++
++/*
++ * API wrappers.
++ */
++static inline void crypto_digest_init(struct crypto_tfm *tfm)
++{
++ BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
++ tfm->crt_digest.dit_init(tfm);
++}
++
++static inline void crypto_digest_update(struct crypto_tfm *tfm,
++ struct scatterlist *sg,
++ unsigned int nsg)
++{
++ BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
++ tfm->crt_digest.dit_update(tfm, sg, nsg);
++}
++
++static inline void crypto_digest_final(struct crypto_tfm *tfm, u8 *out)
++{
++ BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
++ tfm->crt_digest.dit_final(tfm, out);
++}
++
++static inline void crypto_digest_digest(struct crypto_tfm *tfm,
++ struct scatterlist *sg,
++ unsigned int nsg, u8 *out)
++{
++ BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
++ tfm->crt_digest.dit_digest(tfm, sg, nsg, out);
++}
++
++static inline int crypto_digest_setkey(struct crypto_tfm *tfm,
++ const u8 *key, unsigned int keylen)
++{
++ BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
++ if (tfm->crt_digest.dit_setkey == NULL)
++ return -ENOSYS;
++ return tfm->crt_digest.dit_setkey(tfm, key, keylen);
++}
++
++static inline int crypto_cipher_setkey(struct crypto_tfm *tfm,
++ const u8 *key, unsigned int keylen)
++{
++ BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
++ return tfm->crt_cipher.cit_setkey(tfm, key, keylen);
++}
++
++static inline int crypto_cipher_encrypt(struct crypto_tfm *tfm,
++ struct scatterlist *dst,
++ struct scatterlist *src,
++ unsigned int nbytes)
++{
++ BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
++ return tfm->crt_cipher.cit_encrypt(tfm, dst, src, nbytes);
++}
++
++static inline int crypto_cipher_encrypt_iv(struct crypto_tfm *tfm,
++ struct scatterlist *dst,
++ struct scatterlist *src,
++ unsigned int nbytes, u8 *iv)
++{
++ BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
++ BUG_ON(tfm->crt_cipher.cit_mode == CRYPTO_TFM_MODE_ECB);
++ return tfm->crt_cipher.cit_encrypt_iv(tfm, dst, src, nbytes, iv);
++}
++
++static inline int crypto_cipher_decrypt(struct crypto_tfm *tfm,
++ struct scatterlist *dst,
++ struct scatterlist *src,
++ unsigned int nbytes)
++{
++ BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
++ return tfm->crt_cipher.cit_decrypt(tfm, dst, src, nbytes);
++}
++
++static inline int crypto_cipher_decrypt_iv(struct crypto_tfm *tfm,
++ struct scatterlist *dst,
++ struct scatterlist *src,
++ unsigned int nbytes, u8 *iv)
++{
++ BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
++ BUG_ON(tfm->crt_cipher.cit_mode == CRYPTO_TFM_MODE_ECB);
++ return tfm->crt_cipher.cit_decrypt_iv(tfm, dst, src, nbytes, iv);
++}
++
++static inline void crypto_cipher_set_iv(struct crypto_tfm *tfm,
++ const u8 *src, unsigned int len)
++{
++ BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
++ memcpy(tfm->crt_cipher.cit_iv, src, len);
++}
++
++static inline void crypto_cipher_get_iv(struct crypto_tfm *tfm,
++ u8 *dst, unsigned int len)
++{
++ BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
++ memcpy(dst, tfm->crt_cipher.cit_iv, len);
++}
++
++static inline int crypto_comp_compress(struct crypto_tfm *tfm,
++ const u8 *src, unsigned int slen,
++ u8 *dst, unsigned int *dlen)
++{
++ BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_COMPRESS);
++ return tfm->crt_compress.cot_compress(tfm, src, slen, dst, dlen);
++}
++
++static inline int crypto_comp_decompress(struct crypto_tfm *tfm,
++ const u8 *src, unsigned int slen,
++ u8 *dst, unsigned int *dlen)
++{
++ BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_COMPRESS);
++ return tfm->crt_compress.cot_decompress(tfm, src, slen, dst, dlen);
++}
++
++/*
++ * HMAC support.
++ */
++#ifdef CONFIG_CRYPTO_HMAC
++void crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen);
++void crypto_hmac_update(struct crypto_tfm *tfm,
++ struct scatterlist *sg, unsigned int nsg);
++void crypto_hmac_final(struct crypto_tfm *tfm, u8 *key,
++ unsigned int *keylen, u8 *out);
++void crypto_hmac(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen,
++ struct scatterlist *sg, unsigned int nsg, u8 *out);
++#endif /* CONFIG_CRYPTO_HMAC */
++
++#endif /* _LINUX_CRYPTO_H */
++
+diff --git a/drivers/net/wireless/rtl8187b/ieee80211/scatterwalk.h b/drivers/net/wireless/rtl8187b/ieee80211/scatterwalk.h
+new file mode 100644
+index 0000000..b164465
+--- /dev/null
++++ b/drivers/net/wireless/rtl8187b/ieee80211/scatterwalk.h
+@@ -0,0 +1,51 @@
++/*
++ * Cryptographic API.
++ *
++ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
++ * Copyright (c) 2002 Adam J. Richter <adam@yggdrasil.com>
++ * Copyright (c) 2004 Jean-Luc Cooke <jlcooke@certainkey.com>
++ *
++ * 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 _CRYPTO_SCATTERWALK_H
++#define _CRYPTO_SCATTERWALK_H
++#include <linux/mm.h>
++#include <asm/scatterlist.h>
++
++struct scatter_walk {
++ struct scatterlist *sg;
++ struct page *page;
++ void *data;
++ unsigned int len_this_page;
++ unsigned int len_this_segment;
++ unsigned int offset;
++};
++
++/* Define sg_next is an inline routine now in case we want to change
++ scatterlist to a linked list later. */
++static inline struct scatterlist *sg_next(struct scatterlist *sg)
++{
++ return sg + 1;
++}
++
++static inline int scatterwalk_samebuf(struct scatter_walk *walk_in,
++ struct scatter_walk *walk_out,
++ void *src_p, void *dst_p)
++{
++ return walk_in->page == walk_out->page &&
++ walk_in->offset == walk_out->offset &&
++ walk_in->data == src_p && walk_out->data == dst_p;
++}
++
++void *scatterwalk_whichbuf(struct scatter_walk *walk, unsigned int nbytes, void *scratch);
++void scatterwalk_start(struct scatter_walk *walk, struct scatterlist *sg);
++int scatterwalk_copychunks(void *buf, struct scatter_walk *walk, size_t nbytes, int out);
++void scatterwalk_map(struct scatter_walk *walk, int out);
++void scatterwalk_done(struct scatter_walk *walk, int out, int more);
++
++#endif /* _CRYPTO_SCATTERWALK_H */
+diff --git a/drivers/net/wireless/rtl8187b/msh_class.h b/drivers/net/wireless/rtl8187b/msh_class.h
+new file mode 100644
+index 0000000..ccaa939
+--- /dev/null
++++ b/drivers/net/wireless/rtl8187b/msh_class.h
+@@ -0,0 +1,117 @@
++/*! \file msh_class.h
++ \brief msh CLASS extension
++
++ \date 2007/5/2
++ \author Stanley Chang <chagnsl@cs.nctu.edu.tw>
++*/
++
++#ifndef _MESH_CLASS_HDR_H_
++#define _MESH_CLASS_HDR_H_
++
++#include <linux/if_ether.h> /* ETH_ALEN */
++#include <linux/kernel.h> /* ARRAY_SIZE */
++#include <linux/version.h>
++#include <linux/jiffies.h>
++#include <linux/timer.h>
++#include <linux/sched.h>
++
++#include "ieee80211/ieee80211.h" // for struct ieee80211-xxxx
++#include "r8187.h" // for struct r8180-priv
++
++#define MAC_TABLE_SIZE 8
++
++struct mshclass {
++ struct r8180_priv * p8187;
++
++ // callback functions
++ // ieee80211_softmac.c
++ int (*ext_patch_ieee80211_start_protocol) (struct ieee80211_device *ieee); // start special mode
++
++ short (*ext_patch_ieee80211_probe_req_1) (struct ieee80211_device *ieee); // return = 0: no more phases, >0: another phase
++ u8* (*ext_patch_ieee80211_probe_req_2) (struct ieee80211_device *ieee, struct sk_buff *skb, u8 *tag); // return tag
++
++ void (*ext_patch_ieee80211_association_req_1) (struct ieee80211_assoc_request_frame *hdr);
++ u8* (*ext_patch_ieee80211_association_req_2) (struct ieee80211_device *ieee, struct ieee80211_network *pstat, struct sk_buff *skb);
++
++ int (*ext_patch_ieee80211_rx_frame_softmac_on_assoc_req) (struct ieee80211_device *ieee, struct sk_buff *skb);
++ int (*ext_patch_ieee80211_rx_frame_softmac_on_assoc_rsp) (struct ieee80211_device *ieee, struct sk_buff *skb);
++
++ void (*ext_patch_ieee80211_stop_protocol) (struct ieee80211_device *ieee); // stop timer
++
++ void (*ext_patch_ieee80211_assoc_resp_by_net_1) (struct ieee80211_assoc_response_frame *assoc);
++ u8* (*ext_patch_ieee80211_assoc_resp_by_net_2) (struct ieee80211_device *ieee, struct ieee80211_network *pstat, int pkt_type, struct sk_buff *skb);
++
++ int (*ext_patch_ieee80211_ext_stop_scan_wq_set_channel) (struct ieee80211_device *ieee);
++
++ struct sk_buff* (*ext_patch_get_beacon_get_probersp)(struct ieee80211_device *ieee, u8 *dest, struct ieee80211_network *net);
++
++ int (*ext_patch_ieee80211_softmac_xmit_get_rate) (struct ieee80211_device *ieee, struct sk_buff *skb);
++ int (*ext_patch_ieee80211_rx_frame_softmac_on_auth)(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats);
++ int (*ext_patch_ieee80211_rx_frame_softmac_on_deauth)(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats);
++//by amy for mesh
++ void (*ext_patch_ieee80211_start_mesh)(struct ieee80211_device *ieee);
++//by amy for mesh
++ /// r8180_wx.c
++ int (*ext_patch_r8180_wx_get_meshinfo) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
++ int (*ext_patch_r8180_wx_enable_mesh) (struct net_device *dev);
++ int (*ext_patch_r8180_wx_disable_mesh) (struct net_device *dev);
++ int (*ext_patch_r8180_wx_set_meshID) ( struct net_device *dev, char *ext);
++//by amy for mesh
++ int (*ext_patch_r8180_wx_set_mesh_chan)(struct net_device *dev, unsigned char channel);
++//by amy for mesh
++ void (*ext_patch_r8180_wx_set_channel) (struct ieee80211_device *ieee, int ch);
++
++ int (*ext_patch_r8180_wx_set_add_mac_allow) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
++ int (*ext_patch_r8180_wx_set_del_mac_allow) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
++ int (*ext_patch_r8180_wx_set_add_mac_deny) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
++ int (*ext_patch_r8180_wx_set_del_mac_deny) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
++ int (*ext_patch_r8180_wx_get_mac_allow) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
++ int (*ext_patch_r8180_wx_get_mac_deny) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
++
++ int (*ext_patch_r8180_wx_get_mesh_list) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
++ int (*ext_patch_r8180_wx_mesh_scan) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
++ int (*ext_patch_r8180_wx_get_selected_mesh)(struct net_device *dev, int en, char *cho, char* id);
++//by amy for networkmanager UI
++ int (*ext_patch_r8180_wx_get_selected_mesh_channel)(struct net_device *dev, char* extmeshid, char *cho);
++//by amy for networkmanager UI
++ /// r8187_core.c
++ u8 (*ext_patch_rtl8180_up) (struct mshclass *priv);
++
++ // ieee80211_rx.c
++ unsigned int (*ext_patch_ieee80211_process_probe_response_1) ( struct ieee80211_device *ieee, struct ieee80211_probe_response *beacon, struct ieee80211_rx_stats *stats);
++ void (*ext_patch_ieee80211_rx_mgt_on_probe_req) ( struct ieee80211_device *ieee, struct ieee80211_probe_request *beacon, struct ieee80211_rx_stats *stats);
++
++ void (*ext_patch_ieee80211_rx_mgt_update_expire) ( struct ieee80211_device *ieee, struct sk_buff *skb);
++
++ int (*ext_patch_ieee80211_rx_on_rx) (struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats, u16 type, u16 stype);
++
++ int (*ext_patch_ieee80211_rx_frame_get_hdrlen) (struct ieee80211_device *ieee, struct sk_buff *skb);
++
++ int (*ext_patch_ieee80211_rx_is_valid_framectl) (struct ieee80211_device *ieee, u16 fc, u16 type, u16 stype);
++
++ // return > 0 is success. 0 when failed
++ int (*ext_patch_ieee80211_rx_process_dataframe) (struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats);
++
++ int (*ext_patch_is_duplicate_packet) (struct ieee80211_device *ieee, struct ieee80211_hdr *header, u16 type, u16 stype);
++ /* added by david for setting acl dynamically */
++ u8 (*ext_patch_ieee80211_acl_query) (struct ieee80211_device *ieee, u8 *sa);
++
++ // r8187_core.c
++ int (*ext_patch_rtl8180_ioctl) (struct net_device *dev, struct ifreq *rq, int cmd);
++ void (*ext_patch_create_proc) (struct r8180_priv *priv);
++ void (*ext_patch_remove_proc) (struct r8180_priv *priv);
++
++ // ieee80211_tx.c
++
++ // locked by ieee->lock. Call ieee80211_softmac_xmit afterward
++ struct ieee80211_txb* (*ext_patch_ieee80211_xmit) (struct sk_buff *skb, struct net_device *dev);
++
++ // DO NOT MODIFY ANY STRUCTURE BELOW THIS LINE
++ u8 priv[0]; // mshclass_priv;
++};
++
++extern void free_mshobj(struct mshclass **pObj);
++extern struct mshclass *alloc_mshobj(struct r8180_priv *caller_priv);
++
++
++#endif // _MESH_CLASS_HDR_H_
+diff --git a/drivers/net/wireless/rtl8187b/r8180_93cx6.c b/drivers/net/wireless/rtl8187b/r8180_93cx6.c
+new file mode 100644
+index 0000000..8de9153
+--- /dev/null
++++ b/drivers/net/wireless/rtl8187b/r8180_93cx6.c
+@@ -0,0 +1,146 @@
++/*
++ This files contains card eeprom (93c46 or 93c56) programming routines,
++ memory is addressed by 16 bits words.
++
++ This is part of rtl8180 OpenSource driver.
++ Copyright (C) Andrea Merello 2004 <andreamrl@tiscali.it>
++ Released under the terms of GPL (General Public Licence)
++
++ Parts of this driver are based on the GPL part of the
++ official realtek driver.
++
++ Parts of this driver are based on the rtl8180 driver skeleton
++ from Patric Schenke & Andres Salomon.
++
++ Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
++
++ We want to tanks the Authors of those projects and the Ndiswrapper
++ project Authors.
++*/
++
++#include "r8180_93cx6.h"
++
++void eprom_cs(struct net_device *dev, short bit)
++{
++ if(bit)
++ write_nic_byte(dev, EPROM_CMD,
++ (1<<EPROM_CS_SHIFT) | \
++ read_nic_byte(dev, EPROM_CMD)); //enable EPROM
++ else
++ write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev, EPROM_CMD)\
++ &~(1<<EPROM_CS_SHIFT)); //disable EPROM
++
++ force_pci_posting(dev);
++ udelay(EPROM_DELAY);
++}
++
++
++void eprom_ck_cycle(struct net_device *dev)
++{
++ write_nic_byte(dev, EPROM_CMD,
++ (1<<EPROM_CK_SHIFT) | read_nic_byte(dev,EPROM_CMD));
++ force_pci_posting(dev);
++ udelay(EPROM_DELAY);
++ write_nic_byte(dev, EPROM_CMD,
++ read_nic_byte(dev, EPROM_CMD) &~ (1<<EPROM_CK_SHIFT));
++ force_pci_posting(dev);
++ udelay(EPROM_DELAY);
++}
++
++
++void eprom_w(struct net_device *dev,short bit)
++{
++ if(bit)
++ write_nic_byte(dev, EPROM_CMD, (1<<EPROM_W_SHIFT) | \
++ read_nic_byte(dev,EPROM_CMD));
++ else
++ write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev,EPROM_CMD)\
++ &~(1<<EPROM_W_SHIFT));
++
++ force_pci_posting(dev);
++ udelay(EPROM_DELAY);
++}
++
++
++short eprom_r(struct net_device *dev)
++{
++ short bit;
++
++ bit=(read_nic_byte(dev, EPROM_CMD) & (1<<EPROM_R_SHIFT) );
++ udelay(EPROM_DELAY);
++
++ if(bit) return 1;
++ return 0;
++}
++
++
++void eprom_send_bits_string(struct net_device *dev, short b[], int len)
++{
++ int i;
++
++ for(i=0; i<len; i++){
++ eprom_w(dev, b[i]);
++ eprom_ck_cycle(dev);
++ }
++}
++
++
++u32 eprom_read(struct net_device *dev, u32 addr)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ short read_cmd[]={1,1,0};
++ short addr_str[8];
++ int i;
++ int addr_len;
++ u32 ret;
++
++ ret=0;
++ //enable EPROM programming
++ write_nic_byte(dev, EPROM_CMD,
++ (EPROM_CMD_PROGRAM<<EPROM_CMD_OPERATING_MODE_SHIFT));
++ force_pci_posting(dev);
++ udelay(EPROM_DELAY);
++
++ if (priv->epromtype==EPROM_93c56){
++ addr_str[7]=addr & 1;
++ addr_str[6]=addr & (1<<1);
++ addr_str[5]=addr & (1<<2);
++ addr_str[4]=addr & (1<<3);
++ addr_str[3]=addr & (1<<4);
++ addr_str[2]=addr & (1<<5);
++ addr_str[1]=addr & (1<<6);
++ addr_str[0]=addr & (1<<7);
++ addr_len=8;
++ }else{
++ addr_str[5]=addr & 1;
++ addr_str[4]=addr & (1<<1);
++ addr_str[3]=addr & (1<<2);
++ addr_str[2]=addr & (1<<3);
++ addr_str[1]=addr & (1<<4);
++ addr_str[0]=addr & (1<<5);
++ addr_len=6;
++ }
++ eprom_cs(dev, 1);
++ eprom_ck_cycle(dev);
++ eprom_send_bits_string(dev, read_cmd, 3);
++ eprom_send_bits_string(dev, addr_str, addr_len);
++
++ //keep chip pin D to low state while reading.
++ //I'm unsure if it is necessary, but anyway shouldn't hurt
++ eprom_w(dev, 0);
++
++ for(i=0;i<16;i++){
++ //eeprom needs a clk cycle between writing opcode&adr
++ //and reading data. (eeprom outs a dummy 0)
++ eprom_ck_cycle(dev);
++ ret |= (eprom_r(dev)<<(15-i));
++ }
++
++ eprom_cs(dev, 0);
++ eprom_ck_cycle(dev);
++
++ //disable EPROM programming
++ write_nic_byte(dev, EPROM_CMD,
++ (EPROM_CMD_NORMAL<<EPROM_CMD_OPERATING_MODE_SHIFT));
++ return ret;
++}
+diff --git a/drivers/net/wireless/rtl8187b/r8180_93cx6.h b/drivers/net/wireless/rtl8187b/r8180_93cx6.h
+new file mode 100644
+index 0000000..4d08565
+--- /dev/null
++++ b/drivers/net/wireless/rtl8187b/r8180_93cx6.h
+@@ -0,0 +1,46 @@
++/*
++ This is part of rtl8187 OpenSource driver
++ Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it>
++ Released under the terms of GPL (General Public Licence)
++
++ Parts of this driver are based on the GPL part of the official realtek driver
++ Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon
++ Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
++
++ We want to tanks the Authors of such projects and the Ndiswrapper project Authors.
++*/
++
++/*This files contains card eeprom (93c46 or 93c56) programming routines*/
++/*memory is addressed by WORDS*/
++
++#include "r8187.h"
++#include "r8180_hw.h"
++
++#define EPROM_DELAY 10
++
++#define EPROM_ANAPARAM_ADDRLWORD 0xd
++#define EPROM_ANAPARAM_ADDRHWORD 0xe
++
++#define EPROM_CHANNEL_PLAN 0x3 //0x6>>1
++//0x77 BIT[0]0:use gpio 1 bit 1, 1:use gpio 1 bit 2.
++#define EPROM_SELECT_GPIO (0x77 >> 1)
++//#define EEPROM_COUNTRY_CODE 0x2E//87se channel plan is here
++
++#define EPROM_RFCHIPID 0x6
++#define EPROM_TXPW_BASE 0x05
++#define EPROM_RFCHIPID_RTL8225U 5
++#define EPROM_RFCHIPID_RTL8225U_VF 6
++#define EPROM_RF_PARAM 0x4
++#define EPROM_CONFIG2 0xc
++
++#define EPROM_VERSION 0x1E
++#define MAC_ADR 0x7
++
++#define CIS 0x18
++
++#define EPROM_TXPW0 0x16
++#define EPROM_TXPW2 0x1b
++#define EPROM_TXPW1 0x3d
++
++
++u32 eprom_read(struct net_device *dev,u32 addr); //reads a 16 bits word
+diff --git a/drivers/net/wireless/rtl8187b/r8180_dm.c b/drivers/net/wireless/rtl8187b/r8180_dm.c
+new file mode 100644
+index 0000000..684610e
+--- /dev/null
++++ b/drivers/net/wireless/rtl8187b/r8180_dm.c
+@@ -0,0 +1,882 @@
++/*++
++Copyright (c) Realtek Semiconductor Corp. All rights reserved.
++
++Module Name:
++ r8180_dig.c
++
++Abstract:
++ Hardware dynamic mechanism for RTL8187B
++
++Major Change History:
++ When Who What
++ ---------- --------------- -------------------------------
++ 2006-11-15 david Created
++
++Notes:
++ This file is ported from RTL8187B Windows driver.
++
++
++--*/
++#include "r8180_dm.h"
++#include "r8180_hw.h"
++#include "r8180_rtl8225.h"
++
++//================================================================================
++// Local Constant.
++//================================================================================
++#define Z1_HIPWR_UPPER_TH 99
++#define Z1_HIPWR_LOWER_TH 70
++#define Z2_HIPWR_UPPER_TH 99
++#define Z2_HIPWR_LOWER_TH 90
++
++bool CheckDig(struct net_device *dev)
++{
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ struct ieee80211_device *ieee = priv->ieee80211;
++
++ if(ieee->state != IEEE80211_LINKED)
++ return false;
++
++ if(priv->card_8187 == NIC_8187B) {
++ //
++ // We need to schedule dig workitem on either of the below mechanisms.
++ // By Bruce, 2007-06-01.
++ //
++ if(!priv->bDigMechanism && !priv->bCCKThMechanism)
++ return false;
++
++ if(priv->CurrentOperaRate < 36) // Schedule Dig under all OFDM rates. By Bruce, 2007-06-01.
++ return false;
++ } else {
++ if(!priv->bDigMechanism)
++ return false;
++
++ if(priv->CurrentOperaRate < 48)
++ return false;
++ }
++ return true;
++}
++
++
++//
++// Description:
++// Implementation of DIG for Zebra and Zebra2.
++//
++void DIG_Zebra(struct net_device *dev)
++{
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ //PHAL_DATA_8187 pHalData = GetHalData8187(Adapter);
++ u16 CCKFalseAlarm, OFDMFalseAlarm;
++ u16 OfdmFA1, OfdmFA2;
++ int InitialGainStep = 7; // The number of initial gain stages.
++ int LowestGainStage = 4; // The capable lowest stage of performing dig workitem.
++
++// printk("---------> DIG_Zebra()\n");
++
++ //Read only 1 byte because of HW bug. This is a temporal modification. Joseph
++ // Modify by Isaiah 2006-06-27
++ if(priv->card_8187_Bversion == VERSION_8187B_B)
++ {
++ CCKFalseAlarm = 0;
++ OFDMFalseAlarm = (u16)(priv->FalseAlarmRegValue);
++ OfdmFA1 = 0x01;
++ OfdmFA2 = priv->RegDigOfdmFaUpTh;
++ }
++ else
++ {
++ CCKFalseAlarm = (u16)(priv->FalseAlarmRegValue & 0x0000ffff);
++ OFDMFalseAlarm = (u16)((priv->FalseAlarmRegValue >> 16) & 0x0000ffff);
++ OfdmFA1 = 0x15;
++ //OfdmFA2 = 0xC00;
++ OfdmFA2 = ((u16)(priv->RegDigOfdmFaUpTh)) << 8;
++ }
++
++// printk("DIG**********CCK False Alarm: %#X \n",CCKFalseAlarm);
++// printk("DIG**********OFDM False Alarm: %#X \n",OFDMFalseAlarm);
++
++
++
++ // The number of initial gain steps is different, by Bruce, 2007-04-13.
++ if(priv->card_8187 == NIC_8187) {
++ if (priv->InitialGain == 0 ) //autoDIG
++ {
++ switch( priv->rf_chip)
++ {
++ case RF_ZEBRA:
++ priv->InitialGain = 5; // m74dBm;
++ break;
++ case RF_ZEBRA2:
++ priv->InitialGain = 4; // m78dBm;
++ break;
++ default:
++ priv->InitialGain = 5; // m74dBm;
++ break;
++ }
++ }
++ InitialGainStep = 7;
++ if(priv->InitialGain > 7)
++ priv->InitialGain = 5;
++ LowestGainStage = 4;
++ } else {
++ if (priv->InitialGain == 0 ) //autoDIG
++ { // Advised from SD3 DZ, by Bruce, 2007-06-05.
++ priv->InitialGain = 4; // In 87B, m74dBm means State 4 (m82dBm)
++ }
++ if(priv->card_8187_Bversion != VERSION_8187B_B)
++ { // Advised from SD3 DZ, by Bruce, 2007-06-05.
++ OfdmFA1 = 0x20;
++ }
++ InitialGainStep = 8;
++ LowestGainStage = priv->RegBModeGainStage; // Lowest gain stage.
++ }
++
++ if (OFDMFalseAlarm > OfdmFA1)
++ {
++ if (OFDMFalseAlarm > OfdmFA2)
++ {
++ priv->DIG_NumberFallbackVote++;
++ if (priv->DIG_NumberFallbackVote >1)
++ {
++ //serious OFDM False Alarm, need fallback
++ // By Bruce, 2007-03-29.
++ // if (pHalData->InitialGain < 7) // In 87B, m66dBm means State 7 (m74dBm)
++ if (priv->InitialGain < InitialGainStep)
++ {
++ priv->InitialGain = (priv->InitialGain + 1);
++ //printk("DIG**********OFDM False Alarm: %#X, OfdmFA1: %#X, OfdmFA2: %#X\n", OFDMFalseAlarm, OfdmFA1, OfdmFA2);
++ //printk("DIG+++++++ fallback OFDM:%d \n", priv->InitialGain);
++ UpdateInitialGain(dev); // 2005.01.06, by rcnjko.
++ }
++ priv->DIG_NumberFallbackVote = 0;
++ priv->DIG_NumberUpgradeVote=0;
++ }
++ }
++ else
++ {
++ if (priv->DIG_NumberFallbackVote)
++ priv->DIG_NumberFallbackVote--;
++ }
++ priv->DIG_NumberUpgradeVote=0;
++ }
++ else //OFDM False Alarm < 0x15
++ {
++ if (priv->DIG_NumberFallbackVote)
++ priv->DIG_NumberFallbackVote--;
++ priv->DIG_NumberUpgradeVote++;
++
++ if (priv->DIG_NumberUpgradeVote>9)
++ {
++ if (priv->InitialGain > LowestGainStage) // In 87B, m78dBm means State 4 (m864dBm)
++ {
++ priv->InitialGain = (priv->InitialGain - 1);
++ //printk("DIG**********OFDM False Alarm: %#X, OfdmFA1: %#X, OfdmFA2: %#X\n", OFDMFalseAlarm, OfdmFA1, OfdmFA2);
++ //printk("DIG--------- Upgrade OFDM:%d \n", priv->InitialGain);
++ UpdateInitialGain(dev); // 2005.01.06, by rcnjko.
++ }
++ priv->DIG_NumberFallbackVote = 0;
++ priv->DIG_NumberUpgradeVote=0;
++ }
++ }
++
++// printk("DIG+++++++ OFDM:%d\n", priv->InitialGain);
++// printk("<--------- DIG_Zebra()\n");
++}
++
++//
++// Description:
++// Dispatch DIG implementation according to RF.
++//
++void DynamicInitGain(struct net_device *dev)
++{
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++
++ switch(priv->rf_chip)
++ {
++ case RF_ZEBRA:
++ case RF_ZEBRA2: // [AnnieWorkaround] For Zebra2, 2005-08-01.
++ //case RF_ZEBRA4:
++ DIG_Zebra(dev);
++ break;
++
++ default:
++ printk("DynamicInitGain(): unknown RFChipID(%d) !!!\n", priv->rf_chip);
++ break;
++ }
++}
++
++// By Bruce, 2007-03-29.
++//
++// Description:
++// Dispatch CCK Power Detection implementation according to RF.
++//
++void DynamicCCKThreshold(struct net_device *dev)
++{
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ u16 CCK_Up_Th;
++ u16 CCK_Lw_Th;
++ u16 CCKFalseAlarm;
++
++ printk("=====>DynamicCCKThreshold()\n");
++
++ CCK_Up_Th = priv->CCKUpperTh;
++ CCK_Lw_Th = priv->CCKLowerTh;
++ CCKFalseAlarm = (u16)((priv->FalseAlarmRegValue & 0x0000ffff) >> 8); // We only care about the higher byte.
++ printk("DynamicCCKThreshold(): CCK Upper Threshold: 0x%02X, Lower Threshold: 0x%02X, CCKFalseAlarmHighByte: 0x%02X\n", CCK_Up_Th, CCK_Lw_Th, CCKFalseAlarm);
++
++ if(priv->StageCCKTh < 3 && CCKFalseAlarm >= CCK_Up_Th)
++ {
++ priv->StageCCKTh ++;
++ UpdateCCKThreshold(dev);
++ }
++ else if(priv->StageCCKTh > 0 && CCKFalseAlarm <= CCK_Lw_Th)
++ {
++ priv->StageCCKTh --;
++ UpdateCCKThreshold(dev);
++ }
++
++ printk("<=====DynamicCCKThreshold()\n");
++}
++
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
++void rtl8180_hw_dig_wq (struct work_struct *work)
++{
++ struct delayed_work *dwork = container_of(work,struct delayed_work,work);
++ struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_dig_wq);
++ struct net_device *dev = ieee->dev;
++#else
++void rtl8180_hw_dig_wq(struct net_device *dev)
++{
++ // struct r8180_priv *priv = ieee80211_priv(dev);
++#endif
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ // Read CCK and OFDM False Alarm.
++ if(priv->card_8187_Bversion == VERSION_8187B_B) {
++ // Read only 1 byte because of HW bug. This is a temporal modification. Joseph
++ // Modify by Isaiah 2006-06-27
++ priv->FalseAlarmRegValue = (u32)read_nic_byte(dev, (OFDM_FALSE_ALARM+1));
++ } else {
++ priv->FalseAlarmRegValue = read_nic_dword(dev, CCK_FALSE_ALARM);
++ }
++
++ // Adjust Initial Gain dynamically.
++ if(priv->bDigMechanism) {
++ DynamicInitGain(dev);
++ }
++
++ //
++ // Move from DynamicInitGain to be independent of the OFDM DIG mechanism, by Bruce, 2007-06-01.
++ //
++ if(priv->card_8187 == NIC_8187B) {
++ // By Bruce, 2007-03-29.
++ // Dynamically update CCK Power Detection Threshold.
++ if(priv->bCCKThMechanism)
++ {
++ DynamicCCKThreshold(dev);
++ }
++ }
++}
++
++void SetTxPowerLevel8187(struct net_device *dev, short chan)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ switch(priv->rf_chip)
++ {
++ case RF_ZEBRA:
++ rtl8225_SetTXPowerLevel(dev,chan);
++ break;
++
++ case RF_ZEBRA2:
++ //case RF_ZEBRA4:
++ rtl8225z2_SetTXPowerLevel(dev,chan);
++ break;
++ }
++}
++
++//
++// Description:
++// Check if input power signal strength exceeds maximum input power threshold
++// of current HW.
++// If yes, we set our HW to high input power state:
++// RX: always force TR switch to SW Tx mode to reduce input power.
++// TX: turn off smaller Tx output power (see RtUsbCheckForHang).
++//
++// If no, we restore our HW to normal input power state:
++/// RX: restore TR switch to HW controled mode.
++// TX: restore TX output power (see RtUsbCheckForHang).
++//
++// TODO:
++// 1. Tx power control shall not be done in Platform-dependent timer (e.g. RtUsbCheckForHang).
++// 2. Allow these threshold adjustable by RF SD.
++//
++void DoRxHighPower(struct net_device *dev)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ TR_SWITCH_STATE TrSwState;
++ u16 HiPwrUpperTh = 0;
++ u16 HiPwrLowerTh = 0;
++ u16 RSSIHiPwrUpperTh = 0;
++ u16 RSSIHiPwrLowerTh = 0;
++
++ //87S remove TrSwitch mechanism
++ if((priv->card_8187 == NIC_8187B)||(priv->card_8187 == NIC_8187)) {
++
++ //printk("----> DoRxHighPower()\n");
++
++ //
++ // Get current TR switch setting.
++ //
++ //Adapter->HalFunc.GetHwRegHandler(Adapter, HW_VAR_TR_SWITCH, (pu1Byte)(&TrSwState));
++ TrSwState = priv->TrSwitchState;
++
++ //
++ // Determine threshold according to RF type.
++ //
++ switch(priv->rf_chip)
++ {
++ case RF_ZEBRA:
++ HiPwrUpperTh = Z1_HIPWR_UPPER_TH;
++ HiPwrLowerTh = Z1_HIPWR_LOWER_TH;
++ printk("DoRxHighPower(): RF_ZEBRA, Upper Threshold: %d LOWER Threshold: %d\n",
++ HiPwrUpperTh, HiPwrLowerTh);
++ break;
++
++ case RF_ZEBRA2:
++ if((priv->card_8187 == NIC_8187)) {
++ HiPwrUpperTh = Z2_HIPWR_UPPER_TH;
++ HiPwrLowerTh = Z2_HIPWR_LOWER_TH;
++ } else {
++ // By Bruce, 2007-04-11.
++ // HiPwrUpperTh = Z2_HIPWR_UPPER_TH;
++ // HiPwrLowerTh = Z2_HIPWR_LOWER_TH;
++
++ HiPwrUpperTh = priv->Z2HiPwrUpperTh;
++ HiPwrLowerTh = priv->Z2HiPwrLowerTh;
++ HiPwrUpperTh = HiPwrUpperTh * 10;
++ HiPwrLowerTh = HiPwrLowerTh * 10;
++
++ RSSIHiPwrUpperTh = priv->Z2RSSIHiPwrUpperTh;
++ RSSIHiPwrLowerTh = priv->Z2RSSIHiPwrLowerTh;
++ //printk("DoRxHighPower(): RF_ZEBRA2, Upper Threshold: %d LOWER Threshold: %d, RSSI Upper Th: %d, RSSI Lower Th: %d\n",HiPwrUpperTh, HiPwrLowerTh, RSSIHiPwrUpperTh, RSSIHiPwrLowerTh);
++ }
++ break;
++
++ default:
++ printk("DoRxHighPower(): Unknown RFChipID(%d), UndecoratedSmoothedSS(%d), TrSwState(%d)!!!\n",
++ priv->rf_chip, priv->UndecoratedSmoothedSS, TrSwState);
++ return;
++ break;
++ }
++
++ /*printk(">>>>>>>>>>Set TR switch to software control, UndecoratedSmoothedSS:%d, CurCCKRSSI = %d\n",\
++ priv->UndecoratedSmoothedSS, priv->CurCCKRSSI);
++ */
++ if((priv->card_8187 == NIC_8187)) {
++ //
++ // Perform Rx part High Power Mechanism by UndecoratedSmoothedSS.
++ //
++ if (priv->UndecoratedSmoothedSS > HiPwrUpperTh)
++ { // High input power state.
++ if( priv->TrSwitchState == TR_HW_CONTROLLED )
++ {
++ /* printk(">>>>>>>>>>Set TR switch to software control, UndecoratedSmoothedSS:%d \n", \
++ priv->UndecoratedSmoothedSS);
++ // printk(">>>>>>>>>> TR_SW_TX\n");
++ */
++ write_nic_byte(dev, RFPinsSelect,
++ (u8)(priv->wMacRegRfPinsSelect | TR_SW_MASK_8187 ));
++ write_nic_byte(dev, RFPinsOutput,
++ (u8)((priv->wMacRegRfPinsOutput&(~TR_SW_MASK_8187))|TR_SW_MASK_TX_8187));
++ priv->TrSwitchState = TR_SW_TX;
++ priv->bToUpdateTxPwr = true;
++ }
++ }
++ else if (priv->UndecoratedSmoothedSS < HiPwrLowerTh)
++ { // Normal input power state.
++ if( priv->TrSwitchState == TR_SW_TX)
++ {
++ /* printk("<<<<<<<<<<<Set TR switch to hardware control UndecoratedSmoothedSS:%d \n", \
++ priv->UndecoratedSmoothedSS);
++ // printk("<<<<<<<<<< TR_HW_CONTROLLED\n");
++ */
++ write_nic_byte(dev, RFPinsOutput, (u8)(priv->wMacRegRfPinsOutput));
++ write_nic_byte(dev, RFPinsSelect, (u8)(priv->wMacRegRfPinsSelect));
++ priv->TrSwitchState = TR_HW_CONTROLLED;
++ priv->bToUpdateTxPwr = true;
++ }
++ }
++ }else {
++ /*printk("=====>TrSwState = %s\n", (TrSwState==TR_HW_CONTROLLED)?"TR_HW_CONTROLLED":"TR_SW_TX");
++ //printk("UndecoratedSmoothedSS:%d, CurCCKRSSI = %d\n",priv->UndecoratedSmoothedSS, priv->CurCCKRSSI); */
++ // Asked by SD3 DZ, by Bruce, 2007-04-12.
++ if(TrSwState == TR_HW_CONTROLLED)
++ {
++ if((priv->UndecoratedSmoothedSS > HiPwrUpperTh) ||
++ (priv->bCurCCKPkt && (priv->CurCCKRSSI > RSSIHiPwrUpperTh)))
++ {
++ //printk("===============================> high power!\n");
++ write_nic_byte(dev, RFPinsSelect, (u8)(priv->wMacRegRfPinsSelect|TR_SW_MASK_8187 ));
++ write_nic_byte(dev, RFPinsOutput,
++ (u8)((priv->wMacRegRfPinsOutput&(~TR_SW_MASK_8187))|TR_SW_MASK_TX_8187));
++ priv->TrSwitchState = TR_SW_TX;
++ priv->bToUpdateTxPwr = true;
++ }
++ }
++ else
++ {
++ if((priv->UndecoratedSmoothedSS < HiPwrLowerTh) &&
++ (!priv->bCurCCKPkt || priv->CurCCKRSSI < RSSIHiPwrLowerTh))
++ {
++ write_nic_byte(dev, RFPinsOutput, (u8)(priv->wMacRegRfPinsOutput));
++ write_nic_byte(dev, RFPinsSelect, (u8)(priv->wMacRegRfPinsSelect));
++ priv->TrSwitchState = TR_HW_CONTROLLED;
++ priv->bToUpdateTxPwr = true;
++ }
++ }
++ //printk("<=======TrSwState = %s\n", (TrSwState==TR_HW_CONTROLLED)?"TR_HW_CONTROLLED":"TR_SW_TX");
++ }
++ //printk("<---- DoRxHighPower()\n");
++ }
++}
++
++
++//
++// Description:
++// Callback function of UpdateTxPowerWorkItem.
++// Because of some event happend, e.g. CCX TPC, High Power Mechanism,
++// We update Tx power of current channel again.
++//
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
++void rtl8180_tx_pw_wq (struct work_struct *work)
++{
++ struct delayed_work *dwork = container_of(work,struct delayed_work,work);
++ struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,tx_pw_wq);
++ struct net_device *dev = ieee->dev;
++#else
++void rtl8180_tx_pw_wq(struct net_device *dev)
++{
++ // struct r8180_priv *priv = ieee80211_priv(dev);
++#endif
++
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ //printk("----> UpdateTxPowerWorkItemCallback()\n");
++
++ if(priv->bToUpdateTxPwr)
++ {
++ //printk("DoTxHighPower(): schedule UpdateTxPowerWorkItem......\n");
++ priv->bToUpdateTxPwr = false;
++ SetTxPowerLevel8187(dev, priv->chan);
++ }
++
++ DoRxHighPower(dev);
++ //printk("<---- UpdateTxPowerWorkItemCallback()\n");
++}
++
++//
++// Description:
++// Return TRUE if we shall perform High Power Mecahnism, FALSE otherwise.
++//
++bool CheckHighPower(struct net_device *dev)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ struct ieee80211_device *ieee = priv->ieee80211;
++
++ if(!priv->bRegHighPowerMechanism)
++ {
++ return false;
++ }
++
++ if((ieee->state == IEEE80211_LINKED_SCANNING)||(ieee->state == IEEE80211_MESH_SCANNING))
++ {
++ return false;
++ }
++
++ return true;
++}
++
++#ifdef SW_ANTE_DIVERSITY
++
++#define ANTENNA_DIVERSITY_TIMER_PERIOD 1000 // 1000 m
++
++void
++SwAntennaDiversityRxOk8185(
++ struct net_device *dev,
++ u8 SignalStrength
++ )
++{
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++
++ //printk("+SwAntennaDiversityRxOk8185: RxSs: %d\n", SignalStrength);
++
++ priv->AdRxOkCnt++;
++
++ if( priv->AdRxSignalStrength != -1)
++ {
++ priv->AdRxSignalStrength = ((priv->AdRxSignalStrength*7) + (SignalStrength*3)) / 10;
++ }
++ else
++ { // Initialization case.
++ priv->AdRxSignalStrength = SignalStrength;
++ }
++
++ //printk("====>pkt rcvd by %d\n", priv->LastRxPktAntenna);
++ if( priv->LastRxPktAntenna ) //Main antenna.
++ priv->AdMainAntennaRxOkCnt++;
++ else // Aux antenna.
++ priv->AdAuxAntennaRxOkCnt++;
++ //printk("-SwAntennaDiversityRxOk8185: AdRxOkCnt: %d AdRxSignalStrength: %d\n", priv->AdRxOkCnt, priv->AdRxSignalStrength);
++}
++
++//
++// Description: Change Antenna Switch.
++//
++bool
++SetAntenna8185(
++ struct net_device *dev,
++ u8 u1bAntennaIndex
++ )
++{
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ bool bAntennaSwitched = false;
++
++// printk("+SetAntenna8185(): Antenna is switching to: %d \n", u1bAntennaIndex);
++
++ switch(u1bAntennaIndex)
++ {
++ case 0://main antenna
++ switch(priv->rf_chip)
++ {
++ case RF_ZEBRA:
++ case RF_ZEBRA2:
++ //case RF_ZEBRA4:
++ // Tx Antenna.
++ write_nic_byte(dev, ANTSEL, 0x03); // Config TX antenna.
++
++ //PlatformEFIOWrite4Byte(Adapter, BBAddr, 0x01009b90); // Config CCK RX antenna.
++ //PlatformEFIOWrite4Byte(Adapter, BBAddr, 0x5c8D); // Config OFDM RX antenna.
++
++ // Rx CCK .
++ write_nic_byte(dev, 0x7f, ((0x01009b90 & 0xff000000) >> 24));
++ write_nic_byte(dev, 0x7e, ((0x01009b90 & 0x00ff0000) >> 16));
++ write_nic_byte(dev, 0x7d, ((0x01009b90 & 0x0000ff00) >> 8));
++ write_nic_byte(dev, 0x7c, ((0x01009b90 & 0x000000ff) >> 0));
++
++ // Rx OFDM.
++ write_nic_byte(dev, 0x7f, ((0x00005c8D & 0xff000000) >> 24));
++ write_nic_byte(dev, 0x7e, ((0x00005c8D & 0x00ff0000) >> 16));
++ write_nic_byte(dev, 0x7d, ((0x00005c8D & 0x0000ff00) >> 8));
++ write_nic_byte(dev, 0x7c, ((0x00005c8D & 0x000000ff) >> 0));
++
++ bAntennaSwitched = true;
++ break;
++
++ default:
++ printk("SetAntenna8185: unkown RFChipID(%d)\n", priv->rf_chip);
++ break;
++ }
++ break;
++
++ case 1:
++ switch(priv->rf_chip)
++ {
++ case RF_ZEBRA:
++ case RF_ZEBRA2:
++ //case RF_ZEBRA4:
++ // Tx Antenna.
++ write_nic_byte(dev, ANTSEL, 0x00); // Config TX antenna.
++
++ //PlatformEFIOWrite4Byte(Adapter, BBAddr, 0x0100bb90); // Config CCK RX antenna.
++ //PlatformEFIOWrite4Byte(Adapter, BBAddr, 0x548D); // Config OFDM RX antenna.
++
++ // Rx CCK.
++ write_nic_byte(dev, 0x7f, ((0x0100bb90 & 0xff000000) >> 24));
++ write_nic_byte(dev, 0x7e, ((0x0100bb90 & 0x00ff0000) >> 16));
++ write_nic_byte(dev, 0x7d, ((0x0100bb90 & 0x0000ff00) >> 8));
++ write_nic_byte(dev, 0x7c, ((0x0100bb90 & 0x000000ff) >> 0));
++
++ // Rx OFDM.
++ write_nic_byte(dev, 0x7f, ((0x0000548D & 0xff000000) >> 24));
++ write_nic_byte(dev, 0x7e, ((0x0000548D & 0x00ff0000) >> 16));
++ write_nic_byte(dev, 0x7d, ((0x0000548D & 0x0000ff00) >> 8));
++ write_nic_byte(dev, 0x7c, ((0x0000548D & 0x000000ff) >> 0));
++
++ bAntennaSwitched = true;
++ break;
++
++ default:
++ printk("SetAntenna8185: unkown RFChipID(%d)\n", priv->rf_chip);
++ break;
++ }
++ break;
++
++ default:
++ printk("SetAntenna8185: unkown u1bAntennaIndex(%d)\n", u1bAntennaIndex);
++ break;
++ }
++
++ if(bAntennaSwitched)
++ {
++ priv->CurrAntennaIndex = u1bAntennaIndex;
++ }
++
++// printk("-SetAntenna8185(): return (%#X)\n", bAntennaSwitched);
++
++ return bAntennaSwitched;
++}
++
++//
++// Description: Toggle Antenna switch.
++//
++bool SwitchAntenna(struct net_device *dev)
++{
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++
++ bool bResult = false;
++
++ if(priv->CurrAntennaIndex == 0)
++ {
++ bResult = SetAntenna8185(dev, 1);
++ if(priv->ieee80211->state == IEEE80211_LINKED)
++ printk("Switching to Aux antenna 1 \n");
++ }
++ else
++ {
++ bResult = SetAntenna8185(dev, 0);
++ if(priv->ieee80211->state == IEEE80211_LINKED)
++ printk("Switching to Main antenna 0 \n");
++ }
++
++ return bResult;
++}
++
++//
++// Description:
++// Engine of SW Antenna Diversity mechanism.
++// Since 8187 has no Tx part information,
++// this implementation is only dependend on Rx part information.
++//
++// 2006.04.17, by rcnjko.
++//
++void SwAntennaDiversity(struct net_device *dev)
++{
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ //bool bSwCheckSS=false;
++ bool bSwCheckSS=true;//open the SignalStrength check if not switched by rx ok pkt.
++
++// printk("+SwAntennaDiversity(): CurrAntennaIndex: %d\n", priv->CurrAntennaIndex);
++
++//by amy 080312
++ if(bSwCheckSS){
++ priv->AdTickCount++;
++
++ //printk("(1) AdTickCount: %d, AdCheckPeriod: %d\n", priv->AdTickCount, priv->AdCheckPeriod);
++ //printk("(2) AdRxSignalStrength: %ld, AdRxSsThreshold: %ld\n", priv->AdRxSignalStrength, priv->AdRxSsThreshold);
++ }
++// priv->AdTickCount++;//-by amy 080312
++
++ // Case 1. No Link.
++ if(priv->ieee80211->state != IEEE80211_LINKED){
++ //printk("SwAntennaDiversity(): Case 1. No Link.\n");
++
++ priv->bAdSwitchedChecking = false;
++ // I switch antenna here to prevent any one of antenna is broken before link established, 2006.04.18, by rcnjko..
++ SwitchAntenna(dev);
++ }
++ // Case 2. Linked but no packet received.
++ else if(priv->AdRxOkCnt == 0){
++ printk("SwAntennaDiversity(): Case 2. Linked but no packet received.\n");
++
++ priv->bAdSwitchedChecking = false;
++ SwitchAntenna(dev);
++ }
++ // Case 3. Evaluate last antenna switch action in case4. and undo it if necessary.
++ else if(priv->bAdSwitchedChecking == true){
++ //printk("SwAntennaDiversity(): Case 3. Evaluate last antenna switch action.\n");
++
++ priv->bAdSwitchedChecking = false;
++
++ // Adjust Rx signal strength threashold.
++ priv->AdRxSsThreshold = (priv->AdRxSignalStrength + priv->AdRxSsBeforeSwitched) / 2;
++
++ priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ?
++ priv->AdMaxRxSsThreshold: priv->AdRxSsThreshold;
++ if(priv->AdRxSignalStrength < priv->AdRxSsBeforeSwitched){
++ // Rx signal strength is not improved after we swtiched antenna. => Swich back.
++ printk("SwAntennaDiversity(): Rx Signal Strength is not improved, CurrRxSs: %ld, LastRxSs: %ld\n", priv->AdRxSignalStrength, priv->AdRxSsBeforeSwitched);
++
++ //by amy 080312
++ // Increase Antenna Diversity checking period due to bad decision.
++ priv->AdCheckPeriod *= 2;
++ //by amy 080312
++ //
++ // Increase Antenna Diversity checking period.
++ if(priv->AdCheckPeriod > priv->AdMaxCheckPeriod)
++ priv->AdCheckPeriod = priv->AdMaxCheckPeriod;
++
++ // Wrong deceision => switch back.
++ SwitchAntenna(dev);
++ }else{ // Rx Signal Strength is improved.
++ printk("SwAntennaDiversity(): Rx Signal Strength is improved, CurrRxSs: %ld, LastRxSs: %ld\n", priv->AdRxSignalStrength, priv->AdRxSsBeforeSwitched);
++
++ // Reset Antenna Diversity checking period to its min value.
++ priv->AdCheckPeriod = priv->AdMinCheckPeriod;
++ }
++
++ //printk("SwAntennaDiversity(): AdRxSsThreshold: %ld, AdCheckPeriod: %d\n",
++ // priv->AdRxSsThreshold, priv->AdCheckPeriod);
++ }
++ // Case 4. Evaluate if we shall switch antenna now.
++ // Cause Table Speed is very fast in TRC Dell Lab, we check it every time.
++ else// if(priv->AdTickCount >= priv->AdCheckPeriod)//-by amy 080312
++ {
++ //printk("SwAntennaDiversity(): Case 4. Evaluate if we shall switch antenna now.\n");
++
++ priv->AdTickCount = 0;
++
++ //
++ // <Roger_Notes> We evaluate RxOk counts for each antenna first and than
++ // evaluate signal strength.
++ // The following operation can overcome the disability of CCA on both two antennas
++ // When signal strength was extremely low or high.
++ // 2008.01.30.
++ //
++
++ //
++ // Evaluate RxOk count from each antenna if we shall switch default antenna now.
++ // Added by Roger, 2008.02.21.
++
++ //{by amy 080312
++ if((priv->AdMainAntennaRxOkCnt < priv->AdAuxAntennaRxOkCnt) && (priv->CurrAntennaIndex == 0)){
++ // We set Main antenna as default but RxOk count was less than Aux ones.
++
++ printk("SwAntennaDiversity(): Main antenna %d RxOK is poor, AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",priv->CurrAntennaIndex, priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);
++
++ // Switch to Aux antenna.
++ SwitchAntenna(dev);
++ priv->bHWAdSwitched = true;
++ }else if((priv->AdAuxAntennaRxOkCnt < priv->AdMainAntennaRxOkCnt) && (priv->CurrAntennaIndex == 1)){
++ // We set Aux antenna as default but RxOk count was less than Main ones.
++
++ printk("SwAntennaDiversity(): Aux antenna %d RxOK is poor, AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",priv->CurrAntennaIndex, priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);
++
++ // Switch to Main antenna.
++ SwitchAntenna(dev);
++ priv->bHWAdSwitched = true;
++ }else{// Default antenna is better.
++
++ printk("SwAntennaDiversity(): Current Antenna %d is better., AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",priv->CurrAntennaIndex, priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);
++
++ // Still need to check current signal strength.
++ priv->bHWAdSwitched = false;
++ }
++ //
++ // <Roger_Notes> We evaluate Rx signal strength ONLY when default antenna
++ // didn't changed by HW evaluation.
++ // 2008.02.27.
++ //
++ // [TRC Dell Lab] SignalStrength is inaccuracy. Isaiah 2008-03-05
++ // For example, Throughput of aux is better than main antenna(about 10M v.s 2M),
++ // but AdRxSignalStrength is less than main.
++ // Our guess is that main antenna have lower throughput and get many change
++ // to receive more CCK packets(ex.Beacon) which have stronger SignalStrength.
++ //
++ if( (!priv->bHWAdSwitched) && (bSwCheckSS)){
++ //by amy 080312}
++
++ // Evaluate Rx signal strength if we shall switch antenna now.
++ if(priv->AdRxSignalStrength < priv->AdRxSsThreshold){
++ // Rx signal strength is weak => Switch Antenna.
++ printk("SwAntennaDiversity(): Rx Signal Strength is weak, CurrRxSs: %ld, RxSsThreshold: %ld\n", priv->AdRxSignalStrength, priv->AdRxSsThreshold);
++
++ priv->AdRxSsBeforeSwitched = priv->AdRxSignalStrength;
++ priv->bAdSwitchedChecking = true;
++
++ SwitchAntenna(dev);
++ }else{ // Rx signal strength is OK.
++ printk("SwAntennaDiversity(): Rx Signal Strength is OK, CurrRxSs: %ld, RxSsThreshold: %ld\n", priv->AdRxSignalStrength, priv->AdRxSsThreshold);
++
++ priv->bAdSwitchedChecking = false;
++ // Increase Rx signal strength threashold if necessary.
++ if( (priv->AdRxSignalStrength > (priv->AdRxSsThreshold + 10)) && // Signal is much stronger than current threshold
++ priv->AdRxSsThreshold <= priv->AdMaxRxSsThreshold) // Current threhold is not yet reach upper limit.
++ {
++ priv->AdRxSsThreshold = (priv->AdRxSsThreshold + priv->AdRxSignalStrength) / 2;
++ priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ?
++ priv->AdMaxRxSsThreshold: priv->AdRxSsThreshold;//+by amy 080312
++ }
++
++ // Reduce Antenna Diversity checking period if possible.
++ if( priv->AdCheckPeriod > priv->AdMinCheckPeriod )
++ {
++ priv->AdCheckPeriod /= 2;
++ }
++ }
++ }
++ }
++//by amy 080312
++ // Reset antenna diversity Rx related statistics.
++ priv->AdRxOkCnt = 0;
++ priv->AdMainAntennaRxOkCnt = 0;
++ priv->AdAuxAntennaRxOkCnt = 0;
++//by amy 080312
++
++// priv->AdRxOkCnt = 0;//-by amy 080312
++
++ //printk("-SwAntennaDiversity()\n");
++}
++
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
++void SwAntennaWorkItemCallback(struct work_struct *work)
++{
++ struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, SwAntennaWorkItem.work);
++ struct net_device *dev = ieee->dev;
++#else
++void SwAntennaWorkItemCallback(struct net_device *dev)
++{
++#endif
++ //printk("==>%s \n", __func__);
++ SwAntennaDiversity(dev);
++}
++
++//
++// Description: Timer callback function of SW Antenna Diversity.
++//
++void SwAntennaDiversityTimerCallback(struct net_device *dev)
++{
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ RT_RF_POWER_STATE rtState;
++
++ //printk("+SwAntennaDiversityTimerCallback()\n");
++
++ //
++ // We do NOT need to switch antenna while RF is off.
++ // 2007.05.09, added by Roger.
++ //
++ rtState = priv->eRFPowerState;
++ do{
++ if (rtState == eRfOff){
++// printk("SwAntennaDiversityTimer - RF is OFF.\n");
++ break;
++ }else if (rtState == eRfSleep){
++ // Don't access BB/RF under Disable PLL situation.
++ //RT_TRACE((COMP_RF|COMP_ANTENNA), DBG_LOUD, ("SwAntennaDiversityTimerCallback(): RF is Sleep => skip it\n"));
++ break;
++ }
++
++ queue_work(priv->ieee80211->wq,(void *)&priv->ieee80211->SwAntennaWorkItem);
++
++ }while(false);
++
++ if(priv->up){
++ //priv->SwAntennaDiversityTimer.expires = jiffies + MSECS(ANTENNA_DIVERSITY_TIMER_PERIOD);
++ //add_timer(&priv->SwAntennaDiversityTimer);
++ mod_timer(&priv->SwAntennaDiversityTimer, jiffies + MSECS(ANTENNA_DIVERSITY_TIMER_PERIOD));
++ }
++
++}
++#endif
++
++
++
+diff --git a/drivers/net/wireless/rtl8187b/r8180_dm.h b/drivers/net/wireless/rtl8187b/r8180_dm.h
+new file mode 100644
+index 0000000..2b7e671
+--- /dev/null
++++ b/drivers/net/wireless/rtl8187b/r8180_dm.h
+@@ -0,0 +1,38 @@
++/*
++ Hardware dynamic mechanism for RTL8187B.
++Notes:
++ This file is ported from RTL8187B Windows driver
++*/
++
++#ifndef R8180_DM_H
++#define R8180_DM_H
++
++#include "r8187.h"
++
++bool CheckDig(struct net_device *dev);
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
++void rtl8180_hw_dig_wq (struct work_struct *work);
++#else
++void rtl8180_hw_dig_wq(struct net_device *dev);
++#endif
++
++bool CheckHighPower(struct net_device *dev);
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
++void rtl8180_tx_pw_wq (struct work_struct *work);
++#else
++void rtl8180_tx_pw_wq(struct net_device *dev);
++#endif
++
++//by lzm for antenna
++#ifdef SW_ANTE_DIVERSITY
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
++void SwAntennaWorkItemCallback(struct work_struct *work);
++#else
++void SwAntennaWorkItemCallback(struct net_device *dev);
++#endif
++void SwAntennaDiversityRxOk8185(struct net_device *dev, u8 SignalStrength);
++void SwAntennaDiversityTimerCallback(struct net_device *dev);
++#endif
++//by lzm for antenna
++
++#endif //R8180_PM_H
+diff --git a/drivers/net/wireless/rtl8187b/r8180_hw.h b/drivers/net/wireless/rtl8187b/r8180_hw.h
+new file mode 100644
+index 0000000..c050fca
+--- /dev/null
++++ b/drivers/net/wireless/rtl8187b/r8180_hw.h
+@@ -0,0 +1,788 @@
++/*
++ This is part of rtl8187 OpenSource driver.
++ Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it>
++ Released under the terms of GPL (General Public Licence)
++
++ Parts of this driver are based on the GPL part of the
++ official Realtek driver.
++ Parts of this driver are based on the rtl8180 driver skeleton
++ from Patric Schenke & Andres Salomon.
++ Parts of this driver are based on the Intel Pro Wireless
++ 2100 GPL driver.
++
++ We want to tanks the Authors of those projects
++ and the Ndiswrapper project Authors.
++*/
++
++/* Mariusz Matuszek added full registers definition with Realtek's name */
++
++/* this file contains register definitions for the rtl8187 MAC controller */
++#ifndef R8180_HW
++#define R8180_HW
++
++typedef enum _RF_TYPE_8187{
++ RF_TYPE_MIN,
++ RF_ZEBRA = 5,
++ RF_ZEBRA2, // added by Annie, 2005-08-01.
++ RF_TYPE_MAX,
++}RF_TYPE_8187,*PRF_TYPE_8187;
++
++typedef enum _VERSION_8187{
++ // RTL8187
++ VERSION_8187_B, // B-cut
++ VERSION_8187_D, // D-cut
++ // RTL8187B
++ VERSION_8187B_B, // B-cut
++ VERSION_8187B_D, //D-cut //added 2007-9-14
++ VERSION_8187B_E, //E-cut //added 2007-9-14
++}VERSION_8187,*PVERSION_8187;
++
++//by lzm for antenna
++#ifdef SW_ANTE_DIVERSITY
++#define RF_PARAM 0x19
++#define RF_PARAM_DIGPHY_SHIFT 0
++#define RF_PARAM_ANTBDEFAULT_SHIFT 1
++#define EEPROM_VERSION 0x3c
++#define EEPROM_CONFIG2 0x18
++#define EEPROM_CS_THRESHOLD 0x2F
++#define EEPROM_RF_PARAM 0x08
++//// BIT[8-9] is for SW Antenna Diversity. Only the value EEPROM_SW_AD_ENABLE means enable, other values are diable.
++#define EEPROM_SW_AD_MASK 0x0300
++#define EEPROM_SW_AD_ENABLE 0x0100
++//// BIT[10-11] determine if Antenna 1 is the Default Antenna. Only the value EEPROM_DEF_ANT_1 means TRUE, other values are FALSE.
++#define EEPROM_DEF_ANT_MASK 0x0C00
++#define EEPROM_DEF_ANT_1 0x0400
++
++#define RCR_EnCS1 BIT29 // enable carrier sense method 1
++#define RCR_EnCS2 BIT30 // enable carrier sense method 2
++#endif
++//by lzm for antenna
++
++#define RTL8187_RF_INDEX 0x8225
++#define RTL8187_REQT_READ 0xc0
++#define RTL8187_REQT_WRITE 0x40
++#define RTL8187_REQ_GET_REGS 0x05
++#define RTL8187_REQ_SET_REGS 0x05
++
++
++
++#define MAX_TX_URB 5
++#define MAX_RX_URB 16
++#define RX_URB_SIZE 0x9C4
++
++
++
++
++
++#define BB_ANTATTEN_CHAN14 0x0c
++#define BB_ANTENNA_B 0x40
++
++#define BB_HOST_BANG (1<<30)
++#define BB_HOST_BANG_EN (1<<2)
++#define BB_HOST_BANG_CLK (1<<1)
++#define BB_HOST_BANG_RW (1<<3)
++#define BB_HOST_BANG_DATA 1
++
++#define ANAPARAM_TXDACOFF_SHIFT 27
++#define ANAPARAM_PWR0_MASK ((1<<30)|(1<<29)|(1<<28))
++#define ANAPARAM_PWR0_SHIFT 28
++#define ANAPARAM_PWR1_MASK ((1<<26)|(1<<25)|(1<<24)|(1<<23)|(1<<22)|(1<<21)|(1<<20))
++#define ANAPARAM_PWR1_SHIFT 20
++
++#define MAC0 0
++#define MAC1 1
++#define MAC2 2
++#define MAC3 3
++#define MAC4 4
++#define MAC5 5
++
++#define RXFIFOCOUNT 0x10
++#define TXFIFOCOUNT 0x12
++#define BcnIntTime 0x74
++#define TALLY_SEL 0xfc
++#define BQREQ 0x13
++
++#define CMD 0x37
++#define CMD_RST_SHIFT 4
++#define CMD_RESERVED_MASK ((1<<1) | (1<<5) | (1<<6) | (1<<7))
++#define CMD_RX_ENABLE_SHIFT 3
++#define CMD_TX_ENABLE_SHIFT 2
++
++#define EPROM_CMD 0x50
++#define EPROM_CMD_RESERVED_MASK ((1<<5)|(1<<4))
++#define EPROM_CMD_OPERATING_MODE_SHIFT 6
++#define EPROM_CMD_OPERATING_MODE_MASK ((1<<7)|(1<<6))
++#define EPROM_CMD_CONFIG 0x3
++#define EPROM_CMD_NORMAL 0
++#define EPROM_CMD_LOAD 1
++#define EPROM_CMD_PROGRAM 2
++#define EPROM_CS_SHIFT 3
++#define EPROM_CK_SHIFT 2
++#define EPROM_W_SHIFT 1
++#define EPROM_R_SHIFT 0
++#define CONFIG2_DMA_POLLING_MODE_SHIFT 3
++#define INTA 0x3e
++#define INTA_TXOVERFLOW (1<<15)
++#define INTA_TIMEOUT (1<<14)
++#define INTA_BEACONTIMEOUT (1<<13)
++#define INTA_ATIM (1<<12)
++#define INTA_BEACONDESCERR (1<<11)
++#define INTA_BEACONDESCOK (1<<10)
++#define INTA_HIPRIORITYDESCERR (1<<9)
++#define INTA_HIPRIORITYDESCOK (1<<8)
++#define INTA_NORMPRIORITYDESCERR (1<<7)
++#define INTA_NORMPRIORITYDESCOK (1<<6)
++#define INTA_RXOVERFLOW (1<<5)
++#define INTA_RXDESCERR (1<<4)
++#define INTA_LOWPRIORITYDESCERR (1<<3)
++#define INTA_LOWPRIORITYDESCOK (1<<2)
++#define INTA_RXCRCERR (1<<1)
++#define INTA_RXOK (1)
++#define INTA_MASK 0x3c
++#define RXRING_ADDR 0xe4 // page 0
++#define PGSELECT 0x5e
++#define PGSELECT_PG_SHIFT 0
++#define RX_CONF 0x44
++#define MAC_FILTER_MASK ((1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<5) | \
++(1<<12) | (1<<18) | (1<<19) | (1<<20) | (1<<21) | (1<<22) | (1<<23))
++#define RX_CHECK_BSSID_SHIFT 23
++#define ACCEPT_PWR_FRAME_SHIFT 22
++#define ACCEPT_MNG_FRAME_SHIFT 20
++#define ACCEPT_CTL_FRAME_SHIFT 19
++#define ACCEPT_DATA_FRAME_SHIFT 18
++#define ACCEPT_ICVERR_FRAME_SHIFT 12
++#define ACCEPT_CRCERR_FRAME_SHIFT 5
++#define ACCEPT_BCAST_FRAME_SHIFT 3
++#define ACCEPT_MCAST_FRAME_SHIFT 2
++#define ACCEPT_ALLMAC_FRAME_SHIFT 0
++#define ACCEPT_NICMAC_FRAME_SHIFT 1
++#define RX_FIFO_THRESHOLD_MASK ((1<<13) | (1<<14) | (1<<15))
++#define RX_FIFO_THRESHOLD_SHIFT 13
++#define RX_FIFO_THRESHOLD_128 3
++#define RX_FIFO_THRESHOLD_256 4
++#define RX_FIFO_THRESHOLD_512 5
++#define RX_FIFO_THRESHOLD_1024 6
++#define RX_FIFO_THRESHOLD_NONE 7
++#define RX_AUTORESETPHY_SHIFT 28
++#define EPROM_TYPE_SHIFT 6
++#define TX_CONF 0x40
++#define TX_CONF_HEADER_AUTOICREMENT_SHIFT 30
++#define TX_LOOPBACK_SHIFT 17
++#define TX_LOOPBACK_MAC 1
++#define TX_LOOPBACK_BASEBAND 2
++#define TX_LOOPBACK_NONE 0
++#define TX_LOOPBACK_CONTINUE 3
++#define TX_LOOPBACK_MASK ((1<<17)|(1<<18))
++#define TX_LRLRETRY_SHIFT 0
++#define R8180_MAX_RETRY 255
++#define TX_SRLRETRY_SHIFT 8
++#define TX_NOICV_SHIFT 19
++#define TX_NOCRC_SHIFT 16
++#define TX_DMA_POLLING 0xd9
++#define TX_DMA_POLLING_BEACON_SHIFT 7
++#define TX_DMA_POLLING_HIPRIORITY_SHIFT 6
++#define TX_DMA_POLLING_NORMPRIORITY_SHIFT 5
++#define TX_DMA_POLLING_LOWPRIORITY_SHIFT 4
++#define TX_DMA_STOP_BEACON_SHIFT 3
++#define TX_DMA_STOP_HIPRIORITY_SHIFT 2
++#define TX_DMA_STOP_NORMPRIORITY_SHIFT 1
++#define TX_DMA_STOP_LOWPRIORITY_SHIFT 0
++#define TX_NORMPRIORITY_RING_ADDR 0x24
++#define TX_HIGHPRIORITY_RING_ADDR 0x28
++#define TX_LOWPRIORITY_RING_ADDR 0x20
++#define MAX_RX_DMA_MASK ((1<<8) | (1<<9) | (1<<10))
++#define MAX_RX_DMA_2048 7
++#define MAX_RX_DMA_1024 6
++#define MAX_RX_DMA_SHIFT 10
++#define INT_TIMEOUT 0x48
++#define CONFIG3_CLKRUN_SHIFT 2
++#define CONFIG3_ANAPARAM_W_SHIFT 6
++#define ANAPARAM 0x54
++#define BEACON_INTERVAL 0x70
++#define BEACON_INTERVAL_MASK ((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)| \
++(1<<6)|(1<<7)|(1<<8)|(1<<9))
++#define ATIM_MASK ((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7)| \
++(1<<8)|(1<<9))
++#define ATIM 0x72
++#define EPROM_CS_SHIFT 3
++#define EPROM_CK_SHIFT 2
++#define PHY_DELAY 0x78
++#define PHY_CONFIG 0x80
++#define PHY_ADR 0x7c
++#define PHY_READ 0x7e
++#define CARRIER_SENSE_COUNTER 0x79 //byte
++#define SECURITY 0x5f
++#define SECURITY_WEP_TX_ENABLE_SHIFT 1
++#define SECURITY_WEP_RX_ENABLE_SHIFT 0
++#define SECURITY_ENCRYP_104 1
++#define SECURITY_ENCRYP_SHIFT 4
++#define SECURITY_ENCRYP_MASK ((1<<4)|(1<<5))
++#define KEY0 0x90
++#define CONFIG2_ANTENNA_SHIFT 6
++#define TX_BEACON_RING_ADDR 0x4c
++#define CONFIG0_WEP40_SHIFT 7
++#define CONFIG0_WEP104_SHIFT 6
++#define AGCRESET_SHIFT 5
++
++
++
++/*
++ * Operational registers offsets in PCI (I/O) space.
++ * RealTek names are used.
++ */
++
++#define IDR0 0x0000
++#define IDR1 0x0001
++#define IDR2 0x0002
++#define IDR3 0x0003
++#define IDR4 0x0004
++#define IDR5 0x0005
++
++/* 0x0006 - 0x0007 - reserved */
++
++#define MAR0 0x0008
++#define MAR1 0x0009
++#define MAR2 0x000A
++#define MAR3 0x000B
++#define MAR4 0x000C
++#define MAR5 0x000D
++#define MAR6 0x000E
++#define MAR7 0x000F
++
++/* 0x0010 - 0x0017 - reserved */
++
++#define TSFTR 0x0018
++#define TSFTR_END 0x001F
++
++#define TLPDA 0x0020
++#define TLPDA_END 0x0023
++#define TNPDA 0x0024
++#define TNPDA_END 0x0027
++#define THPDA 0x0028
++#define THPDA_END 0x002B
++
++#define BRSR_8187 0x002C
++#define BRSR_8187_END 0x002D
++#define BRSR_8187B 0x0034
++#define BRSR_8187B_END 0x0035
++
++#define BSSID 0x002E
++#define BSSID_END 0x0033
++
++/* 0x0034 - 0x0034 - reserved */
++
++/* 0x0038 - 0x003B - reserved */
++
++#define IMR 0x003C
++#define IMR_END 0x003D
++
++#define ISR 0x003E
++#define ISR_END 0x003F
++
++#define TCR 0x0040
++#define TCR_END 0x0043
++
++#define RCR 0x0044
++#define RCR_END 0x0047
++
++#define TimerInt 0x0048
++#define TimerInt_END 0x004B
++
++#define TBDA 0x004C
++#define TBDA_END 0x004F
++
++#define CR9346 0x0050
++
++#define CONFIG0 0x0051
++#define CONFIG1 0x0052
++#define CONFIG2 0x0053
++
++#define ANA_PARAM 0x0054
++#define ANA_PARAM_END 0x0x0057
++
++#define MSR 0x0058
++
++#define CONFIG3 0x0059
++#define CONFIG4 0x005A
++
++#define TESTR 0x005B
++
++/* 0x005C - 0x005D - reserved */
++#define TFPC_AC 0x005C
++#define PSR 0x005E
++
++#define SCR 0x005F
++
++/* 0x0060 - 0x006F - reserved */
++#define ANA_PARAM2 0x0060
++#define ANA_PARAM2_END 0x0063
++
++#define BcnIntv 0x0070
++#define BcnItv_END 0x0071
++
++#define AtimWnd 0x0072
++#define AtimWnd_END 0x0073
++
++#define BintrItv 0x0074
++#define BintrItv_END 0x0075
++
++#define AtimtrItv 0x0076
++#define AtimtrItv_END 0x0077
++
++#define PhyDelay 0x0078
++
++//#define CRCount 0x0079
++
++#define AckTimeOutReg 0x79 // ACK timeout register, in unit of 4 us.
++/* 0x007A - 0x007B - reserved */
++#define BBAddr 0x007C
++
++
++#define PhyAddr 0x007C
++#define PhyDataW 0x007D
++#define PhyDataR 0x007E
++#define RF_Ready 0x007F
++
++#define PhyCFG 0x0080
++#define PhyCFG_END 0x0083
++
++/* following are for rtl8185 */
++#define RFPinsOutput 0x80
++#define RFPinsEnable 0x82
++#define RF_TIMING 0x8c
++#define RFPinsSelect 0x84
++#define ANAPARAM2 0x60
++#define RF_PARA 0x88
++#define RFPinsInput 0x86
++#define GP_ENABLE 0x90
++#define GPIO 0x91
++#define HSSI_PARA 0x94 // HSS Parameter
++#define SW_CONTROL_GPIO 0x400
++#define CCK_TXAGC 0x9d
++#define OFDM_TXAGC 0x9e
++#define ANTSEL 0x9f
++#define TXAGC_CTL_PER_PACKET_ANT_SEL 0x02
++#define WPA_CONFIG 0xb0
++#define TX_AGC_CTL 0x9c
++#define TX_AGC_CTL_PER_PACKET_TXAGC 0x01
++#define TX_AGC_CTL_PERPACKET_GAIN_SHIFT 0
++#define TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT 1
++#define TX_AGC_CTL_FEEDBACK_ANT 2
++#define RESP_RATE 0x34
++#define SIFS 0xb4
++#define DIFS 0xb5
++#define EIFS_8187 0x35
++#define EIFS_8187B 0x2D
++#define SLOT 0xb6
++#define CW_VAL 0xbd
++#define CW_CONF 0xbc
++#define CW_CONF_PERPACKET_RETRY_LIMIT 0x02
++#define CW_CONF_PERPACKET_CW 0x01
++#define CW_CONF_PERPACKET_RETRY_SHIFT 1
++#define CW_CONF_PERPACKET_CW_SHIFT 0
++#define MAX_RESP_RATE_SHIFT 4
++#define MIN_RESP_RATE_SHIFT 0
++#define RATE_FALLBACK 0xbe
++#define RATE_FALLBACK_CTL_ENABLE 0x80
++#define RATE_FALLBACK_CTL_AUTO_STEP0 0x00
++
++#define ARFR 0x1E0 // Auto Rate Fallback Register (0x1e0 ~ 0x1e2)
++#define RMS 0x1EC // Rx Max Pacetk Size (0x1ec[0:12])
++
++/*
++ * 0x0084 - 0x00D3 is selected to page 1 when PSEn bit (bit0, PSR)
++ * is set to 1
++ */
++
++#define Wakeup0 0x0084
++#define Wakeup0_END 0x008B
++
++#define Wakeup1 0x008C
++#define Wakeup1_END 0x0093
++
++#define Wakeup2LD 0x0094
++#define Wakeup2LD_END 0x009B
++#define Wakeup2HD 0x009C
++#define Wakeup2HD_END 0x00A3
++
++#define Wakeup3LD 0x00A4
++#define Wakeup3LD_END 0x00AB
++#define Wakeup3HD 0x00AC
++#define Wakeup3HD_END 0x00B3
++
++#define Wakeup4LD 0x00B4
++#define Wakeup4LD_END 0x00BB
++#define Wakeup4HD 0x00BC
++#define Wakeup4HD_END 0x00C3
++
++#define CRC0 0x00C4
++#define CRC0_END 0x00C5
++#define CRC1 0x00C6
++#define CRC1_END 0x00C7
++#define CRC2 0x00C8
++#define CRC2_END 0x00C9
++#define CRC3 0x00CA
++#define CRC3_END 0x00CB
++#define CRC4 0x00CC
++#define CRC4_END 0x00CD
++
++/* 0x00CE - 0x00D3 - reserved */
++
++
++
++/*
++ * 0x0084 - 0x00D3 is selected to page 0 when PSEn bit (bit0, PSR)
++ * is set to 0
++ */
++
++/* 0x0084 - 0x008F - reserved */
++
++#define DK0 0x0090
++#define DK0_END 0x009F
++#define DK1 0x00A0
++#define DK1_END 0x00AF
++#define DK2 0x00B0
++#define DK2_END 0x00BF
++#define DK3 0x00C0
++#define DK3_END 0x00CF
++
++#define GPO 0x90
++#define GPE 0x91
++#define GPI 0x92
++
++#define RFTiming 0x008C
++#define ACM_CONTROL 0x00BF // ACM Control Registe
++#define INT_MIG 0x00E2 // Interrupt Migration (0xE2 ~ 0xE3)
++#define TID_AC_MAP 0x00E8 // TID to AC Mapping Register
++
++#define AC_VO_PARAM 0x00F0 // AC_VO Parameters Record
++#define AC_VI_PARAM 0x00F4 // AC_VI Parameters Record
++#define AC_BE_PARAM 0x00F8 // AC_BE Parameters Record
++#define AC_BK_PARAM 0x00FC // AC_BK Parameters Record
++
++/* 0x00D0 - 0x00D3 - reserved */
++#define CCK_FALSE_ALARM 0x00D0
++#define OFDM_FALSE_ALARM 0x00D2
++
++
++/* 0x00D4 - 0x00D7 - reserved */
++
++#define CONFIG5 0x00D8
++
++#define TPPoll 0x00D9
++
++/* 0x00DA - 0x00DB - reserved */
++
++#define CWR 0x00DC
++#define CWR_END 0x00DD
++
++#define RetryCTR 0x00DE
++
++/* 0x00DF - 0x00E3 - reserved */
++
++#define RDSAR 0x00E4
++#define RDSAR_END 0x00E7
++
++/* 0x00E8 - 0x00EF - reserved */
++#define ANA_PARAM3 0x00EE
++
++#define FER 0x00F0
++#define FER_END 0x00F3
++
++#define FEMR 0x1D4 // Function Event Mask register (0xf4 ~ 0xf7)
++//#define FEMR 0x00F4
++#define FEMR_END 0x00F7
++
++#define FPSR 0x00F8
++#define FPSR_END 0x00FB
++
++#define FFER 0x00FC
++#define FFER_END 0x00FF
++
++/*
++ * 0x0000 - 0x00ff is selected to page 0 when PSEn bit (bit0, PSR)
++ * is set to 2
++ */
++#define RFSW_CTRL 0x272 // 0x272-0x273.
++
++
++
++//----------------------------------------------------------------------------
++// 8187B AC_XX_PARAM bits
++//----------------------------------------------------------------------------
++#define AC_PARAM_TXOP_LIMIT_OFFSET 16
++#define AC_PARAM_ECW_MAX_OFFSET 12
++#define AC_PARAM_ECW_MIN_OFFSET 8
++#define AC_PARAM_AIFS_OFFSET 0
++
++//----------------------------------------------------------------------------
++// 8187B ACM_CONTROL bits (Offset 0xBF, 1 Byte)
++//----------------------------------------------------------------------------
++#define VOQ_ACM_EN (0x01 << 7) //BIT7
++#define VIQ_ACM_EN (0x01 << 6) //BIT6
++#define BEQ_ACM_EN (0x01 << 5) //BIT5
++#define ACM_HW_EN (0x01 << 4) //BIT4
++#define TXOPSEL (0x01 << 3) //BIT3
++#define VOQ_ACM_CTL (0x01 << 2) //BIT2 // Set to 1 when AC_VO used time reaches or exceeds the admitted time
++#define VIQ_ACM_CTL (0x01 << 1) //BIT1 // Set to 1 when AC_VI used time reaches or exceeds the admitted time
++#define BEQ_ACM_CTL (0x01 << 0) //BIT0 // Set to 1 when AC_BE used time reaches or exceeds the admitted time
++
++//----------------------------------------------------------------------------
++// 8187B RF pins related setting (offset 0xFF80-0xFF87,)
++//----------------------------------------------------------------------------
++#define TR_SW_MASK_TX_8187 BIT5
++#define TR_SW_MASK_RX_8187 BIT6
++#define TR_SW_MASK_8187 (TR_SW_MASK_TX_8187 | TR_SW_MASK_RX_8187)
++
++/*
++ * Bitmasks for specific register functions.
++ * Names are derived from the register name and function name.
++ *
++ * <REGISTER>_<FUNCTION>[<bit>]
++ *
++ * this leads to some awkward names...
++ */
++
++#define BRSR_BPLCP ((1<< 8))
++#define BRSR_MBR ((1<< 1)|(1<< 0))
++#define BRSR_MBR_8185 ((1<< 11)|(1<< 10)|(1<< 9)|(1<< 8)|(1<< 7)|(1<< 6)|(1<< 5)|(1<< 4)|(1<< 3)|(1<< 2)|(1<< 1)|(1<< 0))
++#define BRSR_MBR0 ((1<< 0))
++#define BRSR_MBR1 ((1<< 1))
++
++#define CR_RST ((1<< 4))
++#define CR_RE ((1<< 3))
++#define CR_TE ((1<< 2))
++#define CR_MulRW ((1<< 0))
++
++#define IMR_TXFOVW ((1<<15))
++#define IMR_TimeOut ((1<<14))
++#define IMR_BcnInt ((1<<13))
++#define IMR_ATIMInt ((1<<12))
++#define IMR_TBDER ((1<<11))
++#define IMR_TBDOK ((1<<10))
++#define IMR_THPDER ((1<< 9))
++#define IMR_THPDOK ((1<< 8))
++#define IMR_TNPDER ((1<< 7))
++#define IMR_TNPDOK ((1<< 6))
++#define IMR_RXFOVW ((1<< 5))
++#define IMR_RDU ((1<< 4))
++#define IMR_TLPDER ((1<< 3))
++#define IMR_TLPDOK ((1<< 2))
++#define IMR_RER ((1<< 1))
++#define IMR_ROK ((1<< 0))
++
++#define ISR_TXFOVW ((1<<15))
++#define ISR_TimeOut ((1<<14))
++#define ISR_BcnInt ((1<<13))
++#define ISR_ATIMInt ((1<<12))
++#define ISR_TBDER ((1<<11))
++#define ISR_TBDOK ((1<<10))
++#define ISR_THPDER ((1<< 9))
++#define ISR_THPDOK ((1<< 8))
++#define ISR_TNPDER ((1<< 7))
++#define ISR_TNPDOK ((1<< 6))
++#define ISR_RXFOVW ((1<< 5))
++#define ISR_RDU ((1<< 4))
++#define ISR_TLPDER ((1<< 3))
++#define ISR_TLPDOK ((1<< 2))
++#define ISR_RER ((1<< 1))
++#define ISR_ROK ((1<< 0))
++
++#define HW_VERID_R8180_F 3
++#define HW_VERID_R8180_ABCD 2
++#define HW_VERID_R8185_ABC 4
++#define HW_VERID_R8185_D 5
++
++#define TCR_DurProcMode ((1<<30))
++#define TCR_DISReqQsize ((1<<28))
++#define TCR_HWVERID_MASK ((1<<27)|(1<<26)|(1<<25))
++#define TCR_HWVERID_SHIFT 25
++#define TCR_SWPLCPLEN ((1<<24))
++#define TCR_PLCP_LEN TCR_SAT // rtl8180
++#define TCR_MXDMA_MASK ((1<<23)|(1<<22)|(1<<21))
++#define TCR_MXDMA_1024 6
++#define TCR_MXDMA_2048 7
++#define TCR_MXDMA_SHIFT 21
++#define TCR_DISCW ((1<<20))
++#define TCR_ICV ((1<<19))
++#define TCR_LBK ((1<<18)|(1<<17))
++#define TCR_LBK1 ((1<<18))
++#define TCR_LBK0 ((1<<17))
++#define TCR_CRC ((1<<16))
++#define TCR_SRL_MASK ((1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9)|(1<<8))
++#define TCR_LRL_MASK ((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7))
++#define TCR_PROBE_NOTIMESTAMP_SHIFT 29 //rtl8185
++
++#define RCR_ONLYERLPKT ((1<<31))
++#define RCR_CS_SHIFT 29
++#define RCR_CS_MASK ((1<<30) | (1<<29))
++#define RCR_ENMARP ((1<<28))
++#define RCR_CBSSID ((1<<23))
++#define RCR_APWRMGT ((1<<22))
++#define RCR_ADD3 ((1<<21))
++#define RCR_AMF ((1<<20))
++#define RCR_ACF ((1<<19))
++#define RCR_ADF ((1<<18))
++#define RCR_RXFTH ((1<<15)|(1<<14)|(1<<13))
++#define RCR_RXFTH2 ((1<<15))
++#define RCR_RXFTH1 ((1<<14))
++#define RCR_RXFTH0 ((1<<13))
++#define RCR_AICV ((1<<12))
++#define RCR_MXDMA ((1<<10)|(1<< 9)|(1<< 8))
++#define RCR_MXDMA2 ((1<<10))
++#define RCR_MXDMA1 ((1<< 9))
++#define RCR_MXDMA0 ((1<< 8))
++#define RCR_9356SEL ((1<< 6))
++#define RCR_ACRC32 ((1<< 5))
++#define RCR_AB ((1<< 3))
++#define RCR_AM ((1<< 2))
++#define RCR_APM ((1<< 1))
++#define RCR_AAP ((1<< 0))
++
++#define CR9346_EEM ((1<<7)|(1<<6))
++#define CR9346_EEM1 ((1<<7))
++#define CR9346_EEM0 ((1<<6))
++#define CR9346_EECS ((1<<3))
++#define CR9346_EESK ((1<<2))
++#define CR9346_EED1 ((1<<1))
++#define CR9346_EED0 ((1<<0))
++
++#define CONFIG0_WEP104 ((1<<6))
++#define CONFIG0_LEDGPO_En ((1<<4))
++#define CONFIG0_Aux_Status ((1<<3))
++#define CONFIG0_GL ((1<<1)|(1<<0))
++#define CONFIG0_GL1 ((1<<1))
++#define CONFIG0_GL0 ((1<<0))
++
++#define CONFIG1_LEDS ((1<<7)|(1<<6))
++#define CONFIG1_LEDS1 ((1<<7))
++#define CONFIG1_LEDS0 ((1<<6))
++#define CONFIG1_LWACT ((1<<4))
++#define CONFIG1_MEMMAP ((1<<3))
++#define CONFIG1_IOMAP ((1<<2))
++#define CONFIG1_VPD ((1<<1))
++#define CONFIG1_PMEn ((1<<0))
++
++#define CONFIG2_LCK ((1<<7))
++#define CONFIG2_ANT ((1<<6))
++#define CONFIG2_DPS ((1<<3))
++#define CONFIG2_PAPE_sign ((1<<2))
++#define CONFIG2_PAPE_time ((1<<1)|(1<<0))
++#define CONFIG2_PAPE_time1 ((1<<1))
++#define CONFIG2_PAPE_time0 ((1<<0))
++
++#define CONFIG3_GNTSel ((1<<7))
++#define CONFIG3_PARM_En ((1<<6))
++#define CONFIG3_Magic ((1<<5))
++#define CONFIG3_CardB_En ((1<<3))
++#define CONFIG3_CLKRUN_En ((1<<2))
++#define CONFIG3_FuncRegEn ((1<<1))
++#define CONFIG3_FBtbEn ((1<<0))
++
++#define CONFIG4_VCOPDN ((1<<7))
++#define CONFIG4_PWROFF ((1<<6))
++#define CONFIG4_PWRMGT ((1<<5))
++#define CONFIG4_LWPME ((1<<4))
++#define CONFIG4_LWPTN ((1<<2))
++#define CONFIG4_RFTYPE ((1<<1)|(1<<0))
++#define CONFIG4_RFTYPE1 ((1<<1))
++#define CONFIG4_RFTYPE0 ((1<<0))
++
++#define CONFIG5_TX_FIFO_OK ((1<<7))
++#define CONFIG5_RX_FIFO_OK ((1<<6))
++#define CONFIG5_CALON ((1<<5))
++#define CONFIG5_EACPI ((1<<2))
++#define CONFIG5_LANWake ((1<<1))
++#define CONFIG5_PME_STS ((1<<0))
++
++#define MSR_LINK_MASK ((1<<2)|(1<<3))
++#define MSR_LINK_MANAGED 2
++#define MSR_LINK_NONE 0
++#define MSR_LINK_SHIFT 2
++#define MSR_LINK_ADHOC 1
++#define MSR_LINK_MASTER 3
++#define MSR_LINK_ENEDCA (1<<4)
++
++#define PSR_GPO ((1<<7))
++#define PSR_GPI ((1<<6))
++#define PSR_LEDGPO1 ((1<<5))
++#define PSR_LEDGPO0 ((1<<4))
++#define PSR_UWF ((1<<1))
++#define PSR_PSEn ((1<<0))
++
++#define SCR_KM ((1<<5)|(1<<4))
++#define SCR_KM1 ((1<<5))
++#define SCR_KM0 ((1<<4))
++#define SCR_TXSECON ((1<<1))
++#define SCR_RXSECON ((1<<0))
++
++#define BcnItv_BcnItv (0x01FF)
++
++#define AtimWnd_AtimWnd (0x01FF)
++
++#define BintrItv_BintrItv (0x01FF)
++
++#define AtimtrItv_AtimtrItv (0x01FF)
++
++#define PhyDelay_PhyDelay ((1<<2)|(1<<1)|(1<<0))
++
++#define TPPoll_BQ ((1<<7))
++#define TPPoll_HPQ ((1<<6))
++#define TPPoll_NPQ ((1<<5))
++#define TPPoll_LPQ ((1<<4))
++#define TPPoll_SBQ ((1<<3))
++#define TPPoll_SHPQ ((1<<2))
++#define TPPoll_SNPQ ((1<<1))
++#define TPPoll_SLPQ ((1<<0))
++
++#define CWR_CW (0x01FF)
++
++#define FER_INTR ((1<<15))
++#define FER_GWAKE ((1<< 4))
++
++#define FEMR_INTR ((1<<15))
++#define FEMR_WKUP ((1<<14))
++#define FEMR_GWAKE ((1<< 4))
++
++#define FPSR_INTR ((1<<15))
++#define FPSR_GWAKE ((1<< 4))
++
++#define FFER_INTR ((1<<15))
++#define FFER_GWAKE ((1<< 4))
++
++
++//----------------------------------------------------------------------------
++// 818xB AnaParm & AnaParm2 Register
++//----------------------------------------------------------------------------
++/*
++#ifdef RTL8185B_FPGA
++#define ANAPARM_FPGA_ON 0xa0000b59
++//#define ANAPARM_FPGA_OFF
++#define ANAPARM2_FPGA_ON 0x860dec11
++//#define ANAPARM2_FPGA_OFF
++#else //ASIC
++*/
++#define ANAPARM_ASIC_ON 0x45090658
++//#define ANAPARM_ASIC_OFF
++#define ANAPARM2_ASIC_ON 0x727f3f52
++//#define ANAPARM2_ASIC_OFF
++//#endif
++//by amy for power save
++#define RF_CHANGE_BY_SW BIT31
++#define RF_CHANGE_BY_HW BIT30
++#define RF_CHANGE_BY_PS BIT29
++#define RF_CHANGE_BY_IPS BIT28
++#define ANAPARM_ASIC_ON 0x45090658
++#define ANAPARM2_ASIC_ON 0x727f3f52
++
++#define ANAPARM_ON ANAPARM_ASIC_ON
++#define ANAPARM2_ON ANAPARM2_ASIC_ON
++#define TFPC 0x5C // Tx FIFO Packet Count for BK, BE, VI, VO queues (2 bytes)
++#define Config4_PowerOff BIT6 // Turn ON/Off RF Power(RFMD)
++#define ANAPARM_OFF 0x51480658
++#define ANAPARM2_OFF 0x72003f70
++//by amy for power save
++
++#define MAX_DOZE_WAITING_TIMES_87B 500
++
++#endif
+diff --git a/drivers/net/wireless/rtl8187b/r8180_pm.c b/drivers/net/wireless/rtl8187b/r8180_pm.c
+new file mode 100644
+index 0000000..90a0bd9
+--- /dev/null
++++ b/drivers/net/wireless/rtl8187b/r8180_pm.c
+@@ -0,0 +1,97 @@
++/*
++ Power management interface routines.
++ Written by Mariusz Matuszek.
++ This code is currently just a placeholder for later work and
++ does not do anything useful.
++
++ This is part of rtl8180 OpenSource driver.
++ Copyright (C) Andrea Merello 2004 <andreamrl@tiscali.it>
++ Released under the terms of GPL (General Public Licence)
++*/
++
++#ifdef CONFIG_RTL8180_PM
++
++
++#include "r8180_hw.h"
++#include "r8180_pm.h"
++#include "r8187.h"
++int rtl8180_save_state (struct pci_dev *dev, u32 state)
++{
++ printk(KERN_NOTICE "r8180 save state call (state %u).\n", state);
++ return(-EAGAIN);
++}
++
++//netif_running is set to 0 before system call rtl8180_close,
++//netif_running is set to 1 before system call rtl8180_open,
++//if open success it will not change, or it change to 0;
++int rtl8187_suspend (struct usb_interface *intf, pm_message_t state)
++{
++ struct r8180_priv *priv;
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
++ struct net_device *dev = usb_get_intfdata(intf);
++#else
++ //struct net_device *dev = (struct net_device *)ptr;
++#endif
++
++ printk("====>%s \n", __func__);
++ priv=ieee80211_priv(dev);
++
++ if(dev) {
++ /* save the old rfkill state and then power off it */
++ priv->eInactivePowerState = priv->eRFPowerState;
++ /* power off the wifi by default */
++ r8187b_wifi_change_rfkill_state(dev, eRfOff);
++
++ if (!netif_running(dev)) {
++ //printk(KERN_WARNING "UI or other close dev before suspend, go out suspend function\n");
++ return 0;
++ }
++
++ dev->netdev_ops->ndo_stop(dev);
++ netif_device_detach(dev);
++ }
++ return 0;
++}
++
++
++int rtl8187_resume (struct usb_interface *intf)
++{
++ struct r8180_priv *priv;
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
++ struct net_device *dev = usb_get_intfdata(intf);
++#else
++ //struct net_device *dev = (struct net_device *)ptr;
++#endif
++
++ printk("====>%s \n", __func__);
++ priv=ieee80211_priv(dev);
++
++ if(dev) {
++ /* resume the old rfkill state */
++ r8187b_wifi_change_rfkill_state(dev, priv->eInactivePowerState);
++
++ if (!netif_running(dev)){
++ //printk(KERN_WARNING "UI or other close dev before suspend, go out resume function\n");
++ return 0;
++ }
++
++ netif_device_attach(dev);
++ dev->netdev_ops->ndo_open(dev);
++ }
++
++ return 0;
++}
++
++
++int rtl8180_enable_wake (struct pci_dev *dev, u32 state, int enable)
++{
++
++ //printk(KERN_NOTICE "r8180 enable wake call (state %u, enable %d).\n",
++ // state, enable);
++ return 0;
++ //return(-EAGAIN);
++}
++
++
++
++#endif //CONFIG_RTL8180_PM
+diff --git a/drivers/net/wireless/rtl8187b/r8180_pm.h b/drivers/net/wireless/rtl8187b/r8180_pm.h
+new file mode 100644
+index 0000000..efcba1d
+--- /dev/null
++++ b/drivers/net/wireless/rtl8187b/r8180_pm.h
+@@ -0,0 +1,28 @@
++/*
++ Power management interface routines.
++ Written by Mariusz Matuszek.
++ This code is currently just a placeholder for later work and
++ does not do anything useful.
++
++ This is part of rtl8180 OpenSource driver.
++ Copyright (C) Andrea Merello 2004 <andreamrl@tiscali.it>
++ Released under the terms of GPL (General Public Licence)
++
++*/
++
++#ifdef CONFIG_RTL8180_PM
++
++#ifndef R8180_PM_H
++#define R8180_PM_H
++
++#include <linux/types.h>
++#include <linux/usb.h>
++
++int rtl8180_save_state (struct pci_dev *dev, u32 state);
++int rtl8187_suspend (struct usb_interface *intf,pm_message_t state);
++int rtl8187_resume (struct usb_interface *intf);
++int rtl8180_enable_wake (struct pci_dev *dev, u32 state, int enable);
++
++#endif //R8180_PM_H
++
++#endif // CONFIG_RTL8180_PM
+diff --git a/drivers/net/wireless/rtl8187b/r8180_rtl8225.c b/drivers/net/wireless/rtl8187b/r8180_rtl8225.c
+new file mode 100644
+index 0000000..e53d4cd
+--- /dev/null
++++ b/drivers/net/wireless/rtl8187b/r8180_rtl8225.c
+@@ -0,0 +1,1007 @@
++/*
++ This is part of the rtl8180-sa2400 driver
++ released under the GPL (See file COPYING for details).
++ Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
++
++ This files contains programming code for the rtl8225
++ radio frontend.
++
++ *Many* thanks to Realtek Corp. for their great support!
++
++*/
++
++
++
++#include "r8180_hw.h"
++#include "r8180_rtl8225.h"
++#ifdef ENABLE_DOT11D
++#include "dot11d.h"
++#endif
++
++#define USE_8051_3WIRE 1
++
++u8 rtl8225_threshold[]={
++ 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd,
++};
++
++u8 rtl8225_gain[]={
++ 0x23,0x88,0x7c,0xa5,// -82dbm
++ 0x23,0x88,0x7c,0xb5,// -82dbm
++ 0x23,0x88,0x7c,0xc5,// -82dbm
++ 0x33,0x80,0x79,0xc5,// -78dbm
++ 0x43,0x78,0x76,0xc5,// -74dbm
++ 0x53,0x60,0x73,0xc5,// -70dbm
++ 0x63,0x58,0x70,0xc5,// -66dbm
++};
++
++u16 rtl8225bcd_rxgain[]={
++ 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
++ 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
++ 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
++ 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
++ 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
++ 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
++ 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
++ 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
++ 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
++ 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
++ 0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3,
++ 0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb
++
++};
++
++
++
++u8 rtl8225_tx_gain_cck_ofdm[]={
++ 0x02,0x06,0x0e,0x1e,0x3e,0x7e
++};
++
++
++u8 rtl8225_tx_power_ofdm[]={
++ 0x80,0x90,0xa2,0xb5,0xcb,0xe4
++};
++
++
++u8 rtl8225_tx_power_cck_ch14[]={
++ 0x18,0x17,0x15,0x0c,0x00,0x00,0x00,0x00,
++ 0x1b,0x1a,0x17,0x0e,0x00,0x00,0x00,0x00,
++ 0x1f,0x1e,0x1a,0x0f,0x00,0x00,0x00,0x00,
++ 0x22,0x21,0x1d,0x11,0x00,0x00,0x00,0x00,
++ 0x26,0x25,0x21,0x13,0x00,0x00,0x00,0x00,
++ 0x2b,0x2a,0x25,0x15,0x00,0x00,0x00,0x00
++};
++
++
++u8 rtl8225_tx_power_cck[]={
++ 0x18,0x17,0x15,0x11,0x0c,0x08,0x04,0x02,
++ 0x1b,0x1a,0x17,0x13,0x0e,0x09,0x04,0x02,
++ 0x1f,0x1e,0x1a,0x15,0x10,0x0a,0x05,0x02,
++ 0x22,0x21,0x1d,0x18,0x11,0x0b,0x06,0x02,
++ 0x26,0x25,0x21,0x1b,0x14,0x0d,0x06,0x03,
++ 0x2b,0x2a,0x25,0x1e,0x16,0x0e,0x07,0x03
++};
++
++u8 rtl8225_agc[]={
++ 0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9d,0x9c,0x9b,0x9a,0x99,0x98,0x97,0x96,
++ 0x95,0x94,0x93,0x92,0x91,0x90,0x8f,0x8e,0x8d,0x8c,0x8b,0x8a,0x89,0x88,0x87,0x86,
++ 0x85,0x84,0x83,0x82,0x81,0x80,0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38,0x37,0x36,
++ 0x35,0x34,0x33,0x32,0x31,0x30,0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28,0x27,0x26,
++ 0x25,0x24,0x23,0x22,0x21,0x20,0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18,0x17,0x16,
++ 0x15,0x14,0x13,0x12,0x11,0x10,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06,
++ 0x05,0x04,0x03,0x02,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
++ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
++};
++
++u32 rtl8225_chan[] = {
++ 0, //dummy channel 0
++ 0x085c, //1
++ 0x08dc, //2
++ 0x095c, //3
++ 0x09dc, //4
++ 0x0a5c, //5
++ 0x0adc, //6
++ 0x0b5c, //7
++ 0x0bdc, //8
++ 0x0c5c, //9
++ 0x0cdc, //10
++ 0x0d5c, //11
++ 0x0ddc, //12
++ 0x0e5c, //13
++ //0x0f5c, //14
++ 0x0f72, // 14
++};
++
++void rtl8225_set_gain(struct net_device *dev, short gain)
++{
++ write_phy_ofdm(dev, 0x0d, rtl8225_gain[gain * 4]);
++ write_phy_ofdm(dev, 0x1b, rtl8225_gain[gain * 4 + 2]);
++ write_phy_ofdm(dev, 0x1d, rtl8225_gain[gain * 4 + 3]);
++ write_phy_ofdm(dev, 0x23, rtl8225_gain[gain * 4 + 1]);
++
++}
++
++
++void write_rtl8225(struct net_device *dev, u8 adr, u16 data)
++{
++//in windows the delays in this function was del from 85 to 87,
++//here we mod to sleep, or The CPU occupany is too hight. LZM 31/10/2008
++
++#ifdef USE_8051_3WIRE
++
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ struct usb_device *udev = priv->udev;
++ //u8 bit;
++ //u16 wReg80, wReg82, wReg84;
++ u16 wReg80, wReg84;
++
++ wReg80 = read_nic_word(dev, RFPinsOutput);
++ wReg80 &= 0xfff3;
++// wReg82 = read_nic_word(dev, RFPinsEnable);
++ wReg84 = read_nic_word(dev, RFPinsSelect);
++ // <RJ_NOTE> 3-wire should be controled by HW when we finish SW 3-wire programming. 2005.08.10, by rcnjko.
++ //wReg84 &= 0xfff0;
++ wReg84 &= 0xfff8; //modified by david according to windows segment code.
++
++ // We must set SW enabled before terminating HW 3-wire, 2005.07.29, by rcnjko.
++// write_nic_word(dev, RFPinsEnable, (wReg82|0x0007)); // Set To Output Enable
++ write_nic_word(dev, RFPinsSelect, (wReg84|0x0007)); // Set To SW Switch
++// force_pci_posting(dev);
++// udelay(10); //
++
++ write_nic_word(dev, 0x80, (BB_HOST_BANG_EN|wReg80)); // Set SI_EN (RFLE)
++// force_pci_posting(dev);
++// udelay(2);
++ //twreg.struc.enableB = 0;
++ write_nic_word(dev, 0x80, (wReg80)); // Clear SI_EN (RFLE)
++// force_pci_posting(dev);
++// udelay(10);
++
++ usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
++ RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
++ adr, 0x8225, &data, 2, HZ / 2);
++
++ // write_nic_word(dev, 0x80, (BB_HOST_BANG_EN|wReg80));
++// force_pci_posting(dev);
++// udelay(10);
++
++ write_nic_word(dev, 0x80, (wReg80|0x0004));
++ write_nic_word(dev, 0x84, (wReg84|0x0000));// Set To SW Switch
++
++ if(priv->card_type == USB)
++ ;// msleep(2);
++ else
++ ; // rtl8185_rf_pins_enable(dev);
++
++#else
++ int i;
++ u16 out,select;
++ u8 bit;
++ u32 bangdata = (data << 4) | (adr & 0xf);
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ out = read_nic_word(dev, RFPinsOutput) & 0xfff3;
++
++ write_nic_word(dev,RFPinsEnable,
++ (read_nic_word(dev,RFPinsEnable) | 0x7));
++
++ select = read_nic_word(dev, RFPinsSelect);
++
++ write_nic_word(dev, RFPinsSelect, select | 0x7 |
++ ((priv->card_type == USB) ? 0 : SW_CONTROL_GPIO));
++
++// force_pci_posting(dev);
++// udelay(10);
++
++ write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN );//| 0x1fff);
++
++// force_pci_posting(dev);
++// udelay(2);
++
++ write_nic_word(dev, RFPinsOutput, out);
++
++// force_pci_posting(dev);
++// udelay(10);
++
++
++ for(i=15; i>=0;i--){
++
++ bit = (bangdata & (1<<i)) >> i;
++
++ write_nic_word(dev, RFPinsOutput, bit | out);
++
++ write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
++ write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
++
++ i--;
++ bit = (bangdata & (1<<i)) >> i;
++
++ write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
++ write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
++
++ write_nic_word(dev, RFPinsOutput, bit | out);
++
++ }
++
++ write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN);
++
++// force_pci_posting(dev);
++// udelay(10);
++
++ write_nic_word(dev, RFPinsOutput, out |
++ ((priv->card_type == USB) ? 4 : BB_HOST_BANG_EN));
++
++ write_nic_word(dev, RFPinsSelect, select |
++ ((priv->card_type == USB) ? 0 : SW_CONTROL_GPIO));
++
++ if(priv->card_type == USB)
++ ;// msleep(2);
++ else
++// rtl8185_rf_pins_enable(dev);
++#endif
++}
++
++
++void write_rtl8225_patch(struct net_device *dev, u8 adr, u16 data)
++{
++
++ int i;
++ u16 out,select;
++ u8 bit;
++ u32 bangdata = (data << 4) | (adr & 0xf);
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ out = read_nic_word(dev, RFPinsOutput) & 0xfff3;
++
++ write_nic_word(dev,RFPinsEnable,
++ (read_nic_word(dev,RFPinsEnable) | 0x7));
++
++ select = read_nic_word(dev, RFPinsSelect);
++
++ write_nic_word(dev, RFPinsSelect, select | 0x7 |
++ ((priv->card_type == USB) ? 0 : SW_CONTROL_GPIO));
++
++ force_pci_posting(dev);
++ udelay(10);
++
++ write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN );//| 0x1fff);
++
++ force_pci_posting(dev);
++ udelay(2);
++
++ write_nic_word(dev, RFPinsOutput, out);
++
++ force_pci_posting(dev);
++ udelay(10);
++
++ for(i=15; i>=0;i--){
++
++ bit = (bangdata & (1<<i)) >> i;
++
++ write_nic_word(dev, RFPinsOutput, bit | out);
++
++ write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
++ write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
++
++ i--;
++ bit = (bangdata & (1<<i)) >> i;
++
++ write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
++ write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
++
++ write_nic_word(dev, RFPinsOutput, bit | out);
++
++ }
++
++ write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN);
++
++ force_pci_posting(dev);
++ udelay(10);
++
++ write_nic_word(dev, RFPinsOutput, out |
++ ((priv->card_type == USB) ? 4 : BB_HOST_BANG_EN));
++
++ write_nic_word(dev, RFPinsSelect, select |
++ ((priv->card_type == USB) ? 0 : SW_CONTROL_GPIO));
++
++ if(priv->card_type == USB)
++ mdelay(2);
++ else
++ rtl8185_rf_pins_enable(dev);
++
++}
++
++void rtl8225_rf_close(struct net_device *dev)
++{
++ write_rtl8225(dev, 0x4, 0x1f);
++
++ force_pci_posting(dev);
++ mdelay(1);
++
++ rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_OFF);
++ rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_OFF);
++}
++
++#ifdef ENABLE_DOT11D
++//
++// Description:
++// Map dBm into Tx power index according to
++// current HW model, for example, RF and PA, and
++// current wireless mode.
++//
++s8
++DbmToTxPwrIdx(
++ struct r8180_priv *priv,
++ WIRELESS_MODE WirelessMode,
++ s32 PowerInDbm
++ )
++{
++ bool bUseDefault = true;
++ s8 TxPwrIdx = 0;
++
++#ifdef CONFIG_RTL818X_S
++ //
++ // 071011, SD3 SY:
++ // OFDM Power in dBm = Index * 0.5 + 0
++ // CCK Power in dBm = Index * 0.25 + 13
++ //
++ if(priv->card_8185 >= VERSION_8187S_B)
++ {
++ s32 tmp = 0;
++
++ if(WirelessMode == WIRELESS_MODE_G)
++ {
++ bUseDefault = false;
++ tmp = (2 * PowerInDbm);
++
++ if(tmp < 0)
++ TxPwrIdx = 0;
++ else if(tmp > 40) // 40 means 20 dBm.
++ TxPwrIdx = 40;
++ else
++ TxPwrIdx = (s8)tmp;
++ }
++ else if(WirelessMode == WIRELESS_MODE_B)
++ {
++ bUseDefault = false;
++ tmp = (4 * PowerInDbm) - 52;
++
++ if(tmp < 0)
++ TxPwrIdx = 0;
++ else if(tmp > 28) // 28 means 20 dBm.
++ TxPwrIdx = 28;
++ else
++ TxPwrIdx = (s8)tmp;
++ }
++ }
++#endif
++
++ //
++ // TRUE if we want to use a default implementation.
++ // We shall set it to FALSE when we have exact translation formular
++ // for target IC. 070622, by rcnjko.
++ //
++ if(bUseDefault)
++ {
++ if(PowerInDbm < 0)
++ TxPwrIdx = 0;
++ else if(PowerInDbm > 35)
++ TxPwrIdx = 35;
++ else
++ TxPwrIdx = (u8)PowerInDbm;
++ }
++
++ return TxPwrIdx;
++}
++#endif
++
++
++short rtl8225_rf_set_sens(struct net_device *dev, short sens)
++{
++ if (sens <0 || sens > 6) return -1;
++
++ if(sens > 4)
++ write_rtl8225(dev, 0x0c, 0x850);
++ else
++ write_rtl8225(dev, 0x0c, 0x50);
++
++ sens= 6-sens;
++ rtl8225_set_gain(dev, sens);
++
++ write_phy_cck(dev, 0x41, rtl8225_threshold[sens]);
++ return 0;
++
++}
++
++void rtl8225_SetTXPowerLevel(struct net_device *dev, short ch)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ int GainIdx;
++ int GainSetting;
++ int i;
++ u8 power;
++ u8 *cck_power_table;
++ u8 max_cck_power_level;
++ u8 max_ofdm_power_level;
++ u8 min_ofdm_power_level;
++ u8 cck_power_level = 0xff & priv->chtxpwr[ch];
++ u8 ofdm_power_level = 0xff & priv->chtxpwr_ofdm[ch];
++
++#ifdef ENABLE_DOT11D
++ if(IS_DOT11D_ENABLE(priv->ieee80211) &&
++ IS_DOT11D_STATE_DONE(priv->ieee80211) )
++ {
++ //PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(priv->ieee80211);
++ u8 MaxTxPwrInDbm = DOT11D_GetMaxTxPwrInDbm(priv->ieee80211, ch);
++ u8 CckMaxPwrIdx = DbmToTxPwrIdx(priv, WIRELESS_MODE_B, MaxTxPwrInDbm);
++ u8 OfdmMaxPwrIdx = DbmToTxPwrIdx(priv, WIRELESS_MODE_G, MaxTxPwrInDbm);
++
++ //printk("Max Tx Power dBm (%d) => CCK Tx power index : %d, OFDM Tx power index: %d\n", MaxTxPwrInDbm, CckMaxPwrIdx, OfdmMaxPwrIdx);
++
++ //printk("EEPROM channel(%d) => CCK Tx power index: %d, OFDM Tx power index: %d\n",
++ // ch, cck_power_level, ofdm_power_level);
++
++ if(cck_power_level > CckMaxPwrIdx)
++ cck_power_level = CckMaxPwrIdx;
++ if(ofdm_power_level > OfdmMaxPwrIdx)
++ ofdm_power_level = OfdmMaxPwrIdx;
++ }
++
++ //priv->CurrentCckTxPwrIdx = cck_power_level;
++ //priv->CurrentOfdmTxPwrIdx = ofdm_power_level;
++#endif
++
++
++ if(priv->card_type == USB){
++ max_cck_power_level = 11;
++ max_ofdm_power_level = 25; // 12 -> 25
++ min_ofdm_power_level = 10;
++ }else{
++ max_cck_power_level = 35;
++ max_ofdm_power_level = 35;
++ min_ofdm_power_level = 0;
++ }
++ if( priv->TrSwitchState == TR_SW_TX )
++ {
++ printk("SetTxPowerLevel8187(): Origianl OFDM Tx power level %d\n", ofdm_power_level);
++ ofdm_power_level -= GetTxOfdmHighPowerBias(dev);
++ cck_power_level -= GetTxCckHighPowerBias(dev);
++ printk("SetTxPowerLevel8187(): Adjusted OFDM Tx power level %d for we are in High Power state\n",
++ ofdm_power_level);
++ printk("SetTxPowerLevel8187(): Adjusted CCK Tx power level %d for we are in High Power state\n",
++ cck_power_level);
++ }
++
++
++
++ /* CCK power setting */
++ if(cck_power_level > max_cck_power_level)
++ cck_power_level = max_cck_power_level;
++ GainIdx=cck_power_level % 6;
++ GainSetting=cck_power_level / 6;
++
++ if(ch == 14)
++ cck_power_table = rtl8225_tx_power_cck_ch14;
++ else
++ cck_power_table = rtl8225_tx_power_cck;
++
++// if(priv->card_8185 == 1 && priv->card_8185_Bversion ){
++ /*Ver B*/
++// write_nic_byte(dev, TX_GAIN_CCK, rtl8225_tx_gain_cck_ofdm[GainSetting]);
++// }else{
++ /*Ver C - D */
++ write_nic_byte(dev, CCK_TXAGC, rtl8225_tx_gain_cck_ofdm[GainSetting]>>1);
++// }
++
++ for(i=0;i<8;i++){
++
++ power = cck_power_table[GainIdx * 8 + i];
++ write_phy_cck(dev, 0x44 + i, power);
++ }
++
++ /* FIXME Is this delay really needeed ? */
++ force_pci_posting(dev);
++ mdelay(1);
++
++ /* OFDM power setting */
++// Old:
++// if(ofdm_power_level > max_ofdm_power_level)
++// ofdm_power_level = 35;
++// ofdm_power_level += min_ofdm_power_level;
++// Latest:
++ if(ofdm_power_level > (max_ofdm_power_level - min_ofdm_power_level))
++ ofdm_power_level = max_ofdm_power_level;
++ else
++ ofdm_power_level += min_ofdm_power_level;
++ if(ofdm_power_level > 35)
++ ofdm_power_level = 35;
++//
++
++ GainIdx=ofdm_power_level % 6;
++ GainSetting=ofdm_power_level / 6;
++#if 1
++// if(priv->card_type == USB){
++ rtl8185_set_anaparam2(dev,RTL8225_ANAPARAM2_ON);
++
++ write_phy_ofdm(dev,2,0x42);
++ write_phy_ofdm(dev,6,0);
++ write_phy_ofdm(dev,8,0);
++// }
++#endif
++// if(priv->card_8185 == 1 && priv->card_8185_Bversion){
++// /*Ver B*/
++// write_nic_byte(dev, TX_GAIN_OFDM, rtl8225_tx_gain_cck_ofdm[GainSetting]);
++// }else{
++ /*Ver C - D */
++ write_nic_byte(dev, OFDM_TXAGC, rtl8225_tx_gain_cck_ofdm[GainSetting]>>1);
++// }
++
++
++ power = rtl8225_tx_power_ofdm[GainIdx];
++
++ write_phy_ofdm(dev, 0x5, power);
++ write_phy_ofdm(dev, 0x7, power);
++
++ force_pci_posting(dev);
++ mdelay(1);
++ //write_nic_byte(dev, TX_AGC_CONTROL,4);
++}
++
++void rtl8225_rf_set_chan(struct net_device *dev, short ch)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ short gset = (priv->ieee80211->state == IEEE80211_LINKED &&
++ ieee80211_is_54g(priv->ieee80211->current_network)) ||
++ priv->ieee80211->iw_mode == IW_MODE_MONITOR;
++ int eifs_addr;
++
++ if(NIC_8187 == priv->card_8187) {
++ eifs_addr = EIFS_8187;
++ } else {
++ eifs_addr = EIFS_8187B;
++ }
++
++#ifdef ENABLE_DOT11D
++ if(!IsLegalChannel(priv->ieee80211, ch) )
++ {
++ printk("channel(%d). is invalide\n", ch);
++ return;
++ }
++#endif
++
++ rtl8225_SetTXPowerLevel(dev, ch);
++
++ write_rtl8225(dev, 0x7, rtl8225_chan[ch]);
++
++ force_pci_posting(dev);
++ mdelay(10);
++
++ write_nic_byte(dev,SIFS,0x22);// SIFS: 0x22
++
++ if(gset)
++ write_nic_byte(dev,DIFS,20); //DIFS: 20
++ else
++ write_nic_byte(dev,DIFS,0x24); //DIFS: 36
++
++ if(priv->ieee80211->state == IEEE80211_LINKED &&
++ ieee80211_is_shortslot(priv->ieee80211->current_network))
++ write_nic_byte(dev,SLOT,0x9); //SLOT: 9
++
++ else
++ write_nic_byte(dev,SLOT,0x14); //SLOT: 20 (0x14)
++
++
++ if(gset){
++ write_nic_byte(dev,eifs_addr,91 - 20); // EIFS: 91 (0x5B)
++ write_nic_byte(dev,CW_VAL,0x73); //CW VALUE: 0x37
++ //DMESG("using G net params");
++ }else{
++ write_nic_byte(dev,eifs_addr,91 - 0x24); // EIFS: 91 (0x5B)
++ write_nic_byte(dev,CW_VAL,0xa5); //CW VALUE: 0x37
++ //DMESG("using B net params");
++ }
++
++
++}
++
++void rtl8225_host_pci_init(struct net_device *dev)
++{
++ write_nic_word(dev, RFPinsOutput, 0x480);
++
++ rtl8185_rf_pins_enable(dev);
++
++ //if(priv->card_8185 == 2 && priv->enable_gpio0 ) /* version D */
++ //write_nic_word(dev, RFPinsSelect, 0x88);
++ //else
++ write_nic_word(dev, RFPinsSelect, 0x88 | SW_CONTROL_GPIO); /* 0x488 | SW_CONTROL_GPIO */
++
++ write_nic_byte(dev, GP_ENABLE, 0);
++
++ force_pci_posting(dev);
++ mdelay(200);
++
++ write_nic_word(dev, GP_ENABLE, 0xff & (~(1<<6))); /* bit 6 is for RF on/off detection */
++
++
++}
++
++void rtl8225_host_usb_init(struct net_device *dev)
++{
++ write_nic_byte(dev,RFPinsSelect+1,0);
++
++ write_nic_byte(dev,GPIO,0);
++
++ write_nic_byte_E(dev,0x53,read_nic_byte_E(dev,0x53) | (1<<7));
++
++ write_nic_byte(dev,RFPinsSelect+1,4);
++
++ write_nic_byte(dev,GPIO,0x20);
++
++ write_nic_byte(dev,GP_ENABLE,0);
++
++
++ /* Config BB & RF */
++ write_nic_word(dev, RFPinsOutput, 0x80);
++
++ write_nic_word(dev, RFPinsSelect, 0x80);
++
++ write_nic_word(dev, RFPinsEnable, 0x80);
++
++
++ mdelay(100);
++
++ mdelay(1000);
++
++}
++
++void rtl8225_rf_init(struct net_device *dev)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ int i;
++ short channel = 1;
++ u16 brsr;
++ int brsr_addr;
++
++ if(NIC_8187 == priv->card_8187) {
++ brsr_addr = BRSR_8187;
++ } else {
++ brsr_addr = BRSR_8187B;
++ }
++
++
++ priv->chan = channel;
++
++ rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
++
++
++ if(priv->card_type == USB)
++ rtl8225_host_usb_init(dev);
++ else
++ rtl8225_host_pci_init(dev);
++
++ write_nic_dword(dev, RF_TIMING, 0x000a8008);
++
++ //brsr = read_nic_word(dev, BRSR);
++ brsr = read_nic_word(dev, brsr_addr);
++
++ //write_nic_word(dev, BRSR, 0xffff);
++ write_nic_word(dev, brsr_addr, 0xffff);
++
++ write_nic_dword(dev, RF_PARA, 0x100044);
++
++ #if 1 //0->1
++ rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
++ write_nic_byte(dev, CONFIG3, 0x44);
++ rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
++ #endif
++
++ if(priv->card_type == USB){
++ rtl8185_rf_pins_enable(dev);
++
++ mdelay(1000);
++ }
++
++ write_rtl8225(dev, 0x0, 0x67); mdelay(1);
++
++
++ write_rtl8225(dev, 0x1, 0xfe0); mdelay(1);
++
++ write_rtl8225(dev, 0x2, 0x44d); mdelay(1);
++
++ write_rtl8225(dev, 0x3, 0x441); mdelay(1);
++
++ if(priv->card_type == USB)
++ write_rtl8225(dev, 0x4, 0x486);
++ else
++ write_rtl8225(dev, 0x4, 0x8be);
++
++ mdelay(1);
++
++
++ /* version B & C */
++
++ if(priv->card_type == USB)
++ write_rtl8225(dev, 0x5, 0xbc0);
++ else if(priv->card_type == MINIPCI)
++ write_rtl8225(dev, 0x5, 0xbc0 + 3 +(6<<3));
++ else
++ write_rtl8225(dev, 0x5, 0xbc0 + (6<<3));
++
++ mdelay(1);
++// }
++
++ write_rtl8225(dev, 0x6, 0xae6); mdelay(1);
++
++ write_rtl8225(dev, 0x7, ((priv->card_type == USB)? 0x82a : rtl8225_chan[channel])); mdelay(1);
++
++ write_rtl8225(dev, 0x8, 0x1f); mdelay(1);
++
++ write_rtl8225(dev, 0x9, 0x334); mdelay(1);
++
++ write_rtl8225(dev, 0xa, 0xfd4); mdelay(1);
++
++ write_rtl8225(dev, 0xb, 0x391); mdelay(1);
++
++ write_rtl8225(dev, 0xc, 0x50); mdelay(1);
++
++
++ write_rtl8225(dev, 0xd, 0x6db); mdelay(1);
++
++ write_rtl8225(dev, 0xe, 0x29); mdelay(1);
++
++ write_rtl8225(dev, 0xf, 0x914);
++
++ if(priv->card_type == USB){
++ //force_pci_posting(dev);
++ mdelay(100);
++ }
++
++ write_rtl8225(dev, 0x2, 0xc4d);
++
++ if(priv->card_type == USB){
++ // force_pci_posting(dev);
++ mdelay(200);
++
++ write_rtl8225(dev, 0x2, 0x44d);
++
++ // force_pci_posting(dev);
++ mdelay(100);
++
++ }//End of if(priv->card_type == USB)
++ /* FIXME!! rtl8187 we have to check if calibrarion
++ * is successful and eventually cal. again (repeat
++ * the two write on reg 2)
++ */
++ force_pci_posting(dev);
++
++ mdelay(100); //200 for 8187
++
++ //if(priv->card_type != USB) /* maybe not needed even for 8185 */
++// write_rtl8225(dev, 0x7, rtl8225_chan[channel]);
++
++ write_rtl8225(dev, 0x0, 0x127);
++
++ for(i=0;i<95;i++){
++ write_rtl8225(dev, 0x1, (u8)(i+1));
++
++ /* version B & C & D*/
++
++ write_rtl8225(dev, 0x2, rtl8225bcd_rxgain[i]);
++ }
++
++ write_rtl8225(dev, 0x0, 0x27);
++
++
++// //if(priv->card_type != USB){
++// write_rtl8225(dev, 0x2, 0x44d);
++// write_rtl8225(dev, 0x7, rtl8225_chan[channel]);
++// write_rtl8225(dev, 0x2, 0x47d);
++//
++// force_pci_posting(dev);
++// mdelay(100);
++//
++// write_rtl8225(dev, 0x2, 0x44d);
++// //}
++
++ write_rtl8225(dev, 0x0, 0x22f);
++
++ if(priv->card_type != USB)
++ rtl8185_rf_pins_enable(dev);
++
++ for(i=0;i<128;i++){
++ write_phy_ofdm(dev, 0xb, rtl8225_agc[i]);
++
++ mdelay(1);
++ write_phy_ofdm(dev, 0xa, (u8)i+ 0x80);
++
++ mdelay(1);
++ }
++
++ force_pci_posting(dev);
++ mdelay(1);
++
++ write_phy_ofdm(dev, 0x0, 0x1); mdelay(1);
++ write_phy_ofdm(dev, 0x1, 0x2); mdelay(1);
++ write_phy_ofdm(dev, 0x2, ((priv->card_type == USB)? 0x42 : 0x62)); mdelay(1);
++ write_phy_ofdm(dev, 0x3, 0x0); mdelay(1);
++ write_phy_ofdm(dev, 0x4, 0x0); mdelay(1);
++ write_phy_ofdm(dev, 0x5, 0x0); mdelay(1);
++ write_phy_ofdm(dev, 0x6, 0x40); mdelay(1);
++ write_phy_ofdm(dev, 0x7, 0x0); mdelay(1);
++ write_phy_ofdm(dev, 0x8, 0x40); mdelay(1);
++ write_phy_ofdm(dev, 0x9, 0xfe); mdelay(1);
++
++ /* ver C & D */
++ write_phy_ofdm(dev, 0xa, 0x9); mdelay(1);
++
++ //write_phy_ofdm(dev, 0x18, 0xef);
++ // }
++ //}
++ write_phy_ofdm(dev, 0xb, 0x80); mdelay(1);
++
++ write_phy_ofdm(dev, 0xc, 0x1);mdelay(1);
++
++
++ //if(priv->card_type != USB)
++ //write_phy_ofdm(dev, 0xd, 0x33); // <>
++
++ write_phy_ofdm(dev, 0xe, 0xd3);mdelay(1);
++
++ write_phy_ofdm(dev, 0xf, 0x38);mdelay(1);
++/*ver D & 8187*/
++// }
++
++// if(priv->card_8185 == 1 && priv->card_8185_Bversion)
++// write_phy_ofdm(dev, 0x10, 0x04);/*ver B*/
++// else
++ write_phy_ofdm(dev, 0x10, 0x84);mdelay(1);
++/*ver C & D & 8187*/
++
++ write_phy_ofdm(dev, 0x11, 0x06);mdelay(1);
++/*agc resp time 700*/
++
++
++// if(priv->card_8185 == 2){
++ /* Ver D & 8187*/
++ write_phy_ofdm(dev, 0x12, 0x20);mdelay(1);
++
++ write_phy_ofdm(dev, 0x13, 0x20);mdelay(1);
++
++ write_phy_ofdm(dev, 0x14, 0x0); mdelay(1);
++ write_phy_ofdm(dev, 0x15, 0x40); mdelay(1);
++ write_phy_ofdm(dev, 0x16, 0x0); mdelay(1);
++ write_phy_ofdm(dev, 0x17, 0x40); mdelay(1);
++
++// if (priv->card_type == USB)
++// write_phy_ofdm(dev, 0x18, 0xef);
++
++ write_phy_ofdm(dev, 0x18, 0xef);mdelay(1);
++
++
++ write_phy_ofdm(dev, 0x19, 0x19); mdelay(1);
++ write_phy_ofdm(dev, 0x1a, 0x20); mdelay(1);
++
++// if (priv->card_type != USB){
++// if(priv->card_8185 == 1 && priv->card_8185_Bversion)
++// write_phy_ofdm(dev, 0x1b, 0x66); /* Ver B */
++// else
++ write_phy_ofdm(dev, 0x1b, 0x76);mdelay(1);
++ /* Ver C & D */ //FIXME:MAYBE not needed
++// }
++
++ write_phy_ofdm(dev, 0x1c, 0x4);mdelay(1);
++
++ /*ver D & 8187*/
++ write_phy_ofdm(dev, 0x1e, 0x95);mdelay(1);
++
++ write_phy_ofdm(dev, 0x1f, 0x75); mdelay(1);
++
++// }
++
++ write_phy_ofdm(dev, 0x20, 0x1f);mdelay(1);
++
++ write_phy_ofdm(dev, 0x21, 0x27);mdelay(1);
++
++ write_phy_ofdm(dev, 0x22, 0x16);mdelay(1);
++
++// if(priv->card_type != USB)
++ //write_phy_ofdm(dev, 0x23, 0x43); //FIXME maybe not needed // <>
++
++ write_phy_ofdm(dev, 0x24, 0x46); mdelay(1);
++ write_phy_ofdm(dev, 0x25, 0x20); mdelay(1);
++ write_phy_ofdm(dev, 0x26, 0x90); mdelay(1);
++ write_phy_ofdm(dev, 0x27, 0x88); mdelay(1);
++/* Ver C & D & 8187*/
++
++ // <> Set init. gain to m74dBm.
++
++ rtl8225_set_gain(dev,4);
++ /*write_phy_ofdm(dev, 0x0d, 0x43); mdelay(1);
++ write_phy_ofdm(dev, 0x1b, 0x76); mdelay(1);
++ write_phy_ofdm(dev, 0x1d, 0xc5); mdelay(1);
++ write_phy_ofdm(dev, 0x23, 0x78); mdelay(1);
++*/
++ //if(priv->card_type == USB);
++ // rtl8225_set_gain_usb(dev, 1); /* FIXME this '2' is random */
++
++ write_phy_cck(dev, 0x0, 0x98); mdelay(1);
++ write_phy_cck(dev, 0x3, 0x20); mdelay(1);
++ write_phy_cck(dev, 0x4, 0x7e); mdelay(1);
++ write_phy_cck(dev, 0x5, 0x12); mdelay(1);
++ write_phy_cck(dev, 0x6, 0xfc); mdelay(1);
++ write_phy_cck(dev, 0x7, 0x78);mdelay(1);
++ /* Ver C & D & 8187*/
++
++ write_phy_cck(dev, 0x8, 0x2e);mdelay(1);
++
++ write_phy_cck(dev, 0x10, ((priv->card_type == USB) ? 0x9b: 0x93)); mdelay(1);
++ write_phy_cck(dev, 0x11, 0x88); mdelay(1);
++ write_phy_cck(dev, 0x12, 0x47); mdelay(1);
++ write_phy_cck(dev, 0x13, 0xd0); /* Ver C & D & 8187*/
++
++ write_phy_cck(dev, 0x19, 0x0);
++ write_phy_cck(dev, 0x1a, 0xa0);
++ write_phy_cck(dev, 0x1b, 0x8);
++ write_phy_cck(dev, 0x40, 0x86); /* CCK Carrier Sense Threshold */
++
++ write_phy_cck(dev, 0x41, 0x8d);mdelay(1);
++
++
++ write_phy_cck(dev, 0x42, 0x15); mdelay(1);
++ write_phy_cck(dev, 0x43, 0x18); mdelay(1);
++ write_phy_cck(dev, 0x44, 0x1f); mdelay(1);
++ write_phy_cck(dev, 0x45, 0x1e); mdelay(1);
++ write_phy_cck(dev, 0x46, 0x1a); mdelay(1);
++ write_phy_cck(dev, 0x47, 0x15); mdelay(1);
++ write_phy_cck(dev, 0x48, 0x10); mdelay(1);
++ write_phy_cck(dev, 0x49, 0xa); mdelay(1);
++ write_phy_cck(dev, 0x4a, 0x5); mdelay(1);
++ write_phy_cck(dev, 0x4b, 0x2); mdelay(1);
++ write_phy_cck(dev, 0x4c, 0x5);mdelay(1);
++
++
++ write_nic_byte(dev, 0x5b, 0x0d); mdelay(1);
++
++
++
++// <>
++// // TESTR 0xb 8187
++// write_phy_cck(dev, 0x10, 0x93);// & 0xfb);
++//
++// //if(priv->card_type != USB){
++// write_phy_ofdm(dev, 0x2, 0x62);
++// write_phy_ofdm(dev, 0x6, 0x0);
++// write_phy_ofdm(dev, 0x8, 0x0);
++// //}
++
++ rtl8225_SetTXPowerLevel(dev, channel);
++
++ write_phy_cck(dev, 0x10, 0x9b); mdelay(1); /* Rx ant A, 0xdb for B */
++ write_phy_ofdm(dev, 0x26, 0x90); mdelay(1); /* Rx ant A, 0x10 for B */
++
++ rtl8185_tx_antenna(dev, 0x3); /* TX ant A, 0x0 for B */
++
++ /* switch to high-speed 3-wire
++ * last digit. 2 for both cck and ofdm
++ */
++ if(priv->card_type == USB)
++ write_nic_dword(dev, 0x94, 0x3dc00002);
++ else{
++ write_nic_dword(dev, 0x94, 0x15c00002);
++ rtl8185_rf_pins_enable(dev);
++ }
++
++// if(priv->card_type != USB)
++// rtl8225_set_gain(dev, 4); /* FIXME this '1' is random */ // <>
++// rtl8225_set_mode(dev, 1); /* FIXME start in B mode */ // <>
++//
++// /* make sure is waken up! */
++// write_rtl8225(dev,0x4, 0x9ff);
++// rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
++// rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_ON);
++
++ rtl8225_rf_set_chan(dev, priv->chan);
++
++ //write_nic_word(dev,BRSR,brsr);
++
++}
+diff --git a/drivers/net/wireless/rtl8187b/r8180_rtl8225.h b/drivers/net/wireless/rtl8187b/r8180_rtl8225.h
+new file mode 100644
+index 0000000..138e0d0
+--- /dev/null
++++ b/drivers/net/wireless/rtl8187b/r8180_rtl8225.h
+@@ -0,0 +1,77 @@
++/*
++ This is part of the rtl8180-sa2400 driver
++ released under the GPL (See file COPYING for details).
++ Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
++
++ This files contains programming code for the rtl8225
++ radio frontend.
++
++ *Many* thanks to Realtek Corp. for their great support!
++
++*/
++
++#ifndef RTL8225H
++#define RTL8225H
++
++#include "r8187.h"
++
++#define RTL8225_ANAPARAM_ON 0xa0000a59
++
++// FIXME: OFF ANAPARAM MIGHT BE WRONG!
++#define RTL8225_ANAPARAM_OFF 0xa00beb59
++#define RTL8225_ANAPARAM2_OFF 0x840dec11
++
++#define RTL8225_ANAPARAM2_ON 0x860c7312
++
++void rtl8225_rf_init(struct net_device *dev);
++void rtl8225z2_rf_init(struct net_device *dev);
++void rtl8225z2_rf_set_chan(struct net_device *dev, short ch);
++short rtl8225_is_V_z2(struct net_device *dev);
++void rtl8225_rf_set_chan(struct net_device *dev,short ch);
++void rtl8225_rf_close(struct net_device *dev);
++short rtl8225_rf_set_sens(struct net_device *dev, short sens);
++void rtl8225_host_pci_init(struct net_device *dev);
++void rtl8225_host_usb_init(struct net_device *dev);
++void write_rtl8225(struct net_device *dev, u8 adr, u16 data);
++void rtl8225z2_rf_set_mode(struct net_device *dev) ;
++void rtl8185_rf_pins_enable(struct net_device *dev);
++void rtl8180_set_mode(struct net_device *dev,int mode);
++void UpdateInitialGain(struct net_device *dev);
++void UpdateCCKThreshold(struct net_device *dev);
++void rtl8225_SetTXPowerLevel(struct net_device *dev, short ch);
++void rtl8225z2_SetTXPowerLevel(struct net_device *dev, short ch);
++
++#define RTL8225_RF_MAX_SENS 6
++#define RTL8225_RF_DEF_SENS 4
++
++extern inline char GetTxOfdmHighPowerBias(struct net_device *dev)
++{
++ //
++ // We should always adjust our Tx Power for 8187 and 8187B.
++ // It was ever recommended not to adjust Tx Power of 8187B with Atheros AP
++ // for throughput by David, but now we found it is not the issue to impact
++ // the Atheros's problem and also no adjustion for Tx Power will cause "low"
++ // throughput. By Bruce, 2007-07-03.
++ //
++ return 10;
++}
++
++//
++// Description:
++// Return Tx power level to minus if we are in high power state.
++//
++// Note:
++// Adjust it according to RF if required.
++//
++extern inline char GetTxCckHighPowerBias(struct net_device *dev)
++{
++ return 7;
++}
++
++
++
++extern u8 rtl8225_agc[];
++
++extern u32 rtl8225_chan[];
++
++#endif
+diff --git a/drivers/net/wireless/rtl8187b/r8180_rtl8225z2.c b/drivers/net/wireless/rtl8187b/r8180_rtl8225z2.c
+new file mode 100644
+index 0000000..1fa7b71
+--- /dev/null
++++ b/drivers/net/wireless/rtl8187b/r8180_rtl8225z2.c
+@@ -0,0 +1,2090 @@
++/*
++ This is part of the rtl8180-sa2400 driver
++ released under the GPL (See file COPYING for details).
++ Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
++
++ This files contains programming code for the rtl8225
++ radio frontend.
++
++ *Many* thanks to Realtek Corp. for their great support!
++
++*/
++
++
++
++#include "r8180_hw.h"
++#include "r8180_rtl8225.h"
++#ifdef ENABLE_DOT11D
++#include "dot11d.h"
++#endif
++
++//2005.11.16
++u8 rtl8225z2_threshold[]={
++ 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd,
++};
++
++// 0xd 0x19 0x1b 0x21
++u8 rtl8225z2_gain_bg[]={
++ 0x23, 0x15, 0xa5, // -82-1dbm
++ 0x23, 0x15, 0xb5, // -82-2dbm
++ 0x23, 0x15, 0xc5, // -82-3dbm
++ 0x33, 0x15, 0xc5, // -78dbm
++ 0x43, 0x15, 0xc5, // -74dbm
++ 0x53, 0x15, 0xc5, // -70dbm
++ 0x63, 0x15, 0xc5, // -66dbm
++};
++
++u8 rtl8225z2_gain_a[]={
++ 0x13,0x27,0x5a,//,0x37,// -82dbm
++ 0x23,0x23,0x58,//,0x37,// -82dbm
++ 0x33,0x1f,0x56,//,0x37,// -82dbm
++ 0x43,0x1b,0x54,//,0x37,// -78dbm
++ 0x53,0x17,0x51,//,0x37,// -74dbm
++ 0x63,0x24,0x4f,//,0x37,// -70dbm
++ 0x73,0x0f,0x4c,//,0x37,// -66dbm
++};
++static u32 MAC_REG_TABLE[][3]={
++ {0xf0, 0x32, 0000}, {0xf1, 0x32, 0000}, {0xf2, 0x00, 0000}, {0xf3, 0x00, 0000},
++ {0xf4, 0x32, 0000}, {0xf5, 0x43, 0000}, {0xf6, 0x00, 0000}, {0xf7, 0x00, 0000},
++ {0xf8, 0x46, 0000}, {0xf9, 0xa4, 0000}, {0xfa, 0x00, 0000}, {0xfb, 0x00, 0000},
++ {0xfc, 0x96, 0000}, {0xfd, 0xa4, 0000}, {0xfe, 0x00, 0000}, {0xff, 0x00, 0000},
++
++ {0x58, 0x4b, 0001}, {0x59, 0x00, 0001}, {0x5a, 0x4b, 0001}, {0x5b, 0x00, 0001},
++ {0x60, 0x4b, 0001}, {0x61, 0x09, 0001}, {0x62, 0x4b, 0001}, {0x63, 0x09, 0001},
++ {0xce, 0x0f, 0001}, {0xcf, 0x00, 0001}, {0xe0, 0xff, 0001}, {0xe1, 0x0f, 0001},
++ {0xe2, 0x00, 0001}, {0xf0, 0x4e, 0001}, {0xf1, 0x01, 0001}, {0xf2, 0x02, 0001},
++ {0xf3, 0x03, 0001}, {0xf4, 0x04, 0001}, {0xf5, 0x05, 0001}, {0xf6, 0x06, 0001},
++ {0xf7, 0x07, 0001}, {0xf8, 0x08, 0001},
++
++ {0x4e, 0x00, 0002}, {0x0c, 0x04, 0002}, {0x21, 0x61, 0002}, {0x22, 0x68, 0002},
++ {0x23, 0x6f, 0002}, {0x24, 0x76, 0002}, {0x25, 0x7d, 0002}, {0x26, 0x84, 0002},
++ {0x27, 0x8d, 0002}, {0x4d, 0x08, 0002}, {0x50, 0x05, 0002}, {0x51, 0xf5, 0002},
++ {0x52, 0x04, 0002}, {0x53, 0xa0, 0002}, {0x54, 0x1f, 0002}, {0x55, 0x23, 0002},
++ {0x56, 0x45, 0002}, {0x57, 0x67, 0002}, {0x58, 0x08, 0002}, {0x59, 0x08, 0002},
++ {0x5a, 0x08, 0002}, {0x5b, 0x08, 0002}, {0x60, 0x08, 0002}, {0x61, 0x08, 0002},
++ {0x62, 0x08, 0002}, {0x63, 0x08, 0002}, {0x64, 0xcf, 0002}, {0x72, 0x56, 0002},
++ {0x73, 0x9a, 0002},
++
++ {0x34, 0xf0, 0000}, {0x35, 0x0f, 0000}, {0x5b, 0x40, 0000}, {0x84, 0x88, 0000},
++ {0x85, 0x24, 0000}, {0x88, 0x54, 0000}, {0x8b, 0xb8, 0000}, {0x8c, 0x07, 0000},
++ {0x8d, 0x00, 0000}, {0x94, 0x1b, 0000}, {0x95, 0x12, 0000}, {0x96, 0x00, 0000},
++ {0x97, 0x06, 0000}, {0x9d, 0x1a, 0000}, {0x9f, 0x10, 0000}, {0xb4, 0x22, 0000},
++ {0xbe, 0x80, 0000}, {0xdb, 0x00, 0000}, {0xee, 0x00, 0000}, {0x91, 0x01, 0000},
++ //lzm mode 0x91 form 0x03->0x01 open GPIO BIT1,
++ //because Polling methord will rurn off Radio
++ //the first time when read GPI(0x92).
++ //because after 0x91:bit1 form 1->0, there will
++ //be time for 0x92:bit1 form 0->1
++
++ {0x4c, 0x00, 0002}, {0x9f, 0x00, 0003}, {0x8c, 0x01, 0000}, {0x8d, 0x10, 0000},
++ {0x8e, 0x08, 0000}, {0x8f, 0x00, 0000}
++};
++
++static u8 ZEBRA_AGC[]={
++ 0,
++ 0x5e,0x5e,0x5e,0x5e,0x5d,0x5b,0x59,0x57,0x55,0x53,0x51,0x4f,0x4d,0x4b,0x49,0x47,
++ 0x45,0x43,0x41,0x3f,0x3d,0x3b,0x39,0x37,0x35,0x33,0x31,0x2f,0x2d,0x2b,0x29,0x27,
++ 0x25,0x23,0x21,0x1f,0x1d,0x1b,0x19,0x17,0x15,0x13,0x11,0x0f,0x0d,0x0b,0x09,0x07,
++ 0x05,0x03,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
++ 0x19,0x19,0x19,0x019,0x19,0x19,0x19,0x19,0x19,0x20,0x21,0x22,0x23,0x24,0x25,0x26,
++ 0x26,0x27,0x27,0x28,0x28,0x29,0x2a,0x2a,0x2a,0x2b,0x2b,0x2b,0x2c,0x2c,0x2c,0x2d,
++ 0x2d,0x2d,0x2d,0x2e,0x2e,0x2e,0x2e,0x2f,0x2f,0x2f,0x30,0x30,0x31,0x31,0x31,0x31,
++ 0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31
++};
++
++static u32 ZEBRA_RF_RX_GAIN_TABLE[]={
++ 0,
++ 0x0400,0x0401,0x0402,0x0403,0x0404,0x0405,0x0408,0x0409,
++ 0x040a,0x040b,0x0502,0x0503,0x0504,0x0505,0x0540,0x0541,
++ 0x0542,0x0543,0x0544,0x0545,0x0580,0x0581,0x0582,0x0583,
++ 0x0584,0x0585,0x0588,0x0589,0x058a,0x058b,0x0643,0x0644,
++ 0x0645,0x0680,0x0681,0x0682,0x0683,0x0684,0x0685,0x0688,
++ 0x0689,0x068a,0x068b,0x068c,0x0742,0x0743,0x0744,0x0745,
++ 0x0780,0x0781,0x0782,0x0783,0x0784,0x0785,0x0788,0x0789,
++ 0x078a,0x078b,0x078c,0x078d,0x0790,0x0791,0x0792,0x0793,
++ 0x0794,0x0795,0x0798,0x0799,0x079a,0x079b,0x079c,0x079d,
++ 0x07a0,0x07a1,0x07a2,0x07a3,0x07a4,0x07a5,0x07a8,0x07a9,
++ 0x03aa,0x03ab,0x03ac,0x03ad,0x03b0,0x03b1,0x03b2,0x03b3,
++ 0x03b4,0x03b5,0x03b8,0x03b9,0x03ba,0x03bb,0x03bb
++};
++
++// Use the new SD3 given param, by shien chang, 2006.07.14
++
++static u8 OFDM_CONFIG[]={
++ // 0x00
++ 0x10, 0x0d, 0x01, 0x00, 0x14, 0xfb, 0xfb, 0x60,
++ 0x00, 0x60, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00,
++
++ // 0x10
++ 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0xa8, 0x26,
++ 0x32, 0x33, 0x07, 0xa5, 0x6f, 0x55, 0xc8, 0xb3,
++
++ // 0x20
++ 0x0a, 0xe1, 0x2C, 0x8a, 0x86, 0x83, 0x34, 0x0f,
++ 0x4f, 0x24, 0x6f, 0xc2, 0x6b, 0x40, 0x80, 0x00,
++
++ // 0x30
++ 0xc0, 0xc1, 0x58, 0xf1, 0x00, 0xe4, 0x90, 0x3e,
++ 0x6d, 0x3c, 0xfb, 0x07//0xc7
++ };
++
++//2005.11.16,
++u8 ZEBRA2_CCK_OFDM_GAIN_SETTING[]={
++ 0x00,0x01,0x02,0x03,0x04,0x05,
++ 0x06,0x07,0x08,0x09,0x0a,0x0b,
++ 0x0c,0x0d,0x0e,0x0f,0x10,0x11,
++ 0x12,0x13,0x14,0x15,0x16,0x17,
++ 0x18,0x19,0x1a,0x1b,0x1c,0x1d,
++ 0x1e,0x1f,0x20,0x21,0x22,0x23,
++};
++//-
++u16 rtl8225z2_rxgain[]={
++ 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
++ 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
++ 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
++ 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
++ 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
++ 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
++ 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
++ 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
++ 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
++ 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
++ 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
++ 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
++
++};
++
++
++/*
++ from 0 to 0x23
++u8 rtl8225_tx_gain_cck_ofdm[]={
++ 0x02,0x06,0x0e,0x1e,0x3e,0x7e
++};
++*/
++
++//-
++u8 rtl8225z2_tx_power_ofdm[]={
++ 0x42,0x00,0x40,0x00,0x40
++};
++
++
++//-
++u8 rtl8225z2_tx_power_cck_ch14[]={
++ 0x36,0x35,0x2e,0x1b,0x00,0x00,0x00,0x00,
++ 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
++ 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
++ 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
++};
++
++
++//-
++u8 rtl8225z2_tx_power_cck[]={
++ 0x36,0x35,0x2e,0x25,0x1c,0x12,0x09,0x04,
++ 0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03,
++ 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03,
++ 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03
++};
++
++#ifdef ENABLE_DOT11D
++//
++// Description:
++// Map dBm into Tx power index according to
++// current HW model, for example, RF and PA, and
++// current wireless mode.
++//
++s8
++rtl8187B_DbmToTxPwrIdx(
++ struct r8180_priv *priv,
++ WIRELESS_MODE WirelessMode,
++ s32 PowerInDbm
++ )
++{
++ bool bUseDefault = true;
++ s8 TxPwrIdx = 0;
++
++#ifdef CONFIG_RTL818X_S
++ //
++ // 071011, SD3 SY:
++ // OFDM Power in dBm = Index * 0.5 + 0
++ // CCK Power in dBm = Index * 0.25 + 13
++ //
++ if(priv->card_8185 >= VERSION_8187S_B)
++ {
++ s32 tmp = 0;
++
++ if(WirelessMode == WIRELESS_MODE_G)
++ {
++ bUseDefault = false;
++ tmp = (2 * PowerInDbm);
++
++ if(tmp < 0)
++ TxPwrIdx = 0;
++ else if(tmp > 40) // 40 means 20 dBm.
++ TxPwrIdx = 40;
++ else
++ TxPwrIdx = (s8)tmp;
++ }
++ else if(WirelessMode == WIRELESS_MODE_B)
++ {
++ bUseDefault = false;
++ tmp = (4 * PowerInDbm) - 52;
++
++ if(tmp < 0)
++ TxPwrIdx = 0;
++ else if(tmp > 28) // 28 means 20 dBm.
++ TxPwrIdx = 28;
++ else
++ TxPwrIdx = (s8)tmp;
++ }
++ }
++#endif
++
++ //
++ // TRUE if we want to use a default implementation.
++ // We shall set it to FALSE when we have exact translation formular
++ // for target IC. 070622, by rcnjko.
++ //
++ if(bUseDefault)
++ {
++ if(PowerInDbm < 0)
++ TxPwrIdx = 0;
++ else if(PowerInDbm > 35)
++ TxPwrIdx = 35;
++ else
++ TxPwrIdx = (u8)PowerInDbm;
++ }
++
++ return TxPwrIdx;
++}
++#endif
++
++
++void rtl8225z2_set_gain(struct net_device *dev, short gain)
++{
++ u8* rtl8225_gain;
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ u8 mode = priv->ieee80211->mode;
++
++ if(mode == IEEE_B || mode == IEEE_G)
++ rtl8225_gain = rtl8225z2_gain_bg;
++ else
++ rtl8225_gain = rtl8225z2_gain_a;
++
++ //write_phy_ofdm(dev, 0x0d, rtl8225_gain[gain * 3]);
++ //write_phy_ofdm(dev, 0x19, rtl8225_gain[gain * 3 + 1]);
++ //write_phy_ofdm(dev, 0x1b, rtl8225_gain[gain * 3 + 2]);
++ //2005.11.17, by ch-hsu
++ write_phy_ofdm(dev, 0x0b, rtl8225_gain[gain * 3]);
++ write_phy_ofdm(dev, 0x1b, rtl8225_gain[gain * 3 + 1]);
++ write_phy_ofdm(dev, 0x1d, rtl8225_gain[gain * 3 + 2]);
++ write_phy_ofdm(dev, 0x21, 0x37);
++
++}
++
++u32 read_rtl8225(struct net_device *dev, u8 adr)
++{
++ u32 data2Write = ((u32)(adr & 0x1f)) << 27;
++ u32 dataRead;
++ u32 mask;
++ u16 oval,oval2,oval3,tmp;
++// ThreeWireReg twreg;
++// ThreeWireReg tdata;
++ int i;
++ short bit, rw;
++
++ u8 wLength = 6;
++ u8 rLength = 12;
++ u8 low2high = 0;
++
++ oval = read_nic_word(dev, RFPinsOutput);
++ oval2 = read_nic_word(dev, RFPinsEnable);
++ oval3 = read_nic_word(dev, RFPinsSelect);
++ write_nic_word(dev, RFPinsEnable, (oval2|0xf));
++ write_nic_word(dev, RFPinsSelect, (oval3|0xf));
++
++ dataRead = 0;
++
++ oval &= ~0xf;
++
++ write_nic_word(dev, RFPinsOutput, oval | BB_HOST_BANG_EN ); udelay(4);
++
++ write_nic_word(dev, RFPinsOutput, oval ); udelay(5);
++
++ rw = 0;
++
++ mask = (low2high) ? 0x01 : (((u32)0x01)<<(32-1));
++ for(i = 0; i < wLength/2; i++)
++ {
++ bit = ((data2Write&mask) != 0) ? 1 : 0;
++ write_nic_word(dev, RFPinsOutput, bit|oval | rw); udelay(1);
++
++ write_nic_word(dev, RFPinsOutput, bit|oval | BB_HOST_BANG_CLK | rw); udelay(2);
++ write_nic_word(dev, RFPinsOutput, bit|oval | BB_HOST_BANG_CLK | rw); udelay(2);
++
++ mask = (low2high) ? (mask<<1): (mask>>1);
++
++ if(i == 2)
++ {
++ rw = BB_HOST_BANG_RW;
++ write_nic_word(dev, RFPinsOutput, bit|oval | BB_HOST_BANG_CLK | rw); udelay(2);
++ write_nic_word(dev, RFPinsOutput, bit|oval | rw); udelay(2);
++ break;
++ }
++
++ bit = ((data2Write&mask) != 0) ? 1: 0;
++
++ write_nic_word(dev, RFPinsOutput, oval|bit|rw| BB_HOST_BANG_CLK); udelay(2);
++ write_nic_word(dev, RFPinsOutput, oval|bit|rw| BB_HOST_BANG_CLK); udelay(2);
++
++ write_nic_word(dev, RFPinsOutput, oval| bit |rw); udelay(1);
++
++ mask = (low2high) ? (mask<<1) : (mask>>1);
++ }
++
++ //twreg.struc.clk = 0;
++ //twreg.struc.data = 0;
++ write_nic_word(dev, RFPinsOutput, rw|oval); udelay(2);
++ mask = (low2high) ? 0x01 : (((u32)0x01) << (12-1));
++
++ // We must set data pin to HW controled, otherwise RF can't driver it and
++ // value RF register won't be able to read back properly. 2006.06.13, by rcnjko.
++ write_nic_word(dev, RFPinsEnable,((oval2|0xe) & (~0x01)));
++
++ for(i = 0; i < rLength; i++)
++ {
++ write_nic_word(dev, RFPinsOutput, rw|oval); udelay(1);
++
++ write_nic_word(dev, RFPinsOutput, rw|oval|BB_HOST_BANG_CLK); udelay(2);
++ write_nic_word(dev, RFPinsOutput, rw|oval|BB_HOST_BANG_CLK); udelay(2);
++ write_nic_word(dev, RFPinsOutput, rw|oval|BB_HOST_BANG_CLK); udelay(2);
++ tmp = read_nic_word(dev, RFPinsInput);
++
++ dataRead |= (tmp & BB_HOST_BANG_CLK ? mask : 0);
++
++ write_nic_word(dev, RFPinsOutput, (rw|oval)); udelay(2);
++
++ mask = (low2high) ? (mask<<1) : (mask>>1);
++ }
++
++ write_nic_word(dev, RFPinsOutput, BB_HOST_BANG_EN|BB_HOST_BANG_RW|oval); udelay(2);
++
++ write_nic_word(dev, RFPinsEnable, oval2);
++ write_nic_word(dev, RFPinsSelect, oval3); // Set To SW Switch
++ write_nic_word(dev, RFPinsOutput, 0x3a0);
++
++ return dataRead;
++
++}
++short rtl8225_is_V_z2(struct net_device *dev)
++{
++ short vz2 = 1;
++ //set VCO-PDN pin
++// printk("%s()\n", __FUNCTION__);
++ write_nic_word(dev, RFPinsOutput, 0x0080);
++ write_nic_word(dev, RFPinsSelect, 0x0080);
++ write_nic_word(dev, RFPinsEnable, 0x0080);
++
++ //lzm mod for up take too long time 20081201
++ //mdelay(100);
++ //mdelay(1000);
++
++ /* sw to reg pg 1 */
++ write_rtl8225(dev, 0, 0x1b7);
++ /* reg 8 pg 1 = 23*/
++ if( read_rtl8225(dev, 8) != 0x588)
++ vz2 = 0;
++
++ else /* reg 9 pg 1 = 24 */
++ if( read_rtl8225(dev, 9) != 0x700)
++ vz2 = 0;
++
++ /* sw back to pg 0 */
++ write_rtl8225(dev, 0, 0xb7);
++
++ return vz2;
++
++}
++
++void rtl8225z2_SetTXPowerLevel(struct net_device *dev, short ch)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++// int GainIdx;
++// int GainSetting;
++ int i;
++ u8 power;
++ u8 *cck_power_table;
++ u8 max_cck_power_level;
++ u8 min_cck_power_level;
++ u8 max_ofdm_power_level;
++ u8 min_ofdm_power_level;
++ s8 cck_power_level = 0xff & priv->chtxpwr[ch];
++ s8 ofdm_power_level = 0xff & priv->chtxpwr_ofdm[ch];
++ u8 hw_version = priv->card_8187_Bversion;
++
++#ifdef ENABLE_DOT11D
++ if(IS_DOT11D_ENABLE(priv->ieee80211) &&
++ IS_DOT11D_STATE_DONE(priv->ieee80211) )
++ {
++ //PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(priv->ieee80211);
++ u8 MaxTxPwrInDbm = DOT11D_GetMaxTxPwrInDbm(priv->ieee80211, ch);
++ u8 CckMaxPwrIdx = rtl8187B_DbmToTxPwrIdx(priv, WIRELESS_MODE_B, MaxTxPwrInDbm);
++ u8 OfdmMaxPwrIdx = rtl8187B_DbmToTxPwrIdx(priv, WIRELESS_MODE_G, MaxTxPwrInDbm);
++
++ //printk("Max Tx Power dBm (%d) => CCK Tx power index : %d, OFDM Tx power index: %d\n", MaxTxPwrInDbm, CckMaxPwrIdx, OfdmMaxPwrIdx);
++
++ //printk("EEPROM channel(%d) => CCK Tx power index: %d, OFDM Tx power index: %d\n",
++ // ch, cck_power_level, ofdm_power_level);
++
++ if(cck_power_level > CckMaxPwrIdx)
++ cck_power_level = CckMaxPwrIdx;
++ if(ofdm_power_level > OfdmMaxPwrIdx)
++ ofdm_power_level = OfdmMaxPwrIdx;
++ }
++
++ //priv->CurrentCckTxPwrIdx = cck_power_level;
++ //priv->CurrentOfdmTxPwrIdx = ofdm_power_level;
++#endif
++
++ if (NIC_8187B == priv->card_8187)
++ {
++ if (hw_version == VERSION_8187B_B)
++ {
++ min_cck_power_level = 0;
++ max_cck_power_level = 15;
++ min_ofdm_power_level = 2;
++ max_ofdm_power_level = 17;
++ }else
++ {
++ min_cck_power_level = 7;
++ max_cck_power_level = 22;
++ min_ofdm_power_level = 10;
++ max_ofdm_power_level = 25;
++ }
++
++ if( priv->TrSwitchState == TR_SW_TX )
++ {
++ //printk("SetTxPowerLevel8187(): Origianl OFDM Tx power level %d, adjust value = %d\n", ofdm_power_level,GetTxOfdmHighPowerBias(dev));
++ ofdm_power_level -= GetTxOfdmHighPowerBias(dev);
++ cck_power_level -= GetTxCckHighPowerBias(dev);
++ //printk("SetTxPowerLevel8187(): Adjusted OFDM Tx power level %d for we are in High Power state\n",
++ // ofdm_power_level);
++ //printk("SetTxPowerLevel8187(): Adjusted CCK Tx power level %d for we are in High Power state\n",
++ // cck_power_level);
++ }
++ /* CCK power setting */
++ if(cck_power_level > (max_cck_power_level -min_cck_power_level))
++ cck_power_level = max_cck_power_level;
++ else
++ cck_power_level += min_cck_power_level;
++ cck_power_level += priv->cck_txpwr_base;
++
++ if(cck_power_level > 35)
++ cck_power_level = 35;
++ if(cck_power_level < 0)
++ cck_power_level = 0;
++
++ if(ch == 14)
++ cck_power_table = rtl8225z2_tx_power_cck_ch14;
++ else
++ cck_power_table = rtl8225z2_tx_power_cck;
++ if (hw_version == VERSION_8187B_B)
++ {
++ if (cck_power_level <= 6){
++ }
++ else if (cck_power_level <=11){
++ cck_power_table += 8;
++ }
++ else{
++ cck_power_table += (8*2);
++ }
++ }else{
++ if (cck_power_level<=5){
++ }else if(cck_power_level<=11){
++ cck_power_table += 8;
++ }else if(cck_power_level <= 17){
++ cck_power_table += 8*2;
++ }else{
++ cck_power_table += 8*3;
++ }
++ }
++
++
++
++ for(i=0;i<8;i++){
++
++ power = cck_power_table[i];
++ write_phy_cck(dev, 0x44 + i, power);
++ }
++
++ //write_nic_byte(dev, TX_GAIN_CCK, power);
++ //2005.11.17,
++ write_nic_byte(dev, CCK_TXAGC, (ZEBRA2_CCK_OFDM_GAIN_SETTING[cck_power_level]*2));
++
++// force_pci_posting(dev);
++// msleep(1);
++//in windows the delay was del from 85 to 87,
++//here we mod to sleep, or The CPU occupany is too hight. LZM 31/10/2008
++
++ /* OFDM power setting */
++ // Old:
++ // if(ofdm_power_level > max_ofdm_power_level)
++ // ofdm_power_level = 35;
++ // ofdm_power_level += min_ofdm_power_level;
++ // Latest:
++ if(ofdm_power_level > (max_ofdm_power_level - min_ofdm_power_level))
++ ofdm_power_level = max_ofdm_power_level;
++ else
++ ofdm_power_level += min_ofdm_power_level;
++
++ ofdm_power_level += priv->ofdm_txpwr_base;
++
++ if(ofdm_power_level > 35)
++ ofdm_power_level = 35;
++
++ if(ofdm_power_level < 0)
++ ofdm_power_level = 0;
++ write_nic_byte(dev, OFDM_TXAGC, ZEBRA2_CCK_OFDM_GAIN_SETTING[ofdm_power_level]*2);
++
++ if (hw_version == VERSION_8187B_B)
++ {
++ if(ofdm_power_level<=11){
++ write_phy_ofdm(dev, 0x87, 0x60);
++ write_phy_ofdm(dev, 0x89, 0x60);
++ }
++ else{
++ write_phy_ofdm(dev, 0x87, 0x5c);
++ write_phy_ofdm(dev, 0x89, 0x5c);
++ }
++ }else{
++ if(ofdm_power_level<=11){
++ write_phy_ofdm(dev, 0x87, 0x5c);
++ write_phy_ofdm(dev, 0x89, 0x5c);
++ }
++ if(ofdm_power_level<=17){
++ write_phy_ofdm(dev, 0x87, 0x54);
++ write_phy_ofdm(dev, 0x89, 0x54);
++ }
++ else{
++ write_phy_ofdm(dev, 0x87, 0x50);
++ write_phy_ofdm(dev, 0x89, 0x50);
++ }
++ }
++// force_pci_posting(dev);
++// msleep(1);
++//in windows the delay was del from 85 to 87,
++//and here we mod to sleep, or The CPU occupany is too hight. LZM 31/10/2008
++ }else if(NIC_8187 == priv->card_8187) {
++ min_cck_power_level = 0;
++ max_cck_power_level = 15;
++ min_ofdm_power_level = 10;
++ max_ofdm_power_level = 25;
++ if(cck_power_level > (max_cck_power_level -min_cck_power_level))
++ cck_power_level = max_cck_power_level;
++ else
++ cck_power_level += min_cck_power_level;
++ cck_power_level += priv->cck_txpwr_base;
++
++ if(cck_power_level > 35)
++ cck_power_level = 35;
++
++ if(ch == 14)
++ cck_power_table = rtl8225z2_tx_power_cck_ch14;
++ else
++ cck_power_table = rtl8225z2_tx_power_cck;
++ for(i=0;i<8;i++){
++ power = cck_power_table[i];
++ write_phy_cck(dev, 0x44 + i, power);
++ }
++
++ //write_nic_byte(dev, TX_GAIN_CCK, power);
++ //2005.11.17,
++ write_nic_byte(dev, CCK_TXAGC, ZEBRA2_CCK_OFDM_GAIN_SETTING[cck_power_level]);
++
++// force_pci_posting(dev);
++// msleep(1);
++//in windows the delay was del from 85 to 87,
++//and here we mod to sleep, or The CPU occupany is too hight. LZM 31/10/2008
++ if(ofdm_power_level > (max_ofdm_power_level - min_ofdm_power_level))
++ ofdm_power_level = max_ofdm_power_level;
++ else
++ ofdm_power_level += min_ofdm_power_level;
++
++ ofdm_power_level += priv->ofdm_txpwr_base;
++
++ if(ofdm_power_level > 35)
++ ofdm_power_level = 35;
++ write_nic_byte(dev, OFDM_TXAGC, ZEBRA2_CCK_OFDM_GAIN_SETTING[ofdm_power_level]);
++
++ rtl8185_set_anaparam2(dev,RTL8225_ANAPARAM2_ON);
++
++ write_phy_ofdm(dev,2,0x42);
++ write_phy_ofdm(dev,5,0);
++ write_phy_ofdm(dev,6,0x40);
++ write_phy_ofdm(dev,7,0);
++ write_phy_ofdm(dev,8,0x40);
++ }
++
++}
++
++void rtl8225z2_rf_set_chan(struct net_device *dev, short ch)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ short gset = (priv->ieee80211->state == IEEE80211_LINKED &&
++ ieee80211_is_54g(priv->ieee80211->current_network)) ||
++ priv->ieee80211->iw_mode == IW_MODE_MONITOR;
++ int eifs_addr;
++
++ down(&priv->set_chan_sem);
++
++ if(NIC_8187 == priv->card_8187) {
++ eifs_addr = EIFS_8187;
++ } else {
++ eifs_addr = EIFS_8187B;
++ }
++
++#ifdef ENABLE_DOT11D
++ if(!IsLegalChannel(priv->ieee80211, ch) )
++ {
++ printk("channel(%d). is invalide\n", ch);
++ up(&priv->set_chan_sem);
++ return;
++ }
++#endif
++ //87B not do it FIXME
++ rtl8225z2_SetTXPowerLevel(dev, ch);
++
++ //write_nic_byte(dev,0x7,(u8)rtl8225_chan[ch]);
++ write_rtl8225(dev, 0x7, rtl8225_chan[ch]);
++
++ force_pci_posting(dev);
++ //mdelay(10);
++//in windows the delay was del from 85 to 87,
++//and here we mod to sleep, or The CPU occupany is too hight. LZM 31/10/2008
++ if(NIC_8187 == priv->card_8187){
++ write_nic_byte(dev,SIFS,0x22);// SIFS: 0x22
++
++ if(gset)
++ write_nic_byte(dev,DIFS,20); //DIFS: 20
++ else
++ write_nic_byte(dev,DIFS,0x24); //DIFS: 36
++
++ if(priv->ieee80211->state == IEEE80211_LINKED &&
++ ieee80211_is_shortslot(priv->ieee80211->current_network))
++ write_nic_byte(dev,SLOT,0x9); //SLOT: 9
++
++ else
++ write_nic_byte(dev,SLOT,0x14); //SLOT: 20 (0x14)
++
++
++ if(gset){
++ write_nic_byte(dev,eifs_addr,91 - 20); // EIFS: 91 (0x5B)
++ write_nic_byte(dev,CW_VAL,0x73); //CW VALUE: 0x37
++ //DMESG("using G net params");
++ }else{
++ write_nic_byte(dev,eifs_addr,91 - 0x24); // EIFS: 91 (0x5B)
++ write_nic_byte(dev,CW_VAL,0xa5); //CW VALUE: 0x37
++ //DMESG("using B net params");
++ }
++ }
++
++ else {
++#ifdef THOMAS_TURBO
++ if(priv->ieee80211->current_network.Turbo_Enable && priv->ieee80211->iw_mode == IW_MODE_INFRA){
++ write_nic_word(dev,AC_VO_PARAM,0x5114);
++ write_nic_word(dev,AC_VI_PARAM,0x5114);
++ write_nic_word(dev,AC_BE_PARAM,0x5114);
++ write_nic_word(dev,AC_BK_PARAM,0x5114);
++ } else {
++ write_nic_word(dev,AC_VO_PARAM,0x731c);
++ write_nic_word(dev,AC_VI_PARAM,0x731c);
++ write_nic_word(dev,AC_BE_PARAM,0x731c);
++ write_nic_word(dev,AC_BK_PARAM,0x731c);
++ }
++#endif
++ }
++
++ up(&priv->set_chan_sem);
++}
++void
++MacConfig_87BASIC_HardCode(struct net_device *dev)
++{
++ //============================================================================
++ // MACREG.TXT
++ //============================================================================
++ int nLinesRead = 0;
++ u32 u4bRegOffset, u4bRegValue, u4bPageIndex;
++ int i;
++
++ nLinesRead=(sizeof(MAC_REG_TABLE)/3)/4;
++
++ for(i = 0; i < nLinesRead; i++)
++ {
++ u4bRegOffset=MAC_REG_TABLE[i][0];
++ u4bRegValue=MAC_REG_TABLE[i][1];
++ u4bPageIndex=MAC_REG_TABLE[i][2];
++
++ u4bRegOffset|= (u4bPageIndex << 8);
++
++ write_nic_byte(dev, u4bRegOffset, (u8)u4bRegValue);
++ }
++ //============================================================================
++}
++
++static void MacConfig_87BASIC(struct net_device *dev)
++{
++ MacConfig_87BASIC_HardCode(dev);
++
++ //============================================================================
++
++ // Follow TID_AC_MAP of WMac.
++ //PlatformEFIOWrite2Byte(dev, TID_AC_MAP, 0xfa50);
++ write_nic_word(dev, TID_AC_MAP, 0xfa50);
++
++ // Interrupt Migration, Jong suggested we use set 0x0000 first, 2005.12.14, by rcnjko.
++ write_nic_word(dev, INT_MIG, 0x0000);
++
++ // Prevent TPC to cause CRC error. Added by Annie, 2006-06-10.
++ write_nic_dword(dev, 0x1F0, 0x00000000);
++ write_nic_dword(dev, 0x1F4, 0x00000000);
++ write_nic_byte(dev, 0x1F8, 0x00);
++
++ // For WiFi 5.2.2.5 Atheros AP performance. Added by Annie, 2006-06-12.
++ // PlatformIOWrite4Byte(dev, RFTiming, 0x0008e00f);
++ // Asked for by SD3 CM Lin, 2006.06.27, by rcnjko.
++ write_nic_dword(dev, RFTiming, 0x00004001);
++
++#ifdef TODO
++ // Asked for by Victor, for 87B B-cut Rx FIFO overflow bug, 2006.06.27, by rcnjko.
++ if(dev->NdisUsbDev.CardInfo.USBIsHigh == FALSE)
++ {
++ PlatformEFIOWrite1Byte(dev, 0x24E, 0x01);
++ }
++#endif
++}
++
++
++//
++// Description:
++// Initialize RFE and read Zebra2 version code.
++//
++// 2005-08-01, by Annie.
++//
++void
++SetupRFEInitialTiming(struct net_device* dev)
++{
++ //u32 data8, data9;
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ // setup initial timing for RFE
++ // Set VCO-PDN pin.
++ write_nic_word(dev, RFPinsOutput, 0x0480);
++ write_nic_word(dev, RFPinsSelect, 0x2488);
++ write_nic_word(dev, RFPinsEnable, 0x1FFF);
++
++ mdelay(100);
++ // Steven recommends: delay 1 sec for setting RF 1.8V. by Annie, 2005-04-28.
++ mdelay(1000);
++
++ //
++ // TODO: Read Zebra version code if necessary.
++ //
++ priv->rf_chip = RF_ZEBRA2;
++}
++
++
++void ZEBRA_Config_87BASIC_HardCode(struct net_device* dev)
++{
++ u32 i;
++ u32 addr,data;
++ u32 u4bRegOffset, u4bRegValue;
++
++
++ //=============================================================================
++ // RADIOCFG.TXT
++ //=============================================================================
++ write_rtl8225(dev, 0x00, 0x00b7); mdelay(1);
++ write_rtl8225(dev, 0x01, 0x0ee0); mdelay(1);
++ write_rtl8225(dev, 0x02, 0x044d); mdelay(1);
++ write_rtl8225(dev, 0x03, 0x0441); mdelay(1);
++ write_rtl8225(dev, 0x04, 0x08c3); mdelay(1);
++ write_rtl8225(dev, 0x05, 0x0c72); mdelay(1);
++ write_rtl8225(dev, 0x06, 0x00e6); mdelay(1);
++ write_rtl8225(dev, 0x07, 0x082a); mdelay(1);
++ write_rtl8225(dev, 0x08, 0x003f); mdelay(1);
++ write_rtl8225(dev, 0x09, 0x0335); mdelay(1);
++ write_rtl8225(dev, 0x0a, 0x09d4); mdelay(1);
++ write_rtl8225(dev, 0x0b, 0x07bb); mdelay(1);
++ write_rtl8225(dev, 0x0c, 0x0850); mdelay(1);
++ write_rtl8225(dev, 0x0d, 0x0cdf); mdelay(1);
++ write_rtl8225(dev, 0x0e, 0x002b); mdelay(1);
++ write_rtl8225(dev, 0x0f, 0x0114); mdelay(1);
++
++ write_rtl8225(dev, 0x00, 0x01b7); mdelay(1);
++
++
++ for(i=1;i<=95;i++)
++ {
++ write_rtl8225(dev, 0x01, i);mdelay(1);
++ write_rtl8225(dev, 0x02, ZEBRA_RF_RX_GAIN_TABLE[i]); mdelay(1);
++ //DbgPrint("RF - 0x%x = 0x%x\n", i, ZEBRA_RF_RX_GAIN_TABLE[i]);
++ }
++
++ write_rtl8225(dev, 0x03, 0x0080); mdelay(1); // write reg 18
++ write_rtl8225(dev, 0x05, 0x0004); mdelay(1); // write reg 20
++ write_rtl8225(dev, 0x00, 0x00b7); mdelay(1); // switch to reg0-reg15
++ //lzm mod for up take too long time 20081201
++#ifdef THOMAS_BEACON
++ msleep(1000);// Deay 1 sec. //0xfd
++ //msleep(1000);// Deay 1 sec. //0xfd
++ //msleep(1000);// Deay 1 sec. //0xfd
++ msleep(400);// Deay 1 sec. //0xfd
++#else
++
++ mdelay(1000);
++ //mdelay(1000);
++ //mdelay(1000);
++ mdelay(400);
++#endif
++ write_rtl8225(dev, 0x02, 0x0c4d); mdelay(1);
++ //lzm mod for up take too long time 20081201
++ //mdelay(1000);
++ //mdelay(1000);
++ msleep(100);// Deay 100 ms. //0xfe
++ msleep(100);// Deay 100 ms. //0xfe
++ write_rtl8225(dev, 0x02, 0x044d); mdelay(1);
++ write_rtl8225(dev, 0x00, 0x02bf); mdelay(1); //0x002f disable 6us corner change, 06f--> enable
++
++ //=============================================================================
++
++ //=============================================================================
++ // CCKCONF.TXT
++ //=============================================================================
++ /*
++ u4bRegOffset=0x41;
++ u4bRegValue=0xc8;
++
++ //DbgPrint("\nCCK- 0x%x = 0x%x\n", u4bRegOffset, u4bRegValue);
++ WriteBB(dev, (0x01000080 | (u4bRegOffset & 0x7f) | ((u4bRegValue & 0xff) << 8)));
++ */
++
++
++ //=============================================================================
++
++ //=============================================================================
++ // Follow WMAC RTL8225_Config()
++ //=============================================================================
++// //
++// // enable EEM0 and EEM1 in 9346CR
++// PlatformEFIOWrite1Byte(dev, CR9346, PlatformEFIORead1Byte(dev, CR9346)|0xc0);
++// // enable PARM_En in Config3
++// PlatformEFIOWrite1Byte(dev, CONFIG3, PlatformEFIORead1Byte(dev, CONFIG3)|0x40);
++//
++// PlatformEFIOWrite4Byte(dev, AnaParm2, ANAPARM2_ASIC_ON); //0x727f3f52
++// PlatformEFIOWrite4Byte(dev, AnaParm, ANAPARM_ASIC_ON); //0x45090658
++
++ // power control
++ write_nic_byte(dev, CCK_TXAGC, 0x03);
++ write_nic_byte(dev, OFDM_TXAGC, 0x07);
++ write_nic_byte(dev, ANTSEL, 0x03);
++
++// // disable PARM_En in Config3
++// PlatformEFIOWrite1Byte(dev, CONFIG3, PlatformEFIORead1Byte(dev, CONFIG3)&0xbf);
++// // disable EEM0 and EEM1 in 9346CR
++// PlatformEFIOWrite1Byte(dev, CR9346, PlatformEFIORead1Byte(dev, CR9346)&0x3f);
++ //=============================================================================
++
++ //=============================================================================
++ // AGC.txt
++ //=============================================================================
++ //write_nic_dword( dev, PhyAddr, 0x00001280); // Annie, 2006-05-05
++ //write_phy_ofdm( dev, 0x00, 0x12); // David, 2006-08-01
++ write_phy_ofdm( dev, 0x80, 0x12); // David, 2006-08-09
++
++ for (i=0; i<128; i++)
++ {
++ //DbgPrint("AGC - [%x+1] = 0x%x\n", i, ZEBRA_AGC[i+1]);
++
++ data = ZEBRA_AGC[i+1];
++ data = data << 8;
++ data = data | 0x0000008F;
++
++ addr = i + 0x80; //enable writing AGC table
++ addr = addr << 8;
++ addr = addr | 0x0000008E;
++
++ write_phy_ofdm(dev,data&0x7f,(data>>8)&0xff);
++ write_phy_ofdm(dev,addr&0x7f,(addr>>8)&0xff);
++ write_phy_ofdm(dev,0x0E,0x00);
++ }
++
++ //write_nic_dword(dev, PhyAddr, 0x00001080); // Annie, 2006-05-05
++ //write_phy_ofdm( dev, 0x00, 0x10); // David, 2006-08-01
++ write_phy_ofdm( dev, 0x80, 0x10); // David, 2006-08-09
++
++ //=============================================================================
++
++ //=============================================================================
++ // OFDMCONF.TXT
++ //=============================================================================
++
++ for(i=0; i<60; i++)
++ {
++ u4bRegOffset=i;
++ u4bRegValue=OFDM_CONFIG[i];
++ //u4bRegValue=OFDM_CONFIG3m82[i];
++
++ // write_nic_dword(dev,PhyAddr,(0x00000080 | (u4bRegOffset & 0x7f) | ((u4bRegValue & 0xff) << 8)));
++ write_phy_ofdm(dev,i,u4bRegValue);
++ }
++
++
++ //=============================================================================
++}
++
++void ZEBRA_Config_87BASIC(struct net_device *dev)
++{
++ ZEBRA_Config_87BASIC_HardCode(dev);
++}
++//by amy for DIG
++//
++// Description:
++// Update initial gain into PHY.
++//
++void
++UpdateCCKThreshold(
++ struct net_device *dev
++ )
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ // Update CCK Power Detection(0x41) value.
++ switch(priv->StageCCKTh)
++ {
++ case 0:
++// printk("Update CCK Stage 0: 88 \n");
++ write_phy_cck(dev, 0xc1, 0x88);mdelay(1);
++ break;
++
++ case 1:
++// printk("Update CCK Stage 1: 98 \n");
++ write_phy_cck(dev, 0xc1, 0x98);mdelay(1);
++ break;
++
++ case 2:
++// printk("Update CCK Stage 2: C8 \n");
++ write_phy_cck(dev, 0xc1, 0xC8);mdelay(1);
++ break;
++
++ case 3:
++// printk("Update CCK Stage 3: D8 \n");
++ write_phy_cck(dev, 0xc1, 0xD8);mdelay(1);
++ break;
++
++ default:
++// printk("Update CCK Stage %d ERROR!\n", pHalData->StageCCKTh);
++ break;
++ }
++}
++//
++// Description:
++// Update initial gain into PHY.
++//
++void
++UpdateInitialGain(
++ struct net_device *dev
++ )
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ //u8 u1Tmp=0;
++
++ //printk("UpdateInitialGain(): InitialGain: %d RFChipID: %d\n", priv->InitialGain, priv->rf_chip);
++
++ switch(priv->rf_chip)
++ {
++ case RF_ZEBRA:
++ case RF_ZEBRA2:
++
++ //
++ // Note:
++ // Whenever we update this gain table, we should be careful about those who call it.
++ // Functions which call UpdateInitialGain as follows are important:
++ // (1)StaRateAdaptive87B
++ // (2)DIG_Zebra
++ // (3)ActSetWirelessMode8187 (when the wireless mode is "B" mode, we set the
++ // OFDM[0x17] = 0x26 to improve the Rx sensitivity).
++ // By Bruce, 2007-06-01.
++ //
++
++ //
++ // SD3 C.M. Lin Initial Gain Table, by Bruce, 2007-06-01.
++ //
++ switch(priv->InitialGain)
++ {
++ case 1: //m861dBm
++ DMESG("RTL8187 + 8225 Initial Gain State 1: -82 dBm ");
++ write_phy_ofdm(dev, 0x97, 0x26); mdelay(1);
++ write_phy_ofdm(dev, 0xa4, 0x86); mdelay(1);
++ write_phy_ofdm(dev, 0x85, 0xfa); mdelay(1);
++ break;
++
++ case 2: //m862dBm
++ DMESG("RTL8187 + 8225 Initial Gain State 2: -78 dBm ");
++ write_phy_ofdm(dev, 0x97, 0x36); mdelay(1);// Revise 0x26 to 0x36, by Roger, 2007.05.03.
++ write_phy_ofdm(dev, 0xa4, 0x86); mdelay(1);
++ write_phy_ofdm(dev, 0x85, 0xfa); mdelay(1);
++ break;
++
++ case 3: //m863dBm
++ DMESG("RTL8187 + 8225 Initial Gain State 3: -78 dBm ");
++ write_phy_ofdm(dev, 0x97, 0x36); mdelay(1);// Revise 0x26 to 0x36, by Roger, 2007.05.03.
++ write_phy_ofdm(dev, 0xa4, 0x86); mdelay(1);
++ write_phy_ofdm(dev, 0x85, 0xfb); mdelay(1);
++ break;
++
++ case 4: //m864dBm
++ DMESG("RTL8187 + 8225 Initial Gain State 4: -74 dBm ");
++ write_phy_ofdm(dev, 0x97, 0x46); mdelay(1);// Revise 0x26 to 0x36, by Roger, 2007.05.03.
++ write_phy_ofdm(dev, 0xa4, 0x86); mdelay(1);
++ write_phy_ofdm(dev, 0x85, 0xfb); mdelay(1);
++ break;
++
++ case 5: //m82dBm
++ DMESG("RTL8187 + 8225 Initial Gain State 5: -74 dBm ");
++ write_phy_ofdm(dev, 0x97, 0x46); mdelay(1);
++ write_phy_ofdm(dev, 0xa4, 0x96); mdelay(1);
++ write_phy_ofdm(dev, 0x85, 0xfb); mdelay(1);
++ break;
++
++ case 6: //m78dBm
++ DMESG("RTL8187 + 8225 Initial Gain State 6: -70 dBm ");
++ write_phy_ofdm(dev, 0x97, 0x56); mdelay(1);
++ write_phy_ofdm(dev, 0xa4, 0x96); mdelay(1);
++ write_phy_ofdm(dev, 0x85, 0xfc); mdelay(1);
++ break;
++
++ case 7: //m74dBm
++ DMESG("RTL8187 + 8225 Initial Gain State 7: -70 dBm ");
++ write_phy_ofdm(dev, 0x97, 0x56); mdelay(1);
++ write_phy_ofdm(dev, 0xa4, 0xa6); mdelay(1);
++ write_phy_ofdm(dev, 0x85, 0xfc); mdelay(1);
++ break;
++
++ // By Bruce, 2007-03-29.
++ case 8:
++ write_phy_ofdm(dev, 0x97, 0x66); mdelay(1);
++ write_phy_ofdm(dev, 0xa4, 0xb6); mdelay(1);
++ write_phy_ofdm(dev, 0x85, 0xfc); mdelay(1);
++ break;
++
++ default: //MP
++ DMESG("RTL8187 + 8225 Initial Gain State: -82 dBm (default), InitialGain(%d)", priv->InitialGain);
++ write_phy_ofdm(dev, 0x97, 0x26); mdelay(1);
++ write_phy_ofdm(dev, 0xa4, 0x86); mdelay(1);
++ write_phy_ofdm(dev, 0x85, 0xfa); mdelay(1);
++ break;
++ }
++ break;
++
++ default:
++ break;
++ }
++}
++//by amy for DIG
++void PhyConfig8187(struct net_device *dev)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ u8 btConfig4;
++
++ btConfig4 = read_nic_byte(dev, CONFIG4);
++ priv->RFProgType = (btConfig4 & 0x03);
++
++
++
++ switch(priv->rf_chip)
++ {
++ case RF_ZEBRA2:
++ ZEBRA_Config_87BASIC(dev);
++ break;
++ }
++ if(priv->bDigMechanism)
++ {
++ if(priv->InitialGain == 0)
++ priv->InitialGain = 4;
++ DMESG("DIG is enabled, set default initial gain index to %d", priv->InitialGain);
++ }
++
++ // By Bruce, 2007-03-29.
++ UpdateCCKThreshold(dev);
++ // Update initial gain after PhyConfig comleted, asked for by SD3 CMLin.
++ UpdateInitialGain(dev);
++ return ;
++}
++
++u8 GetSupportedWirelessMode8187(struct net_device* dev)
++{
++ u8 btSupportedWirelessMode;
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ btSupportedWirelessMode = 0;
++
++ switch(priv->rf_chip)
++ {
++ case RF_ZEBRA:
++ case RF_ZEBRA2:
++ btSupportedWirelessMode = (WIRELESS_MODE_B | WIRELESS_MODE_G);
++ break;
++ default:
++ btSupportedWirelessMode = WIRELESS_MODE_B;
++ break;
++ }
++ return btSupportedWirelessMode;
++}
++
++void ActUpdateChannelAccessSetting(struct net_device *dev,
++ int WirelessMode,
++ PCHANNEL_ACCESS_SETTING ChnlAccessSetting)
++{
++ AC_CODING eACI;
++ AC_PARAM AcParam;
++#ifdef TODO
++ PSTA_QOS pStaQos = Adapter->MgntInfo.pStaQos;
++#endif
++ //bool bFollowLegacySetting = false;
++
++
++ switch( WirelessMode )
++ {
++ case WIRELESS_MODE_A:
++ ChnlAccessSetting->SIFS_Timer = 0x22;
++ ChnlAccessSetting->DIFS_Timer = 34; // 34 = 16 + 2*9. 2006.06.07, by rcnjko.
++ ChnlAccessSetting->SlotTimeTimer = 9;
++ ChnlAccessSetting->EIFS_Timer = 23;
++ ChnlAccessSetting->CWminIndex = 4;
++ ChnlAccessSetting->CWmaxIndex = 10;
++ break;
++
++ case WIRELESS_MODE_B:
++ ChnlAccessSetting->SIFS_Timer = 0x22;
++ ChnlAccessSetting->DIFS_Timer = 50; // 50 = 10 + 2*20. 2006.06.07, by rcnjko.
++ ChnlAccessSetting->SlotTimeTimer = 20;
++ ChnlAccessSetting->EIFS_Timer = 91;
++ ChnlAccessSetting->CWminIndex = 5;
++ ChnlAccessSetting->CWmaxIndex = 10;
++ break;
++
++ case WIRELESS_MODE_G:
++ //
++ // <RJ_TODO_8185B>
++ // TODO: We still don't know how to set up these registers, just follow WMAC to
++ // verify 8185B FPAG.
++ //
++ // <RJ_TODO_8185B>
++ // Jong said CWmin/CWmax register are not functional in 8185B,
++ // so we shall fill channel access realted register into AC parameter registers,
++ // even in nQBss.
++ //
++ ChnlAccessSetting->SIFS_Timer = 0x22; // Suggested by Jong, 2005.12.08.
++ ChnlAccessSetting->SlotTimeTimer = 9; // 2006.06.07, by rcnjko.
++ ChnlAccessSetting->DIFS_Timer = 28; // 28 = 10 + 2*9. 2006.06.07, by rcnjko.
++ ChnlAccessSetting->EIFS_Timer = 0x5B; // Suggested by wcchu, it is the default value of EIFS register, 2005.12.08.
++#ifdef TODO
++ switch (Adapter->NdisUsbDev.CWinMaxMin)
++#else
++ switch (2)
++#endif
++ {
++ case 0:// 0: [max:7 min:1 ]
++ ChnlAccessSetting->CWminIndex = 1;
++ ChnlAccessSetting->CWmaxIndex = 7;
++ break;
++ case 1:// 1: [max:7 min:2 ]
++ ChnlAccessSetting->CWminIndex = 2;
++ ChnlAccessSetting->CWmaxIndex = 7;
++ break;
++ case 2:// 2: [max:7 min:3 ]
++ ChnlAccessSetting->CWminIndex = 3;
++ ChnlAccessSetting->CWmaxIndex = 7;
++ break;
++ case 3:// 3: [max:9 min:1 ]
++ ChnlAccessSetting->CWminIndex = 1;
++ ChnlAccessSetting->CWmaxIndex = 9;
++ break;
++ case 4:// 4: [max:9 min:2 ]
++ ChnlAccessSetting->CWminIndex = 2;
++ ChnlAccessSetting->CWmaxIndex = 9;
++ break;
++ case 5:// 5: [max:9 min:3 ]
++ ChnlAccessSetting->CWminIndex = 3;
++ ChnlAccessSetting->CWmaxIndex = 9;
++ break;
++ case 6:// 6: [max:A min:5 ]
++ ChnlAccessSetting->CWminIndex = 5;
++ ChnlAccessSetting->CWmaxIndex = 10;
++ break;
++ case 7:// 7: [max:A min:4 ]
++ ChnlAccessSetting->CWminIndex = 4;
++ ChnlAccessSetting->CWmaxIndex = 10;
++ break;
++
++ default:
++ ChnlAccessSetting->CWminIndex = 1;
++ ChnlAccessSetting->CWmaxIndex = 7;
++ break;
++ }
++#ifdef TODO
++ if( Adapter->MgntInfo.OpMode == RT_OP_MODE_IBSS)
++ {
++ ChnlAccessSetting->CWminIndex= 4;
++ ChnlAccessSetting->CWmaxIndex= 10;
++ }
++#endif
++ break;
++ }
++
++
++ write_nic_byte(dev, SIFS, ChnlAccessSetting->SIFS_Timer);
++//{ update slot time related by david, 2006-7-21
++ write_nic_byte(dev, SLOT, ChnlAccessSetting->SlotTimeTimer); // Rewrited from directly use PlatformEFIOWrite1Byte(), by Annie, 2006-03-29.
++#ifdef TODO
++ if(pStaQos->CurrentQosMode > QOS_DISABLE)
++ {
++ for(eACI = 0; eACI < AC_MAX; eACI++)
++ {
++ Adapter->HalFunc.SetHwRegHandler(Adapter, HW_VAR_AC_PARAM, \
++ (pu1Byte)(&(pStaQos->WMMParamEle.AcParam[eACI])) );
++ }
++ }
++ else
++#endif
++ {
++ u8 u1bAIFS = aSifsTime + (2 * ChnlAccessSetting->SlotTimeTimer );
++
++ write_nic_byte(dev, AC_VO_PARAM, u1bAIFS);
++ write_nic_byte(dev, AC_VI_PARAM, u1bAIFS);
++ write_nic_byte(dev, AC_BE_PARAM, u1bAIFS);
++ write_nic_byte(dev, AC_BK_PARAM, u1bAIFS);
++ }
++//}
++
++ write_nic_byte(dev, EIFS_8187B, ChnlAccessSetting->EIFS_Timer);
++ write_nic_byte(dev, AckTimeOutReg, 0x5B); // <RJ_EXPR_QOS> Suggested by wcchu, it is the default value of EIFS register, 2005.12.08.
++#ifdef TODO
++ // <RJ_TODO_NOW_8185B> Update ECWmin/ECWmax, AIFS, TXOP Limit of each AC to the value defined by SPEC.
++ if( pStaQos->CurrentQosMode > QOS_DISABLE )
++ { // QoS mode.
++ if(pStaQos->QBssWirelessMode == WirelessMode)
++ {
++ // Follow AC Parameters of the QBSS.
++ for(eACI = 0; eACI < AC_MAX; eACI++)
++ {
++ Adapter->HalFunc.SetHwRegHandler(Adapter, HW_VAR_AC_PARAM, (pu1Byte)(&(pStaQos->WMMParamEle.AcParam[eACI])) );
++ }
++ }
++ else
++ {
++ // Follow Default WMM AC Parameters.
++ bFollowLegacySetting = TRUE;
++ }
++ }
++ else
++ { // Legacy 802.11.
++ bFollowLegacySetting = TRUE;
++ }
++
++ if(bFollowLegacySetting)
++#endif
++ if(true)
++ {
++ //
++ // Follow 802.11 seeting to AC parameter, all AC shall use the same parameter.
++ // 2005.12.01, by rcnjko.
++ //
++ AcParam.longData = 0;
++ AcParam.f.AciAifsn.f.AIFSN = 2; // Follow 802.11 DIFS.
++ AcParam.f.AciAifsn.f.ACM = 0;
++ AcParam.f.Ecw.f.ECWmin = ChnlAccessSetting->CWminIndex; // Follow 802.11 CWmin.
++ AcParam.f.Ecw.f.ECWmax = ChnlAccessSetting->CWmaxIndex; // Follow 802.11 CWmax.
++ AcParam.f.TXOPLimit = 0;
++ for(eACI = 0; eACI < AC_MAX; eACI++)
++ {
++ AcParam.f.AciAifsn.f.ACI = (u8)eACI;
++ {
++ PAC_PARAM pAcParam = (PAC_PARAM)(&AcParam);
++ AC_CODING eACI;
++ u8 u1bAIFS;
++ u32 u4bAcParam;
++
++ // Retrive paramters to udpate.
++ eACI = pAcParam->f.AciAifsn.f.ACI;
++ u1bAIFS = pAcParam->f.AciAifsn.f.AIFSN * ChnlAccessSetting->SlotTimeTimer + aSifsTime;
++ u4bAcParam = ( (((u32)(pAcParam->f.TXOPLimit)) << AC_PARAM_TXOP_LIMIT_OFFSET) |
++ (((u32)(pAcParam->f.Ecw.f.ECWmax)) << AC_PARAM_ECW_MAX_OFFSET) |
++ (((u32)(pAcParam->f.Ecw.f.ECWmin)) << AC_PARAM_ECW_MIN_OFFSET) |
++ (((u32)u1bAIFS) << AC_PARAM_AIFS_OFFSET));
++
++ switch(eACI)
++ {
++ case AC1_BK:
++ write_nic_dword(dev, AC_BK_PARAM, u4bAcParam);
++ break;
++
++ case AC0_BE:
++ write_nic_dword(dev, AC_BE_PARAM, u4bAcParam);
++ break;
++
++ case AC2_VI:
++ write_nic_dword(dev, AC_VI_PARAM, u4bAcParam);
++ break;
++
++ case AC3_VO:
++ write_nic_dword(dev, AC_VO_PARAM, u4bAcParam);
++ break;
++
++ default:
++ printk(KERN_WARNING "SetHwReg8185(): invalid ACI: %d !\n", eACI);
++ break;
++ }
++
++ // Cehck ACM bit.
++ // If it is set, immediately set ACM control bit to downgrading AC for passing WMM testplan. Annie, 2005-12-13.
++ //write_nic_byte(dev, ACM_CONTROL, pAcParam->f.AciAifsn);
++ {
++ PACI_AIFSN pAciAifsn = (PACI_AIFSN)(&pAcParam->f.AciAifsn);
++ AC_CODING eACI = pAciAifsn->f.ACI;
++
++ //modified Joseph
++ //for 8187B AsynIORead issue
++#ifdef TODO
++ u8 AcmCtrl = pHalData->AcmControl;
++#else
++ u8 AcmCtrl = 0;
++#endif
++ if( pAciAifsn->f.ACM )
++ { // ACM bit is 1.
++ switch(eACI)
++ {
++ case AC0_BE:
++ AcmCtrl |= (BEQ_ACM_EN|BEQ_ACM_CTL|ACM_HW_EN); // or 0x21
++ break;
++
++ case AC2_VI:
++ AcmCtrl |= (VIQ_ACM_EN|VIQ_ACM_CTL|ACM_HW_EN); // or 0x42
++ break;
++
++ case AC3_VO:
++ AcmCtrl |= (VOQ_ACM_EN|VOQ_ACM_CTL|ACM_HW_EN); // or 0x84
++ break;
++
++ default:
++ printk(KERN_WARNING "SetHwReg8185(): [HW_VAR_ACM_CTRL] ACM set\
++ failed: eACI is %d\n", eACI );
++ break;
++ }
++ }
++ else
++ { // ACM bit is 0.
++ switch(eACI)
++ {
++ case AC0_BE:
++ AcmCtrl &= ( (~BEQ_ACM_EN) & (~BEQ_ACM_CTL) & (~ACM_HW_EN) ); // and 0xDE
++ break;
++
++ case AC2_VI:
++ AcmCtrl &= ( (~VIQ_ACM_EN) & (~VIQ_ACM_CTL) & (~ACM_HW_EN) ); // and 0xBD
++ break;
++
++ case AC3_VO:
++ AcmCtrl &= ( (~VOQ_ACM_EN) & (~VOQ_ACM_CTL) & (~ACM_HW_EN) ); // and 0x7B
++ break;
++
++ default:
++ break;
++ }
++ }
++
++ //printk(KERN_WARNING "SetHwReg8185(): [HW_VAR_ACM_CTRL] Write 0x%X\n", AcmCtrl);
++
++#ifdef TO_DO
++ pHalData->AcmControl = AcmCtrl;
++#endif
++ write_nic_byte(dev, ACM_CONTROL, AcmCtrl);
++ }
++ }
++ }
++ }
++}
++
++void ActSetWirelessMode8187(struct net_device* dev, u8 btWirelessMode)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ struct ieee80211_device *ieee = priv->ieee80211;
++ //PMGNT_INFO pMgntInfo = &(pAdapter->MgntInfo);
++ u8 btSupportedWirelessMode = GetSupportedWirelessMode8187(dev);
++
++ if( (btWirelessMode & btSupportedWirelessMode) == 0 )
++ { // Don't switch to unsupported wireless mode, 2006.02.15, by rcnjko.
++ printk(KERN_WARNING "ActSetWirelessMode8187(): WirelessMode(%d) is not supported (%d)!\n",
++ btWirelessMode, btSupportedWirelessMode);
++ return;
++ }
++
++ // 1. Assign wireless mode to swtich if necessary.
++ if( (btWirelessMode == WIRELESS_MODE_AUTO) ||
++ (btWirelessMode & btSupportedWirelessMode) == 0 )
++ {
++ if((btSupportedWirelessMode & WIRELESS_MODE_A))
++ {
++ btWirelessMode = WIRELESS_MODE_A;
++ }
++ else if((btSupportedWirelessMode & WIRELESS_MODE_G))
++ {
++ btWirelessMode = WIRELESS_MODE_G;
++ }
++ else if((btSupportedWirelessMode & WIRELESS_MODE_B))
++ {
++ btWirelessMode = WIRELESS_MODE_B;
++ }
++ else
++ {
++ printk(KERN_WARNING "MptActSetWirelessMode8187(): No valid wireless mode supported, \
++ btSupportedWirelessMode(%x)!!!\n", btSupportedWirelessMode);
++ btWirelessMode = WIRELESS_MODE_B;
++ }
++ }
++
++ // 2. Swtich band.
++ switch(priv->rf_chip)
++ {
++ case RF_ZEBRA:
++ case RF_ZEBRA2:
++ {
++ // Update current wireless mode if we swtich to specified band successfully.
++ ieee->mode = (WIRELESS_MODE)btWirelessMode;
++ }
++ break;
++
++ default:
++ printk(KERN_WARNING "MptActSetWirelessMode8187(): unsupported RF: 0x%X !!!\n", priv->rf_chip);
++ break;
++ }
++
++ // 4. Change related setting.
++ if( ieee->mode == WIRELESS_MODE_A ){
++ DMESG("WIRELESS_MODE_A");
++ }
++ else if(ieee->mode == WIRELESS_MODE_B ){
++ DMESG("WIRELESS_MODE_B");
++ }
++ else if( ieee->mode == WIRELESS_MODE_G ){
++ DMESG("WIRELESS_MODE_G");
++ }
++ ActUpdateChannelAccessSetting(dev, ieee->mode, &priv->ChannelAccessSetting );
++//by amy 0305
++#ifdef TODO
++ if(ieee->mode == WIRELESS_MODE_B && priv->InitialGain > pHalData->RegBModeGainStage)
++ {
++ pHalData->InitialGain = pHalData->RegBModeGainStage; // B mode, OFDM[0x17] = 26.
++ RT_TRACE(COMP_INIT | COMP_DIG, DBG_LOUD, ("ActSetWirelessMode8187(): update init_gain to index %d for B mode\n",pHalData->InitialGain));
++ PlatformScheduleWorkItem( &(pHalData->UpdateDigWorkItem) );
++ }
++// pAdapter->MgntInfo.dot11CurrentWirelessMode = pHalData->CurrentWirelessMode;
++// MgntSetRegdot11OperationalRateSet( pAdapter );
++#endif
++//by amy 0305
++}
++
++
++void
++InitializeExtraRegsOn8185(struct net_device *dev)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ struct ieee80211_device *ieee = priv->ieee80211;
++ //RTL8185_TODO: Determine Retrylimit, TxAGC, AutoRateFallback control.
++ bool bUNIVERSAL_CONTROL_RL = false; // Enable per-packet tx retry, 2005.03.31, by rcnjko.
++ bool bUNIVERSAL_CONTROL_AGC = true;//false;
++ bool bUNIVERSAL_CONTROL_ANT = true;//false;
++ bool bAUTO_RATE_FALLBACK_CTL = true;
++ u8 val8;
++
++ // Set up ACK rate.
++ // Suggested by wcchu, 2005.08.25, by rcnjko.
++ // 1. Initialize (MinRR, MaxRR) to (6,24) for A/G.
++ // 2. MUST Set RR before BRSR.
++ // 3. CCK must be basic rate.
++ if((ieee->mode == IEEE_G)||(ieee->mode == IEEE_A))
++ {
++ write_nic_word(dev, BRSR_8187B, 0x0fff);
++ }
++ else
++ {
++ write_nic_word(dev, BRSR_8187B, 0x000f);
++ }
++
++
++ // Retry limit
++ val8 = read_nic_byte(dev, CW_CONF);
++ if(bUNIVERSAL_CONTROL_RL)
++ {
++ val8 &= (~CW_CONF_PERPACKET_RETRY_LIMIT);
++ }
++ else
++ {
++ val8 |= CW_CONF_PERPACKET_RETRY_LIMIT;
++ }
++
++ write_nic_byte(dev, CW_CONF, val8);
++
++ // Tx AGC
++ val8 = read_nic_byte(dev, TX_AGC_CTL);
++ if(bUNIVERSAL_CONTROL_AGC)
++ {
++ val8 &= (~TX_AGC_CTL_PER_PACKET_TXAGC);
++ write_nic_byte(dev, CCK_TXAGC, 128);
++ write_nic_byte(dev, OFDM_TXAGC, 128);
++ }
++ else
++ {
++ val8 |= TX_AGC_CTL_PER_PACKET_TXAGC;
++ }
++ write_nic_byte(dev, TX_AGC_CTL, val8);
++
++ // Tx Antenna including Feedback control
++ val8 = read_nic_byte(dev, TX_AGC_CTL);
++
++ if(bUNIVERSAL_CONTROL_ANT)
++ {
++ write_nic_byte(dev, ANTSEL, 0x00);
++ val8 &= (~TXAGC_CTL_PER_PACKET_ANT_SEL);
++ }
++ else
++ {
++ val8 |= TXAGC_CTL_PER_PACKET_ANT_SEL;
++ }
++ write_nic_byte(dev, TX_AGC_CTL, val8);
++
++ // Auto Rate fallback control
++ val8 = read_nic_byte(dev, RATE_FALLBACK);
++ if( bAUTO_RATE_FALLBACK_CTL )
++ {
++ val8 |= RATE_FALLBACK_CTL_ENABLE | RATE_FALLBACK_CTL_AUTO_STEP0;
++
++ // <RJ_TODO_8187B> We shall set up the ARFR according to user's setting.
++ write_nic_word(dev, ARFR, 0x0fff); // set 1M ~ 54M
++ }
++ else
++ {
++ val8 &= (~RATE_FALLBACK_CTL_ENABLE);
++ }
++ write_nic_byte(dev, RATE_FALLBACK, val8);
++
++}
++///////////////////////////
++void rtl8225z2_rf_init(struct net_device *dev)
++{
++
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ if (NIC_8187B == priv->card_8187){
++ struct ieee80211_device *ieee = priv->ieee80211;
++ u8 InitWirelessMode;
++ u8 SupportedWirelessMode;
++ bool bInvalidWirelessMode = false;
++ InitializeExtraRegsOn8185(dev);
++
++ write_nic_byte(dev, MSR, read_nic_byte(dev,MSR) & 0xf3); // default network type to 'No Link'
++ //{to avoid tx stall
++ write_nic_byte(dev, MSR, read_nic_byte(dev, MSR)|MSR_LINK_ENEDCA);//should always set ENDCA bit
++ write_nic_byte(dev, ACM_CONTROL, priv->AcmControl);
++
++ write_nic_word(dev, BcnIntv, 100);
++ write_nic_word(dev, AtimWnd, 2);
++ write_nic_word(dev, FEMR, 0xFFFF);
++ //LED TYPE
++ {
++ write_nic_byte(dev, CONFIG1,((read_nic_byte(dev, CONFIG1)&0x3f)|0x80)); //turn on bit 5:Clkrun_mode
++ }
++ write_nic_byte(dev, CR9346, 0x0); // disable config register write
++
++ //{ add some info here
++ write_nic_dword(dev, MAC0, ((u32*)dev->dev_addr)[0]);
++ write_nic_word(dev, MAC4, ((u32*)dev->dev_addr)[1] & 0xffff );
++
++ write_nic_byte(dev, WPA_CONFIG, 0);
++ //}
++
++ MacConfig_87BASIC(dev);
++
++ // Override the RFSW_CTRL (MAC offset 0x272-0x273), 2006.06.07, by rcnjko.
++ write_nic_word(dev, RFSW_CTRL, 0x569a);
++#ifdef JOHN_TKIP
++ {
++ void CamResetAllEntry(struct net_device *dev);
++ void EnableHWSecurityConfig8187(struct net_device *dev);
++ CamResetAllEntry(dev);
++ EnableHWSecurityConfig8187(dev);
++ write_nic_word(dev, AESMSK_FC, AESMSK_FC_DEFAULT); mdelay(1);
++ write_nic_word(dev, AESMSK_SC, AESMSK_SC_DEFAULT); mdelay(1);
++ write_nic_word(dev, AESMSK_QC, AESMSK_QC_DEFAULT); mdelay(1);
++ }
++#endif
++ //-----------------------------------------------------------------------------
++ // Set up PHY related.
++ //-----------------------------------------------------------------------------
++ // Enable Config3.PARAM_En to revise AnaaParm.
++ write_nic_byte(dev, CR9346, 0xC0);
++ write_nic_byte(dev, CONFIG3, read_nic_byte(dev,CONFIG3)|CONFIG3_PARM_En);
++ write_nic_byte(dev, CR9346, 0x0);
++
++ // Initialize RFE and read Zebra2 version code. Added by Annie, 2005-08-01.
++ SetupRFEInitialTiming(dev);
++ // PHY config.
++ PhyConfig8187(dev);
++
++ // We assume RegWirelessMode has already been initialized before,
++ // however, we has to validate the wireless mode here and provide a reasonble
++ // initialized value if necessary. 2005.01.13, by rcnjko.
++ SupportedWirelessMode = GetSupportedWirelessMode8187(dev);
++
++ if((ieee->mode != WIRELESS_MODE_B) &&
++ (ieee->mode != WIRELESS_MODE_G) &&
++ (ieee->mode != WIRELESS_MODE_A) &&
++ (ieee->mode != WIRELESS_MODE_AUTO))
++ { // It should be one of B, G, A, or AUTO.
++ bInvalidWirelessMode = true;
++ }
++ else
++ { // One of B, G, A, or AUTO.
++ // Check if the wireless mode is supported by RF.
++ if( (ieee->mode != WIRELESS_MODE_AUTO) &&
++ (ieee->mode & SupportedWirelessMode) == 0 )
++ {
++ bInvalidWirelessMode = true;
++ }
++ }
++
++ if(bInvalidWirelessMode || ieee->mode==WIRELESS_MODE_AUTO)
++ { // Auto or other invalid value.
++ // Assigne a wireless mode to initialize.
++ if((SupportedWirelessMode & WIRELESS_MODE_A))
++ {
++ InitWirelessMode = WIRELESS_MODE_A;
++ }
++ else if((SupportedWirelessMode & WIRELESS_MODE_G))
++ {
++
++ InitWirelessMode = WIRELESS_MODE_G;
++ }
++ else if((SupportedWirelessMode & WIRELESS_MODE_B))
++ {
++
++ InitWirelessMode = WIRELESS_MODE_B;
++ }
++ else
++ {
++ printk(KERN_WARNING
++ "InitializeAdapter8187(): No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n",
++ SupportedWirelessMode);
++ InitWirelessMode = WIRELESS_MODE_B;
++ }
++
++ // Initialize RegWirelessMode if it is not a valid one.
++ if(bInvalidWirelessMode)
++ {
++ ieee->mode = (WIRELESS_MODE)InitWirelessMode;
++ }
++ }
++ else
++ { // One of B, G, A.
++ InitWirelessMode = ieee->mode;
++ }
++ ActSetWirelessMode8187(dev, (u8)(InitWirelessMode));
++ {//added for init gain
++ write_phy_ofdm(dev, 0x97, 0x46); mdelay(1);
++ write_phy_ofdm(dev, 0xa4, 0xb6); mdelay(1);
++ write_phy_ofdm(dev, 0x85, 0xfc); mdelay(1);
++ write_phy_cck(dev, 0xc1, 0x88); mdelay(1);
++ }
++
++ }
++ else{
++ int i;
++ short channel = 1;
++ u16 brsr;
++ u32 data,addr;
++
++ priv->chan = channel;
++
++ rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
++
++ if(priv->card_type == USB)
++ rtl8225_host_usb_init(dev);
++ else
++ rtl8225_host_pci_init(dev);
++
++ write_nic_dword(dev, RF_TIMING, 0x000a8008);
++
++ brsr = read_nic_word(dev, BRSR_8187);
++
++ write_nic_word(dev, BRSR_8187, 0xffff);
++
++
++ write_nic_dword(dev, RF_PARA, 0x100044);
++
++ #if 1 //0->1
++ rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
++ write_nic_byte(dev, CONFIG3, 0x44);
++ rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
++ #endif
++
++
++ rtl8185_rf_pins_enable(dev);
++
++ // mdelay(1000);
++
++ write_rtl8225(dev, 0x0, 0x2bf); mdelay(1);
++
++
++ write_rtl8225(dev, 0x1, 0xee0); mdelay(1);
++
++ write_rtl8225(dev, 0x2, 0x44d); mdelay(1);
++
++ write_rtl8225(dev, 0x3, 0x441); mdelay(1);
++
++
++ write_rtl8225(dev, 0x4, 0x8c3);mdelay(1);
++
++
++
++ write_rtl8225(dev, 0x5, 0xc72);mdelay(1);
++ // }
++
++ write_rtl8225(dev, 0x6, 0xe6); mdelay(1);
++
++ write_rtl8225(dev, 0x7, ((priv->card_type == USB)? 0x82a : rtl8225_chan[channel])); mdelay(1);
++
++ write_rtl8225(dev, 0x8, 0x3f); mdelay(1);
++
++ write_rtl8225(dev, 0x9, 0x335); mdelay(1);
++
++ write_rtl8225(dev, 0xa, 0x9d4); mdelay(1);
++
++ write_rtl8225(dev, 0xb, 0x7bb); mdelay(1);
++
++ write_rtl8225(dev, 0xc, 0x850); mdelay(1);
++
++
++ write_rtl8225(dev, 0xd, 0xcdf); mdelay(1);
++
++ write_rtl8225(dev, 0xe, 0x2b); mdelay(1);
++
++ write_rtl8225(dev, 0xf, 0x114);
++
++
++ mdelay(100);
++
++
++ //if(priv->card_type != USB) /* maybe not needed even for 8185 */
++ // write_rtl8225(dev, 0x7, rtl8225_chan[channel]);
++
++ write_rtl8225(dev, 0x0, 0x1b7);
++
++ for(i=0;i<95;i++){
++ write_rtl8225(dev, 0x1, (u8)(i+1));
++ /* version B & C & D*/
++ write_rtl8225(dev, 0x2, rtl8225z2_rxgain[i]);
++ }
++ //write_rtl8225(dev, 0x3, 0x80);
++ write_rtl8225(dev, 0x3, 0x2);
++ write_rtl8225(dev, 0x5, 0x4);
++
++ write_rtl8225(dev, 0x0, 0xb7);
++
++ write_rtl8225(dev, 0x2, 0xc4d);
++
++ if(priv->card_type == USB){
++ // force_pci_posting(dev);
++ mdelay(200);
++
++ write_rtl8225(dev, 0x2, 0x44d);
++
++ // force_pci_posting(dev);
++ mdelay(200);
++
++ }//End of if(priv->card_type == USB)
++ /* FIXME!! rtl8187 we have to check if calibrarion
++ * is successful and eventually cal. again (repeat
++ * the two write on reg 2)
++ */
++ // Check for calibration status, 2005.11.17,
++ data = read_rtl8225(dev, 6);
++ if (!(data&0x00000080))
++ {
++ write_rtl8225(dev, 0x02, 0x0c4d);
++ force_pci_posting(dev); mdelay(200);
++ write_rtl8225(dev, 0x02, 0x044d);
++ force_pci_posting(dev); mdelay(100);
++ data = read_rtl8225(dev, 6);
++ if (!(data&0x00000080))
++ {
++ DMESGW("RF Calibration Failed!!!!\n");
++ }
++ }
++ //force_pci_posting(dev);
++
++ mdelay(200); //200 for 8187
++
++
++ // //if(priv->card_type != USB){
++ // write_rtl8225(dev, 0x2, 0x44d);
++ // write_rtl8225(dev, 0x7, rtl8225_chan[channel]);
++ // write_rtl8225(dev, 0x2, 0x47d);
++ //
++ // force_pci_posting(dev);
++ // mdelay(100);
++ //
++ // write_rtl8225(dev, 0x2, 0x44d);
++ // //}
++
++ write_rtl8225(dev, 0x0, 0x2bf);
++
++ if(priv->card_type != USB)
++ rtl8185_rf_pins_enable(dev);
++ //set up ZEBRA AGC table, 2005.11.17,
++ for(i=0;i<128;i++){
++ data = rtl8225_agc[i];
++
++ addr = i + 0x80; //enable writing AGC table
++ write_phy_ofdm(dev, 0xb, data);
++
++ mdelay(1);
++ write_phy_ofdm(dev, 0xa, addr);
++
++ mdelay(1);
++ }
++
++ force_pci_posting(dev);
++ mdelay(1);
++
++ write_phy_ofdm(dev, 0x0, 0x1); mdelay(1);
++ write_phy_ofdm(dev, 0x1, 0x2); mdelay(1);
++ write_phy_ofdm(dev, 0x2, ((priv->card_type == USB)? 0x42 : 0x62)); mdelay(1);
++ write_phy_ofdm(dev, 0x3, 0x0); mdelay(1);
++ write_phy_ofdm(dev, 0x4, 0x0); mdelay(1);
++ write_phy_ofdm(dev, 0x5, 0x0); mdelay(1);
++ write_phy_ofdm(dev, 0x6, 0x40); mdelay(1);
++ write_phy_ofdm(dev, 0x7, 0x0); mdelay(1);
++ write_phy_ofdm(dev, 0x8, 0x40); mdelay(1);
++ write_phy_ofdm(dev, 0x9, 0xfe); mdelay(1);
++
++ write_phy_ofdm(dev, 0xa, 0x8); mdelay(1);
++
++ //write_phy_ofdm(dev, 0x18, 0xef);
++ // }
++ //}
++ write_phy_ofdm(dev, 0xb, 0x80); mdelay(1);
++
++ write_phy_ofdm(dev, 0xc, 0x1);mdelay(1);
++
++
++ //if(priv->card_type != USB)
++ write_phy_ofdm(dev, 0xd, 0x43);
++
++ write_phy_ofdm(dev, 0xe, 0xd3);mdelay(1);
++
++ write_phy_ofdm(dev, 0xf, 0x38);mdelay(1);
++ /*ver D & 8187*/
++ // }
++
++ // if(priv->card_8185 == 1 && priv->card_8185_Bversion)
++ // write_phy_ofdm(dev, 0x10, 0x04);/*ver B*/
++ // else
++ write_phy_ofdm(dev, 0x10, 0x84);mdelay(1);
++ /*ver C & D & 8187*/
++
++ write_phy_ofdm(dev, 0x11, 0x07);mdelay(1);
++ /*agc resp time 700*/
++
++
++ // if(priv->card_8185 == 2){
++ /* Ver D & 8187*/
++ write_phy_ofdm(dev, 0x12, 0x20);mdelay(1);
++
++ write_phy_ofdm(dev, 0x13, 0x20);mdelay(1);
++
++ write_phy_ofdm(dev, 0x14, 0x0); mdelay(1);
++ write_phy_ofdm(dev, 0x15, 0x40); mdelay(1);
++ write_phy_ofdm(dev, 0x16, 0x0); mdelay(1);
++ write_phy_ofdm(dev, 0x17, 0x40); mdelay(1);
++
++ // if (priv->card_type == USB)
++ // write_phy_ofdm(dev, 0x18, 0xef);
++
++ write_phy_ofdm(dev, 0x18, 0xef);mdelay(1);
++
++
++ write_phy_ofdm(dev, 0x19, 0x19); mdelay(1);
++ write_phy_ofdm(dev, 0x1a, 0x20); mdelay(1);
++ write_phy_ofdm(dev, 0x1b, 0x15);mdelay(1);
++
++ write_phy_ofdm(dev, 0x1c, 0x4);mdelay(1);
++
++ write_phy_ofdm(dev, 0x1d, 0xc5);mdelay(1); //2005.11.17,
++
++ write_phy_ofdm(dev, 0x1e, 0x95);mdelay(1);
++
++ write_phy_ofdm(dev, 0x1f, 0x75); mdelay(1);
++
++ // }
++
++ write_phy_ofdm(dev, 0x20, 0x1f);mdelay(1);
++
++ write_phy_ofdm(dev, 0x21, 0x17);mdelay(1);
++
++ write_phy_ofdm(dev, 0x22, 0x16);mdelay(1);
++
++ // if(priv->card_type != USB)
++ write_phy_ofdm(dev, 0x23, 0x80);mdelay(1); //FIXME maybe not needed // <>
++
++ write_phy_ofdm(dev, 0x24, 0x46); mdelay(1);
++ write_phy_ofdm(dev, 0x25, 0x00); mdelay(1);
++ write_phy_ofdm(dev, 0x26, 0x90); mdelay(1);
++
++ write_phy_ofdm(dev, 0x27, 0x88); mdelay(1);
++
++
++ // <> Set init. gain to m74dBm.
++
++ rtl8225z2_set_gain(dev,4);
++ //rtl8225z2_set_gain(dev,2);
++
++ write_phy_cck(dev, 0x0, 0x98); mdelay(1);
++ write_phy_cck(dev, 0x3, 0x20); mdelay(1);
++ write_phy_cck(dev, 0x4, 0x7e); mdelay(1);
++ write_phy_cck(dev, 0x5, 0x12); mdelay(1);
++ write_phy_cck(dev, 0x6, 0xfc); mdelay(1);
++ write_phy_cck(dev, 0x7, 0x78);mdelay(1);
++ /* Ver C & D & 8187*/
++ write_phy_cck(dev, 0x8, 0x2e);mdelay(1);
++
++ write_phy_cck(dev, 0x9, 0x11);mdelay(1);
++ write_phy_cck(dev, 0xa, 0x17);mdelay(1);
++ write_phy_cck(dev, 0xb, 0x11);mdelay(1);
++
++ write_phy_cck(dev, 0x10, ((priv->card_type == USB) ? 0x9b: 0x93)); mdelay(1);
++ write_phy_cck(dev, 0x11, 0x88); mdelay(1);
++ write_phy_cck(dev, 0x12, 0x47); mdelay(1);
++ write_phy_cck(dev, 0x13, 0xd0); /* Ver C & D & 8187*/
++
++ write_phy_cck(dev, 0x19, 0x0); mdelay(1);
++ write_phy_cck(dev, 0x1a, 0xa0); mdelay(1);
++ write_phy_cck(dev, 0x1b, 0x8); mdelay(1);
++ write_phy_cck(dev, 0x1d, 0x0); mdelay(1);
++
++ write_phy_cck(dev, 0x40, 0x86); /* CCK Carrier Sense Threshold */ mdelay(1);
++
++ write_phy_cck(dev, 0x41, 0x9d);mdelay(1);
++
++
++ write_phy_cck(dev, 0x42, 0x15); mdelay(1);
++ write_phy_cck(dev, 0x43, 0x18); mdelay(1);
++
++
++ write_phy_cck(dev, 0x44, 0x36); mdelay(1);
++ write_phy_cck(dev, 0x45, 0x35); mdelay(1);
++ write_phy_cck(dev, 0x46, 0x2e); mdelay(1);
++ write_phy_cck(dev, 0x47, 0x25); mdelay(1);
++ write_phy_cck(dev, 0x48, 0x1c); mdelay(1);
++ write_phy_cck(dev, 0x49, 0x12); mdelay(1);
++ write_phy_cck(dev, 0x4a, 0x09); mdelay(1);
++ write_phy_cck(dev, 0x4b, 0x04); mdelay(1);
++ write_phy_cck(dev, 0x4c, 0x5);mdelay(1);
++
++
++ write_nic_byte(dev, 0x5b, 0x0d); mdelay(1);
++
++
++
++ // <>
++ // // TESTR 0xb 8187
++ // write_phy_cck(dev, 0x10, 0x93);// & 0xfb);
++ //
++ // //if(priv->card_type != USB){
++ // write_phy_ofdm(dev, 0x2, 0x62);
++ // write_phy_ofdm(dev, 0x6, 0x0);
++ // write_phy_ofdm(dev, 0x8, 0x0);
++ // //}
++
++ rtl8225z2_SetTXPowerLevel(dev, channel);
++
++ write_phy_cck(dev, 0x10, 0x9b); mdelay(1); /* Rx ant A, 0xdb for B */
++ write_phy_ofdm(dev, 0x26, 0x90); mdelay(1); /* Rx ant A, 0x10 for B */
++
++ rtl8185_tx_antenna(dev, 0x3); /* TX ant A, 0x0 for B */
++
++ /* switch to high-speed 3-wire
++ * last digit. 2 for both cck and ofdm
++ */
++ if(priv->card_type == USB)
++ write_nic_dword(dev, 0x94, 0x3dc00002);
++ else{
++ write_nic_dword(dev, 0x94, 0x15c00002);
++ rtl8185_rf_pins_enable(dev);
++ }
++
++ // if(priv->card_type != USB)
++ // rtl8225_set_gain(dev, 4); /* FIXME this '1' is random */ // <>
++ // rtl8225_set_mode(dev, 1); /* FIXME start in B mode */ // <>
++ //
++ // /* make sure is waken up! */
++ // write_rtl8225(dev,0x4, 0x9ff);
++ // rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
++ // rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_ON);
++
++ rtl8225_rf_set_chan(dev, priv->chan);
++
++ //write_nic_word(dev,BRSR,brsr);
++
++ //rtl8225z2_rf_set_mode(dev);
++ }
++}
++
++void rtl8225z2_rf_set_mode(struct net_device *dev)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ if(priv->ieee80211->mode == IEEE_A)
++ {
++ write_rtl8225(dev, 0x5, 0x1865);
++ write_nic_dword(dev, RF_PARA, 0x10084);
++ write_nic_dword(dev, RF_TIMING, 0xa8008);
++ write_phy_ofdm(dev, 0x0, 0x0);
++ write_phy_ofdm(dev, 0xa, 0x6);
++ write_phy_ofdm(dev, 0xb, 0x99);
++ write_phy_ofdm(dev, 0xf, 0x20);
++ write_phy_ofdm(dev, 0x11, 0x7);
++
++ rtl8225z2_set_gain(dev,4);
++
++ write_phy_ofdm(dev,0x15, 0x40);
++ write_phy_ofdm(dev,0x17, 0x40);
++
++ write_nic_dword(dev, 0x94,0x10000000);
++ }else{
++
++ write_rtl8225(dev, 0x5, 0x1864);
++ write_nic_dword(dev, RF_PARA, 0x10044);
++ write_nic_dword(dev, RF_TIMING, 0xa8008);
++ write_phy_ofdm(dev, 0x0, 0x1);
++ write_phy_ofdm(dev, 0xa, 0x6);
++ write_phy_ofdm(dev, 0xb, 0x99);
++ write_phy_ofdm(dev, 0xf, 0x20);
++ write_phy_ofdm(dev, 0x11, 0x7);
++
++ rtl8225z2_set_gain(dev,4);
++
++ write_phy_ofdm(dev,0x15, 0x40);
++ write_phy_ofdm(dev,0x17, 0x40);
++
++ write_nic_dword(dev, 0x94,0x04000002);
++ }
++}
+diff --git a/drivers/net/wireless/rtl8187b/r8180_wx.c b/drivers/net/wireless/rtl8187b/r8180_wx.c
+new file mode 100644
+index 0000000..2bb9fe3
+--- /dev/null
++++ b/drivers/net/wireless/rtl8187b/r8180_wx.c
+@@ -0,0 +1,2067 @@
++/*
++ This file contains wireless extension handlers.
++
++ This is part of rtl8180 OpenSource driver.
++ Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it>
++ Released under the terms of GPL (General Public Licence)
++
++ Parts of this driver are based on the GPL part
++ of the official realtek driver.
++
++ Parts of this driver are based on the rtl8180 driver skeleton
++ from Patric Schenke & Andres Salomon.
++
++ Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
++
++ We want to tanks the Authors of those projects and the Ndiswrapper
++ project Authors.
++*/
++
++
++
++#include "r8187.h"
++#include "r8180_hw.h"
++//added 1117
++#include "ieee80211/ieee80211.h"
++#ifdef ENABLE_DOT11D
++#include "dot11d.h"
++#endif
++
++
++//#define RATE_COUNT 4
++u32 rtl8180_rates[] = {1000000,2000000,5500000,11000000,
++ 6000000,9000000,12000000,18000000,24000000,36000000,48000000,54000000};
++#define RATE_COUNT sizeof(rtl8180_rates)/(sizeof(rtl8180_rates[0]))
++
++#ifdef _RTL8187_EXT_PATCH_
++#define IW_MODE_MESH 11
++static int r8180_wx_join_mesh(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
++int r8180_wx_set_channel(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
++static int r8180_wx_mesh_scan(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
++static int r8180_wx_get_mesh_list(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
++#endif
++
++static int r8180_wx_get_freq(struct net_device *dev,
++ struct iw_request_info *a,
++ union iwreq_data *wrqu, char *b)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ return ieee80211_wx_get_freq(priv->ieee80211,a,wrqu,b);
++}
++
++
++#if 0
++
++static int r8180_wx_set_beaconinterval(struct net_device *dev, struct iw_request_info *aa,
++ union iwreq_data *wrqu, char *b)
++{
++ int *parms = (int *)b;
++ int bi = parms[0];
++
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ if(priv->ieee80211->bHwRadioOff)
++ return 0;
++ down(&priv->wx_sem);
++ DMESG("setting beacon interval to %x",bi);
++
++ priv->ieee80211->beacon_interval=bi;
++ rtl8180_commit(dev);
++ up(&priv->wx_sem);
++
++ return 0;
++}
++
++
++static int r8180_wx_set_forceassociate(struct net_device *dev, struct iw_request_info *aa,
++ union iwreq_data *wrqu, char *extra)
++{
++ struct r8180_priv *priv=ieee80211_priv(dev);
++ int *parms = (int *)extra;
++ if(priv->ieee80211->bHwRadioOff)
++ return 0;
++
++ priv->ieee80211->force_associate = (parms[0] > 0);
++
++
++ return 0;
++}
++
++#endif
++static int r8180_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
++ union iwreq_data *wrqu, char *b)
++{
++ struct r8180_priv *priv=ieee80211_priv(dev);
++
++ return ieee80211_wx_get_mode(priv->ieee80211,a,wrqu,b);
++}
++
++
++
++static int r8180_wx_get_rate(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ return ieee80211_wx_get_rate(priv->ieee80211,info,wrqu,extra);
++}
++
++
++
++static int r8180_wx_set_rate(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ int ret;
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ if(priv->ieee80211->bHwRadioOff)
++ return 0;
++
++ down(&priv->wx_sem);
++
++ ret = ieee80211_wx_set_rate(priv->ieee80211,info,wrqu,extra);
++
++ up(&priv->wx_sem);
++
++ return ret;
++}
++#ifdef JOHN_IOCTL
++u16 read_rtl8225(struct net_device *dev, u8 addr);
++void write_rtl8225(struct net_device *dev, u8 adr, u16 data);
++u32 john_read_rtl8225(struct net_device *dev, u8 adr);
++void _write_rtl8225(struct net_device *dev, u8 adr, u16 data);
++
++static int r8180_wx_read_regs(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ u8 addr = 0;
++ u16 data1;
++
++ down(&priv->wx_sem);
++
++
++ get_user(addr,(u8*)wrqu->data.pointer);
++ data1 = read_rtl8225(dev, addr);
++ wrqu->data.length = data1;
++
++ up(&priv->wx_sem);
++ return 0;
++
++}
++
++static int r8180_wx_write_regs(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ u8 addr = 0;
++
++ down(&priv->wx_sem);
++
++ get_user(addr, (u8*)wrqu->data.pointer);
++ write_rtl8225(dev, addr, wrqu->data.length);
++
++ up(&priv->wx_sem);
++ return 0;
++
++}
++
++void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
++u8 rtl8187_read_phy(struct net_device *dev,u8 adr, u32 data);
++
++static int r8180_wx_read_bb(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ u8 databb;
++#if 0
++ int i;
++ for(i=0;i<12;i++) printk("%8x\n", read_cam(dev, i) );
++#endif
++
++ down(&priv->wx_sem);
++
++ databb = rtl8187_read_phy(dev, (u8)wrqu->data.length, 0x00000000);
++ wrqu->data.length = databb;
++
++ up(&priv->wx_sem);
++ return 0;
++}
++
++void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
++static int r8180_wx_write_bb(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ u8 databb = 0;
++
++ down(&priv->wx_sem);
++
++ get_user(databb, (u8*)wrqu->data.pointer);
++ rtl8187_write_phy(dev, wrqu->data.length, databb);
++
++ up(&priv->wx_sem);
++ return 0;
++
++}
++
++
++static int r8180_wx_write_nicb(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ u32 addr = 0;
++
++ down(&priv->wx_sem);
++
++ get_user(addr, (u32*)wrqu->data.pointer);
++ write_nic_byte(dev, addr, wrqu->data.length);
++
++ up(&priv->wx_sem);
++ return 0;
++
++}
++static int r8180_wx_read_nicb(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ u32 addr = 0;
++ u16 data1;
++
++ down(&priv->wx_sem);
++
++ get_user(addr,(u32*)wrqu->data.pointer);
++ data1 = read_nic_byte(dev, addr);
++ wrqu->data.length = data1;
++
++ up(&priv->wx_sem);
++ return 0;
++}
++
++static inline int is_same_network(struct ieee80211_network *src,
++ struct ieee80211_network *dst,
++ struct ieee80211_device *ieee)
++{
++ /* A network is only a duplicate if the channel, BSSID, ESSID
++ * and the capability field (in particular IBSS and BSS) all match.
++ * We treat all <hidden> with the same BSSID and channel
++ * as one network */
++ return (((src->ssid_len == dst->ssid_len)||(ieee->iw_mode == IW_MODE_INFRA)) && //YJ,mod, 080819,for hidden ap
++ //((src->ssid_len == dst->ssid_len) &&
++ (src->channel == dst->channel) &&
++ !memcmp(src->bssid, dst->bssid, ETH_ALEN) &&
++ (!memcmp(src->ssid, dst->ssid, src->ssid_len)||(ieee->iw_mode == IW_MODE_INFRA)) && //YJ,mod, 080819,for hidden ap
++ //!memcmp(src->ssid, dst->ssid, src->ssid_len) &&
++ ((src->capability & WLAN_CAPABILITY_IBSS) ==
++ (dst->capability & WLAN_CAPABILITY_IBSS)) &&
++ ((src->capability & WLAN_CAPABILITY_BSS) ==
++ (dst->capability & WLAN_CAPABILITY_BSS)));
++}
++
++static int r8180_wx_get_ap_status(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ struct ieee80211_device *ieee = priv->ieee80211;
++ struct ieee80211_network *target;
++ int name_len;
++
++ down(&priv->wx_sem);
++
++ //count the length of input ssid
++ for(name_len=0 ; ((char*)wrqu->data.pointer)[name_len]!='\0' ; name_len++);
++
++ //search for the correspoding info which is received
++ list_for_each_entry(target, &ieee->network_list, list) {
++ if ( (target->ssid_len == name_len) &&
++ (strncmp(target->ssid, (char*)wrqu->data.pointer, name_len)==0)){
++ if( ((jiffies-target->last_scanned)/HZ > 1) && (ieee->state == IEEE80211_LINKED) && (is_same_network(&ieee->current_network,target, ieee)) )
++ wrqu->data.length = 999;
++ else
++ wrqu->data.length = target->SignalStrength;
++ if(target->wpa_ie_len>0 || target->rsn_ie_len>0 )
++ //set flags=1 to indicate this ap is WPA
++ wrqu->data.flags = 1;
++ else wrqu->data.flags = 0;
++
++
++ break;
++ }
++ }
++
++ if (&target->list == &ieee->network_list){
++ wrqu->data.flags = 3;
++ }
++ up(&priv->wx_sem);
++ return 0;
++}
++
++
++
++#endif
++
++static int r8180_wx_set_rawtx(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ int ret;
++
++ if(priv->ieee80211->bHwRadioOff)
++ return 0;
++
++ down(&priv->wx_sem);
++
++ ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
++
++ up(&priv->wx_sem);
++
++ return ret;
++
++}
++
++static int r8180_wx_set_crcmon(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ int *parms = (int *)extra;
++ int enable = (parms[0] > 0);
++ short prev = priv->crcmon;
++
++ if(priv->ieee80211->bHwRadioOff)
++ return 0;
++
++ down(&priv->wx_sem);
++
++ if(enable)
++ priv->crcmon=1;
++ else
++ priv->crcmon=0;
++
++ DMESG("bad CRC in monitor mode are %s",
++ priv->crcmon ? "accepted" : "rejected");
++
++ if(prev != priv->crcmon && priv->up){
++ rtl8180_down(dev);
++ rtl8180_up(dev);
++ }
++
++ up(&priv->wx_sem);
++
++ return 0;
++}
++
++static int r8180_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
++ union iwreq_data *wrqu, char *b)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ int ret;
++ if(priv->ieee80211->bHwRadioOff)
++ return 0;
++
++#ifdef _RTL8187_EXT_PATCH_
++ if (priv->mshobj && (priv->ieee80211->iw_ext_mode==11)) return 0;
++#endif
++ down(&priv->wx_sem);
++
++#ifdef CONFIG_IPS
++ if(priv->bInactivePs){
++ if(wrqu->mode != IW_MODE_INFRA){
++ down(&priv->ieee80211->ips_sem);
++ IPSLeave(dev);
++ up(&priv->ieee80211->ips_sem);
++ }
++ }
++#endif
++ ret = ieee80211_wx_set_mode(priv->ieee80211,a,wrqu,b);
++
++ rtl8187_set_rxconf(dev);
++
++ up(&priv->wx_sem);
++ return ret;
++}
++
++
++//YJ,add,080819,for hidden ap
++struct iw_range_with_scan_capa
++{
++ /* Informative stuff (to choose between different interface) */
++ __u32 throughput; /* To give an idea... */
++ /* In theory this value should be the maximum benchmarked
++ * TCP/IP throughput, because with most of these devices the
++ * bit rate is meaningless (overhead an co) to estimate how
++ * fast the connection will go and pick the fastest one.
++ * I suggest people to play with Netperf or any benchmark...
++ */
++
++ /* NWID (or domain id) */
++ __u32 min_nwid; /* Minimal NWID we are able to set */
++ __u32 max_nwid; /* Maximal NWID we are able to set */
++
++ /* Old Frequency (backward compat - moved lower ) */
++ __u16 old_num_channels;
++ __u8 old_num_frequency;
++
++ /* Scan capabilities */
++ __u8 scan_capa;
++};
++//YJ,add,080819,for hidden ap
++
++static int rtl8180_wx_get_range(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ struct iw_range *range = (struct iw_range *)extra;
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ u16 val;
++ int i;
++ struct iw_range_with_scan_capa* tmp = (struct iw_range_with_scan_capa*)range; //YJ,add,080819,for hidden ap
++
++ wrqu->data.length = sizeof(*range);
++ memset(range, 0, sizeof(*range));
++
++ /* Let's try to keep this struct in the same order as in
++ * linux/include/wireless.h
++ */
++
++ /* TODO: See what values we can set, and remove the ones we can't
++ * set, or fill them with some default data.
++ */
++
++ /* ~5 Mb/s real (802.11b) */
++ range->throughput = 5 * 1000 * 1000;
++
++ // TODO: Not used in 802.11b?
++// range->min_nwid; /* Minimal NWID we are able to set */
++ // TODO: Not used in 802.11b?
++// range->max_nwid; /* Maximal NWID we are able to set */
++
++ /* Old Frequency (backward compat - moved lower ) */
++// range->old_num_channels;
++// range->old_num_frequency;
++// range->old_freq[6]; /* Filler to keep "version" at the same offset */
++ if(priv->rf_set_sens != NULL)
++ range->sensitivity = priv->max_sens; /* signal level threshold range */
++
++ range->max_qual.qual = 100;
++ /* TODO: Find real max RSSI and stick here */
++ range->max_qual.level = 0;
++ range->max_qual.noise = -98;
++ range->max_qual.updated = 7; /* Updated all three */
++
++ range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
++ /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
++ range->avg_qual.level = 20 + -98;
++ range->avg_qual.noise = 0;
++ range->avg_qual.updated = 7; /* Updated all three */
++
++ range->num_bitrates = RATE_COUNT;
++
++ for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) {
++ range->bitrate[i] = rtl8180_rates[i];
++ }
++
++ range->min_frag = MIN_FRAG_THRESHOLD;
++ range->max_frag = MAX_FRAG_THRESHOLD;
++
++ range->pm_capa = 0;
++
++ range->we_version_compiled = WIRELESS_EXT;
++ range->we_version_source = 16;
++
++// range->retry_capa; /* What retry options are supported */
++// range->retry_flags; /* How to decode max/min retry limit */
++// range->r_time_flags; /* How to decode max/min retry life */
++// range->min_retry; /* Minimal number of retries */
++// range->max_retry; /* Maximal number of retries */
++// range->min_r_time; /* Minimal retry lifetime */
++// range->max_r_time; /* Maximal retry lifetime */
++
++ range->num_channels = 14;
++
++ for (i = 0, val = 0; i < 14; i++) {
++
++ // Include only legal frequencies for some countries
++#ifdef ENABLE_DOT11D
++ if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
++#else
++ if ((priv->ieee80211->channel_map)[i+1]) {
++#endif
++ range->freq[val].i = i + 1;
++ range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
++ range->freq[val].e = 1;
++ val++;
++ } else {
++ // FIXME: do we need to set anything for channels
++ // we don't use ?
++ }
++
++ if (val == IW_MAX_FREQUENCIES)
++ break;
++ }
++
++ range->num_frequency = val;
++ range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
++ IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
++
++ tmp->scan_capa = 0x01; //YJ,add,080819,for hidden ap
++
++ return 0;
++}
++
++
++static int r8180_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
++ union iwreq_data *wrqu, char *b)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ struct ieee80211_device* ieee = priv->ieee80211;
++ int ret;
++
++ if(priv->ieee80211->bHwRadioOff)
++ return 0;
++ //printk("==============>%s()\n",__FUNCTION__);
++ if(!priv->up)
++ return -1;
++
++ if (wrqu->data.flags & IW_SCAN_THIS_ESSID)
++ {
++ struct iw_scan_req* req = (struct iw_scan_req*)b;
++ if (req->essid_len)
++ {
++ ieee->current_network.ssid_len = req->essid_len;
++ memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
++ }
++ }
++
++ //set Tr switch to hardware control to scan more bss
++ if(priv->TrSwitchState == TR_SW_TX) {
++ //YJ,add,080611
++ write_nic_byte(dev, RFPinsSelect, (u8)(priv->wMacRegRfPinsSelect));
++ write_nic_byte(dev, RFPinsOutput, (u8)(priv->wMacRegRfPinsOutput));
++ //YJ,add,080611,end
++ priv->TrSwitchState = TR_HW_CONTROLLED;
++ }
++#ifdef _RTL8187_EXT_PATCH_
++ if((priv->ieee80211->iw_mode == IW_MODE_MESH) && (priv->ieee80211->iw_ext_mode == IW_MODE_MESH)){
++ r8180_wx_mesh_scan(dev,a,wrqu,b);
++ ret = 0;
++ }
++ else
++#endif
++ {
++ down(&priv->wx_sem);
++ if(priv->ieee80211->state != IEEE80211_LINKED){
++ //printk("===>start no link scan\n");
++ //ieee80211_start_scan(priv->ieee80211);
++ //lzm mod 090115 because wq can't scan complete once
++ //because after start protocal wq scan is in doing
++ //so we should stop it first.
++ ieee80211_stop_scan(priv->ieee80211);
++ ieee80211_start_scan_syncro(priv->ieee80211);
++ ret = 0;
++ } else {
++ ret = ieee80211_wx_set_scan(priv->ieee80211,a,wrqu,b);
++ }
++ up(&priv->wx_sem);
++ }
++ return ret;
++}
++
++
++static int r8180_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
++ union iwreq_data *wrqu, char *b)
++{
++
++ int ret;
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ if(!priv->up) return -1;
++#ifdef _RTL8187_EXT_PATCH_
++ if((priv->ieee80211->iw_mode == IW_MODE_MESH) && (priv->ieee80211->iw_ext_mode == IW_MODE_MESH)){
++ ret = r8180_wx_get_mesh_list(dev, a, wrqu, b);
++ }
++ else
++#endif
++ {
++ down(&priv->wx_sem);
++
++ ret = ieee80211_wx_get_scan(priv->ieee80211,a,wrqu,b);
++
++ up(&priv->wx_sem);
++ }
++ return ret;
++}
++
++
++static int r8180_wx_set_essid(struct net_device *dev,
++ struct iw_request_info *a,
++ union iwreq_data *wrqu, char *b)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ int ret;
++#ifdef _RTL8187_EXT_PATCH_
++ struct ieee80211_device *ieee = priv->ieee80211;
++ char ch = 0;
++ char tmpmeshid[32];
++ char *p;
++ int tmpmeshid_len=0;
++ int i;
++ short proto_started;
++#endif
++ if(priv->ieee80211->bHwRadioOff)
++ return 0;
++ //printk("==========>%s()\n",__FUNCTION__);
++ down(&priv->wx_sem);
++
++#ifdef _RTL8187_EXT_PATCH_
++ if((priv->ieee80211->iw_mode == IW_MODE_MESH) && (priv->ieee80211->iw_ext_mode == IW_MODE_MESH)){
++ if (wrqu->essid.length > IW_ESSID_MAX_SIZE){
++ ret= -E2BIG;
++ goto out;
++ }
++ if (wrqu->essid.flags && (wrqu->essid.length > 1)) {
++ memset(tmpmeshid,0,32);
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
++ tmpmeshid_len=wrqu->essid.length;
++#else
++ tmpmeshid_len=wrqu->essid.length + 1;
++#endif
++ p=b+tmpmeshid_len-2;
++ for(i=tmpmeshid_len-1;i>0;i--)
++ {
++ if((*p)=='@')
++ break;
++ p--;
++ }
++ if((i == 0) || (i == 1)){
++ printk("error:wrong meshid\n");
++ ret = -1;
++ goto out;
++ }
++
++ memcpy(tmpmeshid,b,(i-1));
++ p++;
++ if((tmpmeshid_len-1-i)==1)
++ {
++ if(*p > '9'|| *p <= '0'){
++ goto out;
++ } else {
++ ch = *p - '0';
++ }
++ }
++ else if((tmpmeshid_len-1-i)==2)
++ {
++ if((*p == '1') && (*(p+1) >= '0') && (*(p+1) <= '9'))
++ ch = (*p - '0') * 10 + (*(p+1) - '0');
++ else
++ goto out;
++ }
++ else {
++ ret = 0;
++ goto out;
++ }
++ if(ch > 14)
++ {
++ ret = 0;
++ printk("channel is invalid: %d\n",ch);
++ goto out;
++ }
++ ieee->sync_scan_hurryup = 1;
++
++ proto_started = ieee->proto_started;
++ if(proto_started)
++ ieee80211_stop_protocol(ieee);
++
++ printk("==============>tmpmeshid is %s\n",tmpmeshid);
++ priv->mshobj->ext_patch_r8180_wx_set_meshID(dev, tmpmeshid);
++ priv->mshobj->ext_patch_r8180_wx_set_mesh_chan(dev,ch);
++ r8180_wx_set_channel(dev, NULL, NULL, &ch);
++ if (proto_started)
++ ieee80211_start_protocol(ieee);
++ }
++ else{
++ printk("BUG:meshid is null\n");
++ ret=0;
++ goto out;
++ }
++
++ ret = 0;
++ }
++ else
++#endif
++ {
++ ret = ieee80211_wx_set_essid(priv->ieee80211,a,wrqu,b);
++ }
++
++#ifdef _RTL8187_EXT_PATCH_
++out:
++#endif
++ up(&priv->wx_sem);
++ return ret;
++}
++
++
++static int r8180_wx_get_essid(struct net_device *dev,
++ struct iw_request_info *a,
++ union iwreq_data *wrqu, char *b)
++{
++ int ret;
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ down(&priv->wx_sem);
++
++ ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
++
++ up(&priv->wx_sem);
++
++ return ret;
++}
++
++
++static int r8180_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
++ union iwreq_data *wrqu, char *b)
++{
++ int ret;
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ if(priv->ieee80211->bHwRadioOff)
++ return 0;
++
++ down(&priv->wx_sem);
++
++ ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
++
++ up(&priv->wx_sem);
++ return ret;
++}
++
++static int r8180_wx_get_name(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
++}
++
++
++static int r8180_wx_set_frag(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ if(priv->ieee80211->bHwRadioOff)
++ return 0;
++
++ if (wrqu->frag.disabled)
++ priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
++ else {
++ if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
++ wrqu->frag.value > MAX_FRAG_THRESHOLD)
++ return -EINVAL;
++
++ priv->ieee80211->fts = wrqu->frag.value & ~0x1;
++ }
++
++ return 0;
++}
++
++
++static int r8180_wx_get_frag(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ wrqu->frag.value = priv->ieee80211->fts;
++ wrqu->frag.fixed = 0; /* no auto select */
++ wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
++
++ return 0;
++}
++
++
++static int r8180_wx_set_wap(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *awrq,
++ char *extra)
++{
++ int ret;
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ if(priv->ieee80211->bHwRadioOff)
++ return 0;
++
++ //printk("in function %s\n",__FUNCTION__);
++#ifdef _RTL8187_EXT_PATCH_
++ if (priv->mshobj && (priv->ieee80211->iw_ext_mode==11)){
++ return 0;
++ }
++#endif
++ down(&priv->wx_sem);
++
++ ret = ieee80211_wx_set_wap(priv->ieee80211,info,awrq,extra);
++
++ up(&priv->wx_sem);
++ return ret;
++
++}
++
++
++static int r8180_wx_get_wap(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ return ieee80211_wx_get_wap(priv->ieee80211,info,wrqu,extra);
++}
++
++
++static int r8180_wx_get_enc(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *key)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
++}
++
++static int r8180_wx_set_enc(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *key)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ int ret;
++#ifdef JOHN_HWSEC
++// struct ieee80211_device *ieee = priv->ieee80211;
++// u32 TargetContent;
++ u32 hwkey[4]={0,0,0,0};
++ u8 mask=0xff;
++ u32 key_idx=0;
++ u8 broadcast_addr[6] ={ 0xff,0xff,0xff,0xff,0xff,0xff};
++ u8 zero_addr[4][6] ={ {0x00,0x00,0x00,0x00,0x00,0x00},
++ {0x00,0x00,0x00,0x00,0x00,0x01},
++ {0x00,0x00,0x00,0x00,0x00,0x02},
++ {0x00,0x00,0x00,0x00,0x00,0x03} };
++ int i;
++
++#endif
++
++ if(priv->ieee80211->bHwRadioOff)
++ return 0;
++
++ down(&priv->wx_sem);
++
++ DMESG("Setting SW wep key");
++ ret = ieee80211_wx_set_encode(priv->ieee80211,info,wrqu,key);
++
++ up(&priv->wx_sem);
++
++#ifdef JOHN_HWSEC
++
++ //sometimes, the length is zero while we do not type key value
++ if(wrqu->encoding.length!=0){
++
++ for(i=0 ; i<4 ; i++){
++ hwkey[i] |= key[4*i+0]&mask;
++ if(i==1&&(4*i+1)==wrqu->encoding.length) mask=0x00;
++ if(i==3&&(4*i+1)==wrqu->encoding.length) mask=0x00;
++ hwkey[i] |= (key[4*i+1]&mask)<<8;
++ hwkey[i] |= (key[4*i+2]&mask)<<16;
++ hwkey[i] |= (key[4*i+3]&mask)<<24;
++ }
++
++ #define CONF_WEP40 0x4
++ #define CONF_WEP104 0x14
++
++ switch(wrqu->encoding.flags){
++ case 0:
++ case 1: key_idx = 0; break;
++ case 2: key_idx = 1; break;
++ case 3: key_idx = 2; break;
++ case 4: key_idx = 3; break;
++ default: break;
++ }
++
++ if(wrqu->encoding.length==0x5){
++ setKey( dev,
++ key_idx, //EntryNo
++ key_idx, //KeyIndex
++ KEY_TYPE_WEP40, //KeyType
++ zero_addr[key_idx],
++ 0, //DefaultKey
++ hwkey); //KeyContent
++
++ if(key_idx == 0){
++
++ write_nic_byte(dev, WPA_CONFIG, 7);
++
++ setKey( dev,
++ 4, //EntryNo
++ key_idx, //KeyIndex
++ KEY_TYPE_WEP40, //KeyType
++ broadcast_addr, //addr
++ 0, //DefaultKey
++ hwkey); //KeyContent
++ }
++ }
++
++ else if(wrqu->encoding.length==0xd){
++ setKey( dev,
++ key_idx, //EntryNo
++ key_idx, //KeyIndex
++ KEY_TYPE_WEP104, //KeyType
++ zero_addr[key_idx],
++ 0, //DefaultKey
++ hwkey); //KeyContent
++
++ if(key_idx == 0){
++
++ write_nic_byte(dev, WPA_CONFIG, 7);
++
++ setKey( dev,
++ 4, //EntryNo
++ key_idx, //KeyIndex
++ KEY_TYPE_WEP104, //KeyType
++ broadcast_addr, //addr
++ 0, //DefaultKey
++ hwkey); //KeyContent
++ }
++ }
++ else printk("wrong type in WEP, not WEP40 and WEP104\n");
++
++ }
++
++ //consider the setting different key index situation
++ //wrqu->encoding.flags = 801 means that we set key with index "1"
++ if(wrqu->encoding.length==0 && (wrqu->encoding.flags >>8) == 0x8 ){
++
++ write_nic_byte(dev, WPA_CONFIG, 7);
++
++ //copy wpa config from default key(key0~key3) to broadcast key(key5)
++ //
++ key_idx = (wrqu->encoding.flags & 0xf)-1 ;
++ write_cam(dev, (4*6), 0xffff0000|read_cam(dev, key_idx*6) );
++ write_cam(dev, (4*6)+1, 0xffffffff);
++ write_cam(dev, (4*6)+2, read_cam(dev, (key_idx*6)+2) );
++ write_cam(dev, (4*6)+3, read_cam(dev, (key_idx*6)+3) );
++ write_cam(dev, (4*6)+4, read_cam(dev, (key_idx*6)+4) );
++ write_cam(dev, (4*6)+5, read_cam(dev, (key_idx*6)+5) );
++ }
++
++#endif /*JOHN_HWSEC*/
++ return ret;
++}
++
++
++static int r8180_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union
++ iwreq_data *wrqu, char *p){
++
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ int *parms=(int*)p;
++ int mode=parms[0];
++
++ if(priv->ieee80211->bHwRadioOff)
++ return 0;
++
++ priv->ieee80211->active_scan = mode;
++
++ return 1;
++}
++
++
++
++static int r8180_wx_set_retry(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ int err = 0;
++
++ if(priv->ieee80211->bHwRadioOff)
++ return 0;
++
++ down(&priv->wx_sem);
++
++ if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
++ wrqu->retry.disabled){
++ err = -EINVAL;
++ goto exit;
++ }
++ if (!(wrqu->retry.flags & IW_RETRY_LIMIT)){
++ err = -EINVAL;
++ goto exit;
++ }
++
++ if(wrqu->retry.value > R8180_MAX_RETRY){
++ err= -EINVAL;
++ goto exit;
++ }
++ if (wrqu->retry.flags & IW_RETRY_MAX) {
++ priv->retry_rts = wrqu->retry.value;
++ DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
++
++ }else {
++ priv->retry_data = wrqu->retry.value;
++ DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
++ }
++
++ /* FIXME !
++ * We might try to write directly the TX config register
++ * or to restart just the (R)TX process.
++ * I'm unsure if whole reset is really needed
++ */
++
++ rtl8180_commit(dev);
++ /*
++ if(priv->up){
++ rtl8180_rtx_disable(dev);
++ rtl8180_rx_enable(dev);
++ rtl8180_tx_enable(dev);
++
++ }
++ */
++exit:
++ up(&priv->wx_sem);
++
++ return err;
++}
++
++static int r8180_wx_get_retry(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++
++ wrqu->retry.disabled = 0; /* can't be disabled */
++
++ if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
++ IW_RETRY_LIFETIME)
++ return -EINVAL;
++
++ if (wrqu->retry.flags & IW_RETRY_MAX) {
++ wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MAX;
++ wrqu->retry.value = priv->retry_rts;
++ } else {
++ wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MIN;
++ wrqu->retry.value = priv->retry_data;
++ }
++ //DMESG("returning %d",wrqu->retry.value);
++
++
++ return 0;
++}
++
++static int r8180_wx_get_sens(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ if(priv->rf_set_sens == NULL)
++ return -1; /* we have not this support for this radio */
++ wrqu->sens.value = priv->sens;
++ return 0;
++}
++
++
++static int r8180_wx_set_sens(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ short err = 0;
++
++ if(priv->ieee80211->bHwRadioOff)
++ return 0;
++
++ down(&priv->wx_sem);
++ //DMESG("attempt to set sensivity to %ddb",wrqu->sens.value);
++ if(priv->rf_set_sens == NULL) {
++ err= -1; /* we have not this support for this radio */
++ goto exit;
++ }
++ if(priv->rf_set_sens(dev, wrqu->sens.value) == 0)
++ priv->sens = wrqu->sens.value;
++ else
++ err= -EINVAL;
++
++exit:
++ up(&priv->wx_sem);
++
++ return err;
++}
++
++
++static int dummy(struct net_device *dev, struct iw_request_info *a,
++ union iwreq_data *wrqu,char *b)
++{
++ return -1;
++}
++static int r8180_wx_set_enc_ext(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ //printk("===>%s()\n", __FUNCTION__);
++
++ int ret=0;
++
++ if(priv->ieee80211->bHwRadioOff)
++ return 0;
++
++ down(&priv->wx_sem);
++ ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra);
++ up(&priv->wx_sem);
++ return ret;
++
++}
++static int r8180_wx_set_auth(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data* data, char *extra)
++{
++ //printk("====>%s()\n", __FUNCTION__);
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ int ret=0;
++
++ if(priv->ieee80211->bHwRadioOff)
++ return 0;
++
++ down(&priv->wx_sem);
++ ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra);
++ up(&priv->wx_sem);
++ return ret;
++}
++
++static int r8180_wx_set_mlme(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ //printk("====>%s()\n", __FUNCTION__);
++
++ int ret=0;
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ if(priv->ieee80211->bHwRadioOff)
++ return 0;
++
++ down(&priv->wx_sem);
++#if 1
++ ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
++#endif
++ up(&priv->wx_sem);
++ return ret;
++}
++
++static int r8180_wx_set_gen_ie(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data* data, char *extra)
++{
++ //printk("====>%s(), len:%d\n", __FUNCTION__, data->length);
++ int ret=0;
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ if(priv->ieee80211->bHwRadioOff)
++ return 0;
++
++ down(&priv->wx_sem);
++#if 1
++ ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length);
++#endif
++ up(&priv->wx_sem);
++ //printk("<======%s(), ret:%d\n", __FUNCTION__, ret);
++ return ret;
++
++
++}
++
++#ifdef _RTL8187_EXT_PATCH_
++/*
++ Output:
++ (case 1) Mesh: Enable. MESHID=[%s] (max length of %s is 32 bytes).
++ (case 2) Mesh: Disable.
++*/
++static int r8180_wx_get_meshinfo(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_get_meshinfo )
++ return 0;
++ return priv->mshobj->ext_patch_r8180_wx_get_meshinfo(dev, info, wrqu, extra);
++}
++
++
++static int r8180_wx_enable_mesh(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ struct ieee80211_device *ieee = priv->ieee80211;
++
++ int ret = 0;
++
++ if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_enable_mesh )
++ return 0;
++
++ down(&priv->wx_sem);
++ if(priv->mshobj->ext_patch_r8180_wx_enable_mesh(dev))
++ {
++ union iwreq_data tmprqu;
++ tmprqu.mode = ieee->iw_mode;
++ ieee->iw_mode = 0;
++ ret = ieee80211_wx_set_mode(ieee, info, &tmprqu, extra);
++ rtl8187_set_rxconf(dev);
++ }
++
++ up(&priv->wx_sem);
++
++ return ret;
++
++}
++
++static int r8180_wx_disable_mesh(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ struct ieee80211_device *ieee = priv->ieee80211;
++
++ int ret = 0;
++
++ if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_disable_mesh )
++ return 0;
++
++ down(&priv->wx_sem);
++ if(priv->mshobj->ext_patch_r8180_wx_disable_mesh(dev))
++ {
++ union iwreq_data tmprqu;
++ tmprqu.mode = ieee->iw_mode;
++ ieee->iw_mode = 999;
++ ret = ieee80211_wx_set_mode(ieee, info, &tmprqu, extra);
++ rtl8187_set_rxconf(dev);
++ }
++
++ up(&priv->wx_sem);
++
++ return ret;
++}
++
++
++int r8180_wx_set_channel(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ int ch = *extra;
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ struct ieee80211_device *ieee = priv->ieee80211;
++
++ if(priv->ieee80211->bHwRadioOff)
++ return 0;
++
++ // is 11s ?
++ if (!priv->mshobj || (ieee->iw_mode != ieee->iw_ext_mode) || !priv->mshobj->ext_patch_r8180_wx_set_channel )
++ return 0;
++
++ printk("set channel = %d\n", ch);
++ if ( ch < 0 )
++ {
++ ieee80211_start_scan(ieee); // auto
++ ieee->meshScanMode =2;
++ }
++ else
++ {
++//#ifdef NETWORKMANAGER_UI
++ if((priv->ieee80211->iw_mode == IW_MODE_MESH) && (priv->ieee80211->iw_ext_mode == IW_MODE_MESH)){
++ }
++//#else
++ else{
++ down(&priv->wx_sem);}
++//#endif
++ ieee->meshScanMode =0;
++ // ieee->set_chan(dev, ch);
++//#ifdef _RTL8187_EXT_PATCH_
++ if(priv->mshobj->ext_patch_r8180_wx_set_channel)
++ {
++ priv->mshobj->ext_patch_r8180_wx_set_channel(ieee, ch);
++ priv->mshobj->ext_patch_r8180_wx_set_mesh_chan(dev,ch);
++ }
++//#endif
++ ieee->set_chan(ieee->dev, ch);
++ ieee->current_network.channel = ch;
++ queue_work(ieee->wq, &ieee->ext_stop_scan_wq);
++ ieee80211_ext_send_11s_beacon(ieee);
++//#ifdef NETWORKMANAGER_UI
++ if((priv->ieee80211->iw_mode == IW_MODE_MESH) && (priv->ieee80211->iw_ext_mode == IW_MODE_MESH)){
++ }
++//#else
++ else{
++ up(&priv->wx_sem);}
++//#endif
++ //up(&ieee->wx_sem);
++
++ // ieee80211_stop_scan(ieee); // user set
++ //
++
++ /*
++ netif_carrier_off(ieee->dev);
++
++ if (ieee->data_hard_stop)
++ ieee->data_hard_stop(ieee->dev);
++
++ ieee->state = IEEE80211_NOLINK;
++ ieee->link_change(ieee->dev);
++
++ ieee->current_network.channel = fwrq->m;
++ ieee->set_chan(ieee->dev, ieee->current_network.channel);
++
++
++ if (ieee->data_hard_resume)
++ ieee->data_hard_resume(ieee->dev);
++
++ netif_carrier_on(ieee->dev);
++ */
++
++ }
++
++ return 0;
++}
++
++static int r8180_wx_set_meshID(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ if(priv->ieee80211->bHwRadioOff)
++ return 0;
++
++ if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_set_meshID )
++ return 0;
++
++ //printk("len=%d\n", wrqu->data.length);
++ //printk("\nCall setMeshid.");
++ return priv->mshobj->ext_patch_r8180_wx_set_meshID(dev, wrqu->data.pointer);
++}
++
++
++/* reserved for future
++static int r8180_wx_add_mac_allow(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_set_add_mac_allow )
++ return 0;
++
++ return priv->mshobj->ext_patch_r8180_wx_set_add_mac_allow(dev, info, wrqu, extra);
++}
++
++static int r8180_wx_del_mac_allow(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_set_del_mac_allow )
++ return 0;
++
++ return priv->mshobj->ext_patch_r8180_wx_set_del_mac_allow(dev, info, wrqu, extra);
++}
++*/
++static int r8180_wx_add_mac_deny(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_set_add_mac_deny )
++ return 0;
++
++ return priv->mshobj->ext_patch_r8180_wx_set_add_mac_deny(dev, info, wrqu, extra);
++}
++
++static int r8180_wx_del_mac_deny(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_set_del_mac_deny )
++ return 0;
++
++ return priv->mshobj->ext_patch_r8180_wx_set_del_mac_deny(dev, info, wrqu, extra);
++}
++
++/* reserved for future
++static int r8180_wx_get_mac_allow(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_get_mac_allow )
++ return 0;
++
++ return priv->mshobj->ext_patch_r8180_wx_get_mac_allow(dev, info, wrqu, extra);
++}
++*/
++
++static int r8180_wx_get_mac_deny(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_get_mac_deny )
++ return 0;
++
++ return priv->mshobj->ext_patch_r8180_wx_get_mac_deny(dev, info, wrqu, extra);
++}
++
++
++static int r8180_wx_get_mesh_list(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_get_mesh_list )
++ return 0;
++
++ return priv->mshobj->ext_patch_r8180_wx_get_mesh_list(dev, info, wrqu, extra);
++}
++
++static int r8180_wx_mesh_scan(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_mesh_scan )
++ return 0;
++
++ return priv->mshobj->ext_patch_r8180_wx_mesh_scan(dev, info, wrqu, extra);
++}
++
++static int r8180_wx_join_mesh(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ int index;
++ int ret=0;
++ char extmeshid[32];
++ int len=0;
++ char id[50], ch;
++//#ifdef NETWORKMANAGER_UI
++
++ if((priv->ieee80211->iw_mode == IW_MODE_MESH) && (priv->ieee80211->iw_ext_mode == IW_MODE_MESH)){
++ printk("join mesh %s\n",extra);
++ if (wrqu->essid.length > IW_ESSID_MAX_SIZE){
++ ret= -E2BIG;
++ goto out;
++ }
++ //printk("wrqu->essid.length is %d\n",wrqu->essid.length);
++ //printk("wrqu->essid.flags is %d\n",wrqu->essid.flags);
++ if((wrqu->essid.length == 1) && (wrqu->essid.flags == 1)){
++ ret = 0;
++ goto out;
++ }
++ if (wrqu->essid.flags && wrqu->essid.length) {
++ if(priv->mshobj->ext_patch_r8180_wx_get_selected_mesh_channel(dev, extra, &ch))
++ {
++ priv->mshobj->ext_patch_r8180_wx_set_meshID(dev, extra);
++ priv->mshobj->ext_patch_r8180_wx_set_mesh_chan(dev,ch);
++ r8180_wx_set_channel(dev, NULL, NULL, &ch);
++ }
++ else
++ printk("invalid mesh #\n");
++
++ }
++#if 0
++ else{
++ if(priv->mshobj->ext_patch_r8180_wx_get_selected_mesh_channel(dev, 0, &ch))
++ {
++ priv->mshobj->ext_patch_r8180_wx_set_meshID(dev, extra);
++ priv->mshobj->ext_patch_r8180_wx_set_mesh_chan(dev,ch);
++ r8180_wx_set_channel(dev, NULL, NULL, &ch);
++ }
++ else
++ printk("invalid mesh #\n");
++
++ }
++#endif
++ }
++ else{
++//#else
++ index = *(extra);
++// printk("index=%d\n", index);
++
++ if( ! priv->mshobj
++ || !priv->mshobj->ext_patch_r8180_wx_set_meshID
++ || !priv->mshobj->ext_patch_r8180_wx_get_selected_mesh )
++ return 0;
++
++ if( priv->mshobj->ext_patch_r8180_wx_get_selected_mesh(dev, index, &ch, id) )
++ {
++ // printk("ch=%d, id=%s\n", ch, id);
++ priv->mshobj->ext_patch_r8180_wx_set_meshID(dev, id);
++ priv->mshobj->ext_patch_r8180_wx_set_mesh_chan(dev,ch);
++ r8180_wx_set_channel(dev, NULL, NULL, &ch);
++ }
++ else
++ printk("invalid mesh #\n");
++ }
++//#endif
++out:
++ return ret;
++}
++
++#endif // _RTL8187_EXT_PATCH_
++
++
++static int r8180_wx_get_radion(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++// u8 addr;
++
++ down(&priv->wx_sem);
++ if(priv->radion == 1) {
++ *(int *)extra = 1;
++ } else {
++
++ *(int *)extra = 0;
++ }
++ up(&priv->wx_sem);
++ return 0;
++
++}
++
++static int r8180_wx_set_radion(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ int radion = *extra;
++ struct r8180_priv *priv = ieee80211_priv(dev);
++// struct ieee80211_device *ieee = priv->ieee80211;
++ u8 btCR9346, btConfig3;
++ int i;
++ u16 u2bTFPC = 0;
++ u8 u1bTmp;
++
++ if(priv->ieee80211->bHwRadioOff)
++ return 0;
++
++ down(&priv->wx_sem);
++ printk("set radion = %d\n", radion);
++
++#ifdef _RTL8187_EXT_PATCH_
++ if(ieee->iw_mode == ieee->iw_ext_mode) {
++ printk("mesh mode:: could not set radi on/off = %d\n", radion);
++ up(&priv->wx_sem);
++ return 0;
++ }
++#endif
++ // Set EEM0 and EEM1 in 9346CR.
++ btCR9346 = read_nic_byte(dev, CR9346);
++ write_nic_byte(dev, CR9346, (btCR9346|0xC0) );
++ // Set PARM_En in Config3.
++ btConfig3 = read_nic_byte(dev, CONFIG3);
++ write_nic_byte(dev, CONFIG3, (btConfig3|CONFIG3_PARM_En) );
++
++ if ( radion == 1) //radion off
++ {
++ printk("==================>RF on\n");
++ write_nic_dword(dev, ANAPARAM, ANAPARM_ON);
++ write_nic_dword(dev, ANAPARAM2, ANAPARM2_ON);
++ write_nic_byte(dev, CONFIG4, (priv->RFProgType));
++
++ write_nic_byte(dev, 0x085, 0x24); // 061219, SD3 ED: for minicard CCK power leakage issue.
++ write_rtl8225(dev, 0x4, 0x9FF);
++
++ u1bTmp = read_nic_byte(dev, 0x24E);
++ write_nic_byte(dev, 0x24E, (u1bTmp & (~(BIT5|BIT6))) );// 070124 SD1 Alex: turn on CCK and OFDM.
++ priv->radion = 1; //radion on
++ }
++ else
++ {
++ printk("==================>RF off\n");
++ for(i = 0; i < MAX_DOZE_WAITING_TIMES_87B; i++)
++ { // Make sure TX FIFO is empty befor turn off RFE pwoer.
++ u2bTFPC = read_nic_word(dev, TFPC);
++ if(u2bTFPC == 0)
++ {
++ break;
++ }
++ else
++ {
++ printk("%d times TFPC: %d != 0 before doze!\n", (i+1), u2bTFPC);
++ udelay(10);
++ }
++ }
++ if( i == MAX_DOZE_WAITING_TIMES_87B )
++ {
++ printk("\n\n\n SetZebraRFPowerState8187B(): %d times TFPC: %d != 0 !!!\n\n\n",\
++ MAX_DOZE_WAITING_TIMES_87B, u2bTFPC);
++ }
++
++ u1bTmp = read_nic_byte(dev, 0x24E);
++ write_nic_byte(dev, 0x24E, (u1bTmp|BIT5|BIT6));// 070124 SD1 Alex: turn off CCK and OFDM.
++
++ write_rtl8225(dev, 0x4,0x1FF); // Turn off RF first to prevent BB lock up, suggested by PJ, 2006.03.03.
++ write_nic_byte(dev, 0x085, 0x04); // 061219, SD3 ED: for minicard CCK power leakage issue.
++
++ write_nic_byte(dev, CONFIG4, (priv->RFProgType|Config4_PowerOff));
++
++ write_nic_dword(dev, ANAPARAM, ANAPARM_OFF);
++ write_nic_dword(dev, ANAPARAM2, ANAPARM2_OFF); // 070301, SD1 William: to reduce RF off power consumption to 80 mA.
++ priv->radion = 0; //radion off
++ }
++ // Clear PARM_En in Config3.
++ btConfig3 &= ~(CONFIG3_PARM_En);
++ write_nic_byte(dev, CONFIG3, btConfig3);
++ // Clear EEM0 and EEM1 in 9346CR.
++ btCR9346 &= ~(0xC0);
++ write_nic_byte(dev, CR9346, btCR9346);
++
++ up(&priv->wx_sem);
++
++ return 0;
++}
++
++static int r8180_wx_set_ratadpt (struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ int ratadapt = *extra;
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ struct ieee80211_device *ieee = priv->ieee80211;
++
++ if(priv->ieee80211->bHwRadioOff)
++ return 0;
++
++ down(&priv->wx_sem);
++ printk("Set rate adaptive %s\n", (ratadapt==0)?"on":"off");
++ if(ratadapt == 0) {
++ del_timer_sync(&priv->rateadapter_timer);
++ cancel_delayed_work(&priv->ieee80211->rate_adapter_wq);
++ priv->rateadapter_timer.function((unsigned long)dev);
++ } else {
++ del_timer_sync(&priv->rateadapter_timer);
++ cancel_delayed_work(&priv->ieee80211->rate_adapter_wq);
++ printk("force rate to %d\n", ratadapt);
++ ieee->rate = ratadapt;
++ }
++ up(&priv->wx_sem);
++ return 0;
++}
++
++#ifdef ENABLE_TOSHIBA_CONFIG
++static int r8180_wx_get_tblidx(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ //extern u8 chan_plan_index;
++ //printk("=========>%s(), %x\n", __FUNCTION__, priv->channel_plan);
++ down(&priv->wx_sem);
++ put_user(priv->channel_plan, (u8*)wrqu->data.pointer);
++ up(&priv->wx_sem);
++ return 0;
++
++}
++
++//This func will be called after probe auto
++static int r8180_wx_set_tbl (struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ u8 len = 0;
++ s8 err = -1;
++ extern CHANNEL_LIST Current_tbl;
++ down(&priv->wx_sem);
++ if (!wrqu->data.pointer)
++ {
++ printk("user data pointer is null\n");
++ goto exit;
++ }
++ len = wrqu->data.length;
++ //printk("=========>%s(), len:%d\n", __FUNCTION__, len);
++ //memset(&Current_tbl, 0, sizeof(CHANNEL_LIST));
++ if (copy_from_user((u8*)&Current_tbl, (void*)wrqu->data.pointer, len))
++ {
++ printk("error copy from user\n");
++ goto exit;
++ }
++ {
++ int i;
++ Current_tbl.Len = len;
++ //printk("%d\n", Current_tbl.Len);
++
++ Dot11d_Init(priv->ieee80211);
++ priv->ieee80211->bGlobalDomain = false;
++ priv->ieee80211->bWorldWide13 = false;
++
++ //lzm add 081205
++ priv->ieee80211->MinPassiveChnlNum=12;
++ priv->ieee80211->IbssStartChnl= 10;
++
++ for (i=0; i<Current_tbl.Len; i++){
++ //printk("%2d ", Current_tbl.Channel[i]);
++ if(priv->channel_plan == COUNTRY_CODE_ETSI)
++ {
++ if(Current_tbl.Channel[i] <= 11)
++ {
++#ifdef ENABLE_DOT11D
++ GET_DOT11D_INFO(priv->ieee80211)->channel_map[Current_tbl.Channel[i]] = 1;
++#else
++ priv->ieee80211->channel_map[Current_tbl.Channel[i]] = 1;
++#endif
++ }
++ else if((Current_tbl.Channel[i] >= 11) && (Current_tbl.Channel[i] <= 13))
++ {
++#ifdef ENABLE_DOT11D
++ GET_DOT11D_INFO(priv->ieee80211)->channel_map[Current_tbl.Channel[i]] = 2;
++#else
++ priv->ieee80211->channel_map[Current_tbl.Channel[i]] = 2;
++#endif
++ }
++ }
++ else
++ {
++ if(Current_tbl.Channel[i] <= 14)
++ {
++#ifdef ENABLE_DOT11D
++ GET_DOT11D_INFO(priv->ieee80211)->channel_map[Current_tbl.Channel[i]] = 1;
++#else
++ priv->ieee80211->channel_map[Current_tbl.Channel[i]] = 1;
++#endif
++ }
++ }
++ }
++#if 0
++ printk("\n");
++ for(i=1; i<MAX_CHANNEL_NUMBER; i++)
++ {
++#ifdef ENABLE_DOT11D
++ printk("%2d ", GET_DOT11D_INFO(priv->ieee80211)->channel_map[i]);
++#else
++ printk("%2d ", priv->ieee80211->channel_map[i]);
++#endif
++ }
++ printk("\n");
++
++#endif
++ if(priv->ieee80211->proto_started)
++ {//we need to restart protocol now if it was start before channel map
++ ieee80211_softmac_stop_protocol(priv->ieee80211);
++ //mdelay(1);
++ ieee80211_softmac_start_protocol(priv->ieee80211);
++ }
++ }
++ err = 0;
++exit:
++ up(&priv->wx_sem);
++ return err;
++
++
++}
++
++#endif
++
++
++static iw_handler r8180_wx_handlers[] =
++{
++ NULL, /* SIOCSIWCOMMIT */
++ r8180_wx_get_name, /* SIOCGIWNAME */
++ dummy, /* SIOCSIWNWID */
++ dummy, /* SIOCGIWNWID */
++ r8180_wx_set_freq, /* SIOCSIWFREQ */
++ r8180_wx_get_freq, /* SIOCGIWFREQ */
++ r8180_wx_set_mode, /* SIOCSIWMODE */
++ r8180_wx_get_mode, /* SIOCGIWMODE */
++ r8180_wx_set_sens, /* SIOCSIWSENS */
++ r8180_wx_get_sens, /* SIOCGIWSENS */
++ NULL, /* SIOCSIWRANGE */
++ rtl8180_wx_get_range, /* SIOCGIWRANGE */
++ NULL, /* SIOCSIWPRIV */
++ NULL, /* SIOCGIWPRIV */
++ NULL, /* SIOCSIWSTATS */
++ NULL, /* SIOCGIWSTATS */
++ dummy, /* SIOCSIWSPY */
++ dummy, /* SIOCGIWSPY */
++ NULL, /* SIOCGIWTHRSPY */
++ NULL, /* SIOCWIWTHRSPY */
++ r8180_wx_set_wap, /* SIOCSIWAP */
++ r8180_wx_get_wap, /* SIOCGIWAP */
++ r8180_wx_set_mlme, //NULL, /* SIOCSIWMLME*/ /* -- hole -- */
++ dummy, /* SIOCGIWAPLIST -- depricated */
++ r8180_wx_set_scan, /* SIOCSIWSCAN */
++ r8180_wx_get_scan, /* SIOCGIWSCAN */
++ r8180_wx_set_essid, /* SIOCSIWESSID */
++ r8180_wx_get_essid, /* SIOCGIWESSID */
++ dummy, /* SIOCSIWNICKN */
++ dummy, /* SIOCGIWNICKN */
++ NULL, /* -- hole -- */
++ NULL, /* -- hole -- */
++ r8180_wx_set_rate, /* SIOCSIWRATE */
++ r8180_wx_get_rate, /* SIOCGIWRATE */
++ dummy, /* SIOCSIWRTS */
++ dummy, /* SIOCGIWRTS */
++ r8180_wx_set_frag, /* SIOCSIWFRAG */
++ r8180_wx_get_frag, /* SIOCGIWFRAG */
++ dummy, /* SIOCSIWTXPOW */
++ dummy, /* SIOCGIWTXPOW */
++ r8180_wx_set_retry, /* SIOCSIWRETRY */
++ r8180_wx_get_retry, /* SIOCGIWRETRY */
++ r8180_wx_set_enc, /* SIOCSIWENCODE */
++ r8180_wx_get_enc, /* SIOCGIWENCODE */
++ dummy, /* SIOCSIWPOWER */
++ dummy, /* SIOCGIWPOWER */
++ NULL, /*---hole---*/
++ NULL, /*---hole---*/
++ r8180_wx_set_gen_ie,//NULL, /* SIOCSIWGENIE */
++ NULL, /* SIOCSIWGENIE */
++ r8180_wx_set_auth,//NULL, /* SIOCSIWAUTH */
++ NULL,//r8180_wx_get_auth,//NULL, /* SIOCSIWAUTH */
++ r8180_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
++ NULL,//r8180_wx_get_enc_ext,//NULL, /* SIOCSIWENCODEEXT */
++ NULL, /* SIOCSIWPMKSA */
++ NULL, /*---hole---*/
++};
++
++
++static const struct iw_priv_args r8180_private_args[] = {
++ {
++ SIOCIWFIRSTPRIV + 0x0,
++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
++ },
++
++ {
++ SIOCIWFIRSTPRIV + 0x1,
++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
++
++ },
++ {
++ SIOCIWFIRSTPRIV + 0x2,
++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
++ },
++#ifdef JOHN_IOCTL
++ {
++ SIOCIWFIRSTPRIV + 0x3,
++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readRF"
++ }
++ ,
++ {
++ SIOCIWFIRSTPRIV + 0x4,
++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeRF"
++ }
++ ,
++ {
++ SIOCIWFIRSTPRIV + 0x5,
++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readBB"
++ }
++ ,
++ {
++ SIOCIWFIRSTPRIV + 0x6,
++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeBB"
++ }
++ ,
++ {
++ SIOCIWFIRSTPRIV + 0x7,
++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readnicb"
++ }
++ ,
++ {
++ SIOCIWFIRSTPRIV + 0x8,
++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writenicb"
++ }
++ ,
++ {
++ SIOCIWFIRSTPRIV + 0x9,
++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
++ },
++#endif
++ {
++ SIOCIWFIRSTPRIV + 0xA,
++ 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED |1, "getradion"
++ },
++ {
++ SIOCIWFIRSTPRIV + 0xB,
++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setradion"
++ },
++ {
++ SIOCIWFIRSTPRIV + 0xC,
++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "ratadpt"
++ },
++#ifdef ENABLE_TOSHIBA_CONFIG
++ {
++ SIOCIWFIRSTPRIV + 0xD,
++ 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gettblidx"
++ },
++ {
++ SIOCIWFIRSTPRIV + 0xE,
++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,0, "settblidx"
++ },
++
++#endif
++
++};
++
++/*
++ * Private ioctl interface information
++
++struct iw_priv_args
++{
++// __u32 cmd;
++// __u16 set_args;
++// __u16 get_args;
++// char name[IFNAMSIZ];
++//};
++*/
++//If get cmd's number is big,there may cause some problemes.
++//So modified by Lawrence,071120
++
++static iw_handler r8180_private_handler[] = {
++// r8180_wx_set_monitor, /* SIOCIWFIRSTPRIV */
++ r8180_wx_set_crcmon, /*SIOCIWSECONDPRIV*/
++// r8180_wx_set_forceassociate,
++// r8180_wx_set_beaconinterval,
++// r8180_wx_set_monitor_type,
++ r8180_wx_set_scan_type,
++ r8180_wx_set_rawtx,
++
++#if 0
++#ifdef _RTL8187_EXT_PATCH_
++ r8180_wx_get_meshinfo,
++ r8180_wx_enable_mesh,
++ r8180_wx_disable_mesh,
++ r8180_wx_set_channel,
++ r8180_wx_set_meshID,
++
++// r8180_wx_add_mac_allow,
++// r8180_wx_get_mac_allow,
++// r8180_wx_del_mac_allow,
++ r8180_wx_add_mac_deny,
++ r8180_wx_get_mac_deny,
++ r8180_wx_del_mac_deny,
++ r8180_wx_get_mesh_list,
++ r8180_wx_mesh_scan,
++ r8180_wx_join_mesh,
++#endif
++#endif
++
++#ifdef JOHN_IOCTL
++ r8180_wx_read_regs,
++ r8180_wx_write_regs,
++ r8180_wx_read_bb,
++ r8180_wx_write_bb,
++ r8180_wx_read_nicb,
++ r8180_wx_write_nicb,
++ r8180_wx_get_ap_status,
++#endif
++ r8180_wx_get_radion,
++ r8180_wx_set_radion,
++ r8180_wx_set_ratadpt,
++#ifdef ENABLE_TOSHIBA_CONFIG
++ r8180_wx_get_tblidx,
++ r8180_wx_set_tbl,
++#endif
++};
++
++#if WIRELESS_EXT >= 17
++//WB modefied to show signal to GUI on 18-01-2008
++static struct iw_statistics *r8180_get_wireless_stats(struct net_device *dev)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ struct ieee80211_device* ieee = priv->ieee80211;
++ struct iw_statistics* wstats = &priv->wstats;
++// struct ieee80211_network* target = NULL;
++ int tmp_level = 0;
++ int tmp_qual = 0;
++ int tmp_noise = 0;
++// unsigned long flag;
++
++ if (ieee->state < IEEE80211_LINKED)
++ {
++ wstats->qual.qual = 0;
++ wstats->qual.level = 0;
++ wstats->qual.noise = 0;
++ wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
++ return wstats;
++ }
++#if 0
++ spin_lock_irqsave(&ieee->lock, flag);
++ list_for_each_entry(target, &ieee->network_list, list)
++ {
++ if (is_same_network(target, &ieee->current_network))
++ {
++ printk("it's same network:%s\n", target->ssid);
++#if 0
++ if (!tmp_level)
++ {
++ tmp_level = target->stats.signalstrength;
++ tmp_qual = target->stats.signal;
++ }
++ else
++ {
++
++ tmp_level = (15*tmp_level + target->stats.signalstrength)/16;
++ tmp_qual = (15*tmp_qual + target->stats.signal)/16;
++ }
++#else
++ tmp_level = target->stats.signal;
++ tmp_qual = target->stats.signalstrength;
++ tmp_noise = target->stats.noise;
++ printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
++#endif
++ break;
++ }
++ }
++ spin_unlock_irqrestore(&ieee->lock, flag);
++#endif
++ tmp_level = (&ieee->current_network)->stats.signal;
++ tmp_qual = (&ieee->current_network)->stats.signalstrength;
++ tmp_noise = (&ieee->current_network)->stats.noise;
++ //printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
++
++ wstats->qual.level = tmp_level;
++ wstats->qual.qual = tmp_qual;
++ wstats->qual.noise = tmp_noise;
++ wstats->qual.updated = IW_QUAL_ALL_UPDATED| IW_QUAL_DBM;
++ return wstats;
++}
++#endif
++
++
++struct iw_handler_def r8180_wx_handlers_def={
++ .standard = r8180_wx_handlers,
++ .num_standard = sizeof(r8180_wx_handlers) / sizeof(iw_handler),
++ .private = r8180_private_handler,
++ .num_private = sizeof(r8180_private_handler) / sizeof(iw_handler),
++ .num_private_args = sizeof(r8180_private_args) / sizeof(struct iw_priv_args),
++#if WIRELESS_EXT >= 17
++ .get_wireless_stats = r8180_get_wireless_stats,
++#endif
++ .private_args = (struct iw_priv_args *)r8180_private_args,
++};
++#ifdef _RTL8187_EXT_PATCH_
++EXPORT_SYMBOL(r8180_wx_set_channel);
++#endif
+diff --git a/drivers/net/wireless/rtl8187b/r8180_wx.h b/drivers/net/wireless/rtl8187b/r8180_wx.h
+new file mode 100644
+index 0000000..0c62a99
+--- /dev/null
++++ b/drivers/net/wireless/rtl8187b/r8180_wx.h
+@@ -0,0 +1,21 @@
++/*
++ This is part of rtl8180 OpenSource driver - v 0.3
++ Copyright (C) Andrea Merello 2004 <andreamrl@tiscali.it>
++ Released under the terms of GPL (General Public Licence)
++
++ Parts of this driver are based on the GPL part of the official realtek driver
++ Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon
++ Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
++
++ We want to tanks the Authors of such projects and the Ndiswrapper project Authors.
++*/
++
++/* this file (will) contains wireless extension handlers*/
++
++#ifndef R8180_WX_H
++#define R8180_WX_H
++#include <linux/wireless.h>
++#include "ieee80211/ieee80211.h"
++extern struct iw_handler_def r8180_wx_handlers_def;
++
++#endif
+diff --git a/drivers/net/wireless/rtl8187b/r8187.h b/drivers/net/wireless/rtl8187b/r8187.h
+new file mode 100644
+index 0000000..ab18683
+--- /dev/null
++++ b/drivers/net/wireless/rtl8187b/r8187.h
+@@ -0,0 +1,811 @@
++/*
++ This is part of rtl8187 OpenSource driver.
++ Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it>
++ Released under the terms of GPL (General Public Licence)
++
++ Parts of this driver are based on the GPL part of the
++ official realtek driver
++
++ Parts of this driver are based on the rtl8180 driver skeleton
++ from Patric Schenke & Andres Salomon
++
++ Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
++
++ We want to tanks the Authors of those projects and the Ndiswrapper
++ project Authors.
++*/
++
++#ifndef R8180H
++#define R8180H
++
++
++#define RTL8187_MODULE_NAME "rtl8187"
++#define DMESG(x,a...) printk(KERN_INFO RTL8187_MODULE_NAME ": " x "\n", ## a)
++#define DMESGW(x,a...) printk(KERN_WARNING RTL8187_MODULE_NAME ": WW:" x "\n", ## a)
++#define DMESGE(x,a...) printk(KERN_WARNING RTL8187_MODULE_NAME ": EE:" x "\n", ## a)
++
++#include <linux/module.h>
++#include <linux/kernel.h>
++//#include <linux/config.h>
++#include <linux/init.h>
++#include <linux/ioport.h>
++#include <linux/sched.h>
++#include <linux/types.h>
++#include <linux/slab.h>
++#include <linux/netdevice.h>
++//#include <linux/pci.h>
++#include <linux/usb.h>
++#include <linux/etherdevice.h>
++#include <linux/delay.h>
++#include <linux/rtnetlink.h> //for rtnl_lock()
++#include <linux/wireless.h>
++#include <linux/timer.h>
++#include <linux/proc_fs.h> // Necessary because we use the proc fs
++#include <linux/if_arp.h>
++#include <linux/random.h>
++#include <linux/version.h>
++#include <asm/io.h>
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
++#include <asm/semaphore.h>
++#endif
++#include "ieee80211/ieee80211.h"
++#ifdef _RTL8187_EXT_PATCH_
++#include "msh_class.h"
++#endif
++#ifdef LED
++#include "r8187_led.h"
++#endif
++
++//added for HW security, john.0629
++#define FALSE 0
++#define TRUE 1
++#define MAX_KEY_LEN 61
++#define KEY_BUF_SIZE 5
++
++#define BIT0 0x00000001
++#define BIT1 0x00000002
++#define BIT2 0x00000004
++#define BIT3 0x00000008
++#define BIT4 0x00000010
++#define BIT5 0x00000020
++#define BIT6 0x00000040
++#define BIT7 0x00000080
++#define BIT8 0x00000100
++#define BIT9 0x00000200
++#define BIT10 0x00000400
++#define BIT11 0x00000800
++#define BIT12 0x00001000
++#define BIT13 0x00002000
++#define BIT14 0x00004000
++#define BIT15 0x00008000
++#define BIT16 0x00010000
++#define BIT17 0x00020000
++#define BIT18 0x00040000
++#define BIT19 0x00080000
++#define BIT20 0x00100000
++#define BIT21 0x00200000
++#define BIT22 0x00400000
++#define BIT23 0x00800000
++#define BIT24 0x01000000
++#define BIT25 0x02000000
++#define BIT26 0x04000000
++#define BIT27 0x08000000
++#define BIT28 0x10000000
++#define BIT29 0x20000000
++#define BIT30 0x40000000
++#define BIT31 0x80000000
++
++//8187B Security
++#define RWCAM 0xA0 // Software read/write CAM config
++#define WCAMI 0xA4 // Software write CAM input content
++#define RCAMO 0xA8 // Output value from CAM according to 0xa0 setting
++#define DCAM 0xAC // Debug CAM Interface
++#define SECR 0xB0 // Security configuration register
++#define AESMSK_FC 0xB2 // AES Mask register for frame control (0xB2~0xB3). Added by Annie, 2006-03-06.
++#define AESMSK_SC 0x1FC // AES Mask for Sequence Control (0x1FC~0X1FD). Added by Annie, 2006-03-06.
++#define AESMSK_QC 0x1CE // AES Mask register for QoS Control when computing AES MIC, default = 0x000F. (2 bytes)
++
++#define AESMSK_FC_DEFAULT 0xC78F // default value of AES MASK for Frame Control Field. (2 bytes)
++#define AESMSK_SC_DEFAULT 0x000F // default value of AES MASK for Sequence Control Field. (2 bytes)
++#define AESMSK_QC_DEFAULT 0x000F // default value of AES MASK for QoS Control Field. (2 bytes)
++
++#define CAM_CONTENT_COUNT 6
++#define CFG_DEFAULT_KEY BIT5
++#define CFG_VALID BIT15
++
++//----------------------------------------------------------------------------
++// 8187B WPA Config Register (offset 0xb0, 1 byte)
++//----------------------------------------------------------------------------
++#define SCR_UseDK 0x01
++#define SCR_TxSecEnable 0x02
++#define SCR_RxSecEnable 0x04
++
++//----------------------------------------------------------------------------
++// 8187B CAM Config Setting (offset 0xb0, 1 byte)
++//----------------------------------------------------------------------------
++#define CAM_VALID 0x8000
++#define CAM_NOTVALID 0x0000
++#define CAM_USEDK 0x0020
++
++
++#define CAM_NONE 0x0
++#define CAM_WEP40 0x01
++#define CAM_TKIP 0x02
++#define CAM_AES 0x04
++#define CAM_WEP104 0x05
++
++
++//#define CAM_SIZE 16
++#define TOTAL_CAM_ENTRY 16
++#define CAM_ENTRY_LEN_IN_DW 6 // 6, unit: in u4byte. Added by Annie, 2006-05-25.
++#define CAM_ENTRY_LEN_IN_BYTE (CAM_ENTRY_LEN_IN_DW*sizeof(u4Byte)) // 24, unit: in u1byte. Added by Annie, 2006-05-25.
++
++#define CAM_CONFIG_USEDK 1
++#define CAM_CONFIG_NO_USEDK 0
++
++#define CAM_WRITE 0x00010000
++#define CAM_READ 0x00000000
++#define CAM_POLLINIG 0x80000000
++
++//=================================================================
++//=================================================================
++
++#define EPROM_93c46 0
++#define EPROM_93c56 1
++
++#define DEFAULT_FRAG_THRESHOLD 2342U
++#define MIN_FRAG_THRESHOLD 256U
++#define DEFAULT_BEACONINTERVAL 0x64U
++#define DEFAULT_BEACON_ESSID "Rtl8187"
++
++#define DEFAULT_SSID ""
++#define DEFAULT_RETRY_RTS 7
++#define DEFAULT_RETRY_DATA 7
++#define PRISM_HDR_SIZE 64
++
++typedef enum _WIRELESS_MODE {
++ WIRELESS_MODE_UNKNOWN = 0x00,
++ WIRELESS_MODE_A = 0x01,
++ WIRELESS_MODE_B = 0x02,
++ WIRELESS_MODE_G = 0x04,
++ WIRELESS_MODE_AUTO = 0x08,
++} WIRELESS_MODE;
++
++typedef enum _TR_SWITCH_STATE{
++ TR_HW_CONTROLLED = 0,
++ TR_SW_TX = 1,
++}TR_SWITCH_STATE, *PTR_SWITCH_STATE;
++
++
++#define RTL_IOCTL_WPA_SUPPLICANT SIOCIWFIRSTPRIV+30
++
++typedef struct buffer
++{
++ struct buffer *next;
++ u32 *buf;
++
++} buffer;
++
++typedef struct rtl_reg_debug{
++ unsigned int cmd;
++ struct {
++ unsigned char type;
++ unsigned char addr;
++ unsigned char page;
++ unsigned char length;
++ } head;
++ unsigned char buf[0xff];
++}rtl_reg_debug;
++typedef struct _CHANNEL_LIST{
++ u8 Channel[MAX_CHANNEL_NUMBER + 1];
++ u8 Len;
++}CHANNEL_LIST, *PCHANNEL_LIST;
++
++#define MAX_LD_SLOT_NUM 10
++#define DEFAULT_SLOT_NUM 2
++#define KEEP_ALIVE_INTERVAL 20 // in seconds.
++#define CHECK_FOR_HANG_PERIOD 2 //be equal to watchdog check time
++#define DEFAULT_KEEP_ALIVE_LEVEL 1
++
++typedef struct _link_detect_t
++{
++ u32 RxFrameNum[MAX_LD_SLOT_NUM]; // number of Rx Frame / CheckForHang_period to determine link status
++ u16 SlotNum; // number of CheckForHang period to determine link status, default is 2
++ u16 SlotIndex;
++
++ u32 NumTxOkInPeriod; //number of packet transmitted during CheckForHang
++ u32 NumRxOkInPeriod; //number of packet received during CheckForHang
++
++ u8 IdleCount; // (KEEP_ALIVE_INTERVAL / CHECK_FOR_HANG_PERIOD)
++ u32 LastNumTxUnicast;
++ u32 LastNumRxUnicast;
++
++ bool bBusyTraffic; //when it is set to 1, UI cann't scan at will.
++}link_detect_t, *plink_detect_t;
++
++#if 0
++
++typedef struct tx_pendingbuf
++{
++ struct ieee80211_txb *txb;
++ short ispending;
++ short descfrag;
++} tx_pendigbuf;
++
++#endif
++
++typedef struct Stats
++{
++ unsigned long txrdu;
++// unsigned long rxrdu;
++ //unsigned long rxnolast;
++ //unsigned long rxnodata;
++// unsigned long rxreset;
++// unsigned long rxwrkaround;
++// unsigned long rxnopointer;
++ unsigned long rxok;
++ unsigned long rxurberr;
++ unsigned long rxstaterr;
++ unsigned long txnperr;
++ unsigned long txnpdrop;
++ unsigned long txresumed;
++// unsigned long rxerr;
++// unsigned long rxoverflow;
++// unsigned long rxint;
++ unsigned long txnpokint;
++// unsigned long txhpokint;
++// unsigned long txhperr;
++// unsigned long ints;
++// unsigned long shints;
++ unsigned long txoverflow;
++// unsigned long rxdmafail;
++// unsigned long txbeacon;
++// unsigned long txbeaconerr;
++ unsigned long txlpokint;
++ unsigned long txlpdrop;
++ unsigned long txlperr;
++ unsigned long txbeokint;
++ unsigned long txbedrop;
++ unsigned long txbeerr;
++ unsigned long txbkokint;
++ unsigned long txbkdrop;
++ unsigned long txbkerr;
++ unsigned long txviokint;
++ unsigned long txvidrop;
++ unsigned long txvierr;
++ unsigned long txvookint;
++ unsigned long txvodrop;
++ unsigned long txvoerr;
++ unsigned long txbeaconokint;
++ unsigned long txbeacondrop;
++ unsigned long txbeaconerr;
++ unsigned long txmanageokint;
++ unsigned long txmanagedrop;
++ unsigned long txmanageerr;
++ unsigned long txdatapkt;
++} Stats;
++
++typedef struct ChnlAccessSetting {
++ u16 SIFS_Timer;
++ u16 DIFS_Timer;
++ u16 SlotTimeTimer;
++ u16 EIFS_Timer;
++ u16 CWminIndex;
++ u16 CWmaxIndex;
++}*PCHANNEL_ACCESS_SETTING,CHANNEL_ACCESS_SETTING;
++
++
++typedef enum _RT_RF_POWER_STATE
++{
++ eRfOn,
++ eRfSleep,
++ eRfOff
++}RT_RF_POWER_STATE;
++typedef enum _RT_PS_MODE
++{
++ eActive, // Active/Continuous access.
++ eMaxPs, // Max power save mode.
++ eFastPs // Fast power save mode.
++}RT_PS_MODE;
++//
++// Three wire mode.
++//
++#define IC_DEFAULT_THREE_WIRE 0
++#define SW_THREE_WIRE 1
++//RTL818xB
++#define SW_THREE_WIRE_BY_8051 2
++#define HW_THREE_WIRE 3
++#define HW_THREE_WIRE_BY_8051 4
++//lzm add for write time out test
++typedef struct write_read_register
++{
++ u32 address;
++ u32 content;
++ u32 flag;
++} write_read_register;
++//lzm add for write time out test
++typedef struct r8180_priv
++{
++//lzm add for write time out test
++ struct write_read_register write_read_registers[200];
++ u8 write_read_register_index;
++//lzm add for write time out test
++
++ struct usb_device *udev;
++ short epromtype;
++ int irq;
++ struct ieee80211_device *ieee80211;
++
++ short card_8187; /* O: rtl8180, 1:rtl8185 V B/C, 2:rtl8185 V D */
++ short card_8187_Bversion; /* if TCR reports card V B/C this discriminates */
++ short phy_ver; /* meaningful for rtl8225 1:A 2:B 3:C */
++ short enable_gpio0;
++ enum card_type {PCI,MINIPCI,CARDBUS,USB/*rtl8187*/}card_type;
++ short hw_plcp_len;
++ short plcp_preamble_mode;
++
++ spinlock_t irq_lock;
++// spinlock_t irq_th_lock;
++ spinlock_t tx_lock;
++//by amy for ps
++ spinlock_t rf_ps_lock;
++//by amy for ps
++
++ u16 irq_mask;
++// short irq_enabled;
++ struct net_device *dev;
++ short chan;
++ short sens;
++ short max_sens;
++ u8 chtxpwr[15]; //channels from 1 to 14, 0 not used
++ u8 chtxpwr_ofdm[15]; //channels from 1 to 14, 0 not used
++ u8 cck_txpwr_base;
++ u8 ofdm_txpwr_base;
++ u8 challow[15]; //channels from 1 to 14, 0 not used
++ short up;
++ short crcmon; //if 1 allow bad crc frame reception in monitor mode
++// short prism_hdr;
++
++// struct timer_list scan_timer;
++ /*short scanpending;
++ short stopscan;*/
++// spinlock_t scan_lock;
++// u8 active_probe;
++ //u8 active_scan_num;
++ struct semaphore wx_sem;
++ struct semaphore set_chan_sem;
++// short hw_wep;
++
++// short digphy;
++// short antb;
++// short diversity;
++// u8 cs_treshold;
++// short rcr_csense;
++ short rf_chip;
++// u32 key0[4];
++ short (*rf_set_sens)(struct net_device *dev,short sens);
++ void (*rf_set_chan)(struct net_device *dev,short ch);
++ void (*rf_close)(struct net_device *dev);
++ void (*rf_init)(struct net_device *dev);
++ //short rate;
++ short promisc;
++ /*stats*/
++ struct Stats stats;
++ struct _link_detect_t link_detect; //added on 1016.2008
++ struct iw_statistics wstats;
++ struct proc_dir_entry *dir_dev;
++
++ /*RX stuff*/
++// u32 *rxring;
++// u32 *rxringtail;
++// dma_addr_t rxringdma;
++ struct urb **rx_urb;
++#ifdef THOMAS_BEACON
++ unsigned long *oldaddr; //lzm for 64bit CPU crash
++#endif
++
++#ifdef THOMAS_TASKLET
++ atomic_t irt_counter;//count for irq_rx_tasklet
++#endif
++#ifdef JACKSON_NEW_RX
++ struct sk_buff **pp_rxskb;
++ int rx_inx;
++#endif
++
++ short tx_urb_index;
++
++ //struct buffer *rxbuffer;
++ //struct buffer *rxbufferhead;
++ //int rxringcount;
++ //u16 rxbuffersize;
++
++ //struct sk_buff *rx_skb;
++
++ //short rx_skb_complete;
++
++ //u32 rx_prevlen;
++ //atomic_t tx_lp_pending;
++ //atomic_t tx_np_pending;
++ atomic_t tx_pending[0x10];//UART_PRIORITY+1
++
++#if 0
++ /*TX stuff*/
++ u32 *txlpring;
++ u32 *txhpring;
++ u32 *txnpring;
++ dma_addr_t txlpringdma;
++ dma_addr_t txhpringdma;
++ dma_addr_t txnpringdma;
++ u32 *txlpringtail;
++ u32 *txhpringtail;
++ u32 *txnpringtail;
++ u32 *txlpringhead;
++ u32 *txhpringhead;
++ u32 *txnpringhead;
++ struct buffer *txlpbufs;
++ struct buffer *txhpbufs;
++ struct buffer *txnpbufs;
++ struct buffer *txlpbufstail;
++ struct buffer *txhpbufstail;
++ struct buffer *txnpbufstail;
++ int txringcount;
++ int txbuffsize;
++
++ //struct tx_pendingbuf txnp_pending;
++ struct tasklet_struct irq_tx_tasklet;
++#endif
++ struct tasklet_struct irq_rx_tasklet;
++ struct urb *rxurb_task;
++// u8 dma_poll_mask;
++ //short tx_suspend;
++
++ /* adhoc/master mode stuff */
++#if 0
++ u32 *txbeacontail;
++ dma_addr_t txbeaconringdma;
++ u32 *txbeaconring;
++ int txbeaconcount;
++#endif
++// struct ieee_tx_beacon *beacon_buf;
++ //char *master_essid;
++// dma_addr_t beacondmabuf;
++ //u16 master_beaconinterval;
++// u32 master_beaconsize;
++ //u16 beacon_interval;
++
++ //2 Tx Related variables
++ u16 ShortRetryLimit;
++ u16 LongRetryLimit;
++ u32 TransmitConfig;
++ u8 RegCWinMin; // For turbo mode CW adaptive. Added by Annie, 2005-10-27.
++
++ //2 Rx Related variables
++ u16 EarlyRxThreshold;
++ u32 ReceiveConfig;
++ u8 AcmControl;
++
++ u8 RFProgType;
++
++ u8 retry_data;
++ u8 retry_rts;
++ u16 rts;
++
++//by amy
++ long LastSignalStrengthInPercent;
++ long SignalStrength;
++ long SignalQuality;
++ u8 antenna_flag;
++ bool flag_beacon;
++//by amy
++//by amy for rate adaptive
++ struct timer_list rateadapter_timer;
++ u16 LastRetryCnt;
++ u16 LastRetryRate;
++ unsigned long LastTxokCnt;
++ unsigned long LastRxokCnt;
++ u16 CurrRetryCnt;
++ long RecvSignalPower;
++ unsigned long LastTxOKBytes;
++ u8 LastFailTxRate;
++ long LastFailTxRateSS;
++ u8 FailTxRateCount;
++ u32 LastTxThroughput;
++ unsigned long txokbytestotal;
++ //for up rate
++ unsigned short bTryuping;
++ u8 CurrTxRate; //the rate before up
++ u16 CurrRetryRate;
++ u16 TryupingCount;
++ u8 TryDownCountLowData;
++ u8 TryupingCountNoData;
++
++ u8 CurrentOperaRate;
++//by amy for rate adaptive
++//by amy for power save
++ struct timer_list watch_dog_timer;
++ bool bInactivePs;
++ bool bSwRfProcessing;
++ RT_RF_POWER_STATE eInactivePowerState;
++ RT_RF_POWER_STATE eRFPowerState;
++ u32 RfOffReason;
++ bool RFChangeInProgress;
++ bool bInHctTest;
++ bool SetRFPowerStateInProgress;
++ //u8 RFProgType;
++ bool bLeisurePs;
++ RT_PS_MODE dot11PowerSaveMode;
++ u32 NumRxOkInPeriod;
++ u32 NumTxOkInPeriod;
++ u8 RegThreeWireMode;
++ bool ps_mode;
++//by amy for power save
++//by amy for DIG
++ bool bDigMechanism;
++ bool bCCKThMechanism;
++ u8 InitialGain;
++ u8 StageCCKTh;
++ u8 RegBModeGainStage;
++ u8 RegDigOfdmFaUpTh; //added by david, 2008.3.6
++ u8 DIG_NumberFallbackVote;
++ u8 DIG_NumberUpgradeVote;
++ u16 CCKUpperTh;
++ u16 CCKLowerTh;
++ u32 FalseAlarmRegValue; //added by david, 2008.3.6
++//by amy for DIG
++//{ added by david for high power, 2008.3.11
++ int UndecoratedSmoothedSS;
++ bool bRegHighPowerMechanism;
++ bool bToUpdateTxPwr;
++ u8 Z2HiPwrUpperTh;
++ u8 Z2HiPwrLowerTh;
++ u8 Z2RSSIHiPwrUpperTh;
++ u8 Z2RSSIHiPwrLowerTh;
++ // Current CCK RSSI value to determine CCK high power, asked by SD3 DZ, by Bruce, 2007-04-12.
++ u8 CurCCKRSSI;
++ bool bCurCCKPkt;
++ u32 wMacRegRfPinsOutput;
++ u32 wMacRegRfPinsSelect;
++ TR_SWITCH_STATE TrSwitchState;
++//}
++//{added by david for radio on/off
++ u8 radion;
++//}
++ struct ChnlAccessSetting ChannelAccessSetting;
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
++ struct work_struct reset_wq;
++#else
++ struct tq_struct reset_wq;
++#endif
++
++#ifdef _RTL8187_EXT_PATCH_
++ struct mshclass *mshobj;
++#endif
++
++#ifdef LED
++ /* add for led controll */
++ u8 EEPROMCustomerID;
++ RT_CID_TYPE CustomerID;
++ LED_8187 Gpio0Led;
++ LED_8187 SwLed0;
++ LED_8187 SwLed1;
++ u8 bEnableLedCtrl;
++ LED_STRATEGY_8187 LedStrategy;
++ u8 PsrValue;
++ struct work_struct Gpio0LedWorkItem;
++ struct work_struct SwLed0WorkItem;
++ struct work_struct SwLed1WorkItem;
++#endif
++ u8 driver_upping;
++#ifdef CPU_64BIT
++ u8 *usb_buf;
++ struct dma_pool *usb_pool;
++#endif
++
++
++#ifdef SW_ANTE_DIVERSITY
++
++//#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
++// struct delayed_work SwAntennaWorkItem;
++//#else
++// struct work_struct SwAntennaWorkItem;
++//#endif
++
++ bool bAntennaDiversityTimerIssued;
++ short antb;
++ short diversity;
++ bool AutoloadFailFlag;
++ u16 EEPROMVersion;
++ u8 EEPROMAntennaDiversity;
++ u16 EEPROMCSThreshold;
++ u8 EEPROMDefaultAntennaB;
++ u8 EEPROMDigitalPhy;
++ u32 EEPROMCSMethod;
++ u8 EEPROMGEPRFOffState;
++ // For HW antenna diversity, added by Roger, 2008.01.30.
++ u32 AdMainAntennaRxOkCnt; // Main antenna Rx OK count.
++ u32 AdAuxAntennaRxOkCnt; // Aux antenna Rx OK count.
++ bool bHWAdSwitched; // TRUE if we has switched default antenna by HW evaluation.
++ u8 EEPROMSwAntennaDiversity;
++ bool EEPROMDefaultAntenna1;
++ u8 RegSwAntennaDiversityMechanism;// 0:default from EEPROM, 1: disable, 2: enable.
++ bool bSwAntennaDiverity;
++ u8 RegDefaultAntenna;// 0: default from EEPROM, 1: main, 2: aux. Added by Roger, 2007.11.05.
++ bool bDefaultAntenna1;
++ //long SignalStrength;
++ long Stats_SignalStrength;
++ //long LastSignalStrengthInPercent; // In percentange, used for smoothing, e.g. Moving Average.
++ //long SignalQuality; // in 0-100 index.
++ long Stats_SignalQuality;
++ //long RecvSignalPower; // in dBm.
++ long Stats_RecvSignalPower;
++ u8 LastRxPktAntenna; // +by amy 080312 Antenn which received the lasted packet. 0: Aux, 1:Main. Added by Roger, 2008.01.25.
++ u32 AdRxOkCnt;
++ long AdRxSignalStrength; // Rx signal strength for Antenna Diversity, which had been smoothing, its valid range is [0,100].
++ u8 CurrAntennaIndex; // Index to current Antenna (both Tx and Rx).
++ u8 AdTickCount; // Times of SwAntennaDiversityTimer happened.
++ u8 AdCheckPeriod; // # of period SwAntennaDiversityTimer to check Rx signal strength for SW Antenna Diversity.
++ u8 AdMinCheckPeriod; // Min value of AdCheckPeriod.
++ u8 AdMaxCheckPeriod; // Max value of AdCheckPeriod.
++ long AdRxSsThreshold; // Signal strength threshold to switch antenna.
++ long AdMaxRxSsThreshold; // Max value of AdRxSsThreshold.
++ bool bAdSwitchedChecking; // TRUE if we shall shall check Rx signal strength for last time switching antenna.
++ long AdRxSsBeforeSwitched; // Rx signal strength before we swithed antenna.
++ struct timer_list SwAntennaDiversityTimer;
++#endif
++ u8 commit;
++
++//#ifdef ENABLE_DOT11D
++ u8 channel_plan;
++//#endif
++ u8 EEPROMSelectNewGPIO;
++}r8180_priv;
++
++// for rtl8187
++// now mirging to rtl8187B
++/*
++typedef enum{
++ LOW_PRIORITY = 0x02,
++ NORM_PRIORITY
++ } priority_t;
++*/
++//for rtl8187B
++typedef enum{
++ BULK_PRIORITY = 0x01,
++ //RSVD0,
++ //RSVD1,
++ LOW_PRIORITY,
++ NORM_PRIORITY,
++ VO_PRIORITY,
++ VI_PRIORITY, //0x05
++ BE_PRIORITY,
++ BK_PRIORITY,
++ RSVD2,
++ RSVD3,
++ BEACON_PRIORITY, //0x0A
++ HIGH_PRIORITY,
++ MANAGE_PRIORITY,
++ RSVD4,
++ RSVD5,
++ UART_PRIORITY //0x0F
++} priority_t;
++
++typedef enum{
++ NIC_8187 = 1,
++ NIC_8187B
++ } nic_t;
++
++
++typedef u32 AC_CODING;
++#define AC0_BE 0 // ACI: 0x00 // Best Effort
++#define AC1_BK 1 // ACI: 0x01 // Background
++#define AC2_VI 2 // ACI: 0x10 // Video
++#define AC3_VO 3 // ACI: 0x11 // Voice
++#define AC_MAX 4 // Max: define total number; Should not to be used as a real enum.
++
++//
++// ECWmin/ECWmax field.
++// Ref: WMM spec 2.2.2: WME Parameter Element, p.13.
++//
++typedef union _ECW{
++ u8 charData;
++ struct
++ {
++ u8 ECWmin:4;
++ u8 ECWmax:4;
++ }f; // Field
++}ECW, *PECW;
++
++//
++// ACI/AIFSN Field.
++// Ref: WMM spec 2.2.2: WME Parameter Element, p.12.
++//
++typedef union _ACI_AIFSN{
++ u8 charData;
++
++ struct
++ {
++ u8 AIFSN:4;
++ u8 ACM:1;
++ u8 ACI:2;
++ u8 Reserved:1;
++ }f; // Field
++}ACI_AIFSN, *PACI_AIFSN;
++
++//
++// AC Parameters Record Format.
++// Ref: WMM spec 2.2.2: WME Parameter Element, p.12.
++//
++typedef union _AC_PARAM{
++ u32 longData;
++ u8 charData[4];
++
++ struct
++ {
++ ACI_AIFSN AciAifsn;
++ ECW Ecw;
++ u16 TXOPLimit;
++ }f; // Field
++}AC_PARAM, *PAC_PARAM;
++
++#ifdef JOHN_HWSEC
++struct ssid_thread {
++ struct net_device *dev;
++ u8 name[IW_ESSID_MAX_SIZE + 1];
++};
++#endif
++
++short rtl8180_tx(struct net_device *dev,u32* skbuf, int len,priority_t priority,short morefrag,short rate);
++
++#ifdef JOHN_TKIP
++u32 read_cam(struct net_device *dev, u8 addr);
++void write_cam(struct net_device *dev, u8 addr, u32 data);
++#endif
++u8 read_nic_byte(struct net_device *dev, int x);
++u8 read_nic_byte_E(struct net_device *dev, int x);
++u32 read_nic_dword(struct net_device *dev, int x);
++u16 read_nic_word(struct net_device *dev, int x) ;
++void write_nic_byte(struct net_device *dev, int x,u8 y);
++void write_nic_byte_E(struct net_device *dev, int x,u8 y);
++void write_nic_word(struct net_device *dev, int x,u16 y);
++void write_nic_dword(struct net_device *dev, int x,u32 y);
++void force_pci_posting(struct net_device *dev);
++
++void rtl8180_rtx_disable(struct net_device *);
++void rtl8180_rx_enable(struct net_device *);
++void rtl8180_tx_enable(struct net_device *);
++
++void rtl8180_disassociate(struct net_device *dev);
++//void fix_rx_fifo(struct net_device *dev);
++void rtl8185_set_rf_pins_enable(struct net_device *dev,u32 a);
++
++void rtl8180_set_anaparam(struct net_device *dev,u32 a);
++void rtl8185_set_anaparam2(struct net_device *dev,u32 a);
++void rtl8180_update_msr(struct net_device *dev);
++int rtl8180_down(struct net_device *dev);
++int rtl8180_up(struct net_device *dev);
++void rtl8180_commit(struct net_device *dev);
++void rtl8180_set_chan(struct net_device *dev,short ch);
++void write_phy(struct net_device *dev, u8 adr, u8 data);
++void write_phy_cck(struct net_device *dev, u8 adr, u32 data);
++void write_phy_ofdm(struct net_device *dev, u8 adr, u32 data);
++void rtl8185_tx_antenna(struct net_device *dev, u8 ant);
++void rtl8187_set_rxconf(struct net_device *dev);
++bool MgntActSet_RF_State(struct net_device *dev,RT_RF_POWER_STATE StateToSet,u32 ChangeSource);
++void IPSEnter(struct net_device *dev);
++void IPSLeave(struct net_device *dev);
++int r8187b_rfkill_init(struct net_device *dev);
++void r8187b_rfkill_exit(void);
++int r8187b_wifi_report_state(r8180_priv *priv);
++void r8187b_wifi_change_rfkill_state(struct net_device *dev, RT_RF_POWER_STATE eRfPowerStateToSet);
++bool SetRFPowerState(struct net_device *dev,RT_RF_POWER_STATE eRFPowerState);
++void rtl8180_patch_ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee);
++#ifdef _RTL8187_EXT_PATCH_
++extern int r8180_wx_set_channel(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
++#endif
++#ifdef JOHN_TKIP
++void EnableHWSecurityConfig8187(struct net_device *dev);
++void setKey(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType, u8 *MacAddr, u8 DefaultKey, u32 *KeyContent );
++
++#endif
++
++#endif
+diff --git a/drivers/net/wireless/rtl8187b/r8187_core.c b/drivers/net/wireless/rtl8187b/r8187_core.c
+new file mode 100644
+index 0000000..7044546
+--- /dev/null
++++ b/drivers/net/wireless/rtl8187b/r8187_core.c
+@@ -0,0 +1,7042 @@
++/*
++ This is part of rtl8187 OpenSource driver - v 0.1
++ Copyright (C) Andrea Merello 2005 <andreamrl@tiscali.it>
++ Released under the terms of GPL (General Public License)
++
++
++ Parts of this driver are based on the rtl8180 driver skeleton
++ from Patric Schenke & Andres Salomon.
++
++ Parts of this driver are based on the Intel Pro Wireless 2*00 GPL drivers.
++
++ some ideas might be derived from David Young rtl8180 netbsd driver.
++
++ Parts of the usb code are from the r8150.c driver in linux kernel
++
++ Some ideas borrowed from the 8139too.c driver included in linux kernel.
++
++ We (I?) want to thanks the Authors of those projecs and also the
++ Ndiswrapper's project Authors.
++
++ A special big thanks goes also to Realtek corp. for their help in my
++ attempt to add RTL8187 and RTL8225 support, and to David Young also.
++
++ - Please note that this file is a modified version from rtl8180-sa2400
++ drv. So some other people have contributed to this project, and they are
++ thanked in the rtl8180-sa2400 CHANGELOG.
++*/
++
++#undef LOOP_TEST
++#undef DUMP_RX
++#undef DUMP_TX
++#undef DEBUG_TX_DESC2
++#undef RX_DONT_PASS_UL
++#undef DEBUG_EPROM
++#undef DEBUG_RX_VERBOSE
++#undef DUMMY_RX
++#undef DEBUG_ZERO_RX
++#undef DEBUG_RX_SKB
++#undef DEBUG_TX_FRAG
++#undef DEBUG_RX_FRAG
++#undef DEBUG_TX_FILLDESC
++#undef DEBUG_TX
++#undef DEBUG_IRQ
++#undef DEBUG_RX
++#undef DEBUG_RXALLOC
++#undef DEBUG_REGISTERS
++#undef DEBUG_RING
++#undef DEBUG_IRQ_TASKLET
++#undef DEBUG_TX_ALLOC
++#undef DEBUG_TX_DESC
++#undef CONFIG_SOFT_BEACON
++#undef DEBUG_RW_REGISTER
++
++#define CONFIG_RTL8180_IO_MAP
++//#define CONFIG_SOFT_BEACON
++//#define DEBUG_RW_REGISTER
++
++#include "r8180_hw.h"
++#include "r8187.h"
++#include "r8180_rtl8225.h" /* RTL8225 Radio frontend */
++#include "r8180_93cx6.h" /* Card EEPROM */
++#include "r8180_wx.h"
++#include "r8180_dm.h"
++
++#include <linux/dmapool.h>
++
++#include <linux/usb.h>
++// FIXME: check if 2.6.7 is ok
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7))
++#define usb_kill_urb usb_unlink_urb
++#endif
++
++#ifdef CONFIG_RTL8180_PM
++#include "r8180_pm.h"
++#endif
++
++#ifdef ENABLE_DOT11D
++#include "dot11d.h"
++#endif
++
++#ifndef USB_VENDOR_ID_REALTEK
++#define USB_VENDOR_ID_REALTEK 0x0bda
++#endif
++#ifndef USB_VENDOR_ID_NETGEAR
++#define USB_VENDOR_ID_NETGEAR 0x0846
++#endif
++
++#define TXISR_SELECT(priority) ((priority == MANAGE_PRIORITY)?rtl8187_managetx_isr:\
++ (priority == BEACON_PRIORITY)?rtl8187_beacontx_isr: \
++ (priority == VO_PRIORITY)?rtl8187_votx_isr: \
++ (priority == VI_PRIORITY)?rtl8187_vitx_isr:\
++ (priority == BE_PRIORITY)?rtl8187_betx_isr:rtl8187_bktx_isr)
++
++static struct usb_device_id rtl8187_usb_id_tbl[] = {
++ {USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8187)},
++ {USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8189)},
++// {USB_DEVICE_VER(USB_VENDOR_ID_REALTEK, 0x8187,0x0200,0x0200)},
++ {USB_DEVICE(USB_VENDOR_ID_NETGEAR, 0x6100)},
++ {USB_DEVICE(USB_VENDOR_ID_NETGEAR, 0x6a00)},
++ {USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8197)},
++ {USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8198)},
++ {}
++};
++
++static char* ifname = "wlan%d";
++#if 0
++static int hwseqnum = 0;
++static int hwwep = 0;
++#endif
++static int channels = 0x3fff;
++//static int channels = 0x7ff;// change by thomas, use 1 - 11 channel 0907-2007
++#define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 )
++//by amy for rate adaptive
++#define DEFAULT_RATE_ADAPTIVE_TIMER_PERIOD 300
++//by amy for rate adaptive
++//by amy for ps
++#define IEEE80211_WATCH_DOG_TIME 2000
++//by amy for ps
++MODULE_LICENSE("GPL");
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
++MODULE_VERSION("V 1.1");
++#endif
++MODULE_DEVICE_TABLE(usb, rtl8187_usb_id_tbl);
++MODULE_AUTHOR("Realsil Wlan");
++MODULE_DESCRIPTION("Linux driver for Realtek RTL8187 WiFi cards");
++
++#if 0
++MODULE_PARM(ifname,"s");
++MODULE_PARM_DESC(devname," Net interface name, wlan%d=default");
++
++MODULE_PARM(hwseqnum,"i");
++MODULE_PARM_DESC(hwseqnum," Try to use hardware 802.11 header sequence numbers. Zero=default");
++
++MODULE_PARM(hwwep,"i");
++MODULE_PARM_DESC(hwwep," Try to use hardware WEP support. Still broken and not available on all cards");
++
++MODULE_PARM(channels,"i");
++MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI");
++#endif
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 9)
++module_param(ifname, charp, S_IRUGO|S_IWUSR );
++//module_param(hwseqnum,int, S_IRUGO|S_IWUSR);
++//module_param(hwwep,int, S_IRUGO|S_IWUSR);
++module_param(channels,int, S_IRUGO|S_IWUSR);
++#else
++MODULE_PARM(ifname, "s");
++//MODULE_PARM(hwseqnum,"i");
++//MODULE_PARM(hwwep,"i");
++MODULE_PARM(channels,"i");
++#endif
++
++MODULE_PARM_DESC(devname," Net interface name, wlan%d=default");
++//MODULE_PARM_DESC(hwseqnum," Try to use hardware 802.11 header sequence numbers. Zero=default");
++//MODULE_PARM_DESC(hwwep," Try to use hardware WEP support. Still broken and not available on all cards");
++MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI");
++
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
++static int __devinit rtl8187_usb_probe(struct usb_interface *intf,
++ const struct usb_device_id *id);
++static void __devexit rtl8187_usb_disconnect(struct usb_interface *intf);
++#else
++static void *__devinit rtl8187_usb_probe(struct usb_device *udev,unsigned int ifnum,
++ const struct usb_device_id *id);
++static void __devexit rtl8187_usb_disconnect(struct usb_device *udev, void *ptr);
++#endif
++
++
++static struct usb_driver rtl8187_usb_driver = {
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 15)
++ .owner = THIS_MODULE,
++#endif
++ .name = RTL8187_MODULE_NAME, /* Driver name */
++ .id_table = rtl8187_usb_id_tbl, /* PCI_ID table */
++ .probe = rtl8187_usb_probe, /* probe fn */
++ .disconnect = rtl8187_usb_disconnect, /* remove fn */
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)
++#ifdef CONFIG_RTL8180_PM
++ .suspend = rtl8187_suspend, /* PM suspend fn */
++ .resume = rtl8187_resume, /* PM resume fn */
++#else
++ .suspend = NULL, /* PM suspend fn */
++ .resume = NULL, /* PM resume fn */
++#endif
++#endif
++};
++
++#ifdef JOHN_HWSEC
++void CAM_mark_invalid(struct net_device *dev, u8 ucIndex)
++{
++ u32 ulContent=0;
++ u32 ulCommand=0;
++ u32 ulEncAlgo=CAM_AES;
++
++ // keyid must be set in config field
++ ulContent |= (ucIndex&3) | ((u16)(ulEncAlgo)<<2);
++
++ ulContent |= BIT15;
++ // polling bit, and No Write enable, and address
++ ulCommand= CAM_CONTENT_COUNT*ucIndex;
++ ulCommand= ulCommand | BIT31|BIT16;
++ // write content 0 is equall to mark invalid
++
++ write_nic_dword(dev, WCAMI, ulContent); //delay_ms(40);
++ //RT_TRACE(COMP_SEC, DBG_LOUD, ("CAM_mark_invalid(): WRITE A4: %x \n",ulContent));
++ write_nic_dword(dev, RWCAM, ulCommand); //delay_ms(40);
++ //RT_TRACE(COMP_SEC, DBG_LOUD, ("CAM_mark_invalid(): WRITE A0: %x \n",ulCommand));
++}
++
++void CAM_empty_entry(struct net_device *dev, u8 ucIndex)
++{
++ u32 ulCommand=0;
++ u32 ulContent=0;
++ u8 i;
++ u32 ulEncAlgo=CAM_AES;
++
++ for(i=0;i<6;i++)
++ {
++
++ // filled id in CAM config 2 byte
++ if( i == 0)
++ {
++ ulContent |=(ucIndex & 0x03) | (ulEncAlgo<<2);
++ ulContent |= BIT15;
++
++ }
++ else
++ {
++ ulContent = 0;
++ }
++ // polling bit, and No Write enable, and address
++ ulCommand= CAM_CONTENT_COUNT*ucIndex+i;
++ ulCommand= ulCommand | BIT31|BIT16;
++ // write content 0 is equall to mark invalid
++ write_nic_dword(dev, WCAMI, ulContent); //delay_ms(40);
++ //RT_TRACE(COMP_SEC, DBG_LOUD, ("CAM_empty_entry(): WRITE A4: %x \n",ulContent));
++ write_nic_dword(dev, RWCAM, ulCommand); //delay_ms(40);
++ //RT_TRACE(COMP_SEC, DBG_LOUD, ("CAM_empty_entry(): WRITE A0: %x \n",ulCommand));
++ }
++}
++
++void CamResetAllEntry(struct net_device *dev)
++{
++ u8 ucIndex;
++
++ //2004/02/11 In static WEP, OID_ADD_KEY or OID_ADD_WEP are set before STA associate to AP.
++ // However, ResetKey is called on OID_802_11_INFRASTRUCTURE_MODE and MlmeAssociateRequest
++ // In this condition, Cam can not be reset because upper layer will not set this static key again.
++ //if(Adapter->EncAlgorithm == WEP_Encryption)
++ // return;
++ //debug
++ //DbgPrint("========================================\n");
++ //DbgPrint(" Call ResetAllEntry \n");
++ //DbgPrint("========================================\n\n");
++
++ for(ucIndex=0;ucIndex<TOTAL_CAM_ENTRY;ucIndex++)
++ CAM_mark_invalid(dev, ucIndex);
++ for(ucIndex=0;ucIndex<TOTAL_CAM_ENTRY;ucIndex++)
++ CAM_empty_entry(dev, ucIndex);
++
++}
++
++
++void write_cam(struct net_device *dev, u8 addr, u32 data)
++{
++ write_nic_dword(dev, WCAMI, data);
++ write_nic_dword(dev, RWCAM, BIT31|BIT16|(addr&0xff) );
++}
++u32 read_cam(struct net_device *dev, u8 addr)
++{
++ write_nic_dword(dev, RWCAM, 0x80000000|(addr&0xff) );
++ return read_nic_dword(dev, 0xa8);
++}
++#endif /*JOHN_HWSEC*/
++
++#ifdef DEBUG_RW_REGISTER
++//lzm add for write time out test
++void add_into_rw_registers(struct net_device *dev, u32 addr, u32 cont, u8 flag)
++{
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ int reg_index = (priv->write_read_register_index % 200) ;
++
++ priv->write_read_registers[reg_index].address = 0;
++ priv->write_read_registers[reg_index].content = 0;
++ priv->write_read_registers[reg_index].flag = 0;
++
++ priv->write_read_registers[reg_index].address = addr;
++ priv->write_read_registers[reg_index].content = cont;
++ priv->write_read_registers[reg_index].flag = flag;
++
++ priv->write_read_register_index = (priv->write_read_register_index + 1) % 200;
++}
++
++bool print_once = 0;
++
++void print_rw_registers(struct net_device *dev)
++{
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ int reg_index = 0;
++ int watchdog = 0;
++ if(print_once == false)
++ {
++ print_once = true;
++ for(reg_index = ((priv->write_read_register_index + 1) % 200); watchdog <= 199; reg_index++)
++ {
++ watchdog++;
++ printk("====>reg_addr:0x%x, reg_cont:0x%x, read_or_write:0x%d\n",
++ priv->write_read_registers[reg_index].address,
++ priv->write_read_registers[reg_index].content,
++ priv->write_read_registers[reg_index].flag);
++ }
++ }
++}
++//lzm add for write time out test
++#endif
++
++#ifdef CPU_64BIT
++void write_nic_byte_E(struct net_device *dev, int indx, u8 data)
++{
++ int status;
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ struct usb_device *udev = priv->udev;
++
++ status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
++ RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
++ indx|0xfe00, 0, &data, 1, HZ / 2);
++
++//lzm add for write time out test
++#ifdef DEBUG_RW_REGISTER
++ add_into_rw_registers(dev, indx, data, 2);
++#endif
++
++ if (status < 0)
++ {
++ printk("write_nic_byte_E TimeOut!addr:%x, status:%x\n", indx, status);
++#ifdef DEBUG_RW_REGISTER
++ print_rw_registers(dev);
++#endif
++ }
++}
++
++u8 read_nic_byte_E(struct net_device *dev, int indx)
++{
++ int status;
++ u8 data, *buf;
++ dma_addr_t dma_handle;
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ struct usb_device *udev = priv->udev;
++
++ buf = dma_pool_alloc(priv->usb_pool, GFP_ATOMIC, &dma_handle);
++ if (!buf) {
++ printk("read_nic_byte_E out of memory\n");
++ return -ENOMEM;
++ }
++ status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
++ RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
++ indx|0xfe00, 0, buf, 1, HZ / 2);
++//lzm add for write time out test
++#ifdef DEBUG_RW_REGISTER
++ add_into_rw_registers(dev, indx, buf[0], 1);
++#endif
++
++ if (status < 0)
++ {
++ printk("read_nic_byte_E TimeOut!addr:%x, status:%x\n",indx, status);
++#ifdef DEBUG_RW_REGISTER
++ print_rw_registers(dev);
++#endif
++ }
++
++ data = buf[0];
++ dma_pool_free(priv->usb_pool, buf, dma_handle);
++ return data;
++}
++
++void write_nic_byte(struct net_device *dev, int indx, u8 data)
++{
++ int status;
++
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ struct usb_device *udev = priv->udev;
++
++ status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
++ RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
++ (indx&0xff)|0xff00, (indx>>8)&0x03, &data, 1, HZ / 2);
++
++//lzm add for write time out test
++#ifdef DEBUG_RW_REGISTER
++ add_into_rw_registers(dev, indx, data, 2);
++#endif
++ if (status < 0)
++ {
++ printk("write_nic_byte TimeOut!addr:%x, status:%x\n",indx, status);
++#ifdef DEBUG_RW_REGISTER
++ print_rw_registers(dev);
++#endif
++ }
++
++
++}
++
++void write_nic_word(struct net_device *dev, int indx, u16 data)
++{
++
++ int status;
++
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ struct usb_device *udev = priv->udev;
++
++ status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
++ RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
++ (indx&0xff)|0xff00, (indx>>8)&0x03, &data, 2, HZ / 2);
++
++//lzm add for write time out test
++#ifdef DEBUG_RW_REGISTER
++ add_into_rw_registers(dev, indx, data, 2);
++
++ if(priv->write_read_register_index == 199)
++ {
++ //print_rw_registers(dev);
++ }
++#endif
++ if (status < 0)
++ {
++ printk("write_nic_word TimeOut!addr:%x, status:%x\n",indx, status);
++#ifdef DEBUG_RW_REGISTER
++ print_rw_registers(dev);
++#endif
++ }
++
++}
++
++void write_nic_dword(struct net_device *dev, int indx, u32 data)
++{
++
++ int status;
++
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ struct usb_device *udev = priv->udev;
++
++ status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
++ RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
++ (indx&0xff)|0xff00, (indx>>8)&0x03, &data, 4, HZ / 2);
++//lzm add for write time out test
++#ifdef DEBUG_RW_REGISTER
++ add_into_rw_registers(dev, indx, data, 2);
++#endif
++
++
++ if (status < 0)
++ {
++ printk("write_nic_dword TimeOut!addr:%x, status:%x\n",indx, status);
++#ifdef DEBUG_RW_REGISTER
++ print_rw_registers(dev);
++#endif
++ }
++
++}
++
++ u8 read_nic_byte(struct net_device *dev, int indx)
++{
++ u8 data, *buf;
++ int status;
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ struct usb_device *udev = priv->udev;
++ dma_addr_t dma_handle;
++
++ buf = dma_pool_alloc(priv->usb_pool, GFP_ATOMIC, &dma_handle);
++ if (!buf) {
++ printk("read_nic_byte: out of memory\n");
++ return -ENOMEM;
++ }
++ status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
++ RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
++ (indx&0xff)|0xff00, (indx>>8)&0x03, buf, 1, HZ / 2);
++//lzm add for write time out test
++#ifdef DEBUG_RW_REGISTER
++ add_into_rw_registers(dev, indx, buf[0], 1);
++#endif
++
++ if (status < 0)
++ {
++ printk("read_nic_byte TimeOut!addr:%x, status:%x\n",indx, status);
++#ifdef DEBUG_RW_REGISTER
++ print_rw_registers(dev);
++#endif
++ }
++
++ data = buf[0];
++ dma_pool_free(priv->usb_pool, buf, dma_handle);
++ return data;
++}
++
++u16 read_nic_word(struct net_device *dev, int indx)
++{
++ u16 data, *buf;
++ int status;
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ struct usb_device *udev = priv->udev;
++ dma_addr_t dma_handle;
++
++ buf = dma_pool_alloc(priv->usb_pool, GFP_ATOMIC, &dma_handle);
++ if (!buf) {
++ printk("read_nic_word: out of memory\n");
++ return -ENOMEM;
++ }
++ status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
++ RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
++ (indx&0xff)|0xff00, (indx>>8)&0x03, buf, 2, HZ / 2);
++//lzm add for write time out test
++#ifdef DEBUG_RW_REGISTER
++ add_into_rw_registers(dev, indx, buf[0], 1);
++#endif
++
++ if (status < 0)
++ {
++ printk("read_nic_word TimeOut!addr:%x, status:%x\n",indx, status);
++#ifdef DEBUG_RW_REGISTER
++ print_rw_registers(dev);
++#endif
++ }
++
++
++ data = buf[0];
++ dma_pool_free(priv->usb_pool, buf, dma_handle);
++ return data;
++}
++
++u32 read_nic_dword(struct net_device *dev, int indx)
++{
++ u32 data, *buf;
++ int status;
++ dma_addr_t dma_handle;
++// int result;
++
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ struct usb_device *udev = priv->udev;
++
++ buf = dma_pool_alloc(priv->usb_pool, GFP_ATOMIC, &dma_handle);
++ if (!buf){
++ printk("read_nic_dword: out of memory\n");
++ return -ENOMEM;
++ }
++ status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
++ RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
++ (indx&0xff)|0xff00, (indx>>8)&0x03, buf, 4, HZ / 2);
++//lzm add for write time out test
++#ifdef DEBUG_RW_REGISTER
++ add_into_rw_registers(dev, indx, buf[0], 1);
++#endif
++
++ if (status < 0)
++ {
++ printk("read_nic_dword TimeOut!addr:%x, status:%x\n",indx, status);
++#ifdef DEBUG_RW_REGISTER
++ print_rw_registers(dev);
++#endif
++ }
++
++
++
++ data = buf[0];
++ dma_pool_free(priv->usb_pool, buf, dma_handle);
++ return data;
++}
++#else
++void write_nic_byte_E(struct net_device *dev, int indx, u8 data)
++{
++ int status;
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ struct usb_device *udev = priv->udev;
++
++ status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
++ RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
++ indx|0xfe00, 0, &data, 1, HZ / 2);
++
++ if (status < 0)
++ {
++ printk("write_nic_byte_E TimeOut!addr:0x%x,val:0x%x, status:%x\n", indx,data,status);
++ }
++}
++
++u8 read_nic_byte_E(struct net_device *dev, int indx)
++{
++ int status;
++ u8 data = 0;
++ u8 buf[64];
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ struct usb_device *udev = priv->udev;
++
++ status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
++ RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
++ indx|0xfe00, 0, buf, 1, HZ / 2);
++
++ if (status < 0)
++ {
++ printk("read_nic_byte_E TimeOut!addr:0x%x, status:%x\n", indx, status);
++ }
++
++ data = *(u8*)buf;
++ return data;
++}
++
++void write_nic_byte(struct net_device *dev, int indx, u8 data)
++{
++ int status;
++
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ struct usb_device *udev = priv->udev;
++
++ status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
++ RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
++ (indx&0xff)|0xff00, (indx>>8)&0x03, &data, 1, HZ / 2);
++
++ if (status < 0)
++ {
++ printk("write_nic_byte TimeOut!addr:0x%x,val:0x%x, status:%x\n", indx,data, status);
++ }
++
++
++}
++
++void write_nic_word(struct net_device *dev, int indx, u16 data)
++{
++
++ int status;
++
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ struct usb_device *udev = priv->udev;
++
++ status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
++ RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
++ (indx&0xff)|0xff00, (indx>>8)&0x03, &data, 2, HZ / 2);
++
++ if (status < 0)
++ {
++ printk("write_nic_word TimeOut!addr:0x%x,val:0x%x, status:%x\n", indx,data, status);
++ }
++
++}
++
++void write_nic_dword(struct net_device *dev, int indx, u32 data)
++{
++
++ int status;
++
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ struct usb_device *udev = priv->udev;
++
++ status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
++ RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
++ (indx&0xff)|0xff00, (indx>>8)&0x03, &data, 4, HZ / 2);
++
++
++ if (status < 0)
++ {
++ printk("write_nic_dword TimeOut!addr:0x%x,val:0x%x, status:%x\n", indx,data, status);
++ }
++
++}
++
++u8 read_nic_byte(struct net_device *dev, int indx)
++{
++ u8 data = 0;
++ u8 buf[64];
++ int status;
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ struct usb_device *udev = priv->udev;
++
++ status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
++ RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
++ (indx&0xff)|0xff00, (indx>>8)&0x03, buf, 1, HZ / 2);
++
++ if (status < 0)
++ {
++ printk("read_nic_byte TimeOut!addr:0x%x,status:%x\n", indx,status);
++ }
++
++
++ data = *(u8*)buf;
++ return data;
++}
++
++u16 read_nic_word(struct net_device *dev, int indx)
++{
++ u16 data = 0;
++ u8 buf[64];
++ int status;
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ struct usb_device *udev = priv->udev;
++
++ status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
++ RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
++ (indx&0xff)|0xff00, (indx>>8)&0x03, buf, 2, HZ / 2);
++
++ if (status < 0)
++ {
++ printk("read_nic_word TimeOut!addr:0x%x,status:%x\n", indx,status);
++ }
++
++ data = *(u16*)buf;
++ return data;
++}
++
++u32 read_nic_dword(struct net_device *dev, int indx)
++{
++ u32 data = 0;
++ u8 buf[64];
++ int status;
++
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ struct usb_device *udev = priv->udev;
++
++ status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
++ RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
++ (indx&0xff)|0xff00, (indx>>8)&0x03, buf, 4, HZ / 2);
++
++ if (status < 0)
++ {
++ printk("read_nic_dword TimeOut!addr:0x%x,status:%x\n", indx, status);
++ }
++
++
++ data = *(u32*)buf;
++ return data;
++}
++#endif
++
++
++u8 read_phy_cck(struct net_device *dev, u8 adr);
++u8 read_phy_ofdm(struct net_device *dev, u8 adr);
++/* this might still called in what was the PHY rtl8185/rtl8187 common code
++ * plans are to possibilty turn it again in one common code...
++ */
++inline void force_pci_posting(struct net_device *dev)
++{
++}
++
++
++static struct net_device_stats *rtl8180_stats(struct net_device *dev);
++void rtl8180_commit(struct net_device *dev);
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
++void rtl8180_restart(struct work_struct *work);
++#else
++void rtl8180_restart(struct net_device *dev);
++#endif
++/****************************************************************************
++ -----------------------------PROCFS STUFF-------------------------
++*****************************************************************************/
++
++static struct proc_dir_entry *rtl8180_proc = NULL;
++static int proc_get_stats_ap(char *page, char **start,
++ off_t offset, int count,
++ int *eof, void *data)
++{
++ struct net_device *dev = data;
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ struct ieee80211_device *ieee = priv->ieee80211;
++ struct ieee80211_network *target;
++
++ int len = 0;
++
++ list_for_each_entry(target, &ieee->network_list, list) {
++
++ len += snprintf(page + len, count - len,
++ "%s ", target->ssid);
++ len += snprintf(page + len, count - len,
++ "%ld ", (jiffies-target->last_scanned)/HZ);
++
++
++
++ if(target->wpa_ie_len>0 || target->rsn_ie_len>0){
++ len += snprintf(page + len, count - len,
++ "WPA\n");
++ }
++ else{
++ len += snprintf(page + len, count - len,
++ "non_WPA\n");
++ }
++
++ }
++
++ *eof = 1;
++ return len;
++}
++
++static int proc_get_registers(char *page, char **start,
++ off_t offset, int count,
++ int *eof, void *data)
++{
++ struct net_device *dev = data;
++
++ int len = 0;
++ int i,n;
++
++ int max=0xff;
++
++ /* This dump the current register page */
++len += snprintf(page + len, count - len,
++ "\n####################page 0##################\n ");
++
++ for(n=0;n<=max;)
++ {
++ //printk( "\nD: %2x> ", n);
++ len += snprintf(page + len, count - len,
++ "\nD: %2x > ",n);
++
++ for(i=0;i<16 && n<=max;i++,n++)
++ len += snprintf(page + len, count - len,
++ "%2x ",read_nic_byte(dev,n));
++
++ // printk("%2x ",read_nic_byte(dev,n));
++ }
++ len += snprintf(page + len, count - len,"\n");
++len += snprintf(page + len, count - len,
++ "\n####################page 1##################\n ");
++ for(n=0;n<=max;)
++ {
++ //printk( "\nD: %2x> ", n);
++ len += snprintf(page + len, count - len,
++ "\nD: %2x > ",n);
++
++ for(i=0;i<16 && n<=max;i++,n++)
++ len += snprintf(page + len, count - len,
++ "%2x ",read_nic_byte(dev,0x100|n));
++
++ // printk("%2x ",read_nic_byte(dev,n));
++ }
++len += snprintf(page + len, count - len,
++ "\n####################page 2##################\n ");
++ for(n=0;n<=max;)
++ {
++ //printk( "\nD: %2x> ", n);
++ len += snprintf(page + len, count - len,
++ "\nD: %2x > ",n);
++
++ for(i=0;i<16 && n<=max;i++,n++)
++ len += snprintf(page + len, count - len,
++ "%2x ",read_nic_byte(dev,0x200|n));
++
++ // printk("%2x ",read_nic_byte(dev,n));
++ }
++
++
++
++ *eof = 1;
++ return len;
++
++}
++
++
++static int proc_get_cck_reg(char *page, char **start,
++ off_t offset, int count,
++ int *eof, void *data)
++{
++ struct net_device *dev = data;
++
++ int len = 0;
++ int i,n;
++
++ int max = 0x5F;
++
++ /* This dump the current register page */
++ for(n=0;n<=max;)
++ {
++ //printk( "\nD: %2x> ", n);
++ len += snprintf(page + len, count - len,
++ "\nD: %2x > ",n);
++
++ for(i=0;i<16 && n<=max;i++,n++)
++ len += snprintf(page + len, count - len,
++ "%2x ",read_phy_cck(dev,n));
++
++ // printk("%2x ",read_nic_byte(dev,n));
++ }
++ len += snprintf(page + len, count - len,"\n");
++
++
++ *eof = 1;
++ return len;
++
++}
++
++
++static int proc_get_ofdm_reg(char *page, char **start,
++ off_t offset, int count,
++ int *eof, void *data)
++{
++ struct net_device *dev = data;
++
++ int len = 0;
++ int i,n;
++
++ //int max=0xff;
++ int max = 0x40;
++
++ /* This dump the current register page */
++ for(n=0;n<=max;)
++ {
++ //printk( "\nD: %2x> ", n);
++ len += snprintf(page + len, count - len,
++ "\nD: %2x > ",n);
++
++ for(i=0;i<16 && n<=max;i++,n++)
++ len += snprintf(page + len, count - len,
++ "%2x ",read_phy_ofdm(dev,n));
++
++ // printk("%2x ",read_nic_byte(dev,n));
++ }
++ len += snprintf(page + len, count - len,"\n");
++
++
++
++ *eof = 1;
++ return len;
++
++}
++
++
++#if 0
++static int proc_get_stats_hw(char *page, char **start,
++ off_t offset, int count,
++ int *eof, void *data)
++{
++ struct net_device *dev = data;
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++
++ int len = 0;
++
++ len += snprintf(page + len, count - len,
++ "NIC int: %lu\n"
++ "Total int: %lu\n",
++ priv->stats.ints,
++ priv->stats.shints);
++
++ *eof = 1;
++ return len;
++}
++#endif
++
++static int proc_get_stats_tx(char *page, char **start,
++ off_t offset, int count,
++ int *eof, void *data)
++{
++ struct net_device *dev = data;
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++
++ int len = 0;
++
++ len += snprintf(page + len, count - len,
++ "TX VI priority ok int: %lu\n"
++ "TX VI priority error int: %lu\n"
++ "TX VO priority ok int: %lu\n"
++ "TX VO priority error int: %lu\n"
++ "TX BE priority ok int: %lu\n"
++ "TX BE priority error int: %lu\n"
++ "TX BK priority ok int: %lu\n"
++ "TX BK priority error int: %lu\n"
++ "TX MANAGE priority ok int: %lu\n"
++ "TX MANAGE priority error int: %lu\n"
++ "TX BEACON priority ok int: %lu\n"
++ "TX BEACON priority error int: %lu\n"
++// "TX high priority ok int: %lu\n"
++// "TX high priority failed error int: %lu\n"
++ "TX queue resume: %lu\n"
++ "TX queue stopped?: %d\n"
++ "TX fifo overflow: %lu\n"
++// "TX beacon: %lu\n"
++ "TX VI queue: %d\n"
++ "TX VO queue: %d\n"
++ "TX BE queue: %d\n"
++ "TX BK queue: %d\n"
++ "TX BEACON queue: %d\n"
++ "TX MANAGE queue: %d\n"
++// "TX HW queue: %d\n"
++ "TX VI dropped: %lu\n"
++ "TX VO dropped: %lu\n"
++ "TX BE dropped: %lu\n"
++ "TX BK dropped: %lu\n"
++ "TX total data packets %lu\n",
++// "TX beacon aborted: %lu\n",
++ priv->stats.txviokint,
++ priv->stats.txvierr,
++ priv->stats.txvookint,
++ priv->stats.txvoerr,
++ priv->stats.txbeokint,
++ priv->stats.txbeerr,
++ priv->stats.txbkokint,
++ priv->stats.txbkerr,
++ priv->stats.txmanageokint,
++ priv->stats.txmanageerr,
++ priv->stats.txbeaconokint,
++ priv->stats.txbeaconerr,
++// priv->stats.txhpokint,
++// priv->stats.txhperr,
++ priv->stats.txresumed,
++ netif_queue_stopped(dev),
++ priv->stats.txoverflow,
++// priv->stats.txbeacon,
++ atomic_read(&(priv->tx_pending[VI_PRIORITY])),
++ atomic_read(&(priv->tx_pending[VO_PRIORITY])),
++ atomic_read(&(priv->tx_pending[BE_PRIORITY])),
++ atomic_read(&(priv->tx_pending[BK_PRIORITY])),
++ atomic_read(&(priv->tx_pending[BEACON_PRIORITY])),
++ atomic_read(&(priv->tx_pending[MANAGE_PRIORITY])),
++// read_nic_byte(dev, TXFIFOCOUNT),
++ priv->stats.txvidrop,
++ priv->stats.txvodrop,
++ priv->stats.txbedrop,
++ priv->stats.txbkdrop,
++ priv->stats.txdatapkt
++// priv->stats.txbeaconerr
++ );
++
++ *eof = 1;
++ return len;
++}
++
++
++
++static int proc_get_stats_rx(char *page, char **start,
++ off_t offset, int count,
++ int *eof, void *data)
++{
++ struct net_device *dev = data;
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++
++ int len = 0;
++
++ len += snprintf(page + len, count - len,
++ "RX packets: %lu\n"
++ "RX urb status error: %lu\n"
++ "RX invalid urb error: %lu\n",
++ priv->stats.rxok,
++ priv->stats.rxstaterr,
++ priv->stats.rxurberr);
++
++ *eof = 1;
++ return len;
++}
++
++#if WIRELESS_EXT < 17
++static struct iw_statistics *r8180_get_wireless_stats(struct net_device *dev)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ return &priv->wstats;
++}
++#endif
++
++void rtl8180_proc_module_init(void)
++{
++ DMESG("Initializing proc filesystem");
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
++ rtl8180_proc=create_proc_entry(RTL8187_MODULE_NAME, S_IFDIR, proc_net);
++#else
++ rtl8180_proc=create_proc_entry(RTL8187_MODULE_NAME, S_IFDIR, init_net.proc_net);
++#endif
++}
++
++
++void rtl8180_proc_module_remove(void)
++{
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
++ remove_proc_entry(RTL8187_MODULE_NAME, proc_net);
++#else
++ remove_proc_entry(RTL8187_MODULE_NAME, init_net.proc_net);
++#endif
++}
++
++
++void rtl8180_proc_remove_one(struct net_device *dev)
++{
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ if (priv->dir_dev) {
++ // remove_proc_entry("stats-hw", priv->dir_dev);
++ remove_proc_entry("stats-tx", priv->dir_dev);
++ remove_proc_entry("stats-rx", priv->dir_dev);
++ // remove_proc_entry("stats-ieee", priv->dir_dev);
++ remove_proc_entry("stats-ap", priv->dir_dev);
++ remove_proc_entry("registers", priv->dir_dev);
++ remove_proc_entry("cck-registers",priv->dir_dev);
++ remove_proc_entry("ofdm-registers",priv->dir_dev);
++ remove_proc_entry(dev->name, rtl8180_proc);
++ priv->dir_dev = NULL;
++ }
++}
++
++
++void rtl8180_proc_init_one(struct net_device *dev)
++{
++ struct proc_dir_entry *e;
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ priv->dir_dev = create_proc_entry(dev->name,
++ S_IFDIR | S_IRUGO | S_IXUGO,
++ rtl8180_proc);
++ if (!priv->dir_dev) {
++ DMESGE("Unable to initialize /proc/net/rtl8187/%s\n",
++ dev->name);
++ return;
++ }
++ #if 0
++ e = create_proc_read_entry("stats-hw", S_IFREG | S_IRUGO,
++ priv->dir_dev, proc_get_stats_hw, dev);
++
++ if (!e) {
++ DMESGE("Unable to initialize "
++ "/proc/net/rtl8187/%s/stats-hw\n",
++ dev->name);
++ }
++ #endif
++ e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO,
++ priv->dir_dev, proc_get_stats_rx, dev);
++
++ if (!e) {
++ DMESGE("Unable to initialize "
++ "/proc/net/rtl8187/%s/stats-rx\n",
++ dev->name);
++ }
++
++
++ e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO,
++ priv->dir_dev, proc_get_stats_tx, dev);
++
++ if (!e) {
++ DMESGE("Unable to initialize "
++ "/proc/net/rtl8187/%s/stats-tx\n",
++ dev->name);
++ }
++ #if 0
++ e = create_proc_read_entry("stats-ieee", S_IFREG | S_IRUGO,
++ priv->dir_dev, proc_get_stats_ieee, dev);
++
++ if (!e) {
++ DMESGE("Unable to initialize "
++ "/proc/net/rtl8187/%s/stats-ieee\n",
++ dev->name);
++ }
++
++ #endif
++
++ e = create_proc_read_entry("stats-ap", S_IFREG | S_IRUGO,
++ priv->dir_dev, proc_get_stats_ap, dev);
++
++ if (!e) {
++ DMESGE("Unable to initialize "
++ "/proc/net/rtl8187/%s/stats-ap\n",
++ dev->name);
++ }
++
++ e = create_proc_read_entry("registers", S_IFREG | S_IRUGO,
++ priv->dir_dev, proc_get_registers, dev);
++ if (!e) {
++ DMESGE("Unable to initialize "
++ "/proc/net/rtl8187/%s/registers\n",
++ dev->name);
++ }
++
++ e = create_proc_read_entry("cck-registers", S_IFREG | S_IRUGO,
++ priv->dir_dev, proc_get_cck_reg, dev);
++ if (!e) {
++ DMESGE("Unable to initialize "
++ "/proc/net/rtl8187/%s/cck-registers\n",
++ dev->name);
++ }
++
++ e = create_proc_read_entry("ofdm-registers", S_IFREG | S_IRUGO,
++ priv->dir_dev, proc_get_ofdm_reg, dev);
++ if (!e) {
++ DMESGE("Unable to initialize "
++ "/proc/net/rtl8187/%s/ofdm-registers\n",
++ dev->name);
++ }
++
++#ifdef _RTL8187_EXT_PATCH_
++ if( priv->mshobj && priv->mshobj->ext_patch_create_proc )
++ priv->mshobj->ext_patch_create_proc(priv);
++#endif
++
++}
++/****************************************************************************
++ -----------------------------MISC STUFF-------------------------
++*****************************************************************************/
++
++/* this is only for debugging */
++void print_buffer(u32 *buffer, int len)
++{
++ int i;
++ u8 *buf =(u8*)buffer;
++
++ printk("ASCII BUFFER DUMP (len: %x):\n",len);
++
++ for(i=0;i<len;i++)
++ printk("%c",buf[i]);
++
++ printk("\nBINARY BUFFER DUMP (len: %x):\n",len);
++
++ for(i=0;i<len;i++)
++ printk("%x",buf[i]);
++
++ printk("\n");
++}
++
++short check_nic_enought_desc(struct net_device *dev, priority_t priority)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ //int used = atomic_read((priority == NORM_PRIORITY) ?
++ // &priv->tx_np_pending : &priv->tx_lp_pending);
++ int used = atomic_read(&priv->tx_pending[priority]);
++
++ return (used < MAX_TX_URB);
++}
++
++void tx_timeout(struct net_device *dev)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ //rtl8180_commit(dev);
++ printk("@@@@ Transmit timeout at %ld, latency %ld\n", jiffies,
++ jiffies - dev->trans_start);
++
++ printk("@@@@ netif_queue_stopped = %d\n", netif_queue_stopped(dev));
++
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
++ schedule_work(&priv->reset_wq);
++#else
++ schedule_task(&priv->reset_wq);
++#endif
++ //DMESG("TXTIMEOUT");
++}
++
++
++/* this is only for debug */
++void dump_eprom(struct net_device *dev)
++{
++ int i;
++ for(i=0; i<63; i++)
++ DMESG("EEPROM addr %x : %x", i, eprom_read(dev,i));
++}
++
++/* this is only for debug */
++void rtl8180_dump_reg(struct net_device *dev)
++{
++ int i;
++ int n;
++ int max=0xff;
++
++ DMESG("Dumping NIC register map");
++
++ for(n=0;n<=max;)
++ {
++ printk( "\nD: %2x> ", n);
++ for(i=0;i<16 && n<=max;i++,n++)
++ printk("%2x ",read_nic_byte(dev,n));
++ }
++ printk("\n");
++}
++
++/****************************************************************************
++ ------------------------------HW STUFF---------------------------
++*****************************************************************************/
++
++
++void rtl8180_irq_enable(struct net_device *dev)
++{
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ //priv->irq_enabled = 1;
++
++ //write_nic_word(dev,INTA_MASK,INTA_RXOK | INTA_RXDESCERR | INTA_RXOVERFLOW |
++ // INTA_TXOVERFLOW | INTA_HIPRIORITYDESCERR | INTA_HIPRIORITYDESCOK |
++ // INTA_NORMPRIORITYDESCERR | INTA_NORMPRIORITYDESCOK |
++ // INTA_LOWPRIORITYDESCERR | INTA_LOWPRIORITYDESCOK | INTA_TIMEOUT);
++
++ write_nic_word(dev,INTA_MASK, priv->irq_mask);
++}
++
++
++void rtl8180_irq_disable(struct net_device *dev)
++{
++ write_nic_word(dev,INTA_MASK,0);
++ force_pci_posting(dev);
++// priv->irq_enabled = 0;
++}
++
++
++void rtl8180_set_mode(struct net_device *dev,int mode)
++{
++ u8 ecmd;
++ ecmd=read_nic_byte(dev, EPROM_CMD);
++ ecmd=ecmd &~ EPROM_CMD_OPERATING_MODE_MASK;
++ ecmd=ecmd | (mode<<EPROM_CMD_OPERATING_MODE_SHIFT);
++ ecmd=ecmd &~ (1<<EPROM_CS_SHIFT);
++ ecmd=ecmd &~ (1<<EPROM_CK_SHIFT);
++ write_nic_byte(dev, EPROM_CMD, ecmd);
++}
++
++
++void rtl8180_update_msr(struct net_device *dev)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ u8 msr;
++
++ msr = read_nic_byte(dev, MSR);
++ msr &= ~ MSR_LINK_MASK;
++
++ /* do not change in link_state != WLAN_LINK_ASSOCIATED.
++ * msr must be updated if the state is ASSOCIATING.
++ * this is intentional and make sense for ad-hoc and
++ * master (see the create BSS/IBSS func)
++ */
++ if (priv->ieee80211->state == IEEE80211_LINKED){
++
++ if (priv->ieee80211->iw_mode == IW_MODE_INFRA)
++ msr |= (MSR_LINK_MANAGED<<MSR_LINK_SHIFT);
++ else if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
++ msr |= (MSR_LINK_ADHOC<<MSR_LINK_SHIFT);
++ else if (priv->ieee80211->iw_mode == IW_MODE_MASTER)
++ msr |= (MSR_LINK_MASTER<<MSR_LINK_SHIFT);
++
++ }else
++ msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT);
++
++ write_nic_byte(dev, MSR, msr);
++}
++
++void rtl8180_set_chan(struct net_device *dev,short ch)
++{
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ u32 tx;
++
++ priv->chan=ch;
++ #if 0
++ if(priv->ieee80211->iw_mode == IW_MODE_ADHOC ||
++ priv->ieee80211->iw_mode == IW_MODE_MASTER){
++
++ priv->ieee80211->link_state = WLAN_LINK_ASSOCIATED;
++ priv->ieee80211->master_chan = ch;
++ rtl8180_update_beacon_ch(dev);
++ }
++ #endif
++
++ /* this hack should avoid frame TX during channel setting*/
++ tx = read_nic_dword(dev,TX_CONF);
++ tx &= ~TX_LOOPBACK_MASK;
++
++#ifndef LOOP_TEST
++ write_nic_dword(dev,TX_CONF, tx |( TX_LOOPBACK_MAC<<TX_LOOPBACK_SHIFT));
++ priv->rf_set_chan(dev,priv->chan);
++ //mdelay(10); //CPU occupany is too high. LZM 31/10/2008
++ write_nic_dword(dev,TX_CONF,tx | (TX_LOOPBACK_NONE<<TX_LOOPBACK_SHIFT));
++#endif
++}
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
++void rtl8187_rx_isr(struct urb *rx_urb, struct pt_regs *regs);
++#else
++void rtl8187_rx_isr(struct urb* rx_urb);
++#endif
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
++void rtl8187_rx_manage_isr(struct urb *rx_urb, struct pt_regs *regs);
++#else
++void rtl8187_rx_manage_isr(struct urb* rx_urb);
++#endif
++
++
++
++void rtl8187_rx_urbsubmit(struct net_device *dev, struct urb* rx_urb)
++{
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ int err;
++
++ usb_fill_bulk_urb(rx_urb,priv->udev,
++ usb_rcvbulkpipe(priv->udev,(NIC_8187 == priv->card_8187)?0x81:0x83),
++ rx_urb->transfer_buffer,
++ RX_URB_SIZE,
++ rtl8187_rx_isr,
++ dev);
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
++ err = usb_submit_urb(rx_urb, GFP_ATOMIC);
++#else
++ err = usb_submit_urb(rx_urb);
++#endif
++ if(err && err != -EPERM){
++ DMESGE("cannot submit RX command. URB_STATUS %x",rx_urb->status);
++ }
++}
++
++
++void rtl8187_rx_manage_urbsubmit(struct net_device *dev, struct urb* rx_urb)
++{
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ int err;
++#ifdef THOMAS_BEACON
++ usb_fill_bulk_urb(rx_urb,priv->udev,
++ usb_rcvbulkpipe(priv->udev,0x09),
++ rx_urb->transfer_buffer,
++ rx_urb->transfer_buffer_length,
++ rtl8187_rx_manage_isr, dev);
++#endif
++
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
++ err = usb_submit_urb(rx_urb, GFP_ATOMIC);
++#else
++ err = usb_submit_urb(rx_urb);
++#endif
++ if(err && err != -EPERM){
++ DMESGE("cannot submit RX command. URB_STATUS %x",rx_urb->status);
++ }
++}
++
++
++
++void rtl8187_rx_initiate(struct net_device *dev)
++{
++ int i;
++ unsigned long flags;
++ struct urb *purb;
++
++ struct sk_buff *pskb;
++
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++
++ priv->tx_urb_index = 0;
++
++ if ((!priv->rx_urb) || (!priv->pp_rxskb)) {
++
++ DMESGE("Cannot intiate RX urb mechanism");
++ return;
++
++ }
++
++ priv->rx_inx = 0;
++#ifdef THOMAS_TASKLET
++ atomic_set(&priv->irt_counter,0);
++#endif
++ for(i = 0;i < MAX_RX_URB; i++){
++
++ purb = priv->rx_urb[i] = usb_alloc_urb(0,GFP_KERNEL);
++
++ if(!priv->rx_urb[i])
++ goto destroy;
++
++ pskb = priv->pp_rxskb[i] = dev_alloc_skb (RX_URB_SIZE);
++
++ if (pskb == NULL)
++ goto destroy;
++
++ purb->transfer_buffer_length = RX_URB_SIZE;
++ purb->transfer_buffer = pskb->data;
++ }
++
++ spin_lock_irqsave(&priv->irq_lock,flags);//added by thomas
++
++ for(i=0;i<MAX_RX_URB;i++)
++ rtl8187_rx_urbsubmit(dev,priv->rx_urb[i]);
++
++ spin_unlock_irqrestore(&priv->irq_lock,flags);//added by thomas
++
++ return;
++
++destroy:
++
++ for(i = 0; i < MAX_RX_URB; i++) {
++
++ purb = priv->rx_urb[i];
++
++ if (purb)
++ usb_free_urb(purb);
++
++ pskb = priv->pp_rxskb[i];
++
++ if (pskb)
++ dev_kfree_skb_any(pskb);
++
++ }
++
++ return;
++}
++
++
++void rtl8187_rx_manage_initiate(struct net_device *dev)
++{
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ if(!priv->rx_urb)
++ DMESGE("Cannot intiate RX urb mechanism");
++
++ rtl8187_rx_manage_urbsubmit(dev,priv->rx_urb[MAX_RX_URB]);
++
++}
++
++
++void rtl8187_set_rxconf(struct net_device *dev)
++{
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ u32 rxconf;
++
++ rxconf=read_nic_dword(dev,RX_CONF);
++ rxconf = rxconf &~ MAC_FILTER_MASK;
++ rxconf = rxconf | (1<<ACCEPT_MNG_FRAME_SHIFT);
++ rxconf = rxconf | (1<<ACCEPT_DATA_FRAME_SHIFT);
++ rxconf = rxconf | (1<<ACCEPT_BCAST_FRAME_SHIFT);
++ rxconf = rxconf | (1<<ACCEPT_MCAST_FRAME_SHIFT);
++ //rxconf = rxconf | (1<<ACCEPT_CTL_FRAME_SHIFT);
++#ifdef SW_ANTE_DIVERSITY
++ rxconf = rxconf | priv->EEPROMCSMethod;//for antenna
++#endif
++
++ if (dev->flags & IFF_PROMISC) DMESG ("NIC in promisc mode");
++
++ if(priv->ieee80211->iw_mode == IW_MODE_MONITOR || \
++ dev->flags & IFF_PROMISC){
++ rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT);
++ } /*else if(priv->ieee80211->iw_mode == IW_MODE_MASTER){
++ rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT);
++ rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT);
++ }*/else{
++ rxconf = rxconf | (1<<ACCEPT_NICMAC_FRAME_SHIFT);
++ rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT);
++ }
++
++
++ if(priv->ieee80211->iw_mode == IW_MODE_MONITOR){
++ rxconf = rxconf | (1<<ACCEPT_ICVERR_FRAME_SHIFT);
++ rxconf = rxconf | (1<<ACCEPT_PWR_FRAME_SHIFT);
++ }
++
++ if( priv->crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR)
++ rxconf = rxconf | (1<<ACCEPT_CRCERR_FRAME_SHIFT);
++
++
++ rxconf = rxconf &~ RX_FIFO_THRESHOLD_MASK;
++ rxconf = rxconf | (RX_FIFO_THRESHOLD_NONE<<RX_FIFO_THRESHOLD_SHIFT);
++ rxconf = rxconf &~ MAX_RX_DMA_MASK;
++ rxconf = rxconf | (MAX_RX_DMA_2048<<MAX_RX_DMA_SHIFT);
++
++ rxconf = rxconf | (1<<RX_AUTORESETPHY_SHIFT);
++ rxconf = rxconf | RCR_ONLYERLPKT;
++
++ //rxconf = rxconf &~ RCR_CS_MASK;
++ //rxconf = rxconf | (1<<RCR_CS_SHIFT);
++
++ write_nic_dword(dev, RX_CONF, rxconf);
++
++ #ifdef DEBUG_RX
++ DMESG("rxconf: %x %x",rxconf ,read_nic_dword(dev,RX_CONF));
++ #endif
++}
++
++void rtl8180_rx_enable(struct net_device *dev)
++{
++ u8 cmd;
++
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++
++ rtl8187_rx_initiate(dev);
++ rtl8187_set_rxconf(dev);
++
++ if(NIC_8187 == priv->card_8187) {
++ cmd=read_nic_byte(dev,CMD);
++ write_nic_byte(dev,CMD,cmd | (1<<CMD_RX_ENABLE_SHIFT));
++ } else {
++ //write_nic_dword(dev, RCR, priv->ReceiveConfig);
++ }
++}
++
++
++void rtl8180_tx_enable(struct net_device *dev)
++{
++ u8 cmd;
++ u8 byte;
++ u32 txconf = 0;
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++
++ if(NIC_8187B == priv->card_8187){
++ write_nic_dword(dev, TCR, priv->TransmitConfig);
++ byte = read_nic_byte(dev, MSR);
++ byte |= MSR_LINK_ENEDCA;
++ write_nic_byte(dev, MSR, byte);
++#ifdef LOOP_TEST
++ txconf= read_nic_dword(dev,TX_CONF);
++ txconf = txconf | (TX_LOOPBACK_MAC<<TX_LOOPBACK_SHIFT);
++ write_nic_dword(dev,TX_CONF,txconf);
++#endif
++ } else {
++ byte = read_nic_byte(dev,CW_CONF);
++ byte &= ~(1<<CW_CONF_PERPACKET_CW_SHIFT);
++ byte &= ~(1<<CW_CONF_PERPACKET_RETRY_SHIFT);
++ write_nic_byte(dev, CW_CONF, byte);
++
++ byte = read_nic_byte(dev, TX_AGC_CTL);
++ byte &= ~(1<<TX_AGC_CTL_PERPACKET_GAIN_SHIFT);
++ byte &= ~(1<<TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT);
++ byte &= ~(1<<TX_AGC_CTL_FEEDBACK_ANT);
++ write_nic_byte(dev, TX_AGC_CTL, byte);
++
++ txconf= read_nic_dword(dev,TX_CONF);
++
++
++ txconf = txconf &~ TX_LOOPBACK_MASK;
++
++#ifndef LOOP_TEST
++ txconf = txconf | (TX_LOOPBACK_NONE<<TX_LOOPBACK_SHIFT);
++#else
++ txconf = txconf | (TX_LOOPBACK_BASEBAND<<TX_LOOPBACK_SHIFT);
++#endif
++ txconf = txconf &~ TCR_SRL_MASK;
++ txconf = txconf &~ TCR_LRL_MASK;
++
++ txconf = txconf | (priv->retry_data<<TX_LRLRETRY_SHIFT); // long
++ txconf = txconf | (priv->retry_rts<<TX_SRLRETRY_SHIFT); // short
++
++ txconf = txconf &~ (1<<TX_NOCRC_SHIFT);
++
++ txconf = txconf &~ TCR_MXDMA_MASK;
++ txconf = txconf | (TCR_MXDMA_2048<<TCR_MXDMA_SHIFT);
++
++ txconf = txconf | TCR_DISReqQsize;
++ txconf = txconf | TCR_DISCW;
++ txconf = txconf &~ TCR_SWPLCPLEN;
++
++ txconf=txconf | (1<<TX_NOICV_SHIFT);
++
++ write_nic_dword(dev,TX_CONF,txconf);
++
++#ifdef DEBUG_TX
++ DMESG("txconf: %x %x",txconf,read_nic_dword(dev,TX_CONF));
++#endif
++
++ cmd=read_nic_byte(dev,CMD);
++ write_nic_byte(dev,CMD,cmd | (1<<CMD_TX_ENABLE_SHIFT));
++ }
++}
++
++#if 0
++void rtl8180_beacon_tx_enable(struct net_device *dev)
++{
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ priv->dma_poll_mask &=~(1<<TX_DMA_STOP_BEACON_SHIFT);
++ rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
++ write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
++ rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
++}
++
++
++void rtl8180_
++_disable(struct net_device *dev)
++{
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ priv->dma_poll_mask |= (1<<TX_DMA_STOP_BEACON_SHIFT);
++ rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
++ write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
++ rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
++}
++
++#endif
++
++
++void rtl8180_rtx_disable(struct net_device *dev)
++{
++ u8 cmd;
++ int i;
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ cmd=read_nic_byte(dev,CMD);
++ write_nic_byte(dev, CMD, cmd &~ \
++ ((1<<CMD_RX_ENABLE_SHIFT)|(1<<CMD_TX_ENABLE_SHIFT)));
++ force_pci_posting(dev);
++ mdelay(10);
++
++#ifdef THOMAS_BEACON
++ {
++ int index = priv->rx_inx;//0
++ i=0;
++ if(priv->rx_urb){
++ while(i<MAX_RX_URB){
++ if(priv->rx_urb[index]){
++ usb_kill_urb(priv->rx_urb[index]);
++ }
++ if( index == (MAX_RX_URB-1) )
++ index=0;
++ else
++ index=index+1;
++ i++;
++ }
++ if(priv->rx_urb[MAX_RX_URB])
++ usb_kill_urb(priv->rx_urb[MAX_RX_URB]);
++ }
++ }
++#endif
++}
++
++
++int alloc_tx_beacon_desc_ring(struct net_device *dev, int count)
++{
++ #if 0
++ int i;
++ u32 *tmp;
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++
++ priv->txbeaconring = (u32*)pci_alloc_consistent(priv->pdev,
++ sizeof(u32)*8*count,
++ &priv->txbeaconringdma);
++ if (!priv->txbeaconring) return -1;
++ for (tmp=priv->txbeaconring,i=0;i<count;i++){
++ *tmp = *tmp &~ (1<<31); // descriptor empty, owned by the drv
++ /*
++ *(tmp+2) = (u32)dma_tmp;
++ *(tmp+3) = bufsize;
++ */
++ if(i+1<count)
++ *(tmp+4) = (u32)priv->txbeaconringdma+((i+1)*8*4);
++ else
++ *(tmp+4) = (u32)priv->txbeaconringdma;
++
++ tmp=tmp+8;
++ }
++ #endif
++ return 0;
++}
++
++long NetgearSignalStrengthTranslate(long LastSS,long CurrSS)
++{
++ long RetSS;
++
++ // Step 1. Scale mapping.
++ if(CurrSS >= 71 && CurrSS <= 100){
++ RetSS = 90 + ((CurrSS - 70) / 3);
++ }else if(CurrSS >= 41 && CurrSS <= 70){
++ RetSS = 78 + ((CurrSS - 40) / 3);
++ }else if(CurrSS >= 31 && CurrSS <= 40){
++ RetSS = 66 + (CurrSS - 30);
++ }else if(CurrSS >= 21 && CurrSS <= 30){
++ RetSS = 54 + (CurrSS - 20);
++ }else if(CurrSS >= 5 && CurrSS <= 20){
++ RetSS = 42 + (((CurrSS - 5) * 2) / 3);
++ }else if(CurrSS == 4){
++ RetSS = 36;
++ }else if(CurrSS == 3){
++ RetSS = 27;
++ }else if(CurrSS == 2){
++ RetSS = 18;
++ }else if(CurrSS == 1){
++ RetSS = 9;
++ }else{
++ RetSS = CurrSS;
++ }
++ //RT_TRACE(COMP_DBG, DBG_LOUD, ("##### After Mapping: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
++
++ // Step 2. Smoothing.
++ if(LastSS > 0){
++ RetSS = ((LastSS * 5) + (RetSS)+ 5) / 6;
++ }
++ //RT_TRACE(COMP_DBG, DBG_LOUD, ("$$$$$ After Smoothing: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
++
++ return RetSS;
++}
++
++extern long TranslateToDbm8187(u8 SignalStrengthIndex); // 0-100 index.
++//long TranslateToDbm8187(u8 SignalStrengthIndex) // 0-100 index.
++//{
++ // long SignalPower; // in dBm.
++
++ // Translate to dBm (x=0.5y-95).
++ // SignalPower = (long)((SignalStrengthIndex + 1) >> 1);
++ // SignalPower -= 95;
++
++ // return SignalPower;
++//}
++
++
++void rtl8180_reset(struct net_device *dev)
++{
++
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ u8 cr;
++ int i;
++
++
++ /* make sure the analog power is on before
++ * reset, otherwise reset may fail
++ */
++ if(NIC_8187 == priv->card_8187) {
++ rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
++ rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_ON);
++ rtl8180_irq_disable(dev);
++ mdelay(200);
++ write_nic_byte_E(dev,0x18,0x10);
++ write_nic_byte_E(dev,0x18,0x11);
++ write_nic_byte_E(dev,0x18,0x00);
++ mdelay(200);
++ }
++
++
++ cr=read_nic_byte(dev,CMD);
++ cr = cr & 2;
++ cr = cr | (1<<CMD_RST_SHIFT);
++ write_nic_byte(dev,CMD,cr);
++
++ //lzm mod for up take too long time 20081201
++ //force_pci_posting(dev);
++ //mdelay(200);
++ udelay(20);
++
++ if(read_nic_byte(dev,CMD) & (1<<CMD_RST_SHIFT))
++ DMESGW("Card reset timeout!");
++ else
++ DMESG("Card successfully reset");
++
++ if(NIC_8187 == priv->card_8187) {
++
++ //printk("This is RTL8187 Reset procedure\n");
++ rtl8180_set_mode(dev,EPROM_CMD_LOAD);
++ force_pci_posting(dev);
++ mdelay(200);
++
++ /* after the eeprom load cycle, make sure we have
++ * correct anaparams
++ */
++ rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
++ rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_ON);
++ }
++ else {
++ //printk("This is RTL8187B Reset procedure\n");
++ //test pending bug, john 20070815
++ //initialize tx_pending
++ for(i=0;i<0x10;i++) atomic_set(&(priv->tx_pending[i]), 0);
++
++ }
++
++}
++
++inline u16 ieeerate2rtlrate(int rate)
++{
++ switch(rate){
++ case 10:
++ return 0;
++ case 20:
++ return 1;
++ case 55:
++ return 2;
++ case 110:
++ return 3;
++ case 60:
++ return 4;
++ case 90:
++ return 5;
++ case 120:
++ return 6;
++ case 180:
++ return 7;
++ case 240:
++ return 8;
++ case 360:
++ return 9;
++ case 480:
++ return 10;
++ case 540:
++ return 11;
++ default:
++ return 3;
++
++ }
++}
++static u16 rtl_rate[] = {10,20,55,110,60,90,120,180,240,360,480,540,720};
++inline u16 rtl8180_rate2rate(short rate)
++{
++ if (rate >12) return 10;
++ return rtl_rate[rate];
++}
++
++void rtl8180_irq_rx_tasklet(struct r8180_priv *priv);
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
++void rtl8187_rx_isr(struct urb *rx_urb, struct pt_regs *regs)
++#else
++void rtl8187_rx_isr(struct urb* rx_urb)
++#endif
++{
++ struct net_device *dev = (struct net_device*)rx_urb->context;
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ priv->rxurb_task = rx_urb;
++
++
++ //DMESGW("David: Rx tasklet start!");
++
++#ifdef THOMAS_TASKLET
++ atomic_inc( &priv->irt_counter );
++
++ //if( likely(priv->irt_counter_head+1 != priv->irt_counter_tail) ){
++ // priv->irt_counter_head = (priv->irt_counter_head+1)&0xffff ;
++ tasklet_schedule(&priv->irq_rx_tasklet);
++ //} else{
++ //DMESG("error: priv->irt_counter_head is going to pass through priv->irt_counter_tail\n");
++ /*
++ skb = priv->pp_rxskb[priv->rx_inx];
++ dev_kfree_skb_any(skb);
++
++ skb = dev_alloc_skb(RX_URB_SIZE);
++ if (skb == NULL)
++ panic("No Skb For RX!/n");
++
++ rx_urb->transfer_buffer = skb->data;
++
++ priv->pp_rxskb[priv->rx_inx] = skb;
++ if(status == 0)
++ rtl8187_rx_urbsubmit(dev,rx_urb);
++ else {
++ priv->pp_rxskb[priv->rx_inx] = NULL;
++ dev_kfree_skb_any(skb);
++ printk("RX process aborted due to explicit shutdown (%x) ", status);
++ }
++
++ if (*prx_inx == (MAX_RX_URB -1))
++ *prx_inx = 0;
++ else
++ *prx_inx = *prx_inx + 1;
++
++ */
++ //}
++#endif
++
++}
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
++void rtl8187_rx_manage_isr(struct urb *rx_urb, struct pt_regs *regs)
++#else
++void rtl8187_rx_manage_isr(struct urb* rx_urb)
++#endif
++{
++ struct net_device *dev = (struct net_device*)rx_urb->context;
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ int status,cmd;
++ struct sk_buff *skb;
++ u32 *desc;
++ int ret;
++ unsigned long flag;
++
++ //DMESG("RX %d ",rx_urb->status);
++ status = rx_urb->status;
++ if(status == 0){
++
++ desc = (u32*)(rx_urb->transfer_buffer);
++ cmd = (desc[0] >> 30) & 0x03;
++ //printk(KERN_ALERT "buffersize = %d, length = %d, pipe = %p\n",
++ //rx_urb->transfer_buffer_length, rx_urb->actual_length, rx_urb->pipe>>15);
++
++ if(cmd == 0x00) {//beacon interrupt
++ //send beacon packet
++
++ spin_lock_irqsave(&priv->ieee80211->beaconflag_lock,flag);
++ if(priv->flag_beacon == true){
++ //printk("rtl8187_rx_manage_isr(): CMD_TYPE0_BCN_INTR\n");
++
++ skb = ieee80211_get_beacon(priv->ieee80211);
++ if(!skb){
++ DMESG("not enought memory for allocating beacon");
++ return;
++ }
++ //printk(KERN_WARNING "to send beacon packet through beacon endpoint!\n");
++ ret = rtl8180_tx(dev, (u32*)skb->data, skb->len, BEACON_PRIORITY,
++ 0, ieeerate2rtlrate(priv->ieee80211->basic_rate));
++
++ if( ret != 0 ){
++ printk(KERN_ALERT "tx beacon packet error : %d !\n", ret);
++ }
++ dev_kfree_skb_any(skb);
++
++ //} else {//0x00
++ //{ log the device information
++ // At present, It is not implemented just now.
++ //}
++ //}
++
++ }
++ spin_unlock_irqrestore(&priv->ieee80211->beaconflag_lock,flag);
++ }
++ else if(cmd == 0x01){
++ //printk("rtl8187_rx_manage_isr(): CMD_TYPE1_TX_CLOSE\n");
++ priv->CurrRetryCnt += (u16)desc[0]&0x000000ff;
++ //printk("priv->CurrRetryCnt is %d\n",priv->CurrRetryCnt);
++ }
++ else
++ printk("HalUsbInCommandComplete8187B(): unknown Type(%#X) !!!\n", cmd);
++
++ }else{
++ priv->stats.rxstaterr++;
++ priv->ieee80211->stats.rx_errors++;
++ }
++
++
++ if( status == 0 )
++ //if(status != -ENOENT)
++ rtl8187_rx_manage_urbsubmit(dev, rx_urb);
++ else
++ ;//DMESG("Mangement RX process aborted due to explicit shutdown");
++}
++
++#if 0
++void rtl8180_tx_queues_stop(struct net_device *dev)
++{
++ //struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ u8 dma_poll_mask = (1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
++ dma_poll_mask |= (1<<TX_DMA_STOP_HIPRIORITY_SHIFT);
++ dma_poll_mask |= (1<<TX_DMA_STOP_NORMPRIORITY_SHIFT);
++ dma_poll_mask |= (1<<TX_DMA_STOP_BEACON_SHIFT);
++
++ rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
++ write_nic_byte(dev,TX_DMA_POLLING,dma_poll_mask);
++ rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
++}
++#endif
++
++void rtl8180_data_hard_stop(struct net_device *dev)
++{
++ //FIXME !!
++ #if 0
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ priv->dma_poll_mask |= (1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
++ rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
++ write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
++ rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
++ #endif
++}
++
++
++void rtl8180_data_hard_resume(struct net_device *dev)
++{
++ // FIXME !!
++ #if 0
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ priv->dma_poll_mask &= ~(1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
++ rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
++ write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
++ rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
++ #endif
++}
++
++unsigned int PRI2EP[4] = {0x06,0x07,0x05,0x04};
++// this function TX data frames when the ieee80211 stack requires this.
++// It checks also if we need to stop the ieee tx queue, eventually do it
++void rtl8180_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, int rate)
++{
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++
++ short morefrag = 0;
++ unsigned long flags;
++ struct ieee80211_hdr *h = (struct ieee80211_hdr *) skb->data;
++
++ unsigned char ep;
++ short ret; //john
++
++ if (le16_to_cpu(h->frame_ctl) & IEEE80211_FCTL_MOREFRAGS)
++ morefrag = 1;
++ //DMESG("%x %x", h->frame_ctl, h->seq_ctl);
++ /*
++ * This function doesn't require lock because we make
++ * sure it's called with the tx_lock already acquired.
++ * this come from the kernel's hard_xmit callback (trought
++ * the ieee stack, or from the try_wake_queue (again trought
++ * the ieee stack.
++ */
++ spin_lock_irqsave(&priv->tx_lock,flags);
++
++ //lzm mod 20081128 for sometimes wlan down but it still have some pkt to tx
++ if((priv->ieee80211->bHwRadioOff)||(!priv->up))
++ {
++ spin_unlock_irqrestore(&priv->tx_lock,flags);
++
++ return;
++ }
++
++ if(NIC_8187B == priv->card_8187){
++ ep = PRI2EP[skb->priority];
++ } else {
++ ep = LOW_PRIORITY;
++ }
++ //if (!check_nic_enought_desc(dev, PRI2EP[skb->priority])){
++ if (!check_nic_enought_desc(dev, ep)){
++ DMESG("Error: no TX slot ");
++ ieee80211_stop_queue(priv->ieee80211);
++ }
++
++#ifdef LED_SHIN
++ priv->ieee80211->ieee80211_led_contorl(dev,LED_CTL_TX);
++#endif
++
++ ret = rtl8180_tx(dev, (u32*)skb->data, skb->len, ep, morefrag,ieeerate2rtlrate(rate));
++ if(ret!=0) DMESG("Error: rtl8180_tx failed in rtl8180_hard_data_xmit\n");//john
++
++ priv->stats.txdatapkt++;
++
++ //if (!check_nic_enought_desc(dev, PRI2EP[skb->priority])){
++ if (!check_nic_enought_desc(dev, ep)){
++ ieee80211_stop_queue(priv->ieee80211);
++ }
++
++ spin_unlock_irqrestore(&priv->tx_lock,flags);
++
++}
++
++//This is a rough attempt to TX a frame
++//This is called by the ieee 80211 stack to TX management frames.
++//If the ring is full packet are dropped (for data frame the queue
++//is stopped before this can happen).
++
++int rtl8180_hard_start_xmit(struct sk_buff *skb,struct net_device *dev)
++{
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ struct ieee80211_device *ieee = priv->ieee80211;
++ int ret;
++ unsigned long flags;
++ spin_lock_irqsave(&priv->tx_lock,flags);
++
++ //lzm mod 20081128 for sometimes wlan down but it still have some pkt to tx
++ if((priv->ieee80211->bHwRadioOff)||(!priv->up))
++ {
++ spin_unlock_irqrestore(&priv->tx_lock,flags);
++ return 0;
++ }
++
++ ret = rtl8180_tx(dev, (u32*)skb->data, skb->len, MANAGE_PRIORITY, 0, ieeerate2rtlrate(ieee->basic_rate));
++
++ priv->ieee80211->stats.tx_bytes+=skb->len;
++ priv->ieee80211->stats.tx_packets++;
++
++ spin_unlock_irqrestore(&priv->tx_lock,flags);
++
++ return ret;
++}
++
++
++#if 0
++// longpre 144+48 shortpre 72+24
++u16 rtl8180_len2duration(u32 len, short rate,short* ext)
++{
++ u16 duration;
++ u16 drift;
++ *ext=0;
++
++ switch(rate){
++ case 0://1mbps
++ *ext=0;
++ duration = ((len+4)<<4) /0x2;
++ drift = ((len+4)<<4) % 0x2;
++ if(drift ==0 ) break;
++ duration++;
++ break;
++
++ case 1://2mbps
++ *ext=0;
++ duration = ((len+4)<<4) /0x4;
++ drift = ((len+4)<<4) % 0x4;
++ if(drift ==0 ) break;
++ duration++;
++ break;
++
++ case 2: //5.5mbps
++ *ext=0;
++ duration = ((len+4)<<4) /0xb;
++ drift = ((len+4)<<4) % 0xb;
++ if(drift ==0 )
++ break;
++ duration++;
++ break;
++
++ default:
++ case 3://11mbps
++ *ext=0;
++ duration = ((len+4)<<4) /0x16;
++ drift = ((len+4)<<4) % 0x16;
++ if(drift ==0 )
++ break;
++ duration++;
++ if(drift > 6)
++ break;
++ *ext=1;
++ break;
++ }
++
++ return duration;
++}
++#endif
++
++void rtl8180_try_wake_queue(struct net_device *dev, int pri);
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
++void rtl8187_lptx_isr(struct urb *tx_urb, struct pt_regs *regs)
++#else
++void rtl8187_lptx_isr(struct urb* tx_urb)
++#endif
++{
++ struct net_device *dev = (struct net_device*)tx_urb->context;
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ if(tx_urb->status == 0){
++ dev->trans_start = jiffies; //john
++ priv->stats.txlpokint++;
++ priv->txokbytestotal+=tx_urb->actual_length;
++ }else{
++ priv->stats.txlperr++;
++ }
++
++ kfree(tx_urb->transfer_buffer);
++ usb_free_urb(tx_urb);
++
++ if(atomic_read(&priv->tx_pending[LOW_PRIORITY]) >= 1)
++ atomic_dec(&priv->tx_pending[LOW_PRIORITY]);
++
++ rtl8180_try_wake_queue(dev,LOW_PRIORITY);
++}
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
++void rtl8187_nptx_isr(struct urb *tx_urb, struct pt_regs *regs)
++#else
++void rtl8187_nptx_isr(struct urb* tx_urb)
++#endif
++{
++ struct net_device *dev = (struct net_device*)tx_urb->context;
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ if(tx_urb->status == 0){
++ dev->trans_start = jiffies; //john
++ priv->stats.txnpokint++;
++ }else{
++ priv->stats.txnperr++;
++ }
++
++ kfree(tx_urb->transfer_buffer);
++ usb_free_urb(tx_urb);
++
++ if(atomic_read(&priv->tx_pending[NORM_PRIORITY]) >= 1)
++ atomic_dec(&priv->tx_pending[NORM_PRIORITY]);
++ //rtl8180_try_wake_queue(dev,NORM_PRIORITY);
++}
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
++void rtl8187_votx_isr(struct urb *tx_urb, struct pt_regs *regs)
++#else
++void rtl8187_votx_isr(struct urb* tx_urb)
++#endif
++{
++ struct net_device *dev = (struct net_device*)tx_urb->context;
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ if(tx_urb->status == 0){
++ dev->trans_start = jiffies; //john
++ priv->stats.txvookint++;
++ priv->txokbytestotal+=tx_urb->actual_length;
++ }else{
++ priv->stats.txvoerr++;
++ }
++
++ kfree(tx_urb->transfer_buffer);
++ usb_free_urb(tx_urb);
++
++ if(atomic_read(&priv->tx_pending[VO_PRIORITY]) >= 1)
++ atomic_dec(&priv->tx_pending[VO_PRIORITY]);
++ rtl8180_try_wake_queue(dev,VO_PRIORITY);
++}
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
++void rtl8187_vitx_isr(struct urb *tx_urb, struct pt_regs *regs)
++#else
++void rtl8187_vitx_isr(struct urb* tx_urb)
++#endif
++{
++ struct net_device *dev = (struct net_device*)tx_urb->context;
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ if(tx_urb->status == 0){
++ dev->trans_start = jiffies; //john
++ priv->stats.txviokint++;
++ priv->txokbytestotal+=tx_urb->actual_length;
++ }else{
++ priv->stats.txvierr++;
++ }
++
++ kfree(tx_urb->transfer_buffer);
++ usb_free_urb(tx_urb);
++
++ if(atomic_read(&priv->tx_pending[VI_PRIORITY]) >= 1)
++ atomic_dec(&priv->tx_pending[VI_PRIORITY]);
++ rtl8180_try_wake_queue(dev,VI_PRIORITY);
++}
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
++void rtl8187_betx_isr(struct urb *tx_urb, struct pt_regs *regs)
++#else
++void rtl8187_betx_isr(struct urb* tx_urb)
++#endif
++{
++ struct net_device *dev = (struct net_device*)tx_urb->context;
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ if(tx_urb->status == 0){
++ dev->trans_start = jiffies; //john
++ priv->stats.txbeokint++;
++ priv->txokbytestotal+=tx_urb->actual_length;
++ }else{
++ priv->stats.txbeerr++;
++ }
++
++ kfree(tx_urb->transfer_buffer);
++ usb_free_urb(tx_urb);
++
++ if(atomic_read(&priv->tx_pending[BE_PRIORITY]) >= 1)
++ atomic_dec(&priv->tx_pending[BE_PRIORITY]);
++ rtl8180_try_wake_queue(dev, BE_PRIORITY);
++}
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
++void rtl8187_bktx_isr(struct urb *tx_urb, struct pt_regs *regs)
++#else
++void rtl8187_bktx_isr(struct urb* tx_urb)
++#endif
++{
++ struct net_device *dev = (struct net_device*)tx_urb->context;
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ if(tx_urb->status == 0){
++ dev->trans_start = jiffies; //john
++ priv->stats.txbkokint++;
++ }else{
++ priv->stats.txbkerr++;
++ }
++
++ kfree(tx_urb->transfer_buffer);
++ usb_free_urb(tx_urb);
++
++ if(atomic_read(&priv->tx_pending[BK_PRIORITY]) >= 1)
++ atomic_dec(&priv->tx_pending[BK_PRIORITY]);
++ rtl8180_try_wake_queue(dev,BK_PRIORITY);
++}
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
++void rtl8187_beacontx_isr(struct urb *tx_urb, struct pt_regs *regs)
++#else
++void rtl8187_beacontx_isr(struct urb* tx_urb)
++#endif
++{
++ struct net_device *dev = (struct net_device*)tx_urb->context;
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ if(tx_urb->status == 0){
++ dev->trans_start = jiffies; //john
++ priv->stats.txbeaconokint++;
++ priv->txokbytestotal+=tx_urb->actual_length;
++ }else{
++ priv->stats.txbeaconerr++;
++ }
++
++ kfree(tx_urb->transfer_buffer);
++ usb_free_urb(tx_urb);
++
++ if(atomic_read(&priv->tx_pending[BEACON_PRIORITY]) >= 1)
++ atomic_dec(&priv->tx_pending[BEACON_PRIORITY]);
++ //rtl8180_try_wake_queue(dev,BEACON_PRIORITY);
++}
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
++void rtl8187_managetx_isr(struct urb *tx_urb, struct pt_regs *regs)
++#else
++void rtl8187_managetx_isr(struct urb* tx_urb)
++#endif
++{
++ struct net_device *dev = (struct net_device*)tx_urb->context;
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ if(tx_urb->status == 0){
++ dev->trans_start = jiffies; //john
++ priv->stats.txmanageokint++;
++ priv->txokbytestotal+=tx_urb->actual_length;
++ }else{
++ priv->stats.txmanageerr++;
++ }
++
++ kfree(tx_urb->transfer_buffer);
++ usb_free_urb(tx_urb);
++
++ if(atomic_read(&priv->tx_pending[MANAGE_PRIORITY]) >= 1)
++ atomic_dec(&priv->tx_pending[MANAGE_PRIORITY]);
++// rtl8180_try_wake_queue(dev,MANAGE_PRIORITY);
++}
++
++void rtl8187_beacon_stop(struct net_device *dev)
++{
++ u8 msr, msrm, msr2;
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ unsigned long flag;
++ msr = read_nic_byte(dev, MSR);
++ msrm = msr & MSR_LINK_MASK;
++ msr2 = msr & ~MSR_LINK_MASK;
++ if(NIC_8187B == priv->card_8187) {
++ spin_lock_irqsave(&priv->ieee80211->beaconflag_lock,flag);
++ priv->flag_beacon = false;
++ spin_unlock_irqrestore(&priv->ieee80211->beaconflag_lock,flag);
++ }
++ if ((msrm == (MSR_LINK_ADHOC<<MSR_LINK_SHIFT) ||
++ (msrm == (MSR_LINK_MASTER<<MSR_LINK_SHIFT)))){
++ write_nic_byte(dev, MSR, msr2 | MSR_LINK_NONE);
++ write_nic_byte(dev, MSR, msr);
++ }
++}
++
++
++void rtl8187_net_update(struct net_device *dev)
++{
++
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ struct ieee80211_network *net;
++ net = & priv->ieee80211->current_network;
++
++
++ write_nic_dword(dev,BSSID,((u32*)net->bssid)[0]);
++ write_nic_word(dev,BSSID+4,((u16*)net->bssid)[2]);
++
++ rtl8180_update_msr(dev);
++
++ //rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
++ write_nic_word(dev, AtimWnd, 2);
++ write_nic_word(dev, AtimtrItv, 100);
++ write_nic_word(dev, BEACON_INTERVAL, net->beacon_interval);
++ //write_nic_word(dev, BcnIntTime, 100);
++ write_nic_word(dev, BcnIntTime, 0x3FF);
++
++
++}
++
++void rtl8187_beacon_tx(struct net_device *dev)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ struct sk_buff *skb;
++ int i = 0;
++ u8 cr;
++ unsigned long flag;
++ rtl8187_net_update(dev);
++
++ if(NIC_8187B == priv->card_8187) {
++ //Cause TSF timer of MAC reset to 0
++ cr=read_nic_byte(dev,CMD);
++ cr = cr | (1<<CMD_RST_SHIFT);
++ write_nic_byte(dev,CMD,cr);
++
++ //lzm mod 20081201
++ //mdelay(200);
++ mdelay(20);
++
++ if(read_nic_byte(dev,CMD) & (1<<CMD_RST_SHIFT))
++ DMESGW("Card reset timeout for ad-hoc!");
++ else
++ DMESG("Card successfully reset for ad-hoc");
++
++ write_nic_byte(dev,CMD, (read_nic_byte(dev,CMD)|CR_RE|CR_TE));
++ spin_lock_irqsave(&priv->ieee80211->beaconflag_lock,flag);
++ priv->flag_beacon = true;
++ spin_unlock_irqrestore(&priv->ieee80211->beaconflag_lock,flag);
++
++ //rtl8187_rx_manage_initiate(dev);
++ } else {
++ printk(KERN_WARNING "get the beacon!\n");
++ skb = ieee80211_get_beacon(priv->ieee80211);
++ if(!skb){
++ DMESG("not enought memory for allocating beacon");
++ return;
++ }
++
++ write_nic_byte(dev, BQREQ, read_nic_byte(dev, BQREQ) | (1<<7));
++
++ i=0;
++ //while(!read_nic_byte(dev,BQREQ & (1<<7)))
++ while( (read_nic_byte(dev, BQREQ) & (1<<7)) == 0 )
++ {
++ msleep_interruptible_rtl(HZ/2);
++ if(i++ > 10){
++ DMESGW("get stuck to wait HW beacon to be ready");
++ return ;
++ }
++ }
++ //tx
++ rtl8180_tx(dev, (u32*)skb->data, skb->len, NORM_PRIORITY,
++ 0, ieeerate2rtlrate(priv->ieee80211->basic_rate));
++ if(skb)
++ dev_kfree_skb_any(skb);
++ }
++}
++
++#if 0
++void rtl8187_nptx_isr(struct urb *tx_urb, struct pt_regs *regs)
++{
++ struct net_device *dev = (struct net_device*)tx_urb->context;
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ if(tx_urb->status == 0)
++ priv->stats.txnpokint++;
++ else
++ priv->stats.txnperr++;
++ kfree(tx_urb->transfer_buffer);
++ usb_free_urb(tx_urb);
++ atomic_dec(&priv->tx_np_pending);
++ //rtl8180_try_wake_queue(dev,NORM_PRIORITY);
++}
++#endif
++inline u8 rtl8180_IsWirelessBMode(u16 rate)
++{
++ if( ((rate <= 110) && (rate != 60) && (rate != 90)) || (rate == 220) )
++ return 1;
++ else return 0;
++}
++
++u16 N_DBPSOfRate(u16 DataRate);
++
++u16 ComputeTxTime(
++ u16 FrameLength,
++ u16 DataRate,
++ u8 bManagementFrame,
++ u8 bShortPreamble
++ )
++{
++ u16 FrameTime;
++ u16 N_DBPS;
++ u16 Ceiling;
++
++ if( rtl8180_IsWirelessBMode(DataRate) )
++ {
++ if( bManagementFrame || !bShortPreamble || DataRate == 10 ){ // long preamble
++ FrameTime = (u16)(144+48+(FrameLength*8/(DataRate/10)));
++ }else{ // Short preamble
++ FrameTime = (u16)(72+24+(FrameLength*8/(DataRate/10)));
++ }
++ if( ( FrameLength*8 % (DataRate/10) ) != 0 ) //Get the Ceilling
++ FrameTime ++;
++ } else { //802.11g DSSS-OFDM PLCP length field calculation.
++ N_DBPS = N_DBPSOfRate(DataRate);
++ Ceiling = (16 + 8*FrameLength + 6) / N_DBPS
++ + (((16 + 8*FrameLength + 6) % N_DBPS) ? 1 : 0);
++ FrameTime = (u16)(16 + 4 + 4*Ceiling + 6);
++ }
++ return FrameTime;
++}
++
++u16 N_DBPSOfRate(u16 DataRate)
++{
++ u16 N_DBPS = 24;
++
++ switch(DataRate)
++ {
++ case 60:
++ N_DBPS = 24;
++ break;
++
++ case 90:
++ N_DBPS = 36;
++ break;
++
++ case 120:
++ N_DBPS = 48;
++ break;
++
++ case 180:
++ N_DBPS = 72;
++ break;
++
++ case 240:
++ N_DBPS = 96;
++ break;
++
++ case 360:
++ N_DBPS = 144;
++ break;
++
++ case 480:
++ N_DBPS = 192;
++ break;
++
++ case 540:
++ N_DBPS = 216;
++ break;
++
++ default:
++ break;
++ }
++
++ return N_DBPS;
++}
++// NOte!!!
++// the rate filled in is the rtl_rate.
++// while the priv->ieee80211->basic_rate,used in the following code is ieee80211 rate.
++
++#ifdef JUST_FOR_87SEMESH
++#define ActionHeadLen 30
++#endif
++#define sCrcLng 4
++#define sAckCtsLng 112 // bits in ACK and CTS frames
++short rtl8180_tx(struct net_device *dev, u32* txbuf, int len, priority_t priority,
++ short morefrag, short rate)
++{
++ u32 *tx;
++ int pend ;
++ int status;
++ struct urb *tx_urb;
++ int urb_len;
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ struct ieee80211_hdr_3addr_QOS *frag_hdr = (struct ieee80211_hdr_3addr_QOS *)txbuf;
++ struct ieee80211_device *ieee;//added for descriptor
++ u8 dest[ETH_ALEN];
++
++ bool bUseShortPreamble = false;
++ bool bCTSEnable = false;
++ bool bRTSEnable = false;
++ u16 Duration = 0;
++ u16 RtsDur = 0;
++ u16 ThisFrameTime = 0;
++ u16 TxDescDuration = 0;
++
++ ieee = priv->ieee80211;
++#if 0
++//{added by david for filter the packet listed in the filter table
++#ifdef _RTL8187_EXT_PATCH_
++ if((ieee->iw_mode == ieee->iw_ext_mode) && (ieee->ext_patch_ieee80211_acl_query))
++ {
++ if(!ieee->ext_patch_ieee80211_acl_query(ieee, frag_hdr->addr1)) {
++ return 0;
++ }
++ }
++#endif
++//}
++#endif
++
++#ifdef JUST_FOR_87SEMESH
++//#ifdef Lawrence_Mesh
++ u8* meshtype = (u8*)txbuf;
++ if(*meshtype == 0xA8)
++ {
++ //overflow??
++ //memcpy(meshtype+ActionHeadLen+2,meshtype+ActionHeadLen,Len-ActionHeadLen);
++ //memcpy(meshtype+ActionHeadLen,0,2);
++ u8 actionframe[256];
++ memset(actionframe,0,256);
++ memcpy(actionframe,meshtype,ActionHeadLen);
++ memcpy(actionframe+ActionHeadLen+2,meshtype+ActionHeadLen,len-ActionHeadLen);
++ txbuf = (u32*)actionframe;
++ len=len+2;
++ frag_hdr = (struct ieee80211_hdr_3addr_QOS *)txbuf;
++ }
++#endif
++
++ //pend = atomic_read((priority == NORM_PRIORITY)? &priv->tx_np_pending : &priv->tx_lp_pending);
++ pend = atomic_read(&priv->tx_pending[priority]);
++ /* we are locked here so the two atomic_read and inc are executed without interleaves */
++ if( pend > MAX_TX_URB){
++ if(NIC_8187 == priv->card_8187) {
++ if(priority == NORM_PRIORITY)
++ priv->stats.txnpdrop++;
++ else
++ priv->stats.txlpdrop++;
++
++ } else {
++ switch (priority) {
++ case VO_PRIORITY:
++ priv->stats.txvodrop++;
++ break;
++ case VI_PRIORITY:
++ priv->stats.txvidrop++;
++ break;
++ case BE_PRIORITY:
++ priv->stats.txbedrop++;
++ break;
++ case MANAGE_PRIORITY: //lzm for MANAGE_PRIORITY pending
++ if(priv->commit == 0)
++ {
++ priv->commit = 1;
++ printk(KERN_INFO "manage pkt pending will commit now....\n");
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
++ schedule_work(&priv->reset_wq);
++#else
++ schedule_task(&priv->reset_wq);
++#endif
++ }
++ break;
++ default://BK_PRIORITY
++ priv->stats.txbkdrop++;
++ break;
++ }
++ }
++ //printk(KERN_INFO "tx_pending: %d > MAX_TX_URB\n", priority);
++ return -1;
++ }
++
++ urb_len = len + ((NIC_8187 == priv->card_8187)?(4*3):(4*8));
++ if((0 == (urb_len&63))||(0 == (urb_len&511))) {
++ urb_len += 1;
++ }
++
++ tx = kmalloc(urb_len, GFP_ATOMIC);
++ if(!tx) return -ENOMEM;
++ memset(tx, 0, sizeof(u32) * 8);
++
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
++ tx_urb = usb_alloc_urb(0,GFP_ATOMIC);
++#else
++ tx_urb = usb_alloc_urb(0);
++#endif
++
++ if(!tx_urb){
++ kfree(tx);
++ return -ENOMEM;
++ }
++
++ // Check multicast/broadcast
++ if (ieee->iw_mode == IW_MODE_INFRA) {
++ /* To DS: Addr1 = BSSID, Addr2 = SA,
++ Addr3 = DA */
++ //memcpy(&dest, frag_hdr->addr3, ETH_ALEN);
++ memcpy(&dest, frag_hdr->addr1, ETH_ALEN);
++ } else if (ieee->iw_mode == IW_MODE_ADHOC) {
++ /* not From/To DS: Addr1 = DA, Addr2 = SA,
++ Addr3 = BSSID */
++ memcpy(&dest, frag_hdr->addr1, ETH_ALEN);
++ }
++
++ if (is_multicast_ether_addr(dest) ||is_broadcast_ether_addr(dest))
++ {
++ Duration = 0;
++ RtsDur = 0;
++ bRTSEnable = false;
++ bCTSEnable = false;
++
++ ThisFrameTime = ComputeTxTime(len + sCrcLng, rtl8180_rate2rate(rate), false, bUseShortPreamble);
++ TxDescDuration = ThisFrameTime;
++ } else {// Unicast packet
++ //u8 AckRate;
++ u16 AckTime;
++
++ // Figure out ACK rate according to BSS basic rate and Tx rate, 2006.03.08 by rcnjko.
++ //AckRate = ComputeAckRate( pMgntInfo->mBrates, (u1Byte)(pTcb->DataRate) );
++ // Figure out ACK time according to the AckRate and assume long preamble is used on receiver, 2006.03.08, by rcnjko.
++ //AckTime = ComputeTxTime( sAckCtsLng/8, AckRate, FALSE, FALSE);
++ //For simplicity, just use the 1M basic rate
++ AckTime = ComputeTxTime(14, 10,false, false); // AckCTSLng = 14 use 1M bps send
++ //AckTime = ComputeTxTime(14, 2,false, false); // AckCTSLng = 14 use 1M bps send
++
++ if ( ((len + sCrcLng) > priv->rts) && priv->rts ){ // RTS/CTS.
++ u16 RtsTime, CtsTime;
++ //u16 CtsRate;
++ bRTSEnable = true;
++ bCTSEnable = false;
++
++ // Rate and time required for RTS.
++ RtsTime = ComputeTxTime( sAckCtsLng/8,priv->ieee80211->basic_rate, false, false);
++ // Rate and time required for CTS.
++ CtsTime = ComputeTxTime(14, 10,false, false); // AckCTSLng = 14 use 1M bps send
++
++ // Figure out time required to transmit this frame.
++ ThisFrameTime = ComputeTxTime(len + sCrcLng,
++ rtl8180_rate2rate(rate),
++ false,
++ bUseShortPreamble);
++
++ // RTS-CTS-ThisFrame-ACK.
++ RtsDur = CtsTime + ThisFrameTime + AckTime + 3*aSifsTime;
++
++ TxDescDuration = RtsTime + RtsDur;
++ }else {// Normal case.
++ bCTSEnable = false;
++ bRTSEnable = false;
++ RtsDur = 0;
++
++ ThisFrameTime = ComputeTxTime(len + sCrcLng, rtl8180_rate2rate(rate), false, bUseShortPreamble);
++ TxDescDuration = ThisFrameTime + aSifsTime + AckTime;
++ }
++
++ if(!(frag_hdr->frame_ctl & IEEE80211_FCTL_MOREFRAGS)) { //no more fragment
++ // ThisFrame-ACK.
++ Duration = aSifsTime + AckTime;
++ } else { // One or more fragments remained.
++ u16 NextFragTime;
++ NextFragTime = ComputeTxTime( len + sCrcLng, //pretend following packet length equal current packet
++ rtl8180_rate2rate(rate),
++ false, bUseShortPreamble );
++
++ //ThisFrag-ACk-NextFrag-ACK.
++ Duration = NextFragTime + 3*aSifsTime + 2*AckTime;
++ }
++
++ } // End of Unicast packet
++
++
++ //fill the tx desriptor
++ tx[0] |= len & 0xfff;
++#ifdef JOHN_HWSEC
++ if(frag_hdr->frame_ctl & IEEE80211_FCTL_WEP ){
++ tx[0] &= 0xffff7fff;
++ //group key may be different from pairwise key
++ if( frag_hdr->addr1[0]==0xff &&
++ frag_hdr->addr1[0]==0xff &&
++ frag_hdr->addr1[0]==0xff &&
++ frag_hdr->addr1[0]==0xff &&
++ frag_hdr->addr1[0]==0xff &&
++ frag_hdr->addr1[0]==0xff ){
++ if(ieee->broadcast_key_type == KEY_TYPE_CCMP) tx[7] |= 0x2;//ccmp
++ else tx[7] |= 0x1;//wep and tkip
++ }
++ else {
++ if(ieee->pairwise_key_type == KEY_TYPE_CCMP) tx[7] |= 0x2;//CCMP
++ else tx[7] |= 0x1;//WEP and TKIP
++ }
++ }
++ else
++#endif /*JOHN_HWSEC*/
++
++ tx[0] |= (1<<15);
++
++ if (priv->ieee80211->current_network.capability&WLAN_CAPABILITY_SHORT_PREAMBLE){
++ if (priv->plcp_preamble_mode==1 && rate!=0) { // short mode now, not long!
++ tx[0] |= (1<<16);
++ } // enable short preamble mode.
++ }
++
++ if(morefrag) tx[0] |= (1<<17);
++ //printk(KERN_WARNING "rtl_rate = %d\n", rate);
++ tx[0] |= (rate << 24); //TX rate
++ frag_hdr->duration_id = Duration;
++
++ if(NIC_8187B == priv->card_8187) {
++ if(bCTSEnable) {
++ tx[0] |= (1<<18);
++ }
++
++ if(bRTSEnable) //rts enable
++ {
++ tx[0] |= ((ieeerate2rtlrate(priv->ieee80211->basic_rate))<<19);//RTS RATE
++ tx[0] |= (1<<23);//rts enable
++ tx[1] |= RtsDur;//RTS Duration
++ }
++ tx[3] |= (TxDescDuration<<16); //DURATION
++ if( WLAN_FC_GET_STYPE(le16_to_cpu(frag_hdr->frame_ctl)) == IEEE80211_STYPE_PROBE_RESP )
++ tx[5] |= (1<<8);//(priv->retry_data<<8); //retry lim ;
++ else
++ tx[5] |= (11<<8);//(priv->retry_data<<8); //retry lim ;
++
++ //frag_hdr->duration_id = Duration;
++ memcpy(tx+8,txbuf,len);
++ } else {
++ if ( (len>priv->rts) && priv->rts && priority==LOW_PRIORITY){
++ tx[0] |= (1<<23); //enalbe RTS function
++ tx[1] |= RtsDur; //Need to edit here! ----hikaru
++ }
++ else {
++ tx[1]=0;
++ }
++ tx[0] |= (ieeerate2rtlrate(priv->ieee80211->basic_rate) << 19); /* RTS RATE - should be basic rate */
++
++ tx[2] = 3; // CW min
++ tx[2] |= (7<<4); //CW max
++ tx[2] |= (11<<8);//(priv->retry_data<<8); //retry lim
++
++ // printk("%x\n%x\n",tx[0],tx[1]);
++
++#ifdef DUMP_TX
++ int i;
++ printk("<Tx pkt>--rate %x---",rate);
++ for (i = 0; i < (len + 3); i++)
++ printk("%2x", ((u8*)tx)[i]);
++ printk("---------------\n");
++#endif
++ memcpy(tx+3,txbuf,len);
++ }
++
++#ifdef JOHN_DUMP_TXDESC
++ int i;
++ printk("<Tx descriptor>--rate %x---",rate);
++ for (i = 0; i < 8; i++)
++ printk("%8x ", tx[i]);
++ printk("\n");
++#endif
++#ifdef JOHN_DUMP_TXPKT
++ {
++ int j;
++ printk("\n---------------------------------------------------------------------\n");
++ printk("<Tx packet>--rate %x--urb_len in decimal %d",rate, urb_len);
++ for (j = 32; j < (urb_len); j++){
++ if( ( (j-32)%24 )==0 ) printk("\n");
++ printk("%2x ", ((u8*)tx)[j]);
++ }
++ printk("\n---------------------------------------------------------------------\n");
++
++ }
++#endif
++
++ if(NIC_8187 == priv->card_8187) {
++ usb_fill_bulk_urb(tx_urb,priv->udev,
++ usb_sndbulkpipe(priv->udev,priority), tx,
++ urb_len, (priority == LOW_PRIORITY)?rtl8187_lptx_isr:rtl8187_nptx_isr, dev);
++
++ } else {
++ //printk(KERN_WARNING "Tx packet use by submit urb!\n");
++ /* FIXME check what EP is for low/norm PRI */
++ usb_fill_bulk_urb(tx_urb,priv->udev,
++ usb_sndbulkpipe(priv->udev,priority), tx,
++ urb_len, TXISR_SELECT(priority), dev);
++ }
++
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
++ status = usb_submit_urb(tx_urb, GFP_ATOMIC);
++#else
++ status = usb_submit_urb(tx_urb);
++#endif
++
++ if (!status){
++ //atomic_inc((priority == NORM_PRIORITY)? &priv->tx_np_pending : &priv->tx_lp_pending);
++ atomic_inc(&priv->tx_pending[priority]);
++ dev->trans_start = jiffies;
++ //printk("=====> tx_pending[%d]=%d\n", priority, atomic_read(&priv->tx_pending[priority]));
++ return 0;
++ }else{
++ DMESGE("Error TX URB %d, error pending %d",
++ //atomic_read((priority == NORM_PRIORITY)? &priv->tx_np_pending : &priv->tx_lp_pending),
++ atomic_read(&priv->tx_pending[priority]),
++ status);
++ return -1;
++ }
++}
++
++ short rtl8187_usb_initendpoints(struct net_device *dev)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ priv->rx_urb = (struct urb**) kmalloc (sizeof(struct urb*) * (MAX_RX_URB+1), GFP_KERNEL);
++
++ memset(priv->rx_urb, 0, sizeof(struct urb*) * MAX_RX_URB);
++
++#ifdef JACKSON_NEW_RX
++ priv->pp_rxskb = (struct sk_buff **)kmalloc(sizeof(struct sk_buff *) * MAX_RX_URB, GFP_KERNEL);
++ if (priv->pp_rxskb == NULL)
++ goto destroy;
++
++ memset(priv->pp_rxskb, 0, sizeof(struct sk_buff*) * MAX_RX_URB);
++#endif
++#ifdef THOMAS_BEACON
++ {
++ int align;
++ unsigned long oldaddr,newaddr; //lzm mod for 64bit cpu crash 20081107
++ priv->rx_urb[MAX_RX_URB] = usb_alloc_urb(0, GFP_KERNEL);
++ priv->oldaddr = kmalloc(16, GFP_KERNEL);
++ oldaddr = (unsigned long)priv->oldaddr;
++ align = oldaddr&3;
++ if(align != 0 ){
++ newaddr = oldaddr + 4 - align;
++ priv->rx_urb[MAX_RX_URB]->transfer_buffer_length = 16-4+align;
++ }
++ else{
++ newaddr = oldaddr;
++ priv->rx_urb[MAX_RX_URB]->transfer_buffer_length = 16;
++ }
++ priv->rx_urb[MAX_RX_URB]->transfer_buffer = (u32*)newaddr;
++ }
++#endif
++
++
++ goto _middle;
++
++
++destroy:
++
++#ifdef JACKSON_NEW_RX
++ if (priv->pp_rxskb) {
++ kfree(priv->pp_rxskb);
++ priv->pp_rxskb = NULL;
++
++ }
++#endif
++ if (priv->rx_urb) {
++ kfree(priv->rx_urb);
++ }
++ priv->rx_urb = NULL;
++
++ DMESGE("Endpoint Alloc Failure");
++ return -ENOMEM;
++
++
++_middle:
++
++ return 0;
++
++}
++#ifdef THOMAS_BEACON
++void rtl8187_usb_deleteendpoints(struct net_device *dev)
++{
++ int i;
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ if( in_interrupt() )
++ printk(KERN_ALERT " %ld in interrupt \n",in_interrupt() );
++ if(priv->rx_urb){
++ for(i=0;i<(MAX_RX_URB+1);i++){
++ if(priv->rx_urb[i]) {
++ usb_kill_urb(priv->rx_urb[i]);
++ usb_free_urb(priv->rx_urb[i]);
++ }
++ }
++ kfree(priv->rx_urb);
++ priv->rx_urb = NULL;
++ }
++ if(priv->oldaddr){
++ kfree(priv->oldaddr);
++ priv->oldaddr = NULL;
++ }
++ if (priv->pp_rxskb) {
++ kfree(priv->pp_rxskb);
++ priv->pp_rxskb = 0;
++ }
++}
++#endif
++
++void rtl8187_set_rate(struct net_device *dev)
++{
++ int i;
++ u16 word;
++ int basic_rate,min_rr_rate,max_rr_rate;
++
++ //if (ieee80211_is_54g(priv->ieee80211->current_network) &&
++ // priv->ieee80211->state == IEEE80211_LINKED){
++ basic_rate = ieeerate2rtlrate(240);
++ min_rr_rate = ieeerate2rtlrate(60);
++ max_rr_rate = ieeerate2rtlrate(240);
++
++ /*
++ }else{
++ basic_rate = ieeerate2rtlrate(20);
++ min_rr_rate = ieeerate2rtlrate(10);
++ max_rr_rate = ieeerate2rtlrate(110);
++ }
++ */
++
++ write_nic_byte(dev, RESP_RATE,
++ max_rr_rate<<MAX_RESP_RATE_SHIFT| min_rr_rate<<MIN_RESP_RATE_SHIFT);
++
++ //word = read_nic_word(dev, BRSR);
++ word = read_nic_word(dev, BRSR_8187);
++ word &= ~BRSR_MBR_8185;
++
++
++ for(i=0;i<=basic_rate;i++)
++ word |= (1<<i);
++
++ //write_nic_word(dev, BRSR, word);
++ write_nic_word(dev, BRSR_8187, word);
++}
++
++
++void rtl8187_link_change(struct net_device *dev)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ //write_nic_word(dev, BintrItv, net->beacon_interval);
++ rtl8187_net_update(dev);
++ /*update timing params*/
++ rtl8180_set_chan(dev, priv->chan);
++ rtl8187_set_rxconf(dev);
++}
++
++#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
++void rtl8180_wmm_param_update(struct work_struct* work)
++{
++ struct ieee80211_device * ieee = container_of(work, struct ieee80211_device,wmm_param_update_wq);
++ struct net_device *dev = ieee->dev;
++ struct r8180_priv *priv = ieee80211_priv(dev);
++#else
++void rtl8180_wmm_param_update(struct ieee80211_device *ieee)
++{
++ struct net_device *dev = ieee->dev;
++ struct r8180_priv *priv = ieee80211_priv(dev);
++#endif
++ u8 *ac_param = (u8 *)(ieee->current_network.wmm_param);
++ u8 mode = ieee->current_network.mode;
++ AC_CODING eACI;
++ AC_PARAM AcParam;
++ PAC_PARAM pAcParam;
++ u8 i;
++
++ //8187 need not to update wmm param, added by David, 2006.9.8
++ if(NIC_8187 == priv->card_8187) {
++ return;
++ }
++
++ if(!ieee->current_network.QoS_Enable)
++ {
++ //legacy ac_xx_param update
++
++ AcParam.longData = 0;
++ AcParam.f.AciAifsn.f.AIFSN = 2; // Follow 802.11 DIFS.
++ AcParam.f.AciAifsn.f.ACM = 0;
++ AcParam.f.Ecw.f.ECWmin = 3; // Follow 802.11 CWmin.
++ AcParam.f.Ecw.f.ECWmax = 7; // Follow 802.11 CWmax.
++ AcParam.f.TXOPLimit = 0;
++ for(eACI = 0; eACI < AC_MAX; eACI++)
++ {
++ AcParam.f.AciAifsn.f.ACI = (u8)eACI;
++ {
++ u8 u1bAIFS;
++ u32 u4bAcParam;
++
++
++ pAcParam = (PAC_PARAM)(&AcParam);
++ // Retrive paramters to udpate.
++ u1bAIFS = pAcParam->f.AciAifsn.f.AIFSN *(((mode&IEEE_G) == IEEE_G)?9:20) + aSifsTime;
++ u4bAcParam = ((((u32)(pAcParam->f.TXOPLimit)) << AC_PARAM_TXOP_LIMIT_OFFSET) |
++ (((u32)(pAcParam->f.Ecw.f.ECWmax)) << AC_PARAM_ECW_MAX_OFFSET) |
++ (((u32)(pAcParam->f.Ecw.f.ECWmin)) << AC_PARAM_ECW_MIN_OFFSET) |
++ (((u32)u1bAIFS) << AC_PARAM_AIFS_OFFSET));
++
++ switch(eACI)
++ {
++ case AC1_BK:
++ write_nic_dword(dev, AC_BK_PARAM, u4bAcParam);
++ break;
++
++ case AC0_BE:
++ write_nic_dword(dev, AC_BE_PARAM, u4bAcParam);
++ break;
++
++ case AC2_VI:
++ write_nic_dword(dev, AC_VI_PARAM, u4bAcParam);
++ break;
++
++ case AC3_VO:
++ write_nic_dword(dev, AC_VO_PARAM, u4bAcParam);
++ break;
++
++ default:
++ printk(KERN_WARNING "SetHwReg8185(): invalid ACI: %d !\n", eACI);
++ break;
++ }
++ }
++ }
++
++ return;
++ }
++ //
++ for(i = 0; i < AC_MAX; i++){
++ pAcParam = (AC_PARAM * )ac_param;
++ {
++ AC_CODING eACI;
++ u8 u1bAIFS;
++ u32 u4bAcParam;
++
++ // Retrive paramters to udpate.
++ eACI = pAcParam->f.AciAifsn.f.ACI;
++ //Mode G/A: slotTimeTimer = 9; Mode B: 20
++ u1bAIFS = pAcParam->f.AciAifsn.f.AIFSN * (((mode&IEEE_G) == IEEE_G)?9:20) + aSifsTime;
++ u4bAcParam = ((((u32)(pAcParam->f.TXOPLimit)) << AC_PARAM_TXOP_LIMIT_OFFSET) |
++ (((u32)(pAcParam->f.Ecw.f.ECWmax)) << AC_PARAM_ECW_MAX_OFFSET) |
++ (((u32)(pAcParam->f.Ecw.f.ECWmin)) << AC_PARAM_ECW_MIN_OFFSET) |
++ (((u32)u1bAIFS) << AC_PARAM_AIFS_OFFSET));
++
++ switch(eACI)
++ {
++ case AC1_BK:
++ write_nic_dword(dev, AC_BK_PARAM, u4bAcParam);
++ //printk(KERN_WARNING "[%04x]:0x%08x\n",AC_BK_PARAM,read_nic_dword(dev, AC_BK_PARAM));
++ break;
++
++ case AC0_BE:
++ write_nic_dword(dev, AC_BE_PARAM, u4bAcParam);
++ //printk(KERN_WARNING "[%04x]:0x%08x\n",AC_BE_PARAM,read_nic_dword(dev, AC_BE_PARAM));
++ break;
++
++ case AC2_VI:
++ write_nic_dword(dev, AC_VI_PARAM, u4bAcParam);
++ //printk(KERN_WARNING "[%04x]:0x%08x\n",AC_VI_PARAM,read_nic_dword(dev, AC_VI_PARAM));
++ break;
++
++ case AC3_VO:
++ write_nic_dword(dev, AC_VO_PARAM, u4bAcParam);
++ //printk(KERN_WARNING "[%04x]:0x%08x\n",AC_VO_PARAM,read_nic_dword(dev, AC_VO_PARAM));
++ break;
++
++ default:
++ printk(KERN_WARNING "SetHwReg8185(): invalid ACI: %d !\n", eACI);
++ break;
++ }
++ }
++ ac_param += (sizeof(AC_PARAM));
++ }
++}
++
++int IncludedInSupportedRates(struct r8180_priv *priv, u8 TxRate )
++{
++ u8 rate_len;
++ u8 rate_ex_len;
++ u8 RateMask = 0x7F;
++ u8 idx;
++ unsigned short Found = 0;
++ u8 NaiveTxRate = TxRate&RateMask;
++
++ rate_len = priv->ieee80211->current_network.rates_len;
++ rate_ex_len = priv->ieee80211->current_network.rates_ex_len;
++
++ for( idx=0; idx< rate_len; idx++ ){
++ if( (priv->ieee80211->current_network.rates[idx] & RateMask) == NaiveTxRate ) {
++ Found = 1;
++ goto found_rate;
++ }
++ }
++
++ for( idx=0; idx< rate_ex_len; idx++ ) {
++ if( (priv->ieee80211->current_network.rates_ex[idx] & RateMask) == NaiveTxRate ) {
++ Found = 1;
++ goto found_rate;
++ }
++ }
++
++ return Found;
++ found_rate:
++ return Found;
++}
++//
++// Description:
++// Get the Tx rate one degree up form the input rate in the supported rates.
++// Return the upgrade rate if it is successed, otherwise return the input rate.
++// By Bruce, 2007-06-05.
++//
++u8 GetUpgradeTxRate(struct net_device *dev, u8 rate)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ u8 UpRate;
++
++ // Upgrade 1 degree.
++ switch(rate)
++ {
++ case 108: // Up to 54Mbps.
++ UpRate = 108;
++ break;
++
++ case 96: // Up to 54Mbps.
++ UpRate = 108;
++ break;
++
++ case 72: // Up to 48Mbps.
++ UpRate = 96;
++ break;
++
++ case 48: // Up to 36Mbps.
++ UpRate = 72;
++ break;
++
++ case 36: // Up to 24Mbps.
++ UpRate = 48;
++ break;
++
++ case 22: // Up to 18Mbps.
++ UpRate = 36;
++ break;
++
++ case 11: // Up to 11Mbps.
++ UpRate = 22;
++ break;
++
++ case 4: // Up to 5.5Mbps.
++ UpRate = 11;
++ break;
++
++ case 2: // Up to 2Mbps.
++ UpRate = 4;
++ break;
++
++ default:
++ printk("GetUpgradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate);
++ return rate;
++ }
++ // Check if the rate is valid.
++ if(IncludedInSupportedRates(priv, UpRate))
++ {
++// printk("GetUpgradeTxRate(): GetUpgrade Tx rate(%d) from %d !\n", UpRate, priv->CurrentOperaRate);
++ return UpRate;
++ }
++ else
++ {
++ printk("GetUpgradeTxRate(): Tx rate (%d) is not in supported rates\n", UpRate);
++ return rate;
++ }
++ return rate;
++}
++//
++// Description:
++// Get the Tx rate one degree down form the input rate in the supported rates.
++// Return the degrade rate if it is successed, otherwise return the input rate.
++// By Bruce, 2007-06-05.
++//
++u8 GetDegradeTxRate( struct net_device *dev, u8 rate)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ u8 DownRate;
++
++ // Upgrade 1 degree.
++ switch(rate)
++ {
++ case 108: // Down to 48Mbps.
++ DownRate = 96;
++ break;
++
++ case 96: // Down to 36Mbps.
++ DownRate = 72;
++ break;
++
++ case 72: // Down to 24Mbps.
++ DownRate = 48;
++ break;
++
++ case 48: // Down to 18Mbps.
++ DownRate = 36;
++ break;
++
++ case 36: // Down to 11Mbps.
++ DownRate = 22;
++ break;
++
++ case 22: // Down to 5.5Mbps.
++ DownRate = 11;
++ break;
++
++ case 11: // Down to 2Mbps.
++ DownRate = 4;
++ break;
++
++ case 4: // Down to 1Mbps.
++ DownRate = 2;
++ break;
++
++ case 2: // Down to 1Mbps.
++ DownRate = 2;
++ break;
++
++ default:
++ printk("GetDegradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate);
++ return rate;
++ }
++ // Check if the rate is valid.
++ if(IncludedInSupportedRates(priv, DownRate)){
++// printk("GetDegradeTxRate(): GetDegrade Tx rate(%d) from %d!\n", DownRate, priv->CurrentOperaRate);
++ return DownRate;
++ }else{
++ printk("GetDegradeTxRate(): Tx rate (%d) is not in supported rates\n", DownRate);
++ return rate;
++ }
++ return rate;
++}
++
++//
++// Helper function to determine if specified data rate is
++// CCK rate.
++// 2005.01.25, by rcnjko.
++//
++bool MgntIsCckRate(u16 rate )
++{
++ bool bReturn = false;
++
++ if((rate <= 22) && (rate != 12) && (rate != 18)){
++ bReturn = true;
++ }
++
++ return bReturn;
++}
++//by amy for rate adaptive
++//
++// Description:
++// Core logic to adjust Tx data rate in STA mode according to
++// OFDM retry count ratio.
++//
++// Note:
++// RTL8187 : pHalData->CurrRetryCnt = TallyCnt
++// RTL8187B : pHalData->CurrRetryCnt = PktRetryCnt in TxClosedCommand
++//
++void sta_rateadaptive8187B(struct net_device *dev)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ unsigned long CurrTxokCnt;
++ u16 CurrRetryCnt;
++ u16 CurrRetryRate;
++ unsigned long CurrRxokCnt;
++ bool bTryUp = false;
++ bool bTryDown = false;
++ u8 TryUpTh = 1;
++ u8 TryDownTh = 2;
++ u32 TxThroughput;
++ long CurrSignalStrength;
++ bool bUpdateInitialGain = false;
++ CurrRetryCnt = priv->CurrRetryCnt;
++ CurrTxokCnt = (priv->stats.txbeaconokint + priv->stats.txmanageokint +
++ priv->stats.txvookint + priv->stats.txviokint + priv->stats.txbeokint)- priv->LastTxokCnt;
++ CurrRxokCnt = priv->stats.rxok - priv->LastRxokCnt;
++ CurrSignalStrength = priv->RecvSignalPower;
++ TxThroughput = (u32)(priv->txokbytestotal - priv->LastTxOKBytes);
++ priv->LastTxOKBytes = priv->txokbytestotal;
++ priv->CurrentOperaRate = priv->ieee80211->rate / 5;
++ //printk("priv->CurrentOperaRate is %d\n",priv->CurrentOperaRate);
++
++#if 1
++ //2 Compute retry ratio.
++ if (CurrTxokCnt>0)
++ {
++ CurrRetryRate = (u16)(CurrRetryCnt*100/CurrTxokCnt);
++ }
++ else
++ { // It may be serious retry. To distinguish serious retry or no packets modified by Bruce
++ CurrRetryRate = (u16)(CurrRetryCnt*100/1);
++ }
++#endif
++
++
++ //printk("\n(1) priv->LastRetryRate: %d \n",priv->LastRetryRate);
++ //printk("(2) CurrRetryCnt = %d \n", CurrRetryCnt);
++ //printk("(3) TxokCnt = %d \n", CurrTxokCnt);
++ //printk("(4) CurrRetryRate = %d \n", CurrRetryRate);
++ //printk("(5) SignalStrength = %d \n",priv->RecvSignalPower);
++
++ priv->LastRetryCnt = priv->CurrRetryCnt;
++ priv->LastTxokCnt = (priv->stats.txbeaconokint + priv->stats.txmanageokint +
++ priv->stats.txvookint + priv->stats.txviokint + priv->stats.txbeokint);
++ priv->LastRxokCnt = priv->stats.rxok;
++ priv->CurrRetryCnt = 0;
++ //2No Tx packets, return to init_rate or not?
++ if (CurrRetryRate==0 && CurrTxokCnt == 0)
++ {
++ //
++ // 2007.04.09, by Roger. after 4.5 seconds in this condition, we try to raise rate.
++ //
++ priv->TryupingCountNoData++;
++
++ //printk("No Tx packets, TryupingCountNoData(%d)\n", priv->TryupingCountNoData);
++ //printk("(6) priv->CurrentOperaRate =%d\n", priv->CurrentOperaRate);
++
++ if (priv->TryupingCountNoData>15)
++ {
++ priv->TryupingCountNoData = 0;
++ priv->CurrentOperaRate = GetUpgradeTxRate(dev, priv->CurrentOperaRate);
++ // Reset Fail Record
++ priv->LastFailTxRate = 0;
++ priv->LastFailTxRateSS = -200;
++ priv->FailTxRateCount = 0;
++ }
++ goto SetInitialGain;
++ }
++ else
++ {
++ priv->TryupingCountNoData=0; //Reset trying up times.
++ }
++
++ //
++ // For Netgear case, I comment out the following signal strength estimation,
++ // which can results in lower rate to transmit when sample is NOT enough (e.g. PING request).
++ // 2007.04.09, by Roger.
++ //
++#if 1
++ // If sample is not enough, we use signalstrength.
++ if ( CurrTxokCnt<10|| CurrRetryCnt<10)
++ {
++ //printk("Sample is not enough, we use signalstrength for rate adaptive\n");
++ //After 3 sec, and trying up.
++ priv->TryupingCountNoData++;
++ if (priv->TryupingCountNoData>10)
++ {
++ //printk("Sample is not enough and After 3 sec try up\n");
++ priv->TryupingCountNoData=0;
++
++ //
++ // Added by Roger, 2007.01.04.
++ // Signal strength plus 3 for air link.
++ //
++
++ if ( CurrSignalStrength>-68 )//&& IncludedInSupportedRates(Adapter, 108) )
++ {
++ priv->ieee80211->rate = 540;
++ //pMgntInfo->CurrentOperaRate = 108;
++ }
++ else if (CurrSignalStrength>-70)// && IncludedInSupportedRates(Adapter, 96) )
++ {
++ priv->ieee80211->rate = 480;
++ //pMgntInfo->CurrentOperaRate = 96;
++ }
++ else if (CurrSignalStrength>-73)// && IncludedInSupportedRates(Adapter, 72) )
++ {
++ priv->ieee80211->rate = 360;
++ //pMgntInfo->CurrentOperaRate = 72;
++ }
++ else if (CurrSignalStrength>-79)// && IncludedInSupportedRates(Adapter, 48) )
++ {
++ priv->ieee80211->rate = 240;
++ //pMgntInfo->CurrentOperaRate = 48;
++ }
++ else if (CurrSignalStrength>-81)// && IncludedInSupportedRates(Adapter, 36) )
++ {
++ priv->ieee80211->rate = 180;
++ //pMgntInfo->CurrentOperaRate = 36;
++ }
++ else if (CurrSignalStrength>-83)// && IncludedInSupportedRates(Adapter, 22) )
++ {
++ priv->ieee80211->rate = 110;
++ //pMgntInfo->CurrentOperaRate = 22;
++ }
++ else if (CurrSignalStrength>-85)// && IncludedInSupportedRates(Adapter, 11) )
++ {
++ priv->ieee80211->rate = 55;
++ //pMgntInfo->CurrentOperaRate = 11;
++ }
++ else if (CurrSignalStrength>-89)// && IncludedInSupportedRates(Adapter, 4) )
++ {
++ priv->ieee80211->rate = 20;
++ //pMgntInfo->CurrentOperaRate = 4;
++ }
++
++
++ }
++
++ //2004.12.23 skip record for 0
++ //pHalData->LastRetryRate = CurrRetryRate;
++ //printk("pMgntInfo->CurrentOperaRate =%d\n",priv->ieee80211->rate);
++ return;
++ }
++ else
++ {
++ priv->TryupingCountNoData=0;
++ }
++#endif
++ //
++ // Restructure rate adaptive as the following main stages:
++ // (1) Add retry threshold in 54M upgrading condition with signal strength.
++ // (2) Add the mechanism to degrade to CCK rate according to signal strength
++ // and retry rate.
++ // (3) Remove all Initial Gain Updates over OFDM rate. To avoid the complicated
++ // situation, Initial Gain Update is upon on DIG mechanism except CCK rate.
++ // (4) Add the mehanism of trying to upgrade tx rate.
++ // (5) Record the information of upping tx rate to avoid trying upping tx rate constantly.
++ // By Bruce, 2007-06-05.
++ //
++ //
++
++ // 11Mbps or 36Mbps
++ // Check more times in these rate(key rates).
++ //
++ if(priv->CurrentOperaRate == 22 || priv->CurrentOperaRate == 72)
++ {
++ TryUpTh += 9;
++ }
++ //
++ // Let these rates down more difficult.
++ //
++ if(MgntIsCckRate(priv->CurrentOperaRate) || priv->CurrentOperaRate == 36)
++ {
++ TryDownTh += 1;
++ }
++
++ //1 Adjust Rate.
++ if (priv->bTryuping == true)
++ {
++ //2 For Test Upgrading mechanism
++ // Note:
++ // Sometimes the throughput is upon on the capability bwtween the AP and NIC,
++ // thus the low data rate does not improve the performance.
++ // We randomly upgrade the data rate and check if the retry rate is improved.
++
++ // Upgrading rate did not improve the retry rate, fallback to the original rate.
++ if ( (CurrRetryRate > 25) && TxThroughput < priv->LastTxThroughput)
++ {
++ //Not necessary raising rate, fall back rate.
++ bTryDown = true;
++ //printk("Not necessary raising rate, fall back rate....\n");
++ //printk("(7) priv->CurrentOperaRate =%d, TxThroughput = %d, LastThroughput = %d\n",
++ // priv->CurrentOperaRate, TxThroughput, priv->LastTxThroughput);
++ }
++ else
++ {
++ priv->bTryuping = false;
++ }
++ }
++ else if (CurrSignalStrength > -51 && (CurrRetryRate < 100))
++ {
++ //2For High Power
++ //
++ // Added by Roger, 2007.04.09.
++ // Return to highest data rate, if signal strength is good enough.
++ // SignalStrength threshold(-50dbm) is for RTL8186.
++ // Revise SignalStrength threshold to -51dbm.
++ //
++ // Also need to check retry rate for safety, by Bruce, 2007-06-05.
++ if(priv->CurrentOperaRate != 108)
++ {
++ bTryUp = true;
++ // Upgrade Tx Rate directly.
++ priv->TryupingCount += TryUpTh;
++ //printk("StaRateAdaptive87B: Power(%d) is high enough!!. \n", CurrSignalStrength);
++ }
++ }
++ // To avoid unstable rate jumping, comment out this condition, by Bruce, 2007-06-26.
++ /*
++ else if(CurrSignalStrength < -86 && CurrRetryRate >= 100)
++ {
++ //2 For Low Power
++ //
++ // Low signal strength and high current tx rate may cause Tx rate to degrade too slowly.
++ // Update Tx rate to CCK rate directly.
++ // By Bruce, 2007-06-05.
++ //
++ if(!MgntIsCckRate(pMgntInfo->CurrentOperaRate))
++ {
++ if(CurrSignalStrength > -88 && IncludedInSupportedRates(Adapter, 22)) // 11M
++ pMgntInfo->CurrentOperaRate = 22;
++ else if(CurrSignalStrength > -90 && IncludedInSupportedRates(Adapter, 11)) // 5.5M
++ pMgntInfo->CurrentOperaRate = 11;
++ else if(CurrSignalStrength > -92 && IncludedInSupportedRates(Adapter, 4)) // 2M
++ pMgntInfo->CurrentOperaRate = 4;
++ else // 1M
++ pMgntInfo->CurrentOperaRate = 2;
++ }
++ else if(CurrRetryRate >= 200)
++ {
++ pMgntInfo->CurrentOperaRate = GetDegradeTxRate(Adapter, pMgntInfo->CurrentOperaRate);
++ }
++ RT_TRACE(COMP_RATE, DBG_LOUD, ("RA: Low Power(%d), or High Retry Rate(%d), set rate to CCK rate (%d). \n",
++ CurrSignalStrength, CurrRetryRate, pMgntInfo->CurrentOperaRate));
++ bUpdateInitialGain = TRUE;
++ // Reset Fail Record
++ pHalData->LastFailTxRate = 0;
++ pHalData->LastFailTxRateSS = -200;
++ pHalData->FailTxRateCount = 0;
++ goto SetInitialGain;
++ }
++ */
++ else if(CurrTxokCnt< 100 && CurrRetryRate >= 600)
++ {
++ //2 For Serious Retry
++ //
++ // Traffic is not busy but our Tx retry is serious.
++ //
++ bTryDown = true;
++ // Let Rate Mechanism to degrade tx rate directly.
++ priv->TryDownCountLowData += TryDownTh;
++ //printk("RA: Tx Retry is serious. Degrade Tx Rate to %d directly...\n", priv->CurrentOperaRate);
++ }
++ else if ( priv->CurrentOperaRate == 108 )
++ {
++ //2For 54Mbps
++ // if ( (CurrRetryRate>38)&&(pHalData->LastRetryRate>35))
++ if ( (CurrRetryRate>33)&&(priv->LastRetryRate>32))
++ {
++ //(30,25) for cable link threshold. (38,35) for air link.
++ //Down to rate 48Mbps.
++ bTryDown = true;
++ }
++ }
++ else if ( priv->CurrentOperaRate == 96 )
++ {
++ //2For 48Mbps
++ // if ( ((CurrRetryRate>73) && (pHalData->LastRetryRate>72)) && IncludedInSupportedRates(Adapter, 72) )
++ if ( ((CurrRetryRate>48) && (priv->LastRetryRate>47)))
++ {
++ //(73, 72) for temp used.
++ //(25, 23) for cable link, (60,59) for air link.
++ //CurrRetryRate plus 25 and 26 respectively for air link.
++ //Down to rate 36Mbps.
++ bTryDown = true;
++ }
++ else if ( (CurrRetryRate<8) && (priv->LastRetryRate<8) ) //TO DO: need to consider (RSSI)
++ {
++ bTryUp = true;
++ }
++ }
++ else if ( priv->CurrentOperaRate == 72 )
++ {
++ //2For 36Mbps
++ //if ( (CurrRetryRate>97) && (pHalData->LastRetryRate>97))
++ if ( (CurrRetryRate>55) && (priv->LastRetryRate>54))
++ {
++ //(30,25) for cable link threshold respectively. (103,10) for air link respectively.
++ //CurrRetryRate plus 65 and 69 respectively for air link threshold.
++ //Down to rate 24Mbps.
++ bTryDown = true;
++ }
++ // else if ( (CurrRetryRate<20) && (pHalData->LastRetryRate<20) && IncludedInSupportedRates(Adapter, 96) )//&& (device->LastRetryRate<15) ) //TO DO: need to consider (RSSI)
++ else if ( (CurrRetryRate<15) && (priv->LastRetryRate<16))//&& (device->LastRetryRate<15) ) //TO DO: need to consider (RSSI)
++ {
++ bTryUp = true;
++ }
++ }
++ else if ( priv->CurrentOperaRate == 48 )
++ {
++ //2For 24Mbps
++ // if ( ((CurrRetryRate>119) && (pHalData->LastRetryRate>119) && IncludedInSupportedRates(Adapter, 36)))
++ if ( ((CurrRetryRate>63) && (priv->LastRetryRate>62)))
++ {
++ //(15,15) for cable link threshold respectively. (119, 119) for air link threshold.
++ //Plus 84 for air link threshold.
++ //Down to rate 18Mbps.
++ bTryDown = true;
++ }
++ // else if ( (CurrRetryRate<14) && (pHalData->LastRetryRate<15) && IncludedInSupportedRates(Adapter, 72)) //TO DO: need to consider (RSSI)
++ else if ( (CurrRetryRate<20) && (priv->LastRetryRate<21)) //TO DO: need to consider (RSSI)
++ {
++ bTryUp = true;
++ }
++ }
++ else if ( priv->CurrentOperaRate == 36 )
++ {
++ //2For 18Mbps
++ if ( ((CurrRetryRate>109) && (priv->LastRetryRate>109)))
++ {
++ //(99,99) for cable link, (109,109) for air link.
++ //Down to rate 11Mbps.
++ bTryDown = true;
++ }
++ // else if ( (CurrRetryRate<15) && (pHalData->LastRetryRate<16) && IncludedInSupportedRates(Adapter, 48)) //TO DO: need to consider (RSSI)
++ else if ( (CurrRetryRate<25) && (priv->LastRetryRate<26)) //TO DO: need to consider (RSSI)
++ {
++ bTryUp = true;
++ }
++ }
++ else if ( priv->CurrentOperaRate == 22 )
++ {
++ //2For 11Mbps
++ // if (CurrRetryRate>299 && IncludedInSupportedRates(Adapter, 11))
++ if (CurrRetryRate>95)
++ {
++ bTryDown = true;
++ }
++ else if (CurrRetryRate<55)//&& (device->LastRetryRate<55) ) //TO DO: need to consider (RSSI)
++ {
++ bTryUp = true;
++ }
++ }
++ else if ( priv->CurrentOperaRate == 11 )
++ {
++ //2For 5.5Mbps
++ // if (CurrRetryRate>159 && IncludedInSupportedRates(Adapter, 4) )
++ if (CurrRetryRate>149)
++ {
++ bTryDown = true;
++ }
++ // else if ( (CurrRetryRate<30) && (pHalData->LastRetryRate<30) && IncludedInSupportedRates(Adapter, 22) )
++ else if ( (CurrRetryRate<60) && (priv->LastRetryRate < 65))
++ {
++ bTryUp = true;
++ }
++ }
++ else if ( priv->CurrentOperaRate == 4 )
++ {
++ //2For 2 Mbps
++ if((CurrRetryRate>99) && (priv->LastRetryRate>99))
++ {
++ bTryDown = true;
++ }
++ // else if ( (CurrRetryRate<50) && (pHalData->LastRetryRate<65) && IncludedInSupportedRates(Adapter, 11) )
++ else if ( (CurrRetryRate < 65) && (priv->LastRetryRate < 70))
++ {
++ bTryUp = true;
++ }
++ }
++ else if ( priv->CurrentOperaRate == 2 )
++ {
++ //2For 1 Mbps
++ // if ( (CurrRetryRate<50) && (pHalData->LastRetryRate<65) && IncludedInSupportedRates(Adapter, 4))
++ if ( (CurrRetryRate<70) && (priv->LastRetryRate<75))
++ {
++ bTryUp = true;
++ }
++ }
++ if(bTryUp && bTryDown)
++ printk("StaRateAdaptive87B(): Tx Rate tried upping and downing simultaneously!\n");
++
++ //1 Test Upgrading Tx Rate
++ // Sometimes the cause of the low throughput (high retry rate) is the compatibility between the AP and NIC.
++ // To test if the upper rate may cause lower retry rate, this mechanism randomly occurs to test upgrading tx rate.
++ if(!bTryUp && !bTryDown && (priv->TryupingCount == 0) && (priv->TryDownCountLowData == 0)
++ && priv->CurrentOperaRate != 108 && priv->FailTxRateCount < 2)
++ {
++#if 1
++ if(jiffies% (CurrRetryRate + 101) == 0)
++ {
++ bTryUp = true;
++ priv->bTryuping = true;
++ printk("======================================================>StaRateAdaptive87B(): Randomly try upgrading...\n");
++ }
++#endif
++ }
++ //1 Rate Mechanism
++ if(bTryUp)
++ {
++ priv->TryupingCount++;
++ priv->TryDownCountLowData = 0;
++
++ //
++ // Check more times if we need to upgrade indeed.
++ // Because the largest value of pHalData->TryupingCount is 0xFFFF and
++ // the largest value of pHalData->FailTxRateCount is 0x14,
++ // this condition will be satisfied at most every 2 min.
++ //
++ if((priv->TryupingCount > (TryUpTh + priv->FailTxRateCount * priv->FailTxRateCount)) ||
++ (CurrSignalStrength > priv->LastFailTxRateSS) || priv->bTryuping)
++ {
++ priv->TryupingCount = 0;
++ //
++ // When transfering from CCK to OFDM, DIG is an important issue.
++ //
++ if(priv->CurrentOperaRate == 22)
++ bUpdateInitialGain = true;
++ // (1)To avoid upgrade frequently to the fail tx rate, add the FailTxRateCount into the threshold.
++ // (2)If the signal strength is increased, it may be able to upgrade.
++ priv->CurrentOperaRate = GetUpgradeTxRate(dev, priv->CurrentOperaRate);
++ //printk("StaRateAdaptive87B(): Upgrade Tx Rate to %d\n", priv->CurrentOperaRate);
++
++ // Update Fail Tx rate and count.
++ if(priv->LastFailTxRate != priv->CurrentOperaRate)
++ {
++ priv->LastFailTxRate = priv->CurrentOperaRate;
++ priv->FailTxRateCount = 0;
++ priv->LastFailTxRateSS = -200; // Set lowest power.
++ }
++ }
++ }
++ else
++ {
++ if(priv->TryupingCount > 0)
++ priv->TryupingCount --;
++ }
++
++ if(bTryDown)
++ {
++ priv->TryDownCountLowData++;
++ priv->TryupingCount = 0;
++
++
++ //Check if Tx rate can be degraded or Test trying upgrading should fallback.
++ if(priv->TryDownCountLowData > TryDownTh || priv->bTryuping)
++ {
++ priv->TryDownCountLowData = 0;
++ priv->bTryuping = false;
++ // Update fail information.
++ if(priv->LastFailTxRate == priv->CurrentOperaRate)
++ {
++ priv->FailTxRateCount ++;
++ // Record the Tx fail rate signal strength.
++ if(CurrSignalStrength > priv->LastFailTxRateSS)
++ {
++ priv->LastFailTxRateSS = CurrSignalStrength;
++ }
++ }
++ else
++ {
++ priv->LastFailTxRate = priv->CurrentOperaRate;
++ priv->FailTxRateCount = 1;
++ priv->LastFailTxRateSS = CurrSignalStrength;
++ }
++ priv->CurrentOperaRate = GetDegradeTxRate(dev, priv->CurrentOperaRate);
++ //
++ // When it is CCK rate, it may need to update initial gain to receive lower power packets.
++ //
++ if(MgntIsCckRate(priv->CurrentOperaRate))
++ {
++ bUpdateInitialGain = true;
++ }
++ //printk("StaRateAdaptive87B(): Degrade Tx Rate to %d\n", priv->CurrentOperaRate);
++ }
++ }
++ else
++ {
++ if(priv->TryDownCountLowData > 0)
++ priv->TryDownCountLowData --;
++ }
++ // Keep the Tx fail rate count to equal to 0x15 at most.
++ // Reduce the fail count at least to 10 sec if tx rate is tending stable.
++ if(priv->FailTxRateCount >= 0x15 ||
++ (!bTryUp && !bTryDown && priv->TryDownCountLowData == 0 && priv->TryupingCount && priv->FailTxRateCount > 0x6))
++ {
++ priv->FailTxRateCount --;
++ }
++
++ //
++ // We need update initial gain when we set tx rate "from OFDM to CCK" or
++ // "from CCK to OFDM".
++ //
++SetInitialGain:
++#if 1 //to be done
++ if(bUpdateInitialGain)
++ {
++ if(MgntIsCckRate(priv->CurrentOperaRate)) // CCK
++ {
++ if(priv->InitialGain > priv->RegBModeGainStage)
++ {
++ if(CurrSignalStrength < -85) // Low power, OFDM [0x17] = 26.
++ {
++ priv->InitialGain = priv->RegBModeGainStage;
++ }
++ else if(priv->InitialGain > priv->RegBModeGainStage + 1)
++ {
++ priv->InitialGain -= 2;
++ }
++ else
++ {
++ priv->InitialGain --;
++ }
++ UpdateInitialGain(dev);
++ }
++ }
++ else // OFDM
++ {
++ if(priv->InitialGain < 4)
++ {
++ priv->InitialGain ++;
++ UpdateInitialGain(dev);
++ }
++ }
++ }
++#endif
++ //Record the related info
++ priv->LastRetryRate = CurrRetryRate;
++ priv->LastTxThroughput = TxThroughput;
++ priv->ieee80211->rate = priv->CurrentOperaRate * 5;
++}
++
++#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
++void rtl8180_rate_adapter(struct work_struct * work)
++{
++ struct delayed_work *dwork = container_of(work,struct delayed_work,work);
++ struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,rate_adapter_wq);
++ struct net_device *dev = ieee->dev;
++#else
++void rtl8180_rate_adapter(struct net_device *dev)
++{
++
++#endif
++ sta_rateadaptive8187B(dev);
++}
++
++void timer_rate_adaptive(unsigned long data)
++{
++ struct r8180_priv* priv = ieee80211_priv((struct net_device *)data);
++ //DMESG("---->timer_rate_adaptive()\n");
++ if(!priv->up)
++ {
++ //DMESG("<----timer_rate_adaptive():driver is not up!\n");
++ return;
++ }
++ if( (priv->ieee80211->mode != IEEE_B) &&
++ (priv->ieee80211->iw_mode != IW_MODE_MASTER)
++ && ((priv->ieee80211->state == IEEE80211_LINKED)||(priv->ieee80211->state == IEEE80211_MESH_LINKED)))
++ {
++ //DMESG("timer_rate_adaptive():schedule rate_adapter_wq\n");
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
++ queue_delayed_work(priv->ieee80211->wq,&priv->ieee80211->rate_adapter_wq, 0);
++#else
++ queue_work(priv->ieee80211->wq,&priv->ieee80211->rate_adapter_wq);
++#endif
++ }
++
++ mod_timer(&priv->rateadapter_timer, jiffies + MSECS(DEFAULT_RATE_ADAPTIVE_TIMER_PERIOD));
++ //DMESG("<----timer_rate_adaptive()\n");
++}
++//by amy for rate adaptive
++
++
++void rtl8180_irq_rx_tasklet_new(struct r8180_priv *priv);
++void rtl8180_irq_rx_tasklet(struct r8180_priv *priv);
++
++//YJ,add,080828,for KeepAlive
++#if 0
++static void MgntLinkKeepAlive(struct r8180_priv *priv )
++{
++ if (priv->keepAliveLevel == 0)
++ return;
++
++ if(priv->ieee80211->state == IEEE80211_LINKED)
++ {
++ //
++ // Keep-Alive.
++ //
++ //printk("LastTx:%d Tx:%d LastRx:%d Rx:%ld Idle:%d\n",priv->link_detect.LastNumTxUnicast,priv->NumTxUnicast, priv->link_detect.LastNumRxUnicast, priv->ieee80211->NumRxUnicast, priv->link_detect.IdleCount);
++
++ if ( (priv->keepAliveLevel== 2) ||
++ (priv->link_detect.LastNumTxUnicast == priv->NumTxUnicast &&
++ priv->link_detect.LastNumRxUnicast == priv->ieee80211->NumRxUnicast )
++ )
++ {
++ priv->link_detect.IdleCount++;
++
++ //
++ // Send a Keep-Alive packet packet to AP if we had been idle for a while.
++ //
++ if(priv->link_detect.IdleCount >= ((KEEP_ALIVE_INTERVAL / CHECK_FOR_HANG_PERIOD)-1) )
++ {
++ priv->link_detect.IdleCount = 0;
++ ieee80211_sta_ps_send_null_frame(priv->ieee80211, false);
++ }
++ }
++ else
++ {
++ priv->link_detect.IdleCount = 0;
++ }
++ priv->link_detect.LastNumTxUnicast = priv->NumTxUnicast;
++ priv->link_detect.LastNumRxUnicast = priv->ieee80211->NumRxUnicast;
++ }
++}
++//YJ,add,080828,for KeepAlive,end
++#endif
++void InactivePowerSave(struct net_device *dev)
++{
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++
++ //
++ // This flag "bSwRfProcessing", indicates the status of IPS procedure, should be set if the IPS workitem
++ // is really scheduled.
++ // The old code, sets this flag before scheduling the IPS workitem and however, at the same time the
++ // previous IPS workitem did not end yet, fails to schedule the current workitem. Thus, bSwRfProcessing
++ // blocks the IPS procedure of switching RF.
++ // By Bruce, 2007-12-25.
++ //
++ priv->bSwRfProcessing = true;
++ MgntActSet_RF_State(dev, priv->eInactivePowerState, RF_CHANGE_BY_IPS);
++
++ //
++ // To solve CAM values miss in RF OFF, rewrite CAM values after RF ON. By Bruce, 2007-09-20.
++ //
++#if 0
++ while( index < 4 )
++ {
++ if( ( pMgntInfo->SecurityInfo.PairwiseEncAlgorithm == WEP104_Encryption ) ||
++ (pMgntInfo->SecurityInfo.PairwiseEncAlgorithm == WEP40_Encryption) )
++ {
++ if( pMgntInfo->SecurityInfo.KeyLen[index] != 0)
++ pAdapter->HalFunc.SetKeyHandler(pAdapter, index, 0, FALSE, pMgntInfo->SecurityInfo.PairwiseEncAlgorithm, TRUE, FALSE);
++
++ }
++ index++;
++ }
++#endif
++ priv->bSwRfProcessing = false;
++}
++
++//
++// Description:
++// Enter the inactive power save mode. RF will be off
++// 2007.08.17, by shien chang.
++//
++void IPSEnter(struct net_device *dev)
++{
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ RT_RF_POWER_STATE rtState;
++
++ if (priv->bInactivePs)
++ {
++ rtState = priv->eRFPowerState;
++
++ //
++ // Added by Bruce, 2007-12-25.
++ // Do not enter IPS in the following conditions:
++ // (1) RF is already OFF or Sleep
++ // (2) bSwRfProcessing (indicates the IPS is still under going)
++ // (3) Connectted (only disconnected can trigger IPS)
++ // (4) IBSS (send Beacon)
++ // (5) AP mode (send Beacon)
++ //
++ if (rtState == eRfOn && !priv->bSwRfProcessing && (priv->ieee80211->iw_mode != IW_MODE_ADHOC)
++ && (priv->ieee80211->state != IEEE80211_LINKED ))
++ {
++#ifdef CONFIG_RADIO_DEBUG
++ DMESG("IPSEnter(): Turn off RF.");
++#endif
++ priv->eInactivePowerState = eRfOff;
++ InactivePowerSave(dev);
++ //SetRFPowerState(dev, priv->eInactivePowerState);
++ //MgntActSet_RF_State(dev, priv->eInactivePowerState, RF_CHANGE_BY_IPS);
++ }
++ }
++ //printk("priv->eRFPowerState is %d\n",priv->eRFPowerState);
++}
++
++void IPSLeave(struct net_device *dev)
++{
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ RT_RF_POWER_STATE rtState;
++ if (priv->bInactivePs)
++ {
++ rtState = priv->eRFPowerState;
++ if (rtState == eRfOff && (!priv->bSwRfProcessing) && priv->RfOffReason <= RF_CHANGE_BY_IPS)
++ {
++#ifdef CONFIG_RADIO_DEBUG
++ DMESG("ISLeave(): Turn on RF.");
++#endif
++ priv->eInactivePowerState = eRfOn;
++ InactivePowerSave(dev);
++ }
++ }
++// printk("priv->eRFPowerState is %d\n",priv->eRFPowerState);
++}
++//by amy for power save
++
++//YJ,add,081230
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
++void IPSLeave_wq (struct work_struct *work)
++{
++ struct ieee80211_device *ieee = container_of(work,struct ieee80211_device,ips_leave_wq);
++ struct net_device *dev = ieee->dev;
++#else
++void IPSLeave_wq(struct net_device *dev)
++{
++#endif
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ down(&priv->ieee80211->ips_sem);
++ IPSLeave(dev);
++ up(&priv->ieee80211->ips_sem);
++}
++
++void ieee80211_ips_leave(struct net_device *dev)
++{
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ if(priv->bInactivePs){
++ if(priv->eRFPowerState == eRfOff)
++ {
++ //DMESG("%s", __FUNCTION__);
++ queue_work(priv->ieee80211->wq,&priv->ieee80211->ips_leave_wq);
++ }
++ }
++}
++//YJ,add,081230,end
++
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
++void rtl8180_watch_dog_wq (struct work_struct *work)
++{
++ struct delayed_work *dwork = container_of(work,struct delayed_work,work);
++ struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,watch_dog_wq);
++ struct net_device *dev = ieee->dev;
++#else
++void rtl8180_watch_dog_wq(struct net_device *dev)
++{
++#endif
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ //bool bEnterPS = false;
++ //bool bBusyTraffic = false;
++ u32 TotalRxNum = 0;
++ u16 SlotIndex = 0, i=0;
++ //YJ,add,080828,for link state check
++ if((priv->ieee80211->state == IEEE80211_LINKED) && (priv->ieee80211->iw_mode == IW_MODE_INFRA)){
++ SlotIndex = (priv->link_detect.SlotIndex++) % priv->link_detect.SlotNum;
++ priv->link_detect.RxFrameNum[SlotIndex] = priv->ieee80211->NumRxDataInPeriod + priv->ieee80211->NumRxBcnInPeriod;
++ for( i=0; i<priv->link_detect.SlotNum; i++ )
++ TotalRxNum+= priv->link_detect.RxFrameNum[i];
++#if 0 //for roaming temp del
++ if(TotalRxNum == 0){
++ priv->ieee80211->state = IEEE80211_ASSOCIATING;
++ printk("=========>turn to another AP\n");
++ queue_work(priv->ieee80211->wq, &priv->ieee80211->associate_procedure_wq);
++ }
++#endif
++ }
++ priv->link_detect.NumRxOkInPeriod = 0;
++ priv->link_detect.NumTxOkInPeriod = 0;
++ priv->ieee80211->NumRxDataInPeriod = 0;
++ priv->ieee80211->NumRxBcnInPeriod = 0;
++
++#ifdef CONFIG_IPS
++ if(priv->ieee80211->actscanning == false){
++ if((priv->ieee80211->iw_mode == IW_MODE_INFRA) &&
++ (priv->ieee80211->state == IEEE80211_NOLINK) &&
++ (priv->eRFPowerState == eRfOn))
++ {
++ //printk("actscanning:%d, state:%d, eRFPowerState:%d\n",
++ // priv->ieee80211->actscanning,
++ // priv->ieee80211->state,
++ // priv->eRFPowerState);
++
++ down(&priv->ieee80211->ips_sem);
++ IPSEnter(dev);
++ up(&priv->ieee80211->ips_sem);
++ }
++ }
++ //queue_delayed_work(priv->ieee80211->wq,&priv->ieee80211->watch_dog_wq,IEEE80211_WATCH_DOG_TIME);
++#endif
++
++ //printk("========================>leave rtl8180_watch_dog_wq()\n");
++}
++
++void watch_dog_adaptive(unsigned long data)
++{
++ struct net_device* dev = (struct net_device*)data;
++ struct r8180_priv* priv = ieee80211_priv(dev);
++ //DMESG("---->watch_dog_adaptive()\n");
++ if(!priv->up){
++ //DMESG("<----watch_dog_adaptive():driver is not up!\n");
++ return;
++ }
++ // Tx and Rx High Power Mechanism.
++ if(CheckHighPower(dev)){
++ //printk("===============================> high power!\n");
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
++ queue_delayed_work(priv->ieee80211->wq,&priv->ieee80211->tx_pw_wq, 0);
++#else
++ queue_work(priv->ieee80211->wq,&priv->ieee80211->tx_pw_wq);
++#endif
++ }
++
++ // Schedule an workitem to perform DIG
++ if(CheckDig(dev) == true){
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
++ queue_delayed_work(priv->ieee80211->wq,&priv->ieee80211->hw_dig_wq,0);
++#else
++ queue_work(priv->ieee80211->wq,&priv->ieee80211->hw_dig_wq);
++#endif
++ }
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
++ queue_delayed_work(priv->ieee80211->wq,&priv->ieee80211->watch_dog_wq,0);
++#else
++ queue_work(priv->ieee80211->wq,&priv->ieee80211->watch_dog_wq);
++#endif
++
++ mod_timer(&priv->watch_dog_timer, jiffies + MSECS(IEEE80211_WATCH_DOG_TIME));
++ //DMESG("<----watch_dog_adaptive()\n");
++}
++
++#ifdef ENABLE_DOT11D
++
++CHANNEL_LIST Current_tbl;
++
++static CHANNEL_LIST ChannelPlan[] = {
++ {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64},19}, //FCC
++ {{1,2,3,4,5,6,7,8,9,10,11},11}, //IC
++ {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //ETSI
++ {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //Spain. Change to ETSI.
++ {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //France. Change to ETSI.
++ {{14,36,40,44,48,52,56,60,64},9}, //MKK
++ {{1,2,3,4,5,6,7,8,9,10,11,12,13,14, 36,40,44,48,52,56,60,64},22},//MKK1
++ {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //Israel.
++ {{1,2,3,4,5,6,7,8,9,10,11,12,13,34,38,42,46},17}, // For 11a , TELEC
++ {{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14}, //For Global Domain. 1-11:active scan, 12-14 passive scan. //+YJ, 080626
++ {{1,2,3,4,5,6,7,8,9,10,11,12,13},13} //world wide 13: ch1~ch11 active scan, ch12~13 passive //lzm add 081205
++};
++
++static void rtl8180_set_channel_map(u8 channel_plan, struct ieee80211_device *ieee)
++{
++ int i;
++
++ //lzm add 081205
++ ieee->MinPassiveChnlNum=MAX_CHANNEL_NUMBER+1;
++ ieee->IbssStartChnl=0;
++
++ switch (channel_plan)
++ {
++ case COUNTRY_CODE_FCC:
++ case COUNTRY_CODE_IC:
++ case COUNTRY_CODE_ETSI:
++ case COUNTRY_CODE_SPAIN:
++ case COUNTRY_CODE_FRANCE:
++ case COUNTRY_CODE_MKK:
++ case COUNTRY_CODE_MKK1:
++ case COUNTRY_CODE_ISRAEL:
++ case COUNTRY_CODE_TELEC:
++ {
++ Dot11d_Init(ieee);
++ ieee->bGlobalDomain = false;
++ ieee->bWorldWide13 = false;
++ if (ChannelPlan[channel_plan].Len != 0){
++ // Clear old channel map
++ memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map));
++ // Set new channel map
++ for (i=0;i<ChannelPlan[channel_plan].Len;i++)
++ {
++ if(ChannelPlan[channel_plan].Channel[i] <= 14)
++ GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 1;
++ }
++ }
++ break;
++ }
++ case COUNTRY_CODE_GLOBAL_DOMAIN:
++ {
++ GET_DOT11D_INFO(ieee)->bEnabled = 0;
++ Dot11d_Reset(ieee);
++ ieee->bGlobalDomain = true;
++ ieee->bWorldWide13 = false;
++
++ //lzm add 081205
++ ieee->MinPassiveChnlNum=12;
++ ieee->IbssStartChnl= 10;
++
++ break;
++ }
++ case COUNTRY_CODE_WORLD_WIDE_13_INDEX://lzm add 081205
++ {
++ Dot11d_Init(ieee);
++ ieee->bGlobalDomain = false;
++ ieee->bWorldWide13 = true;
++
++ //lzm add 081205
++ ieee->MinPassiveChnlNum=12;
++ ieee->IbssStartChnl= 10;
++
++ if (ChannelPlan[channel_plan].Len != 0){
++ // Clear old channel map
++ memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map));
++ // Set new channel map
++ for (i=0;i<ChannelPlan[channel_plan].Len;i++)
++ {
++ if(ChannelPlan[channel_plan].Channel[i] <= 11)//ch1~ch11 active scan
++ GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 1;
++ else//ch12~13 passive scan
++ GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 2;
++ }
++ }
++
++ break;
++ }
++ default:
++ {
++ Dot11d_Init(ieee);
++ ieee->bGlobalDomain = false;
++ ieee->bWorldWide13 = false;
++ memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map));
++ for (i=1;i<=14;i++)
++ {
++ GET_DOT11D_INFO(ieee)->channel_map[i] = 1;
++ }
++ break;
++ }
++ }
++}
++#endif
++
++
++static void rtl8180_link_detect_init(plink_detect_t plink_detect)
++{
++ memset(plink_detect, 0, sizeof(link_detect_t));
++ plink_detect->SlotNum = DEFAULT_SLOT_NUM;
++}
++
++#ifdef SW_ANTE_DIVERSITY
++static void rtl8187_antenna_diversity_read(struct net_device *dev)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ u16 usValue;
++
++ //2 Read CustomerID
++ usValue = eprom_read(dev, EEPROM_SW_REVD_OFFSET>>1);
++ priv->EEPROMCustomerID = (u8)( usValue & EEPROM_CID_MASK );
++ //DMESG("EEPROM Customer ID: %02X\n", priv->EEPROMCustomerID);
++
++ //2 Read AntennaDiversity
++ // SW Antenna Diversity.
++ if( (usValue & EEPROM_SW_AD_MASK) != EEPROM_SW_AD_ENABLE ){
++ priv->EEPROMSwAntennaDiversity = false;
++ DMESG("EEPROM Disable SW Antenna Diversity");
++ }else{
++ priv->EEPROMSwAntennaDiversity = true;
++ DMESG("EEPROM Enable SW Antenna Diversity");
++ }
++ // Default Antenna to use.
++ if( (usValue & EEPROM_DEF_ANT_MASK) != EEPROM_DEF_ANT_1 ) {
++ priv->EEPROMDefaultAntenna1 = false;
++ DMESG("EEPROM Default Main Antenna 0");
++ }else{
++ priv->EEPROMDefaultAntenna1 = false;
++ DMESG( "EEPROM Default Aux Antenna 1");
++ }
++
++ //
++ // Antenna diversity mechanism. Added by Roger, 2007.11.05.
++ //
++ if( priv->RegSwAntennaDiversityMechanism == 0 ) // Auto //set it to 0 when init
++ {// 0: default from EEPROM.
++ priv->bSwAntennaDiverity = priv->EEPROMSwAntennaDiversity;
++ }else{// 1:disable antenna diversity, 2: enable antenna diversity.
++ priv->bSwAntennaDiverity = ((priv->RegSwAntennaDiversityMechanism == 1)? false : true);
++ }
++ //DMESG("bSwAntennaDiverity = %d\n", priv->bSwAntennaDiverity);
++
++
++ //
++ // Default antenna settings. Added by Roger, 2007.11.05.
++ //
++ if( priv->RegDefaultAntenna == 0)//set it to 0 when init
++ { // 0: default from EEPROM.
++ priv->bDefaultAntenna1 = priv->EEPROMDefaultAntenna1;
++ }else{// 1: main, 2: aux.
++ priv->bDefaultAntenna1 = ((priv->RegDefaultAntenna== 2) ? true : false);
++ }
++ //DMESG("bDefaultAntenna1 = %d\n", priv->bDefaultAntenna1);
++
++//by amy for antenna
++}
++#endif
++
++short rtl8180_init(struct net_device *dev)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ int i, j;
++ u16 word;
++ //int ch;
++ //u16 version;
++ u8 hw_version;
++ //u8 config3;
++ struct usb_device *udev;
++ u16 idProduct;
++ u16 bcdDevice;
++ //u8 chan_plan_index;
++
++ //FIXME: these constants are placed in a bad pleace.
++
++ //priv->txbuffsize = 1024;
++ //priv->txringcount = 32;
++ //priv->rxbuffersize = 1024;
++ //priv->rxringcount = 32;
++ //priv->txbeaconcount = 3;
++ //priv->rx_skb_complete = 1;
++ //priv->txnp_pending.ispending=0;
++ /* ^^ the SKB does not containt a partial RXed packet (is empty) */
++
++ //memcpy(priv->stats,0,sizeof(struct Stats));
++
++ //priv->irq_enabled=0;
++ priv->driver_upping = 0;
++ priv->commit = 0;
++
++ //priv->stats.rxdmafail=0;
++ priv->stats.txrdu=0;
++ //priv->stats.rxrdu=0;
++ //priv->stats.rxnolast=0;
++ //priv->stats.rxnodata=0;
++ //priv->stats.rxreset=0;
++ //priv->stats.rxwrkaround=0;
++ //priv->stats.rxnopointer=0;
++ priv->stats.txbeerr=0;
++ priv->stats.txbkerr=0;
++ priv->stats.txvierr=0;
++ priv->stats.txvoerr=0;
++ priv->stats.txmanageerr=0;
++ priv->stats.txbeaconerr=0;
++ priv->stats.txresumed=0;
++ //priv->stats.rxerr=0;
++ //priv->stats.rxoverflow=0;
++ //priv->stats.rxint=0;
++ priv->stats.txbeokint=0;
++ priv->stats.txbkokint=0;
++ priv->stats.txviokint=0;
++ priv->stats.txvookint=0;
++ priv->stats.txmanageokint=0;
++ priv->stats.txbeaconokint=0;
++ /*priv->stats.txhpokint=0;
++ priv->stats.txhperr=0;*/
++ priv->stats.rxurberr=0;
++ priv->stats.rxstaterr=0;
++ priv->stats.txoverflow=0;
++ priv->stats.rxok=0;
++ //priv->stats.txbeaconerr=0;
++ //priv->stats.txlperr=0;
++ //priv->stats.txlpokint=0;
++//john
++ priv->stats.txnpdrop=0;
++ priv->stats.txlpdrop =0;
++ priv->stats.txbedrop =0;
++ priv->stats.txbkdrop =0;
++ priv->stats.txvidrop =0;
++ priv->stats.txvodrop =0;
++ priv->stats.txbeacondrop =0;
++ priv->stats.txmanagedrop =0;
++
++ // priv->stats.txokbytestotal =0;
++//by amy
++ priv->LastSignalStrengthInPercent=0;
++ priv->SignalStrength=0;
++ priv->SignalQuality=0;
++ priv->antenna_flag=0;
++ priv->flag_beacon = false;
++//by amy
++//david
++ //radion on defaultly
++ priv->radion = 1;
++//david
++//by amy for rate adaptive
++ priv->CurrRetryCnt=0;
++ priv->LastRetryCnt=0;
++ priv->LastTxokCnt=0;
++ priv->LastRxokCnt=0;
++ priv->LastRetryRate=0;
++ priv->bTryuping=0;
++ priv->CurrTxRate=0;
++ priv->CurrRetryRate=0;
++ priv->TryupingCount=0;
++ priv->TryupingCountNoData=0;
++ priv->TryDownCountLowData=0;
++ priv->RecvSignalPower=0;
++ priv->LastTxOKBytes=0;
++ priv->LastFailTxRate=0;
++ priv->LastFailTxRateSS=0;
++ priv->FailTxRateCount=0;
++ priv->LastTxThroughput=0;
++ priv->txokbytestotal=0;
++//by amy for rate adaptive
++//by amy for ps
++ priv->RFChangeInProgress = false;
++ priv->SetRFPowerStateInProgress = false;
++ priv->RFProgType = 0;
++ priv->bInHctTest = false;
++ priv->bInactivePs = true;//false;
++ priv->ieee80211->bInactivePs = priv->bInactivePs;
++ priv->eInactivePowerState = eRfOn;//lzm add for IPS and Polling methord
++ priv->bSwRfProcessing = false;
++ priv->eRFPowerState = eRfOff;
++ priv->RfOffReason = 0;
++ priv->NumRxOkInPeriod = 0;
++ priv->NumTxOkInPeriod = 0;
++ priv->bLeisurePs = true;
++ priv->dot11PowerSaveMode = eActive;
++ priv->RegThreeWireMode=HW_THREE_WIRE_BY_8051;
++ priv->ps_mode = false;
++//by amy for ps
++//by amy for DIG
++ priv->bDigMechanism = 1;
++ priv->bCCKThMechanism = 0;
++ priv->InitialGain = 0;
++ priv->StageCCKTh = 0;
++ priv->RegBModeGainStage = 2;
++//by amy for DIG
++// {by david for DIG, 2008.3.6
++ priv->RegDigOfdmFaUpTh = 0x0c;
++ priv->RegBModeGainStage = 0x02;
++ priv->DIG_NumberFallbackVote = 0;
++ priv->DIG_NumberUpgradeVote = 0;
++ priv->CCKUpperTh = 0x100;
++ priv->CCKLowerTh = 0x20;
++//}
++//{added by david for High tx power, 2008.3.11
++ priv->bRegHighPowerMechanism = true;
++ priv->bToUpdateTxPwr = false;
++
++ priv->Z2HiPwrUpperTh = 77;
++ priv->Z2HiPwrLowerTh = 75;
++ priv->Z2RSSIHiPwrUpperTh = 70;
++ priv->Z2RSSIHiPwrLowerTh = 20;
++ //specify for rtl8187B
++ priv->wMacRegRfPinsOutput = 0x0480;
++ priv->wMacRegRfPinsSelect = 0x2488;
++ //
++ // Note that, we just set TrSwState to TR_HW_CONTROLLED here instead of changing
++ // HW setting because we assume it should be inialized as HW controlled. 061010, by rcnjko.
++ //
++ priv->TrSwitchState = TR_HW_CONTROLLED;
++//}
++ priv->ieee80211->iw_mode = IW_MODE_INFRA;
++//test pending bug, john 20070815
++ for(i=0;i<0x10;i++) atomic_set(&(priv->tx_pending[i]), 0);
++//by lizhaoming for LED
++#ifdef LED
++ priv->ieee80211->ieee80211_led_contorl = LedControl8187;
++#endif
++#ifdef CONFIG_IPS
++ priv->ieee80211->ieee80211_ips_leave = ieee80211_ips_leave;//IPSLeave;
++#endif
++
++#ifdef SW_ANTE_DIVERSITY
++ priv->antb=0;
++ priv->diversity=1;
++ priv->LastRxPktAntenna = 0;
++ priv->AdMinCheckPeriod = 5;
++ priv->AdMaxCheckPeriod = 10;
++ // Lower signal strength threshold to fit the HW participation in antenna diversity. +by amy 080312
++ priv->AdMaxRxSsThreshold = 30;//60->30
++ priv->AdRxSsThreshold = 20;//50->20
++ priv->AdCheckPeriod = priv->AdMinCheckPeriod;
++ priv->AdTickCount = 0;
++ priv->AdRxSignalStrength = -1;
++ priv->RegSwAntennaDiversityMechanism = 0;
++ priv->RegDefaultAntenna = 0;
++ priv->SignalStrength = 0;
++ priv->AdRxOkCnt = 0;
++ priv->CurrAntennaIndex = 0;
++ priv->AdRxSsBeforeSwitched = 0;
++ init_timer(&priv->SwAntennaDiversityTimer);
++ priv->SwAntennaDiversityTimer.data = (unsigned long)dev;
++ priv->SwAntennaDiversityTimer.function = (void *)SwAntennaDiversityTimerCallback;
++#endif
++
++ priv->retry_rts = DEFAULT_RETRY_RTS;
++ priv->retry_data = DEFAULT_RETRY_DATA;
++ priv->ieee80211->rate = 110; //11 mbps
++ priv->CurrentOperaRate=priv->ieee80211->rate/5;
++ priv->ieee80211->short_slot = 1;
++ priv->ieee80211->mode = IEEE_G;
++ priv->promisc = (dev->flags & IFF_PROMISC) ? 1:0;
++
++ rtl8180_link_detect_init(&priv->link_detect);
++
++ spin_lock_init(&priv->tx_lock);
++ spin_lock_init(&priv->irq_lock);//added by thomas
++ spin_lock_init(&priv->rf_ps_lock);
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
++ INIT_WORK(&priv->reset_wq, (void*)rtl8180_restart);
++ INIT_WORK(&priv->ieee80211->ips_leave_wq, (void*)IPSLeave_wq); //YJ,add,081230,for IPS
++ INIT_DELAYED_WORK(&priv->ieee80211->rate_adapter_wq,(void*)rtl8180_rate_adapter);
++ INIT_DELAYED_WORK(&priv->ieee80211->hw_dig_wq,(void*)rtl8180_hw_dig_wq);
++ INIT_DELAYED_WORK(&priv->ieee80211->watch_dog_wq,(void*)rtl8180_watch_dog_wq);
++ INIT_DELAYED_WORK(&priv->ieee80211->tx_pw_wq,(void*)rtl8180_tx_pw_wq);
++
++#ifdef SW_ANTE_DIVERSITY
++ INIT_DELAYED_WORK(&priv->ieee80211->SwAntennaWorkItem,(void*) SwAntennaWorkItemCallback);
++#endif
++
++#else
++ INIT_WORK(&priv->reset_wq,(void*) rtl8180_restart,dev);
++ INIT_WORK(&priv->ieee80211->ips_leave_wq, (void*)IPSLeave_wq,dev); //YJ,add,081230,for IPS
++ INIT_WORK(&priv->ieee80211->rate_adapter_wq,(void*)rtl8180_rate_adapter,dev);
++ INIT_WORK(&priv->ieee80211->hw_dig_wq,(void*)rtl8180_hw_dig_wq,dev);
++ INIT_WORK(&priv->ieee80211->watch_dog_wq,(void*)rtl8180_watch_dog_wq,dev);
++ INIT_WORK(&priv->ieee80211->tx_pw_wq,(void*)rtl8180_tx_pw_wq,dev);
++
++#ifdef SW_ANTE_DIVERSITY
++ INIT_WORK(&priv->ieee80211->SwAntennaWorkItem,(void*) SwAntennaWorkItemCallback, dev);
++#endif
++
++#endif
++#else
++ tq_init(&priv->reset_wq,(void*) rtl8180_restart,dev);
++#endif
++ sema_init(&priv->wx_sem,1);
++ sema_init(&priv->set_chan_sem,1);
++#ifdef THOMAS_TASKLET
++ tasklet_init(&priv->irq_rx_tasklet,
++ (void(*)(unsigned long))rtl8180_irq_rx_tasklet_new,
++ (unsigned long)priv);
++#else
++ tasklet_init(&priv->irq_rx_tasklet,
++ (void(*)(unsigned long))rtl8180_irq_rx_tasklet,
++ (unsigned long)priv);
++#endif
++//by amy for rate adaptive
++ init_timer(&priv->rateadapter_timer);
++ priv->rateadapter_timer.data = (unsigned long)dev;
++ priv->rateadapter_timer.function = timer_rate_adaptive;
++//by amy for rate adaptive
++//by amy for ps
++ init_timer(&priv->watch_dog_timer);
++ priv->watch_dog_timer.data = (unsigned long)dev;
++ priv->watch_dog_timer.function = watch_dog_adaptive;
++//by amy
++//by amy for ps
++ priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
++ priv->ieee80211->iw_mode = IW_MODE_INFRA;
++ priv->ieee80211->softmac_features = IEEE_SOFTMAC_SCAN |
++ IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ |
++#ifdef CONFIG_SOFT_BEACON
++ IEEE_SOFTMAC_BEACONS | //IEEE_SOFTMAC_SINGLE_QUEUE;
++#endif
++ IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE;
++
++ priv->ieee80211->active_scan = 1;
++ //priv->ieee80211->ch_lock = 0;
++ priv->ieee80211->rate = 110; //11 mbps
++ priv->ieee80211->modulation = IEEE80211_CCK_MODULATION | IEEE80211_OFDM_MODULATION;
++ priv->ieee80211->host_encrypt = 1;
++ priv->ieee80211->host_decrypt = 1;
++#ifdef CONFIG_SOFT_BEACON
++ priv->ieee80211->start_send_beacons = NULL;
++ priv->ieee80211->stop_send_beacons = NULL;
++#else
++ priv->ieee80211->start_send_beacons = rtl8187_beacon_tx;
++ priv->ieee80211->stop_send_beacons = rtl8187_beacon_stop;
++#endif
++ priv->ieee80211->softmac_hard_start_xmit = rtl8180_hard_start_xmit;
++ priv->ieee80211->set_chan = rtl8180_set_chan;
++ priv->ieee80211->link_change = rtl8187_link_change;
++ priv->ieee80211->softmac_data_hard_start_xmit = rtl8180_hard_data_xmit;
++ priv->ieee80211->data_hard_stop = rtl8180_data_hard_stop;
++ priv->ieee80211->data_hard_resume = rtl8180_data_hard_resume;
++
++#ifdef _RTL8187_EXT_PATCH_
++ priv->ieee80211->meshScanMode = 0;
++ priv->mshobj = alloc_mshobj(priv);
++ if(priv->mshobj)
++ {
++ priv->ieee80211->ext_patch_ieee80211_start_protocol = priv->mshobj->ext_patch_ieee80211_start_protocol;
++ priv->ieee80211->ext_patch_ieee80211_stop_protocol = priv->mshobj->ext_patch_ieee80211_stop_protocol;
++//by amy for mesh
++ priv->ieee80211->ext_patch_ieee80211_start_mesh = priv->mshobj->ext_patch_ieee80211_start_mesh;
++//by amy for mesh
++ priv->ieee80211->ext_patch_ieee80211_probe_req_1 = priv->mshobj->ext_patch_ieee80211_probe_req_1;
++ priv->ieee80211->ext_patch_ieee80211_probe_req_2 = priv->mshobj->ext_patch_ieee80211_probe_req_2;
++ priv->ieee80211->ext_patch_ieee80211_association_req_1 = priv->mshobj->ext_patch_ieee80211_association_req_1;
++ priv->ieee80211->ext_patch_ieee80211_association_req_2 = priv->mshobj->ext_patch_ieee80211_association_req_2;
++ priv->ieee80211->ext_patch_ieee80211_assoc_resp_by_net_1 = priv->mshobj->ext_patch_ieee80211_assoc_resp_by_net_1;
++ priv->ieee80211->ext_patch_ieee80211_assoc_resp_by_net_2 = priv->mshobj->ext_patch_ieee80211_assoc_resp_by_net_2;
++ priv->ieee80211->ext_patch_ieee80211_rx_frame_softmac_on_auth = priv->mshobj->ext_patch_ieee80211_rx_frame_softmac_on_auth;
++ priv->ieee80211->ext_patch_ieee80211_rx_frame_softmac_on_deauth = priv->mshobj->ext_patch_ieee80211_rx_frame_softmac_on_deauth;
++ priv->ieee80211->ext_patch_ieee80211_rx_frame_softmac_on_assoc_req = priv->mshobj->ext_patch_ieee80211_rx_frame_softmac_on_assoc_req;
++ priv->ieee80211->ext_patch_ieee80211_rx_frame_softmac_on_assoc_rsp = priv->mshobj->ext_patch_ieee80211_rx_frame_softmac_on_assoc_rsp;
++ priv->ieee80211->ext_patch_ieee80211_ext_stop_scan_wq_set_channel = priv->mshobj->ext_patch_ieee80211_ext_stop_scan_wq_set_channel;
++ priv->ieee80211->ext_patch_ieee80211_process_probe_response_1 = priv->mshobj->ext_patch_ieee80211_process_probe_response_1;
++ priv->ieee80211->ext_patch_ieee80211_rx_mgt_on_probe_req = priv->mshobj->ext_patch_ieee80211_rx_mgt_on_probe_req;
++ priv->ieee80211->ext_patch_ieee80211_rx_mgt_update_expire = priv->mshobj->ext_patch_ieee80211_rx_mgt_update_expire;
++ priv->ieee80211->ext_patch_get_beacon_get_probersp = priv->mshobj->ext_patch_get_beacon_get_probersp;
++ priv->ieee80211->ext_patch_ieee80211_rx_on_rx = priv->mshobj->ext_patch_ieee80211_rx_on_rx;
++ priv->ieee80211->ext_patch_ieee80211_xmit = priv->mshobj->ext_patch_ieee80211_xmit;
++ priv->ieee80211->ext_patch_ieee80211_rx_frame_get_hdrlen = priv->mshobj->ext_patch_ieee80211_rx_frame_get_hdrlen;
++ priv->ieee80211->ext_patch_ieee80211_rx_is_valid_framectl = priv->mshobj->ext_patch_ieee80211_rx_is_valid_framectl;
++ priv->ieee80211->ext_patch_ieee80211_rx_process_dataframe = priv->mshobj->ext_patch_ieee80211_rx_process_dataframe;
++ // priv->ieee80211->ext_patch_is_duplicate_packet = priv->mshobj->ext_patch_is_duplicate_packet;
++ priv->ieee80211->ext_patch_ieee80211_softmac_xmit_get_rate = priv->mshobj->ext_patch_ieee80211_softmac_xmit_get_rate;
++ /* added by david for setting acl dynamically */
++ priv->ieee80211->ext_patch_ieee80211_acl_query = priv->mshobj->ext_patch_ieee80211_acl_query;
++ }
++
++#endif // _RTL8187_EXT_PATCH_
++
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
++ INIT_WORK(&priv->ieee80211->wmm_param_update_wq,\
++ (void(*)(void*)) rtl8180_wmm_param_update,\
++ priv->ieee80211);
++#else
++ INIT_WORK(&priv->ieee80211->wmm_param_update_wq,\
++ rtl8180_wmm_param_update);
++#endif
++#else
++ tq_init(&priv->ieee80211->wmm_param_update_wq,\
++ (void(*)(void*)) rtl8180_wmm_param_update,\
++ priv->ieee80211);
++#endif
++ priv->ieee80211->init_wmmparam_flag = 0;
++ priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
++
++ //priv->card_8185 = 2;
++ priv->phy_ver = 2;
++ priv->card_type = USB;
++//{add for 87B
++ priv->ShortRetryLimit = 7;
++ priv->LongRetryLimit = 7;
++ priv->EarlyRxThreshold = 7;
++
++ priv->TransmitConfig =
++ TCR_DurProcMode | //for RTL8185B, duration setting by HW
++ TCR_DISReqQsize |
++ (TCR_MXDMA_2048<<TCR_MXDMA_SHIFT)| // Max DMA Burst Size per Tx DMA Burst, 7: reservied.
++ (priv->ShortRetryLimit<<TX_SRLRETRY_SHIFT)| // Short retry limit
++ (priv->LongRetryLimit<<TX_LRLRETRY_SHIFT) | // Long retry limit
++ (false ? TCR_SWPLCPLEN : 0); // FALSE: HW provies PLCP length and LENGEXT, TURE: SW proiveds them
++
++ priv->ReceiveConfig =
++ RCR_AMF | RCR_ADF | //accept management/data
++ RCR_ACF | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
++ RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
++ //RCR_AICV | RCR_ACRC32 | //accept ICV/CRC error packet
++ RCR_MXDMA | // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
++ (priv->EarlyRxThreshold<<RX_FIFO_THRESHOLD_SHIFT) | // Rx FIFO Threshold, 7: No Rx threshold.
++ (priv->EarlyRxThreshold == 7 ? RCR_ONLYERLPKT:0);
++
++ priv->AcmControl = 0;
++//}
++ priv->rf_chip = 0xff & eprom_read(dev,EPROM_RFCHIPID);
++ //DMESG("rf_chip:%x\n", priv->rf_chip);
++ if (!priv->rf_chip)
++ {
++ DMESG("Can't get rf chip ID from EEPROM");
++ DMESGW("So set rf chip ID to defalut EPROM_RFCHIPID_RTL8225U");
++ DMESGW("use it with care and at your own risk and");
++ DMESGW("**PLEASE** REPORT SUCCESS/INSUCCESS TO Realtek");
++ priv->rf_chip = EPROM_RFCHIPID_RTL8225U;
++
++ }
++
++
++//{put the card to detect different card here, mainly I/O processing
++ udev = priv->udev;
++ idProduct = le16_to_cpu(udev->descriptor.idProduct);
++ //idProduct = 0x8197;
++ bcdDevice = le16_to_cpu(udev->descriptor.bcdDevice);
++ DMESG("idProduct:0x%x, bcdDevice:0x%x", idProduct,bcdDevice);
++ switch (idProduct) {
++ case 0x8189:
++ case 0x8197:
++ case 0x8198:
++ /* check RF frontend chipset */
++ priv->card_8187 = NIC_8187B;
++ priv->rf_init = rtl8225z2_rf_init;
++ priv->rf_set_chan = rtl8225z2_rf_set_chan;
++ priv->rf_set_sens = NULL;
++ break;
++
++ case 0x8187:
++ if(bcdDevice == 0x0200){
++ priv->card_8187 = NIC_8187B;
++ priv->rf_init = rtl8225z2_rf_init;
++ priv->rf_set_chan = rtl8225z2_rf_set_chan;
++ priv->rf_set_sens = NULL;
++ break;
++ }else{
++ //0x0100 is for 8187
++ //legacy 8187 NIC
++ //delet
++ ;
++ }
++ default:
++ /* check RF frontend chipset */
++ priv->ieee80211->softmac_features |= IEEE_SOFTMAC_SINGLE_QUEUE;
++ priv->card_8187 = NIC_8187;
++ switch (priv->rf_chip) {
++ case EPROM_RFCHIPID_RTL8225U:
++ DMESG("Card reports RF frontend Realtek 8225");
++ DMESGW("This driver has EXPERIMENTAL support for this chipset.");
++ DMESGW("use it with care and at your own risk and");
++ DMESGW("**PLEASE** REPORT SUCCESS/INSUCCESS TO Realtek");
++ if(rtl8225_is_V_z2(dev)){
++ priv->rf_init = rtl8225z2_rf_init;
++ priv->rf_set_chan = rtl8225z2_rf_set_chan;
++ priv->rf_set_sens = NULL;
++ DMESG("This seems a new V2 radio");
++ }else{
++ priv->rf_init = rtl8225_rf_init;
++ priv->rf_set_chan = rtl8225_rf_set_chan;
++ priv->rf_set_sens = rtl8225_rf_set_sens;
++ DMESG("This seems a legacy 1st version radio");
++ }
++ break;
++
++ case EPROM_RFCHIPID_RTL8225U_VF:
++ priv->rf_init = rtl8225z2_rf_init;
++ priv->rf_set_chan = rtl8225z2_rf_set_chan;
++ priv->rf_set_sens = NULL;
++ DMESG("This seems a new V2 radio");
++ break;
++
++ default:
++ DMESGW("Unknown RF module %x",priv->rf_chip);
++ DMESGW("Exiting...");
++ return -1;
++ }
++ break;
++ }
++
++ priv->rf_close = rtl8225_rf_close;
++ priv->max_sens = RTL8225_RF_MAX_SENS;
++ priv->sens = RTL8225_RF_DEF_SENS;
++
++#ifdef ENABLE_DOT11D
++#if 0
++ for(i=0;i<0xFF;i++) {
++ if(i%16 == 0)
++ printk("\n[%x]: ", i/16);
++ printk("\t%4.4x", eprom_read(dev,i));
++ }
++#endif
++ priv->channel_plan = eprom_read(dev,EPROM_CHANNEL_PLAN) & 0xFF;
++ //DMESG("EPROM_CHANNEL_PLAN is %x", priv->channel_plan);
++
++ // lzm add 081205 for Toshiba:
++ // For Toshiba,reading the value from EEPROM 0x6h bit[7] to determine the priority of
++ // channel plan to be defined.
++ // -If bit[7] is true, then the channel plan is defined by EEPROM but no user defined.
++ // -If bit[7] is false, then the channel plan is defined by user first.
++ //
++ if(priv->channel_plan & 0x80) {
++ DMESG("Toshiba channel plan is defined by EEPROM");
++ priv->channel_plan &= 0xf;
++ }
++ else
++ priv->channel_plan = 0;
++
++ //if(priv->channel_plan > COUNTRY_CODE_WORLD_WIDE_13_INDEX){
++ if(priv->channel_plan > COUNTRY_CODE_GLOBAL_DOMAIN){
++ DMESG("rtl8180_init:Error channel plan! Set to default.\n");
++ priv->channel_plan = 0;
++ }
++
++ //priv->channel_plan = 9; //Global Domain
++ //priv->channel_plan = 2; //ETSI
++
++
++ DMESG("Channel plan is %d ",priv->channel_plan);
++
++ //for Toshiba card we read channel plan from ChanPlanBin
++ if((idProduct != 0x8197) && (idProduct != 0x8198))
++ rtl8180_set_channel_map(priv->channel_plan, priv->ieee80211);
++#else
++ int ch;
++ priv->channel_plan = eprom_read(dev,EPROM_CHANNEL_PLAN) & 0xff;
++ if(priv->channel_plan & 0x80) {
++ priv->channel_plan &= 0x7f;
++ if (ChannelPlan[priv->channel_plan].Len != 0){
++ // force channel plan map
++ for (i=0;i<ChannelPlan[priv->channel_plan].Len;i++)
++ priv->ieee80211->channel_map[ChannelPlan[priv->channel_plan].Channel[i]] = 1;
++ } else {
++ DMESG("No channels, aborting");
++ return -1;
++ }
++ } else {
++ //default channel plan setting
++ if(!channels){
++ DMESG("No channels, aborting");
++ return -1;
++ }
++ ch=channels;
++ // set channels 1..14 allowed in given locale
++ for (i=1; i<=14; i++) {
++ (priv->ieee80211->channel_map)[i] = (u8)(ch & 0x01);
++ ch >>= 1;
++ }
++ }
++#endif
++
++ if((idProduct == 0x8197) || (idProduct == 0x8198)) {
++ // lzm add 081205 for Toshiba:
++ // 0x77h bit[0]=1: use GPIO bit[2], bit[0]=0: use GPIO bit[1]
++ priv->EEPROMSelectNewGPIO =((u8)((eprom_read(dev,EPROM_SELECT_GPIO) & 0xff00) >> 8)) ? true : false;
++ DMESG("EPROM_SELECT_GPIO:%d", priv->EEPROMSelectNewGPIO);
++ } else {
++ priv->EEPROMSelectNewGPIO = false;
++ }
++
++
++ if (NIC_8187 == priv->card_8187){
++ hw_version =( read_nic_dword(dev, TCR) & TCR_HWVERID_MASK)>>TCR_HWVERID_SHIFT;
++ switch (hw_version) {
++ case 0x06:
++ //priv->card_8187_Bversion = VERSION_8187B_B;
++ break;
++ case 0x05:
++ priv->card_8187_Bversion = VERSION_8187_D;
++ break;
++ default:
++ priv->card_8187_Bversion = VERSION_8187_B;
++ break;
++ }
++ }else{
++ hw_version = read_nic_byte(dev, 0xe1); //87B hw version reg
++ switch (hw_version){
++ case 0x00:
++ priv->card_8187_Bversion = VERSION_8187B_B;
++ break;
++ case 0x01:
++ priv->card_8187_Bversion = VERSION_8187B_D;
++ break;
++ case 0x02:
++ priv->card_8187_Bversion = VERSION_8187B_E;
++ break;
++ default:
++ priv->card_8187_Bversion = VERSION_8187B_B; //defalt
++ break;
++ }
++ }
++
++ //printk("=====hw_version:%x\n", priv->card_8187_Bversion);
++ priv->enable_gpio0 = 0;
++
++ /*the eeprom type is stored in RCR register bit #6 */
++ if (RCR_9356SEL & read_nic_dword(dev, RCR)){
++ priv->epromtype=EPROM_93c56;
++ DMESG("Reported EEPROM chip is a 93c56 (2Kbit)");
++ }else{
++ priv->epromtype=EPROM_93c46;
++ DMESG("Reported EEPROM chip is a 93c46 (1Kbit)");
++ }
++
++ dev->dev_addr[0]=eprom_read(dev,MAC_ADR) & 0xff;
++ dev->dev_addr[1]=(eprom_read(dev,MAC_ADR) & 0xff00)>>8;
++ dev->dev_addr[2]=eprom_read(dev,MAC_ADR+1) & 0xff;
++ dev->dev_addr[3]=(eprom_read(dev,MAC_ADR+1) & 0xff00)>>8;
++ dev->dev_addr[4]=eprom_read(dev,MAC_ADR+2) & 0xff;
++ dev->dev_addr[5]=((eprom_read(dev,MAC_ADR+2) & 0xff00)>>8)+1;
++
++ DMESG("Card MAC address is "MAC_FMT, MAC_ARG(dev->dev_addr));
++
++ for(i=1,j=0; i<6; i+=2,j++){
++
++ word = eprom_read(dev,EPROM_TXPW0 + j);
++ priv->chtxpwr[i]=word & 0xf;
++ priv->chtxpwr_ofdm[i]=(word & 0xf0)>>4;
++ priv->chtxpwr[i+1]=(word & 0xf00)>>8;
++ priv->chtxpwr_ofdm[i+1]=(word & 0xf000)>>12;
++ }
++
++ for(i=1,j=0; i<4; i+=2,j++){
++
++ word = eprom_read(dev,EPROM_TXPW1 + j);
++ priv->chtxpwr[i+6]=word & 0xf;
++ priv->chtxpwr_ofdm[i+6]=(word & 0xf0)>>4;
++ priv->chtxpwr[i+6+1]=(word & 0xf00)>>8;
++ priv->chtxpwr_ofdm[i+6+1]=(word & 0xf000)>>12;
++ }
++ if (priv->card_8187 == NIC_8187){
++ for(i=1,j=0; i<4; i+=2,j++){
++ word = eprom_read(dev,EPROM_TXPW2 + j);
++ priv->chtxpwr[i+6+4]=word & 0xf;
++ priv->chtxpwr_ofdm[i+6+4]=(word & 0xf0)>>4;
++ priv->chtxpwr[i+6+4+1]=(word & 0xf00)>>8;
++ priv->chtxpwr_ofdm[i+6+4+1]=(word & 0xf000)>>12;
++ }
++ } else{
++ word = eprom_read(dev, 0x1B) & 0xff; //channel 11;
++ priv->chtxpwr[11]=word & 0xf;
++ priv->chtxpwr_ofdm[11] = (word & 0xf0)>>4;
++
++ word = eprom_read(dev, 0xA) & 0xff; //channel 12;
++ priv->chtxpwr[12]=word & 0xf;
++ priv->chtxpwr_ofdm[12] = (word & 0xf0)>>4;
++
++ word = eprom_read(dev, 0x1c) ; //channel 13 ,14;
++ priv->chtxpwr[13]=word & 0xf;
++ priv->chtxpwr_ofdm[13] = (word & 0xf0)>>4;
++ priv->chtxpwr[14]=(word & 0xf00)>>8;
++ priv->chtxpwr_ofdm[14] = (word & 0xf000)>>12;
++ }
++
++ word = eprom_read(dev,EPROM_TXPW_BASE);
++ priv->cck_txpwr_base = word & 0xf;
++ priv->ofdm_txpwr_base = (word>>4) & 0xf;
++
++ //DMESG("PAPE from CONFIG2: %x",read_nic_byte(dev,CONFIG2)&0x7);
++
++#ifdef SW_ANTE_DIVERSITY
++ rtl8187_antenna_diversity_read(dev);
++#endif
++
++ if(rtl8187_usb_initendpoints(dev)!=0){
++ DMESG("Endopoints initialization failed");
++ return -ENOMEM;
++ }
++#ifdef LED
++ InitSwLeds(dev);
++#endif
++#ifdef DEBUG_EPROM
++ dump_eprom(dev);
++#endif
++ return 0;
++
++}
++
++void rtl8185_rf_pins_enable(struct net_device *dev)
++{
++/* u16 tmp;
++ tmp = read_nic_word(dev, RFPinsEnable);*/
++ write_nic_word(dev, RFPinsEnable, 0x1ff7);// | tmp);
++}
++
++
++void rtl8185_set_anaparam2(struct net_device *dev, u32 a)
++{
++ u8 conf3;
++
++ rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
++
++ conf3 = read_nic_byte(dev, CONFIG3);
++ write_nic_byte(dev, CONFIG3, conf3 | (1<<CONFIG3_ANAPARAM_W_SHIFT));
++
++ write_nic_dword(dev, ANAPARAM2, a);
++
++ conf3 = read_nic_byte(dev, CONFIG3);
++ write_nic_byte(dev, CONFIG3, conf3 &~(1<<CONFIG3_ANAPARAM_W_SHIFT));
++
++ rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
++
++}
++
++
++void rtl8180_set_anaparam(struct net_device *dev, u32 a)
++{
++ u8 conf3;
++
++ rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
++
++ conf3 = read_nic_byte(dev, CONFIG3);
++ write_nic_byte(dev, CONFIG3, conf3 | (1<<CONFIG3_ANAPARAM_W_SHIFT));
++
++ write_nic_dword(dev, ANAPARAM, a);
++
++ conf3 = read_nic_byte(dev, CONFIG3);
++ write_nic_byte(dev, CONFIG3, conf3 &~(1<<CONFIG3_ANAPARAM_W_SHIFT));
++
++ rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
++
++}
++
++
++void rtl8185_tx_antenna(struct net_device *dev, u8 ant)
++{
++ write_nic_byte(dev, ANTSEL, ant);
++ //lzm mod for up take too long time 20081201
++ //mdelay(1);
++}
++
++
++void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data)
++{
++ u32 phyw;
++
++ adr |= 0x80;
++
++ phyw= ((data<<8) | adr);
++
++
++
++ // Note that, we must write 0xff7c after 0x7d-0x7f to write BB register.
++ write_nic_byte(dev, 0x7f, ((phyw & 0xff000000) >> 24));
++ write_nic_byte(dev, 0x7e, ((phyw & 0x00ff0000) >> 16));
++ write_nic_byte(dev, 0x7d, ((phyw & 0x0000ff00) >> 8));
++ write_nic_byte(dev, 0x7c, ((phyw & 0x000000ff) ));
++
++ //read_nic_dword(dev, PHY_ADR);
++#if 0
++ for(i=0;i<10;i++){
++ write_nic_dword(dev, PHY_ADR, 0xffffff7f & phyw);
++ phyr = read_nic_byte(dev, PHY_READ);
++ if(phyr == (data&0xff)) break;
++
++ }
++#endif
++ /* this is ok to fail when we write AGC table. check for AGC table might be
++ * done by masking with 0x7f instead of 0xff */
++ //if(phyr != (data&0xff)) DMESGW("Phy write timeout %x %x %x", phyr, data, adr);
++ //msdelay(1);//CPU occupany is too high. LZM 31/10/2008
++}
++
++u8 rtl8187_read_phy(struct net_device *dev,u8 adr, u32 data)
++{
++ u32 phyw;
++
++ adr &= ~0x80;
++ phyw= ((data<<8) | adr);
++
++
++ // Note that, we must write 0xff7c after 0x7d-0x7f to write BB register.
++ write_nic_byte(dev, 0x7f, ((phyw & 0xff000000) >> 24));
++ write_nic_byte(dev, 0x7e, ((phyw & 0x00ff0000) >> 16));
++ write_nic_byte(dev, 0x7d, ((phyw & 0x0000ff00) >> 8));
++ write_nic_byte(dev, 0x7c, ((phyw & 0x000000ff) ));
++
++ return(read_nic_byte(dev,0x7e));
++
++}
++
++u8 read_phy_ofdm(struct net_device *dev, u8 adr)
++{
++ return(rtl8187_read_phy(dev, adr, 0x000000));
++}
++
++u8 read_phy_cck(struct net_device *dev, u8 adr)
++{
++ return(rtl8187_read_phy(dev, adr, 0x10000));
++}
++
++inline void write_phy_ofdm (struct net_device *dev, u8 adr, u32 data)
++{
++ data = data & 0xff;
++ rtl8187_write_phy(dev, adr, data);
++}
++
++
++void write_phy_cck (struct net_device *dev, u8 adr, u32 data)
++{
++ data = data & 0xff;
++ rtl8187_write_phy(dev, adr, data | 0x10000);
++}
++//
++// Description: Change ZEBRA's power state.
++//
++// Assumption: This function must be executed in PASSIVE_LEVEL.
++//
++// 061214, by rcnjko.
++//
++//#define MAX_DOZE_WAITING_TIMES_87B 1000//500
++#define MAX_DOZE_WAITING_TIMES_87B_MOD 500
++
++bool SetZebraRFPowerState8187B(struct net_device *dev,RT_RF_POWER_STATE eRFPowerState)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ u8 btCR9346, btConfig3;
++ bool bResult = true;
++ int i;
++ u16 u2bTFPC = 0;
++ u8 u1bTmp;
++
++ // Set EEM0 and EEM1 in 9346CR.
++ btCR9346 = read_nic_byte(dev, CR9346);
++ write_nic_byte(dev, CR9346, (btCR9346|0xC0) );
++ // Set PARM_En in Config3.
++ btConfig3 = read_nic_byte(dev, CONFIG3);
++ write_nic_byte(dev, CONFIG3, (btConfig3|CONFIG3_PARM_En) );
++ // BB and RF related operations:
++ switch(eRFPowerState)
++ {
++ case eRfOn:
++//#ifdef CONFIG_RADIO_DEBUG
++ DMESG("Now Radio ON!");
++//#endif
++ write_nic_dword(dev, ANAPARAM, ANAPARM_ON);
++ write_nic_dword(dev, ANAPARAM2, ANAPARM2_ON);
++ //write_nic_byte(dev, CONFIG4, (priv->RFProgType));
++
++ write_nic_byte(dev, 0x085, 0x24); // 061219, SD3 ED: for minicard CCK power leakage issue.
++ write_rtl8225(dev, 0x4, 0x9FF);
++ mdelay(1);
++ //
++ // <Roger_Notes> We reset PLL to reduce power consumption about 30 mA. 2008.01.16.
++ //
++ {
++ u8 Reg62;
++
++ write_nic_byte(dev, 0x61, 0x10);
++ Reg62 = read_nic_byte(dev, 0x62);
++ write_nic_byte(dev, 0x62, (Reg62 & (~BIT5)) );
++ write_nic_byte(dev, 0x62, (Reg62 | BIT5) ); // Enable PLL.
++ }
++
++ u1bTmp = read_nic_byte(dev, 0x24E);
++ write_nic_byte(dev, 0x24E, (u1bTmp & (~(BIT5|BIT6))) );// 070124 SD1 Alex: turn on CCK and OFDM.
++ break;
++
++ case eRfSleep:
++#ifdef CONFIG_RADIO_DEBUG
++ DMESG("Now Radio Sleep!");
++#endif
++ for(i = 0; i < MAX_DOZE_WAITING_TIMES_87B_MOD; i++)
++ { // Make sure TX FIFO is empty befor turn off RFE pwoer.
++ u2bTFPC = read_nic_word(dev, TFPC);
++ if(u2bTFPC == 0){
++ printk("%d times TFPC: %d == 0 before doze...\n", (i+1), u2bTFPC);
++ break;
++ }else{
++ printk("%d times TFPC: %d != 0 before doze!\n", (i+1), u2bTFPC);
++ udelay(10);
++ }
++ }
++
++ if( i == MAX_DOZE_WAITING_TIMES_87B_MOD ){
++ printk("\n\n\n SetZebraRFPowerState8187B(): %d times TFPC: %d != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_87B_MOD, u2bTFPC);
++ }
++
++ u1bTmp = read_nic_byte(dev, 0x24E);
++ write_nic_byte(dev, 0x24E, (u1bTmp|BIT5|BIT6));// 070124 SD1 Alex: turn off CCK and OFDM.
++
++ write_rtl8225(dev, 0x4, 0xDFF); // Turn off RF first to prevent BB lock up, suggested by PJ, 2006.03.03.
++ write_nic_byte(dev, 0x085, 0x04); // 061219, SD3 ED: for minicard CCK power leakage issue.
++
++ //write_nic_byte(dev, CONFIG4, (priv->RFProgType|Config4_PowerOff));
++
++ write_nic_dword(dev, ANAPARAM, ANAPARM_OFF);
++ write_nic_dword(dev, ANAPARAM2, 0x72303f70); // 070126, by SD1 William.
++ break;
++
++ case eRfOff:
++//#ifdef CONFIG_RADIO_DEBUG
++ DMESG("Now Radio OFF!");
++//#endif
++ for(i = 0; i < MAX_DOZE_WAITING_TIMES_87B_MOD; i++)
++ { // Make sure TX FIFO is empty befor turn off RFE pwoer.
++ u2bTFPC = read_nic_word(dev, TFPC);
++ if(u2bTFPC == 0) {
++ //printk("%d times TFPC: %d == 0 before doze...\n", (i+1), u2bTFPC);
++ break;
++ }else{
++ //printk("%d times TFPC: 0x%x != 0 before doze!\n", (i+1), u2bTFPC);
++ udelay(10);
++ }
++ }
++
++ if( i == MAX_DOZE_WAITING_TIMES_87B_MOD){
++ printk("\n\n\nSetZebraRFPowerState8187B(): %d times TFPC: 0x%x != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_87B_MOD, u2bTFPC);
++ }
++
++ u1bTmp = read_nic_byte(dev, 0x24E);
++ write_nic_byte(dev, 0x24E, (u1bTmp|BIT5|BIT6));// 070124 SD1 Alex: turn off CCK and OFDM.
++
++ write_rtl8225(dev, 0x4,0x1FF); // Turn off RF first to prevent BB lock up, suggested by PJ, 2006.03.03.
++ write_nic_byte(dev, 0x085, 0x04); // 061219, SD3 ED: for minicard CCK power leakage issue.
++
++ //write_nic_byte(dev, CONFIG4, (priv->RFProgType|Config4_PowerOff));
++
++ write_nic_dword(dev, ANAPARAM, ANAPARM_OFF);
++ write_nic_dword(dev, ANAPARAM2, ANAPARM2_OFF); // 070301, SD1 William: to reduce RF off power consumption to 80 mA.
++ break;
++
++ default:
++ bResult = false;
++ printk("SetZebraRFPowerState8187B(): unknow state to set: 0x%X!!!\n", eRFPowerState);
++ break;
++ }
++
++ // Clear PARM_En in Config3.
++ btConfig3 &= ~(CONFIG3_PARM_En);
++ write_nic_byte(dev, CONFIG3, btConfig3);
++ // Clear EEM0 and EEM1 in 9346CR.
++ btCR9346 &= ~(0xC0);
++ write_nic_byte(dev, CR9346, btCR9346);
++
++ if(bResult){
++ // Update current RF state variable.
++ priv->eRFPowerState = eRFPowerState;
++ }
++
++ return bResult;
++}
++//by amy for ps
++//
++// Description: Chang RF Power State.
++// Note that, only MgntActSet_RF_State() is allowed to set HW_VAR_RF_STATE.
++//
++// Assumption:PASSIVE LEVEL.
++//
++bool SetRFPowerState(struct net_device *dev,RT_RF_POWER_STATE eRFPowerState)
++{
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ bool bResult = false;
++
++ //printk("---------> SetRFPowerState(): eRFPowerState(%d)\n", eRFPowerState);
++ if(eRFPowerState == priv->eRFPowerState)
++ {
++ //printk("<--------- SetRFPowerState(): discard the request for eRFPowerState(%d) is the same.\n", eRFPowerState);
++ return bResult;
++ }
++
++ switch(priv->rf_chip)
++ {
++ case RF_ZEBRA2:
++ bResult = SetZebraRFPowerState8187B(dev, eRFPowerState);
++ break;
++
++ default:
++ printk("SetRFPowerState8185(): unknown RFChipID: 0x%X!!!\n", priv->rf_chip);
++ break;;
++ }
++ //printk("<--------- SetRFPowerState(): bResult(%d)\n", bResult);
++
++ return bResult;
++}
++
++bool
++MgntActSet_RF_State(struct net_device *dev,RT_RF_POWER_STATE StateToSet,u32 ChangeSource)
++{
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ bool bActionAllowed = false;
++ bool bConnectBySSID = false;
++ RT_RF_POWER_STATE rtState;
++ u16 RFWaitCounter = 0;
++ unsigned long flag;
++ // printk("===>MgntActSet_RF_State(): StateToSet(%d), ChangeSource(0x%x)\n",StateToSet, ChangeSource);
++ //
++ // Prevent the race condition of RF state change. By Bruce, 2007-11-28.
++ // Only one thread can change the RF state at one time, and others should wait to be executed.
++ //
++#if 1
++ while(true)
++ {
++ //down(&priv->rf_state);
++ spin_lock_irqsave(&priv->rf_ps_lock,flag);
++ if(priv->RFChangeInProgress)
++ {
++ //up(&priv->rf_state);
++ //RT_TRACE(COMP_RF, DBG_LOUD, ("MgntActSet_RF_State(): RF Change in progress! Wait to set..StateToSet(%d).\n", StateToSet));
++ spin_unlock_irqrestore(&priv->rf_ps_lock,flag);
++ // Set RF after the previous action is done.
++ while(priv->RFChangeInProgress)
++ {
++ RFWaitCounter ++;
++ //RT_TRACE(COMP_RF, DBG_LOUD, ("MgntActSet_RF_State(): Wait 1 ms (%d times)...\n", RFWaitCounter));
++ udelay(1000); // 1 ms
++
++ // Wait too long, return FALSE to avoid to be stuck here.
++ if(RFWaitCounter > 1000) // 1sec
++ {
++ DMESG("MgntActSet_RF_State(): Wait too long to set RF");
++ // TODO: Reset RF state?
++ return false;
++ }
++ }
++ }
++ else
++ {
++ priv->RFChangeInProgress = true;
++// up(&priv->rf_state);
++ spin_unlock_irqrestore(&priv->rf_ps_lock,flag);
++ break;
++ }
++ }
++#endif
++ rtState = priv->eRFPowerState;
++
++ switch(StateToSet)
++ {
++ case eRfOn:
++ //
++ // Turn On RF no matter the IPS setting because we need to update the RF state to Ndis under Vista, or
++ // the Windows does not allow the driver to perform site survey any more. By Bruce, 2007-10-02.
++ //
++ // leave last reasons and kick this reason till priv->RfOffReason = 0;
++ // if one reason turn radio off check if off->on reason is the same.if so turn, or reject it.
++ // if more than 1 reasons turn radio off we only turn on radio when all reasons turn on radio,
++ // so first turn on trys will reject till priv->RfOffReason = 0;
++ priv->RfOffReason &= (~ChangeSource);
++
++ if(! priv->RfOffReason)
++ {
++ priv->RfOffReason = 0;
++ bActionAllowed = true;
++
++ if(rtState == eRfOff && ChangeSource >=RF_CHANGE_BY_HW && !priv->bInHctTest)
++ {
++ bConnectBySSID = true;
++ }
++ } else {
++ ;//lzm must or TX_PENDING 12>MAX_TX_URB
++ //printk("Turn Radio On Reject because RfOffReason= 0x%x, ChangeSource=0x%X\n", priv->RfOffReason, ChangeSource);
++ }
++ break;
++
++ case eRfOff:
++ // 070125, rcnjko: we always keep connected in AP mode.
++ if (priv->RfOffReason > RF_CHANGE_BY_IPS)
++ {
++ //
++ // 060808, Annie:
++ // Disconnect to current BSS when radio off. Asked by QuanTa.
++ //
++
++ //
++ // Calling MgntDisconnect() instead of MgntActSet_802_11_DISASSOCIATE(),
++ // because we do NOT need to set ssid to dummy ones.
++ // Revised by Roger, 2007.12.04.
++ //
++//by amy not supported
++ //MgntDisconnect( dev, disas_lv_ss );
++
++ // Clear content of bssDesc[] and bssDesc4Query[] to avoid reporting old bss to UI.
++ // 2007.05.28, by shien chang.
++ //PlatformZeroMemory( pMgntInfo->bssDesc, sizeof(RT_WLAN_BSS)*MAX_BSS_DESC );
++ //pMgntInfo->NumBssDesc = 0;
++ //PlatformZeroMemory( pMgntInfo->bssDesc4Query, sizeof(RT_WLAN_BSS)*MAX_BSS_DESC );
++ //pMgntInfo->NumBssDesc4Query = 0;
++ }
++
++
++
++ priv->RfOffReason |= ChangeSource;
++ bActionAllowed = true;
++ //printk("Turn Radio Off RfOffReason= 0x%x, ChangeSource=0x%X\n", priv->RfOffReason, ChangeSource);
++ break;
++
++ case eRfSleep:
++ priv->RfOffReason |= ChangeSource;
++ bActionAllowed = true;
++ break;
++
++ default:
++ break;
++ }
++
++ if(bActionAllowed)
++ {
++ // Config HW to the specified mode.
++ //printk("MgntActSet_RF_State(): Action is allowed.... StateToSet(%d), RfOffReason(%#X)\n", StateToSet, priv->RfOffReason);
++ SetRFPowerState(dev, StateToSet);
++ // Turn on RF.
++ if(StateToSet == eRfOn)
++ {
++ //HalEnableRx8185Dummy(dev);
++ if(bConnectBySSID)
++ {
++ // by amy not supported
++ //MgntActSet_802_11_SSID(Adapter, Adapter->MgntInfo.Ssid.Octet, Adapter->MgntInfo.Ssid.Length, TRUE );
++ }
++ }
++ // Turn off RF.
++ else if(StateToSet == eRfOff)
++ {
++ //HalDisableRx8185Dummy(dev);
++ }
++ }
++ else
++ {
++ //printk("Action is rejected.... StateToSet(%d), ChangeSource(%#X), RfOffReason(%#X)\n",
++ // StateToSet, ChangeSource, priv->RfOffReason);
++ }
++
++ // Release RF spinlock
++ //down(&priv->rf_state);
++ spin_lock_irqsave(&priv->rf_ps_lock,flag);
++ priv->RFChangeInProgress = false;
++ //up(&priv->rf_state);
++ spin_unlock_irqrestore(&priv->rf_ps_lock,flag);
++ return bActionAllowed;
++}
++//by amy for ps
++
++void rtl8180_adapter_start(struct net_device *dev)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++// struct ieee80211_device *ieee = priv->ieee80211;
++// u8 InitWirelessMode;
++// u8 SupportedWirelessMode;
++// bool bInvalidWirelessMode = false;
++
++
++ if(NIC_8187 == priv->card_8187) {
++ //rtl8180_rtx_disable(dev);
++ rtl8180_reset(dev);
++
++ write_nic_byte(dev,0x85,0);
++ write_nic_byte(dev,0x91,0);
++
++ /* light blink! */
++ write_nic_byte(dev,0x85,4);
++ write_nic_byte(dev,0x91,1);
++ write_nic_byte(dev,0x90,0);
++
++ //by lizhaoming for LED POWR ON
++ //LedControl8187(dev, LED_CTL_POWER_ON);
++
++ /*
++ write_nic_byte(dev, CR9346, 0xC0);
++ //LED TYPE
++ write_nic_byte(dev, CONFIG1,((read_nic_byte(dev, CONFIG1)&0x3f)|0x80)); //turn on bit 5:Clkrun_mode
++ write_nic_byte(dev, CR9346, 0x0); // disable config register write
++ */
++ priv->irq_mask = 0xffff;
++ /*
++ priv->dma_poll_mask = 0;
++ priv->dma_poll_mask|= (1<<TX_DMA_STOP_BEACON_SHIFT);
++ */
++ // rtl8180_beacon_tx_disable(dev);
++
++ rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
++ write_nic_dword(dev, MAC0, ((u32*)dev->dev_addr)[0]);
++ write_nic_word(dev, MAC4, ((u32*)dev->dev_addr)[1] & 0xffff );
++
++ rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
++ rtl8180_update_msr(dev);
++
++ rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
++
++ write_nic_word(dev,0xf4,0xffff);
++ write_nic_byte(dev,
++ CONFIG1, (read_nic_byte(dev,CONFIG1) & 0x3f) | 0x80);
++
++ rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
++
++ write_nic_dword(dev,INT_TIMEOUT,0);
++
++#ifdef DEBUG_REGISTERS
++ rtl8180_dump_reg(dev);
++#endif
++
++
++ write_nic_byte(dev, WPA_CONFIG, 0);
++
++ write_nic_byte(dev, RATE_FALLBACK, 0x81);
++ rtl8187_set_rate(dev);
++
++ priv->rf_init(dev);
++
++ if(priv->rf_set_sens != NULL) {
++ priv->rf_set_sens(dev,priv->sens);
++ }
++
++ write_nic_word(dev,0x5e,1);
++ //mdelay(1);
++ write_nic_word(dev,0xfe,0x10);
++ // mdelay(1);
++ write_nic_byte(dev, TALLY_SEL, 0x80);//Set NQ retry count
++ write_nic_byte(dev, 0xff, 0x60);
++ write_nic_word(dev,0x5e,0);
++
++ rtl8180_irq_enable(dev);
++ } else {
++ /**
++ * IO part migrated from Windows Driver.
++ */
++ priv->irq_mask = 0xffff;
++ // Enable Config3.PARAM_En.
++ write_nic_byte(dev, CR9346, 0xC0);
++
++ write_nic_byte(dev, CONFIG3, (read_nic_byte(dev, CONFIG3)| CONFIG3_PARM_En|CONFIG3_GNTSel));
++ // Turn on Analog power.
++ // setup A/D D/A parameter for 8185 b2
++ // Asked for by William, otherwise, MAC 3-wire can't work, 2006.06.27, by rcnjko.
++ write_nic_dword(dev, ANA_PARAM2, ANAPARM2_ASIC_ON);
++ write_nic_dword(dev, ANA_PARAM, ANAPARM_ASIC_ON);
++ write_nic_byte(dev, ANA_PARAM3, 0x00);
++
++ //by lizhaoming for LED POWR ON
++ //LedControl8187(dev, LED_CTL_POWER_ON);
++
++ {//added for reset PLL
++ u8 bReg62;
++ write_nic_byte(dev, 0x61, 0x10);
++ bReg62 = read_nic_byte(dev, 0x62);
++ write_nic_byte(dev, 0x62, bReg62&(~(0x1<<5)));
++ write_nic_byte(dev, 0x62, bReg62|(0x1<<5));
++ }
++ write_nic_byte(dev, CONFIG3, (read_nic_byte(dev, CONFIG3)&(~CONFIG3_PARM_En)));
++ write_nic_byte(dev, CR9346, 0x00);
++
++ //rtl8180_rtx_disable(dev);
++ rtl8180_reset(dev);
++ write_nic_byte(dev, CR9346, 0xc0); // enable config register write
++ priv->rf_init(dev);
++ // Enable tx/rx
++
++ write_nic_byte(dev, CMD, (CR_RE|CR_TE));// Using HW_VAR_COMMAND instead of writing CMDR directly. Rewrited by Annie, 2006-04-07.
++
++ //add this is for 8187B Rx stall problem
++
++ rtl8180_irq_enable(dev);
++
++ write_nic_byte_E(dev, 0x41, 0xF4);
++ write_nic_byte_E(dev, 0x40, 0x00);
++ write_nic_byte_E(dev, 0x42, 0x00);
++ write_nic_byte_E(dev, 0x42, 0x01);
++ write_nic_byte_E(dev, 0x40, 0x0F);
++ write_nic_byte_E(dev, 0x42, 0x00);
++ write_nic_byte_E(dev, 0x42, 0x01);
++
++ // 8187B demo board MAC and AFE power saving parameters from SD1 William, 2006.07.20.
++ // Parameter revised by SD1 William, 2006.08.21:
++ // 373h -> 0x4F // Original: 0x0F
++ // 377h -> 0x59 // Original: 0x4F
++ // Victor 2006/8/21: ¬Ù¹q°Ñ¼Æ«Øijµ¥SD3 °ª§C·Å and cable link test OK¤~¥¿¦¡ release,¤£«Øij¤Ó§Ö
++ // 2006/9/5, Victor & ED: it is OK to use.
++ //if(pHalData->RegBoardType == BT_DEMO_BOARD)
++ //{
++ // AFE.
++ //
++ // Revise the content of Reg0x372, 0x374, 0x378 and 0x37a to fix unusual electronic current
++ // while CTS-To-Self occurs, by DZ's request.
++ // Modified by Roger, 2007.06.22.
++ //
++ write_nic_byte(dev, 0x0DB, (read_nic_byte(dev, 0x0DB)|(BIT2)));
++ write_nic_word(dev, 0x372, 0x59FA); // 0x4FFA-> 0x59FA.
++ write_nic_word(dev, 0x374, 0x59D2); // 0x4FD2-> 0x59D2.
++ write_nic_word(dev, 0x376, 0x59D2);
++ write_nic_word(dev, 0x378, 0x19FA); // 0x0FFA-> 0x19FA.
++ write_nic_word(dev, 0x37A, 0x19FA); // 0x0FFA-> 0x19FA.
++ write_nic_word(dev, 0x37C, 0x00D0);
++
++ write_nic_byte(dev, 0x061, 0x00);
++
++ // MAC.
++ write_nic_byte(dev, 0x180, 0x0F);
++ write_nic_byte(dev, 0x183, 0x03);
++ // 061218, lanhsin: for victorh request
++ write_nic_byte(dev, 0x0DA, 0x10);
++ //}
++
++ //
++ // 061213, rcnjko:
++ // Set MAC.0x24D to 0x00 to prevent cts-to-self Tx/Rx stall symptom.
++ // If we set MAC 0x24D to 0x08, OFDM and CCK will turn off
++ // if not in use, and there is a bug about this action when
++ // we try to send CCK CTS and OFDM data together.
++ //
++ //PlatformEFIOWrite1Byte(Adapter, 0x24D, 0x00);
++ // 061218, lanhsin: for victorh request
++ write_nic_byte(dev, 0x24D, 0x08);
++
++ //
++ // 061215, rcnjko:
++ // Follow SD3 RTL8185B_87B_MacPhy_Register.doc v0.4.
++ //
++ write_nic_dword(dev, HSSI_PARA, 0x0600321B);
++ //
++ // 061226, rcnjko:
++ // Babble found in HCT 2c_simultaneous test, server with 87B might
++ // receive a packet size about 2xxx bytes.
++ // So, we restrict RMS to 2048 (0x800), while as IC default value is 0xC00.
++ //
++ write_nic_word(dev, RMS, 0x0800);
++
++ /*****20070321 Resolve HW page bug on system logo test
++ u8 faketemp=read_nic_byte(dev, 0x50);*/
++ }
++}
++
++/* this configures registers for beacon tx and enables it via
++ * rtl8180_beacon_tx_enable(). rtl8180_beacon_tx_disable() might
++ * be used to stop beacon transmission
++ */
++#if 0
++void rtl8180_start_tx_beacon(struct net_device *dev)
++{
++ int i;
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ u16 word;
++ DMESG("Enabling beacon TX");
++ //write_nic_byte(dev, 0x42,0xe6);// TCR
++ //rtl8180_init_beacon(dev);
++ //set_nic_txring(dev);
++// rtl8180_prepare_beacon(dev);
++ rtl8180_irq_disable(dev);
++// rtl8180_beacon_tx_enable(dev);
++ rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
++ //write_nic_byte(dev,0x9d,0x20); //DMA Poll
++ //write_nic_word(dev,0x7a,0);
++ //write_nic_word(dev,0x7a,0x8000);
++
++
++ word = read_nic_word(dev, BcnItv);
++ word &= ~BcnItv_BcnItv; // clear Bcn_Itv
++ write_nic_word(dev, BcnItv, word);
++
++ write_nic_word(dev, AtimWnd,
++ read_nic_word(dev, AtimWnd) &~ AtimWnd_AtimWnd);
++
++ word = read_nic_word(dev, BintrItv);
++ word &= ~BintrItv_BintrItv;
++
++ //word |= priv->ieee80211->beacon_interval *
++ // ((priv->txbeaconcount > 1)?(priv->txbeaconcount-1):1);
++ // FIXME:FIXME check if correct ^^ worked with 0x3e8;
++
++ write_nic_word(dev, BintrItv, word);
++
++ //write_nic_word(dev,0x2e,0xe002);
++ //write_nic_dword(dev,0x30,0xb8c7832e);
++ for(i=0; i<ETH_ALEN; i++)
++ write_nic_byte(dev, BSSID+i, priv->ieee80211->beacon_cell_ssid[i]);
++
++// rtl8180_update_msr(dev);
++
++
++ //write_nic_byte(dev,CONFIG4,3); /* !!!!!!!!!! */
++
++ rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
++
++ rtl8180_irq_enable(dev);
++
++ /* VV !!!!!!!!!! VV*/
++ /*
++ rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
++ write_nic_byte(dev,0x9d,0x00);
++ rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
++*/
++}
++#endif
++/***************************************************************************
++ -------------------------------NET STUFF---------------------------
++***************************************************************************/
++static struct net_device_stats *rtl8180_stats(struct net_device *dev)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ return &priv->ieee80211->stats;
++}
++
++int _rtl8180_up(struct net_device *dev)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ //int i;
++
++ priv->driver_upping = 1;
++ priv->up=1;
++
++#ifdef LED
++ if(priv->ieee80211->bHwRadioOff == false)
++ priv->ieee80211->ieee80211_led_contorl(dev,LED_CTL_POWER_ON);
++#endif
++ MgntActSet_RF_State(dev, eRfOn, RF_CHANGE_BY_SW);
++
++ rtl8180_adapter_start(dev);
++ rtl8180_rx_enable(dev);
++ rtl8180_tx_enable(dev);
++//by amy for rate adaptive
++ timer_rate_adaptive((unsigned long)dev);
++//by amy for rate adaptive
++
++#ifdef SW_ANTE_DIVERSITY
++ if(priv->bSwAntennaDiverity){
++ //DMESG("SW Antenna Diversity Enable!");
++ SwAntennaDiversityTimerCallback(dev);
++ }
++#endif
++
++ ieee80211_softmac_start_protocol(priv->ieee80211);
++
++//by amy for ps
++ watch_dog_adaptive((unsigned long)dev);
++//by amy for ps
++
++ ieee80211_reset_queue(priv->ieee80211);
++ if(!netif_queue_stopped(dev))
++ netif_start_queue(dev);
++ else
++ netif_wake_queue(dev);
++
++#ifndef CONFIG_SOFT_BEACON
++ if(NIC_8187B == priv->card_8187)
++ rtl8187_rx_manage_initiate(dev);
++#endif
++
++#ifdef _RTL8187_EXT_PATCH_
++ if(priv->mshobj && priv->mshobj->ext_patch_rtl8180_up )
++ priv->mshobj->ext_patch_rtl8180_up(priv->mshobj);
++#endif
++
++
++ priv->driver_upping = 0;
++ DMESG("rtl8187_open process complete");
++ return 0;
++}
++
++
++int rtl8180_open(struct net_device *dev)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ int ret;
++//changed by lizhaoming for power on/off
++ if(priv->ieee80211->bHwRadioOff == false){
++ DMESG("rtl8187_open process ");
++ down(&priv->wx_sem);
++ ret = rtl8180_up(dev);
++ up(&priv->wx_sem);
++ return ret;
++ }else{
++ DMESG("rtl8187_open process failed because radio off");
++ return -1;
++ }
++
++}
++
++
++int rtl8180_up(struct net_device *dev)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ if (priv->up == 1) return -1;
++
++ return _rtl8180_up(dev);
++}
++
++
++int rtl8180_close(struct net_device *dev)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ int ret;
++
++ if (priv->up == 0) return -1;
++
++ down(&priv->wx_sem);
++
++ //DMESG("rtl8187_close process");
++ ret = rtl8180_down(dev);
++#ifdef LED
++ priv->ieee80211->ieee80211_led_contorl(dev,LED_CTL_POWER_OFF);
++#endif
++ up(&priv->wx_sem);
++
++ return ret;
++
++}
++
++int rtl8180_down(struct net_device *dev)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ if (priv->up == 0) return -1;
++
++ priv->up=0;
++
++/* FIXME */
++ if (!netif_queue_stopped(dev))
++ netif_stop_queue(dev);
++
++ DMESG("rtl8180_down process");
++ rtl8180_rtx_disable(dev);
++ rtl8180_irq_disable(dev);
++//by amy for rate adaptive
++ del_timer_sync(&priv->rateadapter_timer);
++ cancel_delayed_work(&priv->ieee80211->rate_adapter_wq);
++//by amy for rate adaptive
++ del_timer_sync(&priv->watch_dog_timer);
++ cancel_delayed_work(&priv->ieee80211->watch_dog_wq);
++ cancel_delayed_work(&priv->ieee80211->hw_dig_wq);
++ cancel_delayed_work(&priv->ieee80211->tx_pw_wq);
++
++#ifdef SW_ANTE_DIVERSITY
++ del_timer_sync(&priv->SwAntennaDiversityTimer);
++ cancel_delayed_work(&priv->ieee80211->SwAntennaWorkItem);
++#endif
++
++ ieee80211_softmac_stop_protocol(priv->ieee80211);
++ MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_SW);
++ //amy,081212
++ memset(&(priv->ieee80211->current_network),0,sizeof(struct ieee80211_network));
++ return 0;
++}
++
++bool SetZebraRFPowerState8187B(struct net_device *dev,RT_RF_POWER_STATE eRFPowerState);
++
++void rtl8180_commit(struct net_device *dev)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ int i;
++
++ if (priv->up == 0) return ;
++ printk("==========>%s()\n", __FUNCTION__);
++
++ /* FIXME */
++ if (!netif_queue_stopped(dev))
++ netif_stop_queue(dev);
++
++//by amy for rate adaptive
++ del_timer_sync(&priv->rateadapter_timer);
++ cancel_delayed_work(&priv->ieee80211->rate_adapter_wq);
++//by amy for rate adaptive
++ del_timer_sync(&priv->watch_dog_timer);
++ cancel_delayed_work(&priv->ieee80211->watch_dog_wq);
++ cancel_delayed_work(&priv->ieee80211->hw_dig_wq);
++ cancel_delayed_work(&priv->ieee80211->tx_pw_wq);
++
++#ifdef SW_ANTE_DIVERSITY
++ del_timer_sync(&priv->SwAntennaDiversityTimer);
++ cancel_delayed_work(&priv->ieee80211->SwAntennaWorkItem);
++#endif
++ ieee80211_softmac_stop_protocol(priv->ieee80211);
++
++#if 0
++ if(priv->ieee80211->bHwRadioOff == false){
++ MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_HW);
++ mdelay(10);
++ MgntActSet_RF_State(dev, eRfOn, RF_CHANGE_BY_HW);
++ }
++#endif
++
++ rtl8180_irq_disable(dev);
++ rtl8180_rtx_disable(dev);
++
++ //test pending bug, john 20070815
++ //initialize tx_pending
++ for(i=0;i<0x10;i++) atomic_set(&(priv->tx_pending[i]), 0);
++
++ _rtl8180_up(dev);
++ priv->commit = 0;
++}
++
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
++void rtl8180_restart(struct work_struct *work)
++{
++ struct r8180_priv *priv = container_of(work, struct r8180_priv, reset_wq);
++ struct ieee80211_device* ieee = priv->ieee80211;//for commit crash
++ struct net_device *dev = ieee->dev;//for commit crash
++#else
++void rtl8180_restart(struct net_device *dev)
++{
++
++ struct r8180_priv *priv = ieee80211_priv(dev);
++#endif
++
++ down(&priv->wx_sem);
++
++ rtl8180_commit(dev);
++
++ up(&priv->wx_sem);
++}
++
++static void r8180_set_multicast(struct net_device *dev)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ short promisc;
++
++ //down(&priv->wx_sem);
++
++ /* FIXME FIXME */
++
++ promisc = (dev->flags & IFF_PROMISC) ? 1:0;
++
++ if (promisc != priv->promisc)
++ // rtl8180_commit(dev);
++
++ priv->promisc = promisc;
++
++ //schedule_work(&priv->reset_wq);
++ //up(&priv->wx_sem);
++}
++
++
++int r8180_set_mac_adr(struct net_device *dev, void *mac)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ struct sockaddr *addr = mac;
++
++ down(&priv->wx_sem);
++
++ memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
++
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
++ schedule_work(&priv->reset_wq);
++#else
++ schedule_task(&priv->reset_wq);
++#endif
++ up(&priv->wx_sem);
++
++ return 0;
++}
++
++struct ipw_param {
++ u32 cmd;
++ u8 sta_addr[ETH_ALEN];
++ union {
++ struct {
++ u8 name;
++ u32 value;
++ } wpa_param;
++ struct {
++ u32 len;
++ u8 reserved[32];
++ u8 data[0];
++ } wpa_ie;
++ struct{
++ u32 command;
++ u32 reason_code;
++ } mlme;
++ struct {
++ u8 alg[16];
++ u8 set_tx;
++ u32 err;
++ u8 idx;
++ u8 seq[8];
++ u16 key_len;
++ u8 key[0];
++ } crypt;
++
++ } u;
++};
++
++
++/* based on ipw2200 driver */
++int rtl8180_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
++{
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ struct iwreq *wrq = (struct iwreq *)rq;
++ int ret=-1;
++
++#ifdef JOHN_TKIP
++ u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
++
++ struct ieee80211_device *ieee = priv->ieee80211;
++ struct ipw_param *ipw = (struct ipw_param *)wrq->u.data.pointer;
++ u32 key[4];
++
++#endif
++
++#ifdef _RTL8187_EXT_PATCH_
++ if(priv->mshobj && (priv->ieee80211->iw_mode == priv->ieee80211->iw_ext_mode) && priv->mshobj->ext_patch_rtl8180_ioctl)
++ {
++ // DO NOT put the belowing function in critical section, due to it uses "spin lock"
++ if((ret = priv->mshobj->ext_patch_rtl8180_ioctl(dev, rq, cmd)) != -EOPNOTSUPP)
++ return ret;
++ }
++#endif
++
++ down(&priv->wx_sem);
++
++ switch (cmd) {
++ case RTL_IOCTL_WPA_SUPPLICANT:
++#ifdef JOHN_TKIP
++
++//the following code is specified for ipw driver in wpa_supplicant
++ if( ((u32*)wrq->u.data.pointer)[0]==3 ){
++
++
++ if( ((u32*)wrq->u.data.pointer)[7] &&
++ ( ((u32*)wrq->u.data.pointer)[3]==0x504d4343 ||
++ ((u32*)wrq->u.data.pointer)[3]==0x50494b54 )) {//50494b54 tkip and 504d4343 ccmp
++
++ //enable HW security of TKIP and CCMP
++ write_nic_byte(dev, WPA_CONFIG, SCR_TxSecEnable | SCR_RxSecEnable );
++
++ //copy key from wpa_supplicant ioctl info
++ key[0] = ((u32*)wrq->u.data.pointer)[12];
++ key[1] = ((u32*)wrq->u.data.pointer)[13];
++ key[2] = ((u32*)wrq->u.data.pointer)[14];
++ key[3] = ((u32*)wrq->u.data.pointer)[15];
++ switch (ieee->pairwise_key_type){
++ case KEY_TYPE_TKIP:
++ setKey( dev,
++ 0, //EntryNo
++ ipw->u.crypt.idx, //KeyIndex
++ KEY_TYPE_TKIP, //KeyType
++ (u8*)ieee->ap_mac_addr, //MacAddr
++ 0, //DefaultKey
++ key); //KeyContent
++ break;
++
++ case KEY_TYPE_CCMP:
++ setKey( dev,
++ 0, //EntryNo
++ ipw->u.crypt.idx, //KeyIndex
++ KEY_TYPE_CCMP, //KeyType
++ (u8*)ieee->ap_mac_addr, //MacAddr
++ 0, //DefaultKey
++ key); //KeyContent
++ break
++;
++ default:
++ printk("error on key_type: %d\n", ieee->pairwise_key_type);
++ break;
++ }
++ }
++
++ //group key for broadcast
++ if( ((u32*)wrq->u.data.pointer)[9] ) {
++
++ key[0] = ((u32*)wrq->u.data.pointer)[12];
++ key[1] = ((u32*)wrq->u.data.pointer)[13];
++ key[2] = ((u32*)wrq->u.data.pointer)[14];
++ key[3] = ((u32*)wrq->u.data.pointer)[15];
++
++ if( ((u32*)wrq->u.data.pointer)[3]==0x50494b54 ){//50494b54 is the ASCII code of TKIP in reversed order
++ setKey( dev,
++ 1, //EntryNo
++ ipw->u.crypt.idx,//KeyIndex
++ KEY_TYPE_TKIP, //KeyType
++ broadcast_addr, //MacAddr
++ 0, //DefaultKey
++ key); //KeyContent
++ }
++ else if( ((u32*)wrq->u.data.pointer)[3]==0x504d4343 ){//CCMP
++ setKey( dev,
++ 1, //EntryNo
++ ipw->u.crypt.idx,//KeyIndex
++ KEY_TYPE_CCMP, //KeyType
++ broadcast_addr, //MacAddr
++ 0, //DefaultKey
++ key); //KeyContent
++ }
++ else if( ((u32*)wrq->u.data.pointer)[3]==0x656e6f6e ){//none
++ //do nothing
++ }
++ else if( ((u32*)wrq->u.data.pointer)[3]==0x504557 ){//WEP
++ setKey( dev,
++ 1, //EntryNo
++ ipw->u.crypt.idx,//KeyIndex
++ KEY_TYPE_WEP40, //KeyType
++ broadcast_addr, //MacAddr
++ 0, //DefaultKey
++ key); //KeyContent
++ }
++ else printk("undefine group key type: %8x\n", ((u32*)wrq->u.data.pointer)[3]);
++ }
++
++ }
++#endif /*JOHN_TKIP*/
++
++
++#ifdef JOHN_HWSEC_DEBUG
++ {
++ int i;
++ //john's test 0711
++ printk("@@ wrq->u pointer = ");
++ for(i=0;i<wrq->u.data.length;i++){
++ if(i%10==0) printk("\n");
++ printk( "%8x|", ((u32*)wrq->u.data.pointer)[i] );
++ }
++ printk("\n");
++ }
++#endif /*JOHN_HWSEC_DEBUG*/
++ ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data);
++ break;
++
++ default:
++ ret = -EOPNOTSUPP;
++ break;
++ }
++
++ up(&priv->wx_sem);
++
++ return ret;
++}
++
++
++struct tx_desc {
++
++#ifdef _LINUX_BYTEORDER_LITTLE_ENDIAN_H
++
++
++//dword 0
++unsigned int tpktsize:12;
++unsigned int rsvd0:3;
++unsigned int no_encrypt:1;
++unsigned int splcp:1;
++unsigned int morefrag:1;
++unsigned int ctsen:1;
++unsigned int rtsrate:4;
++unsigned int rtsen:1;
++unsigned int txrate:4;
++unsigned int last:1;
++unsigned int first:1;
++unsigned int dmaok:1;
++unsigned int own:1;
++
++//dword 1
++unsigned short rtsdur;
++unsigned short length:15;
++unsigned short l_ext:1;
++
++//dword 2
++unsigned int bufaddr;
++
++
++//dword 3
++unsigned short rxlen:12;
++unsigned short rsvd1:3;
++unsigned short miccal:1;
++unsigned short dur;
++
++//dword 4
++unsigned int nextdescaddr;
++
++//dword 5
++unsigned char rtsagc;
++unsigned char retrylimit;
++unsigned short rtdb:1;
++unsigned short noacm:1;
++unsigned short pifs:1;
++unsigned short rsvd2:4;
++unsigned short rtsratefallback:4;
++unsigned short ratefallback:5;
++
++//dword 6
++unsigned short delaybound;
++unsigned short rsvd3:4;
++unsigned short agc:8;
++unsigned short antenna:1;
++unsigned short spc:2;
++unsigned short rsvd4:1;
++
++//dword 7
++unsigned char len_adjust:2;
++unsigned char rsvd5:1;
++unsigned char tpcdesen:1;
++unsigned char tpcpolarity:2;
++unsigned char tpcen:1;
++unsigned char pten:1;
++
++unsigned char bckey:6;
++unsigned char enbckey:1;
++unsigned char enpmpd:1;
++unsigned short fragqsz;
++
++
++#else
++
++#error "please modify tx_desc to your own\n"
++
++#endif
++
++
++} __attribute__((packed));
++
++struct rx_desc_rtl8187b {
++
++#ifdef _LINUX_BYTEORDER_LITTLE_ENDIAN_H
++
++//dword 0
++unsigned int rxlen:12;
++unsigned int icv:1;
++unsigned int crc32:1;
++unsigned int pwrmgt:1;
++unsigned int res:1;
++unsigned int bar:1;
++unsigned int pam:1;
++unsigned int mar:1;
++unsigned int qos:1;
++unsigned int rxrate:4;
++unsigned int trsw:1;
++unsigned int splcp:1;
++unsigned int fovf:1;
++unsigned int dmafail:1;
++unsigned int last:1;
++unsigned int first:1;
++unsigned int eor:1;
++unsigned int own:1;
++
++
++//dword 1
++unsigned int tsftl;
++
++
++//dword 2
++unsigned int tsfth;
++
++
++//dword 3
++unsigned char sq;
++unsigned char rssi:7;
++unsigned char antenna:1;
++
++unsigned char agc;
++unsigned char decrypted:1;
++unsigned char wakeup:1;
++unsigned char shift:1;
++unsigned char rsvd0:5;
++
++//dword 4
++unsigned int num_mcsi:4;
++unsigned int snr_long2end:6;
++unsigned int cfo_bias:6;
++
++int pwdb_g12:8;
++unsigned int fot:8;
++
++
++
++
++#else
++
++#error "please modify tx_desc to your own\n"
++
++#endif
++
++}__attribute__((packed));
++
++
++
++struct rx_desc_rtl8187 {
++
++#ifdef _LINUX_BYTEORDER_LITTLE_ENDIAN_H
++
++//dword 0
++unsigned int rxlen:12;
++unsigned int icv:1;
++unsigned int crc32:1;
++unsigned int pwrmgt:1;
++unsigned int res:1;
++unsigned int bar:1;
++unsigned int pam:1;
++unsigned int mar:1;
++unsigned int qos:1;
++unsigned int rxrate:4;
++unsigned int trsw:1;
++unsigned int splcp:1;
++unsigned int fovf:1;
++unsigned int dmafail:1;
++unsigned int last:1;
++unsigned int first:1;
++unsigned int eor:1;
++unsigned int own:1;
++
++//dword 1
++unsigned char sq;
++unsigned char rssi:7;
++unsigned char antenna:1;
++
++unsigned char agc;
++unsigned char decrypted:1;
++unsigned char wakeup:1;
++unsigned char shift:1;
++unsigned char rsvd0:5;
++
++//dword 2
++unsigned int tsftl;
++
++//dword 3
++unsigned int tsfth;
++
++
++
++#else
++
++#error "please modify tx_desc to your own\n"
++
++#endif
++
++
++}__attribute__((packed));
++
++
++
++union rx_desc {
++
++struct rx_desc_rtl8187b desc_87b;
++struct rx_desc_rtl8187 desc_87;
++
++}__attribute__((packed));
++
++//
++// Description:
++// Perform signal smoothing for dynamic mechanism.
++// This is different with PerformSignalSmoothing8187 in smoothing fomula.
++// No dramatic adjustion is apply because dynamic mechanism need some degree
++// of correctness.
++// 2007.01.23, by shien chang.
++//
++void PerformUndecoratedSignalSmoothing8187(struct net_device *dev, struct ieee80211_rx_stats *stats)
++{
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++ bool bCckRate = rtl8180_IsWirelessBMode(rtl8180_rate2rate(stats->rate));
++
++ if(NIC_8187 == priv->card_8187) {
++ if(priv->UndecoratedSmoothedSS >= 0) {
++ priv->UndecoratedSmoothedSS = ((priv->UndecoratedSmoothedSS * 50) + (stats->signalstrength * 11)) / 60;
++ }else{
++ priv->UndecoratedSmoothedSS = stats->signalstrength;
++ }
++ } else {
++ // Determin the current packet is CCK rate, by Bruce, 2007-04-12.
++ priv->bCurCCKPkt = bCckRate;
++
++ // Tesing for SD3 DZ, by Bruce, 2007-04-11.
++ if(priv->UndecoratedSmoothedSS >= 0) {
++ priv->UndecoratedSmoothedSS = ((priv->UndecoratedSmoothedSS * 5) + (stats->signalstrength * 10)) / 6;
++ }else{
++ priv->UndecoratedSmoothedSS = stats->signalstrength * 10;
++ }
++
++ //
++ // Bacause the AGC parameter is not exactly correct under high power (AGC saturation), we need to record the RSSI value to be
++ // referenced by DoRxHighPower. It is not necessary to record this value when this packet is sent by OFDM rate.
++ // Advised by SD3 DZ, by Bruce, 2007-04-12.
++ //
++ if(bCckRate){
++ priv->CurCCKRSSI = stats->signal;
++ }else{
++ priv->CurCCKRSSI = 0;
++ }
++ }
++ //printk("Sommthing SignalSterngth (%d) => UndecoratedSmoothedSS (%d)\n", stats->signalstrength, priv->UndecoratedSmoothedSS);
++}
++
++#ifdef THOMAS_SKB
++void rtl8180_irq_rx_tasklet(struct r8180_priv *priv)
++{
++ int status,len,flen;
++
++#ifdef SW_ANTE_DIVERSITY
++ u8 Antenna = 0;
++#endif
++ u32 SignalStrength = 0;
++ u32 quality = 0;
++ bool bCckRate = false;
++ char RX_PWDB = 0;
++ long RecvSignalPower=0;
++ struct sk_buff *skb;
++ struct sk_buff *skb2;//skb for check out of memory
++ union rx_desc *desc;
++ //struct urb *rx_urb = priv->rxurb_task;
++ struct ieee80211_hdr *hdr;//by amy
++ u16 fc,type;
++ u8 bHwError=0,bCRC=0,bICV=0;
++ long SignalStrengthIndex = 0;
++ struct ieee80211_rx_stats stats = {
++ .signal = 0,
++ .noise = -98,
++ .rate = 0,
++ //.mac_time = jiffies,
++ .freq = IEEE80211_24GHZ_BAND,
++ };
++
++ int *prx_inx=&priv->rx_inx;
++ struct urb *rx_urb=priv->rx_urb[*prx_inx]; //changed by jackson
++ struct net_device *dev = (struct net_device*)rx_urb->context;
++ //DMESG("=====>RX %x ",rx_urb->status);
++
++ skb = priv->pp_rxskb[*prx_inx];
++ status = rx_urb->status;
++ skb2 = dev_alloc_skb(RX_URB_SIZE);
++
++ if (skb2 == NULL){
++ printk(KERN_ALERT "No Skb For RX!/n");
++ //rx_urb->transfer_buffer = skb->data;
++ //priv->pp_rxskb[*prx_inx] = skb;
++ } else {
++
++ if(status == 0)
++ {
++ if(NIC_8187B == priv->card_8187)
++ {
++ stats.nic_type = NIC_8187B;
++ len = rx_urb->actual_length;
++ len -= sizeof (struct rx_desc_rtl8187b);
++ desc = (union rx_desc *)(rx_urb->transfer_buffer + len);
++ flen = desc->desc_87b.rxlen ;
++
++ if( flen <= rx_urb->actual_length){
++#if 1
++#ifdef SW_ANTE_DIVERSITY
++ Antenna = desc->desc_87b.antenna;
++#endif
++ stats.mac_time[0] = desc->desc_87b.tsftl;
++ stats.mac_time[1] = desc->desc_87b.tsfth;
++
++ stats.signal = desc->desc_87b.rssi;
++ //stats.noise = desc->desc_87b.sq;
++ quality = desc->desc_87b.sq;
++ stats.rate = desc->desc_87b.rxrate;
++ bCckRate = rtl8180_IsWirelessBMode(rtl8180_rate2rate(stats.rate));
++
++ if(!bCckRate) { // OFDM rate.
++ if(desc->desc_87b.pwdb_g12 < -106)
++ SignalStrength = 0;
++ else
++ SignalStrength = desc->desc_87b.pwdb_g12 + 106;
++ RX_PWDB = (desc->desc_87b.pwdb_g12)/2 -42;
++ } else { // CCK rate.
++ if(desc->desc_87b.agc> 174)
++ SignalStrength = 0;
++ else
++ SignalStrength = 174 - desc->desc_87b.agc;
++ RX_PWDB = ((desc->desc_87b.agc)/2)*(-1) - 8;
++ }
++
++ //lzm mod 081028 based on windows driver
++ //compensate SignalStrength when switch TR to SW controled
++ if(priv->TrSwitchState == TR_SW_TX) {
++ SignalStrength = SignalStrength + 54;
++ RX_PWDB = RX_PWDB + 27;
++ }
++
++ if(SignalStrength > 100)
++ SignalStrength = 100;
++ SignalStrength = (SignalStrength * 70) / 100 + 30;
++
++ if(SignalStrength > 50)
++ SignalStrength = SignalStrength + 10;
++ if(SignalStrength > 100)
++ SignalStrength = 100;
++
++ RecvSignalPower = RX_PWDB;
++ //printk("SignalStrength = %d \n",SignalStrength);
++ bHwError = (desc->desc_87b.fovf | desc->desc_87b.icv | desc->desc_87b.crc32);
++ bCRC = desc->desc_87b.crc32;
++ bICV = desc->desc_87b.icv;
++ priv->wstats.qual.level = (u8)SignalStrength;
++
++ if(!bCckRate){
++ if (quality > 127)
++ quality = 0;
++ else if (quality <27)
++ quality = 100;
++ else
++ quality = 127 - quality;
++ } else {
++ if(quality > 64)
++ quality = 0;
++ else
++ quality = ((64-quality)*100)/64;
++ }
++
++
++ priv ->wstats.qual.qual = quality;
++ priv->wstats.qual.noise = 100 - priv ->wstats.qual.qual;
++
++ stats.signalstrength = (u8)SignalStrength;
++ stats.signal = (u8)quality;
++ stats.noise = desc->desc_87b.snr_long2end;
++
++ skb_put(skb,flen-4);
++
++ priv->stats.rxok++;
++ //by amy
++ hdr = (struct ieee80211_hdr *)skb->data;
++ fc = le16_to_cpu(hdr->frame_ctl);
++ type = WLAN_FC_GET_TYPE(fc);
++
++ if((IEEE80211_FTYPE_CTL != type) &&
++ (eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3)) && (!bHwError) && (!bCRC)&& (!bICV))
++ {
++ // Perform signal smoothing for dynamic mechanism on demand.
++ // This is different with PerformSignalSmoothing8187 in smoothing fomula.
++ // No dramatic adjustion is apply because dynamic mechanism need some degree
++ // of correctness. 2007.01.23, by shien chang.
++ PerformUndecoratedSignalSmoothing8187(dev, &stats);
++
++ //Update signal strength and realted into private RxStats for UI query.
++ SignalStrengthIndex = NetgearSignalStrengthTranslate(priv->LastSignalStrengthInPercent, priv->wstats.qual.level);
++ priv->LastSignalStrengthInPercent = SignalStrengthIndex;
++ priv->SignalStrength = TranslateToDbm8187((u8)SignalStrengthIndex);
++ priv->SignalQuality = (priv->SignalQuality*5+quality+5)/6;
++ priv->RecvSignalPower = (priv->RecvSignalPower * 5 + RecvSignalPower - 1) / 6;
++#ifdef SW_ANTE_DIVERSITY
++ priv->LastRxPktAntenna = Antenna ? 1:0;
++ SwAntennaDiversityRxOk8185(dev, SignalStrength);
++#endif
++ }
++ //by amy
++#endif
++ if(!ieee80211_rx(priv->ieee80211,skb, &stats)) {
++ dev_kfree_skb_any(skb);
++ }
++ }else {
++ priv->stats.rxurberr++;
++ printk("URB Error flen:%d actual_length:%d\n", flen , rx_urb->actual_length);
++ dev_kfree_skb_any(skb);
++ }
++ } else {
++ stats.nic_type = NIC_8187;
++ len = rx_urb->actual_length;
++ len -= sizeof (struct rx_desc_rtl8187);
++ desc = (union rx_desc *)(rx_urb->transfer_buffer + len);
++ flen = desc->desc_87.rxlen ;
++
++ if(flen <= rx_urb->actual_length){
++ stats.signal = desc->desc_87.rssi;
++ stats.noise = desc->desc_87.sq;
++ stats.rate = desc->desc_87.rxrate;
++ stats.mac_time[0] = desc->desc_87.tsftl;
++ stats.mac_time[1] = desc->desc_87.tsfth;
++ SignalStrength = (desc->desc_87.agc&0xfe) >> 1;
++ if( ((stats.rate <= 22) && (stats.rate != 12) && (stats.rate != 18)) || (stats.rate == 44) )//need to translate to real rate here
++ bCckRate= TRUE;
++ if (!bCckRate)
++ {
++ if (SignalStrength > 90) SignalStrength = 90;
++ else if (SignalStrength < 25) SignalStrength = 25;
++ SignalStrength = ((90 - SignalStrength)*100)/65;
++ }
++ else
++ {
++ if (SignalStrength >95) SignalStrength = 95;
++ else if (SignalStrength < 30) SignalStrength = 30;
++ SignalStrength = ((95 - SignalStrength)*100)/65;
++ }
++ stats.signalstrength = (u8)SignalStrength;
++
++ skb_put(skb,flen-4);
++
++ priv->stats.rxok++;
++
++ if(!ieee80211_rx(priv->ieee80211,skb, &stats))
++ dev_kfree_skb_any(skb);
++
++
++ }else {
++ priv->stats.rxurberr++;
++ printk("URB Error flen:%d actual_length:%d\n", flen , rx_urb->actual_length);
++ dev_kfree_skb_any(skb);
++ }
++ }
++ }else{
++
++ //printk("RX Status Error!\n");
++ priv->stats.rxstaterr++;
++ priv->ieee80211->stats.rx_errors++;
++ dev_kfree_skb_any(skb);
++
++ }
++
++ rx_urb->transfer_buffer = skb2->data;
++
++ priv->pp_rxskb[*prx_inx] = skb2;
++ }
++
++ if(status != -ENOENT ){
++ rtl8187_rx_urbsubmit(dev,rx_urb);
++ } else {
++ priv->pp_rxskb[*prx_inx] = NULL;
++ dev_kfree_skb_any(skb2);
++ //printk("RX process %d aborted due to explicit shutdown (%x)(%d)\n ", *prx_inx, status, status);
++ }
++
++ if (*prx_inx == (MAX_RX_URB -1))
++ *prx_inx = 0;
++ else
++ *prx_inx = *prx_inx + 1;
++}
++#endif
++
++#ifdef THOMAS_TASKLET
++void rtl8180_irq_rx_tasklet_new(struct r8180_priv *priv){
++ unsigned long flags;
++ while( atomic_read( &priv->irt_counter ) ){
++ spin_lock_irqsave(&priv->irq_lock,flags);//added by thomas
++ rtl8180_irq_rx_tasklet(priv);
++ spin_unlock_irqrestore(&priv->irq_lock,flags);//added by thomas
++ if(atomic_read(&priv->irt_counter) >= 1)
++ atomic_dec( &priv->irt_counter );
++ }
++}
++#endif
++/****************************************************************************
++ ---------------------------- USB_STUFF---------------------------
++*****************************************************************************/
++
++static const struct net_device_ops rtl8187_netdev_ops = {
++ .ndo_open = rtl8180_open,
++ .ndo_stop = rtl8180_close,
++ .ndo_tx_timeout = tx_timeout,
++ .ndo_do_ioctl = rtl8180_ioctl,
++ .ndo_set_multicast_list = r8180_set_multicast,
++ .ndo_set_mac_address = r8180_set_mac_adr,
++ .ndo_validate_addr = eth_validate_addr,
++ .ndo_change_mtu = eth_change_mtu,
++ .ndo_start_xmit = ieee80211_xmit,
++ .ndo_get_stats = rtl8180_stats,
++};
++
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
++static int __devinit rtl8187_usb_probe(struct usb_interface *intf,
++ const struct usb_device_id *id)
++#else
++static void * __devinit rtl8187_usb_probe(struct usb_device *udev,
++ unsigned int ifnum,
++ const struct usb_device_id *id)
++#endif
++{
++ struct net_device *dev = NULL;
++ struct r8180_priv *priv= NULL;
++
++
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
++ struct usb_device *udev = interface_to_usbdev(intf);
++#endif
++
++ dev = alloc_ieee80211(sizeof(struct r8180_priv));
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
++ SET_MODULE_OWNER(dev);
++#endif
++
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
++ usb_set_intfdata(intf, dev);
++ SET_NETDEV_DEV(dev, &intf->dev);
++#endif
++ priv = ieee80211_priv(dev);
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
++ priv->ieee80211 = netdev_priv(dev);
++#else
++ priv->ieee80211 = (struct net_device *)dev->priv;
++#endif
++ priv->udev=udev;
++#ifdef CPU_64BIT
++ priv->usb_buf = kmalloc(0x200, GFP_KERNEL);
++ priv->usb_pool = dma_pool_create("rtl8187b", NULL, 64, 64, 0);
++#endif
++//lzm add for write time out test
++#ifdef DEBUG_RW_REGISTER
++ {
++ int reg_index = 0;
++ for(reg_index = 0; reg_index <= 199; reg_index++)
++ {
++ priv->write_read_registers[reg_index].address = 0;
++ priv->write_read_registers[reg_index].content = 0;
++ priv->write_read_registers[reg_index].flag = 0;
++ }
++ priv->write_read_register_index = 0;
++ }
++#endif
++ //init netdev_ops, added by falcon....
++ dev->netdev_ops = &rtl8187_netdev_ops;
++
++ dev->wireless_handlers = &r8180_wx_handlers_def;
++#if WIRELESS_EXT >= 12
++#if WIRELESS_EXT < 17
++ dev->get_wireless_stats = r8180_get_wireless_stats;
++#endif
++ dev->wireless_handlers = (struct iw_handler_def *) &r8180_wx_handlers_def;
++#endif
++
++ dev->type=ARPHRD_ETHER;
++ dev->watchdog_timeo = HZ*3; //modified by john, 0805
++
++ if (dev_alloc_name(dev, ifname) < 0){
++ DMESG("Oops: devname already taken! Trying wlan%%d...\n");
++ ifname = "wlan%d";
++ dev_alloc_name(dev, ifname);
++ }
++
++ if(rtl8180_init(dev)!=0){
++ DMESG("Initialization failed");
++ goto fail;
++ }
++
++ netif_carrier_off(dev);
++ netif_stop_queue(dev);
++
++ register_netdev(dev);
++
++ rtl8180_proc_init_one(dev);
++
++ /* init rfkill */
++ r8187b_rfkill_init(dev);
++
++ DMESG("Driver probe completed");
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++ return dev;
++#else
++ return 0;
++#endif
++
++
++fail:
++ free_ieee80211(dev);
++
++ DMESG("wlan driver load failed\n");
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++ return NULL;
++#else
++ return -ENODEV;
++#endif
++
++}
++
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
++static void __devexit rtl8187_usb_disconnect(struct usb_interface *intf)
++#else
++static void __devexit rtl8187_usb_disconnect(struct usb_device *udev, void *ptr)
++#endif
++{
++ struct r8180_priv *priv = NULL;
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
++ struct net_device *dev = usb_get_intfdata(intf);
++#else
++ struct net_device *dev = (struct net_device *)ptr;
++#endif
++ if(dev){
++ unregister_netdev(dev);
++
++ priv=ieee80211_priv(dev);
++
++ MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_SW);
++
++#ifdef _RTL8187_EXT_PATCH_
++ if(priv && priv->mshobj)
++ {
++ if(priv->mshobj->ext_patch_remove_proc)
++ priv->mshobj->ext_patch_remove_proc(priv);
++ priv->ieee80211->ext_patch_ieee80211_start_protocol = 0;
++ priv->ieee80211->ext_patch_ieee80211_stop_protocol = 0;
++ priv->ieee80211->ext_patch_ieee80211_probe_req_1 = 0;
++ priv->ieee80211->ext_patch_ieee80211_probe_req_2 = 0;
++ priv->ieee80211->ext_patch_ieee80211_association_req_1 = 0;
++ priv->ieee80211->ext_patch_ieee80211_association_req_2 = 0;
++ priv->ieee80211->ext_patch_ieee80211_assoc_resp_by_net_1 = 0;
++ priv->ieee80211->ext_patch_ieee80211_assoc_resp_by_net_2 = 0;
++ priv->ieee80211->ext_patch_ieee80211_rx_frame_softmac_on_auth =0;
++ priv->ieee80211->ext_patch_ieee80211_rx_frame_softmac_on_deauth =0;
++ priv->ieee80211->ext_patch_ieee80211_rx_frame_softmac_on_assoc_req = 0;
++ priv->ieee80211->ext_patch_ieee80211_rx_frame_softmac_on_assoc_rsp = 0;
++ priv->ieee80211->ext_patch_ieee80211_ext_stop_scan_wq_set_channel = 0;
++ priv->ieee80211->ext_patch_ieee80211_process_probe_response_1 = 0;
++ priv->ieee80211->ext_patch_ieee80211_rx_mgt_on_probe_req = 0;
++ priv->ieee80211->ext_patch_ieee80211_rx_mgt_update_expire = 0;
++ priv->ieee80211->ext_patch_ieee80211_rx_on_rx = 0;
++ priv->ieee80211->ext_patch_get_beacon_get_probersp = 0;
++ priv->ieee80211->ext_patch_ieee80211_xmit = 0;
++ priv->ieee80211->ext_patch_ieee80211_rx_frame_get_hdrlen = 0;
++ priv->ieee80211->ext_patch_ieee80211_rx_is_valid_framectl = 0;
++ priv->ieee80211->ext_patch_ieee80211_rx_process_dataframe = 0;
++ // priv->ieee80211->ext_patch_is_duplicate_packet = 0;
++ priv->ieee80211->ext_patch_ieee80211_softmac_xmit_get_rate = 0;
++ free_mshobj(&priv->mshobj);
++ }
++#endif // _RTL8187_EXT_PATCH_
++
++ rtl8180_proc_remove_one(dev);
++
++ rtl8180_down(dev);
++ priv->rf_close(dev);
++
++ //rtl8180_rtx_disable(dev);
++ rtl8187_usb_deleteendpoints(dev);
++#ifdef LED
++ DeInitSwLeds(dev);
++#endif
++ rtl8180_irq_disable(dev);
++ rtl8180_reset(dev);
++ mdelay(10);
++
++ }
++
++#ifdef CPU_64BIT
++ if(priv->usb_buf)
++ kfree(priv->usb_buf);
++ if(priv->usb_pool) {
++ dma_pool_destroy(priv->usb_pool);
++ priv->usb_pool = NULL;
++ }
++#endif
++ free_ieee80211(dev);
++ DMESG("wlan driver removed");
++}
++
++/* fun with the built-in ieee80211 stack... */
++extern int ieee80211_crypto_init(void);
++extern void ieee80211_crypto_deinit(void);
++extern int ieee80211_crypto_tkip_init(void);
++extern void ieee80211_crypto_tkip_exit(void);
++extern int ieee80211_crypto_ccmp_init(void);
++extern void ieee80211_crypto_ccmp_exit(void);
++extern int ieee80211_crypto_wep_init(void);
++extern void ieee80211_crypto_wep_exit(void);
++
++static int __init rtl8187_usb_module_init(void)
++{
++ int ret;
++
++ ret = ieee80211_crypto_init();
++ if (ret) {
++ printk(KERN_ERR "ieee80211_crypto_init() failed %d\n", ret);
++ return ret;
++ }
++ ret = ieee80211_crypto_tkip_init();
++ if (ret) {
++ printk(KERN_ERR "ieee80211_crypto_tkip_init() failed %d\n", ret);
++ return ret;
++ }
++ ret = ieee80211_crypto_ccmp_init();
++ if (ret) {
++ printk(KERN_ERR "ieee80211_crypto_ccmp_init() failed %d\n", ret);
++ return ret;
++ }
++ ret = ieee80211_crypto_wep_init();
++ if (ret) {
++ printk(KERN_ERR "ieee80211_crypto_wep_init() failed %d\n", ret);
++ return ret;
++ }
++
++ printk("\nLinux kernel driver for RTL8187/RTL8187B based WLAN cards\n");
++ printk("Copyright (c) 2004-2008, Realsil Wlan\n");
++ DMESG("Initializing module");
++ DMESG("Wireless extensions version %d", WIRELESS_EXT);
++ rtl8180_proc_module_init();
++ return usb_register(&rtl8187_usb_driver);
++}
++
++static void __exit rtl8187_usb_module_exit(void)
++{
++ r8187b_rfkill_exit();
++ usb_deregister(&rtl8187_usb_driver);
++ rtl8180_proc_module_remove();
++ ieee80211_crypto_tkip_exit();
++ ieee80211_crypto_ccmp_exit();
++ ieee80211_crypto_wep_exit();
++ ieee80211_crypto_deinit();
++
++ DMESG("Exiting\n");
++}
++
++
++void rtl8180_try_wake_queue(struct net_device *dev, int pri)
++{
++ unsigned long flags;
++ short enough_desc;
++ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
++
++ spin_lock_irqsave(&priv->tx_lock,flags);
++ enough_desc = check_nic_enought_desc(dev,pri);
++ spin_unlock_irqrestore(&priv->tx_lock,flags);
++
++ if(enough_desc)
++ ieee80211_wake_queue(priv->ieee80211);
++}
++
++#ifdef JOHN_HWSEC
++void EnableHWSecurityConfig8187(struct net_device *dev)
++{
++ u8 SECR_value = 0x0;
++ SECR_value = SCR_TxSecEnable | SCR_RxSecEnable;
++ {
++ write_nic_byte(dev, WPA_CONFIG, 0x7);//SECR_value | SCR_UseDK );
++ }
++}
++
++void setKey(struct net_device *dev,
++ u8 EntryNo,
++ u8 KeyIndex,
++ u16 KeyType,
++ u8 *MacAddr,
++ u8 DefaultKey,
++ u32 *KeyContent )
++{
++ u32 TargetCommand = 0;
++ u32 TargetContent = 0;
++ u16 usConfig = 0;
++ int i;
++ usConfig |= BIT15 | (KeyType<<2) | (DefaultKey<<5) | KeyIndex;
++
++
++ for(i=0 ; i<6 ; i++){
++ TargetCommand = i+6*EntryNo;
++ TargetCommand |= BIT31|BIT16;
++
++ if(i==0){//MAC|Config
++ TargetContent = (u32)(*(MacAddr+0)) << 16|
++ (u32)(*(MacAddr+1)) << 24|
++ (u32)usConfig;
++
++ write_nic_dword(dev, WCAMI, TargetContent);
++ write_nic_dword(dev, RWCAM, TargetCommand);
++ //printk("setkey cam =%8x\n", read_cam(dev, i+6*EntryNo));
++ } else if(i==1){//MAC
++ TargetContent = (u32)(*(MacAddr+2)) |
++ (u32)(*(MacAddr+3)) << 8|
++ (u32)(*(MacAddr+4)) << 16|
++ (u32)(*(MacAddr+5)) << 24;
++ write_nic_dword(dev, WCAMI, TargetContent);
++ write_nic_dword(dev, RWCAM, TargetCommand);
++ } else { //Key Material
++ write_nic_dword(dev, WCAMI, (u32)(*(KeyContent+i-2)) );
++ write_nic_dword(dev, RWCAM, TargetCommand);
++ }
++ }
++
++}
++#endif
++
++/****************************************************************************
++ --------------------------- RF power on/power off -----------------
++*****************************************************************************/
++
++/*
++ * the interface for changing the rfkill state
++ * @dev: the device of r8187b
++ * @eRfPowerStateToSet: the state we need to change,
++ * eRfOn: power on
++ * eRfOff: power off
++ *
++ * This function should be called by the SCI interrupt handler when the
++ * KEY_WLAN event happen(or install to the notify function of the SCI
++ * interrupt) or called in the wifi_set function of the rfkill interface for
++ * user-space, and also, it can be called to initialize the wifi state, and
++ * called when suspend/resume.
++ */
++
++void r8187b_wifi_change_rfkill_state(struct net_device *dev, RT_RF_POWER_STATE eRfPowerStateToSet)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++ if (eRfPowerStateToSet == eRfOn)
++ priv->ieee80211->bHwRadioOff = false;
++ else
++ priv->ieee80211->bHwRadioOff = true;
++
++ DMESG("SCI interrupt Methord Will Turn Radio %s",
++ (priv->ieee80211->bHwRadioOff == true) ? "Off" : "On");
++
++#ifdef LED //by lizhaoming
++ if (priv->ieee80211->bHwRadioOff)
++ priv->ieee80211->ieee80211_led_contorl(dev, LED_CTL_POWER_OFF);
++ else
++ priv->ieee80211->ieee80211_led_contorl(dev, LED_CTL_POWER_ON);
++#endif
++
++ MgntActSet_RF_State(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW);
++
++ /* report the rfkill state to the user-space via uevent interface */
++ r8187b_wifi_report_state(priv);
++}
++
++/***************************************************************************
++ ------------------- module init / exit stubs ----------------
++****************************************************************************/
++module_init(rtl8187_usb_module_init);
++module_exit(rtl8187_usb_module_exit);
+diff --git a/drivers/net/wireless/rtl8187b/r8187_led.c b/drivers/net/wireless/rtl8187b/r8187_led.c
+new file mode 100644
+index 0000000..dba3b5a
+--- /dev/null
++++ b/drivers/net/wireless/rtl8187b/r8187_led.c
+@@ -0,0 +1,1629 @@
++/*++
++Copyright (c) Realtek Semiconductor Corp. All rights reserved.
++
++Module Name:
++ r8187_led.c
++
++Abstract:
++ RTL8187 LED control functions
++
++Major Change History:
++ When Who What
++ ---------- --------------- -------------------------------
++ 2006-09-07 Xiong Created
++
++Notes:
++
++--*/
++
++/*--------------------------Include File------------------------------------*/
++#include "ieee80211/ieee80211.h"
++#include "r8180_hw.h"
++#include "r8187.h"
++#include "r8180_93cx6.h"
++#include "r8187_led.h"
++
++/**
++*
++* Initialization function for Sw Leds controll.
++*
++* \param dev The net device for this driver.
++* \return void.
++*
++* Note:
++*
++*/
++
++void
++InitSwLeds(
++ struct net_device *dev
++ )
++{
++
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ u16 usValue;
++// printk("========>%s()\n", __FUNCTION__);
++
++// priv->CustomerID = RT_CID_87B_DELL; //by lizhaoming for DELL 2008.6.3
++ priv->CustomerID = RT_CID_DEFAULT; //just set to default now
++ priv->bEnableLedCtrl = 1;
++ priv->PsrValue = read_nic_byte(dev, PSR);
++ usValue = eprom_read(dev, EEPROM_SW_REVD_OFFSET >> 1);
++ priv->EEPROMCustomerID = (u8)( usValue & EEPROM_CID_MASK );
++ DMESG("EEPROM Customer ID: %02X", priv->EEPROMCustomerID);
++
++ if(priv->CustomerID == RT_CID_DEFAULT)
++ { // If we have not yet change priv->CustomerID in register,
++ // we initialzie it from that of EEPROM with proper translation, 2006.07.03, by rcnjko.
++ switch(priv->EEPROMCustomerID)
++ {
++ case EEPROM_CID_RSVD0:
++ case EEPROM_CID_RSVD1:
++ priv->CustomerID = RT_CID_DEFAULT;
++ break;
++
++ case EEPROM_CID_ALPHA0:
++ priv->CustomerID = RT_CID_8187_ALPHA0;
++ break;
++
++ case EEPROM_CID_SERCOMM_PS:
++ priv->CustomerID = RT_CID_8187_SERCOMM_PS;
++ break;
++
++ case EEPROM_CID_HW_LED:
++ priv->CustomerID = RT_CID_8187_HW_LED;
++ break;
++
++ case EEPROM_CID_QMI:
++ priv->CustomerID = RT_CID_87B_QMI;
++ break;
++
++ case EEPROM_CID_DELL:
++ priv->CustomerID = RT_CID_87B_DELL;
++ break;
++
++ default:
++ // Invalid value, so, we use default value instead.
++ priv->CustomerID = RT_CID_DEFAULT;
++ break;
++ }
++ }
++ switch(priv->CustomerID)
++ {
++ case RT_CID_DEFAULT:
++ priv->LedStrategy = SW_LED_MODE0;
++ break;
++
++ case RT_CID_8187_ALPHA0:
++ priv->LedStrategy = SW_LED_MODE1;
++ break;
++
++ case RT_CID_8187_SERCOMM_PS:
++ priv->LedStrategy = SW_LED_MODE3;
++ break;
++
++ case RT_CID_87B_QMI:
++ priv->LedStrategy = SW_LED_MODE4;
++ break;
++
++ case RT_CID_87B_DELL:
++ priv->LedStrategy = SW_LED_MODE5;
++ break;
++
++ case RT_CID_8187_HW_LED:
++ priv->LedStrategy = HW_LED;
++ break;
++
++ default:
++ priv->LedStrategy = SW_LED_MODE0;
++ break;
++ }
++
++ InitLed8187(dev,
++ &(priv->Gpio0Led),
++ LED_PIN_GPIO0,
++ Gpio0LedBlinkTimerCallback);
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
++ INIT_WORK(&priv->Gpio0LedWorkItem,
++ (void(*)(void*))Gpio0LedWorkItemCallback, dev);
++
++ InitLed8187(dev,
++ &(priv->SwLed0),
++ LED_PIN_LED0,
++ SwLed0BlinkTimerCallback);
++ INIT_WORK(&priv->SwLed0WorkItem,
++ (void(*)(void*))SwLed0WorkItemCallback, dev);
++
++ InitLed8187(dev,
++ &(priv->SwLed1),
++ LED_PIN_LED1,
++ SwLed1BlinkTimerCallback);
++ INIT_WORK(&priv->SwLed1WorkItem,
++ (void(*)(void*))SwLed1WorkItemCallback, dev);
++#else
++INIT_WORK(&priv->Gpio0LedWorkItem,
++ Gpio0LedWorkItemCallback);
++
++ InitLed8187(dev,
++ &(priv->SwLed0),
++ LED_PIN_LED0,
++ SwLed0BlinkTimerCallback);
++ INIT_WORK(&priv->SwLed0WorkItem,
++ SwLed0WorkItemCallback);
++
++ InitLed8187(dev,
++ &(priv->SwLed1),
++ LED_PIN_LED1,
++ SwLed1BlinkTimerCallback);
++ INIT_WORK(&priv->SwLed1WorkItem,
++ SwLed1WorkItemCallback);
++#endif
++}
++
++void
++DeInitSwLeds(
++ struct net_device *dev
++ )
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++// printk("=========>%s In\n", __FUNCTION__);
++ DeInitLed8187(dev, &(priv->Gpio0Led));
++ DeInitLed8187(dev, &(priv->SwLed0));
++ DeInitLed8187(dev, &(priv->SwLed1));
++}
++
++void
++InitLed8187(
++ struct net_device *dev,
++ PLED_8187 pLed,
++ LED_PIN_8187 LedPin,
++ void * BlinkCallBackFunc)
++{
++// printk("=========>%s In\n", __FUNCTION__);
++ pLed->LedPin = LedPin;
++
++ pLed->bLedOn = 0;
++ pLed->CurrLedState = LED_OFF;
++
++ pLed->bLedBlinkInProgress = 0;
++ pLed->BlinkTimes = 0;
++ pLed->BlinkingLedState = LED_OFF;
++
++ init_timer(&(pLed->BlinkTimer));
++ pLed->BlinkTimer.data = (unsigned long)dev;
++ pLed->BlinkTimer.function = BlinkCallBackFunc;
++ //PlatformInitializeTimer(dev, &(pLed->BlinkTimer), BlinkCallBackFunc);
++}
++
++void
++DeInitLed8187(
++ struct net_device *dev,
++ PLED_8187 pLed)
++{
++ //printk("=========>%s In\n", __FUNCTION__);
++ //PlatformCancelTimer(dev, &(pLed->BlinkTimer));
++ del_timer_sync(&(pLed->BlinkTimer));
++ // We should reset bLedBlinkInProgress if we cancel the LedControlTimer, 2005.03.10, by rcnjko.
++ pLed->bLedBlinkInProgress = 0;
++}
++
++void
++LedControl8187(
++ struct net_device *dev,
++ LED_CTL_MODE LedAction
++)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++// printk("=========>%s In\n", __FUNCTION__);
++ if( priv->bEnableLedCtrl == 0)
++ return;
++
++
++ if( priv->eRFPowerState != eRfOn &&
++ (LedAction == LED_CTL_TX || LedAction == LED_CTL_RX ||
++ LedAction == LED_CTL_SITE_SURVEY ||
++ LedAction == LED_CTL_LINK ||
++ LedAction == LED_CTL_NO_LINK) )
++ {
++ return;
++ }
++
++
++ switch(priv->LedStrategy)
++ {
++ case SW_LED_MODE0:
++ SwLedControlMode0(dev, LedAction);
++ break;
++
++ case SW_LED_MODE1:
++ SwLedControlMode1(dev, LedAction);
++ break;
++
++ case SW_LED_MODE2:
++ SwLedControlMode2(dev, LedAction);
++ break;
++
++ case SW_LED_MODE3:
++ SwLedControlMode3(dev, LedAction);
++ break;
++ case SW_LED_MODE4:
++ SwLedControlMode4(dev, LedAction);
++ break;
++
++ case SW_LED_MODE5:
++ SwLedControlMode5(dev, LedAction);
++ break;
++
++ default:
++ break;
++ }
++}
++
++
++//
++// Description:
++// Implement each led action for SW_LED_MODE0.
++// This is default strategy.
++//
++void
++SwLedControlMode0(
++ struct net_device *dev,
++ LED_CTL_MODE LedAction
++)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ PLED_8187 pLed = &(priv->Gpio0Led);
++
++// printk("===+++++++++++++++======>%s In\n", __FUNCTION__);
++ // Decide led state
++ switch(LedAction)
++ {
++ case LED_CTL_TX:
++ case LED_CTL_RX:
++ if( pLed->bLedBlinkInProgress == 0 )
++ {
++ pLed->CurrLedState = LED_BLINK_NORMAL;
++ pLed->BlinkTimes = 2;
++ // printk("===========>LED_CTL_TX/RX \n");
++ }
++ else
++ {
++ return;
++ }
++ break;
++
++ case LED_CTL_SITE_SURVEY:
++ if( pLed->bLedBlinkInProgress == 0 )
++ {
++ pLed->CurrLedState = LED_BLINK_SLOWLY;
++ // pLed->BlinkTimes = 10;
++ //printk("===========>LED_CTL_SURVEY \n");
++ }
++ else
++ {
++ return;
++ }
++ break;
++
++ case LED_CTL_LINK:
++ // printk("===========>associate commplite LED_CTL_LINK\n");
++ pLed->CurrLedState = LED_ON;
++ break;
++
++ case LED_CTL_NO_LINK:
++ pLed->CurrLedState = LED_OFF;
++ break;
++
++ case LED_CTL_POWER_ON:
++ // printk("===========>LED_CTL_POWER_ON\n");
++ pLed->CurrLedState = LED_POWER_ON_BLINK;
++ break;
++
++ case LED_CTL_POWER_OFF:
++ pLed->CurrLedState = LED_OFF;
++ break;
++
++ default:
++ return;
++ break;
++ }
++
++ // Change led state.
++ switch(pLed->CurrLedState)
++ {
++ case LED_ON:
++ if( pLed->bLedBlinkInProgress == 0 )
++ {
++ SwLedOn(dev, pLed);
++ }
++ break;
++
++ case LED_OFF://modified by lizhaoming 2008.6.23
++ // if( pLed->bLedBlinkInProgress == 0 )
++ // {
++ // SwLedOff(dev, pLed);
++ // }
++
++ if(pLed->bLedBlinkInProgress )/////////lizhaoming
++ {
++ del_timer_sync(&(pLed->BlinkTimer));
++ pLed->bLedBlinkInProgress = FALSE;
++ }
++ SwLedOff(dev, pLed);
++ break;
++
++ case LED_BLINK_NORMAL:
++ if( pLed->bLedBlinkInProgress == 0 )
++ {
++ pLed->bLedBlinkInProgress = 1;
++ if( pLed->bLedOn )
++ pLed->BlinkingLedState = LED_OFF;
++ else
++ pLed->BlinkingLedState = LED_ON;
++
++ //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
++ //add_timer(&(pLed->BlinkTimer));
++ mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
++ //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
++ }
++ break;
++
++ case LED_BLINK_SLOWLY:
++ if( pLed->bLedBlinkInProgress == 0 )
++ {
++ //printk("=======>%s SLOWLY\n", __func__);
++ pLed->bLedBlinkInProgress = 1;
++ // if( pLed->bLedOn )
++ pLed->BlinkingLedState = LED_OFF;//for LED_SHIN is LED on
++ // else
++ // pLed->BlinkingLedState = LED_ON;
++
++ mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL));
++ }
++ break;
++
++ case LED_POWER_ON_BLINK:
++ SwLedOn(dev, pLed);
++#ifdef LED_SHIN
++ mdelay(100);
++ SwLedOff(dev, pLed);
++#endif
++ break;
++
++ default:
++ break;
++ }
++}
++
++//
++// Description:
++// Implement each led action for SW_LED_MODE1.
++// For example, this is applied by ALPHA.
++//
++void
++SwLedControlMode1(
++ struct net_device *dev,
++ LED_CTL_MODE LedAction
++)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ PLED_8187 pLed0 = &(priv->SwLed0);
++ PLED_8187 pLed1 = &(priv->SwLed1);
++// printk("=====++++++++++++++++++++++====>%s In\n", __FUNCTION__);
++
++ switch(LedAction)
++ {
++ case LED_CTL_TX:
++ if( pLed0->bLedBlinkInProgress == 0 )
++ {
++ pLed0->CurrLedState = LED_BLINK_NORMAL;
++ pLed0->BlinkTimes = 2;
++ pLed0->bLedBlinkInProgress = 1;
++ if( pLed0->bLedOn )
++ pLed0->BlinkingLedState = LED_OFF;
++ else
++ pLed0->BlinkingLedState = LED_ON;
++
++ //pLed0->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
++ //add_timer(&(pLed0->BlinkTimer));
++ mod_timer(&pLed0->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
++ //PlatformSetTimer(dev, &(pLed0->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
++ }
++ break;
++
++ case LED_CTL_LINK:
++ pLed0->CurrLedState = LED_ON;
++ if( pLed0->bLedBlinkInProgress == 0 )
++ {
++ SwLedOn(dev, pLed0);
++ }
++ break;
++
++ case LED_CTL_NO_LINK:
++ pLed0->CurrLedState = LED_OFF;
++ if( pLed0->bLedBlinkInProgress == 0 )
++ {
++ SwLedOff(dev, pLed0);
++ }
++ break;
++
++ case LED_CTL_POWER_ON:
++ pLed0->CurrLedState = LED_OFF;
++ SwLedOff(dev, pLed0);
++
++ pLed1->CurrLedState = LED_ON;
++ SwLedOn(dev, pLed1);
++
++ break;
++
++ case LED_CTL_POWER_OFF:
++ pLed0->CurrLedState = LED_OFF;
++ SwLedOff(dev, pLed0);
++
++ pLed1->CurrLedState = LED_OFF;
++ SwLedOff(dev, pLed1);
++ break;
++
++ case LED_CTL_SITE_SURVEY:
++ if( pLed0->bLedBlinkInProgress == 0 )
++ {
++ pLed0->CurrLedState = LED_BLINK_SLOWLY;;
++ pLed0->BlinkTimes = 10;
++ pLed0->bLedBlinkInProgress = 1;
++ if( pLed0->bLedOn )
++ pLed0->BlinkingLedState = LED_OFF;
++ else
++ pLed0->BlinkingLedState = LED_ON;
++
++ //pLed0->BlinkTimer.expires = jiffies + LED_BLINK_SLOWLY_INTERVAL;
++ //add_timer(&(pLed0->BlinkTimer));
++ mod_timer(&pLed0->BlinkTimer, jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL));
++ //PlatformSetTimer(dev, &(pLed0->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
++ }
++ break;
++
++ default:
++ break;
++ }
++}
++
++//
++// Description:
++// Implement each led action for SW_LED_MODE2,
++// which is customized for AzWave 8187 minicard.
++// 2006.04.03, by rcnjko.
++//
++void
++SwLedControlMode2(
++ struct net_device *dev,
++ LED_CTL_MODE LedAction
++)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ PLED_8187 pLed = &(priv->Gpio0Led);
++
++// printk("====+++++++++++++++++++++=====>%s In\n", __FUNCTION__);
++ // Decide led state
++ switch(LedAction)
++ {
++ case LED_CTL_TX:
++ case LED_CTL_RX:
++ if( pLed->bLedBlinkInProgress == 0 )
++ {
++ pLed->bLedBlinkInProgress = 1;
++
++ pLed->CurrLedState = LED_BLINK_NORMAL;
++ pLed->BlinkTimes = 2;
++
++ if( pLed->bLedOn )
++ pLed->BlinkingLedState = LED_OFF;
++ else
++ pLed->BlinkingLedState = LED_ON;
++
++ //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
++ //add_timer(&(pLed->BlinkTimer));
++ mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
++ //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
++ }
++ break;
++
++ case LED_CTL_SITE_SURVEY:
++ if( pLed->bLedBlinkInProgress == 0 )
++ {
++ pLed->bLedBlinkInProgress = 1;
++
++ //if( dev->MgntInfo.mAssoc ||
++ // dev->MgntInfo.mIbss )
++ //{
++ pLed->CurrLedState = LED_SCAN_BLINK;
++ pLed->BlinkTimes = 4;
++ //}
++ //else
++ //{
++ // pLed->CurrLedState = LED_NO_LINK_BLINK;
++ // pLed->BlinkTimes = 24;
++ //}
++
++ if( pLed->bLedOn )
++ {
++ pLed->BlinkingLedState = LED_OFF;
++ //pLed->BlinkTimer.expires = jiffies + LED_CM2_BLINK_ON_INTERVAL;
++ //add_timer(&(pLed->BlinkTimer));
++ mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM2_BLINK_ON_INTERVAL));
++ //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM2_BLINK_ON_INTERVAL);
++ }
++ else
++ {
++ pLed->BlinkingLedState = LED_ON;
++ //pLed->BlinkTimer.expires = jiffies + LED_CM2_BLINK_OFF_INTERVAL;
++ //add_timer(&(pLed->BlinkTimer));
++ mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM2_BLINK_OFF_INTERVAL));
++ //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM2_BLINK_OFF_INTERVAL);
++ }
++ }
++ else
++ {
++ if(pLed->CurrLedState != LED_NO_LINK_BLINK)
++ {
++ pLed->CurrLedState = LED_SCAN_BLINK;
++ /*
++ if( dev->MgntInfo.mAssoc ||
++ dev->MgntInfo.mIbss )
++ {
++ pLed->CurrLedState = LED_SCAN_BLINK;
++ }
++ else
++ {
++ pLed->CurrLedState = LED_NO_LINK_BLINK;
++ }
++ */
++ }
++ }
++ break;
++
++ case LED_CTL_NO_LINK:
++ if( pLed->bLedBlinkInProgress == 0 )
++ {
++ pLed->bLedBlinkInProgress = 1;
++
++ pLed->CurrLedState = LED_NO_LINK_BLINK;
++ pLed->BlinkTimes = 24;
++
++ if( pLed->bLedOn )
++ {
++ pLed->BlinkingLedState = LED_OFF;
++ //pLed->BlinkTimer.expires = jiffies + LED_CM2_BLINK_ON_INTERVAL;
++ //add_timer(&(pLed->BlinkTimer));
++ mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM2_BLINK_ON_INTERVAL));
++ //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM2_BLINK_ON_INTERVAL);
++ }
++ else
++ {
++ pLed->BlinkingLedState = LED_ON;
++ //pLed->BlinkTimer.expires = jiffies + LED_CM2_BLINK_OFF_INTERVAL;
++ //add_timer(&(pLed->BlinkTimer));
++ mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM2_BLINK_OFF_INTERVAL));
++ //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM2_BLINK_OFF_INTERVAL);
++ }
++ }
++ else
++ {
++ pLed->CurrLedState = LED_NO_LINK_BLINK;
++ }
++ break;
++
++ case LED_CTL_LINK:
++ pLed->CurrLedState = LED_ON;
++ if( pLed->bLedBlinkInProgress == 0 )
++ {
++ SwLedOn(dev, pLed);
++ }
++ break;
++
++ case LED_CTL_POWER_OFF:
++ pLed->CurrLedState = LED_OFF;
++ if( pLed->bLedBlinkInProgress == 0 )
++ {
++ SwLedOff(dev, pLed);
++ }
++ break;
++
++ default:
++ break;
++ }
++}
++
++
++//
++// Description:
++// Implement each led action for SW_LED_MODE3,
++// which is customized for Sercomm Printer Server case.
++// 2006.04.21, by rcnjko.
++//
++void
++SwLedControlMode3(
++ struct net_device *dev,
++ LED_CTL_MODE LedAction
++)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ PLED_8187 pLed = &(priv->Gpio0Led);
++
++// printk("=====+++++++++++++++++++====>%s In\n", __FUNCTION__);
++ // Decide led state
++ switch(LedAction)
++ {
++ case LED_CTL_TX:
++ case LED_CTL_RX:
++ if( pLed->bLedBlinkInProgress == 0 )
++ {
++ pLed->bLedBlinkInProgress = 1;
++
++ pLed->CurrLedState = LED_BLINK_CM3;
++ pLed->BlinkTimes = 2;
++
++ if( pLed->bLedOn )
++ pLed->BlinkingLedState = LED_OFF;
++ else
++ pLed->BlinkingLedState = LED_ON;
++
++ //pLed->BlinkTimer.expires = jiffies + LED_CM3_BLINK_INTERVAL;
++ //add_timer(&(pLed->BlinkTimer));
++ mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM3_BLINK_INTERVAL));
++ //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM3_BLINK_INTERVAL);
++ }
++ break;
++
++ case LED_CTL_SITE_SURVEY:
++ if( pLed->bLedBlinkInProgress == 0 )
++ {
++ pLed->bLedBlinkInProgress = 1;
++
++ pLed->CurrLedState = LED_BLINK_CM3;
++ pLed->BlinkTimes = 10;
++
++ if( pLed->bLedOn )
++ pLed->BlinkingLedState = LED_OFF;
++ else
++ pLed->BlinkingLedState = LED_ON;
++
++ //pLed->BlinkTimer.expires = jiffies + LED_CM3_BLINK_INTERVAL;
++ //add_timer(&(pLed->BlinkTimer));
++ mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM3_BLINK_INTERVAL));
++ //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM3_BLINK_INTERVAL);
++ }
++ break;
++
++ case LED_CTL_LINK:
++ pLed->CurrLedState = LED_ON;
++ if( pLed->bLedBlinkInProgress == 0 )
++ {
++ SwLedOn(dev, pLed);
++ }
++ break;
++
++ case LED_CTL_NO_LINK:
++ pLed->CurrLedState = LED_OFF;
++ if( pLed->bLedBlinkInProgress == 0 )
++ {
++ SwLedOff(dev, pLed);
++ }
++ break;
++
++ case LED_CTL_POWER_ON:
++ pLed->CurrLedState = LED_POWER_ON_BLINK;
++ SwLedOn(dev, pLed);
++ mdelay(100);
++ SwLedOff(dev, pLed);
++ break;
++
++ case LED_CTL_POWER_OFF:
++ pLed->CurrLedState = LED_OFF;
++ if( pLed->bLedBlinkInProgress == 0 )
++ {
++ SwLedOff(dev, pLed);
++ }
++ break;
++
++ default:
++ break;
++ }
++}
++
++// added by lizhaoming 2008.6.2
++//
++// Description:
++// Implement each led action for SW_LED_MODE4,
++// which is customized for QMI 8187B minicard.
++// 2008.04.21, by chiyokolin.
++//
++void
++SwLedControlMode4(
++ struct net_device *dev,
++ LED_CTL_MODE LedAction
++ )
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ PLED_8187 pLed = &(priv->Gpio0Led);
++
++ //printk("=====+++++++++++++++++++++====>%s In\n", __FUNCTION__);
++ // Decide led state
++ switch(LedAction)
++ {
++ case LED_CTL_TX:
++ case LED_CTL_RX:
++ //if( pLed->bLedBlinkInProgress == false && !priv->bScanInProgress)//?????
++ if( pLed->bLedBlinkInProgress == 0)
++ {
++ pLed->bLedBlinkInProgress = 1;
++
++ pLed->CurrLedState = LED_BLINK_NORMAL;
++ pLed->BlinkTimes = 2;
++
++ if( pLed->bLedOn )
++ pLed->BlinkingLedState = LED_OFF;
++ else
++ pLed->BlinkingLedState = LED_ON;
++
++ //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
++ //add_timer(&(pLed->BlinkTimer));
++ mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
++ //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
++ }
++ else
++ //printk("----->LED_CTL_RX/TX bLedBlinkInProgress\n");
++
++ break;
++
++ case LED_CTL_SITE_SURVEY:
++ if( pLed->bLedBlinkInProgress == 0 )
++ {
++
++ pLed->bLedBlinkInProgress = 1;
++ //if( priv->MgntInfo.mAssoc || priv->MgntInfo.mIbss )//////////??????
++ //{
++ pLed->CurrLedState = LED_SCAN_BLINK;
++ pLed->BlinkTimes = 10;
++
++ pLed->BlinkingLedState = LED_ON;
++
++ //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
++ //add_timer(&(pLed->BlinkTimer));
++ mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
++ //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
++ //}
++ //else
++ //{
++ // pLed->CurrLedState = LED_NO_LINK_BLINK;
++ // pLed->BlinkTimes = 24;
++ //
++ // if( pLed->bLedOn )
++ // {
++ // pLed->BlinkingLedState = LED_OFF;
++ //
++ // pLed->BlinkTimer.expires = jiffies + LED_CM4_BLINK_ON_INTERVAL;
++ // add_timer(&(pLed->BlinkTimer));
++ // //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_CM4_BLINK_ON_INTERVAL);
++ // }
++ // else
++ // {
++ // pLed->BlinkingLedState = LED_ON;
++
++ // pLed->BlinkTimer.expires = jiffies + LED_CM4_BLINK_OFF_INTERVAL;
++ // add_timer(&(pLed->BlinkTimer));
++ // //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_CM4_BLINK_OFF_INTERVAL);
++ // }
++ //}
++ }
++ else
++ {
++ if(pLed->CurrLedState != LED_NO_LINK_BLINK)
++ {
++ //if( priv->MgntInfo.mAssoc || priv->MgntInfo.mIbss )//???????????
++ //{
++ //}
++ //else
++ //{
++ // pLed->CurrLedState = LED_NO_LINK_BLINK;
++ //}
++ }
++
++ //printk("----->LED_CTL_SITE_SURVEY bLedBlinkInProgress\n");
++ }
++ break;
++
++ case LED_CTL_NO_LINK:
++ if( pLed->bLedBlinkInProgress == 0 )
++ {
++ pLed->bLedBlinkInProgress = 1;
++
++ pLed->CurrLedState = LED_NO_LINK_BLINK;
++ pLed->BlinkTimes = 24;
++
++ if( pLed->bLedOn )
++ {
++ pLed->BlinkingLedState = LED_OFF;
++
++ //pLed->BlinkTimer.expires = jiffies + LED_CM4_BLINK_ON_INTERVAL;
++ //add_timer(&(pLed->BlinkTimer));
++ mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM4_BLINK_ON_INTERVAL));
++ //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_CM4_BLINK_ON_INTERVAL);
++ }
++ else
++ {
++ pLed->BlinkingLedState = LED_ON;
++
++ //pLed->BlinkTimer.expires = jiffies + LED_CM4_BLINK_OFF_INTERVAL;
++ //add_timer(&(pLed->BlinkTimer));
++ mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM4_BLINK_OFF_INTERVAL));
++ //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_CM4_BLINK_OFF_INTERVAL);
++ }
++ }
++ else
++ {
++ pLed->CurrLedState = LED_NO_LINK_BLINK;
++ //printk("----->LED_CTL_NO_LINK bLedBlinkInProgress\n");
++ }
++ break;
++
++ case LED_CTL_LINK:
++ pLed->CurrLedState = LED_ON;
++ if( pLed->bLedBlinkInProgress == 0)
++ {
++ SwLedOn(dev, pLed);
++ }
++ else
++ ;//printk("----->LED_CTL_LINK bLedBlinkInProgress\n");
++
++ break;
++
++ case LED_CTL_POWER_OFF:
++ pLed->CurrLedState = LED_OFF;
++ if(pLed->bLedBlinkInProgress)
++ {
++ printk("----->LED_CTL_POWER_OFF bLedBlinkInProgress\n");
++
++ //PlatformCancelTimer(Adapter, &(pLed->BlinkTimer));
++ del_timer_sync(&(pLed->BlinkTimer));
++ pLed->bLedBlinkInProgress = 0;
++ }
++ SwLedOff(dev, pLed);
++ break;
++
++ default:
++ break;
++ }
++}
++
++
++
++//added by lizhaoming 2008.6.3
++//
++// Description:
++// Implement each led action for SW_LED_MODE5,
++// which is customized for DELL 8187B minicard.
++// 2008.04.24, by chiyokolin.
++//
++void
++SwLedControlMode5(
++ struct net_device *dev,
++ LED_CTL_MODE LedAction
++ )
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ PLED_8187 pLed = &(priv->Gpio0Led);
++
++ // Decide led state
++ //printk("====++++++++++++++++++++++=====>%s In\n", __FUNCTION__);
++ switch(LedAction)
++ {
++ case LED_CTL_TX:
++ case LED_CTL_RX:
++ case LED_CTL_SITE_SURVEY:
++ case LED_CTL_POWER_ON:
++ case LED_CTL_NO_LINK:
++ case LED_CTL_LINK:
++ pLed->CurrLedState = LED_ON;
++ if( pLed->bLedBlinkInProgress == 0 )
++ {
++ pLed->bLedBlinkInProgress = 1;
++ if(! pLed->bLedOn )
++ pLed->BlinkingLedState = LED_ON;
++ else
++ break;
++
++ //printk("====++++++++++++++++++++++=====>%s In LED:%d\n", __FUNCTION__, pLed->bLedOn);
++ //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
++ //add_timer(&(pLed->BlinkTimer));
++ mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
++ // SwLedOn(dev, pLed);
++ }
++ else
++ ;//printk("----->LED_CTL_LINK bLedBlinkInProgress\n");
++
++ break;
++
++ case LED_CTL_POWER_OFF:
++ pLed->CurrLedState = LED_OFF;
++ // printk("<====++++++++++++++++++++++=====%s In LED:%d\n", __FUNCTION__, pLed->bLedOn);
++ if(pLed->bLedBlinkInProgress)
++ {
++ // printk("----->LED_CTL_POWER_OFF bLedBlinkInProgress\n");
++
++ //PlatformCancelTimer(Adapter, &(pLed->BlinkTimer));
++ del_timer_sync(&(pLed->BlinkTimer));
++ pLed->bLedBlinkInProgress = 0;
++ }
++ SwLedOff(dev, pLed);
++ break;
++
++ default:
++ break;
++ }
++}
++
++//
++// Callback fuction of the timer, Gpio0Led.BlinkTimer.
++//
++void
++Gpio0LedBlinkTimerCallback(
++ unsigned long data
++ )
++{
++ struct net_device *dev = (struct net_device *)data;
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++// printk("=========>%s In\n", __FUNCTION__);
++ PlatformSwLedBlink(dev, &(priv->Gpio0Led));
++}
++
++
++
++//
++// Callback fuction of the timer, SwLed0.BlinkTimer.
++//
++void
++SwLed0BlinkTimerCallback(
++ unsigned long data
++ )
++{
++ struct net_device *dev = (struct net_device *)data;
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++// printk("=========>%s In\n", __FUNCTION__);
++ PlatformSwLedBlink(dev, &(priv->SwLed0));
++}
++
++
++
++//
++// Callback fuction of the timer, SwLed1.BlinkTimer.
++//
++void
++SwLed1BlinkTimerCallback(
++ unsigned long data
++ )
++{
++ struct net_device *dev = (struct net_device *)data;
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++// printk("=========>%s In\n", __FUNCTION__);
++ PlatformSwLedBlink(dev, &(priv->SwLed1));
++}
++
++void
++PlatformSwLedBlink(
++ struct net_device *dev,
++ PLED_8187 pLed
++ )
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++// printk("=========>%s In\n", __FUNCTION__);
++ switch(pLed->LedPin)
++ {
++ case LED_PIN_GPIO0:
++ schedule_work(&(priv->Gpio0LedWorkItem));
++ break;
++
++ case LED_PIN_LED0:
++ schedule_work(&(priv->SwLed0WorkItem));
++ break;
++
++ case LED_PIN_LED1:
++ schedule_work(&(priv->SwLed1WorkItem));
++ break;
++
++ default:
++ break;
++ }
++}
++
++//
++// Callback fucntion of the workitem for SW LEDs.
++// 2006.03.01, by rcnjko.
++//
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
++void Gpio0LedWorkItemCallback(struct work_struct *work)
++{
++ struct r8180_priv *priv = container_of(work, struct r8180_priv,Gpio0LedWorkItem);
++ struct net_device *dev = priv->ieee80211->dev;
++#else
++void
++Gpio0LedWorkItemCallback(
++ void * Context
++ )
++{
++ struct net_device *dev = (struct net_device *)Context;
++ struct r8180_priv *priv = ieee80211_priv(dev);
++#endif
++ PLED_8187 pLed = &(priv->Gpio0Led);
++ if (priv == NULL || dev == NULL){
++// printk("=========>%s In\n", __FUNCTION__);
++ //printk("ft=====================>%s()\n", __FUNCTION__);
++ }
++
++#if 0 // by lizahoming 2008.6.3
++ if(priv->LedStrategy == SW_LED_MODE2)
++ SwLedCm2Blink(dev, pLed);
++ else
++ SwLedBlink(dev, pLed);
++#endif
++
++#if 1 // by lizahoming 2008.6.3
++ switch(priv->LedStrategy)
++ {
++ case SW_LED_MODE2:
++ SwLedCm2Blink(dev, pLed);
++ break;
++ case SW_LED_MODE4:
++ SwLedCm4Blink(dev, pLed);
++ break;
++ default:
++ SwLedBlink(dev, pLed);
++ break;
++ }
++#endif
++
++ //LeaveCallbackOfRtWorkItem( &(usbdevice->Gpio0LedWorkItem) );
++}
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
++void SwLed0WorkItemCallback(struct work_struct *work)
++{
++ //struct r8180_priv *priv = container_of(work, struct r8180_priv, SwLed0WorkItem);
++ //struct net_device *dev = priv->dev;
++#else
++void SwLed0WorkItemCallback(void * Context)
++{
++ //struct net_device *dev = (struct net_device *)Context;
++ //struct r8180_priv *priv = ieee80211_priv(dev);
++#endif
++ //SwLedBlink(dev, &(priv->SwLed0));
++// printk("=========>%s In\n", __FUNCTION__);
++
++ //LeaveCallbackOfRtWorkItem( &(usbdevice->SwLed0WorkItem) );
++}
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
++void SwLed1WorkItemCallback(struct work_struct *work)
++{
++ //struct r8180_priv *priv = container_of(work, struct r8180_priv, SwLed1WorkItem);
++// struct net_device *dev = priv->dev;
++#else
++void
++SwLed1WorkItemCallback(
++ void * Context
++ )
++{
++ //struct net_device *dev = (struct net_device *)Context;
++ //struct r8180_priv *priv = ieee80211_priv(dev);
++#endif
++// printk("=========>%s In\n", __FUNCTION__);
++ //SwLedBlink(dev, &(priv->SwLed1));
++
++ //LeaveCallbackOfRtWorkItem( &(usbdevice->SwLed1WorkItem) );
++}
++
++//
++// Implementation of LED blinking behavior.
++// It toggle off LED and schedule corresponding timer if necessary.
++//
++void
++SwLedBlink(
++ struct net_device *dev,
++ PLED_8187 pLed
++ )
++{
++ u8 bStopBlinking = 0;
++
++ //printk("=========>%s In state:%d\n", __FUNCTION__, pLed->CurrLedState);
++ // Change LED according to BlinkingLedState specified.
++ if( pLed->BlinkingLedState == LED_ON )
++ {
++ SwLedOn(dev, pLed);
++// printk("Blinktimes (%d): turn on\n", pLed->BlinkTimes);
++ }
++ else
++ {
++ SwLedOff(dev, pLed);
++// printk("Blinktimes (%d): turn off\n", pLed->BlinkTimes);
++ }
++
++ // Determine if we shall change LED state again.
++//by lizhaoming for LED BLINK SLOWLY
++ if(pLed->CurrLedState == LED_BLINK_SLOWLY)
++ {
++ bStopBlinking = 0;
++ } else {
++ pLed->BlinkTimes--;
++ if( pLed->BlinkTimes == 0 )
++ {
++ bStopBlinking = 1;
++ }
++ else
++ {
++ if( pLed->CurrLedState != LED_BLINK_NORMAL &&
++ pLed->CurrLedState != LED_BLINK_SLOWLY &&
++ pLed->CurrLedState != LED_BLINK_CM3 )
++ {
++ bStopBlinking = 1;
++ }
++ }
++ }
++
++ if(bStopBlinking)
++ {
++ if( pLed->CurrLedState == LED_ON && pLed->bLedOn == 0)
++ {
++ SwLedOn(dev, pLed);
++ }
++ else if(pLed->CurrLedState == LED_OFF && pLed->bLedOn == 1)
++ {
++ SwLedOff(dev, pLed);
++ }
++
++ pLed->BlinkTimes = 0;
++ pLed->bLedBlinkInProgress = 0;
++ }
++ else
++ {
++ // Assign LED state to toggle.
++ if( pLed->BlinkingLedState == LED_ON )
++ pLed->BlinkingLedState = LED_OFF;
++ else
++ pLed->BlinkingLedState = LED_ON;
++
++ // Schedule a timer to toggle LED state.
++ switch( pLed->CurrLedState )
++ {
++ case LED_BLINK_NORMAL:
++ //printk("LED_BLINK_NORMAL:Blinktimes (%d): turn off\n", pLed->BlinkTimes+1);
++ //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
++ //add_timer(&(pLed->BlinkTimer));
++ mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
++ //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
++ break;
++
++ case LED_BLINK_SLOWLY:
++ if( pLed->bLedOn == 1 )
++ {
++ //printk("LED_BLINK_SLOWLY:turn off\n");
++ //pLed->BlinkTimer.expires = jiffies + LED_BLINK_SLOWLY_INTERVAL+50;//for pcie mini card spec page 33, 250ms
++ //add_timer(&(pLed->BlinkTimer));
++ mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL+50));
++ pLed->BlinkingLedState = LED_OFF;
++ } else {
++ //printk("LED_BLINK_SLOWLY:turn on\n");
++ //pLed->BlinkTimer.expires = jiffies + 5000;//for pcie mini card spec page 33, 5s
++ //add_timer(&(pLed->BlinkTimer));
++ mod_timer(&pLed->BlinkTimer, jiffies + MSECS(5000));
++ pLed->BlinkingLedState = LED_ON;
++ }
++ break;
++
++ case LED_BLINK_CM3:
++ //printk("LED_BLINK_CM3:Blinktimes (%d): turn off\n", pLed->BlinkTimes+1);
++ //pLed->BlinkTimer.expires = jiffies + LED_CM3_BLINK_INTERVAL;
++ //add_timer(&(pLed->BlinkTimer));
++ mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM3_BLINK_INTERVAL));
++ //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM3_BLINK_INTERVAL);
++ break;
++
++ default:
++ //printk("LED_BLINK_default:Blinktimes (%d): turn off\n", pLed->BlinkTimes+1);
++ //pLed->BlinkTimer.expires = jiffies + LED_BLINK_SLOWLY_INTERVAL;
++ //add_timer(&(pLed->BlinkTimer));
++ mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL));
++ //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
++ break;
++ }
++ }
++}
++
++
++
++//
++// Implementation of LED blinking behavior for SwLedControlMode2.
++//
++void
++SwLedCm2Blink(
++ struct net_device *dev,
++ PLED_8187 pLed
++ )
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ //PMGNT_INFO priv = &(dev->MgntInfo);
++ u8 bStopBlinking = 0;
++
++ //printk("========+++++++++++++=>%s In\n", __FUNCTION__);
++ //To avoid LED blinking when rf is off, add by lizhaoming 2008.6.2
++ if((priv->eRFPowerState == eRfOff) && (priv->RfOffReason>RF_CHANGE_BY_IPS))
++ {
++ SwLedOff(dev, pLed);
++
++ //pLed->BlinkTimer.expires = jiffies + LED_CM2_BLINK_ON_INTERVAL;
++ //add_timer(&(pLed->BlinkTimer));
++ mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM2_BLINK_ON_INTERVAL));
++ //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_CM2_BLINK_ON_INTERVAL);
++ //printk(" Hw/Soft Radio Off, turn off Led\n");
++ return;
++ }
++
++ // Change LED according to BlinkingLedState specified.
++ if( pLed->BlinkingLedState == LED_ON )
++ {
++ SwLedOn(dev, pLed);
++ //DMESG("Blinktimes (%d): turn on\n", pLed->BlinkTimes);
++ }
++ else
++ {
++ SwLedOff(dev, pLed);
++ //DMESG("Blinktimes (%d): turn off\n", pLed->BlinkTimes);
++ }
++
++ //Add by lizhaoming for avoid BlinkTimers <0, 2008.6.2
++ if(pLed->BlinkTimes > 0)
++ {//by lizhaoming 2008.6.2
++ // Determine if we shall change LED state again.
++ pLed->BlinkTimes--;
++ }//by lizhaoming 2008.6.2
++
++ switch(pLed->CurrLedState)
++ {
++ case LED_BLINK_NORMAL:
++ if(pLed->BlinkTimes == 0)
++ {
++ bStopBlinking = 1;
++ }
++ break;
++/* CM2 scan blink and no link blind now not be supported
++ case LED_SCAN_BLINK:
++ if( (priv->mAssoc || priv->mIbss) && // Linked.
++ (!priv->bScanInProgress) && // Not in scan stage.
++ (pLed->BlinkTimes % 2 == 0)) // Even
++ {
++ bStopBlinking = 1;
++ }
++ break;
++
++ case LED_NO_LINK_BLINK:
++ //Revised miniCard Ad-hoc mode "Slow Blink" by Isaiah 2006-08-03
++ //if( (priv->mAssoc || priv->mIbss) ) // Linked.
++ if( priv->mAssoc)
++ {
++ bStopBlinking = 1;
++ }
++ else if(priv->mIbss && priv->bMediaConnect )
++ {
++ bStopBlinking = 1;
++ }
++ break;
++*/
++ default:
++ bStopBlinking = 1;
++ break;
++ }
++
++ if(bStopBlinking)
++ {
++/*
++ if( priv->eRFPowerState != eRfOn )
++ {
++ SwLedOff(dev, pLed);
++ }
++ else if( priv->bMediaConnect == 1 && pLed->bLedOn == 0)
++ {
++ SwLedOn(dev, pLed);
++ }
++ else if( priv->bMediaConnect == 0 && pLed->bLedOn == 1)
++ {
++ SwLedOff(dev, pLed);
++ }
++*/
++ pLed->BlinkTimes = 0;
++ pLed->bLedBlinkInProgress = 0;
++ }
++ else
++ {
++ // Assign LED state to toggle.
++ if( pLed->BlinkingLedState == LED_ON )
++ pLed->BlinkingLedState = LED_OFF;
++ else
++ pLed->BlinkingLedState = LED_ON;
++
++ // Schedule a timer to toggle LED state.
++ switch( pLed->CurrLedState )
++ {
++ case LED_BLINK_NORMAL:
++ //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
++ //add_timer(&(pLed->BlinkTimer));
++ mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
++ //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
++ break;
++
++ case LED_BLINK_SLOWLY:
++ //pLed->BlinkTimer.expires = jiffies + LED_BLINK_SLOWLY_INTERVAL;
++ //add_timer(&(pLed->BlinkTimer));
++ mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL));
++ //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
++ break;
++
++ case LED_SCAN_BLINK:
++ case LED_NO_LINK_BLINK:
++ if( pLed->bLedOn ) {
++ //pLed->BlinkTimer.expires = jiffies + LED_CM2_BLINK_ON_INTERVAL;
++ //add_timer(&(pLed->BlinkTimer));
++ mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM2_BLINK_ON_INTERVAL));
++ //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM2_BLINK_ON_INTERVAL);
++ } else {
++ //pLed->BlinkTimer.expires = jiffies + LED_CM2_BLINK_OFF_INTERVAL;
++ //add_timer(&(pLed->BlinkTimer));
++ mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM2_BLINK_OFF_INTERVAL));
++ //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM2_BLINK_OFF_INTERVAL);
++ }
++ break;
++
++ default:
++ //RT_ASSERT(0, ("SwLedCm2Blink(): unexpected state!\n"));
++ //pLed->BlinkTimer.expires = jiffies + LED_BLINK_SLOWLY_INTERVAL;
++ //add_timer(&(pLed->BlinkTimer));
++ mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL));
++ //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
++ break;
++ }
++ }
++}
++
++// added by lizhaoming 2008.6.2
++//
++// Description:
++// Implement LED blinking behavior for SW_LED_MODE4.
++//
++void
++SwLedCm4Blink(
++ struct net_device *dev,
++ PLED_8187 pLed
++ )
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++ u8 bStopBlinking = 0;
++
++ printk("======++++++++++++++++++======>%s In\n", __FUNCTION__);
++ //To avoid LED blinking when rf is off, add by Maddest 20080307
++ if((priv->eRFPowerState == eRfOff) && (priv->RfOffReason>RF_CHANGE_BY_IPS))
++ {
++ SwLedOff(dev, pLed);
++
++ //pLed->BlinkTimer.expires = jiffies + LED_CM4_BLINK_ON_INTERVAL;
++ //add_timer(&(pLed->BlinkTimer));
++ mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM4_BLINK_ON_INTERVAL));
++ //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_CM4_BLINK_ON_INTERVAL);
++ printk(" Hw/Soft Radio Off, turn off Led\n");
++ return;
++ }
++ // Change LED according to BlinkingLedState specified.
++ if( pLed->BlinkingLedState == LED_ON )
++ {
++ if(!pLed->bLedOn)
++ {
++ SwLedOn(dev, pLed);
++ }
++ printk("Blinktimes (%d): turn on\n", pLed->BlinkTimes);
++ }
++ else
++ {
++ SwLedOff(dev, pLed);
++ printk("Blinktimes (%d): turn off\n", pLed->BlinkTimes);
++ }
++
++ //Add by Maddest for avoid BlinkTimers <0, 20080307;
++ if(pLed->BlinkTimes > 0)
++ {
++ // Determine if we shall change LED state again.
++ pLed->BlinkTimes--;
++ }
++ printk("pLed->CurrLedState %d pLed->BlinkTimes %d\n", pLed->CurrLedState,pLed->BlinkTimes);
++ switch(pLed->CurrLedState)
++ {
++ case LED_BLINK_NORMAL:
++ if(pLed->BlinkTimes == 0)
++ {
++ bStopBlinking = 1;
++ }
++ break;
++
++/* CM2 scan blink and no link blind now not be supported
++ case LED_SCAN_BLINK:
++ if( (priv->mAssoc || priv->mIbss) && // Linked.//????????????
++ (!priv->bScanInProgress) && // Not in scan stage.//????????????
++ (pLed->BlinkTimes % 2 == 0)) // Even
++ {
++ bStopBlinking = 1;
++ }
++ break;
++
++ case LED_NO_LINK_BLINK:
++ //Revised miniCard Ad-hoc mode "Slow Blink" by Isaiah 2006-08-03
++ //if( (pMgntInfo->mAssoc || pMgntInfo->mIbss) ) // Linked.
++ if( priv->mAssoc) //????????????
++ {
++ bStopBlinking = 1;
++ }
++ else if(priv->mIbss && priv->bMediaConnect )//????????????
++ {
++ bStopBlinking = 1;
++ }
++ break;
++*/
++
++ default:
++ bStopBlinking = 1;
++ break;
++ }
++
++ if(bStopBlinking)
++ {
++ /*
++ if( priv->eRFPowerState != eRfOn )
++ {
++ SwLedOff(dev, pLed);
++ }
++ else if( priv->bMediaConnect == true && pLed->bLedOn == false)//????????????
++ {
++ SwLedOn(dev, pLed);
++ }
++ else if( priv->bMediaConnect == false && pLed->bLedOn == true)//????????????
++ {
++ SwLedOff(dev, pLed);
++ }
++ */
++
++ pLed->BlinkTimes = 0;
++ pLed->bLedBlinkInProgress = 0;
++ }
++ else
++ {
++ // Assign LED state to toggle.
++ if( pLed->BlinkingLedState == LED_ON )
++ pLed->BlinkingLedState = LED_OFF;
++ else
++ pLed->BlinkingLedState = LED_ON;
++
++ // Schedule a timer to toggle LED state.
++ switch( pLed->CurrLedState )
++ {
++ case LED_BLINK_NORMAL:
++ //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
++ //add_timer(&(pLed->BlinkTimer));
++ mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
++ //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
++ break;
++
++ case LED_BLINK_SLOWLY:
++ //pLed->BlinkTimer.expires = jiffies + LED_BLINK_SLOWLY_INTERVAL;
++ //add_timer(&(pLed->BlinkTimer));
++ mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL));
++ //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
++ break;
++
++ case LED_SCAN_BLINK:
++ pLed->BlinkingLedState = LED_ON;
++ //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
++ //add_timer(&(pLed->BlinkTimer));
++ mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
++ //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
++
++ case LED_NO_LINK_BLINK:
++ if( pLed->bLedOn ){
++ //pLed->BlinkTimer.expires = jiffies + LED_CM4_BLINK_ON_INTERVAL;
++ //add_timer(&(pLed->BlinkTimer));
++ mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM4_BLINK_ON_INTERVAL));
++ //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_CM4_BLINK_ON_INTERVAL);
++ }else{
++ //pLed->BlinkTimer.expires = jiffies + LED_CM4_BLINK_OFF_INTERVAL;
++ //add_timer(&(pLed->BlinkTimer));
++ mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM4_BLINK_OFF_INTERVAL));
++ //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_CM4_BLINK_OFF_INTERVAL);
++ }
++ break;
++
++ default:
++ printk("SwLedCm2Blink(): unexpected state!\n");
++ //pLed->BlinkTimer.expires = jiffies + LED_BLINK_SLOWLY_INTERVAL;
++ //add_timer(&(pLed->BlinkTimer));
++ mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL));
++ //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
++ break;
++ }
++ }
++}
++
++void
++SwLedOn(
++ struct net_device *dev,
++ PLED_8187 pLed
++)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++// printk("=========>%s(), pin:%d\n", __FUNCTION__, pLed->LedPin);
++ switch(pLed->LedPin)
++ {
++ case LED_PIN_GPIO0:
++ write_nic_byte(dev,0x0091,0x01);
++ write_nic_byte(dev,0x0090,0x00); // write 0 : LED on
++ break;
++
++ case LED_PIN_LED0:
++ priv->PsrValue &= ~(0x01 << 4);
++ write_nic_byte(dev, PSR, priv->PsrValue);
++ break;
++
++ case LED_PIN_LED1:
++ priv->PsrValue &= ~(0x01 << 5);
++ write_nic_byte(dev, PSR, priv->PsrValue);
++ break;
++
++ default:
++ break;
++ }
++
++ pLed->bLedOn = 1;
++}
++
++void
++SwLedOff(
++ struct net_device *dev,
++ PLED_8187 pLed
++)
++{
++ struct r8180_priv *priv = ieee80211_priv(dev);
++
++
++ //printk("=========>%s(), pin:%d\n", __FUNCTION__, pLed->LedPin);
++ switch(pLed->LedPin)
++ {
++ case LED_PIN_GPIO0:
++ write_nic_byte(dev,0x0091,0x01);
++ write_nic_byte(dev,0x0090,0x01); // write 1 : LED off
++ break;
++
++ case LED_PIN_LED0:
++ priv->PsrValue |= (0x01 << 4);
++ write_nic_byte(dev, PSR, priv->PsrValue);
++ break;
++
++ case LED_PIN_LED1:
++ priv->PsrValue |= (0x01 << 5);
++ write_nic_byte(dev, PSR, priv->PsrValue);
++ break;
++
++ default:
++ break;
++ }
++
++ pLed->bLedOn = 0;
++}
++
+diff --git a/drivers/net/wireless/rtl8187b/r8187_led.h b/drivers/net/wireless/rtl8187b/r8187_led.h
+new file mode 100644
+index 0000000..83492db
+--- /dev/null
++++ b/drivers/net/wireless/rtl8187b/r8187_led.h
+@@ -0,0 +1,276 @@
++/*++
++
++Copyright (c) Microsoft Corporation. All rights reserved.
++
++Module Name:
++ r8187_led.h
++
++Abstract:
++ definitions and stuctures for rtl8187 led control.
++
++Major Change History:
++ When Who What
++ ---------- ------ ----------------------------------------------
++ 2006-09-07 Xiong Created
++
++Notes:
++
++--*/
++
++#ifndef R8187_LED_H
++#define R8187_LED_H
++
++#include <linux/types.h>
++#include <linux/timer.h>
++
++
++/*--------------------------Define -------------------------------------------*/
++//
++// 0x7E-0x7F is reserved for SW customization. 2006.04.21, by rcnjko.
++//
++// BIT[0-7] is for CustomerID where value 0x00 and 0xFF is reserved for Realtek.
++#define EEPROM_SW_REVD_OFFSET 0x7E
++
++#define EEPROM_CID_MASK 0x00FF
++#define EEPROM_CID_RSVD0 0x00
++#define EEPROM_CID_RSVD1 0xFF
++#define EEPROM_CID_ALPHA0 0x01
++#define EEPROM_CID_SERCOMM_PS 0x02
++#define EEPROM_CID_HW_LED 0x03
++
++#define EEPROM_CID_QMI 0x07 //Added by lizhaoming 2008.6.3
++#define EEPROM_CID_DELL 0x08 //Added by lizhaoming 2008.6.3
++
++#define LED_BLINK_NORMAL_INTERVAL 100 //by lizhaoming 50 -> 100
++#define LED_BLINK_SLOWLY_INTERVAL 200
++
++// Customized for AzWave, 2006.04.03, by rcnjko.
++#define LED_CM2_BLINK_ON_INTERVAL 250
++#define LED_CM2_BLINK_OFF_INTERVAL 4750
++//
++
++// Customized for Sercomm Printer Server case, 2006.04.21, by rcnjko.
++#define LED_CM3_BLINK_INTERVAL 1500
++
++// by lizhaoming 2008.6.3: Customized for QMI.
++//
++#define LED_CM4_BLINK_ON_INTERVAL 500
++#define LED_CM4_BLINK_OFF_INTERVAL 4500
++
++
++/*--------------------------Define MACRO--------------------------------------*/
++
++
++/*------------------------------Define Struct---------------------------------*/
++typedef enum _LED_STATE_8187{
++ LED_UNKNOWN = 0,
++ LED_ON = 1,
++ LED_OFF = 2,
++ LED_BLINK_NORMAL = 3,
++ LED_BLINK_SLOWLY = 4,
++ LED_POWER_ON_BLINK = 5,
++ LED_SCAN_BLINK = 6, // LED is blinking during scanning period, the # of times to blink is depend on time for scanning.
++ LED_NO_LINK_BLINK = 7, // LED is blinking during no link state.
++ LED_BLINK_CM3 = 8, // Customzied for Sercomm Printer Server case
++}LED_STATE_8187;
++
++typedef enum _RT_CID_TYPE {
++ RT_CID_DEFAULT,
++ RT_CID_8187_ALPHA0,
++ RT_CID_8187_SERCOMM_PS,
++ RT_CID_8187_HW_LED,
++
++ RT_CID_87B_QMI , //Added by lizhaoming 2008.6.3
++ RT_CID_87B_DELL, //Added by lizhaoming 2008.6.3
++
++} RT_CID_TYPE;
++
++typedef enum _LED_STRATEGY_8187{
++ SW_LED_MODE0, // SW control 1 LED via GPIO0. It is default option.
++ SW_LED_MODE1, // 2 LEDs, through LED0 and LED1. For ALPHA.
++ SW_LED_MODE2, // SW control 1 LED via GPIO0, customized for AzWave 8187 minicard.
++ SW_LED_MODE3, // SW control 1 LED via GPIO0, customized for Sercomm Printer Server case.
++ SW_LED_MODE4, //added by lizhaoming for bluetooth 2008.6.3
++ SW_LED_MODE5, //added by lizhaoming for bluetooth 2008.6.3
++ HW_LED, // HW control 2 LEDs, LED0 and LED1 (there are 4 different control modes, see MAC.CONFIG1 for details.)
++}LED_STRATEGY_8187, *PLED_STRATEGY_8187;
++
++typedef enum _LED_PIN_8187{
++ LED_PIN_GPIO0,
++ LED_PIN_LED0,
++ LED_PIN_LED1
++}LED_PIN_8187;
++
++//by lizhaoming for LED 2008.6.23 into ieee80211.h
++//typedef enum _LED_CTL_MODE {
++// LED_CTL_POWER_ON,
++// LED_CTL_POWER_OFF,
++// LED_CTL_LINK,
++// LED_CTL_NO_LINK,
++// LED_CTL_TX,
++// LED_CTL_RX,
++// LED_CTL_SITE_SURVEY,
++//} LED_CTL_MODE;
++
++typedef struct _LED_8187{
++ LED_PIN_8187 LedPin; // Identify how to implement this SW led.
++
++ LED_STATE_8187 CurrLedState; // Current LED state.
++ u8 bLedOn; // TRUE if LED is ON, FALSE if LED is OFF.
++
++ u8 bLedBlinkInProgress; // TRUE if it is blinking, FALSE o.w..
++ u32 BlinkTimes; // Number of times to toggle led state for blinking.
++ LED_STATE_8187 BlinkingLedState; // Next state for blinking, either LED_ON or LED_OFF are.
++ struct timer_list BlinkTimer; // Timer object for led blinking.
++} LED_8187, *PLED_8187;
++
++
++
++/*------------------------Export global variable------------------------------*/
++
++
++/*------------------------------Funciton declaration--------------------------*/
++void
++InitSwLeds(
++ struct net_device *dev
++ );
++
++void
++DeInitSwLeds(
++ struct net_device *dev
++ );
++
++void
++InitLed8187(
++ struct net_device *dev,
++ PLED_8187 pLed,
++ LED_PIN_8187 LedPin,
++ void * BlinkCallBackFunc);
++
++void
++DeInitLed8187(
++ struct net_device *dev,
++ PLED_8187 pLed);
++
++void
++LedControl8187(
++ struct net_device *dev,
++ LED_CTL_MODE LedAction
++);
++
++void
++SwLedControlMode0(
++ struct net_device *dev,
++ LED_CTL_MODE LedAction
++);
++
++void
++SwLedControlMode1(
++ struct net_device *dev,
++ LED_CTL_MODE LedAction
++);
++
++void
++SwLedControlMode2(
++ struct net_device *dev,
++ LED_CTL_MODE LedAction
++);
++
++void
++SwLedControlMode3(
++ struct net_device *dev,
++ LED_CTL_MODE LedAction
++);
++
++
++void
++SwLedControlMode4(
++ struct net_device *dev,
++ LED_CTL_MODE LedAction
++);
++
++
++void
++SwLedControlMode5(
++ struct net_device *dev,
++ LED_CTL_MODE LedAction
++);
++
++void
++Gpio0LedBlinkTimerCallback(
++ unsigned long data
++ );
++
++void
++SwLed0BlinkTimerCallback(
++ unsigned long data
++ );
++
++void
++SwLed1BlinkTimerCallback(
++ unsigned long data
++ );
++
++void
++PlatformSwLedBlink(
++ struct net_device *dev,
++ PLED_8187 pLed
++ );
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
++void
++Gpio0LedWorkItemCallback(
++ void * Context
++ );
++
++void
++SwLed0WorkItemCallback(
++ void * Context
++ );
++
++void
++SwLed1WorkItemCallback(
++ void * Context
++ );
++#else
++void
++Gpio0LedWorkItemCallback(struct work_struct *work);
++
++void
++SwLed0WorkItemCallback(struct work_struct *work);
++
++void
++SwLed1WorkItemCallback(struct work_struct *work);
++
++#endif
++void
++SwLedBlink(
++ struct net_device *dev,
++ PLED_8187 pLed
++ );
++
++void
++SwLedCm2Blink(
++ struct net_device *dev,
++ PLED_8187 pLed
++ );
++
++void
++SwLedCm4Blink(
++ struct net_device *dev,
++ PLED_8187 pLed
++ );
++
++void
++SwLedOn(
++ struct net_device *dev,
++ PLED_8187 pLed
++);
++
++void
++SwLedOff(
++ struct net_device *dev,
++ PLED_8187 pLed
++);
++
++
++#endif
+diff --git a/drivers/net/wireless/rtl8187b/r8187_rfkill.c b/drivers/net/wireless/rtl8187b/r8187_rfkill.c
+new file mode 100644
+index 0000000..51717d6
+--- /dev/null
++++ b/drivers/net/wireless/rtl8187b/r8187_rfkill.c
+@@ -0,0 +1,157 @@
++/*
++ * rtl8187b specific rfkill support
++ *
++ * NOTE: we only concern about two states
++ * eRfOff: RFKILL_STATE_SOFT_BLOCKED
++ * eRfOn: RFKILL_STATE_UNBLOCKED
++ * TODO: move led controlling source code to rfkill framework
++ *
++ * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
++ * Author: Wu Zhangjin <wuzj@lemote.com>
++ */
++
++#include <linux/module.h>
++#include <linux/rfkill.h>
++#include <linux/device.h>
++
++/* LED macros are defined in r8187.h and rfkill.h, we not use any of them here
++ * just avoid compiling erros here.
++ */
++#undef LED
++
++#include "r8187.h"
++#include "ieee80211/ieee80211.h"
++#include "linux/netdevice.h"
++
++static struct rfkill *r8187b_rfkill;
++static struct work_struct r8187b_rfkill_task;
++static int initialized;
++/* turn off by default */
++int r8187b_rfkill_state = RFKILL_USER_STATE_SOFT_BLOCKED;
++struct net_device *r8187b_dev = NULL;
++RT_RF_POWER_STATE eRfPowerStateToSet;
++
++/* These two mutexes are used to ensure the relative rfkill status are accessed
++ * by different tasks exclusively */
++DEFINE_MUTEX(statetoset_lock);
++DEFINE_MUTEX(state_lock);
++
++static void r8187b_wifi_rfkill_task(struct work_struct *work)
++{
++ if (r8187b_dev) {
++ mutex_lock(&statetoset_lock);
++ r8187b_wifi_change_rfkill_state(r8187b_dev, eRfPowerStateToSet);
++ mutex_unlock(&statetoset_lock);
++ }
++}
++
++static int r8187b_wifi_update_rfkill_state(int status)
++{
++ /* ensure r8187b_rfkill is initialized if dev is not initialized, means
++ * wifi driver is not start, the status is eRfOff be default.
++ */
++ if (!r8187b_dev)
++ return eRfOff;
++
++ if (initialized == 0) {
++ /* init the rfkill work task */
++ INIT_WORK(&r8187b_rfkill_task, r8187b_wifi_rfkill_task);
++ initialized = 1;
++ }
++
++ mutex_lock(&statetoset_lock);
++ if (status == 1)
++ eRfPowerStateToSet = eRfOn;
++ else if (status == 0)
++ eRfPowerStateToSet = eRfOff;
++ else if (status == 2) {
++ /* if the KEY_WLAN is pressed, just switch it! */
++ mutex_lock(&state_lock);
++ if (r8187b_rfkill_state == RFKILL_USER_STATE_UNBLOCKED)
++ eRfPowerStateToSet = eRfOff;
++ else if (r8187b_rfkill_state == RFKILL_USER_STATE_SOFT_BLOCKED)
++ eRfPowerStateToSet = eRfOn;
++ mutex_unlock(&state_lock);
++ }
++ mutex_unlock(&statetoset_lock);
++
++ schedule_work(&r8187b_rfkill_task);
++
++ return eRfPowerStateToSet;
++}
++
++static int r8187b_rfkill_set(void *data, bool blocked)
++{
++ r8187b_wifi_update_rfkill_state(!blocked);
++
++ return 0;
++}
++
++static void r8187b_rfkill_query(struct rfkill *rfkill, void *data)
++{
++ static bool blocked;
++
++ mutex_lock(&state_lock);
++ if (r8187b_rfkill_state == RFKILL_USER_STATE_UNBLOCKED)
++ blocked = 0;
++ else if (r8187b_rfkill_state == RFKILL_USER_STATE_SOFT_BLOCKED)
++ blocked = 1;
++ mutex_unlock(&state_lock);
++
++ rfkill_set_hw_state(rfkill, blocked);
++}
++
++int r8187b_wifi_report_state(r8180_priv *priv)
++{
++ mutex_lock(&state_lock);
++ r8187b_rfkill_state = RFKILL_USER_STATE_UNBLOCKED;
++ if (priv->ieee80211->bHwRadioOff && priv->eRFPowerState == eRfOff)
++ r8187b_rfkill_state = RFKILL_USER_STATE_SOFT_BLOCKED;
++ mutex_unlock(&state_lock);
++
++ r8187b_rfkill_query(r8187b_rfkill, NULL);
++
++ return 0;
++}
++
++static const struct rfkill_ops r8187b_rfkill_ops = {
++ .set_block = r8187b_rfkill_set,
++ .query = r8187b_rfkill_query,
++};
++
++int r8187b_rfkill_init(struct net_device *dev)
++{
++ int ret;
++
++ /* init the r8187b device */
++ r8187b_dev = dev;
++
++ /* init the rfkill struct */
++ r8187b_rfkill = rfkill_alloc("r8187b-wifi", &dev->dev,
++ RFKILL_TYPE_WLAN, &r8187b_rfkill_ops,
++ (void *)1);
++
++ if (!r8187b_rfkill) {
++ rfkill_destroy(r8187b_rfkill);
++ printk(KERN_WARNING "r8187b: Unable to allocate rfkill\n");
++ return -ENOMEM;
++ }
++ ret = rfkill_register(r8187b_rfkill);
++ if (ret) {
++ rfkill_destroy(r8187b_rfkill);
++ return ret;
++ }
++
++ /* The default status is passed to the rfkill module */
++
++ return 0;
++}
++
++void r8187b_rfkill_exit(void)
++{
++ if (r8187b_rfkill) {
++ rfkill_unregister(r8187b_rfkill);
++ rfkill_destroy(r8187b_rfkill);
++ }
++ r8187b_rfkill = NULL;
++}
+diff --git a/drivers/net/wireless/rtl8187b/readme b/drivers/net/wireless/rtl8187b/readme
+new file mode 100644
+index 0000000..4438d2a
+--- /dev/null
++++ b/drivers/net/wireless/rtl8187b/readme
+@@ -0,0 +1,124 @@
++rtl8187 Linux kernel driver
++Released under the terms of GNU General Public Licence (GPL)
++Copyright(c) Andrea Merello - 2004,2005
++
++Portions of this driver are based on other projects, please see the notes
++in the source files for detail.
++A special thanks go to Realtek corp for their support and to David Young
++------------------------------------------------------------------------------
++
++This is an attempt to write somethig that can make rtl8187 usb dongle wifi card
++on Linux using only opensource stuff.
++The rtl8225 radio is supported.
++
++It's in early development stage so don't expect too much from it
++(also use it at your own risk!)
++This should be considered just a fragment of code.. using it on your(any)
++system is at your own risk! Please note that I never supported the idea to
++use it in any way, so i cannot be considered responsible in any way for
++anything deriving by it usage.
++
++Anyway for now we have monitor mode and managed mode
++basically working! This isn't necessary stable, but seems to work..
++
++This driver is still under development and very far from perfect. It should work on x86,
++Other archs are untested..
++
++To compile the driver simply run make.
++
++The driver contains also the ieee80211.h and ieee80211_crypt.h from the ieee stack.
++Note that for some reasons this stack is NOT the same that will be included in newer
++2.6 kernel. I will try to port to this stack as soon as it will have enought features
++to support 8187 cards.
++Please note that you will have to make sure the two .h files are the same of the ieee
++stack.
++In other words when you download from the CVS this driver and the ieee80211 stack a good
++idea is to copy the ieee80211.h and ieee80211_crypt.h from the ieee directory to the drv
++directory
++
++Warning during compile are OK
++
++To wake up the nic run:
++
++ ifconfig <ifacename> up
++
++(where <ifacename> is your network device for wlan card).
++
++Please note that the default interface name is wlanX.
++
++Please note thet this will take several seconds..
++
++If you would like to set the interface name to something else you may use the
++'devname=' module parameter. For example:
++
++ insmod r8187.ko ifname=eth%d
++
++will set the interface name of this device to something like eth0.
++
++Once the nic is up it can be put in a monitor mode by running:
++
++ iwconfig <ifacename> mode monitor
++
++and channel number may be changed by running:
++
++ iwconfig <ifacename> channel XX
++
++
++In monitor mode a choice may be made via iwpriv if the nic should pass packets
++with bad crc or drop them.
++
++To put the nic in managed mode run:
++
++ iwconfig <ifacename> mode managed
++
++In managed mode there is support for
++
++ iwlist scan
++
++that should report the currently available networks.
++Please note that in managed mode channels cannot be changed manually.
++
++To associate with a network
++
++ iwconfig <ifacename> essid XXXXX
++
++where XXXXX is the network essid (name) reported by 'iwlist scan'. Please
++note that essid is case sensitive.
++
++If your network is not broadcasting the ESSID, then you need to specify *also*
++the AP MAC address
++
++ iwconfig <ifacename> ap XX:XX:XX:XX:XX:XX
++
++The driver accepts another boolean parameter: hwseqnum
++If set to 1 it lets the card HW take care of the sequence number of the TXed
++frames. Altought in managed mode I can't see an important reason to use HW to
++do that, when we'll start to TX beacons in master (AP) and ad-hoc modes most
++probably it will be extremely useful (since most probably we will use two HW
++queues).
++
++I'm unsure if it will work correctly on all NICs.. reports are *VERY, VERY* apreciated..
++
++
++ WEP
++ ===
++
++WEP encryption should work. For now it's done by host, not by the nic. Key can be set with:
++Key can be set with
++
++ iwconfig <ifacename> key 12345...
++
++WEP is supported via software thanks to the ipw stack.
++
++Shared and open authentication are supported
++
++ IWPRIV
++ ======
++
++This driver supports some private handlers:
++-badcrc: let you choose to kill or to pass to the upper layer frames with bad crc in monitor mode
++-activescan: if 0 the driver will avoid to send probe requests, sanning will be only on beacon basis
++
++
++If you have some question/comments please feel free to write me.
++
+diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
+index 17f38a7..5ed3b93 100644
+--- a/drivers/pcmcia/Kconfig
++++ b/drivers/pcmcia/Kconfig
+@@ -192,6 +192,27 @@ config PCMCIA_AU1X00
+ tristate "Au1x00 pcmcia support"
+ depends on SOC_AU1X00 && PCMCIA
+
++config PCMCIA_ALCHEMY_DEVBOARD
++ tristate "Alchemy Db/Pb1xxx PCMCIA socket services"
++ depends on SOC_AU1X00 && PCMCIA
++ select 64BIT_PHYS_ADDR
++ help
++ Enable this driver of you want PCMCIA support on your Alchemy
++ Db1000, Db/Pb1100, Db/Pb1500, Db/Pb1550, Db/Pb1200 board.
++ NOT suitable for the PB1000!
++
++ This driver is also available as a module called db1xxx_ss.ko
++
++config PCMCIA_XXS1500
++ tristate "MyCable XXS1500 PCMCIA socket support"
++ depends on PCMCIA && MIPS_XXS1500
++ select 64BIT_PHYS_ADDR
++ help
++ Support for the PCMCIA/CF socket interface on MyCable XXS1500
++ systems.
++
++ This driver is also available as a module called xxs1500_ss.ko
++
+ config PCMCIA_BCM63XX
+ tristate "bcm63xx pcmcia support"
+ depends on BCM63XX && PCMCIA
+diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
+index a03a38a..8bd8b02 100644
+--- a/drivers/pcmcia/Makefile
++++ b/drivers/pcmcia/Makefile
+@@ -34,21 +34,13 @@ obj-$(CONFIG_OMAP_CF) += omap_cf.o
+ obj-$(CONFIG_BFIN_CFPCMCIA) += bfin_cf_pcmcia.o
+ obj-$(CONFIG_AT91_CF) += at91_cf.o
+ obj-$(CONFIG_ELECTRA_CF) += electra_cf.o
++obj-$(CONFIG_PCMCIA_ALCHEMY_DEVBOARD) += db1xxx_ss.o
+
+ sa11xx_core-y += soc_common.o sa11xx_base.o
+ pxa2xx_core-y += soc_common.o pxa2xx_base.o
+
+ au1x00_ss-y += au1000_generic.o
+ au1x00_ss-$(CONFIG_MIPS_PB1000) += au1000_pb1x00.o
+-au1x00_ss-$(CONFIG_MIPS_PB1100) += au1000_pb1x00.o
+-au1x00_ss-$(CONFIG_MIPS_PB1200) += au1000_db1x00.o
+-au1x00_ss-$(CONFIG_MIPS_PB1500) += au1000_pb1x00.o
+-au1x00_ss-$(CONFIG_MIPS_DB1000) += au1000_db1x00.o
+-au1x00_ss-$(CONFIG_MIPS_DB1100) += au1000_db1x00.o
+-au1x00_ss-$(CONFIG_MIPS_DB1200) += au1000_db1x00.o
+-au1x00_ss-$(CONFIG_MIPS_DB1500) += au1000_db1x00.o
+-au1x00_ss-$(CONFIG_MIPS_DB1550) += au1000_db1x00.o
+-au1x00_ss-$(CONFIG_MIPS_XXS1500) += au1000_xxs1500.o
+
+ sa1111_cs-y += sa1111_generic.o
+ sa1111_cs-$(CONFIG_ASSABET_NEPONSET) += sa1100_neponset.o
+@@ -78,3 +70,5 @@ pxa2xx-obj-$(CONFIG_MACH_E740) += pxa2xx_e740.o
+ pxa2xx-obj-$(CONFIG_MACH_STARGATE2) += pxa2xx_stargate2.o
+
+ obj-$(CONFIG_PCMCIA_PXA2XX) += pxa2xx_core.o $(pxa2xx-obj-y)
++
++obj-$(CONFIG_PCMCIA_XXS1500) += xxs1500_ss.o
+diff --git a/drivers/pcmcia/au1000_db1x00.c b/drivers/pcmcia/au1000_db1x00.c
+deleted file mode 100644
+index c78d77f..0000000
+--- a/drivers/pcmcia/au1000_db1x00.c
++++ /dev/null
+@@ -1,305 +0,0 @@
+-/*
+- *
+- * Alchemy Semi Db1x00 boards specific pcmcia routines.
+- *
+- * Copyright 2002 MontaVista Software Inc.
+- * Author: MontaVista Software, Inc.
+- * ppopov@mvista.com or source@mvista.com
+- *
+- * Copyright 2004 Pete Popov, updated the driver to 2.6.
+- * Followed the sa11xx API and largely copied many of the hardware
+- * independent functions.
+- *
+- * ########################################################################
+- *
+- * This program is free software; you can distribute it and/or modify it
+- * under the terms of the GNU General Public License (Version 2) as
+- * published by the Free Software Foundation.
+- *
+- * This program is distributed in the hope it will be useful, but WITHOUT
+- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+- * for more details.
+- *
+- * You should have received a copy of the GNU General Public License along
+- * with this program; if not, write to the Free Software Foundation, Inc.,
+- * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+- *
+- * ########################################################################
+- *
+- *
+- */
+-
+-#include <linux/module.h>
+-#include <linux/kernel.h>
+-#include <linux/errno.h>
+-#include <linux/interrupt.h>
+-#include <linux/device.h>
+-#include <linux/init.h>
+-
+-#include <asm/irq.h>
+-#include <asm/signal.h>
+-#include <asm/mach-au1x00/au1000.h>
+-
+-#if defined(CONFIG_MIPS_DB1200)
+- #include <db1200.h>
+-#elif defined(CONFIG_MIPS_PB1200)
+- #include <pb1200.h>
+-#else
+- #include <asm/mach-db1x00/db1x00.h>
+- static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
+-#endif
+-
+-#include "au1000_generic.h"
+-
+-#if 0
+-#define debug(x,args...) printk(KERN_DEBUG "%s: " x, __func__ , ##args)
+-#else
+-#define debug(x,args...)
+-#endif
+-
+-
+-struct au1000_pcmcia_socket au1000_pcmcia_socket[PCMCIA_NUM_SOCKS];
+-extern int au1x00_pcmcia_socket_probe(struct device *, struct pcmcia_low_level *, int, int);
+-
+-static int db1x00_pcmcia_hw_init(struct au1000_pcmcia_socket *skt)
+-{
+-#ifdef CONFIG_MIPS_DB1550
+- skt->irq = skt->nr ? AU1000_GPIO_5 : AU1000_GPIO_3;
+-#elif defined(CONFIG_MIPS_DB1200) || defined(CONFIG_MIPS_PB1200)
+- skt->irq = skt->nr ? BOARD_PC1_INT : BOARD_PC0_INT;
+-#else
+- skt->irq = skt->nr ? AU1000_GPIO_5 : AU1000_GPIO_2;
+-#endif
+- return 0;
+-}
+-
+-static void db1x00_pcmcia_shutdown(struct au1000_pcmcia_socket *skt)
+-{
+- bcsr->pcmcia = 0; /* turn off power */
+- au_sync_delay(2);
+-}
+-
+-static void
+-db1x00_pcmcia_socket_state(struct au1000_pcmcia_socket *skt, struct pcmcia_state *state)
+-{
+- u32 inserted;
+- unsigned char vs;
+-
+- state->ready = 0;
+- state->vs_Xv = 0;
+- state->vs_3v = 0;
+- state->detect = 0;
+-
+- switch (skt->nr) {
+- case 0:
+- vs = bcsr->status & 0x3;
+-#if defined(CONFIG_MIPS_DB1200) || defined(CONFIG_MIPS_PB1200)
+- inserted = BOARD_CARD_INSERTED(0);
+-#else
+- inserted = !(bcsr->status & (1<<4));
+-#endif
+- break;
+- case 1:
+- vs = (bcsr->status & 0xC)>>2;
+-#if defined(CONFIG_MIPS_DB1200) || defined(CONFIG_MIPS_PB1200)
+- inserted = BOARD_CARD_INSERTED(1);
+-#else
+- inserted = !(bcsr->status & (1<<5));
+-#endif
+- break;
+- default:/* should never happen */
+- return;
+- }
+-
+- if (inserted)
+- debug("db1x00 socket %d: inserted %d, vs %d pcmcia %x\n",
+- skt->nr, inserted, vs, bcsr->pcmcia);
+-
+- if (inserted) {
+- switch (vs) {
+- case 0:
+- case 2:
+- state->vs_3v=1;
+- break;
+- case 3: /* 5V */
+- break;
+- default:
+- /* return without setting 'detect' */
+- printk(KERN_ERR "db1x00 bad VS (%d)\n",
+- vs);
+- }
+- state->detect = 1;
+- state->ready = 1;
+- }
+- else {
+- /* if the card was previously inserted and then ejected,
+- * we should turn off power to it
+- */
+- if ((skt->nr == 0) && (bcsr->pcmcia & BCSR_PCMCIA_PC0RST)) {
+- bcsr->pcmcia &= ~(BCSR_PCMCIA_PC0RST |
+- BCSR_PCMCIA_PC0DRVEN |
+- BCSR_PCMCIA_PC0VPP |
+- BCSR_PCMCIA_PC0VCC);
+- au_sync_delay(10);
+- }
+- else if ((skt->nr == 1) && bcsr->pcmcia & BCSR_PCMCIA_PC1RST) {
+- bcsr->pcmcia &= ~(BCSR_PCMCIA_PC1RST |
+- BCSR_PCMCIA_PC1DRVEN |
+- BCSR_PCMCIA_PC1VPP |
+- BCSR_PCMCIA_PC1VCC);
+- au_sync_delay(10);
+- }
+- }
+-
+- state->bvd1=1;
+- state->bvd2=1;
+- state->wrprot=0;
+-}
+-
+-static int
+-db1x00_pcmcia_configure_socket(struct au1000_pcmcia_socket *skt, struct socket_state_t *state)
+-{
+- u16 pwr;
+- int sock = skt->nr;
+-
+- debug("config_skt %d Vcc %dV Vpp %dV, reset %d\n",
+- sock, state->Vcc, state->Vpp,
+- state->flags & SS_RESET);
+-
+- /* pcmcia reg was set to zero at init time. Be careful when
+- * initializing a socket not to wipe out the settings of the
+- * other socket.
+- */
+- pwr = bcsr->pcmcia;
+- pwr &= ~(0xf << sock*8); /* clear voltage settings */
+-
+- state->Vpp = 0;
+- switch(state->Vcc){
+- case 0: /* Vcc 0 */
+- pwr |= SET_VCC_VPP(0,0,sock);
+- break;
+- case 50: /* Vcc 5V */
+- switch(state->Vpp) {
+- case 0:
+- pwr |= SET_VCC_VPP(2,0,sock);
+- break;
+- case 50:
+- pwr |= SET_VCC_VPP(2,1,sock);
+- break;
+- case 12:
+- pwr |= SET_VCC_VPP(2,2,sock);
+- break;
+- case 33:
+- default:
+- pwr |= SET_VCC_VPP(0,0,sock);
+- printk("%s: bad Vcc/Vpp (%d:%d)\n",
+- __func__,
+- state->Vcc,
+- state->Vpp);
+- break;
+- }
+- break;
+- case 33: /* Vcc 3.3V */
+- switch(state->Vpp) {
+- case 0:
+- pwr |= SET_VCC_VPP(1,0,sock);
+- break;
+- case 12:
+- pwr |= SET_VCC_VPP(1,2,sock);
+- break;
+- case 33:
+- pwr |= SET_VCC_VPP(1,1,sock);
+- break;
+- case 50:
+- default:
+- pwr |= SET_VCC_VPP(0,0,sock);
+- printk("%s: bad Vcc/Vpp (%d:%d)\n",
+- __func__,
+- state->Vcc,
+- state->Vpp);
+- break;
+- }
+- break;
+- default: /* what's this ? */
+- pwr |= SET_VCC_VPP(0,0,sock);
+- printk(KERN_ERR "%s: bad Vcc %d\n",
+- __func__, state->Vcc);
+- break;
+- }
+-
+- bcsr->pcmcia = pwr;
+- au_sync_delay(300);
+-
+- if (sock == 0) {
+- if (!(state->flags & SS_RESET)) {
+- pwr |= BCSR_PCMCIA_PC0DRVEN;
+- bcsr->pcmcia = pwr;
+- au_sync_delay(300);
+- pwr |= BCSR_PCMCIA_PC0RST;
+- bcsr->pcmcia = pwr;
+- au_sync_delay(100);
+- }
+- else {
+- pwr &= ~(BCSR_PCMCIA_PC0RST | BCSR_PCMCIA_PC0DRVEN);
+- bcsr->pcmcia = pwr;
+- au_sync_delay(100);
+- }
+- }
+- else {
+- if (!(state->flags & SS_RESET)) {
+- pwr |= BCSR_PCMCIA_PC1DRVEN;
+- bcsr->pcmcia = pwr;
+- au_sync_delay(300);
+- pwr |= BCSR_PCMCIA_PC1RST;
+- bcsr->pcmcia = pwr;
+- au_sync_delay(100);
+- }
+- else {
+- pwr &= ~(BCSR_PCMCIA_PC1RST | BCSR_PCMCIA_PC1DRVEN);
+- bcsr->pcmcia = pwr;
+- au_sync_delay(100);
+- }
+- }
+- return 0;
+-}
+-
+-/*
+- * Enable card status IRQs on (re-)initialisation. This can
+- * be called at initialisation, power management event, or
+- * pcmcia event.
+- */
+-void db1x00_socket_init(struct au1000_pcmcia_socket *skt)
+-{
+- /* nothing to do for now */
+-}
+-
+-/*
+- * Disable card status IRQs and PCMCIA bus on suspend.
+- */
+-void db1x00_socket_suspend(struct au1000_pcmcia_socket *skt)
+-{
+- /* nothing to do for now */
+-}
+-
+-struct pcmcia_low_level db1x00_pcmcia_ops = {
+- .owner = THIS_MODULE,
+-
+- .hw_init = db1x00_pcmcia_hw_init,
+- .hw_shutdown = db1x00_pcmcia_shutdown,
+-
+- .socket_state = db1x00_pcmcia_socket_state,
+- .configure_socket = db1x00_pcmcia_configure_socket,
+-
+- .socket_init = db1x00_socket_init,
+- .socket_suspend = db1x00_socket_suspend
+-};
+-
+-int au1x_board_init(struct device *dev)
+-{
+- int ret = -ENODEV;
+- bcsr->pcmcia = 0; /* turn off power, if it's not already off */
+- au_sync_delay(2);
+- ret = au1x00_pcmcia_socket_probe(dev, &db1x00_pcmcia_ops, 0, 2);
+- return ret;
+-}
+diff --git a/drivers/pcmcia/au1000_generic.h b/drivers/pcmcia/au1000_generic.h
+index 13a4fbc..aa743f6 100644
+--- a/drivers/pcmcia/au1000_generic.h
++++ b/drivers/pcmcia/au1000_generic.h
+@@ -44,22 +44,12 @@
+ /* pcmcia socket 1 needs external glue logic so the memory map
+ * differs from board to board.
+ */
+-#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1100) || \
+- defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_PB1550) || \
+- defined(CONFIG_MIPS_PB1200)
++#if defined(CONFIG_MIPS_PB1000)
+ #define AU1X_SOCK1_IO 0xF08000000ULL
+ #define AU1X_SOCK1_PHYS_ATTR 0xF48000000ULL
+ #define AU1X_SOCK1_PHYS_MEM 0xF88000000ULL
+ #define AU1X_SOCK1_PSEUDO_PHYS_ATTR 0xF4800000
+ #define AU1X_SOCK1_PSEUDO_PHYS_MEM 0xF8800000
+-#elif defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || \
+- defined(CONFIG_MIPS_DB1500) || defined(CONFIG_MIPS_DB1550) || \
+- defined(CONFIG_MIPS_DB1200)
+-#define AU1X_SOCK1_IO 0xF04000000ULL
+-#define AU1X_SOCK1_PHYS_ATTR 0xF44000000ULL
+-#define AU1X_SOCK1_PHYS_MEM 0xF84000000ULL
+-#define AU1X_SOCK1_PSEUDO_PHYS_ATTR 0xF4400000
+-#define AU1X_SOCK1_PSEUDO_PHYS_MEM 0xF8400000
+ #endif
+
+ struct pcmcia_state {
+diff --git a/drivers/pcmcia/au1000_pb1x00.c b/drivers/pcmcia/au1000_pb1x00.c
+index b1984ed..5a979cb 100644
+--- a/drivers/pcmcia/au1000_pb1x00.c
++++ b/drivers/pcmcia/au1000_pb1x00.c
+@@ -1,6 +1,6 @@
+ /*
+ *
+- * Alchemy Semi Pb1x00 boards specific pcmcia routines.
++ * Alchemy Semi Pb1000 boards specific pcmcia routines.
+ *
+ * Copyright 2002 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+@@ -46,20 +46,11 @@
+
+ #define debug(fmt, arg...) do { } while (0)
+
+-#ifdef CONFIG_MIPS_PB1000
+ #include <asm/pb1000.h>
+ #define PCMCIA_IRQ AU1000_GPIO_15
+-#elif defined (CONFIG_MIPS_PB1500)
+-#include <asm/pb1500.h>
+-#define PCMCIA_IRQ AU1500_GPIO_203
+-#elif defined (CONFIG_MIPS_PB1100)
+-#include <asm/pb1100.h>
+-#define PCMCIA_IRQ AU1000_GPIO_11
+-#endif
+
+ static int pb1x00_pcmcia_init(struct pcmcia_init *init)
+ {
+-#ifdef CONFIG_MIPS_PB1000
+ u16 pcr;
+ pcr = PCR_SLOT_0_RST | PCR_SLOT_1_RST;
+
+@@ -74,21 +65,10 @@ static int pb1x00_pcmcia_init(struct pcmcia_init *init)
+ au_sync_delay(20);
+
+ return PCMCIA_NUM_SOCKS;
+-
+-#else /* fixme -- take care of the Pb1500 at some point */
+-
+- u16 pcr;
+- pcr = au_readw(PCMCIA_BOARD_REG) & ~0xf; /* turn off power */
+- pcr &= ~(PC_DEASSERT_RST | PC_DRV_EN);
+- au_writew(pcr, PCMCIA_BOARD_REG);
+- au_sync_delay(500);
+- return PCMCIA_NUM_SOCKS;
+-#endif
+ }
+
+ static int pb1x00_pcmcia_shutdown(void)
+ {
+-#ifdef CONFIG_MIPS_PB1000
+ u16 pcr;
+ pcr = PCR_SLOT_0_RST | PCR_SLOT_1_RST;
+ pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,0);
+@@ -96,14 +76,6 @@ static int pb1x00_pcmcia_shutdown(void)
+ au_writel(pcr, PB1000_PCR);
+ au_sync_delay(20);
+ return 0;
+-#else
+- u16 pcr;
+- pcr = au_readw(PCMCIA_BOARD_REG) & ~0xf; /* turn off power */
+- pcr &= ~(PC_DEASSERT_RST | PC_DRV_EN);
+- au_writew(pcr, PCMCIA_BOARD_REG);
+- au_sync_delay(2);
+- return 0;
+-#endif
+ }
+
+ static int
+@@ -112,21 +84,11 @@ pb1x00_pcmcia_socket_state(unsigned sock, struct pcmcia_state *state)
+ u32 inserted0, inserted1;
+ u16 vs0, vs1;
+
+-#ifdef CONFIG_MIPS_PB1000
+ vs0 = vs1 = (u16)au_readl(PB1000_ACR1);
+ inserted0 = !(vs0 & (ACR1_SLOT_0_CD1 | ACR1_SLOT_0_CD2));
+ inserted1 = !(vs1 & (ACR1_SLOT_1_CD1 | ACR1_SLOT_1_CD2));
+ vs0 = (vs0 >> 4) & 0x3;
+ vs1 = (vs1 >> 12) & 0x3;
+-#else
+- vs0 = (au_readw(BOARD_STATUS_REG) >> 4) & 0x3;
+-#ifdef CONFIG_MIPS_PB1500
+- inserted0 = !((au_readl(GPIO2_PINSTATE) >> 1) & 0x1); /* gpio 201 */
+-#else /* Pb1100 */
+- inserted0 = !((au_readl(SYS_PINSTATERD) >> 9) & 0x1); /* gpio 9 */
+-#endif
+- inserted1 = 0;
+-#endif
+
+ state->ready = 0;
+ state->vs_Xv = 0;
+@@ -203,7 +165,6 @@ pb1x00_pcmcia_configure_socket(const struct pcmcia_configure *configure)
+
+ if(configure->sock > PCMCIA_MAX_SOCK) return -1;
+
+-#ifdef CONFIG_MIPS_PB1000
+ pcr = au_readl(PB1000_PCR);
+
+ if (configure->sock == 0) {
+@@ -323,84 +284,6 @@ pb1x00_pcmcia_configure_socket(const struct pcmcia_configure *configure)
+ au_writel(pcr, PB1000_PCR);
+ au_sync_delay(300);
+
+-#else
+-
+- pcr = au_readw(PCMCIA_BOARD_REG) & ~0xf;
+-
+- debug("Vcc %dV Vpp %dV, pcr %x, reset %d\n",
+- configure->vcc, configure->vpp, pcr, configure->reset);
+-
+-
+- switch(configure->vcc){
+- case 0: /* Vcc 0 */
+- pcr |= SET_VCC_VPP(0,0);
+- break;
+- case 50: /* Vcc 5V */
+- switch(configure->vpp) {
+- case 0:
+- pcr |= SET_VCC_VPP(2,0);
+- break;
+- case 50:
+- pcr |= SET_VCC_VPP(2,1);
+- break;
+- case 12:
+- pcr |= SET_VCC_VPP(2,2);
+- break;
+- case 33:
+- default:
+- pcr |= SET_VCC_VPP(0,0);
+- printk("%s: bad Vcc/Vpp (%d:%d)\n",
+- __func__,
+- configure->vcc,
+- configure->vpp);
+- break;
+- }
+- break;
+- case 33: /* Vcc 3.3V */
+- switch(configure->vpp) {
+- case 0:
+- pcr |= SET_VCC_VPP(1,0);
+- break;
+- case 12:
+- pcr |= SET_VCC_VPP(1,2);
+- break;
+- case 33:
+- pcr |= SET_VCC_VPP(1,1);
+- break;
+- case 50:
+- default:
+- pcr |= SET_VCC_VPP(0,0);
+- printk("%s: bad Vcc/Vpp (%d:%d)\n",
+- __func__,
+- configure->vcc,
+- configure->vpp);
+- break;
+- }
+- break;
+- default: /* what's this ? */
+- pcr |= SET_VCC_VPP(0,0);
+- printk(KERN_ERR "%s: bad Vcc %d\n",
+- __func__, configure->vcc);
+- break;
+- }
+-
+- au_writew(pcr, PCMCIA_BOARD_REG);
+- au_sync_delay(300);
+-
+- if (!configure->reset) {
+- pcr |= PC_DRV_EN;
+- au_writew(pcr, PCMCIA_BOARD_REG);
+- au_sync_delay(100);
+- pcr |= PC_DEASSERT_RST;
+- au_writew(pcr, PCMCIA_BOARD_REG);
+- au_sync_delay(100);
+- }
+- else {
+- pcr &= ~(PC_DEASSERT_RST | PC_DRV_EN);
+- au_writew(pcr, PCMCIA_BOARD_REG);
+- au_sync_delay(100);
+- }
+-#endif
+ return 0;
+ }
+
+diff --git a/drivers/pcmcia/au1000_xxs1500.c b/drivers/pcmcia/au1000_xxs1500.c
+deleted file mode 100644
+index b43d47b..0000000
+--- a/drivers/pcmcia/au1000_xxs1500.c
++++ /dev/null
+@@ -1,188 +0,0 @@
+-/*
+- *
+- * MyCable board specific pcmcia routines.
+- *
+- * Copyright 2003 MontaVista Software Inc.
+- * Author: Pete Popov, MontaVista Software, Inc.
+- * ppopov@mvista.com or source@mvista.com
+- *
+- * ########################################################################
+- *
+- * This program is free software; you can distribute it and/or modify it
+- * under the terms of the GNU General Public License (Version 2) as
+- * published by the Free Software Foundation.
+- *
+- * This program is distributed in the hope it will be useful, but WITHOUT
+- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+- * for more details.
+- *
+- * You should have received a copy of the GNU General Public License along
+- * with this program; if not, write to the Free Software Foundation, Inc.,
+- * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+- *
+- * ########################################################################
+- *
+- *
+- */
+-#include <linux/module.h>
+-#include <linux/init.h>
+-#include <linux/delay.h>
+-#include <linux/ioport.h>
+-#include <linux/kernel.h>
+-#include <linux/timer.h>
+-#include <linux/mm.h>
+-#include <linux/proc_fs.h>
+-#include <linux/types.h>
+-
+-#include <pcmcia/cs_types.h>
+-#include <pcmcia/cs.h>
+-#include <pcmcia/ss.h>
+-#include <pcmcia/cistpl.h>
+-#include <pcmcia/bus_ops.h>
+-
+-#include <asm/io.h>
+-#include <asm/irq.h>
+-#include <asm/system.h>
+-
+-#include <asm/au1000.h>
+-#include <asm/au1000_pcmcia.h>
+-
+-#define PCMCIA_MAX_SOCK 0
+-#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1)
+-#define PCMCIA_IRQ AU1000_GPIO_4
+-
+-#if 0
+-#define DEBUG(x, args...) printk(__func__ ": " x, ##args)
+-#else
+-#define DEBUG(x,args...)
+-#endif
+-
+-static int xxs1500_pcmcia_init(struct pcmcia_init *init)
+-{
+- return PCMCIA_NUM_SOCKS;
+-}
+-
+-static int xxs1500_pcmcia_shutdown(void)
+-{
+- /* turn off power */
+- au_writel(au_readl(GPIO2_PINSTATE) | (1<<14)|(1<<30),
+- GPIO2_OUTPUT);
+- au_sync_delay(100);
+-
+- /* assert reset */
+- au_writel(au_readl(GPIO2_PINSTATE) | (1<<4)|(1<<20),
+- GPIO2_OUTPUT);
+- au_sync_delay(100);
+- return 0;
+-}
+-
+-
+-static int
+-xxs1500_pcmcia_socket_state(unsigned sock, struct pcmcia_state *state)
+-{
+- u32 inserted; u32 vs;
+- unsigned long gpio, gpio2;
+-
+- if(sock > PCMCIA_MAX_SOCK) return -1;
+-
+- gpio = au_readl(SYS_PINSTATERD);
+- gpio2 = au_readl(GPIO2_PINSTATE);
+-
+- vs = gpio2 & ((1<<8) | (1<<9));
+- inserted = (!(gpio & 0x1) && !(gpio & 0x2));
+-
+- state->ready = 0;
+- state->vs_Xv = 0;
+- state->vs_3v = 0;
+- state->detect = 0;
+-
+- if (inserted) {
+- switch (vs) {
+- case 0:
+- case 1:
+- case 2:
+- state->vs_3v=1;
+- break;
+- case 3: /* 5V */
+- default:
+- /* return without setting 'detect' */
+- printk(KERN_ERR "au1x00_cs: unsupported VS\n",
+- vs);
+- return;
+- }
+- state->detect = 1;
+- }
+-
+- if (state->detect) {
+- state->ready = 1;
+- }
+-
+- state->bvd1= gpio2 & (1<<10);
+- state->bvd2 = gpio2 & (1<<11);
+- state->wrprot=0;
+- return 1;
+-}
+-
+-
+-static int xxs1500_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
+-{
+-
+- if(info->sock > PCMCIA_MAX_SOCK) return -1;
+- info->irq = PCMCIA_IRQ;
+- return 0;
+-}
+-
+-
+-static int
+-xxs1500_pcmcia_configure_socket(const struct pcmcia_configure *configure)
+-{
+-
+- if(configure->sock > PCMCIA_MAX_SOCK) return -1;
+-
+- DEBUG("Vcc %dV Vpp %dV, reset %d\n",
+- configure->vcc, configure->vpp, configure->reset);
+-
+- switch(configure->vcc){
+- case 33: /* Vcc 3.3V */
+- /* turn on power */
+- DEBUG("turn on power\n");
+- au_writel((au_readl(GPIO2_PINSTATE) & ~(1<<14))|(1<<30),
+- GPIO2_OUTPUT);
+- au_sync_delay(100);
+- break;
+- case 50: /* Vcc 5V */
+- default: /* what's this ? */
+- printk(KERN_ERR "au1x00_cs: unsupported VCC\n");
+- case 0: /* Vcc 0 */
+- /* turn off power */
+- au_sync_delay(100);
+- au_writel(au_readl(GPIO2_PINSTATE) | (1<<14)|(1<<30),
+- GPIO2_OUTPUT);
+- break;
+- }
+-
+- if (!configure->reset) {
+- DEBUG("deassert reset\n");
+- au_writel((au_readl(GPIO2_PINSTATE) & ~(1<<4))|(1<<20),
+- GPIO2_OUTPUT);
+- au_sync_delay(100);
+- au_writel((au_readl(GPIO2_PINSTATE) & ~(1<<5))|(1<<21),
+- GPIO2_OUTPUT);
+- }
+- else {
+- DEBUG("assert reset\n");
+- au_writel(au_readl(GPIO2_PINSTATE) | (1<<4)|(1<<20),
+- GPIO2_OUTPUT);
+- }
+- au_sync_delay(100);
+- return 0;
+-}
+-
+-struct pcmcia_low_level xxs1500_pcmcia_ops = {
+- xxs1500_pcmcia_init,
+- xxs1500_pcmcia_shutdown,
+- xxs1500_pcmcia_socket_state,
+- xxs1500_pcmcia_get_irq_info,
+- xxs1500_pcmcia_configure_socket
+-};
+diff --git a/drivers/pcmcia/db1xxx_ss.c b/drivers/pcmcia/db1xxx_ss.c
+new file mode 100644
+index 0000000..b35b72b
+--- /dev/null
++++ b/drivers/pcmcia/db1xxx_ss.c
+@@ -0,0 +1,630 @@
++/*
++ * PCMCIA socket code for the Alchemy Db1xxx/Pb1xxx boards.
++ *
++ * Copyright (c) 2009 Manuel Lauss <manuel.lauss@gmail.com>
++ *
++ */
++
++/* This is a fairly generic PCMCIA socket driver suitable for the
++ * following Alchemy Development boards:
++ * Db1000, Db/Pb1500, Db/Pb1100, Db/Pb1550, Db/Pb1200.
++ *
++ * The Db1000 is used as a reference: Per-socket card-, carddetect- and
++ * statuschange IRQs connected to SoC GPIOs, control and status register
++ * bits arranged in per-socket groups in an external PLD. All boards
++ * listed here use this layout, including bit positions and meanings.
++ * Of course there are exceptions in later boards:
++ *
++ * - Pb1100/Pb1500: single socket only; voltage key bits VS are
++ * at STATUS[5:4] (instead of STATUS[1:0]).
++ * - Au1200-based: additional card-eject irqs, irqs not gpios!
++ */
++
++#include <linux/delay.h>
++#include <linux/gpio.h>
++#include <linux/interrupt.h>
++#include <linux/pm.h>
++#include <linux/platform_device.h>
++#include <linux/resource.h>
++#include <linux/spinlock.h>
++
++#include <pcmcia/cs_types.h>
++#include <pcmcia/ss.h>
++
++#include <asm/mach-au1x00/au1000.h>
++#include <asm/mach-db1x00/bcsr.h>
++
++#define MEM_MAP_SIZE 0x400000
++#define IO_MAP_SIZE 0x1000
++
++struct db1x_pcmcia_sock {
++ struct pcmcia_socket socket;
++ int nr; /* socket number */
++ void *virt_io;
++
++ /* the "pseudo" addresses of the PCMCIA space. */
++ unsigned long phys_io;
++ unsigned long phys_attr;
++ unsigned long phys_mem;
++
++ /* previous flags for set_socket() */
++ unsigned int old_flags;
++
++ /* interrupt sources: linux irq numbers! */
++ int insert_irq; /* default carddetect irq */
++ int stschg_irq; /* card-status-change irq */
++ int card_irq; /* card irq */
++ int eject_irq; /* db1200/pb1200 have these */
++
++#define BOARD_TYPE_DEFAULT 0 /* most boards */
++#define BOARD_TYPE_DB1200 1 /* IRQs aren't gpios */
++#define BOARD_TYPE_PB1100 2 /* VS bits slightly different */
++ int board_type;
++};
++
++#define to_db1x_socket(x) container_of(x, struct db1x_pcmcia_sock, socket)
++
++/* DB/PB1200: check CPLD SIGSTATUS register bit 10/12 */
++static int db1200_card_inserted(struct db1x_pcmcia_sock *sock)
++{
++ unsigned short sigstat;
++
++ sigstat = bcsr_read(BCSR_SIGSTAT);
++ return sigstat & 1 << (8 + 2 * sock->nr);
++}
++
++/* carddetect gpio: low-active */
++static int db1000_card_inserted(struct db1x_pcmcia_sock *sock)
++{
++ return !gpio_get_value(irq_to_gpio(sock->insert_irq));
++}
++
++static int db1x_card_inserted(struct db1x_pcmcia_sock *sock)
++{
++ switch (sock->board_type) {
++ case BOARD_TYPE_DB1200:
++ return db1200_card_inserted(sock);
++ default:
++ return db1000_card_inserted(sock);
++ }
++}
++
++/* STSCHG tends to bounce heavily when cards are inserted/ejected.
++ * To avoid this, the interrupt is normally disabled and only enabled
++ * after reset to a card has been de-asserted.
++ */
++static inline void set_stschg(struct db1x_pcmcia_sock *sock, int en)
++{
++ if (sock->stschg_irq != -1) {
++ if (en)
++ enable_irq(sock->stschg_irq);
++ else
++ disable_irq(sock->stschg_irq);
++ }
++}
++
++static irqreturn_t db1000_pcmcia_cdirq(int irq, void *data)
++{
++ struct db1x_pcmcia_sock *sock = data;
++
++ pcmcia_parse_events(&sock->socket, SS_DETECT);
++
++ return IRQ_HANDLED;
++}
++
++static irqreturn_t db1000_pcmcia_stschgirq(int irq, void *data)
++{
++ struct db1x_pcmcia_sock *sock = data;
++
++ pcmcia_parse_events(&sock->socket, SS_STSCHG);
++
++ return IRQ_HANDLED;
++}
++
++static irqreturn_t db1200_pcmcia_cdirq(int irq, void *data)
++{
++ struct db1x_pcmcia_sock *sock = data;
++
++ /* Db/Pb1200 have separate per-socket insertion and ejection
++ * interrupts which stay asserted as long as the card is
++ * inserted/missing. The one which caused us to be called
++ * needs to be disabled and the other one enabled.
++ */
++ if (irq == sock->insert_irq) {
++ disable_irq_nosync(sock->insert_irq);
++ enable_irq(sock->eject_irq);
++ } else {
++ disable_irq_nosync(sock->eject_irq);
++ enable_irq(sock->insert_irq);
++ }
++
++ pcmcia_parse_events(&sock->socket, SS_DETECT);
++
++ return IRQ_HANDLED;
++}
++
++static int db1x_pcmcia_setup_irqs(struct db1x_pcmcia_sock *sock)
++{
++ int ret;
++ unsigned long flags;
++
++ if (sock->stschg_irq != -1) {
++ ret = request_irq(sock->stschg_irq, db1000_pcmcia_stschgirq,
++ 0, "pcmcia_stschg", sock);
++ if (ret)
++ return ret;
++ }
++
++ /* Db/Pb1200 have separate per-socket insertion and ejection
++ * interrupts, which should show edge behaviour but don't.
++ * So interrupts are disabled until both insertion and
++ * ejection handler have been registered and the currently
++ * active one disabled.
++ */
++ if (sock->board_type == BOARD_TYPE_DB1200) {
++ local_irq_save(flags);
++
++ ret = request_irq(sock->insert_irq, db1200_pcmcia_cdirq,
++ IRQF_DISABLED, "pcmcia_insert", sock);
++ if (ret)
++ goto out1;
++
++ ret = request_irq(sock->eject_irq, db1200_pcmcia_cdirq,
++ IRQF_DISABLED, "pcmcia_eject", sock);
++ if (ret) {
++ free_irq(sock->insert_irq, sock);
++ local_irq_restore(flags);
++ goto out1;
++ }
++
++ /* disable the currently active one */
++ if (db1200_card_inserted(sock))
++ disable_irq_nosync(sock->insert_irq);
++ else
++ disable_irq_nosync(sock->eject_irq);
++
++ local_irq_restore(flags);
++ } else {
++ /* all other (older) Db1x00 boards use a GPIO to show
++ * card detection status: use both-edge triggers.
++ */
++ set_irq_type(sock->insert_irq, IRQ_TYPE_EDGE_BOTH);
++ ret = request_irq(sock->insert_irq, db1000_pcmcia_cdirq,
++ 0, "pcmcia_carddetect", sock);
++
++ if (ret)
++ goto out1;
++ }
++
++ return 0; /* all done */
++
++out1:
++ if (sock->stschg_irq != -1)
++ free_irq(sock->stschg_irq, sock);
++
++ return ret;
++}
++
++static void db1x_pcmcia_free_irqs(struct db1x_pcmcia_sock *sock)
++{
++ if (sock->stschg_irq != -1)
++ free_irq(sock->stschg_irq, sock);
++
++ free_irq(sock->insert_irq, sock);
++ if (sock->eject_irq != -1)
++ free_irq(sock->eject_irq, sock);
++}
++
++/*
++ * configure a PCMCIA socket on the Db1x00 series of boards (and
++ * compatibles).
++ *
++ * 2 external registers are involved:
++ * pcmcia_status (offset 0x04): bits [0:1/2:3]: read card voltage id
++ * pcmcia_control(offset 0x10):
++ * bits[0:1] set vcc for card
++ * bits[2:3] set vpp for card
++ * bit 4: enable data buffers
++ * bit 7: reset# for card
++ * add 8 for second socket.
++ */
++static int db1x_pcmcia_configure(struct pcmcia_socket *skt,
++ struct socket_state_t *state)
++{
++ struct db1x_pcmcia_sock *sock = to_db1x_socket(skt);
++ unsigned short cr_clr, cr_set;
++ unsigned int changed;
++ int v, p, ret;
++
++ /* card voltage setup */
++ cr_clr = (0xf << (sock->nr * 8)); /* clear voltage settings */
++ cr_set = 0;
++ v = p = ret = 0;
++
++ switch (state->Vcc) {
++ case 50:
++ ++v;
++ case 33:
++ ++v;
++ case 0:
++ break;
++ default:
++ printk(KERN_INFO "pcmcia%d unsupported Vcc %d\n",
++ sock->nr, state->Vcc);
++ }
++
++ switch (state->Vpp) {
++ case 12:
++ ++p;
++ case 33:
++ case 50:
++ ++p;
++ case 0:
++ break;
++ default:
++ printk(KERN_INFO "pcmcia%d unsupported Vpp %d\n",
++ sock->nr, state->Vpp);
++ }
++
++ /* sanity check: Vpp must be 0, 12, or Vcc */
++ if (((state->Vcc == 33) && (state->Vpp == 50)) ||
++ ((state->Vcc == 50) && (state->Vpp == 33))) {
++ printk(KERN_INFO "pcmcia%d bad Vcc/Vpp combo (%d %d)\n",
++ sock->nr, state->Vcc, state->Vpp);
++ v = p = 0;
++ ret = -EINVAL;
++ }
++
++ /* create new voltage code */
++ cr_set |= ((v << 2) | p) << (sock->nr * 8);
++
++ changed = state->flags ^ sock->old_flags;
++
++ if (changed & SS_RESET) {
++ if (state->flags & SS_RESET) {
++ set_stschg(sock, 0);
++ /* assert reset, disable io buffers */
++ cr_clr |= (1 << (7 + (sock->nr * 8)));
++ cr_clr |= (1 << (4 + (sock->nr * 8)));
++ } else {
++ /* de-assert reset, enable io buffers */
++ cr_set |= 1 << (7 + (sock->nr * 8));
++ cr_set |= 1 << (4 + (sock->nr * 8));
++ }
++ }
++
++ /* update PCMCIA configuration */
++ bcsr_mod(BCSR_PCMCIA, cr_clr, cr_set);
++
++ sock->old_flags = state->flags;
++
++ /* reset was taken away: give card time to initialize properly */
++ if ((changed & SS_RESET) && !(state->flags & SS_RESET)) {
++ msleep(500);
++ set_stschg(sock, 1);
++ }
++
++ return ret;
++}
++
++/* VCC bits at [3:2]/[11:10] */
++#define GET_VCC(cr, socknr) \
++ ((((cr) >> 2) >> ((socknr) * 8)) & 3)
++
++/* VS bits at [0:1]/[3:2] */
++#define GET_VS(sr, socknr) \
++ (((sr) >> (2 * (socknr))) & 3)
++
++/* reset bits at [7]/[15] */
++#define GET_RESET(cr, socknr) \
++ ((cr) & (1 << (7 + (8 * (socknr)))))
++
++static int db1x_pcmcia_get_status(struct pcmcia_socket *skt,
++ unsigned int *value)
++{
++ struct db1x_pcmcia_sock *sock = to_db1x_socket(skt);
++ unsigned short cr, sr;
++ unsigned int status;
++
++ status = db1x_card_inserted(sock) ? SS_DETECT : 0;
++
++ cr = bcsr_read(BCSR_PCMCIA);
++ sr = bcsr_read(BCSR_STATUS);
++
++ /* PB1100/PB1500: voltage key bits are at [5:4] */
++ if (sock->board_type == BOARD_TYPE_PB1100)
++ sr >>= 4;
++
++ /* determine card type */
++ switch (GET_VS(sr, sock->nr)) {
++ case 0:
++ case 2:
++ status |= SS_3VCARD; /* 3V card */
++ case 3:
++ break; /* 5V card: set nothing */
++ default:
++ status |= SS_XVCARD; /* treated as unsupported in core */
++ }
++
++ /* if Vcc is not zero, we have applied power to a card */
++ status |= GET_VCC(cr, sock->nr) ? SS_POWERON : 0;
++
++ /* reset de-asserted? then we're ready */
++ status |= (GET_RESET(cr, sock->nr)) ? SS_READY : SS_RESET;
++
++ *value = status;
++
++ return 0;
++}
++
++static int db1x_pcmcia_sock_init(struct pcmcia_socket *skt)
++{
++ return 0;
++}
++
++static int db1x_pcmcia_sock_suspend(struct pcmcia_socket *skt)
++{
++ return 0;
++}
++
++static int au1x00_pcmcia_set_io_map(struct pcmcia_socket *skt,
++ struct pccard_io_map *map)
++{
++ struct db1x_pcmcia_sock *sock = to_db1x_socket(skt);
++
++ map->start = (u32)sock->virt_io;
++ map->stop = map->start + IO_MAP_SIZE;
++
++ return 0;
++}
++
++static int au1x00_pcmcia_set_mem_map(struct pcmcia_socket *skt,
++ struct pccard_mem_map *map)
++{
++ struct db1x_pcmcia_sock *sock = to_db1x_socket(skt);
++
++ if (map->flags & MAP_ATTRIB)
++ map->static_start = sock->phys_attr + map->card_start;
++ else
++ map->static_start = sock->phys_mem + map->card_start;
++
++ return 0;
++}
++
++static struct pccard_operations db1x_pcmcia_operations = {
++ .init = db1x_pcmcia_sock_init,
++ .suspend = db1x_pcmcia_sock_suspend,
++ .get_status = db1x_pcmcia_get_status,
++ .set_socket = db1x_pcmcia_configure,
++ .set_io_map = au1x00_pcmcia_set_io_map,
++ .set_mem_map = au1x00_pcmcia_set_mem_map,
++};
++
++static int __devinit db1x_pcmcia_socket_probe(struct platform_device *pdev)
++{
++ struct db1x_pcmcia_sock *sock;
++ struct resource *r;
++ phys_t physio;
++ int ret, bid;
++
++ sock = kzalloc(sizeof(struct db1x_pcmcia_sock), GFP_KERNEL);
++ if (!sock)
++ return -ENOMEM;
++
++ sock->nr = pdev->id;
++
++ bid = BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI));
++ switch (bid) {
++ case BCSR_WHOAMI_PB1500:
++ case BCSR_WHOAMI_PB1500R2:
++ case BCSR_WHOAMI_PB1100:
++ sock->board_type = BOARD_TYPE_PB1100;
++ break;
++ case BCSR_WHOAMI_DB1000 ... BCSR_WHOAMI_PB1550_SDR:
++ sock->board_type = BOARD_TYPE_DEFAULT;
++ break;
++ case BCSR_WHOAMI_PB1200 ... BCSR_WHOAMI_DB1200:
++ sock->board_type = BOARD_TYPE_DB1200;
++ break;
++ default:
++ printk(KERN_INFO "db1xxx-ss: unknown board %d!\n", bid);
++ ret = -ENODEV;
++ goto out0;
++ };
++
++ /*
++ * gather resources necessary and optional nice-to-haves to
++ * operate a socket:
++ * This includes IRQs for Carddetection/ejection, the card
++ * itself and optional status change detection.
++ * Also, the memory areas covered by a socket. For these
++ * we require the 32bit "pseudo" addresses (see the au1000.h
++ * header for more information).
++ */
++
++ /* card: irq assigned to the card itself. */
++ r = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "card");
++ sock->card_irq = r ? r->start : 0;
++
++ /* insert: irq which triggers on card insertion/ejection */
++ r = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "insert");
++ sock->insert_irq = r ? r->start : -1;
++
++ /* stschg: irq which trigger on card status change (optional) */
++ r = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "stschg");
++ sock->stschg_irq = r ? r->start : -1;
++
++ /* eject: irq which triggers on ejection (DB1200/PB1200 only) */
++ r = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "eject");
++ sock->eject_irq = r ? r->start : -1;
++
++ ret = -ENODEV;
++
++ /*
++ * pseudo-attr: The 32bit address of the PCMCIA attribute space
++ * for this socket (usually the 36bit address shifted 4 to the
++ * right).
++ */
++ r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pseudo-attr");
++ if (!r) {
++ printk(KERN_ERR "pcmcia%d has no 'pseudo-attr' resource!\n",
++ sock->nr);
++ goto out0;
++ }
++ sock->phys_attr = r->start;
++
++ /*
++ * pseudo-mem: The 32bit address of the PCMCIA memory space for
++ * this socket (usually the 36bit address shifted 4 to the right)
++ */
++ r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pseudo-mem");
++ if (!r) {
++ printk(KERN_ERR "pcmcia%d has no 'pseudo-mem' resource!\n",
++ sock->nr);
++ goto out0;
++ }
++ sock->phys_mem = r->start;
++
++ /*
++ * pseudo-io: The 32bit address of the PCMCIA IO space for this
++ * socket (usually the 36bit address shifted 4 to the right).
++ */
++ r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pseudo-io");
++ if (!r) {
++ printk(KERN_ERR "pcmcia%d has no 'pseudo-io' resource!\n",
++ sock->nr);
++ goto out0;
++ }
++ sock->phys_io = r->start;
++
++
++ /* IO: we must remap the full 36bit address (for reference see
++ * alchemy/common/setup.c::__fixup_bigphys_addr())
++ */
++ physio = ((phys_t)sock->phys_io) << 4;
++
++ /*
++ * PCMCIA client drivers use the inb/outb macros to access
++ * the IO registers. Since mips_io_port_base is added
++ * to the access address of the mips implementation of
++ * inb/outb, we need to subtract it here because we want
++ * to access the I/O or MEM address directly, without
++ * going through this "mips_io_port_base" mechanism.
++ */
++ sock->virt_io = (void *)(ioremap(physio, IO_MAP_SIZE) -
++ mips_io_port_base);
++
++ if (!sock->virt_io) {
++ printk(KERN_ERR "pcmcia%d: cannot remap IO area\n",
++ sock->nr);
++ ret = -ENOMEM;
++ goto out0;
++ }
++
++ sock->socket.ops = &db1x_pcmcia_operations;
++ sock->socket.owner = THIS_MODULE;
++ sock->socket.pci_irq = sock->card_irq;
++ sock->socket.features = SS_CAP_STATIC_MAP | SS_CAP_PCCARD;
++ sock->socket.map_size = MEM_MAP_SIZE;
++ sock->socket.io_offset = (unsigned long)sock->virt_io;
++ sock->socket.dev.parent = &pdev->dev;
++ sock->socket.resource_ops = &pccard_static_ops;
++
++ platform_set_drvdata(pdev, sock);
++
++ ret = db1x_pcmcia_setup_irqs(sock);
++ if (ret) {
++ printk(KERN_ERR "pcmcia%d cannot setup interrupts\n",
++ sock->nr);
++ goto out1;
++ }
++
++ set_stschg(sock, 0);
++
++ ret = pcmcia_register_socket(&sock->socket);
++ if (ret) {
++ printk(KERN_ERR "pcmcia%d failed to register\n", sock->nr);
++ goto out2;
++ }
++
++ printk(KERN_INFO "Alchemy Db/Pb1xxx pcmcia%d @ io/attr/mem %08lx"
++ "(%p) %08lx %08lx card/insert/stschg/eject irqs @ %d "
++ "%d %d %d\n", sock->nr, sock->phys_io, sock->virt_io,
++ sock->phys_attr, sock->phys_mem, sock->card_irq,
++ sock->insert_irq, sock->stschg_irq, sock->eject_irq);
++
++ return 0;
++
++out2:
++ db1x_pcmcia_free_irqs(sock);
++out1:
++ iounmap((void *)(sock->virt_io + (u32)mips_io_port_base));
++out0:
++ kfree(sock);
++ return ret;
++}
++
++static int __devexit db1x_pcmcia_socket_remove(struct platform_device *pdev)
++{
++ struct db1x_pcmcia_sock *sock = platform_get_drvdata(pdev);
++
++ db1x_pcmcia_free_irqs(sock);
++ pcmcia_unregister_socket(&sock->socket);
++ iounmap((void *)(sock->virt_io + (u32)mips_io_port_base));
++ kfree(sock);
++
++ return 0;
++}
++
++#ifdef CONFIG_PM
++static int db1x_pcmcia_suspend(struct device *dev)
++{
++ return pcmcia_socket_dev_suspend(dev);
++}
++
++static int db1x_pcmcia_resume(struct device *dev)
++{
++ return pcmcia_socket_dev_resume(dev);
++}
++
++static struct dev_pm_ops db1x_pcmcia_pmops = {
++ .resume = db1x_pcmcia_resume,
++ .suspend = db1x_pcmcia_suspend,
++ .thaw = db1x_pcmcia_resume,
++ .freeze = db1x_pcmcia_suspend,
++};
++
++#define DB1XXX_SS_PMOPS &db1x_pcmcia_pmops
++
++#else
++
++#define DB1XXX_SS_PMOPS NULL
++
++#endif
++
++static struct platform_driver db1x_pcmcia_socket_driver = {
++ .driver = {
++ .name = "db1xxx_pcmcia",
++ .owner = THIS_MODULE,
++ .pm = DB1XXX_SS_PMOPS
++ },
++ .probe = db1x_pcmcia_socket_probe,
++ .remove = __devexit_p(db1x_pcmcia_socket_remove),
++};
++
++int __init db1x_pcmcia_socket_load(void)
++{
++ return platform_driver_register(&db1x_pcmcia_socket_driver);
++}
++
++void __exit db1x_pcmcia_socket_unload(void)
++{
++ platform_driver_unregister(&db1x_pcmcia_socket_driver);
++}
++
++module_init(db1x_pcmcia_socket_load);
++module_exit(db1x_pcmcia_socket_unload);
++
++MODULE_LICENSE("GPL");
++MODULE_DESCRIPTION("PCMCIA Socket Services for Alchemy Db/Pb1x00 boards");
++MODULE_AUTHOR("Manuel Lauss");
+diff --git a/drivers/pcmcia/xxs1500_ss.c b/drivers/pcmcia/xxs1500_ss.c
+new file mode 100644
+index 0000000..4e36930
+--- /dev/null
++++ b/drivers/pcmcia/xxs1500_ss.c
+@@ -0,0 +1,357 @@
++/*
++ * PCMCIA socket code for the MyCable XXS1500 system.
++ *
++ * Copyright (c) 2009 Manuel Lauss <manuel.lauss@gmail.com>
++ *
++ */
++
++#include <linux/delay.h>
++#include <linux/gpio.h>
++#include <linux/interrupt.h>
++#include <linux/io.h>
++#include <linux/ioport.h>
++#include <linux/mm.h>
++#include <linux/platform_device.h>
++#include <linux/pm.h>
++#include <linux/resource.h>
++#include <linux/spinlock.h>
++
++#include <pcmcia/cs_types.h>
++#include <pcmcia/cs.h>
++#include <pcmcia/ss.h>
++#include <pcmcia/cistpl.h>
++
++#include <asm/irq.h>
++#include <asm/system.h>
++#include <asm/mach-au1x00/au1000.h>
++
++#define MEM_MAP_SIZE 0x400000
++#define IO_MAP_SIZE 0x1000
++
++
++/*
++ * 3.3V cards only; all interfacing is done via gpios:
++ *
++ * 0/1: carddetect (00 = card present, xx = huh)
++ * 4: card irq
++ * 204: reset (high-act)
++ * 205: buffer enable (low-act)
++ * 208/209: card voltage key (00,01,10,11)
++ * 210: battwarn
++ * 211: batdead
++ * 214: power (low-act)
++ */
++#define GPIO_CDA 0
++#define GPIO_CDB 1
++#define GPIO_CARDIRQ 4
++#define GPIO_RESET 204
++#define GPIO_OUTEN 205
++#define GPIO_VSL 208
++#define GPIO_VSH 209
++#define GPIO_BATTDEAD 210
++#define GPIO_BATTWARN 211
++#define GPIO_POWER 214
++
++struct xxs1500_pcmcia_sock {
++ struct pcmcia_socket socket;
++ void *virt_io;
++
++ /* the "pseudo" addresses of the PCMCIA space. */
++ unsigned long phys_io;
++ unsigned long phys_attr;
++ unsigned long phys_mem;
++
++ /* previous flags for set_socket() */
++ unsigned int old_flags;
++};
++
++#define to_xxs_socket(x) container_of(x, struct xxs1500_pcmcia_sock, socket)
++
++static irqreturn_t cdirq(int irq, void *data)
++{
++ struct xxs1500_pcmcia_sock *sock = data;
++
++ pcmcia_parse_events(&sock->socket, SS_DETECT);
++
++ return IRQ_HANDLED;
++}
++
++static int xxs1500_pcmcia_configure(struct pcmcia_socket *skt,
++ struct socket_state_t *state)
++{
++ struct xxs1500_pcmcia_sock *sock = to_xxs_socket(skt);
++ unsigned int changed;
++
++ /* power control */
++ switch (state->Vcc) {
++ case 0:
++ gpio_set_value(GPIO_POWER, 1); /* power off */
++ break;
++ case 33:
++ gpio_set_value(GPIO_POWER, 0); /* power on */
++ break;
++ case 50:
++ default:
++ return -EINVAL;
++ }
++
++ changed = state->flags ^ sock->old_flags;
++
++ if (changed & SS_RESET) {
++ if (state->flags & SS_RESET) {
++ gpio_set_value(GPIO_RESET, 1); /* assert reset */
++ gpio_set_value(GPIO_OUTEN, 1); /* buffers off */
++ } else {
++ gpio_set_value(GPIO_RESET, 0); /* deassert reset */
++ gpio_set_value(GPIO_OUTEN, 0); /* buffers on */
++ msleep(500);
++ }
++ }
++
++ sock->old_flags = state->flags;
++
++ return 0;
++}
++
++static int xxs1500_pcmcia_get_status(struct pcmcia_socket *skt,
++ unsigned int *value)
++{
++ unsigned int status;
++ int i;
++
++ status = 0;
++
++ /* check carddetects: GPIO[0:1] must both be low */
++ if (!gpio_get_value(GPIO_CDA) && !gpio_get_value(GPIO_CDB))
++ status |= SS_DETECT;
++
++ /* determine card voltage: GPIO[208:209] binary value */
++ i = (!!gpio_get_value(GPIO_VSL)) | ((!!gpio_get_value(GPIO_VSH)) << 1);
++
++ switch (i) {
++ case 0:
++ case 1:
++ case 2:
++ status |= SS_3VCARD; /* 3V card */
++ break;
++ case 3: /* 5V card, unsupported */
++ default:
++ status |= SS_XVCARD; /* treated as unsupported in core */
++ }
++
++ /* GPIO214: low active power switch */
++ status |= gpio_get_value(GPIO_POWER) ? 0 : SS_POWERON;
++
++ /* GPIO204: high-active reset line */
++ status |= gpio_get_value(GPIO_RESET) ? SS_RESET : SS_READY;
++
++ /* other stuff */
++ status |= gpio_get_value(GPIO_BATTDEAD) ? 0 : SS_BATDEAD;
++ status |= gpio_get_value(GPIO_BATTWARN) ? 0 : SS_BATWARN;
++
++ *value = status;
++
++ return 0;
++}
++
++static int xxs1500_pcmcia_sock_init(struct pcmcia_socket *skt)
++{
++ gpio_direction_input(GPIO_CDA);
++ gpio_direction_input(GPIO_CDB);
++ gpio_direction_input(GPIO_VSL);
++ gpio_direction_input(GPIO_VSH);
++ gpio_direction_input(GPIO_BATTDEAD);
++ gpio_direction_input(GPIO_BATTWARN);
++ gpio_direction_output(GPIO_RESET, 1); /* assert reset */
++ gpio_direction_output(GPIO_OUTEN, 1); /* disable buffers */
++ gpio_direction_output(GPIO_POWER, 1); /* power off */
++
++ return 0;
++}
++
++static int xxs1500_pcmcia_sock_suspend(struct pcmcia_socket *skt)
++{
++ return 0;
++}
++
++static int au1x00_pcmcia_set_io_map(struct pcmcia_socket *skt,
++ struct pccard_io_map *map)
++{
++ struct xxs1500_pcmcia_sock *sock = to_xxs_socket(skt);
++
++ map->start = (u32)sock->virt_io;
++ map->stop = map->start + IO_MAP_SIZE;
++
++ return 0;
++}
++
++static int au1x00_pcmcia_set_mem_map(struct pcmcia_socket *skt,
++ struct pccard_mem_map *map)
++{
++ struct xxs1500_pcmcia_sock *sock = to_xxs_socket(skt);
++
++ if (map->flags & MAP_ATTRIB)
++ map->static_start = sock->phys_attr + map->card_start;
++ else
++ map->static_start = sock->phys_mem + map->card_start;
++
++ return 0;
++}
++
++static struct pccard_operations xxs1500_pcmcia_operations = {
++ .init = xxs1500_pcmcia_sock_init,
++ .suspend = xxs1500_pcmcia_sock_suspend,
++ .get_status = xxs1500_pcmcia_get_status,
++ .set_socket = xxs1500_pcmcia_configure,
++ .set_io_map = au1x00_pcmcia_set_io_map,
++ .set_mem_map = au1x00_pcmcia_set_mem_map,
++};
++
++static int __devinit xxs1500_pcmcia_probe(struct platform_device *pdev)
++{
++ struct xxs1500_pcmcia_sock *sock;
++ struct resource *r;
++ phys_t physio;
++ int ret, irq;
++
++ sock = kzalloc(sizeof(struct xxs1500_pcmcia_sock), GFP_KERNEL);
++ if (!sock)
++ return -ENOMEM;
++
++ ret = -ENODEV;
++
++ /*
++ * pseudo-attr: The 32bit address of the PCMCIA attribute space
++ * for this socket (usually the 36bit address shifted 4 to the
++ * right).
++ */
++ r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pseudo-attr");
++ if (!r) {
++ dev_err(&pdev->dev, "missing 'pseudo-attr' resource!\n");
++ goto out0;
++ }
++ sock->phys_attr = r->start;
++
++ /*
++ * pseudo-mem: The 32bit address of the PCMCIA memory space for
++ * this socket (usually the 36bit address shifted 4 to the right)
++ */
++ r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pseudo-mem");
++ if (!r) {
++ dev_err(&pdev->dev, "missing 'pseudo-mem' resource!\n");
++ goto out0;
++ }
++ sock->phys_mem = r->start;
++
++ /*
++ * pseudo-io: The 32bit address of the PCMCIA IO space for this
++ * socket (usually the 36bit address shifted 4 to the right).
++ */
++ r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pseudo-io");
++ if (!r) {
++ dev_err(&pdev->dev, "missing 'pseudo-io' resource!\n");
++ goto out0;
++ }
++ sock->phys_io = r->start;
++
++
++ /* for io must remap the full 36bit address (for reference see
++ * alchemy/common/setup.c::__fixup_bigphys_addr)
++ */
++ physio = ((phys_t)sock->phys_io) << 4;
++
++ /*
++ * PCMCIA client drivers use the inb/outb macros to access
++ * the IO registers. Since mips_io_port_base is added
++ * to the access address of the mips implementation of
++ * inb/outb, we need to subtract it here because we want
++ * to access the I/O or MEM address directly, without
++ * going through this "mips_io_port_base" mechanism.
++ */
++ sock->virt_io = (void *)(ioremap(physio, IO_MAP_SIZE) -
++ mips_io_port_base);
++
++ if (!sock->virt_io) {
++ dev_err(&pdev->dev, "cannot remap IO area\n");
++ ret = -ENOMEM;
++ goto out0;
++ }
++
++ sock->socket.ops = &xxs1500_pcmcia_operations;
++ sock->socket.owner = THIS_MODULE;
++ sock->socket.pci_irq = gpio_to_irq(GPIO_CARDIRQ);
++ sock->socket.features = SS_CAP_STATIC_MAP | SS_CAP_PCCARD;
++ sock->socket.map_size = MEM_MAP_SIZE;
++ sock->socket.io_offset = (unsigned long)sock->virt_io;
++ sock->socket.dev.parent = &pdev->dev;
++ sock->socket.resource_ops = &pccard_static_ops;
++
++ platform_set_drvdata(pdev, sock);
++
++ /* setup carddetect irq: use one of the 2 GPIOs as an
++ * edge detector.
++ */
++ irq = gpio_to_irq(GPIO_CDA);
++ set_irq_type(irq, IRQ_TYPE_EDGE_BOTH);
++ ret = request_irq(irq, cdirq, 0, "pcmcia_carddetect", sock);
++ if (ret) {
++ dev_err(&pdev->dev, "cannot setup cd irq\n");
++ goto out1;
++ }
++
++ ret = pcmcia_register_socket(&sock->socket);
++ if (ret) {
++ dev_err(&pdev->dev, "failed to register\n");
++ goto out2;
++ }
++
++ printk(KERN_INFO "MyCable XXS1500 PCMCIA socket services\n");
++
++ return 0;
++
++out2:
++ free_irq(gpio_to_irq(GPIO_CDA), sock);
++out1:
++ iounmap((void *)(sock->virt_io + (u32)mips_io_port_base));
++out0:
++ kfree(sock);
++ return ret;
++}
++
++static int __devexit xxs1500_pcmcia_remove(struct platform_device *pdev)
++{
++ struct xxs1500_pcmcia_sock *sock = platform_get_drvdata(pdev);
++
++ pcmcia_unregister_socket(&sock->socket);
++ free_irq(gpio_to_irq(GPIO_CDA), sock);
++ iounmap((void *)(sock->virt_io + (u32)mips_io_port_base));
++ kfree(sock);
++
++ return 0;
++}
++
++static struct platform_driver xxs1500_pcmcia_socket_driver = {
++ .driver = {
++ .name = "xxs1500_pcmcia",
++ .owner = THIS_MODULE,
++ },
++ .probe = xxs1500_pcmcia_probe,
++ .remove = __devexit_p(xxs1500_pcmcia_remove),
++};
++
++int __init xxs1500_pcmcia_socket_load(void)
++{
++ return platform_driver_register(&xxs1500_pcmcia_socket_driver);
++}
++
++void __exit xxs1500_pcmcia_socket_unload(void)
++{
++ platform_driver_unregister(&xxs1500_pcmcia_socket_driver);
++}
++
++module_init(xxs1500_pcmcia_socket_load);
++module_exit(xxs1500_pcmcia_socket_unload);
++
++MODULE_LICENSE("GPL");
++MODULE_DESCRIPTION("PCMCIA Socket Services for MyCable XXS1500 systems");
++MODULE_AUTHOR("Manuel Lauss");
+diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
+index f7a4701..820bdad 100644
+--- a/drivers/rtc/rtc-cmos.c
++++ b/drivers/rtc/rtc-cmos.c
+@@ -691,7 +691,8 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
+ */
+ #if defined(CONFIG_ATARI)
+ address_space = 64;
+-#elif defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__sparc__)
++#elif defined(__i386__) || defined(__x86_64__) || defined(__arm__) \
++ || defined(__sparc__) || defined(__mips__)
+ address_space = 128;
+ #else
+ #warning Assuming 128 bytes of RTC+NVRAM address space, not 64 bytes.
+@@ -756,9 +757,8 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
+ /* FIXME teach the alarm code how to handle binary mode;
+ * <asm-generic/rtc.h> doesn't know 12-hour mode either.
+ */
+- if (is_valid_irq(rtc_irq) &&
+- (!(rtc_control & RTC_24H) || (rtc_control & (RTC_DM_BINARY)))) {
+- dev_dbg(dev, "only 24-hr BCD mode supported\n");
++ if (is_valid_irq(rtc_irq) && !(rtc_control & RTC_24H)) {
++ dev_dbg(dev, "only 24-hr supported\n");
+ retval = -ENXIO;
+ goto cleanup1;
+ }
+diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
+index 737b4c9..b221a6c 100644
+--- a/drivers/serial/8250.c
++++ b/drivers/serial/8250.c
+@@ -1214,12 +1214,6 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
+ }
+ #endif
+
+-#ifdef CONFIG_SERIAL_8250_AU1X00
+- /* if access method is AU, it is a 16550 with a quirk */
+- if (up->port.type == PORT_16550A && up->port.iotype == UPIO_AU)
+- up->bugs |= UART_BUG_NOMSR;
+-#endif
+-
+ serial_outp(up, UART_LCR, save_lcr);
+
+ if (up->capabilities != uart_config[up->port.type].flags) {
+@@ -2429,7 +2423,7 @@ serial8250_pm(struct uart_port *port, unsigned int state,
+ static unsigned int serial8250_port_size(struct uart_8250_port *pt)
+ {
+ if (pt->port.iotype == UPIO_AU)
+- return 0x100000;
++ return 0x1000;
+ #ifdef CONFIG_ARCH_OMAP
+ if (is_omap_port(pt))
+ return 0x16 << pt->port.regshift;
+@@ -2586,6 +2580,13 @@ static void serial8250_config_port(struct uart_port *port, int flags)
+
+ if (flags & UART_CONFIG_TYPE)
+ autoconfig(up, probeflags);
++
++#ifdef CONFIG_SERIAL_8250_AU1X00
++ /* if access method is AU, it is a 16550 with a quirk */
++ if (up->port.type == PORT_16550A && up->port.iotype == UPIO_AU)
++ up->bugs |= UART_BUG_NOMSR;
++#endif
++
+ if (up->port.type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ)
+ autoconfig_irq(up);
+
+diff --git a/drivers/spi/au1550_spi.c b/drivers/spi/au1550_spi.c
+index 76cbc1a..c343f00 100644
+--- a/drivers/spi/au1550_spi.c
++++ b/drivers/spi/au1550_spi.c
+@@ -406,11 +406,13 @@ static int au1550_spi_dma_txrxb(struct spi_device *spi, struct spi_transfer *t)
+ }
+
+ /* put buffers on the ring */
+- res = au1xxx_dbdma_put_dest(hw->dma_rx_ch, hw->rx, t->len);
++ res = au1xxx_dbdma_put_dest(hw->dma_rx_ch, virt_to_phys(hw->rx),
++ t->len, DDMA_FLAGS_IE);
+ if (!res)
+ dev_err(hw->dev, "rx dma put dest error\n");
+
+- res = au1xxx_dbdma_put_source(hw->dma_tx_ch, (void *)hw->tx, t->len);
++ res = au1xxx_dbdma_put_source(hw->dma_tx_ch, virt_to_phys(hw->tx),
++ t->len, DDMA_FLAGS_IE);
+ if (!res)
+ dev_err(hw->dev, "tx dma put source error\n");
+
+diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
+index d21b346..99cfe4d 100644
+--- a/drivers/staging/Kconfig
++++ b/drivers/staging/Kconfig
+@@ -125,5 +125,7 @@ source "drivers/staging/sep/Kconfig"
+
+ source "drivers/staging/iio/Kconfig"
+
++source "drivers/staging/sm7xx/Kconfig"
++
+ endif # !STAGING_EXCLUDE_BUILD
+ endif # STAGING
+diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
+index 8cbf1ae..0b41de0 100644
+--- a/drivers/staging/Makefile
++++ b/drivers/staging/Makefile
+@@ -44,3 +44,4 @@ obj-$(CONFIG_VME_BUS) += vme/
+ obj-$(CONFIG_RAR_REGISTER) += rar/
+ obj-$(CONFIG_DX_SEP) += sep/
+ obj-$(CONFIG_IIO) += iio/
++obj-$(CONFIG_FB_SM7XX) += sm7xx/
+diff --git a/drivers/staging/octeon/Kconfig b/drivers/staging/octeon/Kconfig
+index 536e238..638ad6b 100644
+--- a/drivers/staging/octeon/Kconfig
++++ b/drivers/staging/octeon/Kconfig
+@@ -1,7 +1,8 @@
+ config OCTEON_ETHERNET
+ tristate "Cavium Networks Octeon Ethernet support"
+ depends on CPU_CAVIUM_OCTEON
+- select MII
++ select PHYLIB
++ select MDIO_OCTEON
+ help
+ This driver supports the builtin ethernet ports on Cavium
+ Networks' products in the Octeon family. This driver supports the
+diff --git a/drivers/staging/octeon/ethernet-mdio.c b/drivers/staging/octeon/ethernet-mdio.c
+index 31a58e5..05a5cc0 100644
+--- a/drivers/staging/octeon/ethernet-mdio.c
++++ b/drivers/staging/octeon/ethernet-mdio.c
+@@ -26,7 +26,8 @@
+ **********************************************************************/
+ #include <linux/kernel.h>
+ #include <linux/ethtool.h>
+-#include <linux/mii.h>
++#include <linux/phy.h>
++
+ #include <net/dst.h>
+
+ #include <asm/octeon/octeon.h>
+@@ -34,86 +35,12 @@
+ #include "ethernet-defines.h"
+ #include "octeon-ethernet.h"
+ #include "ethernet-mdio.h"
++#include "ethernet-util.h"
+
+ #include "cvmx-helper-board.h"
+
+ #include "cvmx-smix-defs.h"
+
+-DECLARE_MUTEX(mdio_sem);
+-
+-/**
+- * Perform an MII read. Called by the generic MII routines
+- *
+- * @dev: Device to perform read for
+- * @phy_id: The MII phy id
+- * @location: Register location to read
+- * Returns Result from the read or zero on failure
+- */
+-static int cvm_oct_mdio_read(struct net_device *dev, int phy_id, int location)
+-{
+- union cvmx_smix_cmd smi_cmd;
+- union cvmx_smix_rd_dat smi_rd;
+-
+- smi_cmd.u64 = 0;
+- smi_cmd.s.phy_op = 1;
+- smi_cmd.s.phy_adr = phy_id;
+- smi_cmd.s.reg_adr = location;
+- cvmx_write_csr(CVMX_SMIX_CMD(0), smi_cmd.u64);
+-
+- do {
+- if (!in_interrupt())
+- yield();
+- smi_rd.u64 = cvmx_read_csr(CVMX_SMIX_RD_DAT(0));
+- } while (smi_rd.s.pending);
+-
+- if (smi_rd.s.val)
+- return smi_rd.s.dat;
+- else
+- return 0;
+-}
+-
+-static int cvm_oct_mdio_dummy_read(struct net_device *dev, int phy_id,
+- int location)
+-{
+- return 0xffff;
+-}
+-
+-/**
+- * Perform an MII write. Called by the generic MII routines
+- *
+- * @dev: Device to perform write for
+- * @phy_id: The MII phy id
+- * @location: Register location to write
+- * @val: Value to write
+- */
+-static void cvm_oct_mdio_write(struct net_device *dev, int phy_id, int location,
+- int val)
+-{
+- union cvmx_smix_cmd smi_cmd;
+- union cvmx_smix_wr_dat smi_wr;
+-
+- smi_wr.u64 = 0;
+- smi_wr.s.dat = val;
+- cvmx_write_csr(CVMX_SMIX_WR_DAT(0), smi_wr.u64);
+-
+- smi_cmd.u64 = 0;
+- smi_cmd.s.phy_op = 0;
+- smi_cmd.s.phy_adr = phy_id;
+- smi_cmd.s.reg_adr = location;
+- cvmx_write_csr(CVMX_SMIX_CMD(0), smi_cmd.u64);
+-
+- do {
+- if (!in_interrupt())
+- yield();
+- smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(0));
+- } while (smi_wr.s.pending);
+-}
+-
+-static void cvm_oct_mdio_dummy_write(struct net_device *dev, int phy_id,
+- int location, int val)
+-{
+-}
+-
+ static void cvm_oct_get_drvinfo(struct net_device *dev,
+ struct ethtool_drvinfo *info)
+ {
+@@ -125,49 +52,37 @@ static void cvm_oct_get_drvinfo(struct net_device *dev,
+ static int cvm_oct_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+ {
+ struct octeon_ethernet *priv = netdev_priv(dev);
+- int ret;
+
+- down(&mdio_sem);
+- ret = mii_ethtool_gset(&priv->mii_info, cmd);
+- up(&mdio_sem);
++ if (priv->phydev)
++ return phy_ethtool_gset(priv->phydev, cmd);
+
+- return ret;
++ return -EINVAL;
+ }
+
+ static int cvm_oct_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+ {
+ struct octeon_ethernet *priv = netdev_priv(dev);
+- int ret;
+
+- down(&mdio_sem);
+- ret = mii_ethtool_sset(&priv->mii_info, cmd);
+- up(&mdio_sem);
++ if (!capable(CAP_NET_ADMIN))
++ return -EPERM;
++
++ if (priv->phydev)
++ return phy_ethtool_sset(priv->phydev, cmd);
+
+- return ret;
++ return -EINVAL;
+ }
+
+ static int cvm_oct_nway_reset(struct net_device *dev)
+ {
+ struct octeon_ethernet *priv = netdev_priv(dev);
+- int ret;
+
+- down(&mdio_sem);
+- ret = mii_nway_restart(&priv->mii_info);
+- up(&mdio_sem);
++ if (!capable(CAP_NET_ADMIN))
++ return -EPERM;
+
+- return ret;
+-}
++ if (priv->phydev)
++ return phy_start_aneg(priv->phydev);
+
+-static u32 cvm_oct_get_link(struct net_device *dev)
+-{
+- struct octeon_ethernet *priv = netdev_priv(dev);
+- u32 ret;
+-
+- down(&mdio_sem);
+- ret = mii_link_ok(&priv->mii_info);
+- up(&mdio_sem);
+-
+- return ret;
++ return -EINVAL;
+ }
+
+ const struct ethtool_ops cvm_oct_ethtool_ops = {
+@@ -175,7 +90,7 @@ const struct ethtool_ops cvm_oct_ethtool_ops = {
+ .get_settings = cvm_oct_get_settings,
+ .set_settings = cvm_oct_set_settings,
+ .nway_reset = cvm_oct_nway_reset,
+- .get_link = cvm_oct_get_link,
++ .get_link = ethtool_op_get_link,
+ .get_sg = ethtool_op_get_sg,
+ .get_tx_csum = ethtool_op_get_tx_csum,
+ };
+@@ -191,41 +106,78 @@ const struct ethtool_ops cvm_oct_ethtool_ops = {
+ int cvm_oct_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+ {
+ struct octeon_ethernet *priv = netdev_priv(dev);
+- struct mii_ioctl_data *data = if_mii(rq);
+- unsigned int duplex_chg;
+- int ret;
+
+- down(&mdio_sem);
+- ret = generic_mii_ioctl(&priv->mii_info, data, cmd, &duplex_chg);
+- up(&mdio_sem);
++ if (!netif_running(dev))
++ return -EINVAL;
++
++ if (!priv->phydev)
++ return -EINVAL;
++
++ return phy_mii_ioctl(priv->phydev, if_mii(rq), cmd);
++}
+
+- return ret;
++static void cvm_oct_adjust_link(struct net_device *dev)
++{
++ struct octeon_ethernet *priv = netdev_priv(dev);
++ cvmx_helper_link_info_t link_info;
++
++ if (priv->last_link != priv->phydev->link) {
++ priv->last_link = priv->phydev->link;
++ link_info.u64 = 0;
++ link_info.s.link_up = priv->last_link ? 1 : 0;
++ link_info.s.full_duplex = priv->phydev->duplex ? 1 : 0;
++ link_info.s.speed = priv->phydev->speed;
++ cvmx_helper_link_set( priv->port, link_info);
++ if (priv->last_link) {
++ netif_carrier_on(dev);
++ if (priv->queue != -1)
++ DEBUGPRINT("%s: %u Mbps %s duplex, "
++ "port %2d, queue %2d\n",
++ dev->name, priv->phydev->speed,
++ priv->phydev->duplex ?
++ "Full" : "Half",
++ priv->port, priv->queue);
++ else
++ DEBUGPRINT("%s: %u Mbps %s duplex, "
++ "port %2d, POW\n",
++ dev->name, priv->phydev->speed,
++ priv->phydev->duplex ?
++ "Full" : "Half",
++ priv->port);
++ } else {
++ netif_carrier_off(dev);
++ DEBUGPRINT("%s: Link down\n", dev->name);
++ }
++ }
+ }
+
++
+ /**
+- * Setup the MDIO device structures
++ * Setup the PHY
+ *
+ * @dev: Device to setup
+ *
+ * Returns Zero on success, negative on failure
+ */
+-int cvm_oct_mdio_setup_device(struct net_device *dev)
++int cvm_oct_phy_setup_device(struct net_device *dev)
+ {
+ struct octeon_ethernet *priv = netdev_priv(dev);
+- int phy_id = cvmx_helper_board_get_mii_address(priv->port);
+- if (phy_id != -1) {
+- priv->mii_info.dev = dev;
+- priv->mii_info.phy_id = phy_id;
+- priv->mii_info.phy_id_mask = 0xff;
+- priv->mii_info.supports_gmii = 1;
+- priv->mii_info.reg_num_mask = 0x1f;
+- priv->mii_info.mdio_read = cvm_oct_mdio_read;
+- priv->mii_info.mdio_write = cvm_oct_mdio_write;
+- } else {
+- /* Supply dummy MDIO routines so the kernel won't crash
+- if the user tries to read them */
+- priv->mii_info.mdio_read = cvm_oct_mdio_dummy_read;
+- priv->mii_info.mdio_write = cvm_oct_mdio_dummy_write;
++
++ int phy_addr = cvmx_helper_board_get_mii_address(priv->port);
++ if (phy_addr != -1) {
++ char phy_id[20];
++
++ snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT, "0", phy_addr);
++
++ priv->phydev = phy_connect(dev, phy_id, cvm_oct_adjust_link, 0,
++ PHY_INTERFACE_MODE_GMII);
++
++ if (IS_ERR(priv->phydev)) {
++ priv->phydev = NULL;
++ return -1;
++ }
++ priv->last_link = 0;
++ phy_start_aneg(priv->phydev);
+ }
+ return 0;
+ }
+diff --git a/drivers/staging/octeon/ethernet-mdio.h b/drivers/staging/octeon/ethernet-mdio.h
+index b3328ae..55d0614 100644
+--- a/drivers/staging/octeon/ethernet-mdio.h
++++ b/drivers/staging/octeon/ethernet-mdio.h
+@@ -43,4 +43,4 @@
+
+ extern const struct ethtool_ops cvm_oct_ethtool_ops;
+ int cvm_oct_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+-int cvm_oct_mdio_setup_device(struct net_device *dev);
++int cvm_oct_phy_setup_device(struct net_device *dev);
+diff --git a/drivers/staging/octeon/ethernet-proc.c b/drivers/staging/octeon/ethernet-proc.c
+index 8fa88fc..16308d4 100644
+--- a/drivers/staging/octeon/ethernet-proc.c
++++ b/drivers/staging/octeon/ethernet-proc.c
+@@ -25,7 +25,6 @@
+ * Contact Cavium Networks for more information
+ **********************************************************************/
+ #include <linux/kernel.h>
+-#include <linux/mii.h>
+ #include <linux/seq_file.h>
+ #include <linux/proc_fs.h>
+ #include <net/dst.h>
+@@ -38,112 +37,6 @@
+ #include "cvmx-helper.h"
+ #include "cvmx-pip.h"
+
+-static unsigned long long cvm_oct_stats_read_switch(struct net_device *dev,
+- int phy_id, int offset)
+-{
+- struct octeon_ethernet *priv = netdev_priv(dev);
+-
+- priv->mii_info.mdio_write(dev, phy_id, 0x1d, 0xcc00 | offset);
+- return ((uint64_t) priv->mii_info.
+- mdio_read(dev, phy_id,
+- 0x1e) << 16) | (uint64_t) priv->mii_info.
+- mdio_read(dev, phy_id, 0x1f);
+-}
+-
+-static int cvm_oct_stats_switch_show(struct seq_file *m, void *v)
+-{
+- static const int ports[] = { 0, 1, 2, 3, 9, -1 };
+- struct net_device *dev = cvm_oct_device[0];
+- int index = 0;
+-
+- while (ports[index] != -1) {
+-
+- /* Latch port */
+- struct octeon_ethernet *priv = netdev_priv(dev);
+-
+- priv->mii_info.mdio_write(dev, 0x1b, 0x1d,
+- 0xdc00 | ports[index]);
+- seq_printf(m, "\nSwitch Port %d\n", ports[index]);
+- seq_printf(m, "InGoodOctets: %12llu\t"
+- "OutOctets: %12llu\t"
+- "64 Octets: %12llu\n",
+- cvm_oct_stats_read_switch(dev, 0x1b,
+- 0x00) |
+- (cvm_oct_stats_read_switch(dev, 0x1b, 0x01) << 32),
+- cvm_oct_stats_read_switch(dev, 0x1b,
+- 0x0E) |
+- (cvm_oct_stats_read_switch(dev, 0x1b, 0x0F) << 32),
+- cvm_oct_stats_read_switch(dev, 0x1b, 0x08));
+-
+- seq_printf(m, "InBadOctets: %12llu\t"
+- "OutUnicast: %12llu\t"
+- "65-127 Octets: %12llu\n",
+- cvm_oct_stats_read_switch(dev, 0x1b, 0x02),
+- cvm_oct_stats_read_switch(dev, 0x1b, 0x10),
+- cvm_oct_stats_read_switch(dev, 0x1b, 0x09));
+-
+- seq_printf(m, "InUnicast: %12llu\t"
+- "OutBroadcasts: %12llu\t"
+- "128-255 Octets: %12llu\n",
+- cvm_oct_stats_read_switch(dev, 0x1b, 0x04),
+- cvm_oct_stats_read_switch(dev, 0x1b, 0x13),
+- cvm_oct_stats_read_switch(dev, 0x1b, 0x0A));
+-
+- seq_printf(m, "InBroadcasts: %12llu\t"
+- "OutMulticasts: %12llu\t"
+- "256-511 Octets: %12llu\n",
+- cvm_oct_stats_read_switch(dev, 0x1b, 0x06),
+- cvm_oct_stats_read_switch(dev, 0x1b, 0x12),
+- cvm_oct_stats_read_switch(dev, 0x1b, 0x0B));
+-
+- seq_printf(m, "InMulticasts: %12llu\t"
+- "OutPause: %12llu\t"
+- "512-1023 Octets:%12llu\n",
+- cvm_oct_stats_read_switch(dev, 0x1b, 0x07),
+- cvm_oct_stats_read_switch(dev, 0x1b, 0x15),
+- cvm_oct_stats_read_switch(dev, 0x1b, 0x0C));
+-
+- seq_printf(m, "InPause: %12llu\t"
+- "Excessive: %12llu\t"
+- "1024-Max Octets:%12llu\n",
+- cvm_oct_stats_read_switch(dev, 0x1b, 0x16),
+- cvm_oct_stats_read_switch(dev, 0x1b, 0x11),
+- cvm_oct_stats_read_switch(dev, 0x1b, 0x0D));
+-
+- seq_printf(m, "InUndersize: %12llu\t"
+- "Collisions: %12llu\n",
+- cvm_oct_stats_read_switch(dev, 0x1b, 0x18),
+- cvm_oct_stats_read_switch(dev, 0x1b, 0x1E));
+-
+- seq_printf(m, "InFragments: %12llu\t"
+- "Deferred: %12llu\n",
+- cvm_oct_stats_read_switch(dev, 0x1b, 0x19),
+- cvm_oct_stats_read_switch(dev, 0x1b, 0x05));
+-
+- seq_printf(m, "InOversize: %12llu\t"
+- "Single: %12llu\n",
+- cvm_oct_stats_read_switch(dev, 0x1b, 0x1A),
+- cvm_oct_stats_read_switch(dev, 0x1b, 0x14));
+-
+- seq_printf(m, "InJabber: %12llu\t"
+- "Multiple: %12llu\n",
+- cvm_oct_stats_read_switch(dev, 0x1b, 0x1B),
+- cvm_oct_stats_read_switch(dev, 0x1b, 0x17));
+-
+- seq_printf(m, "In RxErr: %12llu\t"
+- "OutFCSErr: %12llu\n",
+- cvm_oct_stats_read_switch(dev, 0x1b, 0x1C),
+- cvm_oct_stats_read_switch(dev, 0x1b, 0x03));
+-
+- seq_printf(m, "InFCSErr: %12llu\t"
+- "Late: %12llu\n",
+- cvm_oct_stats_read_switch(dev, 0x1b, 0x1D),
+- cvm_oct_stats_read_switch(dev, 0x1b, 0x1F));
+- index++;
+- }
+- return 0;
+-}
+-
+ /**
+ * User is reading /proc/octeon_ethernet_stats
+ *
+@@ -215,11 +108,6 @@ static int cvm_oct_stats_show(struct seq_file *m, void *v)
+ }
+ }
+
+- if (cvm_oct_device[0]) {
+- priv = netdev_priv(cvm_oct_device[0]);
+- if (priv->imode == CVMX_HELPER_INTERFACE_MODE_GMII)
+- cvm_oct_stats_switch_show(m, v);
+- }
+ return 0;
+ }
+
+diff --git a/drivers/staging/octeon/ethernet-rgmii.c b/drivers/staging/octeon/ethernet-rgmii.c
+index 8704133..d238611 100644
+--- a/drivers/staging/octeon/ethernet-rgmii.c
++++ b/drivers/staging/octeon/ethernet-rgmii.c
+@@ -147,32 +147,36 @@ static void cvm_oct_rgmii_poll(struct net_device *dev)
+ cvmx_write_csr(CVMX_GMXX_RXX_INT_REG(index, interface),
+ gmxx_rxx_int_reg.u64);
+ }
+-
+- link_info = cvmx_helper_link_autoconf(priv->port);
+- priv->link_info = link_info.u64;
++ if (priv->phydev == NULL) {
++ link_info = cvmx_helper_link_autoconf(priv->port);
++ priv->link_info = link_info.u64;
++ }
+ spin_unlock_irqrestore(&global_register_lock, flags);
+
+- /* Tell Linux */
+- if (link_info.s.link_up) {
+-
+- if (!netif_carrier_ok(dev))
+- netif_carrier_on(dev);
+- if (priv->queue != -1)
+- DEBUGPRINT
+- ("%s: %u Mbps %s duplex, port %2d, queue %2d\n",
+- dev->name, link_info.s.speed,
+- (link_info.s.full_duplex) ? "Full" : "Half",
+- priv->port, priv->queue);
+- else
+- DEBUGPRINT("%s: %u Mbps %s duplex, port %2d, POW\n",
+- dev->name, link_info.s.speed,
+- (link_info.s.full_duplex) ? "Full" : "Half",
+- priv->port);
+- } else {
+-
+- if (netif_carrier_ok(dev))
+- netif_carrier_off(dev);
+- DEBUGPRINT("%s: Link down\n", dev->name);
++ if (priv->phydev == NULL) {
++ /* Tell core. */
++ if (link_info.s.link_up) {
++ if (!netif_carrier_ok(dev))
++ netif_carrier_on(dev);
++ if (priv->queue != -1)
++ DEBUGPRINT("%s: %u Mbps %s duplex, "
++ "port %2d, queue %2d\n",
++ dev->name, link_info.s.speed,
++ (link_info.s.full_duplex) ?
++ "Full" : "Half",
++ priv->port, priv->queue);
++ else
++ DEBUGPRINT("%s: %u Mbps %s duplex, "
++ "port %2d, POW\n",
++ dev->name, link_info.s.speed,
++ (link_info.s.full_duplex) ?
++ "Full" : "Half",
++ priv->port);
++ } else {
++ if (netif_carrier_ok(dev))
++ netif_carrier_off(dev);
++ DEBUGPRINT("%s: Link down\n", dev->name);
++ }
+ }
+ }
+
+diff --git a/drivers/staging/octeon/ethernet-sgmii.c b/drivers/staging/octeon/ethernet-sgmii.c
+index 2b54996..6061d01 100644
+--- a/drivers/staging/octeon/ethernet-sgmii.c
++++ b/drivers/staging/octeon/ethernet-sgmii.c
+@@ -113,7 +113,7 @@ int cvm_oct_sgmii_init(struct net_device *dev)
+ struct octeon_ethernet *priv = netdev_priv(dev);
+ cvm_oct_common_init(dev);
+ dev->netdev_ops->ndo_stop(dev);
+- if (!octeon_is_simulation())
++ if (!octeon_is_simulation() && priv->phydev == NULL)
+ priv->poll = cvm_oct_sgmii_poll;
+
+ /* FIXME: Need autoneg logic */
+diff --git a/drivers/staging/octeon/ethernet-xaui.c b/drivers/staging/octeon/ethernet-xaui.c
+index 0c2e7cc..ee3dc41 100644
+--- a/drivers/staging/octeon/ethernet-xaui.c
++++ b/drivers/staging/octeon/ethernet-xaui.c
+@@ -112,7 +112,7 @@ int cvm_oct_xaui_init(struct net_device *dev)
+ struct octeon_ethernet *priv = netdev_priv(dev);
+ cvm_oct_common_init(dev);
+ dev->netdev_ops->ndo_stop(dev);
+- if (!octeon_is_simulation())
++ if (!octeon_is_simulation() && priv->phydev == NULL)
+ priv->poll = cvm_oct_xaui_poll;
+
+ return 0;
+diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c
+index 492c502..4cfd4b1 100644
+--- a/drivers/staging/octeon/ethernet.c
++++ b/drivers/staging/octeon/ethernet.c
+@@ -30,7 +30,7 @@
+ #include <linux/netdevice.h>
+ #include <linux/etherdevice.h>
+ #include <linux/delay.h>
+-#include <linux/mii.h>
++#include <linux/phy.h>
+
+ #include <net/dst.h>
+
+@@ -132,8 +132,6 @@ static struct timer_list cvm_oct_poll_timer;
+ */
+ struct net_device *cvm_oct_device[TOTAL_NUMBER_OF_PORTS];
+
+-extern struct semaphore mdio_sem;
+-
+ /**
+ * Periodic timer tick for slow management operations
+ *
+@@ -160,13 +158,8 @@ static void cvm_do_timer(unsigned long arg)
+ goto out;
+
+ priv = netdev_priv(cvm_oct_device[port]);
+- if (priv->poll) {
+- /* skip polling if we don't get the lock */
+- if (!down_trylock(&mdio_sem)) {
+- priv->poll(cvm_oct_device[port]);
+- up(&mdio_sem);
+- }
+- }
++ if (priv->poll)
++ priv->poll(cvm_oct_device[port]);
+
+ queues_per_port = cvmx_pko_get_num_queues(port);
+ /* Drain any pending packets in the free list */
+@@ -524,7 +517,7 @@ int cvm_oct_common_init(struct net_device *dev)
+ dev->features |= NETIF_F_LLTX;
+ SET_ETHTOOL_OPS(dev, &cvm_oct_ethtool_ops);
+
+- cvm_oct_mdio_setup_device(dev);
++ cvm_oct_phy_setup_device(dev);
+ dev->netdev_ops->ndo_set_mac_address(dev, &sa);
+ dev->netdev_ops->ndo_change_mtu(dev, dev->mtu);
+
+@@ -540,7 +533,10 @@ int cvm_oct_common_init(struct net_device *dev)
+
+ void cvm_oct_common_uninit(struct net_device *dev)
+ {
+- /* Currently nothing to do */
++ struct octeon_ethernet *priv = netdev_priv(dev);
++
++ if (priv->phydev)
++ phy_disconnect(priv->phydev);
+ }
+
+ static const struct net_device_ops cvm_oct_npi_netdev_ops = {
+@@ -627,6 +623,8 @@ static const struct net_device_ops cvm_oct_pow_netdev_ops = {
+ #endif
+ };
+
++extern void octeon_mdiobus_force_mod_depencency(void);
++
+ /**
+ * Module/ driver initialization. Creates the linux network
+ * devices.
+@@ -640,6 +638,7 @@ static int __init cvm_oct_init_module(void)
+ int fau = FAU_NUM_PACKET_BUFFERS_TO_FREE;
+ int qos;
+
++ octeon_mdiobus_force_mod_depencency();
+ pr_notice("cavium-ethernet %s\n", OCTEON_ETHERNET_VERSION);
+
+ if (OCTEON_IS_MODEL(OCTEON_CN52XX))
+diff --git a/drivers/staging/octeon/octeon-ethernet.h b/drivers/staging/octeon/octeon-ethernet.h
+index 3aef987..402a15b 100644
+--- a/drivers/staging/octeon/octeon-ethernet.h
++++ b/drivers/staging/octeon/octeon-ethernet.h
+@@ -50,9 +50,9 @@ struct octeon_ethernet {
+ /* List of outstanding tx buffers per queue */
+ struct sk_buff_head tx_free_list[16];
+ /* Device statistics */
+- struct net_device_stats stats
+-; /* Generic MII info structure */
+- struct mii_if_info mii_info;
++ struct net_device_stats stats;
++ struct phy_device *phydev;
++ unsigned int last_link;
+ /* Last negotiated link state */
+ uint64_t link_info;
+ /* Called periodically to check link status */
+diff --git a/drivers/staging/sm7xx/Kconfig b/drivers/staging/sm7xx/Kconfig
+new file mode 100644
+index 0000000..204dbfc
+--- /dev/null
++++ b/drivers/staging/sm7xx/Kconfig
+@@ -0,0 +1,15 @@
++config FB_SM7XX
++ tristate "Silicon Motion SM7XX Frame Buffer Support"
++ depends on FB
++ select FB_CFB_FILLRECT
++ select FB_CFB_COPYAREA
++ select FB_CFB_IMAGEBLIT
++ help
++ Frame Buffer driver for the Silicon Motion SM7XX serial graphic card.
++
++config FB_SM7XX_ACCEL
++ bool "Siliconmotion Acceleration functions (EXPERIMENTAL)"
++ depends on FB_SM7XX && EXPERIMENTAL
++ help
++ This will compile the Trident frame buffer device with
++ acceleration functions.
+diff --git a/drivers/staging/sm7xx/Makefile b/drivers/staging/sm7xx/Makefile
+new file mode 100644
+index 0000000..f43cb91
+--- /dev/null
++++ b/drivers/staging/sm7xx/Makefile
+@@ -0,0 +1,3 @@
++obj-$(CONFIG_FB_SM7XX) += sm7xx.o
++
++sm7xx-y := smtcfb.o
+diff --git a/drivers/staging/sm7xx/TODO b/drivers/staging/sm7xx/TODO
+new file mode 100644
+index 0000000..8acca77
+--- /dev/null
++++ b/drivers/staging/sm7xx/TODO
+@@ -0,0 +1,11 @@
++TODO:
++- Dual head support
++- use kernel coding style
++- checkpatch.pl clean
++- refine the code and remove unused code
++- use kernel framebuffer mode setting instead of hard code
++- make sure it work on all exisiting archs
++- move it to drivers/video/sm7xx/ or make it be drivers/video/sm7xxfb.c
++
++Please send any patches to Greg Kroah-Hartman <greg@kroah.com> and
++Teddy Wang <teddy.wang@siliconmotion.com.cn>.
+diff --git a/drivers/staging/sm7xx/smtc2d.c b/drivers/staging/sm7xx/smtc2d.c
+new file mode 100644
+index 0000000..133b86c
+--- /dev/null
++++ b/drivers/staging/sm7xx/smtc2d.c
+@@ -0,0 +1,979 @@
++/*
++ * Silicon Motion SM7XX 2D drawing engine functions.
++ *
++ * Copyright (C) 2006 Silicon Motion Technology Corp.
++ * Author: Boyod boyod.yang@siliconmotion.com.cn
++ *
++ * Copyright (C) 2009 Lemote, Inc.
++ * Author: Wu Zhangjin, wuzj@lemote.com
++ *
++ * 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.
++ *
++ * Version 0.10.26192.21.01
++ * - Add PowerPC support
++ * - Add 2D support for Lynx -
++ * Verified on 2.6.19.2
++ * Boyod.yang <boyod.yang@siliconmotion.com.cn>
++ */
++
++unsigned char smtc_de_busy;
++
++void SMTC_write2Dreg(unsigned long nOffset, unsigned long nData)
++{
++ writel(nData, smtc_2DBaseAddress + nOffset);
++}
++
++unsigned long SMTC_read2Dreg(unsigned long nOffset)
++{
++ return readl(smtc_2DBaseAddress + nOffset);
++}
++
++void SMTC_write2Ddataport(unsigned long nOffset, unsigned long nData)
++{
++ writel(nData, smtc_2Ddataport + nOffset);
++}
++
++/**********************************************************************
++ *
++ * deInit
++ *
++ * Purpose
++ * Drawing engine initialization.
++ *
++ **********************************************************************/
++
++void deInit(unsigned int nModeWidth, unsigned int nModeHeight,
++ unsigned int bpp)
++{
++ /* Get current power configuration. */
++ unsigned char clock;
++ clock = smtc_seqr(0x21);
++
++ /* initialize global 'mutex lock' variable */
++ smtc_de_busy = 0;
++
++ /* Enable 2D Drawing Engine */
++ smtc_seqw(0x21, clock & 0xF8);
++
++ SMTC_write2Dreg(DE_CLIP_TL,
++ FIELD_VALUE(0, DE_CLIP_TL, TOP, 0) |
++ FIELD_SET(0, DE_CLIP_TL, STATUS, DISABLE) |
++ FIELD_SET(0, DE_CLIP_TL, INHIBIT, OUTSIDE) |
++ FIELD_VALUE(0, DE_CLIP_TL, LEFT, 0));
++
++ if (bpp >= 24) {
++ SMTC_write2Dreg(DE_PITCH,
++ FIELD_VALUE(0, DE_PITCH, DESTINATION,
++ nModeWidth * 3) | FIELD_VALUE(0,
++ DE_PITCH,
++ SOURCE,
++ nModeWidth
++ * 3));
++ } else {
++ SMTC_write2Dreg(DE_PITCH,
++ FIELD_VALUE(0, DE_PITCH, DESTINATION,
++ nModeWidth) | FIELD_VALUE(0,
++ DE_PITCH,
++ SOURCE,
++ nModeWidth));
++ }
++
++ SMTC_write2Dreg(DE_WINDOW_WIDTH,
++ FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
++ nModeWidth) | FIELD_VALUE(0,
++ DE_WINDOW_WIDTH,
++ SOURCE,
++ nModeWidth));
++
++ switch (bpp) {
++ case 8:
++ SMTC_write2Dreg(DE_STRETCH_FORMAT,
++ FIELD_SET(0, DE_STRETCH_FORMAT, PATTERN_XY,
++ NORMAL) | FIELD_VALUE(0,
++ DE_STRETCH_FORMAT,
++ PATTERN_Y,
++ 0) |
++ FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_X,
++ 0) | FIELD_SET(0, DE_STRETCH_FORMAT,
++ PIXEL_FORMAT,
++ 8) | FIELD_SET(0,
++ DE_STRETCH_FORMAT,
++ ADDRESSING,
++ XY) |
++ FIELD_VALUE(0, DE_STRETCH_FORMAT,
++ SOURCE_HEIGHT, 3));
++ break;
++ case 24:
++ SMTC_write2Dreg(DE_STRETCH_FORMAT,
++ FIELD_SET(0, DE_STRETCH_FORMAT, PATTERN_XY,
++ NORMAL) | FIELD_VALUE(0,
++ DE_STRETCH_FORMAT,
++ PATTERN_Y,
++ 0) |
++ FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_X,
++ 0) | FIELD_SET(0, DE_STRETCH_FORMAT,
++ PIXEL_FORMAT,
++ 24) | FIELD_SET(0,
++ DE_STRETCH_FORMAT,
++ ADDRESSING,
++ XY) |
++ FIELD_VALUE(0, DE_STRETCH_FORMAT,
++ SOURCE_HEIGHT, 3));
++ break;
++ case 16:
++ default:
++ SMTC_write2Dreg(DE_STRETCH_FORMAT,
++ FIELD_SET(0, DE_STRETCH_FORMAT, PATTERN_XY,
++ NORMAL) | FIELD_VALUE(0,
++ DE_STRETCH_FORMAT,
++ PATTERN_Y,
++ 0) |
++ FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_X,
++ 0) | FIELD_SET(0, DE_STRETCH_FORMAT,
++ PIXEL_FORMAT,
++ 16) | FIELD_SET(0,
++ DE_STRETCH_FORMAT,
++ ADDRESSING,
++ XY) |
++ FIELD_VALUE(0, DE_STRETCH_FORMAT,
++ SOURCE_HEIGHT, 3));
++ break;
++ }
++
++ SMTC_write2Dreg(DE_MASKS,
++ FIELD_VALUE(0, DE_MASKS, BYTE_MASK, 0xFFFF) |
++ FIELD_VALUE(0, DE_MASKS, BIT_MASK, 0xFFFF));
++ SMTC_write2Dreg(DE_COLOR_COMPARE_MASK,
++ FIELD_VALUE(0, DE_COLOR_COMPARE_MASK, MASKS, \
++ 0xFFFFFF));
++ SMTC_write2Dreg(DE_COLOR_COMPARE,
++ FIELD_VALUE(0, DE_COLOR_COMPARE, COLOR, 0xFFFFFF));
++}
++
++void deVerticalLine(unsigned long dst_base,
++ unsigned long dst_pitch,
++ unsigned long nX,
++ unsigned long nY,
++ unsigned long dst_height, unsigned long nColor)
++{
++ deWaitForNotBusy();
++
++ SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE,
++ FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS,
++ dst_base));
++
++ SMTC_write2Dreg(DE_PITCH,
++ FIELD_VALUE(0, DE_PITCH, DESTINATION, dst_pitch) |
++ FIELD_VALUE(0, DE_PITCH, SOURCE, dst_pitch));
++
++ SMTC_write2Dreg(DE_WINDOW_WIDTH,
++ FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
++ dst_pitch) | FIELD_VALUE(0, DE_WINDOW_WIDTH,
++ SOURCE,
++ dst_pitch));
++
++ SMTC_write2Dreg(DE_FOREGROUND,
++ FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor));
++
++ SMTC_write2Dreg(DE_DESTINATION,
++ FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) |
++ FIELD_VALUE(0, DE_DESTINATION, X, nX) |
++ FIELD_VALUE(0, DE_DESTINATION, Y, nY));
++
++ SMTC_write2Dreg(DE_DIMENSION,
++ FIELD_VALUE(0, DE_DIMENSION, X, 1) |
++ FIELD_VALUE(0, DE_DIMENSION, Y_ET, dst_height));
++
++ SMTC_write2Dreg(DE_CONTROL,
++ FIELD_SET(0, DE_CONTROL, STATUS, START) |
++ FIELD_SET(0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT) |
++ FIELD_SET(0, DE_CONTROL, MAJOR, Y) |
++ FIELD_SET(0, DE_CONTROL, STEP_X, NEGATIVE) |
++ FIELD_SET(0, DE_CONTROL, STEP_Y, POSITIVE) |
++ FIELD_SET(0, DE_CONTROL, LAST_PIXEL, OFF) |
++ FIELD_SET(0, DE_CONTROL, COMMAND, SHORT_STROKE) |
++ FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) |
++ FIELD_VALUE(0, DE_CONTROL, ROP, 0x0C));
++
++ smtc_de_busy = 1;
++}
++
++void deHorizontalLine(unsigned long dst_base,
++ unsigned long dst_pitch,
++ unsigned long nX,
++ unsigned long nY,
++ unsigned long dst_width, unsigned long nColor)
++{
++ deWaitForNotBusy();
++
++ SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE,
++ FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS,
++ dst_base));
++
++ SMTC_write2Dreg(DE_PITCH,
++ FIELD_VALUE(0, DE_PITCH, DESTINATION, dst_pitch) |
++ FIELD_VALUE(0, DE_PITCH, SOURCE, dst_pitch));
++
++ SMTC_write2Dreg(DE_WINDOW_WIDTH,
++ FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
++ dst_pitch) | FIELD_VALUE(0, DE_WINDOW_WIDTH,
++ SOURCE,
++ dst_pitch));
++ SMTC_write2Dreg(DE_FOREGROUND,
++ FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor));
++ SMTC_write2Dreg(DE_DESTINATION,
++ FIELD_SET(0, DE_DESTINATION, WRAP,
++ DISABLE) | FIELD_VALUE(0, DE_DESTINATION, X,
++ nX) | FIELD_VALUE(0,
++ DE_DESTINATION,
++ Y,
++ nY));
++ SMTC_write2Dreg(DE_DIMENSION,
++ FIELD_VALUE(0, DE_DIMENSION, X,
++ dst_width) | FIELD_VALUE(0, DE_DIMENSION,
++ Y_ET, 1));
++ SMTC_write2Dreg(DE_CONTROL,
++ FIELD_SET(0, DE_CONTROL, STATUS, START) | FIELD_SET(0,
++ DE_CONTROL,
++ DIRECTION,
++ RIGHT_TO_LEFT)
++ | FIELD_SET(0, DE_CONTROL, MAJOR, X) | FIELD_SET(0,
++ DE_CONTROL,
++ STEP_X,
++ POSITIVE)
++ | FIELD_SET(0, DE_CONTROL, STEP_Y,
++ NEGATIVE) | FIELD_SET(0, DE_CONTROL,
++ LAST_PIXEL,
++ OFF) | FIELD_SET(0,
++ DE_CONTROL,
++ COMMAND,
++ SHORT_STROKE)
++ | FIELD_SET(0, DE_CONTROL, ROP_SELECT,
++ ROP2) | FIELD_VALUE(0, DE_CONTROL, ROP,
++ 0x0C));
++
++ smtc_de_busy = 1;
++}
++
++void deLine(unsigned long dst_base,
++ unsigned long dst_pitch,
++ unsigned long nX1,
++ unsigned long nY1,
++ unsigned long nX2, unsigned long nY2, unsigned long nColor)
++{
++ unsigned long nCommand =
++ FIELD_SET(0, DE_CONTROL, STATUS, START) |
++ FIELD_SET(0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT) |
++ FIELD_SET(0, DE_CONTROL, MAJOR, X) |
++ FIELD_SET(0, DE_CONTROL, STEP_X, POSITIVE) |
++ FIELD_SET(0, DE_CONTROL, STEP_Y, POSITIVE) |
++ FIELD_SET(0, DE_CONTROL, LAST_PIXEL, OFF) |
++ FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) |
++ FIELD_VALUE(0, DE_CONTROL, ROP, 0x0C);
++ unsigned long DeltaX;
++ unsigned long DeltaY;
++
++ /* Calculate delta X */
++ if (nX1 <= nX2)
++ DeltaX = nX2 - nX1;
++ else {
++ DeltaX = nX1 - nX2;
++ nCommand = FIELD_SET(nCommand, DE_CONTROL, STEP_X, NEGATIVE);
++ }
++
++ /* Calculate delta Y */
++ if (nY1 <= nY2)
++ DeltaY = nY2 - nY1;
++ else {
++ DeltaY = nY1 - nY2;
++ nCommand = FIELD_SET(nCommand, DE_CONTROL, STEP_Y, NEGATIVE);
++ }
++
++ /* Determine the major axis */
++ if (DeltaX < DeltaY)
++ nCommand = FIELD_SET(nCommand, DE_CONTROL, MAJOR, Y);
++
++ /* Vertical line? */
++ if (nX1 == nX2)
++ deVerticalLine(dst_base, dst_pitch, nX1, nY1, DeltaY, nColor);
++
++ /* Horizontal line? */
++ else if (nY1 == nY2)
++ deHorizontalLine(dst_base, dst_pitch, nX1, nY1, \
++ DeltaX, nColor);
++
++ /* Diagonal line? */
++ else if (DeltaX == DeltaY) {
++ deWaitForNotBusy();
++
++ SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE,
++ FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE,
++ ADDRESS, dst_base));
++
++ SMTC_write2Dreg(DE_PITCH,
++ FIELD_VALUE(0, DE_PITCH, DESTINATION,
++ dst_pitch) | FIELD_VALUE(0,
++ DE_PITCH,
++ SOURCE,
++ dst_pitch));
++
++ SMTC_write2Dreg(DE_WINDOW_WIDTH,
++ FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
++ dst_pitch) | FIELD_VALUE(0,
++ DE_WINDOW_WIDTH,
++ SOURCE,
++ dst_pitch));
++
++ SMTC_write2Dreg(DE_FOREGROUND,
++ FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor));
++
++ SMTC_write2Dreg(DE_DESTINATION,
++ FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) |
++ FIELD_VALUE(0, DE_DESTINATION, X, 1) |
++ FIELD_VALUE(0, DE_DESTINATION, Y, nY1));
++
++ SMTC_write2Dreg(DE_DIMENSION,
++ FIELD_VALUE(0, DE_DIMENSION, X, 1) |
++ FIELD_VALUE(0, DE_DIMENSION, Y_ET, DeltaX));
++
++ SMTC_write2Dreg(DE_CONTROL,
++ FIELD_SET(nCommand, DE_CONTROL, COMMAND,
++ SHORT_STROKE));
++ }
++
++ /* Generic line */
++ else {
++ unsigned int k1, k2, et, w;
++ if (DeltaX < DeltaY) {
++ k1 = 2 * DeltaX;
++ et = k1 - DeltaY;
++ k2 = et - DeltaY;
++ w = DeltaY + 1;
++ } else {
++ k1 = 2 * DeltaY;
++ et = k1 - DeltaX;
++ k2 = et - DeltaX;
++ w = DeltaX + 1;
++ }
++
++ deWaitForNotBusy();
++
++ SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE,
++ FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE,
++ ADDRESS, dst_base));
++
++ SMTC_write2Dreg(DE_PITCH,
++ FIELD_VALUE(0, DE_PITCH, DESTINATION,
++ dst_pitch) | FIELD_VALUE(0,
++ DE_PITCH,
++ SOURCE,
++ dst_pitch));
++
++ SMTC_write2Dreg(DE_WINDOW_WIDTH,
++ FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
++ dst_pitch) | FIELD_VALUE(0,
++ DE_WINDOW_WIDTH,
++ SOURCE,
++ dst_pitch));
++
++ SMTC_write2Dreg(DE_FOREGROUND,
++ FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor));
++
++ SMTC_write2Dreg(DE_SOURCE,
++ FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) |
++ FIELD_VALUE(0, DE_SOURCE, X_K1, k1) |
++ FIELD_VALUE(0, DE_SOURCE, Y_K2, k2));
++
++ SMTC_write2Dreg(DE_DESTINATION,
++ FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) |
++ FIELD_VALUE(0, DE_DESTINATION, X, nX1) |
++ FIELD_VALUE(0, DE_DESTINATION, Y, nY1));
++
++ SMTC_write2Dreg(DE_DIMENSION,
++ FIELD_VALUE(0, DE_DIMENSION, X, w) |
++ FIELD_VALUE(0, DE_DIMENSION, Y_ET, et));
++
++ SMTC_write2Dreg(DE_CONTROL,
++ FIELD_SET(nCommand, DE_CONTROL, COMMAND,
++ LINE_DRAW));
++ }
++
++ smtc_de_busy = 1;
++}
++
++void deFillRect(unsigned long dst_base,
++ unsigned long dst_pitch,
++ unsigned long dst_X,
++ unsigned long dst_Y,
++ unsigned long dst_width,
++ unsigned long dst_height, unsigned long nColor)
++{
++ deWaitForNotBusy();
++
++ SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE,
++ FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS,
++ dst_base));
++
++ if (dst_pitch) {
++ SMTC_write2Dreg(DE_PITCH,
++ FIELD_VALUE(0, DE_PITCH, DESTINATION,
++ dst_pitch) | FIELD_VALUE(0,
++ DE_PITCH,
++ SOURCE,
++ dst_pitch));
++
++ SMTC_write2Dreg(DE_WINDOW_WIDTH,
++ FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
++ dst_pitch) | FIELD_VALUE(0,
++ DE_WINDOW_WIDTH,
++ SOURCE,
++ dst_pitch));
++ }
++
++ SMTC_write2Dreg(DE_FOREGROUND,
++ FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor));
++
++ SMTC_write2Dreg(DE_DESTINATION,
++ FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) |
++ FIELD_VALUE(0, DE_DESTINATION, X, dst_X) |
++ FIELD_VALUE(0, DE_DESTINATION, Y, dst_Y));
++
++ SMTC_write2Dreg(DE_DIMENSION,
++ FIELD_VALUE(0, DE_DIMENSION, X, dst_width) |
++ FIELD_VALUE(0, DE_DIMENSION, Y_ET, dst_height));
++
++ SMTC_write2Dreg(DE_CONTROL,
++ FIELD_SET(0, DE_CONTROL, STATUS, START) |
++ FIELD_SET(0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT) |
++ FIELD_SET(0, DE_CONTROL, LAST_PIXEL, OFF) |
++ FIELD_SET(0, DE_CONTROL, COMMAND, RECTANGLE_FILL) |
++ FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) |
++ FIELD_VALUE(0, DE_CONTROL, ROP, 0x0C));
++
++ smtc_de_busy = 1;
++}
++
++/**********************************************************************
++ *
++ * deRotatePattern
++ *
++ * Purpose
++ * Rotate the given pattern if necessary
++ *
++ * Parameters
++ * [in]
++ * pPattern - Pointer to DE_SURFACE structure containing
++ * pattern attributes
++ * patternX - X position (0-7) of pattern origin
++ * patternY - Y position (0-7) of pattern origin
++ *
++ * [out]
++ * pattern_dstaddr - Pointer to pre-allocated buffer containing
++ * rotated pattern
++ *
++ **********************************************************************/
++void deRotatePattern(unsigned char *pattern_dstaddr,
++ unsigned long pattern_src_addr,
++ unsigned long pattern_BPP,
++ unsigned long pattern_stride, int patternX, int patternY)
++{
++ unsigned int i;
++ unsigned long pattern[PATTERN_WIDTH * PATTERN_HEIGHT];
++ unsigned int x, y;
++ unsigned char *pjPatByte;
++
++ if (pattern_dstaddr != NULL) {
++ deWaitForNotBusy();
++
++ if (patternX || patternY) {
++ /* Rotate pattern */
++ pjPatByte = (unsigned char *)pattern;
++
++ switch (pattern_BPP) {
++ case 8:
++ {
++ for (y = 0; y < 8; y++) {
++ unsigned char *pjBuffer =
++ pattern_dstaddr +
++ ((patternY + y) & 7) * 8;
++ for (x = 0; x < 8; x++) {
++ pjBuffer[(patternX +
++ x) & 7] =
++ pjPatByte[x];
++ }
++ pjPatByte += pattern_stride;
++ }
++ break;
++ }
++
++ case 16:
++ {
++ for (y = 0; y < 8; y++) {
++ unsigned short *pjBuffer =
++ (unsigned short *)
++ pattern_dstaddr +
++ ((patternY + y) & 7) * 8;
++ for (x = 0; x < 8; x++) {
++ pjBuffer[(patternX +
++ x) & 7] =
++ ((unsigned short *)
++ pjPatByte)[x];
++ }
++ pjPatByte += pattern_stride;
++ }
++ break;
++ }
++
++ case 32:
++ {
++ for (y = 0; y < 8; y++) {
++ unsigned long *pjBuffer =
++ (unsigned long *)
++ pattern_dstaddr +
++ ((patternY + y) & 7) * 8;
++ for (x = 0; x < 8; x++) {
++ pjBuffer[(patternX +
++ x) & 7] =
++ ((unsigned long *)
++ pjPatByte)[x];
++ }
++ pjPatByte += pattern_stride;
++ }
++ break;
++ }
++ }
++ } else {
++ /*Don't rotate,just copy pattern into pattern_dstaddr*/
++ for (i = 0; i < (pattern_BPP * 2); i++) {
++ ((unsigned long *)pattern_dstaddr)[i] =
++ pattern[i];
++ }
++ }
++
++ }
++}
++
++/**********************************************************************
++ *
++ * deCopy
++ *
++ * Purpose
++ * Copy a rectangular area of the source surface to a destination surface
++ *
++ * Remarks
++ * Source bitmap must have the same color depth (BPP) as the destination
++ * bitmap.
++ *
++**********************************************************************/
++void deCopy(unsigned long dst_base,
++ unsigned long dst_pitch,
++ unsigned long dst_BPP,
++ unsigned long dst_X,
++ unsigned long dst_Y,
++ unsigned long dst_width,
++ unsigned long dst_height,
++ unsigned long src_base,
++ unsigned long src_pitch,
++ unsigned long src_X,
++ unsigned long src_Y, pTransparent pTransp, unsigned char nROP2)
++{
++ unsigned long nDirection = 0;
++ unsigned long nTransparent = 0;
++ /* Direction of ROP2 operation:
++ * 1 = Left to Right,
++ * (-1) = Right to Left
++ */
++ unsigned long opSign = 1;
++ /* xWidth is in pixels */
++ unsigned long xWidth = 192 / (dst_BPP / 8);
++ unsigned long de_ctrl = 0;
++
++ deWaitForNotBusy();
++
++ SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE,
++ FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS,
++ dst_base));
++
++ SMTC_write2Dreg(DE_WINDOW_SOURCE_BASE,
++ FIELD_VALUE(0, DE_WINDOW_SOURCE_BASE, ADDRESS,
++ src_base));
++
++ if (dst_pitch && src_pitch) {
++ SMTC_write2Dreg(DE_PITCH,
++ FIELD_VALUE(0, DE_PITCH, DESTINATION,
++ dst_pitch) | FIELD_VALUE(0,
++ DE_PITCH,
++ SOURCE,
++ src_pitch));
++
++ SMTC_write2Dreg(DE_WINDOW_WIDTH,
++ FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
++ dst_pitch) | FIELD_VALUE(0,
++ DE_WINDOW_WIDTH,
++ SOURCE,
++ src_pitch));
++ }
++
++ /* Set transparent bits if necessary */
++ if (pTransp != NULL) {
++ nTransparent =
++ pTransp->match | pTransp->select | pTransp->control;
++
++ /* Set color compare register */
++ SMTC_write2Dreg(DE_COLOR_COMPARE,
++ FIELD_VALUE(0, DE_COLOR_COMPARE, COLOR,
++ pTransp->color));
++ }
++
++ /* Determine direction of operation */
++ if (src_Y < dst_Y) {
++ /* +----------+
++ |S |
++ | +----------+
++ | | | |
++ | | | |
++ +---|------+ |
++ | D |
++ +----------+ */
++
++ nDirection = BOTTOM_TO_TOP;
++ } else if (src_Y > dst_Y) {
++ /* +----------+
++ |D |
++ | +----------+
++ | | | |
++ | | | |
++ +---|------+ |
++ | S |
++ +----------+ */
++
++ nDirection = TOP_TO_BOTTOM;
++ } else {
++ /* src_Y == dst_Y */
++
++ if (src_X <= dst_X) {
++ /* +------+---+------+
++ |S | | D|
++ | | | |
++ | | | |
++ | | | |
++ +------+---+------+ */
++
++ nDirection = RIGHT_TO_LEFT;
++ } else {
++ /* src_X > dst_X */
++
++ /* +------+---+------+
++ |D | | S|
++ | | | |
++ | | | |
++ | | | |
++ +------+---+------+ */
++
++ nDirection = LEFT_TO_RIGHT;
++ }
++ }
++
++ if ((nDirection == BOTTOM_TO_TOP) || (nDirection == RIGHT_TO_LEFT)) {
++ src_X += dst_width - 1;
++ src_Y += dst_height - 1;
++ dst_X += dst_width - 1;
++ dst_Y += dst_height - 1;
++ opSign = (-1);
++ }
++
++ if (dst_BPP >= 24) {
++ src_X *= 3;
++ src_Y *= 3;
++ dst_X *= 3;
++ dst_Y *= 3;
++ dst_width *= 3;
++ if ((nDirection == BOTTOM_TO_TOP)
++ || (nDirection == RIGHT_TO_LEFT)) {
++ src_X += 2;
++ dst_X += 2;
++ }
++ }
++
++ /* Workaround for 192 byte hw bug */
++ if ((nROP2 != 0x0C) && ((dst_width * (dst_BPP / 8)) >= 192)) {
++ /*
++ * Perform the ROP2 operation in chunks of (xWidth *
++ * dst_height)
++ */
++ while (1) {
++ deWaitForNotBusy();
++
++ SMTC_write2Dreg(DE_SOURCE,
++ FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) |
++ FIELD_VALUE(0, DE_SOURCE, X_K1, src_X) |
++ FIELD_VALUE(0, DE_SOURCE, Y_K2, src_Y));
++
++ SMTC_write2Dreg(DE_DESTINATION,
++ FIELD_SET(0, DE_DESTINATION, WRAP,
++ DISABLE) | FIELD_VALUE(0,
++ DE_DESTINATION,
++ X,
++ dst_X)
++ | FIELD_VALUE(0, DE_DESTINATION, Y,
++ dst_Y));
++
++ SMTC_write2Dreg(DE_DIMENSION,
++ FIELD_VALUE(0, DE_DIMENSION, X,
++ xWidth) | FIELD_VALUE(0,
++ DE_DIMENSION,
++ Y_ET,
++ dst_height));
++
++ de_ctrl =
++ FIELD_VALUE(0, DE_CONTROL, ROP,
++ nROP2) | nTransparent | FIELD_SET(0,
++ DE_CONTROL,
++ ROP_SELECT,
++ ROP2)
++ | FIELD_SET(0, DE_CONTROL, COMMAND,
++ BITBLT) | ((nDirection ==
++ 1) ? FIELD_SET(0,
++ DE_CONTROL,
++ DIRECTION,
++ RIGHT_TO_LEFT)
++ : FIELD_SET(0, DE_CONTROL,
++ DIRECTION,
++ LEFT_TO_RIGHT)) |
++ FIELD_SET(0, DE_CONTROL, STATUS, START);
++
++ SMTC_write2Dreg(DE_CONTROL, de_ctrl);
++
++ src_X += (opSign * xWidth);
++ dst_X += (opSign * xWidth);
++ dst_width -= xWidth;
++
++ if (dst_width <= 0) {
++ /* ROP2 operation is complete */
++ break;
++ }
++
++ if (xWidth > dst_width)
++ xWidth = dst_width;
++ }
++ } else {
++ deWaitForNotBusy();
++ SMTC_write2Dreg(DE_SOURCE,
++ FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) |
++ FIELD_VALUE(0, DE_SOURCE, X_K1, src_X) |
++ FIELD_VALUE(0, DE_SOURCE, Y_K2, src_Y));
++
++ SMTC_write2Dreg(DE_DESTINATION,
++ FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) |
++ FIELD_VALUE(0, DE_DESTINATION, X, dst_X) |
++ FIELD_VALUE(0, DE_DESTINATION, Y, dst_Y));
++
++ SMTC_write2Dreg(DE_DIMENSION,
++ FIELD_VALUE(0, DE_DIMENSION, X, dst_width) |
++ FIELD_VALUE(0, DE_DIMENSION, Y_ET, dst_height));
++
++ de_ctrl = FIELD_VALUE(0, DE_CONTROL, ROP, nROP2) |
++ nTransparent |
++ FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) |
++ FIELD_SET(0, DE_CONTROL, COMMAND, BITBLT) |
++ ((nDirection == 1) ? FIELD_SET(0, DE_CONTROL, DIRECTION,
++ RIGHT_TO_LEFT)
++ : FIELD_SET(0, DE_CONTROL, DIRECTION,
++ LEFT_TO_RIGHT)) | FIELD_SET(0, DE_CONTROL,
++ STATUS, START);
++ SMTC_write2Dreg(DE_CONTROL, de_ctrl);
++ }
++
++ smtc_de_busy = 1;
++}
++
++/*
++ * This function sets the pixel format that will apply to the 2D Engine.
++ */
++void deSetPixelFormat(unsigned long bpp)
++{
++ unsigned long de_format;
++
++ de_format = SMTC_read2Dreg(DE_STRETCH_FORMAT);
++
++ switch (bpp) {
++ case 8:
++ de_format =
++ FIELD_SET(de_format, DE_STRETCH_FORMAT, PIXEL_FORMAT, 8);
++ break;
++ default:
++ case 16:
++ de_format =
++ FIELD_SET(de_format, DE_STRETCH_FORMAT, PIXEL_FORMAT, 16);
++ break;
++ case 32:
++ de_format =
++ FIELD_SET(de_format, DE_STRETCH_FORMAT, PIXEL_FORMAT, 32);
++ break;
++ }
++
++ SMTC_write2Dreg(DE_STRETCH_FORMAT, de_format);
++}
++
++/*
++ * System memory to Video memory monochrome expansion.
++ *
++ * Source is monochrome image in system memory. This function expands the
++ * monochrome data to color image in video memory.
++ */
++
++long deSystemMem2VideoMemMonoBlt(const char *pSrcbuf,
++ long srcDelta,
++ unsigned long startBit,
++ unsigned long dBase,
++ unsigned long dPitch,
++ unsigned long bpp,
++ unsigned long dx, unsigned long dy,
++ unsigned long width, unsigned long height,
++ unsigned long fColor,
++ unsigned long bColor,
++ unsigned long rop2) {
++ unsigned long bytePerPixel;
++ unsigned long ulBytesPerScan;
++ unsigned long ul4BytesPerScan;
++ unsigned long ulBytesRemain;
++ unsigned long de_ctrl = 0;
++ unsigned char ajRemain[4];
++ long i, j;
++
++ bytePerPixel = bpp / 8;
++
++ /* Just make sure the start bit is within legal range */
++ startBit &= 7;
++
++ ulBytesPerScan = (width + startBit + 7) / 8;
++ ul4BytesPerScan = ulBytesPerScan & ~3;
++ ulBytesRemain = ulBytesPerScan & 3;
++
++ if (smtc_de_busy)
++ deWaitForNotBusy();
++
++ /*
++ * 2D Source Base. Use 0 for HOST Blt.
++ */
++
++ SMTC_write2Dreg(DE_WINDOW_SOURCE_BASE, 0);
++
++ /*
++ * 2D Destination Base.
++ *
++ * It is an address offset (128 bit aligned) from the beginning of
++ * frame buffer.
++ */
++
++ SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, dBase);
++
++ if (dPitch) {
++
++ /*
++ * Program pitch (distance between the 1st points of two
++ * adjacent lines).
++ *
++ * Note that input pitch is BYTE value, but the 2D Pitch
++ * register uses pixel values. Need Byte to pixel convertion.
++ */
++
++ SMTC_write2Dreg(DE_PITCH,
++ FIELD_VALUE(0, DE_PITCH, DESTINATION,
++ dPitch /
++ bytePerPixel) | FIELD_VALUE(0,
++ DE_PITCH,
++ SOURCE,
++ dPitch /
++ bytePerPixel));
++
++ /* Screen Window width in Pixels.
++ *
++ * 2D engine uses this value to calculate the linear address in
++ * frame buffer for a given point.
++ */
++
++ SMTC_write2Dreg(DE_WINDOW_WIDTH,
++ FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
++ (dPitch /
++ bytePerPixel)) | FIELD_VALUE(0,
++ DE_WINDOW_WIDTH,
++ SOURCE,
++ (dPitch
++ /
++ bytePerPixel)));
++ }
++ /* Note: For 2D Source in Host Write, only X_K1 field is needed, and
++ * Y_K2 field is not used. For mono bitmap, use startBit for X_K1.
++ */
++
++ SMTC_write2Dreg(DE_SOURCE,
++ FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) |
++ FIELD_VALUE(0, DE_SOURCE, X_K1, startBit) |
++ FIELD_VALUE(0, DE_SOURCE, Y_K2, 0));
++
++ SMTC_write2Dreg(DE_DESTINATION,
++ FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) |
++ FIELD_VALUE(0, DE_DESTINATION, X, dx) |
++ FIELD_VALUE(0, DE_DESTINATION, Y, dy));
++
++ SMTC_write2Dreg(DE_DIMENSION,
++ FIELD_VALUE(0, DE_DIMENSION, X, width) |
++ FIELD_VALUE(0, DE_DIMENSION, Y_ET, height));
++
++ SMTC_write2Dreg(DE_FOREGROUND, fColor);
++ SMTC_write2Dreg(DE_BACKGROUND, bColor);
++
++ if (bpp)
++ deSetPixelFormat(bpp);
++ /* Set the pixel format of the destination */
++
++ de_ctrl = FIELD_VALUE(0, DE_CONTROL, ROP, rop2) |
++ FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) |
++ FIELD_SET(0, DE_CONTROL, COMMAND, HOST_WRITE) |
++ FIELD_SET(0, DE_CONTROL, HOST, MONO) |
++ FIELD_SET(0, DE_CONTROL, STATUS, START);
++
++ SMTC_write2Dreg(DE_CONTROL, de_ctrl | deGetTransparency());
++
++ /* Write MONO data (line by line) to 2D Engine data port */
++ for (i = 0; i < height; i++) {
++ /* For each line, send the data in chunks of 4 bytes */
++ for (j = 0; j < (ul4BytesPerScan / 4); j++)
++ SMTC_write2Ddataport(0,
++ *(unsigned long *)(pSrcbuf +
++ (j * 4)));
++
++ if (ulBytesRemain) {
++ memcpy(ajRemain, pSrcbuf + ul4BytesPerScan,
++ ulBytesRemain);
++ SMTC_write2Ddataport(0, *(unsigned long *)ajRemain);
++ }
++
++ pSrcbuf += srcDelta;
++ }
++ smtc_de_busy = 1;
++
++ return 0;
++}
++
++/*
++ * This function gets the transparency status from DE_CONTROL register.
++ * It returns a double word with the transparent fields properly set,
++ * while other fields are 0.
++ */
++unsigned long deGetTransparency(void)
++{
++ unsigned long de_ctrl;
++
++ de_ctrl = SMTC_read2Dreg(DE_CONTROL);
++
++ de_ctrl &=
++ FIELD_MASK(DE_CONTROL_TRANSPARENCY_MATCH) |
++ FIELD_MASK(DE_CONTROL_TRANSPARENCY_SELECT) |
++ FIELD_MASK(DE_CONTROL_TRANSPARENCY);
++
++ return de_ctrl;
++}
+diff --git a/drivers/staging/sm7xx/smtc2d.h b/drivers/staging/sm7xx/smtc2d.h
+new file mode 100644
+index 0000000..38d0c33
+--- /dev/null
++++ b/drivers/staging/sm7xx/smtc2d.h
+@@ -0,0 +1,530 @@
++/*
++ * Silicon Motion SM712 2D drawing engine functions.
++ *
++ * Copyright (C) 2006 Silicon Motion Technology Corp.
++ * Author: Ge Wang, gewang@siliconmotion.com
++ *
++ * Copyright (C) 2009 Lemote, Inc.
++ * Author: Wu Zhangjin, wuzj@lemote.com
++ *
++ * 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 NULL
++#define NULL 0
++#endif
++
++/* Internal macros */
++
++#define _F_START(f) (0 ? f)
++#define _F_END(f) (1 ? f)
++#define _F_SIZE(f) (1 + _F_END(f) - _F_START(f))
++#define _F_MASK(f) (((1ULL << _F_SIZE(f)) - 1) << _F_START(f))
++#define _F_NORMALIZE(v, f) (((v) & _F_MASK(f)) >> _F_START(f))
++#define _F_DENORMALIZE(v, f) (((v) << _F_START(f)) & _F_MASK(f))
++
++/* Global macros */
++
++#define FIELD_GET(x, reg, field) \
++( \
++ _F_NORMALIZE((x), reg ## _ ## field) \
++)
++
++#define FIELD_SET(x, reg, field, value) \
++( \
++ (x & ~_F_MASK(reg ## _ ## field)) \
++ | _F_DENORMALIZE(reg ## _ ## field ## _ ## value, reg ## _ ## field) \
++)
++
++#define FIELD_VALUE(x, reg, field, value) \
++( \
++ (x & ~_F_MASK(reg ## _ ## field)) \
++ | _F_DENORMALIZE(value, reg ## _ ## field) \
++)
++
++#define FIELD_CLEAR(reg, field) \
++( \
++ ~_F_MASK(reg ## _ ## field) \
++)
++
++/* Field Macros */
++
++#define FIELD_START(field) (0 ? field)
++#define FIELD_END(field) (1 ? field)
++#define FIELD_SIZE(field) \
++ (1 + FIELD_END(field) - FIELD_START(field))
++
++#define FIELD_MASK(field) \
++ (((1 << (FIELD_SIZE(field)-1)) \
++ | ((1 << (FIELD_SIZE(field)-1)) - 1)) \
++ << FIELD_START(field))
++
++#define FIELD_NORMALIZE(reg, field) \
++ (((reg) & FIELD_MASK(field)) >> FIELD_START(field))
++
++#define FIELD_DENORMALIZE(field, value) \
++ (((value) << FIELD_START(field)) & FIELD_MASK(field))
++
++#define FIELD_INIT(reg, field, value) \
++ FIELD_DENORMALIZE(reg ## _ ## field, \
++ reg ## _ ## field ## _ ## value)
++
++#define FIELD_INIT_VAL(reg, field, value) \
++ (FIELD_DENORMALIZE(reg ## _ ## field, value))
++
++#define FIELD_VAL_SET(x, r, f, v) ({ \
++ x = (x & ~FIELD_MASK(r ## _ ## f)) \
++ | FIELD_DENORMALIZE(r ## _ ## f, r ## _ ## f ## _ ## v) \
++})
++
++#define RGB(r, g, b) ((unsigned long)(((r) << 16) | ((g) << 8) | (b)))
++
++/* Transparent info definition */
++typedef struct {
++ unsigned long match; /* Matching pixel is OPAQUE/TRANSPARENT */
++ unsigned long select; /* Transparency controlled by SRC/DST */
++ unsigned long control; /* ENABLE/DISABLE transparency */
++ unsigned long color; /* Transparent color */
++} Transparent, *pTransparent;
++
++#define PIXEL_DEPTH_1_BP 0 /* 1 bit per pixel */
++#define PIXEL_DEPTH_8_BPP 1 /* 8 bits per pixel */
++#define PIXEL_DEPTH_16_BPP 2 /* 16 bits per pixel */
++#define PIXEL_DEPTH_32_BPP 3 /* 32 bits per pixel */
++#define PIXEL_DEPTH_YUV422 8 /* 16 bits per pixel YUV422 */
++#define PIXEL_DEPTH_YUV420 9 /* 16 bits per pixel YUV420 */
++
++#define PATTERN_WIDTH 8
++#define PATTERN_HEIGHT 8
++
++#define TOP_TO_BOTTOM 0
++#define BOTTOM_TO_TOP 1
++#define RIGHT_TO_LEFT BOTTOM_TO_TOP
++#define LEFT_TO_RIGHT TOP_TO_BOTTOM
++
++/* Constants used in Transparent structure */
++#define MATCH_OPAQUE 0x00000000
++#define MATCH_TRANSPARENT 0x00000400
++#define SOURCE 0x00000000
++#define DESTINATION 0x00000200
++
++/* 2D registers. */
++
++#define DE_SOURCE 0x000000
++#define DE_SOURCE_WRAP 31 : 31
++#define DE_SOURCE_WRAP_DISABLE 0
++#define DE_SOURCE_WRAP_ENABLE 1
++#define DE_SOURCE_X_K1 29 : 16
++#define DE_SOURCE_Y_K2 15 : 0
++
++#define DE_DESTINATION 0x000004
++#define DE_DESTINATION_WRAP 31 : 31
++#define DE_DESTINATION_WRAP_DISABLE 0
++#define DE_DESTINATION_WRAP_ENABLE 1
++#define DE_DESTINATION_X 28 : 16
++#define DE_DESTINATION_Y 15 : 0
++
++#define DE_DIMENSION 0x000008
++#define DE_DIMENSION_X 28 : 16
++#define DE_DIMENSION_Y_ET 15 : 0
++
++#define DE_CONTROL 0x00000C
++#define DE_CONTROL_STATUS 31 : 31
++#define DE_CONTROL_STATUS_STOP 0
++#define DE_CONTROL_STATUS_START 1
++#define DE_CONTROL_PATTERN 30 : 30
++#define DE_CONTROL_PATTERN_MONO 0
++#define DE_CONTROL_PATTERN_COLOR 1
++#define DE_CONTROL_UPDATE_DESTINATION_X 29 : 29
++#define DE_CONTROL_UPDATE_DESTINATION_X_DISABLE 0
++#define DE_CONTROL_UPDATE_DESTINATION_X_ENABLE 1
++#define DE_CONTROL_QUICK_START 28 : 28
++#define DE_CONTROL_QUICK_START_DISABLE 0
++#define DE_CONTROL_QUICK_START_ENABLE 1
++#define DE_CONTROL_DIRECTION 27 : 27
++#define DE_CONTROL_DIRECTION_LEFT_TO_RIGHT 0
++#define DE_CONTROL_DIRECTION_RIGHT_TO_LEFT 1
++#define DE_CONTROL_MAJOR 26 : 26
++#define DE_CONTROL_MAJOR_X 0
++#define DE_CONTROL_MAJOR_Y 1
++#define DE_CONTROL_STEP_X 25 : 25
++#define DE_CONTROL_STEP_X_POSITIVE 1
++#define DE_CONTROL_STEP_X_NEGATIVE 0
++#define DE_CONTROL_STEP_Y 24 : 24
++#define DE_CONTROL_STEP_Y_POSITIVE 1
++#define DE_CONTROL_STEP_Y_NEGATIVE 0
++#define DE_CONTROL_STRETCH 23 : 23
++#define DE_CONTROL_STRETCH_DISABLE 0
++#define DE_CONTROL_STRETCH_ENABLE 1
++#define DE_CONTROL_HOST 22 : 22
++#define DE_CONTROL_HOST_COLOR 0
++#define DE_CONTROL_HOST_MONO 1
++#define DE_CONTROL_LAST_PIXEL 21 : 21
++#define DE_CONTROL_LAST_PIXEL_OFF 0
++#define DE_CONTROL_LAST_PIXEL_ON 1
++#define DE_CONTROL_COMMAND 20 : 16
++#define DE_CONTROL_COMMAND_BITBLT 0
++#define DE_CONTROL_COMMAND_RECTANGLE_FILL 1
++#define DE_CONTROL_COMMAND_DE_TILE 2
++#define DE_CONTROL_COMMAND_TRAPEZOID_FILL 3
++#define DE_CONTROL_COMMAND_ALPHA_BLEND 4
++#define DE_CONTROL_COMMAND_RLE_STRIP 5
++#define DE_CONTROL_COMMAND_SHORT_STROKE 6
++#define DE_CONTROL_COMMAND_LINE_DRAW 7
++#define DE_CONTROL_COMMAND_HOST_WRITE 8
++#define DE_CONTROL_COMMAND_HOST_READ 9
++#define DE_CONTROL_COMMAND_HOST_WRITE_BOTTOM_UP 10
++#define DE_CONTROL_COMMAND_ROTATE 11
++#define DE_CONTROL_COMMAND_FONT 12
++#define DE_CONTROL_COMMAND_TEXTURE_LOAD 15
++#define DE_CONTROL_ROP_SELECT 15 : 15
++#define DE_CONTROL_ROP_SELECT_ROP3 0
++#define DE_CONTROL_ROP_SELECT_ROP2 1
++#define DE_CONTROL_ROP2_SOURCE 14 : 14
++#define DE_CONTROL_ROP2_SOURCE_BITMAP 0
++#define DE_CONTROL_ROP2_SOURCE_PATTERN 1
++#define DE_CONTROL_MONO_DATA 13 : 12
++#define DE_CONTROL_MONO_DATA_NOT_PACKED 0
++#define DE_CONTROL_MONO_DATA_8_PACKED 1
++#define DE_CONTROL_MONO_DATA_16_PACKED 2
++#define DE_CONTROL_MONO_DATA_32_PACKED 3
++#define DE_CONTROL_REPEAT_ROTATE 11 : 11
++#define DE_CONTROL_REPEAT_ROTATE_DISABLE 0
++#define DE_CONTROL_REPEAT_ROTATE_ENABLE 1
++#define DE_CONTROL_TRANSPARENCY_MATCH 10 : 10
++#define DE_CONTROL_TRANSPARENCY_MATCH_OPAQUE 0
++#define DE_CONTROL_TRANSPARENCY_MATCH_TRANSPARENT 1
++#define DE_CONTROL_TRANSPARENCY_SELECT 9 : 9
++#define DE_CONTROL_TRANSPARENCY_SELECT_SOURCE 0
++#define DE_CONTROL_TRANSPARENCY_SELECT_DESTINATION 1
++#define DE_CONTROL_TRANSPARENCY 8 : 8
++#define DE_CONTROL_TRANSPARENCY_DISABLE 0
++#define DE_CONTROL_TRANSPARENCY_ENABLE 1
++#define DE_CONTROL_ROP 7 : 0
++
++/* Pseudo fields. */
++
++#define DE_CONTROL_SHORT_STROKE_DIR 27 : 24
++#define DE_CONTROL_SHORT_STROKE_DIR_225 0
++#define DE_CONTROL_SHORT_STROKE_DIR_135 1
++#define DE_CONTROL_SHORT_STROKE_DIR_315 2
++#define DE_CONTROL_SHORT_STROKE_DIR_45 3
++#define DE_CONTROL_SHORT_STROKE_DIR_270 4
++#define DE_CONTROL_SHORT_STROKE_DIR_90 5
++#define DE_CONTROL_SHORT_STROKE_DIR_180 8
++#define DE_CONTROL_SHORT_STROKE_DIR_0 10
++#define DE_CONTROL_ROTATION 25 : 24
++#define DE_CONTROL_ROTATION_0 0
++#define DE_CONTROL_ROTATION_270 1
++#define DE_CONTROL_ROTATION_90 2
++#define DE_CONTROL_ROTATION_180 3
++
++#define DE_PITCH 0x000010
++#define DE_PITCH_DESTINATION 28 : 16
++#define DE_PITCH_SOURCE 12 : 0
++
++#define DE_FOREGROUND 0x000014
++#define DE_FOREGROUND_COLOR 31 : 0
++
++#define DE_BACKGROUND 0x000018
++#define DE_BACKGROUND_COLOR 31 : 0
++
++#define DE_STRETCH_FORMAT 0x00001C
++#define DE_STRETCH_FORMAT_PATTERN_XY 30 : 30
++#define DE_STRETCH_FORMAT_PATTERN_XY_NORMAL 0
++#define DE_STRETCH_FORMAT_PATTERN_XY_OVERWRITE 1
++#define DE_STRETCH_FORMAT_PATTERN_Y 29 : 27
++#define DE_STRETCH_FORMAT_PATTERN_X 25 : 23
++#define DE_STRETCH_FORMAT_PIXEL_FORMAT 21 : 20
++#define DE_STRETCH_FORMAT_PIXEL_FORMAT_8 0
++#define DE_STRETCH_FORMAT_PIXEL_FORMAT_16 1
++#define DE_STRETCH_FORMAT_PIXEL_FORMAT_24 3
++#define DE_STRETCH_FORMAT_PIXEL_FORMAT_32 2
++#define DE_STRETCH_FORMAT_ADDRESSING 19 : 16
++#define DE_STRETCH_FORMAT_ADDRESSING_XY 0
++#define DE_STRETCH_FORMAT_ADDRESSING_LINEAR 15
++#define DE_STRETCH_FORMAT_SOURCE_HEIGHT 11 : 0
++
++#define DE_COLOR_COMPARE 0x000020
++#define DE_COLOR_COMPARE_COLOR 23 : 0
++
++#define DE_COLOR_COMPARE_MASK 0x000024
++#define DE_COLOR_COMPARE_MASK_MASKS 23 : 0
++
++#define DE_MASKS 0x000028
++#define DE_MASKS_BYTE_MASK 31 : 16
++#define DE_MASKS_BIT_MASK 15 : 0
++
++#define DE_CLIP_TL 0x00002C
++#define DE_CLIP_TL_TOP 31 : 16
++#define DE_CLIP_TL_STATUS 13 : 13
++#define DE_CLIP_TL_STATUS_DISABLE 0
++#define DE_CLIP_TL_STATUS_ENABLE 1
++#define DE_CLIP_TL_INHIBIT 12 : 12
++#define DE_CLIP_TL_INHIBIT_OUTSIDE 0
++#define DE_CLIP_TL_INHIBIT_INSIDE 1
++#define DE_CLIP_TL_LEFT 11 : 0
++
++#define DE_CLIP_BR 0x000030
++#define DE_CLIP_BR_BOTTOM 31 : 16
++#define DE_CLIP_BR_RIGHT 12 : 0
++
++#define DE_MONO_PATTERN_LOW 0x000034
++#define DE_MONO_PATTERN_LOW_PATTERN 31 : 0
++
++#define DE_MONO_PATTERN_HIGH 0x000038
++#define DE_MONO_PATTERN_HIGH_PATTERN 31 : 0
++
++#define DE_WINDOW_WIDTH 0x00003C
++#define DE_WINDOW_WIDTH_DESTINATION 28 : 16
++#define DE_WINDOW_WIDTH_SOURCE 12 : 0
++
++#define DE_WINDOW_SOURCE_BASE 0x000040
++#define DE_WINDOW_SOURCE_BASE_EXT 27 : 27
++#define DE_WINDOW_SOURCE_BASE_EXT_LOCAL 0
++#define DE_WINDOW_SOURCE_BASE_EXT_EXTERNAL 1
++#define DE_WINDOW_SOURCE_BASE_CS 26 : 26
++#define DE_WINDOW_SOURCE_BASE_CS_0 0
++#define DE_WINDOW_SOURCE_BASE_CS_1 1
++#define DE_WINDOW_SOURCE_BASE_ADDRESS 25 : 0
++
++#define DE_WINDOW_DESTINATION_BASE 0x000044
++#define DE_WINDOW_DESTINATION_BASE_EXT 27 : 27
++#define DE_WINDOW_DESTINATION_BASE_EXT_LOCAL 0
++#define DE_WINDOW_DESTINATION_BASE_EXT_EXTERNAL 1
++#define DE_WINDOW_DESTINATION_BASE_CS 26 : 26
++#define DE_WINDOW_DESTINATION_BASE_CS_0 0
++#define DE_WINDOW_DESTINATION_BASE_CS_1 1
++#define DE_WINDOW_DESTINATION_BASE_ADDRESS 25 : 0
++
++#define DE_ALPHA 0x000048
++#define DE_ALPHA_VALUE 7 : 0
++
++#define DE_WRAP 0x00004C
++#define DE_WRAP_X 31 : 16
++#define DE_WRAP_Y 15 : 0
++
++#define DE_STATUS 0x000050
++#define DE_STATUS_CSC 1 : 1
++#define DE_STATUS_CSC_CLEAR 0
++#define DE_STATUS_CSC_NOT_ACTIVE 0
++#define DE_STATUS_CSC_ACTIVE 1
++#define DE_STATUS_2D 0 : 0
++#define DE_STATUS_2D_CLEAR 0
++#define DE_STATUS_2D_NOT_ACTIVE 0
++#define DE_STATUS_2D_ACTIVE 1
++
++/* Color Space Conversion registers. */
++
++#define CSC_Y_SOURCE_BASE 0x0000C8
++#define CSC_Y_SOURCE_BASE_EXT 27 : 27
++#define CSC_Y_SOURCE_BASE_EXT_LOCAL 0
++#define CSC_Y_SOURCE_BASE_EXT_EXTERNAL 1
++#define CSC_Y_SOURCE_BASE_CS 26 : 26
++#define CSC_Y_SOURCE_BASE_CS_0 0
++#define CSC_Y_SOURCE_BASE_CS_1 1
++#define CSC_Y_SOURCE_BASE_ADDRESS 25 : 0
++
++#define CSC_CONSTANTS 0x0000CC
++#define CSC_CONSTANTS_Y 31 : 24
++#define CSC_CONSTANTS_R 23 : 16
++#define CSC_CONSTANTS_G 15 : 8
++#define CSC_CONSTANTS_B 7 : 0
++
++#define CSC_Y_SOURCE_X 0x0000D0
++#define CSC_Y_SOURCE_X_INTEGER 26 : 16
++#define CSC_Y_SOURCE_X_FRACTION 15 : 3
++
++#define CSC_Y_SOURCE_Y 0x0000D4
++#define CSC_Y_SOURCE_Y_INTEGER 27 : 16
++#define CSC_Y_SOURCE_Y_FRACTION 15 : 3
++
++#define CSC_U_SOURCE_BASE 0x0000D8
++#define CSC_U_SOURCE_BASE_EXT 27 : 27
++#define CSC_U_SOURCE_BASE_EXT_LOCAL 0
++#define CSC_U_SOURCE_BASE_EXT_EXTERNAL 1
++#define CSC_U_SOURCE_BASE_CS 26 : 26
++#define CSC_U_SOURCE_BASE_CS_0 0
++#define CSC_U_SOURCE_BASE_CS_1 1
++#define CSC_U_SOURCE_BASE_ADDRESS 25 : 0
++
++#define CSC_V_SOURCE_BASE 0x0000DC
++#define CSC_V_SOURCE_BASE_EXT 27 : 27
++#define CSC_V_SOURCE_BASE_EXT_LOCAL 0
++#define CSC_V_SOURCE_BASE_EXT_EXTERNAL 1
++#define CSC_V_SOURCE_BASE_CS 26 : 26
++#define CSC_V_SOURCE_BASE_CS_0 0
++#define CSC_V_SOURCE_BASE_CS_1 1
++#define CSC_V_SOURCE_BASE_ADDRESS 25 : 0
++
++#define CSC_SOURCE_DIMENSION 0x0000E0
++#define CSC_SOURCE_DIMENSION_X 31 : 16
++#define CSC_SOURCE_DIMENSION_Y 15 : 0
++
++#define CSC_SOURCE_PITCH 0x0000E4
++#define CSC_SOURCE_PITCH_Y 31 : 16
++#define CSC_SOURCE_PITCH_UV 15 : 0
++
++#define CSC_DESTINATION 0x0000E8
++#define CSC_DESTINATION_WRAP 31 : 31
++#define CSC_DESTINATION_WRAP_DISABLE 0
++#define CSC_DESTINATION_WRAP_ENABLE 1
++#define CSC_DESTINATION_X 27 : 16
++#define CSC_DESTINATION_Y 11 : 0
++
++#define CSC_DESTINATION_DIMENSION 0x0000EC
++#define CSC_DESTINATION_DIMENSION_X 31 : 16
++#define CSC_DESTINATION_DIMENSION_Y 15 : 0
++
++#define CSC_DESTINATION_PITCH 0x0000F0
++#define CSC_DESTINATION_PITCH_X 31 : 16
++#define CSC_DESTINATION_PITCH_Y 15 : 0
++
++#define CSC_SCALE_FACTOR 0x0000F4
++#define CSC_SCALE_FACTOR_HORIZONTAL 31 : 16
++#define CSC_SCALE_FACTOR_VERTICAL 15 : 0
++
++#define CSC_DESTINATION_BASE 0x0000F8
++#define CSC_DESTINATION_BASE_EXT 27 : 27
++#define CSC_DESTINATION_BASE_EXT_LOCAL 0
++#define CSC_DESTINATION_BASE_EXT_EXTERNAL 1
++#define CSC_DESTINATION_BASE_CS 26 : 26
++#define CSC_DESTINATION_BASE_CS_0 0
++#define CSC_DESTINATION_BASE_CS_1 1
++#define CSC_DESTINATION_BASE_ADDRESS 25 : 0
++
++#define CSC_CONTROL 0x0000FC
++#define CSC_CONTROL_STATUS 31 : 31
++#define CSC_CONTROL_STATUS_STOP 0
++#define CSC_CONTROL_STATUS_START 1
++#define CSC_CONTROL_SOURCE_FORMAT 30 : 28
++#define CSC_CONTROL_SOURCE_FORMAT_YUV422 0
++#define CSC_CONTROL_SOURCE_FORMAT_YUV420I 1
++#define CSC_CONTROL_SOURCE_FORMAT_YUV420 2
++#define CSC_CONTROL_SOURCE_FORMAT_YVU9 3
++#define CSC_CONTROL_SOURCE_FORMAT_IYU1 4
++#define CSC_CONTROL_SOURCE_FORMAT_IYU2 5
++#define CSC_CONTROL_SOURCE_FORMAT_RGB565 6
++#define CSC_CONTROL_SOURCE_FORMAT_RGB8888 7
++#define CSC_CONTROL_DESTINATION_FORMAT 27 : 26
++#define CSC_CONTROL_DESTINATION_FORMAT_RGB565 0
++#define CSC_CONTROL_DESTINATION_FORMAT_RGB8888 1
++#define CSC_CONTROL_HORIZONTAL_FILTER 25 : 25
++#define CSC_CONTROL_HORIZONTAL_FILTER_DISABLE 0
++#define CSC_CONTROL_HORIZONTAL_FILTER_ENABLE 1
++#define CSC_CONTROL_VERTICAL_FILTER 24 : 24
++#define CSC_CONTROL_VERTICAL_FILTER_DISABLE 0
++#define CSC_CONTROL_VERTICAL_FILTER_ENABLE 1
++#define CSC_CONTROL_BYTE_ORDER 23 : 23
++#define CSC_CONTROL_BYTE_ORDER_YUYV 0
++#define CSC_CONTROL_BYTE_ORDER_UYVY 1
++
++#define DE_DATA_PORT_501 0x110000
++#define DE_DATA_PORT_712 0x400000
++#define DE_DATA_PORT_722 0x6000
++
++/* point to virtual Memory Map IO starting address */
++extern char *smtc_RegBaseAddress;
++/* point to virtual video memory starting address */
++extern char *smtc_VRAMBaseAddress;
++extern unsigned char smtc_de_busy;
++
++extern unsigned long memRead32(unsigned long nOffset);
++extern void memWrite32(unsigned long nOffset, unsigned long nData);
++extern unsigned long SMTC_read2Dreg(unsigned long nOffset);
++
++/* 2D functions */
++extern void deInit(unsigned int nModeWidth, unsigned int nModeHeight,
++ unsigned int bpp);
++
++extern void deWaitForNotBusy(void);
++
++extern void deVerticalLine(unsigned long dst_base,
++ unsigned long dst_pitch,
++ unsigned long nX,
++ unsigned long nY,
++ unsigned long dst_height,
++ unsigned long nColor);
++
++extern void deHorizontalLine(unsigned long dst_base,
++ unsigned long dst_pitch,
++ unsigned long nX,
++ unsigned long nY,
++ unsigned long dst_width,
++ unsigned long nColor);
++
++extern void deLine(unsigned long dst_base,
++ unsigned long dst_pitch,
++ unsigned long nX1,
++ unsigned long nY1,
++ unsigned long nX2,
++ unsigned long nY2,
++ unsigned long nColor);
++
++extern void deFillRect(unsigned long dst_base,
++ unsigned long dst_pitch,
++ unsigned long dst_X,
++ unsigned long dst_Y,
++ unsigned long dst_width,
++ unsigned long dst_height,
++ unsigned long nColor);
++
++extern void deRotatePattern(unsigned char *pattern_dstaddr,
++ unsigned long pattern_src_addr,
++ unsigned long pattern_BPP,
++ unsigned long pattern_stride,
++ int patternX,
++ int patternY);
++
++extern void deCopy(unsigned long dst_base,
++ unsigned long dst_pitch,
++ unsigned long dst_BPP,
++ unsigned long dst_X,
++ unsigned long dst_Y,
++ unsigned long dst_width,
++ unsigned long dst_height,
++ unsigned long src_base,
++ unsigned long src_pitch,
++ unsigned long src_X,
++ unsigned long src_Y,
++ pTransparent pTransp,
++ unsigned char nROP2);
++
++/*
++ * System memory to Video memory monochrome expansion.
++ *
++ * Source is monochrome image in system memory. This function expands the
++ * monochrome data to color image in video memory.
++ *
++ * @pSrcbuf: pointer to start of source buffer in system memory
++ * @srcDelta: Pitch value (in bytes) of the source buffer, +ive means top
++ * down and -ive mean button up
++ * @startBit: Mono data can start at any bit in a byte, this value should
++ * be 0 to 7
++ * @dBase: Address of destination : offset in frame buffer
++ * @dPitch: Pitch value of destination surface in BYTE
++ * @bpp: Color depth of destination surface
++ * @dx, dy: Starting coordinate of destination surface
++ * @width, height: width and height of rectange in pixel value
++ * @fColor,bColor: Foreground, Background color (corresponding to a 1, 0 in
++ * the monochrome data)
++ * @rop2: ROP value
++ */
++
++extern long deSystemMem2VideoMemMonoBlt(
++ const char *pSrcbuf,
++ long srcDelta,
++ unsigned long startBit,
++ unsigned long dBase,
++ unsigned long dPitch,
++ unsigned long bpp,
++ unsigned long dx, unsigned long dy,
++ unsigned long width, unsigned long height,
++ unsigned long fColor,
++ unsigned long bColor,
++ unsigned long rop2);
++
++extern unsigned long deGetTransparency(void);
++extern void deSetPixelFormat(unsigned long bpp);
+diff --git a/drivers/staging/sm7xx/smtcfb.c b/drivers/staging/sm7xx/smtcfb.c
+new file mode 100644
+index 0000000..f5d500c
+--- /dev/null
++++ b/drivers/staging/sm7xx/smtcfb.c
+@@ -0,0 +1,1254 @@
++/*
++ * Silicon Motion SM7XX frame buffer device
++ *
++ * Copyright (C) 2006 Silicon Motion Technology Corp.
++ * Authors: Ge Wang, gewang@siliconmotion.com
++ * Boyod boyod.yang@siliconmotion.com.cn
++ *
++ * Copyright (C) 2009 Lemote, Inc.
++ * Author: Wu Zhangjin, wuzj@lemote.com
++ *
++ * 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.
++ *
++ * Version 0.10.26192.21.01
++ * - Add PowerPC/Big endian support
++ * - Add 2D support for Lynx
++ * - Verified on2.6.19.2 Boyod.yang <boyod.yang@siliconmotion.com.cn>
++ *
++ * Version 0.09.2621.00.01
++ * - Only support Linux Kernel's version 2.6.21.
++ * Boyod.yang <boyod.yang@siliconmotion.com.cn>
++ *
++ * Version 0.09
++ * - Only support Linux Kernel's version 2.6.12.
++ * Boyod.yang <boyod.yang@siliconmotion.com.cn>
++ */
++
++#ifndef __KERNEL__
++#define __KERNEL__
++#endif
++
++#include <linux/io.h>
++#include <linux/fb.h>
++#include <linux/pci.h>
++#include <linux/init.h>
++#include <linux/uaccess.h>
++#include <linux/console.h>
++#include <linux/screen_info.h>
++
++#ifdef CONFIG_PM
++#include <linux/pm.h>
++#endif
++
++struct screen_info smtc_screen_info;
++
++#include "smtcfb.h"
++#include "smtc2d.h"
++
++#ifdef DEBUG
++#define smdbg(format, arg...) printk(KERN_DEBUG format , ## arg)
++#else
++#define smdbg(format, arg...)
++#endif
++
++/*
++* Private structure
++*/
++struct smtcfb_info {
++ /*
++ * The following is a pointer to be passed into the
++ * functions below. The modules outside the main
++ * voyager.c driver have no knowledge as to what
++ * is within this structure.
++ */
++ struct fb_info fb;
++ struct display_switch *dispsw;
++ struct pci_dev *dev;
++ signed int currcon;
++
++ struct {
++ u8 red, green, blue;
++ } palette[NR_RGB];
++
++ u_int palette_size;
++};
++
++struct par_info {
++ /*
++ * Hardware
++ */
++ u16 chipID;
++ unsigned char __iomem *m_pMMIO;
++ char __iomem *m_pLFB;
++ char *m_pDPR;
++ char *m_pVPR;
++ char *m_pCPR;
++
++ u_int width;
++ u_int height;
++ u_int hz;
++ u_long BaseAddressInVRAM;
++ u8 chipRevID;
++};
++
++struct vesa_mode_table {
++ char mode_index[6];
++ u16 lfb_width;
++ u16 lfb_height;
++ u16 lfb_depth;
++};
++
++static struct vesa_mode_table vesa_mode[] = {
++ {"0x301", 640, 480, 8},
++ {"0x303", 800, 600, 8},
++ {"0x305", 1024, 768, 8},
++ {"0x307", 1280, 1024, 8},
++
++ {"0x311", 640, 480, 16},
++ {"0x313", 800, 480, 16},
++ {"0x314", 800, 600, 16},
++ {"0x317", 1024, 768, 16},
++ {"0x31A", 1280, 1024, 16},
++
++ {"0x312", 640, 480, 24},
++ {"0x315", 800, 600, 24},
++ {"0x318", 1024, 768, 24},
++ {"0x31B", 1280, 1024, 24},
++};
++
++char __iomem *smtc_RegBaseAddress; /* Memory Map IO starting address */
++char __iomem *smtc_VRAMBaseAddress; /* video memory starting address */
++
++char *smtc_2DBaseAddress; /* 2D engine starting address */
++char *smtc_2Ddataport; /* 2D data port offset */
++short smtc_2Dacceleration;
++
++static u32 colreg[17];
++static struct par_info hw; /* hardware information */
++
++u16 smtc_ChipIDs[] = {
++ 0x710,
++ 0x712,
++ 0x720
++};
++
++#define numSMTCchipIDs (sizeof(smtc_ChipIDs) / sizeof(u16))
++
++void deWaitForNotBusy(void)
++{
++ unsigned long i = 0x1000000;
++ while (i--) {
++ if ((smtc_seqr(0x16) & 0x18) == 0x10)
++ break;
++ }
++ smtc_de_busy = 0;
++}
++
++static void sm712_set_timing(struct smtcfb_info *sfb,
++ struct par_info *ppar_info)
++{
++ int i = 0, j = 0;
++ u32 m_nScreenStride;
++
++ smdbg("\nppar_info->width = %d ppar_info->height = %d"
++ "sfb->fb.var.bits_per_pixel = %d ppar_info->hz = %d\n",
++ ppar_info->width, ppar_info->height,
++ sfb->fb.var.bits_per_pixel, ppar_info->hz);
++
++ for (j = 0; j < numVGAModes; j++) {
++ if (VGAMode[j].mmSizeX == ppar_info->width &&
++ VGAMode[j].mmSizeY == ppar_info->height &&
++ VGAMode[j].bpp == sfb->fb.var.bits_per_pixel &&
++ VGAMode[j].hz == ppar_info->hz) {
++
++ smdbg("\nVGAMode[j].mmSizeX = %d VGAMode[j].mmSizeY ="
++ "%d VGAMode[j].bpp = %d"
++ "VGAMode[j].hz=%d\n",
++ VGAMode[j].mmSizeX, VGAMode[j].mmSizeY,
++ VGAMode[j].bpp, VGAMode[j].hz);
++
++ smdbg("VGAMode index=%d\n", j);
++
++ smtc_mmiowb(0x0, 0x3c6);
++
++ smtc_seqw(0, 0x1);
++
++ smtc_mmiowb(VGAMode[j].Init_MISC, 0x3c2);
++
++ /* init SEQ register SR00 - SR04 */
++ for (i = 0; i < SIZE_SR00_SR04; i++)
++ smtc_seqw(i, VGAMode[j].Init_SR00_SR04[i]);
++
++ /* init SEQ register SR10 - SR24 */
++ for (i = 0; i < SIZE_SR10_SR24; i++)
++ smtc_seqw(i + 0x10,
++ VGAMode[j].Init_SR10_SR24[i]);
++
++ /* init SEQ register SR30 - SR75 */
++ for (i = 0; i < SIZE_SR30_SR75; i++)
++ if (((i + 0x30) != 0x62) \
++ && ((i + 0x30) != 0x6a) \
++ && ((i + 0x30) != 0x6b))
++ smtc_seqw(i + 0x30,
++ VGAMode[j].Init_SR30_SR75[i]);
++
++ /* init SEQ register SR80 - SR93 */
++ for (i = 0; i < SIZE_SR80_SR93; i++)
++ smtc_seqw(i + 0x80,
++ VGAMode[j].Init_SR80_SR93[i]);
++
++ /* init SEQ register SRA0 - SRAF */
++ for (i = 0; i < SIZE_SRA0_SRAF; i++)
++ smtc_seqw(i + 0xa0,
++ VGAMode[j].Init_SRA0_SRAF[i]);
++
++ /* init Graphic register GR00 - GR08 */
++ for (i = 0; i < SIZE_GR00_GR08; i++)
++ smtc_grphw(i, VGAMode[j].Init_GR00_GR08[i]);
++
++ /* init Attribute register AR00 - AR14 */
++ for (i = 0; i < SIZE_AR00_AR14; i++)
++ smtc_attrw(i, VGAMode[j].Init_AR00_AR14[i]);
++
++ /* init CRTC register CR00 - CR18 */
++ for (i = 0; i < SIZE_CR00_CR18; i++)
++ smtc_crtcw(i, VGAMode[j].Init_CR00_CR18[i]);
++
++ /* init CRTC register CR30 - CR4D */
++ for (i = 0; i < SIZE_CR30_CR4D; i++)
++ smtc_crtcw(i + 0x30,
++ VGAMode[j].Init_CR30_CR4D[i]);
++
++ /* init CRTC register CR90 - CRA7 */
++ for (i = 0; i < SIZE_CR90_CRA7; i++)
++ smtc_crtcw(i + 0x90,
++ VGAMode[j].Init_CR90_CRA7[i]);
++ }
++ }
++ smtc_mmiowb(0x67, 0x3c2);
++
++ /* set VPR registers */
++ writel(0x0, ppar_info->m_pVPR + 0x0C);
++ writel(0x0, ppar_info->m_pVPR + 0x40);
++
++ /* set data width */
++ m_nScreenStride =
++ (ppar_info->width * sfb->fb.var.bits_per_pixel) / 64;
++ switch (sfb->fb.var.bits_per_pixel) {
++ case 8:
++ writel(0x0, ppar_info->m_pVPR + 0x0);
++ break;
++ case 16:
++ writel(0x00020000, ppar_info->m_pVPR + 0x0);
++ break;
++ case 24:
++ writel(0x00040000, ppar_info->m_pVPR + 0x0);
++ break;
++ case 32:
++ writel(0x00030000, ppar_info->m_pVPR + 0x0);
++ break;
++ }
++ writel((u32) (((m_nScreenStride + 2) << 16) | m_nScreenStride),
++ ppar_info->m_pVPR + 0x10);
++
++}
++
++static void sm712_setpalette(int regno, unsigned red, unsigned green,
++ unsigned blue, struct fb_info *info)
++{
++ struct par_info *cur_par = (struct par_info *)info->par;
++
++ if (cur_par->BaseAddressInVRAM)
++ /*
++ * second display palette for dual head. Enable CRT RAM, 6-bit
++ * RAM
++ */
++ smtc_seqw(0x66, (smtc_seqr(0x66) & 0xC3) | 0x20);
++ else
++ /* primary display palette. Enable LCD RAM only, 6-bit RAM */
++ smtc_seqw(0x66, (smtc_seqr(0x66) & 0xC3) | 0x10);
++ smtc_mmiowb(regno, dac_reg);
++ smtc_mmiowb(red >> 10, dac_val);
++ smtc_mmiowb(green >> 10, dac_val);
++ smtc_mmiowb(blue >> 10, dac_val);
++}
++
++static void smtc_set_timing(struct smtcfb_info *sfb, struct par_info
++ *ppar_info)
++{
++ switch (ppar_info->chipID) {
++ case 0x710:
++ case 0x712:
++ case 0x720:
++ sm712_set_timing(sfb, ppar_info);
++ break;
++ }
++}
++
++static struct fb_var_screeninfo smtcfb_var = {
++ .xres = 1024,
++ .yres = 600,
++ .xres_virtual = 1024,
++ .yres_virtual = 600,
++ .bits_per_pixel = 16,
++ .red = {16, 8, 0},
++ .green = {8, 8, 0},
++ .blue = {0, 8, 0},
++ .activate = FB_ACTIVATE_NOW,
++ .height = -1,
++ .width = -1,
++ .vmode = FB_VMODE_NONINTERLACED,
++};
++
++static struct fb_fix_screeninfo smtcfb_fix = {
++ .id = "sm712fb",
++ .type = FB_TYPE_PACKED_PIXELS,
++ .visual = FB_VISUAL_TRUECOLOR,
++ .line_length = 800 * 3,
++ .accel = FB_ACCEL_SMI_LYNX,
++};
++
++/* chan_to_field
++ *
++ * convert a colour value into a field position
++ *
++ * from pxafb.c
++ */
++
++static inline unsigned int chan_to_field(unsigned int chan,
++ struct fb_bitfield *bf)
++{
++ chan &= 0xffff;
++ chan >>= 16 - bf->length;
++ return chan << bf->offset;
++}
++
++static int smtcfb_blank(int blank_mode, struct fb_info *info)
++{
++ /* clear DPMS setting */
++ switch (blank_mode) {
++ case FB_BLANK_UNBLANK:
++ /* Screen On: HSync: On, VSync : On */
++ smtc_seqw(0x01, (smtc_seqr(0x01) & (~0x20)));
++ smtc_seqw(0x6a, 0x16);
++ smtc_seqw(0x6b, 0x02);
++ smtc_seqw(0x21, (smtc_seqr(0x21) & 0x77));
++ smtc_seqw(0x22, (smtc_seqr(0x22) & (~0x30)));
++ smtc_seqw(0x23, (smtc_seqr(0x23) & (~0xc0)));
++ smtc_seqw(0x24, (smtc_seqr(0x24) | 0x01));
++ smtc_seqw(0x31, (smtc_seqr(0x31) | 0x03));
++ break;
++ case FB_BLANK_NORMAL:
++ /* Screen Off: HSync: On, VSync : On Soft blank */
++ smtc_seqw(0x01, (smtc_seqr(0x01) & (~0x20)));
++ smtc_seqw(0x6a, 0x16);
++ smtc_seqw(0x6b, 0x02);
++ smtc_seqw(0x22, (smtc_seqr(0x22) & (~0x30)));
++ smtc_seqw(0x23, (smtc_seqr(0x23) & (~0xc0)));
++ smtc_seqw(0x24, (smtc_seqr(0x24) | 0x01));
++ smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
++ break;
++ case FB_BLANK_VSYNC_SUSPEND:
++ /* Screen On: HSync: On, VSync : Off */
++ smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20));
++ smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0)));
++ smtc_seqw(0x6a, 0x0c);
++ smtc_seqw(0x6b, 0x02);
++ smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88));
++ smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x20));
++ smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0x20));
++ smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01)));
++ smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
++ smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80));
++ break;
++ case FB_BLANK_HSYNC_SUSPEND:
++ /* Screen On: HSync: Off, VSync : On */
++ smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20));
++ smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0)));
++ smtc_seqw(0x6a, 0x0c);
++ smtc_seqw(0x6b, 0x02);
++ smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88));
++ smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x10));
++ smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0xD8));
++ smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01)));
++ smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
++ smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80));
++ break;
++ case FB_BLANK_POWERDOWN:
++ /* Screen On: HSync: Off, VSync : Off */
++ smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20));
++ smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0)));
++ smtc_seqw(0x6a, 0x0c);
++ smtc_seqw(0x6b, 0x02);
++ smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88));
++ smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x30));
++ smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0xD8));
++ smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01)));
++ smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
++ smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80));
++ break;
++ default:
++ return -EINVAL;
++ }
++
++ return 0;
++}
++
++static int smtc_setcolreg(unsigned regno, unsigned red, unsigned green,
++ unsigned blue, unsigned trans, struct fb_info *info)
++{
++ struct smtcfb_info *sfb = (struct smtcfb_info *)info;
++ u32 val;
++
++ if (regno > 255)
++ return 1;
++
++ switch (sfb->fb.fix.visual) {
++ case FB_VISUAL_DIRECTCOLOR:
++ case FB_VISUAL_TRUECOLOR:
++ /*
++ * 16/32 bit true-colour, use pseuo-palette for 16 base color
++ */
++ if (regno < 16) {
++ if (sfb->fb.var.bits_per_pixel == 16) {
++ u32 *pal = sfb->fb.pseudo_palette;
++ val = chan_to_field(red, &sfb->fb.var.red);
++ val |= chan_to_field(green, \
++ &sfb->fb.var.green);
++ val |= chan_to_field(blue, &sfb->fb.var.blue);
++#ifdef __BIG_ENDIAN
++ pal[regno] =
++ ((red & 0xf800) >> 8) |
++ ((green & 0xe000) >> 13) |
++ ((green & 0x1c00) << 3) |
++ ((blue & 0xf800) >> 3);
++#else
++ pal[regno] = val;
++#endif
++ } else {
++ u32 *pal = sfb->fb.pseudo_palette;
++ val = chan_to_field(red, &sfb->fb.var.red);
++ val |= chan_to_field(green, \
++ &sfb->fb.var.green);
++ val |= chan_to_field(blue, &sfb->fb.var.blue);
++#ifdef __BIG_ENDIAN
++ val =
++ (val & 0xff00ff00 >> 8) |
++ (val & 0x00ff00ff << 8);
++#endif
++ pal[regno] = val;
++ }
++ }
++ break;
++
++ case FB_VISUAL_PSEUDOCOLOR:
++ /* color depth 8 bit */
++ sm712_setpalette(regno, red, green, blue, info);
++ break;
++
++ default:
++ return 1; /* unknown type */
++ }
++
++ return 0;
++
++}
++
++#ifdef __BIG_ENDIAN
++static ssize_t smtcfb_read(struct fb_info *info, char __user * buf, size_t
++ count, loff_t *ppos)
++{
++ unsigned long p = *ppos;
++
++ u32 *buffer, *dst;
++ u32 __iomem *src;
++ int c, i, cnt = 0, err = 0;
++ unsigned long total_size;
++
++ if (!info || !info->screen_base)
++ return -ENODEV;
++
++ if (info->state != FBINFO_STATE_RUNNING)
++ return -EPERM;
++
++ total_size = info->screen_size;
++
++ if (total_size == 0)
++ total_size = info->fix.smem_len;
++
++ if (p >= total_size)
++ return 0;
++
++ if (count >= total_size)
++ count = total_size;
++
++ if (count + p > total_size)
++ count = total_size - p;
++
++ buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, GFP_KERNEL);
++ if (!buffer)
++ return -ENOMEM;
++
++ src = (u32 __iomem *) (info->screen_base + p);
++
++ if (info->fbops->fb_sync)
++ info->fbops->fb_sync(info);
++
++ while (count) {
++ c = (count > PAGE_SIZE) ? PAGE_SIZE : count;
++ dst = buffer;
++ for (i = c >> 2; i--;) {
++ *dst = fb_readl(src++);
++ *dst =
++ (*dst & 0xff00ff00 >> 8) |
++ (*dst & 0x00ff00ff << 8);
++ dst++;
++ }
++ if (c & 3) {
++ u8 *dst8 = (u8 *) dst;
++ u8 __iomem *src8 = (u8 __iomem *) src;
++
++ for (i = c & 3; i--;) {
++ if (i & 1) {
++ *dst8++ = fb_readb(++src8);
++ } else {
++ *dst8++ = fb_readb(--src8);
++ src8 += 2;
++ }
++ }
++ src = (u32 __iomem *) src8;
++ }
++
++ if (copy_to_user(buf, buffer, c)) {
++ err = -EFAULT;
++ break;
++ }
++ *ppos += c;
++ buf += c;
++ cnt += c;
++ count -= c;
++ }
++
++ kfree(buffer);
++
++ return (err) ? err : cnt;
++}
++
++static ssize_t
++smtcfb_write(struct fb_info *info, const char __user *buf, size_t count,
++ loff_t *ppos)
++{
++ unsigned long p = *ppos;
++
++ u32 *buffer, *src;
++ u32 __iomem *dst;
++ int c, i, cnt = 0, err = 0;
++ unsigned long total_size;
++
++ if (!info || !info->screen_base)
++ return -ENODEV;
++
++ if (info->state != FBINFO_STATE_RUNNING)
++ return -EPERM;
++
++ total_size = info->screen_size;
++
++ if (total_size == 0)
++ total_size = info->fix.smem_len;
++
++ if (p > total_size)
++ return -EFBIG;
++
++ if (count > total_size) {
++ err = -EFBIG;
++ count = total_size;
++ }
++
++ if (count + p > total_size) {
++ if (!err)
++ err = -ENOSPC;
++
++ count = total_size - p;
++ }
++
++ buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, GFP_KERNEL);
++ if (!buffer)
++ return -ENOMEM;
++
++ dst = (u32 __iomem *) (info->screen_base + p);
++
++ if (info->fbops->fb_sync)
++ info->fbops->fb_sync(info);
++
++ while (count) {
++ c = (count > PAGE_SIZE) ? PAGE_SIZE : count;
++ src = buffer;
++
++ if (copy_from_user(src, buf, c)) {
++ err = -EFAULT;
++ break;
++ }
++
++ for (i = c >> 2; i--;) {
++ fb_writel((*src & 0xff00ff00 >> 8) |
++ (*src & 0x00ff00ff << 8), dst++);
++ src++;
++ }
++ if (c & 3) {
++ u8 *src8 = (u8 *) src;
++ u8 __iomem *dst8 = (u8 __iomem *) dst;
++
++ for (i = c & 3; i--;) {
++ if (i & 1) {
++ fb_writeb(*src8++, ++dst8);
++ } else {
++ fb_writeb(*src8++, --dst8);
++ dst8 += 2;
++ }
++ }
++ dst = (u32 __iomem *) dst8;
++ }
++
++ *ppos += c;
++ buf += c;
++ cnt += c;
++ count -= c;
++ }
++
++ kfree(buffer);
++
++ return (cnt) ? cnt : err;
++}
++#endif /* ! __BIG_ENDIAN */
++
++#include "smtc2d.c"
++
++void smtcfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
++{
++ struct par_info *p = (struct par_info *)info->par;
++
++ if (smtc_2Dacceleration) {
++ if (!area->width || !area->height)
++ return;
++
++ deCopy(p->BaseAddressInVRAM, 0, info->var.bits_per_pixel,
++ area->dx, area->dy, area->width, area->height,
++ p->BaseAddressInVRAM, 0, area->sx, area->sy, 0, 0xC);
++
++ } else
++ cfb_copyarea(info, area);
++}
++
++void smtcfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
++{
++ struct par_info *p = (struct par_info *)info->par;
++
++ if (smtc_2Dacceleration) {
++ if (!rect->width || !rect->height)
++ return;
++ if (info->var.bits_per_pixel >= 24)
++ deFillRect(p->BaseAddressInVRAM, 0, rect->dx * 3,
++ rect->dy * 3, rect->width * 3, rect->height,
++ rect->color);
++ else
++ deFillRect(p->BaseAddressInVRAM, 0, rect->dx, rect->dy,
++ rect->width, rect->height, rect->color);
++ } else
++ cfb_fillrect(info, rect);
++}
++
++void smtcfb_imageblit(struct fb_info *info, const struct fb_image *image)
++{
++ struct par_info *p = (struct par_info *)info->par;
++ u32 bg_col = 0, fg_col = 0;
++
++ if ((smtc_2Dacceleration) && (image->depth == 1)) {
++ if (smtc_de_busy)
++ deWaitForNotBusy();
++
++ switch (info->var.bits_per_pixel) {
++ case 8:
++ bg_col = image->bg_color;
++ fg_col = image->fg_color;
++ break;
++ case 16:
++ bg_col =
++ ((u32 *) (info->pseudo_palette))[image->bg_color];
++ fg_col =
++ ((u32 *) (info->pseudo_palette))[image->fg_color];
++ break;
++ case 32:
++ bg_col =
++ ((u32 *) (info->pseudo_palette))[image->bg_color];
++ fg_col =
++ ((u32 *) (info->pseudo_palette))[image->fg_color];
++ break;
++ }
++
++ deSystemMem2VideoMemMonoBlt(
++ image->data,
++ image->width / 8,
++ 0,
++ p->BaseAddressInVRAM,
++ 0,
++ 0,
++ image->dx, image->dy,
++ image->width, image->height,
++ fg_col, bg_col,
++ 0x0C);
++
++ } else
++ cfb_imageblit(info, image);
++}
++
++static struct fb_ops smtcfb_ops = {
++ .owner = THIS_MODULE,
++ .fb_setcolreg = smtc_setcolreg,
++ .fb_blank = smtcfb_blank,
++ .fb_fillrect = smtcfb_fillrect,
++ .fb_imageblit = smtcfb_imageblit,
++ .fb_copyarea = smtcfb_copyarea,
++#ifdef __BIG_ENDIAN
++ .fb_read = smtcfb_read,
++ .fb_write = smtcfb_write,
++#endif
++
++};
++
++void smtcfb_setmode(struct smtcfb_info *sfb)
++{
++ switch (sfb->fb.var.bits_per_pixel) {
++ case 32:
++ sfb->fb.fix.visual = FB_VISUAL_TRUECOLOR;
++ sfb->fb.fix.line_length = sfb->fb.var.xres * 4;
++ sfb->fb.var.red.length = 8;
++ sfb->fb.var.green.length = 8;
++ sfb->fb.var.blue.length = 8;
++ sfb->fb.var.red.offset = 16;
++ sfb->fb.var.green.offset = 8;
++ sfb->fb.var.blue.offset = 0;
++
++ break;
++ case 8:
++ sfb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR;
++ sfb->fb.fix.line_length = sfb->fb.var.xres;
++ sfb->fb.var.red.offset = 5;
++ sfb->fb.var.red.length = 3;
++ sfb->fb.var.green.offset = 2;
++ sfb->fb.var.green.length = 3;
++ sfb->fb.var.blue.offset = 0;
++ sfb->fb.var.blue.length = 2;
++ break;
++ case 24:
++ sfb->fb.fix.visual = FB_VISUAL_TRUECOLOR;
++ sfb->fb.fix.line_length = sfb->fb.var.xres * 3;
++ sfb->fb.var.red.length = 8;
++ sfb->fb.var.green.length = 8;
++ sfb->fb.var.blue.length = 8;
++
++ sfb->fb.var.red.offset = 16;
++ sfb->fb.var.green.offset = 8;
++ sfb->fb.var.blue.offset = 0;
++
++ break;
++ case 16:
++ default:
++ sfb->fb.fix.visual = FB_VISUAL_TRUECOLOR;
++ sfb->fb.fix.line_length = sfb->fb.var.xres * 2;
++
++ sfb->fb.var.red.length = 5;
++ sfb->fb.var.green.length = 6;
++ sfb->fb.var.blue.length = 5;
++
++ sfb->fb.var.red.offset = 11;
++ sfb->fb.var.green.offset = 5;
++ sfb->fb.var.blue.offset = 0;
++
++ break;
++ }
++
++ hw.width = sfb->fb.var.xres;
++ hw.height = sfb->fb.var.yres;
++ hw.hz = 60;
++ smtc_set_timing(sfb, &hw);
++ if (smtc_2Dacceleration) {
++ printk("2D acceleration enabled!\n");
++ /* Init smtc drawing engine */
++ deInit(sfb->fb.var.xres, sfb->fb.var.yres,
++ sfb->fb.var.bits_per_pixel);
++ }
++}
++
++/*
++ * Alloc struct smtcfb_info and assign the default value
++ */
++static struct smtcfb_info *smtc_alloc_fb_info(struct pci_dev *dev,
++ char *name)
++{
++ struct smtcfb_info *sfb;
++
++ sfb = kmalloc(sizeof(struct smtcfb_info), GFP_KERNEL);
++
++ if (!sfb)
++ return NULL;
++
++ memset(sfb, 0, sizeof(struct smtcfb_info));
++
++ sfb->currcon = -1;
++ sfb->dev = dev;
++
++ /*** Init sfb->fb with default value ***/
++ sfb->fb.flags = FBINFO_FLAG_DEFAULT;
++ sfb->fb.fbops = &smtcfb_ops;
++ sfb->fb.var = smtcfb_var;
++ sfb->fb.fix = smtcfb_fix;
++
++ strcpy(sfb->fb.fix.id, name);
++
++ sfb->fb.fix.type = FB_TYPE_PACKED_PIXELS;
++ sfb->fb.fix.type_aux = 0;
++ sfb->fb.fix.xpanstep = 0;
++ sfb->fb.fix.ypanstep = 0;
++ sfb->fb.fix.ywrapstep = 0;
++ sfb->fb.fix.accel = FB_ACCEL_SMI_LYNX;
++
++ sfb->fb.var.nonstd = 0;
++ sfb->fb.var.activate = FB_ACTIVATE_NOW;
++ sfb->fb.var.height = -1;
++ sfb->fb.var.width = -1;
++ /* text mode acceleration */
++ sfb->fb.var.accel_flags = FB_ACCELF_TEXT;
++ sfb->fb.var.vmode = FB_VMODE_NONINTERLACED;
++ sfb->fb.par = &hw;
++ sfb->fb.pseudo_palette = colreg;
++
++ return sfb;
++}
++
++/*
++ * Unmap in the memory mapped IO registers
++ */
++
++static void smtc_unmap_mmio(struct smtcfb_info *sfb)
++{
++ if (sfb && smtc_RegBaseAddress)
++ smtc_RegBaseAddress = NULL;
++}
++
++/*
++ * Map in the screen memory
++ */
++
++static int smtc_map_smem(struct smtcfb_info *sfb,
++ struct pci_dev *dev, u_long smem_len)
++{
++ if (sfb->fb.var.bits_per_pixel == 32) {
++#ifdef __BIG_ENDIAN
++ sfb->fb.fix.smem_start = pci_resource_start(dev, 0)
++ + 0x800000;
++#else
++ sfb->fb.fix.smem_start = pci_resource_start(dev, 0);
++#endif
++ } else {
++ sfb->fb.fix.smem_start = pci_resource_start(dev, 0);
++ }
++
++ sfb->fb.fix.smem_len = smem_len;
++
++ sfb->fb.screen_base = smtc_VRAMBaseAddress;
++
++ if (!sfb->fb.screen_base) {
++ printk(KERN_INFO "%s: unable to map screen memory\n",
++ sfb->fb.fix.id);
++ return -ENOMEM;
++ }
++
++ return 0;
++}
++
++/*
++ * Unmap in the screen memory
++ *
++ */
++static void smtc_unmap_smem(struct smtcfb_info *sfb)
++{
++ if (sfb && sfb->fb.screen_base) {
++ iounmap(sfb->fb.screen_base);
++ sfb->fb.screen_base = NULL;
++ }
++}
++
++/*
++ * We need to wake up the LynxEM+, and make sure its in linear memory mode.
++ */
++static inline void sm7xx_init_hw(void)
++{
++ outb_p(0x18, 0x3c4);
++ outb_p(0x11, 0x3c5);
++}
++
++static void smtc_free_fb_info(struct smtcfb_info *sfb)
++{
++ if (sfb) {
++ fb_alloc_cmap(&sfb->fb.cmap, 0, 0);
++ kfree(sfb);
++ }
++}
++
++/*
++ * sm712vga_setup - process command line options, get vga parameter
++ * @options: string of options
++ * Returns zero.
++ *
++ */
++static int __init __maybe_unused sm712vga_setup(char *options)
++{
++ int index;
++
++ if (!options || !*options) {
++ smdbg("\n No vga parameter\n");
++ return -EINVAL;
++ }
++
++ smtc_screen_info.lfb_width = 0;
++ smtc_screen_info.lfb_height = 0;
++ smtc_screen_info.lfb_depth = 0;
++
++ smdbg("\nsm712vga_setup = %s\n", options);
++
++ for (index = 0;
++ index < (sizeof(vesa_mode) / sizeof(struct vesa_mode_table));
++ index++) {
++ if (strstr(options, vesa_mode[index].mode_index)) {
++ smtc_screen_info.lfb_width = vesa_mode[index].lfb_width;
++ smtc_screen_info.lfb_height =
++ vesa_mode[index].lfb_height;
++ smtc_screen_info.lfb_depth = vesa_mode[index].lfb_depth;
++ return 0;
++ }
++ }
++
++ return -1;
++}
++__setup("vga=", sm712vga_setup);
++
++/* Jason (08/13/2009)
++ * Original init function changed to probe method to be used by pci_drv
++ * process used to detect chips replaced with kernel process in pci_drv
++ */
++static int __init smtcfb_pci_probe(struct pci_dev *pdev,
++ const struct pci_device_id *ent)
++{
++ struct smtcfb_info *sfb;
++ u_long smem_size = 0x00800000; /* default 8MB */
++ char name[16];
++ int err;
++ unsigned long pFramebufferPhysical;
++
++ printk(KERN_INFO
++ "Silicon Motion display driver " SMTC_LINUX_FB_VERSION "\n");
++
++ err = pci_enable_device(pdev); /* enable SMTC chip */
++
++ if (err)
++ return err;
++ err = -ENOMEM;
++
++ hw.chipID = ent->device;
++ sprintf(name, "sm%Xfb", hw.chipID);
++
++ sfb = smtc_alloc_fb_info(pdev, name);
++
++ if (!sfb)
++ goto failed;
++ /* Jason (08/13/2009)
++ * Store fb_info to be further used when suspending and resuming
++ */
++ pci_set_drvdata(pdev, sfb);
++
++ sm7xx_init_hw();
++
++ /*get mode parameter from smtc_screen_info */
++ if (smtc_screen_info.lfb_width != 0) {
++ sfb->fb.var.xres = smtc_screen_info.lfb_width;
++ sfb->fb.var.yres = smtc_screen_info.lfb_height;
++ sfb->fb.var.bits_per_pixel = smtc_screen_info.lfb_depth;
++ } else {
++ /* default resolution 1024x600 16bit mode */
++ sfb->fb.var.xres = SCREEN_X_RES;
++ sfb->fb.var.yres = SCREEN_Y_RES;
++ sfb->fb.var.bits_per_pixel = SCREEN_BPP;
++ }
++
++#ifdef __BIG_ENDIAN
++ if (sfb->fb.var.bits_per_pixel == 24)
++ sfb->fb.var.bits_per_pixel = (smtc_screen_info.lfb_depth = 32);
++#endif
++ /* Map address and memory detection */
++ pFramebufferPhysical = pci_resource_start(pdev, 0);
++ pci_read_config_byte(pdev, PCI_REVISION_ID, &hw.chipRevID);
++
++ switch (hw.chipID) {
++ case 0x710:
++ case 0x712:
++ sfb->fb.fix.mmio_start = pFramebufferPhysical + 0x00400000;
++ sfb->fb.fix.mmio_len = 0x00400000;
++ smem_size = SM712_VIDEOMEMORYSIZE;
++#ifdef __BIG_ENDIAN
++ hw.m_pLFB = (smtc_VRAMBaseAddress =
++ ioremap(pFramebufferPhysical, 0x00c00000));
++#else
++ hw.m_pLFB = (smtc_VRAMBaseAddress =
++ ioremap(pFramebufferPhysical, 0x00800000));
++#endif
++ hw.m_pMMIO = (smtc_RegBaseAddress =
++ smtc_VRAMBaseAddress + 0x00700000);
++ smtc_2DBaseAddress = (hw.m_pDPR =
++ smtc_VRAMBaseAddress + 0x00408000);
++ smtc_2Ddataport = smtc_VRAMBaseAddress + DE_DATA_PORT_712;
++ hw.m_pVPR = hw.m_pLFB + 0x0040c000;
++#ifdef __BIG_ENDIAN
++ if (sfb->fb.var.bits_per_pixel == 32) {
++ smtc_VRAMBaseAddress += 0x800000;
++ hw.m_pLFB += 0x800000;
++ printk(KERN_INFO
++ "\nsmtc_VRAMBaseAddress=%p hw.m_pLFB=%p\n",
++ smtc_VRAMBaseAddress, hw.m_pLFB);
++ }
++#endif
++ if (!smtc_RegBaseAddress) {
++ printk(KERN_INFO
++ "%s: unable to map memory mapped IO\n",
++ sfb->fb.fix.id);
++ return -ENOMEM;
++ }
++
++ /* set MCLK = 14.31818 * (0x16 / 0x2) */
++ smtc_seqw(0x6a, 0x16);
++ smtc_seqw(0x6b, 0x02);
++ smtc_seqw(0x62, 0x3e);
++ /* enable PCI burst */
++ smtc_seqw(0x17, 0x20);
++ /* enable word swap */
++#ifdef __BIG_ENDIAN
++ if (sfb->fb.var.bits_per_pixel == 32)
++ smtc_seqw(0x17, 0x30);
++#endif
++#ifdef CONFIG_FB_SM7XX_ACCEL
++ smtc_2Dacceleration = 1;
++#endif
++ break;
++ case 0x720:
++ sfb->fb.fix.mmio_start = pFramebufferPhysical;
++ sfb->fb.fix.mmio_len = 0x00200000;
++ smem_size = SM722_VIDEOMEMORYSIZE;
++ smtc_2DBaseAddress = (hw.m_pDPR =
++ ioremap(pFramebufferPhysical, 0x00a00000));
++ hw.m_pLFB = (smtc_VRAMBaseAddress =
++ smtc_2DBaseAddress + 0x00200000);
++ hw.m_pMMIO = (smtc_RegBaseAddress =
++ smtc_2DBaseAddress + 0x000c0000);
++ smtc_2Ddataport = smtc_2DBaseAddress + DE_DATA_PORT_722;
++ hw.m_pVPR = smtc_2DBaseAddress + 0x800;
++
++ smtc_seqw(0x62, 0xff);
++ smtc_seqw(0x6a, 0x0d);
++ smtc_seqw(0x6b, 0x02);
++ smtc_2Dacceleration = 0;
++ break;
++ default:
++ printk(KERN_INFO
++ "No valid Silicon Motion display chip was detected!\n");
++
++ smtc_free_fb_info(sfb);
++ return err;
++ }
++
++ /* can support 32 bpp */
++ if (15 == sfb->fb.var.bits_per_pixel)
++ sfb->fb.var.bits_per_pixel = 16;
++
++ sfb->fb.var.xres_virtual = sfb->fb.var.xres;
++ sfb->fb.var.yres_virtual = sfb->fb.var.yres;
++ err = smtc_map_smem(sfb, pdev, smem_size);
++ if (err)
++ goto failed;
++
++ smtcfb_setmode(sfb);
++ /* Primary display starting from 0 postion */
++ hw.BaseAddressInVRAM = 0;
++ sfb->fb.par = &hw;
++
++ err = register_framebuffer(&sfb->fb);
++ if (err < 0)
++ goto failed;
++
++ printk(KERN_INFO "Silicon Motion SM%X Rev%X primary display mode"
++ "%dx%d-%d Init Complete.\n", hw.chipID, hw.chipRevID,
++ sfb->fb.var.xres, sfb->fb.var.yres,
++ sfb->fb.var.bits_per_pixel);
++
++ return 0;
++
++ failed:
++ printk(KERN_INFO "Silicon Motion, Inc. primary display init fail\n");
++
++ smtc_unmap_smem(sfb);
++ smtc_unmap_mmio(sfb);
++ smtc_free_fb_info(sfb);
++
++ return err;
++}
++
++
++/* Jason (08/11/2009) PCI_DRV wrapper essential structs */
++static struct pci_device_id smtcfb_pci_table[] = {
++ {0x126f, 0x710, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
++ {0x126f, 0x712, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
++ {0x126f, 0x720, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
++ {0,}
++};
++
++
++/* Jason (08/14/2009)
++ * do some clean up when the driver module is removed
++ */
++static void __devexit smtcfb_pci_remove(struct pci_dev *pdev)
++{
++ struct smtcfb_info *sfb;
++
++ sfb = pci_get_drvdata(pdev);
++ pci_set_drvdata(pdev, NULL);
++ smtc_unmap_smem(sfb);
++ smtc_unmap_mmio(sfb);
++ unregister_framebuffer(&sfb->fb);
++ smtc_free_fb_info(sfb);
++}
++
++/* Jason (08/14/2009)
++ * suspend function, called when the suspend event is triggered
++ */
++static int __maybe_unused smtcfb_suspend(struct pci_dev *pdev, pm_message_t msg)
++{
++ struct smtcfb_info *sfb;
++ int retv;
++
++ sfb = pci_get_drvdata(pdev);
++
++ /* set the hw in sleep mode use externel clock and self memory refresh
++ * so that we can turn off internal PLLs later on
++ */
++ smtc_seqw(0x20, (smtc_seqr(0x20) | 0xc0));
++ smtc_seqw(0x69, (smtc_seqr(0x69) & 0xf7));
++
++ switch (msg.event) {
++ case PM_EVENT_FREEZE:
++ case PM_EVENT_PRETHAW:
++ pdev->dev.power.power_state = msg;
++ return 0;
++ }
++
++ /* when doing suspend, call fb apis and pci apis */
++ if (msg.event == PM_EVENT_SUSPEND) {
++ acquire_console_sem();
++ fb_set_suspend(&sfb->fb, 1);
++ release_console_sem();
++ retv = pci_save_state(pdev);
++ pci_disable_device(pdev);
++ retv = pci_choose_state(pdev, msg);
++ retv = pci_set_power_state(pdev, retv);
++ }
++
++ pdev->dev.power.power_state = msg;
++
++ /* additionaly turn off all function blocks including internal PLLs */
++ smtc_seqw(0x21, 0xff);
++
++ return 0;
++}
++
++static int __maybe_unused smtcfb_resume(struct pci_dev *pdev)
++{
++ struct smtcfb_info *sfb;
++ int retv;
++
++ sfb = pci_get_drvdata(pdev);
++
++ /* when resuming, restore pci data and fb cursor */
++ if (pdev->dev.power.power_state.event != PM_EVENT_FREEZE) {
++ retv = pci_set_power_state(pdev, PCI_D0);
++ retv = pci_restore_state(pdev);
++ if (pci_enable_device(pdev))
++ return -1;
++ pci_set_master(pdev);
++ }
++
++ /* reinit hardware */
++ sm7xx_init_hw();
++ switch (hw.chipID) {
++ case 0x710:
++ case 0x712:
++ /* set MCLK = 14.31818 * (0x16 / 0x2) */
++ smtc_seqw(0x6a, 0x16);
++ smtc_seqw(0x6b, 0x02);
++ smtc_seqw(0x62, 0x3e);
++ /* enable PCI burst */
++ smtc_seqw(0x17, 0x20);
++#ifdef __BIG_ENDIAN
++ if (sfb->fb.var.bits_per_pixel == 32)
++ smtc_seqw(0x17, 0x30);
++#endif
++ break;
++ case 0x720:
++ smtc_seqw(0x62, 0xff);
++ smtc_seqw(0x6a, 0x0d);
++ smtc_seqw(0x6b, 0x02);
++ break;
++ }
++
++ smtc_seqw(0x34, (smtc_seqr(0x34) | 0xc0));
++ smtc_seqw(0x33, ((smtc_seqr(0x33) | 0x08) & 0xfb));
++
++ smtcfb_setmode(sfb);
++
++ acquire_console_sem();
++ fb_set_suspend(&sfb->fb, 0);
++ release_console_sem();
++
++ return 0;
++}
++
++/* Jason (08/13/2009)
++ * pci_driver struct used to wrap the original driver
++ * so that it can be registered into the kernel and
++ * the proper method would be called when suspending and resuming
++ */
++static struct pci_driver smtcfb_driver = {
++ .name = "smtcfb",
++ .id_table = smtcfb_pci_table,
++ .probe = smtcfb_pci_probe,
++ .remove = __devexit_p(smtcfb_pci_remove),
++#ifdef CONFIG_PM
++ .suspend = smtcfb_suspend,
++ .resume = smtcfb_resume,
++#endif
++};
++
++static int __init smtcfb_init(void)
++{
++ return pci_register_driver(&smtcfb_driver);
++}
++
++static void __exit smtcfb_exit(void)
++{
++ pci_unregister_driver(&smtcfb_driver);
++}
++
++module_init(smtcfb_init);
++module_exit(smtcfb_exit);
++
++MODULE_AUTHOR("Siliconmotion ");
++MODULE_DESCRIPTION("Framebuffer driver for SMI Graphic Cards");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/staging/sm7xx/smtcfb.h b/drivers/staging/sm7xx/smtcfb.h
+new file mode 100644
+index 0000000..7f2c341
+--- /dev/null
++++ b/drivers/staging/sm7xx/smtcfb.h
+@@ -0,0 +1,793 @@
++/*
++ * Silicon Motion SM712 frame buffer device
++ *
++ * Copyright (C) 2006 Silicon Motion Technology Corp.
++ * Authors: Ge Wang, gewang@siliconmotion.com
++ * Boyod boyod.yang@siliconmotion.com.cn
++ *
++ * Copyright (C) 2009 Lemote, Inc.
++ * Author: Wu Zhangjin, wuzj@lemote.com
++ *
++ * 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 SMTC_LINUX_FB_VERSION "version 0.11.2619.21.01 July 27, 2008"
++
++#define NR_PALETTE 256
++#define NR_RGB 2
++
++#define FB_ACCEL_SMI_LYNX 88
++
++#ifdef __BIG_ENDIAN
++#define PC_VGA 0
++#else
++#define PC_VGA 1
++#endif
++
++#define SCREEN_X_RES 1024
++#define SCREEN_Y_RES 600
++#define SCREEN_BPP 16
++
++#ifndef FIELD_OFFSET
++#define FIELD_OFSFET(type, field) \
++ ((unsigned long) (PUCHAR) & (((type *)0)->field))
++#endif
++
++/*Assume SM712 graphics chip has 4MB VRAM */
++#define SM712_VIDEOMEMORYSIZE 0x00400000
++/*Assume SM722 graphics chip has 8MB VRAM */
++#define SM722_VIDEOMEMORYSIZE 0x00800000
++
++#define dac_reg (0x3c8)
++#define dac_val (0x3c9)
++
++extern char *smtc_RegBaseAddress;
++#define smtc_mmiowb(dat, reg) writeb(dat, smtc_RegBaseAddress + reg)
++#define smtc_mmioww(dat, reg) writew(dat, smtc_RegBaseAddress + reg)
++#define smtc_mmiowl(dat, reg) writel(dat, smtc_RegBaseAddress + reg)
++
++#define smtc_mmiorb(reg) readb(smtc_RegBaseAddress + reg)
++#define smtc_mmiorw(reg) readw(smtc_RegBaseAddress + reg)
++#define smtc_mmiorl(reg) readl(smtc_RegBaseAddress + reg)
++
++#define SIZE_SR00_SR04 (0x04 - 0x00 + 1)
++#define SIZE_SR10_SR24 (0x24 - 0x10 + 1)
++#define SIZE_SR30_SR75 (0x75 - 0x30 + 1)
++#define SIZE_SR80_SR93 (0x93 - 0x80 + 1)
++#define SIZE_SRA0_SRAF (0xAF - 0xA0 + 1)
++#define SIZE_GR00_GR08 (0x08 - 0x00 + 1)
++#define SIZE_AR00_AR14 (0x14 - 0x00 + 1)
++#define SIZE_CR00_CR18 (0x18 - 0x00 + 1)
++#define SIZE_CR30_CR4D (0x4D - 0x30 + 1)
++#define SIZE_CR90_CRA7 (0xA7 - 0x90 + 1)
++#define SIZE_VPR (0x6C + 1)
++#define SIZE_DPR (0x44 + 1)
++
++static inline void smtc_crtcw(int reg, int val)
++{
++ smtc_mmiowb(reg, 0x3d4);
++ smtc_mmiowb(val, 0x3d5);
++}
++
++static inline unsigned int smtc_crtcr(int reg)
++{
++ smtc_mmiowb(reg, 0x3d4);
++ return smtc_mmiorb(0x3d5);
++}
++
++static inline void smtc_grphw(int reg, int val)
++{
++ smtc_mmiowb(reg, 0x3ce);
++ smtc_mmiowb(val, 0x3cf);
++}
++
++static inline unsigned int smtc_grphr(int reg)
++{
++ smtc_mmiowb(reg, 0x3ce);
++ return smtc_mmiorb(0x3cf);
++}
++
++static inline void smtc_attrw(int reg, int val)
++{
++ smtc_mmiorb(0x3da);
++ smtc_mmiowb(reg, 0x3c0);
++ smtc_mmiorb(0x3c1);
++ smtc_mmiowb(val, 0x3c0);
++}
++
++static inline void smtc_seqw(int reg, int val)
++{
++ smtc_mmiowb(reg, 0x3c4);
++ smtc_mmiowb(val, 0x3c5);
++}
++
++static inline unsigned int smtc_seqr(int reg)
++{
++ smtc_mmiowb(reg, 0x3c4);
++ return smtc_mmiorb(0x3c5);
++}
++
++/* The next structure holds all information relevant for a specific video mode.
++ */
++
++struct ModeInit {
++ int mmSizeX;
++ int mmSizeY;
++ int bpp;
++ int hz;
++ unsigned char Init_MISC;
++ unsigned char Init_SR00_SR04[SIZE_SR00_SR04];
++ unsigned char Init_SR10_SR24[SIZE_SR10_SR24];
++ unsigned char Init_SR30_SR75[SIZE_SR30_SR75];
++ unsigned char Init_SR80_SR93[SIZE_SR80_SR93];
++ unsigned char Init_SRA0_SRAF[SIZE_SRA0_SRAF];
++ unsigned char Init_GR00_GR08[SIZE_GR00_GR08];
++ unsigned char Init_AR00_AR14[SIZE_AR00_AR14];
++ unsigned char Init_CR00_CR18[SIZE_CR00_CR18];
++ unsigned char Init_CR30_CR4D[SIZE_CR30_CR4D];
++ unsigned char Init_CR90_CRA7[SIZE_CR90_CRA7];
++};
++
++/**********************************************************************
++ SM712 Mode table.
++ **********************************************************************/
++struct ModeInit VGAMode[] = {
++ {
++ /* mode#0: 640 x 480 16Bpp 60Hz */
++ 640, 480, 16, 60,
++ /* Init_MISC */
++ 0xE3,
++ { /* Init_SR0_SR4 */
++ 0x03, 0x01, 0x0F, 0x00, 0x0E,
++ },
++ { /* Init_SR10_SR24 */
++ 0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C,
++ 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++ 0xC4, 0x30, 0x02, 0x01, 0x01,
++ },
++ { /* Init_SR30_SR75 */
++ 0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32,
++ 0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF,
++ 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
++ 0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32,
++ 0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA,
++ 0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32,
++ 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
++ 0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04,
++ 0x00, 0x45, 0x30, 0x30, 0x40, 0x30,
++ },
++ { /* Init_SR80_SR93 */
++ 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32,
++ 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32,
++ 0x00, 0x00, 0x00, 0x00,
++ },
++ { /* Init_SRA0_SRAF */
++ 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,
++ 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF,
++ },
++ { /* Init_GR00_GR08 */
++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
++ 0xFF,
++ },
++ { /* Init_AR00_AR14 */
++ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
++ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
++ 0x41, 0x00, 0x0F, 0x00, 0x00,
++ },
++ { /* Init_CR00_CR18 */
++ 0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E,
++ 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++ 0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3,
++ 0xFF,
++ },
++ { /* Init_CR30_CR4D */
++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20,
++ 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD,
++ 0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00,
++ 0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF,
++ },
++ { /* Init_CR90_CRA7 */
++ 0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55,
++ 0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00,
++ 0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00,
++ },
++ },
++ {
++ /* mode#1: 640 x 480 24Bpp 60Hz */
++ 640, 480, 24, 60,
++ /* Init_MISC */
++ 0xE3,
++ { /* Init_SR0_SR4 */
++ 0x03, 0x01, 0x0F, 0x00, 0x0E,
++ },
++ { /* Init_SR10_SR24 */
++ 0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C,
++ 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++ 0xC4, 0x30, 0x02, 0x01, 0x01,
++ },
++ { /* Init_SR30_SR75 */
++ 0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32,
++ 0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF,
++ 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
++ 0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32,
++ 0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA,
++ 0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32,
++ 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
++ 0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04,
++ 0x00, 0x45, 0x30, 0x30, 0x40, 0x30,
++ },
++ { /* Init_SR80_SR93 */
++ 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32,
++ 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32,
++ 0x00, 0x00, 0x00, 0x00,
++ },
++ { /* Init_SRA0_SRAF */
++ 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,
++ 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF,
++ },
++ { /* Init_GR00_GR08 */
++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
++ 0xFF,
++ },
++ { /* Init_AR00_AR14 */
++ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
++ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
++ 0x41, 0x00, 0x0F, 0x00, 0x00,
++ },
++ { /* Init_CR00_CR18 */
++ 0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E,
++ 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++ 0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3,
++ 0xFF,
++ },
++ { /* Init_CR30_CR4D */
++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20,
++ 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD,
++ 0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00,
++ 0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF,
++ },
++ { /* Init_CR90_CRA7 */
++ 0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55,
++ 0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00,
++ 0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00,
++ },
++ },
++ {
++ /* mode#0: 640 x 480 32Bpp 60Hz */
++ 640, 480, 32, 60,
++ /* Init_MISC */
++ 0xE3,
++ { /* Init_SR0_SR4 */
++ 0x03, 0x01, 0x0F, 0x00, 0x0E,
++ },
++ { /* Init_SR10_SR24 */
++ 0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C,
++ 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++ 0xC4, 0x30, 0x02, 0x01, 0x01,
++ },
++ { /* Init_SR30_SR75 */
++ 0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32,
++ 0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF,
++ 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
++ 0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32,
++ 0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA,
++ 0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32,
++ 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
++ 0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04,
++ 0x00, 0x45, 0x30, 0x30, 0x40, 0x30,
++ },
++ { /* Init_SR80_SR93 */
++ 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32,
++ 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32,
++ 0x00, 0x00, 0x00, 0x00,
++ },
++ { /* Init_SRA0_SRAF */
++ 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,
++ 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF,
++ },
++ { /* Init_GR00_GR08 */
++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
++ 0xFF,
++ },
++ { /* Init_AR00_AR14 */
++ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
++ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
++ 0x41, 0x00, 0x0F, 0x00, 0x00,
++ },
++ { /* Init_CR00_CR18 */
++ 0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E,
++ 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++ 0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3,
++ 0xFF,
++ },
++ { /* Init_CR30_CR4D */
++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20,
++ 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD,
++ 0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00,
++ 0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF,
++ },
++ { /* Init_CR90_CRA7 */
++ 0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55,
++ 0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00,
++ 0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00,
++ },
++ },
++
++ { /* mode#2: 800 x 600 16Bpp 60Hz */
++ 800, 600, 16, 60,
++ /* Init_MISC */
++ 0x2B,
++ { /* Init_SR0_SR4 */
++ 0x03, 0x01, 0x0F, 0x03, 0x0E,
++ },
++ { /* Init_SR10_SR24 */
++ 0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C,
++ 0x99, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
++ 0xC4, 0x30, 0x02, 0x01, 0x01,
++ },
++ { /* Init_SR30_SR75 */
++ 0x34, 0x03, 0x20, 0x09, 0xC0, 0x24, 0x24, 0x24,
++ 0x24, 0x24, 0x24, 0x24, 0x00, 0x00, 0x03, 0xFF,
++ 0x00, 0xFC, 0x00, 0x00, 0x20, 0x38, 0x00, 0xFC,
++ 0x20, 0x0C, 0x44, 0x20, 0x00, 0x24, 0x24, 0x24,
++ 0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58,
++ 0x04, 0x55, 0x59, 0x24, 0x24, 0x00, 0x00, 0x24,
++ 0x01, 0x80, 0x7A, 0x1A, 0x1A, 0x00, 0x00, 0x00,
++ 0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13,
++ 0x02, 0x45, 0x30, 0x35, 0x40, 0x20,
++ },
++ { /* Init_SR80_SR93 */
++ 0x00, 0x00, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x24,
++ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x24, 0x24,
++ 0x00, 0x00, 0x00, 0x00,
++ },
++ { /* Init_SRA0_SRAF */
++ 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,
++ 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF,
++ },
++ { /* Init_GR00_GR08 */
++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
++ 0xFF,
++ },
++ { /* Init_AR00_AR14 */
++ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
++ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
++ 0x41, 0x00, 0x0F, 0x00, 0x00,
++ },
++ { /* Init_CR00_CR18 */
++ 0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0,
++ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++ 0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3,
++ 0xFF,
++ },
++ { /* Init_CR30_CR4D */
++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20,
++ 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD,
++ 0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00,
++ 0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57,
++ },
++ { /* Init_CR90_CRA7 */
++ 0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA,
++ 0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00,
++ 0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00,
++ },
++ },
++ { /* mode#3: 800 x 600 24Bpp 60Hz */
++ 800, 600, 24, 60,
++ 0x2B,
++ { /* Init_SR0_SR4 */
++ 0x03, 0x01, 0x0F, 0x03, 0x0E,
++ },
++ { /* Init_SR10_SR24 */
++ 0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C,
++ 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++ 0xC4, 0x30, 0x02, 0x01, 0x01,
++ },
++ { /* Init_SR30_SR75 */
++ 0x36, 0x03, 0x20, 0x09, 0xC0, 0x36, 0x36, 0x36,
++ 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x03, 0xFF,
++ 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
++ 0x20, 0x0C, 0x44, 0x20, 0x00, 0x36, 0x36, 0x36,
++ 0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58,
++ 0x04, 0x55, 0x59, 0x36, 0x36, 0x00, 0x00, 0x36,
++ 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
++ 0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13,
++ 0x02, 0x45, 0x30, 0x30, 0x40, 0x20,
++ },
++ { /* Init_SR80_SR93 */
++ 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x36,
++ 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x36, 0x36,
++ 0x00, 0x00, 0x00, 0x00,
++ },
++ { /* Init_SRA0_SRAF */
++ 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,
++ 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF,
++ },
++ { /* Init_GR00_GR08 */
++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
++ 0xFF,
++ },
++ { /* Init_AR00_AR14 */
++ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
++ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
++ 0x41, 0x00, 0x0F, 0x00, 0x00,
++ },
++ { /* Init_CR00_CR18 */
++ 0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0,
++ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++ 0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3,
++ 0xFF,
++ },
++ { /* Init_CR30_CR4D */
++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20,
++ 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD,
++ 0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00,
++ 0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57,
++ },
++ { /* Init_CR90_CRA7 */
++ 0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA,
++ 0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00,
++ 0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00,
++ },
++ },
++ { /* mode#7: 800 x 600 32Bpp 60Hz */
++ 800, 600, 32, 60,
++ /* Init_MISC */
++ 0x2B,
++ { /* Init_SR0_SR4 */
++ 0x03, 0x01, 0x0F, 0x03, 0x0E,
++ },
++ { /* Init_SR10_SR24 */
++ 0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C,
++ 0x99, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
++ 0xC4, 0x30, 0x02, 0x01, 0x01,
++ },
++ { /* Init_SR30_SR75 */
++ 0x34, 0x03, 0x20, 0x09, 0xC0, 0x24, 0x24, 0x24,
++ 0x24, 0x24, 0x24, 0x24, 0x00, 0x00, 0x03, 0xFF,
++ 0x00, 0xFC, 0x00, 0x00, 0x20, 0x38, 0x00, 0xFC,
++ 0x20, 0x0C, 0x44, 0x20, 0x00, 0x24, 0x24, 0x24,
++ 0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58,
++ 0x04, 0x55, 0x59, 0x24, 0x24, 0x00, 0x00, 0x24,
++ 0x01, 0x80, 0x7A, 0x1A, 0x1A, 0x00, 0x00, 0x00,
++ 0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13,
++ 0x02, 0x45, 0x30, 0x35, 0x40, 0x20,
++ },
++ { /* Init_SR80_SR93 */
++ 0x00, 0x00, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x24,
++ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x24, 0x24,
++ 0x00, 0x00, 0x00, 0x00,
++ },
++ { /* Init_SRA0_SRAF */
++ 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,
++ 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF,
++ },
++ { /* Init_GR00_GR08 */
++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
++ 0xFF,
++ },
++ { /* Init_AR00_AR14 */
++ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
++ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
++ 0x41, 0x00, 0x0F, 0x00, 0x00,
++ },
++ { /* Init_CR00_CR18 */
++ 0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0,
++ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++ 0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3,
++ 0xFF,
++ },
++ { /* Init_CR30_CR4D */
++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20,
++ 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD,
++ 0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00,
++ 0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57,
++ },
++ { /* Init_CR90_CRA7 */
++ 0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA,
++ 0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00,
++ 0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00,
++ },
++ },
++ /* We use 1024x768 table to light 1024x600 panel for lemote */
++ { /* mode#4: 1024 x 600 16Bpp 60Hz */
++ 1024, 600, 16, 60,
++ /* Init_MISC */
++ 0xEB,
++ { /* Init_SR0_SR4 */
++ 0x03, 0x01, 0x0F, 0x00, 0x0E,
++ },
++ { /* Init_SR10_SR24 */
++ 0xC8, 0x40, 0x14, 0x60, 0x00, 0x0A, 0x17, 0x20,
++ 0x51, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
++ 0xC4, 0x30, 0x02, 0x00, 0x01,
++ },
++ { /* Init_SR30_SR75 */
++ 0x22, 0x03, 0x24, 0x09, 0xC0, 0x22, 0x22, 0x22,
++ 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x03, 0xFF,
++ 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
++ 0x20, 0x0C, 0x44, 0x20, 0x00, 0x22, 0x22, 0x22,
++ 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03,
++ 0x00, 0x60, 0x59, 0x22, 0x22, 0x00, 0x00, 0x22,
++ 0x01, 0x80, 0x7A, 0x1A, 0x1A, 0x00, 0x00, 0x00,
++ 0x50, 0x03, 0x16, 0x02, 0x0D, 0x82, 0x09, 0x02,
++ 0x04, 0x45, 0x3F, 0x30, 0x40, 0x20,
++ },
++ { /* Init_SR80_SR93 */
++ 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A,
++ 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A,
++ 0x00, 0x00, 0x00, 0x00,
++ },
++ { /* Init_SRA0_SRAF */
++ 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED,
++ 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF,
++ },
++ { /* Init_GR00_GR08 */
++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
++ 0xFF,
++ },
++ { /* Init_AR00_AR14 */
++ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
++ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
++ 0x41, 0x00, 0x0F, 0x00, 0x00,
++ },
++ { /* Init_CR00_CR18 */
++ 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5,
++ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++ 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3,
++ 0xFF,
++ },
++ { /* Init_CR30_CR4D */
++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20,
++ 0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF,
++ 0xA3, 0x7F, 0x00, 0x82, 0x0b, 0x6f, 0x57, 0x00,
++ 0x5c, 0x0f, 0xE0, 0xe0, 0x7F, 0x57,
++ },
++ { /* Init_CR90_CRA7 */
++ 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26,
++ 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00,
++ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03,
++ },
++ },
++ { /* mode#5: 1024 x 768 24Bpp 60Hz */
++ 1024, 768, 24, 60,
++ /* Init_MISC */
++ 0xEB,
++ { /* Init_SR0_SR4 */
++ 0x03, 0x01, 0x0F, 0x03, 0x0E,
++ },
++ { /* Init_SR10_SR24 */
++ 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C,
++ 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
++ 0xC4, 0x30, 0x02, 0x01, 0x01,
++ },
++ { /* Init_SR30_SR75 */
++ 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A,
++ 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF,
++ 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
++ 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A,
++ 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03,
++ 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A,
++ 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
++ 0x50, 0x03, 0x74, 0x14, 0x3B, 0x0D, 0x09, 0x02,
++ 0x04, 0x45, 0x30, 0x30, 0x40, 0x20,
++ },
++ { /* Init_SR80_SR93 */
++ 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A,
++ 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A,
++ 0x00, 0x00, 0x00, 0x00,
++ },
++ { /* Init_SRA0_SRAF */
++ 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED,
++ 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF,
++ },
++ { /* Init_GR00_GR08 */
++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
++ 0xFF,
++ },
++ { /* Init_AR00_AR14 */
++ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
++ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
++ 0x41, 0x00, 0x0F, 0x00, 0x00,
++ },
++ { /* Init_CR00_CR18 */
++ 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5,
++ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++ 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3,
++ 0xFF,
++ },
++ { /* Init_CR30_CR4D */
++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20,
++ 0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF,
++ 0xA3, 0x7F, 0x00, 0x86, 0x15, 0x24, 0xFF, 0x00,
++ 0x01, 0x07, 0xE5, 0x20, 0x7F, 0xFF,
++ },
++ { /* Init_CR90_CRA7 */
++ 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26,
++ 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00,
++ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03,
++ },
++ },
++ { /* mode#4: 1024 x 768 32Bpp 60Hz */
++ 1024, 768, 32, 60,
++ /* Init_MISC */
++ 0xEB,
++ { /* Init_SR0_SR4 */
++ 0x03, 0x01, 0x0F, 0x03, 0x0E,
++ },
++ { /* Init_SR10_SR24 */
++ 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C,
++ 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
++ 0xC4, 0x32, 0x02, 0x01, 0x01,
++ },
++ { /* Init_SR30_SR75 */
++ 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A,
++ 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF,
++ 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
++ 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A,
++ 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03,
++ 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A,
++ 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
++ 0x50, 0x03, 0x74, 0x14, 0x3B, 0x0D, 0x09, 0x02,
++ 0x04, 0x45, 0x30, 0x30, 0x40, 0x20,
++ },
++ { /* Init_SR80_SR93 */
++ 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A,
++ 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A,
++ 0x00, 0x00, 0x00, 0x00,
++ },
++ { /* Init_SRA0_SRAF */
++ 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED,
++ 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF,
++ },
++ { /* Init_GR00_GR08 */
++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
++ 0xFF,
++ },
++ { /* Init_AR00_AR14 */
++ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
++ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
++ 0x41, 0x00, 0x0F, 0x00, 0x00,
++ },
++ { /* Init_CR00_CR18 */
++ 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5,
++ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++ 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3,
++ 0xFF,
++ },
++ { /* Init_CR30_CR4D */
++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20,
++ 0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF,
++ 0xA3, 0x7F, 0x00, 0x86, 0x15, 0x24, 0xFF, 0x00,
++ 0x01, 0x07, 0xE5, 0x20, 0x7F, 0xFF,
++ },
++ { /* Init_CR90_CRA7 */
++ 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26,
++ 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00,
++ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03,
++ },
++ },
++ { /* mode#6: 320 x 240 16Bpp 60Hz */
++ 320, 240, 16, 60,
++ /* Init_MISC */
++ 0xEB,
++ { /* Init_SR0_SR4 */
++ 0x03, 0x01, 0x0F, 0x03, 0x0E,
++ },
++ { /* Init_SR10_SR24 */
++ 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C,
++ 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
++ 0xC4, 0x32, 0x02, 0x01, 0x01,
++ },
++ { /* Init_SR30_SR75 */
++ 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A,
++ 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF,
++ 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
++ 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A,
++ 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03,
++ 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A,
++ 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
++ 0x50, 0x03, 0x74, 0x14, 0x08, 0x43, 0x08, 0x43,
++ 0x04, 0x45, 0x30, 0x30, 0x40, 0x20,
++ },
++ { /* Init_SR80_SR93 */
++ 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A,
++ 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A,
++ 0x00, 0x00, 0x00, 0x00,
++ },
++ { /* Init_SRA0_SRAF */
++ 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED,
++ 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF,
++ },
++ { /* Init_GR00_GR08 */
++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
++ 0xFF,
++ },
++ { /* Init_AR00_AR14 */
++ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
++ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
++ 0x41, 0x00, 0x0F, 0x00, 0x00,
++ },
++ { /* Init_CR00_CR18 */
++ 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5,
++ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++ 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3,
++ 0xFF,
++ },
++ { /* Init_CR30_CR4D */
++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20,
++ 0x00, 0x00, 0x30, 0x40, 0x00, 0xFF, 0xBF, 0xFF,
++ 0x2E, 0x27, 0x00, 0x2b, 0x0c, 0x0F, 0xEF, 0x00,
++ 0xFe, 0x0f, 0x01, 0xC0, 0x27, 0xEF,
++ },
++ { /* Init_CR90_CRA7 */
++ 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26,
++ 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00,
++ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03,
++ },
++ },
++
++ { /* mode#8: 320 x 240 32Bpp 60Hz */
++ 320, 240, 32, 60,
++ /* Init_MISC */
++ 0xEB,
++ { /* Init_SR0_SR4 */
++ 0x03, 0x01, 0x0F, 0x03, 0x0E,
++ },
++ { /* Init_SR10_SR24 */
++ 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C,
++ 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
++ 0xC4, 0x32, 0x02, 0x01, 0x01,
++ },
++ { /* Init_SR30_SR75 */
++ 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A,
++ 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF,
++ 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
++ 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A,
++ 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03,
++ 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A,
++ 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
++ 0x50, 0x03, 0x74, 0x14, 0x08, 0x43, 0x08, 0x43,
++ 0x04, 0x45, 0x30, 0x30, 0x40, 0x20,
++ },
++ { /* Init_SR80_SR93 */
++ 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A,
++ 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A,
++ 0x00, 0x00, 0x00, 0x00,
++ },
++ { /* Init_SRA0_SRAF */
++ 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED,
++ 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF,
++ },
++ { /* Init_GR00_GR08 */
++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
++ 0xFF,
++ },
++ { /* Init_AR00_AR14 */
++ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
++ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
++ 0x41, 0x00, 0x0F, 0x00, 0x00,
++ },
++ { /* Init_CR00_CR18 */
++ 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5,
++ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++ 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3,
++ 0xFF,
++ },
++ { /* Init_CR30_CR4D */
++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20,
++ 0x00, 0x00, 0x30, 0x40, 0x00, 0xFF, 0xBF, 0xFF,
++ 0x2E, 0x27, 0x00, 0x2b, 0x0c, 0x0F, 0xEF, 0x00,
++ 0xFe, 0x0f, 0x01, 0xC0, 0x27, 0xEF,
++ },
++ { /* Init_CR90_CRA7 */
++ 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26,
++ 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00,
++ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03,
++ },
++ },
++};
++
++#define numVGAModes (sizeof(VGAMode) / sizeof(struct ModeInit))
+diff --git a/drivers/video/sis/310vtbl.h b/drivers/video/sis/310vtbl.h
+index 54fcbbf..4957a66 100644
+--- a/drivers/video/sis/310vtbl.h
++++ b/drivers/video/sis/310vtbl.h
+@@ -471,7 +471,7 @@ static const struct SiS_CRT1Table SiS310_CRT1Table[] =
+ {{0x81,0x6A,0x6A,0x85,0x70,0x00,0x0F,0x3E, /* 856x480-60 */
+ 0xEB,0x8E,0xDF,0xDF,0x10,0x00,0x00,0x02,
+ 0x00}}, /* 0x48 */
+- {{0xdd,0xa9,0xa9,0x81,0xb4,0x97,0x26,0xfd, /* 1360x768-60 */
++ {{0xfc,0xa9,0xa9,0x81,0xb4,0x97,0x26,0xfd, /* 1360x768-60 */
+ 0x01,0x8d,0xff,0x00,0x27,0x10,0x00,0x03,
+ 0x01}}, /* 0x49 */
+ {{0xd9,0x8f,0x8f,0x9d,0xba,0x0a,0x8a,0xff, /* 1152x864-84 */
+@@ -755,7 +755,7 @@ static struct SiS_VCLKData SiS310_VCLKData[] =
+ { 0x62,0xc6, 34}, /* 0x55 848x480-60 */
+ { 0x6a,0xc6, 37}, /* 0x56 848x480-75 - TEMP */
+ { 0xbf,0xc8, 35}, /* 0x57 856x480-38i,60 */
+- { 0x30,0x23, 88}, /* 0x58 1360x768-62 (is 60Hz!) */
++ { 0x54,0x63, 76}, /* 0x58 1360x768-62 (is 60Hz!) */
+ { 0x52,0x07,149}, /* 0x59 1280x960-85 */
+ { 0x56,0x07,156}, /* 0x5a 1400x1050-75 */
+ { 0x70,0x29, 81}, /* 0x5b 1280x768 LCD */
+diff --git a/drivers/video/sis/init301.c b/drivers/video/sis/init301.c
+index da33d80..4eb4a04 100644
+--- a/drivers/video/sis/init301.c
++++ b/drivers/video/sis/init301.c
+@@ -4886,7 +4886,7 @@ SiS_EnableBridge(struct SiS_Private *SiS_Pr)
+ } /* 310 series */
+
+ } /* LVDS */
+-
++ SiS_SetReg(SiS_Pr->SiS_Part1Port, 0x2d, 0x11);
+ }
+
+ /*********************************************/
+diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c
+index ff43c88..d91924f 100644
+--- a/drivers/video/tdfxfb.c
++++ b/drivers/video/tdfxfb.c
+@@ -1571,8 +1571,8 @@ out_err_iobase:
+ if (default_par->mtrr_handle >= 0)
+ mtrr_del(default_par->mtrr_handle, info->fix.smem_start,
+ info->fix.smem_len);
+- release_mem_region(pci_resource_start(pdev, 2),
+- pci_resource_len(pdev, 2));
++ release_region(pci_resource_start(pdev, 2),
++ pci_resource_len(pdev, 2));
+ out_err_screenbase:
+ if (info->screen_base)
+ iounmap(info->screen_base);
+diff --git a/include/linux/decompress/unlzo.h b/include/linux/decompress/unlzo.h
+new file mode 100644
+index 0000000..9872297
+--- /dev/null
++++ b/include/linux/decompress/unlzo.h
+@@ -0,0 +1,10 @@
++#ifndef DECOMPRESS_UNLZO_H
++#define DECOMPRESS_UNLZO_H
++
++int unlzo(unsigned char *inbuf, int len,
++ int(*fill)(void*, unsigned int),
++ int(*flush)(void*, unsigned int),
++ unsigned char *output,
++ int *pos,
++ void(*error)(char *x));
++#endif
+diff --git a/init/Kconfig b/init/Kconfig
+index eb4b337..da6c4dd 100644
+--- a/init/Kconfig
++++ b/init/Kconfig
+@@ -115,10 +115,13 @@ config HAVE_KERNEL_BZIP2
+ config HAVE_KERNEL_LZMA
+ bool
+
++config HAVE_KERNEL_LZO
++ bool
++
+ choice
+ prompt "Kernel compression mode"
+ default KERNEL_GZIP
+- depends on HAVE_KERNEL_GZIP || HAVE_KERNEL_BZIP2 || HAVE_KERNEL_LZMA
++ depends on HAVE_KERNEL_GZIP || HAVE_KERNEL_BZIP2 || HAVE_KERNEL_LZMA || HAVE_KERNEL_LZO
+ help
+ The linux kernel is a kind of self-extracting executable.
+ Several compression algorithms are available, which differ
+@@ -141,9 +144,8 @@ config KERNEL_GZIP
+ bool "Gzip"
+ depends on HAVE_KERNEL_GZIP
+ help
+- The old and tried gzip compression. Its compression ratio is
+- the poorest among the 3 choices; however its speed (both
+- compression and decompression) is the fastest.
++ The old and tried gzip compression. It provides a good balance
++ between compression ration and decompression speed.
+
+ config KERNEL_BZIP2
+ bool "Bzip2"
+@@ -164,6 +166,14 @@ config KERNEL_LZMA
+ two. Compression is slowest. The kernel size is about 33%
+ smaller with LZMA in comparison to gzip.
+
++config KERNEL_LZO
++ bool "LZO"
++ depends on HAVE_KERNEL_LZO
++ help
++ Its compression ratio is the poorest among the 4. The kernel
++ size is about about 10% bigger than gzip; however its speed
++ (both compression and decompression) is the fastest.
++
+ endchoice
+
+ config SWAP
+diff --git a/lib/decompress_unlzo.c b/lib/decompress_unlzo.c
+new file mode 100644
+index 0000000..2bb736f
+--- /dev/null
++++ b/lib/decompress_unlzo.c
+@@ -0,0 +1,208 @@
++/*
++ * LZO decompressor for the Linux kernel. Code borrowed from the lzo
++ * implementation by Markus Franz Xaver Johannes Oberhumer.
++ *
++ * Linux kernel adaptation:
++ * Copyright (C) 2009
++ * Albin Tonnerre, Free Electrons <albin.tonnerre@free-electrons.com>
++ *
++ * Original code:
++ * Copyright (C) 1996-2005 Markus Franz Xaver Johannes Oberhumer
++ * All Rights Reserved.
++ *
++ * lzop and the LZO library are free software; you can redistribute them
++ * and/or modify them 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; see the file COPYING.
++ * If not, write to the Free Software Foundation, Inc.,
++ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++ *
++ * Markus F.X.J. Oberhumer
++ * <markus@oberhumer.com>
++ * http://www.oberhumer.com/opensource/lzop/
++ */
++
++#ifdef STATIC
++#include "lzo/lzo1x_decompress.c"
++#else
++#include <linux/slab.h>
++#include <linux/decompress/unlzo.h>
++#endif
++
++#include <linux/types.h>
++#include <linux/lzo.h>
++#include <linux/decompress/mm.h>
++
++#include <linux/compiler.h>
++#include <asm/unaligned.h>
++
++static const unsigned char lzop_magic[] =
++ { 0x89, 0x4c, 0x5a, 0x4f, 0x00, 0x0d, 0x0a, 0x1a, 0x0a };
++
++#define LZO_BLOCK_SIZE (256*1024l)
++#define HEADER_HAS_FILTER 0x00000800L
++
++STATIC inline int INIT parse_header(u8 *input, u8 *skip)
++{
++ int l;
++ u8 *parse = input;
++ u8 level = 0;
++ u16 version;
++
++ /* read magic: 9 first bits */
++ for (l = 0; l < 9; l++) {
++ if (*parse++ != lzop_magic[l])
++ return 0;
++ }
++ /* get version (2bytes), skip library version (2),
++ * 'need to be extracted' version (2) and
++ * method (1) */
++ version = get_unaligned_be16(parse);
++ parse += 7;
++ if (version >= 0x0940)
++ level = *parse++;
++ if (get_unaligned_be32(parse) & HEADER_HAS_FILTER)
++ parse += 8; /* flags + filter info */
++ else
++ parse += 4; /* flags */
++
++ /* skip mode and mtime_low */
++ parse += 8;
++ if (version >= 0x0940)
++ parse += 4; /* skip mtime_high */
++
++ l = *parse++;
++ /* don't care about the file name, and skip checksum */
++ parse += l + 4;
++
++ *skip = parse - input;
++ return 1;
++}
++
++STATIC inline int INIT unlzo(u8 *input, int in_len,
++ int (*fill) (void *, unsigned int),
++ int (*flush) (void *, unsigned int),
++ u8 *output, int *posp,
++ void (*error_fn) (char *x))
++{
++ u8 skip = 0, r = 0;
++ u32 src_len, dst_len;
++ size_t tmp;
++ u8 *in_buf, *in_buf_save, *out_buf;
++ int obytes_processed = 0;
++
++ set_error_fn(error_fn);
++
++ if (output)
++ out_buf = output;
++ else if (!flush) {
++ error("NULL output pointer and no flush function provided");
++ goto exit;
++ } else {
++ out_buf = malloc(LZO_BLOCK_SIZE);
++ if (!out_buf) {
++ error("Could not allocate output buffer");
++ goto exit;
++ }
++ }
++
++ if (input && fill) {
++ error("Both input pointer and fill function provided, don't know what to do");
++ goto exit_1;
++ } else if (input)
++ in_buf = input;
++ else if (!fill || !posp) {
++ error("NULL input pointer and missing position pointer or fill function");
++ goto exit_1;
++ } else {
++ in_buf = malloc(lzo1x_worst_compress(LZO_BLOCK_SIZE));
++ if (!in_buf) {
++ error("Could not allocate input buffer");
++ goto exit_1;
++ }
++ }
++ in_buf_save = in_buf;
++
++ if (posp)
++ *posp = 0;
++
++ if (fill)
++ fill(in_buf, lzo1x_worst_compress(LZO_BLOCK_SIZE));
++
++ if (!parse_header(input, &skip)) {
++ error("invalid header");
++ goto exit_2;
++ }
++ in_buf += skip;
++
++ if (posp)
++ *posp = skip;
++
++ for (;;) {
++ /* read uncompressed block size */
++ dst_len = get_unaligned_be32(in_buf);
++ in_buf += 4;
++
++ /* exit if last block */
++ if (dst_len == 0) {
++ if (posp)
++ *posp += 4;
++ break;
++ }
++
++ if (dst_len > LZO_BLOCK_SIZE) {
++ error("dest len longer than block size");
++ goto exit_2;
++ }
++
++ /* read compressed block size, and skip block checksum info */
++ src_len = get_unaligned_be32(in_buf);
++ in_buf += 8;
++
++ if (src_len <= 0 || src_len > dst_len) {
++ error("file corrupted");
++ goto exit_2;
++ }
++
++ /* decompress */
++ tmp = dst_len;
++ r = lzo1x_decompress_safe((u8 *) in_buf, src_len, out_buf, &tmp);
++
++ if (r != LZO_E_OK || dst_len != tmp) {
++ error("Compressed data violation");
++ goto exit_2;
++ }
++
++ obytes_processed += dst_len;
++ if (flush)
++ flush(out_buf, dst_len);
++ if (output)
++ out_buf += dst_len;
++ if (posp)
++ *posp += src_len + 12;
++ if (fill) {
++ in_buf = in_buf_save;
++ fill(in_buf, lzo1x_worst_compress(LZO_BLOCK_SIZE));
++ } else
++ in_buf += src_len;
++ }
++
++exit_2:
++ if (!input)
++ free(in_buf);
++exit_1:
++ if (!output)
++ free(out_buf);
++exit:
++ return obytes_processed;
++}
++
++#define decompress unlzo
+diff --git a/lib/lzo/lzo1x_decompress.c b/lib/lzo/lzo1x_decompress.c
+index 5dc6b29..f2fd098 100644
+--- a/lib/lzo/lzo1x_decompress.c
++++ b/lib/lzo/lzo1x_decompress.c
+@@ -11,11 +11,13 @@
+ * Richard Purdie <rpurdie@openedhand.com>
+ */
+
++#ifndef STATIC
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+-#include <linux/lzo.h>
+-#include <asm/byteorder.h>
++#endif
++
+ #include <asm/unaligned.h>
++#include <linux/lzo.h>
+ #include "lzodefs.h"
+
+ #define HAVE_IP(x, ip_end, ip) ((size_t)(ip_end - ip) < (x))
+@@ -244,9 +246,10 @@ lookbehind_overrun:
+ *out_len = op - out;
+ return LZO_E_LOOKBEHIND_OVERRUN;
+ }
+-
++#ifndef STATIC
+ EXPORT_SYMBOL_GPL(lzo1x_decompress_safe);
+
+ MODULE_LICENSE("GPL");
+ MODULE_DESCRIPTION("LZO1X Decompressor");
+
++#endif
+diff --git a/net/rfkill/core.c b/net/rfkill/core.c
+index a001f7c..f5c3704 100644
+--- a/net/rfkill/core.c
++++ b/net/rfkill/core.c
+@@ -111,7 +111,7 @@ static LIST_HEAD(rfkill_list); /* list of registered rf switches */
+ static DEFINE_MUTEX(rfkill_global_mutex);
+ static LIST_HEAD(rfkill_fds); /* list of open fds of /dev/rfkill */
+
+-static unsigned int rfkill_default_state = 1;
++static unsigned int rfkill_default_state = 0;
+ module_param_named(default_state, rfkill_default_state, uint, 0444);
+ MODULE_PARM_DESC(default_state,
+ "Default initial state for all radio types, 0 = radio off");
+diff --git a/scripts/Makefile.build b/scripts/Makefile.build
+index 341b589..0b94d2f 100644
+--- a/scripts/Makefile.build
++++ b/scripts/Makefile.build
+@@ -207,6 +207,7 @@ endif
+
+ ifdef CONFIG_FTRACE_MCOUNT_RECORD
+ cmd_record_mcount = set -e ; perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \
++ "$(if $(CONFIG_CPU_BIG_ENDIAN),big,little)" \
+ "$(if $(CONFIG_64BIT),64,32)" \
+ "$(OBJDUMP)" "$(OBJCOPY)" "$(CC)" "$(LD)" "$(NM)" "$(RM)" "$(MV)" \
+ "$(if $(part-of-module),1,0)" "$(@)";
+diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
+index ffdafb2..39c3483 100644
+--- a/scripts/Makefile.lib
++++ b/scripts/Makefile.lib
+@@ -230,3 +230,8 @@ quiet_cmd_lzma = LZMA $@
+ cmd_lzma = (cat $(filter-out FORCE,$^) | \
+ lzma -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \
+ (rm -f $@ ; false)
++
++quiet_cmd_lzo = LZO $@
++cmd_lzo = (cat $(filter-out FORCE,$^) | \
++ lzop -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \
++ (rm -f $@ ; false)
+diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl
+index 090d300..d016c71 100755
+--- a/scripts/recordmcount.pl
++++ b/scripts/recordmcount.pl
+@@ -99,13 +99,13 @@ $P =~ s@.*/@@g;
+
+ my $V = '0.1';
+
+-if ($#ARGV < 7) {
+- print "usage: $P arch bits objdump objcopy cc ld nm rm mv is_module inputfile\n";
++if ($#ARGV != 11) {
++ print "usage: $P arch endian bits objdump objcopy cc ld nm rm mv is_module inputfile\n";
+ print "version: $V\n";
+ exit(1);
+ }
+
+-my ($arch, $bits, $objdump, $objcopy, $cc,
++my ($arch, $endian, $bits, $objdump, $objcopy, $cc,
+ $ld, $nm, $rm, $mv, $is_module, $inputfile) = @ARGV;
+
+ # This file refers to mcount and shouldn't be ftraced, so lets' ignore it
+@@ -245,6 +245,60 @@ if ($arch eq "x86_64") {
+ $ld .= " -m elf64_sparc";
+ $cc .= " -m64";
+ $objcopy .= " -O elf64-sparc";
++
++} elsif ($arch eq "mips") {
++ # To enable module support, we need to enable the -mlong-calls option
++ # of gcc for module, after using this option, we can not get the real
++ # offset of the calling to _mcount, but the offset of the lui
++ # instruction or the addiu one. herein, we record the address of the
++ # first one, and then we can replace this instruction by a branch
++ # instruction to jump over the profiling function to filter the
++ # indicated functions, or swith back to the lui instruction to trace
++ # them, which means dynamic tracing.
++ #
++ # c: 3c030000 lui v1,0x0
++ # c: R_MIPS_HI16 _mcount
++ # c: R_MIPS_NONE *ABS*
++ # c: R_MIPS_NONE *ABS*
++ # 10: 64630000 daddiu v1,v1,0
++ # 10: R_MIPS_LO16 _mcount
++ # 10: R_MIPS_NONE *ABS*
++ # 10: R_MIPS_NONE *ABS*
++ # 14: 03e0082d move at,ra
++ # 18: 0060f809 jalr v1
++ #
++ # for the kernel:
++ #
++ # 10: 03e0082d move at,ra
++ # 14: 0c000000 jal 0 <loongson_halt>
++ # 14: R_MIPS_26 _mcount
++ # 14: R_MIPS_NONE *ABS*
++ # 14: R_MIPS_NONE *ABS*
++ # 18: 00020021 nop
++ if ($is_module eq "0") {
++ $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s_mcount\$";
++ } else {
++ $mcount_regex = "^\\s*([0-9a-fA-F]+): R_MIPS_HI16\\s+_mcount\$";
++ }
++ $objdump .= " -Melf-trad".$endian."mips ";
++
++ if ($endian eq "big") {
++ $endian = " -EB ";
++ $ld .= " -melf".$bits."btsmip";
++ } else {
++ $endian = " -EL ";
++ $ld .= " -melf".$bits."ltsmip";
++ }
++
++ $cc .= " -mno-abicalls -fno-pic -mabi=" . $bits . $endian;
++ $ld .= $endian;
++
++ if ($bits == 64) {
++ $function_regex =
++ "^([0-9a-fA-F]+)\\s+<(.|[^\$]L.*?|\$[^L].*?|[^\$][^L].*?)>:";
++ $type = ".dword";
++ }
++
+ } else {
+ die "Arch $arch is not supported with CONFIG_FTRACE_MCOUNT_RECORD";
+ }
+diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
+index ab73edf..2779b9a 100644
+--- a/sound/core/pcm_native.c
++++ b/sound/core/pcm_native.c
+@@ -3087,7 +3087,11 @@ static int snd_pcm_mmap_data_fault(struct vm_area_struct *area,
+ return VM_FAULT_SIGBUS;
+ } else {
+ vaddr = runtime->dma_area + offset;
++#if defined(__mips__) && defined(CONFIG_DMA_NONCOHERENT)
++ page = virt_to_page(CAC_ADDR(vaddr));
++#else
+ page = virt_to_page(vaddr);
++#endif
+ }
+ get_page(page);
+ vmf->page = page;
+@@ -3202,6 +3206,11 @@ static int snd_pcm_mmap(struct file *file, struct vm_area_struct *area)
+ if (PCM_RUNTIME_CHECK(substream))
+ return -ENXIO;
+
++#if defined(__mips__) && defined(CONFIG_DMA_NONCOHERENT)
++ /* all mmap using uncached mode */
++ area->vm_page_prot = pgprot_noncached(area->vm_page_prot);
++ area->vm_flags |= (VM_RESERVED | VM_IO);
++#endif
+ offset = area->vm_pgoff << PAGE_SHIFT;
+ switch (offset) {
+ case SNDRV_PCM_MMAP_OFFSET_STATUS:
+diff --git a/sound/core/sgbuf.c b/sound/core/sgbuf.c
+index 4e7ec2b..c0fcf0d 100644
+--- a/sound/core/sgbuf.c
++++ b/sound/core/sgbuf.c
+@@ -114,7 +114,11 @@ void *snd_malloc_sgbuf_pages(struct device *device,
+ if (!i)
+ table->addr |= chunk; /* mark head */
+ table++;
++#if defined(__mips__) && defined(CONFIG_DMA_NONCOHERENT)
++ *pgtable++ = virt_to_page(CAC_ADDR(tmpb.area));
++#else
+ *pgtable++ = virt_to_page(tmpb.area);
++#endif
+ tmpb.area += PAGE_SIZE;
+ tmpb.addr += PAGE_SIZE;
+ }
+@@ -125,7 +129,12 @@ void *snd_malloc_sgbuf_pages(struct device *device,
+ }
+
+ sgbuf->size = size;
++#if defined(__mips__) && defined(CONFIG_DMA_NONCOHERENT)
++ dmab->area = vmap(sgbuf->page_table, sgbuf->pages, \
++ VM_MAP | VM_IO, pgprot_noncached(PAGE_KERNEL));
++#else
+ dmab->area = vmap(sgbuf->page_table, sgbuf->pages, VM_MAP, PAGE_KERNEL);
++#endif
+ if (! dmab->area)
+ goto _failed;
+ if (res_size)
+diff --git a/sound/oss/au1550_ac97.c b/sound/oss/au1550_ac97.c
+index 4191acc..c1070e3 100644
+--- a/sound/oss/au1550_ac97.c
++++ b/sound/oss/au1550_ac97.c
+@@ -614,7 +614,8 @@ start_adc(struct au1550_state *s)
+ /* Put two buffers on the ring to get things started.
+ */
+ for (i=0; i<2; i++) {
+- au1xxx_dbdma_put_dest(db->dmanr, db->nextIn, db->dma_fragsize);
++ au1xxx_dbdma_put_dest(db->dmanr, virt_to_phys(db->nextIn),
++ db->dma_fragsize, DDMA_FLAGS_IE);
+
+ db->nextIn += db->dma_fragsize;
+ if (db->nextIn >= db->rawbuf + db->dmasize)
+@@ -732,8 +733,9 @@ static void dac_dma_interrupt(int irq, void *dev_id)
+ db->dma_qcount--;
+
+ if (db->count >= db->fragsize) {
+- if (au1xxx_dbdma_put_source(db->dmanr, db->nextOut,
+- db->fragsize) == 0) {
++ if (au1xxx_dbdma_put_source(db->dmanr,
++ virt_to_phys(db->nextOut), db->fragsize,
++ DDMA_FLAGS_IE) == 0) {
+ err("qcount < 2 and no ring room!");
+ }
+ db->nextOut += db->fragsize;
+@@ -777,7 +779,8 @@ static void adc_dma_interrupt(int irq, void *dev_id)
+
+ /* Put a new empty buffer on the destination DMA.
+ */
+- au1xxx_dbdma_put_dest(dp->dmanr, dp->nextIn, dp->dma_fragsize);
++ au1xxx_dbdma_put_dest(dp->dmanr, virt_to_phys(dp->nextIn),
++ dp->dma_fragsize, DDMA_FLAGS_IE);
+
+ dp->nextIn += dp->dma_fragsize;
+ if (dp->nextIn >= dp->rawbuf + dp->dmasize)
+@@ -1177,8 +1180,9 @@ au1550_write(struct file *file, const char *buffer, size_t count, loff_t * ppos)
+ * we know the dma has stopped.
+ */
+ while ((db->dma_qcount < 2) && (db->count >= db->fragsize)) {
+- if (au1xxx_dbdma_put_source(db->dmanr, db->nextOut,
+- db->fragsize) == 0) {
++ if (au1xxx_dbdma_put_source(db->dmanr,
++ virt_to_phys(db->nextOut), db->fragsize,
++ DDMA_FLAGS_IE) == 0) {
+ err("qcount < 2 and no ring room!");
+ }
+ db->nextOut += db->fragsize;
+diff --git a/sound/soc/au1x/Kconfig b/sound/soc/au1x/Kconfig
+index 410a893..4b67140 100644
+--- a/sound/soc/au1x/Kconfig
++++ b/sound/soc/au1x/Kconfig
+@@ -22,11 +22,13 @@ config SND_SOC_AU1XPSC_AC97
+ ##
+ ## Boards
+ ##
+-config SND_SOC_SAMPLE_PSC_AC97
+- tristate "Sample Au12x0/Au1550 PSC AC97 sound machine"
++config SND_SOC_DB1200
++ tristate "DB1200 AC97+I2S audio support"
+ depends on SND_SOC_AU1XPSC
+ select SND_SOC_AU1XPSC_AC97
+ select SND_SOC_AC97_CODEC
++ select SND_SOC_AU1XPSC_I2S
++ select SND_SOC_WM8731
+ help
+- This is a sample AC97 sound machine for use in Au12x0/Au1550
+- based systems which have audio on PSC1 (e.g. Db1200 demoboard).
++ Select this option to enable audio (AC97 or I2S) on the
++ Alchemy/AMD/RMI DB1200 demoboard.
+diff --git a/sound/soc/au1x/Makefile b/sound/soc/au1x/Makefile
+index 6c6950b..1687307 100644
+--- a/sound/soc/au1x/Makefile
++++ b/sound/soc/au1x/Makefile
+@@ -8,6 +8,6 @@ obj-$(CONFIG_SND_SOC_AU1XPSC_I2S) += snd-soc-au1xpsc-i2s.o
+ obj-$(CONFIG_SND_SOC_AU1XPSC_AC97) += snd-soc-au1xpsc-ac97.o
+
+ # Boards
+-snd-soc-sample-ac97-objs := sample-ac97.o
++snd-soc-db1200-objs := db1200.o
+
+-obj-$(CONFIG_SND_SOC_SAMPLE_PSC_AC97) += snd-soc-sample-ac97.o
++obj-$(CONFIG_SND_SOC_DB1200) += snd-soc-db1200.o
+diff --git a/sound/soc/au1x/db1200.c b/sound/soc/au1x/db1200.c
+new file mode 100644
+index 0000000..cdf7be1
+--- /dev/null
++++ b/sound/soc/au1x/db1200.c
+@@ -0,0 +1,141 @@
++/*
++ * DB1200 ASoC audio fabric support code.
++ *
++ * (c) 2008-9 Manuel Lauss <manuel.lauss@gmail.com>
++ *
++ */
++
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/timer.h>
++#include <linux/interrupt.h>
++#include <linux/platform_device.h>
++#include <sound/core.h>
++#include <sound/pcm.h>
++#include <sound/soc.h>
++#include <sound/soc-dapm.h>
++#include <asm/mach-au1x00/au1000.h>
++#include <asm/mach-au1x00/au1xxx_psc.h>
++#include <asm/mach-au1x00/au1xxx_dbdma.h>
++#include <asm/mach-db1x00/bcsr.h>
++
++#include "../codecs/ac97.h"
++#include "../codecs/wm8731.h"
++#include "psc.h"
++
++/*------------------------- AC97 PART ---------------------------*/
++
++static struct snd_soc_dai_link db1200_ac97_dai = {
++ .name = "AC97",
++ .stream_name = "AC97 HiFi",
++ .cpu_dai = &au1xpsc_ac97_dai,
++ .codec_dai = &ac97_dai,
++};
++
++static struct snd_soc_card db1200_ac97_machine = {
++ .name = "DB1200_AC97",
++ .dai_link = &db1200_ac97_dai,
++ .num_links = 1,
++ .platform = &au1xpsc_soc_platform,
++};
++
++static struct snd_soc_device db1200_ac97_devdata = {
++ .card = &db1200_ac97_machine,
++ .codec_dev = &soc_codec_dev_ac97,
++};
++
++/*------------------------- I2S PART ---------------------------*/
++
++static int db1200_i2s_startup(struct snd_pcm_substream *substream)
++{
++ struct snd_soc_pcm_runtime *rtd = substream->private_data;
++ struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
++ struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
++ int ret;
++
++ /* WM8731 has its own 12MHz crystal */
++ snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK,
++ 12000000, SND_SOC_CLOCK_IN);
++
++ /* codec is bitclock and lrclk master */
++ ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_LEFT_J |
++ SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
++ if (ret < 0)
++ goto out;
++
++ ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_LEFT_J |
++ SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
++ if (ret < 0)
++ goto out;
++
++ ret = 0;
++out:
++ return ret;
++}
++
++static struct snd_soc_ops db1200_i2s_wm8731_ops = {
++ .startup = db1200_i2s_startup,
++};
++
++static struct snd_soc_dai_link db1200_i2s_dai = {
++ .name = "WM8731",
++ .stream_name = "WM8731 PCM",
++ .cpu_dai = &au1xpsc_i2s_dai,
++ .codec_dai = &wm8731_dai,
++ .ops = &db1200_i2s_wm8731_ops,
++};
++
++static struct snd_soc_card db1200_i2s_machine = {
++ .name = "DB1200_I2S",
++ .dai_link = &db1200_i2s_dai,
++ .num_links = 1,
++ .platform = &au1xpsc_soc_platform,
++};
++
++static struct snd_soc_device db1200_i2s_devdata = {
++ .card = &db1200_i2s_machine,
++ .codec_dev = &soc_codec_dev_wm8731,
++};
++
++/*------------------------- COMMON PART ---------------------------*/
++
++static struct platform_device *db1200_asoc_dev;
++
++static int __init db1200_audio_load(void)
++{
++ int ret;
++
++ ret = -ENOMEM;
++ db1200_asoc_dev = platform_device_alloc("soc-audio", -1);
++ if (!db1200_asoc_dev)
++ goto out;
++
++ /* DB1200 board setup set PSC1MUX to preferred audio device */
++ if (bcsr_read(BCSR_RESETS) & BCSR_RESETS_PSC1MUX)
++ platform_set_drvdata(db1200_asoc_dev, &db1200_i2s_devdata);
++ else
++ platform_set_drvdata(db1200_asoc_dev, &db1200_ac97_devdata);
++
++ db1200_ac97_devdata.dev = &db1200_asoc_dev->dev;
++ db1200_i2s_devdata.dev = &db1200_asoc_dev->dev;
++ ret = platform_device_add(db1200_asoc_dev);
++
++ if (ret) {
++ platform_device_put(db1200_asoc_dev);
++ db1200_asoc_dev = NULL;
++ }
++out:
++ return ret;
++}
++
++static void __exit db1200_audio_unload(void)
++{
++ platform_device_unregister(db1200_asoc_dev);
++}
++
++module_init(db1200_audio_load);
++module_exit(db1200_audio_unload);
++
++MODULE_LICENSE("GPL");
++MODULE_DESCRIPTION("DB1200 ASoC audio support");
++MODULE_AUTHOR("Manuel Lauss");
+diff --git a/sound/soc/au1x/dbdma2.c b/sound/soc/au1x/dbdma2.c
+index 594c6c5..72617d7 100644
+--- a/sound/soc/au1x/dbdma2.c
++++ b/sound/soc/au1x/dbdma2.c
+@@ -51,8 +51,8 @@ struct au1xpsc_audio_dmadata {
+ struct snd_pcm_substream *substream;
+ unsigned long curr_period; /* current segment DDMA is working on */
+ unsigned long q_period; /* queue period(s) */
+- unsigned long dma_area; /* address of queued DMA area */
+- unsigned long dma_area_s; /* start address of DMA area */
++ dma_addr_t dma_area; /* address of queued DMA area */
++ dma_addr_t dma_area_s; /* start address of DMA area */
+ unsigned long pos; /* current byte position being played */
+ unsigned long periods; /* number of SG segments in total */
+ unsigned long period_bytes; /* size in bytes of one SG segment */
+@@ -94,8 +94,7 @@ static const struct snd_pcm_hardware au1xpsc_pcm_hardware = {
+
+ static void au1x_pcm_queue_tx(struct au1xpsc_audio_dmadata *cd)
+ {
+- au1xxx_dbdma_put_source_flags(cd->ddma_chan,
+- (void *)phys_to_virt(cd->dma_area),
++ au1xxx_dbdma_put_source(cd->ddma_chan, cd->dma_area,
+ cd->period_bytes, DDMA_FLAGS_IE);
+
+ /* update next-to-queue period */
+@@ -109,9 +108,8 @@ static void au1x_pcm_queue_tx(struct au1xpsc_audio_dmadata *cd)
+
+ static void au1x_pcm_queue_rx(struct au1xpsc_audio_dmadata *cd)
+ {
+- au1xxx_dbdma_put_dest_flags(cd->ddma_chan,
+- (void *)phys_to_virt(cd->dma_area),
+- cd->period_bytes, DDMA_FLAGS_IE);
++ au1xxx_dbdma_put_dest(cd->ddma_chan, cd->dma_area,
++ cd->period_bytes, DDMA_FLAGS_IE);
+
+ /* update next-to-queue period */
+ ++cd->q_period;
+@@ -233,7 +231,7 @@ static int au1xpsc_pcm_hw_params(struct snd_pcm_substream *substream,
+ pcd->substream = substream;
+ pcd->period_bytes = params_period_bytes(params);
+ pcd->periods = params_periods(params);
+- pcd->dma_area_s = pcd->dma_area = (unsigned long)runtime->dma_addr;
++ pcd->dma_area_s = pcd->dma_area = runtime->dma_addr;
+ pcd->q_period = 0;
+ pcd->curr_period = 0;
+ pcd->pos = 0;
+diff --git a/sound/soc/au1x/sample-ac97.c b/sound/soc/au1x/sample-ac97.c
+deleted file mode 100644
+index 27683eb..0000000
+--- a/sound/soc/au1x/sample-ac97.c
++++ /dev/null
+@@ -1,144 +0,0 @@
+-/*
+- * Sample Au12x0/Au1550 PSC AC97 sound machine.
+- *
+- * Copyright (c) 2007-2008 Manuel Lauss <mano@roarinelk.homelinux.net>
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms outlined in the file COPYING at the root of this
+- * source archive.
+- *
+- * This is a very generic AC97 sound machine driver for boards which
+- * have (AC97) audio at PSC1 (e.g. DB1200 demoboards).
+- */
+-
+-#include <linux/module.h>
+-#include <linux/moduleparam.h>
+-#include <linux/timer.h>
+-#include <linux/interrupt.h>
+-#include <linux/platform_device.h>
+-#include <sound/core.h>
+-#include <sound/pcm.h>
+-#include <sound/soc.h>
+-#include <sound/soc-dapm.h>
+-#include <asm/mach-au1x00/au1000.h>
+-#include <asm/mach-au1x00/au1xxx_psc.h>
+-#include <asm/mach-au1x00/au1xxx_dbdma.h>
+-
+-#include "../codecs/ac97.h"
+-#include "psc.h"
+-
+-static int au1xpsc_sample_ac97_init(struct snd_soc_codec *codec)
+-{
+- snd_soc_dapm_sync(codec);
+- return 0;
+-}
+-
+-static struct snd_soc_dai_link au1xpsc_sample_ac97_dai = {
+- .name = "AC97",
+- .stream_name = "AC97 HiFi",
+- .cpu_dai = &au1xpsc_ac97_dai, /* see psc-ac97.c */
+- .codec_dai = &ac97_dai, /* see codecs/ac97.c */
+- .init = au1xpsc_sample_ac97_init,
+- .ops = NULL,
+-};
+-
+-static struct snd_soc_card au1xpsc_sample_ac97_machine = {
+- .name = "Au1xxx PSC AC97 Audio",
+- .dai_link = &au1xpsc_sample_ac97_dai,
+- .num_links = 1,
+-};
+-
+-static struct snd_soc_device au1xpsc_sample_ac97_devdata = {
+- .card = &au1xpsc_sample_ac97_machine,
+- .platform = &au1xpsc_soc_platform, /* see dbdma2.c */
+- .codec_dev = &soc_codec_dev_ac97,
+-};
+-
+-static struct resource au1xpsc_psc1_res[] = {
+- [0] = {
+- .start = CPHYSADDR(PSC1_BASE_ADDR),
+- .end = CPHYSADDR(PSC1_BASE_ADDR) + 0x000fffff,
+- .flags = IORESOURCE_MEM,
+- },
+- [1] = {
+-#ifdef CONFIG_SOC_AU1200
+- .start = AU1200_PSC1_INT,
+- .end = AU1200_PSC1_INT,
+-#elif defined(CONFIG_SOC_AU1550)
+- .start = AU1550_PSC1_INT,
+- .end = AU1550_PSC1_INT,
+-#endif
+- .flags = IORESOURCE_IRQ,
+- },
+- [2] = {
+- .start = DSCR_CMD0_PSC1_TX,
+- .end = DSCR_CMD0_PSC1_TX,
+- .flags = IORESOURCE_DMA,
+- },
+- [3] = {
+- .start = DSCR_CMD0_PSC1_RX,
+- .end = DSCR_CMD0_PSC1_RX,
+- .flags = IORESOURCE_DMA,
+- },
+-};
+-
+-static struct platform_device *au1xpsc_sample_ac97_dev;
+-
+-static int __init au1xpsc_sample_ac97_load(void)
+-{
+- int ret;
+-
+-#ifdef CONFIG_SOC_AU1200
+- unsigned long io;
+-
+- /* modify sys_pinfunc for AC97 on PSC1 */
+- io = au_readl(SYS_PINFUNC);
+- io |= SYS_PINFUNC_P1C;
+- io &= ~(SYS_PINFUNC_P1A | SYS_PINFUNC_P1B);
+- au_writel(io, SYS_PINFUNC);
+- au_sync();
+-#endif
+-
+- ret = -ENOMEM;
+-
+- /* setup PSC clock source for AC97 part: external clock provided
+- * by codec. The psc-ac97.c driver depends on this setting!
+- */
+- au_writel(PSC_SEL_CLK_SERCLK, PSC1_BASE_ADDR + PSC_SEL_OFFSET);
+- au_sync();
+-
+- au1xpsc_sample_ac97_dev = platform_device_alloc("soc-audio", -1);
+- if (!au1xpsc_sample_ac97_dev)
+- goto out;
+-
+- au1xpsc_sample_ac97_dev->resource =
+- kmemdup(au1xpsc_psc1_res, sizeof(struct resource) *
+- ARRAY_SIZE(au1xpsc_psc1_res), GFP_KERNEL);
+- au1xpsc_sample_ac97_dev->num_resources = ARRAY_SIZE(au1xpsc_psc1_res);
+- au1xpsc_sample_ac97_dev->id = 1;
+-
+- platform_set_drvdata(au1xpsc_sample_ac97_dev,
+- &au1xpsc_sample_ac97_devdata);
+- au1xpsc_sample_ac97_devdata.dev = &au1xpsc_sample_ac97_dev->dev;
+- ret = platform_device_add(au1xpsc_sample_ac97_dev);
+-
+- if (ret) {
+- platform_device_put(au1xpsc_sample_ac97_dev);
+- au1xpsc_sample_ac97_dev = NULL;
+- }
+-
+-out:
+- return ret;
+-}
+-
+-static void __exit au1xpsc_sample_ac97_exit(void)
+-{
+- platform_device_unregister(au1xpsc_sample_ac97_dev);
+-}
+-
+-module_init(au1xpsc_sample_ac97_load);
+-module_exit(au1xpsc_sample_ac97_exit);
+-
+-MODULE_LICENSE("GPL");
+-MODULE_DESCRIPTION("Au1xxx PSC sample AC97 machine");
+-MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>");
diff --git a/lemote/gnewsense/tags/2.6.32-libre-lemote_0lxo/2.6.32-yeeloong-battery.patch b/lemote/gnewsense/tags/2.6.32-libre-lemote_0lxo/2.6.32-yeeloong-battery.patch
new file mode 100644
index 000000000..176e34466
--- /dev/null
+++ b/lemote/gnewsense/tags/2.6.32-libre-lemote_0lxo/2.6.32-yeeloong-battery.patch
@@ -0,0 +1,401 @@
+This is taken from the 2.6.31.6 Lemote patchset. yeeloong_battery.c
+used to be in drivers/platform/loongson, now moved to
+arch/mips/loongson/lemote-2f. Changed to include ec_kb3310b.h instead
+of ec/kb3310b.h, and adjusted calls to
+yeeloong_sci_{,un}install_handler, formerly *_event_handler. -lxoliva
+
+
+Index: arch/mips/loongson/lemote-2f/Makefile
+===================================================================
+--- arch/mips/loongson/lemote-2f/Makefile.orig 2009-12-12 20:51:06.000000000 -0200
++++ arch/mips/loongson/lemote-2f/Makefile 2009-12-12 20:51:07.000000000 -0200
+@@ -14,4 +14,4 @@ obj-$(CONFIG_LOONGSON_SUSPEND) += pm.o
+ # Platform Drivers
+ #
+ obj-$(CONFIG_LEMOTE_LYNLOONG2F_PDEV) += lynloong_pc.o
+-obj-$(CONFIG_LEMOTE_YEELOONG2F_PDEV) += yeeloong_laptop.o
++obj-$(CONFIG_LEMOTE_YEELOONG2F_PDEV) += yeeloong_laptop.o yeeloong_battery.o
+Index: arch/mips/loongson/lemote-2f/yeeloong_battery.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ arch/mips/loongson/lemote-2f/yeeloong_battery.c 2009-12-12 20:57:41.000000000 -0200
+@@ -0,0 +1,379 @@
++/*
++ * EC(Embedded Controller) KB3310B battery management driver on Linux
++ *
++ * Copyright (C) 2008 Lemote Inc.
++ * Author: liujl <liujl@lemote.com>
++ *
++ * NOTE: The SDA0/SCL0 in KB3310B are used to communicate with the battery
++ * IC, Here we use DS2786 IC to handle the battery management. All the
++ * resources for handle battery management in KB3310B are:
++ * 1, one SMBus interface with port 0
++ * 2, gpio40 output for charge enable
++ */
++
++#include <linux/module.h>
++#include <linux/poll.h>
++#include <linux/proc_fs.h>
++#include <linux/miscdevice.h>
++#include <linux/capability.h>
++#include <linux/sched.h>
++#include <linux/device.h>
++#include <linux/kernel.h>
++#include <linux/list.h>
++#include <linux/init.h>
++#include <linux/completion.h>
++#include <linux/delay.h>
++#include <linux/timer.h>
++
++#include <asm/delay.h>
++
++#include "ec_kb3310b.h"
++
++#ifndef APM_32_BIT_SUPPORT
++#define APM_32_BIT_SUPPORT 0x0002
++#endif
++
++/* The EC Battery device, here is his minor number. */
++#define ECBAT_MINOR_DEV MISC_DYNAMIC_MINOR
++
++/*
++ * apm threshold : percent unit.
++ */
++#define BAT_MAX_THRESHOLD 99
++#define BAT_MIN_THRESHOLD 5
++
++/*
++ * This structure gets filled in by the machine specific 'get_power_status'
++ * implementation. Any fields which are not set default to a safe value.
++ */
++struct apm_pwr_info {
++ unsigned char ac_line_status;
++#define APM_AC_OFFLINE 0
++#define APM_AC_ONLINE 1
++#define APM_AC_BACKUP 2
++#define APM_AC_UNKNOWN 0xff
++
++ unsigned char battery_status;
++#define APM_BATTERY_STATUS_HIGH 0
++#define APM_BATTERY_STATUS_LOW 1
++#define APM_BATTERY_STATUS_CRITICAL 2
++#define APM_BATTERY_STATUS_CHARGING 3
++#define APM_BATTERY_STATUS_NOT_PRESENT 4
++#define APM_BATTERY_STATUS_UNKNOWN 0xff
++
++ unsigned char battery_flag;
++#define APM_BATTERY_FLAG_HIGH (1 << 0)
++#define APM_BATTERY_FLAG_LOW (1 << 1)
++#define APM_BATTERY_FLAG_CRITICAL (1 << 2)
++#define APM_BATTERY_FLAG_CHARGING (1 << 3)
++#define APM_BATTERY_FLAG_NOT_PRESENT (1 << 7)
++#define APM_BATTERY_FLAG_UNKNOWN 0xff
++
++ int battery_life;
++ int time;
++ int units;
++#define APM_UNITS_MINS 0
++#define APM_UNITS_SECS 1
++#define APM_UNITS_UNKNOWN -1
++
++ /* battery designed capacity */
++ unsigned int bat_design_cap;
++ /* battery designed voltage */
++ unsigned int bat_design_vol;
++ /* battery capacity after full charged */
++ unsigned int bat_full_charged_cap;
++ /* battery vendor number */
++ unsigned char bat_vendor;
++ /* battery cell count */
++ unsigned char bat_cell_count;
++
++ /* battery dynamic charge/discharge voltage */
++ unsigned int bat_voltage;
++ /* battery dynamic charge/discharge current */
++ int bat_current;
++ /* battery current temperature */
++ unsigned int bat_temperature;
++};
++
++static DEFINE_MUTEX(bat_info_lock);
++struct bat_info {
++ unsigned int ac_in;
++ unsigned int bat_in;
++ unsigned int bat_flag;
++ /* we use capacity for caculating the life and time */
++ unsigned int curr_bat_cap;
++
++ /* battery designed capacity */
++ unsigned int bat_design_cap;
++ /* battery designed voltage */
++ unsigned int bat_design_vol;
++ /* battery capacity after full charged */
++ unsigned int bat_full_charged_cap;
++ /* battery vendor number */
++ unsigned char bat_vendor;
++ /* battery cell count */
++ unsigned char bat_cell_count;
++
++ /* battery dynamic charge/discharge voltage */
++ unsigned int bat_voltage;
++ /* battery dynamic charge/discharge current */
++ int bat_current;
++ /* battery current temperature */
++ unsigned int bat_temperature;
++} bat_info = {
++ .ac_in = APM_AC_UNKNOWN,
++ .bat_in = APM_BATTERY_STATUS_UNKNOWN,
++ .curr_bat_cap = 0,
++ /* fixed value */
++ .bat_design_cap = 0,
++ .bat_full_charged_cap = 0,
++ .bat_design_vol = 0,
++ .bat_vendor = 0,
++ .bat_cell_count = 0,
++ /* rest variable */
++ .bat_voltage = 0,
++ .bat_current = 0,
++ .bat_temperature = 0
++};
++
++/*
++ * 1.4 :
++ * 1, 89inch basic work version.
++ * 2, you should set xorg.conf ServerFlag of "NoPM" to true
++ * 1.5 :
++ * 1, bat_flag is added to struct bat_info.
++ * 2, BAT_MIN_THRESHOLD is changed to 5%.
++ */
++static const char driver_version[] = "1.38"; /* no spaces */
++
++static struct miscdevice apm_device = {
++ .minor = ECBAT_MINOR_DEV,
++ .name = "apm_bios",
++ .fops = NULL
++};
++
++static void get_battery_fixed_info(void)
++{
++ bat_info.bat_design_cap = (ec_read(REG_BAT_DESIGN_CAP_HIGH) << 8)
++ | ec_read(REG_BAT_DESIGN_CAP_LOW);
++ bat_info.bat_full_charged_cap = (ec_read(REG_BAT_FULLCHG_CAP_HIGH) << 8)
++ | ec_read(REG_BAT_FULLCHG_CAP_LOW);
++ bat_info.bat_design_vol = (ec_read(REG_BAT_DESIGN_VOL_HIGH) << 8)
++ | ec_read(REG_BAT_DESIGN_VOL_LOW);
++ bat_info.bat_vendor = ec_read(REG_BAT_VENDOR);
++ bat_info.bat_cell_count = ec_read(REG_BAT_CELL_COUNT);
++ if (bat_info.bat_vendor != 0) {
++ printk(KERN_INFO
++ "battery vendor(%s), cells count(%d), "
++ "with designed capacity(%d),designed voltage(%d),"
++ " full charged capacity(%d)\n",
++ (bat_info.bat_vendor ==
++ FLAG_BAT_VENDOR_SANYO) ? "SANYO" : "SIMPLO",
++ (bat_info.bat_cell_count == FLAG_BAT_CELL_3S1P) ? 3 : 6,
++ bat_info.bat_design_cap, bat_info.bat_design_vol,
++ bat_info.bat_full_charged_cap);
++ }
++}
++
++static void get_battery_variable_info(void)
++{
++ unsigned char bat_charge;
++ unsigned char power_flag;
++ unsigned char bat_status;
++ unsigned char charge_status;
++
++ mutex_lock(&bat_info_lock);
++
++ bat_charge = ec_read(REG_BAT_CHARGE);
++ power_flag = ec_read(REG_BAT_POWER);
++ bat_status = ec_read(REG_BAT_STATUS);
++ charge_status = ec_read(REG_BAT_CHARGE_STATUS);
++ bat_info.bat_voltage =
++ (ec_read(REG_BAT_VOLTAGE_HIGH) << 8) |
++ (ec_read(REG_BAT_VOLTAGE_LOW));
++ bat_info.bat_current =
++ (ec_read(REG_BAT_CURRENT_HIGH) << 8) |
++ (ec_read(REG_BAT_CURRENT_LOW));
++ bat_info.bat_temperature =
++ (ec_read(REG_BAT_TEMPERATURE_HIGH) << 8) |
++ (ec_read(REG_BAT_TEMPERATURE_LOW));
++ bat_info.curr_bat_cap =
++ (ec_read(REG_BAT_RELATIVE_CAP_HIGH) << 8) |
++ (ec_read(REG_BAT_RELATIVE_CAP_LOW));
++
++ bat_info.ac_in =
++ (power_flag & BIT_BAT_POWER_ACIN) ? APM_AC_ONLINE :
++ APM_AC_OFFLINE;
++ if (!(bat_status & BIT_BAT_STATUS_IN)) {
++ /* there is no battery inserted */
++ bat_info.bat_in = APM_BATTERY_STATUS_NOT_PRESENT;
++ bat_info.bat_flag = APM_BATTERY_FLAG_NOT_PRESENT;
++ } else {
++ /* there is adapter inserted */
++ if (bat_info.ac_in == APM_AC_ONLINE) {
++ /* if the battery is not fully charged */
++ if (!(bat_status & BIT_BAT_STATUS_FULL)) {
++ bat_info.bat_in =
++ APM_BATTERY_STATUS_CHARGING;
++ bat_info.bat_flag =
++ APM_BATTERY_FLAG_CHARGING;
++ } else {
++ /* if the battery is fully charged */
++ bat_info.bat_in =
++ APM_BATTERY_STATUS_HIGH;
++ bat_info.bat_flag =
++ APM_BATTERY_FLAG_HIGH;
++ bat_info.curr_bat_cap = 100;
++ }
++ } else {
++ /* if the battery is too low */
++ if (bat_status & BIT_BAT_STATUS_LOW) {
++ bat_info.bat_in =
++ APM_BATTERY_STATUS_LOW;
++ bat_info.bat_flag =
++ APM_BATTERY_FLAG_LOW;
++ if (bat_info.curr_bat_cap <=
++ BAT_MIN_THRESHOLD) {
++ bat_info.bat_in =
++ APM_BATTERY_STATUS_CRITICAL;
++ bat_info.bat_flag =
++ APM_BATTERY_FLAG_CRITICAL;
++ }
++ /* we should power off the system now */
++ } else {
++ /* assume the battery is high enough. */
++ bat_info.bat_in =
++ APM_BATTERY_STATUS_HIGH;
++ bat_info.bat_flag =
++ APM_BATTERY_FLAG_HIGH;
++ }
++ }
++ }
++
++ mutex_unlock(&bat_info_lock);
++}
++
++#ifdef CONFIG_PROC_FS
++static int bat_proc_read(char *page, char **start, off_t off, int count,
++ int *eof, void *data);
++static struct proc_dir_entry *bat_proc_entry;
++
++static int bat_proc_read(char *page, char **start, off_t off, int count,
++ int *eof, void *data)
++{
++ struct apm_pwr_info info;
++ char *units;
++ int ret;
++
++ /* get variable battery infomation */
++ get_battery_variable_info();
++
++ mutex_lock(&bat_info_lock);
++ info.battery_life = bat_info.curr_bat_cap;
++ info.ac_line_status = bat_info.ac_in;
++ info.battery_status = bat_info.bat_in;
++ info.battery_flag = bat_info.bat_flag;
++ info.bat_voltage = bat_info.bat_voltage;
++ if (bat_info.bat_current & 0x8000)
++ info.bat_current = 0xffff - bat_info.bat_current;
++ else
++ info.bat_current = bat_info.bat_current;
++ info.bat_temperature = bat_info.bat_temperature;
++
++ /* this should be charged according to the capacity-time flow. */
++ if (info.battery_status != APM_BATTERY_STATUS_NOT_PRESENT)
++ info.time = ((bat_info.curr_bat_cap - 3) * 54 + 142) / 60;
++ else
++ info.time = 0x00;
++ info.units = APM_UNITS_MINS;
++
++ mutex_unlock(&bat_info_lock);
++ switch (info.units) {
++ default:
++ units = "?";
++ break;
++ case 0:
++ units = "min";
++ break;
++ case 1:
++ units = "sec";
++ break;
++ }
++
++ ret =
++ sprintf(page,
++ "%s 1.2 0x%02x 0x%02x 0x%02x 0x%02x %d%% %d %s %dmV %dmA %d\n",
++ driver_version, APM_32_BIT_SUPPORT, info.ac_line_status,
++ info.battery_status, info.battery_flag, info.battery_life,
++ info.time, units, info.bat_voltage, info.bat_current,
++ info.bat_temperature);
++
++ ret -= off;
++ if (ret < off + count)
++ *eof = 1;
++ *start = page + off;
++ if (ret > count)
++ ret = count;
++ if (ret < 0)
++ ret = 0;
++
++ return ret;
++}
++#endif
++
++static int ac_bat_action(int status)
++{
++ get_battery_variable_info();
++
++ return status;
++}
++
++static int __init apm_init(void)
++{
++ int ret;
++
++ printk(KERN_INFO
++ "APM of battery on KB3310B Embedded Controller init.\n");
++
++ /* get fixed battery infomation */
++ get_battery_fixed_info();
++ /* install battery event handler */
++ yeeloong_install_sci_handler(EVENT_AC_BAT, ac_bat_action);
++
++#ifdef CONFIG_PROC_FS
++ bat_proc_entry = NULL;
++ bat_proc_entry = create_proc_entry("apm", S_IWUSR | S_IRUGO, NULL);
++ if (bat_proc_entry == NULL) {
++ printk(KERN_ERR "EC BAT : register /proc/apm failed.\n");
++ return -EINVAL;
++ }
++ bat_proc_entry->read_proc = bat_proc_read;
++ bat_proc_entry->write_proc = NULL;
++ bat_proc_entry->data = NULL;
++#endif
++
++ ret = misc_register(&apm_device);
++ if (ret != 0) {
++ remove_proc_entry("apm", NULL);
++ printk(KERN_ERR "ecbat : misc register error.\n");
++ }
++ return ret;
++}
++
++static void __exit apm_exit(void)
++{
++ /* uninstall battery event handler */
++ yeeloong_uninstall_sci_handler(EVENT_AC_BAT, ac_bat_action);
++
++ misc_deregister(&apm_device);
++#ifdef CONFIG_PROC_FS
++ remove_proc_entry("apm", NULL);
++#endif
++}
++
++module_init(apm_init);
++module_exit(apm_exit);
++
++MODULE_AUTHOR("liujl <liujl@lemote.com>");
++MODULE_DESCRIPTION("Advanced Power Management For Kb3310");
++MODULE_LICENSE("GPL");
diff --git a/lemote/gnewsense/tags/2.6.32-libre-lemote_0lxo/freedo.patch b/lemote/gnewsense/tags/2.6.32-libre-lemote_0lxo/freedo.patch
new file mode 100644
index 000000000..c7ba75609
--- /dev/null
+++ b/lemote/gnewsense/tags/2.6.32-libre-lemote_0lxo/freedo.patch
@@ -0,0 +1,5273 @@
+By Alexandre Oliva, based on Ali Gündüz's
+http://www.aligunduz.org/gNewSense/librelogo-2.6.29-fshoppe1.patch
+
+Updated for 2.6.32 and modified to use this image:
+http://www.aligunduz.org/gNewSense/freedo_libre.png
+
+Image converted using the following commands:
+convert -background black -flatten freedo_libre.png freedo_libre.ppm &&
+ppmquant -fs 223 < freedo_libre.ppm |
+pnmtoplainpnm > drivers/video/logo/logo_libre_clut224.ppm
+
+Index: drivers/video/logo/Kconfig
+===================================================================
+--- drivers/video/logo/Kconfig.orig 2009-12-03 01:51:21.000000000 -0200
++++ drivers/video/logo/Kconfig 2009-12-12 16:43:53.000000000 -0200
+@@ -42,6 +42,10 @@ config LOGO_DEC_CLUT224
+ depends on MACH_DECSTATION || ALPHA
+ default y
+
++config LOGO_LIBRE_CLUT224
++ bool "224-color Linux-libre logo"
++ default y
++
+ config LOGO_MAC_CLUT224
+ bool "224-color Macintosh Linux logo"
+ depends on MAC
+Index: drivers/video/logo/logo.c
+===================================================================
+--- drivers/video/logo/logo.c.orig 2009-12-03 01:51:21.000000000 -0200
++++ drivers/video/logo/logo.c 2009-12-12 16:43:53.000000000 -0200
+@@ -75,6 +75,10 @@ const struct linux_logo * __init_refok f
+ /* DEC Linux logo on MIPS/MIPS64 or ALPHA */
+ logo = &logo_dec_clut224;
+ #endif
++#ifdef CONFIG_LOGO_LIBRE_CLUT224
++ /* Linux-libre logo */
++ logo = &logo_libre_clut224;
++#endif
+ #ifdef CONFIG_LOGO_MAC_CLUT224
+ /* Macintosh Linux logo on m68k */
+ if (MACH_IS_MAC)
+Index: drivers/video/logo/logo_libre_clut224.ppm
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ drivers/video/logo/logo_libre_clut224.ppm 2009-12-12 16:58:12.000000000 -0200
+@@ -0,0 +1,5203 @@
++P3
++200 200
++255
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 11 2 0
++43 0 0 68 0 0 98 0 0 120 0 0 120 0 0 128 0 0 128 0 0 128 0 0
++128 0 0 138 0 0 138 0 0 149 0 0 149 0 0 160 0 0 160 0 0 160 0 0
++160 0 0 138 0 0 138 0 0 120 0 0 110 0 0 83 0 0 68 0 0 43 0 0
++11 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++5 2 0 55 0 0 98 0 0 120 0 0 138 0 0 149 0 0 167 0 0 170 0 0
++170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0
++170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0
++170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0
++170 0 0 160 0 0 128 0 0 98 0 0 83 0 0 68 0 0 55 0 0 21 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 5 2 0 32 0 0 55 0 0 83 0 0 110 0 0
++167 0 0 167 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0
++170 0 0 180 30 30 194 73 73 208 114 114 210 122 122 210 122 122 211 125 125 212 128 128
++215 135 135 217 141 141 219 148 148 222 155 155 224 161 161 226 168 168 228 174 174 230 181 181
++228 174 174 222 155 155 216 138 138 209 119 119 201 95 95 189 59 59 178 25 25 170 0 0
++170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0
++160 0 0 120 0 0 68 0 0 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 43 0 0 120 0 0 167 0 0 170 0 0 170 0 0 170 0 0 170 0 0
++170 0 0 172 6 6 191 64 64 206 110 110 217 141 141 224 164 164 232 187 187 239 209 209
++250 240 240 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 252 246 246
++241 213 213 227 171 171 212 128 128 199 87 87 188 55 55 183 38 38 175 16 16 170 0 0
++170 0 0 170 0 0 170 0 0 170 0 0 138 0 0 98 0 0 55 0 0 11 2 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 32 0 0 68 0 0
++138 0 0 167 0 0 170 0 0 170 0 0 170 0 0 176 19 19 189 59 59 202 97 97
++224 161 161 250 240 240 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 253 249 249 243 227 227 237 200 200 228 174 174 219 148 148
++241 213 213 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 243 221 221
++224 164 164 200 91 91 175 16 16 170 0 0 170 0 0 170 0 0 170 0 0 167 0 0
++128 0 0 68 0 0 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 21 0 0 83 0 0 128 0 0 160 0 0 170 0 0 170 0 0
++170 0 0 170 0 0 191 64 64 228 174 174 248 236 236 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 230 181 181 212 128 128 203 100 100
++194 73 73 185 47 47 177 22 22 170 1 1 170 0 0 170 0 0 170 0 0 170 0 0
++200 91 91 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 253 249 249 201 95 95
++224 164 164 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 254 252 252 234 194 194 212 128 128 191 64 64 172 6 6 170 0 0
++170 0 0 170 0 0 167 0 0 128 0 0 55 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 2 0
++55 0 0 128 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 176 19 19
++200 91 91 237 203 203 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 179 27 27 170 0 0 170 0 0
++170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 173 8 8
++229 177 177 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 239 206 206 170 0 0
++196 78 78 255 254 254 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 252 246 246 231 184 184
++203 100 100 176 19 19 170 0 0 170 0 0 170 0 0 138 0 0 68 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 21 0 0 98 0 0 160 0 0
++170 0 0 170 0 0 170 0 0 180 30 30 206 110 110 226 168 168 243 221 221 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 253 248 248 239 209 209 248 233 233 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 199 87 87 170 0 0 208 114 114
++170 0 0 176 19 19 184 44 44 193 71 71 202 97 97 212 128 128 226 168 168 248 233 233
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 224 161 161 170 0 0
++204 103 103 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 253 249 249 230 181 181 196 78 78 170 1 1 170 0 0 170 0 0 149 0 0
++83 0 0 43 0 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 2 1 0 55 0 0 128 0 0 167 0 0 170 0 0 170 0 0
++172 7 7 199 87 87 231 184 184 254 253 253 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 242 216 216 219 148 148 194 73 73 173 10 10 170 0 0 170 1 1 194 73 73
++247 231 231 255 255 255 255 255 255 255 255 255 255 255 255 212 128 128 170 0 0 219 148 148
++215 135 135 255 254 254 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 208 114 114 170 0 0
++227 171 171 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 242 216 216 233 190 190 254 251 251
++255 255 255 255 255 255 255 255 255 255 255 255 241 213 213 201 95 95 172 5 5 170 0 0
++170 0 0 170 0 0 160 0 0 110 0 0 43 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++11 2 0 83 0 0 149 0 0 170 0 0 170 0 0 170 0 0 181 33 33 215 135 135
++248 233 233 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 230 181 181 204 103 103
++181 33 33 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0
++184 44 44 253 248 248 255 255 255 255 255 255 255 255 255 222 155 155 170 0 0 217 141 141
++224 164 164 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 193 71 71 170 0 0
++250 240 240 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 196 78 78 170 0 0 175 16 16
++200 91 91 227 171 171 251 242 242 255 255 255 255 255 255 255 255 255 243 227 227 211 125 125
++187 53 53 170 1 1 170 0 0 170 0 0 170 0 0 128 0 0 43 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 32 0 0 110 0 0
++167 0 0 170 0 0 170 0 0 171 3 3 197 81 81 231 184 184 255 254 254 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 254 254 172 5 5 170 0 0
++171 3 3 170 0 0 170 0 0 175 14 14 197 81 81 219 148 148 206 110 110 178 25 25
++170 0 0 218 144 144 255 255 255 255 255 255 255 255 255 230 181 181 170 0 0 216 138 138
++241 213 213 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 177 22 22 181 33 33
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 210 122 122 191 64 64 172 5 5
++170 0 0 170 0 0 178 25 25 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 248 233 233 224 161 161 189 59 59 170 0 0 170 0 0 170 0 0 138 0 0
++43 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 2 1 0 55 0 0 128 0 0 170 0 0 170 0 0
++170 0 0 177 22 22 210 122 122 243 227 227 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 197 81 81 172 7 7
++201 95 95 204 103 103 233 190 190 253 249 249 255 255 255 255 255 255 255 255 255 250 240 240
++172 5 5 191 64 64 255 255 255 255 255 255 255 255 255 239 209 209 170 0 0 209 119 119
++210 122 122 199 87 87 189 59 59 181 33 33 173 12 12 227 171 171 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 248 233 233 170 0 0 196 78 78
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 248 233 233 222 158 158 170 0 0
++212 128 128 171 3 3 193 71 71 255 255 255 255 255 255 255 255 255 219 148 148 215 135 135
++250 240 240 255 255 255 255 255 255 255 255 255 232 187 187 191 64 64 170 0 0 170 0 0
++170 0 0 128 0 0 43 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 32 0 0 138 0 0 170 0 0 170 0 0 170 0 0 187 53 53
++224 164 164 253 248 248 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 224 164 164 170 0 0
++209 119 119 255 254 254 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 254 254
++176 19 19 188 55 55 255 255 255 255 255 255 255 255 255 248 236 236 170 0 0 170 0 0
++170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 183 41 41 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 232 187 187 170 0 0 211 125 125
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 215 135 135 170 0 0
++243 227 227 233 190 190 250 240 240 255 255 255 255 255 255 239 206 206 170 0 0 170 0 0
++173 12 12 206 110 110 245 224 224 255 255 255 255 255 255 255 255 255 234 194 194 191 64 64
++170 0 0 170 0 0 170 0 0 120 0 0 32 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 83 0 0 167 0 0 170 0 0 170 1 1 199 87 87 235 197 197 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 251 242 242 251 242 242 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 248 236 236 171 2 2
++189 59 59 255 255 255 255 255 255 255 255 255 255 255 255 255 254 254 252 246 246 224 164 164
++170 1 1 194 73 73 253 248 248 255 255 255 255 255 255 255 254 254 171 4 4 188 55 55
++187 50 50 170 0 0 170 0 0 170 1 1 181 33 33 222 158 158 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 217 141 141 170 0 0 227 171 171
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 188 55 55 187 50 50
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 209 119 119 170 0 0 183 38 38
++170 0 0 170 0 0 171 2 2 201 95 95 243 221 221 255 255 255 255 255 255 255 255 255
++234 194 194 189 59 59 170 0 0 170 0 0 167 0 0 98 0 0 11 2 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 21 0 0
++120 0 0 170 0 0 170 0 0 185 47 47 235 197 197 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 185 47 47 193 71 71 255 254 254 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 189 59 59
++172 5 5 252 246 246 255 255 255 255 255 255 255 254 254 239 206 206 215 135 135 175 14 14
++170 0 0 200 91 91 254 252 252 255 255 255 255 255 255 255 255 255 177 22 22 177 22 22
++211 125 125 226 168 168 245 224 224 253 249 249 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 201 95 95 170 0 0 242 216 216
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 247 231 231 170 1 1 212 128 128
++255 255 255 255 255 255 255 255 255 255 255 255 252 246 246 176 19 19 171 4 4 228 174 174
++183 41 41 170 0 0 170 0 0 170 0 0 173 12 12 226 168 168 255 255 255 255 255 255
++255 255 255 255 255 255 230 181 181 183 38 38 170 0 0 170 0 0 160 0 0 68 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 55 0 0 160 0 0
++170 0 0 170 0 0 206 110 110 253 249 249 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 187 50 50 170 0 0 200 91 91 253 249 249
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 212 128 128
++170 0 0 237 200 200 224 164 164 200 91 91 177 22 22 170 0 0 170 0 0 184 44 44
++203 100 100 234 194 194 255 255 255 255 255 255 255 255 255 255 255 255 184 44 44 171 2 2
++222 158 158 241 213 213 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 185 47 47 173 12 12 254 253 253
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 222 155 155 170 0 0 239 206 206
++255 255 255 255 255 255 255 255 255 255 255 255 219 152 152 170 0 0 208 114 114 255 254 254
++255 255 255 231 184 184 193 71 71 170 0 0 170 0 0 171 4 4 234 194 194 255 255 255
++255 255 255 255 255 255 255 255 255 253 249 249 218 144 144 175 16 16 170 0 0 170 0 0
++128 0 0 32 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 21 0 0 120 0 0 170 0 0 170 0 0
++176 19 19 228 174 174 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 189 59 59 170 0 0 170 0 0 189 59 59
++247 231 231 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 237 203 203
++170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 201 95 95 170 1 1 179 27 27
++229 177 177 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 191 64 64 170 0 0
++235 197 197 241 213 213 255 255 255 255 255 255 255 255 255 255 255 255 255 254 254 250 240 240
++243 218 218 249 238 238 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 254 251 251 172 7 7 189 59 59 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 196 78 78 180 30 30 255 255 255
++255 255 255 255 255 255 255 255 255 254 251 251 181 33 33 182 36 36 253 248 248 255 255 255
++255 255 255 255 255 255 255 255 255 237 203 203 177 22 22 170 0 0 204 103 103 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 248 233 233 201 95 95 170 0 0
++170 0 0 167 0 0 83 0 0 11 2 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 2 1 0 55 0 0 160 0 0 170 0 0 170 0 0 197 81 81
++248 233 233 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 189 59 59 188 55 55 205 106 106 170 0 0
++180 30 30 245 224 224 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 254 253 253
++175 16 16 183 38 38 189 59 59 175 14 14 200 91 91 209 119 119 179 27 27 175 14 14
++170 0 0 200 91 91 249 238 238 255 255 255 255 255 255 255 255 255 188 55 55 170 1 1
++206 110 110 204 103 103 197 81 81 191 64 64 184 44 44 177 22 22 171 4 4 170 0 0
++170 0 0 196 78 78 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 241 213 213 170 0 0 191 64 64 229 177 177
++237 203 203 251 244 244 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 251 244 244 172 7 7 206 110 110 255 255 255
++255 255 255 255 255 255 255 255 255 224 161 161 170 0 0 171 4 4 202 97 97 239 206 206
++255 255 255 255 255 255 255 255 255 255 255 255 204 103 103 170 0 0 202 97 97 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 232 187 187
++182 36 36 170 0 0 170 0 0 149 0 0 43 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 11 2 0 120 0 0 170 0 0 170 0 0 176 19 19 226 168 168 255 254 254
++255 255 255 255 255 255 252 246 246 209 119 119 237 200 200 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 191 64 64 180 30 30 215 135 135 170 0 0
++170 0 0 181 33 33 247 231 231 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++197 81 81 170 0 0 204 103 103 248 233 233 255 255 255 255 255 255 239 206 206 208 114 114
++185 47 47 170 0 0 178 25 25 230 181 181 255 255 255 255 255 255 187 53 53 170 0 0
++170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 172 7 7 175 14 14 170 1 1
++175 14 14 224 164 164 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 232 187 187 170 0 0 170 0 0 170 0 0
++170 0 0 170 1 1 181 33 33 194 73 73 209 119 119 224 161 161 237 203 203 252 246 246
++255 255 255 255 255 255 255 255 255 255 255 255 222 158 158 170 0 0 232 187 187 255 255 255
++255 255 255 255 255 255 254 253 253 183 38 38 172 7 7 180 30 30 170 0 0 170 0 0
++188 55 55 224 164 164 253 249 249 253 249 249 187 50 50 170 0 0 224 161 161 255 255 255
++255 255 255 255 255 255 255 255 255 250 240 240 217 141 141 252 246 246 255 255 255 255 255 255
++253 248 248 212 128 128 172 6 6 170 0 0 167 0 0 98 0 0 11 2 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++43 0 0 149 0 0 170 0 0 170 0 0 198 84 84 248 233 233 255 255 255 255 255 255
++255 255 255 255 255 255 230 181 181 170 0 0 180 30 30 253 249 249 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 193 71 71 171 4 4 224 164 164 200 91 91
++182 36 36 170 0 0 188 55 55 253 249 249 255 255 255 255 255 255 255 255 255 255 255 255
++216 138 138 170 0 0 216 138 138 255 255 255 255 255 255 255 255 255 255 255 255 249 238 238
++209 119 119 187 50 50 170 0 0 170 0 0 233 190 190 255 255 255 232 187 187 189 59 59
++182 36 36 183 41 41 189 59 59 196 78 78 202 97 97 208 114 114 219 148 148 235 197 197
++252 246 246 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 216 138 138 198 84 84 189 59 59
++189 59 59 188 55 55 176 19 19 170 0 0 170 0 0 170 0 0 170 0 0 181 33 33
++255 255 255 255 255 255 255 255 255 255 255 255 193 71 71 175 16 16 253 249 249 255 255 255
++255 255 255 255 255 255 226 168 168 170 0 0 194 73 73 203 100 100 172 5 5 170 0 0
++170 0 0 170 0 0 177 22 22 181 33 33 170 0 0 179 27 27 251 242 242 255 255 255
++255 255 255 255 255 255 255 255 255 205 106 106 170 0 0 182 36 36 234 194 194 255 255 255
++255 255 255 255 255 255 241 213 213 189 59 59 170 0 0 170 0 0 149 0 0 32 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 83 0 0
++167 0 0 170 0 0 176 19 19 227 171 171 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 254 253 253 189 59 59 170 0 0 226 168 168 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 197 81 81 170 0 0 224 161 161 245 224 224
++251 244 244 216 138 138 173 10 10 206 110 110 255 255 255 255 255 255 255 255 255 255 255 255
++231 184 184 170 0 0 193 71 71 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 237 203 203 193 71 71 191 64 64 243 227 227 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 243 218 218
++226 168 168 210 122 122 209 119 119 204 103 103 193 71 71 193 71 71 185 47 47 204 103 103
++255 255 255 245 224 224 196 78 78 219 148 148 175 16 16 217 141 141 255 255 255 255 255 255
++255 255 255 255 254 254 184 44 44 170 0 0 232 187 187 255 255 255 239 206 206 196 78 78
++171 2 2 170 0 0 170 0 0 170 0 0 206 110 110 243 227 227 255 255 255 255 255 255
++255 255 255 255 255 255 239 206 206 172 5 5 183 38 38 170 0 0 170 1 1 206 110 110
++251 244 244 255 255 255 255 255 255 254 253 253 218 144 144 173 8 8 170 0 0 167 0 0
++68 0 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 21 0 0 128 0 0 170 0 0
++170 0 0 188 55 55 245 224 224 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 226 168 168 173 12 12 185 47 47 253 249 249 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 205 106 106 170 0 0 229 177 177 242 216 216
++255 255 255 248 236 236 200 91 91 170 0 0 205 106 106 250 240 240 255 255 255 255 255 255
++242 216 216 170 0 0 170 0 0 241 213 213 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 254 251 251 242 216 216
++231 184 184 234 194 194 241 213 213 247 231 231 251 242 242 252 246 246 254 252 252 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 254 251 251 243 227 227 251 242 242 255 255 255
++255 255 255 234 194 194 170 0 0 170 0 0 170 0 0 183 41 41 212 128 128 253 248 248
++255 255 255 228 174 174 170 0 0 187 50 50 255 255 255 255 255 255 255 255 255 255 255 255
++243 218 218 205 106 106 172 6 6 170 0 0 210 122 122 255 255 255 255 255 255 255 255 255
++255 255 255 253 249 249 185 47 47 170 0 0 202 97 97 170 0 0 170 0 0 170 0 0
++181 33 33 233 190 190 255 255 255 255 255 255 255 255 255 241 213 213 184 44 44 170 0 0
++170 0 0 120 0 0 11 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 43 0 0 160 0 0 170 0 0 170 0 0
++206 110 110 254 251 251 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 229 177 177 218 144 144 170 0 0 216 138 138 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 212 128 128 170 0 0 248 233 233 242 216 216
++203 100 100 172 7 7 170 0 0 182 36 36 170 0 0 176 19 19 224 164 164 255 255 255
++254 252 252 181 33 33 170 1 1 235 197 197 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 250 240 240
++230 181 181 209 119 119 197 81 81 193 71 71 189 59 59 183 41 41 172 5 5 170 0 0
++170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 171 3 3
++173 12 12 177 22 22 181 33 33 188 55 55 196 78 78 204 103 103 215 135 135 229 177 177
++243 218 218 255 254 254 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 247 231 231 206 110 110 205 106 106 176 19 19 170 0 0 241 213 213
++255 255 255 187 50 50 170 0 0 228 174 174 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 210 122 122 170 0 0 187 53 53 255 255 255 255 255 255 255 255 255
++255 255 255 212 128 128 170 0 0 202 97 97 252 246 246 237 200 200 184 44 44 170 0 0
++170 0 0 170 1 1 208 114 114 255 255 255 255 255 255 255 255 255 252 246 246 203 100 100
++170 0 0 170 0 0 138 0 0 32 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 2 1 0 43 0 0 167 0 0 170 0 0 179 27 27 230 181 181
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 245 224 224 182 36 36 173 12 12 243 227 227
++255 255 255 255 255 255 255 255 255 255 255 255 219 152 152 171 4 4 196 78 78 170 1 1
++170 0 0 173 12 12 172 5 5 194 73 73 180 30 30 170 0 0 170 0 0 233 190 190
++255 255 255 243 227 227 235 197 197 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 254 251 251 242 216 216 229 177 177 215 135 135 199 87 87 183 38 38 171 2 2
++170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0
++172 7 7 170 1 1 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0
++170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0
++170 0 0 175 14 14 191 64 64 209 119 119 231 184 184 252 246 246 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 254 253 253 234 194 194 216 138 138 229 177 177 255 255 255
++251 242 242 170 0 0 170 0 0 181 33 33 219 148 148 252 246 246 255 255 255 255 255 255
++255 255 255 255 254 254 226 168 168 170 0 0 182 36 36 255 255 255 255 255 255 255 255 255
++241 213 213 172 6 6 179 27 27 250 240 240 255 255 255 255 255 255 253 248 248 210 122 122
++171 3 3 170 0 0 170 0 0 227 171 171 255 255 255 255 255 255 255 255 255 255 255 255
++222 155 155 172 7 7 170 0 0 160 0 0 55 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 68 0 0 167 0 0 170 0 0 184 44 44 248 233 233 255 255 255
++255 255 255 255 255 255 218 144 144 199 87 87 251 242 242 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 217 141 141 170 0 0 199 87 87
++255 255 255 255 255 255 255 255 255 255 255 255 222 158 158 170 0 0 170 0 0 170 1 1
++179 27 27 201 95 95 239 209 209 255 255 255 248 236 236 198 84 84 193 71 71 247 231 231
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 250 240 240 219 152 152
++187 53 53 171 4 4 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0
++172 5 5 188 55 55 204 103 103 209 119 119 212 128 128 219 148 148 231 184 184 243 227 227
++255 255 255 255 255 255 249 238 238 241 213 213 237 203 203 237 200 200 234 194 194 232 187 187
++229 177 177 226 168 168 222 155 155 215 135 135 206 110 110 199 87 87 187 50 50 173 8 8
++170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 173 8 8 191 64 64 212 128 128
++233 190 190 252 246 246 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 222 158 158 173 8 8 170 0 0 170 0 0 176 19 19 211 125 125 247 231 231
++255 255 255 255 254 254 200 91 91 170 0 0 205 106 106 255 255 255 255 255 255 254 251 251
++187 50 50 173 10 10 243 218 218 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++237 200 200 176 19 19 170 0 0 193 71 71 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 237 200 200 179 27 27 170 0 0 167 0 0 83 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++2 1 0 83 0 0 170 0 0 170 0 0 185 47 47 248 233 233 255 255 255 255 255 255
++255 255 255 255 255 255 176 19 19 170 0 0 204 103 103 255 255 255 255 255 255 255 255 255
++255 255 255 226 168 168 205 106 106 252 246 246 255 255 255 253 249 249 185 47 47 170 0 0
++237 200 200 255 255 255 255 255 255 255 255 255 219 152 152 170 0 0 219 148 148 185 47 47
++245 224 224 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 250 240 240 226 168 168 199 87 87 173 8 8 170 0 0
++170 0 0 170 0 0 170 0 0 173 10 10 185 47 47 200 91 91 216 138 138 233 190 190
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++243 218 218 226 168 168 208 114 114 188 55 55 171 2 2 170 0 0 170 1 1 170 0 0
++170 0 0 171 4 4 191 64 64 218 144 144 243 221 221 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 237 200 200 193 71 71 170 0 0 170 0 0 170 0 0 172 7 7
++196 78 78 184 44 44 170 0 0 171 3 3 243 227 227 255 255 255 255 255 255 212 128 128
++170 0 0 170 0 0 193 71 71 245 224 224 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 206 110 110 171 2 2 183 38 38 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 247 231 231 189 59 59 170 0 0 170 0 0 98 0 0 2 1 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 11 2 0
++110 0 0 170 0 0 170 0 0 194 73 73 251 242 242 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 233 190 190 175 16 16 170 0 0 224 161 161 255 255 255 255 255 255
++255 255 255 189 59 59 170 0 0 175 16 16 208 114 114 248 233 233 245 224 224 178 25 25
++206 110 110 255 255 255 255 255 255 255 255 255 216 138 138 170 0 0 191 64 64 243 227 227
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++243 227 227 219 148 148 193 71 71 172 6 6 170 0 0 170 0 0 170 0 0 175 14 14
++203 100 100 232 187 187 243 227 227 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 253 249 249 227 171 171 205 106 106 184 44 44
++170 1 1 170 0 0 170 0 0 170 0 0 170 0 0 187 50 50 219 152 152 250 240 240
++255 255 255 255 255 255 255 255 255 255 255 255 237 200 200 194 73 73 170 0 0 170 0 0
++170 0 0 170 0 0 181 33 33 230 181 181 255 255 255 255 255 255 234 194 194 172 5 5
++183 41 41 194 73 73 170 0 0 175 14 14 222 155 155 255 255 255 253 248 248 255 255 255
++255 255 255 237 203 203 170 0 0 194 73 73 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 253 248 248 200 91 91 170 0 0 170 0 0 120 0 0
++2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 1 0 21 0 0 149 0 0
++170 0 0 170 0 0 204 103 103 254 252 252 255 255 255 255 255 255 245 224 224 255 255 255
++255 255 255 255 255 255 255 255 255 241 213 213 176 19 19 173 8 8 237 203 203 255 255 255
++255 255 255 203 100 100 170 0 0 187 50 50 170 0 0 175 14 14 215 135 135 219 148 148
++175 14 14 242 216 216 255 255 255 255 255 255 226 168 168 170 0 0 173 10 10 248 236 236
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 253 248 248 222 158 158 188 55 55
++170 1 1 170 0 0 170 0 0 170 0 0 172 7 7 194 73 73 224 161 161 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++252 246 246 229 177 177 204 103 103 178 25 25 170 0 0 170 0 0 170 0 0 173 8 8
++202 97 97 239 206 206 255 255 255 255 255 255 255 255 255 255 255 255 241 213 213 209 119 119
++193 71 71 206 110 110 253 249 249 255 255 255 255 255 255 243 227 227 178 25 25 170 0 0
++210 122 122 188 55 55 170 0 0 170 0 0 170 0 0 193 71 71 243 221 221 255 255 255
++247 231 231 191 64 64 170 0 0 227 171 171 255 255 255 255 255 255 255 255 255 255 255 255
++237 203 203 202 97 97 249 238 238 255 255 255 255 255 255 212 128 128 170 0 0 170 0 0
++110 0 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 21 0 0 160 0 0 167 0 0
++173 8 8 219 152 152 255 255 255 255 255 255 255 255 255 209 119 119 170 0 0 229 177 177
++255 255 255 255 255 255 255 255 255 255 255 255 231 184 184 170 1 1 179 27 27 235 197 197
++247 231 231 205 106 106 170 0 0 206 110 110 183 41 41 180 30 30 170 0 0 170 0 0
++170 0 0 182 36 36 248 236 236 255 255 255 253 249 249 212 128 128 228 174 174 255 254 254
++255 255 255 255 255 255 255 255 255 249 238 238 212 128 128 177 22 22 170 0 0 170 0 0
++170 0 0 176 19 19 203 100 100 229 177 177 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 235 197 197 203 100 100 175 14 14 170 0 0
++170 0 0 170 0 0 175 16 16 208 114 114 251 242 242 255 255 255 255 255 255 255 255 255
++255 254 254 255 255 255 255 255 255 255 255 255 252 246 246 181 33 33 170 0 0 201 95 95
++253 249 249 255 255 255 234 194 194 191 64 64 191 64 64 170 0 0 173 8 8 180 30 30
++170 1 1 170 0 0 201 95 95 255 255 255 255 255 255 255 255 255 255 255 255 251 244 244
++183 41 41 170 0 0 185 47 47 247 231 231 255 255 255 255 255 255 217 141 141 170 0 0
++170 0 0 110 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 21 0 0 149 0 0 170 0 0 176 19 19
++239 206 206 255 255 255 255 255 255 255 255 255 211 125 125 170 0 0 170 0 0 215 135 135
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 209 119 119 170 0 0 197 81 81
++233 190 190 209 119 119 170 0 0 182 36 36 201 95 95 206 110 110 206 110 110 185 47 47
++170 0 0 170 0 0 201 95 95 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 247 231 231 208 114 114 173 12 12 170 0 0 170 0 0 172 5 5 199 87 87
++233 190 190 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 222 155 155
++183 38 38 170 0 0 170 0 0 170 0 0 179 27 27 226 168 168 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 228 174 174 170 0 0 170 1 1 243 221 221
++255 255 255 255 255 255 255 254 254 215 135 135 175 16 16 172 7 7 199 87 87 171 3 3
++189 59 59 217 141 141 255 255 255 255 255 255 255 255 255 255 255 255 253 249 249 193 71 71
++170 0 0 183 41 41 170 0 0 182 36 36 245 224 224 255 255 255 255 255 255 212 128 128
++170 0 0 170 0 0 83 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 11 2 0 149 0 0 170 0 0 175 16 16 239 206 206
++255 255 255 255 255 255 255 255 255 216 138 138 170 0 0 173 12 12 184 44 44 249 238 238
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 254 252 252 189 59 59 170 1 1
++219 152 152 226 168 168 170 0 0 200 91 91 253 249 249 255 254 254 231 184 184 210 122 122
++182 36 36 170 0 0 209 119 119 255 255 255 255 255 255 255 255 255 255 255 255 248 233 233
++206 110 110 173 8 8 170 0 0 170 0 0 176 19 19 210 122 122 243 227 227 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 243 218 218 212 128 128 173 12 12 170 0 0 170 0 0 185 47 47 226 168 168
++254 252 252 255 255 255 255 255 255 255 255 255 248 236 236 200 91 91 219 152 152 255 255 255
++255 255 255 255 255 255 255 255 255 224 161 161 189 59 59 171 2 2 248 233 233 210 122 122
++224 161 161 249 238 238 255 255 255 255 255 255 255 255 255 254 252 252 198 84 84 170 0 0
++187 50 50 210 122 122 170 0 0 170 0 0 180 30 30 242 216 216 255 255 255 255 255 255
++201 95 95 170 0 0 170 0 0 83 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 11 2 0 138 0 0 170 0 0 173 8 8 235 197 197 255 255 255
++255 255 255 255 255 255 218 144 144 170 0 0 179 27 27 176 19 19 239 209 209 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 243 227 227 177 22 22
++172 7 7 215 135 135 170 0 0 204 103 103 253 248 248 255 255 255 255 255 255 255 255 255
++248 236 236 239 209 209 255 255 255 255 255 255 255 255 255 251 242 242 211 125 125 173 12 12
++170 0 0 170 0 0 178 25 25 216 138 138 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 243 227 227 200 91 91 170 0 0 170 0 0 170 0 0
++181 33 33 224 164 164 255 254 254 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 228 174 174 198 84 84 170 0 0 243 218 218 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 254 254 201 95 95 170 0 0 188 55 55
++232 187 187 216 138 138 188 55 55 170 0 0 170 0 0 177 22 22 239 209 209 255 255 255
++254 251 251 197 81 81 170 0 0 167 0 0 83 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 2 1 0 120 0 0 170 0 0 171 3 3 229 177 177 255 255 255 255 255 255
++255 254 254 209 119 119 170 0 0 170 0 0 216 138 138 242 216 216 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 233 190 190
++172 6 6 170 0 0 170 0 0 202 97 97 249 238 238 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 254 252 252 219 152 152 177 22 22 170 0 0 170 0 0
++176 19 19 216 138 138 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 239 209 209 199 87 87 171 2 2
++170 0 0 170 0 0 187 53 53 234 194 194 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 235 197 197 194 73 73 170 0 0 232 187 187 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 204 103 103 170 0 0 203 100 100 243 227 227
++228 174 174 255 255 255 250 240 240 191 64 64 170 0 0 170 0 0 175 16 16 235 197 197
++255 255 255 253 249 249 197 81 81 170 0 0 170 0 0 68 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 98 0 0 170 0 0 170 0 0 222 155 155 255 255 255 255 255 255 253 248 248
++199 87 87 170 0 0 187 53 53 196 78 78 170 0 0 206 110 110 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 254 254
++226 168 168 170 0 0 170 0 0 200 91 91 252 246 246 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 243 221 221 188 55 55 170 0 0 170 0 0 173 12 12 212 128 128
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 243 218 218
++199 87 87 170 0 0 170 0 0 170 0 0 198 84 84 243 221 221 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 247 231 231 188 55 55 170 0 0 222 158 158 255 255 255
++255 255 255 255 255 255 255 255 255 208 114 114 170 0 0 170 0 0 177 22 22 227 171 171
++255 255 255 255 255 255 255 255 255 252 246 246 194 73 73 170 0 0 170 0 0 173 12 12
++232 187 187 255 255 255 253 249 249 196 78 78 170 0 0 170 0 0 55 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++83 0 0 170 0 0 170 0 0 211 125 125 255 255 255 255 255 255 250 240 240 189 59 59
++170 0 0 170 0 0 180 30 30 224 164 164 187 50 50 170 0 0 209 119 119 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 189 59 59 170 0 0 175 14 14 254 253 253 255 255 255 255 255 255 255 255 255
++255 255 255 224 164 164 175 14 14 170 0 0 170 1 1 203 100 100 247 231 231 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 237 200 200 189 59 59 170 0 0 170 0 0 172 6 6 210 122 122 254 252 252
++255 255 255 255 255 255 255 255 255 255 255 255 189 59 59 170 0 0 212 128 128 255 255 255
++255 255 255 255 255 255 210 122 122 170 0 0 181 33 33 205 106 106 170 0 0 171 2 2
++222 155 155 255 255 255 255 255 255 255 255 255 254 251 251 201 95 95 170 0 0 170 0 0
++172 7 7 234 194 194 255 255 255 252 246 246 189 59 59 170 0 0 160 0 0 32 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 55 0 0
++167 0 0 170 0 0 200 91 91 255 255 255 255 255 255 255 255 255 222 158 158 170 0 0
++171 2 2 185 47 47 248 233 233 251 244 244 249 238 238 185 47 47 170 0 0 209 119 119
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 242 216 216 200 91 91 224 164 164 255 255 255 255 255 255 255 255 255 247 231 231
++196 78 78 170 0 0 170 0 0 179 27 27 232 187 187 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 227 171 171 180 30 30 170 0 0 170 0 0 193 71 71
++249 238 238 255 255 255 255 255 255 255 255 255 224 164 164 177 22 22 224 164 164 255 255 255
++252 246 246 204 103 103 170 0 0 179 27 27 228 174 174 178 25 25 170 0 0 170 0 0
++170 0 0 217 141 141 255 255 255 255 255 255 255 255 255 254 253 253 216 138 138 173 8 8
++173 12 12 232 187 187 255 255 255 255 255 255 248 233 233 181 33 33 170 0 0 160 0 0
++21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 32 0 0 160 0 0
++170 0 0 189 59 59 253 248 248 255 255 255 255 255 255 255 255 255 254 251 251 216 138 138
++217 141 141 249 238 238 255 255 255 255 255 255 255 255 255 248 236 236 184 44 44 170 0 0
++209 119 119 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 227 171 171 176 19 19
++170 0 0 170 0 0 197 81 81 251 244 244 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 209 119 119 170 0 0 170 0 0
++182 36 36 239 209 209 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++193 71 71 170 0 0 182 36 36 233 190 190 204 103 103 252 246 246 199 87 87 170 0 0
++170 0 0 170 0 0 226 168 168 255 255 255 255 255 255 255 255 255 255 255 255 252 246 246
++249 238 238 255 255 255 255 255 255 255 255 255 255 255 255 242 216 216 175 16 16 170 0 0
++138 0 0 5 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 21 0 0 149 0 0 170 0 0
++182 36 36 249 238 238 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 247 231 231 183 41 41
++170 0 0 208 114 114 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 247 231 231 198 84 84 170 0 0 170 0 0
++175 16 16 224 164 164 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 226 168 168 173 8 8
++170 0 0 172 7 7 212 128 128 254 251 251 255 255 255 255 255 255 255 255 255 255 255 255
++175 16 16 170 0 0 188 55 55 239 209 209 252 246 246 255 255 255 254 253 253 204 103 103
++170 0 0 170 0 0 234 194 194 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 232 187 187 171 3 3
++170 0 0 110 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 5 2 0 128 0 0 170 0 0 175 16 16
++242 216 216 255 255 255 255 255 255 239 209 209 248 236 236 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 247 231 231
++182 36 36 170 0 0 206 110 110 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 230 181 181 176 19 19 170 0 0 170 0 0 194 73 73
++247 231 231 255 254 254 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 237 203 203
++183 38 38 170 0 0 170 0 0 188 55 55 247 231 231 255 255 255 255 255 255 255 255 255
++212 128 128 173 8 8 170 0 0 189 59 59 251 242 242 255 255 255 255 255 255 255 255 255
++231 184 184 212 128 128 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 218 144 144
++170 0 0 170 0 0 83 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 98 0 0 170 0 0 171 4 4 233 190 190
++255 255 255 255 255 255 239 206 206 171 2 2 179 27 27 248 233 233 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++243 227 227 181 33 33 170 1 1 206 110 110 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 254 254 215 135 135 171 2 2 170 0 0 176 19 19 224 161 161 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 208 114 114 171 2 2 170 0 0 179 27 27 237 203 203 255 255 255 255 255 255
++255 254 254 204 103 103 172 5 5 170 0 0 188 55 55 250 240 240 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++202 97 97 170 0 0 167 0 0 43 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 43 0 0 170 0 0 170 0 0 211 125 125 255 255 255
++255 255 255 249 238 238 183 41 41 170 0 0 171 2 2 242 216 216 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 245 224 224 175 16 16 170 0 0 222 158 158 255 255 255 255 255 255 255 255 255
++251 242 242 198 84 84 170 0 0 170 0 0 189 59 59 247 231 231 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 230 181 181 175 16 16 170 0 0 173 8 8 227 171 171 255 255 255
++255 255 255 254 253 253 200 91 91 171 3 3 170 0 0 188 55 55 250 240 240 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++252 246 246 187 50 50 170 0 0 160 0 0 21 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 11 2 0 160 0 0 170 0 0 189 59 59 254 252 252 255 255 255
++255 255 255 194 73 73 170 0 0 170 0 0 208 114 114 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 222 155 155 175 14 14 226 168 168 255 255 255 255 255 255 243 221 221
++184 44 44 170 0 0 170 0 0 204 103 103 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 242 216 216 183 41 41 170 0 0 171 2 2 218 144 144
++255 255 255 255 255 255 254 252 252 201 95 95 172 6 6 170 0 0 187 53 53 250 240 240
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 245 224 224 176 19 19 170 0 0 128 0 0 5 2 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 120 0 0 170 0 0 175 16 16 245 224 224 255 255 255 255 255 255
++218 144 144 170 0 0 170 0 0 184 44 44 253 248 248 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 237 200 200 176 19 19
++170 0 0 172 6 6 222 155 155 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 250 248 248 246 246 246 241 241 241 237 237 237
++239 239 239 243 242 242 251 251 251 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 254 252 252 191 64 64 170 0 0 170 0 0
++208 114 114 255 254 254 255 255 255 254 253 253 204 103 103 173 12 12 170 0 0 187 50 50
++249 238 238 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 232 187 187 171 3 3 170 0 0 98 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 68 0 0 170 0 0 170 0 0 226 168 168 255 255 255 255 255 255 241 213 213
++172 7 7 170 0 0 172 5 5 239 206 206 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 241 213 213 176 19 19 170 0 0
++179 27 27 237 200 200 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++239 239 239 214 214 214 180 180 180 137 137 137 105 100 100 91 72 72 55 70 84 91 72 72
++55 59 65 87 87 87 105 100 100 137 137 137 180 180 180 210 206 206 237 237 237 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 197 81 81 170 0 0
++170 1 1 202 97 97 254 252 252 255 255 255 255 255 255 217 141 141 172 5 5 170 0 0
++189 59 59 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 212 128 128 170 0 0 170 0 0 43 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++21 0 0 160 0 0 170 0 0 199 87 87 255 255 255 255 255 255 253 248 248 185 47 47
++170 0 0 170 0 0 215 135 135 255 254 254 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 243 221 221 179 27 27 170 0 0 178 25 25
++243 221 221 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 246 246 246 206 206 206 137 137 137
++70 80 89 37 34 34 19 19 19 6 7 9 6 7 9 4 5 6 5 3 2 1 1 1
++4 5 6 5 3 2 4 5 6 6 7 9 14 13 13 37 34 34 70 80 89 127 127 127
++198 194 194 241 241 241 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 204 103 103
++170 0 0 170 0 0 198 84 84 252 246 246 255 255 255 255 255 255 233 190 190 194 73 73
++212 128 128 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 254 253 253 191 64 64 170 0 0 160 0 0 11 2 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++110 0 0 170 0 0 177 22 22 248 236 236 255 255 255 255 255 255 208 114 114 170 0 0
++170 0 0 188 55 55 254 252 252 255 255 255 255 255 255 251 242 242 215 135 135 243 221 221
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 248 236 236 182 36 36 170 0 0 175 16 16 241 213 213
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 254 254 254 234 234 234 173 173 173 105 100 100 37 34 34 8 10 11
++5 2 0 1 1 1 1 1 1 0 0 0 0 0 0 2 3 4 4 5 6 6 7 9
++4 5 6 2 3 4 0 0 0 0 0 0 1 1 2 1 1 1 5 2 0 8 10 11
++37 34 34 87 87 87 165 165 165 226 226 226 253 253 253 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++211 125 125 170 0 0 170 0 0 191 64 64 251 242 242 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 243 227 227 175 16 16 167 0 0 120 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 55 0 0
++170 0 0 170 0 0 226 168 168 255 255 255 255 255 255 232 187 187 170 1 1 170 1 1
++172 5 5 242 216 216 255 255 255 255 255 255 255 255 255 202 97 97 170 0 0 189 59 59
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 252 246 246 188 55 55 170 0 0 173 8 8 234 194 194 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++254 254 254 239 239 239 180 180 180 97 97 97 19 25 31 5 3 2 1 1 2 0 0 0
++4 5 6 13 16 19 27 31 34 45 57 69 70 80 89 86 104 117 90 112 135 96 123 148
++90 112 135 86 104 117 55 70 84 45 57 69 27 31 34 13 16 19 4 5 6 0 0 0
++0 0 0 2 3 4 19 19 19 70 80 89 165 165 165 228 228 228 253 253 253 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 218 144 144 170 1 1 170 0 0 188 55 55 249 238 238 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 226 168 168 170 0 0 170 0 0
++43 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 2 0 149 0 0
++170 0 0 193 71 71 255 255 255 255 255 255 255 255 255 184 44 44 170 0 0 196 78 78
++227 171 171 250 240 240 255 255 255 255 255 255 228 174 174 170 0 0 170 0 0 197 81 81
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 253 248 248 194 73 73 170 0 0 171 3 3 228 174 174 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 251 251 251
++214 214 214 113 113 113 37 34 34 0 0 0 0 0 0 2 2 2 10 12 13 33 37 45
++71 90 109 109 140 168 133 171 205 151 192 230 157 201 242 162 207 250 166 211 254 167 212 255
++166 211 254 162 207 250 161 204 245 151 192 230 133 171 205 109 140 168 71 90 109 37 46 56
++13 16 19 2 3 4 0 0 0 2 1 0 19 19 19 87 87 87 188 187 187 246 246 246
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 224 161 161 171 4 4 170 0 0 188 55 55 251 242 242 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 188 55 55 170 0 0
++128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 83 0 0 170 0 0
++172 7 7 242 216 216 255 255 255 255 255 255 255 255 255 219 148 148 183 41 41 170 0 0
++175 16 16 235 197 197 255 255 255 248 236 236 177 22 22 170 0 0 181 33 33 242 216 216
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++253 249 249 194 73 73 170 0 0 170 0 0 222 155 155 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 243 242 242 173 173 173
++55 59 65 9 6 4 0 0 0 1 1 2 13 16 19 45 57 69 96 123 148 140 179 215
++165 209 252 168 214 255 169 215 255 168 214 255 168 213 255 168 213 255 167 212 255 167 212 255
++167 212 255 167 212 255 168 213 255 168 214 255 169 215 255 169 215 255 166 211 254 140 179 215
++96 123 148 55 70 84 13 16 19 2 3 4 0 0 0 1 1 1 46 46 46 137 137 137
++232 232 232 253 253 253 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 228 174 174 171 4 4 170 0 0 191 64 64 253 249 249
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 234 194 194 170 0 0
++170 0 0 55 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 32 0 0 170 0 0 170 0 0
++211 125 125 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 252 246 246 202 97 97
++170 0 0 173 12 12 233 190 190 201 95 95 170 0 0 170 0 0 215 135 135 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 254 252 252
++196 78 78 170 0 0 170 0 0 218 144 144 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 241 241 241 237 237 237 246 246 246 246 246 246 251 251 251 255 255 255 255 255 255
++255 255 255 255 255 255 254 254 254 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 254 254 254 228 228 228 137 137 137 37 34 34
++2 2 2 0 0 0 10 12 13 37 46 56 96 123 148 140 179 215 166 211 254 168 214 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 169 216 255
++169 215 255 151 192 230 109 140 168 55 70 84 13 16 19 0 0 1 0 0 0 14 13 13
++105 100 100 206 206 206 251 251 251 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 224 161 161 170 1 1 170 0 0 201 95 95
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 243 227 227 250 240 240 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 196 78 78
++170 0 0 138 0 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 5 2 0 138 0 0 170 0 0 183 41 41
++253 248 248 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++226 168 168 179 27 27 171 2 2 170 0 0 196 78 78 176 19 19 251 244 244 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 204 103 103
++170 0 0 170 0 0 216 138 138 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 254 254 254 218 218 218 113 113 113 19 19 19 1 1 1
++1 1 2 19 25 31 71 90 109 133 171 205 162 207 250 169 216 255 168 213 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 168 214 255 165 210 253 140 179 215 90 112 135 37 46 56 4 5 6 0 0 0
++2 3 4 70 80 89 180 180 180 250 248 248 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 218 144 144 170 0 0 170 0 0
++230 181 181 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 254 253 253 176 19 19 198 84 84 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 241 213 213
++171 3 3 170 0 0 83 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 2 1 0 83 0 0 170 0 0 171 3 3 237 203 203
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 250 240 240 198 84 84 170 0 0 189 59 59 243 221 221 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 254 254 215 135 135 170 0 0
++170 0 0 210 122 122 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 214 214 214 97 97 97 10 12 13 0 0 0 4 4 5
++37 46 56 109 140 168 154 196 236 169 215 255 168 213 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 168 214 255 172 216 255 161 204 245 126 161 193 55 70 84 13 16 19
++0 0 0 2 1 0 55 59 65 165 165 165 246 246 246 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 194 73 73 170 0 0
++180 30 30 251 242 242 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 253 249 249 205 106 106 170 0 0 230 181 181 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++206 110 110 170 0 0 160 0 0 11 2 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 32 0 0 167 0 0 170 0 0 210 122 122 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 217 141 141 171 2 2 175 14 14 219 152 152 255 254 254
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 237 200 200 171 2 2 170 0 0
++201 95 95 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 254 254 254 214 214 214 87 87 87 1 1 1 0 0 0 8 10 11 45 57 69
++126 161 193 162 207 250 169 216 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 168 214 255 169 216 255 140 179 215 86 104 117
++19 25 31 0 0 0 0 0 0 46 46 46 156 150 150 246 246 246 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 245 224 224 173 12 12
++170 0 0 198 84 84 254 253 253 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 219 152 152 196 78 78 179 27 27 251 242 242
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++249 238 238 176 19 19 170 0 0 110 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 120 0 0 170 0 0 182 36 36 253 249 249 255 255 255
++255 255 255 254 252 252 228 174 174 197 81 81 182 36 36 187 50 50 209 119 119 245 224 224
++255 255 255 255 255 255 255 255 255 255 255 255 229 177 177 173 12 12 170 0 0 191 64 64
++232 187 187 255 255 255 255 255 255 251 251 251 241 241 241 183 41 41 149 0 0 185 47 47
++234 234 234 228 228 228 214 214 214 210 206 206 232 232 232 250 248 248 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 218 218 218 97 97 97 4 5 6 0 0 1 8 10 11 70 80 89 133 171 205
++169 215 255 168 213 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 169 215 255 154 196 236
++96 123 148 27 31 34 1 1 1 0 0 0 46 46 46 165 165 165 246 246 246 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 219 152 152
++170 0 0 170 0 0 205 106 106 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 241 213 213 218 144 144 173 8 8 208 114 114
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 219 152 152 170 0 0 167 0 0 21 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 43 0 0 167 0 0 170 0 0 227 171 171 255 255 255 255 255 255
++248 236 236 189 59 59 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 172 6 6
++204 103 103 247 231 231 255 255 255 255 255 255 255 255 255 237 203 203 173 12 12 170 0 0
++171 3 3 223 222 222 188 187 187 156 150 150 91 72 72 83 0 0 83 0 0 97 97 97
++105 100 100 97 97 97 70 80 89 55 59 65 105 100 100 156 150 150 223 222 222 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++239 239 239 127 127 127 14 13 13 0 0 0 8 10 11 71 90 109 133 171 205 169 215 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 168 214 255 169 215 255
++169 215 255 168 213 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 168 213 255 169 215 255 168 214 255 168 213 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 169 215 255
++157 201 242 96 123 148 33 37 45 0 0 0 0 0 0 46 46 46 173 173 173 251 251 251
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++209 119 119 170 0 0 170 0 0 216 138 138 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 215 135 135 208 114 114 171 3 3
++239 206 206 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 254 252 252 183 41 41 170 0 0 110 0 0 2 1 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 128 0 0 170 0 0 187 53 53 255 254 254 255 255 255 255 255 255
++198 84 84 170 0 0 170 0 0 175 16 16 194 73 73 205 106 106 194 73 73 177 22 22
++170 0 0 173 12 12 215 135 135 255 255 255 255 255 255 255 255 255 243 221 221 188 77 77
++134 90 49 87 87 87 46 46 46 19 19 19 11 2 0 5 2 0 5 3 2 5 3 2
++2 3 4 0 0 0 2 1 0 2 1 0 2 2 2 27 31 34 97 97 97 188 187 187
++253 253 253 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++165 165 165 27 31 34 0 0 0 2 3 4 55 70 84 140 179 215 168 214 255 168 213 255
++167 212 255 167 212 255 167 212 255 167 212 255 168 213 255 167 212 255 151 192 230 126 161 193
++133 171 205 157 201 242 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 168 214 255 157 201 242 151 192 230 140 179 215 161 204 245 168 214 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++169 215 255 161 204 245 96 123 148 27 31 34 0 0 0 9 6 4 55 59 65 198 194 194
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 251 251 251 239 239 239 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 202 97 97 170 0 0 173 8 8 247 231 231 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 248 236 236 208 114 114 182 36 36
++187 53 53 254 253 253 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 227 171 171 170 0 0 170 0 0 32 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 32 0 0 170 0 0 170 0 0 232 187 187 255 255 255 255 255 255 242 216 216
++170 0 0 170 0 0 178 25 25 243 227 227 255 255 255 255 255 255 250 240 240 217 141 141
++212 128 128 178 25 25 170 0 0 212 128 128 250 240 240 255 255 255 218 218 218 113 113 113
++27 31 34 1 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 2 1 0 9 6 4 5 3 2 0 0 0 0 0 0 4 5 6 55 59 65
++173 173 173 246 246 246 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 218 218 218
++55 59 65 9 6 4 0 0 1 37 46 56 133 171 205 168 213 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 168 213 255 165 209 252 126 161 193 71 90 109 33 37 45
++37 46 56 90 112 135 151 192 230 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 140 179 215 90 112 135 55 70 84 55 70 84 96 123 148 151 192 230 168 214 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 168 214 255 157 201 242 96 123 148 19 25 31 0 0 0 6 7 9 87 87 87
++214 214 214 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 246 246 246 226 226 226 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 179 27 27 170 0 0 203 100 100 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 219 148 148 211 125 125
++170 0 0 219 148 148 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 254 254 187 50 50 170 0 0 120 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 98 0 0 170 0 0 184 44 44 255 255 255 255 255 255 255 255 255 211 125 125
++170 0 0 170 0 0 230 181 181 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 250 240 240 191 64 64 170 0 0 215 135 135 210 206 206 105 100 100 19 19 19
++0 0 0 0 0 0 5 2 0 5 3 2 1 1 1 0 0 0 0 0 0 0 0 0
++0 0 0 16 8 3 56 42 30 127 80 21 56 42 30 16 8 3 0 0 0 5 2 0
++46 46 46 165 165 165 250 248 248 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 250 248 248 137 137 137
++14 13 13 0 0 0 19 25 31 109 140 168 166 211 254 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 169 216 255 140 179 215 70 80 89 4 5 6 0 0 1
++1 1 2 18 19 24 109 140 168 162 207 250 167 212 255 167 212 255 167 212 255 166 211 254
++157 201 242 86 104 117 13 16 19 0 0 0 0 0 0 27 31 34 96 123 148 162 207 250
++168 213 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 168 214 255 154 196 236 90 112 135 13 16 19 0 0 0 14 13 13
++113 113 113 232 232 232 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 237 237 237
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 222 155 155 170 0 0 171 3 3 239 206 206 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 254 253 253 206 110 110
++197 81 81 175 14 14 243 227 227 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 230 181 181 170 0 0 170 0 0 32 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++5 2 0 160 0 0 170 0 0 217 141 141 255 255 255 255 255 255 255 255 255 197 81 81
++170 0 0 172 5 5 252 246 246 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 233 190 190 170 0 0 188 77 77 91 72 72 19 19 19 0 0 0
++2 1 0 34 13 13 56 42 30 127 80 21 71 32 32 56 42 30 16 8 3 1 1 1
++0 0 0 2 1 0 37 30 17 127 80 21 127 80 21 127 80 21 9 6 4 5 2 0
++2 3 4 46 46 46 180 180 180 253 253 253 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 206 206 206 46 46 46
++4 5 6 2 3 4 71 90 109 154 196 236 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 168 213 255 165 209 252 109 140 168 18 19 24 1 1 2 0 0 0
++0 0 0 0 0 0 71 90 109 157 201 242 167 212 255 167 212 255 167 212 255 165 210 253
++126 161 193 27 31 34 0 0 1 0 0 0 0 0 0 2 3 4 70 80 89 154 196 236
++169 215 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 151 192 230 71 90 109 4 5 6 0 0 1
++37 34 34 156 150 150 251 251 251 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++250 248 248 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 184 44 44 170 0 0 185 47 47 253 249 249 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 243 227 227
++228 174 174 173 12 12 209 119 119 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 184 44 44 170 0 0 110 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++55 0 0 170 0 0 172 5 5 248 233 233 255 255 255 255 255 255 255 255 255 199 87 87
++170 0 0 184 44 44 243 227 227 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 254 254 250 248 248 149 0 0 110 0 0 34 13 13 0 0 0 0 0 0
++2 1 0 16 8 3 37 30 17 56 42 30 127 80 21 127 80 21 127 80 21 56 42 30
++5 2 0 0 0 0 11 2 0 37 30 17 127 80 21 176 111 31 127 80 21 16 8 3
++2 1 0 4 5 6 91 72 72 206 206 206 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 251 251 251 127 127 127 19 19 19
++0 0 1 27 31 34 126 161 193 166 211 254 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 168 214 255 151 192 230 70 80 89 0 0 1 0 0 0 0 0 0
++0 0 0 4 5 6 90 112 135 161 204 245 167 212 255 167 212 255 167 212 255 162 207 250
++86 104 117 1 1 2 0 0 0 0 0 0 0 0 0 6 7 9 71 90 109 157 201 242
++168 214 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 165 209 252 133 171 205 45 57 69 0 0 0
++9 6 4 55 59 65 206 206 206 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 234 234 234 218 218 218 214 214 214 236 236 236 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 237 200 200 171 3 3 170 0 0 212 128 128 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 239 209 209 250 240 240 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 224 164 164 170 0 0 167 0 0 21 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++128 0 0 170 0 0 197 81 81 255 255 255 255 255 255 255 255 255 255 255 255 233 190 190
++170 0 0 201 95 95 215 135 135 255 255 255 251 251 251 234 234 234 214 214 214 188 187 187
++165 165 165 137 137 137 97 97 97 43 0 0 16 8 3 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 5 2 0 11 2 0 16 8 3 88 72 43 127 80 21 176 111 31
++71 32 32 16 8 3 0 0 0 2 1 0 37 30 17 127 80 21 176 111 31 88 72 43
++16 8 3 0 0 0 10 12 13 105 100 100 232 232 232 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 210 206 206 55 59 65 5 3 2
++0 0 0 71 90 109 157 201 242 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 168 214 255 126 161 193 37 46 56 0 0 1 0 0 0 0 0 0
++0 0 0 27 31 34 126 161 193 165 210 253 167 212 255 167 212 255 166 211 254 151 192 230
++45 57 69 0 0 0 0 0 0 0 0 0 0 0 0 18 19 24 96 123 148 168 214 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 162 207 250 109 140 168 27 31 34
++0 0 0 14 13 13 113 113 113 236 236 236 255 255 255 255 255 255 250 248 248 198 194 194
++137 137 137 70 80 89 46 46 46 46 46 46 87 87 87 145 144 144 214 214 214 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 209 119 119 170 0 0 172 6 6 243 218 218
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 254 252 252 180 30 30 170 0 0 98 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 32 0 0
++170 0 0 170 0 0 233 190 190 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++187 53 53 172 7 7 208 131 131 156 150 150 105 100 100 70 80 89 46 46 46 37 34 34
++19 25 31 14 13 13 4 5 6 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 4 4 5 1 1 2 0 0 0 2 1 0 9 6 4 71 32 32 127 80 21
++176 111 31 71 32 32 9 6 4 0 0 0 16 8 3 71 32 32 176 111 31 176 111 31
++71 32 32 5 3 2 0 0 0 37 34 34 156 150 150 254 254 254 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 156 150 150 19 25 31 0 0 0
++19 25 31 126 161 193 165 210 253 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 169 215 255 109 140 168 19 25 31 0 0 0 0 0 0 0 0 0
++0 0 0 55 70 84 151 192 230 167 212 255 167 212 255 167 212 255 165 210 253 140 179 215
++27 31 34 0 0 0 0 0 0 0 0 0 0 0 0 37 46 56 133 171 205 169 216 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 154 196 236 86 104 117
++6 7 9 0 0 0 46 46 46 180 180 180 255 255 255 226 226 226 137 137 137 46 46 46
++14 13 13 5 3 2 5 3 2 1 1 1 4 4 5 19 19 19 55 59 65 173 173 173
++251 251 251 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 181 33 33 170 0 0 193 71 71
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 211 125 125 170 0 0 149 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 110 0 0
++170 0 0 187 50 50 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++230 181 181 149 0 0 83 0 0 16 8 3 9 6 4 2 2 2 2 1 0 0 0 1
++0 0 0 0 0 0 0 0 0 2 3 4 14 13 13 27 31 34 46 46 46 70 80 89
++105 100 100 137 137 137 113 113 113 46 46 46 6 7 9 0 0 0 5 2 0 37 30 17
++127 80 21 176 111 31 56 42 30 11 2 0 0 0 0 16 8 3 127 80 21 176 111 31
++127 80 21 56 42 30 0 0 0 2 3 4 70 80 89 206 206 206 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 234 234 234 97 97 97 9 6 4 0 0 0
++55 70 84 151 192 230 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 168 213 255 165 210 253 109 140 168 10 12 13 1 1 2 0 0 0 0 0 0
++0 0 0 86 104 117 154 196 236 167 212 255 167 212 255 167 212 255 166 211 254 126 161 193
++18 19 24 0 0 0 0 0 0 0 0 0 4 4 5 55 70 84 154 196 236 168 214 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 166 211 254 133 171 205
++45 57 69 0 0 1 4 4 5 97 97 97 206 206 206 137 137 137 18 19 24 5 3 2
++1 1 2 2 3 4 14 13 13 10 12 13 0 0 0 2 2 2 9 6 4 46 46 46
++165 165 165 246 246 246 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 231 184 184 170 0 0 170 0 0
++226 168 168 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 243 221 221 170 0 0 170 0 0
++43 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 21 0 0 167 0 0
++170 0 0 224 164 164 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++239 239 239 141 107 101 16 8 3 1 1 1 0 0 1 1 1 1 6 7 9 2 1 0
++27 31 34 55 59 65 97 97 97 127 127 127 165 165 165 188 187 187 206 206 206 218 218 218
++223 222 222 218 218 218 198 194 194 137 137 137 46 46 46 1 1 1 0 0 0 16 8 3
++37 30 17 176 111 31 127 80 21 37 30 17 0 0 0 5 2 0 37 30 17 176 111 31
++178 112 31 127 80 21 16 8 3 2 1 0 14 13 13 137 137 137 246 246 246 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 188 187 187 46 46 46 0 0 1 4 5 6
++109 140 168 162 207 250 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 168 213 255 165 209 252 96 123 148 10 12 13 0 0 0 0 0 0 0 0 0
++1 1 2 96 123 148 161 204 245 167 212 255 167 212 255 167 212 255 167 212 255 126 161 193
++13 16 19 0 0 0 0 0 0 0 0 0 8 10 11 71 90 109 161 204 245 168 214 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 162 207 250
++96 123 148 13 16 19 0 0 0 27 31 34 87 87 87 46 46 46 2 2 2 0 0 0
++46 46 46 113 113 113 165 165 165 165 165 165 105 100 100 18 19 24 0 0 0 2 3 4
++46 46 46 173 173 173 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 250 248 248 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 199 87 87 170 0 0
++179 27 27 252 246 246 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 189 59 59 170 0 0
++110 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 68 0 0 170 0 0
++177 22 22 253 249 249 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++198 194 194 46 46 46 1 1 2 0 0 0 46 46 46 127 127 127 156 150 150 113 113 113
++87 87 87 180 180 180 228 228 228 226 226 226 214 214 214 198 194 194 180 180 180 145 144 144
++113 113 113 97 97 97 87 87 87 87 87 87 105 100 100 70 80 89 16 8 3 1 1 2
++5 2 0 71 32 32 176 111 31 127 80 21 2 1 0 2 1 0 16 8 3 127 80 21
++176 111 31 176 111 31 56 42 30 11 2 0 0 0 1 55 59 65 206 206 206 254 254 254
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 145 144 144 19 19 19 0 0 0 37 46 56
++140 179 215 165 209 252 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 168 213 255 165 210 253 109 140 168 10 12 13 1 1 2 0 0 0 0 0 0
++8 10 11 109 140 168 161 204 245 167 212 255 167 212 255 167 212 255 166 211 254 126 161 193
++13 16 19 0 0 0 0 0 0 0 0 0 10 12 13 86 104 117 162 207 250 168 214 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 168 214 255
++151 192 230 55 70 84 2 3 4 2 1 0 6 7 9 2 2 2 1 1 1 55 59 65
++180 180 180 246 246 246 254 254 254 254 254 254 241 241 241 156 150 150 37 34 34 0 0 0
++4 5 6 55 59 65 210 206 206 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 245 224 224 172 6 6
++170 0 0 218 144 144 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 222 158 158 170 0 0
++167 0 0 11 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 1 0 128 0 0 170 0 0
++204 103 103 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 252 246 246 243 242 242
++127 127 127 14 13 13 2 2 2 46 46 46 180 180 180 228 228 228 236 236 236 223 222 222
++145 144 144 97 97 97 113 113 113 113 113 113 97 97 97 105 100 100 113 113 113 137 137 137
++165 165 165 180 180 180 198 194 194 218 218 218 232 232 232 198 194 194 87 87 87 6 7 9
++5 3 2 16 8 3 127 80 21 176 111 31 37 30 17 0 0 0 2 2 2 34 13 13
++176 111 31 176 111 31 127 80 21 34 13 13 0 0 0 19 19 19 137 137 137 246 246 246
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 234 234 234 97 97 97 4 5 6 0 0 0 71 90 109
++157 201 242 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 118 151 181 33 37 45 0 0 0 0 0 0 2 3 4
++27 31 34 126 161 193 165 210 253 167 212 255 167 212 255 167 212 255 165 210 253 140 179 215
++27 31 34 0 0 0 0 0 0 0 0 0 19 25 31 96 123 148 166 211 254 168 213 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 168 214 255
++157 201 242 109 140 168 19 25 31 0 0 0 1 1 1 2 2 2 19 19 19 156 150 150
++246 246 246 255 255 255 255 255 255 255 255 255 255 255 255 243 242 242 156 150 150 19 19 19
++0 0 0 19 19 19 113 113 113 243 242 242 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 246 246 246 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 204 103 103
++170 0 0 178 25 25 253 249 249 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 252 246 246 176 19 19
++170 0 0 83 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 21 0 0 170 0 0 170 0 0
++233 190 190 255 255 255 255 255 255 255 255 255 243 221 221 194 73 73 170 1 1 182 36 36
++70 80 89 2 1 0 4 5 6 113 113 113 223 222 222 237 237 237 236 236 236 237 237 237
++226 226 226 127 127 127 70 80 89 165 165 165 198 194 194 214 214 214 228 228 228 234 234 234
++234 234 234 236 236 236 236 236 236 234 234 234 228 228 228 223 222 222 145 144 144 37 34 34
++0 0 0 1 1 1 56 42 30 176 111 31 127 80 21 16 8 3 0 0 0 16 8 3
++127 80 21 176 111 31 176 111 31 56 42 30 11 2 0 0 0 0 70 80 89 214 214 214
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 198 194 194 46 46 46 2 2 2 10 12 13 109 140 168
++162 207 250 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 168 214 255 151 192 230 86 104 117 19 25 31 8 10 11 33 37 45
++96 123 148 154 196 236 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 157 201 242
++86 104 117 13 16 19 6 7 9 18 19 24 71 90 109 140 179 215 169 216 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++169 215 255 140 179 215 55 70 84 0 0 0 0 0 0 0 0 0 87 87 87 223 222 222
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 254 254 254 234 234 234 113 113 113
++1 1 1 0 0 0 46 46 46 180 180 180 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 254 254 254 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 245 224 224
++171 3 3 170 0 0 224 164 164 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 209 119 119
++170 0 0 149 0 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 2 1 0 68 0 0 170 0 0 177 22 22
++254 252 252 255 255 255 255 255 255 232 187 187 173 12 12 170 0 0 170 0 0 120 0 0
++37 30 17 0 0 0 27 31 34 165 165 165 234 234 234 237 237 237 236 236 236 236 236 236
++241 241 241 198 194 194 113 113 113 173 173 173 239 239 239 234 234 234 228 228 228 223 222 222
++214 214 214 206 206 206 188 187 187 165 165 165 137 137 137 113 113 113 105 100 100 55 59 65
++10 12 13 1 1 1 11 2 0 127 80 21 176 111 31 37 30 17 0 0 0 5 2 0
++56 42 30 176 111 31 176 111 31 127 80 21 16 8 3 0 0 0 27 31 34 165 165 165
++253 253 253 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 254 254 254 165 165 165 27 31 34 0 0 1 33 37 45 133 171 205
++165 210 253 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 154 196 236 109 140 168 109 140 168 126 161 193
++161 204 245 167 212 255 166 211 254 166 211 254 166 211 254 166 211 254 166 211 254 165 210 253
++151 192 230 96 123 148 86 104 117 109 140 168 151 192 230 169 215 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 162 207 250 90 112 135 10 12 13 0 0 0 19 25 31 156 150 150 246 246 246
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 254 254 254 206 206 206
++55 59 65 0 0 0 8 10 11 105 100 100 236 236 236 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++197 81 81 170 0 0 189 59 59 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 245 224 224
++171 2 2 170 0 0 43 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 170 0 0 204 103 103
++255 255 255 255 255 255 239 206 206 173 10 10 175 14 14 206 110 110 194 73 73 141 107 101
++27 31 34 0 0 0 55 59 65 198 194 194 237 237 237 236 236 236 236 236 236 236 236 236
++236 236 236 239 239 239 165 165 165 113 113 113 198 194 194 173 173 173 156 150 150 127 127 127
++105 100 100 105 100 100 105 100 100 127 127 127 137 137 137 165 165 165 198 194 194 188 187 187
++55 59 65 9 6 4 0 0 0 37 30 17 176 111 31 88 72 43 11 2 0 0 0 0
++34 13 13 127 80 21 178 112 31 176 111 31 37 30 17 11 2 0 2 3 4 113 113 113
++234 234 234 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 246 246 246 113 113 113 10 12 13 0 0 0 55 70 84 151 192 230
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 168 213 255 168 213 255 167 212 255 162 207 250 157 201 242
++151 192 230 140 179 215 140 179 215 140 179 215 140 179 215 140 179 215 151 192 230 154 196 236
++161 204 245 168 214 255 167 212 255 169 215 255 167 212 255 166 211 254 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++168 213 255 157 201 242 90 112 135 4 5 6 0 0 1 91 72 72 214 214 214 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 254 254 254 250 248 248
++145 144 144 10 12 13 0 0 0 37 34 34 180 180 180 254 254 254 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++232 187 187 170 0 0 170 0 0 239 206 206 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++185 47 47 170 0 0 83 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 21 0 0 170 0 0 170 0 0 233 190 190
++255 255 255 255 254 254 189 59 59 170 0 0 173 10 10 219 148 148 251 251 251 156 150 150
++19 19 19 0 0 0 70 80 89 198 194 194 239 239 239 236 236 236 236 236 236 236 236 236
++236 236 236 236 236 236 214 214 214 97 97 97 87 87 87 113 113 113 127 127 127 145 144 144
++173 173 173 206 206 206 223 222 222 232 232 232 239 239 239 241 241 241 239 239 239 243 242 242
++145 144 144 19 19 19 2 1 0 16 8 3 127 80 21 127 80 21 16 8 3 5 2 0
++0 0 0 127 80 21 176 111 31 176 111 31 127 80 21 9 6 4 2 1 0 55 59 65
++206 206 206 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 223 222 222 87 87 87 2 2 2 2 2 2 90 112 135 157 201 242
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 162 207 250 154 196 236 133 171 205 118 151 181 90 112 135 71 90 109
++55 70 84 45 57 69 37 46 56 37 46 56 37 46 56 37 46 56 55 70 84 71 90 109
++96 123 148 118 151 181 151 192 230 161 204 245 167 212 255 168 213 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++169 215 255 140 179 215 55 70 84 0 0 0 4 5 6 113 113 113 237 237 237 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 251 251 251
++210 206 206 55 59 65 0 0 0 10 12 13 113 113 113 239 239 239 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 183 41 41 170 0 0 202 97 97 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++241 213 213 198 84 84 202 97 97 252 246 246 255 255 255 255 255 255 255 255 255 255 255 255
++199 87 87 167 0 0 110 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 68 0 0 170 0 0 177 22 22 254 252 252
++255 255 255 255 255 255 173 12 12 170 0 0 191 64 64 255 255 255 251 251 251 145 144 144
++14 13 13 0 0 0 91 72 72 206 206 206 239 239 239 236 236 236 236 236 236 236 236 236
++236 236 236 236 236 236 232 232 232 156 150 150 105 100 100 223 222 222 236 236 236 239 239 239
++241 241 241 241 241 241 239 239 239 234 234 234 228 228 228 218 218 218 206 206 206 198 194 194
++156 150 150 37 34 34 1 1 2 0 0 0 71 32 32 176 111 31 56 42 30 2 1 0
++5 3 2 56 42 30 176 111 31 176 111 31 127 80 21 34 13 13 1 1 1 19 19 19
++165 165 165 250 248 248 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 198 194 194 46 46 46 1 1 1 18 19 24 109 140 168 166 211 254
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++166 211 254 151 192 230 109 140 168 71 90 109 37 46 56 18 19 24 2 3 4 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
++2 3 4 19 25 31 55 70 84 96 123 148 133 171 205 161 204 245 168 213 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++168 213 255 126 161 193 33 37 45 0 0 1 19 25 31 165 165 165 253 253 253 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 234 234 234 188 187 187
++145 144 144 55 59 65 5 2 0 0 0 0 46 46 46 198 194 194 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 219 148 148 170 0 0 173 8 8 249 238 238 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++206 110 110 170 0 0 170 0 0 188 55 55 224 164 164 251 242 242 255 255 255 255 255 255
++212 128 128 170 0 0 138 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 2 1 0 128 0 0 170 0 0 204 103 103 255 255 255
++255 255 255 253 249 249 170 0 0 170 0 0 211 125 125 255 255 255 251 251 251 137 137 137
++11 2 0 0 0 0 87 87 87 206 206 206 239 239 239 236 236 236 236 236 236 236 236 236
++236 236 236 236 236 236 237 237 237 206 206 206 113 113 113 198 194 194 234 234 234 223 222 222
++214 214 214 206 206 206 188 187 187 173 173 173 145 144 144 137 137 137 127 127 127 127 127 127
++127 127 127 55 59 65 6 7 9 0 0 0 37 30 17 127 80 21 127 80 21 0 0 0
++5 3 2 34 13 13 176 111 31 178 112 31 176 111 31 56 42 30 0 0 0 4 4 5
++113 113 113 237 237 237 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 165 165 165 27 31 34 0 0 0 37 46 56 133 171 205 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 162 207 250
++140 179 215 71 90 109 19 25 31 1 1 1 0 0 1 0 0 0 1 1 1 16 8 3
++16 8 3 37 30 17 37 30 17 37 30 17 37 30 17 37 30 17 16 8 3 9 6 4
++0 0 0 0 0 1 0 0 0 10 12 13 45 57 69 96 123 148 151 192 230 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 168 213 255
++165 209 252 109 140 168 18 19 24 2 1 0 55 59 65 206 206 206 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 232 232 232 127 127 127 46 46 46
++10 12 13 4 4 5 0 0 0 1 1 1 19 19 19 127 127 127 239 239 239 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 175 14 14 170 0 0 217 141 141 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++219 152 152 217 141 141 182 36 36 170 0 0 170 0 0 197 81 81 255 255 255 255 255 255
++226 168 168 170 0 0 160 0 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 11 2 0 167 0 0 170 0 0 231 184 184 255 255 255
++255 255 255 250 240 240 170 1 1 171 3 3 205 106 106 255 255 255 251 251 251 91 72 72
++21 0 0 0 0 0 87 87 87 206 206 206 239 239 239 236 236 236 236 236 236 236 236 236
++236 236 236 236 236 236 236 236 236 226 226 226 127 127 127 113 113 113 165 165 165 145 144 144
++127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 145 144 144 165 165 165 198 194 194
++218 218 218 165 165 165 27 31 34 0 0 0 16 8 3 127 80 21 127 80 21 16 8 3
++0 0 0 16 8 3 127 80 21 177 112 32 176 111 31 88 72 43 11 2 0 0 0 0
++87 87 87 223 222 222 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 251 251 251 137 137 137 19 19 19 0 0 0 55 70 84 140 179 215 169 215 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 162 207 250 126 161 193
++55 70 84 4 5 6 1 1 2 2 1 0 34 13 13 56 42 30 88 72 43 127 80 21
++134 90 49 180 122 43 180 122 43 215 156 66 180 122 43 180 122 43 134 90 49 134 90 49
++88 72 43 37 30 17 16 8 3 0 0 0 0 0 0 19 25 31 90 112 135 151 192 230
++168 214 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 168 213 255
++161 204 245 90 112 135 8 10 11 0 0 0 87 87 87 223 222 222 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 250 248 248 156 150 150 19 19 19 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 46 46 46 127 127 127 214 214 214
++250 248 248 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 205 106 106 170 0 0 189 59 59 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 253 248 248 229 177 177
++201 95 95 175 16 16 170 0 0 182 36 36 205 106 106 237 200 200 255 255 255 255 255 255
++248 233 233 171 4 4 170 0 0 55 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 55 0 0 170 0 0 172 5 5 252 246 246 255 255 255
++255 255 255 255 255 255 194 73 73 170 0 0 197 81 81 252 246 246 235 197 197 110 0 0
++11 2 0 0 0 0 70 80 89 206 206 206 239 239 239 236 236 236 236 236 236 236 236 236
++236 236 236 236 236 236 236 236 236 232 232 232 173 173 173 55 59 65 113 113 113 137 137 137
++165 165 165 180 180 180 206 206 206 218 218 218 232 232 232 239 239 239 243 242 242 243 242 242
++243 242 242 206 206 206 46 46 46 0 0 1 11 2 0 88 72 43 176 111 31 34 13 13
++5 2 0 5 3 2 127 80 21 178 112 31 176 111 31 127 80 21 16 8 3 2 2 2
++46 46 46 206 206 206 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 243 242 242 113 113 113 6 7 9 0 0 0 71 90 109 154 196 236 168 213 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 162 207 250 133 171 205 45 57 69
++0 0 1 2 2 2 16 8 3 88 72 43 134 90 49 215 156 66 215 156 66 248 180 77
++251 182 78 251 182 78 251 182 78 251 182 78 251 182 78 251 182 78 251 182 78 248 180 77
++215 156 66 180 122 43 127 80 21 37 30 17 5 3 2 0 0 0 19 25 31 96 123 148
++161 204 245 168 214 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 168 213 255
++157 201 242 86 104 117 1 1 2 2 3 4 105 100 100 234 234 234 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 228 228 228 55 59 65 0 0 0 2 3 4
++33 37 45 55 70 84 33 37 45 10 12 13 0 0 0 0 0 1 14 13 13 70 80 89
++165 165 165 234 234 234 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 231 184 184 170 0 0 171 3 3 249 238 238 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 250 240 240 226 168 168 199 87 87 175 14 14 170 0 0
++179 27 27 208 114 114 239 206 206 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 194 73 73 170 0 0 110 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 98 0 0 167 0 0 189 59 59 255 255 255 255 255 255
++255 255 255 255 255 255 233 190 190 170 0 0 179 27 27 194 73 73 173 12 12 98 0 0
++21 0 0 0 0 0 55 59 65 198 194 194 237 237 237 236 236 236 236 236 236 236 236 236
++236 236 236 236 236 236 236 236 236 236 236 236 206 206 206 113 113 113 188 187 187 236 236 236
++236 236 236 241 241 241 243 242 242 243 242 242 239 239 239 234 234 234 223 222 222 214 214 214
++188 187 187 165 165 165 46 46 46 4 4 5 0 0 0 71 32 32 176 111 31 37 30 17
++11 2 0 5 3 2 71 32 32 176 111 31 178 112 31 127 80 21 37 30 17 0 0 0
++27 31 34 173 173 173 253 253 253 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 226 226 226 87 87 87 1 1 1 2 3 4 90 112 135 157 201 242 168 213 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 140 179 215 55 70 84 4 4 5
++0 0 0 34 13 13 134 90 49 215 156 66 248 180 77 251 182 78 251 182 78 251 182 78
++248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77
++251 182 78 251 182 78 248 180 77 180 122 43 88 72 43 0 0 0 2 1 0 37 46 56
++126 161 193 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 168 214 255
++151 192 230 71 90 109 0 0 0 2 2 2 127 127 127 239 239 239 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 206 206 206 37 34 34 0 0 0 13 16 19
++96 123 148 140 179 215 126 161 193 86 104 117 37 46 56 6 7 9 0 0 0 5 2 0
++37 34 34 137 137 137 228 228 228 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 173 12 12 170 0 0 224 161 161 255 255 255 255 255 255
++234 194 194 187 53 53 176 19 19 170 0 0 170 0 0 175 14 14 202 97 97 233 190 190
++254 253 253 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 226 168 168 170 0 0 167 0 0 11 2 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 138 0 0 170 0 0 210 122 122 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 199 87 87 170 0 0 170 0 0 170 0 0 110 0 0
++34 13 13 0 0 0 55 59 65 188 187 187 237 237 237 236 236 236 236 236 236 236 236 236
++236 236 236 236 236 236 236 236 236 236 236 236 223 222 222 137 137 137 165 165 165 246 246 246
++237 237 237 223 222 222 214 214 214 180 180 180 165 165 165 137 137 137 127 127 127 127 127 127
++127 127 127 127 127 127 70 80 89 4 5 6 5 2 0 37 30 17 176 111 31 71 32 32
++0 0 0 9 6 4 56 42 30 176 111 31 176 111 31 176 111 31 37 30 17 0 0 0
++8 10 11 145 144 144 246 246 246 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 206 206 206 55 59 65 0 0 1 10 12 13 109 140 168 162 207 250 167 212 255
++167 212 255 167 212 255 167 212 255 166 211 254 157 201 242 86 104 117 8 10 11 5 3 2
++16 8 3 134 90 49 215 156 66 251 182 78 248 180 77 248 180 77 248 180 77 248 180 77
++248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77
++248 180 77 248 180 77 248 180 77 248 180 77 180 122 43 56 42 30 0 0 0 6 7 9
++86 104 117 154 196 236 168 214 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 168 213 255
++151 192 230 70 80 89 0 0 0 6 7 9 127 127 127 246 246 246 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 180 180 180 19 19 19 0 0 1 27 31 34
++140 179 215 172 216 255 166 211 254 157 201 242 126 161 193 71 90 109 19 25 31 0 0 1
++2 1 0 19 25 31 127 127 127 228 228 228 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 199 87 87 170 0 0 189 59 59 255 255 255 255 255 255
++218 144 144 170 0 0 170 0 0 193 71 71 227 171 171 252 246 246 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 252 246 246 175 16 16 170 0 0 68 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 11 2 0 170 0 0 170 0 0 232 187 187 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 242 216 216 219 148 148 204 103 103 141 107 101
++46 46 46 0 0 0 37 34 34 173 173 173 236 236 236 236 236 236 236 236 236 236 236 236
++236 236 236 236 236 236 236 236 236 236 236 236 232 232 232 156 150 150 113 113 113 156 150 150
++137 137 137 127 127 127 127 127 127 127 127 127 127 127 127 137 137 137 156 150 150 173 173 173
++198 194 194 214 214 214 137 137 137 14 13 13 0 0 0 34 13 13 127 80 21 127 80 21
++0 0 0 2 1 0 37 30 17 176 111 31 176 111 31 176 111 31 56 42 30 11 2 0
++0 0 1 127 127 127 241 241 241 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 180 180 180 37 34 34 1 1 1 19 25 31 126 161 193 165 209 252 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 118 151 181 27 31 34 0 0 1 9 6 4
++127 80 21 215 156 66 251 182 78 251 182 78 248 180 77 248 180 77 248 180 77 248 180 77
++248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77
++248 180 77 248 180 77 248 180 77 251 182 78 248 180 77 134 90 49 16 8 3 1 1 1
++37 46 56 133 171 205 168 214 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 168 214 255
++151 192 230 55 70 84 0 0 1 10 12 13 145 144 144 246 246 246 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 180 180 180 19 19 19 0 0 0 33 37 45
++140 179 215 168 214 255 167 212 255 168 214 255 167 212 255 151 192 230 96 123 148 37 46 56
++2 3 4 2 1 0 19 19 19 127 127 127 223 222 222 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 234 194 194 170 0 0 170 0 0 239 206 206 255 255 255
++252 246 246 215 135 135 237 203 203 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 198 84 84 170 0 0 110 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 55 0 0 170 0 0 172 5 5 252 246 246 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 214 214 214
++91 72 72 0 0 0 10 12 13 156 150 150 232 232 232 237 237 237 236 236 236 236 236 236
++236 236 236 236 236 236 236 236 236 236 236 236 232 232 232 180 180 180 70 80 89 127 127 127
++145 144 144 165 165 165 180 180 180 198 194 194 210 206 206 223 222 222 232 232 232 241 241 241
++241 241 241 241 241 241 165 165 165 19 19 19 1 1 1 34 13 13 127 80 21 127 80 21
++1 1 1 5 2 0 37 30 17 127 80 21 176 111 31 176 111 31 71 32 32 2 1 0
++0 0 0 113 113 113 236 236 236 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++250 248 248 137 137 137 19 19 19 0 0 0 45 57 69 133 171 205 167 212 255 167 212 255
++167 212 255 167 212 255 166 211 254 157 201 242 70 80 89 0 0 1 11 2 0 56 42 30
++215 156 66 251 182 78 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77
++248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77
++248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 215 156 66 56 42 30 0 0 0
++19 25 31 109 140 168 165 210 253 168 213 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 168 214 255
++140 179 215 55 70 84 0 0 0 14 13 13 145 144 144 251 251 251 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 180 180 180 19 19 19 0 0 1 27 31 34
++140 179 215 169 215 255 167 212 255 167 212 255 167 212 255 168 214 255 162 207 250 118 151 181
++45 57 69 4 4 5 0 0 0 19 19 19 113 113 113 228 228 228 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 185 47 47 170 0 0 202 97 97 255 255 255
++255 255 255 255 254 254 255 255 255 255 255 255 252 246 246 242 216 216 255 255 255 253 249 249
++235 197 197 212 128 128 191 64 64 173 12 12 172 5 5 193 71 71 237 200 200 255 255 255
++255 255 255 255 255 255 219 152 152 170 0 0 160 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 98 0 0 167 0 0 189 59 59 255 254 254 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 232 232 232
++97 97 97 0 0 1 2 2 2 113 113 113 223 222 222 237 237 237 236 236 236 236 236 236
++236 236 236 236 236 236 236 236 236 236 236 236 236 236 236 198 194 194 113 113 113 180 180 180
++226 226 226 232 232 232 237 237 237 241 241 241 239 239 239 237 237 237 226 226 226 206 206 206
++173 173 173 156 150 150 97 97 97 10 12 13 0 0 0 16 8 3 127 80 21 127 80 21
++5 3 2 0 0 0 34 13 13 176 111 31 176 111 31 176 111 31 71 32 32 16 8 3
++0 0 0 105 100 100 232 232 232 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++228 228 228 97 97 97 4 4 5 0 0 0 71 90 109 154 196 236 168 213 255 167 212 255
++167 212 255 167 212 255 166 211 254 118 151 181 18 19 24 0 0 1 34 13 13 177 120 42
++248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77
++248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77
++248 180 77 248 180 77 248 180 77 248 180 77 251 182 78 215 156 66 88 72 43 5 2 0
++6 7 9 90 112 135 161 204 245 168 213 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 168 214 255
++140 179 215 45 57 69 0 0 1 13 16 19 156 150 150 253 253 253 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 198 194 194 19 25 31 2 1 0 19 25 31
++133 171 205 168 213 255 167 212 255 167 212 255 167 212 255 167 212 255 168 213 255 165 209 252
++126 161 193 45 57 69 6 7 9 0 0 0 18 19 24 127 127 127 234 234 234 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 219 152 152 170 0 0 176 19 19 254 253 253
++255 255 255 255 255 255 255 255 255 241 213 213 209 119 119 205 106 106 179 27 27 172 6 6
++170 0 0 170 0 0 170 1 1 182 36 36 170 0 0 170 0 0 171 3 3 224 164 164
++255 255 255 255 255 255 243 221 221 170 0 0 170 0 0 32 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 128 0 0 170 0 0 209 119 119 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 250 248 248
++127 127 127 14 13 13 0 0 0 87 87 87 214 214 214 237 237 237 236 236 236 236 236 236
++236 236 236 236 236 236 236 236 236 236 236 236 237 237 237 206 206 206 127 127 127 188 187 187
++246 246 246 237 237 237 223 222 222 188 187 187 165 165 165 127 127 127 113 113 113 113 113 113
++113 113 113 137 137 137 127 127 127 19 19 19 1 1 1 16 8 3 127 80 21 127 80 21
++9 6 4 2 2 2 34 13 13 127 80 21 178 112 31 176 111 31 88 72 43 5 2 0
++0 0 0 105 100 100 232 232 232 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++198 194 194 46 46 46 0 0 0 13 16 19 109 140 168 162 207 250 168 213 255 167 212 255
++167 212 255 167 212 255 161 204 245 71 90 109 1 1 1 0 0 0 88 72 43 215 156 66
++251 182 78 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77
++248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77
++248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 127 80 21 0 0 0
++4 5 6 86 104 117 157 201 242 168 213 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 169 215 255
++140 179 215 45 57 69 0 0 0 14 13 13 145 144 144 251 251 251 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 206 206 206 37 34 34 0 0 1 13 16 19
++118 151 181 168 214 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 168 213 255
++166 211 254 126 161 193 45 57 69 2 2 2 2 1 0 18 19 24 137 137 137 246 246 246
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 245 224 224 170 0 0 170 0 0 237 200 200
++255 255 255 255 255 255 252 246 246 208 114 114 182 36 36 170 0 0 173 8 8 193 71 71
++215 135 135 227 171 171 243 227 227 253 249 249 224 161 161 183 41 41 170 0 0 172 7 7
++249 238 238 255 255 255 255 255 255 181 33 33 167 0 0 83 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 167 0 0 170 0 0 228 174 174 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++165 165 165 27 31 34 0 0 0 46 46 46 198 194 194 237 237 237 236 236 236 236 236 236
++236 236 236 236 236 236 236 236 236 236 236 236 236 236 236 218 218 218 127 127 127 127 127 127
++156 150 150 127 127 127 113 113 113 105 100 100 113 113 113 145 144 144 173 173 173 198 194 194
++218 218 218 228 228 228 180 180 180 27 31 34 0 0 0 16 8 3 127 80 21 127 80 21
++16 8 3 0 0 0 34 13 13 127 80 21 180 122 43 176 111 31 71 32 32 16 8 3
++0 0 0 105 100 100 232 232 232 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 251 251 251
++156 150 150 18 19 24 2 1 0 37 46 56 133 171 205 168 214 255 167 212 255 167 212 255
++167 212 255 167 212 255 140 179 215 37 46 56 0 0 0 16 8 3 134 90 49 251 182 78
++248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77
++248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77
++248 180 77 248 180 77 248 180 77 248 180 77 251 182 78 215 156 66 127 80 21 2 3 4
++2 3 4 90 112 135 157 201 242 168 213 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 168 214 255
++151 192 230 55 70 84 2 3 4 9 6 4 137 137 137 243 242 242 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 218 218 218 46 46 46 1 1 2 8 10 11
++96 123 148 168 214 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++168 213 255 166 211 254 126 161 193 45 57 69 1 1 1 1 1 1 27 31 34 156 150 150
++251 251 251 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 183 41 41 170 0 0 212 128 128
++255 255 255 255 255 255 228 174 174 196 78 78 170 0 0 193 71 71 253 248 248 254 251 251
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 237 203 203 170 0 0 170 0 0
++230 181 181 255 255 255 255 255 255 201 95 95 170 0 0 120 0 0 0 0 0 0 0 0
++
++0 0 0 21 0 0 170 0 0 170 0 0 242 216 216 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++198 194 194 46 46 46 1 1 1 19 19 19 165 165 165 232 232 232 236 236 236 236 236 236
++236 236 236 236 236 236 236 236 236 236 236 236 236 236 236 226 226 226 113 113 113 70 80 89
++127 127 127 165 165 165 188 187 187 206 206 206 218 218 218 228 228 228 234 234 234 237 237 237
++234 234 234 223 222 222 156 150 150 19 19 19 0 0 0 16 8 3 127 80 21 127 80 21
++5 3 2 0 0 0 37 30 17 127 80 21 178 112 31 176 111 31 71 32 32 2 1 0
++0 0 0 113 113 113 236 236 236 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 232 232 232
++113 113 113 2 2 2 0 0 0 71 90 109 151 192 230 168 214 255 167 212 255 167 212 255
++167 212 255 167 212 255 126 161 193 18 19 24 2 1 0 37 30 17 215 156 66 251 182 78
++248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77
++248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77
++248 180 77 248 180 77 248 180 77 248 180 77 251 182 78 215 156 66 88 72 43 0 0 0
++13 16 19 96 123 148 162 207 250 168 213 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 168 213 255
++154 196 236 71 90 109 0 0 0 0 0 0 113 113 113 237 237 237 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 234 234 234 70 80 89 0 0 0 8 10 11
++71 90 109 165 210 253 168 213 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 168 213 255 165 210 253 118 151 181 37 46 56 0 0 0 1 1 1 37 34 34
++173 173 173 253 253 253 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 206 110 110 170 0 0 194 73 73
++255 255 255 255 255 255 226 168 168 171 4 4 175 14 14 248 236 236 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 175 16 16 170 0 0
++211 125 125 255 255 255 255 255 255 222 155 155 167 0 0 160 0 0 0 0 0 0 0 0
++
++0 0 0 55 0 0 167 0 0 172 6 6 254 252 252 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++228 228 228 87 87 87 4 4 5 0 0 0 113 113 113 218 218 218 239 239 239 236 236 236
++236 236 236 236 236 236 236 236 236 236 236 236 237 237 237 226 226 226 145 144 144 127 127 127
++226 226 226 234 234 234 234 234 234 236 236 236 234 234 234 223 222 222 198 194 194 165 165 165
++127 127 127 113 113 113 70 80 89 9 6 4 1 1 2 16 8 3 127 80 21 127 80 21
++0 0 0 1 1 1 37 30 17 176 111 31 177 112 32 176 111 31 56 42 30 5 2 0
++2 3 4 127 127 127 243 242 242 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 206 206 206
++55 59 65 0 0 0 13 16 19 96 123 148 162 207 250 168 213 255 167 212 255 167 212 255
++167 212 255 166 211 254 96 123 148 4 5 6 2 1 0 71 32 32 215 156 66 251 182 78
++248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77
++248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77
++248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 180 122 43 37 30 17 0 0 0
++33 37 45 118 151 181 168 214 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 168 214 255
++157 201 242 90 112 135 4 5 6 0 0 0 97 97 97 228 228 228 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 246 246 246 113 113 113 0 0 0 2 2 2
++45 57 69 151 192 230 169 215 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 165 210 253 109 140 168 33 37 45 0 0 1 2 2 2
++55 59 65 188 187 187 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 226 168 168 170 0 0 176 19 19
++255 255 255 255 255 255 200 91 91 170 0 0 183 41 41 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 237 200 200 196 78 78 170 0 0
++210 122 122 255 255 255 255 255 255 242 216 216 170 0 0 170 0 0 21 0 0 2 1 0
++
++0 0 0 68 0 0 170 0 0 184 44 44 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++250 248 248 137 137 137 14 13 13 2 1 0 55 59 65 206 206 206 236 236 236 236 236 236
++236 236 236 236 236 236 236 236 236 236 236 236 236 236 236 228 228 228 156 150 150 137 137 137
++236 236 236 228 228 228 206 206 206 173 173 173 137 137 137 105 100 100 97 97 97 113 113 113
++156 150 150 180 180 180 137 137 137 19 19 19 0 0 0 34 13 13 127 80 21 88 72 43
++0 0 0 11 2 0 37 30 17 176 111 31 178 112 31 127 80 21 37 30 17 0 0 0
++19 19 19 156 150 150 250 248 248 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 251 251 251 165 165 165
++19 19 19 0 0 0 37 46 56 126 161 193 168 214 255 167 212 255 167 212 255 167 212 255
++168 213 255 161 204 245 71 90 109 0 0 0 4 5 6 127 80 21 248 180 77 248 180 77
++248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77
++248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77
++248 180 77 248 180 77 248 180 77 251 182 78 215 156 66 134 90 49 11 2 0 0 0 0
++55 70 84 140 179 215 168 214 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 168 213 255
++162 207 250 96 123 148 10 12 13 0 0 0 70 80 89 214 214 214 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 253 253 253 165 165 165 10 12 13 0 0 0
++19 25 31 109 140 168 169 215 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 168 213 255 165 209 252 96 123 148 18 19 24 0 0 0
++5 2 0 70 80 89 214 214 214 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 243 221 221 170 0 0 170 0 0
++242 216 216 255 255 255 216 138 138 170 0 0 181 33 33 255 254 254 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 237 200 200 235 197 197 241 213 213 193 71 71 170 0 0
++232 187 187 255 255 255 255 255 255 255 255 255 177 22 22 170 0 0 68 0 0 0 0 0
++
++0 0 0 98 0 0 170 0 0 196 78 78 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 180 180 180 37 34 34 2 3 4 19 19 19 165 165 165 232 232 232 236 236 236
++236 236 236 236 236 236 236 236 236 236 236 236 236 236 236 228 228 228 165 165 165 97 97 97
++145 144 144 113 113 113 87 87 87 105 100 100 137 137 137 180 180 180 210 206 206 228 228 228
++234 234 234 232 232 232 137 137 137 6 7 9 1 1 1 34 13 13 127 80 21 71 32 32
++0 0 0 5 3 2 71 32 32 176 111 31 177 112 32 127 80 21 16 8 3 2 1 0
++46 46 46 198 194 194 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 239 239 239 113 113 113
++4 5 6 0 0 0 70 80 89 151 192 230 168 214 255 167 212 255 167 212 255 167 212 255
++168 213 255 154 196 236 45 57 69 1 1 2 9 6 4 134 90 49 251 182 78 248 180 77
++248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77
++248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77
++248 180 77 248 180 77 248 180 77 248 180 77 180 122 43 37 30 17 0 0 0 13 16 19
++96 123 148 161 204 245 168 214 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 168 213 255
++166 211 254 109 140 168 19 25 31 0 0 0 46 46 46 198 194 194 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 214 214 214 55 59 65 2 1 0
++4 5 6 70 80 89 154 196 236 168 214 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 157 201 242 86 104 117 8 10 11
++0 0 1 9 6 4 105 100 100 234 234 234 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 175 14 14 170 0 0
++228 174 174 255 255 255 247 231 231 183 41 41 170 0 0 219 152 152 255 255 255 255 255 255
++250 240 240 251 244 244 239 209 209 224 161 161 205 106 106 184 44 44 170 0 0 204 103 103
++255 255 255 255 255 255 255 255 255 255 255 255 187 50 50 170 0 0 83 0 0 0 0 0
++
++0 0 0 120 0 0 170 0 0 206 110 110 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 223 222 222 87 87 87 4 5 6 0 0 0 105 100 100 218 218 218 236 236 236
++236 236 236 236 236 236 236 236 236 236 236 236 237 237 237 228 228 228 165 165 165 55 59 65
++137 137 137 165 165 165 206 206 206 223 222 222 232 232 232 232 232 232 218 218 218 206 206 206
++165 165 165 127 127 127 46 46 46 0 0 1 11 2 0 37 30 17 176 111 31 88 72 43
++16 8 3 34 13 13 127 80 21 176 111 31 176 111 31 71 32 32 5 3 2 0 0 0
++87 87 87 218 218 218 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 254 254 254 214 214 214 55 59 65
++0 0 0 10 12 13 90 112 135 161 204 245 168 214 255 167 212 255 167 212 255 167 212 255
++168 214 255 151 192 230 45 57 69 0 0 0 14 13 13 177 120 42 251 182 78 248 180 77
++248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77
++248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77
++248 180 77 248 180 77 248 180 77 215 156 66 88 72 43 0 0 0 0 0 1 55 70 84
++140 179 215 169 215 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++168 213 255 126 161 193 33 37 45 0 0 0 27 31 34 173 173 173 253 253 253 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 246 246 246 137 137 137 6 7 9
++0 0 1 27 31 34 109 140 168 169 215 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 168 213 255 151 192 230 71 90 109
++4 5 6 2 3 4 19 19 19 145 144 144 250 248 248 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 183 41 41 170 0 0
++218 144 144 255 255 255 255 255 255 234 194 194 170 0 0 171 2 2 198 84 84 211 125 125
++200 91 91 182 36 36 170 0 0 170 0 0 170 1 1 173 8 8 215 135 135 255 254 254
++255 255 255 255 255 255 255 255 255 255 255 255 193 71 71 167 0 0 98 0 0 0 0 0
++
++0 0 0 128 0 0 170 0 0 210 122 122 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 251 251 251 137 137 137 19 19 19 0 0 0 46 46 46 180 180 180 236 236 236
++236 236 236 236 236 236 236 236 236 236 236 236 236 236 236 228 228 228 165 165 165 127 127 127
++234 234 234 236 236 236 228 228 228 214 214 214 188 187 187 156 150 150 113 113 113 113 113 113
++127 127 127 137 137 137 55 59 65 2 1 0 0 0 0 71 32 32 176 111 31 176 111 31
++127 80 21 127 80 21 176 111 31 176 111 31 127 80 21 37 30 17 5 2 0 8 10 11
++127 127 127 243 242 242 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 251 251 251 173 173 173 27 31 34
++2 1 0 33 37 45 118 151 181 168 213 255 167 212 255 167 212 255 167 212 255 167 212 255
++168 214 255 151 192 230 33 37 45 1 1 2 16 8 3 177 120 42 248 180 77 248 180 77
++248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77
++248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77
++248 180 77 248 180 77 215 156 66 88 72 43 5 2 0 0 0 0 27 31 34 109 140 168
++165 209 252 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++168 214 255 140 179 215 45 57 69 0 0 1 10 12 13 145 144 144 246 246 246 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 254 254 254 214 214 214 55 59 65
++2 1 0 4 5 6 70 80 89 154 196 236 168 214 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 140 179 215
++45 57 69 2 3 4 2 2 2 37 34 34 173 173 173 253 253 253 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 193 71 71 170 0 0
++208 114 114 255 255 255 255 255 255 255 255 255 234 194 194 187 53 53 170 0 0 170 0 0
++170 0 0 172 7 7 189 59 59 209 119 119 230 181 181 250 240 240 255 254 254 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 200 91 91 170 0 0 110 0 0 0 0 0
++
++0 0 0 128 0 0 170 0 0 212 128 128 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 198 194 194 55 59 65 0 0 0 6 7 9 113 113 113 226 226 226
++236 236 236 236 236 236 236 236 236 236 236 236 236 236 236 228 228 228 156 150 150 127 127 127
++206 206 206 188 187 187 145 144 144 113 113 113 113 113 113 127 127 127 165 165 165 198 194 194
++210 206 206 165 165 165 46 46 46 1 1 1 0 0 0 127 80 21 176 111 31 176 111 31
++178 112 31 178 112 31 176 111 31 176 111 31 71 32 32 5 2 0 0 0 0 55 59 65
++198 194 194 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 239 239 239 127 127 127 5 3 2
++0 0 0 55 70 84 140 179 215 169 215 255 167 212 255 167 212 255 167 212 255 167 212 255
++169 215 255 140 179 215 37 46 56 2 1 0 14 13 13 180 122 43 251 182 78 248 180 77
++248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77
++248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77
++248 180 77 215 156 66 127 80 21 16 8 3 1 1 1 13 16 19 90 112 135 154 196 236
++169 215 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++168 213 255 151 192 230 70 80 89 0 0 0 5 3 2 113 113 113 237 237 237 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 246 246 246 145 144 144
++6 7 9 1 1 2 19 25 31 109 140 168 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 168 213 255
++126 161 193 33 37 45 0 0 0 9 6 4 55 59 65 206 206 206 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 204 103 103 170 0 0
++196 78 78 255 255 255 255 255 255 255 255 255 255 255 255 254 253 253 239 209 209 231 184 184
++241 213 213 253 249 249 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 206 110 110 170 0 0 120 0 0 0 0 0
++
++0 0 0 160 0 0 167 0 0 222 158 158 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 243 242 242 113 113 113 14 13 13 0 0 0 46 46 46 188 187 187
++234 234 234 236 236 236 236 236 236 236 236 236 237 237 237 223 222 222 137 137 137 70 80 89
++113 113 113 105 100 100 127 127 127 173 173 173 210 206 206 223 222 222 206 206 206 156 150 150
++87 87 87 27 31 34 0 0 0 0 0 0 16 8 3 127 80 21 176 111 31 178 112 31
++177 112 32 177 112 32 176 111 31 71 32 32 34 13 13 0 0 0 13 16 19 127 127 127
++241 241 241 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 214 214 214 91 72 72 0 0 0
++8 10 11 90 112 135 157 201 242 169 215 255 167 212 255 167 212 255 167 212 255 167 212 255
++168 214 255 151 192 230 37 46 56 0 0 0 16 8 3 177 120 42 248 180 77 248 180 77
++248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77
++248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77
++215 156 66 88 72 43 5 3 2 1 1 2 10 12 13 71 90 109 140 179 215 172 216 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++168 213 255 157 201 242 86 104 117 6 7 9 0 0 0 97 97 97 223 222 222 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 254 254 254 218 218 218
++55 59 65 5 3 2 2 3 4 55 70 84 140 179 215 172 216 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++162 207 250 96 123 148 19 25 31 0 0 0 10 12 13 105 100 100 228 228 228 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 219 152 152 170 0 0
++180 30 30 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 216 138 138 170 0 0 138 0 0 0 0 0
++
++11 2 0 170 0 0 170 0 0 239 206 206 255 255 255 227 171 171 172 6 6 183 41 41
++249 238 238 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++247 231 231 233 190 190 247 231 231 198 194 194 46 46 46 1 1 1 4 5 6 105 100 100
++218 218 218 236 236 236 236 236 236 236 236 236 236 236 236 218 218 218 113 113 113 105 100 100
++180 180 180 214 214 214 228 228 228 214 214 214 173 173 173 113 113 113 55 59 65 14 13 13
++0 0 0 0 0 0 0 0 0 11 2 0 37 30 17 176 111 31 178 112 31 177 112 32
++178 112 31 127 80 21 88 72 43 16 8 3 1 1 1 2 2 2 87 87 87 214 214 214
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 250 248 248 165 165 165 18 19 24 0 0 1
++27 31 34 118 151 181 167 212 255 168 213 255 167 212 255 167 212 255 167 212 255 167 212 255
++168 213 255 151 192 230 45 57 69 2 1 0 6 7 9 177 120 42 248 180 77 248 180 77
++248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77
++248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 251 182 78 215 156 66 177 120 42
++56 42 30 5 2 0 0 0 0 13 16 19 70 80 89 140 179 215 169 215 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++168 214 255 161 204 245 109 140 168 13 16 19 0 0 0 55 59 65 206 206 206 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 254 254 254 253 253 253
++156 150 150 19 19 19 0 0 0 18 19 24 96 123 148 165 209 252 168 213 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++166 211 254 157 201 242 71 90 109 4 5 6 2 1 0 19 25 31 156 150 150 250 248 248
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 237 200 200 170 0 0
++170 0 0 248 236 236 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 243 218 218
++254 253 253 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 228 174 174 170 0 0 167 0 0 0 0 0
++
++43 0 0 170 0 0 172 5 5 253 249 249 255 255 255 227 171 171 171 2 2 170 0 0
++183 41 41 239 209 209 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 237 203 203
++178 25 25 170 0 0 175 16 16 243 227 227 127 127 127 19 19 19 0 0 0 19 19 19
++145 144 144 228 228 228 237 237 237 236 236 236 236 236 236 210 206 206 127 127 127 188 187 187
++228 228 228 188 187 187 145 144 144 87 87 87 37 34 34 4 5 6 0 0 0 0 0 0
++2 1 0 16 8 3 37 30 17 71 32 32 127 80 21 176 111 31 176 111 31 176 111 31
++176 111 31 71 32 32 16 8 3 0 0 0 4 5 6 55 59 65 180 180 180 251 251 251
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 223 222 222 97 97 97 0 0 0 1 1 2
++55 70 84 151 192 230 168 213 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++168 213 255 157 201 242 55 70 84 0 0 0 9 6 4 134 90 49 248 180 77 248 180 77
++248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77
++248 180 77 248 180 77 248 180 77 251 182 78 248 180 77 180 122 43 134 90 49 34 13 13
++2 2 2 0 0 0 19 25 31 71 90 109 140 179 215 169 216 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 168 214 255 118 151 181 33 37 45 0 0 0 27 31 34 173 173 173 253 253 253
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 253 253 253
++226 226 226 87 87 87 0 0 0 1 1 2 45 57 69 140 179 215 168 213 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 166 211 254 140 179 215 55 70 84 0 0 0 2 2 2 55 59 65 188 187 187
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 170 0 0
++170 0 0 237 200 200 255 255 255 255 255 255 255 255 255 243 218 218 209 119 119 210 122 122
++202 97 97 204 103 103 201 95 95 193 71 71 182 36 36 175 16 16 180 30 30 204 103 103
++247 231 231 255 255 255 255 255 255 255 255 255 239 209 209 170 0 0 170 0 0 21 0 0
++
++68 0 0 170 0 0 185 47 47 255 255 255 255 255 255 255 255 255 231 184 184 176 19 19
++170 0 0 175 16 16 222 158 158 255 255 255 255 255 255 255 255 255 255 254 254 175 16 16
++193 71 71 210 122 122 170 0 0 218 144 144 210 206 206 70 80 89 5 2 0 2 3 4
++37 34 34 165 165 165 226 226 226 241 241 241 239 239 239 180 180 180 97 97 97 145 144 144
++113 113 113 55 59 65 19 19 19 0 0 0 0 0 0 0 0 0 0 0 0 5 2 0
++16 8 3 127 80 21 127 80 21 176 111 31 178 112 31 177 112 32 177 112 32 178 112 31
++127 80 21 37 30 17 0 0 0 2 1 0 55 59 65 180 180 180 250 248 248 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 254 254 254 218 218 218 127 127 127 19 25 31 0 0 0 18 19 24
++96 123 148 165 210 253 168 213 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 165 209 252 71 90 109 0 0 1 11 2 0 88 72 43 248 180 77 248 180 77
++248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77 248 180 77
++251 182 78 248 180 77 248 180 77 215 156 66 134 90 49 56 42 30 5 3 2 1 1 1
++1 1 2 33 37 45 96 123 148 154 196 236 172 216 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 169 216 255 140 179 215 55 70 84 0 0 0 9 6 4 137 137 137 241 241 241
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++250 248 248 165 165 165 27 31 34 0 0 1 13 16 19 90 112 135 161 204 245 168 214 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 165 209 252 118 151 181 33 37 45 1 1 1 5 3 2 97 97 97
++223 222 222 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 170 0 0
++170 0 0 233 190 190 255 255 255 255 255 255 248 236 236 206 110 110 183 38 38 170 0 0
++170 0 0 170 0 0 170 0 0 170 0 0 173 12 12 184 44 44 171 3 3 170 0 0
++180 30 30 243 221 221 255 255 255 255 255 255 251 244 244 170 0 0 170 0 0 43 0 0
++
++98 0 0 170 0 0 196 78 78 255 255 255 255 255 255 255 255 255 255 255 255 243 227 227
++188 55 55 170 0 0 170 0 0 203 100 100 252 246 246 255 255 255 255 255 255 177 22 22
++173 8 8 176 19 19 170 0 0 204 103 103 255 255 255 173 173 173 34 13 13 0 0 1
++0 0 0 46 46 46 137 137 137 198 194 194 180 180 180 105 100 100 37 34 34 27 31 34
++5 3 2 0 0 0 0 0 0 4 5 6 27 31 34 27 31 34 9 6 4 1 1 2
++37 30 17 176 111 31 176 111 31 178 112 31 177 112 32 177 112 32 177 112 32 176 111 31
++176 111 31 37 30 17 5 2 0 8 10 11 113 113 113 241 241 241 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 234 234 234 180 180 180 87 87 87 19 19 19 2 1 0 0 0 0 45 57 69
++133 171 205 172 216 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 166 211 254 96 123 148 6 7 9 1 1 1 71 32 32 248 180 77 248 180 77
++251 182 78 248 180 77 251 182 78 251 182 78 251 182 78 251 182 78 251 182 78 248 180 77
++215 156 66 215 156 66 127 80 21 56 42 30 16 8 3 1 1 1 0 0 0 13 16 19
++55 70 84 109 140 168 161 204 245 169 215 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 168 214 255 157 201 242 71 90 109 2 3 4 0 0 0 87 87 87 226 226 226
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 246 246 246 250 248 248 255 255 255
++255 255 255 228 228 228 97 97 97 0 0 0 0 0 0 45 57 69 126 161 193 169 215 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 168 213 255 161 204 245 90 112 135 13 16 19 0 0 1 19 19 19
++137 137 137 243 242 242 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 172 6 6
++170 0 0 231 184 184 255 255 255 255 255 255 224 161 161 185 47 47 170 0 0 189 59 59
++235 197 197 245 224 224 254 252 252 254 252 252 255 254 254 254 253 253 215 135 135 175 16 16
++170 0 0 189 59 59 255 255 255 255 255 255 255 255 255 172 7 7 170 0 0 43 0 0
++
++120 0 0 170 0 0 206 110 110 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++253 248 248 201 95 95 170 0 0 170 0 0 189 59 59 245 224 224 255 255 255 222 158 158
++170 0 0 170 0 0 184 44 44 203 100 100 254 254 254 249 238 238 91 72 72 21 0 0
++0 0 0 1 1 1 19 19 19 55 59 65 55 59 65 14 13 13 0 0 0 0 0 0
++0 0 0 13 16 19 46 46 46 105 100 100 156 150 150 127 127 127 27 31 34 1 1 1
++34 13 13 127 80 21 176 111 31 177 112 32 177 112 32 177 112 32 177 112 32 176 111 31
++176 111 31 88 72 43 1 1 1 1 1 1 87 87 87 226 226 226 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 254 254 254 237 237 237
++180 180 180 113 113 113 46 46 46 4 4 5 0 0 0 1 1 2 6 7 9 86 104 117
++161 204 245 168 213 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 169 215 255 118 151 181 18 19 24 0 0 0 37 30 17 177 120 42 215 156 66
++248 180 77 248 180 77 248 180 77 248 180 77 215 156 66 215 156 66 180 122 43 134 90 49
++127 80 21 37 30 17 16 8 3 5 2 0 0 0 0 8 10 11 37 46 56 90 112 135
++140 179 215 167 212 255 168 214 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 168 214 255 162 207 250 109 140 168 18 19 24 0 0 0 46 46 46 198 194 194
++254 254 254 255 255 255 255 255 255 255 255 255 210 206 206 137 137 137 156 150 150 237 237 237
++255 255 255 251 251 251 180 180 180 46 46 46 0 0 0 6 7 9 86 104 117 154 196 236
++169 215 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 165 210 253 151 192 230 70 80 89 2 2 2 0 0 0
++55 59 65 188 187 187 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 175 14 14
++170 0 0 229 177 177 255 255 255 255 255 255 194 73 73 170 0 0 188 55 55 252 246 246
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 218 144 144
++170 0 0 170 0 0 248 236 236 255 255 255 255 255 255 171 4 4 170 0 0 43 0 0
++
++138 0 0 170 0 0 218 144 144 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 215 135 135 170 1 1 171 4 4 183 38 38 235 197 197 224 164 164
++216 138 138 203 100 100 216 138 138 252 246 246 255 255 255 255 255 255 188 70 70 98 0 0
++34 13 13 2 3 4 0 0 0 2 1 0 0 0 0 0 0 0 2 3 4 27 31 34
++91 72 72 127 127 127 188 187 187 232 232 232 255 255 255 206 206 206 46 46 46 2 2 2
++5 3 2 127 80 21 176 111 31 177 112 32 177 112 32 177 112 32 177 112 32 177 112 32
++176 111 31 127 80 21 11 2 0 2 2 2 46 46 46 180 180 180 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 246 246 246 214 214 214 165 165 165 113 113 113
++46 46 46 8 10 11 0 0 0 0 0 0 0 0 0 0 0 0 33 37 45 118 151 181
++168 214 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 168 213 255 140 179 215 33 37 45 0 0 0 5 3 2 37 30 17 127 80 21
++134 90 49 134 90 49 134 90 49 127 80 21 88 72 43 88 72 43 37 30 17 34 13 13
++1 1 1 2 2 2 1 1 1 8 10 11 37 46 56 86 104 117 126 161 193 157 201 242
++169 215 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 169 216 255 133 171 205 37 46 56 1 1 1 8 10 11 156 150 150
++246 246 246 255 255 255 255 255 255 251 251 251 127 127 127 14 13 13 33 37 45 180 180 180
++255 255 255 255 255 255 234 234 234 113 113 113 8 10 11 0 0 0 33 37 45 118 151 181
++166 211 254 168 213 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 162 207 250 126 161 193 33 37 45 1 1 2
++9 6 4 105 100 100 223 222 222 255 255 255 255 255 255 255 255 255 255 255 255 182 36 36
++170 0 0 219 148 148 255 255 255 255 255 255 173 8 8 170 0 0 215 135 135 255 254 254
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 235 197 197
++170 0 0 170 0 0 242 216 216 255 255 255 255 255 255 171 2 2 170 0 0 43 0 0
++
++160 0 0 170 0 0 228 174 174 255 255 255 255 255 255 255 255 255 243 227 227 218 144 144
++211 125 125 243 221 221 255 255 255 229 177 177 173 12 12 170 1 1 176 19 19 226 168 168
++243 218 218 243 227 227 255 255 255 255 255 255 255 255 255 255 255 255 189 59 59 167 0 0
++141 107 101 97 97 97 46 46 46 14 13 13 19 19 19 46 46 46 105 100 100 165 165 165
++218 218 218 243 242 242 255 255 255 255 255 255 254 254 254 236 236 236 97 97 97 6 7 9
++5 2 0 56 42 30 176 111 31 177 112 32 177 112 32 177 112 32 177 112 32 177 112 32
++178 112 31 127 80 21 37 30 17 0 0 0 19 19 19 137 137 137 253 253 253 255 255 255
++255 255 255 253 253 253 223 222 222 180 180 180 127 127 127 55 59 65 113 113 113 6 7 9
++0 0 0 0 0 0 4 4 5 1 1 1 0 0 0 4 5 6 55 70 84 151 192 230
++169 215 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 166 211 254 161 204 245 71 90 109 8 10 11 2 1 0 0 0 1 0 0 0
++9 6 4 16 8 3 16 8 3 9 6 4 11 2 0 0 0 0 0 0 0 0 0 0
++0 0 0 19 25 31 55 70 84 90 112 135 133 171 205 154 196 236 167 212 255 168 214 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 168 214 255 154 196 236 71 90 109 4 4 5 0 0 0 87 87 87
++228 228 228 255 255 255 255 255 255 250 248 248 97 97 97 0 0 0 9 6 4 137 137 137
++255 255 255 255 255 255 255 255 255 206 206 206 55 59 65 0 0 0 1 1 2 70 80 89
++140 179 215 168 214 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 168 214 255 154 196 236 96 123 148 13 16 19
++0 0 0 27 31 34 156 150 150 250 248 248 255 255 255 255 255 255 255 254 254 193 71 71
++170 0 0 208 114 114 255 255 255 255 255 255 181 33 33 170 0 0 222 158 158 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 212 128 128
++187 50 50 170 0 0 239 209 209 255 255 255 255 255 255 170 0 0 170 0 0 43 0 0
++
++160 0 0 170 0 0 231 184 184 255 255 255 255 255 255 235 197 197 173 10 10 170 0 0
++170 0 0 178 25 25 249 238 238 255 255 255 239 209 209 181 33 33 170 0 0 170 1 1
++217 141 141 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 182 36 36 170 0 0
++219 148 148 228 228 228 188 187 187 165 165 165 156 150 150 198 194 194 234 234 234 253 253 253
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 253 253 253 137 137 137 19 19 19
++0 0 0 37 30 17 127 80 21 178 112 31 177 112 32 177 112 32 177 112 32 177 112 32
++178 112 31 176 111 31 71 32 32 5 3 2 4 5 6 105 100 100 228 228 228 228 228 228
++180 180 180 127 127 127 70 80 89 37 34 34 14 13 13 5 3 2 37 34 34 0 0 1
++13 16 19 45 57 69 55 70 84 8 10 11 0 0 0 13 16 19 96 123 148 166 211 254
++168 213 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 166 211 254 140 179 215 90 112 135 45 57 69 18 19 24 2 3 4
++0 0 0 0 0 0 0 0 0 0 0 0 1 1 2 10 12 13 27 31 34 55 70 84
++86 104 117 118 151 181 140 179 215 157 201 242 168 214 255 168 214 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 109 140 168 18 19 24 0 0 1 27 31 34
++180 180 180 253 253 253 255 255 255 255 255 255 137 137 137 4 4 5 4 4 5 97 97 97
++250 248 248 255 255 255 255 255 255 243 242 242 145 144 144 19 19 19 0 0 0 18 19 24
++96 123 148 162 207 250 168 213 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 140 179 215 55 70 84
++1 1 1 1 1 1 55 59 65 210 206 206 254 254 254 255 255 255 255 255 255 204 103 103
++170 0 0 197 81 81 255 255 255 255 255 255 224 164 164 170 0 0 193 71 71 255 255 255
++255 255 255 255 255 255 254 253 253 254 251 251 239 206 206 227 171 171 252 246 246 219 152 152
++176 19 19 175 16 16 254 251 251 255 255 255 255 255 255 178 25 25 170 0 0 55 0 0
++
++149 0 0 170 0 0 227 171 171 255 255 255 255 255 255 199 87 87 175 14 14 210 122 122
++170 0 0 170 0 0 216 138 138 255 255 255 255 255 255 248 233 233 188 55 55 170 0 0
++172 5 5 211 125 125 255 255 255 255 255 255 255 255 255 255 255 255 180 30 30 170 0 0
++224 161 161 255 255 255 255 255 255 251 251 251 251 251 251 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 254 254 254 188 187 187 37 34 34
++0 0 0 16 8 3 127 80 21 176 111 31 177 112 32 177 112 32 177 112 32 177 112 32
++176 111 31 176 111 31 127 80 21 11 2 0 0 0 0 46 46 46 105 100 100 87 87 87
++37 34 34 19 19 19 5 3 2 0 0 0 1 1 2 97 97 97 33 37 45 70 80 89
++96 123 148 126 161 193 71 90 109 1 1 1 2 3 4 37 46 56 133 171 205 169 216 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 168 214 255 157 201 242 140 179 215 109 140 168 90 112 135
++71 90 109 71 90 109 71 90 109 86 104 117 90 112 135 109 140 168 126 161 193 140 179 215
++154 196 236 165 209 252 168 214 255 168 213 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 169 216 255 133 171 205 45 57 69 0 0 1 2 1 0
++113 113 113 236 236 236 255 255 255 255 255 255 173 173 173 19 19 19 0 0 0 55 59 65
++223 222 222 255 255 255 255 255 255 255 255 255 214 214 214 87 87 87 1 1 1 0 0 0
++45 57 69 133 171 205 166 211 254 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 168 213 255 165 209 252 118 151 181
++33 37 45 2 1 0 14 13 13 127 127 127 237 237 237 255 255 255 255 255 255 211 125 125
++170 0 0 191 64 64 255 255 255 255 255 255 253 249 249 177 22 22 170 0 0 201 95 95
++237 200 200 241 213 213 228 174 174 227 171 171 224 161 161 208 114 114 209 119 119 178 25 25
++170 0 0 224 164 164 255 255 255 255 255 255 255 255 255 194 73 73 170 0 0 98 0 0
++
++149 0 0 170 0 0 222 155 155 255 255 255 255 255 255 197 81 81 171 3 3 191 64 64
++170 0 0 170 0 0 210 122 122 255 255 255 255 255 255 255 255 255 250 240 240 189 59 59
++170 0 0 170 0 0 219 148 148 255 255 255 255 255 255 255 255 255 179 27 27 170 0 0
++224 164 164 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 223 222 222 70 80 89
++5 2 0 0 0 0 88 72 43 176 111 31 176 111 31 177 112 32 177 112 32 177 112 32
++177 112 32 176 111 31 127 80 21 34 13 13 1 1 1 4 5 6 10 12 13 4 4 5
++0 0 0 0 0 0 1 1 1 19 25 31 86 104 117 90 112 135 126 161 193 151 192 230
++161 204 245 140 179 215 37 46 56 0 0 0 8 10 11 86 104 117 161 204 245 168 214 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 168 213 255 167 212 255 165 209 252 157 201 242
++154 196 236 154 196 236 151 192 230 154 196 236 157 201 242 161 204 245 166 211 254 167 212 255
++168 214 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 168 214 255 161 204 245 86 104 117 8 10 11 0 0 1
++55 59 65 223 222 222 253 253 253 255 255 255 210 206 206 46 46 46 0 0 0 19 19 19
++173 173 173 255 255 255 255 255 255 255 255 255 250 248 248 165 165 165 37 34 34 0 0 1
++8 10 11 86 104 117 154 196 236 168 213 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 168 214 255 154 196 236
++86 104 117 6 7 9 0 0 0 46 46 46 188 187 187 253 253 253 255 255 255 216 138 138
++170 0 0 187 50 50 255 255 255 255 255 255 255 255 255 247 231 231 189 59 59 170 0 0
++170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 180 30 30
++230 181 181 255 255 255 255 255 255 255 255 255 255 255 255 209 119 119 170 0 0 120 0 0
++
++138 0 0 170 0 0 217 141 141 255 255 255 255 255 255 230 181 181 170 1 1 170 0 0
++170 0 0 170 1 1 237 200 200 255 255 255 255 255 255 255 255 255 255 255 255 251 242 242
++189 59 59 170 0 0 171 4 4 247 231 231 255 255 255 255 255 255 178 25 25 170 0 0
++226 168 168 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 254 252 252 113 113 113
++10 12 13 5 3 2 34 13 13 176 111 31 177 112 32 177 112 32 177 112 32 177 112 32
++177 112 32 176 111 31 176 111 31 56 42 30 0 0 0 0 0 0 0 0 0 0 0 1
++13 16 19 45 57 69 86 104 117 126 161 193 191 201 212 161 204 245 165 210 253 167 212 255
++165 209 252 90 112 135 6 7 9 0 0 0 27 31 34 118 151 181 169 215 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 168 213 255
++168 213 255 168 213 255 168 214 255 168 213 255 168 214 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 168 214 255 162 207 250 86 104 117 8 10 11 1 1 1
++91 72 72 223 222 222 255 255 255 255 255 255 237 237 237 87 87 87 0 0 0 6 7 9
++113 113 113 246 246 246 255 255 255 255 255 255 255 255 255 234 234 234 113 113 113 8 10 11
++1 1 2 27 31 34 118 151 181 162 207 250 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 166 211 254
++133 171 205 45 57 69 0 0 0 4 5 6 105 100 100 232 232 232 255 255 255 222 155 155
++172 7 7 182 36 36 255 255 255 255 255 255 255 255 255 255 255 255 253 248 248 224 164 164
++204 103 103 200 91 91 204 103 103 210 122 122 219 148 148 226 168 168 235 197 197 254 253 253
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 222 155 155 170 0 0 160 0 0
++
++128 0 0 170 0 0 212 128 128 255 255 255 255 255 255 255 255 255 239 206 206 210 122 122
++180 30 30 216 138 138 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++251 242 242 183 41 41 175 14 14 248 233 233 255 255 255 255 255 255 175 16 16 170 0 0
++228 174 174 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 165 165 165
++27 31 34 0 0 0 34 13 13 127 80 21 178 112 31 177 112 32 177 112 32 177 112 32
++177 112 32 178 112 31 176 111 31 71 32 32 16 8 3 0 0 0 18 19 24 71 90 109
++118 151 181 151 192 230 157 201 242 204 219 242 165 210 253 166 211 254 167 212 255 167 212 255
++140 179 215 45 57 69 0 0 0 4 5 6 70 80 89 157 201 242 168 213 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 169 215 255 151 192 230 55 70 84 1 1 2 0 0 0
++113 113 113 241 241 241 254 254 254 255 255 255 253 253 253 165 165 165 14 13 13 0 0 0
++37 34 34 198 194 194 254 254 254 255 255 255 255 255 255 255 255 255 198 194 194 55 59 65
++0 0 0 0 0 1 55 70 84 151 192 230 166 211 254 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 168 213 255
++157 201 242 90 112 135 13 16 19 0 0 0 37 34 34 180 180 180 251 251 251 224 161 161
++173 10 10 180 30 30 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 215 135 135 170 0 0 138 0 0
++
++128 0 0 170 0 0 211 125 125 255 255 255 255 255 255 255 255 255 255 255 255 254 253 253
++253 249 249 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 251 242 242 248 233 233 255 255 255 255 255 255 255 255 255 171 4 4 170 0 0
++232 187 187 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 250 248 248 206 206 206 113 113 113
++19 19 19 1 1 1 0 0 0 127 80 21 176 111 31 177 112 32 177 112 32 177 112 32
++177 112 32 176 111 31 178 112 31 127 80 21 16 8 3 0 0 0 19 25 31 109 140 168
++165 209 252 165 210 253 204 219 242 168 214 255 167 212 255 167 212 255 167 212 255 165 209 252
++109 140 168 8 10 11 0 0 0 19 25 31 118 151 181 168 214 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 168 213 255 168 213 255 167 212 255 168 213 255 167 212 255 166 211 254 165 210 253
++165 209 252 165 209 252 165 210 253 166 211 254 167 212 255 168 213 255 167 212 255 168 213 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 172 216 255 126 161 193 33 37 45 0 0 0 14 13 13
++173 173 173 250 248 248 255 255 255 255 255 255 253 253 253 223 222 222 55 59 65 1 1 1
++8 10 11 113 113 113 239 239 239 255 255 255 255 255 255 255 255 255 246 246 246 145 144 144
++19 25 31 0 0 0 10 12 13 90 112 135 157 201 242 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++169 215 255 133 171 205 45 57 69 0 0 0 4 5 6 105 100 100 234 234 234 222 158 158
++170 0 0 181 33 33 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 211 125 125 167 0 0 128 0 0
++
++120 0 0 170 0 0 209 119 119 255 254 254 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 253 248 248 170 0 0 170 0 0
++237 200 200 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 234 234 234 145 144 144 46 46 46 14 13 13
++1 1 2 1 1 1 0 0 0 37 30 17 176 111 31 176 111 31 177 112 32 177 112 32
++177 112 32 177 112 32 178 112 31 127 80 21 56 42 30 0 0 0 6 7 9 90 112 135
++157 201 242 172 216 255 172 216 255 168 213 255 167 212 255 167 212 255 167 212 255 151 192 230
++45 57 69 1 1 2 2 3 4 55 70 84 154 196 236 168 213 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 166 211 254 167 212 255
++162 207 250 154 196 236 140 179 215 133 171 205 118 151 181 109 140 168 96 123 148 90 112 135
++86 104 117 86 104 117 90 112 135 96 123 148 109 140 168 118 151 181 133 171 205 151 192 230
++157 201 242 165 210 253 167 212 255 166 211 254 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 169 215 255 109 140 168 19 25 31 0 0 1 46 46 46
++206 206 206 254 254 254 255 255 255 255 255 255 255 255 255 250 248 248 156 150 150 14 13 13
++0 0 0 37 34 34 173 173 173 255 255 255 255 255 255 255 255 255 255 255 255 223 222 222
++87 87 87 9 6 4 0 0 1 33 37 45 126 161 193 165 209 252 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++168 213 255 162 207 250 96 123 148 13 16 19 0 0 0 37 34 34 188 187 187 224 164 164
++170 0 0 179 27 27 255 255 255 255 255 255 245 224 224 191 64 64 227 171 171 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 253 248 248 239 209 209
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 209 119 119 170 0 0 120 0 0
++
++120 0 0 170 0 0 206 110 110 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 254 251 251 248 233 233 248 233 233
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 251 242 242 170 0 0 170 0 0
++237 203 203 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 223 222 222 113 113 113 19 19 19 1 1 1 0 0 0
++0 0 0 0 0 0 0 0 0 37 30 17 127 80 21 176 111 31 177 112 32 177 112 32
++177 112 32 177 112 32 177 112 32 178 112 31 71 32 32 0 0 0 0 0 1 55 70 84
++151 192 230 204 219 242 168 213 255 167 212 255 167 212 255 167 212 255 167 212 255 118 151 181
++13 16 19 0 0 0 18 19 24 96 123 148 169 215 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 166 211 254 166 211 254 161 204 245 151 192 230 118 151 181
++86 104 117 55 70 84 33 37 45 19 25 31 13 16 19 8 10 11 4 5 6 2 3 4
++2 3 4 1 1 2 2 3 4 4 5 6 10 12 13 13 16 19 27 31 34 37 46 56
++70 80 89 96 123 148 133 171 205 157 201 242 166 211 254 166 211 254 166 211 254 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 166 211 254 96 123 148 13 16 19 5 2 0 55 59 65
++218 218 218 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 223 222 222 87 87 87
++0 0 0 4 5 6 87 87 87 223 222 222 255 255 255 255 255 255 255 255 255 255 255 255
++180 180 180 46 46 46 0 0 0 1 1 2 70 80 89 151 192 230 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 169 215 255 126 161 193 37 46 56 0 0 0 8 10 11 156 150 150 222 155 155
++170 0 0 182 36 36 255 255 255 255 255 255 219 152 152 170 0 0 173 12 12 237 203 203
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 247 231 231 187 50 50 180 30 30
++203 100 100 241 213 213 255 255 255 255 255 255 255 255 255 206 110 110 170 0 0 110 0 0
++
++110 0 0 170 0 0 204 103 103 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++243 227 227 216 138 138 202 97 97 191 64 64 180 30 30 171 2 2 170 0 0 170 0 0
++180 30 30 224 164 164 255 255 255 255 255 255 255 255 255 255 255 255 171 4 4 170 0 0
++233 190 190 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 228 228 228 113 113 113 19 19 19 0 0 0 1 1 2 33 37 45
++45 57 69 13 16 19 0 0 0 5 2 0 127 80 21 176 111 31 177 112 32 177 112 32
++177 112 32 177 112 32 177 112 32 176 111 31 127 80 21 16 8 3 0 0 0 33 37 45
++158 189 218 166 211 254 167 212 255 167 212 255 167 212 255 168 213 255 157 201 242 71 90 109
++0 0 0 1 1 2 45 57 69 140 179 215 172 216 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 165 209 252 151 192 230 126 161 193 86 104 117 37 46 56 10 12 13
++1 1 2 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1
++2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
++0 0 1 2 3 4 19 25 31 55 70 84 109 140 168 140 179 215 162 207 250 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 165 210 253 96 123 148 13 16 19 0 0 0 91 72 72
++226 226 226 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 251 251 251 173 173 173
++19 25 31 2 1 0 19 19 19 145 144 144 251 251 251 255 255 255 255 255 255 255 255 255
++241 241 241 127 127 127 19 19 19 0 0 0 13 16 19 96 123 148 162 207 250 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 169 215 255 126 161 193 37 46 56 0 0 0 19 19 19 165 165 165 210 122 122
++170 0 0 193 71 71 255 255 255 255 255 255 248 233 233 178 25 25 170 0 0 176 19 19
++241 213 213 255 255 255 255 255 255 255 255 255 255 255 255 202 97 97 170 0 0 170 0 0
++170 0 0 175 16 16 243 227 227 255 255 255 255 255 255 204 103 103 170 0 0 110 0 0
++
++110 0 0 170 0 0 203 100 100 255 255 255 255 255 255 255 255 255 255 255 255 217 141 141
++172 6 6 170 0 0 170 0 0 170 0 0 175 14 14 184 44 44 194 73 73 194 73 73
++175 14 14 170 1 1 199 87 87 255 255 255 255 255 255 255 255 255 177 22 22 170 0 0
++227 171 171 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 243 242 242 145 144 144 19 25 31 0 0 0 2 3 4 55 70 84 118 151 181
++140 179 215 45 57 69 1 1 2 5 2 0 56 42 30 176 111 31 177 112 32 177 112 32
++177 112 32 177 112 32 177 112 32 178 112 31 127 80 21 37 30 17 37 30 17 70 80 89
++96 123 148 161 204 245 168 213 255 167 212 255 167 212 255 168 213 255 133 171 205 33 37 45
++0 0 0 6 7 9 90 112 135 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++165 209 252 151 192 230 109 140 168 55 70 84 18 19 24 0 0 1 0 0 1 0 0 1
++1 1 1 8 10 11 14 13 13 27 31 34 37 34 34 46 46 46 55 59 65 91 72 72
++55 70 84 91 72 72 55 59 65 55 59 65 46 46 46 37 34 34 18 19 24 10 12 13
++4 4 5 1 1 1 1 1 1 0 0 1 6 7 9 45 57 69 90 112 135 140 179 215
++161 204 245 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 166 211 254 96 123 148 13 16 19 2 2 2 55 59 65
++218 218 218 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 254 254 254 239 239 239
++113 113 113 4 5 6 2 2 2 46 46 46 188 187 187 255 255 255 255 255 255 255 255 255
++255 255 255 206 206 206 91 72 72 4 5 6 1 1 2 37 46 56 133 171 205 166 211 254
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++168 213 255 166 211 254 109 140 168 19 25 31 0 0 0 46 46 46 206 206 206 199 87 87
++170 0 0 204 103 103 255 255 255 255 255 255 255 255 255 234 194 194 172 7 7 170 0 0
++179 27 27 245 224 224 255 255 255 255 255 255 255 255 255 179 27 27 170 0 0 177 22 22
++196 78 78 170 0 0 224 161 161 255 255 255 255 255 255 196 78 78 170 0 0 98 0 0
++
++110 0 0 170 0 0 201 95 95 255 255 255 255 255 255 255 255 255 219 152 152 170 0 0
++184 44 44 227 171 171 209 119 119 232 187 187 250 240 240 247 231 231 254 253 253 255 255 255
++243 227 227 180 30 30 170 0 0 234 194 194 255 255 255 255 255 255 183 41 41 170 0 0
++219 152 152 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 198 194 194 55 59 65 2 1 0 1 1 2 55 70 84 126 161 193 168 214 255
++166 211 254 86 104 117 4 5 6 0 0 0 34 13 13 127 80 21 176 111 31 176 111 31
++176 111 31 176 111 31 177 112 32 178 112 31 176 111 31 105 100 100 56 42 30 1 1 2
++70 80 89 151 192 230 168 213 255 167 212 255 167 212 255 165 210 253 90 112 135 6 7 9
++0 0 0 27 31 34 126 161 193 168 214 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 166 211 254 157 201 242
++118 151 181 55 70 84 18 19 24 0 0 0 0 0 1 2 2 2 14 13 13 27 31 34
++55 59 65 113 113 113 156 150 150 180 180 180 198 194 194 223 222 222 228 228 228 234 234 234
++236 236 236 236 236 236 234 234 234 232 232 232 214 214 214 198 194 194 173 173 173 137 137 137
++97 97 97 46 46 46 19 19 19 4 5 6 1 1 1 0 0 0 8 10 11 45 57 69
++96 123 148 151 192 230 165 209 252 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 169 215 255 109 140 168 19 25 31 0 0 0 46 46 46
++206 206 206 253 253 253 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 253 253 253
++206 206 206 55 59 65 2 1 0 6 7 9 113 113 113 239 239 239 255 255 255 255 255 255
++255 255 255 255 255 255 165 165 165 37 34 34 0 0 0 1 1 2 71 90 109 151 192 230
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++168 214 255 161 204 245 90 112 135 6 7 9 0 0 1 87 87 87 223 222 222 188 55 55
++170 0 0 215 135 135 255 255 255 255 255 255 255 255 255 255 255 255 229 177 177 173 8 8
++170 0 0 181 33 33 243 221 221 255 255 255 255 255 255 191 64 64 170 0 0 175 16 16
++197 81 81 170 0 0 231 184 184 255 255 255 255 255 255 187 50 50 170 0 0 83 0 0
++
++98 0 0 170 0 0 200 91 91 255 255 255 255 255 255 255 255 255 179 27 27 175 14 14
++215 135 135 249 238 238 249 238 238 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 222 158 158 170 0 0 182 36 36 255 254 254 255 254 254 193 71 71 170 0 0
++210 122 122 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++237 237 237 113 113 113 9 6 4 1 1 2 33 37 45 118 151 181 165 210 253 168 213 255
++172 216 255 109 140 168 19 25 31 0 0 0 16 8 3 56 42 30 71 32 32 88 72 43
++127 80 21 127 80 21 176 111 31 177 120 42 221 148 97 127 80 21 9 6 4 0 0 0
++45 57 69 133 171 205 168 213 255 167 212 255 168 213 255 151 192 230 45 57 69 0 0 0
++2 3 4 70 80 89 157 201 242 168 213 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 168 213 255 166 211 254 140 179 215 86 104 117
++27 31 34 0 0 1 0 0 0 2 3 4 19 19 19 55 59 65 127 127 127 180 180 180
++228 228 228 251 251 251 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++241 241 241 210 206 206 156 150 150 87 87 87 27 31 34 6 7 9 0 0 0 0 0 1
++13 16 19 71 90 109 133 171 205 162 207 250 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 172 216 255 126 161 193 37 46 56 0 0 0 6 7 9
++156 150 150 246 246 246 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++250 248 248 165 165 165 46 46 46 19 19 19 113 113 113 241 241 241 255 255 255 255 255 255
++255 255 255 255 255 255 243 242 242 113 113 113 14 13 13 0 0 0 13 16 19 96 123 148
++162 207 250 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++169 215 255 151 192 230 70 80 89 1 1 2 4 5 6 113 113 113 239 239 239 181 33 33
++170 0 0 222 158 158 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 229 177 177
++173 8 8 170 0 0 178 25 25 239 209 209 255 255 255 234 194 194 172 5 5 170 0 0
++170 0 0 198 84 84 254 251 251 255 255 255 255 255 255 177 22 22 170 0 0 55 0 0
++
++98 0 0 170 0 0 196 78 78 255 255 255 255 255 255 250 240 240 170 0 0 180 30 30
++209 119 119 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 233 190 190 170 0 0 170 0 0 248 233 233 255 255 255 202 97 97 170 0 0
++199 87 87 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++198 194 194 55 59 65 0 0 0 10 12 13 90 112 135 157 201 242 168 214 255 167 212 255
++157 201 242 96 123 148 19 25 31 0 0 0 0 0 0 0 0 0 5 3 2 2 1 0
++11 2 0 56 42 30 134 90 49 221 148 97 176 111 31 127 80 21 34 13 13 1 1 1
++13 16 19 109 140 168 165 209 252 168 214 255 169 216 255 118 151 181 19 25 31 0 0 0
++10 12 13 109 140 168 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 168 214 255 165 209 252 126 161 193 70 80 89 6 7 9
++1 1 2 1 1 1 19 19 19 91 72 72 145 144 144 223 222 222 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 239 239 239 173 173 173 97 97 97 27 31 34 5 3 2
++0 0 0 1 1 2 45 57 69 118 151 181 157 201 242 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 169 215 255 151 192 230 70 80 89 4 5 6 0 0 0
++70 80 89 218 218 218 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 243 242 242 180 180 180 156 150 150 214 214 214 254 254 254 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 214 214 214 55 59 65 9 6 4 0 0 0 37 46 56
++133 171 205 165 210 253 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++168 214 255 126 161 193 37 46 56 0 0 0 19 19 19 165 165 165 250 248 248 173 12 12
++170 0 0 229 177 177 255 255 255 255 255 255 251 242 242 219 152 152 208 114 114 226 168 168
++227 171 171 181 33 33 170 0 0 175 16 16 235 197 197 255 255 255 242 216 216 226 168 168
++239 206 206 255 255 255 255 255 255 255 255 255 255 255 255 171 4 4 170 0 0 43 0 0
++
++68 0 0 170 0 0 183 41 41 255 255 255 255 255 255 255 255 255 172 7 7 170 0 0
++219 148 148 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 218 144 144 170 0 0 176 19 19 243 227 227 255 255 255 212 128 128 170 0 0
++187 50 50 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 250 248 248
++156 150 150 14 13 13 1 1 1 37 46 56 133 171 205 168 214 255 168 213 255 165 209 252
++96 123 148 19 25 31 0 0 0 0 0 0 0 0 0 4 4 5 2 3 4 2 3 4
++9 6 4 97 97 97 34 13 13 88 72 43 176 111 31 176 111 31 56 42 30 0 0 0
++0 0 1 86 104 117 154 196 236 161 204 245 151 192 230 71 90 109 6 7 9 0 0 0
++37 46 56 140 179 215 168 213 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 168 214 255 161 204 245 118 151 181 45 57 69 2 3 4 0 0 1
++9 6 4 55 59 65 137 137 137 214 214 214 255 255 255 254 254 254 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 232 232 232 165 165 165 91 72 72
++13 16 19 0 0 0 0 0 0 33 37 45 96 123 148 154 196 236 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 168 213 255 165 210 253 109 140 168 19 25 31 0 0 0
++19 19 19 145 144 144 243 242 242 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 251 251 251 254 254 254 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 254 254 173 173 173 37 34 34 0 0 0 0 0 0
++71 90 109 151 192 230 168 213 255 167 212 255 167 212 255 167 212 255 167 212 255 169 215 255
++157 201 242 96 123 148 13 16 19 0 0 0 55 59 65 198 194 194 255 255 255 170 0 0
++170 0 0 237 200 200 255 255 255 249 238 238 193 71 71 193 71 71 185 47 47 222 155 155
++243 227 227 237 200 200 182 36 36 170 0 0 173 8 8 230 181 181 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 254 252 252 170 0 0 170 0 0 43 0 0
++
++55 0 0 170 0 0 173 8 8 255 254 254 255 255 255 255 255 255 183 41 41 170 0 0
++191 64 64 254 251 251 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++239 209 209 176 19 19 170 0 0 204 103 103 255 255 255 255 255 255 230 181 181 170 0 0
++172 5 5 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 239 239 239
++113 113 113 2 3 4 1 1 2 71 90 109 154 196 236 168 214 255 168 213 255 157 201 242
++55 70 84 2 2 2 0 0 0 8 10 11 33 37 45 70 80 89 90 112 135 137 137 137
++37 46 56 0 0 0 0 0 0 34 13 13 127 80 21 176 111 31 71 32 32 16 8 3
++0 0 0 37 46 56 96 123 148 96 123 148 70 80 89 19 25 31 0 0 0 1 1 2
++71 90 109 165 210 253 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 168 214 255 161 204 245 109 140 168 37 46 56 0 0 0 0 0 0 19 19 19
++97 97 97 188 187 187 250 248 248 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 253 253 253 206 206 206
++113 113 113 37 34 34 0 0 0 0 0 1 27 31 34 96 123 148 151 192 230 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 169 215 255 140 179 215 55 70 84 4 5 6
++0 0 0 55 59 65 198 194 194 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 250 248 248 210 206 206 173 173 173 210 206 206 253 253 253 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 239 239 239 113 113 113 14 13 13 0 0 0
++13 16 19 96 123 148 162 207 250 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++133 171 205 45 57 69 0 0 0 1 1 1 105 100 100 234 234 234 237 203 203 170 0 0
++170 0 0 249 238 238 255 255 255 234 194 194 172 5 5 170 0 0 170 0 0 170 1 1
++242 216 216 255 255 255 242 216 216 181 33 33 170 0 0 171 4 4 224 161 161 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 251 244 244 170 0 0 170 0 0 32 0 0
++
++21 0 0 170 0 0 170 0 0 243 227 227 255 255 255 255 255 255 216 138 138 170 0 0
++171 3 3 184 44 44 237 203 203 237 200 200 224 161 161 219 152 152 208 114 114 197 81 81
++175 14 14 170 0 0 196 78 78 222 158 158 255 255 255 255 255 255 249 238 238 170 1 1
++170 0 0 235 197 197 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 232 232 232
++105 100 100 0 0 0 8 10 11 90 112 135 161 204 245 168 213 255 168 214 255 161 204 245
++109 140 168 45 57 69 45 57 69 96 123 148 158 189 218 172 216 255 157 201 242 140 179 215
++109 140 168 33 37 45 0 0 0 11 2 0 37 30 17 176 111 31 127 80 21 16 8 3
++0 0 0 8 10 11 13 16 19 8 10 11 0 0 1 0 0 0 0 0 0 18 19 24
++118 151 181 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++168 214 255 162 207 250 109 140 168 37 46 56 0 0 0 0 0 0 27 31 34 127 127 127
++218 218 218 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++234 234 234 156 150 150 46 46 46 0 0 0 0 0 0 19 25 31 96 123 148 157 201 242
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 168 213 255 167 212 255 118 151 181 27 31 34
++0 0 0 5 3 2 113 113 113 239 239 239 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 226 226 226 105 100 100 18 19 24 105 100 100 223 222 222 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 206 206 206 91 72 72 0 0 0
++0 0 0 37 46 56 126 161 193 169 216 255 167 212 255 167 212 255 168 214 255 151 192 230
++71 90 109 8 10 11 0 0 1 37 34 34 173 173 173 251 251 251 224 161 161 170 0 0
++176 19 19 255 255 255 255 255 255 243 221 221 170 0 0 180 30 30 216 138 138 170 0 0
++224 161 161 255 255 255 255 255 255 248 233 233 189 59 59 170 1 1 170 1 1 212 128 128
++255 255 255 255 255 255 255 255 255 255 255 255 248 236 236 170 0 0 167 0 0 32 0 0
++
++5 2 0 170 0 0 170 0 0 234 194 194 255 255 255 255 255 255 255 254 254 205 106 106
++170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0
++175 16 16 201 95 95 212 128 128 253 249 249 255 255 255 255 255 255 255 255 255 183 38 38
++170 0 0 217 141 141 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 234 234 234
++137 137 137 46 46 46 27 31 34 90 112 135 165 210 253 172 216 255 172 216 255 204 219 242
++204 219 242 191 201 212 154 196 236 161 204 245 172 216 255 172 216 255 168 213 255 172 216 255
++161 204 245 96 123 148 13 16 19 0 0 0 34 13 13 127 80 21 127 80 21 37 30 17
++5 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 45 57 69
++151 192 230 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 168 213 255
++165 210 253 118 151 181 37 46 56 0 0 1 0 0 0 37 34 34 145 144 144 236 236 236
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 246 246 246 165 165 165 46 46 46 4 4 5 0 0 0 27 31 34 109 140 168
++161 204 245 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 168 214 255 154 196 236 71 90 109
++10 12 13 0 0 0 37 34 34 188 187 187 253 253 253 255 255 255 255 255 255 255 255 255
++255 255 255 214 214 214 55 59 65 2 1 0 37 34 34 173 173 173 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 173 173 173 27 31 34
++0 0 0 4 5 6 70 80 89 151 192 230 169 215 255 168 213 255 157 201 242 96 123 148
++19 25 31 0 0 0 10 12 13 113 113 113 236 236 236 255 255 255 209 119 119 170 0 0
++189 59 59 255 255 255 255 255 255 255 255 255 183 41 41 173 10 10 182 36 36 182 36 36
++247 231 231 255 254 254 255 255 255 255 255 255 253 249 249 203 100 100 172 5 5 170 0 0
++200 91 91 252 246 246 255 255 255 255 255 255 239 209 209 170 0 0 170 0 0 21 0 0
++
++0 0 0 149 0 0 170 0 0 222 155 155 255 255 255 255 255 255 255 255 255 255 255 255
++234 194 194 204 103 103 196 78 78 206 110 110 219 148 148 231 184 184 243 218 218 243 218 218
++241 213 213 226 168 168 253 249 249 255 255 255 255 255 255 255 255 255 255 255 255 194 73 73
++170 0 0 206 110 110 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 232 232 232
++113 113 113 1 1 1 4 5 6 86 104 117 154 196 236 172 216 255 168 214 255 167 212 255
++167 212 255 168 214 255 172 216 255 168 213 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 140 179 215 45 57 69 1 1 1 11 2 0 88 72 43 176 111 31 71 32 32
++2 1 0 0 0 0 19 19 19 46 46 46 14 13 13 2 2 2 2 3 4 86 104 117
++165 209 252 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 168 214 255
++133 171 205 55 70 84 2 3 4 0 0 0 27 31 34 145 144 144 234 234 234 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 246 246 246 173 173 173 46 46 46 1 1 1 0 0 0 33 37 45
++118 151 181 165 209 252 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 172 216 255 133 171 205
++37 46 56 1 1 2 0 0 0 105 100 100 239 239 239 255 255 255 255 255 255 255 255 255
++255 255 255 228 228 228 87 87 87 0 0 0 19 19 19 145 144 144 251 251 251 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 241 241 241 127 127 127
++10 12 13 0 0 1 13 16 19 90 112 135 162 207 250 161 204 245 109 140 168 27 31 34
++0 0 0 1 1 1 87 87 87 210 206 206 255 255 255 255 255 255 194 73 73 170 0 0
++206 110 110 255 255 255 255 255 255 255 255 255 235 197 197 201 95 95 204 103 103 250 240 240
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 216 138 138 172 5 5
++170 0 0 198 84 84 255 255 255 255 255 255 222 155 155 167 0 0 160 0 0 0 0 0
++
++0 0 0 128 0 0 170 0 0 210 122 122 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 202 97 97
++170 0 0 200 91 91 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 246 246 246
++145 144 144 4 5 6 0 0 1 37 46 56 133 171 205 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++168 213 255 151 192 230 55 70 84 0 0 0 11 2 0 88 72 43 176 111 31 127 80 21
++9 6 4 2 1 0 37 34 34 97 97 97 18 19 24 2 2 2 18 19 24 118 151 181
++168 214 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 168 214 255 151 192 230
++86 104 117 8 10 11 0 0 1 19 19 19 127 127 127 232 232 232 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 250 248 248 165 165 165 37 34 34 0 0 1 0 0 0
++45 57 69 140 179 215 166 211 254 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 168 213 255 166 211 254
++90 112 135 13 16 19 0 0 0 27 31 34 198 194 194 253 253 253 255 255 255 255 255 255
++255 255 255 239 239 239 127 127 127 0 0 0 10 12 13 127 127 127 246 246 246 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 218 218 218
++70 80 89 2 1 0 0 0 0 33 37 45 118 151 181 118 151 181 37 46 56 0 0 0
++1 1 2 55 59 65 180 180 180 251 251 251 255 255 255 255 255 255 178 25 25 170 0 0
++222 158 158 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 211 125 125
++183 38 38 209 119 119 255 255 255 255 255 255 203 100 100 170 0 0 120 0 0 0 0 0
++
++0 0 0 98 0 0 170 0 0 198 84 84 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 209 119 119
++170 0 0 191 64 64 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 254 254 254
++198 194 194 46 46 46 0 0 0 6 7 9 71 90 109 151 192 230 169 216 255 169 215 255
++168 213 255 168 213 255 167 212 255 168 213 255 168 213 255 168 214 255 169 216 255 172 216 255
++165 210 253 126 161 193 33 37 45 5 3 2 2 1 0 127 80 21 176 111 31 127 80 21
++34 13 13 0 0 0 19 19 19 46 46 46 8 10 11 0 0 1 37 46 56 151 192 230
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 168 213 255 161 204 245 109 140 168
++19 25 31 0 0 0 8 10 11 105 100 100 223 222 222 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 243 242 242 137 137 137 19 19 19 0 0 0
++6 7 9 71 90 109 154 196 236 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 172 216 255
++133 171 205 37 46 56 1 1 1 0 0 0 127 127 127 246 246 246 255 255 255 255 255 255
++255 255 255 243 242 242 127 127 127 0 0 0 4 5 6 113 113 113 241 241 241 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 254 254
++173 173 173 19 25 31 0 0 0 2 3 4 37 46 56 37 46 56 2 2 2 1 1 2
++37 34 34 165 165 165 246 246 246 255 255 255 255 255 255 247 231 231 170 0 0 170 0 0
++239 206 206 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 185 47 47 170 0 0 83 0 0 0 0 0
++
++0 0 0 83 0 0 170 0 0 185 47 47 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 250 240 240 227 171 171 204 103 103
++188 55 55 183 41 41 196 78 78 241 213 213 255 255 255 255 255 255 255 255 255 224 161 161
++170 0 0 176 19 19 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++237 237 237 127 127 127 10 12 13 0 0 0 13 16 19 71 90 109 126 161 193 157 201 242
++166 211 254 168 214 255 169 215 255 168 213 255 166 211 254 157 201 242 140 179 215 126 161 193
++96 123 148 45 57 69 4 5 6 0 0 0 34 13 13 127 80 21 178 112 31 176 111 31
++56 42 30 5 2 0 1 1 2 6 7 9 2 2 2 0 0 0 71 90 109 161 204 245
++166 211 254 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 133 171 205 45 57 69
++2 2 2 0 0 0 55 59 65 206 206 206 254 254 254 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 228 228 228 105 100 100 4 5 6
++0 0 0 19 25 31 109 140 168 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 168 213 255
++161 204 245 71 90 109 8 10 11 0 0 0 55 59 65 223 222 222 255 255 255 255 255 255
++255 255 255 246 246 246 165 165 165 19 19 19 14 13 13 137 137 137 246 246 246 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++228 228 228 91 72 72 0 0 0 0 0 0 1 1 2 1 1 2 0 0 0 27 31 34
++137 137 137 239 239 239 255 255 255 255 255 255 255 255 255 224 164 164 170 0 0 173 10 10
++253 249 249 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 254 252 252 171 3 3 170 0 0 43 0 0 0 0 0
++
++0 0 0 43 0 0 170 0 0 172 5 5 253 248 248 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 248 236 236 216 138 138 191 64 64 172 5 5 170 0 0 170 0 0
++172 5 5 175 14 14 170 0 0 171 3 3 202 97 97 255 255 255 255 255 255 243 221 221
++170 0 0 170 0 0 242 216 216 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 206 206 206 87 87 87 2 3 4 0 0 0 8 10 11 33 37 45 70 80 89
++86 104 117 96 123 148 96 123 148 96 123 148 86 104 117 70 80 89 45 57 69 27 31 34
++13 16 19 2 3 4 0 0 0 16 8 3 71 32 32 176 111 31 177 112 32 176 111 31
++88 72 43 16 8 3 0 0 0 0 0 0 0 0 0 13 16 19 109 140 168 165 210 253
++167 212 255 167 212 255 167 212 255 167 212 255 168 213 255 157 201 242 90 112 135 10 12 13
++0 0 0 37 34 34 165 165 165 246 246 246 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 254 254 254 210 206 206 55 59 65
++1 1 1 1 1 1 45 57 69 140 179 215 168 214 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++169 215 255 118 151 181 18 19 24 2 1 0 18 19 24 188 187 187 255 255 255 255 255 255
++255 255 255 254 254 254 223 222 222 145 144 144 137 137 137 214 214 214 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++251 251 251 137 137 137 6 7 9 0 0 0 0 0 0 2 1 0 18 19 24 127 127 127
++236 236 236 255 255 255 255 255 255 255 255 255 255 255 255 203 100 100 170 0 0 193 71 71
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 247 231 231 170 0 0 170 0 0 32 0 0 0 0 0
++
++0 0 0 21 0 0 170 0 0 170 0 0 237 200 200 255 255 255 255 255 255 255 255 255
++255 255 255 233 190 190 176 19 19 170 0 0 170 0 0 184 44 44 208 114 114 226 168 168
++252 246 246 255 255 255 234 194 194 176 19 19 170 0 0 226 168 168 255 255 255 255 255 255
++178 25 25 170 0 0 222 155 155 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 251 251 251 198 194 194 87 87 87 6 7 9 1 1 1 1 1 2 4 5 6
++10 12 13 13 16 19 13 16 19 10 12 13 8 10 11 6 7 9 1 1 2 0 0 1
++0 0 1 0 0 0 16 8 3 71 32 32 176 111 31 176 111 31 177 112 32 178 112 31
++127 80 21 16 8 3 5 2 0 0 0 0 0 0 0 33 37 45 133 171 205 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 166 211 254 133 171 205 37 46 56 1 1 2
++8 10 11 113 113 113 228 228 228 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 253 253 253 165 165 165
++19 19 19 1 1 1 10 12 13 90 112 135 165 210 253 168 213 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++169 215 255 140 179 215 37 46 56 1 1 2 6 7 9 137 137 137 253 253 253 255 255 255
++255 255 255 255 255 255 253 253 253 246 246 246 243 242 242 253 253 253 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 198 194 194 37 34 34 1 1 1 1 1 1 19 19 19 127 127 127 228 228 228
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 182 36 36 170 0 0 217 141 141
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 235 197 197 170 0 0 170 0 0 11 2 0 0 0 0
++
++0 0 0 0 0 0 149 0 0 170 0 0 219 148 148 255 255 255 255 255 255 255 255 255
++241 213 213 173 10 10 177 22 22 222 155 155 211 125 125 237 200 200 251 242 242 252 246 246
++255 255 255 255 255 255 255 255 255 224 164 164 170 0 0 172 5 5 249 238 238 255 255 255
++198 84 84 170 0 0 196 78 78 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 251 251 251 214 214 214 127 127 127 46 46 46 8 10 11 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
++11 2 0 56 42 30 127 80 21 176 111 31 176 111 31 177 112 32 178 112 31 176 111 31
++176 111 31 37 30 17 2 1 0 0 0 0 0 0 0 55 70 84 151 192 230 167 212 255
++167 212 255 167 212 255 167 212 255 168 213 255 157 201 242 86 104 117 6 7 9 0 0 0
++46 46 46 188 187 187 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 239 239 239
++105 100 100 4 4 5 1 1 2 33 37 45 133 171 205 169 215 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++168 213 255 162 207 250 70 80 89 2 3 4 0 0 0 97 97 97 243 242 242 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 228 228 228 70 80 89 1 1 2 11 2 0 70 80 89 218 218 218 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 245 224 224 170 0 0 170 0 0 239 206 206
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 218 144 144 167 0 0 149 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 120 0 0 170 0 0 200 91 91 255 255 255 255 255 255 255 255 255
++199 87 87 170 0 0 218 144 144 243 227 227 253 248 248 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 243 221 221 170 0 0 170 0 0 228 174 174 255 255 255
++224 161 161 170 0 0 173 10 10 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 254 254 254 243 242 242 214 214 214 165 165 165 105 100 100
++87 87 87 55 59 65 55 59 65 55 59 65 87 87 87 55 59 65 14 13 13 0 0 0
++16 8 3 127 80 21 176 111 31 176 111 31 176 111 31 177 112 32 177 112 32 178 112 31
++176 111 31 71 32 32 16 8 3 0 0 0 0 0 0 86 104 117 161 204 245 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 140 179 215 37 46 56 1 1 2 8 10 11
++113 113 113 239 239 239 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++188 187 187 37 34 34 0 0 0 6 7 9 86 104 117 162 207 250 168 213 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 166 211 254 90 112 135 8 10 11 0 0 0 55 59 65 226 226 226 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 246 246 246 137 137 137 1 1 1 1 1 2 55 59 65 214 214 214 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 222 155 155 170 0 0 177 22 22 255 254 254
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 198 84 84 170 0 0 110 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 83 0 0 170 0 0 182 36 36 255 255 255 255 255 255 255 255 255
++183 41 41 172 6 6 202 97 97 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 241 213 213 170 0 0 179 27 27 231 184 184 255 255 255
++248 236 236 171 3 3 170 0 0 229 177 177 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 253 253 253 253 253 253 243 242 242
++234 234 234 232 232 232 232 232 232 232 232 232 241 241 241 198 194 194 46 46 46 2 1 0
++5 3 2 127 80 21 178 112 31 178 112 31 177 112 32 177 112 32 177 112 32 177 112 32
++178 112 31 127 80 21 16 8 3 0 0 0 13 16 19 109 140 168 165 209 252 167 212 255
++167 212 255 167 212 255 167 212 255 157 201 242 96 123 148 6 7 9 0 0 0 46 46 46
++188 187 187 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++243 242 242 113 113 113 2 3 4 1 1 2 33 37 45 133 171 205 169 215 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 169 216 255 109 140 168 13 16 19 0 0 0 46 46 46 210 206 206 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 246 246 246 214 214 214 214 214 214 243 242 242
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 253 253 253 188 187 187 27 31 34 0 0 0 37 34 34 173 173 173 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 198 84 84 170 0 0 200 91 91 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 254 253 253 175 16 16 170 0 0 68 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 32 0 0 170 0 0 170 0 0 242 216 216 255 255 255 255 255 255
++193 71 71 170 0 0 191 64 64 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 196 78 78 170 0 0 199 87 87 234 194 194 255 255 255
++255 255 255 193 71 71 170 0 0 201 95 95 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 254 254 254 255 255 255 255 255 255 237 237 237 87 87 87 0 0 0
++5 3 2 71 32 32 176 111 31 176 111 31 177 112 32 177 112 32 177 112 32 177 112 32
++178 112 31 127 80 21 16 8 3 2 1 0 27 31 34 133 171 205 165 210 253 167 212 255
++167 212 255 167 212 255 167 212 255 151 192 230 45 57 69 1 1 2 6 7 9 105 100 100
++236 236 236 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 188 187 187 37 34 34 0 0 0 10 12 13 90 112 135 165 210 253 168 213 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 168 214 255 126 161 193 19 25 31 0 0 0 27 31 34 198 194 194 254 254 254
++255 255 255 255 255 255 255 255 255 251 251 251 180 180 180 55 59 65 55 59 65 165 165 165
++251 251 251 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 254 254 254 223 222 222 55 59 65 5 2 0 19 19 19 137 137 137 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 176 19 19 170 0 0 222 158 158 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 237 203 203 170 0 0 170 0 0 21 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 149 0 0 170 0 0 209 119 119 255 255 255 255 255 255
++217 141 141 170 0 0 171 3 3 239 209 209 255 255 255 255 255 255 255 255 255 255 255 255
++251 242 242 224 164 164 196 78 78 170 0 0 176 19 19 209 119 119 255 254 254 255 255 255
++255 255 255 222 155 155 170 0 0 175 14 14 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 251 251 251 137 137 137 2 3 4
++5 2 0 37 30 17 127 80 21 178 112 31 177 112 32 177 112 32 177 112 32 178 112 31
++176 111 31 88 72 43 16 8 3 0 0 1 45 57 69 151 192 230 167 212 255 167 212 255
++167 212 255 167 212 255 165 209 252 118 151 181 18 19 24 0 0 0 27 31 34 165 165 165
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 241 241 241 97 97 97 0 0 0 2 3 4 45 57 69 140 179 215 168 214 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 168 214 255 133 171 205 19 25 31 0 0 0 19 19 19 180 180 180 255 255 255
++255 255 255 255 255 255 255 255 255 241 241 241 127 127 127 5 2 0 0 0 0 105 100 100
++234 234 234 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 243 242 242 113 113 113 0 0 0 6 7 9 97 97 97 241 241 241
++255 255 255 255 255 255 255 255 255 237 203 203 170 0 0 170 0 0 245 224 224 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 215 135 135 170 0 0 138 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 83 0 0 170 0 0 187 53 53 255 255 255 255 255 255
++243 221 221 172 7 7 171 2 2 175 16 16 202 97 97 233 190 190 206 110 110 184 44 44
++171 3 3 170 0 0 170 0 0 182 36 36 209 119 119 235 197 197 255 255 255 255 255 255
++255 255 255 249 238 238 172 5 5 170 0 0 229 177 177 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 188 187 187 27 31 34
++0 0 0 16 8 3 127 80 21 178 112 31 178 112 31 177 112 32 177 112 32 178 112 31
++176 111 31 71 32 32 9 6 4 0 0 0 71 90 109 154 196 236 167 212 255 167 212 255
++167 212 255 167 212 255 157 201 242 86 104 117 0 0 1 2 2 2 91 72 72 214 214 214
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 253 253 253 173 173 173 19 19 19 0 0 0 19 25 31 109 140 168 172 216 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 169 215 255 140 179 215 27 31 34 1 1 2 19 19 19 173 173 173 255 255 255
++255 255 255 255 255 255 255 255 255 234 234 234 105 100 100 1 1 2 0 0 0 105 100 100
++232 232 232 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 250 248 248 165 165 165 6 7 9 2 2 2 55 59 65 206 206 206
++255 255 255 255 255 255 255 255 255 215 135 135 170 0 0 182 36 36 255 255 255 255 255 255
++224 161 161 175 14 14 193 71 71 230 181 181 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 187 53 53 170 0 0 98 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 55 0 0 170 0 0 173 8 8 254 252 252 255 255 255
++255 255 255 231 184 184 176 19 19 170 0 0 170 0 0 170 0 0 170 0 0 175 14 14
++198 84 84 219 152 152 232 187 187 237 200 200 239 209 209 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 194 73 73 170 0 0 200 91 91 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 254 254 254 232 232 232 55 59 65
++0 0 0 16 8 3 71 32 32 176 111 31 178 112 31 177 112 32 177 112 32 176 111 31
++176 111 31 56 42 30 0 0 0 0 0 0 90 112 135 161 204 245 167 212 255 167 212 255
++167 212 255 165 209 252 151 192 230 45 57 69 0 0 0 14 13 13 113 113 113 246 246 246
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 253 253 253 228 228 228 55 59 65 0 0 0 6 7 9 71 90 109 161 204 245
++168 214 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 169 215 255 140 179 215 33 37 45 0 0 1 14 13 13 173 173 173 255 255 255
++255 255 255 255 255 255 255 255 255 232 232 232 105 100 100 0 0 0 1 1 2 105 100 100
++234 234 234 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 251 251 251 206 206 206 37 34 34 0 0 0 37 34 34 173 173 173
++255 255 255 255 255 255 255 255 255 185 47 47 170 0 0 206 110 110 255 255 255 255 255 255
++210 122 122 170 0 0 170 0 0 170 0 0 188 55 55 228 174 174 254 253 253 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 241 213 213 170 0 0 170 0 0 32 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 21 0 0 170 0 0 170 0 0 241 213 213 255 255 255
++255 255 255 255 255 255 248 236 236 218 144 144 201 95 95 206 110 110 230 181 181 253 248 248
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 248 236 236 227 171 171
++254 253 253 255 255 255 222 155 155 170 0 0 175 16 16 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 243 242 242 113 113 113
++5 3 2 1 1 1 56 42 30 176 111 31 176 111 31 177 112 32 177 112 32 178 112 31
++127 80 21 37 30 17 0 0 0 10 12 13 118 151 181 162 207 250 167 212 255 167 212 255
++167 212 255 165 210 253 126 161 193 18 19 24 1 1 2 27 31 34 165 165 165 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 246 246 246 127 127 127 5 3 2 0 0 1 37 46 56 140 179 215
++169 216 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 169 215 255 140 179 215 27 31 34 0 0 1 19 19 19 173 173 173 253 253 253
++255 255 255 255 255 255 255 255 255 234 234 234 113 113 113 0 0 0 0 0 0 105 100 100
++232 232 232 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 254 254 254 226 226 226 55 59 65 5 3 2 19 19 19 145 144 144
++255 255 255 255 255 255 239 206 206 170 0 0 170 0 0 239 209 209 255 255 255 255 255 255
++252 246 246 235 197 197 216 138 138 191 64 64 171 2 2 170 0 0 183 38 38 217 141 141
++247 231 231 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 208 114 114 170 0 0 149 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 160 0 0 170 0 0 224 164 164 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 249 238 238 212 128 128 175 14 14 170 0 0
++219 152 152 255 255 255 248 236 236 171 4 4 170 0 0 229 177 177 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 253 253 253 173 173 173
++14 13 13 0 0 0 34 13 13 127 80 21 178 112 31 177 112 32 178 112 31 178 112 31
++127 80 21 34 13 13 0 0 0 27 31 34 126 161 193 165 210 253 167 212 255 167 212 255
++167 212 255 161 204 245 96 123 148 2 3 4 2 1 0 55 59 65 214 214 214 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 254 254 254 198 194 194 27 31 34 0 0 0 19 25 31 109 140 168
++169 216 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 168 214 255 133 171 205 19 25 31 1 1 1 19 19 19 180 180 180 255 255 255
++255 255 255 255 255 255 255 255 255 237 237 237 127 127 127 2 2 2 0 0 1 87 87 87
++226 226 226 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 239 239 239 105 100 100 0 0 0 10 12 13 113 113 113
++250 248 248 255 255 255 205 106 106 170 0 0 187 50 50 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 243 227 227 215 135 135 171 3 3 170 0 0
++171 3 3 188 55 55 218 144 144 248 233 233 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 179 27 27 170 0 0 83 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 170 0 0 201 95 95 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 237 203 203 202 97 97 173 8 8 170 1 1 170 0 0 175 14 14
++226 168 168 255 255 255 255 255 255 194 73 73 170 0 0 193 71 71 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 254 254 254 218 218 218
++46 46 46 2 2 2 16 8 3 127 80 21 176 111 31 178 112 31 177 112 32 178 112 31
++127 80 21 9 6 4 2 1 0 37 46 56 140 179 215 167 212 255 167 212 255 167 212 255
++167 212 255 154 196 236 70 80 89 0 0 1 6 7 9 105 100 100 243 242 242 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 254 254 254 232 232 232 91 72 72 0 0 0 8 10 11 86 104 117
++162 207 250 168 214 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 169 215 255 126 161 193 19 25 31 0 0 0 27 31 34 198 194 194 254 254 254
++255 255 255 255 255 255 255 255 255 246 246 246 137 137 137 8 10 11 0 0 0 55 59 65
++210 206 206 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 246 246 246 127 127 127 2 3 4 5 3 2 97 97 97
++234 234 234 255 255 255 175 14 14 170 0 0 219 148 148 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 206 110 110 183 38 38 170 0 0 212 128 128
++200 91 91 170 1 1 170 0 0 172 5 5 194 73 73 215 135 135 255 255 255 255 255 255
++242 216 216 170 0 0 170 0 0 32 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 68 0 0 170 0 0 175 14 14 252 246 246
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 251 242 242
++222 155 155 187 53 53 170 0 0 172 6 6 197 81 81 227 171 171 243 221 221 254 253 253
++255 255 255 255 255 255 255 255 255 230 181 181 170 0 0 170 1 1 242 216 216 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 239 239 239
++105 100 100 0 0 0 5 2 0 56 42 30 176 111 31 178 112 31 178 112 31 176 111 31
++88 72 43 16 8 3 1 1 2 45 57 69 151 192 230 167 212 255 167 212 255 167 212 255
++165 210 253 151 192 230 45 57 69 0 0 0 19 19 19 137 137 137 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 243 242 242 127 127 127 0 0 0 2 3 4 45 57 69
++151 192 230 169 215 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 168 213 255 118 151 181 13 16 19 0 0 0 37 34 34 206 206 206 255 255 255
++255 255 255 255 255 255 255 255 255 253 253 253 173 173 173 27 31 34 2 1 0 27 31 34
++165 165 165 253 253 253 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 246 246 246 165 165 165 6 7 9 5 3 2 55 59 65
++223 222 222 222 155 155 170 0 0 173 8 8 250 240 240 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 197 81 81 170 0 0 171 3 3 248 236 236
++255 255 255 239 209 209 199 87 87 178 25 25 170 0 0 194 73 73 255 255 255 255 255 255
++219 152 152 167 0 0 160 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 11 2 0 167 0 0 170 0 0 227 171 171
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 237 200 200 203 100 100 175 14 14
++170 0 0 187 53 53 219 148 148 248 236 236 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 254 253 253 182 36 36 170 0 0 206 110 110 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 250 248 248
++156 150 150 8 10 11 0 0 0 37 30 17 127 80 21 178 112 31 178 112 31 176 111 31
++71 32 32 16 8 3 0 0 0 70 80 89 154 196 236 168 213 255 167 212 255 167 212 255
++166 211 254 133 171 205 19 25 31 0 0 1 27 31 34 173 173 173 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 253 253 253 173 173 173 19 19 19 0 0 0 33 37 45
++126 161 193 169 216 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 109 140 168 8 10 11 1 1 2 46 46 46 218 218 218 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 206 206 206 55 59 65 5 2 0 1 1 2
++113 113 113 236 236 236 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 251 251 251 165 165 165 14 13 13 0 0 0 55 59 65
++218 218 218 187 50 50 170 0 0 202 97 97 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 251 244 244 180 30 30 170 0 0 193 71 71 255 255 255
++255 255 255 251 242 242 208 114 114 189 59 59 170 0 0 222 158 158 255 255 255 255 255 255
++200 91 91 170 0 0 110 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 120 0 0 170 0 0 198 84 84
++255 255 255 255 255 255 255 255 255 228 174 174 180 30 30 170 0 0 175 16 16 208 114 114
++237 200 200 254 253 253 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 218 144 144 170 0 0 176 19 19 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 253 253 253
++206 206 206 46 46 46 2 1 0 16 8 3 127 80 21 178 112 31 176 111 31 176 111 31
++71 32 32 2 1 0 1 1 2 71 90 109 157 201 242 168 213 255 167 212 255 167 212 255
++166 211 254 109 140 168 10 12 13 0 0 0 46 46 46 206 206 206 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 253 253 253 218 218 218 46 46 46 0 0 0 18 19 24
++96 123 148 168 214 255 168 213 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++168 214 255 165 209 252 96 123 148 6 7 9 0 0 0 55 59 65 228 228 228 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 232 232 232 113 113 113 4 4 5 0 0 0
++55 59 65 198 194 194 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 251 251 251 165 165 165 8 10 11 5 3 2 55 59 65
++229 177 177 170 0 0 170 0 0 237 203 203 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 229 177 177 172 5 5 170 0 0 222 158 158 255 255 255
++255 255 255 254 253 253 179 27 27 170 1 1 173 8 8 251 242 242 255 255 255 255 255 255
++179 27 27 170 0 0 68 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 55 0 0 170 0 0 173 8 8
++252 246 246 255 255 255 255 255 255 229 177 177 175 16 16 170 0 0 170 1 1 179 27 27
++180 30 30 255 254 254 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 248 233 233 171 4 4 170 0 0 229 177 177
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++232 232 232 87 87 87 0 0 0 5 3 2 71 32 32 176 111 31 178 112 31 176 111 31
++56 42 30 11 2 0 0 0 1 90 112 135 161 204 245 167 212 255 167 212 255 167 212 255
++165 209 252 90 112 135 2 3 4 2 2 2 70 80 89 232 232 232 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 232 232 232 87 87 87 0 0 0 8 10 11
++90 112 135 162 207 250 168 213 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 90 112 135 2 3 4 0 0 0 55 59 65 232 232 232 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 251 251 251 165 165 165 27 31 34 2 1 0
++6 7 9 127 127 127 236 236 236 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 246 246 246 137 137 137 2 3 4 4 4 5 97 97 97
++185 47 47 170 0 0 194 73 73 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 224 164 164 170 0 0 172 5 5 250 240 240 255 255 255
++255 255 255 234 194 194 170 0 0 170 0 0 199 87 87 255 255 255 255 255 255 241 213 213
++170 0 0 170 0 0 32 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 11 2 0 167 0 0 170 0 0
++230 181 181 255 255 255 255 255 255 255 255 255 255 254 254 234 194 194 178 25 25 170 0 0
++196 78 78 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 194 73 73 170 0 0 194 73 73
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++243 242 242 137 137 137 4 4 5 5 3 2 37 30 17 176 111 31 176 111 31 176 111 31
++37 30 17 0 0 0 2 3 4 96 123 148 162 207 250 167 212 255 167 212 255 166 211 254
++162 207 250 70 80 89 0 0 0 9 6 4 97 97 97 250 248 248 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 243 242 242 113 113 113 0 0 0 2 3 4
++70 80 89 157 201 242 168 214 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 166 211 254 90 112 135 4 5 6 5 2 0 55 59 65 232 232 232 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 218 218 218 97 97 97 2 3 4
++0 0 0 46 46 46 173 173 173 251 251 251 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 239 239 239 105 100 100 0 0 0 10 12 13 228 174 174
++170 0 0 170 0 0 237 203 203 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 253 249 249 210 122 122 219 152 152 255 255 255 255 255 255
++255 255 255 204 103 103 170 0 0 170 0 0 229 177 177 255 255 255 255 255 255 215 135 135
++170 0 0 149 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 170 0 0
++204 103 103 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 247 231 231 232 187 187
++254 252 252 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 229 177 177 170 0 0 170 0 0
++224 164 164 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++253 253 253 173 173 173 27 31 34 0 0 0 34 13 13 127 80 21 178 112 31 176 111 31
++37 30 17 11 2 0 4 5 6 109 140 168 161 204 245 167 212 255 167 212 255 167 212 255
++154 196 236 45 57 69 2 3 4 10 12 13 127 127 127 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 250 248 248 156 150 150 6 7 9 0 0 0
++45 57 69 140 179 215 172 216 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 96 123 148 10 12 13 0 0 0 46 46 46 223 222 222 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 253 253 253 165 165 165 37 34 34
++0 0 0 1 1 1 70 80 89 198 194 194 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 254 254 254 228 228 228 70 80 89 0 0 0 19 19 19 189 59 59
++170 0 0 194 73 73 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++254 251 251 177 22 22 170 0 0 176 19 19 253 249 249 255 255 255 255 255 255 189 59 59
++170 0 0 98 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 83 0 0 170 0 0
++179 27 27 254 253 253 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 198 84 84 170 0 0
++176 19 19 247 231 231 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 218 218 218 55 59 65 0 0 0 16 8 3 37 30 17 127 80 21 71 32 32
++16 8 3 0 0 0 10 12 13 109 140 168 162 207 250 167 212 255 167 212 255 165 210 253
++151 192 230 37 46 56 0 0 0 19 19 19 156 150 150 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 251 251 251 180 180 180 19 19 19 0 0 0
++37 46 56 126 161 193 169 216 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 168 214 255 118 151 181 13 16 19 0 0 0 37 34 34 198 194 194 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 236 236 236 113 113 113
++10 12 13 0 0 0 5 3 2 97 97 97 214 214 214 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 253 253 253 214 214 214 46 46 46 0 0 0 237 200 200 170 0 0
++170 0 0 234 194 194 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++231 184 184 170 0 0 170 0 0 206 110 110 255 255 255 255 255 255 248 233 233 171 2 2
++167 0 0 55 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 21 0 0 170 0 0
++170 0 0 229 177 177 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 248 233 233 177 22 22
++170 0 0 203 100 100 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 239 239 239 113 113 113 2 2 2 0 0 0 11 2 0 9 6 4 16 8 3
++5 3 2 0 0 0 13 16 19 118 151 181 165 209 252 167 212 255 167 212 255 166 211 254
++140 179 215 33 37 45 0 0 0 18 19 24 173 173 173 254 254 254 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 254 254 254 206 206 206 46 46 46 0 0 0
++19 25 31 109 140 168 172 216 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 168 214 255 140 179 215 27 31 34 1 1 2 14 13 13 145 144 144 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 210 206 206
++87 87 87 2 2 2 0 0 1 8 10 11 87 87 87 180 180 180 241 241 241 255 255 255
++255 255 255 255 255 255 253 253 253 206 206 206 37 34 34 0 0 1 193 71 71 170 0 0
++189 59 59 255 255 255 255 255 255 245 224 224 232 187 187 254 252 252 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++202 97 97 170 0 0 170 0 0 239 206 206 255 255 255 255 255 255 212 128 128 170 0 0
++160 0 0 5 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 120 0 0
++170 0 0 193 71 71 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 219 148 148
++170 0 0 172 5 5 245 224 224 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 250 248 248 165 165 165 19 19 19 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 1 1 1 18 19 24 118 151 181 165 210 253 167 212 255 167 212 255 167 212 255
++133 171 205 19 25 31 2 1 0 27 31 34 188 187 187 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 254 254 254 214 214 214 55 59 65 0 0 0
++18 19 24 96 123 148 167 212 255 168 213 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 157 201 242 55 70 84 0 0 1 5 2 0 70 80 89 232 232 232
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 251 251 251
++198 194 194 55 59 65 2 2 2 0 0 0 6 7 9 37 34 34 113 113 113 198 194 194
++243 242 242 255 255 255 255 255 255 206 206 206 37 34 34 229 177 177 170 0 0 170 0 0
++230 181 181 255 255 255 255 255 255 187 50 50 170 0 0 189 59 59 248 233 233 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 253 249 249
++175 16 16 170 1 1 191 64 64 255 255 255 255 255 255 253 248 248 177 22 22 170 0 0
++83 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 43 0 0
++170 0 0 170 1 1 242 216 216 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 252 246 246
++179 27 27 170 0 0 204 103 103 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 223 222 222 127 127 127 91 72 72 55 59 65 91 72 72 55 59 65
++19 19 19 0 0 0 19 25 31 118 151 181 166 211 254 167 212 255 167 212 255 167 212 255
++126 161 193 18 19 24 0 0 0 37 34 34 206 206 206 254 254 254 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 223 222 222 87 87 87 0 0 0
++13 16 19 90 112 135 165 210 253 168 213 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 109 140 168 8 10 11 0 0 1 19 19 19 165 165 165
++254 254 254 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++251 251 251 180 180 180 55 59 65 5 3 2 0 0 0 2 2 2 8 10 11 46 46 46
++105 100 100 165 165 165 206 206 206 188 187 187 33 37 45 182 36 36 170 0 0 194 73 73
++255 255 255 255 255 255 255 255 255 205 106 106 170 0 0 170 0 0 178 25 25 230 181 181
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 250 240 240
++175 16 16 170 0 0 219 152 152 255 255 255 255 255 255 222 155 155 170 0 0 167 0 0
++21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++149 0 0 170 0 0 200 91 91 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++218 144 144 170 0 0 171 3 3 237 203 203 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 243 242 242 228 228 228 232 232 232 232 232 232 188 187 187
++46 46 46 0 0 1 18 19 24 126 161 193 165 210 253 167 212 255 167 212 255 168 213 255
++118 151 181 10 12 13 0 0 0 46 46 46 210 206 206 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 232 232 232 97 97 97 0 0 0
++8 10 11 86 104 117 161 204 245 168 214 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 165 210 253 151 192 230 45 57 69 0 0 0 9 6 4 55 59 65
++214 214 214 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 251 251 251 188 187 187 46 46 46 1 1 1 0 0 0 0 0 0 1 1 1
++6 7 9 19 19 19 37 34 34 46 46 46 218 144 144 170 0 0 172 5 5 242 216 216
++255 255 255 255 255 255 255 255 255 255 255 255 241 213 213 201 95 95 170 1 1 170 0 0
++200 91 91 247 231 231 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++243 227 227 222 158 158 253 249 249 255 255 255 254 253 253 183 41 41 170 0 0 110 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++55 0 0 170 0 0 170 0 0 235 197 197 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++253 249 249 185 47 47 170 0 0 183 41 41 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 206 206 206
++55 59 65 0 0 0 18 19 24 118 151 181 165 210 253 167 212 255 167 212 255 167 212 255
++118 151 181 8 10 11 1 1 1 46 46 46 223 222 222 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 236 236 236 113 113 113 0 0 0
++6 7 9 71 90 109 161 204 245 168 214 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 109 140 168 13 16 19 0 0 1 8 10 11
++113 113 113 232 232 232 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 241 241 241 87 87 87 4 5 6 1 1 1 8 10 11 6 7 9
++0 0 0 0 0 0 1 1 2 248 233 233 178 25 25 170 0 0 203 100 100 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 253 248 248 209 119 119 194 73 73
++170 0 0 175 14 14 217 141 141 253 249 249 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 227 171 171 170 0 0 170 0 0 32 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++5 2 0 128 0 0 170 0 0 187 50 50 255 254 254 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 239 206 206 172 5 5 170 0 0 209 119 119 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 210 206 206
++55 59 65 0 0 0 18 19 24 118 151 181 165 210 253 167 212 255 167 212 255 167 212 255
++109 140 168 6 7 9 2 1 0 55 59 65 226 226 226 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 239 239 239 113 113 113 0 0 0
++4 4 5 71 90 109 157 201 242 168 214 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 168 213 255 151 192 230 71 90 109 2 3 4 0 0 0
++19 19 19 137 137 137 241 241 241 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 239 239 239 87 87 87 4 4 5 1 1 1 97 97 97 137 137 137
++70 80 89 37 34 34 19 19 19 189 59 59 170 0 0 173 12 12 243 221 221 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 189 59 59 183 38 38
++170 0 0 187 50 50 170 0 0 183 41 41 231 184 184 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 187 50 50 170 0 0 120 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 32 0 0 170 0 0 170 0 0 222 158 158 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 212 128 128 170 0 0 171 4 4 239 206 206 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 214 214 214
++55 59 65 2 1 0 13 16 19 118 151 181 162 207 250 167 212 255 167 212 255 167 212 255
++109 140 168 4 5 6 1 1 1 55 59 65 228 228 228 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 241 241 241 127 127 127 0 0 0
++2 3 4 70 80 89 154 196 236 169 215 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 133 171 205 37 46 56 2 3 4
++1 1 1 37 34 34 156 150 150 246 246 246 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 232 232 232 55 59 65 5 3 2 6 7 9 145 144 144 251 251 251
++234 234 234 206 206 206 215 135 135 170 0 0 171 2 2 231 184 184 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 239 206 206 171 2 2 170 0 0
++199 87 87 254 251 251 206 110 110 171 3 3 170 0 0 197 81 81 241 213 213 255 255 255
++255 255 255 255 255 255 255 255 255 231 184 184 170 0 0 170 0 0 32 0 0 2 1 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 110 0 0 170 0 0 181 33 33 254 253 253 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 239 209 209 181 33 33
++235 197 197 245 224 224 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 253 249 249 183 41 41 170 0 0 187 50 50 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 254 254 254 223 222 222
++55 59 65 0 0 0 8 10 11 109 140 168 162 207 250 167 212 255 167 212 255 165 209 252
++109 140 168 4 5 6 5 2 0 55 59 65 232 232 232 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 241 241 241 137 137 137 0 0 0
++2 3 4 70 80 89 154 196 236 169 215 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 165 210 253 118 151 181 33 37 45
++0 0 0 0 0 0 46 46 46 165 165 165 253 253 253 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 214 214 214 55 59 65 0 0 0 14 13 13 173 173 173 254 254 254
++255 255 255 241 213 213 172 7 7 170 0 0 208 114 114 255 255 255 255 255 255 255 255 255
++255 255 255 252 246 246 243 218 218 233 190 190 218 144 144 198 84 84 170 0 0 173 10 10
++245 224 224 255 255 255 255 255 255 239 209 209 189 59 59 170 0 0 170 0 0 212 128 128
++255 255 255 255 255 255 255 254 254 188 55 55 170 0 0 128 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 21 0 0 170 0 0 170 0 0 228 174 174 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 250 240 240 180 30 30
++187 50 50 208 114 114 251 244 244 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 235 197 197 170 1 1 170 0 0 208 114 114 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 226 226 226
++87 87 87 0 0 0 4 5 6 96 123 148 165 210 253 166 211 254 167 212 255 167 212 255
++109 140 168 4 4 5 2 2 2 55 59 65 232 232 232 254 254 254 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 243 242 242 137 137 137 0 0 0
++1 1 2 55 70 84 154 196 236 168 213 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 166 211 254 162 207 250 109 140 168
++27 31 34 0 0 1 0 0 0 46 46 46 180 180 180 251 251 251 255 255 255 255 255 255
++255 255 255 255 255 255 188 187 187 37 34 34 0 0 0 27 31 34 198 194 194 255 255 255
++255 255 255 188 55 55 170 0 0 182 36 36 252 246 246 255 255 255 250 240 240 218 144 144
++203 100 100 193 71 71 196 78 78 194 73 73 173 8 8 193 71 71 170 0 0 212 128 128
++255 255 255 255 255 255 255 255 255 255 255 255 191 64 64 191 64 64 170 0 0 222 155 155
++255 255 255 255 255 255 224 164 164 170 0 0 170 0 0 32 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 120 0 0 170 0 0 191 64 64 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 232 187 187
++170 0 0 206 110 110 206 110 110 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 208 114 114 170 0 0 170 0 0 224 161 161
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 237 237 237
++87 87 87 4 4 5 2 2 2 96 123 148 161 204 245 167 212 255 167 212 255 165 210 253
++109 140 168 6 7 9 5 2 0 55 59 65 228 228 228 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 243 242 242 137 137 137 1 1 1
++2 3 4 70 80 89 151 192 230 169 215 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 161 204 245
++96 123 148 19 25 31 0 0 0 9 6 4 55 59 65 198 194 194 254 254 254 255 255 255
++255 255 255 255 255 255 165 165 165 19 25 31 1 1 1 46 46 46 218 218 218 255 255 255
++212 128 128 170 0 0 171 3 3 234 194 194 255 255 255 255 255 255 206 110 110 170 0 0
++170 0 0 170 0 0 170 0 0 170 0 0 171 3 3 170 0 0 181 33 33 252 246 246
++255 255 255 255 255 255 255 255 255 239 206 206 171 3 3 170 0 0 187 53 53 254 253 253
++255 255 255 252 246 246 179 27 27 170 0 0 110 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 43 0 0 170 0 0 170 0 0 237 203 203 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++204 103 103 172 6 6 212 128 128 230 181 181 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 254 252 252 194 73 73 170 0 0 173 8 8
++237 203 203 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 246 246 246
++113 113 113 6 7 9 0 0 0 86 104 117 161 204 245 167 212 255 167 212 255 167 212 255
++109 140 168 6 7 9 0 0 1 55 59 65 223 222 222 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 243 242 242 137 137 137 0 0 0
++1 1 2 55 70 84 154 196 236 169 215 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++157 201 242 90 112 135 18 19 24 0 0 0 9 6 4 87 87 87 214 214 214 255 255 255
++255 255 255 253 253 253 127 127 127 14 13 13 0 0 0 87 87 87 228 228 228 235 197 197
++171 3 3 170 0 0 211 125 125 255 255 255 255 255 255 255 255 255 219 148 148 183 38 38
++196 78 78 210 122 122 226 168 168 241 213 213 226 168 168 170 0 0 224 164 164 251 244 244
++255 255 255 255 255 255 255 255 255 189 59 59 170 0 0 170 1 1 237 200 200 255 255 255
++255 255 255 211 125 125 170 0 0 167 0 0 21 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 138 0 0 170 0 0 196 78 78 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++251 242 242 180 30 30 189 59 59 208 114 114 252 246 246 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 250 240 240 184 44 44 170 0 0
++180 30 30 253 249 249 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 250 248 248
++127 127 127 14 13 13 0 0 0 71 90 109 154 196 236 167 212 255 167 212 255 167 212 255
++118 151 181 8 10 11 2 1 0 46 46 46 218 218 218 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 243 242 242 127 127 127 0 0 0
++4 5 6 70 80 89 154 196 236 169 215 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++166 211 254 154 196 236 71 90 109 4 5 6 1 1 1 10 12 13 127 127 127 232 232 232
++255 255 255 232 232 232 87 87 87 4 5 6 0 0 0 113 113 113 245 224 224 177 22 22
++170 0 0 188 55 55 254 251 251 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 242 216 216 172 7 7 170 0 0 233 190 190 255 255 255
++255 255 255 255 255 255 224 164 164 170 0 0 170 0 0 201 95 95 255 255 255 255 255 255
++245 224 224 173 8 8 170 0 0 83 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 55 0 0 170 0 0 170 0 0 239 206 206
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 232 187 187 170 1 1 211 125 125 218 144 144 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 243 218 218 175 14 14
++170 0 0 197 81 81 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++137 137 137 19 19 19 0 0 0 55 70 84 151 192 230 167 212 255 167 212 255 167 212 255
++126 161 193 10 12 13 0 0 1 46 46 46 210 206 206 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 241 241 241 127 127 127 0 0 0
++2 3 4 71 90 109 154 196 236 169 215 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 126 161 193 27 31 34 0 0 0 0 0 0 37 34 34 165 165 165
++250 248 248 188 187 187 46 46 46 0 0 0 13 16 19 188 187 187 183 41 41 170 0 0
++177 22 22 243 221 221 255 255 255 255 255 255 229 177 177 212 128 128 249 238 238 255 255 255
++255 255 255 255 255 255 255 255 255 252 246 246 194 73 73 170 0 0 210 122 122 255 255 255
++255 255 255 249 238 238 179 27 27 170 0 0 175 14 14 247 231 231 255 255 255 255 255 255
++198 84 84 170 0 0 149 0 0 11 2 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 138 0 0 170 0 0 196 78 78
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 206 110 110 173 10 10 219 152 152 239 209 209 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 227 171 171
++170 0 0 170 0 0 204 103 103 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++156 150 150 27 31 34 0 0 0 45 57 69 140 179 215 167 212 255 167 212 255 167 212 255
++126 161 193 18 19 24 0 0 0 37 34 34 198 194 194 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 237 237 237 113 113 113 0 0 0
++4 5 6 71 90 109 157 201 242 168 214 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 126 161 193 27 31 34 0 0 0 0 0 0 2 1 0 55 59 65
++198 194 194 127 127 127 19 19 19 0 0 0 55 59 65 189 59 59 170 0 0 173 8 8
++237 200 200 255 255 255 255 255 255 210 122 122 170 0 0 170 0 0 189 59 59 254 251 251
++255 255 255 255 255 255 255 255 255 255 255 255 241 213 213 179 27 27 171 4 4 215 135 135
++206 110 110 179 27 27 170 0 0 170 0 0 217 141 141 255 255 255 255 255 255 234 194 194
++170 0 0 170 0 0 55 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 55 0 0 170 0 0 170 0 0
++234 194 194 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 252 246 246 183 38 38 187 53 53 232 187 187 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++208 114 114 170 0 0 170 0 0 208 114 114 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++173 173 173 37 34 34 0 0 0 33 37 45 133 171 205 167 212 255 167 212 255 167 212 255
++133 171 205 19 25 31 0 0 0 27 31 34 188 187 187 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 234 234 234 105 100 100 0 0 1
++6 7 9 86 104 117 157 201 242 169 215 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 165 209 252 118 151 181 13 16 19 0 0 1 0 0 0 0 0 0 14 13 13
++87 87 87 46 46 46 6 7 9 0 0 0 194 73 73 170 0 0 171 2 2 228 174 174
++255 255 255 255 255 255 212 128 128 172 5 5 170 0 0 171 4 4 170 0 0 194 73 73
++251 244 244 255 255 255 255 255 255 255 255 255 255 255 255 241 213 213 179 27 27 170 0 0
++170 0 0 170 0 0 170 0 0 196 78 78 253 249 249 255 255 255 255 254 254 188 55 55
++170 0 0 128 0 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 1 0 128 0 0 170 0 0
++181 33 33 251 244 244 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 237 200 200 171 2 2 208 114 114 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 254 254 205 106 106 170 0 0 170 0 0 218 144 144 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++198 194 194 46 46 46 0 0 0 18 19 24 118 151 181 165 209 252 167 212 255 166 211 254
++140 179 215 33 37 45 2 1 0 18 19 24 173 173 173 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 228 228 228 87 87 87 0 0 1
++8 10 11 90 112 135 162 207 250 168 214 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 162 207 250 96 123 148 6 7 9 2 2 2 8 10 11 4 5 6 0 0 0
++6 7 9 4 5 6 0 0 0 202 97 97 170 0 0 170 0 0 219 152 152 255 255 255
++255 255 255 222 158 158 170 1 1 170 0 0 183 41 41 243 227 227 185 47 47 170 0 0
++187 53 53 247 231 231 255 255 255 255 255 255 255 255 255 255 255 255 252 246 246 222 155 155
++202 97 97 202 97 97 227 171 171 255 254 254 255 255 255 255 255 255 226 168 168 170 0 0
++170 0 0 43 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 32 0 0 167 0 0
++170 0 0 205 106 106 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 231 184 184 248 236 236 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 254 254 201 95 95 170 0 0 172 7 7 235 197 197 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++218 218 218 55 59 65 9 6 4 1 1 2 96 123 148 165 209 252 166 211 254 166 211 254
++151 192 230 37 46 56 0 0 0 19 19 19 156 150 150 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 223 222 222 70 80 89 2 1 0
++13 16 19 96 123 148 162 207 250 168 214 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 157 201 242 86 104 117 1 1 2 6 7 9 55 59 65 55 59 65 5 2 0
++0 0 1 0 0 0 206 110 110 170 0 0 170 0 0 212 128 128 255 255 255 255 255 255
++231 184 184 173 10 10 170 0 0 178 25 25 245 224 224 222 158 158 224 161 161 197 81 81
++170 0 0 181 33 33 241 213 213 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 253 249 249 181 33 33 170 0 0
++110 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 83 0 0
++170 0 0 170 1 1 233 190 190 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 252 246 246 183 41 41 170 0 0 175 16 16 237 203 203 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++239 239 239 105 100 100 6 7 9 0 0 1 86 104 117 157 201 242 167 212 255 166 211 254
++154 196 236 45 57 69 0 0 0 14 13 13 137 137 137 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 253 253 253 214 214 214 46 46 46 0 0 0
++18 19 24 109 140 168 168 213 255 168 213 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 151 192 230 70 80 89 0 0 0 19 19 19 113 113 113 137 137 137 18 19 24
++0 0 0 211 125 125 170 0 0 170 0 0 206 110 110 255 255 255 255 255 255 241 213 213
++178 25 25 170 0 0 175 14 14 239 209 209 255 255 255 255 255 255 218 144 144 204 103 103
++200 91 91 170 0 0 175 16 16 231 184 184 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 216 138 138 170 0 0 167 0 0
++21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++128 0 0 170 0 0 180 30 30 250 240 240 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 245 224 224 179 27 27 170 0 0 173 12 12 232 187 187
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++253 253 253 127 127 127 13 16 19 0 0 0 55 70 84 151 192 230 167 212 255 167 212 255
++157 201 242 55 70 84 1 1 2 8 10 11 113 113 113 253 253 253 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 253 253 253 198 194 194 37 34 34 0 0 1
++27 31 34 118 151 181 169 215 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 140 179 215 45 57 69 0 0 0 19 25 31 156 150 150 214 214 214 70 80 89
++208 114 114 170 1 1 170 0 0 201 95 95 254 253 253 255 255 255 252 246 246 189 59 59
++170 0 0 172 5 5 232 187 187 255 255 255 255 255 255 255 255 255 209 119 119 170 0 0
++170 0 0 180 30 30 183 38 38 171 4 4 219 148 148 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 237 203 203 172 6 6 170 0 0 98 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++21 0 0 160 0 0 170 0 0 200 91 91 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 241 213 213 179 27 27 170 0 0 172 6 6
++226 168 168 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 156 150 150 27 31 34 0 0 0 37 46 56 140 179 215 166 211 254 167 212 255
++165 209 252 71 90 109 0 0 0 4 5 6 87 87 87 243 242 242 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 251 251 251 173 173 173 14 13 13 0 0 0
++37 46 56 133 171 205 169 216 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++165 209 252 118 151 181 18 19 24 0 0 0 46 46 46 188 187 187 254 253 253 205 106 106
++170 0 0 170 0 0 198 84 84 254 251 251 255 255 255 255 255 255 210 122 122 170 1 1
++170 1 1 224 164 164 255 255 255 255 255 255 255 255 255 224 161 161 170 0 0 170 0 0
++170 0 0 227 171 171 239 206 206 175 16 16 170 0 0 206 110 110 254 252 252 255 255 255
++255 255 255 255 255 255 255 255 255 250 240 240 182 36 36 170 0 0 149 0 0 11 2 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 68 0 0 170 0 0 170 0 0 224 164 164 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 252 246 246 253 249 249 255 255 255 255 255 255 243 227 227 183 41 41 170 0 0
++170 1 1 218 144 144 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 188 187 187 37 34 34 1 1 1 18 19 24 126 161 193 165 210 253 167 212 255
++165 209 252 96 123 148 4 5 6 1 1 1 55 59 65 228 228 228 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 246 246 246 137 137 137 4 4 5 0 0 1
++55 70 84 151 192 230 169 215 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++157 201 242 90 112 135 2 3 4 1 1 1 70 80 89 218 218 218 198 84 84 170 0 0
++170 0 0 203 100 100 254 252 252 255 255 255 255 255 255 255 255 255 180 30 30 170 0 0
++215 135 135 255 255 255 255 255 255 255 255 255 241 213 213 172 7 7 170 0 0 170 0 0
++209 119 119 255 255 255 219 152 152 233 190 190 177 22 22 170 0 0 185 47 47 239 206 206
++255 255 255 255 255 255 255 255 255 199 87 87 170 0 0 167 0 0 32 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 110 0 0 170 0 0 173 12 12 242 216 216 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++252 246 246 177 22 22 175 16 16 219 148 148 255 254 254 255 255 255 249 238 238 189 59 59
++170 0 0 170 0 0 209 119 119 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 214 214 214 55 59 65 0 0 1 6 7 9 96 123 148 162 207 250 167 212 255
++166 211 254 118 151 181 13 16 19 0 0 0 46 46 46 206 206 206 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 251 251 251 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 239 239 239 113 113 113 0 0 0 4 5 6
++71 90 109 157 201 242 168 213 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++151 192 230 55 70 84 0 0 0 14 13 13 198 194 194 189 59 59 170 0 0 170 0 0
++209 119 119 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 218 144 144 211 125 125
++255 255 255 255 255 255 255 255 255 255 255 255 209 119 119 170 0 0 170 0 0 196 78 78
++254 253 253 255 255 255 254 251 251 208 114 114 215 135 135 180 30 30 170 0 0 210 122 122
++255 255 255 255 255 255 226 168 168 170 0 0 170 0 0 68 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 11 2 0 149 0 0 170 0 0 184 44 44 252 246 246 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++253 249 249 191 64 64 170 0 0 170 1 1 200 91 91 250 240 240 255 255 255 252 246 246
++196 78 78 170 0 0 170 0 0 199 87 87 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 241 241 241 97 97 97 9 6 4 0 0 1 71 90 109 157 201 242 167 212 255
++167 212 255 133 171 205 27 31 34 0 0 1 27 31 34 180 180 180 254 254 254 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 246 246 246 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 228 228 228 70 80 89 0 0 0 10 12 13
++90 112 135 165 210 253 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 165 209 252
++126 161 193 19 25 31 0 0 0 145 144 144 183 41 41 170 0 0 171 3 3 219 152 152
++255 255 255 255 255 255 255 255 255 245 224 224 248 233 233 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 234 194 194 196 78 78 191 64 64 251 244 244
++255 255 255 255 255 255 254 252 252 193 71 71 170 0 0 170 0 0 187 53 53 252 246 246
++255 255 255 243 227 227 175 16 16 170 0 0 120 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 2 1 0 32 0 0 167 0 0 170 0 0 202 97 97 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 253 248 248 197 81 81 170 0 0 172 5 5 185 47 47 243 227 227 255 255 255
++254 252 252 205 106 106 170 0 0 170 0 0 188 55 55 247 231 231 255 255 255 255 255 255
++255 255 255 253 253 253 137 137 137 19 19 19 0 0 0 45 57 69 140 179 215 167 212 255
++165 209 252 151 192 230 37 46 56 0 0 0 19 19 19 156 150 150 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 210 206 206 46 46 46 0 0 0 18 19 24
++109 140 168 169 215 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 157 201 242
++86 104 117 1 1 2 1 1 1 187 50 50 170 0 0 172 6 6 230 181 181 255 255 255
++255 255 255 248 236 236 200 91 91 170 0 0 175 16 16 242 216 216 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 206 110 110 170 0 0 170 0 0 179 27 27 247 231 231 255 255 255
++255 254 254 191 64 64 170 0 0 149 0 0 11 2 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 83 0 0 167 0 0 170 0 0 224 161 161
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 254 252 252 202 97 97 170 0 0 170 1 1 182 36 36 243 218 218
++255 255 255 255 255 255 217 141 141 171 2 2 170 0 0 179 27 27 235 197 197 255 255 255
++255 255 255 255 255 255 173 173 173 37 34 34 0 0 0 19 25 31 126 161 193 168 213 255
++167 212 255 154 196 236 55 70 84 1 1 2 10 12 13 127 127 127 250 248 248 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 251 251 251 173 173 173 14 13 13 0 0 0 33 37 45
++133 171 205 168 213 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 165 210 253 133 171 205
++33 37 45 228 174 174 183 38 38 170 1 1 171 3 3 228 174 174 255 255 255 255 255 255
++235 197 197 181 33 33 172 6 6 170 0 0 170 0 0 194 73 73 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 222 155 155 170 0 0 170 0 0 173 12 12 239 206 206 255 255 255 255 255 255
++216 138 138 170 0 0 170 0 0 55 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 120 0 0 170 0 0 173 8 8
++237 203 203 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 208 114 114 170 0 0 170 0 0 179 27 27
++239 209 209 255 255 255 255 255 255 228 174 174 175 14 14 170 0 0 172 5 5 218 144 144
++255 255 255 255 255 255 210 206 206 55 59 65 0 0 0 10 12 13 96 123 148 165 210 253
++167 212 255 161 204 245 86 104 117 0 0 0 4 5 6 87 87 87 236 236 236 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 246 246 246 113 113 113 0 0 0 2 3 4 55 70 84
++151 192 230 168 214 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 157 201 242 237 203 203
++188 55 55 170 0 0 170 0 0 171 2 2 224 161 161 255 255 255 255 255 255 222 158 158
++173 8 8 170 0 0 170 0 0 205 106 106 187 53 53 170 0 0 216 138 138 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++233 190 190 172 5 5 170 0 0 170 1 1 228 174 174 255 255 255 255 255 255 237 200 200
++172 6 6 170 0 0 98 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 11 2 0 138 0 0 170 0 0
++179 27 27 247 231 231 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 215 135 135 170 0 0 170 0 0
++181 33 33 241 213 213 255 255 255 255 255 255 242 216 216 184 44 44 170 0 0 170 0 0
++196 78 78 252 246 246 241 241 241 97 97 97 9 6 4 0 0 1 55 70 84 154 196 236
++167 212 255 165 209 252 109 140 168 2 3 4 1 1 1 55 59 65 210 206 206 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 254 254 254 228 228 228 91 72 72 0 0 0 10 12 13 86 104 117
++166 211 254 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 165 209 252 218 144 144 172 6 6
++170 0 0 170 0 0 197 81 81 241 213 213 255 255 255 254 252 252 208 114 114 171 4 4
++170 0 0 172 7 7 222 158 158 235 197 197 232 187 187 175 16 16 171 3 3 232 187 187
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 248 233 233
++177 22 22 170 0 0 170 0 0 215 135 135 255 255 255 255 255 255 239 206 206 175 16 16
++170 0 0 149 0 0 5 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 1 0 21 0 0 160 0 0
++170 0 0 191 64 64 255 254 254 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 254 253 253
++194 73 73 208 114 114 248 236 236 255 255 255 255 255 255 255 255 255 222 155 155 171 2 2
++170 0 0 185 47 47 255 255 255 255 255 255 255 255 255 251 244 244 200 91 91 170 0 0
++170 0 0 180 30 30 229 177 177 156 150 150 19 19 19 1 1 1 19 25 31 118 151 181
++166 211 254 166 211 254 126 161 193 19 25 31 2 1 0 27 31 34 173 173 173 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 253 253 253 253 253 253 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 254 254 254 198 194 194 19 25 31 0 0 0 19 25 31 109 140 168
++172 216 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 168 214 255 204 219 242 197 81 81 170 0 0 170 0 0
++187 50 50 237 200 200 255 255 255 255 255 255 253 249 249 202 97 97 172 5 5 170 0 0
++179 27 27 237 203 203 255 255 255 253 249 249 203 100 100 226 168 168 172 5 5 176 19 19
++243 221 221 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 203 100 100
++170 0 0 170 0 0 201 95 95 255 255 255 255 255 255 243 218 218 176 19 19 170 0 0
++149 0 0 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 55 0 0
++170 0 0 170 0 0 216 138 138 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 231 184 184
++170 1 1 170 0 0 182 36 36 243 218 218 255 255 255 239 209 209 233 190 190 202 97 97
++170 0 0 173 12 12 253 249 249 255 255 255 255 255 255 255 255 255 255 255 255 224 164 164
++175 14 14 170 0 0 170 0 0 191 64 64 239 206 206 4 4 5 1 1 2 71 90 109
++157 201 242 167 212 255 140 179 215 45 57 69 0 0 0 19 19 19 137 137 137 253 253 253
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 246 246 246 137 137 137 0 0 0 1 1 1 37 46 56 140 179 215
++172 216 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 167 212 255 167 212 255 230 181 181 178 25 25 170 0 0 170 0 0 204 103 103
++252 246 246 255 255 255 255 255 255 255 255 255 201 95 95 170 0 0 170 0 0 191 64 64
++248 233 233 255 255 255 255 255 255 255 255 255 226 168 168 183 41 41 198 84 84 170 0 0
++183 41 41 250 240 240 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 187 50 50
++170 0 0 189 59 59 253 249 249 255 255 255 249 238 238 183 38 38 170 0 0 160 0 0
++21 0 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++98 0 0 170 0 0 170 0 0 215 135 135 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 250 240 240 249 238 238 255 255 255 255 255 255 255 255 255 255 255 255 239 206 206
++175 14 14 170 0 0 170 0 0 176 19 19 224 161 161 205 106 106 218 144 144 170 0 0
++173 12 12 226 168 168 255 255 255 243 227 227 205 106 106 239 206 206 255 255 255 255 255 255
++243 221 221 196 78 78 170 0 0 170 0 0 170 1 1 200 91 91 247 231 231 19 25 31
++118 151 181 166 211 254 154 196 236 71 90 109 0 0 0 6 7 9 105 100 100 239 239 239
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 226 226 226 91 72 72 0 0 0 6 7 9 71 90 109 161 204 245
++168 214 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255
++167 212 255 239 206 206 197 81 81 170 0 0 170 0 0 175 16 16 224 164 164 255 255 255
++255 255 255 255 255 255 255 255 255 234 194 194 170 0 0 170 0 0 206 110 110 254 251 251
++255 255 255 255 255 255 255 255 255 226 168 168 173 8 8 170 0 0 170 0 0 185 47 47
++171 4 4 193 71 71 254 251 251 255 255 255 255 255 255 255 255 255 255 255 255 230 181 181
++194 73 73 248 236 236 255 255 255 253 249 249 191 64 64 170 0 0 160 0 0 43 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++5 2 0 120 0 0 170 0 0 170 0 0 210 122 122 255 255 255 255 255 255 255 255 255
++241 213 213 176 19 19 170 0 0 204 103 103 252 246 246 255 255 255 255 255 255 255 255 255
++239 209 209 179 27 27 170 0 0 170 0 0 179 27 27 224 161 161 171 2 2 175 14 14
++237 203 203 255 255 255 255 255 255 219 152 152 170 0 0 182 36 36 255 255 255 255 255 255
++255 255 255 255 255 255 233 190 190 187 50 50 170 0 0 170 0 0 175 14 14 216 138 138
++55 70 84 140 179 215 162 207 250 96 123 148 1 1 2 0 0 0 55 59 65 214 214 214
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 254 254 254 188 187 187 18 19 24 0 0 0 18 19 24 109 140 168 167 212 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 239 206 206
++196 78 78 170 0 0 170 0 0 170 0 0 193 71 71 243 227 227 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 243 218 218 183 38 38 224 161 161 255 255 255 255 255 255
++255 255 255 255 255 255 217 141 141 170 1 1 170 0 0 170 0 0 185 47 47 249 238 238
++200 91 91 170 0 0 205 106 106 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 254 254 201 95 95 170 0 0 170 0 0 55 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 5 2 0 110 0 0 170 0 0 170 0 0 210 122 122 255 255 255 255 255 255
++241 213 213 175 16 16 170 0 0 170 0 0 187 50 50 243 227 227 255 255 255 255 255 255
++255 255 255 243 227 227 184 44 44 170 0 0 188 55 55 175 16 16 172 6 6 232 187 187
++255 255 255 255 255 255 255 255 255 231 184 184 170 0 0 187 53 53 239 206 206 255 255 255
++255 255 255 255 255 255 255 255 255 254 253 253 222 155 155 177 22 22 170 0 0 170 0 0
++177 22 22 217 141 141 157 201 242 126 161 193 19 25 31 0 0 0 37 34 34 173 173 173
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 243 242 242 113 113 113 0 0 0 2 3 4 37 46 56 140 179 215 169 215 255
++167 212 255 167 212 255 167 212 255 167 212 255 167 212 255 243 227 227 201 95 95 170 1 1
++170 0 0 170 0 0 187 50 50 228 174 174 255 254 254 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 243 218 218 171 3 3 170 0 0 170 0 0 196 78 78 251 242 242 237 200 200
++235 197 197 179 27 27 170 0 0 218 144 144 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 254 254 204 103 103 170 0 0 170 0 0 83 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 2 1 0 110 0 0 170 0 0 170 0 0 211 125 125 255 255 255
++255 255 255 241 213 213 180 30 30 170 0 0 170 0 0 179 27 27 239 209 209 255 255 255
++255 255 255 255 255 255 249 238 238 205 106 106 170 0 0 171 3 3 226 168 168 255 255 255
++255 255 255 255 255 255 255 255 255 243 227 227 170 0 0 191 64 64 222 155 155 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 250 240 240 206 110 110 172 6 6
++170 0 0 170 0 0 176 19 19 215 135 135 45 57 69 0 0 0 14 13 13 127 127 127
++251 251 251 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 210 206 206 46 46 46 2 2 2 6 7 9 86 104 117 162 207 250 167 212 255
++167 212 255 167 212 255 167 212 255 204 219 242 210 122 122 173 10 10 170 0 0 170 0 0
++187 50 50 230 181 181 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 243 218 218 182 36 36 170 0 0 206 110 110 254 253 253 255 255 255 255 255 255
++219 152 152 224 164 164 178 25 25 170 0 0 212 128 128 255 255 255 255 255 255 255 255 255
++255 255 255 206 110 110 170 0 0 170 0 0 98 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 5 2 0 110 0 0 170 0 0 170 0 0 209 119 119
++255 254 254 255 254 254 247 231 231 185 47 47 170 0 0 170 0 0 175 14 14 232 187 187
++255 255 255 228 174 174 234 194 194 194 73 73 170 0 0 222 155 155 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 175 14 14 185 47 47 219 152 152 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 243 227 227
++206 110 110 173 8 8 170 0 0 170 0 0 175 16 16 211 125 125 247 231 231 87 87 87
++228 228 228 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++251 251 251 145 144 144 10 12 13 1 1 1 19 25 31 126 161 193 169 215 255 167 212 255
++167 212 255 247 231 231 211 125 125 175 14 14 170 0 0 170 0 0 177 22 22 222 155 155
++254 253 253 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 253 249 249 239 206 206 255 255 255 255 255 255 255 255 255 255 255 255
++216 138 138 175 14 14 183 41 41 170 0 0 196 78 78 255 255 255 255 255 255 255 255 255
++210 122 122 170 0 0 170 0 0 98 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 5 2 0 110 0 0 170 0 0 170 0 0
++201 95 95 254 251 251 255 255 255 251 242 242 193 71 71 170 0 0 170 0 0 172 5 5
++197 81 81 231 184 184 184 44 44 170 0 0 210 122 122 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 243 227 227 252 246 246 187 53 53 176 19 19 222 158 158 255 255 255
++255 255 255 255 255 255 255 255 255 241 213 213 202 97 97 237 203 203 255 255 255 255 255 255
++255 255 255 248 233 233 209 119 119 175 14 14 170 0 0 170 0 0 172 6 6 202 97 97
++237 203 203 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++218 218 218 55 59 65 2 1 0 2 3 4 70 80 89 154 196 236 168 214 255 229 177 177
++196 78 78 171 3 3 170 0 0 170 0 0 175 16 16 215 135 135 251 242 242 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 254 254 210 122 122
++170 0 0 170 0 0 170 0 0 200 91 91 253 248 248 255 255 255 255 255 255 212 128 128
++170 0 0 170 0 0 110 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 1 0 98 0 0 170 0 0
++170 0 0 196 78 78 253 249 249 255 255 255 253 249 249 202 97 97 170 0 0 170 0 0
++198 84 84 193 71 71 170 0 0 200 91 91 255 255 255 255 255 255 255 255 255 255 255 255
++254 253 253 204 103 103 176 19 19 205 106 106 197 81 81 170 0 0 196 78 78 255 255 255
++255 255 255 255 255 255 255 255 255 188 55 55 170 0 0 204 103 103 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 249 238 238 212 128 128 177 22 22 170 0 0 170 0 0
++170 0 0 182 36 36 209 119 119 237 203 203 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++145 144 144 14 13 13 0 0 0 18 19 24 231 184 184 202 97 97 175 16 16 170 0 0
++170 0 0 170 0 0 176 19 19 211 125 125 250 240 240 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 252 246 246 197 81 81 170 0 0
++170 0 0 170 0 0 212 128 128 255 255 255 255 255 255 255 255 255 215 135 135 170 0 0
++170 0 0 110 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 83 0 0
++170 0 0 170 0 0 196 78 78 253 249 249 255 255 255 255 255 255 211 125 125 170 0 0
++173 8 8 170 0 0 189 59 59 253 248 248 255 255 255 255 255 255 255 255 255 251 244 244
++194 73 73 170 0 0 170 0 0 170 0 0 170 0 0 170 1 1 209 119 119 235 197 197
++255 255 255 255 255 255 237 200 200 170 0 0 170 0 0 232 187 187 255 255 255 226 168 168
++197 81 81 243 218 218 255 255 255 255 255 255 255 255 255 253 248 248 222 158 158 184 44 44
++170 0 0 170 0 0 170 0 0 170 0 0 180 30 30 208 114 114 235 197 197 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 214 214 214
++55 59 65 237 200 200 206 110 110 177 22 22 170 0 0 170 0 0 170 0 0 171 4 4
++193 71 71 226 168 168 253 248 248 255 255 255 255 255 255 243 221 221 212 128 128 196 78 78
++201 95 95 226 168 168 252 246 246 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 248 236 236 188 55 55 170 0 0 170 0 0
++172 7 7 226 168 168 255 255 255 255 255 255 251 244 244 201 95 95 170 0 0 170 0 0
++110 0 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 2 0
++68 0 0 170 0 0 170 0 0 196 78 78 253 249 249 255 255 255 255 255 255 222 155 155
++171 4 4 175 14 14 247 231 231 255 255 255 255 255 255 255 255 255 255 255 255 198 84 84
++170 0 0 196 78 78 224 164 164 228 174 174 187 50 50 170 0 0 172 6 6 170 1 1
++196 78 78 212 128 128 185 47 47 170 0 0 217 141 141 255 255 255 255 255 255 199 87 87
++170 0 0 204 103 103 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++239 209 209 210 122 122 182 36 36 170 0 0 170 0 0 170 0 0 170 0 0 180 30 30
++208 114 114 232 187 187 247 231 231 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 241 213 213 224 164 164 200 91 91
++177 22 22 170 0 0 170 0 0 170 0 0 171 2 2 191 64 64 219 152 152 248 236 236
++255 255 255 255 255 255 255 255 255 249 238 238 203 100 100 171 3 3 170 0 0 170 0 0
++170 0 0 175 16 16 191 64 64 254 252 252 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 249 238 238 184 44 44 170 0 0 170 0 0 177 22 22
++235 197 197 255 255 255 255 254 254 241 213 213 183 41 41 170 0 0 170 0 0 110 0 0
++2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 83 0 0 167 0 0 170 0 0 196 78 78 251 242 242 255 255 255 255 255 255
++234 194 194 235 197 197 255 255 255 255 255 255 255 255 255 255 255 255 245 224 224 170 1 1
++189 59 59 255 254 254 255 255 255 252 246 246 254 252 252 219 148 148 175 14 14 170 0 0
++170 0 0 212 128 128 170 1 1 197 81 81 255 255 255 255 255 255 255 255 255 209 119 119
++170 0 0 196 78 78 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 239 209 209 211 125 125 184 44 44 170 0 0 170 0 0
++170 0 0 170 0 0 170 0 0 176 19 19 191 64 64 208 114 114 224 164 164 241 213 213
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++237 203 203 219 152 152 202 97 97 185 47 47 172 7 7 170 0 0 170 0 0 170 0 0
++170 0 0 170 0 0 184 44 44 215 135 135 243 227 227 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 247 231 231 215 135 135 170 1 1 170 0 0 170 0 0 182 36 36
++172 7 7 170 0 0 170 0 0 210 122 122 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 208 114 114 170 0 0 170 0 0 184 44 44 245 224 224
++255 255 255 255 255 255 224 164 164 173 8 8 170 0 0 167 0 0 68 0 0 2 1 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 68 0 0 170 0 0 170 0 0 183 41 41 242 216 216 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 224 161 161 170 0 0
++184 44 44 255 254 254 255 255 255 255 255 255 255 255 255 255 254 254 247 231 231 199 87 87
++170 0 0 172 5 5 177 22 22 248 236 236 255 255 255 255 255 255 255 255 255 228 174 174
++170 0 0 184 44 44 211 125 125 243 227 227 255 255 255 255 255 255 255 255 255 254 253 253
++242 216 216 253 249 249 255 255 255 255 255 255 255 255 255 255 255 255 242 216 216 215 135 135
++187 50 50 171 3 3 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0
++170 1 1 179 27 27 189 59 59 200 91 91 209 119 119 218 144 144 226 168 168 233 190 190
++241 213 213 249 238 238 255 255 255 243 221 221 237 200 200 231 184 184 226 168 168 219 152 152
++215 135 135 210 122 122 206 110 110 203 100 100 201 95 95 194 73 73 180 30 30 170 1 1
++170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 176 19 19 196 78 78
++219 152 152 245 224 224 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 222 155 155 173 10 10 170 0 0 204 103 103 245 224 224 255 255 255
++251 244 244 222 155 155 177 22 22 219 148 148 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 206 110 110 170 0 0 193 71 71 250 240 240 255 255 255
++255 255 255 215 135 135 170 1 1 170 0 0 149 0 0 32 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 2 1 0 68 0 0 167 0 0 170 0 0 175 14 14 227 171 171
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 224 161 161 170 0 0
++172 7 7 237 200 200 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++204 103 103 170 0 0 224 161 161 255 255 255 255 255 255 255 255 255 255 255 255 242 216 216
++170 0 0 173 8 8 172 6 6 176 19 19 197 81 81 230 181 181 231 184 184 230 181 181
++170 0 0 193 71 71 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 252 246 246 239 206 206 224 161 161 208 114 114 191 64 64 176 19 19 170 0 0
++170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0
++170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0
++170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0
++170 0 0 179 27 27 198 84 84 216 138 138 231 184 184 247 231 231 255 254 254 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 254 254 196 78 78 170 0 0 216 138 138 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 248 236 236 224 161 161 254 252 252 255 255 255 254 253 253
++205 106 106 170 0 0 170 0 0 128 0 0 5 2 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 32 0 0 149 0 0 170 0 0 170 0 0
++205 106 106 253 248 248 255 255 255 255 255 255 255 255 255 255 255 255 247 231 231 171 2 2
++170 0 0 175 14 14 219 148 148 254 252 252 255 255 255 255 255 255 255 255 255 231 184 184
++171 3 3 191 64 64 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 237 200 200
++170 0 0 197 81 81 170 1 1 170 0 0 176 19 19 172 6 6 212 128 128 182 36 36
++170 0 0 189 59 59 255 255 255 255 255 255 235 197 197 196 78 78 227 171 171 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 247 231 231
++234 194 194 222 155 155 210 122 122 202 97 97 194 73 73 187 50 50 178 25 25 171 3 3
++170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 172 5 5 177 22 22 183 38 38
++188 55 55 191 64 64 197 81 81 200 91 91 204 103 103 208 114 114 219 152 152 234 194 194
++248 236 236 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 243 227 227
++222 155 155 197 81 81 176 19 19 173 8 8 199 87 87 234 194 194 255 255 255 255 255 255
++255 255 255 255 254 254 173 12 12 180 30 30 253 249 249 255 255 255 255 255 255 255 254 254
++243 218 218 230 181 181 219 152 152 226 168 168 247 231 231 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 243 221 221 191 64 64
++170 0 0 170 0 0 110 0 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 11 2 0 128 0 0 170 0 0
++170 0 0 187 50 50 243 221 221 255 255 255 255 255 255 255 255 255 255 255 255 211 125 125
++170 0 0 170 0 0 170 0 0 187 50 50 237 200 200 255 255 255 252 246 246 181 33 33
++172 5 5 241 213 213 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 222 158 158
++170 0 0 250 240 240 242 216 216 206 110 110 175 16 16 170 0 0 177 22 22 170 0 0
++181 33 33 243 218 218 255 255 255 255 255 255 193 71 71 170 0 0 176 19 19 248 233 233
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 254 253 253
++247 231 231 241 213 213 239 206 206 245 224 224 251 242 242 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 224 164 164 178 25 25
++172 5 5 170 0 0 170 0 0 170 0 0 170 0 0 187 50 50 219 152 152 255 255 255
++255 255 255 255 255 255 183 41 41 187 53 53 229 177 177 218 144 144 200 91 91 176 19 19
++175 14 14 175 14 14 170 0 0 170 0 0 180 30 30 248 236 236 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 254 254 219 152 152 173 12 12 170 0 0
++170 0 0 98 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 83 0 0
++167 0 0 170 0 0 175 16 16 228 174 174 255 255 255 255 255 255 255 255 255 255 255 255
++224 164 164 177 22 22 170 0 0 170 0 0 170 0 0 193 71 71 204 103 103 170 0 0
++209 119 119 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 209 119 119
++170 0 0 233 190 190 255 255 255 253 249 249 252 246 246 205 106 106 170 0 0 189 59 59
++248 233 233 255 255 255 255 255 255 255 255 255 182 36 36 170 0 0 191 64 64 219 148 148
++255 255 255 255 255 255 255 255 255 255 255 255 224 164 164 185 47 47 231 184 184 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++219 148 148 222 155 155 255 255 255 255 255 255 255 255 255 232 187 187 184 44 44 171 4 4
++171 2 2 197 81 81 218 144 144 212 128 128 182 36 36 170 0 0 177 22 22 232 187 187
++255 255 255 255 255 255 247 231 231 175 16 16 184 44 44 187 53 53 170 0 0 170 0 0
++170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 201 95 95 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 243 227 227 193 71 71 170 0 0 170 0 0 149 0 0
++55 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++43 0 0 149 0 0 170 0 0 170 0 0 202 97 97 251 242 242 255 255 255 255 255 255
++255 255 255 249 238 238 204 103 103 170 1 1 170 0 0 191 64 64 173 12 12 179 27 27
++251 244 244 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 203 100 100
++170 0 0 209 119 119 247 231 231 212 128 128 215 135 135 172 5 5 191 64 64 252 246 246
++255 255 255 255 255 255 255 255 255 254 252 252 172 7 7 170 0 0 177 22 22 208 114 114
++255 255 255 255 255 255 254 251 251 219 152 152 183 41 41 170 0 0 194 73 73 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 219 148 148 201 95 95
++254 253 253 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 248 233 233
++170 0 0 170 0 0 243 218 218 255 255 255 255 254 254 216 138 138 173 12 12 173 8 8
++231 184 184 255 255 255 255 255 255 255 255 255 252 246 246 199 87 87 170 0 0 191 64 64
++255 255 255 255 255 255 255 255 255 222 155 155 175 14 14 170 0 0 170 1 1 183 41 41
++202 97 97 222 155 155 230 181 181 217 141 141 172 6 6 171 4 4 245 224 224 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 226 168 168 175 16 16 170 0 0 170 0 0 110 0 0 11 2 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 21 0 0 120 0 0 170 0 0 170 0 0 181 33 33 234 194 194 255 255 255
++255 255 255 255 255 255 255 255 255 237 200 200 185 47 47 170 0 0 170 0 0 224 161 161
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 198 84 84
++170 0 0 173 8 8 208 114 114 215 135 135 170 0 0 185 47 47 250 240 240 255 255 255
++255 255 255 255 255 255 255 255 255 226 168 168 177 22 22 206 110 110 170 0 0 204 103 103
++237 200 200 254 252 252 218 144 144 201 95 95 170 0 0 170 0 0 215 135 135 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 176 19 19 170 0 0
++243 221 221 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++187 50 50 170 0 0 227 171 171 255 255 255 249 238 238 211 125 125 170 0 0 215 135 135
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 254 251 251 183 41 41 172 7 7
++251 242 242 255 255 255 255 255 255 255 255 255 251 242 242 245 224 224 251 242 242 255 255 255
++255 255 255 255 255 255 255 255 255 235 197 197 199 87 87 170 0 0 231 184 184 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++249 238 238 200 91 91 170 0 0 170 0 0 160 0 0 55 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 68 0 0 160 0 0 170 0 0 170 1 1 206 110 110
++251 244 244 255 255 255 255 255 255 255 255 255 254 252 252 217 141 141 197 81 81 254 251 251
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 200 91 91
++170 0 0 189 59 59 219 152 152 170 0 0 180 30 30 243 227 227 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 183 38 38 191 64 64 243 218 218 170 0 0 194 73 73
++191 64 64 208 114 114 198 84 84 170 0 0 171 2 2 170 0 0 241 213 213 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 171 2 2 178 25 25
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++202 97 97 170 0 0 228 174 174 255 255 255 255 255 255 203 100 100 173 8 8 251 242 242
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 209 119 119 170 0 0
++229 177 177 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 254 254 196 78 78 175 16 16 175 14 14 251 242 242 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 235 197 197
++180 30 30 170 0 0 170 0 0 120 0 0 11 2 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 32 0 0 128 0 0 170 0 0 170 0 0
++179 27 27 226 168 168 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 205 106 106
++171 3 3 232 187 187 172 5 5 179 27 27 242 216 216 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 237 203 203 170 0 0 200 91 91 255 255 255 177 22 22 170 1 1
++193 71 71 177 22 22 170 0 0 204 103 103 200 91 91 170 0 0 249 238 238 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 252 246 246 170 0 0 188 55 55
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++217 141 141 170 0 0 228 174 174 255 255 255 255 255 255 196 78 78 171 3 3 251 242 242
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 233 190 190 170 0 0
++204 103 103 255 255 255 255 255 255 255 255 255 241 213 213 173 12 12 200 91 91 241 213 213
++255 255 255 247 231 231 201 95 95 170 0 0 170 0 0 206 110 110 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 254 254 215 135 135 171 3 3
++170 0 0 160 0 0 68 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 1 0 83 0 0 160 0 0
++170 0 0 170 0 0 189 59 59 234 194 194 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 209 119 119
++170 0 0 170 0 0 181 33 33 243 221 221 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 212 128 128 170 0 0 219 148 148 255 255 255 201 95 95 170 1 1
++203 100 100 170 0 0 188 55 55 253 249 249 184 44 44 175 14 14 255 254 254 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 248 233 233 170 0 0 193 71 71
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 254 252 252 227 171 171
++229 177 177 170 0 0 224 164 164 255 255 255 255 255 255 209 119 119 170 0 0 229 177 177
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 251 242 242 173 12 12
++181 33 33 255 255 255 255 255 255 255 255 255 219 148 148 170 0 0 173 8 8 203 100 100
++191 64 64 171 4 4 170 0 0 170 0 0 178 25 25 243 221 221 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 242 216 216 191 64 64 170 0 0 170 0 0
++138 0 0 32 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 21 0 0
++120 0 0 170 0 0 170 0 0 170 0 0 196 78 78 241 213 213 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 205 106 106
++170 0 0 183 38 38 243 227 227 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 189 59 59 173 8 8 247 231 231 255 255 255 232 187 187 170 0 0
++170 0 0 189 59 59 245 224 224 231 184 184 171 3 3 188 55 55 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 245 224 224 170 0 0 198 84 84
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 235 197 197 203 100 100 196 78 78 173 12 12 170 0 0
++219 148 148 170 0 0 219 152 152 255 255 255 255 255 255 230 181 181 170 0 0 177 22 22
++248 233 233 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 228 174 174 193 71 71
++170 0 0 243 218 218 255 255 255 255 255 255 243 227 227 182 36 36 170 0 0 170 0 0
++170 0 0 170 0 0 170 0 0 187 53 53 243 227 227 255 255 255 255 255 255 255 255 255
++255 255 255 254 253 253 230 181 181 197 81 81 172 5 5 170 0 0 170 0 0 98 0 0
++5 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 43 0 0 128 0 0 170 0 0 170 0 0 171 2 2 203 100 100 247 231 231
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 193 71 71
++182 36 36 247 231 231 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 250 240 240 171 2 2 204 103 103 247 231 231 255 255 255 248 236 236 170 1 1
++179 27 27 249 238 238 254 251 251 219 148 148 170 0 0 204 103 103 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 242 216 216 170 0 0 202 97 97
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 254 252 252 173 8 8 170 0 0 171 2 2 170 0 0 170 0 0
++170 0 0 170 0 0 211 125 125 255 255 255 255 255 255 251 244 244 172 6 6 183 41 41
++224 164 164 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 215 135 135 193 71 71
++171 3 3 248 233 233 255 255 255 255 255 255 255 255 255 253 249 249 227 171 171 208 114 114
++201 95 95 202 97 97 217 141 141 252 246 246 255 255 255 255 255 255 255 255 255 255 255 255
++233 190 190 185 47 47 170 0 0 170 0 0 170 0 0 138 0 0 43 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 55 0 0 138 0 0 170 0 0 170 0 0 173 12 12
++209 119 119 248 233 233 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 252 246 246
++250 240 240 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 224 164 164 170 0 0 216 138 138 242 216 216 255 255 255 255 255 255 237 200 200
++247 231 231 255 255 255 255 255 255 219 148 148 170 0 0 219 152 152 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 239 209 209 170 0 0 206 110 110
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 252 246 246 181 33 33 173 8 8 185 47 47 199 87 87 211 125 125
++226 168 168 176 19 19 203 100 100 255 255 255 255 255 255 255 255 255 193 71 71 170 0 0
++201 95 95 251 242 242 255 255 255 255 255 255 255 255 255 243 227 227 199 87 87 172 7 7
++197 81 81 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 242 216 216 197 81 81
++170 0 0 170 0 0 167 0 0 128 0 0 55 0 0 5 2 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 5 2 0 68 0 0 160 0 0 170 0 0
++170 0 0 172 7 7 203 100 100 241 213 213 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 187 53 53 170 0 0 218 144 144 253 248 248 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 209 119 119 170 0 0 237 200 200 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 237 203 203 170 0 0 211 125 125
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 253 249 249 254 253 253 255 255 255 255 255 255 255 255 255
++255 255 255 179 27 27 187 50 50 255 255 255 255 255 255 255 255 255 224 164 164 170 0 0
++172 5 5 185 47 47 231 184 184 234 194 194 219 148 148 177 22 22 172 7 7 170 0 0
++232 187 187 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 254 254 231 184 184 194 73 73 171 2 2 170 0 0
++170 0 0 128 0 0 43 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 2 0 83 0 0
++160 0 0 170 0 0 170 0 0 170 0 0 193 71 71 231 184 184 255 254 254 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++241 213 213 170 0 0 179 27 27 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 196 78 78 170 0 0 252 246 246 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 234 194 194 170 0 0 216 138 138
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 178 25 25 173 8 8 255 255 255 255 255 255 255 255 255 255 254 254 194 73 73
++170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 191 64 64
++255 254 254 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 248 236 236 218 144 144 183 41 41 170 0 0 170 0 0 170 0 0 149 0 0
++55 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++5 2 0 68 0 0 138 0 0 170 0 0 170 0 0 170 0 0 183 41 41 219 152 152
++252 246 246 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++248 236 236 188 55 55 212 128 128 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 181 33 33 172 5 5 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 230 181 181 170 0 0 219 152 152
++253 248 248 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++237 200 200 180 30 30 170 0 0 248 233 233 255 255 255 255 255 255 255 255 255 253 248 248
++206 110 110 172 5 5 170 0 0 170 0 0 170 0 0 175 14 14 208 114 114 253 248 248
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 254 253 253 229 177 177
++197 81 81 172 6 6 170 0 0 170 0 0 170 0 0 128 0 0 55 0 0 2 1 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 2 1 0 43 0 0 120 0 0 170 0 0 170 0 0 170 0 0
++176 19 19 208 114 114 241 213 213 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 248 236 236 170 0 0 170 0 0 254 252 252 255 255 255 255 255 255
++255 255 255 251 242 242 232 187 187 227 171 171 226 168 168 224 161 161 170 0 0 216 138 138
++235 197 197 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 252 246 246 241 213 213 228 174 174 216 138 138 203 100 100 191 64 64 178 25 25
++188 55 55 196 78 78 170 0 0 239 206 206 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 247 231 231 219 152 152 210 122 122 226 168 168 251 242 242 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 250 240 240 217 141 141 181 33 33 170 0 0
++170 0 0 170 0 0 160 0 0 98 0 0 32 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 32 0 0 110 0 0 160 0 0
++170 0 0 170 0 0 170 0 0 187 53 53 215 135 135 234 194 194 252 246 246 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 247 231 231 172 5 5 176 19 19 255 255 255 255 255 255 255 255 255
++247 231 231 175 16 16 175 14 14 176 19 19 170 0 0 216 138 138 170 0 0 215 135 135
++170 0 0 175 14 14 181 33 33 224 161 161 255 255 255 255 255 255 255 255 255 252 246 246
++187 50 50 170 1 1 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0
++170 0 0 170 0 0 170 0 0 206 110 110 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 254 251 251 232 187 187 204 103 103 173 12 12 170 0 0 170 0 0 170 0 0
++120 0 0 55 0 0 5 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 11 2 0
++83 0 0 138 0 0 170 0 0 170 0 0 170 0 0 170 0 0 173 10 10 196 78 78
++222 155 155 248 236 236 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 247 231 231 245 224 224 255 255 255 255 255 255 255 255 255
++234 194 194 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0
++170 0 0 170 0 0 170 0 0 170 1 1 250 240 240 255 255 255 255 255 255 245 224 224
++170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 171 3 3 181 33 33
++191 64 64 204 103 103 216 138 138 248 233 233 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 250 240 240 229 177 177
++202 97 97 176 19 19 170 0 0 170 0 0 170 0 0 160 0 0 98 0 0 21 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 32 0 0 98 0 0 149 0 0 167 0 0 170 0 0 170 0 0
++170 0 0 171 3 3 191 64 64 219 152 152 247 231 231 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 243 221 221 237 203 203 235 197 197 233 190 190 232 187 187 229 177 177 219 152 152
++211 125 125 202 97 97 193 71 71 197 81 81 252 246 246 255 255 255 255 255 255 254 253 253
++208 114 114 209 119 119 219 148 148 222 158 158 233 190 190 243 221 221 254 251 251 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 254 252 252 242 216 216 228 174 174 209 119 119 187 53 53 171 3 3 170 0 0
++170 0 0 170 0 0 170 0 0 128 0 0 68 0 0 11 2 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 2 1 0 0 0 0 0 0 0 11 2 0 55 0 0 110 0 0
++160 0 0 170 0 0 170 0 0 170 0 0 171 2 2 191 64 64 206 110 110 215 135 135
++228 174 174 245 224 224 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 243 218 218 219 152 152 199 87 87
++184 44 44 172 7 7 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 167 0 0
++128 0 0 68 0 0 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++5 2 0 55 0 0 110 0 0 160 0 0 170 0 0 170 0 0 170 0 0 170 0 0
++170 0 0 170 0 0 177 22 22 193 71 71 208 114 114 219 152 152 233 190 190 243 227 227
++251 244 244 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
++250 240 240 228 174 174 212 128 128 200 91 91 180 30 30 170 0 0 170 0 0 170 0 0
++170 0 0 170 0 0 170 0 0 167 0 0 138 0 0 83 0 0 55 0 0 2 1 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 2 1 0 55 0 0 98 0 0 110 0 0 138 0 0
++167 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0
++170 0 0 172 6 6 177 22 22 183 41 41 191 64 64 200 91 91 209 119 119 218 144 144
++222 155 155 224 161 161 226 168 168 228 174 174 228 174 174 226 168 168 224 164 164 224 161 161
++219 148 148 215 135 135 208 114 114 201 95 95 196 78 78 193 71 71 191 64 64 188 55 55
++171 4 4 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 160 0 0 120 0 0
++68 0 0 55 0 0 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++2 1 0 32 0 0 68 0 0 98 0 0 128 0 0 149 0 0 170 0 0 170 0 0
++170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0
++170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0
++170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0 170 0 0
++170 0 0 167 0 0 128 0 0 110 0 0 83 0 0 32 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 2 0 21 0 0
++43 0 0 43 0 0 68 0 0 68 0 0 83 0 0 110 0 0 128 0 0 138 0 0
++149 0 0 149 0 0 160 0 0 160 0 0 160 0 0 160 0 0 149 0 0 149 0 0
++149 0 0 128 0 0 120 0 0 110 0 0 98 0 0 83 0 0 83 0 0 83 0 0
++55 0 0 5 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++
+Index: drivers/video/logo/Makefile
+===================================================================
+--- drivers/video/logo/Makefile.orig 2009-12-03 01:51:21.000000000 -0200
++++ drivers/video/logo/Makefile 2009-12-12 16:43:54.000000000 -0200
+@@ -7,6 +7,7 @@ obj-$(CONFIG_LOGO_LINUX_CLUT224) += logo
+ obj-$(CONFIG_LOGO_BLACKFIN_CLUT224) += logo_blackfin_clut224.o
+ obj-$(CONFIG_LOGO_BLACKFIN_VGA16) += logo_blackfin_vga16.o
+ obj-$(CONFIG_LOGO_DEC_CLUT224) += logo_dec_clut224.o
++obj-$(CONFIG_LOGO_LIBRE_CLUT224) += logo_libre_clut224.o
+ obj-$(CONFIG_LOGO_MAC_CLUT224) += logo_mac_clut224.o
+ obj-$(CONFIG_LOGO_PARISC_CLUT224) += logo_parisc_clut224.o
+ obj-$(CONFIG_LOGO_SGI_CLUT224) += logo_sgi_clut224.o
+Index: include/linux/linux_logo.h
+===================================================================
+--- include/linux/linux_logo.h.orig 2009-12-12 16:45:55.000000000 -0200
++++ include/linux/linux_logo.h 2009-12-12 16:46:32.000000000 -0200
+@@ -38,6 +38,7 @@ extern const struct linux_logo logo_linu
+ extern const struct linux_logo logo_blackfin_vga16;
+ extern const struct linux_logo logo_blackfin_clut224;
+ extern const struct linux_logo logo_dec_clut224;
++extern const struct linux_logo logo_libre_clut224;
+ extern const struct linux_logo logo_mac_clut224;
+ extern const struct linux_logo logo_parisc_clut224;
+ extern const struct linux_logo logo_sgi_clut224;
diff --git a/lemote/gnewsense/tags/2.6.32-libre-lemote_0lxo/lxo-config.patch b/lemote/gnewsense/tags/2.6.32-libre-lemote_0lxo/lxo-config.patch
new file mode 100644
index 000000000..ba9ab3643
--- /dev/null
+++ b/lemote/gnewsense/tags/2.6.32-libre-lemote_0lxo/lxo-config.patch
@@ -0,0 +1,2236 @@
+Index: .config
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ .config 2009-12-13 01:22:30.000000000 -0200
+@@ -0,0 +1,2218 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.32-libre-lemote
++# Sun Dec 13 01:22:30 2009
++#
++CONFIG_MIPS=y
++
++#
++# Machine selection
++#
++# CONFIG_MACH_ALCHEMY is not set
++# CONFIG_AR7 is not set
++# CONFIG_BASLER_EXCITE is not set
++# CONFIG_BCM47XX is not set
++# CONFIG_BCM63XX is not set
++# CONFIG_MIPS_COBALT is not set
++# CONFIG_MACH_DECSTATION is not set
++# CONFIG_MACH_JAZZ is not set
++# CONFIG_LASAT is not set
++CONFIG_MACH_LOONGSON=y
++# CONFIG_MIPS_MALTA is not set
++# CONFIG_MIPS_SIM is not set
++# CONFIG_NEC_MARKEINS is not set
++# CONFIG_MACH_VR41XX is not set
++# CONFIG_NXP_STB220 is not set
++# CONFIG_NXP_STB225 is not set
++# CONFIG_PNX8550_JBS is not set
++# CONFIG_PNX8550_STB810 is not set
++# CONFIG_PMC_MSP is not set
++# CONFIG_PMC_YOSEMITE is not set
++# CONFIG_POWERTV is not set
++# CONFIG_SGI_IP22 is not set
++# CONFIG_SGI_IP27 is not set
++# CONFIG_SGI_IP28 is not set
++# CONFIG_SGI_IP32 is not set
++# CONFIG_SIBYTE_CRHINE is not set
++# CONFIG_SIBYTE_CARMEL is not set
++# CONFIG_SIBYTE_CRHONE is not set
++# CONFIG_SIBYTE_RHONE is not set
++# CONFIG_SIBYTE_SWARM is not set
++# CONFIG_SIBYTE_LITTLESUR is not set
++# CONFIG_SIBYTE_SENTOSA is not set
++# CONFIG_SIBYTE_BIGSUR is not set
++# CONFIG_SNI_RM is not set
++# CONFIG_MACH_TX39XX is not set
++# CONFIG_MACH_TX49XX is not set
++# CONFIG_MIKROTIK_RB532 is not set
++# CONFIG_WR_PPMC is not set
++# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
++# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
++# CONFIG_ALCHEMY_GPIO_INDIRECT is not set
++CONFIG_ARCH_SPARSEMEM_ENABLE=y
++# CONFIG_LEMOTE_FULOONG2E is not set
++CONFIG_LEMOTE_MACH2F=y
++CONFIG_CS5536=y
++CONFIG_CS5536_MFGPT=y
++CONFIG_LOONGSON_SUSPEND=y
++CONFIG_LOONGSON_UART_BASE=y
++
++#
++# Loongson Platform Specific Drivers
++#
++CONFIG_LOONGSON_PLATFORM_DEVICES=y
++CONFIG_LEMOTE_LYNLOONG2F_PDEV=m
++CONFIG_LEMOTE_YEELOONG2F_PDEV=m
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_ARCH_SUPPORTS_OPROFILE=y
++CONFIG_GENERIC_FIND_NEXT_BIT=y
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_GENERIC_TIME=y
++CONFIG_GENERIC_CMOS_UPDATE=y
++CONFIG_SCHED_OMIT_FRAME_POINTER=y
++CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
++CONFIG_DMA_NONCOHERENT=y
++CONFIG_DMA_NEED_PCI_MAP_STATE=y
++CONFIG_SYS_HAS_EARLY_PRINTK=y
++CONFIG_I8259=y
++# CONFIG_NO_IOPORT is not set
++CONFIG_GENERIC_ISA_DMA=y
++CONFIG_GENERIC_ISA_DMA_SUPPORT_BROKEN=y
++# CONFIG_CPU_BIG_ENDIAN is not set
++CONFIG_CPU_LITTLE_ENDIAN=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
++CONFIG_IRQ_CPU=y
++CONFIG_BOOT_ELF32=y
++CONFIG_MIPS_L1_CACHE_SHIFT=5
++
++#
++# CPU selection
++#
++# CONFIG_CPU_LOONGSON2E is not set
++CONFIG_CPU_LOONGSON2F=y
++# CONFIG_CPU_MIPS32_R1 is not set
++# CONFIG_CPU_MIPS32_R2 is not set
++# CONFIG_CPU_MIPS64_R1 is not set
++# CONFIG_CPU_MIPS64_R2 is not set
++# CONFIG_CPU_R3000 is not set
++# CONFIG_CPU_TX39XX is not set
++# CONFIG_CPU_VR41XX is not set
++# CONFIG_CPU_R4300 is not set
++# CONFIG_CPU_R4X00 is not set
++# CONFIG_CPU_TX49XX is not set
++# CONFIG_CPU_R5000 is not set
++# CONFIG_CPU_R5432 is not set
++# CONFIG_CPU_R5500 is not set
++# CONFIG_CPU_R6000 is not set
++# CONFIG_CPU_NEVADA is not set
++# CONFIG_CPU_R8000 is not set
++# CONFIG_CPU_R10000 is not set
++# CONFIG_CPU_RM7000 is not set
++# CONFIG_CPU_RM9000 is not set
++# CONFIG_CPU_SB1 is not set
++# CONFIG_CPU_CAVIUM_OCTEON is not set
++CONFIG_SYS_SUPPORTS_ZBOOT=y
++CONFIG_SYS_SUPPORTS_ZBOOT_UART16550=y
++CONFIG_CPU_LOONGSON2=y
++CONFIG_SYS_HAS_CPU_LOONGSON2F=y
++CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
++CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
++CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
++CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
++CONFIG_CPU_SUPPORTS_CPUFREQ=y
++CONFIG_CPU_SUPPORTS_ADDRWINCFG=y
++CONFIG_CPU_SUPPORTS_UNCACHED_ACCELERATED=y
++
++#
++# Kernel type
++#
++# CONFIG_32BIT is not set
++CONFIG_64BIT=y
++# CONFIG_PAGE_SIZE_4KB is not set
++# CONFIG_PAGE_SIZE_8KB is not set
++CONFIG_PAGE_SIZE_16KB=y
++# CONFIG_PAGE_SIZE_32KB is not set
++# CONFIG_PAGE_SIZE_64KB is not set
++CONFIG_BOARD_SCACHE=y
++CONFIG_MIPS_MT_DISABLED=y
++# CONFIG_MIPS_MT_SMP is not set
++# CONFIG_MIPS_MT_SMTC is not set
++CONFIG_CPU_HAS_WB=y
++CONFIG_CPU_HAS_SYNC=y
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_CPU_SUPPORTS_HIGHMEM=y
++CONFIG_SYS_SUPPORTS_HIGHMEM=y
++CONFIG_ARCH_POPULATES_NODE_MAP=y
++CONFIG_SELECT_MEMORY_MODEL=y
++# CONFIG_FLATMEM_MANUAL is not set
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++CONFIG_SPARSEMEM_MANUAL=y
++CONFIG_SPARSEMEM=y
++CONFIG_HAVE_MEMORY_PRESENT=y
++CONFIG_SPARSEMEM_STATIC=y
++CONFIG_PAGEFLAGS_EXTENDED=y
++CONFIG_SPLIT_PTLOCK_CPUS=4
++CONFIG_PHYS_ADDR_T_64BIT=y
++CONFIG_ZONE_DMA_FLAG=0
++CONFIG_VIRT_TO_BUS=y
++CONFIG_HAVE_MLOCK=y
++CONFIG_HAVE_MLOCKED_PAGE_BIT=y
++# CONFIG_KSM is not set
++CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
++CONFIG_TICK_ONESHOT=y
++CONFIG_NO_HZ=y
++CONFIG_HIGH_RES_TIMERS=y
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++# CONFIG_HZ_48 is not set
++# CONFIG_HZ_100 is not set
++# CONFIG_HZ_128 is not set
++CONFIG_HZ_250=y
++# CONFIG_HZ_256 is not set
++# CONFIG_HZ_1000 is not set
++# CONFIG_HZ_1024 is not set
++CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
++CONFIG_HZ=250
++# CONFIG_PREEMPT_NONE is not set
++# CONFIG_PREEMPT_VOLUNTARY is not set
++CONFIG_PREEMPT=y
++CONFIG_KEXEC=y
++# CONFIG_SECCOMP is not set
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++CONFIG_CONSTRUCTORS=y
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_LOCK_KERNEL=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++# CONFIG_LOCALVERSION_AUTO is not set
++CONFIG_HAVE_KERNEL_GZIP=y
++CONFIG_HAVE_KERNEL_BZIP2=y
++CONFIG_HAVE_KERNEL_LZMA=y
++CONFIG_HAVE_KERNEL_LZO=y
++CONFIG_KERNEL_GZIP=y
++# CONFIG_KERNEL_BZIP2 is not set
++# CONFIG_KERNEL_LZMA is not set
++# CONFIG_KERNEL_LZO is not set
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++# CONFIG_POSIX_MQUEUE is not set
++CONFIG_BSD_PROCESS_ACCT=y
++CONFIG_BSD_PROCESS_ACCT_V3=y
++# CONFIG_TASKSTATS is not set
++CONFIG_AUDIT=y
++
++#
++# RCU Subsystem
++#
++CONFIG_TREE_RCU=y
++# CONFIG_TREE_PREEMPT_RCU is not set
++# CONFIG_RCU_TRACE is not set
++CONFIG_RCU_FANOUT=64
++# CONFIG_RCU_FANOUT_EXACT is not set
++# CONFIG_TREE_RCU_TRACE is not set
++CONFIG_IKCONFIG=y
++CONFIG_IKCONFIG_PROC=y
++CONFIG_LOG_BUF_SHIFT=15
++# CONFIG_GROUP_SCHED is not set
++# CONFIG_CGROUPS is not set
++CONFIG_SYSFS_DEPRECATED=y
++CONFIG_SYSFS_DEPRECATED_V2=y
++# CONFIG_RELAY is not set
++# CONFIG_NAMESPACES is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++CONFIG_RD_GZIP=y
++CONFIG_RD_BZIP2=y
++CONFIG_RD_LZMA=y
++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
++CONFIG_SYSCTL=y
++CONFIG_ANON_INODES=y
++CONFIG_EMBEDDED=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_PCSPKR_PLATFORM=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_AIO=y
++
++#
++# Kernel Performance Events And Counters
++#
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_PCI_QUIRKS=y
++CONFIG_SLUB_DEBUG=y
++CONFIG_COMPAT_BRK=y
++# CONFIG_SLAB is not set
++CONFIG_SLUB=y
++# CONFIG_SLOB is not set
++CONFIG_PROFILING=y
++CONFIG_TRACEPOINTS=y
++CONFIG_OPROFILE=m
++CONFIG_HAVE_OPROFILE=y
++CONFIG_HAVE_SYSCALL_WRAPPERS=y
++
++#
++# GCOV-based kernel profiling
++#
++# CONFIG_GCOV_KERNEL is not set
++CONFIG_SLOW_WORK=y
++# CONFIG_SLOW_WORK_DEBUG is not set
++CONFIG_HAVE_GENERIC_DMA_COHERENT=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++# CONFIG_MODULE_FORCE_LOAD is not set
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++CONFIG_MODVERSIONS=y
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_BLOCK=y
++CONFIG_BLK_DEV_BSG=y
++CONFIG_BLK_DEV_INTEGRITY=y
++CONFIG_BLOCK_COMPAT=y
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=m
++CONFIG_IOSCHED_DEADLINE=m
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_DEFAULT_AS is not set
++# CONFIG_DEFAULT_DEADLINE is not set
++CONFIG_DEFAULT_CFQ=y
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="cfq"
++CONFIG_FREEZER=y
++
++#
++# Bus options (PCI, PCMCIA, EISA, ISA, TC)
++#
++CONFIG_HW_HAS_PCI=y
++CONFIG_PCI=y
++CONFIG_PCI_DOMAINS=y
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++CONFIG_PCI_LEGACY=y
++# CONFIG_PCI_STUB is not set
++# CONFIG_PCI_IOV is not set
++CONFIG_ISA=y
++CONFIG_MMU=y
++# CONFIG_PCCARD is not set
++# CONFIG_HOTPLUG_PCI is not set
++
++#
++# Executable file formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++# CONFIG_HAVE_AOUT is not set
++CONFIG_BINFMT_MISC=m
++CONFIG_MIPS32_COMPAT=y
++CONFIG_COMPAT=y
++CONFIG_SYSVIPC_COMPAT=y
++CONFIG_MIPS32_O32=y
++CONFIG_MIPS32_N32=y
++CONFIG_BINFMT_ELF32=y
++
++#
++# Power management options
++#
++CONFIG_ARCH_HIBERNATION_POSSIBLE=y
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++CONFIG_PM=y
++# CONFIG_PM_DEBUG is not set
++CONFIG_PM_SLEEP=y
++CONFIG_SUSPEND=y
++CONFIG_SUSPEND_FREEZER=y
++CONFIG_HIBERNATION_NVS=y
++CONFIG_HIBERNATION=y
++CONFIG_PM_STD_PARTITION="/dev/hda3"
++CONFIG_APM_EMULATION=y
++CONFIG_PM_RUNTIME=y
++CONFIG_MIPS_EXTERNAL_TIMER=y
++CONFIG_MIPS_CPUFREQ=y
++
++#
++# CPU Frequency scaling
++#
++CONFIG_CPU_FREQ=y
++CONFIG_CPU_FREQ_TABLE=y
++CONFIG_CPU_FREQ_DEBUG=y
++CONFIG_CPU_FREQ_STAT=m
++CONFIG_CPU_FREQ_STAT_DETAILS=y
++# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
++# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
++# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
++CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
++# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
++CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
++CONFIG_CPU_FREQ_GOV_POWERSAVE=m
++CONFIG_CPU_FREQ_GOV_USERSPACE=m
++CONFIG_CPU_FREQ_GOV_ONDEMAND=y
++CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
++
++#
++# CPUFreq processor drivers
++#
++CONFIG_LOONGSON2_CPUFREQ=m
++CONFIG_NET=y
++CONFIG_COMPAT_NETLINK_MESSAGES=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++CONFIG_PACKET_MMAP=y
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++CONFIG_XFRM_USER=m
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_XFRM_STATISTICS is not set
++CONFIG_NET_KEY=m
++# CONFIG_NET_KEY_MIGRATE is not set
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++CONFIG_IP_ADVANCED_ROUTER=y
++CONFIG_ASK_IP_FIB_HASH=y
++# CONFIG_IP_FIB_TRIE is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_MULTIPLE_TABLES=y
++CONFIG_IP_ROUTE_MULTIPATH=y
++CONFIG_IP_ROUTE_VERBOSE=y
++# CONFIG_IP_PNP is not set
++CONFIG_NET_IPIP=m
++CONFIG_NET_IPGRE=m
++# CONFIG_NET_IPGRE_BROADCAST is not set
++CONFIG_IP_MROUTE=y
++CONFIG_IP_PIMSM_V1=y
++CONFIG_IP_PIMSM_V2=y
++CONFIG_ARPD=y
++CONFIG_SYN_COOKIES=y
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++CONFIG_INET_TUNNEL=m
++CONFIG_INET_XFRM_MODE_TRANSPORT=m
++CONFIG_INET_XFRM_MODE_TUNNEL=m
++CONFIG_INET_XFRM_MODE_BEET=m
++CONFIG_INET_LRO=y
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++CONFIG_TCP_CONG_ADVANCED=y
++CONFIG_TCP_CONG_BIC=y
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_TCP_CONG_WESTWOOD=m
++CONFIG_TCP_CONG_HTCP=m
++# CONFIG_TCP_CONG_HSTCP is not set
++# CONFIG_TCP_CONG_HYBLA is not set
++# CONFIG_TCP_CONG_VEGAS is not set
++# CONFIG_TCP_CONG_SCALABLE is not set
++# CONFIG_TCP_CONG_LP is not set
++# CONFIG_TCP_CONG_VENO is not set
++# CONFIG_TCP_CONG_YEAH is not set
++# CONFIG_TCP_CONG_ILLINOIS is not set
++CONFIG_DEFAULT_BIC=y
++# CONFIG_DEFAULT_CUBIC is not set
++# CONFIG_DEFAULT_HTCP is not set
++# CONFIG_DEFAULT_VEGAS is not set
++# CONFIG_DEFAULT_WESTWOOD is not set
++# CONFIG_DEFAULT_RENO is not set
++CONFIG_DEFAULT_TCP_CONG="bic"
++CONFIG_TCP_MD5SIG=y
++CONFIG_IPV6=m
++CONFIG_IPV6_PRIVACY=y
++CONFIG_IPV6_ROUTER_PREF=y
++# CONFIG_IPV6_ROUTE_INFO is not set
++# CONFIG_IPV6_OPTIMISTIC_DAD is not set
++# CONFIG_INET6_AH is not set
++# CONFIG_INET6_ESP is not set
++# CONFIG_INET6_IPCOMP is not set
++# CONFIG_IPV6_MIP6 is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++CONFIG_INET6_TUNNEL=m
++CONFIG_INET6_XFRM_MODE_TRANSPORT=m
++CONFIG_INET6_XFRM_MODE_TUNNEL=m
++CONFIG_INET6_XFRM_MODE_BEET=m
++# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
++CONFIG_IPV6_SIT=m
++CONFIG_IPV6_NDISC_NODETYPE=y
++CONFIG_IPV6_TUNNEL=m
++CONFIG_IPV6_MULTIPLE_TABLES=y
++CONFIG_IPV6_SUBTREES=y
++# CONFIG_IPV6_MROUTE is not set
++CONFIG_NETWORK_SECMARK=y
++CONFIG_NETFILTER=y
++# CONFIG_NETFILTER_DEBUG is not set
++CONFIG_NETFILTER_ADVANCED=y
++CONFIG_BRIDGE_NETFILTER=y
++
++#
++# Core Netfilter Configuration
++#
++# CONFIG_NETFILTER_NETLINK_QUEUE is not set
++# CONFIG_NETFILTER_NETLINK_LOG is not set
++# CONFIG_NF_CONNTRACK is not set
++# CONFIG_NETFILTER_XTABLES is not set
++# CONFIG_IP_VS is not set
++
++#
++# IP: Netfilter Configuration
++#
++# CONFIG_NF_DEFRAG_IPV4 is not set
++# CONFIG_IP_NF_QUEUE is not set
++# CONFIG_IP_NF_IPTABLES is not set
++# CONFIG_IP_NF_ARPTABLES is not set
++
++#
++# IPv6: Netfilter Configuration
++#
++# CONFIG_IP6_NF_QUEUE is not set
++# CONFIG_IP6_NF_IPTABLES is not set
++# CONFIG_BRIDGE_NF_EBTABLES is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_RDS is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++CONFIG_STP=m
++CONFIG_BRIDGE=m
++# CONFIG_NET_DSA is not set
++CONFIG_VLAN_8021Q=m
++# CONFIG_VLAN_8021Q_GVRP is not set
++# CONFIG_DECNET is not set
++CONFIG_LLC=m
++# CONFIG_LLC2 is not set
++CONFIG_IPX=m
++# CONFIG_IPX_INTERN is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++# CONFIG_PHONET is not set
++# CONFIG_IEEE802154 is not set
++CONFIG_NET_SCHED=y
++
++#
++# Queueing/Scheduling
++#
++# CONFIG_NET_SCH_CBQ is not set
++# CONFIG_NET_SCH_HTB is not set
++# CONFIG_NET_SCH_HFSC is not set
++# CONFIG_NET_SCH_PRIO is not set
++# CONFIG_NET_SCH_MULTIQ is not set
++# CONFIG_NET_SCH_RED is not set
++# CONFIG_NET_SCH_SFQ is not set
++# CONFIG_NET_SCH_TEQL is not set
++# CONFIG_NET_SCH_TBF is not set
++# CONFIG_NET_SCH_GRED is not set
++# CONFIG_NET_SCH_DSMARK is not set
++# CONFIG_NET_SCH_NETEM is not set
++# CONFIG_NET_SCH_DRR is not set
++# CONFIG_NET_SCH_INGRESS is not set
++
++#
++# Classification
++#
++CONFIG_NET_CLS=y
++# CONFIG_NET_CLS_BASIC is not set
++# CONFIG_NET_CLS_TCINDEX is not set
++# CONFIG_NET_CLS_ROUTE4 is not set
++# CONFIG_NET_CLS_FW is not set
++# CONFIG_NET_CLS_U32 is not set
++# CONFIG_NET_CLS_RSVP is not set
++# CONFIG_NET_CLS_RSVP6 is not set
++# CONFIG_NET_CLS_FLOW is not set
++CONFIG_NET_EMATCH=y
++CONFIG_NET_EMATCH_STACK=32
++# CONFIG_NET_EMATCH_CMP is not set
++# CONFIG_NET_EMATCH_NBYTE is not set
++# CONFIG_NET_EMATCH_U32 is not set
++# CONFIG_NET_EMATCH_META is not set
++# CONFIG_NET_EMATCH_TEXT is not set
++CONFIG_NET_CLS_ACT=y
++# CONFIG_NET_ACT_POLICE is not set
++# CONFIG_NET_ACT_GACT is not set
++# CONFIG_NET_ACT_MIRRED is not set
++# CONFIG_NET_ACT_NAT is not set
++# CONFIG_NET_ACT_PEDIT is not set
++# CONFIG_NET_ACT_SIMP is not set
++# CONFIG_NET_ACT_SKBEDIT is not set
++CONFIG_NET_SCH_FIFO=y
++# CONFIG_DCB is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_NET_DROP_MONITOR is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++CONFIG_BT=m
++CONFIG_BT_L2CAP=m
++CONFIG_BT_SCO=m
++CONFIG_BT_RFCOMM=m
++CONFIG_BT_RFCOMM_TTY=y
++CONFIG_BT_BNEP=m
++CONFIG_BT_BNEP_MC_FILTER=y
++CONFIG_BT_BNEP_PROTO_FILTER=y
++CONFIG_BT_HIDP=m
++
++#
++# Bluetooth device drivers
++#
++CONFIG_BT_HCIBTUSB=m
++# CONFIG_BT_HCIBTSDIO is not set
++# CONFIG_BT_HCIUART is not set
++# CONFIG_BT_HCIBCM203X is not set
++# CONFIG_BT_HCIBPA10X is not set
++CONFIG_BT_HCIBFUSB=m
++CONFIG_BT_HCIVHCI=m
++# CONFIG_BT_MRVL is not set
++# CONFIG_AF_RXRPC is not set
++CONFIG_FIB_RULES=y
++CONFIG_WIRELESS=y
++CONFIG_CFG80211=m
++# CONFIG_NL80211_TESTMODE is not set
++# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
++# CONFIG_CFG80211_REG_DEBUG is not set
++CONFIG_CFG80211_DEFAULT_PS=y
++CONFIG_CFG80211_DEFAULT_PS_VALUE=1
++# CONFIG_CFG80211_DEBUGFS is not set
++# CONFIG_WIRELESS_OLD_REGULATORY is not set
++CONFIG_WIRELESS_EXT=y
++CONFIG_WIRELESS_EXT_SYSFS=y
++CONFIG_LIB80211=m
++CONFIG_LIB80211_DEBUG=y
++CONFIG_MAC80211=m
++# CONFIG_MAC80211_RC_PID is not set
++CONFIG_MAC80211_RC_MINSTREL=y
++# CONFIG_MAC80211_RC_DEFAULT_PID is not set
++CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
++CONFIG_MAC80211_RC_DEFAULT="minstrel"
++# CONFIG_MAC80211_MESH is not set
++CONFIG_MAC80211_LEDS=y
++# CONFIG_MAC80211_DEBUGFS is not set
++# CONFIG_MAC80211_DEBUG_MENU is not set
++# CONFIG_WIMAX is not set
++CONFIG_RFKILL=m
++CONFIG_RFKILL_LEDS=y
++CONFIG_RFKILL_INPUT=y
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++# CONFIG_DEVTMPFS is not set
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++CONFIG_FW_LOADER=y
++CONFIG_FIRMWARE_IN_KERNEL=y
++CONFIG_EXTRA_FIRMWARE=""
++# CONFIG_SYS_HYPERVISOR is not set
++CONFIG_CONNECTOR=m
++# CONFIG_MTD is not set
++# CONFIG_PARPORT is not set
++# CONFIG_PNP is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_CPQ_DA is not set
++# CONFIG_BLK_CPQ_CISS_DA is not set
++# CONFIG_BLK_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_UMEM is not set
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++CONFIG_BLK_DEV_CRYPTOLOOP=m
++CONFIG_BLK_DEV_NBD=m
++# CONFIG_BLK_DEV_SX8 is not set
++# CONFIG_BLK_DEV_UB is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=16
++CONFIG_BLK_DEV_RAM_SIZE=8192
++# CONFIG_BLK_DEV_XIP is not set
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++# CONFIG_BLK_DEV_HD is not set
++# CONFIG_MISC_DEVICES is not set
++CONFIG_EEPROM_93CX6=m
++CONFIG_HAVE_IDE=y
++CONFIG_IDE=y
++
++#
++# Please see Documentation/ide/ide.txt for help/info on IDE drives
++#
++CONFIG_IDE_XFER_MODE=y
++CONFIG_IDE_TIMINGS=y
++# CONFIG_BLK_DEV_IDE_SATA is not set
++CONFIG_IDE_GD=y
++CONFIG_IDE_GD_ATA=y
++# CONFIG_IDE_GD_ATAPI is not set
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++CONFIG_IDE_TASK_IOCTL=y
++CONFIG_IDE_PROC_FS=y
++
++#
++# IDE chipset support/bugfixes
++#
++# CONFIG_IDE_GENERIC is not set
++# CONFIG_BLK_DEV_PLATFORM is not set
++CONFIG_BLK_DEV_IDEDMA_SFF=y
++
++#
++# PCI IDE chipsets support
++#
++CONFIG_BLK_DEV_IDEPCI=y
++# CONFIG_IDEPCI_PCIBUS_ORDER is not set
++# CONFIG_BLK_DEV_GENERIC is not set
++# CONFIG_BLK_DEV_OPTI621 is not set
++CONFIG_BLK_DEV_IDEDMA_PCI=y
++# CONFIG_BLK_DEV_AEC62XX is not set
++# CONFIG_BLK_DEV_ALI15X3 is not set
++CONFIG_BLK_DEV_AMD74XX=y
++# CONFIG_BLK_DEV_CMD64X is not set
++# CONFIG_BLK_DEV_TRIFLEX is not set
++# CONFIG_BLK_DEV_CS5520 is not set
++# CONFIG_BLK_DEV_CS5530 is not set
++# CONFIG_BLK_DEV_HPT366 is not set
++# CONFIG_BLK_DEV_JMICRON is not set
++# CONFIG_BLK_DEV_SC1200 is not set
++# CONFIG_BLK_DEV_PIIX is not set
++# CONFIG_BLK_DEV_IT8172 is not set
++# CONFIG_BLK_DEV_IT8213 is not set
++# CONFIG_BLK_DEV_IT821X is not set
++# CONFIG_BLK_DEV_NS87415 is not set
++# CONFIG_BLK_DEV_PDC202XX_OLD is not set
++# CONFIG_BLK_DEV_PDC202XX_NEW is not set
++# CONFIG_BLK_DEV_SVWKS is not set
++# CONFIG_BLK_DEV_SIIMAGE is not set
++# CONFIG_BLK_DEV_SLC90E66 is not set
++# CONFIG_BLK_DEV_TRM290 is not set
++# CONFIG_BLK_DEV_VIA82CXXX is not set
++# CONFIG_BLK_DEV_TC86C001 is not set
++
++#
++# Other IDE chipsets support
++#
++
++#
++# Note: most of these also require special kernel boot parameters
++#
++# CONFIG_BLK_DEV_4DRIVES is not set
++# CONFIG_BLK_DEV_ALI14XX is not set
++# CONFIG_BLK_DEV_DTC2278 is not set
++# CONFIG_BLK_DEV_HT6560B is not set
++# CONFIG_BLK_DEV_QD65XX is not set
++# CONFIG_BLK_DEV_UMC8672 is not set
++CONFIG_BLK_DEV_IDEDMA=y
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=m
++CONFIG_SCSI_DMA=y
++# CONFIG_SCSI_TGT is not set
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=m
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++CONFIG_CHR_DEV_SG=m
++# CONFIG_CHR_DEV_SCH is not set
++CONFIG_SCSI_MULTI_LUN=y
++# CONFIG_SCSI_CONSTANTS is not set
++# CONFIG_SCSI_LOGGING is not set
++# CONFIG_SCSI_SCAN_ASYNC is not set
++CONFIG_SCSI_WAIT_SCAN=m
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++# CONFIG_SCSI_ISCSI_ATTRS is not set
++# CONFIG_SCSI_SAS_ATTRS is not set
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++# CONFIG_SCSI_LOWLEVEL is not set
++# CONFIG_SCSI_DH is not set
++# CONFIG_SCSI_OSD_INITIATOR is not set
++# CONFIG_ATA is not set
++CONFIG_MD=y
++CONFIG_BLK_DEV_MD=m
++CONFIG_MD_LINEAR=m
++CONFIG_MD_RAID0=m
++CONFIG_MD_RAID1=m
++CONFIG_MD_RAID10=m
++CONFIG_MD_RAID456=m
++CONFIG_MD_RAID6_PQ=m
++# CONFIG_ASYNC_RAID6_TEST is not set
++CONFIG_MD_MULTIPATH=m
++CONFIG_MD_FAULTY=m
++CONFIG_BLK_DEV_DM=m
++CONFIG_DM_DEBUG=y
++CONFIG_DM_CRYPT=m
++CONFIG_DM_SNAPSHOT=m
++CONFIG_DM_MIRROR=m
++CONFIG_DM_LOG_USERSPACE=m
++CONFIG_DM_ZERO=m
++CONFIG_DM_MULTIPATH=m
++CONFIG_DM_MULTIPATH_QL=m
++CONFIG_DM_MULTIPATH_ST=m
++CONFIG_DM_DELAY=m
++CONFIG_DM_UEVENT=y
++# CONFIG_FUSION is not set
++
++#
++# IEEE 1394 (FireWire) support
++#
++
++#
++# You can enable one or both FireWire driver stacks.
++#
++
++#
++# See the help texts for more information.
++#
++# CONFIG_FIREWIRE is not set
++# CONFIG_IEEE1394 is not set
++# CONFIG_I2O is not set
++CONFIG_NETDEVICES=y
++# CONFIG_IFB is not set
++CONFIG_DUMMY=m
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++CONFIG_TUN=m
++CONFIG_VETH=m
++# CONFIG_ARCNET is not set
++# CONFIG_PHYLIB is not set
++CONFIG_NET_ETHERNET=y
++CONFIG_MII=y
++# CONFIG_AX88796 is not set
++# CONFIG_HAPPYMEAL is not set
++# CONFIG_SUNGEM is not set
++# CONFIG_CASSINI is not set
++# CONFIG_NET_VENDOR_3COM is not set
++# CONFIG_NET_VENDOR_SMC is not set
++# CONFIG_SMC91X is not set
++# CONFIG_DM9000 is not set
++# CONFIG_ETHOC is not set
++# CONFIG_NET_VENDOR_RACAL is not set
++# CONFIG_DNET is not set
++# CONFIG_NET_TULIP is not set
++# CONFIG_AT1700 is not set
++# CONFIG_DEPCA is not set
++# CONFIG_HP100 is not set
++# CONFIG_NET_ISA is not set
++# CONFIG_IBM_NEW_EMAC_ZMII is not set
++# CONFIG_IBM_NEW_EMAC_RGMII is not set
++# CONFIG_IBM_NEW_EMAC_TAH is not set
++# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
++# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
++# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
++# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
++CONFIG_NET_PCI=y
++# CONFIG_PCNET32 is not set
++# CONFIG_AMD8111_ETH is not set
++# CONFIG_ADAPTEC_STARFIRE is not set
++# CONFIG_AC3200 is not set
++# CONFIG_APRICOT is not set
++# CONFIG_B44 is not set
++# CONFIG_FORCEDETH is not set
++# CONFIG_CS89x0 is not set
++# CONFIG_TC35815 is not set
++# CONFIG_E100 is not set
++# CONFIG_FEALNX is not set
++# CONFIG_NATSEMI is not set
++# CONFIG_NE2K_PCI is not set
++# CONFIG_8139CP is not set
++CONFIG_8139TOO=y
++# CONFIG_8139TOO_PIO is not set
++# CONFIG_8139TOO_TUNE_TWISTER is not set
++# CONFIG_8139TOO_8129 is not set
++# CONFIG_8139_OLD_RX_RESET is not set
++# CONFIG_R6040 is not set
++# CONFIG_SIS900 is not set
++# CONFIG_EPIC100 is not set
++# CONFIG_SMSC9420 is not set
++# CONFIG_SUNDANCE is not set
++# CONFIG_TLAN is not set
++# CONFIG_KS8842 is not set
++# CONFIG_KS8851_MLL is not set
++# CONFIG_VIA_RHINE is not set
++# CONFIG_SC92031 is not set
++# CONFIG_ATL2 is not set
++CONFIG_NETDEV_1000=y
++# CONFIG_ACENIC is not set
++# CONFIG_DL2K is not set
++# CONFIG_E1000 is not set
++# CONFIG_E1000E is not set
++# CONFIG_IP1000 is not set
++# CONFIG_IGB is not set
++# CONFIG_IGBVF is not set
++# CONFIG_NS83820 is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++CONFIG_R8169=y
++CONFIG_R8169_VLAN=y
++# CONFIG_SIS190 is not set
++# CONFIG_SKGE is not set
++# CONFIG_SKY2 is not set
++# CONFIG_VIA_VELOCITY is not set
++# CONFIG_TIGON3 is not set
++# CONFIG_BNX2 is not set
++# CONFIG_CNIC is not set
++# CONFIG_QLA3XXX is not set
++# CONFIG_ATL1 is not set
++# CONFIG_ATL1E is not set
++# CONFIG_ATL1C is not set
++# CONFIG_JME is not set
++# CONFIG_NETDEV_10000 is not set
++# CONFIG_TR is not set
++CONFIG_WLAN=y
++CONFIG_WLAN_PRE80211=y
++# CONFIG_STRIP is not set
++# CONFIG_WAVELAN is not set
++CONFIG_WLAN_80211=y
++# CONFIG_LIBERTAS is not set
++# CONFIG_LIBERTAS_THINFIRM is not set
++# CONFIG_ATMEL is not set
++# CONFIG_AT76C50X_USB is not set
++# CONFIG_PRISM54 is not set
++# CONFIG_USB_ZD1201 is not set
++# CONFIG_USB_NET_RNDIS_WLAN is not set
++# CONFIG_RTL8180 is not set
++CONFIG_RTL8187B=m
++# CONFIG_ADM8211 is not set
++# CONFIG_MAC80211_HWSIM is not set
++# CONFIG_MWL8K is not set
++# CONFIG_P54_COMMON is not set
++# CONFIG_ATH_COMMON is not set
++# CONFIG_IPW2100 is not set
++# CONFIG_IPW2200 is not set
++# CONFIG_IWLWIFI is not set
++# CONFIG_HOSTAP is not set
++# CONFIG_B43 is not set
++# CONFIG_B43LEGACY is not set
++# CONFIG_ZD1211RW is not set
++# CONFIG_RT2X00 is not set
++# CONFIG_HERMES is not set
++# CONFIG_WL12XX is not set
++# CONFIG_IWM is not set
++
++#
++# Enable WiMAX (Networking options) to see the WiMAX drivers
++#
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++CONFIG_USB_USBNET=m
++CONFIG_USB_NET_AX8817X=m
++CONFIG_USB_NET_CDCETHER=m
++CONFIG_USB_NET_CDC_EEM=m
++# CONFIG_USB_NET_DM9601 is not set
++# CONFIG_USB_NET_SMSC95XX is not set
++# CONFIG_USB_NET_GL620A is not set
++CONFIG_USB_NET_NET1080=m
++# CONFIG_USB_NET_PLUSB is not set
++# CONFIG_USB_NET_MCS7830 is not set
++# CONFIG_USB_NET_RNDIS_HOST is not set
++CONFIG_USB_NET_CDC_SUBSET=m
++# CONFIG_USB_ALI_M5632 is not set
++# CONFIG_USB_AN2720 is not set
++CONFIG_USB_BELKIN=y
++CONFIG_USB_ARMLINUX=y
++# CONFIG_USB_EPSON2888 is not set
++# CONFIG_USB_KC2190 is not set
++CONFIG_USB_NET_ZAURUS=m
++# CONFIG_USB_HSO is not set
++# CONFIG_USB_NET_INT51X1 is not set
++# CONFIG_WAN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_NET_FC is not set
++CONFIG_NETCONSOLE=m
++CONFIG_NETCONSOLE_DYNAMIC=y
++CONFIG_NETPOLL=y
++# CONFIG_NETPOLL_TRAP is not set
++CONFIG_NET_POLL_CONTROLLER=y
++# CONFIG_ISDN is not set
++# CONFIG_PHONE is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++CONFIG_INPUT_POLLDEV=m
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_PSAUX=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_EVBUG is not set
++# CONFIG_INPUT_APMPOWER is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++CONFIG_KEYBOARD_ATKBD=y
++# CONFIG_KEYBOARD_LKKBD is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_OPENCORES is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++CONFIG_INPUT_MOUSE=y
++CONFIG_MOUSE_PS2=y
++# CONFIG_MOUSE_PS2_ALPS is not set
++# CONFIG_MOUSE_PS2_LOGIPS2PP is not set
++CONFIG_MOUSE_PS2_SYNAPTICS=y
++# CONFIG_MOUSE_PS2_TRACKPOINT is not set
++# CONFIG_MOUSE_PS2_ELANTECH is not set
++# CONFIG_MOUSE_PS2_SENTELIC is not set
++# CONFIG_MOUSE_PS2_TOUCHKIT is not set
++# CONFIG_MOUSE_SERIAL is not set
++CONFIG_MOUSE_APPLETOUCH=m
++# CONFIG_MOUSE_BCM5974 is not set
++# CONFIG_MOUSE_INPORT is not set
++# CONFIG_MOUSE_LOGIBM is not set
++# CONFIG_MOUSE_PC110PAD is not set
++# CONFIG_MOUSE_VSXXXAA is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++# CONFIG_INPUT_TOUCHSCREEN is not set
++# CONFIG_INPUT_MISC is not set
++
++#
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++CONFIG_SERIO_I8042=y
++# CONFIG_SERIO_SERPORT is not set
++# CONFIG_SERIO_PCIPS2 is not set
++CONFIG_SERIO_LIBPS2=y
++# CONFIG_SERIO_RAW is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_CONSOLE_TRANSLATIONS=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
++CONFIG_DEVKMEM=y
++CONFIG_SERIAL_NONSTANDARD=y
++# CONFIG_COMPUTONE is not set
++# CONFIG_ROCKETPORT is not set
++# CONFIG_CYCLADES is not set
++# CONFIG_DIGIEPCA is not set
++# CONFIG_MOXA_INTELLIO is not set
++# CONFIG_MOXA_SMARTIO is not set
++# CONFIG_ISI is not set
++# CONFIG_SYNCLINKMP is not set
++# CONFIG_SYNCLINK_GT is not set
++# CONFIG_N_HDLC is not set
++# CONFIG_RISCOM8 is not set
++# CONFIG_SPECIALIX is not set
++# CONFIG_STALDRV is not set
++# CONFIG_NOZOMI is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=m
++# CONFIG_SERIAL_8250_PCI is not set
++CONFIG_SERIAL_8250_NR_UARTS=16
++CONFIG_SERIAL_8250_RUNTIME_UARTS=4
++CONFIG_SERIAL_8250_EXTENDED=y
++CONFIG_SERIAL_8250_MANY_PORTS=y
++CONFIG_SERIAL_8250_FOURPORT=y
++# CONFIG_SERIAL_8250_ACCENT is not set
++# CONFIG_SERIAL_8250_BOCA is not set
++# CONFIG_SERIAL_8250_EXAR_ST16C554 is not set
++# CONFIG_SERIAL_8250_HUB6 is not set
++# CONFIG_SERIAL_8250_SHARE_IRQ is not set
++# CONFIG_SERIAL_8250_DETECT_IRQ is not set
++# CONFIG_SERIAL_8250_RSA is not set
++
++#
++# Non-8250 serial port support
++#
++CONFIG_SERIAL_CORE=m
++# CONFIG_SERIAL_JSM is not set
++CONFIG_UNIX98_PTYS=y
++# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=16
++# CONFIG_IPMI_HANDLER is not set
++CONFIG_HW_RANDOM=y
++# CONFIG_HW_RANDOM_TIMERIOMEM is not set
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_DEVPORT=y
++# CONFIG_I2C is not set
++# CONFIG_SPI is not set
++
++#
++# PPS support
++#
++# CONFIG_PPS is not set
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++CONFIG_HWMON=y
++# CONFIG_HWMON_VID is not set
++# CONFIG_HWMON_DEBUG_CHIP is not set
++
++#
++# Native drivers
++#
++# CONFIG_SENSORS_I5K_AMB is not set
++# CONFIG_SENSORS_F71805F is not set
++# CONFIG_SENSORS_F71882FG is not set
++# CONFIG_SENSORS_IT87 is not set
++# CONFIG_SENSORS_PC87360 is not set
++# CONFIG_SENSORS_PC87427 is not set
++# CONFIG_SENSORS_SIS5595 is not set
++# CONFIG_SENSORS_SMSC47M1 is not set
++# CONFIG_SENSORS_SMSC47B397 is not set
++# CONFIG_SENSORS_VIA686A is not set
++# CONFIG_SENSORS_VT1211 is not set
++# CONFIG_SENSORS_VT8231 is not set
++# CONFIG_SENSORS_W83627HF is not set
++# CONFIG_SENSORS_W83627EHF is not set
++CONFIG_THERMAL=y
++# CONFIG_THERMAL_HWMON is not set
++# CONFIG_WATCHDOG is not set
++CONFIG_SSB_POSSIBLE=y
++
++#
++# Sonics Silicon Backplane
++#
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_CORE is not set
++# CONFIG_MFD_SM501 is not set
++# CONFIG_HTC_PASIC3 is not set
++# CONFIG_MFD_TMIO is not set
++# CONFIG_REGULATOR is not set
++CONFIG_MEDIA_SUPPORT=m
++
++#
++# Multimedia core support
++#
++CONFIG_VIDEO_DEV=m
++CONFIG_VIDEO_V4L2_COMMON=m
++CONFIG_VIDEO_ALLOW_V4L1=y
++CONFIG_VIDEO_V4L1_COMPAT=y
++# CONFIG_DVB_CORE is not set
++CONFIG_VIDEO_MEDIA=m
++
++#
++# Multimedia drivers
++#
++# CONFIG_MEDIA_ATTACH is not set
++CONFIG_VIDEO_V4L2=m
++CONFIG_VIDEO_V4L1=m
++CONFIG_VIDEOBUF_GEN=m
++CONFIG_VIDEOBUF_VMALLOC=m
++CONFIG_VIDEO_CAPTURE_DRIVERS=y
++# CONFIG_VIDEO_ADV_DEBUG is not set
++# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
++CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
++CONFIG_VIDEO_VIVI=m
++# CONFIG_VIDEO_PMS is not set
++# CONFIG_VIDEO_CPIA is not set
++# CONFIG_VIDEO_CPIA2 is not set
++# CONFIG_VIDEO_STRADIS is not set
++CONFIG_V4L_USB_DRIVERS=y
++CONFIG_USB_VIDEO_CLASS=m
++CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
++CONFIG_USB_GSPCA=m
++CONFIG_USB_M5602=m
++CONFIG_USB_STV06XX=m
++# CONFIG_USB_GL860 is not set
++CONFIG_USB_GSPCA_CONEX=m
++CONFIG_USB_GSPCA_ETOMS=m
++CONFIG_USB_GSPCA_FINEPIX=m
++# CONFIG_USB_GSPCA_JEILINJ is not set
++CONFIG_USB_GSPCA_MARS=m
++CONFIG_USB_GSPCA_MR97310A=m
++CONFIG_USB_GSPCA_OV519=m
++CONFIG_USB_GSPCA_OV534=m
++CONFIG_USB_GSPCA_PAC207=m
++CONFIG_USB_GSPCA_PAC7311=m
++CONFIG_USB_GSPCA_SN9C20X=m
++CONFIG_USB_GSPCA_SN9C20X_EVDEV=y
++CONFIG_USB_GSPCA_SONIXB=m
++CONFIG_USB_GSPCA_SONIXJ=m
++CONFIG_USB_GSPCA_SPCA500=m
++CONFIG_USB_GSPCA_SPCA501=m
++CONFIG_USB_GSPCA_SPCA505=m
++CONFIG_USB_GSPCA_SPCA506=m
++CONFIG_USB_GSPCA_SPCA508=m
++CONFIG_USB_GSPCA_SPCA561=m
++CONFIG_USB_GSPCA_SQ905=m
++CONFIG_USB_GSPCA_SQ905C=m
++CONFIG_USB_GSPCA_STK014=m
++CONFIG_USB_GSPCA_SUNPLUS=m
++CONFIG_USB_GSPCA_T613=m
++CONFIG_USB_GSPCA_TV8532=m
++CONFIG_USB_GSPCA_VC032X=m
++CONFIG_USB_GSPCA_ZC3XX=m
++# CONFIG_VIDEO_HDPVR is not set
++# CONFIG_USB_VICAM is not set
++# CONFIG_USB_IBMCAM is not set
++# CONFIG_USB_KONICAWC is not set
++# CONFIG_USB_QUICKCAM_MESSENGER is not set
++CONFIG_USB_ET61X251=m
++# CONFIG_USB_OV511 is not set
++# CONFIG_USB_SE401 is not set
++CONFIG_USB_SN9C102=m
++# CONFIG_USB_STV680 is not set
++CONFIG_USB_ZC0301=m
++# CONFIG_USB_PWC is not set
++CONFIG_USB_PWC_INPUT_EVDEV=y
++CONFIG_USB_ZR364XX=m
++CONFIG_USB_STKWEBCAM=m
++CONFIG_USB_S2255=m
++# CONFIG_RADIO_ADAPTERS is not set
++# CONFIG_DAB is not set
++
++#
++# Graphics support
++#
++CONFIG_VGA_ARB=y
++# CONFIG_DRM is not set
++# CONFIG_VGASTATE is not set
++CONFIG_VIDEO_OUTPUT_CONTROL=y
++CONFIG_FB=y
++CONFIG_FIRMWARE_EDID=y
++# CONFIG_FB_DDC is not set
++CONFIG_FB_BOOT_VESA_SUPPORT=y
++CONFIG_FB_CFB_FILLRECT=y
++CONFIG_FB_CFB_COPYAREA=y
++CONFIG_FB_CFB_IMAGEBLIT=y
++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
++# CONFIG_FB_SYS_FILLRECT is not set
++# CONFIG_FB_SYS_COPYAREA is not set
++# CONFIG_FB_SYS_IMAGEBLIT is not set
++# CONFIG_FB_FOREIGN_ENDIAN is not set
++# CONFIG_FB_SYS_FOPS is not set
++# CONFIG_FB_SVGALIB is not set
++# CONFIG_FB_MACMODES is not set
++# CONFIG_FB_BACKLIGHT is not set
++CONFIG_FB_MODE_HELPERS=y
++CONFIG_FB_TILEBLITTING=y
++
++#
++# Frame buffer hardware drivers
++#
++# CONFIG_FB_CIRRUS is not set
++# CONFIG_FB_PM2 is not set
++# CONFIG_FB_CYBER2000 is not set
++# CONFIG_FB_ASILIANT is not set
++# CONFIG_FB_IMSTT is not set
++# CONFIG_FB_UVESA is not set
++# CONFIG_FB_S1D13XXX is not set
++# CONFIG_FB_NVIDIA is not set
++# CONFIG_FB_RIVA is not set
++# CONFIG_FB_MATROX is not set
++# CONFIG_FB_RADEON is not set
++# CONFIG_FB_ATY128 is not set
++# CONFIG_FB_ATY is not set
++# CONFIG_FB_S3 is not set
++# CONFIG_FB_SAVAGE is not set
++CONFIG_FB_SIS=y
++CONFIG_FB_SIS_300=y
++CONFIG_FB_SIS_315=y
++# CONFIG_FB_VIA is not set
++# CONFIG_FB_NEOMAGIC is not set
++# CONFIG_FB_KYRO is not set
++# CONFIG_FB_3DFX is not set
++# CONFIG_FB_VOODOO1 is not set
++# CONFIG_FB_VT8623 is not set
++# CONFIG_FB_TRIDENT is not set
++# CONFIG_FB_ARK is not set
++# CONFIG_FB_PM3 is not set
++# CONFIG_FB_CARMINE is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FB_METRONOME is not set
++# CONFIG_FB_MB862XX is not set
++# CONFIG_FB_BROADSHEET is not set
++CONFIG_BACKLIGHT_LCD_SUPPORT=y
++CONFIG_LCD_CLASS_DEVICE=y
++# CONFIG_LCD_ILI9320 is not set
++CONFIG_LCD_PLATFORM=y
++CONFIG_BACKLIGHT_CLASS_DEVICE=y
++CONFIG_BACKLIGHT_GENERIC=m
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++# CONFIG_MDA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE=y
++# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
++CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
++CONFIG_FONTS=y
++CONFIG_FONT_8x8=y
++CONFIG_FONT_8x16=y
++CONFIG_FONT_6x11=y
++CONFIG_FONT_7x14=y
++CONFIG_FONT_PEARL_8x8=y
++CONFIG_FONT_ACORN_8x8=y
++CONFIG_FONT_MINI_4x6=y
++CONFIG_FONT_SUN8x16=y
++CONFIG_FONT_SUN12x22=y
++CONFIG_FONT_10x18=y
++CONFIG_LOGO=y
++# CONFIG_LOGO_LINUX_MONO is not set
++# CONFIG_LOGO_LINUX_VGA16 is not set
++# CONFIG_LOGO_LINUX_CLUT224 is not set
++CONFIG_LOGO_LIBRE_CLUT224=y
++CONFIG_SOUND=m
++CONFIG_SOUND_OSS_CORE=y
++CONFIG_SOUND_OSS_CORE_PRECLAIM=y
++CONFIG_SND=m
++CONFIG_SND_TIMER=m
++CONFIG_SND_PCM=m
++CONFIG_SND_HWDEP=m
++CONFIG_SND_RAWMIDI=m
++CONFIG_SND_SEQUENCER=m
++CONFIG_SND_SEQ_DUMMY=m
++CONFIG_SND_OSSEMUL=y
++CONFIG_SND_MIXER_OSS=m
++CONFIG_SND_PCM_OSS=m
++CONFIG_SND_PCM_OSS_PLUGINS=y
++CONFIG_SND_SEQUENCER_OSS=y
++CONFIG_SND_HRTIMER=m
++CONFIG_SND_SEQ_HRTIMER_DEFAULT=y
++# CONFIG_SND_DYNAMIC_MINORS is not set
++CONFIG_SND_SUPPORT_OLD_API=y
++CONFIG_SND_VERBOSE_PROCFS=y
++# CONFIG_SND_VERBOSE_PRINTK is not set
++# CONFIG_SND_DEBUG is not set
++CONFIG_SND_VMASTER=y
++CONFIG_SND_RAWMIDI_SEQ=m
++# CONFIG_SND_OPL3_LIB_SEQ is not set
++# CONFIG_SND_OPL4_LIB_SEQ is not set
++# CONFIG_SND_SBAWE_SEQ is not set
++# CONFIG_SND_EMU10K1_SEQ is not set
++CONFIG_SND_MPU401_UART=m
++CONFIG_SND_AC97_CODEC=m
++CONFIG_SND_DRIVERS=y
++CONFIG_SND_DUMMY=m
++CONFIG_SND_VIRMIDI=m
++# CONFIG_SND_MTPAV is not set
++CONFIG_SND_SERIAL_U16550=m
++CONFIG_SND_MPU401=m
++CONFIG_SND_AC97_POWER_SAVE=y
++CONFIG_SND_AC97_POWER_SAVE_DEFAULT=10
++CONFIG_SND_PCI=y
++# CONFIG_SND_AD1889 is not set
++# CONFIG_SND_ALS300 is not set
++# CONFIG_SND_ALI5451 is not set
++# CONFIG_SND_ATIIXP is not set
++# CONFIG_SND_ATIIXP_MODEM is not set
++# CONFIG_SND_AU8810 is not set
++# CONFIG_SND_AU8820 is not set
++# CONFIG_SND_AU8830 is not set
++# CONFIG_SND_AW2 is not set
++# CONFIG_SND_AZT3328 is not set
++# CONFIG_SND_BT87X is not set
++# CONFIG_SND_CA0106 is not set
++# CONFIG_SND_CMIPCI is not set
++# CONFIG_SND_OXYGEN is not set
++# CONFIG_SND_CS4281 is not set
++# CONFIG_SND_CS46XX is not set
++CONFIG_SND_CS5535AUDIO=m
++# CONFIG_SND_CTXFI is not set
++# CONFIG_SND_DARLA20 is not set
++# CONFIG_SND_GINA20 is not set
++# CONFIG_SND_LAYLA20 is not set
++# CONFIG_SND_DARLA24 is not set
++# CONFIG_SND_GINA24 is not set
++# CONFIG_SND_LAYLA24 is not set
++# CONFIG_SND_MONA is not set
++# CONFIG_SND_MIA is not set
++# CONFIG_SND_ECHO3G is not set
++# CONFIG_SND_INDIGO is not set
++# CONFIG_SND_INDIGOIO is not set
++# CONFIG_SND_INDIGODJ is not set
++# CONFIG_SND_INDIGOIOX is not set
++# CONFIG_SND_INDIGODJX is not set
++# CONFIG_SND_EMU10K1 is not set
++# CONFIG_SND_EMU10K1X is not set
++# CONFIG_SND_ENS1370 is not set
++# CONFIG_SND_ENS1371 is not set
++# CONFIG_SND_ES1938 is not set
++# CONFIG_SND_ES1968 is not set
++# CONFIG_SND_FM801 is not set
++# CONFIG_SND_HDA_INTEL is not set
++# CONFIG_SND_HDSP is not set
++# CONFIG_SND_HDSPM is not set
++# CONFIG_SND_HIFIER is not set
++# CONFIG_SND_ICE1712 is not set
++# CONFIG_SND_ICE1724 is not set
++# CONFIG_SND_INTEL8X0 is not set
++# CONFIG_SND_INTEL8X0M is not set
++# CONFIG_SND_KORG1212 is not set
++# CONFIG_SND_LX6464ES is not set
++# CONFIG_SND_MAESTRO3 is not set
++# CONFIG_SND_MIXART is not set
++# CONFIG_SND_NM256 is not set
++# CONFIG_SND_PCXHR is not set
++# CONFIG_SND_RIPTIDE is not set
++# CONFIG_SND_RME32 is not set
++# CONFIG_SND_RME96 is not set
++# CONFIG_SND_RME9652 is not set
++# CONFIG_SND_SONICVIBES is not set
++# CONFIG_SND_TRIDENT is not set
++# CONFIG_SND_VIA82XX is not set
++# CONFIG_SND_VIA82XX_MODEM is not set
++# CONFIG_SND_VIRTUOSO is not set
++# CONFIG_SND_VX222 is not set
++# CONFIG_SND_YMFPCI is not set
++# CONFIG_SND_MIPS is not set
++CONFIG_SND_USB=y
++CONFIG_SND_USB_AUDIO=m
++CONFIG_SND_USB_CAIAQ=m
++CONFIG_SND_USB_CAIAQ_INPUT=y
++# CONFIG_SND_SOC is not set
++# CONFIG_SOUND_PRIME is not set
++CONFIG_AC97_BUS=m
++CONFIG_HID_SUPPORT=y
++CONFIG_HID=y
++CONFIG_HIDRAW=y
++
++#
++# USB Input Devices
++#
++CONFIG_USB_HID=y
++# CONFIG_HID_PID is not set
++CONFIG_USB_HIDDEV=y
++
++#
++# Special HID drivers
++#
++# CONFIG_HID_A4TECH is not set
++CONFIG_HID_APPLE=m
++# CONFIG_HID_BELKIN is not set
++# CONFIG_HID_CHERRY is not set
++# CONFIG_HID_CHICONY is not set
++# CONFIG_HID_CYPRESS is not set
++# CONFIG_HID_DRAGONRISE is not set
++# CONFIG_HID_EZKEY is not set
++# CONFIG_HID_KYE is not set
++# CONFIG_HID_GYRATION is not set
++# CONFIG_HID_TWINHAN is not set
++# CONFIG_HID_KENSINGTON is not set
++# CONFIG_HID_LOGITECH is not set
++# CONFIG_HID_MICROSOFT is not set
++# CONFIG_HID_MONTEREY is not set
++# CONFIG_HID_NTRIG is not set
++# CONFIG_HID_PANTHERLORD is not set
++# CONFIG_HID_PETALYNX is not set
++# CONFIG_HID_SAMSUNG is not set
++# CONFIG_HID_SONY is not set
++# CONFIG_HID_SUNPLUS is not set
++# CONFIG_HID_GREENASIA is not set
++# CONFIG_HID_SMARTJOYPLUS is not set
++# CONFIG_HID_TOPSEED is not set
++# CONFIG_HID_THRUSTMASTER is not set
++# CONFIG_HID_WACOM is not set
++# CONFIG_HID_ZEROPLUS is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
++CONFIG_USB_ARCH_HAS_EHCI=y
++CONFIG_USB=y
++# CONFIG_USB_DEBUG is not set
++# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
++
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEVICEFS=y
++# CONFIG_USB_DEVICE_CLASS is not set
++CONFIG_USB_DYNAMIC_MINORS=y
++CONFIG_USB_SUSPEND=y
++# CONFIG_USB_OTG is not set
++CONFIG_USB_OTG_WHITELIST=y
++# CONFIG_USB_OTG_BLACKLIST_HUB is not set
++CONFIG_USB_MON=y
++CONFIG_USB_WUSB=m
++# CONFIG_USB_WUSB_CBAF is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_C67X00_HCD is not set
++# CONFIG_USB_XHCI_HCD is not set
++CONFIG_USB_EHCI_HCD=y
++CONFIG_USB_EHCI_ROOT_HUB_TT=y
++# CONFIG_USB_EHCI_TT_NEWSCHED is not set
++# CONFIG_USB_OXU210HP_HCD is not set
++# CONFIG_USB_ISP116X_HCD is not set
++# CONFIG_USB_ISP1760_HCD is not set
++# CONFIG_USB_ISP1362_HCD is not set
++CONFIG_USB_OHCI_HCD=y
++# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
++# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
++CONFIG_USB_OHCI_LITTLE_ENDIAN=y
++CONFIG_USB_UHCI_HCD=m
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++CONFIG_USB_WHCI_HCD=m
++CONFIG_USB_HWA_HCD=m
++# CONFIG_USB_GADGET_MUSB_HDRC is not set
++
++#
++# USB Device Class drivers
++#
++CONFIG_USB_ACM=m
++CONFIG_USB_PRINTER=m
++CONFIG_USB_WDM=m
++# CONFIG_USB_TMC is not set
++
++#
++# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
++#
++
++#
++# also be needed; see USB_STORAGE Help for more info
++#
++CONFIG_USB_STORAGE=m
++# CONFIG_USB_STORAGE_DEBUG is not set
++CONFIG_USB_STORAGE_DATAFAB=m
++CONFIG_USB_STORAGE_FREECOM=m
++CONFIG_USB_STORAGE_ISD200=m
++CONFIG_USB_STORAGE_USBAT=m
++CONFIG_USB_STORAGE_SDDR09=m
++CONFIG_USB_STORAGE_SDDR55=m
++CONFIG_USB_STORAGE_JUMPSHOT=m
++CONFIG_USB_STORAGE_ALAUDA=m
++# CONFIG_USB_STORAGE_ONETOUCH is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
++CONFIG_USB_LIBUSUAL=y
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++
++#
++# USB port drivers
++#
++CONFIG_USB_SERIAL=m
++# CONFIG_USB_EZUSB is not set
++CONFIG_USB_SERIAL_GENERIC=y
++# CONFIG_USB_SERIAL_AIRCABLE is not set
++# CONFIG_USB_SERIAL_ARK3116 is not set
++# CONFIG_USB_SERIAL_BELKIN is not set
++# CONFIG_USB_SERIAL_CH341 is not set
++# CONFIG_USB_SERIAL_WHITEHEAT is not set
++# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
++# CONFIG_USB_SERIAL_CP210X is not set
++# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
++# CONFIG_USB_SERIAL_EMPEG is not set
++# CONFIG_USB_SERIAL_FTDI_SIO is not set
++# CONFIG_USB_SERIAL_FUNSOFT is not set
++# CONFIG_USB_SERIAL_VISOR is not set
++# CONFIG_USB_SERIAL_IPAQ is not set
++# CONFIG_USB_SERIAL_IR is not set
++# CONFIG_USB_SERIAL_EDGEPORT is not set
++# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
++# CONFIG_USB_SERIAL_GARMIN is not set
++# CONFIG_USB_SERIAL_IPW is not set
++# CONFIG_USB_SERIAL_IUU is not set
++# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
++# CONFIG_USB_SERIAL_KEYSPAN is not set
++# CONFIG_USB_SERIAL_KLSI is not set
++# CONFIG_USB_SERIAL_KOBIL_SCT is not set
++# CONFIG_USB_SERIAL_MCT_U232 is not set
++# CONFIG_USB_SERIAL_MOS7720 is not set
++# CONFIG_USB_SERIAL_MOS7840 is not set
++# CONFIG_USB_SERIAL_MOTOROLA is not set
++# CONFIG_USB_SERIAL_NAVMAN is not set
++# CONFIG_USB_SERIAL_PL2303 is not set
++# CONFIG_USB_SERIAL_OTI6858 is not set
++# CONFIG_USB_SERIAL_QUALCOMM is not set
++# CONFIG_USB_SERIAL_SPCP8X5 is not set
++# CONFIG_USB_SERIAL_HP4X is not set
++# CONFIG_USB_SERIAL_SAFE is not set
++# CONFIG_USB_SERIAL_SIEMENS_MPI is not set
++# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
++# CONFIG_USB_SERIAL_SYMBOL is not set
++# CONFIG_USB_SERIAL_TI is not set
++# CONFIG_USB_SERIAL_CYBERJACK is not set
++# CONFIG_USB_SERIAL_XIRCOM is not set
++# CONFIG_USB_SERIAL_OPTION is not set
++# CONFIG_USB_SERIAL_OMNINET is not set
++# CONFIG_USB_SERIAL_OPTICON is not set
++# CONFIG_USB_SERIAL_DEBUG is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_SEVSEG is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_BERRY_CHARGE is not set
++CONFIG_USB_LED=m
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_SISUSBVGA is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++# CONFIG_USB_IOWARRIOR is not set
++# CONFIG_USB_TEST is not set
++# CONFIG_USB_ISIGHTFW is not set
++# CONFIG_USB_VST is not set
++CONFIG_USB_GADGET=m
++# CONFIG_USB_GADGET_DEBUG_FILES is not set
++# CONFIG_USB_GADGET_DEBUG_FS is not set
++CONFIG_USB_GADGET_VBUS_DRAW=2
++CONFIG_USB_GADGET_SELECTED=y
++# CONFIG_USB_GADGET_AT91 is not set
++# CONFIG_USB_GADGET_ATMEL_USBA is not set
++# CONFIG_USB_GADGET_FSL_USB2 is not set
++# CONFIG_USB_GADGET_LH7A40X is not set
++# CONFIG_USB_GADGET_OMAP is not set
++# CONFIG_USB_GADGET_PXA25X is not set
++# CONFIG_USB_GADGET_R8A66597 is not set
++# CONFIG_USB_GADGET_PXA27X is not set
++# CONFIG_USB_GADGET_S3C_HSOTG is not set
++# CONFIG_USB_GADGET_IMX is not set
++# CONFIG_USB_GADGET_S3C2410 is not set
++CONFIG_USB_GADGET_M66592=y
++CONFIG_USB_M66592=m
++# CONFIG_USB_GADGET_AMD5536UDC is not set
++# CONFIG_USB_GADGET_FSL_QE is not set
++# CONFIG_USB_GADGET_CI13XXX is not set
++# CONFIG_USB_GADGET_NET2280 is not set
++# CONFIG_USB_GADGET_GOKU is not set
++# CONFIG_USB_GADGET_LANGWELL is not set
++# CONFIG_USB_GADGET_DUMMY_HCD is not set
++CONFIG_USB_GADGET_DUALSPEED=y
++# CONFIG_USB_ZERO is not set
++# CONFIG_USB_AUDIO is not set
++# CONFIG_USB_ETH is not set
++# CONFIG_USB_GADGETFS is not set
++# CONFIG_USB_FILE_STORAGE is not set
++# CONFIG_USB_G_SERIAL is not set
++# CONFIG_USB_MIDI_GADGET is not set
++# CONFIG_USB_G_PRINTER is not set
++# CONFIG_USB_CDC_COMPOSITE is not set
++
++#
++# OTG and related infrastructure
++#
++# CONFIG_NOP_USB_XCEIV is not set
++CONFIG_UWB=m
++CONFIG_UWB_HWA=m
++CONFIG_UWB_WHCI=m
++# CONFIG_UWB_WLP is not set
++# CONFIG_UWB_I1480U is not set
++CONFIG_MMC=m
++# CONFIG_MMC_DEBUG is not set
++# CONFIG_MMC_UNSAFE_RESUME is not set
++
++#
++# MMC/SD/SDIO Card Drivers
++#
++CONFIG_MMC_BLOCK=m
++CONFIG_MMC_BLOCK_BOUNCE=y
++# CONFIG_SDIO_UART is not set
++# CONFIG_MMC_TEST is not set
++
++#
++# MMC/SD/SDIO Host Controller Drivers
++#
++# CONFIG_MMC_SDHCI is not set
++# CONFIG_MMC_AT91 is not set
++# CONFIG_MMC_ATMELMCI is not set
++# CONFIG_MMC_TIFM_SD is not set
++# CONFIG_MMC_CB710 is not set
++# CONFIG_MMC_VIA_SDMMC is not set
++# CONFIG_MEMSTICK is not set
++CONFIG_NEW_LEDS=y
++CONFIG_LEDS_CLASS=m
++
++#
++# LED drivers
++#
++
++#
++# LED Triggers
++#
++CONFIG_LEDS_TRIGGERS=y
++# CONFIG_LEDS_TRIGGER_TIMER is not set
++# CONFIG_LEDS_TRIGGER_IDE_DISK is not set
++# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
++# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
++# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
++
++#
++# iptables trigger is under Netfilter config (LED target)
++#
++# CONFIG_ACCESSIBILITY is not set
++# CONFIG_INFINIBAND is not set
++CONFIG_RTC_LIB=y
++CONFIG_RTC_CLASS=y
++CONFIG_RTC_HCTOSYS=y
++CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
++# CONFIG_RTC_DEBUG is not set
++
++#
++# RTC interfaces
++#
++CONFIG_RTC_INTF_SYSFS=y
++CONFIG_RTC_INTF_PROC=y
++CONFIG_RTC_INTF_DEV=y
++# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
++# CONFIG_RTC_DRV_TEST is not set
++
++#
++# SPI RTC drivers
++#
++
++#
++# Platform RTC drivers
++#
++CONFIG_RTC_DRV_CMOS=y
++# CONFIG_RTC_DRV_DS1286 is not set
++# CONFIG_RTC_DRV_DS1511 is not set
++# CONFIG_RTC_DRV_DS1553 is not set
++# CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
++# CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T35 is not set
++# CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_BQ4802 is not set
++# CONFIG_RTC_DRV_V3020 is not set
++
++#
++# on-CPU RTC drivers
++#
++# CONFIG_DMADEVICES is not set
++# CONFIG_AUXDISPLAY is not set
++# CONFIG_UIO is not set
++
++#
++# TI VLYNQ
++#
++CONFIG_STAGING=y
++# CONFIG_STAGING_EXCLUDE_BUILD is not set
++# CONFIG_ET131X is not set
++# CONFIG_USB_IP_COMMON is not set
++# CONFIG_W35UND is not set
++# CONFIG_PRISM2_USB is not set
++# CONFIG_ECHO is not set
++# CONFIG_OTUS is not set
++# CONFIG_COMEDI is not set
++# CONFIG_ASUS_OLED is not set
++# CONFIG_ALTERA_PCIE_CHDMA is not set
++# CONFIG_RTL8187SE is not set
++# CONFIG_RTL8192SU is not set
++# CONFIG_RTL8192E is not set
++# CONFIG_INPUT_MIMIO is not set
++# CONFIG_TRANZPORT is not set
++
++#
++# Android
++#
++
++#
++# Qualcomm MSM Camera And Video
++#
++
++#
++# Camera Sensor Selection
++#
++# CONFIG_INPUT_GPIO is not set
++# CONFIG_DST is not set
++# CONFIG_POHMELFS is not set
++# CONFIG_B3DFG is not set
++# CONFIG_PLAN9AUTH is not set
++# CONFIG_LINE6_USB is not set
++# CONFIG_USB_SERIAL_QUATECH2 is not set
++# CONFIG_USB_SERIAL_QUATECH_USB2 is not set
++# CONFIG_VT6655 is not set
++# CONFIG_VT6656 is not set
++# CONFIG_FB_UDL is not set
++# CONFIG_VME_BUS is not set
++
++#
++# RAR Register Driver
++#
++# CONFIG_RAR_REGISTER is not set
++# CONFIG_IIO is not set
++CONFIG_FB_SM7XX=y
++# CONFIG_FB_SM7XX_ACCEL is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=m
++CONFIG_EXT2_FS_XATTR=y
++CONFIG_EXT2_FS_POSIX_ACL=y
++CONFIG_EXT2_FS_SECURITY=y
++# CONFIG_EXT2_FS_XIP is not set
++CONFIG_EXT3_FS=y
++# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
++CONFIG_EXT3_FS_XATTR=y
++CONFIG_EXT3_FS_POSIX_ACL=y
++CONFIG_EXT3_FS_SECURITY=y
++CONFIG_EXT4_FS=y
++CONFIG_EXT4_FS_XATTR=y
++CONFIG_EXT4_FS_POSIX_ACL=y
++CONFIG_EXT4_FS_SECURITY=y
++# CONFIG_EXT4_DEBUG is not set
++CONFIG_JBD=y
++# CONFIG_JBD_DEBUG is not set
++CONFIG_JBD2=y
++# CONFIG_JBD2_DEBUG is not set
++CONFIG_FS_MBCACHE=y
++CONFIG_REISERFS_FS=m
++# CONFIG_REISERFS_CHECK is not set
++CONFIG_REISERFS_PROC_INFO=y
++CONFIG_REISERFS_FS_XATTR=y
++# CONFIG_REISERFS_FS_POSIX_ACL is not set
++# CONFIG_REISERFS_FS_SECURITY is not set
++CONFIG_JFS_FS=m
++CONFIG_JFS_POSIX_ACL=y
++# CONFIG_JFS_SECURITY is not set
++# CONFIG_JFS_DEBUG is not set
++# CONFIG_JFS_STATISTICS is not set
++CONFIG_FS_POSIX_ACL=y
++CONFIG_XFS_FS=m
++CONFIG_XFS_QUOTA=y
++CONFIG_XFS_POSIX_ACL=y
++# CONFIG_XFS_RT is not set
++# CONFIG_XFS_DEBUG is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++CONFIG_BTRFS_FS=m
++# CONFIG_BTRFS_FS_POSIX_ACL is not set
++# CONFIG_NILFS2_FS is not set
++CONFIG_FILE_LOCKING=y
++CONFIG_FSNOTIFY=y
++CONFIG_DNOTIFY=y
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++CONFIG_QUOTA=y
++# CONFIG_QUOTA_NETLINK_INTERFACE is not set
++CONFIG_PRINT_QUOTA_WARNING=y
++CONFIG_QUOTA_TREE=m
++# CONFIG_QFMT_V1 is not set
++CONFIG_QFMT_V2=m
++CONFIG_QUOTACTL=y
++CONFIG_AUTOFS_FS=m
++CONFIG_AUTOFS4_FS=m
++# CONFIG_FUSE_FS is not set
++
++#
++# Caches
++#
++CONFIG_FSCACHE=m
++# CONFIG_FSCACHE_STATS is not set
++# CONFIG_FSCACHE_HISTOGRAM is not set
++# CONFIG_FSCACHE_DEBUG is not set
++# CONFIG_FSCACHE_OBJECT_LIST is not set
++CONFIG_CACHEFILES=m
++# CONFIG_CACHEFILES_DEBUG is not set
++# CONFIG_CACHEFILES_HISTOGRAM is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++CONFIG_ISO9660_FS=m
++CONFIG_JOLIET=y
++CONFIG_ZISOFS=y
++CONFIG_UDF_FS=m
++CONFIG_UDF_NLS=y
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=m
++CONFIG_MSDOS_FS=m
++CONFIG_VFAT_FS=m
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++CONFIG_NTFS_FS=m
++# CONFIG_NTFS_DEBUG is not set
++CONFIG_NTFS_RW=y
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_KCORE=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++# CONFIG_TMPFS_POSIX_ACL is not set
++# CONFIG_HUGETLB_PAGE is not set
++CONFIG_CONFIGFS_FS=m
++CONFIG_MISC_FILESYSTEMS=y
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++CONFIG_ECRYPT_FS=m
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++CONFIG_CRAMFS=m
++CONFIG_SQUASHFS=m
++CONFIG_SQUASHFS_EMBEDDED=y
++CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_OMFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++CONFIG_ROMFS_FS=m
++CONFIG_ROMFS_BACKED_BY_BLOCK=y
++# CONFIG_ROMFS_BACKED_BY_MTD is not set
++# CONFIG_ROMFS_BACKED_BY_BOTH is not set
++CONFIG_ROMFS_ON_BLOCK=y
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=m
++CONFIG_NFS_V3=y
++CONFIG_NFS_V3_ACL=y
++# CONFIG_NFS_V4 is not set
++# CONFIG_NFS_FSCACHE is not set
++CONFIG_NFSD=m
++CONFIG_NFSD_V3=y
++# CONFIG_NFSD_V3_ACL is not set
++CONFIG_NFSD_V4=y
++CONFIG_LOCKD=m
++CONFIG_LOCKD_V4=y
++CONFIG_EXPORTFS=m
++CONFIG_NFS_ACL_SUPPORT=m
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=m
++CONFIG_SUNRPC_GSS=m
++CONFIG_RPCSEC_GSS_KRB5=m
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
++# CONFIG_SMB_FS is not set
++CONFIG_CIFS=m
++# CONFIG_CIFS_STATS is not set
++# CONFIG_CIFS_WEAK_PW_HASH is not set
++# CONFIG_CIFS_UPCALL is not set
++# CONFIG_CIFS_XATTR is not set
++# CONFIG_CIFS_DEBUG2 is not set
++# CONFIG_CIFS_DFS_UPCALL is not set
++# CONFIG_CIFS_EXPERIMENTAL is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="utf-8"
++CONFIG_NLS_CODEPAGE_437=m
++CONFIG_NLS_CODEPAGE_737=m
++CONFIG_NLS_CODEPAGE_775=m
++CONFIG_NLS_CODEPAGE_850=m
++CONFIG_NLS_CODEPAGE_852=m
++CONFIG_NLS_CODEPAGE_855=m
++CONFIG_NLS_CODEPAGE_857=m
++CONFIG_NLS_CODEPAGE_860=m
++CONFIG_NLS_CODEPAGE_861=m
++CONFIG_NLS_CODEPAGE_862=m
++CONFIG_NLS_CODEPAGE_863=m
++CONFIG_NLS_CODEPAGE_864=m
++CONFIG_NLS_CODEPAGE_865=m
++CONFIG_NLS_CODEPAGE_866=m
++CONFIG_NLS_CODEPAGE_869=m
++CONFIG_NLS_CODEPAGE_936=m
++CONFIG_NLS_CODEPAGE_950=m
++CONFIG_NLS_CODEPAGE_932=m
++CONFIG_NLS_CODEPAGE_949=m
++CONFIG_NLS_CODEPAGE_874=m
++CONFIG_NLS_ISO8859_8=m
++CONFIG_NLS_CODEPAGE_1250=m
++CONFIG_NLS_CODEPAGE_1251=m
++CONFIG_NLS_ASCII=m
++CONFIG_NLS_ISO8859_1=m
++CONFIG_NLS_ISO8859_2=m
++CONFIG_NLS_ISO8859_3=m
++CONFIG_NLS_ISO8859_4=m
++CONFIG_NLS_ISO8859_5=m
++CONFIG_NLS_ISO8859_6=m
++CONFIG_NLS_ISO8859_7=m
++CONFIG_NLS_ISO8859_9=m
++CONFIG_NLS_ISO8859_13=m
++CONFIG_NLS_ISO8859_14=m
++CONFIG_NLS_ISO8859_15=m
++CONFIG_NLS_KOI8_R=m
++CONFIG_NLS_KOI8_U=m
++CONFIG_NLS_UTF8=y
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_PRINTK_TIME=y
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_FRAME_WARN=1024
++CONFIG_MAGIC_SYSRQ=y
++CONFIG_STRIP_ASM_SYMS=y
++# CONFIG_UNUSED_SYMBOLS is not set
++CONFIG_DEBUG_FS=y
++# CONFIG_HEADERS_CHECK is not set
++# CONFIG_DEBUG_KERNEL is not set
++# CONFIG_SLUB_DEBUG_ON is not set
++# CONFIG_SLUB_STATS is not set
++CONFIG_STACKTRACE=y
++# CONFIG_DEBUG_MEMORY_INIT is not set
++# CONFIG_RCU_CPU_STALL_DETECTOR is not set
++CONFIG_SYSCTL_SYSCALL_CHECK=y
++CONFIG_NOP_TRACER=y
++CONFIG_HAVE_FUNCTION_TRACER=y
++CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
++CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
++CONFIG_HAVE_DYNAMIC_FTRACE=y
++CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
++CONFIG_RING_BUFFER=y
++CONFIG_EVENT_TRACING=y
++CONFIG_CONTEXT_SWITCH_TRACER=y
++CONFIG_RING_BUFFER_ALLOW_SWAP=y
++CONFIG_TRACING=y
++CONFIG_TRACING_SUPPORT=y
++# CONFIG_FTRACE is not set
++# CONFIG_DYNAMIC_DEBUG is not set
++# CONFIG_SAMPLES is not set
++CONFIG_HAVE_ARCH_KGDB=y
++CONFIG_CMDLINE=""
++
++#
++# Security options
++#
++CONFIG_KEYS=y
++CONFIG_KEYS_DEBUG_PROC_KEYS=y
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITYFS is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_XOR_BLOCKS=m
++CONFIG_ASYNC_CORE=m
++CONFIG_ASYNC_MEMCPY=m
++CONFIG_ASYNC_XOR=m
++CONFIG_ASYNC_PQ=m
++CONFIG_ASYNC_RAID6_RECOV=m
++CONFIG_CRYPTO=y
++
++#
++# Crypto core or helper
++#
++CONFIG_CRYPTO_FIPS=y
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_ALGAPI2=y
++CONFIG_CRYPTO_AEAD=m
++CONFIG_CRYPTO_AEAD2=y
++CONFIG_CRYPTO_BLKCIPHER=m
++CONFIG_CRYPTO_BLKCIPHER2=y
++CONFIG_CRYPTO_HASH=y
++CONFIG_CRYPTO_HASH2=y
++CONFIG_CRYPTO_RNG=m
++CONFIG_CRYPTO_RNG2=y
++CONFIG_CRYPTO_PCOMP=y
++CONFIG_CRYPTO_MANAGER=m
++CONFIG_CRYPTO_MANAGER2=y
++CONFIG_CRYPTO_GF128MUL=m
++CONFIG_CRYPTO_NULL=m
++CONFIG_CRYPTO_WORKQUEUE=y
++CONFIG_CRYPTO_CRYPTD=m
++CONFIG_CRYPTO_AUTHENC=m
++CONFIG_CRYPTO_TEST=m
++
++#
++# Authenticated Encryption with Associated Data
++#
++CONFIG_CRYPTO_CCM=m
++CONFIG_CRYPTO_GCM=m
++CONFIG_CRYPTO_SEQIV=m
++
++#
++# Block modes
++#
++CONFIG_CRYPTO_CBC=m
++CONFIG_CRYPTO_CTR=m
++# CONFIG_CRYPTO_CTS is not set
++CONFIG_CRYPTO_ECB=m
++CONFIG_CRYPTO_LRW=m
++CONFIG_CRYPTO_PCBC=m
++CONFIG_CRYPTO_XTS=m
++
++#
++# Hash modes
++#
++CONFIG_CRYPTO_HMAC=m
++CONFIG_CRYPTO_XCBC=m
++# CONFIG_CRYPTO_VMAC is not set
++
++#
++# Digest
++#
++CONFIG_CRYPTO_CRC32C=m
++CONFIG_CRYPTO_GHASH=m
++CONFIG_CRYPTO_MD4=m
++CONFIG_CRYPTO_MD5=y
++CONFIG_CRYPTO_MICHAEL_MIC=m
++CONFIG_CRYPTO_RMD128=m
++CONFIG_CRYPTO_RMD160=m
++CONFIG_CRYPTO_RMD256=m
++CONFIG_CRYPTO_RMD320=m
++CONFIG_CRYPTO_SHA1=m
++CONFIG_CRYPTO_SHA256=m
++CONFIG_CRYPTO_SHA512=m
++CONFIG_CRYPTO_TGR192=m
++CONFIG_CRYPTO_WP512=m
++
++#
++# Ciphers
++#
++CONFIG_CRYPTO_AES=m
++CONFIG_CRYPTO_ANUBIS=m
++CONFIG_CRYPTO_ARC4=m
++CONFIG_CRYPTO_BLOWFISH=m
++CONFIG_CRYPTO_CAMELLIA=m
++CONFIG_CRYPTO_CAST5=m
++CONFIG_CRYPTO_CAST6=m
++CONFIG_CRYPTO_DES=m
++CONFIG_CRYPTO_FCRYPT=m
++CONFIG_CRYPTO_KHAZAD=m
++CONFIG_CRYPTO_SALSA20=m
++CONFIG_CRYPTO_SEED=m
++CONFIG_CRYPTO_SERPENT=m
++CONFIG_CRYPTO_TEA=m
++CONFIG_CRYPTO_TWOFISH=m
++CONFIG_CRYPTO_TWOFISH_COMMON=m
++
++#
++# Compression
++#
++CONFIG_CRYPTO_DEFLATE=m
++CONFIG_CRYPTO_ZLIB=m
++CONFIG_CRYPTO_LZO=m
++
++#
++# Random Number Generation
++#
++CONFIG_CRYPTO_ANSI_CPRNG=m
++CONFIG_CRYPTO_HW=y
++# CONFIG_CRYPTO_DEV_HIFN_795X is not set
++CONFIG_BINARY_PRINTF=y
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++CONFIG_GENERIC_FIND_LAST_BIT=y
++# CONFIG_CRC_CCITT is not set
++CONFIG_CRC16=y
++CONFIG_CRC_T10DIF=y
++CONFIG_CRC_ITU_T=m
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++CONFIG_LIBCRC32C=m
++CONFIG_AUDIT_GENERIC=y
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=m
++CONFIG_LZO_COMPRESS=m
++CONFIG_LZO_DECOMPRESS=m
++CONFIG_DECOMPRESS_GZIP=y
++CONFIG_DECOMPRESS_BZIP2=y
++CONFIG_DECOMPRESS_LZMA=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
++CONFIG_NLATTR=y
+Index: Makefile
+===================================================================
+--- Makefile.orig 2009-12-13 01:21:42.000000000 -0200
++++ Makefile 2009-12-13 01:21:45.000000000 -0200
+@@ -1,7 +1,7 @@
+ VERSION = 2
+ PATCHLEVEL = 6
+ SUBLEVEL = 32
+-EXTRAVERSION =-libre
++EXTRAVERSION =-libre-lemote
+ NAME = Man-Eating Seals of Antiquity
+
+ # *DOCUMENTATION*
diff --git a/lemote/gnewsense/tags/2.6.32-libre-lemote_0lxo/series b/lemote/gnewsense/tags/2.6.32-libre-lemote_0lxo/series
new file mode 100644
index 000000000..5993a604b
--- /dev/null
+++ b/lemote/gnewsense/tags/2.6.32-libre-lemote_0lxo/series
@@ -0,0 +1,4 @@
+2.6.32-loongson.patch -p1 # lemote's patches for 2.6.32
+# 2.6.32-yeeloong-battery.patch -p0 # no positive effect
+freedo.patch -p0 # 100% Free Software Freedo logo
+lxo-config.patch -p0 # config file
OpenPOWER on IntegriCloud