Merge tag 'v2.6.32.68' of http://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable into linux-2.6.32-stable

This is the 2.6.32.68 stable release
diff --git a/Makefile b/Makefile
index e28e263..030a267 100644
--- a/Makefile
+++ b/Makefile
@@ -180,7 +180,7 @@
 # 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 @@
 
 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 @@
 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..dc503ac 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -5,9 +5,14 @@
 	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 @@
 
 config MACH_ALCHEMY
 	bool "Alchemy processor based machines"
+	select SYS_SUPPORTS_ZBOOT
 
 config AR7
 	bool "Texas Instruments AR7"
@@ -36,6 +42,7 @@
 	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 MACH_LOONGSON
 	bool "Loongson family of machines"
+	select SYS_SUPPORTS_ZBOOT
 	help
 	  This enables the support of Loongson family of machines.
 
@@ -233,6 +241,7 @@
 	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 @@
 	  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
@@ -501,6 +528,7 @@
 	bool "Sibyte BCM91250A-SWARM"
 	select BOOT_ELF32
 	select DMA_COHERENT
+	select HAVE_PATA_PLATFORM
 	select NR_CPUS_DEFAULT_2
 	select SIBYTE_SB1250
 	select SWAP_IO_SPACE
@@ -515,6 +543,7 @@
 	depends on EXPERIMENTAL
 	select BOOT_ELF32
 	select DMA_COHERENT
+	select HAVE_PATA_PLATFORM
 	select NR_CPUS_DEFAULT_2
 	select SIBYTE_SB1250
 	select SWAP_IO_SPACE
@@ -679,6 +708,7 @@
 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 +808,9 @@
 config CSRC_IOASIC
 	bool
 
+config CSRC_POWERTV
+	bool
+
 config CSRC_R4K_LIB
 	bool
 
@@ -807,8 +840,8 @@
 	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 +1102,23 @@
 	  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
+	select GENERIC_GPIO
+	select ARCH_REQUIRE_GPIOLIB
+	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 +1344,17 @@
 
 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 +1364,12 @@
 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 +1478,17 @@
 	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 +1972,27 @@
 source "kernel/time/Kconfig"
 
 #
+# High Resolution sched_clock() Configuration
+#
+
+config CPU_HAS_FIXED_C0_COUNT
+	bool
+
+config HR_SCHED_CLOCK
+	bool "High Resolution sched_clock()"
+	depends on CSRC_R4K && (CPU_HAS_FIXED_C0_COUNT || !CPU_FREQ)
+	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 +2121,6 @@
 
 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 +2192,7 @@
 
 config I8253
 	bool
+	select MIPS_EXTERNAL_TIMER
 
 config ZONE_DMA32
 	bool
@@ -2180,6 +2269,8 @@
 
 endmenu
 
+source "arch/mips/kernel/cpufreq/Kconfig"
+
 source "net/Kconfig"
 
 source "drivers/Kconfig"
diff --git a/arch/mips/Kconfig.debug b/arch/mips/Kconfig.debug
index 364ca89..9a48472 100644
--- a/arch/mips/Kconfig.debug
+++ b/arch/mips/Kconfig.debug
@@ -51,4 +51,22 @@
 	  arch/mips/include/asm/debug.h for debugging macros.
 	  If unsure, say N.
 
+config DEBUG_ZBOOT
+	bool "Enable compressed kernel support debugging"
+	depends on DEBUG_KERNEL && SYS_SUPPORTS_ZBOOT
+	help
+	  If you want to add compressed kernel support to a new board, and the
+	  board supports uart16550 compatible serial port, please select
+	  SYS_SUPPORTS_ZBOOT_UART16550 for your board and enable this option to
+	  debug it.
+
+	  If your board doesn't support uart16550 compatible serial port, you
+	  can try to select SYS_SUPPORTS_ZBOOT and use the other methods to
+	  debug it. for example, add a new serial port support just as
+	  arch/mips/boot/compressed/uart-16550.c does.
+
+	  After the compressed kernel support works, please disable this option
+	  to reduce the kernel image size and speed up the booting procedure a
+	  little.
+
 endmenu
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 57ff855..838efcb 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -48,7 +48,16 @@
   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 @@
 
 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_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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 	$(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 @@
 
 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 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 	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..fc13203 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 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 @@
 	 * 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)
@@ -412,8 +411,11 @@
 		if (desc_base == 0)
 			return 0;
 
+		ctp->cdb_membase = desc_base;
 		desc_base = ALIGN_ADDR(desc_base, sizeof(au1x_ddma_desc_t));
-	}
+	} else
+		ctp->cdb_membase = desc_base;
+
 	dp = (au1x_ddma_desc_t *)desc_base;
 
 	/* Keep track of the base descriptor. */
@@ -569,7 +571,7 @@
  * 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 +597,7 @@
 		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 +624,13 @@
 	/* 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 +660,7 @@
 	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 +686,7 @@
 	/* 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.
@@ -831,7 +832,7 @@
 
 	au1xxx_dbdma_stop(chanid);
 
-	kfree((void *)ctp->chan_desc_base);
+	kfree((void *)ctp->cdb_membase);
 
 	stp->dev_flags &= ~DEV_FLAGS_INUSE;
 	dtp->dev_flags &= ~DEV_FLAGS_INUSE;
@@ -868,28 +869,6 @@
 	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 +1017,38 @@
 	}
 }
 #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 @@
 		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 @@
 	}
 
 	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 @@
  * 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 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 @@
 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 @@
 	} 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 @@
 		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 @@
 	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 @@
 	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 @@
 	/*
 	 * 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>
+#include <asm/mach-au1x00/au1xxx_eth.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 	\
+#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 @@
 		.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 @@
 		.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 @@
 #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 @@
 };
 #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 @@
 #ifdef SMBUS_PSC_BASE
 	&pbdb_smbus_device,
 #endif
+	&au1xxx_eth0_device,
 };
 
 static int __init au1xxx_platform_init(void)
@@ -362,6 +440,12 @@
 	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 @@
 #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 @@
 	 * 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 @@
 	.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 @@
 	.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 @@
 	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 @@
 	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_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
 
-static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
+/*
+ * 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 */
+};
+
+
+#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 @@
 
 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 @@
 	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 @@
 #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");
-#endif
 }
+
+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 __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 @@
 		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 @@
 
 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 @@
 	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 @@
 		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 @@
 
 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 @@
 		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 @@
 
 	/*
 	 * 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_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 @@
 {
 	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 @@
 	.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 @@
 		.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 @@
 		.cd_setup	= NULL,		/* use poll-timer in driver */
 		.led		= &pb1200mmc_led,
 	},
-#endif
 };
 
 static struct resource ide_resources[] = {
@@ -169,8 +168,36 @@
 
 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 @@
 
 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 @@
 	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 @@
 		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 @@
 
 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 @@
 	}
 #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 @@
 	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 @@
 		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 @@
 	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 @@
 		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 @@
 	/* 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 @@
 #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 @@
 		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/ar7/platform.c b/arch/mips/ar7/platform.c
index 835f3f0..9a10b27 100644
--- a/arch/mips/ar7/platform.c
+++ b/arch/mips/ar7/platform.c
@@ -202,7 +202,7 @@
 		.name = "mem",
 		.flags = IORESOURCE_MEM,
 		.start = 0x03400000,
-		.end = 0x034001fff,
+		.end = 0x03401fff,
 	},
 };
 
@@ -509,7 +509,7 @@
 
 	memset(uart_port, 0, sizeof(struct uart_port) * 2);
 
-	uart_port[0].type = PORT_16550A;
+	uart_port[0].type = PORT_AR7;
 	uart_port[0].line = 0;
 	uart_port[0].irq = AR7_IRQ_UART0;
 	uart_port[0].uartclk = ar7_bus_freq() / 2;
diff --git a/arch/mips/bcm47xx/prom.c b/arch/mips/bcm47xx/prom.c
index fb284c3..29d3cbf 100644
--- a/arch/mips/bcm47xx/prom.c
+++ b/arch/mips/bcm47xx/prom.c
@@ -100,11 +100,11 @@
 
 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 @@
 	 * 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]);
 	}
 }
@@ -141,6 +141,14 @@
 			break;
 	}
 
+	/* Ignoring the last page when ddr size is 128M. Cached
+	 * accesses to last page is causing the processor to prefetch
+	 * using address above 128M stepping out of the ddr address
+	 * space.
+	 */
+	if (mem == 0x8000000)
+		mem -= 0x1000;
+
 	add_memory_region(0, mem, BOOT_MEM_RAM);
 }
 
diff --git a/arch/mips/bcm63xx/boards/board_bcm963xx.c b/arch/mips/bcm63xx/boards/board_bcm963xx.c
index 05a35cf..0866540 100644
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -660,6 +660,17 @@
 	}
 
 	bcm_gpio_writel(val, GPIO_MODE_REG);
+
+	/* Generate MAC address for WLAN and
+	 * register our SPROM */
+#ifdef CONFIG_SSB_PCIHOST
+	if (!board_get_mac_address(bcm63xx_sprom.il0mac)) {
+		memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN);
+		memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN);
+		if (ssb_arch_set_fallback_sprom(&bcm63xx_sprom) < 0)
+			printk(KERN_ERR "failed to register fallback SPROM\n");
+	}
+#endif
 }
 
 /*
@@ -807,17 +818,6 @@
 	if (board.has_dsp)
 		bcm63xx_dsp_register(&board.dsp);
 
-	/* Generate MAC address for WLAN and
-	 * register our SPROM */
-#ifdef CONFIG_SSB_PCIHOST
-	if (!board_get_mac_address(bcm63xx_sprom.il0mac)) {
-		memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN);
-		memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN);
-		if (ssb_arch_set_fallback_sprom(&bcm63xx_sprom) < 0)
-			printk(KERN_ERR "failed to register fallback SPROM\n");
-	}
-#endif
-
 	/* read base address of boot chip select (0) */
 	if (BCMCPU_IS_6345())
 		val = 0x1fc00000;
diff --git a/arch/mips/bcm63xx/gpio.c b/arch/mips/bcm63xx/gpio.c
index 87ca390..315bc7f 100644
--- a/arch/mips/bcm63xx/gpio.c
+++ b/arch/mips/bcm63xx/gpio.c
@@ -125,10 +125,10 @@
 
 int __init bcm63xx_gpio_init(void)
 {
+	gpio_out_low = bcm_gpio_readl(GPIO_DATA_LO_REG);
+	gpio_out_high = bcm_gpio_readl(GPIO_DATA_HI_REG);
 	bcm63xx_gpio_chip.ngpio = bcm63xx_gpio_count();
 	pr_info("registering %d GPIOs\n", bcm63xx_gpio_chip.ngpio);
 
 	return gpiochip_add(&bcm63xx_gpio_chip);
 }
-
-arch_initcall(bcm63xx_gpio_init);
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 @@
 
 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.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..23cc663
--- /dev/null
+++ b/arch/mips/boot/compressed/Makefile
@@ -0,0 +1,104 @@
+#
+# 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 -n $$(($(VMLINUX_SIZE) + (65536 - $(VMLINUX_SIZE) % 65536))))
+# VMLINUZ_LOAD_ADDRESS = concat "high32 of VMLINUX_LOAD_ADDRESS" and "(low32 of VMLINUX_LOAD_ADDRESS) + VMLINUX_SIZE"
+HIGH32 := $(shell A=$(VMLINUX_LOAD_ADDRESS); [ $${\#A} -gt 10 ] && expr substr "$(VMLINUX_LOAD_ADDRESS)" 3 $$(($${\#A} - 10)))
+LOW32 := $(shell [ -n "$(HIGH32)" ] && A=11 || A=3; expr substr "$(VMLINUX_LOAD_ADDRESS)" $${A} 8)
+VMLINUZ_LOAD_ADDRESS := 0x$(shell [ -n "$(VMLINUX_SIZE)" -a -n "$(LOW32)" ] && printf "$(HIGH32)%08x" $$(($(VMLINUX_SIZE) + 0x$(LOW32))))
+
+# 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__ \
+	-DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) \
+	-DKERNEL_ENTRY=0x$(shell $(NM) $(objtree)/$(KBUILD_IMAGE) 2>/dev/null | grep " kernel_entry" | cut -f1 -d \ )
+
+obj-y := $(obj)/head.o $(obj)/decompress.o $(obj)/dbg.o $(obj)/cache.o
+
+ifdef CONFIG_DEBUG_ZBOOT
+obj-$(CONFIG_SYS_SUPPORTS_ZBOOT_UART16550) += $(obj)/uart-16550.o
+endif
+
+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..d5c5d9a
--- /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 __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 @@
 }
 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/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c
index b321d3b..9a06fa9 100644
--- a/arch/mips/cavium-octeon/setup.c
+++ b/arch/mips/cavium-octeon/setup.c
@@ -45,9 +45,6 @@
 extern void pci_console_init(const char *arg);
 #endif
 
-#ifdef CONFIG_CAVIUM_RESERVE32
-extern uint64_t octeon_reserve32_memory;
-#endif
 static unsigned long long MAX_MEMORY = 512ull << 20;
 
 struct octeon_boot_descriptor *octeon_boot_desc_ptr;
@@ -186,54 +183,6 @@
 	write_octeon_c0_dcacheerr(0);
 }
 
-#ifdef CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB
-/**
- * Called on every core to setup the wired tlb entry needed
- * if CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB is set.
- *
- */
-static void octeon_hal_setup_per_cpu_reserved32(void *unused)
-{
-	/*
-	 * The config has selected to wire the reserve32 memory for all
-	 * userspace applications. We need to put a wired TLB entry in for each
-	 * 512MB of reserve32 memory. We only handle double 256MB pages here,
-	 * so reserve32 must be multiple of 512MB.
-	 */
-	uint32_t size = CONFIG_CAVIUM_RESERVE32;
-	uint32_t entrylo0 =
-		0x7 | ((octeon_reserve32_memory & ((1ul << 40) - 1)) >> 6);
-	uint32_t entrylo1 = entrylo0 + (256 << 14);
-	uint32_t entryhi = (0x80000000UL - (CONFIG_CAVIUM_RESERVE32 << 20));
-	while (size >= 512) {
-#if 0
-		pr_info("CPU%d: Adding double wired TLB entry for 0x%lx\n",
-			smp_processor_id(), entryhi);
-#endif
-		add_wired_entry(entrylo0, entrylo1, entryhi, PM_256M);
-		entrylo0 += 512 << 14;
-		entrylo1 += 512 << 14;
-		entryhi += 512 << 20;
-		size -= 512;
-	}
-}
-#endif /* CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB */
-
-/**
- * Called to release the named block which was used to made sure
- * that nobody used the memory for something else during
- * init. Now we'll free it so userspace apps can use this
- * memory region with bootmem_alloc.
- *
- * This function is called only once from prom_free_prom_memory().
- */
-void octeon_hal_setup_reserved32(void)
-{
-#ifdef CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB
-	on_each_cpu(octeon_hal_setup_per_cpu_reserved32, NULL, 0, 1);
-#endif
-}
-
 /**
  * Reboot Octeon
  *
@@ -294,18 +243,6 @@
 	octeon_kill_core(NULL);
 }
 
-#if 0
-/**
- * Platform time init specifics.
- * Returns
- */
-void __init plat_time_init(void)
-{
-	/* Nothing special here, but we are required to have one */
-}
-
-#endif
-
 /**
  * Handle all the error condition interrupts that might occur.
  *
@@ -502,25 +439,13 @@
 	 * memory when it is getting memory from the
 	 * bootloader. Later, after the memory allocations are
 	 * complete, the reserve32 will be freed.
-	 */
-#ifdef CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB
-	if (CONFIG_CAVIUM_RESERVE32 & 0x1ff)
-		pr_err("CAVIUM_RESERVE32 isn't a multiple of 512MB. "
-		       "This is required if CAVIUM_RESERVE32_USE_WIRED_TLB "
-		       "is set\n");
-	else
-		addr = cvmx_bootmem_phy_named_block_alloc(CONFIG_CAVIUM_RESERVE32 << 20,
-							0, 0, 512 << 20,
-							"CAVIUM_RESERVE32", 0);
-#else
-	/*
+	 *
 	 * Allocate memory for RESERVED32 aligned on 2MB boundary. This
 	 * is in case we later use hugetlb entries with it.
 	 */
 	addr = cvmx_bootmem_phy_named_block_alloc(CONFIG_CAVIUM_RESERVE32 << 20,
 						0, 0, 2 << 20,
 						"CAVIUM_RESERVE32", 0);
-#endif
 	if (addr < 0)
 		pr_err("Failed to allocate CAVIUM_RESERVE32 memory area\n");
 	else
@@ -817,9 +742,4 @@
 		panic("Unable to request_irq(OCTEON_IRQ_RML)\n");
 	}
 #endif
-
-	/* This call is here so that it is performed after any TLB
-	   initializations. It needs to be after these in case the
-	   CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB option is set */
-	octeon_hal_setup_reserved32();
 }
diff --git a/arch/mips/cavium-octeon/smp.c b/arch/mips/cavium-octeon/smp.c
index c198efd..09c0b46 100644
--- a/arch/mips/cavium-octeon/smp.c
+++ b/arch/mips/cavium-octeon/smp.c
@@ -279,14 +279,6 @@
 	uint32_t avail_coremask;
 	struct cvmx_bootmem_named_block_desc *block_desc;
 
-#ifdef CONFIG_CAVIUM_OCTEON_WATCHDOG
-	/* Disable the watchdog */
-	cvmx_ciu_wdogx_t ciu_wdog;
-	ciu_wdog.u64 = cvmx_read_csr(CVMX_CIU_WDOGX(cpu));
-	ciu_wdog.s.mode = 0;
-	cvmx_write_csr(CVMX_CIU_WDOGX(cpu), ciu_wdog.u64);
-#endif
-
 	while (per_cpu(cpu_state, cpu) != CPU_DEAD)
 		cpu_relax();
 
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_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_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_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_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_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"
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
 #
-CONFIG_LOCALVERSION=""
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+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_SLOB is not set
+CONFIG_AIO=y
 
 #
-# Loadable module support
+# 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
+
+#
+# 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_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_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 @@
 #
 # 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_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_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_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_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
+# 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
-
-#
-# Plug and Play support
-#
-# CONFIG_PNPACPI is not set
-
-#
-# Block devices
-#
+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
+# 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
 
 #
-# Ethernet (1000 Mbit)
+# Enable WiMAX (Networking options) to see the WiMAX drivers
 #
 
 #
-# Ethernet (10000 Mbit)
+# USB Network Adapters
 #
-
-#
-# Token Ring devices
-#
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# PCMCIA network device support
-#
+# 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_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_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_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_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
-
-#
-# TPM devices
-#
 # 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
 
 #
-# I2C support
+# I2C Algorithms
 #
-# CONFIG_I2C is not set
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
 
 #
-# SPI support
+# I2C Hardware Bus support
 #
-# CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
 
 #
-# Dallas's 1-wire bus
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_AU1550=y
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# 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:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# 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
 
 #
-# Hardware Monitoring support
+# Native drivers
 #
-# CONFIG_HWMON is not set
-# CONFIG_HWMON_VID is not set
+# 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
 
 #
-# Multimedia devices
+# Sonics Silicon Backplane
 #
-# CONFIG_VIDEO_DEV is not set
+# CONFIG_SSB is not set
 
 #
-# Digital Video Broadcasting Devices
+# Multifunction device drivers
 #
-# CONFIG_DVB is not set
+# 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
-
-#
-# Logo configuration
-#
-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
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# HID Devices
-#
+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_HID_DEBUG is not set
+CONFIG_HIDRAW=y
 
 #
-# USB support
+# 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 is not set
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# 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 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_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
+
+#
+# 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
 #
 
 #
-# USB Gadget Support
+# also be needed; see USB_STORAGE Help for more info
 #
-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_LIBUSUAL is not set
 
 #
-# MMC/SD Card support
+# USB Imaging devices
 #
+# CONFIG_USB_MDC800 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_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
+
+#
+# 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 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
 
 #
 # 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
 
 #
-# InfiniBand support
+# 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
 
 #
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+# 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
 
 #
-# Real Time Clock
+# I2C RTC drivers
 #
-# CONFIG_RTC_CLASS 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 Engine support
+# SPI RTC drivers
 #
-# CONFIG_DMA_ENGINE is not set
+# 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 Clients
+# 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
 
 #
-# DMA Devices
+# on-CPU RTC drivers
 #
+CONFIG_RTC_DRV_AU1XXX=y
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
 
 #
-# Auxiliary Display support
+# TI VLYNQ
 #
-
-#
-# Virtualization
-#
+# 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_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_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_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..14122fc 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.12
+# Wed Apr 28 00:39:40 2010
 #
 CONFIG_MIPS=y
 
@@ -12,6 +12,7 @@
 # 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
@@ -27,6 +28,7 @@
 # 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
@@ -49,6 +51,13 @@
 # CONFIG_ALCHEMY_GPIO_INDIRECT is not set
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
 CONFIG_LEMOTE_FULOONG2E=y
+# CONFIG_LEMOTE_MACH2F is not set
+CONFIG_LOONGSON_UART_BASE=y
+
+#
+# Loongson Platform Specific Drivers
+#
+CONFIG_LOONGSON_PLATFORM_DEVICES=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
@@ -67,7 +76,6 @@
 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
@@ -84,6 +92,7 @@
 # CPU selection
 #
 CONFIG_CPU_LOONGSON2E=y
+# CONFIG_CPU_LOONGSON2F is not set
 # CONFIG_CPU_MIPS32_R1 is not set
 # CONFIG_CPU_MIPS32_R2 is not set
 # CONFIG_CPU_MIPS64_R1 is not set
@@ -105,6 +114,7 @@
 # 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_CPU_LOONGSON2=y
 CONFIG_SYS_HAS_CPU_LOONGSON2E=y
 CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
@@ -132,14 +142,13 @@
 CONFIG_GENERIC_IRQ_PROBE=y
 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_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
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
@@ -148,11 +157,13 @@
 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
@@ -180,6 +191,14 @@
 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_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
@@ -193,18 +212,18 @@
 #
 # 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
 # CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 CONFIG_NAMESPACES=y
 # CONFIG_UTS_NS is not set
@@ -235,18 +254,15 @@
 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
@@ -254,9 +270,8 @@
 #
 # 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 +298,7 @@
 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 +336,14 @@
 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 +462,7 @@
 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
@@ -465,7 +486,6 @@
 # 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
@@ -473,6 +493,7 @@
 # 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 +502,6 @@
 #
 # 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 +515,7 @@
 # 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 +525,9 @@
 # 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 +841,7 @@
 # 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 +889,7 @@
 # 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 +905,7 @@
 # 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 +953,16 @@
 # 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 +970,7 @@
 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 +1040,7 @@
 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 +1096,6 @@
 # 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 +1111,6 @@
 # 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 +1127,7 @@
 # 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 +1137,7 @@
 #
 # Graphics support
 #
+CONFIG_VGA_ARB=y
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1198,6 +1222,7 @@
 # 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
@@ -1248,6 +1273,7 @@
 # CONFIG_SND_OXYGEN is not set
 # CONFIG_SND_CS4281 is not set
 # CONFIG_SND_CS46XX is not set
+# CONFIG_SND_CS5535AUDIO is not set
 # CONFIG_SND_CTXFI is not set
 # CONFIG_SND_DARLA20 is not set
 # CONFIG_SND_GINA20 is not set
@@ -1304,7 +1330,6 @@
 CONFIG_AC97_BUS=m
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
 CONFIG_HIDRAW=y
 
 #
@@ -1356,6 +1381,7 @@
 # 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 +1479,7 @@
 # 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,15 +1496,13 @@
 # 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
 CONFIG_JBD2=m
-# CONFIG_JBD2_DEBUG is not set
 CONFIG_FS_MBCACHE=m
 CONFIG_REISERFS_FS=m
 # CONFIG_REISERFS_CHECK is not set
@@ -1489,6 +1514,7 @@
 # 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
@@ -1497,8 +1523,8 @@
 # CONFIG_QUOTA is not set
 CONFIG_AUTOFS_FS=y
 CONFIG_AUTOFS4_FS=y
-CONFIG_FUSE_FS=y
-# CONFIG_CUSE is not set
+CONFIG_FUSE_FS=m
+CONFIG_CUSE=m
 
 #
 # Caches
@@ -1557,7 +1583,6 @@
 # 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,22 +1691,23 @@
 # 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_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL 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_TRACING=y
+CONFIG_RING_BUFFER_ALLOW_SWAP=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=""
@@ -1742,11 +1768,13 @@
 #
 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
@@ -1791,7 +1819,7 @@
 #
 CONFIG_CRYPTO_ANSI_CPRNG=m
 # CONFIG_CRYPTO_HW is not set
-CONFIG_BINARY_PRINTF=y
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig
index 1fc73aa..a0843c2 100644
--- a/arch/mips/configs/ip27_defconfig
+++ b/arch/mips/configs/ip27_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.23-rc2
-# Tue Aug  7 13:04:24 2007
+# Linux kernel version: 2.6.32.7
+# Wed Feb 10 13:13:19 2010
 #
 CONFIG_MIPS=y
 
@@ -9,21 +9,28 @@
 # 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_LEMOTE_FULONG is not set
+# CONFIG_LASAT is not set
+# CONFIG_MACH_LOONGSON is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SIM is not set
-# CONFIG_MARKEINS 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_SGI_IP22 is not set
 CONFIG_SGI_IP27=y
+# CONFIG_SGI_IP28 is not set
 # CONFIG_SGI_IP32 is not set
 # CONFIG_SIBYTE_CRHINE is not set
 # CONFIG_SIBYTE_CARMEL is not set
@@ -34,10 +41,13 @@
 # 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_INDIRECT is not set
 CONFIG_SGI_SN_M_MODE=y
 # CONFIG_SGI_SN_N_MODE is not set
 # CONFIG_MAPPED_KERNEL is not set
@@ -46,11 +56,14 @@
 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_CMOS_UPDATE=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_ARC=y
 CONFIG_DMA_COHERENT=y
@@ -60,6 +73,7 @@
 CONFIG_CPU_BIG_ENDIAN=y
 # CONFIG_CPU_LITTLE_ENDIAN is not set
 CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
+CONFIG_DEFAULT_SGI_PARTITION=y
 CONFIG_MIPS_L1_CACHE_SHIFT=7
 CONFIG_ARC64=y
 CONFIG_BOOT_ELF64=y
@@ -67,7 +81,7 @@
 #
 # CPU selection
 #
-# CONFIG_CPU_LOONGSON2 is not set
+# CONFIG_CPU_LOONGSON2E is not set
 # CONFIG_CPU_MIPS32_R1 is not set
 # CONFIG_CPU_MIPS32_R2 is not set
 # CONFIG_CPU_MIPS64_R1 is not set
@@ -80,6 +94,7 @@
 # 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
@@ -87,6 +102,7 @@
 # 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_R10000=y
 CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
 CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
@@ -100,6 +116,7 @@
 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
@@ -111,6 +128,7 @@
 CONFIG_IRQ_PER_CPU=y
 CONFIG_CPU_SUPPORTS_HIGHMEM=y
 CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_NUMA=y
 CONFIG_SYS_SUPPORTS_NUMA=y
 CONFIG_NODES_SHIFT=6
@@ -121,16 +139,24 @@
 CONFIG_DISCONTIGMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_NEED_MULTIPLE_NODES=y
-# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_MIGRATION=y
-CONFIG_RESOURCES_64BIT=y
+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=65536
 CONFIG_SMP=y
 CONFIG_SYS_SUPPORTS_SMP=y
 CONFIG_NR_CPUS_DEFAULT_64=y
 CONFIG_NR_CPUS=64
+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
@@ -143,13 +169,13 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
-CONFIG_PREEMPT_BKL=y
 # CONFIG_MIPS_INSANE_LARGE is not set
 # CONFIG_KEXEC is not set
 CONFIG_SECCOMP=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -163,20 +189,40 @@
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
-# CONFIG_USER_NS is not set
 # CONFIG_AUDIT is not set
+
+#
+# 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=y
+# CONFIG_CGROUP_DEBUG is not set
+# CONFIG_CGROUP_NS is not set
+# CONFIG_CGROUP_FREEZER is not set
+# CONFIG_CGROUP_DEVICE is not set
 CONFIG_CPUSETS=y
-CONFIG_SYSFS_DEPRECATED=y
+CONFIG_PROC_PID_CPUSET=y
+# CONFIG_CGROUP_CPUACCT is not set
+# CONFIG_RESOURCE_COUNTERS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 CONFIG_RELAY=y
+# CONFIG_NAMESPACES is not set
 # CONFIG_BLK_DEV_INITRD 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
@@ -185,31 +231,49 @@
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
+# CONFIG_PCSPKR_PLATFORM is not set
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=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_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_SYSCALL_WRAPPERS=y
+CONFIG_USE_GENERIC_SMP_HELPERS=y
+
+#
+# GCOV-based kernel profiling
+#
+CONFIG_SLOW_WORK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
 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 is not set
 CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
 CONFIG_STOP_MACHINE=y
 CONFIG_BLOCK=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+CONFIG_BLOCK_COMPAT=y
 
 #
 # IO Schedulers
@@ -218,11 +282,12 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_FREEZER is not set
 
 #
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
@@ -231,11 +296,10 @@
 CONFIG_PCI=y
 CONFIG_PCI_DOMAINS=y
 # CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCI_LEGACY is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 CONFIG_MMU=y
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
 # CONFIG_PCCARD is not set
 # CONFIG_HOTPLUG_PCI is not set
 
@@ -243,8 +307,9 @@
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
+# CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
-# CONFIG_BUILD_ELF64 is not set
 CONFIG_MIPS32_COMPAT=y
 CONFIG_COMPAT=y
 CONFIG_SYSVIPC_COMPAT=y
@@ -256,13 +321,10 @@
 # Power management options
 #
 CONFIG_PM=y
-# CONFIG_PM_LEGACY is not set
 # CONFIG_PM_DEBUG is not set
-
-#
-# Networking
-#
+# CONFIG_PM_RUNTIME is not set
 CONFIG_NET=y
+CONFIG_COMPAT_NETLINK_MESSAGES=y
 
 #
 # Networking options
@@ -274,6 +336,8 @@
 CONFIG_XFRM_USER=m
 # CONFIG_XFRM_SUB_POLICY is not set
 CONFIG_XFRM_MIGRATE=y
+CONFIG_XFRM_STATISTICS=y
+CONFIG_XFRM_IPCOMP=m
 CONFIG_NET_KEY=y
 CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
@@ -293,19 +357,39 @@
 # 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_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 is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
 CONFIG_TCP_MD5SIG=y
-# CONFIG_IPV6 is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
+CONFIG_IPV6=y
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MIP6=m
+CONFIG_INET6_XFRM_TUNNEL=m
+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=m
+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=y
+CONFIG_IPV6_PIMSM_V2=y
 CONFIG_NETWORK_SECMARK=y
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
@@ -315,9 +399,11 @@
 # CONFIG_SCTP_HMAC_NONE is not set
 # CONFIG_SCTP_HMAC_SHA1 is not set
 CONFIG_SCTP_HMAC_MD5=y
+# 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
@@ -327,12 +413,9 @@
 # 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=y
-CONFIG_NET_SCH_FIFO=y
 
 #
 # Queueing/Scheduling
@@ -341,7 +424,7 @@
 CONFIG_NET_SCH_HTB=m
 CONFIG_NET_SCH_HFSC=m
 CONFIG_NET_SCH_PRIO=m
-CONFIG_NET_SCH_RR=m
+CONFIG_NET_SCH_MULTIQ=y
 CONFIG_NET_SCH_RED=m
 CONFIG_NET_SCH_SFQ=m
 CONFIG_NET_SCH_TEQL=m
@@ -349,6 +432,7 @@
 CONFIG_NET_SCH_GRED=m
 CONFIG_NET_SCH_DSMARK=m
 CONFIG_NET_SCH_NETEM=m
+# CONFIG_NET_SCH_DRR is not set
 CONFIG_NET_SCH_INGRESS=m
 
 #
@@ -365,41 +449,59 @@
 CONFIG_CLS_U32_MARK=y
 CONFIG_NET_CLS_RSVP=m
 CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_CLS_FLOW=m
+CONFIG_NET_CLS_CGROUP=y
 # CONFIG_NET_EMATCH is not set
 CONFIG_NET_CLS_ACT=y
 CONFIG_NET_ACT_POLICE=y
 CONFIG_NET_ACT_GACT=m
 CONFIG_GACT_PROB=y
 CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_NAT=m
 CONFIG_NET_ACT_PEDIT=m
 # CONFIG_NET_ACT_SIMP is not set
-CONFIG_NET_CLS_POLICE=y
+CONFIG_NET_ACT_SKBEDIT=m
 # CONFIG_NET_CLS_IND 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
-
-#
-# Wireless
-#
+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_WIRELESS_OLD_REGULATORY is not set
 CONFIG_WIRELESS_EXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+CONFIG_LIB80211=m
+CONFIG_LIB80211_CRYPT_WEP=m
+CONFIG_LIB80211_CRYPT_CCMP=m
+CONFIG_LIB80211_CRYPT_TKIP=m
+# CONFIG_LIB80211_DEBUG is not set
 CONFIG_MAC80211=m
-# CONFIG_MAC80211_DEBUG is not set
-CONFIG_IEEE80211=m
-# CONFIG_IEEE80211_DEBUG is not set
-CONFIG_IEEE80211_CRYPT_WEP=m
-CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_CRYPT_TKIP=m
-CONFIG_IEEE80211_SOFTMAC=m
-# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
+CONFIG_MAC80211_RC_PID=y
+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_DEBUG_MENU is not set
+# CONFIG_WIMAX is not set
 CONFIG_RFKILL=m
+CONFIG_RFKILL_LEDS=y
 # CONFIG_NET_9P is not set
 
 #
@@ -409,9 +511,13 @@
 #
 # 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
@@ -425,13 +531,17 @@
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=m
 # CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_OSD=m
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_RAM is not set
 CONFIG_CDROM_PKTCDVD=m
 CONFIG_CDROM_PKTCDVD_BUFFERS=8
 # CONFIG_CDROM_PKTCDVD_WCACHE is not set
 CONFIG_ATA_OVER_ETH=m
+# CONFIG_BLK_DEV_HD is not set
 # CONFIG_MISC_DEVICES is not set
+CONFIG_EEPROM_93CX6=m
+CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
 #
@@ -454,10 +564,6 @@
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=m
 CONFIG_CHR_DEV_SCH=m
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
 # CONFIG_SCSI_MULTI_LUN is not set
 CONFIG_SCSI_CONSTANTS=y
 CONFIG_SCSI_LOGGING=y
@@ -472,9 +578,14 @@
 CONFIG_SCSI_ISCSI_ATTRS=m
 CONFIG_SCSI_SAS_ATTRS=m
 CONFIG_SCSI_SAS_LIBSAS=m
+CONFIG_SCSI_SAS_HOST_SMP=y
 # CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
 CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
+CONFIG_SCSI_CXGB3_ISCSI=m
+CONFIG_SCSI_BNX2_ISCSI=m
+CONFIG_BE2ISCSI=m
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
 # CONFIG_SCSI_3W_9XXX is not set
 # CONFIG_SCSI_ACARD is not set
@@ -484,11 +595,21 @@
 # CONFIG_SCSI_AIC79XX is not set
 CONFIG_SCSI_AIC94XX=m
 # CONFIG_AIC94XX_DEBUG is not set
+CONFIG_SCSI_MVSAS=m
+# CONFIG_SCSI_MVSAS_DEBUG is not set
+CONFIG_SCSI_DPT_I2O=m
+# CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
+CONFIG_SCSI_MPT2SAS=m
+CONFIG_SCSI_MPT2SAS_MAX_SGE=128
+# CONFIG_SCSI_MPT2SAS_LOGGING is not set
 # CONFIG_SCSI_HPTIOP is not set
+CONFIG_LIBFC=m
+# CONFIG_LIBFCOE is not set
+# CONFIG_FCOE is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_IPS is not set
@@ -503,16 +624,30 @@
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_DEBUG is not set
+CONFIG_SCSI_PMCRAID=m
 # CONFIG_SCSI_SRP is not set
+CONFIG_SCSI_BFA_FC=m
+CONFIG_SCSI_DH=m
+CONFIG_SCSI_DH_RDAC=m
+CONFIG_SCSI_DH_HP_SW=m
+CONFIG_SCSI_DH_EMC=m
+CONFIG_SCSI_DH_ALUA=m
+CONFIG_SCSI_OSD_INITIATOR=m
+CONFIG_SCSI_OSD_ULD=m
+CONFIG_SCSI_OSD_DPRINT_SENSE=1
+# CONFIG_SCSI_OSD_DEBUG is not set
 # CONFIG_ATA is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=y
+CONFIG_MD_AUTODETECT=y
 CONFIG_MD_LINEAR=m
 CONFIG_MD_RAID0=y
 CONFIG_MD_RAID1=y
 CONFIG_MD_RAID10=m
 CONFIG_MD_RAID456=y
-CONFIG_MD_RAID5_RESHAPE=y
+# CONFIG_MULTICORE_RAID456 is not set
+CONFIG_MD_RAID6_PQ=y
+# CONFIG_ASYNC_RAID6_TEST is not set
 CONFIG_MD_MULTIPATH=m
 CONFIG_MD_FAULTY=m
 CONFIG_BLK_DEV_DM=m
@@ -520,36 +655,39 @@
 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_EMC=m
-CONFIG_DM_MULTIPATH_RDAC=m
+CONFIG_DM_MULTIPATH_QL=m
+CONFIG_DM_MULTIPATH_ST=m
 # CONFIG_DM_DELAY is not set
-
-#
-# Fusion MPT device support
-#
+CONFIG_DM_UEVENT=y
 # CONFIG_FUSION is not set
-# CONFIG_FUSION_SPI is not set
-# CONFIG_FUSION_FC is not set
-# CONFIG_FUSION_SAS 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_NETDEVICES_MULTIQUEUE=y
 CONFIG_IFB=m
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 CONFIG_MACVLAN=m
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
+CONFIG_VETH=m
 # CONFIG_ARCNET is not set
-CONFIG_PHYLIB=m
+CONFIG_PHYLIB=y
 
 #
 # MII PHY device drivers
@@ -563,23 +701,50 @@
 CONFIG_SMSC_PHY=m
 # CONFIG_BROADCOM_PHY is not set
 CONFIG_ICPLUS_PHY=m
+CONFIG_REALTEK_PHY=m
+CONFIG_NATIONAL_PHY=m
+CONFIG_STE10XP=m
+CONFIG_LSI_ET1011C_PHY=m
 # CONFIG_FIXED_PHY is not set
+CONFIG_MDIO_BITBANG=m
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 CONFIG_AX88796=m
+CONFIG_AX88796_93CX6=y
 CONFIG_SGI_IOC3_ETH=y
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+CONFIG_SMC91X=m
 # CONFIG_DM9000 is not set
+CONFIG_ETHOC=m
+CONFIG_DNET=m
 # 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=m
+CONFIG_B44_PCI_AUTOSELECT=y
+CONFIG_B44_PCICORE_AUTOSELECT=y
+CONFIG_B44_PCI=y
+CONFIG_KS8842=m
+CONFIG_KS8851_MLL=m
+CONFIG_ATL2=m
 CONFIG_NETDEV_1000=y
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
 # CONFIG_E1000 is not set
+CONFIG_E1000E=m
+CONFIG_IP1000=m
+CONFIG_IGB=m
+CONFIG_IGBVF=m
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
@@ -589,24 +754,57 @@
 # CONFIG_SKY2 is not set
 CONFIG_VIA_VELOCITY=m
 # CONFIG_TIGON3 is not set
-# CONFIG_BNX2 is not set
+CONFIG_BNX2=m
+CONFIG_CNIC=m
 CONFIG_QLA3XXX=m
 # CONFIG_ATL1 is not set
+CONFIG_ATL1E=m
+CONFIG_ATL1C=m
+CONFIG_JME=m
 CONFIG_NETDEV_10000=y
+CONFIG_MDIO=m
 # CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3_DEPENDS=y
 CONFIG_CHELSIO_T3=m
+CONFIG_ENIC=m
+CONFIG_IXGBE=m
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
+CONFIG_VXGE=m
+# CONFIG_VXGE_DEBUG_TRACE_ALL is not set
 # CONFIG_MYRI10GE is not set
 CONFIG_NETXEN_NIC=m
-# CONFIG_MLX4_CORE is not set
+CONFIG_NIU=m
+CONFIG_MLX4_EN=m
+CONFIG_MLX4_CORE=m
+# CONFIG_MLX4_DEBUG is not set
+CONFIG_TEHUTI=m
+CONFIG_BNX2X=m
+CONFIG_QLGE=m
+CONFIG_SFC=m
+CONFIG_BE2NET=m
 # CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
 # CONFIG_WLAN_PRE80211 is not set
 CONFIG_WLAN_80211=y
+CONFIG_LIBERTAS=m
+# CONFIG_LIBERTAS_DEBUG is not set
+CONFIG_LIBERTAS_THINFIRM=m
+CONFIG_ATMEL=m
+CONFIG_PCI_ATMEL=m
+CONFIG_PRISM54=m
+CONFIG_RTL8180=m
+CONFIG_ADM8211=m
+# CONFIG_MAC80211_HWSIM is not set
+CONFIG_MWL8K=m
+CONFIG_P54_COMMON=m
+CONFIG_P54_PCI=m
+CONFIG_P54_LEDS=y
+CONFIG_ATH_COMMON=m
+CONFIG_ATH5K=m
+# CONFIG_ATH5K_DEBUG is not set
+CONFIG_ATH9K=m
+# CONFIG_ATH9K_DEBUG is not set
 CONFIG_IPW2100=m
 CONFIG_IPW2100_MONITOR=y
 CONFIG_IPW2100_DEBUG=y
@@ -616,35 +814,68 @@
 CONFIG_IPW2200_PROMISCUOUS=y
 CONFIG_IPW2200_QOS=y
 CONFIG_IPW2200_DEBUG=y
-CONFIG_LIBERTAS=m
-# CONFIG_LIBERTAS_DEBUG is not set
-CONFIG_HERMES=m
-CONFIG_PLX_HERMES=m
-CONFIG_TMD_HERMES=m
-CONFIG_NORTEL_HERMES=m
-CONFIG_PCI_HERMES=m
-CONFIG_ATMEL=m
-CONFIG_PCI_ATMEL=m
-CONFIG_PRISM54=m
+CONFIG_LIBIPW=m
+# CONFIG_LIBIPW_DEBUG is not set
+CONFIG_IWLWIFI=m
+CONFIG_IWLWIFI_LEDS=y
+CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT=y
+# CONFIG_IWLWIFI_DEBUG is not set
+CONFIG_IWLAGN=m
+CONFIG_IWL4965=y
+CONFIG_IWL5000=y
+CONFIG_IWL3945=m
+CONFIG_IWL3945_SPECTRUM_MEASUREMENT=y
 CONFIG_HOSTAP=m
 CONFIG_HOSTAP_FIRMWARE=y
 CONFIG_HOSTAP_FIRMWARE_NVRAM=y
 CONFIG_HOSTAP_PLX=m
 CONFIG_HOSTAP_PCI=m
-CONFIG_BCM43XX=m
-CONFIG_BCM43XX_DEBUG=y
-CONFIG_BCM43XX_DMA=y
-CONFIG_BCM43XX_PIO=y
-CONFIG_BCM43XX_DMA_AND_PIO_MODE=y
-# CONFIG_BCM43XX_DMA_MODE is not set
-# CONFIG_BCM43XX_PIO_MODE is not set
+CONFIG_B43=m
+CONFIG_B43_PCI_AUTOSELECT=y
+CONFIG_B43_PCICORE_AUTOSELECT=y
+CONFIG_B43_PHY_LP=y
+CONFIG_B43_LEDS=y
+CONFIG_B43_HWRNG=y
+# CONFIG_B43_DEBUG is not set
+CONFIG_B43LEGACY=m
+CONFIG_B43LEGACY_PCI_AUTOSELECT=y
+CONFIG_B43LEGACY_PCICORE_AUTOSELECT=y
+CONFIG_B43LEGACY_LEDS=y
+CONFIG_B43LEGACY_HWRNG=y
+# CONFIG_B43LEGACY_DEBUG is not set
+CONFIG_B43LEGACY_DMA=y
+CONFIG_B43LEGACY_PIO=y
+CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y
+# CONFIG_B43LEGACY_DMA_MODE is not set
+# CONFIG_B43LEGACY_PIO_MODE is not set
+CONFIG_RT2X00=m
+CONFIG_RT2400PCI=m
+CONFIG_RT2500PCI=m
+CONFIG_RT61PCI=m
+CONFIG_RT2X00_LIB_PCI=m
+CONFIG_RT2X00_LIB=m
+CONFIG_RT2X00_LIB_FIRMWARE=y
+CONFIG_RT2X00_LIB_CRYPTO=y
+CONFIG_RT2X00_LIB_LEDS=y
+# CONFIG_RT2X00_DEBUG is not set
+CONFIG_HERMES=m
+# CONFIG_HERMES_CACHE_FW_ON_INIT is not set
+CONFIG_PLX_HERMES=m
+CONFIG_TMD_HERMES=m
+CONFIG_NORTEL_HERMES=m
+CONFIG_PCI_HERMES=m
+CONFIG_WL12XX=m
+CONFIG_WL1251=m
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 # 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_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
@@ -671,7 +902,9 @@
 # Character devices
 #
 # CONFIG_VT is not set
+CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_NOZOMI=m
 
 #
 # Serial drivers
@@ -694,95 +927,262 @@
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
+CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
-# CONFIG_WATCHDOG is not set
 CONFIG_HW_RANDOM=m
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM_TIMERIOMEM=m
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-# CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
 CONFIG_DEVPORT=y
-# CONFIG_I2C is not set
+CONFIG_I2C=m
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_ALGOBIT=m
+CONFIG_I2C_ALGOPCA=m
 
 #
-# SPI support
+# I2C Hardware Bus support
 #
+
+#
+# PC SMBus host controller drivers
+#
+CONFIG_I2C_ALI1535=m
+CONFIG_I2C_ALI1563=m
+CONFIG_I2C_ALI15X3=m
+CONFIG_I2C_AMD756=m
+CONFIG_I2C_AMD8111=m
+CONFIG_I2C_I801=m
+CONFIG_I2C_ISCH=m
+CONFIG_I2C_PIIX4=m
+CONFIG_I2C_NFORCE2=m
+CONFIG_I2C_SIS5595=m
+CONFIG_I2C_SIS630=m
+CONFIG_I2C_SIS96X=m
+CONFIG_I2C_VIA=m
+CONFIG_I2C_VIAPRO=m
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_OCORES=m
+CONFIG_I2C_SIMTEC=m
+
+#
+# External I2C/SMBus adapter drivers
+#
+CONFIG_I2C_PARPORT_LIGHT=m
+CONFIG_I2C_TAOS_EVM=m
+
+#
+# Graphics adapter I2C/DDC channel drivers
+#
+CONFIG_I2C_VOODOO3=m
+
+#
+# Other I2C/SMBus bus drivers
+#
+CONFIG_I2C_PCA_PLATFORM=m
+CONFIG_I2C_STUB=m
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+CONFIG_SENSORS_TSL2550=m
+# 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 is not set
-# CONFIG_SPI_MASTER is not set
+
+#
+# PPS support
+#
+CONFIG_PPS=m
+# CONFIG_PPS_DEBUG is not set
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
+CONFIG_THERMAL=m
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB=m
+CONFIG_SSB_SPROM=y
+CONFIG_SSB_PCIHOST_POSSIBLE=y
+CONFIG_SSB_PCIHOST=y
+CONFIG_SSB_B43_PCI_BRIDGE=y
+# CONFIG_SSB_SILENT is not set
+# CONFIG_SSB_DEBUG is not set
+CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y
+CONFIG_SSB_DRIVER_PCICORE=y
+# CONFIG_SSB_DRIVER_MIPS is not set
 
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_DAB is not set
+# 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=m
+CONFIG_MFD_WM8350_I2C=m
+CONFIG_MFD_PCF50633=m
+CONFIG_PCF50633_ADC=m
+CONFIG_PCF50633_GPIO=m
+CONFIG_AB3100_CORE=m
+CONFIG_AB3100_OTP=m
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
 #
+# CONFIG_VGA_ARB is not set
+# 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_VGASTATE is not set
-# CONFIG_VIDEO_OUTPUT_CONTROL is not set
-# CONFIG_FB is not set
-
-#
-# Sound
-#
 # CONFIG_SOUND 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 is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# Enable Host or Gadget support to see Inventra options
 #
 
 #
-# USB Gadget Support
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 # CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_UWB is not set
 # CONFIG_MMC is not set
-# CONFIG_NEW_LEDS is not set
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=m
+
+#
+# LED drivers
+#
+CONFIG_LEDS_LP3944=m
+CONFIG_LEDS_PCA955X=m
+CONFIG_LEDS_WM8350=m
+CONFIG_LEDS_BD2802=m
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+CONFIG_LEDS_TRIGGER_BACKLIGHT=m
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
+# CONFIG_ACCESSIBILITY is not set
 # CONFIG_INFINIBAND is not set
-# CONFIG_RTC_CLASS 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
 
 #
-# DMA Engine support
+# RTC interfaces
 #
-# CONFIG_DMA_ENGINE 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 Clients
+# I2C RTC drivers
+#
+# 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
+
+#
+# SPI RTC drivers
 #
 
 #
-# 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=y
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+# CONFIG_RTC_DRV_WM8350 is not set
+# CONFIG_RTC_DRV_PCF50633 is not set
+CONFIG_RTC_DRV_AB3100=m
 
 #
-# Userspace I/O
+# on-CPU RTC drivers
 #
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 CONFIG_UIO=y
 # CONFIG_UIO_CIF is not set
+# CONFIG_UIO_PDRV is not set
+# CONFIG_UIO_PDRV_GENIRQ is not set
+CONFIG_UIO_SMX=m
+CONFIG_UIO_AEC=m
+CONFIG_UIO_SERCOS3=m
+CONFIG_UIO_PCI_GENERIC=m
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
 
 #
 # File systems
@@ -793,36 +1193,57 @@
 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_EXT4DEV_FS is not set
+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=y
+CONFIG_JBD2=y
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
 CONFIG_XFS_FS=m
 CONFIG_XFS_QUOTA=y
-CONFIG_XFS_SECURITY=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_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+CONFIG_BTRFS_FS=m
+CONFIG_BTRFS_FS_POSIX_ACL=y
+# 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_QUOTACTL=y
-CONFIG_DNOTIFY=y
 CONFIG_AUTOFS_FS=m
 # CONFIG_AUTOFS4_FS is not set
 CONFIG_FUSE_FS=m
+CONFIG_CUSE=m
 CONFIG_GENERIC_ACL=y
 
 #
+# Caches
+#
+CONFIG_FSCACHE=m
+CONFIG_FSCACHE_STATS=y
+# 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 is not set
@@ -841,16 +1262,13 @@
 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=y
 # CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
 CONFIG_CONFIGFS_FS=m
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_ECRYPT_FS is not set
@@ -860,28 +1278,32 @@
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_CRAMFS is not set
+CONFIG_SQUASHFS=m
+# 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=m
 # 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_EXOFS_FS=m
+# CONFIG_EXOFS_DEBUG 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_NFS_DIRECTIO is not set
-# CONFIG_NFSD is not set
 # CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
-# CONFIG_SUNRPC_BIND34 is not set
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -911,35 +1333,31 @@
 # CONFIG_KARMA_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
 # CONFIG_SYSV68_PARTITION is not set
-
-#
-# Native Language Support
-#
 # CONFIG_NLS is not set
-
-#
-# Distributed Lock Manager
-#
 CONFIG_DLM=m
 # CONFIG_DLM_DEBUG is not set
 
 #
-# Profiling support
-#
-# CONFIG_PROFILING is not set
-
-#
 # Kernel hacking
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
+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 is not set
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_CROSSCOMPILE=y
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_CMDLINE=""
 
 #
@@ -948,65 +1366,136 @@
 CONFIG_KEYS=y
 CONFIG_KEYS_DEBUG_PROC_KEYS=y
 # CONFIG_SECURITY is not set
-CONFIG_XOR_BLOCKS=m
-CONFIG_ASYNC_CORE=m
-CONFIG_ASYNC_MEMCPY=m
-CONFIG_ASYNC_XOR=m
+CONFIG_SECURITYFS=y
+CONFIG_SECURITY_FILE_CAPABILITIES=y
+CONFIG_XOR_BLOCKS=y
+CONFIG_ASYNC_CORE=y
+CONFIG_ASYNC_MEMCPY=y
+CONFIG_ASYNC_XOR=y
+CONFIG_ASYNC_PQ=y
+CONFIG_ASYNC_RAID6_RECOV=y
 CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_FIPS=y
 CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_ABLKCIPHER=m
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=m
+CONFIG_CRYPTO_AEAD2=y
 CONFIG_CRYPTO_BLKCIPHER=y
+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=y
+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 is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+CONFIG_CRYPTO_CCM=m
+CONFIG_CRYPTO_GCM=m
+CONFIG_CRYPTO_SEQIV=m
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_CTR=m
+CONFIG_CRYPTO_CTS=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XTS=m
+
+#
+# Hash modes
+#
 CONFIG_CRYPTO_HMAC=y
 CONFIG_CRYPTO_XCBC=m
-CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_VMAC=m
+
+#
+# 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_WP512=m
 CONFIG_CRYPTO_TGR192=m
-CONFIG_CRYPTO_GF128MUL=m
-CONFIG_CRYPTO_ECB=m
-CONFIG_CRYPTO_CBC=y
-CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_LRW=m
-CONFIG_CRYPTO_CRYPTD=m
-CONFIG_CRYPTO_DES=y
-CONFIG_CRYPTO_FCRYPT=m
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_TWOFISH_COMMON=m
-CONFIG_CRYPTO_SERPENT=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_TEA=m
-CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_FCRYPT=m
 CONFIG_CRYPTO_KHAZAD=m
-CONFIG_CRYPTO_ANUBIS=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_MICHAEL_MIC=m
-CONFIG_CRYPTO_CRC32C=m
-CONFIG_CRYPTO_CAMELLIA=m
-# CONFIG_CRYPTO_TEST is not set
+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=m
+# CONFIG_CRYPTO_DEV_HIFN_795X_RNG is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC_CCITT=m
-# CONFIG_CRC16 is not set
-# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC16=y
+CONFIG_CRC_T10DIF=m
+CONFIG_CRC_ITU_T=m
 CONFIG_CRC32=y
-# CONFIG_CRC7 is not set
+CONFIG_CRC7=m
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=m
 CONFIG_ZLIB_DEFLATE=m
-CONFIG_PLIST=y
+CONFIG_LZO_COMPRESS=m
+CONFIG_LZO_DECOMPRESS=m
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/mips/configs/lemote2f_defconfig b/arch/mips/configs/lemote2f_defconfig
new file mode 100644
index 0000000..63efdd0
--- /dev/null
+++ b/arch/mips/configs/lemote2f_defconfig
@@ -0,0 +1,2301 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32.12
+# Wed Apr 28 00:40:29 2010
+#
+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_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_V2 is not set
+# 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 is not set
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_SYSCALL_WRAPPERS=y
+
+#
+# GCOV-based kernel profiling
+#
+CONFIG_SLOW_WORK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=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 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=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_TPROXY is not set
+CONFIG_NETFILTER_XTABLES=m
+# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
+# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
+CONFIG_NETFILTER_XT_TARGET_HL=m
+# CONFIG_NETFILTER_XT_TARGET_LED 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_TRACE is not set
+# CONFIG_NETFILTER_XT_TARGET_SECMARK is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP 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=m
+# 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 is not set
+# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
+# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
+# CONFIG_NETFILTER_XT_MATCH_PHYSDEV 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=m
+# CONFIG_IP_VS_IPV6 is not set
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+# CONFIG_IP_VS_PROTO_TCP is not set
+# CONFIG_IP_VS_PROTO_UDP is not set
+# CONFIG_IP_VS_PROTO_ESP is not set
+# CONFIG_IP_VS_PROTO_AH is not set
+
+#
+# IPVS scheduler
+#
+# CONFIG_IP_VS_RR is not set
+# CONFIG_IP_VS_WRR is not set
+# CONFIG_IP_VS_LC is not set
+# CONFIG_IP_VS_WLC is not set
+# CONFIG_IP_VS_LBLC is not set
+# CONFIG_IP_VS_LBLCR is not set
+# CONFIG_IP_VS_DH is not set
+# CONFIG_IP_VS_SH is not set
+# CONFIG_IP_VS_SED is not set
+# CONFIG_IP_VS_NQ is not set
+
+#
+# IPVS application helper
+#
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_NF_DEFRAG_IPV4 is not set
+# CONFIG_IP_NF_QUEUE is not set
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration
+#
+# CONFIG_IP6_NF_QUEUE is not set
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_AH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_MH=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_TARGET_HL=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_RAW=m
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_IP6=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
+CONFIG_BRIDGE_EBT_NFLOG=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_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_IPT 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_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_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_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=m
+# 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=m
+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=m
+CONFIG_INPUT_POLLDEV=m
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=m
+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=m
+# CONFIG_INPUT_EVBUG is not set
+# CONFIG_INPUT_APMPOWER is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=m
+# 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=m
+# 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 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 is not set
+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=m
+CONFIG_HID_APPLE=m
+CONFIG_HID_BELKIN=m
+CONFIG_HID_CHERRY=m
+CONFIG_HID_CHICONY=m
+CONFIG_HID_CYPRESS=m
+CONFIG_HID_DRAGONRISE=m
+CONFIG_DRAGONRISE_FF=y
+CONFIG_HID_EZKEY=m
+CONFIG_HID_KYE=m
+CONFIG_HID_GYRATION=m
+CONFIG_HID_TWINHAN=m
+CONFIG_HID_KENSINGTON=m
+CONFIG_HID_LOGITECH=m
+CONFIG_LOGITECH_FF=y
+CONFIG_LOGIRUMBLEPAD2_FF=y
+CONFIG_HID_MICROSOFT=m
+CONFIG_HID_MONTEREY=m
+CONFIG_HID_NTRIG=m
+CONFIG_HID_PANTHERLORD=m
+CONFIG_PANTHERLORD_FF=y
+CONFIG_HID_PETALYNX=m
+CONFIG_HID_SAMSUNG=m
+CONFIG_HID_SONY=m
+CONFIG_HID_SUNPLUS=m
+CONFIG_HID_GREENASIA=m
+CONFIG_GREENASIA_FF=y
+CONFIG_HID_SMARTJOYPLUS=m
+CONFIG_SMARTJOYPLUS_FF=y
+CONFIG_HID_TOPSEED=m
+CONFIG_HID_THRUSTMASTER=m
+CONFIG_THRUSTMASTER_FF=y
+CONFIG_HID_WACOM=m
+CONFIG_HID_ZEROPLUS=m
+CONFIG_ZEROPLUS_FF=y
+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_SUSPEND=y
+# CONFIG_USB_OTG is not set
+CONFIG_USB_OTG_WHITELIST=y
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_USB_MON=m
+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_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_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
+
+#
+# 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_JBD2=y
+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=m
+CONFIG_CUSE=m
+
+#
+# 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="utf8"
+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 is not set
+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 is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK 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_RING_BUFFER=y
+CONFIG_RING_BUFFER_ALLOW_SWAP=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE 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 is not set
+
+#
+# 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..bf2ae95
--- /dev/null
+++ b/arch/mips/configs/lemote2f_minimal_defconfig
@@ -0,0 +1,1335 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32.12
+# Wed Apr 28 00:39:59 2010
+#
+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_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_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=""
+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_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_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_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=y
+# 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=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_BELKIN=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+CONFIG_HID_CYPRESS=y
+CONFIG_HID_DRAGONRISE=y
+CONFIG_DRAGONRISE_FF=y
+CONFIG_HID_EZKEY=y
+CONFIG_HID_KYE=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_TWINHAN=y
+CONFIG_HID_KENSINGTON=y
+CONFIG_HID_LOGITECH=y
+CONFIG_LOGITECH_FF=y
+CONFIG_LOGIRUMBLEPAD2_FF=y
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+CONFIG_HID_NTRIG=y
+CONFIG_HID_PANTHERLORD=y
+CONFIG_PANTHERLORD_FF=y
+CONFIG_HID_PETALYNX=y
+CONFIG_HID_SAMSUNG=y
+CONFIG_HID_SONY=y
+CONFIG_HID_SUNPLUS=y
+CONFIG_HID_GREENASIA=y
+CONFIG_GREENASIA_FF=y
+CONFIG_HID_SMARTJOYPLUS=y
+CONFIG_SMARTJOYPLUS_FF=y
+CONFIG_HID_TOPSEED=y
+CONFIG_HID_THRUSTMASTER=y
+CONFIG_THRUSTMASTER_FF=y
+CONFIG_HID_ZEROPLUS=y
+CONFIG_ZEROPLUS_FF=y
+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_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
+
+#
+# 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=y
+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="utf8"
+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 is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=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_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_CMDLINE=""
+
+#
+# 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_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/powertv_defconfig b/arch/mips/configs/powertv_defconfig
new file mode 100644
index 0000000..3aff69ab
--- /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_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..5c8603c8 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 @@
 /*
  * 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-features.h b/arch/mips/include/asm/cpu-features.h
index 1f4df64..272c5ef 100644
--- a/arch/mips/include/asm/cpu-features.h
+++ b/arch/mips/include/asm/cpu-features.h
@@ -191,6 +191,9 @@
 # ifndef cpu_has_64bit_addresses
 # define cpu_has_64bit_addresses	0
 # endif
+# ifndef cpu_vmbits
+# define cpu_vmbits 31
+# endif
 #endif
 
 #ifdef CONFIG_64BIT
@@ -209,6 +212,10 @@
 # ifndef cpu_has_64bit_addresses
 # define cpu_has_64bit_addresses	1
 # endif
+# ifndef cpu_vmbits
+# define cpu_vmbits cpu_data[0].vmbits
+# define __NEED_VMBITS_PROBE
+# endif
 #endif
 
 #if defined(CONFIG_CPU_MIPSR2_IRQ_VI) && !defined(cpu_has_vint)
diff --git a/arch/mips/include/asm/cpu-info.h b/arch/mips/include/asm/cpu-info.h
index 1260443..b39def3 100644
--- a/arch/mips/include/asm/cpu-info.h
+++ b/arch/mips/include/asm/cpu-info.h
@@ -58,6 +58,9 @@
 	struct cache_desc	tcache;	/* Tertiary/split secondary cache */
 	int			srsets;	/* Shadow register sets */
 	int			core;	/* physical core number */
+#ifdef CONFIG_64BIT
+	int			vmbits;	/* Virtual memory size in bits */
+#endif
 #if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_MIPS_MT_SMTC)
 	/*
 	 * In the MIPS MT "SMTC" model, each TC is considered
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/elf.h b/arch/mips/include/asm/elf.h
index 7990694..2d8495e 100644
--- a/arch/mips/include/asm/elf.h
+++ b/arch/mips/include/asm/elf.h
@@ -310,6 +310,7 @@
 
 #endif /* CONFIG_64BIT */
 
+struct pt_regs;
 struct task_struct;
 
 extern void elf_dump_regs(elf_greg_t *, struct pt_regs *regs);
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 @@
 
 #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-ar7/ar7.h b/arch/mips/include/asm/mach-ar7/ar7.h
index 21cbbc7..a140232 100644
--- a/arch/mips/include/asm/mach-ar7/ar7.h
+++ b/arch/mips/include/asm/mach-ar7/ar7.h
@@ -50,7 +50,7 @@
 #define UR8_REGS_WDT	(AR7_REGS_BASE + 0x0b00)
 #define UR8_REGS_UART1	(AR7_REGS_BASE + 0x0f00)
 
-#define AR7_RESET_PEREPHERIAL	0x0
+#define AR7_RESET_PERIPHERAL	0x0
 #define AR7_RESET_SOFTWARE	0x4
 #define AR7_RESET_STATUS	0x8
 
@@ -145,7 +145,7 @@
 static inline void ar7_device_enable(u32 bit)
 {
 	void *reset_reg =
-		(void *)KSEG1ADDR(AR7_REGS_RESET + AR7_RESET_PEREPHERIAL);
+		(void *)KSEG1ADDR(AR7_REGS_RESET + AR7_RESET_PERIPHERAL);
 	writel(readl(reset_reg) | (1 << bit), reset_reg);
 	msleep(20);
 }
@@ -153,7 +153,7 @@
 static inline void ar7_device_disable(u32 bit)
 {
 	void *reset_reg =
-		(void *)KSEG1ADDR(AR7_REGS_RESET + AR7_RESET_PEREPHERIAL);
+		(void *)KSEG1ADDR(AR7_REGS_RESET + AR7_RESET_PERIPHERAL);
 	writel(readl(reset_reg) & ~(1 << bit), reset_reg);
 	msleep(20);
 }
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 @@
 	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 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,
 
-/* boards call this to register additional (GPIO) interrupts */
-void au1xxx_setup_irqmap(struct au1xxx_irqmap *map, int count);
+	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,
+};
+
+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 @@
 
 #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 @@
 
 /* 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 @@
 
 /* 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 @@
 #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 @@
 #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,16 +1004,10 @@
 #define USBMSRMCFG_RDCOMB	30
 #define USBMSRMCFG_PFEN 	31
 
+#define FOR_PLATFORM_C_USB_HOST_INT AU1200_USB_INT
+
 #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 AU1000_MAX_INTR 	AU1000_INTC1_INT_LAST
-#define INTX			0xFF			/* not valid */
-
 /* Programmable Counters 0 and 1 */
 #define SYS_BASE		0xB1900000
 #define SYS_COUNTER_CNTRL	(SYS_BASE + 0x14)
@@ -1231,14 +1255,6 @@
 #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 @@
 #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 @@
 
 #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..8c6b110 100644
--- a/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h
+++ b/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h
@@ -305,6 +305,7 @@
 	dbdev_tab_t		*chan_dest;
 	au1x_dma_chan_t		*chan_ptr;
 	au1x_ddma_desc_t	*chan_desc_base;
+	u32			cdb_membase; /* kmalloc base of above */
 	au1x_ddma_desc_t	*get_ptr, *put_ptr, *cur_ptr;
 	void			*chan_callparam;
 	void			(*chan_callback)(int, void *);
@@ -338,8 +339,8 @@
 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 +363,6 @@
 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 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 	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-bcm63xx/bcm63xx_gpio.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h
index 76a0b72..43d4da0 100644
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h
@@ -10,6 +10,10 @@
 	switch (bcm63xx_get_cpu_id()) {
 	case BCM6358_CPU_ID:
 		return 40;
+	case BCM6338_CPU_ID:
+		return 8;
+	case BCM6345_CPU_ID:
+		return 16;
 	case BCM6348_CPU_ID:
 	default:
 		return 37;
diff --git a/arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h b/arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h
index 71742bac..f453c01 100644
--- a/arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h
@@ -24,7 +24,7 @@
 #define cpu_has_smartmips		0
 #define cpu_has_vtag_icache		0
 
-#if !defined(BCMCPU_RUNTIME_DETECT) && (defined(CONFIG_BCMCPU_IS_6348) || defined(CONFIG_CPU_IS_6338) || defined(CONFIG_CPU_IS_BCM6345))
+#if !defined(BCMCPU_RUNTIME_DETECT) && (defined(CONFIG_BCM63XX_CPU_6348) || defined(CONFIG_BCM63XX_CPU_6345) || defined(CONFIG_BCM63XX_CPU_6338))
 #define cpu_has_dc_aliases		0
 #endif
 
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 @@
 #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 @@
  *   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 @@
 	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 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/gpio.h b/arch/mips/include/asm/mach-loongson/gpio.h
new file mode 100644
index 0000000..e30e73d
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson/gpio.h
@@ -0,0 +1,35 @@
+/*
+ * STLS2F GPIO Support
+ *
+ * Copyright (c) 2008  Richard Liu, STMicroelectronics <richard.liu@st.com>
+ * Copyright (c) 2008-2010  Arnaud Patard <apatard@mandriva.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	__STLS2F_GPIO_H
+#define	__STLS2F_GPIO_H
+
+#include <asm-generic/gpio.h>
+
+extern void gpio_set_value(unsigned gpio, int value);
+extern int gpio_get_value(unsigned gpio);
+extern int gpio_cansleep(unsigned gpio);
+
+/* The chip can do interrupt
+ * but it has not been tested and doc not clear
+ */
+static inline int gpio_to_irq(int gpio)
+{
+	return -EINVAL;
+}
+
+static inline int irq_to_gpio(int gpio)
+{
+	return -EINVAL;
+}
+
+#endif				/* __STLS2F_GPIO_H */
diff --git a/arch/mips/include/asm/mach-loongson/loongson.h b/arch/mips/include/asm/mach-loongson/loongson.h
index da70bcf..300f1ed 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 @@
 /* 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 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)
 
-/* loongson2-specific perf counter IRQ */
-#define LOONGSON2_PERFCNT_IRQ   (MIPS_CPU_IRQ_BASE + 6)
+/* 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 = (dst) | 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)
+
+#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
+
+/*
+ * 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.
  */
 
-#ifdef CONFIG_LEMOTE_FULOONG2E
-
-#define LOONGSON_HIGHMEM_START  0x20000000
-
 #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 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)
 /* this is an offset from mips_io_port_base */
 #define LOONGSON_PCI_IO_START	0x00004000UL
 
-#endif
+#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	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	/* !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 @@
 	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/mach-tx49xx/kmalloc.h b/arch/mips/include/asm/mach-tx49xx/kmalloc.h
index 913ff19..b74caf6 100644
--- a/arch/mips/include/asm/mach-tx49xx/kmalloc.h
+++ b/arch/mips/include/asm/mach-tx49xx/kmalloc.h
@@ -1,8 +1,6 @@
 #ifndef __ASM_MACH_TX49XX_KMALLOC_H
 #define __ASM_MACH_TX49XX_KMALLOC_H
 
-/*
- * All happy, no need to define ARCH_KMALLOC_MINALIGN
- */
+#define ARCH_KMALLOC_MINALIGN	L1_CACHE_BYTES
 
 #endif /* __ASM_MACH_TX49XX_KMALLOC_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 @@
 	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/page.h b/arch/mips/include/asm/page.h
index f266295..33ca0d9 100644
--- a/arch/mips/include/asm/page.h
+++ b/arch/mips/include/asm/page.h
@@ -200,8 +200,10 @@
 #define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
 				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
-#define UNCAC_ADDR(addr)	((addr) - PAGE_OFFSET + UNCAC_BASE)
-#define CAC_ADDR(addr)		((addr) - UNCAC_BASE + PAGE_OFFSET)
+#define UNCAC_ADDR(addr)	((addr) - PAGE_OFFSET + UNCAC_BASE + 	\
+								PHYS_OFFSET)
+#define CAC_ADDR(addr)		((addr) - UNCAC_BASE + PAGE_OFFSET -	\
+								PHYS_OFFSET)
 
 #include <asm-generic/memory_model.h>
 #include <asm-generic/getorder.h>
diff --git a/arch/mips/include/asm/pgtable-64.h b/arch/mips/include/asm/pgtable-64.h
index 9cd5089..2d7acd4 100644
--- a/arch/mips/include/asm/pgtable-64.h
+++ b/arch/mips/include/asm/pgtable-64.h
@@ -107,10 +107,17 @@
 #endif
 #define FIRST_USER_ADDRESS	0UL
 
-#define VMALLOC_START		MAP_BASE
+/*
+ * TLB refill handlers also map the vmalloc area into xuseg.  Avoid
+ * the first couple of pages so NULL pointer dereferences will still
+ * reliably trap.
+ */
+#define VMALLOC_START		(MAP_BASE + (2 * PAGE_SIZE))
 #define VMALLOC_END	\
-	(VMALLOC_START + \
-	 PTRS_PER_PGD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE - (1UL << 32))
+	(MAP_BASE + \
+	 min(PTRS_PER_PGD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE, \
+	     (1UL << cpu_vmbits)) - (1UL << 32))
+
 #if defined(CONFIG_MODULES) && defined(KBUILD_64BIT_SYM32) && \
 	VMALLOC_START != CKSSEG
 /* Load modules into 32bit-compatible segment. */
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 @@
 #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/ptrace.h b/arch/mips/include/asm/ptrace.h
index ce47118..cdc6a46 100644
--- a/arch/mips/include/asm/ptrace.h
+++ b/arch/mips/include/asm/ptrace.h
@@ -142,9 +142,9 @@
 
 extern asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit);
 
-extern NORET_TYPE void die(const char *, const struct pt_regs *) ATTRIB_NORET;
+extern NORET_TYPE void die(const char *, struct pt_regs *) ATTRIB_NORET;
 
-static inline void die_if_kernel(const char *str, const struct pt_regs *regs)
+static inline void die_if_kernel(const char *str, struct pt_regs *regs)
 {
 	if (unlikely(!user_mode(regs)))
 		die(str, regs);
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 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/sn/agent.h b/arch/mips/include/asm/sn/agent.h
index ac4ea85..dc81114 100644
--- a/arch/mips/include/asm/sn/agent.h
+++ b/arch/mips/include/asm/sn/agent.h
@@ -11,7 +11,6 @@
 #ifndef _ASM_SGI_SN_AGENT_H
 #define _ASM_SGI_SN_AGENT_H
 
-#include <linux/topology.h>
 #include <asm/sn/addrs.h>
 #include <asm/sn/arch.h>
 
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 @@
 #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/mm/uasm.h b/arch/mips/include/asm/uasm.h
similarity index 91%
rename from arch/mips/mm/uasm.h
rename to arch/mips/include/asm/uasm.h
index 5198ae5..f8bb7bb 100644
--- a/arch/mips/mm/uasm.h
+++ b/arch/mips/include/asm/uasm.h
@@ -34,6 +34,11 @@
 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(_dsra);
 Ip_u2u1u3(_dsrl);
 Ip_u2u1u3(_dsrl32);
+Ip_u2u1u3(_drotr);
 Ip_u3u1u2(_dsubu);
 Ip_0(_eret);
 Ip_u1(_j);
@@ -94,6 +100,7 @@
 Ip_0(_tlbwr);
 Ip_u3u1u2(_xor);
 Ip_u2u1u3(_xori);
+Ip_u2u1msbu3(_dins);
 
 /* Handle labels. */
 struct uasm_label {
@@ -155,6 +162,24 @@
 #define uasm_i_ssnop(buf) uasm_i_sll(buf, 0, 0, 1)
 #define uasm_i_ehb(buf) uasm_i_sll(buf, 0, 0, 3)
 
+static inline void uasm_i_dsrl_safe(u32 **p, unsigned int a1,
+				    unsigned int a2, unsigned int a3)
+{
+	if (a3 < 32)
+		uasm_i_dsrl(p, a1, a2, a3);
+	else
+		uasm_i_dsrl32(p, a1, a2, a3 - 32);
+}
+
+static inline void uasm_i_dsll_safe(u32 **p, unsigned int a1,
+				    unsigned int a2, unsigned int a3)
+{
+	if (a3 < 32)
+		uasm_i_dsll(p, a1, a2, a3);
+	else
+		uasm_i_dsll32(p, a1, a2, a3 - 32);
+}
+
 /* Handle relocations. */
 struct uasm_reloc {
 	u32 *addr;
diff --git a/arch/mips/jazz/setup.c b/arch/mips/jazz/setup.c
index 7043f6b..0d0f054 100644
--- a/arch/mips/jazz/setup.c
+++ b/arch/mips/jazz/setup.c
@@ -76,15 +76,9 @@
 
 #ifdef CONFIG_VT
 	screen_info = (struct screen_info) {
-		0, 0,		/* orig-x, orig-y */
-		0,		/* unused */
-		0,		/* orig_video_page */
-		0,		/* orig_video_mode */
-		160,		/* orig_video_cols */
-		0, 0, 0,	/* unused, ega_bx, unused */
-		64,		/* orig_video_lines */
-		0,		/* orig_video_isVGA */
-		16		/* orig_video_points */
+		.orig_video_cols	= 160,
+		.orig_video_lines	= 64,
+		.orig_video_points	= 16,
 	};
 #endif
 
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index 700dc14..3056d18 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_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 @@
 
 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..758ad42 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)
 {
@@ -282,6 +284,15 @@
 	return ((cpu_get_fpu_id() & 0xff00) != FPIR_IMP_NONE);
 }
 
+static inline void cpu_probe_vmbits(struct cpuinfo_mips *c)
+{
+#ifdef __NEED_VMBITS_PROBE
+	write_c0_entryhi(0x3fffffffffffe000ULL);
+	back_to_back_c0_hazard();
+	c->vmbits = fls64(read_c0_entryhi() & 0x3fffffffffffe000ULL);
+#endif
+}
+
 #define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE \
 		| MIPS_CPU_COUNTER)
 
@@ -967,6 +978,8 @@
 		c->srsets = ((read_c0_srsctl() >> 26) & 0x0f) + 1;
 	else
 		c->srsets = 1;
+
+	cpu_probe_vmbits(c);
 }
 
 __cpuinit void cpu_report(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..c3479a43
--- /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..2bdabaa
--- /dev/null
+++ b/arch/mips/kernel/csrc-r4k-hres.c
@@ -0,0 +1,57 @@
+/*
+ * 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>
+
+#define CLOCK2NS_SCALE_FACTOR 8
+
+static unsigned long __read_mostly cycle2ns_scale;
+
+unsigned long long notrace sched_clock(void)
+{
+	unsigned long long v = cnt32_to_63(read_c0_count());
+	return (v * cycle2ns_scale) >> CLOCK2NS_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 = NSEC_PER_SEC;
+	v <<= CLOCK2NS_SCALE_FACTOR;
+	v += clock/2;
+	do_div(v, clock);
+	/*
+	 * 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++;
+	clock2ns_scale = v;
+
+	data = 0x80000000UL / 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 @@
 
 	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 @@
 		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-mt-fpaff.c b/arch/mips/kernel/mips-mt-fpaff.c
index cbc6182..0fd8b3a 100644
--- a/arch/mips/kernel/mips-mt-fpaff.c
+++ b/arch/mips/kernel/mips-mt-fpaff.c
@@ -3,6 +3,7 @@
  * Copyright (C) 2005 Mips Technologies, Inc
  */
 #include <linux/cpu.h>
+#include <linux/cpuset.h>
 #include <linux/cpumask.h>
 #include <linux/delay.h>
 #include <linux/kernel.h>
@@ -39,6 +40,21 @@
 	return pid ? find_task_by_vpid(pid) : current;
 }
 
+/*
+ * check the target process has a UID that matches the current process's
+ */
+static bool check_same_owner(struct task_struct *p)
+{
+	const struct cred *cred = current_cred(), *pcred;
+	bool match;
+
+	rcu_read_lock();
+	pcred = __task_cred(p);
+	match = (cred->euid == pcred->euid ||
+		 cred->euid == pcred->uid);
+	rcu_read_unlock();
+	return match;
+}
 
 /*
  * mipsmt_sys_sched_setaffinity - set the cpu affinity of a process
@@ -46,12 +62,10 @@
 asmlinkage long mipsmt_sys_sched_setaffinity(pid_t pid, unsigned int len,
 				      unsigned long __user *user_mask_ptr)
 {
-	cpumask_t new_mask;
-	cpumask_t effective_mask;
-	int retval;
-	struct task_struct *p;
+	cpumask_var_t cpus_allowed, new_mask, effective_mask;
 	struct thread_info *ti;
-	uid_t euid;
+	struct task_struct *p;
+	int retval;
 
 	if (len < sizeof(new_mask))
 		return -EINVAL;
@@ -71,42 +85,68 @@
 
 	/*
 	 * It is not safe to call set_cpus_allowed with the
-	 * tasklist_lock held.  We will bump the task_struct's
+	 * tasklist_lock held. We will bump the task_struct's
 	 * usage count and drop tasklist_lock before invoking
 	 * set_cpus_allowed.
 	 */
 	get_task_struct(p);
+	read_unlock(&tasklist_lock);
 
-	euid = current_euid();
-	retval = -EPERM;
-	if (euid != p->cred->euid && euid != p->cred->uid &&
-	    !capable(CAP_SYS_NICE)) {
-		read_unlock(&tasklist_lock);
-		goto out_unlock;
+	if (!alloc_cpumask_var(&cpus_allowed, GFP_KERNEL)) {
+		retval = -ENOMEM;
+		goto out_put_task;
 	}
+	if (!alloc_cpumask_var(&new_mask, GFP_KERNEL)) {
+		retval = -ENOMEM;
+		goto out_free_cpus_allowed;
+	}
+	if (!alloc_cpumask_var(&effective_mask, GFP_KERNEL)) {
+		retval = -ENOMEM;
+		goto out_free_new_mask;
+	}
+	retval = -EPERM;
+	if (!check_same_owner(p) && !capable(CAP_SYS_NICE))
+		goto out_unlock;
 
 	retval = security_task_setscheduler(p, 0, NULL);
 	if (retval)
 		goto out_unlock;
 
 	/* Record new user-specified CPU set for future reference */
-	p->thread.user_cpus_allowed = new_mask;
+	cpumask_copy(&p->thread.user_cpus_allowed, new_mask);
 
-	/* Unlock the task list */
-	read_unlock(&tasklist_lock);
-
+ again:
 	/* Compute new global allowed CPU set if necessary */
 	ti = task_thread_info(p);
 	if (test_ti_thread_flag(ti, TIF_FPUBOUND) &&
-	    cpus_intersects(new_mask, mt_fpu_cpumask)) {
-		cpus_and(effective_mask, new_mask, mt_fpu_cpumask);
-		retval = set_cpus_allowed(p, effective_mask);
+	    cpus_intersects(*new_mask, mt_fpu_cpumask)) {
+		cpus_and(*effective_mask, *new_mask, mt_fpu_cpumask);
+		retval = set_cpus_allowed_ptr(p, effective_mask);
 	} else {
+		cpumask_copy(effective_mask, new_mask);
 		clear_ti_thread_flag(ti, TIF_FPUBOUND);
-		retval = set_cpus_allowed(p, new_mask);
+		retval = set_cpus_allowed_ptr(p, new_mask);
 	}
 
+	if (!retval) {
+		cpuset_cpus_allowed(p, cpus_allowed);
+		if (!cpumask_subset(effective_mask, cpus_allowed)) {
+			/*
+			 * We must have raced with a concurrent cpuset
+			 * update. Just reset the cpus_allowed to the
+			 * cpuset's cpus_allowed
+			 */
+			cpumask_copy(new_mask, cpus_allowed);
+			goto again;
+		}
+	}
 out_unlock:
+	free_cpumask_var(effective_mask);
+out_free_new_mask:
+	free_cpumask_var(new_mask);
+out_free_cpus_allowed:
+	free_cpumask_var(cpus_allowed);
+out_put_task:
 	put_task_struct(p);
 	put_online_cpus();
 	return retval;
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_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/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index 0a51c3d..37f4245 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -385,7 +385,7 @@
 	PTR	sys_fchmodat
 	PTR	sys_faccessat
 	PTR	compat_sys_pselect6
-	PTR	sys_ppoll			/* 6265 */
+	PTR	compat_sys_ppoll		/* 6265 */
 	PTR	sys_unshare
 	PTR	sys_splice
 	PTR	sys_sync_file_range
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 @@
 
 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 @@
 	 * 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 @@
 /*
  * 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..285454f 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>
@@ -180,7 +181,7 @@
 	{0, 0, 0, 0, 0, 0, 0, 1}
 };
 int tcnoprog[NR_CPUS];
-static atomic_t idle_hook_initialized = {0};
+static atomic_t idle_hook_initialized = ATOMIC_INIT(0);
 static int clock_hang_reported[NR_CPUS];
 
 #endif /* CONFIG_SMTC_IDLE_HOOK_DEBUG */
@@ -939,23 +940,29 @@
 
 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/time.c b/arch/mips/kernel/time.c
index 1f467d5..a4903e4 100644
--- a/arch/mips/kernel/time.c
+++ b/arch/mips/kernel/time.c
@@ -152,6 +152,11 @@
 
 void __init time_init(void)
 {
+#ifdef CONFIG_HR_SCHED_CLOCK
+	if (!mips_clockevent_init() || !cpu_has_mfc0_count_bug())
+		write_c0_count(0);
+#endif
+
 	plat_time_init();
 
 	if (!mips_clockevent_init() || !cpu_has_mfc0_count_bug())
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 0a18b4c..3943c68 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -48,6 +48,7 @@
 #include <asm/types.h>
 #include <asm/stacktrace.h>
 #include <asm/irq.h>
+#include <asm/uasm.h>
 
 extern void check_wait(void);
 extern asmlinkage void r4k_wait(void);
@@ -353,9 +354,10 @@
 
 static DEFINE_SPINLOCK(die_lock);
 
-void __noreturn die(const char * str, const struct pt_regs * regs)
+void __noreturn die(const char * str, struct pt_regs * regs)
 {
 	static int die_counter;
+	int sig = SIGSEGV;
 #ifdef CONFIG_MIPS_MT_SMTC
 	unsigned long dvpret = dvpe();
 #endif /* CONFIG_MIPS_MT_SMTC */
@@ -366,6 +368,10 @@
 #ifdef CONFIG_MIPS_MT_SMTC
 	mips_mt_regdump(dvpret);
 #endif /* CONFIG_MIPS_MT_SMTC */
+
+	if (notify_die(DIE_OOPS, str, regs, 0, current->thread.trap_no, SIGSEGV) == NOTIFY_STOP)
+		sig = 0;
+
 	printk("%s[#%d]:\n", str, ++die_counter);
 	show_registers(regs);
 	add_taint(TAINT_DIE);
@@ -380,7 +386,7 @@
 		panic("Fatal exception");
 	}
 
-	do_exit(SIGSEGV);
+	do_exit(sig);
 }
 
 extern struct exception_table_entry __start___dbe_table[];
@@ -1243,21 +1249,25 @@
 unsigned long exception_handlers[32];
 unsigned long vi_handlers[64];
 
-/*
- * As a side effect of the way this is implemented we're limited
- * to interrupt handlers in the address range from
- * KSEG0 <= x < KSEG0 + 256mb on the Nevada.  Oh well ...
- */
-void *set_except_vector(int n, void *addr)
+void __init *set_except_vector(int n, void *addr)
 {
 	unsigned long handler = (unsigned long) addr;
 	unsigned long old_handler = exception_handlers[n];
 
 	exception_handlers[n] = handler;
 	if (n == 0 && cpu_has_divec) {
-		*(u32 *)(ebase + 0x200) = 0x08000000 |
-					  (0x03ffffff & (handler >> 2));
-		local_flush_icache_range(ebase + 0x200, ebase + 0x204);
+		unsigned long jump_mask = ~((1 << 28) - 1);
+		u32 *buf = (u32 *)(ebase + 0x200);
+		unsigned int k0 = 26;
+		if ((handler & jump_mask) == ((ebase + 0x200) & jump_mask)) {
+			uasm_i_j(&buf, handler & ~jump_mask);
+			uasm_i_nop(&buf);
+		} else {
+			UASM_i_LA(&buf, k0, handler);
+			uasm_i_jr(&buf, k0);
+			uasm_i_nop(&buf);
+		}
+		local_flush_icache_range(ebase + 0x200, (unsigned long)buf);
 	}
 	return (void *)old_handler;
 }
@@ -1592,12 +1602,7 @@
 void __cpuinit set_uncached_handler(unsigned long offset, void *addr,
 	unsigned long size)
 {
-#ifdef CONFIG_32BIT
-	unsigned long uncached_ebase = KSEG1ADDR(ebase);
-#endif
-#ifdef CONFIG_64BIT
-	unsigned long uncached_ebase = TO_UNCAC(ebase);
-#endif
+	unsigned long uncached_ebase = CKSEG1ADDR(ebase);
 
 	if (!addr)
 		panic(panic_null_cerr);
@@ -1634,7 +1639,7 @@
 		ebase = (unsigned long)
 			__alloc_bootmem(size, 1 << fls(size), 0);
 	} else {
-		ebase = CAC_BASE;
+		ebase = CKSEG0;
 		if (cpu_has_mips_r2)
 			ebase += (read_c0_ebase() & 0x3ffff000);
 	}
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S
index d5c95d6..b98ab5b 100644
--- a/arch/mips/kernel/vmlinux.lds.S
+++ b/arch/mips/kernel/vmlinux.lds.S
@@ -47,6 +47,7 @@
 		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 @@
 
 	/* 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/lib/delay.c b/arch/mips/lib/delay.c
index 6b3b1de9..5995969 100644
--- a/arch/mips/lib/delay.c
+++ b/arch/mips/lib/delay.c
@@ -41,7 +41,7 @@
 
 void __udelay(unsigned long us)
 {
-	unsigned int lpj = current_cpu_data.udelay_val;
+	unsigned int lpj = raw_current_cpu_data.udelay_val;
 
 	__delay((us * 0x000010c7ull * HZ * lpj) >> 32);
 }
@@ -49,7 +49,7 @@
 
 void __ndelay(unsigned long ns)
 {
-	unsigned int lpj = current_cpu_data.udelay_val;
+	unsigned int lpj = raw_current_cpu_data.udelay_val;
 
 	__delay((ns * 0x00000005ull * HZ * lpj) >> 32);
 }
diff --git a/arch/mips/lib/libgcc.h b/arch/mips/lib/libgcc.h
index 3f19d1c..05909d58 100644
--- a/arch/mips/lib/libgcc.h
+++ b/arch/mips/lib/libgcc.h
@@ -17,8 +17,7 @@
 #error I feel sick.
 #endif
 
-typedef union
-{
+typedef union {
 	struct DWstruct s;
 	long long ll;
 } DWunion;
diff --git a/arch/mips/loongson/Kconfig b/arch/mips/loongson/Kconfig
index d450925..269bf6f 100644
--- a/arch/mips/loongson/Kconfig
+++ b/arch/mips/loongson/Kconfig
@@ -1,31 +1,139 @@
 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
+	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.
+	  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
+	select 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_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..39a8b96 100644
--- a/arch/mips/loongson/common/Makefile
+++ b/arch/mips/loongson/common/Makefile
@@ -3,9 +3,30 @@
 #
 
 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
+obj-$(CONFIG_GENERIC_GPIO) += gpio.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 @@
 	.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 @@
 {
 	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 @@
 		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..ea6c3be
--- /dev/null
+++ b/arch/mips/loongson/common/cs5536/cs5536_ehci.c
@@ -0,0 +1,160 @@
+/*
+ * 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) {
+			_rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
+			lo = value;
+			_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..56dd2f4
--- /dev/null
+++ b/arch/mips/loongson/common/cs5536/cs5536_ide.c
@@ -0,0 +1,192 @@
+/*
+ * 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) {
+			_rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo);
+			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 {
+			_rdmsr(IDE_MSR_REG(IDE_CFG), &hi, &lo);
+			lo = value;
+			_wrmsr(IDE_MSR_REG(IDE_CFG), hi, lo);
+		}
+		break;
+	case PCI_IDE_DTC_REG:
+		_rdmsr(IDE_MSR_REG(IDE_DTC), &hi, &lo);
+		lo = value;
+		_wrmsr(IDE_MSR_REG(IDE_DTC), hi, lo);
+		break;
+	case PCI_IDE_CAST_REG:
+		_rdmsr(IDE_MSR_REG(IDE_CAST), &hi, &lo);
+		lo = value;
+		_wrmsr(IDE_MSR_REG(IDE_CAST), hi, lo);
+		break;
+	case PCI_IDE_ETC_REG:
+		_rdmsr(IDE_MSR_REG(IDE_ETC), &hi, &lo);
+		lo = value;
+		_wrmsr(IDE_MSR_REG(IDE_ETC), hi, lo);
+		break;
+	case PCI_IDE_PM_REG:
+		_rdmsr(IDE_MSR_REG(IDE_INTERNAL_PM), &hi, &lo);
+		lo = value;
+		_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;
+		break;
+	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..479b935
--- /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(offset), 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(offset), 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..c38b3af
--- /dev/null
+++ b/arch/mips/loongson/common/cs5536/cs5536_ohci.c
@@ -0,0 +1,149 @@
+/*
+ * 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) {
+			_rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo);
+			lo = value;
+			_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/gpio.c b/arch/mips/loongson/common/gpio.c
new file mode 100644
index 0000000..e8a0ffa
--- /dev/null
+++ b/arch/mips/loongson/common/gpio.c
@@ -0,0 +1,139 @@
+/*
+ *  STLS2F GPIO Support
+ *
+ *  Copyright (c) 2008 Richard Liu,  STMicroelectronics  <richard.liu@st.com>
+ *  Copyright (c) 2008-2010 Arnaud Patard <apatard@mandriva.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/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/err.h>
+#include <asm/types.h>
+#include <loongson.h>
+#include <linux/gpio.h>
+
+#define STLS2F_N_GPIO		4
+#define STLS2F_GPIO_IN_OFFSET	16
+
+static DEFINE_SPINLOCK(gpio_lock);
+
+int gpio_get_value(unsigned gpio)
+{
+	u32 val;
+	u32 mask;
+
+	if (gpio >= STLS2F_N_GPIO)
+		return __gpio_get_value(gpio);
+
+	mask = 1 << (gpio + STLS2F_GPIO_IN_OFFSET);
+	spin_lock(&gpio_lock);
+	val = LOONGSON_GPIODATA;
+	spin_unlock(&gpio_lock);
+
+	return ((val & mask) != 0);
+}
+EXPORT_SYMBOL(gpio_get_value);
+
+void gpio_set_value(unsigned gpio, int state)
+{
+	u32 val;
+	u32 mask;
+
+	if (gpio >= STLS2F_N_GPIO) {
+		__gpio_set_value(gpio, state);
+		return ;
+	}
+
+	mask = 1 << gpio;
+
+	spin_lock(&gpio_lock);
+	val = LOONGSON_GPIODATA;
+	if (state)
+		val |= mask;
+	else
+		val &= (~mask);
+	LOONGSON_GPIODATA = val;
+	spin_unlock(&gpio_lock);
+}
+EXPORT_SYMBOL(gpio_set_value);
+
+int gpio_cansleep(unsigned gpio)
+{
+	if (gpio < STLS2F_N_GPIO)
+		return 0;
+	else
+		return __gpio_cansleep(gpio);
+}
+EXPORT_SYMBOL(gpio_cansleep);
+
+static int ls2f_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
+{
+	u32 temp;
+	u32 mask;
+
+	if (gpio >= STLS2F_N_GPIO)
+		return -EINVAL;
+
+	spin_lock(&gpio_lock);
+	mask = 1 << gpio;
+	temp = LOONGSON_GPIOIE;
+	temp |= mask;
+	LOONGSON_GPIOIE = temp;
+	spin_unlock(&gpio_lock);
+
+	return 0;
+}
+
+static int ls2f_gpio_direction_output(struct gpio_chip *chip,
+		unsigned gpio, int level)
+{
+	u32 temp;
+	u32 mask;
+
+	if (gpio >= STLS2F_N_GPIO)
+		return -EINVAL;
+
+	gpio_set_value(gpio, level);
+	spin_lock(&gpio_lock);
+	mask = 1 << gpio;
+	temp = LOONGSON_GPIOIE;
+	temp &= (~mask);
+	LOONGSON_GPIOIE = temp;
+	spin_unlock(&gpio_lock);
+
+	return 0;
+}
+
+static int ls2f_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
+{
+	return gpio_get_value(gpio);
+}
+
+static void ls2f_gpio_set_value(struct gpio_chip *chip,
+		unsigned gpio, int value)
+{
+	gpio_set_value(gpio, value);
+}
+
+static struct gpio_chip ls2f_chip = {
+	.label                  = "ls2f",
+	.direction_input        = ls2f_gpio_direction_input,
+	.get                    = ls2f_gpio_get_value,
+	.direction_output       = ls2f_gpio_direction_output,
+	.set                    = ls2f_gpio_set_value,
+	.base                   = 0,
+	.ngpio                  = STLS2F_N_GPIO,
+};
+
+static int __init ls2f_gpio_setup(void)
+{
+	return gpiochip_add(&ls2f_chip);
+}
+arch_initcall(ls2f_gpio_setup);
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 @@
 	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 @@
 	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..63b9459 100644
--- a/arch/mips/loongson/common/machtype.c
+++ b/arch/mips/loongson/common/machtype.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
  *
  * Copyright (c) 2009 Zhang Le <r0bertz@gentoo.org>
@@ -15,36 +15,51 @@
 #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",
 	[MACH_LEMOTE_FL2F]              "lemote-fuloong-2f-box",
 	[MACH_LEMOTE_ML2F7]             "lemote-mengloong-2f-7inches",
 	[MACH_LEMOTE_YL2F89]            "lemote-yeeloong-2f-8.9inches",
-	[MACH_DEXXON_GDIUM2F10]         "dexxon-gidum-2f-10inches",
+	[MACH_DEXXON_GDIUM2F10]         "dexxon-gdium-2f",
+	[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 __weak __init mach_prom_init_machtype(void)
 {
+}
+
+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) {
+		mach_prom_init_machtype();
+		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..d07b18c 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 @@
 		((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 >> 16) == PCI_BASE_CLASS_DISPLAY) {
+			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 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 @@
 	 * 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 @@
 	/* 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..83cc514 100644
--- a/arch/mips/loongson/common/reset.c
+++ b/arch/mips/loongson/common/reset.c
@@ -21,22 +21,43 @@
 	/* 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)
+static void loongson_poweroff(void)
 {
 	mach_prepare_shutdown();
 	while (1)
 		;
 }
 
+static void loongson_halt(void)
+{
+	pr_notice("** You can safely turn off the power ** !\n");
+	while (1) {
+		if (cpu_wait)
+			cpu_wait();
+	}
+}
+
 static int __init mips_reboot_setup(void)
 {
 	_machine_restart = loongson_restart;
 	_machine_halt = loongson_halt;
-	pm_power_off = loongson_halt;
+	pm_power_off = loongson_poweroff;
 
 	return 0;
 }
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..d35512c
--- /dev/null
+++ b/arch/mips/loongson/common/serial.c
@@ -0,0 +1,80 @@
+/*
+ * 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);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("liu shiwei <liushiwei@anheng.com.cn>");
+MODULE_DESCRIPTION("loongson serial");
diff --git a/arch/mips/loongson/common/setup.c b/arch/mips/loongson/common/setup.c
index 4cd2aa9..27d826b 100644
--- a/arch/mips/loongson/common/setup.c
+++ b/arch/mips/loongson/common/setup.c
@@ -41,15 +41,12 @@
 	conswitchp = &vga_con;
 
 	screen_info = (struct screen_info) {
-		0, 25,		/* orig-x, orig-y */
-		    0,		/* unused */
-		    0,		/* orig-video-page */
-		    0,		/* orig-video-mode */
-		    80,		/* orig-video-cols */
-		    0, 0, 0,	/* ega_ax, ega_bx, ega_cx */
-		    25,		/* orig-video-lines */
-		    VIDEO_TYPE_VGAC,	/* orig-video-isVGA */
-		    16		/* orig-video-points */
+		.orig_x			= 0,
+		.orig_y			= 25,
+		.orig_video_cols	= 80,
+		.orig_video_lines	= 25,
+		.orig_video_isVGA	= VIDEO_TYPE_VGAC,
+		.orig_video_points	= 16,
 	};
 #elif defined(CONFIG_DUMMY_CONSOLE)
 	conswitchp = &dummy_con;
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 @@
 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..f776f36
--- /dev/null
+++ b/arch/mips/loongson/lemote-2f/Makefile
@@ -0,0 +1,17 @@
+#
+# Makefile for lemote loongson2f family machines
+#
+
+obj-y += machtype.o 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..0ad3d72
--- /dev/null
+++ b/arch/mips/loongson/lemote-2f/ec_kb3310b.c
@@ -0,0 +1,129 @@
+/*
+ * 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;
+	}
+
+	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..320c245
--- /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 */
+#if defined(CONFIG_OPROFILE) || defined(CONFIG_OPROFILE_MODULE)
+		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..5fb06dc
--- /dev/null
+++ b/arch/mips/loongson/lemote-2f/lynloong_pc.c
@@ -0,0 +1,589 @@
+/*
+ *  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;
+
+DEFINE_SPINLOCK(backlight_lock);
+/* tune the brightness */
+static void setup_mfgpt2(void)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&backlight_lock, flags);
+	/* 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);
+	spin_unlock_irqrestore(&backlight_lock, flags);
+}
+
+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/machtype.c b/arch/mips/loongson/lemote-2f/machtype.c
new file mode 100644
index 0000000..610f431
--- /dev/null
+++ b/arch/mips/loongson/lemote-2f/machtype.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 <asm/bootinfo.h>
+
+#include <loongson.h>
+
+void __init mach_prom_init_machtype(void)
+{
+	/* We share the same kernel image file among Lemote 2F family
+	 * of machines, and provide the machtype= kernel command line
+	 * to users to indicate their machine, this command line will
+	 * be passed by the latest PMON automatically. and fortunately,
+	 * up to now, we can get the machine type from the PMON_VER=
+	 * commandline directly except the NAS machine, In the old
+	 * machines, this will help the users a lot.
+	 *
+	 * If no "machtype=" passed, get machine type from "PMON_VER=".
+	 * 	PMON_VER=LM8089		Lemote 8.9'' netbook
+	 * 	         LM8101		Lemote 10.1'' netbook
+	 * 	(The above two netbooks have the same kernel support)
+	 *	         LM6XXX		Lemote FuLoong(2F) box series
+	 *	         LM9XXX		Lemote LynLoong PC series
+	 */
+	if (strstr(arcs_cmdline, "PMON_VER=LM")) {
+		if (strstr(arcs_cmdline, "PMON_VER=LM8"))
+			mips_machtype = MACH_LEMOTE_YL2F89;
+		else if (strstr(arcs_cmdline, "PMON_VER=LM6"))
+			mips_machtype = MACH_LEMOTE_FL2F;
+		else if (strstr(arcs_cmdline, "PMON_VER=LM9"))
+			mips_machtype = MACH_LEMOTE_LL2F;
+		else
+			mips_machtype = MACH_LEMOTE_NAS;
+
+		strcat(arcs_cmdline, " machtype=");
+		strcat(arcs_cmdline, get_system_type());
+		strcat(arcs_cmdline, " ");
+	}
+}
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..b09fc93
--- /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..b0fd8da
--- /dev/null
+++ b/arch/mips/loongson/lemote-2f/yeeloong_laptop.c
@@ -0,0 +1,1330 @@
+/*
+ *  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"
+
+#define EC_VER_LEN 64
+
+static int ec_ver_small_than(char *version)
+{
+	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, version, 64) < 0)
+		return 1;
+	return 0;
+}
+/* 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 */
+
+#define MIN_FAN_SPEED 0
+#define MAX_FAN_SPEED 3
+
+static int get_fan_pwm_enable(void)
+{
+	int level, mode;
+
+	level = ec_read(REG_FAN_SPEED_LEVEL);
+	mode = ec_read(REG_FAN_AUTO_MAN_SWITCH);
+
+	if (level == MAX_FAN_SPEED && mode == BIT_FAN_MANUAL)
+		mode = 0;
+	else if (mode == BIT_FAN_MANUAL)
+		mode = 1;
+	else
+		mode = 2;
+
+	return mode;
+}
+
+static void set_fan_pwm_enable(int mode)
+{
+	switch (mode) {
+	case 0:
+		/* fullspeed */
+		ec_write(REG_FAN_AUTO_MAN_SWITCH, BIT_FAN_MANUAL);
+		ec_write(REG_FAN_SPEED_LEVEL, MAX_FAN_SPEED);
+		break;
+	case 1:
+		ec_write(REG_FAN_AUTO_MAN_SWITCH, BIT_FAN_MANUAL);
+		break;
+	case 2:
+		ec_write(REG_FAN_AUTO_MAN_SWITCH, BIT_FAN_AUTO);
+		break;
+	default:
+		break;
+	}
+}
+
+static int get_fan_pwm(void)
+{
+	return ec_read(REG_FAN_SPEED_LEVEL);
+}
+
+static void set_fan_pwm(int value)
+{
+	int status, mode;
+
+	mode = ec_read(REG_FAN_AUTO_MAN_SWITCH);
+	if (mode != BIT_FAN_MANUAL)
+		return;
+
+	value = SENSORS_LIMIT(value, MIN_FAN_SPEED, MAX_FAN_SPEED);
+
+	/* 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_cpu_temp_max(void)
+{
+	/* 60℃  is the max temp for loongson work normally. */
+	return 60 * 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(temp1_max, S_IRUGO, get_cpu_temp_max, 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_temp1_max.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(2);
+
+	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)
+{
+	if (ec_ver_small_than("EC_VER=PQ1D27")) {
+		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;
+}
+
+static int black_screen_handler(int status)
+{
+	if (ec_ver_small_than("EC_VER=PQ1D26"))
+		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();
+		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(1);
+	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(2);
+
+	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 c15d94b..f2338d1 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 @@
 
 /* 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 */
 
@@ -212,7 +215,7 @@
 	unsigned int cond;
 
 	if (get_user(ir, (mips_instruction __user *) xcp->cp0_epc)) {
-		fpuemustats.errors++;
+		MIPS_FPU_EMU_INC_STATS(errors);
 		return SIGBUS;
 	}
 
@@ -243,7 +246,7 @@
 			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 */
@@ -256,16 +259,16 @@
 	}
 
       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));
@@ -277,10 +280,10 @@
 			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;
@@ -291,9 +294,9 @@
 			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));
@@ -305,10 +308,10 @@
 			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;
@@ -436,7 +439,7 @@
 
 				if (get_user(ir,
 				    (mips_instruction __user *) xcp->cp0_epc)) {
-					fpuemustats.errors++;
+					MIPS_FPU_EMU_INC_STATS(errors);
 					return SIGBUS;
 				}
 
@@ -602,7 +605,7 @@
 {
 	unsigned rcsr = 0;	/* resulting csr */
 
-	fpuemustats.cp1xops++;
+	MIPS_FPU_EMU_INC_STATS(cp1xops);
 
 	switch (MIPSInst_FMA_FFMT(ir)) {
 	case s_fmt:{		/* 0 */
@@ -617,9 +620,9 @@
 			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));
@@ -629,11 +632,11 @@
 			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;
@@ -694,9 +697,9 @@
 			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));
@@ -706,10 +709,10 @@
 			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;
@@ -776,7 +779,7 @@
 #endif
 	} rv;			/* resulting value */
 
-	fpuemustats.cp1ops++;
+	MIPS_FPU_EMU_INC_STATS(cp1ops);
 	switch (rfmt = (MIPSInst_FFMT(ir) & 0xf)) {
 	case s_fmt:{		/* 0 */
 		union {
@@ -1247,7 +1250,7 @@
 		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)
@@ -1283,33 +1286,50 @@
 }
 
 #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/dp_simple.c b/arch/mips/math-emu/dp_simple.c
index d9ae1db..b909742 100644
--- a/arch/mips/math-emu/dp_simple.c
+++ b/arch/mips/math-emu/dp_simple.c
@@ -78,6 +78,7 @@
 	DPSIGN(x) = 0;
 
 	if (xc == IEEE754_CLASS_SNAN) {
+		SETCX(IEEE754_INVALID_OPERATION);
 		return ieee754dp_nanxcpt(ieee754dp_indef(), "abs");
 	}
 
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 @@
 	err |= __put_user(cpc, &fr->epc);
 
 	if (unlikely(err)) {
-		fpuemustats.errors++;
+		MIPS_FPU_EMU_INC_STATS(errors);
 		return SIGBUS;
 	}
 
@@ -136,7 +136,7 @@
 	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/math-emu/sp_simple.c b/arch/mips/math-emu/sp_simple.c
index 3175477..2fd53c9 100644
--- a/arch/mips/math-emu/sp_simple.c
+++ b/arch/mips/math-emu/sp_simple.c
@@ -78,6 +78,7 @@
 	SPSIGN(x) = 0;
 
 	if (xc == IEEE754_CLASS_SNAN) {
+		SETCX(IEEE754_INVALID_OPERATION);
 		return ieee754sp_nanxcpt(ieee754sp_indef(), "abs");
 	}
 
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 @@
 	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/c-octeon.c b/arch/mips/mm/c-octeon.c
index 94e05e5..e06f1af 100644
--- a/arch/mips/mm/c-octeon.c
+++ b/arch/mips/mm/c-octeon.c
@@ -174,7 +174,7 @@
  * Probe Octeon's caches
  *
  */
-static void __devinit probe_octeon(void)
+static void __cpuinit probe_octeon(void)
 {
 	unsigned long icache_size;
 	unsigned long dcache_size;
@@ -235,7 +235,7 @@
  * Setup the Octeon cache flush routines
  *
  */
-void __devinit octeon_cache_init(void)
+void __cpuinit octeon_cache_init(void)
 {
 	extern unsigned long ebase;
 	extern char except_vec2_octeon;
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
index 37603a4..3f359e5 100644
--- a/arch/mips/mm/cache.c
+++ b/arch/mips/mm/cache.c
@@ -145,7 +145,7 @@
 }
 
 unsigned long _page_cachable_default;
-EXPORT_SYMBOL_GPL(_page_cachable_default);
+EXPORT_SYMBOL(_page_cachable_default);
 
 static inline void setup_protection_map(void)
 {
@@ -167,7 +167,7 @@
 	protection_map[15] = PAGE_SHARED;
 }
 
-void __devinit cpu_cache_init(void)
+void __cpuinit cpu_cache_init(void)
 {
 	if (cpu_has_3k_cache) {
 		extern void __weak r3k_cache_init(void);
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 @@
 				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 @@
 			__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/page.c b/arch/mips/mm/page.c
index f5c7375..36272f7 100644
--- a/arch/mips/mm/page.c
+++ b/arch/mips/mm/page.c
@@ -35,7 +35,7 @@
 #include <asm/sibyte/sb1250_dma.h>
 #endif
 
-#include "uasm.h"
+#include <asm/uasm.h>
 
 /* Registers used in the assembled routines. */
 #define ZERO 0
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index 266c003..67ccd00 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -29,8 +29,17 @@
 
 #include <asm/mmu_context.h>
 #include <asm/war.h>
+#include <asm/uasm.h>
 
-#include "uasm.h"
+/*
+ * TLB load/store/modify handlers.
+ *
+ * Only the fastpath gets synthesized at runtime, the slowpath for
+ * do_page_fault remains normal asm.
+ */
+extern void tlb_do_page_fault_0(void);
+extern void tlb_do_page_fault_1(void);
+
 
 static inline int r45k_bvahwbug(void)
 {
@@ -82,6 +91,7 @@
 	label_nopage_tlbm,
 	label_smp_pgtable_change,
 	label_r3000_write_probe_fail,
+	label_large_segbits_fault,
 #ifdef CONFIG_HUGETLB_PAGE
 	label_tlb_huge_update,
 #endif
@@ -98,6 +108,7 @@
 UASM_L_LA(_nopage_tlbm)
 UASM_L_LA(_smp_pgtable_change)
 UASM_L_LA(_r3000_write_probe_fail)
+UASM_L_LA(_large_segbits_fault)
 #ifdef CONFIG_HUGETLB_PAGE
 UASM_L_LA(_tlb_huge_update)
 #endif
@@ -154,6 +165,15 @@
 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.
+ */
+#ifdef CONFIG_64BIT
+static int check_for_high_segbits __cpuinitdata;
+#endif
+
 /*
  * The R3000 TLB handler is simple.
  */
@@ -193,6 +213,7 @@
 
 	dump_handler((u32 *)ebase, 32);
 }
+#endif /* CONFIG_MIPS_PGD_C0_CONTEXT */
 
 /*
  * The R4000 TLB handler is much more complicated. We have two
@@ -491,16 +512,42 @@
 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.
 	 */
 	uasm_i_dmfc0(p, tmp, C0_BADVADDR);
-	uasm_il_bltz(p, r, tmp, label_vmalloc);
+
+	if (check_for_high_segbits) {
+		/*
+		 * The kernel currently implicitely assumes that the
+		 * MIPS SEGBITS parameter for the processor is
+		 * (PGDIR_SHIFT+PGDIR_BITS) or less, and will never
+		 * allocate virtual addresses outside the maximum
+		 * range for SEGBITS = (PGDIR_SHIFT+PGDIR_BITS). But
+		 * that doesn't prevent user code from accessing the
+		 * higher xuseg addresses.  Here, we make sure that
+		 * everything but the lower xuseg addresses goes down
+		 * the module_alloc/vmalloc path.
+		 */
+		uasm_i_dsrl_safe(p, ptr, tmp, PGDIR_SHIFT + PGD_ORDER + PAGE_SHIFT - 3);
+		uasm_il_bnez(p, r, ptr, label_vmalloc);
+	} else {
+		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
@@ -514,7 +561,7 @@
 	 */
 	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);
@@ -540,28 +587,64 @@
 	uasm_i_daddu(p, ptr, ptr, tmp); /* add in pmd offset */
 }
 
+enum vmalloc64_mode {not_refill, refill};
 /*
  * BVADDR is the faulting address, PTR is scratch.
  * PTR will hold the pgd for vmalloc.
  */
 static void __cpuinit
 build_get_pgd_vmalloc64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
-			unsigned int bvaddr, unsigned int ptr)
+			unsigned int bvaddr, unsigned int ptr,
+			enum vmalloc64_mode mode)
 {
 	long swpd = (long)swapper_pg_dir;
+	int single_insn_swpd;
+	int did_vmalloc_branch = 0;
+
+	single_insn_swpd = uasm_in_compat_space_p(swpd) && !uasm_rel_lo(swpd);
 
 	uasm_l_vmalloc(l, *p);
 
-	if (uasm_in_compat_space_p(swpd) && !uasm_rel_lo(swpd)) {
-		uasm_il_b(p, r, label_vmalloc_done);
-		uasm_i_lui(p, ptr, uasm_rel_hi(swpd));
-	} else {
-		UASM_i_LA_mostly(p, ptr, swpd);
-		uasm_il_b(p, r, label_vmalloc_done);
-		if (uasm_in_compat_space_p(swpd))
-			uasm_i_addiu(p, ptr, ptr, uasm_rel_lo(swpd));
-		else
-			uasm_i_daddiu(p, ptr, ptr, uasm_rel_lo(swpd));
+	if (mode == refill && check_for_high_segbits) {
+		if (single_insn_swpd) {
+			uasm_il_bltz(p, r, bvaddr, label_vmalloc_done);
+			uasm_i_lui(p, ptr, uasm_rel_hi(swpd));
+			did_vmalloc_branch = 1;
+			/* fall through */
+		} else {
+			uasm_il_bgez(p, r, bvaddr, label_large_segbits_fault);
+		}
+	}
+	if (!did_vmalloc_branch) {
+		if (uasm_in_compat_space_p(swpd) && !uasm_rel_lo(swpd)) {
+			uasm_il_b(p, r, label_vmalloc_done);
+			uasm_i_lui(p, ptr, uasm_rel_hi(swpd));
+		} else {
+			UASM_i_LA_mostly(p, ptr, swpd);
+			uasm_il_b(p, r, label_vmalloc_done);
+			if (uasm_in_compat_space_p(swpd))
+				uasm_i_addiu(p, ptr, ptr, uasm_rel_lo(swpd));
+			else
+				uasm_i_daddiu(p, ptr, ptr, uasm_rel_lo(swpd));
+		}
+	}
+	if (mode == refill && check_for_high_segbits) {
+		uasm_l_large_segbits_fault(l, *p);
+		/*
+		 * We get here if we are an xsseg address, or if we are
+		 * an xuseg address above (PGDIR_SHIFT+PGDIR_BITS) boundary.
+		 *
+		 * Ignoring xsseg (assume disabled so would generate
+		 * (address errors?), the only remaining possibility
+		 * is the upper xuseg addresses.  On processors with
+		 * TLB_SEGBITS <= PGDIR_SHIFT+PGDIR_BITS, these
+		 * addresses would have taken an address error. We try
+		 * to mimic that here by taking a load/istream page
+		 * fault.
+		 */
+		UASM_i_LA(p, ptr, (unsigned long)tlb_do_page_fault_0);
+		uasm_i_jr(p, ptr);
+		uasm_i_nop(p);
 	}
 }
 
@@ -762,7 +845,7 @@
 #endif
 
 #ifdef CONFIG_64BIT
-	build_get_pgd_vmalloc64(&p, &l, &r, K0, K1);
+	build_get_pgd_vmalloc64(&p, &l, &r, K0, K1, refill);
 #endif
 
 	/*
@@ -872,15 +955,6 @@
 }
 
 /*
- * TLB load/store/modify handlers.
- *
- * Only the fastpath gets synthesized at runtime, the slowpath for
- * do_page_fault remains normal asm.
- */
-extern void tlb_do_page_fault_0(void);
-extern void tlb_do_page_fault_1(void);
-
-/*
  * 128 instructions for the fastpath handler is generous and should
  * never be exceeded.
  */
@@ -1030,6 +1104,7 @@
 	iPTE_LW(p, pte, ptr);
 }
 
+#ifndef CONFIG_MIPS_PGD_C0_CONTEXT
 /*
  * R3000 style TLB load/store/modify handlers.
  */
@@ -1181,6 +1256,7 @@
 
 	dump_handler(handle_tlbm, ARRAY_SIZE(handle_tlbm));
 }
+#endif /* CONFIG_MIPS_PGD_C0_CONTEXT */
 
 /*
  * R4000 style TLB load/store/modify handlers.
@@ -1232,7 +1308,7 @@
 	uasm_i_eret(p); /* return from trap */
 
 #ifdef CONFIG_64BIT
-	build_get_pgd_vmalloc64(p, l, r, tmp, ptr);
+	build_get_pgd_vmalloc64(p, l, r, tmp, ptr, not_refill);
 #endif
 }
 
@@ -1394,6 +1470,10 @@
 	 */
 	static int run_once = 0;
 
+#ifdef CONFIG_64BIT
+	check_for_high_segbits = current_cpu_data.vmbits > (PGDIR_SHIFT + PGD_ORDER + PAGE_SHIFT - 3);
+#endif
+
 	switch (current_cpu_type()) {
 	case CPU_R2000:
 	case CPU_R3000:
@@ -1402,6 +1482,7 @@
 	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();
@@ -1409,6 +1490,9 @@
 			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 e1bd527..29bbd10 100644
--- a/arch/mips/mm/uasm.c
+++ b/arch/mips/mm/uasm.c
@@ -19,8 +19,7 @@
 #include <asm/inst.h>
 #include <asm/elf.h>
 #include <asm/bugs.h>
-
-#include "uasm.h"
+#include <asm/uasm.h>
 
 enum fields {
 	RS = 0x001,
@@ -60,11 +59,11 @@
 	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_or, 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 +103,7 @@
 	{ 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 },
@@ -133,6 +133,7 @@
 	{ 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 }
 };
 
@@ -305,6 +306,12 @@
 	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)						\
 {							\
@@ -350,6 +357,7 @@
 I_u2u1u3(_dsra)
 I_u2u1u3(_dsrl)
 I_u2u1u3(_dsrl32)
+I_u2u1u3(_drotr)
 I_u3u1u2(_dsubu)
 I_0(_eret)
 I_u1(_j)
@@ -379,6 +387,7 @@
 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/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 @@
 	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 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_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/nxp/pnx8550/common/reset.c b/arch/mips/nxp/pnx8550/common/reset.c
index 7b2cbc5..9dc16ff 100644
--- a/arch/mips/nxp/pnx8550/common/reset.c
+++ b/arch/mips/nxp/pnx8550/common/reset.c
@@ -20,6 +20,7 @@
  * Reset the PNX8550 board.
  *
  */
+#include <linux/kernel.h>
 #include <linux/slab.h>
 #include <asm/reboot.h>
 #include <glb.h>
diff --git a/arch/mips/oprofile/common.c b/arch/mips/oprofile/common.c
index 7832ad2..ee46c82 100644
--- a/arch/mips/oprofile/common.c
+++ b/arch/mips/oprofile/common.c
@@ -14,9 +14,9 @@
 
 #include "op_impl.h"
 
-extern struct op_mips_model op_model_mipsxx_ops __attribute__((weak));
-extern struct op_mips_model op_model_rm9000_ops __attribute__((weak));
-extern struct op_mips_model op_model_loongson2_ops __attribute__((weak));
+extern struct op_mips_model op_model_mipsxx_ops __weak;
+extern struct op_mips_model op_model_rm9000_ops __weak;
+extern struct op_mips_model op_model_loongson2_ops __weak;
 
 static struct op_mips_model *model;
 
diff --git a/arch/mips/oprofile/op_model_loongson2.c b/arch/mips/oprofile/op_model_loongson2.c
index 575cd14..5239d0f 100644
--- a/arch/mips/oprofile/op_model_loongson2.c
+++ b/arch/mips/oprofile/op_model_loongson2.c
@@ -1,14 +1,13 @@
 /*
  * 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>
  *
  * 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/init.h>
 #include <linux/oprofile.h>
@@ -17,24 +16,18 @@
 #include <loongson.h>			/* LOONGSON2_PERFCNT_IRQ */
 #include "op_impl.h"
 
-/*
- * a patch should be sent to oprofile with the loongson-specific support.
- * otherwise, the oprofile tool will not recognize this and complain about
- * "cpu_type 'unset' is not valid".
- */
 #define LOONGSON2_CPU_TYPE	"mips/loongson2"
 
-#define LOONGSON2_COUNTER1_EVENT(event)	((event & 0x0f) << 5)
-#define LOONGSON2_COUNTER2_EVENT(event)	((event & 0x0f) << 9)
-
-#define LOONGSON2_PERFCNT_EXL			(1UL	<<  0)
-#define LOONGSON2_PERFCNT_KERNEL		(1UL    <<  1)
-#define LOONGSON2_PERFCNT_SUPERVISOR	(1UL    <<  2)
-#define LOONGSON2_PERFCNT_USER			(1UL    <<  3)
-#define LOONGSON2_PERFCNT_INT_EN		(1UL    <<  4)
 #define LOONGSON2_PERFCNT_OVERFLOW		(1ULL   << 31)
 
-/* Loongson2 performance counter register */
+#define LOONGSON2_PERFCTRL_EXL			(1UL	<<  0)
+#define LOONGSON2_PERFCTRL_KERNEL		(1UL    <<  1)
+#define LOONGSON2_PERFCTRL_SUPERVISOR		(1UL    <<  2)
+#define LOONGSON2_PERFCTRL_USER			(1UL    <<  3)
+#define LOONGSON2_PERFCTRL_ENABLE		(1UL    <<  4)
+#define LOONGSON2_PERFCTRL_EVENT(idx, event) \
+	(((event) & 0x0f) << ((idx) ? 9 : 5))
+
 #define read_c0_perfctrl() __read_64bit_c0_register($24, 0)
 #define write_c0_perfctrl(val) __write_64bit_c0_register($24, 0, val)
 #define read_c0_perfcnt() __read_64bit_c0_register($25, 0)
@@ -51,7 +44,12 @@
 
 static char *oprofid = "LoongsonPerf";
 static irqreturn_t loongson2_perfcount_handler(int irq, void *dev_id);
-/* Compute all of the registers in preparation for enabling profiling.  */
+
+static void reset_counters(void *arg)
+{
+	write_c0_perfctrl(0);
+	write_c0_perfcnt(0);
+}
 
 static void loongson2_reg_setup(struct op_counter_config *cfg)
 {
@@ -59,41 +57,38 @@
 
 	reg.reset_counter1 = 0;
 	reg.reset_counter2 = 0;
-	/* Compute the performance counter ctrl word.  */
-	/* For now count kernel and user mode */
+
+	/*
+	 * Compute the performance counter ctrl word.
+	 * For now, count kernel and user mode.
+	 */
 	if (cfg[0].enabled) {
-		ctrl |= LOONGSON2_COUNTER1_EVENT(cfg[0].event);
+		ctrl |= LOONGSON2_PERFCTRL_EVENT(0, cfg[0].event);
 		reg.reset_counter1 = 0x80000000ULL - cfg[0].count;
 	}
 
 	if (cfg[1].enabled) {
-		ctrl |= LOONGSON2_COUNTER2_EVENT(cfg[1].event);
-		reg.reset_counter2 = (0x80000000ULL - cfg[1].count);
+		ctrl |= LOONGSON2_PERFCTRL_EVENT(1, cfg[1].event);
+		reg.reset_counter2 = 0x80000000ULL - cfg[1].count;
 	}
 
 	if (cfg[0].enabled || cfg[1].enabled) {
-		ctrl |= LOONGSON2_PERFCNT_EXL | LOONGSON2_PERFCNT_INT_EN;
+		ctrl |= LOONGSON2_PERFCTRL_EXL | LOONGSON2_PERFCTRL_ENABLE;
 		if (cfg[0].kernel || cfg[1].kernel)
-			ctrl |= LOONGSON2_PERFCNT_KERNEL;
+			ctrl |= LOONGSON2_PERFCTRL_KERNEL;
 		if (cfg[0].user || cfg[1].user)
-			ctrl |= LOONGSON2_PERFCNT_USER;
+			ctrl |= LOONGSON2_PERFCTRL_USER;
 	}
 
 	reg.ctrl = ctrl;
 
 	reg.cnt1_enabled = cfg[0].enabled;
 	reg.cnt2_enabled = cfg[1].enabled;
-
 }
 
-/* Program all of the registers in preparation for enabling profiling.  */
-
 static void loongson2_cpu_setup(void *args)
 {
-	uint64_t perfcount;
-
-	perfcount = (reg.reset_counter2 << 32) | reg.reset_counter1;
-	write_c0_perfcnt(perfcount);
+	write_c0_perfcnt((reg.reset_counter2 << 32) | reg.reset_counter1);
 }
 
 static void loongson2_cpu_start(void *args)
@@ -117,14 +112,10 @@
 	int enabled;
 	unsigned long flags;
 
-	/*
-	 * LOONGSON2 defines two 32-bit performance counters.
-	 * To avoid a race updating the registers we need to stop the counters
-	 * while we're messing with
-	 * them ...
-	 */
-
 	/* Check whether the irq belongs to me */
+	enabled = read_c0_perfctrl() & LOONGSON2_PERFCTRL_ENABLE;
+	if (!enabled)
+		return IRQ_NONE;
 	enabled = reg.cnt1_enabled | reg.cnt2_enabled;
 	if (!enabled)
 		return IRQ_NONE;
@@ -161,7 +152,7 @@
 
 static void loongson2_exit(void)
 {
-	write_c0_perfctrl(0);
+	reset_counters(NULL);
 	free_irq(LOONGSON2_PERFCNT_IRQ, oprofid);
 }
 
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_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 @@
 			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..4b9768d
--- /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 << 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 @@
 	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..7793efb
--- /dev/null
+++ b/arch/mips/pci/ops-loongson2.c
@@ -0,0 +1,219 @@
+/*
+ * 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
+
+DEFINE_SPINLOCK(msr_lock);
+
+void _rdmsr(u32 msr, u32 *hi, u32 *lo)
+{
+	struct pci_bus bus = {
+		.number = PCI_BUS_CS5536
+	};
+	u32 devfn = PCI_DEVFN(PCI_IDSEL_CS5536, 0);
+	unsigned long flags;
+
+	spin_lock_irqsave(&msr_lock, flags);
+	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);
+	spin_unlock_irqrestore(&msr_lock, flags);
+}
+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);
+	unsigned long flags;
+
+	spin_lock_irqsave(&msr_lock, flags);
+	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);
+	spin_unlock_irqrestore(&msr_lock, flags);
+}
+EXPORT_SYMBOL(_wrmsr);
+#endif
diff --git a/arch/mips/pci/pci-sb1250.c b/arch/mips/pci/pci-sb1250.c
index ada24e6..1711e8e 100644
--- a/arch/mips/pci/pci-sb1250.c
+++ b/arch/mips/pci/pci-sb1250.c
@@ -37,6 +37,7 @@
 #include <linux/mm.h>
 #include <linux/console.h>
 #include <linux/tty.h>
+#include <linux/vt.h>
 
 #include <asm/io.h>
 
@@ -254,7 +255,7 @@
 	 * XXX ehs: Should this happen in PCI Device mode?
 	 */
 	io_map_base = ioremap(A_PHYS_LDTPCI_IO_MATCH_BYTES, 1024 * 1024);
-	sb1250_controller.io_map_base = io_map_base;
+	sb1250_controller.io_map_base = (unsigned long)io_map_base;
 	set_io_port_base((unsigned long)io_map_base);
 
 #ifdef CONFIG_SIBYTE_HAS_LDT
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/mipssim/sim_cmdline.c b/arch/mips/powertv/time.c
similarity index 60%
rename from arch/mips/mipssim/sim_cmdline.c
rename to arch/mips/powertv/time.c
index 74240e1..1e0a5ef 100644
--- a/arch/mips/mipssim/sim_cmdline.c
+++ b/arch/mips/powertv/time.c
@@ -1,5 +1,7 @@
 /*
- * Copyright (C) 2005 MIPS Technologies, Inc.  All rights reserved.
+ * 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
@@ -14,19 +16,22 @@
  *  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 <linux/string.h>
-#include <asm/bootinfo.h>
+#include <asm/mach-powertv/interrupts.h>
+#include <asm/time.h>
 
-extern char arcs_cmdline[];
+#include "powertv-clock.h"
 
-char * __init prom_getcmdline(void)
+unsigned int __cpuinit get_c0_compare_int(void)
 {
-	return arcs_cmdline;
+	return irq_mips_timer;
 }
 
-void  __init prom_init_cmdline(void)
+void __init plat_time_init(void)
 {
-	/* XXX: Get boot line from environment? */
+	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 @@
 		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-berr.c b/arch/mips/sgi-ip22/ip22-berr.c
index de6a0cc..911d399 100644
--- a/arch/mips/sgi-ip22/ip22-berr.c
+++ b/arch/mips/sgi-ip22/ip22-berr.c
@@ -89,7 +89,7 @@
 void ip22_be_interrupt(int irq)
 {
 	const int field = 2 * sizeof(unsigned long);
-	const struct pt_regs *regs = get_irq_regs();
+	struct pt_regs *regs = get_irq_regs();
 
 	save_and_clear_buserr();
 	print_buserr();
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 @@
 
 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 @@
 }
 
 /* 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/sgi-ip22/ip28-berr.c b/arch/mips/sgi-ip22/ip28-berr.c
index 30e12e2..88c684e 100644
--- a/arch/mips/sgi-ip22/ip28-berr.c
+++ b/arch/mips/sgi-ip22/ip28-berr.c
@@ -453,7 +453,7 @@
 
 void ip22_be_interrupt(int irq)
 {
-	const struct pt_regs *regs = get_irq_regs();
+	struct pt_regs *regs = get_irq_regs();
 
 	count_be_interrupt++;
 
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 @@
 	 * 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 @@
 #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/sibyte/swarm/setup.c b/arch/mips/sibyte/swarm/setup.c
index 5277aac..c308989 100644
--- a/arch/mips/sibyte/swarm/setup.c
+++ b/arch/mips/sibyte/swarm/setup.c
@@ -145,15 +145,14 @@
 
 #ifdef CONFIG_VT
 	screen_info = (struct screen_info) {
-		0, 0,           /* orig-x, orig-y */
-		0,              /* unused */
-		52,             /* orig_video_page */
-		3,              /* orig_video_mode */
-		80,             /* orig_video_cols */
-		4626, 3, 9,     /* unused, ega_bx, unused */
-		25,             /* orig_video_lines */
-		0x22,           /* orig_video_isVGA */
-		16              /* orig_video_points */
+		.orig_video_page	= 52,
+		.orig_video_mode	= 3,
+		.orig_video_cols	= 80,
+		.flags			= 12,
+		.orig_video_ega_bx	= 3,
+		.orig_video_lines	= 25,
+		.orig_video_isVGA	= 0x22,
+		.orig_video_points	= 16,
        };
        /* XXXKW for CFE, get lines/cols from environment */
 #endif
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 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 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 @@
 }
 
 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 @@
 }
 
 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 @@
 	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 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/dma/txx9dmac.c b/drivers/dma/txx9dmac.c
index fb6bb64..b81fc77 100644
--- a/drivers/dma/txx9dmac.c
+++ b/drivers/dma/txx9dmac.c
@@ -1359,3 +1359,5 @@
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("TXx9 DMA Controller driver");
 MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
+MODULE_ALIAS("platform:txx9dmac");
+MODULE_ALIAS("platform:txx9dmac-chan");
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 @@
 	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 @@
 	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 @@
 				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 @@
 {
 	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 @@
 				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 @@
 	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_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 @@
 	/* 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 @@
 
 source "drivers/net/fs_enet/Kconfig"
 
+source "drivers/net/octeon/Kconfig"
+
 endif # NET_ETHERNET
 
 #
@@ -2409,6 +2411,13 @@
 	  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 6a793ae..1e17225 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -150,6 +150,8 @@
 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_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 @@
  *
  * 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 @@
  * 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 @@
  * 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 @@
 	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);
+		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_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);
-		return 0;
-# endif /* defined(AU1XXX_PHY1_ADDR) */
-	}
+	} else {
+		int phy_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 (!aup->phy_search_highest_addr)
+					break; /* break out with first one found */
+			}
 
-	/* 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 (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");
 
-# 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");
+				/* 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];
 
-		BUG_ON(!au_macs[0]);
+					if (!tmp_phydev)
+						continue; /* no PHY here... */
 
-		/* 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->attached_dev)
+						continue; /* already claimed by MAC0 */
 
-			if (!tmp_phydev)
-				continue; /* no PHY here... */
-
-			if (tmp_phydev->attached_dev)
-				continue; /* already claimed by MAC0 */
-
-			phydev = tmp_phydev;
-			break; /* found it */
+					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 @@
 	}
 }
 
-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 @@
 	.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);
 
-	if (port_num >= NUM_ETH_INTERFACES)
-		return NULL;
+	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;
+	}
 
-	base  = CPHYSADDR(iflist[port_num].base_addr );
-	macen = CPHYSADDR(iflist[port_num].macen_addr);
-	irq = iflist[port_num].irq;
+	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;
+	}
 
-	if (!request_mem_region( base, MAC_IOSIZE, "Au1x00 ENET") ||
-	    !request_mem_region(macen, 4, "Au1x00 ENET"))
-		return NULL;
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		printk(KERN_ERR DRV_NAME ": failed to retrieve IRQ\n");
+		err = -ENODEV;
+		goto out;
+	}
 
-	if (version_printed++ == 0)
-		printk("%s version %s %s\n", DRV_NAME, DRV_VERSION, DRV_AUTHOR);
+	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 (!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 @@
 						(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 @@
 		}
 
 		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 @@
 	 * 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,24 +1159,20 @@
 
 	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;
 
-	if (mii_probe(dev) != 0) {
-		goto err_out;
+	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)
+		goto err_out;
+
 	pDBfree = NULL;
 	/* setup the data buffer descriptors and attach a buffer to each one */
 	pDB = aup->db;
@@ -1216,19 +1203,35 @@
 		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 @@
 		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);
 
-	for(i = 0; i < num_ifs; i++) {
-		dev = au1000_probe(i);
-		iflist[i].dev = dev;
-		if (dev)
-			found_one++;
-	}
-	if (!found_one)
-		return -ENODEV;
+	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);
+
 	return 0;
 }
 
-static void __exit au1000_cleanup_module(void)
-{
-	int i, j;
-	struct net_device *dev;
-	struct au1000_private *aup;
+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");
 
-	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);
-		}
-	}
+
+static int __init au1000_init_module(void)
+{
+	return platform_driver_register(&au1000_eth_driver);
+}
+
+static void __exit au1000_exit_module(void)
+{
+	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 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 @@
 
 #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 @@
 
 #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 @@
 
 	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..906edeca
--- /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..fc5938ba 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -115,4 +115,15 @@
 	  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_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..dc137bf8
--- /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 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 @@
 	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_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..c688cc9
--- /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..b660d86
--- /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, 0);
+
+		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, 1);
+
+		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..b661ab5
--- /dev/null
+++ b/drivers/net/wireless/rtl8187b/r8180_rtl8225z2.c
@@ -0,0 +1,2092 @@
+/*
+  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 0
+	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"); 
+	}
+#endif
+	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..92cc4f3
--- /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 report_rfkill);
+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..32d4a06
--- /dev/null
+++ b/drivers/net/wireless/rtl8187b/r8187_core.c
@@ -0,0 +1,7043 @@
+/*
+   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!");
+	
+	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°Ñ¼Æ«ØÄ³µ¥SD3 °ª§C·Å and cable link test OK¤~¥¿¦¡ release,¤£«ØÄ³¤Ó§Ö
+                // 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, bool report_rfkill)
+{
+	struct r8180_priv *priv = ieee80211_priv(dev);
+
+	if (eRfPowerStateToSet == eRfOn)
+		priv->ieee80211->bHwRadioOff = false;
+	else
+		priv->ieee80211->bHwRadioOff = true;
+
+#ifdef CONFIG_RADIO_DEBUG 
+	DMESG("SCI interrupt Methord Will Turn Radio %s",
+		(priv->ieee80211->bHwRadioOff == true) ? "Off" : "On");
+#endif
+
+#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 */
+	if (report_rfkill)
+		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..0018708
--- /dev/null
+++ b/drivers/net/wireless/rtl8187b/r8187_rfkill.c
@@ -0,0 +1,158 @@
+/*
+ * 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, 1);
+		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);
+		r8187b_rfkill = NULL;
+		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 @@
 	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_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_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 @@
 	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 @@
 	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 @@
 	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 @@
 
 	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 @@
 	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 2ac43f0..2f96d236 100644
--- a/drivers/rtc/rtc-cmos.c
+++ b/drivers/rtc/rtc-cmos.c
@@ -692,7 +692,8 @@
 	 */
 #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.
@@ -758,9 +759,8 @@
 	/* 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 12e1e9e..ecf1b08 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -1218,12 +1218,6 @@
 	}
 #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 @@
 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 @@
 
 	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 @@
 	}
 
 	/* 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 b926b00..82084f2 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -123,5 +123,7 @@
 
 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 030d8f8..fbb5d97 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -43,3 +43,4 @@
 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 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;
 
-	return ret;
+	if (priv->phydev)
+		return phy_ethtool_sset(priv->phydev, cmd);
+
+	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 @@
 	.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 @@
 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;
 
-	return ret;
+	if (!priv->phydev)
+		return -EINVAL;
+
+	return phy_mii_ioctl(priv->phydev, if_mii(rq), cmd);
 }
 
+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..55d0614a 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 @@
 		}
 	}
 
-	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 @@
 		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 @@
 	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 @@
 	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 @@
  */
 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 @@
 		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 @@
 	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 @@
 
 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 @@
 #endif
 };
 
+extern void octeon_mdiobus_force_mod_depencency(void);
+
 /**
  * Module/ driver initialization. Creates the linux network
  * devices.
@@ -640,6 +638,7 @@
 	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 @@
 	/* 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..315102c
--- /dev/null
+++ b/drivers/staging/sm7xx/Kconfig
@@ -0,0 +1,8 @@
+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.
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/smtcfb.c b/drivers/staging/sm7xx/smtcfb.c
new file mode 100644
index 0000000..041a87a
--- /dev/null
+++ b/drivers/staging/sm7xx/smtcfb.c
@@ -0,0 +1,1147 @@
+/*
+ * 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.
+ *
+ * - Remove the buggy 2D support for Lynx, 2010/01/06, Wu Zhangjin
+ *
+ * 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"
+
+#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 */
+
+static u32 colreg[17];
+static struct par_info hw;	/* hardware information */
+
+u16 smtc_ChipIDs[] = {
+	0x710,
+	0x712,
+	0x720
+};
+
+#define numSMTCchipIDs (sizeof(smtc_ChipIDs) / sizeof(u16))
+
+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 cfb_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 */
+
+static struct fb_ops smtcfb_ops = {
+	.owner = THIS_MODULE,
+	.fb_setcolreg = smtc_setcolreg,
+	.fb_blank = cfb_blank,
+	.fb_fillrect = cfb_fillrect,
+	.fb_imageblit = cfb_imageblit,
+	.fb_copyarea = cfb_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);
+}
+
+/*
+ * 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);
+		hw.m_pDPR = smtc_VRAMBaseAddress + 0x00408000;
+		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
+		break;
+	case 0x720:
+		sfb->fb.fix.mmio_start = pFramebufferPhysical;
+		sfb->fb.fix.mmio_len = 0x00200000;
+		smem_size = SM722_VIDEOMEMORYSIZE;
+		hw.m_pDPR = ioremap(pFramebufferPhysical, 0x00a00000);
+		hw.m_pLFB = (smtc_VRAMBaseAddress =
+		    hw.m_pDPR + 0x00200000);
+		hw.m_pMMIO = (smtc_RegBaseAddress =
+		    hw.m_pDPR + 0x000c0000);
+		hw.m_pVPR = hw.m_pDPR + 0x800;
+
+		smtc_seqw(0x62, 0xff);
+		smtc_seqw(0x6a, 0x0d);
+		smtc_seqw(0x6b, 0x02);
+		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/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 48418f2..e5c3804 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -839,9 +839,13 @@
 	}
 
 	if (ints & OHCI_INTR_WDH) {
-		spin_lock (&ohci->lock);
-		dl_done_list (ohci);
-		spin_unlock (&ohci->lock);
+		if (ohci->hcca->done_head == 0) {
+			ints &= ~OHCI_INTR_WDH;
+		} else {
+			spin_lock (&ohci->lock);
+			dl_done_list (ohci);
+			spin_unlock (&ohci->lock);
+		}
 	}
 
 	if (quirk_zfmicro(ohci) && (ints & OHCI_INTR_SF)) {
diff --git a/drivers/video/sis/310vtbl.h b/drivers/video/sis/310vtbl.h
index 54fcbbf..a095084 100644
--- a/drivers/video/sis/310vtbl.h
+++ b/drivers/video/sis/310vtbl.h
@@ -471,9 +471,9 @@
  {{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 */
-   0x01,0x8d,0xff,0x00,0x27,0x10,0x00,0x03,
-   0x01}},  /* 0x49 */
+ {{0xc3,0xa9,0xa9,0x87,0xb4,0x18,0x24,0xfd, /* 1360x768-60, timing for LynLoong's lvds output */
+   0x02,0x07,0xff,0x01,0x25,0x10,0x00,0x07,
+   0x02}},  /* 0x49 */
  {{0xd9,0x8f,0x8f,0x9d,0xba,0x0a,0x8a,0xff, /* 1152x864-84  */
    0x60,0x8b,0x5f,0x5f,0x8b,0x10,0x00,0x03,
    0x01}},  /* 0x4a */
@@ -755,7 +755,7 @@
 	{ 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,0x27, 76}, /* 0x58 1360x768-62 (is 60Hz!), pixelclock for LynLoong's lvds output, for register SR2B, SR2C */
 	{ 0x52,0x07,149}, /* 0x59 1280x960-85 */
 	{ 0x56,0x07,156}, /* 0x5a 1400x1050-75 */
 	{ 0x70,0x29, 81}, /* 0x5b 1280x768 LCD */
@@ -878,7 +878,7 @@
 	{ 0x62,0xc6, 34}, /* 0x55 848x480-60 */
 	{ 0x6a,0xc6, 37}, /* 0x56 848x480-75 - TEMP, UNUSED */
 	{ 0xbf,0xc8, 35}, /* 0x57 856x480-38i,60  */
-	{ 0x30,0x23, 88}, /* 0x58 1360x768-62 (is 60Hz!) TEMP, UNUSED */
+	{ 0x54,0x27, 76}, /* 0x58 1360x768 60) */ 
 	{ 0x52,0x07,149}, /* 0x59 1280x960-85  */
 	{ 0x56,0x07,156}, /* 0x5a 1400x1050-75 */
 	{ 0x70,0x29, 81}, /* 0x5b 1280x768 LCD (TMDS) */
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 @@
     } /* 310 series */
 
   }  /* LVDS */
-
+  SiS_SetReg(SiS_Pr->SiS_Part1Port, 0x2d, 0x11);
 }
 
 /*********************************************/
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index e1836d7..853c16a 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -3524,6 +3524,16 @@
 
 	outSISIDXREG(SISSR, 0x05, 0x86);
 
+	/* Fix 1360x768 for the Lemote LynLoong Machine
+	 *
+	 * FIXME: part1 register setting for Lemote LynLoong Machine's lvds output,
+	 * Not sure whether it should be added here
+	 */
+	outSISIDXREG(SISPART1, 0x16, 0xc7);
+	outSISIDXREG(SISPART1, 0x1a, 0x18);
+	outSISIDXREG(SISPART1, 0x1b, 0x25);
+	outSISIDXREG(SISPART1, 0x1d, 0x13);
+
 	inSISIDXREG(SISCR, 0x31, cr31);
 	cr31 &= ~0x60;
 	cr31 |= 0x04;
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 @@
 	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 d72691b..9c34a4c 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -115,10 +115,13 @@
 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 @@
 	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 @@
 	  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 eabee8f..e38b014 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)      ((size_t)(ip_end - ip) >= (size_t)(x))
@@ -258,9 +260,10 @@
 	*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 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 @@
 
 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 @@
 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 @@
 
 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 @@
     $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 e6d2d97..f96be9d 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -3091,7 +3091,11 @@
 			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;
@@ -3206,6 +3210,11 @@
 	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 @@
 			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 @@
 	}
 
 	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 @@
 	/* 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 @@
 	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 @@
 
 	/* 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 @@
 		 * 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 @@
 ##
 ## 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_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 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 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_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 @@
 	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/sound/soc/txx9/txx9aclc-ac97.c b/sound/soc/txx9/txx9aclc-ac97.c
index 0f83bdb..ab013d2 100644
--- a/sound/soc/txx9/txx9aclc-ac97.c
+++ b/sound/soc/txx9/txx9aclc-ac97.c
@@ -253,3 +253,4 @@
 MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
 MODULE_DESCRIPTION("TXx9 ACLC AC97 driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:txx9aclc-ac97");
diff --git a/sound/soc/txx9/txx9aclc-generic.c b/sound/soc/txx9/txx9aclc-generic.c
index 3175de9..95b17f7 100644
--- a/sound/soc/txx9/txx9aclc-generic.c
+++ b/sound/soc/txx9/txx9aclc-generic.c
@@ -96,3 +96,4 @@
 MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
 MODULE_DESCRIPTION("Generic TXx9 ACLC ALSA SoC audio driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:txx9aclc-generic");