[PATCH 1/4] Added Realtek rtl8192u driver to staging

Mauro Carvalho Chehab mchehab at infradead.org
Tue Nov 3 09:17:11 UTC 2009


Add Realtek linux driver for rtl8192u as provided by Realtek

rtl8192u_linux_2.6.0006.1031.2008.tar.gz, send to me C/C staging ML.

This version won't compile against upstream, doesn't follow
Linux CodingStyle and has their own ieee80211 stack.

Signed-off-by: Mauro Carvalho Chehab <mchehab at redhat.com>
---
 drivers/staging/rtl8192u/Kconfig                   |    6 +
 drivers/staging/rtl8192u/Makefile                  |   32 +
 drivers/staging/rtl8192u/authors                   |    1 +
 drivers/staging/rtl8192u/changes                   |    5 +
 drivers/staging/rtl8192u/copying                   |  340 +
 drivers/staging/rtl8192u/dot11d.h                  |  102 +
 drivers/staging/rtl8192u/ieee80211.h               | 2795 ++++++++
 drivers/staging/rtl8192u/ieee80211/EndianFree.h    |  199 +
 drivers/staging/rtl8192u/ieee80211/Makefile        |  139 +
 drivers/staging/rtl8192u/ieee80211/aes.c           |  469 ++
 drivers/staging/rtl8192u/ieee80211/api.c           |  246 +
 drivers/staging/rtl8192u/ieee80211/arc4.c          |  103 +
 drivers/staging/rtl8192u/ieee80211/autoload.c      |   40 +
 drivers/staging/rtl8192u/ieee80211/cipher.c        |  299 +
 drivers/staging/rtl8192u/ieee80211/compress.c      |   64 +
 drivers/staging/rtl8192u/ieee80211/crypto_compat.h |   90 +
 drivers/staging/rtl8192u/ieee80211/digest.c        |  108 +
 drivers/staging/rtl8192u/ieee80211/dot11d.c        |  239 +
 drivers/staging/rtl8192u/ieee80211/dot11d.h        |  102 +
 drivers/staging/rtl8192u/ieee80211/ieee80211.h     | 2796 ++++++++
 .../staging/rtl8192u/ieee80211/ieee80211_crypt.c   |  273 +
 .../staging/rtl8192u/ieee80211/ieee80211_crypt.h   |   93 +
 .../rtl8192u/ieee80211/ieee80211_crypt_ccmp.c      |  534 ++
 .../rtl8192u/ieee80211/ieee80211_crypt_tkip.c      | 1034 +++
 .../rtl8192u/ieee80211/ieee80211_crypt_wep.c       |  397 ++
 .../staging/rtl8192u/ieee80211/ieee80211_module.c  |  394 ++
 drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c  | 2778 ++++++++
 .../staging/rtl8192u/ieee80211/ieee80211_softmac.c | 3529 ++++++++++
 .../rtl8192u/ieee80211/ieee80211_softmac_wx.c      |  693 ++
 drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c  |  929 +++
 drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c  | 1032 +++
 drivers/staging/rtl8192u/ieee80211/internal.h      |  115 +
 drivers/staging/rtl8192u/ieee80211/kmap_types.h    |   20 +
 drivers/staging/rtl8192u/ieee80211/michael_mic.c   |  194 +
 drivers/staging/rtl8192u/ieee80211/proc.c          |  116 +
 drivers/staging/rtl8192u/ieee80211/rtl819x_BA.h    |   69 +
 .../staging/rtl8192u/ieee80211/rtl819x_BAProc.c    |  779 +++
 drivers/staging/rtl8192u/ieee80211/rtl819x_HT.h    |  481 ++
 .../staging/rtl8192u/ieee80211/rtl819x_HTProc.c    | 1719 +++++
 drivers/staging/rtl8192u/ieee80211/rtl819x_Qos.h   |  749 ++
 drivers/staging/rtl8192u/ieee80211/rtl819x_TS.h    |   56 +
 .../staging/rtl8192u/ieee80211/rtl819x_TSProc.c    |  654 ++
 drivers/staging/rtl8192u/ieee80211/rtl_crypto.h    |  399 ++
 drivers/staging/rtl8192u/ieee80211/scatterwalk.c   |  126 +
 drivers/staging/rtl8192u/ieee80211/scatterwalk.h   |   51 +
 drivers/staging/rtl8192u/ieee80211_crypt.h         |   86 +
 drivers/staging/rtl8192u/r8180_93cx6.c             |  146 +
 drivers/staging/rtl8192u/r8180_93cx6.h             |   40 +
 drivers/staging/rtl8192u/r8180_pm.c                |   48 +
 drivers/staging/rtl8192u/r8180_pm.h                |   28 +
 drivers/staging/rtl8192u/r8190_rtl8256.c           |  312 +
 drivers/staging/rtl8192u/r8190_rtl8256.h           |   27 +
 drivers/staging/rtl8192u/r8192U.h                  | 1367 ++++
 drivers/staging/rtl8192u/r8192U_core.c             | 7134 ++++++++++++++++++++
 drivers/staging/rtl8192u/r8192U_dm.c               | 4178 ++++++++++++
 drivers/staging/rtl8192u/r8192U_dm.h               |  309 +
 drivers/staging/rtl8192u/r8192U_hw.h               |  746 ++
 drivers/staging/rtl8192u/r8192U_wx.c               | 1310 ++++
 drivers/staging/rtl8192u/r8192U_wx.h               |   23 +
 drivers/staging/rtl8192u/r819xU_HTGen.h            |   13 +
 drivers/staging/rtl8192u/r819xU_HTType.h           |  391 ++
 drivers/staging/rtl8192u/r819xU_cmdpkt.c           |  822 +++
 drivers/staging/rtl8192u/r819xU_cmdpkt.h           |  217 +
 drivers/staging/rtl8192u/r819xU_firmware.c         |  700 ++
 drivers/staging/rtl8192u/r819xU_firmware.h         |   68 +
 drivers/staging/rtl8192u/r819xU_firmware_img.c     | 3447 ++++++++++
 drivers/staging/rtl8192u/r819xU_firmware_img.h     |   35 +
 drivers/staging/rtl8192u/r819xU_phy.c              | 1826 +++++
 drivers/staging/rtl8192u/r819xU_phy.h              |   94 +
 drivers/staging/rtl8192u/r819xU_phyreg.h           |  871 +++
 70 files changed, 49627 insertions(+), 0 deletions(-)
 create mode 100644 drivers/staging/rtl8192u/Kconfig
 create mode 100644 drivers/staging/rtl8192u/Makefile
 create mode 100644 drivers/staging/rtl8192u/authors
 create mode 100644 drivers/staging/rtl8192u/changes
 create mode 100644 drivers/staging/rtl8192u/copying
 create mode 100644 drivers/staging/rtl8192u/dot11d.h
 create mode 100644 drivers/staging/rtl8192u/ieee80211.h
 create mode 100644 drivers/staging/rtl8192u/ieee80211/EndianFree.h
 create mode 100644 drivers/staging/rtl8192u/ieee80211/Makefile
 create mode 100644 drivers/staging/rtl8192u/ieee80211/aes.c
 create mode 100644 drivers/staging/rtl8192u/ieee80211/api.c
 create mode 100644 drivers/staging/rtl8192u/ieee80211/arc4.c
 create mode 100644 drivers/staging/rtl8192u/ieee80211/autoload.c
 create mode 100644 drivers/staging/rtl8192u/ieee80211/cipher.c
 create mode 100644 drivers/staging/rtl8192u/ieee80211/compress.c
 create mode 100644 drivers/staging/rtl8192u/ieee80211/crypto_compat.h
 create mode 100644 drivers/staging/rtl8192u/ieee80211/digest.c
 create mode 100644 drivers/staging/rtl8192u/ieee80211/dot11d.c
 create mode 100644 drivers/staging/rtl8192u/ieee80211/dot11d.h
 create mode 100644 drivers/staging/rtl8192u/ieee80211/ieee80211.h
 create mode 100644 drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.c
 create mode 100644 drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.h
 create mode 100644 drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c
 create mode 100644 drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c
 create mode 100644 drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_wep.c
 create mode 100644 drivers/staging/rtl8192u/ieee80211/ieee80211_module.c
 create mode 100644 drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c
 create mode 100644 drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c
 create mode 100644 drivers/staging/rtl8192u/ieee80211/ieee80211_softmac_wx.c
 create mode 100644 drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c
 create mode 100644 drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c
 create mode 100644 drivers/staging/rtl8192u/ieee80211/internal.h
 create mode 100644 drivers/staging/rtl8192u/ieee80211/kmap_types.h
 create mode 100644 drivers/staging/rtl8192u/ieee80211/michael_mic.c
 create mode 100644 drivers/staging/rtl8192u/ieee80211/proc.c
 create mode 100644 drivers/staging/rtl8192u/ieee80211/rtl819x_BA.h
 create mode 100644 drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c
 create mode 100644 drivers/staging/rtl8192u/ieee80211/rtl819x_HT.h
 create mode 100644 drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c
 create mode 100644 drivers/staging/rtl8192u/ieee80211/rtl819x_Qos.h
 create mode 100644 drivers/staging/rtl8192u/ieee80211/rtl819x_TS.h
 create mode 100644 drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c
 create mode 100644 drivers/staging/rtl8192u/ieee80211/rtl_crypto.h
 create mode 100644 drivers/staging/rtl8192u/ieee80211/scatterwalk.c
 create mode 100644 drivers/staging/rtl8192u/ieee80211/scatterwalk.h
 create mode 100644 drivers/staging/rtl8192u/ieee80211_crypt.h
 create mode 100644 drivers/staging/rtl8192u/r8180_93cx6.c
 create mode 100644 drivers/staging/rtl8192u/r8180_93cx6.h
 create mode 100644 drivers/staging/rtl8192u/r8180_pm.c
 create mode 100644 drivers/staging/rtl8192u/r8180_pm.h
 create mode 100644 drivers/staging/rtl8192u/r8190_rtl8256.c
 create mode 100644 drivers/staging/rtl8192u/r8190_rtl8256.h
 create mode 100644 drivers/staging/rtl8192u/r8192U.h
 create mode 100644 drivers/staging/rtl8192u/r8192U_core.c
 create mode 100644 drivers/staging/rtl8192u/r8192U_dm.c
 create mode 100644 drivers/staging/rtl8192u/r8192U_dm.h
 create mode 100644 drivers/staging/rtl8192u/r8192U_hw.h
 create mode 100644 drivers/staging/rtl8192u/r8192U_wx.c
 create mode 100644 drivers/staging/rtl8192u/r8192U_wx.h
 create mode 100644 drivers/staging/rtl8192u/r819xU_HTGen.h
 create mode 100644 drivers/staging/rtl8192u/r819xU_HTType.h
 create mode 100644 drivers/staging/rtl8192u/r819xU_cmdpkt.c
 create mode 100644 drivers/staging/rtl8192u/r819xU_cmdpkt.h
 create mode 100644 drivers/staging/rtl8192u/r819xU_firmware.c
 create mode 100644 drivers/staging/rtl8192u/r819xU_firmware.h
 create mode 100644 drivers/staging/rtl8192u/r819xU_firmware_img.c
 create mode 100644 drivers/staging/rtl8192u/r819xU_firmware_img.h
 create mode 100644 drivers/staging/rtl8192u/r819xU_phy.c
 create mode 100644 drivers/staging/rtl8192u/r819xU_phy.h
 create mode 100644 drivers/staging/rtl8192u/r819xU_phyreg.h

diff --git a/drivers/staging/rtl8192u/Kconfig b/drivers/staging/rtl8192u/Kconfig
new file mode 100644
index 0000000..808a088
--- /dev/null
+++ b/drivers/staging/rtl8192u/Kconfig
@@ -0,0 +1,6 @@
+config RTL8192U
+	tristate "RealTek RTL8192U Wireless LAN NIC driver"
+	depends on PCI && WLAN
+	depends on WIRELESS_EXT
+	default N
+	---help---
diff --git a/drivers/staging/rtl8192u/Makefile b/drivers/staging/rtl8192u/Makefile
new file mode 100644
index 0000000..9923690
--- /dev/null
+++ b/drivers/staging/rtl8192u/Makefile
@@ -0,0 +1,32 @@
+NIC_SELECT = RTL8192U
+
+EXTRA_CFLAGS += -std=gnu89
+EXTRA_CFLAGS += -O2
+
+EXTRA_CFLAGS += -mhard-float -DCONFIG_FORCE_HARD_FLOAT=y
+EXTRA_CFLAGS += -DJACKSON_NEW_8187 -DJACKSON_NEW_RX
+EXTRA_CFLAGS += -DTHOMAS_BEACON -DTHOMAS_TASKLET -DTHOMAS_SKB -DTHOMAS_TURBO
+#EXTRA_CFLAGS += -DUSB_TX_DRIVER_AGGREGATION_ENABLE
+#EXTRA_CFLAGS += -DUSB_RX_AGGREGATION_SUPPORT
+EXTRA_CFLAGS += -DUSE_ONE_PIPE
+EXTRA_CFLAGS += -DENABLE_DOT11D
+
+r8192u_usb-objs := r8192U_core.o r8180_93cx6.o r8192U_wx.o		\
+		  r8190_rtl8256.o r819xU_phy.o r819xU_firmware.o	\
+		  r819xU_cmdpkt.o r8192U_dm.o r819xU_firmware_img.o	\
+		  ieee80211/ieee80211_crypt.o				\
+		  ieee80211/ieee80211_crypt_tkip.o			\
+		  ieee80211/ieee80211_crypt_ccmp.o			\
+		  ieee80211/ieee80211_crypt_wep.o			\
+		  ieee80211/ieee80211_rx.o				\
+		  ieee80211/ieee80211_softmac.o				\
+		  ieee80211/ieee80211_tx.o				\
+		  ieee80211/ieee80211_wx.o				\
+		  ieee80211/ieee80211_module.o				\
+		  ieee80211/ieee80211_softmac_wx.o			\
+		  ieee80211/rtl819x_HTProc.o				\
+		  ieee80211/rtl819x_TSProc.o				\
+		  ieee80211/rtl819x_BAProc.o				\
+		  ieee80211/dot11d.o
+
+obj-$(CONFIG_RTL8192U) += r8192u_usb.o
diff --git a/drivers/staging/rtl8192u/authors b/drivers/staging/rtl8192u/authors
new file mode 100644
index 0000000..b08bbae
--- /dev/null
+++ b/drivers/staging/rtl8192u/authors
@@ -0,0 +1 @@
+Andrea Merello <andreamrl at tiscali.it>
diff --git a/drivers/staging/rtl8192u/changes b/drivers/staging/rtl8192u/changes
new file mode 100644
index 0000000..87c33fd
--- /dev/null
+++ b/drivers/staging/rtl8192u/changes
@@ -0,0 +1,5 @@
+v 0.1
+
+First version.
+This is based on the rtl8180-sa2400 pre-0.22-CVS code..
+
diff --git a/drivers/staging/rtl8192u/copying b/drivers/staging/rtl8192u/copying
new file mode 100644
index 0000000..d60c31a
--- /dev/null
+++ b/drivers/staging/rtl8192u/copying
@@ -0,0 +1,340 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+

+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+

+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+

+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+

+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+

+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    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
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year  name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/drivers/staging/rtl8192u/dot11d.h b/drivers/staging/rtl8192u/dot11d.h
new file mode 100644
index 0000000..defba0c
--- /dev/null
+++ b/drivers/staging/rtl8192u/dot11d.h
@@ -0,0 +1,102 @@
+#ifndef __INC_DOT11D_H
+#define __INC_DOT11D_H
+
+#ifdef ENABLE_DOT11D
+#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
+);
+#endif //ENABLE_DOT11D
+#endif // #ifndef __INC_DOT11D_H
diff --git a/drivers/staging/rtl8192u/ieee80211.h b/drivers/staging/rtl8192u/ieee80211.h
new file mode 100644
index 0000000..e364751
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211.h
@@ -0,0 +1,2795 @@
+/*
+ * 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 at cc.hut.fi>
+ * Copyright (c) 2002-2003, Jouni Malinen <jkmaline at cc.hut.fi>
+ *
+ * Adaption to a generic IEEE 802.11 stack by James Ketrenos
+ * <jketreno at linux.intel.com>
+ * Copyright (c) 2004, Intel Corporation
+ *
+ * Modified for Realtek's wi-fi cards by Andrea Merello
+ * <andreamrl at 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>
+
+#include <linux/delay.h>
+#include <linux/wireless.h>
+
+#include "../../ieee80211/rtl819x_HT.h"
+#include "../../ieee80211/rtl819x_BA.h"
+#include "../../ieee80211/rtl819x_TS.h"
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
+#ifndef bool
+typedef enum{false = 0, true} bool;
+#endif
+#endif
+
+#ifndef IW_MODE_MONITOR
+#define IW_MODE_MONITOR 6
+#endif
+
+#ifndef IWEVCUSTOM
+#define IWEVCUSTOM 0x8c02
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+#ifndef __bitwise
+#define __bitwise __attribute__((bitwise))
+#endif
+typedef __u16  __le16;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,27))
+struct iw_spy_data{
+	/* --- Standard spy support --- */
+	int 			spy_number;
+	u_char 			spy_address[IW_MAX_SPY][ETH_ALEN];
+	struct iw_quality	spy_stat[IW_MAX_SPY];
+	/* --- Enhanced spy support (event) */
+	struct iw_quality	spy_thr_low; /* Low threshold */
+	struct iw_quality	spy_thr_high; /* High threshold */
+	u_char			spy_thr_under[IW_MAX_SPY];
+}; 
+#endif
+#endif
+
+#ifndef container_of
+/**
+ * container_of - cast a member of a structure out to the containing structure
+ *
+ * @ptr:        the pointer to the member.
+ * @type:       the type of the container struct this is embedded in.
+ * @member:     the name of the member within the struct.
+ *
+ */
+#define container_of(ptr, type, member) ({                      \
+        const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
+        (type *)( (char *)__mptr - offsetof(type,member) );})
+#endif
+
+#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
+
+/* added for rtl819x tx procedure */
+#define MAX_QUEUE_SIZE		0x10
+
+//
+// 8190 queue mapping
+//
+#define BK_QUEUE                               0
+#define BE_QUEUE                               1
+#define VI_QUEUE                               2
+#define VO_QUEUE                               3
+#define HCCA_QUEUE                             4
+#define TXCMD_QUEUE                            5
+#define MGNT_QUEUE                             6
+#define HIGH_QUEUE                             7
+#define BEACON_QUEUE                           8
+
+#define LOW_QUEUE                              BE_QUEUE
+#define NORMAL_QUEUE                           MGNT_QUEUE
+
+//added by amy for ps
+#define SWRF_TIMEOUT				50
+
+//added by amy for LEAP related
+#define IE_CISCO_FLAG_POSITION		0x08	// Flag byte: byte 8, numbered from 0.
+#define SUPPORT_CKIP_MIC			0x08	// bit3
+#define SUPPORT_CKIP_PK			0x10	// bit4
+/* defined for skb cb field */
+/* At most 28 byte */
+typedef struct cb_desc {
+        /* Tx Desc Related flags (8-9) */
+	u8 bLastIniPkt:1;
+	u8 bCmdOrInit:1;
+        u8 bFirstSeg:1;
+        u8 bLastSeg:1;
+        u8 bEncrypt:1;
+        u8 bTxDisableRateFallBack:1;
+        u8 bTxUseDriverAssingedRate:1;
+        u8 bHwSec:1; //indicate whether use Hw security. WB
+
+        u8 reserved1;
+
+        /* Tx Firmware Relaged flags (10-11)*/
+        u8 bCTSEnable:1;
+        u8 bRTSEnable:1;
+        u8 bUseShortGI:1;
+        u8 bUseShortPreamble:1;
+        u8 bTxEnableFwCalcDur:1;
+        u8 bAMPDUEnable:1;
+        u8 bRTSSTBC:1;
+        u8 RTSSC:1;
+
+        u8 bRTSBW:1;
+        u8 bPacketBW:1;
+	u8 bRTSUseShortPreamble:1;
+	u8 bRTSUseShortGI:1;
+	u8 bMulticast:1;
+	u8 bBroadcast:1;
+        //u8 reserved2:2;
+        u8 drv_agg_enable:1;
+        u8 reserved2:1;
+
+        /* Tx Desc related element(12-19) */
+        u8 rata_index;
+        u8 queue_index;
+        //u8 reserved3;
+        //u8 reserved4;
+        u16 txbuf_size;
+        //u8 reserved5;
+	u8 RATRIndex;
+        u8 reserved6;
+        u8 reserved7;
+        u8 reserved8;
+
+        /* Tx firmware related element(20-27) */
+        u8 data_rate;
+        u8 rts_rate;
+        u8 ampdu_factor;
+        u8 ampdu_density;
+        //u8 reserved9;
+        //u8 reserved10;
+        //u8 reserved11;
+        u8 DrvAggrNum;
+	u16 pkt_size;
+        u8 reserved12;
+}cb_desc, *pcb_desc;
+                        
+/*--------------------------Define -------------------------------------------*/
+#define MGN_1M                  0x02
+#define MGN_2M                  0x04
+#define MGN_5_5M                0x0b
+#define MGN_11M                 0x16
+
+#define MGN_6M                  0x0c
+#define MGN_9M                  0x12
+#define MGN_12M                 0x18
+#define MGN_18M                 0x24
+#define MGN_24M                 0x30
+#define MGN_36M                 0x48
+#define MGN_48M                 0x60
+#define MGN_54M                 0x6c
+
+#define MGN_MCS0                0x80
+#define MGN_MCS1                0x81
+#define MGN_MCS2                0x82
+#define MGN_MCS3                0x83
+#define MGN_MCS4                0x84
+#define MGN_MCS5                0x85
+#define MGN_MCS6                0x86
+#define MGN_MCS7                0x87
+#define MGN_MCS8                0x88
+#define MGN_MCS9                0x89
+#define MGN_MCS10               0x8a
+#define MGN_MCS11               0x8b
+#define MGN_MCS12               0x8c
+#define MGN_MCS13               0x8d
+#define MGN_MCS14               0x8e
+#define MGN_MCS15               0x8f
+
+//----------------------------------------------------------------------------
+//		802.11 Management frame Reason Code field
+//----------------------------------------------------------------------------
+enum	_ReasonCode{
+	unspec_reason	= 0x1,
+	auth_not_valid	= 0x2,
+	deauth_lv_ss	= 0x3, 
+	inactivity		= 0x4,
+	ap_overload 	= 0x5, 
+	class2_err		= 0x6,
+	class3_err		= 0x7, 
+	disas_lv_ss 	= 0x8,
+	asoc_not_auth	= 0x9,
+
+	//----MIC_CHECK
+	mic_failure 	= 0xe,
+	//----END MIC_CHECK
+
+	// Reason code defined in 802.11i D10.0 p.28.
+	invalid_IE		= 0x0d,
+	four_way_tmout	= 0x0f,
+	two_way_tmout	= 0x10,
+	IE_dismatch 	= 0x11,
+	invalid_Gcipher = 0x12,
+	invalid_Pcipher = 0x13,
+	invalid_AKMP	= 0x14,
+	unsup_RSNIEver = 0x15,
+	invalid_RSNIE	= 0x16,
+	auth_802_1x_fail= 0x17,
+	ciper_reject		= 0x18,
+
+	// Reason code defined in 7.3.1.7, 802.1e D13.0, p.42. Added by Annie, 2005-11-15.
+	QoS_unspec		= 0x20, // 32
+	QAP_bandwidth	= 0x21, // 33
+	poor_condition	= 0x22, // 34
+	no_facility 	= 0x23, // 35
+							// Where is 36???
+	req_declined	= 0x25, // 37
+	invalid_param	= 0x26, // 38
+	req_not_honored= 0x27,	// 39
+	TS_not_created	= 0x2F, // 47
+	DL_not_allowed	= 0x30, // 48
+	dest_not_exist	= 0x31, // 49
+	dest_not_QSTA	= 0x32, // 50
+};
+
+
+
+#define aSifsTime	 ((priv->ieee80211->current_network.mode == IEEE_A)||(priv->ieee80211->current_network.mode == IEEE_N_24G)||(priv->ieee80211->current_network.mode == IEEE_N_5G))? 16 : 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
+
+#define MAX_IE_LEN  0xff
+
+// added for kernel conflict 
+#define ieee80211_crypt_deinit_entries 	ieee80211_crypt_deinit_entries_rsl
+#define ieee80211_crypt_deinit_handler 	ieee80211_crypt_deinit_handler_rsl
+#define ieee80211_crypt_delayed_deinit 	ieee80211_crypt_delayed_deinit_rsl
+#define ieee80211_register_crypto_ops  	ieee80211_register_crypto_ops_rsl
+#define ieee80211_unregister_crypto_ops ieee80211_unregister_crypto_ops_rsl
+#define ieee80211_get_crypto_ops 	ieee80211_get_crypto_ops_rsl
+
+#define ieee80211_ccmp_null		ieee80211_ccmp_null_rsl
+
+#define ieee80211_tkip_null		ieee80211_tkip_null_rsl
+
+#define ieee80211_wep_null		ieee80211_wep_null_rsl
+
+#define free_ieee80211          	free_ieee80211_rsl
+#define alloc_ieee80211        		alloc_ieee80211_rsl
+
+#define ieee80211_rx 			ieee80211_rx_rsl
+#define ieee80211_rx_mgt		ieee80211_rx_mgt_rsl
+
+#define ieee80211_get_beacon		ieee80211_get_beacon_rsl
+#define ieee80211_wake_queue		ieee80211_wake_queue_rsl
+#define ieee80211_stop_queue		ieee80211_stop_queue_rsl
+#define ieee80211_reset_queue		ieee80211_reset_queue_rsl
+#define ieee80211_softmac_stop_protocol	ieee80211_softmac_stop_protocol_rsl
+#define ieee80211_softmac_start_protocol ieee80211_softmac_start_protocol_rsl
+#define ieee80211_is_shortslot		ieee80211_is_shortslot_rsl
+#define ieee80211_is_54g		ieee80211_is_54g_rsl
+#define ieee80211_wpa_supplicant_ioctl	ieee80211_wpa_supplicant_ioctl_rsl
+#define ieee80211_ps_tx_ack		ieee80211_ps_tx_ack_rsl
+#define ieee80211_softmac_xmit		ieee80211_softmac_xmit_rsl
+#define ieee80211_stop_send_beacons	ieee80211_stop_send_beacons_rsl
+#define notify_wx_assoc_event		notify_wx_assoc_event_rsl
+#define SendDisassociation		SendDisassociation_rsl
+#define ieee80211_disassociate		ieee80211_disassociate_rsl
+#define ieee80211_start_send_beacons	ieee80211_start_send_beacons_rsl
+#define ieee80211_stop_scan		ieee80211_stop_scan_rsl
+#define ieee80211_send_probe_requests	ieee80211_send_probe_requests_rsl
+#define ieee80211_softmac_scan_syncro	ieee80211_softmac_scan_syncro_rsl
+#define ieee80211_start_scan_syncro	ieee80211_start_scan_syncro_rsl
+
+#define ieee80211_wx_get_essid		ieee80211_wx_get_essid_rsl
+#define ieee80211_wx_set_essid		ieee80211_wx_set_essid_rsl
+#define ieee80211_wx_set_rate		ieee80211_wx_set_rate_rsl
+#define ieee80211_wx_get_rate		ieee80211_wx_get_rate_rsl
+#define ieee80211_wx_set_wap		ieee80211_wx_set_wap_rsl
+#define ieee80211_wx_get_wap		ieee80211_wx_get_wap_rsl
+#define ieee80211_wx_set_mode		ieee80211_wx_set_mode_rsl 
+#define ieee80211_wx_get_mode		ieee80211_wx_get_mode_rsl
+#define ieee80211_wx_set_scan		ieee80211_wx_set_scan_rsl
+#define ieee80211_wx_get_freq		ieee80211_wx_get_freq_rsl
+#define ieee80211_wx_set_freq		ieee80211_wx_set_freq_rsl
+#define ieee80211_wx_set_rawtx		ieee80211_wx_set_rawtx_rsl
+#define ieee80211_wx_get_name		ieee80211_wx_get_name_rsl
+#define ieee80211_wx_set_power		ieee80211_wx_set_power_rsl
+#define ieee80211_wx_get_power		ieee80211_wx_get_power_rsl
+#define ieee80211_wlan_frequencies	ieee80211_wlan_frequencies_rsl
+#define ieee80211_wx_set_rts		ieee80211_wx_set_rts_rsl
+#define ieee80211_wx_get_rts		ieee80211_wx_get_rts_rsl
+
+#define ieee80211_txb_free		ieee80211_txb_free_rsl
+
+#define ieee80211_wx_set_gen_ie		ieee80211_wx_set_gen_ie_rsl
+#define ieee80211_wx_get_scan		ieee80211_wx_get_scan_rsl
+#define ieee80211_wx_set_encode		ieee80211_wx_set_encode_rsl
+#define ieee80211_wx_get_encode		ieee80211_wx_get_encode_rsl
+#if WIRELESS_EXT >= 18
+#define ieee80211_wx_set_mlme		ieee80211_wx_set_mlme_rsl
+#define ieee80211_wx_set_auth		ieee80211_wx_set_auth_rsl
+#define ieee80211_wx_set_encode_ext	ieee80211_wx_set_encode_ext_rsl
+#define ieee80211_wx_get_encode_ext	ieee80211_wx_get_encode_ext_rsl
+#endif
+
+
+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_rsl(unsigned int msecs)
+{
+         unsigned long timeout = MSECS(msecs) + 1;
+ 
+         while (timeout) {
+                 set_current_state(TASK_INTERRUPTIBLE);
+                 timeout = schedule_timeout(timeout);
+         }
+         return timeout;
+}
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,31))
+static inline void msleep(unsigned int msecs)
+{
+         unsigned long timeout = MSECS(msecs) + 1;
+ 
+         while (timeout) {
+                 set_current_state(TASK_UNINTERRUPTIBLE);
+                 timeout = schedule_timeout(timeout);
+         }
+}
+#endif
+#else
+#define MSECS(t) msecs_to_jiffies(t)
+#define msleep_interruptible_rsl  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_1ADDR_LEN 10
+#define IEEE80211_2ADDR_LEN 16
+#define IEEE80211_3ADDR_LEN 24
+#define IEEE80211_4ADDR_LEN 30
+#define IEEE80211_FCS_LEN    4
+#define IEEE80211_HLEN                  (IEEE80211_4ADDR_LEN)
+#define IEEE80211_FRAME_LEN             (IEEE80211_DATA_LEN + IEEE80211_HLEN)
+#define IEEE80211_MGMT_HDR_LEN 24
+#define IEEE80211_DATA_HDR3_LEN 24
+#define IEEE80211_DATA_HDR4_LEN 30
+
+#define MIN_FRAG_THRESHOLD     256U
+#define MAX_FRAG_THRESHOLD     2346U
+
+
+/* Frame control field constants */
+#define IEEE80211_FCTL_VERS		0x0003
+#define IEEE80211_FCTL_FTYPE		0x000c
+#define IEEE80211_FCTL_STYPE		0x00f0
+#define IEEE80211_FCTL_FRAMETYPE	0x00fc
+#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
+#define IEEE80211_STYPE_BLOCKACK   0x0094
+
+/* 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
+
+/* QOS control */
+#define IEEE80211_QCTL_TID              0x000F
+
+#define	FC_QOS_BIT					BIT7
+#define IsDataFrame(pdu)			( ((pdu[0] & 0x0C)==0x08) ? true : false )
+#define	IsLegacyDataFrame(pdu)	(IsDataFrame(pdu) && (!(pdu[0]&FC_QOS_BIT)) )	
+//added by wb. Is this right?
+#define IsQoSDataFrame(pframe)  ((*(u16*)pframe&(IEEE80211_STYPE_QOS_DATA|IEEE80211_FTYPE_DATA)) == (IEEE80211_STYPE_QOS_DATA|IEEE80211_FTYPE_DATA))
+#define Frame_Order(pframe)     (*(u16*)pframe&IEEE80211_FCTL_ORDER)
+#define SN_LESS(a, b)		(((a-b)&0x800)!=0)
+#define SN_EQUAL(a, b)	(a == b)
+#define MAX_DEV_ADDR_SIZE 8
+typedef enum _ACT_CATEGORY{
+        ACT_CAT_QOS = 1,
+        ACT_CAT_DLS = 2,
+        ACT_CAT_BA  = 3,
+        ACT_CAT_HT  = 7,
+        ACT_CAT_WMM = 17,
+} ACT_CATEGORY, *PACT_CATEGORY;
+
+typedef enum _TS_ACTION{
+        ACT_ADDTSREQ = 0,
+        ACT_ADDTSRSP = 1,
+        ACT_DELTS    = 2,
+        ACT_SCHEDULE = 3,
+} TS_ACTION, *PTS_ACTION;
+
+typedef enum _BA_ACTION{
+        ACT_ADDBAREQ = 0,
+        ACT_ADDBARSP = 1,
+        ACT_DELBA    = 2,
+} BA_ACTION, *PBA_ACTION;
+
+typedef enum _InitialGainOpType{
+	IG_Backup=0,
+	IG_Restore,
+	IG_Max
+}InitialGainOpType;
+
+/* debug macros */
+#define CONFIG_IEEE80211_DEBUG
+#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: " fmt, ## args); } while (0)
+//wb added to debug out data buf
+//if you want print DATA buffer related BA, please set ieee80211_debug_level to DATA|BA
+#define IEEE80211_DEBUG_DATA(level, data, datalen)	\
+	do{ if ((ieee80211_debug_level & (level)) == (level))	\
+		{ 	\
+			int i;					\
+			u8* pdata = (u8*) data;			\
+			printk(KERN_DEBUG "ieee80211: %s()\n", __FUNCTION__);	\
+			for(i=0; i<(int)(datalen); i++)			\
+			{						\
+				printk("%2x ", pdata[i]);		\
+				if ((i+1)%16 == 0) printk("\n");	\
+			}				\
+			printk("\n");			\
+		}					\
+	} while (0)		
+#else
+#define IEEE80211_DEBUG(level, fmt, args...) do {} while (0)
+#define IEEE80211_DEBUG_DATA(level, data, datalen) do {} while(0)
+#endif	/* CONFIG_IEEE80211_DEBUG */
+
+/* debug macros not dependent on CONFIG_IEEE80211_DEBUG */
+
+#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]
+
+/*
+ * 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_DL_HT		   (1<<10)  //HT
+#define IEEE80211_DL_BA		   (1<<11)  //ba
+#define IEEE80211_DL_TS		   (1<<12)  //TS
+#define IEEE80211_DL_QOS           (1<<13)
+#define IEEE80211_DL_REORDER	   (1<<14)
+#define IEEE80211_DL_IOT	   (1<<15)
+#define IEEE80211_DL_IPS	   (1<<16)
+#define IEEE80211_DL_TRACE	   (1<<29)  //trace function, need to user net_ratelimit() together in order not to print too much to the screen
+#define IEEE80211_DL_DATA	   (1<<30)   //use this flag to control whether print data buf out.
+#define IEEE80211_DL_ERR	   (1<<31)   //always open
+#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)
+#define IEEE80211_DEBUG_QOS(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_QOS, f, ## a)
+
+#ifdef CONFIG_IEEE80211_DEBUG
+/* Added by Annie, 2005-11-22. */
+#define MAX_STR_LEN     64
+/* I want to see ASCII 33 to 126 only. Otherwise, I print '?'. Annie, 2005-11-22.*/
+#define PRINTABLE(_ch)  (_ch>'!' && _ch<'~')    
+#define IEEE80211_PRINT_STR(_Comp, _TitleString, _Ptr, _Len)                            	\
+                        if((_Comp) & level)   							\
+                        {                                                                       \
+                                int             __i;                                            \
+                                u8  buffer[MAX_STR_LEN];                                    	\
+                                int length = (_Len<MAX_STR_LEN)? _Len : (MAX_STR_LEN-1) ;  	\
+                                memset(buffer, 0, MAX_STR_LEN);                      		\
+                                memcpy(buffer, (u8 *)_Ptr, length );            		\
+                                for( __i=0; __i<MAX_STR_LEN; __i++ )                            \
+                                {                                                               \
+                                     if( !PRINTABLE(buffer[__i]) )   buffer[__i] = '?';     	\
+                                }                                                               \
+                                buffer[length] = '\0';                                          \
+                                printk("Rtl819x: ");                                         	\
+                                printk(_TitleString);                                         \
+                                printk(": %d, <%s>\n", _Len, buffer);                         \
+                        }
+#else
+#define IEEE80211_PRINT_STR(_Comp, _TitleString, _Ptr, _Len)  do {} while (0)
+#endif
+
+#include <linux/netdevice.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_VERS(fc) ((fc) & IEEE80211_FCTL_VERS)
+#define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE)
+#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE)
+
+#define WLAN_FC_GET_FRAMETYPE(fc) ((fc) & IEEE80211_FCTL_FRAMETYPE)
+#define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG)
+#define WLAN_GET_SEQ_SEQ(seq)  (((seq) & IEEE80211_SCTL_SEQ) >> 4)
+
+/* Authentication algorithms */
+#define WLAN_AUTH_OPEN 0
+#define WLAN_AUTH_SHARED_KEY 1
+#define WLAN_AUTH_LEAP 2
+
+#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_SPECTRUM_MGMT (1<<8)
+#define WLAN_CAPABILITY_QOS (1<<9)
+#define WLAN_CAPABILITY_SHORT_SLOT (1<<10)
+#define WLAN_CAPABILITY_DSSS_OFDM (1<<13)
+
+/* 802.11g ERP information element */
+#define WLAN_ERP_NON_ERP_PRESENT (1<<0)
+#define WLAN_ERP_USE_PROTECTION (1<<1)
+#define WLAN_ERP_BARKER_PREAMBLE (1<<2)
+
+/* Status codes */
+enum ieee80211_statuscode {
+        WLAN_STATUS_SUCCESS = 0,
+        WLAN_STATUS_UNSPECIFIED_FAILURE = 1,
+        WLAN_STATUS_CAPS_UNSUPPORTED = 10,
+        WLAN_STATUS_REASSOC_NO_ASSOC = 11,
+        WLAN_STATUS_ASSOC_DENIED_UNSPEC = 12,
+        WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG = 13,
+        WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION = 14,
+        WLAN_STATUS_CHALLENGE_FAIL = 15,
+        WLAN_STATUS_AUTH_TIMEOUT = 16,
+        WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA = 17,
+        WLAN_STATUS_ASSOC_DENIED_RATES = 18,
+        /* 802.11b */
+        WLAN_STATUS_ASSOC_DENIED_NOSHORTPREAMBLE = 19,
+        WLAN_STATUS_ASSOC_DENIED_NOPBCC = 20,
+        WLAN_STATUS_ASSOC_DENIED_NOAGILITY = 21,
+        /* 802.11h */
+        WLAN_STATUS_ASSOC_DENIED_NOSPECTRUM = 22,
+        WLAN_STATUS_ASSOC_REJECTED_BAD_POWER = 23,
+        WLAN_STATUS_ASSOC_REJECTED_BAD_SUPP_CHAN = 24,
+        /* 802.11g */
+        WLAN_STATUS_ASSOC_DENIED_NOSHORTTIME = 25,
+        WLAN_STATUS_ASSOC_DENIED_NODSSSOFDM = 26,
+        /* 802.11i */
+        WLAN_STATUS_INVALID_IE = 40,
+        WLAN_STATUS_INVALID_GROUP_CIPHER = 41,
+        WLAN_STATUS_INVALID_PAIRWISE_CIPHER = 42,
+        WLAN_STATUS_INVALID_AKMP = 43,
+        WLAN_STATUS_UNSUPP_RSN_VERSION = 44,
+        WLAN_STATUS_INVALID_RSN_IE_CAP = 45,
+        WLAN_STATUS_CIPHER_SUITE_REJECTED = 46,
+};
+
+/* Reason codes */
+enum ieee80211_reasoncode {
+        WLAN_REASON_UNSPECIFIED = 1,
+        WLAN_REASON_PREV_AUTH_NOT_VALID = 2,
+        WLAN_REASON_DEAUTH_LEAVING = 3,
+        WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY = 4,
+        WLAN_REASON_DISASSOC_AP_BUSY = 5,
+        WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA = 6,
+        WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA = 7,
+        WLAN_REASON_DISASSOC_STA_HAS_LEFT = 8,
+        WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH = 9,
+        /* 802.11h */
+        WLAN_REASON_DISASSOC_BAD_POWER = 10,
+        WLAN_REASON_DISASSOC_BAD_SUPP_CHAN = 11,
+        /* 802.11i */
+        WLAN_REASON_INVALID_IE = 13,
+        WLAN_REASON_MIC_FAILURE = 14,
+        WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT = 15,
+        WLAN_REASON_GROUP_KEY_HANDSHAKE_TIMEOUT = 16,
+        WLAN_REASON_IE_DIFFERENT = 17,
+        WLAN_REASON_INVALID_GROUP_CIPHER = 18,
+        WLAN_REASON_INVALID_PAIRWISE_CIPHER = 19,
+        WLAN_REASON_INVALID_AKMP = 20,
+        WLAN_REASON_UNSUPP_RSN_VERSION = 21,
+        WLAN_REASON_INVALID_RSN_IE_CAP = 22,
+        WLAN_REASON_IEEE8021X_FAILED = 23,
+        WLAN_REASON_CIPHER_SUITE_REJECTED = 24,
+};
+
+#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
+
+
+/* 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
+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;
+};
+
+/* 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 {
+#if 1
+	u32 mac_time[2];
+	s8 rssi;
+	u8 signal;
+	u8 noise;
+	u16 rate; /* in 100 kbps */
+	u8 received_channel;
+	u8 control;
+	u8 mask;
+	u8 freq;
+	u16 len;
+	u64 tsf;
+	u32 beacon_time;
+	u8 nic_type;
+	u16       Length;
+	//      u8        DataRate;      // In 0.5 Mbps
+	u8        SignalQuality; // in 0-100 index. 
+	s32       RecvSignalPower; // Real power in dBm for this packet, no beautification and aggregation.
+	s8        RxPower; // in dBm Translate from PWdB
+	u8        SignalStrength; // in 0-100 index.
+	u16       bHwError:1;
+	u16       bCRC:1;
+	u16       bICV:1;
+	u16       bShortPreamble:1;
+	u16       Antenna:1;      //for rtl8185
+	u16       Decrypted:1;    //for rtl8185, rtl8187
+	u16       Wakeup:1;       //for rtl8185
+	u16       Reserved0:1;    //for rtl8185
+	u8        AGC;
+	u32       TimeStampLow;
+	u32       TimeStampHigh;
+	bool      bShift;
+	bool      bIsQosData;             // Added by Annie, 2005-12-22.
+	u8        UserPriority;
+
+	//1!!!!!!!!!!!!!!!!!!!!!!!!!!!
+	//1Attention Please!!!<11n or 8190 specific code should be put below this line>
+	//1!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+	u8        RxDrvInfoSize;
+	u8        RxBufShift;
+	bool      bIsAMPDU;
+	bool      bFirstMPDU;
+	bool      bContainHTC;
+	bool      RxIs40MHzPacket;
+	u32       RxPWDBAll;
+	u8        RxMIMOSignalStrength[4];        // in 0~100 index
+	s8        RxMIMOSignalQuality[2];
+	bool      bPacketMatchBSSID;
+	bool      bIsCCK;
+	bool      bPacketToSelf;
+	//added by amy
+	u8*       virtual_address;
+	u16          packetlength;              // Total packet length: Must equal to sum of all FragLength
+	u16          fraglength;                        // FragLength should equal to PacketLength in non-fragment case
+	u16          fragoffset;                        // Data offset for this fragment
+	u16          ntotalfrag;
+	bool      	  bisrxaggrsubframe;
+	bool		  bPacketBeacon;	//cosa add for rssi
+	bool		  bToSelfBA;		//cosa add for rssi
+	char 	  cck_adc_pwdb[4];	//cosa add for rx path selection
+	u16		  Seq_Num;
+#endif
+
+};
+
+/* 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_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_ENCRYPT       (1<<9)
+
+#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 SEC_ALG_NONE            0
+#define SEC_ALG_WEP             1
+#define SEC_ALG_TKIP            2
+#define SEC_ALG_CCMP            3
+
+#define WEP_KEYS 		4
+#define WEP_KEY_LEN		13
+#define SCM_KEY_LEN             32
+#define SCM_TEMPORAL_KEY_LENGTH 16
+
+struct ieee80211_security {
+	u16 active_key:2,
+            enabled:1,
+	    auth_mode:2,
+            auth_algo:4,
+            unicast_uses_group:1,
+	    encrypt:1;
+	u8 key_sizes[WEP_KEYS];
+	u8 keys[WEP_KEYS][SCM_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
+*/
+
+/* Management Frame Information Element Types */
+enum ieee80211_mfie {
+        MFIE_TYPE_SSID = 0,
+        MFIE_TYPE_RATES = 1,
+        MFIE_TYPE_FH_SET = 2,
+        MFIE_TYPE_DS_SET = 3,
+        MFIE_TYPE_CF_SET = 4,
+        MFIE_TYPE_TIM = 5,
+        MFIE_TYPE_IBSS_SET = 6,
+        MFIE_TYPE_COUNTRY = 7,
+        MFIE_TYPE_HOP_PARAMS = 8,
+        MFIE_TYPE_HOP_TABLE = 9,
+        MFIE_TYPE_REQUEST = 10,
+        MFIE_TYPE_CHALLENGE = 16,
+        MFIE_TYPE_POWER_CONSTRAINT = 32,
+        MFIE_TYPE_POWER_CAPABILITY = 33,
+        MFIE_TYPE_TPC_REQUEST = 34,
+        MFIE_TYPE_TPC_REPORT = 35,
+        MFIE_TYPE_SUPP_CHANNELS = 36,
+        MFIE_TYPE_CSA = 37,
+        MFIE_TYPE_MEASURE_REQUEST = 38,
+        MFIE_TYPE_MEASURE_REPORT = 39,
+        MFIE_TYPE_QUIET = 40,
+        MFIE_TYPE_IBSS_DFS = 41,
+        MFIE_TYPE_ERP = 42,
+        MFIE_TYPE_RSN = 48,
+        MFIE_TYPE_RATES_EX = 50,
+        MFIE_TYPE_HT_CAP= 45,
+	 MFIE_TYPE_HT_INFO= 61,
+	 MFIE_TYPE_AIRONET=133,
+        MFIE_TYPE_GENERIC = 221,
+        MFIE_TYPE_QOS_PARAMETER = 222,
+};
+
+/* Minimal header; can be used for passing 802.11 frames with sufficient
+ * information to determine what type of underlying data type is actually
+ * stored in the data. */
+struct ieee80211_hdr {
+        __le16 frame_ctl;
+        __le16 duration_id;
+        u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_1addr {
+        __le16 frame_ctl;
+        __le16 duration_id;
+        u8 addr1[ETH_ALEN];
+        u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_2addr {
+        __le16 frame_ctl;
+        __le16 duration_id;
+        u8 addr1[ETH_ALEN];
+        u8 addr2[ETH_ALEN];
+        u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_3addr {
+	__le16 frame_ctl;
+	__le16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 addr2[ETH_ALEN];
+	u8 addr3[ETH_ALEN];
+	__le16 seq_ctl;
+        u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_4addr {
+	__le16 frame_ctl;
+	__le16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 addr2[ETH_ALEN];
+	u8 addr3[ETH_ALEN];
+	__le16 seq_ctl;
+	u8 addr4[ETH_ALEN];
+        u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_3addrqos {
+	__le16 frame_ctl;
+	__le16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 addr2[ETH_ALEN];
+	u8 addr3[ETH_ALEN];
+	__le16 seq_ctl;
+        u8 payload[0];
+	__le16 qos_ctl;
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_4addrqos {
+	__le16 frame_ctl;
+	__le16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 addr2[ETH_ALEN];
+	u8 addr3[ETH_ALEN];
+	__le16 seq_ctl;
+	u8 addr4[ETH_ALEN];
+        u8 payload[0];
+	__le16 qos_ctl;
+} __attribute__ ((packed));
+
+struct ieee80211_info_element {
+	u8 id;
+	u8 len;
+	u8 data[0];
+} __attribute__ ((packed));
+
+struct ieee80211_authentication {
+	struct ieee80211_hdr_3addr header;
+	__le16 algorithm;
+	__le16 transaction;
+	__le16 status;
+	/*challenge*/
+	struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct ieee80211_disassoc {
+        struct ieee80211_hdr_3addr header;
+        __le16 reason;
+} __attribute__ ((packed));
+
+struct ieee80211_probe_request {
+	struct ieee80211_hdr_3addr header;
+	/* SSID, supported rates */
+        struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct ieee80211_probe_response {
+	struct ieee80211_hdr_3addr header;
+	u32 time_stamp[2];
+	__le16 beacon_interval;
+	__le16 capability;
+        /* SSID, supported rates, FH params, DS params,
+         * CF params, IBSS params, TIM (if beacon), RSN */
+        struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+/* Alias beacon for probe_response */
+#define ieee80211_beacon ieee80211_probe_response
+
+struct ieee80211_assoc_request_frame {
+	struct ieee80211_hdr_3addr header;
+	__le16 capability;
+	__le16 listen_interval;
+	/* SSID, supported rates, RSN */
+        struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct ieee80211_reassoc_request_frame {
+	struct ieee80211_hdr_3addr header;
+	__le16 capability;
+	__le16 listen_interval;
+	u8 current_ap[ETH_ALEN];
+	/* SSID, supported rates, RSN */
+        struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct ieee80211_assoc_response_frame {
+	struct ieee80211_hdr_3addr header;
+	__le16 capability;
+	__le16 status;
+	__le16 aid;
+	struct ieee80211_info_element info_element[0]; /* supported rates */
+} __attribute__ ((packed));
+
+struct ieee80211_txb {
+	u8 nr_frags;
+	u8 encrypted;
+	u8 queue_index;
+	u8 rts_included;
+	u16 reserved;
+	__le16 frag_size;
+	__le16 payload_size;
+	struct sk_buff *fragments[0];
+};
+
+#define MAX_TX_AGG_COUNT		  16
+struct ieee80211_drv_agg_txb {
+	u8 nr_drv_agg_frames;
+	struct sk_buff *tx_agg_frames[MAX_TX_AGG_COUNT];
+}__attribute__((packed));
+
+#define MAX_SUBFRAME_COUNT 		  64
+struct ieee80211_rxb {
+	u8 nr_subframes;
+	struct sk_buff *subframes[MAX_SUBFRAME_COUNT];
+	u8 dst[ETH_ALEN];
+	u8 src[ETH_ALEN];
+}__attribute__((packed));
+
+typedef union _frameqos {
+	u16 shortdata;
+	u8  chardata[2];
+	struct {
+		u16 tid:4;
+		u16 eosp:1;
+		u16 ack_policy:2;
+		u16 reserved:1;
+		u16 txop:8;
+	}field;
+}frameqos,*pframeqos;
+
+/* 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
+
+#define MAX_CHANNEL_NUMBER                 161
+#define IEEE80211_SOFTMAC_SCAN_TIME	   100
+//(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)
+
+/* QoS structure */
+#define NETWORK_HAS_QOS_PARAMETERS      (1<<3)
+#define NETWORK_HAS_QOS_INFORMATION     (1<<4)
+#define NETWORK_HAS_QOS_MASK            (NETWORK_HAS_QOS_PARAMETERS | \
+                                         NETWORK_HAS_QOS_INFORMATION)
+/* 802.11h */
+#define NETWORK_HAS_POWER_CONSTRAINT    (1<<5)
+#define NETWORK_HAS_CSA                 (1<<6)
+#define NETWORK_HAS_QUIET               (1<<7)
+#define NETWORK_HAS_IBSS_DFS            (1<<8)
+#define NETWORK_HAS_TPC_REPORT          (1<<9)
+
+#define NETWORK_HAS_ERP_VALUE           (1<<10)
+
+#define QOS_QUEUE_NUM                   4
+#define QOS_OUI_LEN                     3
+#define QOS_OUI_TYPE                    2
+#define QOS_ELEMENT_ID                  221
+#define QOS_OUI_INFO_SUB_TYPE           0
+#define QOS_OUI_PARAM_SUB_TYPE          1
+#define QOS_VERSION_1                   1
+#define QOS_AIFSN_MIN_VALUE             2
+#if 1
+struct ieee80211_qos_information_element {
+        u8 elementID;
+        u8 length;
+        u8 qui[QOS_OUI_LEN];
+        u8 qui_type;
+        u8 qui_subtype;
+        u8 version;
+        u8 ac_info;
+} __attribute__ ((packed));
+
+struct ieee80211_qos_ac_parameter {
+        u8 aci_aifsn;
+        u8 ecw_min_max;
+        __le16 tx_op_limit;
+} __attribute__ ((packed));
+
+struct ieee80211_qos_parameter_info {
+        struct ieee80211_qos_information_element info_element;
+        u8 reserved;
+        struct ieee80211_qos_ac_parameter ac_params_record[QOS_QUEUE_NUM];
+} __attribute__ ((packed));
+
+struct ieee80211_qos_parameters {
+        __le16 cw_min[QOS_QUEUE_NUM];
+        __le16 cw_max[QOS_QUEUE_NUM];
+        u8 aifs[QOS_QUEUE_NUM];
+        u8 flag[QOS_QUEUE_NUM];
+        __le16 tx_op_limit[QOS_QUEUE_NUM];
+} __attribute__ ((packed));
+
+struct ieee80211_qos_data {
+        struct ieee80211_qos_parameters parameters;
+        int active;
+        int supported;
+        u8 param_count;
+        u8 old_param_count;
+};
+
+struct ieee80211_tim_parameters {
+        u8 tim_count;
+        u8 tim_period;
+} __attribute__ ((packed));
+
+//#else
+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));
+#endif
+enum eap_type {
+	EAP_PACKET = 0,
+	EAPOL_START,
+	EAPOL_LOGOFF,
+	EAPOL_KEY,
+	EAPOL_ENCAP_ASF_ALERT
+};
+
+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 ((u32)type >= ARRAY_SIZE(eap_types)) ? "Unknown" : eap_types[type];
+}
+//added by amy for reorder
+static inline u8 Frame_QoSTID(u8* buf)
+{
+	struct ieee80211_hdr_3addr *hdr;
+	u16 fc;
+	hdr = (struct ieee80211_hdr_3addr *)buf;
+	fc = le16_to_cpu(hdr->frame_ctl);
+	return (u8)((frameqos*)(buf + (((fc & IEEE80211_FCTL_TODS)&&(fc & IEEE80211_FCTL_FROMDS))? 30 : 24)))->field.tid;
+}
+
+//added by amy for reorder
+
+struct eapol {
+	u8 snap[6];
+	u16 ethertype;
+	u8 version;
+	u8 type;
+	u16 length;
+} __attribute__ ((packed));
+
+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;
+	unsigned char CurrentShowTxate;
+	unsigned char last_packet_rate;
+	unsigned int txretrycount;
+};
+
+#define BEACON_PROBE_SSID_ID_POSITION 12
+
+struct ieee80211_info_element_hdr {
+	u8 id;
+	u8 len;
+} __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 2 //1Mbps
+
+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)
+
+#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_BK   0x00
+#define WME_AC_BE   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
+
+#define MAX_RECEIVE_BUFFER_SIZE 9100
+
+//UP Mapping to AC, using in MgntQuery_SequenceNumber() and maybe for DSCP
+//#define UP2AC(up)	((up<3) ? ((up==0)?1:0) : (up>>1)) 
+#if 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)	
+#endif
+//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 */
+#define ETHERNET_HEADER_SIZE    14      /* length of two Ethernet address plus ether type*/
+
+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
+
+typedef struct _bss_ht{
+
+	bool				support_ht;
+
+	// HT related elements
+	u8					ht_cap_buf[32];
+	u16					ht_cap_len;
+	u8					ht_info_buf[32];
+	u16					ht_info_len;
+
+	HT_SPEC_VER			ht_spec_ver;
+	//HT_CAPABILITY_ELE			bdHTCapEle;
+	//HT_INFORMATION_ELE		bdHTInfoEle;
+
+	bool				aggregation;
+	bool				long_slot_time;
+}bss_ht, *pbss_ht;
+
+typedef enum _erp_t{
+	ERP_NonERPpresent	= 0x01,
+	ERP_UseProtection	= 0x02,
+	ERP_BarkerPreambleMode = 0x04,
+} erp_t;
+
+
+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;
+#if 1
+        struct ieee80211_qos_data qos_data;
+#else
+       // Qos related. Added by Annie, 2005-11-01.
+        BSS_QOS   BssQos;
+#endif
+	//added by amy for LEAP
+	bool	bWithAironetIE;
+	bool	bCkipSupported;
+	bool	bCcxRmEnable;
+	u16 	CcxRmState[2];
+	// CCXv4 S59, MBSSID.
+	bool	bMBssidValid;
+	u8	MBssidMask;
+	u8	MBssid[6];
+	// CCX 2 S38, WLAN Device Version Number element. Annie, 2006-08-20.
+	bool	bWithCcxVerNum;
+	u8	BssCcxVerNumber;
+	/* 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;
+	u32 flags;
+	u32 last_associate;
+	u32 time_stamp[2];
+	u16 beacon_interval;
+	u16 listen_interval;
+	u16 atim_window;
+	u8  erp_value;
+	u8  wpa_ie[MAX_WPA_IE_LEN];
+	size_t wpa_ie_len;
+	u8  rsn_ie[MAX_WPA_IE_LEN];
+	size_t rsn_ie_len;
+
+        struct ieee80211_tim_parameters tim;
+	u8  dtim_period;
+	u8  dtim_data;
+	u32 last_dtim_sta_time[2];
+
+        //appeded for QoS
+        u8 wmm_info;
+        struct ieee80211_wmm_ac_param wmm_param[4];
+        u8 QoS_Enable;
+#ifdef THOMAS_TURBO
+	u8 Turbo_Enable;//enable turbo mode, added by thomas
+#endif
+#ifdef ENABLE_DOT11D
+	u16 CountryIeLen;
+	u8 CountryIeBuf[MAX_IE_LEN];
+#endif
+        // HT Related, by amy, 2008.04.29
+	BSS_HT	bssht;
+	// Add to handle broadcom AP management frame CCK rate.
+	bool broadcom_cap_exist;
+	bool ralink_cap_exist;
+	bool atheros_cap_exist;
+	bool cisco_cap_exist;
+	bool unknown_cap_exist;
+//	u8	berp_info;
+	bool	berp_info_valid;
+	bool buseprotection;
+	//put at the end of the structure.
+	struct list_head list;
+};
+
+#if 1
+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,
+	
+};
+#else
+enum ieee80211_state {
+        IEEE80211_UNINITIALIZED = 0,
+        IEEE80211_INITIALIZED,
+        IEEE80211_ASSOCIATING,
+        IEEE80211_ASSOCIATED,
+        IEEE80211_AUTHENTICATING,
+        IEEE80211_AUTHENTICATED,
+        IEEE80211_SHUTDOWN
+};
+#endif
+
+#define DEFAULT_MAX_SCAN_AGE (15 * HZ)
+#define DEFAULT_FTS 2346
+
+#define CFG_IEEE80211_RESERVE_FCS (1<<0)
+#define CFG_IEEE80211_COMPUTE_FCS (1<<1)
+#define CFG_IEEE80211_RTS (1<<2)
+
+#define IEEE80211_24GHZ_MIN_CHANNEL 1
+#define IEEE80211_24GHZ_MAX_CHANNEL 14
+#define IEEE80211_24GHZ_CHANNELS (IEEE80211_24GHZ_MAX_CHANNEL - \
+                                  IEEE80211_24GHZ_MIN_CHANNEL + 1)
+
+#define IEEE80211_52GHZ_MIN_CHANNEL 34
+#define IEEE80211_52GHZ_MAX_CHANNEL 165
+#define IEEE80211_52GHZ_CHANNELS (IEEE80211_52GHZ_MAX_CHANNEL - \
+                                  IEEE80211_52GHZ_MIN_CHANNEL + 1)
+
+#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
+
+typedef struct tx_pending_t{
+	int frag;
+	struct ieee80211_txb *txb;
+}tx_pending_t;
+
+typedef struct _bandwidth_autoswitch
+{
+	long threshold_20Mhzto40Mhz;
+	long	threshold_40Mhzto20Mhz;	
+	bool bforced_tx20Mhz;
+	bool bautoswitch_enable;	
+}bandwidth_autoswitch,*pbandwidth_autoswitch;
+
+
+//added by amy for order
+
+#define REORDER_WIN_SIZE	128
+#define REORDER_ENTRY_NUM	128
+typedef struct _RX_REORDER_ENTRY
+{
+	struct list_head	List;
+	u16			SeqNum;
+	struct ieee80211_rxb* prxb;
+} RX_REORDER_ENTRY, *PRX_REORDER_ENTRY;
+//added by amy for order
+typedef enum _Fsync_State{
+	Default_Fsync,
+	HW_Fsync,
+	SW_Fsync
+}Fsync_State;	
+
+// Power save mode configured. 
+typedef	enum _RT_PS_MODE	
+{
+	eActive,	// Active/Continuous access.
+	eMaxPs,		// Max power save mode.
+	eFastPs		// Fast power save mode.
+}RT_PS_MODE;
+
+typedef enum _IPS_CALLBACK_FUNCION
+{
+	IPS_CALLBACK_NONE = 0,
+	IPS_CALLBACK_MGNT_LINK_REQUEST = 1,
+	IPS_CALLBACK_JOIN_REQUEST = 2,
+}IPS_CALLBACK_FUNCION;
+
+typedef enum _RT_JOIN_ACTION{
+	RT_JOIN_INFRA   = 1,
+	RT_JOIN_IBSS  = 2,
+	RT_START_IBSS = 3,
+	RT_NO_ACTION  = 4,
+}RT_JOIN_ACTION;
+
+typedef struct _IbssParms{
+	u16   atimWin;
+}IbssParms, *PIbssParms;
+#define MAX_NUM_RATES	264 // Max num of support rates element: 8,  Max num of ext. support rate: 255. 061122, by rcnjko.
+
+// RF state.
+typedef	enum _RT_RF_POWER_STATE
+{
+	eRfOn,
+	eRfSleep,
+	eRfOff
+}RT_RF_POWER_STATE;
+
+typedef struct _RT_POWER_SAVE_CONTROL
+{
+
+	//
+	// Inactive Power Save(IPS) : Disable RF when disconnected
+	//
+	bool				bInactivePs;
+	bool				bIPSModeBackup;
+	bool				bSwRfProcessing;
+	RT_RF_POWER_STATE	eInactivePowerState;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+	struct work_struct 	InactivePsWorkItem;
+#else
+	struct tq_struct	InactivePsWorkItem;
+#endif
+	struct timer_list	InactivePsTimer;
+
+	// Return point for join action
+	IPS_CALLBACK_FUNCION	ReturnPoint;
+	
+	// Recored Parameters for rescheduled JoinRequest
+	bool				bTmpBssDesc;
+	RT_JOIN_ACTION		tmpJoinAction;
+	struct ieee80211_network tmpBssDesc;
+
+	// Recored Parameters for rescheduled MgntLinkRequest
+	bool				bTmpScanOnly;
+	bool				bTmpActiveScan;
+	bool				bTmpFilterHiddenAP;
+	bool				bTmpUpdateParms;
+	u8					tmpSsidBuf[33];
+	OCTET_STRING			tmpSsid2Scan;
+	bool				bTmpSsid2Scan;
+	u8					tmpNetworkType;
+	u8					tmpChannelNumber;
+	u16					tmpBcnPeriod;
+	u8					tmpDtimPeriod;
+	u16					tmpmCap;
+	OCTET_STRING			tmpSuppRateSet;
+	u8					tmpSuppRateBuf[MAX_NUM_RATES];
+	bool				bTmpSuppRate;
+	IbssParms				tmpIbpm;
+	bool				bTmpIbpm;
+
+	//
+	// Leisre Poswer Save : Disable RF if connected but traffic is not busy
+	//		
+	bool				bLeisurePs;
+	
+}RT_POWER_SAVE_CONTROL,*PRT_POWER_SAVE_CONTROL;
+
+typedef u32 RT_RF_CHANGE_SOURCE;
+#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 RF_CHANGE_BY_INIT	0	// Do not change the RFOff reason. Defined by Bruce, 2008-01-17.
+
+#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,
+	COUNTRY_CODE_MIC,
+	COUNTRY_CODE_GLOBAL_DOMAIN
+}country_code_type_t;	
+#endif
+
+#define RT_MAX_LD_SLOT_NUM	10
+typedef struct _RT_LINK_DETECT_T{
+
+	u32				NumRecvBcnInPeriod;
+	u32				NumRecvDataInPeriod;
+
+	u32				RxBcnNum[RT_MAX_LD_SLOT_NUM];	// number of Rx beacon / CheckForHang_period  to determine link status
+	u32				RxDataNum[RT_MAX_LD_SLOT_NUM];	// number of Rx data / CheckForHang_period  to determine link status
+	u16				SlotNum;	// number of CheckForHang period to determine link status
+	u16				SlotIndex;
+
+	u32				NumTxOkInPeriod;
+	u32				NumRxOkInPeriod;
+	bool				bBusyTraffic;
+}RT_LINK_DETECT_T, *PRT_LINK_DETECT_T;
+
+
+struct ieee80211_device {
+	struct net_device *dev;
+        struct ieee80211_security sec;
+
+	//hw security related
+//	u8 hwsec_support; //support?
+	u8 hwsec_active;  //hw security active.
+	bool is_silent_reset;
+	bool ieee_up;	
+	//added by amy
+	bool bSupportRemoteWakeUp;
+	RT_PS_MODE	dot11PowerSaveMode; // Power save mode configured.
+	bool actscanning;
+	bool beinretry;
+	RT_RF_POWER_STATE		eRFPowerState;
+	RT_RF_CHANGE_SOURCE	RfOffReason;
+	bool is_set_key;
+	//11n spec related I wonder if These info structure need to be moved out of ieee80211_device
+	
+	//11n HT below
+	PRT_HIGH_THROUGHPUT	pHTInfo;
+	//struct timer_list		SwBwTimer;
+//	spinlock_t chnlop_spinlock;
+	spinlock_t bw_spinlock;
+
+	spinlock_t reorder_spinlock;
+	// for HT operation rate set.  we use this one for HT data rate to seperate different descriptors
+	//the way fill this is the same as in the IE
+	u8	Regdot11HTOperationalRateSet[16];		//use RATR format
+	u8	dot11HTOperationalRateSet[16];		//use RATR format
+	u8	RegHTSuppRateSet[16];
+	u8				HTCurrentOperaRate;
+	u8				HTHighestOperaRate;
+	//wb added for rate operation mode to firmware
+	u8	bTxDisableRateFallBack;
+	u8 	bTxUseDriverAssingedRate;
+	atomic_t	atm_chnlop;
+	atomic_t	atm_swbw;
+//	u8	HTHighestOperaRate;
+//	u8 	HTCurrentOperaRate;
+
+	// 802.11e and WMM Traffic Stream Info (TX)
+	struct list_head		Tx_TS_Admit_List;
+	struct list_head		Tx_TS_Pending_List;
+	struct list_head		Tx_TS_Unused_List;
+	TX_TS_RECORD		TxTsRecord[TOTAL_TS_NUM];
+	// 802.11e and WMM Traffic Stream Info (RX)
+	struct list_head		Rx_TS_Admit_List;
+	struct list_head		Rx_TS_Pending_List;
+	struct list_head		Rx_TS_Unused_List;
+	RX_TS_RECORD		RxTsRecord[TOTAL_TS_NUM];
+//#ifdef TO_DO_LIST
+	RX_REORDER_ENTRY	RxReorderEntry[128];
+	struct list_head		RxReorder_Unused_List;
+//#endif
+	// Qos related. Added by Annie, 2005-11-01.
+//	PSTA_QOS			pStaQos;
+	u8				ForcedPriority;		// Force per-packet priority 1~7. (default: 0, not to force it.)
+	
+
+	/* 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_*) */
+	struct iw_spy_data spy_data; 
+
+	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 auth_mode;
+	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_encrypt_msdu;
+	int host_decrypt;
+        /* host performs multicast decryption */
+        int host_mc_decrypt;
+
+        /* host should strip IV and ICV from protected frames */
+        /* meaningful only when hardware decryption is being used */
+        int host_strip_iv_icv;
+
+        int host_open_frag;
+        int host_build_iv;
+	int ieee802_1x; /* is IEEE 802.1X used */
+
+	/* WPA data */
+	bool bHalfWirelessN24GMode;
+	int wpa_enabled;
+	int drop_unencrypted;
+	int tkip_countermeasures;
+	int privacy_invoked;
+	size_t wpa_ie_len;
+	u8 *wpa_ie;
+	u8 ap_mac_addr[6];
+	u16 pairwise_key_type;
+	u16 group_key_type;
+	struct list_head crypt_deinit_list;
+	struct ieee80211_crypt_data *crypt[WEP_KEYS];
+	int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */
+	struct timer_list crypt_deinit_timer;
+        int crypt_quiesced;
+
+	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 */
+#define DEFAULT_RTS_THRESHOLD 2346U
+#define MIN_RTS_THRESHOLD 1
+#define MAX_RTS_THRESHOLD 2346U
+        u16 rts; /* RTS threshold */
+
+        /* Association info */
+        u8 bssid[ETH_ALEN];
+
+	/* 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 reg_mode;
+	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; 
+	
+        int perfect_rssi;
+        int worst_rssi;
+
+        u16 prev_seq_ctl;       /* used to drop duplicate frames */
+
+	/* map of allowed channels. 0 is dummy */
+	// FIXME: remeber to default to a basic channel plan depending of the PHY type
+#ifdef ENABLE_DOT11D
+	void* pDot11dInfo;
+	bool bGlobalDomain;
+#else
+	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;
+	
+	/* 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;
+	int ps_period;
+	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 proto_started;
+	
+	struct semaphore wx_sem;
+	struct semaphore scan_sem;
+	
+	spinlock_t mgmt_tx_lock;	
+	spinlock_t beacon_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;
+	/* set on initialization */
+	u8  qos_support;
+	
+	/* for discarding duplicated packets in IBSS */
+	struct list_head ibss_mac_hash[IEEE_IBSS_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;
+//{ added for rtl819x
+#define IEEE80211_QUEUE_LIMIT 128
+	u8 AsocRetryCount;
+	unsigned int hw_header;
+	struct sk_buff_head skb_waitQ[MAX_QUEUE_SIZE];
+	struct sk_buff_head  skb_aggQ[MAX_QUEUE_SIZE]; 
+	struct sk_buff_head  skb_drv_aggQ[MAX_QUEUE_SIZE]; 
+	u32	sta_edca_param[4];
+	bool aggregation;
+	// Enable/Disable Rx immediate BA capability.
+	bool enable_rx_imm_BA;
+	bool bibsscoordinator;
+
+	//+by amy for DM ,080515
+	//Dynamic Tx power for near/far range enable/Disable  , by amy , 2008-05-15
+	bool	bdynamic_txpower_enable; 
+
+	bool bCTSToSelfEnable;
+	u8 	CTSToSelfTH;
+	
+	u32 	fsync_time_interval;
+	u32	fsync_rate_bitmap;
+	u8	fsync_rssi_threshold;
+	bool	bfsync_enable;
+
+	u8	fsync_multiple_timeinterval;		// FsyncMultipleTimeInterval * FsyncTimeInterval	 
+	u32	fsync_firstdiff_ratethreshold;		// low threshold
+	u32	fsync_seconddiff_ratethreshold;	 // decrease threshold
+	Fsync_State			fsync_state;
+	bool		bis_any_nonbepkts;
+	//20Mhz 40Mhz AutoSwitch Threshold
+	bandwidth_autoswitch bandwidth_auto_switch;
+	//for txpower tracking
+	bool FwRWRF;
+
+	//added by amy for AP roaming
+	RT_LINK_DETECT_T	LinkDetectInfo;
+        //added by amy for ps
+	RT_POWER_SAVE_CONTROL	PowerSaveControl;
+//}	
+	/* 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_procedure_wq;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)        
+        struct delayed_work softmac_scan_wq;
+        struct delayed_work associate_retry_wq;
+	 struct delayed_work start_ibss_wq;
+#else
+        struct work_struct softmac_scan_wq;
+        struct work_struct associate_retry_wq;
+	struct work_struct start_ibss_wq;
+#endif
+        struct work_struct wx_sync_scan_wq;
+        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 softmac_scan_wq;
+	struct tq_struct wx_sync_scan_wq;
+
+#endif
+        // Qos related. Added by Annie, 2005-11-01.
+        //STA_QOS  StaQos;
+
+        //u32 STA_EDCA_PARAM[4];
+	//CHANNEL_ACCESS_SETTING ChannelAccessSetting;
+
+
+	/* 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);
+        int (*is_queue_full) (struct net_device * dev, int pri);
+
+        int (*handle_management) (struct net_device * dev,
+                                  struct ieee80211_network * network, u16 type);
+        int (*is_qos_active) (struct net_device *dev, struct sk_buff *skb);
+
+	/* 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,u16 tx_rate);
+	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);
+#if 0
+	/* Typical STA methods */
+        int (*handle_auth) (struct net_device * dev,
+                            struct ieee80211_auth * auth);
+        int (*handle_deauth) (struct net_device * dev,
+                              struct ieee80211_deauth * auth);
+        int (*handle_action) (struct net_device * dev,
+                              struct ieee80211_action * action,
+                              struct ieee80211_rx_stats * stats);
+        int (*handle_disassoc) (struct net_device * dev,
+                                struct ieee80211_disassoc * assoc);
+#endif
+        int (*handle_beacon) (struct net_device * dev, struct ieee80211_beacon * beacon, struct ieee80211_network * network);
+#if 0
+        int (*handle_probe_response) (struct net_device * dev,
+                                      struct ieee80211_probe_response * resp,
+                                      struct ieee80211_network * network);
+        int (*handle_probe_request) (struct net_device * dev,
+                                     struct ieee80211_probe_request * req,
+                                     struct ieee80211_rx_stats * stats);
+#endif
+        int (*handle_assoc_response) (struct net_device * dev, struct ieee80211_assoc_response_frame * resp, struct ieee80211_network * network);
+
+#if 0
+        /* Typical AP methods */
+        int (*handle_assoc_request) (struct net_device * dev);
+        int (*handle_reassoc_request) (struct net_device * dev,
+                                       struct ieee80211_reassoc_request * req);
+#endif
+
+	/* check whether Tx hw resouce available */
+	short (*check_nic_enough_desc)(struct net_device *dev, int queue_index);
+	//added by wb for HT related
+//	void (*SwChnlByTimerHandler)(struct net_device *dev, int channel);
+	void (*SetBWModeHandler)(struct net_device *dev, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset);
+//	void (*UpdateHalRATRTableHandler)(struct net_device* dev, u8* pMcsRate);
+	bool (*GetNmodeSupportBySecCfg)(struct net_device* dev);
+	void (*SetWirelessMode)(struct net_device* dev, u8 wireless_mode);
+	bool (*GetHalfNmodeSupportByAPsHandler)(struct net_device* dev); 
+	void (*InitialGainHandler)(struct net_device *dev, u8 Operation);
+
+	/* 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_N_24G 		  (1<<4)
+#define	IEEE_N_5G		  (1<<5)
+#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)
+
+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 = IEEE80211_3ADDR_LEN;
+
+	switch (WLAN_FC_GET_TYPE(fc)) {
+	case IEEE80211_FTYPE_DATA:
+		if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
+			hdrlen = IEEE80211_4ADDR_LEN; /* 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 = IEEE80211_1ADDR_LEN;
+			break;
+		default:
+			hdrlen = IEEE80211_2ADDR_LEN;
+			break;
+		}
+		break;
+	}
+
+	return hdrlen;
+}
+
+static inline u8 *ieee80211_get_payload(struct ieee80211_hdr *hdr)
+{
+        switch (ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl))) {
+        case IEEE80211_1ADDR_LEN:
+                return ((struct ieee80211_hdr_1addr *)hdr)->payload;
+        case IEEE80211_2ADDR_LEN:
+                return ((struct ieee80211_hdr_2addr *)hdr)->payload;
+        case IEEE80211_3ADDR_LEN:
+                return ((struct ieee80211_hdr_3addr *)hdr)->payload;
+        case IEEE80211_4ADDR_LEN:
+                return ((struct ieee80211_hdr_4addr *)hdr)->payload;
+        }
+        return NULL;
+}
+
+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;
+}
+
+static inline int ieee80211_is_cck_rate(u8 rate)
+{
+        switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
+        case IEEE80211_CCK_RATE_1MB:
+        case IEEE80211_CCK_RATE_2MB:
+        case IEEE80211_CCK_RATE_5MB:
+        case IEEE80211_CCK_RATE_11MB:
+                return 1;
+        }
+        return 0;
+}
+
+
+/* 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_4addr *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);
+#if WIRELESS_EXT >= 18
+extern int ieee80211_wx_get_encode_ext(struct ieee80211_device *ieee,
+                            struct iw_request_info *info,
+                            union iwreq_data* wrqu, char *extra);
+extern int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
+                            struct iw_request_info *info,
+                            union iwreq_data* wrqu, char *extra);
+extern int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
+                               struct iw_request_info *info,
+                               struct iw_param *data, char *extra);
+extern int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
+                               struct iw_request_info *info,
+                               union iwreq_data *wrqu, char *extra);
+#endif
+extern 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);
+
+void SendDisassociation(struct ieee80211_device *ieee, u8* asSta, u8 asRsn);
+extern void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee);
+
+extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee);
+extern void notify_wx_assoc_event(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 softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee);
+
+/* 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 int ieee80211_wx_set_rts(struct ieee80211_device *ieee, 
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra);
+
+extern int ieee80211_wx_get_rts(struct ieee80211_device *ieee, 
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra);
+//HT				 			     
+#define MAX_RECEIVE_BUFFER_SIZE 9100  //
+extern void HTDebugHTCapability(u8* CapIE, u8* TitleString );
+extern void HTDebugHTInfo(u8*  InfoIE, u8* TitleString);
+
+void HTSetConnectBwMode(struct ieee80211_device* ieee, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET    Offset);
+extern void HTUpdateDefaultSetting(struct ieee80211_device* ieee);
+extern void HTConstructCapabilityElement(struct ieee80211_device* ieee, u8* posHTCap, u8* len, u8 isEncrypt);
+extern void HTConstructInfoElement(struct ieee80211_device* ieee, u8* posHTInfo, u8* len, u8 isEncrypt);
+extern void HTConstructRT2RTAggElement(struct ieee80211_device* ieee, u8* posRT2RTAgg, u8* len);
+extern void HTOnAssocRsp(struct ieee80211_device *ieee);
+extern void HTInitializeHTInfo(struct ieee80211_device* ieee);
+extern void HTInitializeBssDesc(PBSS_HT pBssHT);
+extern void HTResetSelfAndSavePeerSetting(struct ieee80211_device* ieee, struct ieee80211_network * pNetwork);
+extern void HTUpdateSelfAndPeerSetting(struct ieee80211_device* ieee,   struct ieee80211_network * pNetwork);
+extern u8 HTGetHighestMCSRate(struct ieee80211_device* ieee, u8* pMCSRateSet, u8* pMCSFilter);
+extern u8 MCS_FILTER_ALL[];
+extern u16 MCS_DATA_RATE[2][2][77] ;
+extern u8 HTCCheck(struct ieee80211_device* ieee, u8*   pFrame);
+//extern void HTSetConnectBwModeCallback(unsigned long data);
+extern void HTResetIOTSetting(PRT_HIGH_THROUGHPUT  pHTInfo);
+extern bool IsHTHalfNmodeAPs(struct ieee80211_device* ieee);
+extern u16 HTHalfMcsToDataRate(struct ieee80211_device* ieee,  u8      nMcsRate);
+extern u16 HTMcsToDataRate( struct ieee80211_device* ieee, u8 nMcsRate);
+extern u16  TxCountToDataRate( struct ieee80211_device* ieee, u8 nDataRate);
+//function in BAPROC.c
+extern int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb);
+extern int ieee80211_rx_ADDBARsp( struct ieee80211_device* ieee, struct sk_buff *skb);
+extern int ieee80211_rx_DELBA(struct ieee80211_device* ieee,struct sk_buff *skb);
+extern void TsInitAddBA( struct ieee80211_device* ieee, PTX_TS_RECORD   pTS, u8 Policy, u8 bOverwritePending);
+extern void TsInitDelBA( struct ieee80211_device* ieee, PTS_COMMON_INFO pTsCommonInfo, TR_SELECT TxRxSelect);
+extern void BaSetupTimeOut(unsigned long data);
+extern void TxBaInactTimeout(unsigned long data);
+extern void RxBaInactTimeout(unsigned long data);
+extern void ResetBaEntry( PBA_RECORD pBA);
+//function in TS.c
+extern bool GetTs(
+        struct ieee80211_device*        ieee,
+        PTS_COMMON_INFO                 *ppTS,
+        u8*                             Addr,
+        u8                              TID,
+        TR_SELECT                       TxRxSelect,  //Rx:1, Tx:0
+        bool                            bAddNewTs
+        );
+extern void TSInitialize(struct ieee80211_device *ieee);
+extern  void TsStartAddBaProcess(struct ieee80211_device* ieee, PTX_TS_RECORD   pTxTS);			 			     
+extern void RemovePeerTS(struct ieee80211_device* ieee, u8* Addr);
+extern void RemoveAllTS(struct ieee80211_device* ieee);
+void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee);
+
+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;
+}
+
+/* For the function is more related to hardware setting, it's better to use the  
+ * ieee handler to refer to it.
+ */
+extern short check_nic_enough_desc(struct net_device *dev, int queue_index);
+extern int ieee80211_data_xmit(struct sk_buff *skb, struct net_device *dev);
+extern int ieee80211_parse_info_param(struct ieee80211_device *ieee,
+		struct ieee80211_info_element *info_element, 
+		u16 length,
+		struct ieee80211_network *network,
+		struct ieee80211_rx_stats *stats);
+
+void ieee80211_indicate_packets(struct ieee80211_device *ieee, struct ieee80211_rxb** prxbIndicateArray,u8  index);
+#define RT_ASOC_RETRY_LIMIT	5
+#endif /* IEEE80211_H */
diff --git a/drivers/staging/rtl8192u/ieee80211/EndianFree.h b/drivers/staging/rtl8192u/ieee80211/EndianFree.h
new file mode 100644
index 0000000..c723555
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/EndianFree.h
@@ -0,0 +1,199 @@
+#ifndef __INC_ENDIANFREE_H
+#define __INC_ENDIANFREE_H
+
+/*
+ *	Call endian free function when
+ *		1. Read/write packet content.
+ *		2. Before write integer to IO.
+ *		3. After read integer from IO.
+ */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
+#ifndef bool
+typedef enum{false = 0, true} bool;
+#endif
+#endif
+
+#define __MACHINE_LITTLE_ENDIAN 1234    /* LSB first: i386, vax */
+#define __MACHINE_BIG_ENDIAN    4321    /* MSB first: 68000, ibm, net, ppc */
+
+#define BYTE_ORDER __MACHINE_LITTLE_ENDIAN
+
+#if BYTE_ORDER == __MACHINE_LITTLE_ENDIAN
+// Convert data
+#define EF1Byte(_val)				((u8)(_val))
+#define EF2Byte(_val)				((u16)(_val))
+#define EF4Byte(_val)				((u32)(_val))
+
+#else
+// Convert data
+#define EF1Byte(_val)				((u8)(_val))
+#define EF2Byte(_val)				(((((u16)(_val))&0x00ff)<<8)|((((u16)(_val))&0xff00)>>8))
+#define EF4Byte(_val)				(((((u32)(_val))&0x000000ff)<<24)|\
+						((((u32)(_val))&0x0000ff00)<<8)|\
+						((((u32)(_val))&0x00ff0000)>>8)|\
+						((((u32)(_val))&0xff000000)>>24))
+#endif
+
+// Read data from memory
+#define ReadEF1Byte(_ptr)		EF1Byte(*((u8 *)(_ptr)))
+#define ReadEF2Byte(_ptr)		EF2Byte(*((u16 *)(_ptr)))
+#define ReadEF4Byte(_ptr)		EF4Byte(*((u32 *)(_ptr)))
+
+// Write data to memory
+#define WriteEF1Byte(_ptr, _val)	(*((u8 *)(_ptr)))=EF1Byte(_val)
+#define WriteEF2Byte(_ptr, _val)	(*((u16 *)(_ptr)))=EF2Byte(_val)
+#define WriteEF4Byte(_ptr, _val)	(*((u32 *)(_ptr)))=EF4Byte(_val)									
+// Convert Host system specific byte ording (litten or big endia) to Network byte ording (big endian). 
+// 2006.05.07, by rcnjko.
+#if BYTE_ORDER == __MACHINE_LITTLE_ENDIAN
+#define H2N1BYTE(_val)	((u8)(_val))
+#define H2N2BYTE(_val)	(((((u16)(_val))&0x00ff)<<8)|\
+			((((u16)(_val))&0xff00)>>8))
+#define H2N4BYTE(_val)	(((((u32)(_val))&0x000000ff)<<24)|\
+			((((u32)(_val))&0x0000ff00)<<8)	|\
+			((((u32)(_val))&0x00ff0000)>>8)	|\
+			((((u32)(_val))&0xff000000)>>24))
+#else
+#define H2N1BYTE(_val)			((u8)(_val))
+#define H2N2BYTE(_val)			((u16)(_val))
+#define H2N4BYTE(_val)			((u32)(_val))
+#endif
+
+// Convert from Network byte ording (big endian) to Host system specific byte ording (litten or big endia).
+// 2006.05.07, by rcnjko.
+#if BYTE_ORDER == __MACHINE_LITTLE_ENDIAN
+#define N2H1BYTE(_val)	((u8)(_val))
+#define N2H2BYTE(_val)	(((((u16)(_val))&0x00ff)<<8)|\
+			((((u16)(_val))&0xff00)>>8))
+#define N2H4BYTE(_val)	(((((u32)(_val))&0x000000ff)<<24)|\
+			((((u32)(_val))&0x0000ff00)<<8)	|\
+			((((u32)(_val))&0x00ff0000)>>8)	|\
+			((((u32)(_val))&0xff000000)>>24))
+#else
+#define N2H1BYTE(_val)			((u8)(_val))
+#define N2H2BYTE(_val)			((u16)(_val))
+#define N2H4BYTE(_val)			((u32)(_val))
+#endif
+
+//
+//	Example:
+//		BIT_LEN_MASK_32(0) => 0x00000000
+//		BIT_LEN_MASK_32(1) => 0x00000001
+//		BIT_LEN_MASK_32(2) => 0x00000003
+//		BIT_LEN_MASK_32(32) => 0xFFFFFFFF
+//
+#define BIT_LEN_MASK_32(__BitLen) (0xFFFFFFFF >> (32 - (__BitLen)))
+//
+//	Example:
+//		BIT_OFFSET_LEN_MASK_32(0, 2) => 0x00000003
+//		BIT_OFFSET_LEN_MASK_32(16, 2) => 0x00030000
+//
+#define BIT_OFFSET_LEN_MASK_32(__BitOffset, __BitLen) (BIT_LEN_MASK_32(__BitLen) << (__BitOffset)) 
+
+//
+//	Description:
+//		Return 4-byte value in host byte ordering from
+//		4-byte pointer in litten-endian system.
+//
+#define LE_P4BYTE_TO_HOST_4BYTE(__pStart) (EF4Byte(*((u32 *)(__pStart))))
+
+//
+//	Description:
+//		Translate subfield (continuous bits in little-endian) of 4-byte value in litten byte to
+//		4-byte value in host byte ordering.
+//
+#define LE_BITS_TO_4BYTE(__pStart, __BitOffset, __BitLen) \
+	( \
+	  ( LE_P4BYTE_TO_HOST_4BYTE(__pStart) >> (__BitOffset) ) \
+	  & \
+	  BIT_LEN_MASK_32(__BitLen) \
+	)
+
+//
+//	Description:
+//		Mask subfield (continuous bits in little-endian) of 4-byte value in litten byte oredering  
+//		and return the result in 4-byte value in host byte ordering.
+//
+#define LE_BITS_CLEARED_TO_4BYTE(__pStart, __BitOffset, __BitLen) \
+	( \
+	  LE_P4BYTE_TO_HOST_4BYTE(__pStart) \
+	  & \
+	  ( ~BIT_OFFSET_LEN_MASK_32(__BitOffset, __BitLen) ) \
+	)
+
+//
+//	Description:
+//		Set subfield of little-endian 4-byte value to specified value.	
+//
+#define SET_BITS_TO_LE_4BYTE(__pStart, __BitOffset, __BitLen, __Value) \
+	*((u32 *)(__pStart)) = \
+	EF4Byte( \
+	LE_BITS_CLEARED_TO_4BYTE(__pStart, __BitOffset, __BitLen) \
+	| \
+	( (((u32)__Value) & BIT_LEN_MASK_32(__BitLen)) << (__BitOffset) ) \
+       );
+
+
+#define BIT_LEN_MASK_16(__BitLen) \
+	(0xFFFF >> (16 - (__BitLen)))
+
+#define BIT_OFFSET_LEN_MASK_16(__BitOffset, __BitLen) \
+	(BIT_LEN_MASK_16(__BitLen) << (__BitOffset))
+
+#define LE_P2BYTE_TO_HOST_2BYTE(__pStart) \
+	(EF2Byte(*((u16 *)(__pStart))))
+
+#define LE_BITS_TO_2BYTE(__pStart, __BitOffset, __BitLen) \
+	( \
+	  ( LE_P2BYTE_TO_HOST_2BYTE(__pStart) >> (__BitOffset) ) \
+	  & \
+	  BIT_LEN_MASK_16(__BitLen) \
+	)
+
+#define LE_BITS_CLEARED_TO_2BYTE(__pStart, __BitOffset, __BitLen) \
+	( \
+	  LE_P2BYTE_TO_HOST_2BYTE(__pStart) \
+	  & \
+	  ( ~BIT_OFFSET_LEN_MASK_16(__BitOffset, __BitLen) ) \
+	)
+
+#define SET_BITS_TO_LE_2BYTE(__pStart, __BitOffset, __BitLen, __Value) \
+	*((u16 *)(__pStart)) = \
+	EF2Byte( \
+		LE_BITS_CLEARED_TO_2BYTE(__pStart, __BitOffset, __BitLen) \
+		| \
+		( (((u16)__Value) & BIT_LEN_MASK_16(__BitLen)) << (__BitOffset) ) \
+       );
+
+#define BIT_LEN_MASK_8(__BitLen) \
+	(0xFF >> (8 - (__BitLen)))
+
+#define BIT_OFFSET_LEN_MASK_8(__BitOffset, __BitLen) \
+	(BIT_LEN_MASK_8(__BitLen) << (__BitOffset))
+
+#define LE_P1BYTE_TO_HOST_1BYTE(__pStart) \
+	(EF1Byte(*((u8 *)(__pStart))))
+
+#define LE_BITS_TO_1BYTE(__pStart, __BitOffset, __BitLen) \
+	( \
+	  ( LE_P1BYTE_TO_HOST_1BYTE(__pStart) >> (__BitOffset) ) \
+	  & \
+	  BIT_LEN_MASK_8(__BitLen) \
+	)
+
+#define LE_BITS_CLEARED_TO_1BYTE(__pStart, __BitOffset, __BitLen) \
+	( \
+	  LE_P1BYTE_TO_HOST_1BYTE(__pStart) \
+	  & \
+	  ( ~BIT_OFFSET_LEN_MASK_8(__BitOffset, __BitLen) ) \
+	)
+
+#define SET_BITS_TO_LE_1BYTE(__pStart, __BitOffset, __BitLen, __Value) \
+	*((u8 *)(__pStart)) = \
+	EF1Byte( \
+		LE_BITS_CLEARED_TO_1BYTE(__pStart, __BitOffset, __BitLen) \
+		| \
+		( (((u8)__Value) & BIT_LEN_MASK_8(__BitLen)) << (__BitOffset) ) \
+       );
+
+#endif // #ifndef __INC_ENDIANFREE_H
diff --git a/drivers/staging/rtl8192u/ieee80211/Makefile b/drivers/staging/rtl8192u/ieee80211/Makefile
new file mode 100644
index 0000000..0e72128
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/Makefile
@@ -0,0 +1,139 @@
+NIC_SELECT = RTL8192U
+
+KVER  := $(shell uname -r)
+MODDESTDIR := /lib/modules/$(KVER)/kernel/drivers/net/wireless/$(NIC_SELECT)
+
+CC = gcc
+ifneq ($(shell uname -r|cut -d. -f1,2), 2.4)
+EXTRA_CFLAGS += -I$(TOPDIR)/drivers/net/wireless
+EXTRA_CFLAGS += -O2
+EXTRA_CFLAGS += -DJACKSON_NEW_8187 -DJACKSON_NEW_RX
+
+#it will fail to compile in suse linux enterprise 10 sp2. This flag is to solve this problem.
+ifeq ($(shell uname -r | cut -d. -f1,2,3,4), 2.6.16.60-0)
+EXTRA_CFLAGS += -DOPENSUSE_SLED
+endif
+
+ifeq ($(NIC_SELECT),RTL8192U)
+#EXTRA_CFLAGS += -DUSB_TX_DRIVER_AGGREGATION_ENABLE
+#EXTRA_CFLAGS += -DUSB_RX_AGGREGATION_SUPPORT
+endif
+#EXTRA_CFLAGS += -DJOHN_NOCPY
+#flags to enable or disble 80211D feature
+EXTRA_CFLAGS += -DENABLE_DOT11D
+ieee80211-rsl-objs := ieee80211_rx.o \
+		      ieee80211_softmac.o \
+		      ieee80211_tx.o \
+		      ieee80211_wx.o \
+		      ieee80211_module.o \
+		      ieee80211_softmac_wx.o\
+		      rtl819x_HTProc.o\
+		      rtl819x_TSProc.o\
+		      rtl819x_BAProc.o\
+		      dot11d.o
+
+ieee80211_crypt-rsl-objs := ieee80211_crypt.o
+ieee80211_crypt_tkip-rsl-objs := ieee80211_crypt_tkip.o
+ieee80211_crypt_ccmp-rsl-objs := ieee80211_crypt_ccmp.o
+ieee80211_crypt_wep-rsl-objs := ieee80211_crypt_wep.o
+
+obj-m +=ieee80211-rsl.o
+obj-m +=ieee80211_crypt-rsl.o
+obj-m +=ieee80211_crypt_wep-rsl.o
+obj-m +=ieee80211_crypt_tkip-rsl.o
+obj-m +=ieee80211_crypt_ccmp-rsl.o
+
+KSRC := /lib/modules/$(KVER)/build
+INSTALL_PREFIX :=
+
+all: modules
+
+modules:
+	$(MAKE) -C $(KSRC) M=$(PWD) CC=$(CC) modules
+
+install: modules
+	rm -fr $(MODDESTDIR)
+	mkdir -p $(MODDESTDIR)
+	@install -p -m 644 ieee80211_crypt-rsl.ko $(MODDESTDIR)
+	@install -p -m 644 ieee80211_crypt_wep-rsl.ko $(MODDESTDIR)
+	@install -p -m 644 ieee80211_crypt_tkip-rsl.ko $(MODDESTDIR)
+	@install -p -m 644 ieee80211_crypt_ccmp-rsl.ko $(MODDESTDIR)
+	@install -p -m 644 ieee80211-rsl.ko $(MODDESTDIR)
+	depmod -a
+uninstall:
+	rm -fr $(MODDESTDIR)
+	depmod -a 
+
+else
+LD := ld
+KSRC := /lib/modules/$(KVER)/build
+CONFIG_FILE := $(KSRC)/include/linux/autoconf.h
+
+CFLAGS += -DLINUX -D__KERNEL__ -DMODULE -O2 -pipe -Wall
+CFLAGS += -I$(KSRC)/include -I.
+#Kernel 2.4.31
+CFLAGS += -DMODVERSIONS -DEXPORT_SYMTAB -include $(KSRC)/include/linux/modversions.h
+#Kernel 2.4.20
+#CFLAGS += -D__NO_VERSION__ -DEXPORT_SYMTAB 
+#CFLAGS += -DENABLE_DOT11D
+SMP := $(shell $(CC) $(MODCFLAGS) -E -dM $(CONFIG_FILE) | \
+   grep CONFIG_SMP | awk '{print $$3}')
+ifneq ($(SMP),1)
+   SMP := 0
+endif
+ifeq ($(SMP),1)
+   CFLAGS    += -D__SMP__
+endif
+
+#CFLAGS += -DJOHN_NOCPY
+
+OBJS := ${patsubst %.c, %.o, ${wildcard *.c}}
+all:${OBJS} ieee80211_crypt-rsl.o michael_mic-rsl.o aes-rsl.o ieee80211_crypt_wep-rsl.o ieee80211_crypt_tkip-rsl.o ieee80211_crypt_ccmp-rsl.o crypto-rsl.o ieee80211-rsl.o
+
+ieee80211_crypt-rsl.o: ieee80211_crypt.o
+	mv $^ $@	
+
+michael_mic-rsl.o: michael_mic.o
+	mv $^ $@
+
+aes-rsl.o: aes.o
+	mv $^ $@
+
+ieee80211_crypt_wep-rsl.o: ieee80211_crypt_wep.o
+	mv $^ $@
+
+ieee80211_crypt_tkip-rsl.o: ieee80211_crypt_tkip.o
+	mv $^ $@
+
+ieee80211_crypt_ccmp-rsl.o: ieee80211_crypt_ccmp.o
+	mv $^ $@
+
+crypto-rsl.o: arc4.o api.o autoload.o cipher.o compress.o digest.o scatterwalk.o proc.o
+	$(LD) -r $^ -o $@
+
+ieee80211-rsl.o: ieee80211_rx.o ieee80211_tx.o ieee80211_wx.o ieee80211_module.o ieee80211_softmac_wx.o ieee80211_softmac.o rtl819x_HTProc.o rtl819x_TSProc.o rtl819x_BAProc.o dot11d.o
+	$(LD) -r $^ -o $@
+install:
+	rm -fr $(MODDESTDIR)
+	mkdir -p $(MODDESTDIR)
+	@install -p -m 644 ieee80211_crypt-rsl.o $(MODDESTDIR)
+	@install -p -m 644 crypto-rsl.o $(MODDESTDIR)
+	@install -p -m 644 michael_mic-rsl.o $(MODDESTDIR)
+	@install -p -m 644 aes-rsl.o $(MODDESTDIR)
+	@install -p -m 644 ieee80211_crypt_wep-rsl.o $(MODDESTDIR)
+	@install -p -m 644 ieee80211_crypt_tkip-rsl.o $(MODDESTDIR)
+	@install -p -m 644 ieee80211_crypt_ccmp-rsl.o $(MODDESTDIR)
+	@install -p -m 644 ieee80211-rsl.o $(MODDESTDIR)
+	/sbin/depmod -a ${shell uname -r}
+
+uninstall:
+	rm -fr $(MODDESTDIR)
+	/sbin/depmod -a ${shell uname -r}
+
+endif
+
+.PHONY: clean
+clean:
+	rm -fr *.mod.c *.mod *.o .*.cmd *.mod.* *.ko *.o *~
+	rm -rf .tmp_versions
+	rm -rf Module.symvers
diff --git a/drivers/staging/rtl8192u/ieee80211/aes.c b/drivers/staging/rtl8192u/ieee80211/aes.c
new file mode 100644
index 0000000..21ed66d
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/aes.c
@@ -0,0 +1,469 @@
+/* 
+ * Cryptographic API.
+ *
+ * AES Cipher Algorithm.
+ *
+ * Based on Brian Gladman's code.
+ *
+ * Linux developers:
+ *  Alexander Kjeldaas <astor at fast.no>
+ *  Herbert Valerio Riedel <hvr at hvrlab.org>
+ *  Kyle McMartin <kyle at debian.org>
+ *  Adam J. Richter <adam at yggdrasil.com> (conversion to 2.5 API).
+ *
+ * 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.
+ *
+ * ---------------------------------------------------------------------------
+ * Copyright (c) 2002, Dr Brian Gladman <brg at gladman.me.uk>, Worcester, UK.
+ * All rights reserved.
+ *
+ * LICENSE TERMS
+ *
+ * The free distribution and use of this software in both source and binary
+ * form is allowed (with or without changes) provided that:
+ *
+ *   1. distributions of this source code include the above copyright
+ *      notice, this list of conditions and the following disclaimer;
+ *
+ *   2. distributions in binary form include the above copyright
+ *      notice, this list of conditions and the following disclaimer
+ *      in the documentation and/or other associated materials;
+ *
+ *   3. the copyright holder's name is not used to endorse products
+ *      built using this software without specific written permission.
+ *
+ * ALTERNATIVELY, provided that this notice is retained in full, this product
+ * may be distributed under the terms of the GNU General Public License (GPL),
+ * in which case the provisions of the GPL apply INSTEAD OF those given above.
+ *
+ * DISCLAIMER
+ *
+ * This software is provided 'as is' with no explicit or implied warranties
+ * in respect of its properties, including, but not limited to, correctness
+ * and/or fitness for purpose.
+ * ---------------------------------------------------------------------------
+ */
+
+/* Some changes from the Gladman version:
+    s/RIJNDAEL(e_key)/E_KEY/g
+    s/RIJNDAEL(d_key)/D_KEY/g
+*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+//#include <linux/crypto.h>
+#include "rtl_crypto.h"
+#include <asm/byteorder.h>
+
+#define AES_MIN_KEY_SIZE	16
+#define AES_MAX_KEY_SIZE	32
+
+#define AES_BLOCK_SIZE		16
+
+static inline 
+u32 generic_rotr32 (const u32 x, const unsigned bits)
+{
+	const unsigned n = bits % 32;
+	return (x >> n) | (x << (32 - n));
+}
+
+static inline 
+u32 generic_rotl32 (const u32 x, const unsigned bits)
+{
+	const unsigned n = bits % 32;
+	return (x << n) | (x >> (32 - n));
+}
+
+#define rotl generic_rotl32
+#define rotr generic_rotr32
+
+/*
+ * #define byte(x, nr) ((unsigned char)((x) >> (nr*8))) 
+ */
+inline static u8
+byte(const u32 x, const unsigned n)
+{
+	return x >> (n << 3);
+}
+
+#define u32_in(x) le32_to_cpu(*(const u32 *)(x))
+#define u32_out(to, from) (*(u32 *)(to) = cpu_to_le32(from))
+
+struct aes_ctx {
+	int key_length;
+	u32 E[60];
+	u32 D[60];
+};
+
+#define E_KEY ctx->E
+#define D_KEY ctx->D
+
+static u8 pow_tab[256] __initdata;
+static u8 log_tab[256] __initdata;
+static u8 sbx_tab[256] __initdata;
+static u8 isb_tab[256] __initdata;
+static u32 rco_tab[10];
+static u32 ft_tab[4][256];
+static u32 it_tab[4][256];
+
+static u32 fl_tab[4][256];
+static u32 il_tab[4][256];
+
+static inline u8 __init
+f_mult (u8 a, u8 b)
+{
+	u8 aa = log_tab[a], cc = aa + log_tab[b];
+
+	return pow_tab[cc + (cc < aa ? 1 : 0)];
+}
+
+#define ff_mult(a,b)    (a && b ? f_mult(a, b) : 0)
+
+#define f_rn(bo, bi, n, k)					\
+    bo[n] =  ft_tab[0][byte(bi[n],0)] ^				\
+             ft_tab[1][byte(bi[(n + 1) & 3],1)] ^		\
+             ft_tab[2][byte(bi[(n + 2) & 3],2)] ^		\
+             ft_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n)
+
+#define i_rn(bo, bi, n, k)					\
+    bo[n] =  it_tab[0][byte(bi[n],0)] ^				\
+             it_tab[1][byte(bi[(n + 3) & 3],1)] ^		\
+             it_tab[2][byte(bi[(n + 2) & 3],2)] ^		\
+             it_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n)
+
+#define ls_box(x)				\
+    ( fl_tab[0][byte(x, 0)] ^			\
+      fl_tab[1][byte(x, 1)] ^			\
+      fl_tab[2][byte(x, 2)] ^			\
+      fl_tab[3][byte(x, 3)] )
+
+#define f_rl(bo, bi, n, k)					\
+    bo[n] =  fl_tab[0][byte(bi[n],0)] ^				\
+             fl_tab[1][byte(bi[(n + 1) & 3],1)] ^		\
+             fl_tab[2][byte(bi[(n + 2) & 3],2)] ^		\
+             fl_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n)
+
+#define i_rl(bo, bi, n, k)					\
+    bo[n] =  il_tab[0][byte(bi[n],0)] ^				\
+             il_tab[1][byte(bi[(n + 3) & 3],1)] ^		\
+             il_tab[2][byte(bi[(n + 2) & 3],2)] ^		\
+             il_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n)
+
+static void __init
+gen_tabs (void)
+{
+	u32 i, t;
+	u8 p, q;
+
+	/* log and power tables for GF(2**8) finite field with
+	   0x011b as modular polynomial - the simplest primitive
+	   root is 0x03, used here to generate the tables */
+
+	for (i = 0, p = 1; i < 256; ++i) {
+		pow_tab[i] = (u8) p;
+		log_tab[p] = (u8) i;
+
+		p ^= (p << 1) ^ (p & 0x80 ? 0x01b : 0);
+	}
+
+	log_tab[1] = 0;
+
+	for (i = 0, p = 1; i < 10; ++i) {
+		rco_tab[i] = p;
+
+		p = (p << 1) ^ (p & 0x80 ? 0x01b : 0);
+	}
+
+	for (i = 0; i < 256; ++i) {
+		p = (i ? pow_tab[255 - log_tab[i]] : 0);
+		q = ((p >> 7) | (p << 1)) ^ ((p >> 6) | (p << 2));
+		p ^= 0x63 ^ q ^ ((q >> 6) | (q << 2));
+		sbx_tab[i] = p;
+		isb_tab[p] = (u8) i;
+	}
+
+	for (i = 0; i < 256; ++i) {
+		p = sbx_tab[i];
+
+		t = p;
+		fl_tab[0][i] = t;
+		fl_tab[1][i] = rotl (t, 8);
+		fl_tab[2][i] = rotl (t, 16);
+		fl_tab[3][i] = rotl (t, 24);
+
+		t = ((u32) ff_mult (2, p)) |
+		    ((u32) p << 8) |
+		    ((u32) p << 16) | ((u32) ff_mult (3, p) << 24);
+
+		ft_tab[0][i] = t;
+		ft_tab[1][i] = rotl (t, 8);
+		ft_tab[2][i] = rotl (t, 16);
+		ft_tab[3][i] = rotl (t, 24);
+
+		p = isb_tab[i];
+
+		t = p;
+		il_tab[0][i] = t;
+		il_tab[1][i] = rotl (t, 8);
+		il_tab[2][i] = rotl (t, 16);
+		il_tab[3][i] = rotl (t, 24);
+
+		t = ((u32) ff_mult (14, p)) |
+		    ((u32) ff_mult (9, p) << 8) |
+		    ((u32) ff_mult (13, p) << 16) |
+		    ((u32) ff_mult (11, p) << 24);
+
+		it_tab[0][i] = t;
+		it_tab[1][i] = rotl (t, 8);
+		it_tab[2][i] = rotl (t, 16);
+		it_tab[3][i] = rotl (t, 24);
+	}
+}
+
+#define star_x(x) (((x) & 0x7f7f7f7f) << 1) ^ ((((x) & 0x80808080) >> 7) * 0x1b)
+
+#define imix_col(y,x)       \
+    u   = star_x(x);        \
+    v   = star_x(u);        \
+    w   = star_x(v);        \
+    t   = w ^ (x);          \
+   (y)  = u ^ v ^ w;        \
+   (y) ^= rotr(u ^ t,  8) ^ \
+          rotr(v ^ t, 16) ^ \
+          rotr(t,24)
+
+/* initialise the key schedule from the user supplied key */
+
+#define loop4(i)                                    \
+{   t = rotr(t,  8); t = ls_box(t) ^ rco_tab[i];    \
+    t ^= E_KEY[4 * i];     E_KEY[4 * i + 4] = t;    \
+    t ^= E_KEY[4 * i + 1]; E_KEY[4 * i + 5] = t;    \
+    t ^= E_KEY[4 * i + 2]; E_KEY[4 * i + 6] = t;    \
+    t ^= E_KEY[4 * i + 3]; E_KEY[4 * i + 7] = t;    \
+}
+
+#define loop6(i)                                    \
+{   t = rotr(t,  8); t = ls_box(t) ^ rco_tab[i];    \
+    t ^= E_KEY[6 * i];     E_KEY[6 * i + 6] = t;    \
+    t ^= E_KEY[6 * i + 1]; E_KEY[6 * i + 7] = t;    \
+    t ^= E_KEY[6 * i + 2]; E_KEY[6 * i + 8] = t;    \
+    t ^= E_KEY[6 * i + 3]; E_KEY[6 * i + 9] = t;    \
+    t ^= E_KEY[6 * i + 4]; E_KEY[6 * i + 10] = t;   \
+    t ^= E_KEY[6 * i + 5]; E_KEY[6 * i + 11] = t;   \
+}
+
+#define loop8(i)                                    \
+{   t = rotr(t,  8); ; t = ls_box(t) ^ rco_tab[i];  \
+    t ^= E_KEY[8 * i];     E_KEY[8 * i + 8] = t;    \
+    t ^= E_KEY[8 * i + 1]; E_KEY[8 * i + 9] = t;    \
+    t ^= E_KEY[8 * i + 2]; E_KEY[8 * i + 10] = t;   \
+    t ^= E_KEY[8 * i + 3]; E_KEY[8 * i + 11] = t;   \
+    t  = E_KEY[8 * i + 4] ^ ls_box(t);    \
+    E_KEY[8 * i + 12] = t;                \
+    t ^= E_KEY[8 * i + 5]; E_KEY[8 * i + 13] = t;   \
+    t ^= E_KEY[8 * i + 6]; E_KEY[8 * i + 14] = t;   \
+    t ^= E_KEY[8 * i + 7]; E_KEY[8 * i + 15] = t;   \
+}
+
+static int
+aes_set_key(void *ctx_arg, const u8 *in_key, unsigned int key_len, u32 *flags)
+{
+	struct aes_ctx *ctx = ctx_arg;
+	u32 i, t, u, v, w;
+
+	if (key_len != 16 && key_len != 24 && key_len != 32) {
+		*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+		return -EINVAL;
+	}
+
+	ctx->key_length = key_len;
+
+	E_KEY[0] = u32_in (in_key);
+	E_KEY[1] = u32_in (in_key + 4);
+	E_KEY[2] = u32_in (in_key + 8);
+	E_KEY[3] = u32_in (in_key + 12);
+
+	switch (key_len) {
+	case 16:
+		t = E_KEY[3];
+		for (i = 0; i < 10; ++i)
+			loop4 (i);
+		break;
+
+	case 24:
+		E_KEY[4] = u32_in (in_key + 16);
+		t = E_KEY[5] = u32_in (in_key + 20);
+		for (i = 0; i < 8; ++i)
+			loop6 (i);
+		break;
+
+	case 32:
+		E_KEY[4] = u32_in (in_key + 16);
+		E_KEY[5] = u32_in (in_key + 20);
+		E_KEY[6] = u32_in (in_key + 24);
+		t = E_KEY[7] = u32_in (in_key + 28);
+		for (i = 0; i < 7; ++i)
+			loop8 (i);
+		break;
+	}
+
+	D_KEY[0] = E_KEY[0];
+	D_KEY[1] = E_KEY[1];
+	D_KEY[2] = E_KEY[2];
+	D_KEY[3] = E_KEY[3];
+
+	for (i = 4; i < key_len + 24; ++i) {
+		imix_col (D_KEY[i], E_KEY[i]);
+	}
+
+	return 0;
+}
+
+/* encrypt a block of text */
+
+#define f_nround(bo, bi, k) \
+    f_rn(bo, bi, 0, k);     \
+    f_rn(bo, bi, 1, k);     \
+    f_rn(bo, bi, 2, k);     \
+    f_rn(bo, bi, 3, k);     \
+    k += 4
+
+#define f_lround(bo, bi, k) \
+    f_rl(bo, bi, 0, k);     \
+    f_rl(bo, bi, 1, k);     \
+    f_rl(bo, bi, 2, k);     \
+    f_rl(bo, bi, 3, k)
+
+static void aes_encrypt(void *ctx_arg, u8 *out, const u8 *in)
+{
+	const struct aes_ctx *ctx = ctx_arg;
+	u32 b0[4], b1[4];
+	const u32 *kp = E_KEY + 4;
+
+	b0[0] = u32_in (in) ^ E_KEY[0];
+	b0[1] = u32_in (in + 4) ^ E_KEY[1];
+	b0[2] = u32_in (in + 8) ^ E_KEY[2];
+	b0[3] = u32_in (in + 12) ^ E_KEY[3];
+
+	if (ctx->key_length > 24) {
+		f_nround (b1, b0, kp);
+		f_nround (b0, b1, kp);
+	}
+
+	if (ctx->key_length > 16) {
+		f_nround (b1, b0, kp);
+		f_nround (b0, b1, kp);
+	}
+
+	f_nround (b1, b0, kp);
+	f_nround (b0, b1, kp);
+	f_nround (b1, b0, kp);
+	f_nround (b0, b1, kp);
+	f_nround (b1, b0, kp);
+	f_nround (b0, b1, kp);
+	f_nround (b1, b0, kp);
+	f_nround (b0, b1, kp);
+	f_nround (b1, b0, kp);
+	f_lround (b0, b1, kp);
+
+	u32_out (out, b0[0]);
+	u32_out (out + 4, b0[1]);
+	u32_out (out + 8, b0[2]);
+	u32_out (out + 12, b0[3]);
+}
+
+/* decrypt a block of text */
+
+#define i_nround(bo, bi, k) \
+    i_rn(bo, bi, 0, k);     \
+    i_rn(bo, bi, 1, k);     \
+    i_rn(bo, bi, 2, k);     \
+    i_rn(bo, bi, 3, k);     \
+    k -= 4
+
+#define i_lround(bo, bi, k) \
+    i_rl(bo, bi, 0, k);     \
+    i_rl(bo, bi, 1, k);     \
+    i_rl(bo, bi, 2, k);     \
+    i_rl(bo, bi, 3, k)
+
+static void aes_decrypt(void *ctx_arg, u8 *out, const u8 *in)
+{
+	const struct aes_ctx *ctx = ctx_arg;
+	u32 b0[4], b1[4];
+	const int key_len = ctx->key_length;
+	const u32 *kp = D_KEY + key_len + 20;
+
+	b0[0] = u32_in (in) ^ E_KEY[key_len + 24];
+	b0[1] = u32_in (in + 4) ^ E_KEY[key_len + 25];
+	b0[2] = u32_in (in + 8) ^ E_KEY[key_len + 26];
+	b0[3] = u32_in (in + 12) ^ E_KEY[key_len + 27];
+
+	if (key_len > 24) {
+		i_nround (b1, b0, kp);
+		i_nround (b0, b1, kp);
+	}
+
+	if (key_len > 16) {
+		i_nround (b1, b0, kp);
+		i_nround (b0, b1, kp);
+	}
+
+	i_nround (b1, b0, kp);
+	i_nround (b0, b1, kp);
+	i_nround (b1, b0, kp);
+	i_nround (b0, b1, kp);
+	i_nround (b1, b0, kp);
+	i_nround (b0, b1, kp);
+	i_nround (b1, b0, kp);
+	i_nround (b0, b1, kp);
+	i_nround (b1, b0, kp);
+	i_lround (b0, b1, kp);
+
+	u32_out (out, b0[0]);
+	u32_out (out + 4, b0[1]);
+	u32_out (out + 8, b0[2]);
+	u32_out (out + 12, b0[3]);
+}
+
+
+static struct crypto_alg aes_alg = {
+	.cra_name		=	"aes",
+	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
+	.cra_blocksize		=	AES_BLOCK_SIZE,
+	.cra_ctxsize		=	sizeof(struct aes_ctx),
+	.cra_module		=	THIS_MODULE,
+	.cra_list		=	LIST_HEAD_INIT(aes_alg.cra_list),
+	.cra_u			=	{
+		.cipher = {
+			.cia_min_keysize	=	AES_MIN_KEY_SIZE,
+			.cia_max_keysize	=	AES_MAX_KEY_SIZE,
+			.cia_setkey	   	= 	aes_set_key,
+			.cia_encrypt	 	=	aes_encrypt,
+			.cia_decrypt	  	=	aes_decrypt
+		}
+	}
+};
+
+static int __init aes_init(void)
+{
+	gen_tabs();
+	return crypto_register_alg(&aes_alg);
+}
+
+static void __exit aes_fini(void)
+{
+	crypto_unregister_alg(&aes_alg);
+}
+
+module_init(aes_init);
+module_exit(aes_fini);
+
+MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm");
+MODULE_LICENSE("Dual BSD/GPL");
+
diff --git a/drivers/staging/rtl8192u/ieee80211/api.c b/drivers/staging/rtl8192u/ieee80211/api.c
new file mode 100644
index 0000000..a3bd63b
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/api.c
@@ -0,0 +1,246 @@
+/*
+ * Scatterlist Cryptographic API.
+ *
+ * Copyright (c) 2002 James Morris <jmorris at intercode.com.au>
+ * Copyright (c) 2002 David S. Miller (davem at redhat.com)
+ *
+ * Portions derived from Cryptoapi, by Alexander Kjeldaas <astor at 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.
+ *
+ */
+#include "kmap_types.h"
+
+#include <linux/init.h>
+#include <linux/module.h>
+//#include <linux/crypto.h>
+#include "rtl_crypto.h"
+#include <linux/errno.h>
+#include <linux/rwsem.h>
+#include <linux/slab.h>
+#include "internal.h"
+
+LIST_HEAD(crypto_alg_list);
+DECLARE_RWSEM(crypto_alg_sem);
+
+static inline int crypto_alg_get(struct crypto_alg *alg)
+{
+	return try_inc_mod_count(alg->cra_module);
+}
+
+static inline void crypto_alg_put(struct crypto_alg *alg)
+{
+	if (alg->cra_module)
+		__MOD_DEC_USE_COUNT(alg->cra_module);
+}
+
+struct crypto_alg *crypto_alg_lookup(const char *name)
+{
+	struct crypto_alg *q, *alg = NULL;
+
+	if (!name)
+		return NULL;
+	
+	down_read(&crypto_alg_sem);
+	
+	list_for_each_entry(q, &crypto_alg_list, cra_list) {
+		if (!(strcmp(q->cra_name, name))) {
+			if (crypto_alg_get(q))
+				alg = q;
+			break;
+		}
+	}
+	
+	up_read(&crypto_alg_sem);
+	return alg;
+}
+
+static int crypto_init_flags(struct crypto_tfm *tfm, u32 flags)
+{
+	tfm->crt_flags = 0;
+	
+	switch (crypto_tfm_alg_type(tfm)) {
+	case CRYPTO_ALG_TYPE_CIPHER:
+		return crypto_init_cipher_flags(tfm, flags);
+		
+	case CRYPTO_ALG_TYPE_DIGEST:
+		return crypto_init_digest_flags(tfm, flags);
+		
+	case CRYPTO_ALG_TYPE_COMPRESS:
+		return crypto_init_compress_flags(tfm, flags);
+	
+	default:
+		break;
+	}
+	
+	BUG();
+	return -EINVAL;
+}
+
+static int crypto_init_ops(struct crypto_tfm *tfm)
+{
+	switch (crypto_tfm_alg_type(tfm)) {
+	case CRYPTO_ALG_TYPE_CIPHER:
+		return crypto_init_cipher_ops(tfm);
+		
+	case CRYPTO_ALG_TYPE_DIGEST:
+		return crypto_init_digest_ops(tfm);
+		
+	case CRYPTO_ALG_TYPE_COMPRESS:
+		return crypto_init_compress_ops(tfm);
+	
+	default:
+		break;
+	}
+	
+	BUG();
+	return -EINVAL;
+}
+
+static void crypto_exit_ops(struct crypto_tfm *tfm)
+{
+	switch (crypto_tfm_alg_type(tfm)) {
+	case CRYPTO_ALG_TYPE_CIPHER:
+		crypto_exit_cipher_ops(tfm);
+		break;
+		
+	case CRYPTO_ALG_TYPE_DIGEST:
+		crypto_exit_digest_ops(tfm);
+		break;
+		
+	case CRYPTO_ALG_TYPE_COMPRESS:
+		crypto_exit_compress_ops(tfm);
+		break;
+	
+	default:
+		BUG();
+		
+	}
+}
+
+struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags)
+{
+	struct crypto_tfm *tfm = NULL;
+	struct crypto_alg *alg;
+
+	alg = crypto_alg_mod_lookup(name);
+	if (alg == NULL)
+		goto out;
+	
+	tfm = kmalloc(sizeof(*tfm) + alg->cra_ctxsize, GFP_KERNEL);
+	if (tfm == NULL)
+		goto out_put;
+
+	memset(tfm, 0, sizeof(*tfm) + alg->cra_ctxsize);
+	
+	tfm->__crt_alg = alg;
+	
+	if (crypto_init_flags(tfm, flags))
+		goto out_free_tfm;
+		
+	if (crypto_init_ops(tfm)) {
+		crypto_exit_ops(tfm);
+		goto out_free_tfm;
+	}
+
+	goto out;
+
+out_free_tfm:
+	kfree(tfm);
+	tfm = NULL;
+out_put:
+	crypto_alg_put(alg);
+out:
+	return tfm;
+}
+
+void crypto_free_tfm(struct crypto_tfm *tfm)
+{
+	struct crypto_alg *alg = tfm->__crt_alg;
+	int size = sizeof(*tfm) + alg->cra_ctxsize;
+
+	crypto_exit_ops(tfm);
+	crypto_alg_put(alg);
+	memset(tfm, 0, size);
+	kfree(tfm);
+}
+
+int crypto_register_alg(struct crypto_alg *alg)
+{
+	int ret = 0;
+	struct crypto_alg *q;
+	
+	down_write(&crypto_alg_sem);
+	
+	list_for_each_entry(q, &crypto_alg_list, cra_list) {
+		if (!(strcmp(q->cra_name, alg->cra_name))) {
+			ret = -EEXIST;
+			goto out;
+		}
+	}
+	
+	list_add_tail(&alg->cra_list, &crypto_alg_list);
+out:	
+	up_write(&crypto_alg_sem);
+	return ret;
+}
+
+int crypto_unregister_alg(struct crypto_alg *alg)
+{
+	int ret = -ENOENT;
+	struct crypto_alg *q;
+	
+	BUG_ON(!alg->cra_module);
+	
+	down_write(&crypto_alg_sem);
+	list_for_each_entry(q, &crypto_alg_list, cra_list) {
+		if (alg == q) {
+			list_del(&alg->cra_list);
+			ret = 0;
+			goto out;
+		}
+	}
+out:	
+	up_write(&crypto_alg_sem);
+	return ret;
+}
+
+int crypto_alg_available(const char *name, u32 flags)
+{
+	int ret = 0;
+	struct crypto_alg *alg = crypto_alg_mod_lookup(name);
+	
+	if (alg) {
+		crypto_alg_put(alg);
+		ret = 1;
+	}
+	
+	return ret;
+}
+
+static int __init init_crypto(void)
+{
+	printk(KERN_INFO "Initializing Cryptographic API\n");
+	crypto_init_proc();
+	return 0;
+}
+
+__initcall(init_crypto);
+
+/*
+EXPORT_SYMBOL_GPL(crypto_register_alg);
+EXPORT_SYMBOL_GPL(crypto_unregister_alg);
+EXPORT_SYMBOL_GPL(crypto_alloc_tfm);
+EXPORT_SYMBOL_GPL(crypto_free_tfm);
+EXPORT_SYMBOL_GPL(crypto_alg_available);
+*/
+
+EXPORT_SYMBOL_NOVERS(crypto_register_alg);
+EXPORT_SYMBOL_NOVERS(crypto_unregister_alg);
+EXPORT_SYMBOL_NOVERS(crypto_alloc_tfm);
+EXPORT_SYMBOL_NOVERS(crypto_free_tfm);
+EXPORT_SYMBOL_NOVERS(crypto_alg_available);
diff --git a/drivers/staging/rtl8192u/ieee80211/arc4.c b/drivers/staging/rtl8192u/ieee80211/arc4.c
new file mode 100644
index 0000000..95e24f9
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/arc4.c
@@ -0,0 +1,103 @@
+/* 
+ * Cryptographic API
+ *
+ * ARC4 Cipher Algorithm
+ *
+ * Jon Oberheide <jon at 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((unsigned int)++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 at oberheide.org>");
diff --git a/drivers/staging/rtl8192u/ieee80211/autoload.c b/drivers/staging/rtl8192u/ieee80211/autoload.c
new file mode 100644
index 0000000..148132e
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/autoload.c
@@ -0,0 +1,40 @@
+/*
+ * Cryptographic API.
+ *
+ * Algorithm autoloader.
+ *
+ * Copyright (c) 2002 James Morris <jmorris at 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.
+ *
+ */
+#include "kmap_types.h"
+
+#include <linux/kernel.h>
+//#include <linux/crypto.h>
+#include "rtl_crypto.h"
+#include <linux/string.h>
+#include <linux/kmod.h>
+#include "internal.h"
+
+/*
+ * A far more intelligent version of this is planned.  For now, just
+ * try an exact match on the name of the algorithm.
+ */
+void crypto_alg_autoload(const char *name)
+{
+	request_module(name);
+}
+
+struct crypto_alg *crypto_alg_mod_lookup(const char *name)
+{
+	struct crypto_alg *alg = crypto_alg_lookup(name);
+	if (alg == NULL) {
+		crypto_alg_autoload(name);
+		alg = crypto_alg_lookup(name);
+	}
+	return alg;
+}
diff --git a/drivers/staging/rtl8192u/ieee80211/cipher.c b/drivers/staging/rtl8192u/ieee80211/cipher.c
new file mode 100644
index 0000000..ca1bc79
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/cipher.c
@@ -0,0 +1,299 @@
+/*
+ * Cryptographic API.
+ *
+ * Cipher operations.
+ *
+ * Copyright (c) 2002 James Morris <jmorris at 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.
+ *
+ */
+#include <linux/kernel.h>
+//#include <linux/crypto.h>
+#include "rtl_crypto.h"
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <asm/scatterlist.h>
+#include "internal.h"
+#include "scatterwalk.h"
+
+typedef void (cryptfn_t)(void *, u8 *, const u8 *);
+typedef void (procfn_t)(struct crypto_tfm *, u8 *,
+                        u8*, cryptfn_t, int enc, void *, int);
+
+static inline void xor_64(u8 *a, const u8 *b)
+{
+	((u32 *)a)[0] ^= ((u32 *)b)[0];
+	((u32 *)a)[1] ^= ((u32 *)b)[1];
+}
+
+static inline void xor_128(u8 *a, const u8 *b)
+{
+	((u32 *)a)[0] ^= ((u32 *)b)[0];
+	((u32 *)a)[1] ^= ((u32 *)b)[1];
+	((u32 *)a)[2] ^= ((u32 *)b)[2];
+	((u32 *)a)[3] ^= ((u32 *)b)[3];
+}
+
+
+/* 
+ * Generic encrypt/decrypt wrapper for ciphers, handles operations across
+ * multiple page boundaries by using temporary blocks.  In user context,
+ * the kernel is given a chance to schedule us once per block.
+ */
+static int crypt(struct crypto_tfm *tfm,
+		 struct scatterlist *dst,
+		 struct scatterlist *src,
+                 unsigned int nbytes, cryptfn_t crfn,
+                 procfn_t prfn, int enc, void *info)
+{
+	struct scatter_walk walk_in, walk_out;
+	const unsigned int bsize = crypto_tfm_alg_blocksize(tfm);
+	u8 tmp_src[bsize];
+	u8 tmp_dst[bsize];
+
+	if (!nbytes)
+		return 0;
+
+	if (nbytes % bsize) {
+		tfm->crt_flags |= CRYPTO_TFM_RES_BAD_BLOCK_LEN;
+		return -EINVAL;
+	}
+
+	scatterwalk_start(&walk_in, src);
+	scatterwalk_start(&walk_out, dst);
+
+	for(;;) {
+		u8 *src_p, *dst_p;
+		int in_place;
+
+		scatterwalk_map(&walk_in, 0);
+		scatterwalk_map(&walk_out, 1);
+		src_p = scatterwalk_whichbuf(&walk_in, bsize, tmp_src);
+		dst_p = scatterwalk_whichbuf(&walk_out, bsize, tmp_dst);
+		in_place = scatterwalk_samebuf(&walk_in, &walk_out,
+					       src_p, dst_p);
+
+		nbytes -= bsize;
+
+		scatterwalk_copychunks(src_p, &walk_in, bsize, 0);
+
+		prfn(tfm, dst_p, src_p, crfn, enc, info, in_place);
+
+		scatterwalk_done(&walk_in, 0, nbytes);
+
+		scatterwalk_copychunks(dst_p, &walk_out, bsize, 1);
+		scatterwalk_done(&walk_out, 1, nbytes);
+
+		if (!nbytes)
+			return 0;
+
+		crypto_yield(tfm);
+	}
+}
+
+static void cbc_process(struct crypto_tfm *tfm, u8 *dst, u8 *src,
+			cryptfn_t fn, int enc, void *info, int in_place)
+{
+	u8 *iv = info;
+	
+	/* Null encryption */
+	if (!iv)
+		return;
+		
+	if (enc) {
+		tfm->crt_u.cipher.cit_xor_block(iv, src);
+		fn(crypto_tfm_ctx(tfm), dst, iv);
+		memcpy(iv, dst, crypto_tfm_alg_blocksize(tfm));
+	} else {
+		u8 stack[in_place ? crypto_tfm_alg_blocksize(tfm) : 0];
+		u8 *buf = in_place ? stack : dst;
+
+		fn(crypto_tfm_ctx(tfm), buf, src);
+		tfm->crt_u.cipher.cit_xor_block(buf, iv);
+		memcpy(iv, src, crypto_tfm_alg_blocksize(tfm));
+		if (buf != dst)
+			memcpy(dst, buf, crypto_tfm_alg_blocksize(tfm));
+	}
+}
+
+static void ecb_process(struct crypto_tfm *tfm, u8 *dst, u8 *src,
+			cryptfn_t fn, int enc, void *info, int in_place)
+{
+	fn(crypto_tfm_ctx(tfm), dst, src);
+}
+
+static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
+{
+	struct cipher_alg *cia = &tfm->__crt_alg->cra_cipher;
+	
+	if (keylen < cia->cia_min_keysize || keylen > cia->cia_max_keysize) {
+		tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+		return -EINVAL;
+	} else
+		return cia->cia_setkey(crypto_tfm_ctx(tfm), key, keylen,
+		                       &tfm->crt_flags);
+}
+
+static int ecb_encrypt(struct crypto_tfm *tfm,
+		       struct scatterlist *dst,
+                       struct scatterlist *src, unsigned int nbytes)
+{
+	return crypt(tfm, dst, src, nbytes,
+	             tfm->__crt_alg->cra_cipher.cia_encrypt,
+	             ecb_process, 1, NULL);
+}
+
+static int ecb_decrypt(struct crypto_tfm *tfm,
+                       struct scatterlist *dst,
+                       struct scatterlist *src,
+		       unsigned int nbytes)
+{
+	return crypt(tfm, dst, src, nbytes,
+	             tfm->__crt_alg->cra_cipher.cia_decrypt,
+	             ecb_process, 1, NULL);
+}
+
+static int cbc_encrypt(struct crypto_tfm *tfm,
+                       struct scatterlist *dst,
+                       struct scatterlist *src,
+		       unsigned int nbytes)
+{
+	return crypt(tfm, dst, src, nbytes,
+	             tfm->__crt_alg->cra_cipher.cia_encrypt,
+	             cbc_process, 1, tfm->crt_cipher.cit_iv);
+}
+
+static int cbc_encrypt_iv(struct crypto_tfm *tfm,
+                          struct scatterlist *dst,
+                          struct scatterlist *src,
+                          unsigned int nbytes, u8 *iv)
+{
+	return crypt(tfm, dst, src, nbytes,
+	             tfm->__crt_alg->cra_cipher.cia_encrypt,
+	             cbc_process, 1, iv);
+}
+
+static int cbc_decrypt(struct crypto_tfm *tfm,
+                       struct scatterlist *dst,
+                       struct scatterlist *src,
+		       unsigned int nbytes)
+{
+	return crypt(tfm, dst, src, nbytes,
+	             tfm->__crt_alg->cra_cipher.cia_decrypt,
+	             cbc_process, 0, tfm->crt_cipher.cit_iv);
+}
+
+static int cbc_decrypt_iv(struct crypto_tfm *tfm,
+                          struct scatterlist *dst,
+                          struct scatterlist *src,
+                          unsigned int nbytes, u8 *iv)
+{
+	return crypt(tfm, dst, src, nbytes,
+	             tfm->__crt_alg->cra_cipher.cia_decrypt,
+	             cbc_process, 0, iv);
+}
+
+static int nocrypt(struct crypto_tfm *tfm,
+                   struct scatterlist *dst,
+                   struct scatterlist *src,
+		   unsigned int nbytes)
+{
+	return -ENOSYS;
+}
+
+static int nocrypt_iv(struct crypto_tfm *tfm,
+                      struct scatterlist *dst,
+                      struct scatterlist *src,
+                      unsigned int nbytes, u8 *iv)
+{
+	return -ENOSYS;
+}
+
+int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags)
+{
+	u32 mode = flags & CRYPTO_TFM_MODE_MASK;
+	
+	tfm->crt_cipher.cit_mode = mode ? mode : CRYPTO_TFM_MODE_ECB;
+	if (flags & CRYPTO_TFM_REQ_WEAK_KEY)
+		tfm->crt_flags = CRYPTO_TFM_REQ_WEAK_KEY;
+	
+	return 0;
+}
+
+int crypto_init_cipher_ops(struct crypto_tfm *tfm)
+{
+	int ret = 0;
+	struct cipher_tfm *ops = &tfm->crt_cipher;
+
+	ops->cit_setkey = setkey;
+
+	switch (tfm->crt_cipher.cit_mode) {
+	case CRYPTO_TFM_MODE_ECB:
+		ops->cit_encrypt = ecb_encrypt;
+		ops->cit_decrypt = ecb_decrypt;
+		break;
+		
+	case CRYPTO_TFM_MODE_CBC:
+		ops->cit_encrypt = cbc_encrypt;
+		ops->cit_decrypt = cbc_decrypt;
+		ops->cit_encrypt_iv = cbc_encrypt_iv;
+		ops->cit_decrypt_iv = cbc_decrypt_iv;
+		break;
+		
+	case CRYPTO_TFM_MODE_CFB:
+		ops->cit_encrypt = nocrypt;
+		ops->cit_decrypt = nocrypt;
+		ops->cit_encrypt_iv = nocrypt_iv;
+		ops->cit_decrypt_iv = nocrypt_iv;
+		break;
+	
+	case CRYPTO_TFM_MODE_CTR:
+		ops->cit_encrypt = nocrypt;
+		ops->cit_decrypt = nocrypt;
+		ops->cit_encrypt_iv = nocrypt_iv;
+		ops->cit_decrypt_iv = nocrypt_iv;
+		break;
+
+	default:
+		BUG();
+	}
+	
+	if (ops->cit_mode == CRYPTO_TFM_MODE_CBC) {
+	    	
+	    	switch (crypto_tfm_alg_blocksize(tfm)) {
+	    	case 8:
+	    		ops->cit_xor_block = xor_64;
+	    		break;
+	    		
+	    	case 16:
+	    		ops->cit_xor_block = xor_128;
+	    		break;
+	    		
+	    	default:
+	    		printk(KERN_WARNING "%s: block size %u not supported\n",
+	    		       crypto_tfm_alg_name(tfm),
+	    		       crypto_tfm_alg_blocksize(tfm));
+	    		ret = -EINVAL;
+	    		goto out;
+	    	}
+	    	
+		ops->cit_ivsize = crypto_tfm_alg_blocksize(tfm);
+	    	ops->cit_iv = kmalloc(ops->cit_ivsize, GFP_KERNEL);
+		if (ops->cit_iv == NULL)
+			ret = -ENOMEM;
+	}
+
+out:	
+	return ret;
+}
+
+void crypto_exit_cipher_ops(struct crypto_tfm *tfm)
+{
+	if (tfm->crt_cipher.cit_iv)
+		kfree(tfm->crt_cipher.cit_iv);
+}
diff --git a/drivers/staging/rtl8192u/ieee80211/compress.c b/drivers/staging/rtl8192u/ieee80211/compress.c
new file mode 100644
index 0000000..a62c442
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/compress.c
@@ -0,0 +1,64 @@
+/*
+ * Cryptographic API.
+ *
+ * Compression operations.
+ *
+ * Copyright (c) 2002 James Morris <jmorris at 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.
+ *
+ */
+#include <linux/types.h>
+//#include <linux/crypto.h>
+#include "rtl_crypto.h"
+#include <linux/errno.h>
+#include <asm/scatterlist.h>
+#include <linux/string.h>
+#include "internal.h"
+
+static int crypto_compress(struct crypto_tfm *tfm,
+                            const u8 *src, unsigned int slen,
+                            u8 *dst, unsigned int *dlen)
+{
+	return tfm->__crt_alg->cra_compress.coa_compress(crypto_tfm_ctx(tfm),
+	                                                 src, slen, dst,
+	                                                 dlen);
+}
+
+static int crypto_decompress(struct crypto_tfm *tfm,
+                             const u8 *src, unsigned int slen,
+                             u8 *dst, unsigned int *dlen)
+{
+	return tfm->__crt_alg->cra_compress.coa_decompress(crypto_tfm_ctx(tfm),
+	                                                   src, slen, dst,
+	                                                   dlen);
+}
+
+int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags)
+{
+	return flags ? -EINVAL : 0;
+}
+
+int crypto_init_compress_ops(struct crypto_tfm *tfm)
+{
+	int ret = 0;
+	struct compress_tfm *ops = &tfm->crt_compress;
+	
+	ret = tfm->__crt_alg->cra_compress.coa_init(crypto_tfm_ctx(tfm));
+	if (ret)
+		goto out;
+
+	ops->cot_compress = crypto_compress;
+	ops->cot_decompress = crypto_decompress;
+	
+out:
+	return ret;
+}
+
+void crypto_exit_compress_ops(struct crypto_tfm *tfm)
+{
+	tfm->__crt_alg->cra_compress.coa_exit(crypto_tfm_ctx(tfm));
+}
diff --git a/drivers/staging/rtl8192u/ieee80211/crypto_compat.h b/drivers/staging/rtl8192u/ieee80211/crypto_compat.h
new file mode 100644
index 0000000..7abc7f7
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/crypto_compat.h
@@ -0,0 +1,90 @@
+/*
+ * Header file to maintain compatibility among different kernel versions.
+ *
+ * Copyright (c) 2004-2006  <lawrence_wang at realsil.com.cn>
+ *
+ * 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/crypto.h>
+
+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_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);
+}
+
+#if 0 
+/*
+ *	crypto_free_tfm - Free crypto transform
+ *	@tfm: Transform to free
+ *
+ *	crypto_free_tfm() frees up the transform and any associated resources,
+ *	then drops the refcount on the associated algorithm.
+ */
+void crypto_free_tfm(struct crypto_tfm *tfm)
+{
+	struct crypto_alg *alg;
+	int size;
+
+	if (unlikely(!tfm))
+		return;
+
+	alg = tfm->__crt_alg;
+	size = sizeof(*tfm) + alg->cra_ctxsize;
+
+	if (alg->cra_exit)
+		alg->cra_exit(tfm);
+	crypto_exit_ops(tfm);
+	crypto_mod_put(alg);
+	memset(tfm, 0, size);
+	kfree(tfm);
+}
+
+#endif
+#if 1
+ struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags)
+{
+	struct crypto_tfm *tfm = NULL;
+	int err;
+	printk("call crypto_alloc_tfm!!!\n");
+	do {
+		struct crypto_alg *alg;
+
+		alg = crypto_alg_mod_lookup(name, 0, CRYPTO_ALG_ASYNC);
+		err = PTR_ERR(alg);
+		if (IS_ERR(alg))
+			continue;
+
+		tfm = __crypto_alloc_tfm(alg, flags);
+		err = 0;
+		if (IS_ERR(tfm)) {
+			crypto_mod_put(alg);
+			err = PTR_ERR(tfm);
+			tfm = NULL;
+		}
+	} while (err == -EAGAIN && !signal_pending(current));
+
+	return tfm;
+}
+#endif
+//EXPORT_SYMBOL_GPL(crypto_alloc_tfm);
+//EXPORT_SYMBOL_GPL(crypto_free_tfm);
+
+
diff --git a/drivers/staging/rtl8192u/ieee80211/digest.c b/drivers/staging/rtl8192u/ieee80211/digest.c
new file mode 100644
index 0000000..1dfb443
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/digest.c
@@ -0,0 +1,108 @@
+/*
+ * Cryptographic API.
+ *
+ * Digest operations.
+ *
+ * Copyright (c) 2002 James Morris <jmorris at 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.
+ *
+ */
+//#include <linux/crypto.h>
+#include "rtl_crypto.h"
+#include <linux/mm.h>
+#include <linux/errno.h>
+#include <linux/highmem.h>
+#include <asm/scatterlist.h>
+#include "internal.h"
+
+static void init(struct crypto_tfm *tfm)
+{
+	tfm->__crt_alg->cra_digest.dia_init(crypto_tfm_ctx(tfm));
+}
+
+static void update(struct crypto_tfm *tfm,
+                   struct scatterlist *sg, unsigned int nsg)
+{
+	unsigned int i;
+
+	for (i = 0; i < nsg; i++) {
+
+		struct page *pg = sg[i].page;
+		unsigned int offset = sg[i].offset;
+		unsigned int l = sg[i].length;
+
+		do {
+			unsigned int bytes_from_page = min(l, ((unsigned int)
+							   (PAGE_SIZE)) - 
+							   offset);
+			char *p = crypto_kmap(pg, 0) + offset;
+
+			tfm->__crt_alg->cra_digest.dia_update
+					(crypto_tfm_ctx(tfm), p,
+					 bytes_from_page);
+			crypto_kunmap(p, 0);
+			crypto_yield(tfm);
+			offset = 0;
+			pg++;
+			l -= bytes_from_page;
+		} while (l > 0);
+	}
+}
+
+static void final(struct crypto_tfm *tfm, u8 *out)
+{
+	tfm->__crt_alg->cra_digest.dia_final(crypto_tfm_ctx(tfm), out);
+}
+
+static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
+{
+	u32 flags;
+	if (tfm->__crt_alg->cra_digest.dia_setkey == NULL)
+		return -ENOSYS;
+	return tfm->__crt_alg->cra_digest.dia_setkey(crypto_tfm_ctx(tfm),
+						     key, keylen, &flags);
+}
+
+static void digest(struct crypto_tfm *tfm,
+                   struct scatterlist *sg, unsigned int nsg, u8 *out)
+{
+	unsigned int i;
+
+	tfm->crt_digest.dit_init(tfm);
+		
+	for (i = 0; i < nsg; i++) {
+		char *p = crypto_kmap(sg[i].page, 0) + sg[i].offset;
+		tfm->__crt_alg->cra_digest.dia_update(crypto_tfm_ctx(tfm),
+		                                      p, sg[i].length);
+		crypto_kunmap(p, 0);
+		crypto_yield(tfm);
+	}
+	crypto_digest_final(tfm, out);
+}
+
+int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags)
+{
+	return flags ? -EINVAL : 0;
+}
+
+int crypto_init_digest_ops(struct crypto_tfm *tfm)
+{
+	struct digest_tfm *ops = &tfm->crt_digest;
+	
+	ops->dit_init	= init;
+	ops->dit_update	= update;
+	ops->dit_final	= final;
+	ops->dit_digest	= digest;
+	ops->dit_setkey	= setkey;
+	
+	return crypto_alloc_hmac_block(tfm);
+}
+
+void crypto_exit_digest_ops(struct crypto_tfm *tfm)
+{
+	crypto_free_hmac_block(tfm);
+}
diff --git a/drivers/staging/rtl8192u/ieee80211/dot11d.c b/drivers/staging/rtl8192u/ieee80211/dot11d.c
new file mode 100644
index 0000000..81851c5
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/dot11d.c
@@ -0,0 +1,239 @@
+#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);
+#if 0
+	if(!pDot11dInfo->bEnabled)
+		return;
+#endif
+	// 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;
+
+	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");
+			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");
+			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;
+}
+
+
+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;
+}
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
+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);
+#else
+EXPORT_SYMBOL_NOVERS(Dot11d_Init);
+EXPORT_SYMBOL_NOVERS(Dot11d_Reset);
+EXPORT_SYMBOL_NOVERS(Dot11d_UpdateCountryIe);
+EXPORT_SYMBOL_NOVERS(DOT11D_GetMaxTxPwrInDbm);
+EXPORT_SYMBOL_NOVERS(DOT11D_ScanComplete);
+EXPORT_SYMBOL_NOVERS(IsLegalChannel);
+EXPORT_SYMBOL_NOVERS(ToLegalChannel);
+#endif
+
+#endif
diff --git a/drivers/staging/rtl8192u/ieee80211/dot11d.h b/drivers/staging/rtl8192u/ieee80211/dot11d.h
new file mode 100644
index 0000000..defba0c
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/dot11d.h
@@ -0,0 +1,102 @@
+#ifndef __INC_DOT11D_H
+#define __INC_DOT11D_H
+
+#ifdef ENABLE_DOT11D
+#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
+);
+#endif //ENABLE_DOT11D
+#endif // #ifndef __INC_DOT11D_H
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211.h b/drivers/staging/rtl8192u/ieee80211/ieee80211.h
new file mode 100644
index 0000000..dc49831
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211.h
@@ -0,0 +1,2796 @@
+/*
+ * 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 at cc.hut.fi>
+ * Copyright (c) 2002-2003, Jouni Malinen <jkmaline at cc.hut.fi>
+ *
+ * Adaption to a generic IEEE 802.11 stack by James Ketrenos
+ * <jketreno at linux.intel.com>
+ * Copyright (c) 2004, Intel Corporation
+ *
+ * Modified for Realtek's wi-fi cards by Andrea Merello
+ * <andreamrl at 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>
+
+#include <linux/delay.h>
+#include <linux/wireless.h>
+
+#include "rtl819x_HT.h"
+#include "rtl819x_BA.h"
+#include "rtl819x_TS.h"
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
+#ifndef bool
+typedef enum{false = 0, true} bool;
+#endif
+#endif
+
+#ifndef IW_MODE_MONITOR
+#define IW_MODE_MONITOR 6
+#endif
+
+#ifndef IWEVCUSTOM
+#define IWEVCUSTOM 0x8c02
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+#ifndef __bitwise
+#define __bitwise __attribute__((bitwise))
+#endif
+typedef __u16  __le16;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,27))
+struct iw_spy_data{
+	/* --- Standard spy support --- */
+	int 			spy_number;
+	u_char 			spy_address[IW_MAX_SPY][ETH_ALEN];
+	struct iw_quality	spy_stat[IW_MAX_SPY];
+	/* --- Enhanced spy support (event) */
+	struct iw_quality	spy_thr_low; /* Low threshold */
+	struct iw_quality	spy_thr_high; /* High threshold */
+	u_char			spy_thr_under[IW_MAX_SPY];
+}; 
+#endif
+#endif
+
+#ifndef container_of
+/**
+ * container_of - cast a member of a structure out to the containing structure
+ *
+ * @ptr:        the pointer to the member.
+ * @type:       the type of the container struct this is embedded in.
+ * @member:     the name of the member within the struct.
+ *
+ */
+#define container_of(ptr, type, member) ({                      \
+        const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
+        (type *)( (char *)__mptr - offsetof(type,member) );})
+#endif
+
+#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
+
+/* added for rtl819x tx procedure */
+#define MAX_QUEUE_SIZE		0x10
+
+//
+// 8190 queue mapping
+//
+#define BK_QUEUE                               0
+#define BE_QUEUE                               1
+#define VI_QUEUE                               2
+#define VO_QUEUE                               3
+#define HCCA_QUEUE                             4
+#define TXCMD_QUEUE                            5
+#define MGNT_QUEUE                             6
+#define HIGH_QUEUE                             7
+#define BEACON_QUEUE                           8
+
+#define LOW_QUEUE                              BE_QUEUE
+#define NORMAL_QUEUE                           MGNT_QUEUE
+
+//added by amy for ps
+#define SWRF_TIMEOUT				50
+
+//added by amy for LEAP related
+#define IE_CISCO_FLAG_POSITION		0x08	// Flag byte: byte 8, numbered from 0.
+#define SUPPORT_CKIP_MIC			0x08	// bit3
+#define SUPPORT_CKIP_PK			0x10	// bit4
+/* defined for skb cb field */
+/* At most 28 byte */
+typedef struct cb_desc {
+        /* Tx Desc Related flags (8-9) */
+	u8 bLastIniPkt:1;
+	u8 bCmdOrInit:1;
+        u8 bFirstSeg:1;
+        u8 bLastSeg:1;
+        u8 bEncrypt:1;
+        u8 bTxDisableRateFallBack:1;
+        u8 bTxUseDriverAssingedRate:1;
+        u8 bHwSec:1; //indicate whether use Hw security. WB
+
+        u8 reserved1;
+
+        /* Tx Firmware Relaged flags (10-11)*/
+        u8 bCTSEnable:1;
+        u8 bRTSEnable:1;
+        u8 bUseShortGI:1;
+        u8 bUseShortPreamble:1;
+        u8 bTxEnableFwCalcDur:1;
+        u8 bAMPDUEnable:1;
+        u8 bRTSSTBC:1;
+        u8 RTSSC:1;
+
+        u8 bRTSBW:1;
+        u8 bPacketBW:1;
+	u8 bRTSUseShortPreamble:1;
+	u8 bRTSUseShortGI:1;
+	u8 bMulticast:1;
+	u8 bBroadcast:1;
+        //u8 reserved2:2;
+        u8 drv_agg_enable:1;
+        u8 reserved2:1;
+
+        /* Tx Desc related element(12-19) */
+        u8 rata_index;
+        u8 queue_index;
+        //u8 reserved3;
+        //u8 reserved4;
+        u16 txbuf_size;
+        //u8 reserved5;
+	u8 RATRIndex;
+        u8 reserved6;
+        u8 reserved7;
+        u8 reserved8;
+
+        /* Tx firmware related element(20-27) */
+        u8 data_rate;
+        u8 rts_rate;
+        u8 ampdu_factor;
+        u8 ampdu_density;
+        //u8 reserved9;
+        //u8 reserved10;
+        //u8 reserved11;
+        u8 DrvAggrNum;
+	u16 pkt_size;
+        u8 reserved12;
+}cb_desc, *pcb_desc;
+                        
+/*--------------------------Define -------------------------------------------*/
+#define MGN_1M                  0x02
+#define MGN_2M                  0x04
+#define MGN_5_5M                0x0b
+#define MGN_11M                 0x16
+
+#define MGN_6M                  0x0c
+#define MGN_9M                  0x12
+#define MGN_12M                 0x18
+#define MGN_18M                 0x24
+#define MGN_24M                 0x30
+#define MGN_36M                 0x48
+#define MGN_48M                 0x60
+#define MGN_54M                 0x6c
+
+#define MGN_MCS0                0x80
+#define MGN_MCS1                0x81
+#define MGN_MCS2                0x82
+#define MGN_MCS3                0x83
+#define MGN_MCS4                0x84
+#define MGN_MCS5                0x85
+#define MGN_MCS6                0x86
+#define MGN_MCS7                0x87
+#define MGN_MCS8                0x88
+#define MGN_MCS9                0x89
+#define MGN_MCS10               0x8a
+#define MGN_MCS11               0x8b
+#define MGN_MCS12               0x8c
+#define MGN_MCS13               0x8d
+#define MGN_MCS14               0x8e
+#define MGN_MCS15               0x8f
+
+//----------------------------------------------------------------------------
+//		802.11 Management frame Reason Code field
+//----------------------------------------------------------------------------
+enum	_ReasonCode{
+	unspec_reason	= 0x1,
+	auth_not_valid	= 0x2,
+	deauth_lv_ss	= 0x3, 
+	inactivity		= 0x4,
+	ap_overload 	= 0x5, 
+	class2_err		= 0x6,
+	class3_err		= 0x7, 
+	disas_lv_ss 	= 0x8,
+	asoc_not_auth	= 0x9,
+
+	//----MIC_CHECK
+	mic_failure 	= 0xe,
+	//----END MIC_CHECK
+
+	// Reason code defined in 802.11i D10.0 p.28.
+	invalid_IE		= 0x0d,
+	four_way_tmout	= 0x0f,
+	two_way_tmout	= 0x10,
+	IE_dismatch 	= 0x11,
+	invalid_Gcipher = 0x12,
+	invalid_Pcipher = 0x13,
+	invalid_AKMP	= 0x14,
+	unsup_RSNIEver = 0x15,
+	invalid_RSNIE	= 0x16,
+	auth_802_1x_fail= 0x17,
+	ciper_reject		= 0x18,
+
+	// Reason code defined in 7.3.1.7, 802.1e D13.0, p.42. Added by Annie, 2005-11-15.
+	QoS_unspec		= 0x20, // 32
+	QAP_bandwidth	= 0x21, // 33
+	poor_condition	= 0x22, // 34
+	no_facility 	= 0x23, // 35
+							// Where is 36???
+	req_declined	= 0x25, // 37
+	invalid_param	= 0x26, // 38
+	req_not_honored= 0x27,	// 39
+	TS_not_created	= 0x2F, // 47
+	DL_not_allowed	= 0x30, // 48
+	dest_not_exist	= 0x31, // 49
+	dest_not_QSTA	= 0x32, // 50
+};
+
+
+
+#define aSifsTime	 ((priv->ieee80211->current_network.mode == IEEE_A)||(priv->ieee80211->current_network.mode == IEEE_N_24G)||(priv->ieee80211->current_network.mode == IEEE_N_5G))? 16 : 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
+
+#define MAX_IE_LEN  0xff
+
+// added for kernel conflict 
+#define ieee80211_crypt_deinit_entries 	ieee80211_crypt_deinit_entries_rsl
+#define ieee80211_crypt_deinit_handler 	ieee80211_crypt_deinit_handler_rsl
+#define ieee80211_crypt_delayed_deinit 	ieee80211_crypt_delayed_deinit_rsl
+#define ieee80211_register_crypto_ops  	ieee80211_register_crypto_ops_rsl
+#define ieee80211_unregister_crypto_ops ieee80211_unregister_crypto_ops_rsl
+#define ieee80211_get_crypto_ops 	ieee80211_get_crypto_ops_rsl
+
+#define ieee80211_ccmp_null		ieee80211_ccmp_null_rsl
+
+#define ieee80211_tkip_null		ieee80211_tkip_null_rsl
+
+#define ieee80211_wep_null		ieee80211_wep_null_rsl
+
+#define free_ieee80211          	free_ieee80211_rsl
+#define alloc_ieee80211        		alloc_ieee80211_rsl
+
+#define ieee80211_rx 			ieee80211_rx_rsl
+#define ieee80211_rx_mgt		ieee80211_rx_mgt_rsl
+
+#define ieee80211_get_beacon		ieee80211_get_beacon_rsl
+#define ieee80211_wake_queue		ieee80211_wake_queue_rsl
+#define ieee80211_stop_queue		ieee80211_stop_queue_rsl
+#define ieee80211_reset_queue		ieee80211_reset_queue_rsl
+#define ieee80211_softmac_stop_protocol	ieee80211_softmac_stop_protocol_rsl
+#define ieee80211_softmac_start_protocol ieee80211_softmac_start_protocol_rsl
+#define ieee80211_is_shortslot		ieee80211_is_shortslot_rsl
+#define ieee80211_is_54g		ieee80211_is_54g_rsl
+#define ieee80211_wpa_supplicant_ioctl	ieee80211_wpa_supplicant_ioctl_rsl
+#define ieee80211_ps_tx_ack		ieee80211_ps_tx_ack_rsl
+#define ieee80211_softmac_xmit		ieee80211_softmac_xmit_rsl
+#define ieee80211_stop_send_beacons	ieee80211_stop_send_beacons_rsl
+#define notify_wx_assoc_event		notify_wx_assoc_event_rsl
+#define SendDisassociation		SendDisassociation_rsl
+#define ieee80211_disassociate		ieee80211_disassociate_rsl
+#define ieee80211_start_send_beacons	ieee80211_start_send_beacons_rsl
+#define ieee80211_stop_scan		ieee80211_stop_scan_rsl
+#define ieee80211_send_probe_requests	ieee80211_send_probe_requests_rsl
+#define ieee80211_softmac_scan_syncro	ieee80211_softmac_scan_syncro_rsl
+#define ieee80211_start_scan_syncro	ieee80211_start_scan_syncro_rsl
+
+#define ieee80211_wx_get_essid		ieee80211_wx_get_essid_rsl
+#define ieee80211_wx_set_essid		ieee80211_wx_set_essid_rsl
+#define ieee80211_wx_set_rate		ieee80211_wx_set_rate_rsl
+#define ieee80211_wx_get_rate		ieee80211_wx_get_rate_rsl
+#define ieee80211_wx_set_wap		ieee80211_wx_set_wap_rsl
+#define ieee80211_wx_get_wap		ieee80211_wx_get_wap_rsl
+#define ieee80211_wx_set_mode		ieee80211_wx_set_mode_rsl 
+#define ieee80211_wx_get_mode		ieee80211_wx_get_mode_rsl
+#define ieee80211_wx_set_scan		ieee80211_wx_set_scan_rsl
+#define ieee80211_wx_get_freq		ieee80211_wx_get_freq_rsl
+#define ieee80211_wx_set_freq		ieee80211_wx_set_freq_rsl
+#define ieee80211_wx_set_rawtx		ieee80211_wx_set_rawtx_rsl
+#define ieee80211_wx_get_name		ieee80211_wx_get_name_rsl
+#define ieee80211_wx_set_power		ieee80211_wx_set_power_rsl
+#define ieee80211_wx_get_power		ieee80211_wx_get_power_rsl
+#define ieee80211_wlan_frequencies	ieee80211_wlan_frequencies_rsl
+#define ieee80211_wx_set_rts		ieee80211_wx_set_rts_rsl
+#define ieee80211_wx_get_rts		ieee80211_wx_get_rts_rsl
+
+#define ieee80211_txb_free		ieee80211_txb_free_rsl
+
+#define ieee80211_wx_set_gen_ie		ieee80211_wx_set_gen_ie_rsl
+#define ieee80211_wx_get_scan		ieee80211_wx_get_scan_rsl
+#define ieee80211_wx_set_encode		ieee80211_wx_set_encode_rsl
+#define ieee80211_wx_get_encode		ieee80211_wx_get_encode_rsl
+#if WIRELESS_EXT >= 18
+#define ieee80211_wx_set_mlme		ieee80211_wx_set_mlme_rsl
+#define ieee80211_wx_set_auth		ieee80211_wx_set_auth_rsl
+#define ieee80211_wx_set_encode_ext	ieee80211_wx_set_encode_ext_rsl
+#define ieee80211_wx_get_encode_ext	ieee80211_wx_get_encode_ext_rsl
+#endif
+
+
+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_rsl(unsigned int msecs)
+{
+         unsigned long timeout = MSECS(msecs) + 1;
+ 
+         while (timeout) {
+                 set_current_state(TASK_INTERRUPTIBLE);
+                 timeout = schedule_timeout(timeout);
+         }
+         return timeout;
+}
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,31))
+static inline void msleep(unsigned int msecs)
+{
+         unsigned long timeout = MSECS(msecs) + 1;
+ 
+         while (timeout) {
+                 set_current_state(TASK_UNINTERRUPTIBLE);
+                 timeout = schedule_timeout(timeout);
+         }
+}
+#endif
+#else
+#define MSECS(t) msecs_to_jiffies(t)
+#define msleep_interruptible_rsl  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_1ADDR_LEN 10
+#define IEEE80211_2ADDR_LEN 16
+#define IEEE80211_3ADDR_LEN 24
+#define IEEE80211_4ADDR_LEN 30
+#define IEEE80211_FCS_LEN    4
+#define IEEE80211_HLEN                  (IEEE80211_4ADDR_LEN)
+#define IEEE80211_FRAME_LEN             (IEEE80211_DATA_LEN + IEEE80211_HLEN)
+#define IEEE80211_MGMT_HDR_LEN 24
+#define IEEE80211_DATA_HDR3_LEN 24
+#define IEEE80211_DATA_HDR4_LEN 30
+
+#define MIN_FRAG_THRESHOLD     256U
+#define MAX_FRAG_THRESHOLD     2346U
+
+
+/* Frame control field constants */
+#define IEEE80211_FCTL_VERS		0x0003
+#define IEEE80211_FCTL_FTYPE		0x000c
+#define IEEE80211_FCTL_STYPE		0x00f0
+#define IEEE80211_FCTL_FRAMETYPE	0x00fc
+#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
+#define IEEE80211_STYPE_BLOCKACK   0x0094
+
+/* 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
+
+/* QOS control */
+#define IEEE80211_QCTL_TID              0x000F
+
+#define	FC_QOS_BIT					BIT7
+#define IsDataFrame(pdu)			( ((pdu[0] & 0x0C)==0x08) ? true : false )
+#define	IsLegacyDataFrame(pdu)	(IsDataFrame(pdu) && (!(pdu[0]&FC_QOS_BIT)) )	
+//added by wb. Is this right?
+#define IsQoSDataFrame(pframe)  ((*(u16*)pframe&(IEEE80211_STYPE_QOS_DATA|IEEE80211_FTYPE_DATA)) == (IEEE80211_STYPE_QOS_DATA|IEEE80211_FTYPE_DATA))
+#define Frame_Order(pframe)     (*(u16*)pframe&IEEE80211_FCTL_ORDER)
+#define SN_LESS(a, b)		(((a-b)&0x800)!=0)
+#define SN_EQUAL(a, b)	(a == b)
+#define MAX_DEV_ADDR_SIZE 8
+typedef enum _ACT_CATEGORY{
+        ACT_CAT_QOS = 1,
+        ACT_CAT_DLS = 2,
+        ACT_CAT_BA  = 3,
+        ACT_CAT_HT  = 7,
+        ACT_CAT_WMM = 17,
+} ACT_CATEGORY, *PACT_CATEGORY;
+
+typedef enum _TS_ACTION{
+        ACT_ADDTSREQ = 0,
+        ACT_ADDTSRSP = 1,
+        ACT_DELTS    = 2,
+        ACT_SCHEDULE = 3,
+} TS_ACTION, *PTS_ACTION;
+
+typedef enum _BA_ACTION{
+        ACT_ADDBAREQ = 0,
+        ACT_ADDBARSP = 1,
+        ACT_DELBA    = 2,
+} BA_ACTION, *PBA_ACTION;
+
+typedef enum _InitialGainOpType{
+	IG_Backup=0,
+	IG_Restore,
+	IG_Max
+}InitialGainOpType;
+
+/* debug macros */
+#define CONFIG_IEEE80211_DEBUG
+#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: " fmt, ## args); } while (0)
+//wb added to debug out data buf
+//if you want print DATA buffer related BA, please set ieee80211_debug_level to DATA|BA
+#define IEEE80211_DEBUG_DATA(level, data, datalen)	\
+	do{ if ((ieee80211_debug_level & (level)) == (level))	\
+		{ 	\
+			int i;					\
+			u8* pdata = (u8*) data;			\
+			printk(KERN_DEBUG "ieee80211: %s()\n", __FUNCTION__);	\
+			for(i=0; i<(int)(datalen); i++)			\
+			{						\
+				printk("%2x ", pdata[i]);		\
+				if ((i+1)%16 == 0) printk("\n");	\
+			}				\
+			printk("\n");			\
+		}					\
+	} while (0)		
+#else
+#define IEEE80211_DEBUG(level, fmt, args...) do {} while (0)
+#define IEEE80211_DEBUG_DATA(level, data, datalen) do {} while(0)
+#endif	/* CONFIG_IEEE80211_DEBUG */
+
+/* debug macros not dependent on CONFIG_IEEE80211_DEBUG */
+
+#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]
+
+/*
+ * 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_DL_HT		   (1<<10)  //HT
+#define IEEE80211_DL_BA		   (1<<11)  //ba
+#define IEEE80211_DL_TS		   (1<<12)  //TS
+#define IEEE80211_DL_QOS           (1<<13)
+#define IEEE80211_DL_REORDER	   (1<<14)
+#define IEEE80211_DL_IOT	   (1<<15)
+#define IEEE80211_DL_IPS	   (1<<16)
+#define IEEE80211_DL_TRACE	   (1<<29)  //trace function, need to user net_ratelimit() together in order not to print too much to the screen
+#define IEEE80211_DL_DATA	   (1<<30)   //use this flag to control whether print data buf out.
+#define IEEE80211_DL_ERR	   (1<<31)   //always open
+#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)
+#define IEEE80211_DEBUG_QOS(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_QOS, f, ## a)
+
+#ifdef CONFIG_IEEE80211_DEBUG
+/* Added by Annie, 2005-11-22. */
+#define MAX_STR_LEN     64
+/* I want to see ASCII 33 to 126 only. Otherwise, I print '?'. Annie, 2005-11-22.*/
+#define PRINTABLE(_ch)  (_ch>'!' && _ch<'~')    
+#define IEEE80211_PRINT_STR(_Comp, _TitleString, _Ptr, _Len)                            	\
+                        if((_Comp) & level)   							\
+                        {                                                                       \
+                                int             __i;                                            \
+                                u8  buffer[MAX_STR_LEN];                                    	\
+                                int length = (_Len<MAX_STR_LEN)? _Len : (MAX_STR_LEN-1) ;  	\
+                                memset(buffer, 0, MAX_STR_LEN);                      		\
+                                memcpy(buffer, (u8 *)_Ptr, length );            		\
+                                for( __i=0; __i<MAX_STR_LEN; __i++ )                            \
+                                {                                                               \
+                                     if( !PRINTABLE(buffer[__i]) )   buffer[__i] = '?';     	\
+                                }                                                               \
+                                buffer[length] = '\0';                                          \
+                                printk("Rtl819x: ");                                         	\
+                                printk(_TitleString);                                         \
+                                printk(": %d, <%s>\n", _Len, buffer);                         \
+                        }
+#else
+#define IEEE80211_PRINT_STR(_Comp, _TitleString, _Ptr, _Len)  do {} while (0)
+#endif
+
+#include <linux/netdevice.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_VERS(fc) ((fc) & IEEE80211_FCTL_VERS)
+#define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE)
+#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE)
+
+#define WLAN_FC_GET_FRAMETYPE(fc) ((fc) & IEEE80211_FCTL_FRAMETYPE)
+#define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG)
+#define WLAN_GET_SEQ_SEQ(seq)  (((seq) & IEEE80211_SCTL_SEQ) >> 4)
+
+/* Authentication algorithms */
+#define WLAN_AUTH_OPEN 0
+#define WLAN_AUTH_SHARED_KEY 1
+#define WLAN_AUTH_LEAP 2
+
+#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_SPECTRUM_MGMT (1<<8)
+#define WLAN_CAPABILITY_QOS (1<<9)
+#define WLAN_CAPABILITY_SHORT_SLOT (1<<10)
+#define WLAN_CAPABILITY_DSSS_OFDM (1<<13)
+
+/* 802.11g ERP information element */
+#define WLAN_ERP_NON_ERP_PRESENT (1<<0)
+#define WLAN_ERP_USE_PROTECTION (1<<1)
+#define WLAN_ERP_BARKER_PREAMBLE (1<<2)
+
+/* Status codes */
+enum ieee80211_statuscode {
+        WLAN_STATUS_SUCCESS = 0,
+        WLAN_STATUS_UNSPECIFIED_FAILURE = 1,
+        WLAN_STATUS_CAPS_UNSUPPORTED = 10,
+        WLAN_STATUS_REASSOC_NO_ASSOC = 11,
+        WLAN_STATUS_ASSOC_DENIED_UNSPEC = 12,
+        WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG = 13,
+        WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION = 14,
+        WLAN_STATUS_CHALLENGE_FAIL = 15,
+        WLAN_STATUS_AUTH_TIMEOUT = 16,
+        WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA = 17,
+        WLAN_STATUS_ASSOC_DENIED_RATES = 18,
+        /* 802.11b */
+        WLAN_STATUS_ASSOC_DENIED_NOSHORTPREAMBLE = 19,
+        WLAN_STATUS_ASSOC_DENIED_NOPBCC = 20,
+        WLAN_STATUS_ASSOC_DENIED_NOAGILITY = 21,
+        /* 802.11h */
+        WLAN_STATUS_ASSOC_DENIED_NOSPECTRUM = 22,
+        WLAN_STATUS_ASSOC_REJECTED_BAD_POWER = 23,
+        WLAN_STATUS_ASSOC_REJECTED_BAD_SUPP_CHAN = 24,
+        /* 802.11g */
+        WLAN_STATUS_ASSOC_DENIED_NOSHORTTIME = 25,
+        WLAN_STATUS_ASSOC_DENIED_NODSSSOFDM = 26,
+        /* 802.11i */
+        WLAN_STATUS_INVALID_IE = 40,
+        WLAN_STATUS_INVALID_GROUP_CIPHER = 41,
+        WLAN_STATUS_INVALID_PAIRWISE_CIPHER = 42,
+        WLAN_STATUS_INVALID_AKMP = 43,
+        WLAN_STATUS_UNSUPP_RSN_VERSION = 44,
+        WLAN_STATUS_INVALID_RSN_IE_CAP = 45,
+        WLAN_STATUS_CIPHER_SUITE_REJECTED = 46,
+};
+
+/* Reason codes */
+enum ieee80211_reasoncode {
+        WLAN_REASON_UNSPECIFIED = 1,
+        WLAN_REASON_PREV_AUTH_NOT_VALID = 2,
+        WLAN_REASON_DEAUTH_LEAVING = 3,
+        WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY = 4,
+        WLAN_REASON_DISASSOC_AP_BUSY = 5,
+        WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA = 6,
+        WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA = 7,
+        WLAN_REASON_DISASSOC_STA_HAS_LEFT = 8,
+        WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH = 9,
+        /* 802.11h */
+        WLAN_REASON_DISASSOC_BAD_POWER = 10,
+        WLAN_REASON_DISASSOC_BAD_SUPP_CHAN = 11,
+        /* 802.11i */
+        WLAN_REASON_INVALID_IE = 13,
+        WLAN_REASON_MIC_FAILURE = 14,
+        WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT = 15,
+        WLAN_REASON_GROUP_KEY_HANDSHAKE_TIMEOUT = 16,
+        WLAN_REASON_IE_DIFFERENT = 17,
+        WLAN_REASON_INVALID_GROUP_CIPHER = 18,
+        WLAN_REASON_INVALID_PAIRWISE_CIPHER = 19,
+        WLAN_REASON_INVALID_AKMP = 20,
+        WLAN_REASON_UNSUPP_RSN_VERSION = 21,
+        WLAN_REASON_INVALID_RSN_IE_CAP = 22,
+        WLAN_REASON_IEEE8021X_FAILED = 23,
+        WLAN_REASON_CIPHER_SUITE_REJECTED = 24,
+};
+
+#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
+
+
+/* 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
+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;
+};
+
+/* 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 {
+#if 1
+	u32 mac_time[2];
+	s8 rssi;
+	u8 signal;
+	u8 noise;
+	u16 rate; /* in 100 kbps */
+	u8 received_channel;
+	u8 control;
+	u8 mask;
+	u8 freq;
+	u16 len;
+	u64 tsf;
+	u32 beacon_time;
+	u8 nic_type;
+	u16       Length;
+	//      u8        DataRate;      // In 0.5 Mbps
+	u8        SignalQuality; // in 0-100 index. 
+	s32       RecvSignalPower; // Real power in dBm for this packet, no beautification and aggregation.
+	s8        RxPower; // in dBm Translate from PWdB
+	u8        SignalStrength; // in 0-100 index.
+	u16       bHwError:1;
+	u16       bCRC:1;
+	u16       bICV:1;
+	u16       bShortPreamble:1;
+	u16       Antenna:1;      //for rtl8185
+	u16       Decrypted:1;    //for rtl8185, rtl8187
+	u16       Wakeup:1;       //for rtl8185
+	u16       Reserved0:1;    //for rtl8185
+	u8        AGC;
+	u32       TimeStampLow;
+	u32       TimeStampHigh;
+	bool      bShift;
+	bool      bIsQosData;             // Added by Annie, 2005-12-22.
+	u8        UserPriority;
+
+	//1!!!!!!!!!!!!!!!!!!!!!!!!!!!
+	//1Attention Please!!!<11n or 8190 specific code should be put below this line>
+	//1!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+	u8        RxDrvInfoSize;
+	u8        RxBufShift;
+	bool      bIsAMPDU;
+	bool      bFirstMPDU;
+	bool      bContainHTC;
+	bool      RxIs40MHzPacket;
+	u32       RxPWDBAll;
+	u8        RxMIMOSignalStrength[4];        // in 0~100 index
+	s8        RxMIMOSignalQuality[2];
+	bool      bPacketMatchBSSID;
+	bool      bIsCCK;
+	bool      bPacketToSelf;
+	//added by amy
+	u8*       virtual_address;
+	u16          packetlength;              // Total packet length: Must equal to sum of all FragLength
+	u16          fraglength;                        // FragLength should equal to PacketLength in non-fragment case
+	u16          fragoffset;                        // Data offset for this fragment
+	u16          ntotalfrag;
+	bool      	  bisrxaggrsubframe;
+	bool		  bPacketBeacon;	//cosa add for rssi
+	bool		  bToSelfBA;		//cosa add for rssi
+	char 	  cck_adc_pwdb[4];	//cosa add for rx path selection
+	u16		  Seq_Num;
+#endif
+
+};
+
+/* 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_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_ENCRYPT       (1<<9)
+
+#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 SEC_ALG_NONE            0
+#define SEC_ALG_WEP             1
+#define SEC_ALG_TKIP            2
+#define SEC_ALG_CCMP            3
+
+#define WEP_KEYS 		4
+#define WEP_KEY_LEN		13
+#define SCM_KEY_LEN             32
+#define SCM_TEMPORAL_KEY_LENGTH 16
+
+struct ieee80211_security {
+	u16 active_key:2,
+            enabled:1,
+	    auth_mode:2,
+            auth_algo:4,
+            unicast_uses_group:1,
+	    encrypt:1;
+	u8 key_sizes[WEP_KEYS];
+	u8 keys[WEP_KEYS][SCM_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
+*/
+
+/* Management Frame Information Element Types */
+enum ieee80211_mfie {
+        MFIE_TYPE_SSID = 0,
+        MFIE_TYPE_RATES = 1,
+        MFIE_TYPE_FH_SET = 2,
+        MFIE_TYPE_DS_SET = 3,
+        MFIE_TYPE_CF_SET = 4,
+        MFIE_TYPE_TIM = 5,
+        MFIE_TYPE_IBSS_SET = 6,
+        MFIE_TYPE_COUNTRY = 7,
+        MFIE_TYPE_HOP_PARAMS = 8,
+        MFIE_TYPE_HOP_TABLE = 9,
+        MFIE_TYPE_REQUEST = 10,
+        MFIE_TYPE_CHALLENGE = 16,
+        MFIE_TYPE_POWER_CONSTRAINT = 32,
+        MFIE_TYPE_POWER_CAPABILITY = 33,
+        MFIE_TYPE_TPC_REQUEST = 34,
+        MFIE_TYPE_TPC_REPORT = 35,
+        MFIE_TYPE_SUPP_CHANNELS = 36,
+        MFIE_TYPE_CSA = 37,
+        MFIE_TYPE_MEASURE_REQUEST = 38,
+        MFIE_TYPE_MEASURE_REPORT = 39,
+        MFIE_TYPE_QUIET = 40,
+        MFIE_TYPE_IBSS_DFS = 41,
+        MFIE_TYPE_ERP = 42,
+        MFIE_TYPE_RSN = 48,
+        MFIE_TYPE_RATES_EX = 50,
+        MFIE_TYPE_HT_CAP= 45,
+	 MFIE_TYPE_HT_INFO= 61,
+	 MFIE_TYPE_AIRONET=133,
+        MFIE_TYPE_GENERIC = 221,
+        MFIE_TYPE_QOS_PARAMETER = 222,
+};
+
+/* Minimal header; can be used for passing 802.11 frames with sufficient
+ * information to determine what type of underlying data type is actually
+ * stored in the data. */
+struct ieee80211_hdr {
+        __le16 frame_ctl;
+        __le16 duration_id;
+        u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_1addr {
+        __le16 frame_ctl;
+        __le16 duration_id;
+        u8 addr1[ETH_ALEN];
+        u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_2addr {
+        __le16 frame_ctl;
+        __le16 duration_id;
+        u8 addr1[ETH_ALEN];
+        u8 addr2[ETH_ALEN];
+        u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_3addr {
+	__le16 frame_ctl;
+	__le16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 addr2[ETH_ALEN];
+	u8 addr3[ETH_ALEN];
+	__le16 seq_ctl;
+        u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_4addr {
+	__le16 frame_ctl;
+	__le16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 addr2[ETH_ALEN];
+	u8 addr3[ETH_ALEN];
+	__le16 seq_ctl;
+	u8 addr4[ETH_ALEN];
+        u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_3addrqos {
+	__le16 frame_ctl;
+	__le16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 addr2[ETH_ALEN];
+	u8 addr3[ETH_ALEN];
+	__le16 seq_ctl;
+        u8 payload[0];
+	__le16 qos_ctl;
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_4addrqos {
+	__le16 frame_ctl;
+	__le16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 addr2[ETH_ALEN];
+	u8 addr3[ETH_ALEN];
+	__le16 seq_ctl;
+	u8 addr4[ETH_ALEN];
+        u8 payload[0];
+	__le16 qos_ctl;
+} __attribute__ ((packed));
+
+struct ieee80211_info_element {
+	u8 id;
+	u8 len;
+	u8 data[0];
+} __attribute__ ((packed));
+
+struct ieee80211_authentication {
+	struct ieee80211_hdr_3addr header;
+	__le16 algorithm;
+	__le16 transaction;
+	__le16 status;
+	/*challenge*/
+	struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct ieee80211_disassoc {
+        struct ieee80211_hdr_3addr header;
+        __le16 reason;
+} __attribute__ ((packed));
+
+struct ieee80211_probe_request {
+	struct ieee80211_hdr_3addr header;
+	/* SSID, supported rates */
+        struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct ieee80211_probe_response {
+	struct ieee80211_hdr_3addr header;
+	u32 time_stamp[2];
+	__le16 beacon_interval;
+	__le16 capability;
+        /* SSID, supported rates, FH params, DS params,
+         * CF params, IBSS params, TIM (if beacon), RSN */
+        struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+/* Alias beacon for probe_response */
+#define ieee80211_beacon ieee80211_probe_response
+
+struct ieee80211_assoc_request_frame {
+	struct ieee80211_hdr_3addr header;
+	__le16 capability;
+	__le16 listen_interval;
+	/* SSID, supported rates, RSN */
+        struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct ieee80211_reassoc_request_frame {
+	struct ieee80211_hdr_3addr header;
+	__le16 capability;
+	__le16 listen_interval;
+	u8 current_ap[ETH_ALEN];
+	/* SSID, supported rates, RSN */
+        struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct ieee80211_assoc_response_frame {
+	struct ieee80211_hdr_3addr header;
+	__le16 capability;
+	__le16 status;
+	__le16 aid;
+	struct ieee80211_info_element info_element[0]; /* supported rates */
+} __attribute__ ((packed));
+
+struct ieee80211_txb {
+	u8 nr_frags;
+	u8 encrypted;
+	u8 queue_index;
+	u8 rts_included;
+	u16 reserved;
+	__le16 frag_size;
+	__le16 payload_size;
+	struct sk_buff *fragments[0];
+};
+
+#define MAX_TX_AGG_COUNT		  16
+struct ieee80211_drv_agg_txb {
+	u8 nr_drv_agg_frames;
+	struct sk_buff *tx_agg_frames[MAX_TX_AGG_COUNT];
+}__attribute__((packed));
+
+#define MAX_SUBFRAME_COUNT 		  64
+struct ieee80211_rxb {
+	u8 nr_subframes;
+	struct sk_buff *subframes[MAX_SUBFRAME_COUNT];
+	u8 dst[ETH_ALEN];
+	u8 src[ETH_ALEN];
+}__attribute__((packed));
+
+typedef union _frameqos {
+	u16 shortdata;
+	u8  chardata[2];
+	struct {
+		u16 tid:4;
+		u16 eosp:1;
+		u16 ack_policy:2;
+		u16 reserved:1;
+		u16 txop:8;
+	}field;
+}frameqos,*pframeqos;
+
+/* 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
+
+#define MAX_CHANNEL_NUMBER                 161
+#define IEEE80211_SOFTMAC_SCAN_TIME	   100
+//(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)
+
+/* QoS structure */
+#define NETWORK_HAS_QOS_PARAMETERS      (1<<3)
+#define NETWORK_HAS_QOS_INFORMATION     (1<<4)
+#define NETWORK_HAS_QOS_MASK            (NETWORK_HAS_QOS_PARAMETERS | \
+                                         NETWORK_HAS_QOS_INFORMATION)
+/* 802.11h */
+#define NETWORK_HAS_POWER_CONSTRAINT    (1<<5)
+#define NETWORK_HAS_CSA                 (1<<6)
+#define NETWORK_HAS_QUIET               (1<<7)
+#define NETWORK_HAS_IBSS_DFS            (1<<8)
+#define NETWORK_HAS_TPC_REPORT          (1<<9)
+
+#define NETWORK_HAS_ERP_VALUE           (1<<10)
+
+#define QOS_QUEUE_NUM                   4
+#define QOS_OUI_LEN                     3
+#define QOS_OUI_TYPE                    2
+#define QOS_ELEMENT_ID                  221
+#define QOS_OUI_INFO_SUB_TYPE           0
+#define QOS_OUI_PARAM_SUB_TYPE          1
+#define QOS_VERSION_1                   1
+#define QOS_AIFSN_MIN_VALUE             2
+#if 1
+struct ieee80211_qos_information_element {
+        u8 elementID;
+        u8 length;
+        u8 qui[QOS_OUI_LEN];
+        u8 qui_type;
+        u8 qui_subtype;
+        u8 version;
+        u8 ac_info;
+} __attribute__ ((packed));
+
+struct ieee80211_qos_ac_parameter {
+        u8 aci_aifsn;
+        u8 ecw_min_max;
+        __le16 tx_op_limit;
+} __attribute__ ((packed));
+
+struct ieee80211_qos_parameter_info {
+        struct ieee80211_qos_information_element info_element;
+        u8 reserved;
+        struct ieee80211_qos_ac_parameter ac_params_record[QOS_QUEUE_NUM];
+} __attribute__ ((packed));
+
+struct ieee80211_qos_parameters {
+        __le16 cw_min[QOS_QUEUE_NUM];
+        __le16 cw_max[QOS_QUEUE_NUM];
+        u8 aifs[QOS_QUEUE_NUM];
+        u8 flag[QOS_QUEUE_NUM];
+        __le16 tx_op_limit[QOS_QUEUE_NUM];
+} __attribute__ ((packed));
+
+struct ieee80211_qos_data {
+        struct ieee80211_qos_parameters parameters;
+        int active;
+        int supported;
+        u8 param_count;
+        u8 old_param_count;
+};
+
+struct ieee80211_tim_parameters {
+        u8 tim_count;
+        u8 tim_period;
+} __attribute__ ((packed));
+
+//#else
+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));
+#endif
+enum eap_type {
+	EAP_PACKET = 0,
+	EAPOL_START,
+	EAPOL_LOGOFF,
+	EAPOL_KEY,
+	EAPOL_ENCAP_ASF_ALERT
+};
+
+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 ((u32)type >= ARRAY_SIZE(eap_types)) ? "Unknown" : eap_types[type];
+}
+//added by amy for reorder
+static inline u8 Frame_QoSTID(u8* buf)
+{
+	struct ieee80211_hdr_3addr *hdr;
+	u16 fc;
+	hdr = (struct ieee80211_hdr_3addr *)buf;
+	fc = le16_to_cpu(hdr->frame_ctl);
+	return (u8)((frameqos*)(buf + (((fc & IEEE80211_FCTL_TODS)&&(fc & IEEE80211_FCTL_FROMDS))? 30 : 24)))->field.tid;
+}
+
+//added by amy for reorder
+
+struct eapol {
+	u8 snap[6];
+	u16 ethertype;
+	u8 version;
+	u8 type;
+	u16 length;
+} __attribute__ ((packed));
+
+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;
+	unsigned char CurrentShowTxate;
+	unsigned char last_packet_rate;
+	unsigned int txretrycount;
+};
+
+#define BEACON_PROBE_SSID_ID_POSITION 12
+
+struct ieee80211_info_element_hdr {
+	u8 id;
+	u8 len;
+} __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 2 //1Mbps
+
+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)
+
+#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_BK   0x00
+#define WME_AC_BE   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
+
+#define MAX_RECEIVE_BUFFER_SIZE 9100
+
+//UP Mapping to AC, using in MgntQuery_SequenceNumber() and maybe for DSCP
+//#define UP2AC(up)	((up<3) ? ((up==0)?1:0) : (up>>1)) 
+#if 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)	
+#endif
+//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 */
+#define ETHERNET_HEADER_SIZE    14      /* length of two Ethernet address plus ether type*/
+
+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
+
+typedef struct _bss_ht{
+
+	bool				support_ht;
+
+	// HT related elements
+	u8					ht_cap_buf[32];
+	u16					ht_cap_len;
+	u8					ht_info_buf[32];
+	u16					ht_info_len;
+
+	HT_SPEC_VER			ht_spec_ver;
+	//HT_CAPABILITY_ELE			bdHTCapEle;
+	//HT_INFORMATION_ELE		bdHTInfoEle;
+
+	bool				aggregation;
+	bool				long_slot_time;
+}bss_ht, *pbss_ht;
+
+typedef enum _erp_t{
+	ERP_NonERPpresent	= 0x01,
+	ERP_UseProtection	= 0x02,
+	ERP_BarkerPreambleMode = 0x04,
+} erp_t;
+
+
+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;
+#if 1
+        struct ieee80211_qos_data qos_data;
+#else
+       // Qos related. Added by Annie, 2005-11-01.
+        BSS_QOS   BssQos;
+#endif
+
+	//added by amy for LEAP
+	bool	bWithAironetIE;
+	bool	bCkipSupported;
+	bool	bCcxRmEnable;
+	u16 	CcxRmState[2];
+	// CCXv4 S59, MBSSID.
+	bool	bMBssidValid;
+	u8	MBssidMask;
+	u8	MBssid[6];
+	// CCX 2 S38, WLAN Device Version Number element. Annie, 2006-08-20.
+	bool	bWithCcxVerNum;
+	u8	BssCcxVerNumber;
+	/* 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;
+	u32 flags;
+	u32 last_associate;
+	u32 time_stamp[2];
+	u16 beacon_interval;
+	u16 listen_interval;
+	u16 atim_window;
+	u8  erp_value;
+	u8  wpa_ie[MAX_WPA_IE_LEN];
+	size_t wpa_ie_len;
+	u8  rsn_ie[MAX_WPA_IE_LEN];
+	size_t rsn_ie_len;
+
+        struct ieee80211_tim_parameters tim;
+	u8  dtim_period;
+	u8  dtim_data;
+	u32 last_dtim_sta_time[2];
+
+        //appeded for QoS
+        u8 wmm_info;
+        struct ieee80211_wmm_ac_param wmm_param[4];
+        u8 QoS_Enable;
+#ifdef THOMAS_TURBO
+	u8 Turbo_Enable;//enable turbo mode, added by thomas
+#endif
+#ifdef ENABLE_DOT11D
+	u16 CountryIeLen;
+	u8 CountryIeBuf[MAX_IE_LEN];
+#endif
+        // HT Related, by amy, 2008.04.29
+	BSS_HT	bssht;
+	// Add to handle broadcom AP management frame CCK rate.
+	bool broadcom_cap_exist;
+	bool ralink_cap_exist;
+	bool atheros_cap_exist;
+	bool cisco_cap_exist;
+	bool unknown_cap_exist;
+//	u8	berp_info;
+	bool	berp_info_valid;
+	bool buseprotection;
+	//put at the end of the structure.
+	struct list_head list;
+};
+
+#if 1
+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,
+	
+};
+#else
+enum ieee80211_state {
+        IEEE80211_UNINITIALIZED = 0,
+        IEEE80211_INITIALIZED,
+        IEEE80211_ASSOCIATING,
+        IEEE80211_ASSOCIATED,
+        IEEE80211_AUTHENTICATING,
+        IEEE80211_AUTHENTICATED,
+        IEEE80211_SHUTDOWN
+};
+#endif
+
+#define DEFAULT_MAX_SCAN_AGE (15 * HZ)
+#define DEFAULT_FTS 2346
+
+#define CFG_IEEE80211_RESERVE_FCS (1<<0)
+#define CFG_IEEE80211_COMPUTE_FCS (1<<1)
+#define CFG_IEEE80211_RTS (1<<2)
+
+#define IEEE80211_24GHZ_MIN_CHANNEL 1
+#define IEEE80211_24GHZ_MAX_CHANNEL 14
+#define IEEE80211_24GHZ_CHANNELS (IEEE80211_24GHZ_MAX_CHANNEL - \
+                                  IEEE80211_24GHZ_MIN_CHANNEL + 1)
+
+#define IEEE80211_52GHZ_MIN_CHANNEL 34
+#define IEEE80211_52GHZ_MAX_CHANNEL 165
+#define IEEE80211_52GHZ_CHANNELS (IEEE80211_52GHZ_MAX_CHANNEL - \
+                                  IEEE80211_52GHZ_MIN_CHANNEL + 1)
+
+#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
+
+typedef struct tx_pending_t{
+	int frag;
+	struct ieee80211_txb *txb;
+}tx_pending_t;
+
+typedef struct _bandwidth_autoswitch
+{
+	long threshold_20Mhzto40Mhz;
+	long	threshold_40Mhzto20Mhz;	
+	bool bforced_tx20Mhz;
+	bool bautoswitch_enable;	
+}bandwidth_autoswitch,*pbandwidth_autoswitch;
+
+
+//added by amy for order
+
+#define REORDER_WIN_SIZE	128
+#define REORDER_ENTRY_NUM	128
+typedef struct _RX_REORDER_ENTRY
+{
+	struct list_head	List;
+	u16			SeqNum;
+	struct ieee80211_rxb* prxb;
+} RX_REORDER_ENTRY, *PRX_REORDER_ENTRY;
+//added by amy for order
+typedef enum _Fsync_State{
+	Default_Fsync,
+	HW_Fsync,
+	SW_Fsync
+}Fsync_State;	
+
+// Power save mode configured. 
+typedef	enum _RT_PS_MODE	
+{
+	eActive,	// Active/Continuous access.
+	eMaxPs,		// Max power save mode.
+	eFastPs		// Fast power save mode.
+}RT_PS_MODE;
+
+typedef enum _IPS_CALLBACK_FUNCION
+{
+	IPS_CALLBACK_NONE = 0,
+	IPS_CALLBACK_MGNT_LINK_REQUEST = 1,
+	IPS_CALLBACK_JOIN_REQUEST = 2,
+}IPS_CALLBACK_FUNCION;
+
+typedef enum _RT_JOIN_ACTION{
+	RT_JOIN_INFRA   = 1,
+	RT_JOIN_IBSS  = 2,
+	RT_START_IBSS = 3,
+	RT_NO_ACTION  = 4,
+}RT_JOIN_ACTION;
+
+typedef struct _IbssParms{
+	u16   atimWin;
+}IbssParms, *PIbssParms;
+#define MAX_NUM_RATES	264 // Max num of support rates element: 8,  Max num of ext. support rate: 255. 061122, by rcnjko.
+
+// RF state.
+typedef	enum _RT_RF_POWER_STATE
+{
+	eRfOn,
+	eRfSleep,
+	eRfOff
+}RT_RF_POWER_STATE;
+
+typedef struct _RT_POWER_SAVE_CONTROL
+{
+
+	//
+	// Inactive Power Save(IPS) : Disable RF when disconnected
+	//
+	bool				bInactivePs;
+	bool				bIPSModeBackup;
+	bool				bSwRfProcessing;
+	RT_RF_POWER_STATE	eInactivePowerState;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+	struct work_struct 	InactivePsWorkItem;
+#else
+	struct tq_struct	InactivePsWorkItem;
+#endif
+	struct timer_list	InactivePsTimer;
+
+	// Return point for join action
+	IPS_CALLBACK_FUNCION	ReturnPoint;
+	
+	// Recored Parameters for rescheduled JoinRequest
+	bool				bTmpBssDesc;
+	RT_JOIN_ACTION		tmpJoinAction;
+	struct ieee80211_network tmpBssDesc;
+
+	// Recored Parameters for rescheduled MgntLinkRequest
+	bool				bTmpScanOnly;
+	bool				bTmpActiveScan;
+	bool				bTmpFilterHiddenAP;
+	bool				bTmpUpdateParms;
+	u8					tmpSsidBuf[33];
+	OCTET_STRING			tmpSsid2Scan;
+	bool				bTmpSsid2Scan;
+	u8					tmpNetworkType;
+	u8					tmpChannelNumber;
+	u16					tmpBcnPeriod;
+	u8					tmpDtimPeriod;
+	u16					tmpmCap;
+	OCTET_STRING			tmpSuppRateSet;
+	u8					tmpSuppRateBuf[MAX_NUM_RATES];
+	bool				bTmpSuppRate;
+	IbssParms				tmpIbpm;
+	bool				bTmpIbpm;
+
+	//
+	// Leisre Poswer Save : Disable RF if connected but traffic is not busy
+	//		
+	bool				bLeisurePs;
+	
+}RT_POWER_SAVE_CONTROL,*PRT_POWER_SAVE_CONTROL;
+
+typedef u32 RT_RF_CHANGE_SOURCE;
+#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 RF_CHANGE_BY_INIT	0	// Do not change the RFOff reason. Defined by Bruce, 2008-01-17.
+
+#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,
+	COUNTRY_CODE_MIC,
+	COUNTRY_CODE_GLOBAL_DOMAIN
+}country_code_type_t;	
+#endif
+
+#define RT_MAX_LD_SLOT_NUM	10
+typedef struct _RT_LINK_DETECT_T{
+
+	u32				NumRecvBcnInPeriod;
+	u32				NumRecvDataInPeriod;
+
+	u32				RxBcnNum[RT_MAX_LD_SLOT_NUM];	// number of Rx beacon / CheckForHang_period  to determine link status
+	u32				RxDataNum[RT_MAX_LD_SLOT_NUM];	// number of Rx data / CheckForHang_period  to determine link status
+	u16				SlotNum;	// number of CheckForHang period to determine link status
+	u16				SlotIndex;
+
+	u32				NumTxOkInPeriod;
+	u32				NumRxOkInPeriod;
+	bool				bBusyTraffic;
+}RT_LINK_DETECT_T, *PRT_LINK_DETECT_T;
+
+
+struct ieee80211_device {
+	struct net_device *dev;
+        struct ieee80211_security sec;
+
+	//hw security related
+//	u8 hwsec_support; //support?
+	u8 hwsec_active;  //hw security active.
+	bool is_silent_reset;
+	bool ieee_up;	
+	//added by amy
+	bool bSupportRemoteWakeUp;
+	RT_PS_MODE	dot11PowerSaveMode; // Power save mode configured.
+	bool actscanning;
+	bool beinretry;
+	RT_RF_POWER_STATE		eRFPowerState;
+	RT_RF_CHANGE_SOURCE	RfOffReason;
+	bool is_set_key;
+	//11n spec related I wonder if These info structure need to be moved out of ieee80211_device
+	
+	//11n HT below
+	PRT_HIGH_THROUGHPUT	pHTInfo;
+	//struct timer_list		SwBwTimer;
+//	spinlock_t chnlop_spinlock;
+	spinlock_t bw_spinlock;
+
+	spinlock_t reorder_spinlock;
+	// for HT operation rate set.  we use this one for HT data rate to seperate different descriptors
+	//the way fill this is the same as in the IE
+	u8	Regdot11HTOperationalRateSet[16];		//use RATR format
+	u8	dot11HTOperationalRateSet[16];		//use RATR format
+	u8	RegHTSuppRateSet[16];
+	u8				HTCurrentOperaRate;
+	u8				HTHighestOperaRate;
+	//wb added for rate operation mode to firmware
+	u8	bTxDisableRateFallBack;
+	u8 	bTxUseDriverAssingedRate;
+	atomic_t	atm_chnlop;
+	atomic_t	atm_swbw;
+//	u8	HTHighestOperaRate;
+//	u8 	HTCurrentOperaRate;
+
+	// 802.11e and WMM Traffic Stream Info (TX)
+	struct list_head		Tx_TS_Admit_List;
+	struct list_head		Tx_TS_Pending_List;
+	struct list_head		Tx_TS_Unused_List;
+	TX_TS_RECORD		TxTsRecord[TOTAL_TS_NUM];
+	// 802.11e and WMM Traffic Stream Info (RX)
+	struct list_head		Rx_TS_Admit_List;
+	struct list_head		Rx_TS_Pending_List;
+	struct list_head		Rx_TS_Unused_List;
+	RX_TS_RECORD		RxTsRecord[TOTAL_TS_NUM];
+//#ifdef TO_DO_LIST
+	RX_REORDER_ENTRY	RxReorderEntry[128];
+	struct list_head		RxReorder_Unused_List;
+//#endif
+	// Qos related. Added by Annie, 2005-11-01.
+//	PSTA_QOS			pStaQos;
+	u8				ForcedPriority;		// Force per-packet priority 1~7. (default: 0, not to force it.)
+	
+
+	/* 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_*) */
+	struct iw_spy_data spy_data; 
+
+	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 auth_mode;
+	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_encrypt_msdu;
+	int host_decrypt;
+        /* host performs multicast decryption */
+        int host_mc_decrypt;
+
+        /* host should strip IV and ICV from protected frames */
+        /* meaningful only when hardware decryption is being used */
+        int host_strip_iv_icv;
+
+        int host_open_frag;
+        int host_build_iv;
+	int ieee802_1x; /* is IEEE 802.1X used */
+
+	/* WPA data */
+	bool bHalfWirelessN24GMode;
+	int wpa_enabled;
+	int drop_unencrypted;
+	int tkip_countermeasures;
+	int privacy_invoked;
+	size_t wpa_ie_len;
+	u8 *wpa_ie;
+	u8 ap_mac_addr[6];
+	u16 pairwise_key_type;
+	u16 group_key_type;
+	struct list_head crypt_deinit_list;
+	struct ieee80211_crypt_data *crypt[WEP_KEYS];
+	int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */
+	struct timer_list crypt_deinit_timer;
+        int crypt_quiesced;
+
+	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 */
+#define DEFAULT_RTS_THRESHOLD 2346U
+#define MIN_RTS_THRESHOLD 1
+#define MAX_RTS_THRESHOLD 2346U
+        u16 rts; /* RTS threshold */
+
+        /* Association info */
+        u8 bssid[ETH_ALEN];
+
+	/* 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 reg_mode;
+	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; 
+	
+        int perfect_rssi;
+        int worst_rssi;
+
+        u16 prev_seq_ctl;       /* used to drop duplicate frames */
+
+	/* map of allowed channels. 0 is dummy */
+	// FIXME: remeber to default to a basic channel plan depending of the PHY type
+#ifdef ENABLE_DOT11D
+	void* pDot11dInfo;
+	bool bGlobalDomain;
+#else
+	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;
+	
+	/* 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;
+	int ps_period;
+	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 proto_started;
+	
+	struct semaphore wx_sem;
+	struct semaphore scan_sem;
+	
+	spinlock_t mgmt_tx_lock;	
+	spinlock_t beacon_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;
+	/* set on initialization */
+	u8  qos_support;
+	
+	/* for discarding duplicated packets in IBSS */
+	struct list_head ibss_mac_hash[IEEE_IBSS_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;
+//{ added for rtl819x
+#define IEEE80211_QUEUE_LIMIT 128
+	u8 AsocRetryCount;
+	unsigned int hw_header;
+	struct sk_buff_head skb_waitQ[MAX_QUEUE_SIZE];
+	struct sk_buff_head  skb_aggQ[MAX_QUEUE_SIZE]; 
+	struct sk_buff_head  skb_drv_aggQ[MAX_QUEUE_SIZE]; 
+	u32	sta_edca_param[4];
+	bool aggregation;
+	// Enable/Disable Rx immediate BA capability.
+	bool enable_rx_imm_BA;
+	bool bibsscoordinator;
+
+	//+by amy for DM ,080515
+	//Dynamic Tx power for near/far range enable/Disable  , by amy , 2008-05-15
+	bool	bdynamic_txpower_enable; 
+
+	bool bCTSToSelfEnable;
+	u8 	CTSToSelfTH;
+	
+	u32 	fsync_time_interval;
+	u32	fsync_rate_bitmap;
+	u8	fsync_rssi_threshold;
+	bool	bfsync_enable;
+
+	u8	fsync_multiple_timeinterval;		// FsyncMultipleTimeInterval * FsyncTimeInterval	 
+	u32	fsync_firstdiff_ratethreshold;		// low threshold
+	u32	fsync_seconddiff_ratethreshold;	 // decrease threshold
+	Fsync_State			fsync_state;
+	bool		bis_any_nonbepkts;
+	//20Mhz 40Mhz AutoSwitch Threshold
+	bandwidth_autoswitch bandwidth_auto_switch;
+	//for txpower tracking
+	bool FwRWRF;
+
+	//added by amy for AP roaming
+	RT_LINK_DETECT_T	LinkDetectInfo;
+        //added by amy for ps
+	RT_POWER_SAVE_CONTROL	PowerSaveControl;
+//}	
+	/* 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_procedure_wq;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)        
+        struct delayed_work softmac_scan_wq;
+        struct delayed_work associate_retry_wq;
+	 struct delayed_work start_ibss_wq;
+#else
+        struct work_struct softmac_scan_wq;
+        struct work_struct associate_retry_wq;
+	struct work_struct start_ibss_wq;
+#endif
+        struct work_struct wx_sync_scan_wq;
+        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 softmac_scan_wq;
+	struct tq_struct wx_sync_scan_wq;
+
+#endif
+        // Qos related. Added by Annie, 2005-11-01.
+        //STA_QOS  StaQos;
+
+        //u32 STA_EDCA_PARAM[4];
+	//CHANNEL_ACCESS_SETTING ChannelAccessSetting;
+
+
+	/* 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);
+        int (*is_queue_full) (struct net_device * dev, int pri);
+
+        int (*handle_management) (struct net_device * dev,
+                                  struct ieee80211_network * network, u16 type);
+        int (*is_qos_active) (struct net_device *dev, struct sk_buff *skb);
+
+	/* 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,u16 tx_rate);
+	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);
+#if 0
+	/* Typical STA methods */
+        int (*handle_auth) (struct net_device * dev,
+                            struct ieee80211_auth * auth);
+        int (*handle_deauth) (struct net_device * dev,
+                              struct ieee80211_deauth * auth);
+        int (*handle_action) (struct net_device * dev,
+                              struct ieee80211_action * action,
+                              struct ieee80211_rx_stats * stats);
+        int (*handle_disassoc) (struct net_device * dev,
+                                struct ieee80211_disassoc * assoc);
+#endif
+        int (*handle_beacon) (struct net_device * dev, struct ieee80211_beacon * beacon, struct ieee80211_network * network);
+#if 0
+        int (*handle_probe_response) (struct net_device * dev,
+                                      struct ieee80211_probe_response * resp,
+                                      struct ieee80211_network * network);
+        int (*handle_probe_request) (struct net_device * dev,
+                                     struct ieee80211_probe_request * req,
+                                     struct ieee80211_rx_stats * stats);
+#endif
+        int (*handle_assoc_response) (struct net_device * dev, struct ieee80211_assoc_response_frame * resp, struct ieee80211_network * network);
+
+#if 0
+        /* Typical AP methods */
+        int (*handle_assoc_request) (struct net_device * dev);
+        int (*handle_reassoc_request) (struct net_device * dev,
+                                       struct ieee80211_reassoc_request * req);
+#endif
+
+	/* check whether Tx hw resouce available */
+	short (*check_nic_enough_desc)(struct net_device *dev, int queue_index);
+	//added by wb for HT related
+//	void (*SwChnlByTimerHandler)(struct net_device *dev, int channel);
+	void (*SetBWModeHandler)(struct net_device *dev, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset);
+//	void (*UpdateHalRATRTableHandler)(struct net_device* dev, u8* pMcsRate);
+	bool (*GetNmodeSupportBySecCfg)(struct net_device* dev);
+	void (*SetWirelessMode)(struct net_device* dev, u8 wireless_mode);
+	bool (*GetHalfNmodeSupportByAPsHandler)(struct net_device* dev); 
+	void (*InitialGainHandler)(struct net_device *dev, u8 Operation);
+
+	/* 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_N_24G 		  (1<<4)
+#define	IEEE_N_5G		  (1<<5)
+#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)
+
+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 = IEEE80211_3ADDR_LEN;
+
+	switch (WLAN_FC_GET_TYPE(fc)) {
+	case IEEE80211_FTYPE_DATA:
+		if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
+			hdrlen = IEEE80211_4ADDR_LEN; /* 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 = IEEE80211_1ADDR_LEN;
+			break;
+		default:
+			hdrlen = IEEE80211_2ADDR_LEN;
+			break;
+		}
+		break;
+	}
+
+	return hdrlen;
+}
+
+static inline u8 *ieee80211_get_payload(struct ieee80211_hdr *hdr)
+{
+        switch (ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl))) {
+        case IEEE80211_1ADDR_LEN:
+                return ((struct ieee80211_hdr_1addr *)hdr)->payload;
+        case IEEE80211_2ADDR_LEN:
+                return ((struct ieee80211_hdr_2addr *)hdr)->payload;
+        case IEEE80211_3ADDR_LEN:
+                return ((struct ieee80211_hdr_3addr *)hdr)->payload;
+        case IEEE80211_4ADDR_LEN:
+                return ((struct ieee80211_hdr_4addr *)hdr)->payload;
+        }
+        return NULL;
+}
+
+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;
+}
+
+static inline int ieee80211_is_cck_rate(u8 rate)
+{
+        switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
+        case IEEE80211_CCK_RATE_1MB:
+        case IEEE80211_CCK_RATE_2MB:
+        case IEEE80211_CCK_RATE_5MB:
+        case IEEE80211_CCK_RATE_11MB:
+                return 1;
+        }
+        return 0;
+}
+
+
+/* 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_4addr *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);
+#if WIRELESS_EXT >= 18
+extern int ieee80211_wx_get_encode_ext(struct ieee80211_device *ieee,
+                            struct iw_request_info *info,
+                            union iwreq_data* wrqu, char *extra);
+extern int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
+                            struct iw_request_info *info,
+                            union iwreq_data* wrqu, char *extra);
+extern int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
+                               struct iw_request_info *info,
+                               struct iw_param *data, char *extra);
+extern int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
+                               struct iw_request_info *info,
+                               union iwreq_data *wrqu, char *extra);
+#endif
+extern 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);
+
+void SendDisassociation(struct ieee80211_device *ieee, u8* asSta, u8 asRsn);
+extern void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee);
+
+extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee);
+extern void notify_wx_assoc_event(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 softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee);
+
+/* 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 int ieee80211_wx_set_rts(struct ieee80211_device *ieee, 
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra);
+
+extern int ieee80211_wx_get_rts(struct ieee80211_device *ieee, 
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra);
+//HT				 			     
+#define MAX_RECEIVE_BUFFER_SIZE 9100  //
+extern void HTDebugHTCapability(u8* CapIE, u8* TitleString );
+extern void HTDebugHTInfo(u8*  InfoIE, u8* TitleString);
+
+void HTSetConnectBwMode(struct ieee80211_device* ieee, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET    Offset);
+extern void HTUpdateDefaultSetting(struct ieee80211_device* ieee);
+extern void HTConstructCapabilityElement(struct ieee80211_device* ieee, u8* posHTCap, u8* len, u8 isEncrypt);
+extern void HTConstructInfoElement(struct ieee80211_device* ieee, u8* posHTInfo, u8* len, u8 isEncrypt);
+extern void HTConstructRT2RTAggElement(struct ieee80211_device* ieee, u8* posRT2RTAgg, u8* len);
+extern void HTOnAssocRsp(struct ieee80211_device *ieee);
+extern void HTInitializeHTInfo(struct ieee80211_device* ieee);
+extern void HTInitializeBssDesc(PBSS_HT pBssHT);
+extern void HTResetSelfAndSavePeerSetting(struct ieee80211_device* ieee, struct ieee80211_network * pNetwork);
+extern void HTUpdateSelfAndPeerSetting(struct ieee80211_device* ieee,   struct ieee80211_network * pNetwork);
+extern u8 HTGetHighestMCSRate(struct ieee80211_device* ieee, u8* pMCSRateSet, u8* pMCSFilter);
+extern u8 MCS_FILTER_ALL[];
+extern u16 MCS_DATA_RATE[2][2][77] ;
+extern u8 HTCCheck(struct ieee80211_device* ieee, u8*   pFrame);
+//extern void HTSetConnectBwModeCallback(unsigned long data);
+extern void HTResetIOTSetting(PRT_HIGH_THROUGHPUT  pHTInfo);
+extern bool IsHTHalfNmodeAPs(struct ieee80211_device* ieee);
+extern u16 HTHalfMcsToDataRate(struct ieee80211_device* ieee,  u8      nMcsRate);
+extern u16 HTMcsToDataRate( struct ieee80211_device* ieee, u8 nMcsRate);
+extern u16  TxCountToDataRate( struct ieee80211_device* ieee, u8 nDataRate);
+//function in BAPROC.c
+extern int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb);
+extern int ieee80211_rx_ADDBARsp( struct ieee80211_device* ieee, struct sk_buff *skb);
+extern int ieee80211_rx_DELBA(struct ieee80211_device* ieee,struct sk_buff *skb);
+extern void TsInitAddBA( struct ieee80211_device* ieee, PTX_TS_RECORD   pTS, u8 Policy, u8 bOverwritePending);
+extern void TsInitDelBA( struct ieee80211_device* ieee, PTS_COMMON_INFO pTsCommonInfo, TR_SELECT TxRxSelect);
+extern void BaSetupTimeOut(unsigned long data);
+extern void TxBaInactTimeout(unsigned long data);
+extern void RxBaInactTimeout(unsigned long data);
+extern void ResetBaEntry( PBA_RECORD pBA);
+//function in TS.c
+extern bool GetTs(
+        struct ieee80211_device*        ieee,
+        PTS_COMMON_INFO                 *ppTS,
+        u8*                             Addr,
+        u8                              TID,
+        TR_SELECT                       TxRxSelect,  //Rx:1, Tx:0
+        bool                            bAddNewTs
+        );
+extern void TSInitialize(struct ieee80211_device *ieee);
+extern  void TsStartAddBaProcess(struct ieee80211_device* ieee, PTX_TS_RECORD   pTxTS);			 			     
+extern void RemovePeerTS(struct ieee80211_device* ieee, u8* Addr);
+extern void RemoveAllTS(struct ieee80211_device* ieee);
+void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee);
+
+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;
+}
+
+/* For the function is more related to hardware setting, it's better to use the  
+ * ieee handler to refer to it.
+ */
+extern short check_nic_enough_desc(struct net_device *dev, int queue_index);
+extern int ieee80211_data_xmit(struct sk_buff *skb, struct net_device *dev);
+extern int ieee80211_parse_info_param(struct ieee80211_device *ieee,
+		struct ieee80211_info_element *info_element, 
+		u16 length,
+		struct ieee80211_network *network,
+		struct ieee80211_rx_stats *stats);
+
+void ieee80211_indicate_packets(struct ieee80211_device *ieee, struct ieee80211_rxb** prxbIndicateArray,u8  index);
+#define RT_ASOC_RETRY_LIMIT	5
+#endif /* IEEE80211_H */
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.c
new file mode 100644
index 0000000..7e8a3ca
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.c
@@ -0,0 +1,273 @@
+/*
+ * Host AP crypto routines
+ *
+ * Copyright (c) 2002-2003, Jouni Malinen <jkmaline at cc.hut.fi>
+ * Portions Copyright (C) 2004, Intel Corporation <jketreno at 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,
+};
+
+
+static 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;
+}
+
+
+static 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 (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);
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.h b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.h
new file mode 100644
index 0000000..a84df4b
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.h
@@ -0,0 +1,93 @@
+/*
+ * 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 at cc.hut.fi>
+ * Copyright (c) 2002-2003, Jouni Malinen <jkmaline at cc.hut.fi>
+ *
+ * Adaption to a generic IEEE 802.11 stack by James Ketrenos
+ * <jketreno at 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)
+#endif
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,31))
+#define crypto_alloc_tfm crypto_alloc_tfm_rsl
+#define crypto_free_tfm crypto_free_tfm_rsl
+#endif
+
+#endif
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c
new file mode 100644
index 0000000..18db150
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c
@@ -0,0 +1,534 @@
+/*
+ * Host AP crypt: host-based CCMP encryption implementation for Host AP driver
+ *
+ * Copyright (c) 2003-2004, Jouni Malinen <jkmaline at 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");
+
+#ifndef OPENSUSE_SLED
+#define OPENSUSE_SLED 0
+#endif
+
+#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)) && (!OPENSUSE_SLED))
+	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)) && (!OPENSUSE_SLED))
+	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];
+}
+
+
+
+static void ccmp_init_blocks(struct crypto_tfm *tfm,
+			     struct ieee80211_hdr_4addr *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);
+}
+
+
+
+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_4addr *hdr;
+	cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
+
+	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_4addr *) skb->data;
+	if (!tcb_desc->bHwSec)
+	{
+		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;
+
+		//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];
+	}
+	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_4addr *hdr;
+	cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
+	u8 pn[6];
+
+	if (skb->len < hdr_len + CCMP_HDR_LEN + CCMP_MIC_LEN) {
+		key->dot11RSNAStatsCCMPFormatErrors++;
+		return -1;
+	}
+
+	hdr = (struct ieee80211_hdr_4addr *) 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 (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;
+	}
+	if (!tcb_desc->bHwSec)
+	{
+		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;
+		
+
+		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);
+	}
+	/* 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,
+};
+
+
+static int __init ieee80211_crypto_ccmp_init(void)
+{
+	return ieee80211_register_crypto_ops(&ieee80211_crypt_ccmp);
+}
+
+
+static void __exit ieee80211_crypto_ccmp_exit(void)
+{
+	ieee80211_unregister_crypto_ops(&ieee80211_crypt_ccmp);
+}
+
+#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);
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c
new file mode 100644
index 0000000..49816f4
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c
@@ -0,0 +1,1034 @@
+/*
+ * Host AP crypt: host-based TKIP encryption implementation for Host AP driver
+ *
+ * Copyright (c) 2003-2004, Jouni Malinen <jkmaline at 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,6,20))
+//#include "crypto_compat.h"
+#endif
+
+
+#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");
+
+#ifndef OPENSUSE_SLED
+#define OPENSUSE_SLED 0
+#endif
+
+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)) || (OPENSUSE_SLED))
+	struct crypto_blkcipher *rx_tfm_arc4;
+	struct crypto_hash *rx_tfm_michael;
+	struct crypto_blkcipher *tx_tfm_arc4;
+	struct crypto_hash *tx_tfm_michael;
+#else
+	struct crypto_tfm *tx_tfm_arc4;
+	struct crypto_tfm *tx_tfm_michael;
+	struct crypto_tfm *rx_tfm_arc4;
+	struct crypto_tfm *rx_tfm_michael;
+#endif
+	/* 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)) && (!OPENSUSE_SLED))
+	priv->tx_tfm_arc4 = crypto_alloc_tfm("arc4", 0);
+	if (priv->tx_tfm_arc4 == NULL) {
+		printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
+				"crypto API arc4\n");
+		goto fail;
+	}
+
+	priv->tx_tfm_michael = crypto_alloc_tfm("michael_mic", 0);
+	if (priv->tx_tfm_michael == NULL) {
+		printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
+				"crypto API michael_mic\n");
+		goto fail;
+	}
+
+	priv->rx_tfm_arc4 = crypto_alloc_tfm("arc4", 0);
+	if (priv->rx_tfm_arc4 == NULL) {
+		printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
+				"crypto API arc4\n");
+		goto fail;
+	}
+
+	priv->rx_tfm_michael = crypto_alloc_tfm("michael_mic", 0);
+	if (priv->rx_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)) && (!OPENSUSE_SLED))
+		if (priv->tx_tfm_michael)
+			crypto_free_tfm(priv->tx_tfm_michael);
+		if (priv->tx_tfm_arc4)
+			crypto_free_tfm(priv->tx_tfm_arc4);
+		if (priv->rx_tfm_michael)
+			crypto_free_tfm(priv->rx_tfm_michael);
+		if (priv->rx_tfm_arc4)
+			crypto_free_tfm(priv->rx_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)) && (!OPENSUSE_SLED))
+	if (_priv->tx_tfm_michael)
+		crypto_free_tfm(_priv->tx_tfm_michael);
+	if (_priv->tx_tfm_arc4)
+		crypto_free_tfm(_priv->tx_tfm_arc4);
+	if (_priv->rx_tfm_michael)
+		crypto_free_tfm(_priv->rx_tfm_michael);
+	if (_priv->rx_tfm_arc4)
+		crypto_free_tfm(_priv->rx_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));
+}
+
+
+#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
+}
+
+
+static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
+{
+	struct ieee80211_tkip_data *tkey = priv;
+		int len;
+	u8 *pos;
+	struct ieee80211_hdr_4addr *hdr;
+	cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
+
+	#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) || (OPENSUSE_SLED))
+	struct blkcipher_desc desc = {.tfm = tkey->tx_tfm_arc4};
+	int ret = 0;
+	#endif
+	u8 rc4key[16],  *icv;
+	u32 crc;
+	struct scatterlist sg;
+
+	if (skb_headroom(skb) < 8 || skb_tailroom(skb) < 4 ||
+	    skb->len < hdr_len)
+		return -1;
+
+	hdr = (struct ieee80211_hdr_4addr *) 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
+
+	if (!tcb_desc->bHwSec)
+	{
+		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;
+	
+	
+	len = skb->len - hdr_len;
+	pos = skb_push(skb, 8);
+	memmove(pos, pos + 8, hdr_len);
+	pos += hdr_len;
+
+	if (tcb_desc->bHwSec)
+	{
+		*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];
+	}
+
+	*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;
+
+	if (!tcb_desc->bHwSec)
+	{
+		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)) && (!OPENSUSE_SLED))
+		crypto_cipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
+		sg.page = virt_to_page(pos);
+		sg.offset = offset_in_page(pos);
+		sg.length = len + 4;
+		crypto_cipher_encrypt(tkey->tx_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
+
+	}
+
+	tkey->tx_iv16++;
+	if (tkey->tx_iv16 == 0) {
+		tkey->tx_phase1_done = 0;
+		tkey->tx_iv32++;
+	}
+
+	if (!tcb_desc->bHwSec)
+#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
+		return 0;
+	#else
+		return ret;
+	#endif
+	else
+        	return 0;
+
+
+}
+
+static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
+{
+	struct ieee80211_tkip_data *tkey = priv;
+	u8 keyidx, *pos;
+	u32 iv32;
+	u16 iv16;
+	struct ieee80211_hdr_4addr *hdr;
+	cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
+	#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) || (OPENSUSE_SLED))
+	struct blkcipher_desc desc = {.tfm = tkey->rx_tfm_arc4};
+	#endif
+	u8 rc4key[16];
+	u8 icv[4];
+	u32 crc;
+	struct scatterlist sg;
+	int plen;
+	if (skb->len < hdr_len + 8 + 4)
+		return -1;
+
+	hdr = (struct ieee80211_hdr_4addr *) 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;
+
+	if (!tcb_desc->bHwSec)
+	{
+		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;
+		}
+	
+		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)) && (!OPENSUSE_SLED))
+		crypto_cipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
+		sg.page = virt_to_page(pos);
+		sg.offset = offset_in_page(pos);
+		sg.length = plen + 4;
+		crypto_cipher_decrypt(tkey->rx_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;
+		}
+
+	}
+
+	/* 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)) && (!OPENSUSE_SLED))
+static int michael_mic(struct crypto_tfm * tfm_michael, 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 (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;
+
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+	crypto_digest_init(tfm_michael);
+        crypto_digest_setkey(tfm_michael, key, 8);
+        crypto_digest_update(tfm_michael, sg, 2);
+        crypto_digest_final(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_4addr *hdr11;
+
+	hdr11 = (struct ieee80211_hdr_4addr *) 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_4addr *hdr;
+
+	hdr = (struct ieee80211_hdr_4addr *) 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)) && (!OPENSUSE_SLED))
+	if (michael_mic(tkey->tx_tfm_michael, &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_4addr *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_4addr *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_4addr *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_4addr *hdr;
+
+	hdr = (struct ieee80211_hdr_4addr *) 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)) && (!OPENSUSE_SLED))
+	if (michael_mic(tkey->rx_tfm_michael, &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_4addr *hdr;
+		hdr = (struct ieee80211_hdr_4addr *) 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)) && (!OPENSUSE_SLED))
+	struct crypto_tfm *tfm = tkey->tx_tfm_michael;
+	struct crypto_tfm *tfm2 = tkey->tx_tfm_arc4;
+	struct crypto_tfm *tfm3 = tkey->rx_tfm_michael;
+	struct crypto_tfm *tfm4 = tkey->rx_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)) && (!OPENSUSE_SLED))
+	tkey->tx_tfm_michael = tfm;
+	tkey->tx_tfm_arc4 = tfm2;
+	tkey->rx_tfm_michael = tfm3;
+	tkey->rx_tfm_arc4 = tfm4;
+#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,
+};
+
+
+static int __init ieee80211_crypto_tkip_init(void)
+{
+	return ieee80211_register_crypto_ops(&ieee80211_crypt_tkip);
+}
+
+
+static 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 (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);
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_wep.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_wep.c
new file mode 100644
index 0000000..bd3f621
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_wep.c
@@ -0,0 +1,397 @@
+/*
+ * Host AP crypt: host-based WEP encryption implementation for Host AP driver
+ *
+ * Copyright (c) 2002-2004, Jouni Malinen <jkmaline at 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,6,20))
+//#include "crypto_compat.h"
+#endif
+
+
+#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>
+//
+/*
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+#include "rtl_crypto.h"
+#else
+#include <linux/crypto.h>
+#endif
+
+#include <asm/scatterlist.h>
+#include <linux/crc32.h>
+*/
+MODULE_AUTHOR("Jouni Malinen");
+MODULE_DESCRIPTION("Host AP crypt: WEP");
+MODULE_LICENSE("GPL");
+#ifndef OPENSUSE_SLED
+#define OPENSUSE_SLED 0
+#endif
+
+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)) && (!OPENSUSE_SLED))
+	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)) && (!OPENSUSE_SLED))
+	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)) && (!OPENSUSE_SLED))
+	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)) && (!OPENSUSE_SLED))
+	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;
+	u32 klen, len;
+	u8 key[WEP_KEY_LEN + 3];
+	u8 *pos;
+	cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
+	#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) || (OPENSUSE_SLED))
+	struct blkcipher_desc desc = {.tfm = wep->tx_tfm};
+	#endif
+	u32 crc;
+	u8 *icv;
+	struct scatterlist sg;
+	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);
+
+	if (!tcb_desc->bHwSec)
+	{
+	
+		/* 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)) && (!OPENSUSE_SLED))
+		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
+	}
+
+	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;
+	u32  klen, plen;
+	u8 key[WEP_KEY_LEN + 3];
+	u8 keyidx, *pos;
+	cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
+	#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) || (OPENSUSE_SLED))
+	struct blkcipher_desc desc = {.tfm = wep->rx_tfm};
+	#endif
+	u32 crc;
+	u8 icv[4];
+	struct scatterlist sg;
+	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;
+
+	if (!tcb_desc->bHwSec)
+	{
+#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
+		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;
+		}
+	}
+	/* 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,
+};
+
+
+static int __init ieee80211_crypto_wep_init(void)
+{
+	return ieee80211_register_crypto_ops(&ieee80211_crypt_wep);
+}
+
+
+static 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 (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);
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c
new file mode 100644
index 0000000..5a5692f
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c
@@ -0,0 +1,394 @@
+/*******************************************************************************
+
+  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 at cc.hut.fi>
+  Copyright (c) 2002-2003, Jouni Malinen <jkmaline at 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 at 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 at 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
+	dev->hard_start_xmit = ieee80211_xmit;
+
+	memset(ieee, 0, sizeof(struct ieee80211_device)+sizeof_priv);
+	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);
+	spin_lock_init(&ieee->bw_spinlock);
+	spin_lock_init(&ieee->reorder_spinlock);
+	//added by WB
+	atomic_set(&(ieee->atm_chnlop), 0);
+	atomic_set(&(ieee->atm_swbw), 0);
+
+	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;
+	//ieee->hwsec_support = 1; //defalt support hw security. //use module_param instead.
+	ieee->hwsec_active = 0; //disable hwsec, switch it on when necessary.
+
+	ieee80211_softmac_init(ieee);
+	
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13))
+	ieee->pHTInfo = (RT_HIGH_THROUGHPUT*)kzalloc(sizeof(RT_HIGH_THROUGHPUT), GFP_KERNEL);
+#else
+	ieee->pHTInfo = (RT_HIGH_THROUGHPUT*)kmalloc(sizeof(RT_HIGH_THROUGHPUT), GFP_KERNEL);
+	memset(ieee->pHTInfo,0,sizeof(RT_HIGH_THROUGHPUT));
+#endif
+	if (ieee->pHTInfo == NULL)
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for HTInfo\n");
+		return NULL;
+	}	
+	HTUpdateDefaultSetting(ieee);
+	HTInitializeHTInfo(ieee); //may move to other place.
+	TSInitialize(ieee);
+#if 0
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) 
+ 	INIT_WORK(&ieee->ht_onAssRsp, (void(*)(void*)) HTOnAssocRsp_wq);
+#else
+	INIT_WORK(&ieee->ht_onAssRsp, (void(*)(void*)) HTOnAssocRsp_wq, ieee);
+#endif
+#endif
+	for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++)
+		INIT_LIST_HEAD(&ieee->ibss_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;
+	}
+
+//These function were added to load crypte module autoly
+	ieee80211_tkip_null();
+	ieee80211_wep_null();
+	ieee80211_ccmp_null();
+
+	return dev;
+
+ failed:
+	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;
+	//struct list_head *p, *q;
+//	del_timer_sync(&ieee->SwBwTimer);
+#if 1	
+	if (ieee->pHTInfo != NULL)
+	{
+		kfree(ieee->pHTInfo);
+		ieee->pHTInfo = NULL;
+	}
+#endif	
+	RemoveAllTS(ieee);
+	ieee80211_softmac_free(ieee);
+	del_timer_sync(&ieee->crypt_deinit_timer);
+	ieee80211_crypt_deinit_entries(ieee, 1);
+
+	for (i = 0; i < WEP_KEYS; i++) {
+		struct ieee80211_crypt_data *crypt = ieee->crypt[i];
+		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);
+			ieee->crypt[i] = NULL;
+		}
+	}
+
+	ieee80211_networks_free(ieee);
+#if 0	
+	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);
+		}
+	}
+
+#endif
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))	
+	free_netdev(dev);
+#else
+	kfree(dev);
+#endif
+}
+
+#ifdef CONFIG_IEEE80211_DEBUG
+
+u32 ieee80211_debug_level = 0;
+static int debug = \
+	//		    IEEE80211_DL_INFO	|
+	//		    IEEE80211_DL_WX	|
+	//		    IEEE80211_DL_SCAN	|
+	//		    IEEE80211_DL_STATE	|
+	//		    IEEE80211_DL_MGMT	|
+	//		    IEEE80211_DL_FRAG	|
+	//		    IEEE80211_DL_EAP	|
+	//		    IEEE80211_DL_DROP	|
+	//		    IEEE80211_DL_TX	|
+	//		    IEEE80211_DL_RX	|
+			    //IEEE80211_DL_QOS    |
+	//		    IEEE80211_DL_HT 	|
+	//		    IEEE80211_DL_TS	|
+//			    IEEE80211_DL_BA 	|
+	//		    IEEE80211_DL_REORDER|
+//			    IEEE80211_DL_TRACE  |
+			    //IEEE80211_DL_DATA	|
+			    IEEE80211_DL_ERR	  //awayls open this flags to show error out
+			    ;
+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;
+#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
+	ieee80211_proc = create_proc_entry(DRV_NAME, S_IFDIR, proc_net);
+#else
+	ieee80211_proc = create_proc_entry(DRV_NAME, S_IFDIR, init_net.proc_net);
+#endif
+	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) {
+#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
+		remove_proc_entry(DRV_NAME, proc_net);
+#else
+		remove_proc_entry(DRV_NAME, init_net.proc_net);
+#endif
+		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);
+#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
+		remove_proc_entry(DRV_NAME, proc_net);
+#else
+		remove_proc_entry(DRV_NAME, init_net.proc_net);
+#endif
+		ieee80211_proc = NULL;
+	}
+}
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
+#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
+#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/staging/rtl8192u/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c
new file mode 100644
index 0000000..156ca35
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c
@@ -0,0 +1,2778 @@
+/*
+ * 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 at cc.hut.fi>
+ * Copyright (c) 2002-2003, Jouni Malinen <jkmaline at 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 at 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_4addr *hdr = (struct ieee80211_hdr_4addr *)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_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_4addr *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_3addrqos *hdr_3addrqos;
+	struct ieee80211_hdr_4addrqos *hdr_4addrqos;
+	u8 tid;
+	
+	if (((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) {
+	  hdr_4addrqos = (struct ieee80211_hdr_4addrqos *)hdr;
+	  tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QCTL_TID;
+	  tid = UP2AC(tid);
+	  tid ++;
+	} else if (IEEE80211_QOS_HAS_SEQ(fc)) {
+	  hdr_3addrqos = (struct ieee80211_hdr_3addrqos *)hdr;
+	  tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QCTL_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_4addr) +
+				    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_4addr *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_3addrqos *hdr_3addrqos;
+	struct ieee80211_hdr_4addrqos *hdr_4addrqos;
+	u8 tid;
+	
+	if(((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) {
+	  hdr_4addrqos = (struct ieee80211_hdr_4addrqos *)hdr;
+	  tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QCTL_TID;
+	  tid = UP2AC(tid);
+	  tid ++;
+	} else if (IEEE80211_QOS_HAS_SEQ(fc)) {
+	  hdr_3addrqos = (struct ieee80211_hdr_3addrqos *)hdr;
+	  tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QCTL_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_3addr * hdr = (struct ieee80211_hdr_3addr *)skb->data;
+
+	rx_stats->len = skb->len;
+	ieee80211_rx_mgt(ieee,(struct ieee80211_hdr_4addr *)skb->data,rx_stats);	
+        //if ((ieee->state == IEEE80211_LINKED) && (memcmp(hdr->addr3, ieee->current_network.bssid, ETH_ALEN)))
+        if ((memcmp(hdr->addr1, ieee->dev->dev_addr, ETH_ALEN)))//use ADDR1 to perform address matching for Management frames
+        {
+                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_4addr *)
+  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_4addr *hdr;
+	u8 *pos;
+
+	if (skb->len < 24)
+		return 0;
+
+	hdr = (struct ieee80211_hdr_4addr *) 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_4addr *hdr;
+	int res, hdrlen;
+
+	if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
+		return 0;
+#if 1
+	if (ieee->hwsec_active)
+	{
+		cb_desc *tcb_desc = (cb_desc *)(skb->cb+ MAX_DEV_ADDR_SIZE);
+		tcb_desc->bHwSec = 1;
+	}
+#endif	
+	hdr = (struct ieee80211_hdr_4addr *) skb->data;
+	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_4addr *hdr;
+	int res, hdrlen;
+
+	if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
+		return 0;
+	if (ieee->hwsec_active)
+	{
+		cb_desc *tcb_desc = (cb_desc *)(skb->cb+ MAX_DEV_ADDR_SIZE);
+		tcb_desc->bHwSec = 1;
+	}
+
+	hdr = (struct ieee80211_hdr_4addr *) skb->data;
+	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_4addr *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_3addrqos *hdr_3addrqos;
+	struct ieee80211_hdr_4addrqos *hdr_4addrqos;
+	u8 tid;
+	
+	
+	//TO2DS and QoS
+	if(((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) {
+	  hdr_4addrqos = (struct ieee80211_hdr_4addrqos *)header;
+	  tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QCTL_TID;
+	  tid = UP2AC(tid);
+	  tid ++;
+	} else if(IEEE80211_QOS_HAS_SEQ(fc)) { //QoS
+	  hdr_3addrqos = (struct ieee80211_hdr_3addrqos*)header;
+	  tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QCTL_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]) {
+		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:
+		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;
+}
+bool
+AddReorderEntry(
+	PRX_TS_RECORD			pTS,
+	PRX_REORDER_ENTRY		pReorderEntry
+	)
+{
+	struct list_head *pList = &pTS->RxPendingPktList;
+#if  1 
+	while(pList->next != &pTS->RxPendingPktList)
+	{
+		if( SN_LESS(pReorderEntry->SeqNum, ((PRX_REORDER_ENTRY)list_entry(pList->next,RX_REORDER_ENTRY,List))->SeqNum) )
+		{
+			pList = pList->next;
+		}
+		else if( SN_EQUAL(pReorderEntry->SeqNum, ((PRX_REORDER_ENTRY)list_entry(pList->next,RX_REORDER_ENTRY,List))->SeqNum) )
+		{
+			return false;
+		}
+		else
+		{
+			break;
+		}
+	}
+#endif
+	pReorderEntry->List.next = pList->next;
+	pReorderEntry->List.next->prev = &pReorderEntry->List;
+	pReorderEntry->List.prev = pList;
+	pList->next = &pReorderEntry->List;
+
+	return true;
+}
+
+void ieee80211_indicate_packets(struct ieee80211_device *ieee, struct ieee80211_rxb** prxbIndicateArray,u8  index)
+{
+	u8 i = 0 , j=0;
+	u16 ethertype;
+//	if(index > 1)	
+//		IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): hahahahhhh, We indicate packet from reorder list, index is %u\n",__FUNCTION__,index);
+	for(j = 0; j<index; j++)
+	{
+//added by amy for reorder
+		struct ieee80211_rxb* prxb = prxbIndicateArray[j];
+		for(i = 0; i<prxb->nr_subframes; i++) {
+			struct sk_buff *sub_skb = prxb->subframes[i];
+				
+		/* convert hdr + possible LLC headers into Ethernet header */
+			ethertype = (sub_skb->data[6] << 8) | sub_skb->data[7];
+			if (sub_skb->len >= 8 &&
+				((memcmp(sub_skb->data, rfc1042_header, SNAP_SIZE) == 0 &&
+				  ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
+				 memcmp(sub_skb->data, bridge_tunnel_header, SNAP_SIZE) == 0)) {
+			/* remove RFC1042 or Bridge-Tunnel encapsulation and
+			 * replace EtherType */
+				skb_pull(sub_skb, SNAP_SIZE);
+				memcpy(skb_push(sub_skb, ETH_ALEN), prxb->src, ETH_ALEN);
+				memcpy(skb_push(sub_skb, ETH_ALEN), prxb->dst, ETH_ALEN);
+			} else {
+				u16 len;
+			/* Leave Ethernet header part of hdr and full payload */
+				len = htons(sub_skb->len);
+				memcpy(skb_push(sub_skb, 2), &len, 2);
+				memcpy(skb_push(sub_skb, ETH_ALEN), prxb->src, ETH_ALEN);
+				memcpy(skb_push(sub_skb, ETH_ALEN), prxb->dst, ETH_ALEN);
+			}
+			//stats->rx_packets++;
+			//stats->rx_bytes += sub_skb->len;
+
+		/* Indicat the packets to upper layer */
+			if (sub_skb) {
+				//printk("0skb_len(%d)\n", skb->len);
+				sub_skb->protocol = eth_type_trans(sub_skb, ieee->dev);
+				memset(sub_skb->cb, 0, sizeof(sub_skb->cb));
+				sub_skb->dev = ieee->dev;
+				sub_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(sub_skb);
+			}
+		}
+		kfree(prxb);
+		prxb = NULL;	
+	}
+}
+
+
+void RxReorderIndicatePacket( struct ieee80211_device *ieee,
+		struct ieee80211_rxb* prxb,
+		PRX_TS_RECORD		pTS,
+		u16			SeqNum)
+{
+	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
+	PRX_REORDER_ENTRY 	pReorderEntry = NULL;
+	struct ieee80211_rxb* prxbIndicateArray[REORDER_WIN_SIZE];
+	u8			WinSize = pHTInfo->RxReorderWinSize;
+	u16			WinEnd = (pTS->RxIndicateSeq + WinSize -1)%4096;
+	u8			index = 0;
+	bool			bMatchWinStart = false, bPktInBuf = false;
+	IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): Seq is %d,pTS->RxIndicateSeq is %d, WinSize is %d\n",__FUNCTION__,SeqNum,pTS->RxIndicateSeq,WinSize);
+#if 0
+	if(!list_empty(&ieee->RxReorder_Unused_List))
+		IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): ieee->RxReorder_Unused_List is nut NULL\n");
+#endif
+	/* Rx Reorder initialize condition.*/
+	if(pTS->RxIndicateSeq == 0xffff) {
+		pTS->RxIndicateSeq = SeqNum;
+	}
+
+	/* Drop out the packet which SeqNum is smaller than WinStart */
+	if(SN_LESS(SeqNum, pTS->RxIndicateSeq)) {
+		IEEE80211_DEBUG(IEEE80211_DL_REORDER,"Packet Drop! IndicateSeq: %d, NewSeq: %d\n",
+				 pTS->RxIndicateSeq, SeqNum);
+		pHTInfo->RxReorderDropCounter++;
+		{
+			int i;
+			for(i =0; i < prxb->nr_subframes; i++) {
+				dev_kfree_skb(prxb->subframes[i]);
+			}
+			kfree(prxb);
+			prxb = NULL;
+		}
+		return;
+	}
+
+	/*
+	 * Sliding window manipulation. Conditions includes:
+	 * 1. Incoming SeqNum is equal to WinStart =>Window shift 1
+	 * 2. Incoming SeqNum is larger than the WinEnd => Window shift N
+	 */
+	if(SN_EQUAL(SeqNum, pTS->RxIndicateSeq)) {
+		pTS->RxIndicateSeq = (pTS->RxIndicateSeq + 1) % 4096;
+		bMatchWinStart = true;
+	} else if(SN_LESS(WinEnd, SeqNum)) {
+		if(SeqNum >= (WinSize - 1)) {
+			pTS->RxIndicateSeq = SeqNum + 1 -WinSize;
+		} else {
+			pTS->RxIndicateSeq = 4095 - (WinSize - (SeqNum +1)) + 1;
+		}
+		IEEE80211_DEBUG(IEEE80211_DL_REORDER, "Window Shift! IndicateSeq: %d, NewSeq: %d\n",pTS->RxIndicateSeq, SeqNum);
+	}
+
+	/*
+	 * Indication process.
+	 * After Packet dropping and Sliding Window shifting as above, we can now just indicate the packets
+	 * with the SeqNum smaller than latest WinStart and buffer other packets.
+	 */
+	/* For Rx Reorder condition:
+	 * 1. All packets with SeqNum smaller than WinStart => Indicate
+	 * 2. All packets with SeqNum larger than or equal to WinStart => Buffer it.
+	 */
+	if(bMatchWinStart) {
+		/* Current packet is going to be indicated.*/
+		IEEE80211_DEBUG(IEEE80211_DL_REORDER, "Packets indication!! IndicateSeq: %d, NewSeq: %d\n",\
+				pTS->RxIndicateSeq, SeqNum);
+		prxbIndicateArray[0] = prxb;
+//		printk("========================>%s(): SeqNum is %d\n",__FUNCTION__,SeqNum);
+		index = 1;
+	} else {
+		/* Current packet is going to be inserted into pending list.*/
+		//IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): We RX no ordered packed, insert to orderd list\n",__FUNCTION__);
+		if(!list_empty(&ieee->RxReorder_Unused_List)) {
+			pReorderEntry = (PRX_REORDER_ENTRY)list_entry(ieee->RxReorder_Unused_List.next,RX_REORDER_ENTRY,List);
+			list_del_init(&pReorderEntry->List);
+			
+			/* Make a reorder entry and insert into a the packet list.*/
+			pReorderEntry->SeqNum = SeqNum;
+			pReorderEntry->prxb = prxb;
+	//		IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): pREorderEntry->SeqNum is %d\n",__FUNCTION__,pReorderEntry->SeqNum);
+
+#if 1 
+			if(!AddReorderEntry(pTS, pReorderEntry)) {
+				IEEE80211_DEBUG(IEEE80211_DL_REORDER, "%s(): Duplicate packet is dropped!! IndicateSeq: %d, NewSeq: %d\n", 
+					__FUNCTION__, pTS->RxIndicateSeq, SeqNum);
+				list_add_tail(&pReorderEntry->List,&ieee->RxReorder_Unused_List);
+				{
+					int i;
+					for(i =0; i < prxb->nr_subframes; i++) {
+						dev_kfree_skb(prxb->subframes[i]);
+					}
+					kfree(prxb);
+					prxb = NULL;
+				}
+			} else {
+				IEEE80211_DEBUG(IEEE80211_DL_REORDER,
+					 "Pkt insert into buffer!! IndicateSeq: %d, NewSeq: %d\n",pTS->RxIndicateSeq, SeqNum);
+			}
+#endif
+		} 
+		else {
+			/*
+			 * Packets are dropped if there is not enough reorder entries.
+			 * This part shall be modified!! We can just indicate all the 
+			 * packets in buffer and get reorder entries.
+			 */
+			IEEE80211_DEBUG(IEEE80211_DL_ERR, "RxReorderIndicatePacket(): There is no reorder entry!! Packet is dropped!!\n");
+			{
+				int i;
+				for(i =0; i < prxb->nr_subframes; i++) {
+					dev_kfree_skb(prxb->subframes[i]);
+				}
+				kfree(prxb);
+				prxb = NULL;
+			}
+		}
+	}
+
+	/* Check if there is any packet need indicate.*/
+	while(!list_empty(&pTS->RxPendingPktList)) {
+		IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): start RREORDER indicate\n",__FUNCTION__);
+#if 1 
+		pReorderEntry = (PRX_REORDER_ENTRY)list_entry(pTS->RxPendingPktList.prev,RX_REORDER_ENTRY,List);
+		if( SN_LESS(pReorderEntry->SeqNum, pTS->RxIndicateSeq) || 
+				SN_EQUAL(pReorderEntry->SeqNum, pTS->RxIndicateSeq))
+		{
+			/* This protect buffer from overflow. */
+			if(index >= REORDER_WIN_SIZE) {
+				IEEE80211_DEBUG(IEEE80211_DL_ERR, "RxReorderIndicatePacket(): Buffer overflow!! \n");
+				bPktInBuf = true;
+				break;
+			}
+
+			list_del_init(&pReorderEntry->List);
+
+			if(SN_EQUAL(pReorderEntry->SeqNum, pTS->RxIndicateSeq))
+				pTS->RxIndicateSeq = (pTS->RxIndicateSeq + 1) % 4096;
+
+			IEEE80211_DEBUG(IEEE80211_DL_REORDER,"Packets indication!! IndicateSeq: %d, NewSeq: %d\n",pTS->RxIndicateSeq, SeqNum);
+			prxbIndicateArray[index] = pReorderEntry->prxb;
+		//	printk("========================>%s(): pReorderEntry->SeqNum is %d\n",__FUNCTION__,pReorderEntry->SeqNum);
+			index++;
+
+			list_add_tail(&pReorderEntry->List,&ieee->RxReorder_Unused_List);
+		} else {
+			bPktInBuf = true;
+			break;
+		}
+#endif
+	}
+
+	/* Handling pending timer. Set this timer to prevent from long time Rx buffering.*/
+	if(index>0) {
+		// Cancel previous pending timer.
+	//	del_timer_sync(&pTS->RxPktPendingTimer);
+		pTS->RxTimeoutIndicateSeq = 0xffff;
+
+		// Indicate packets
+		if(index>REORDER_WIN_SIZE){
+			IEEE80211_DEBUG(IEEE80211_DL_ERR, "RxReorderIndicatePacket(): Rx Reorer buffer full!! \n");
+			return;
+		}
+		ieee80211_indicate_packets(ieee, prxbIndicateArray, index);
+	}
+
+#if 1 
+	if(bPktInBuf && pTS->RxTimeoutIndicateSeq==0xffff) {
+		// Set new pending timer.
+		IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): SET rx timeout timer\n", __FUNCTION__);
+		pTS->RxTimeoutIndicateSeq = pTS->RxIndicateSeq;
+		if(timer_pending(&pTS->RxPktPendingTimer))
+			del_timer_sync(&pTS->RxPktPendingTimer);
+		pTS->RxPktPendingTimer.expires = jiffies + MSECS(pHTInfo->RxReorderPendingTime);
+		add_timer(&pTS->RxPktPendingTimer);
+	}
+#endif
+}
+
+u8 parse_subframe(struct sk_buff *skb, 
+                  struct ieee80211_rx_stats *rx_stats,
+		  struct ieee80211_rxb *rxb,u8* src,u8* dst)
+{
+	struct ieee80211_hdr_3addr  *hdr = (struct ieee80211_hdr_3addr* )skb->data;
+	u16		fc = le16_to_cpu(hdr->frame_ctl);
+
+	u16		LLCOffset= sizeof(struct ieee80211_hdr_3addr);
+	u16		ChkLength;
+	bool		bIsAggregateFrame = false;
+	u16		nSubframe_Length;
+	u8		nPadding_Length = 0;
+	u16		SeqNum=0;
+
+	struct sk_buff *sub_skb;
+	u8             *data_ptr;	
+	/* just for debug purpose */
+	SeqNum = WLAN_GET_SEQ_SEQ(le16_to_cpu(hdr->seq_ctl));
+
+	if((IEEE80211_QOS_HAS_SEQ(fc))&&\
+			(((frameqos *)(skb->data + IEEE80211_3ADDR_LEN))->field.reserved)) {
+		bIsAggregateFrame = true;
+	}
+
+	if(IEEE80211_QOS_HAS_SEQ(fc)) {
+		LLCOffset += 2;
+	}
+
+	if(rx_stats->bContainHTC) {
+		LLCOffset += sHTCLng;
+	}
+	//printk("ChkLength = %d\n", LLCOffset);
+	// Null packet, don't indicate it to upper layer
+	ChkLength = LLCOffset;/* + (Frame_WEP(frame)!=0 ?Adapter->MgntInfo.SecurityInfo.EncryptionHeadOverhead:0);*/
+
+	if( skb->len <= ChkLength ) {
+		return 0;
+	}
+
+	skb_pull(skb, LLCOffset);
+
+	if(!bIsAggregateFrame) {
+		rxb->nr_subframes = 1;
+#ifdef JOHN_NOCPY
+		rxb->subframes[0] = skb;
+#else
+		rxb->subframes[0] = skb_copy(skb, GFP_ATOMIC);
+#endif
+
+		memcpy(rxb->src,src,ETH_ALEN);
+		memcpy(rxb->dst,dst,ETH_ALEN);
+		//IEEE80211_DEBUG_DATA(IEEE80211_DL_RX,skb->data,skb->len);
+		return 1;
+	} else {
+		rxb->nr_subframes = 0;
+		memcpy(rxb->src,src,ETH_ALEN);
+		memcpy(rxb->dst,dst,ETH_ALEN);
+		while(skb->len > ETHERNET_HEADER_SIZE) {
+			/* Offset 12 denote 2 mac address */
+			nSubframe_Length = *((u16*)(skb->data + 12));
+			//==m==>change the length order
+			nSubframe_Length = (nSubframe_Length>>8) + (nSubframe_Length<<8);
+
+			if(skb->len<(ETHERNET_HEADER_SIZE + nSubframe_Length)) {
+#if 0//cosa
+				RT_ASSERT(
+						(nRemain_Length>=(ETHERNET_HEADER_SIZE + nSubframe_Length)), 
+						("ParseSubframe(): A-MSDU subframe parse error!! Subframe Length: %d\n", nSubframe_Length) );
+#endif
+				printk("%s: A-MSDU parse error!! pRfd->nTotalSubframe : %d\n",\
+						__FUNCTION__,rxb->nr_subframes);
+				printk("%s: A-MSDU parse error!! Subframe Length: %d\n",__FUNCTION__, nSubframe_Length);
+				printk("nRemain_Length is %d and nSubframe_Length is : %d\n",skb->len,nSubframe_Length);
+				printk("The Packet SeqNum is %d\n",SeqNum);
+				return 0;
+			}
+
+			/* move the data point to data content */
+			skb_pull(skb, ETHERNET_HEADER_SIZE);
+
+#ifdef JOHN_NOCPY
+			sub_skb = skb_clone(skb, GFP_ATOMIC);
+			sub_skb->len = nSubframe_Length;
+			sub_skb->tail = sub_skb->data + nSubframe_Length;
+#else
+			/* Allocate new skb for releasing to upper layer */
+			sub_skb = dev_alloc_skb(nSubframe_Length + 12);
+			skb_reserve(sub_skb, 12);
+			data_ptr = (u8 *)skb_put(sub_skb, nSubframe_Length);
+			memcpy(data_ptr,skb->data,nSubframe_Length);
+#endif
+			rxb->subframes[rxb->nr_subframes++] = sub_skb;
+			if(rxb->nr_subframes >= MAX_SUBFRAME_COUNT) {
+				IEEE80211_DEBUG_RX("ParseSubframe(): Too many Subframes! Packets dropped!\n");
+				break;
+			}
+			skb_pull(skb,nSubframe_Length);
+
+			if(skb->len != 0) {
+				nPadding_Length = 4 - ((nSubframe_Length + ETHERNET_HEADER_SIZE) % 4);
+				if(nPadding_Length == 4) {
+					nPadding_Length = 0;
+				}
+
+				if(skb->len < nPadding_Length) {
+					return 0;
+				}
+
+				skb_pull(skb,nPadding_Length);	
+			}			
+		}
+#ifdef JOHN_NOCPY
+		dev_kfree_skb(skb);
+#endif
+		//{just for debug added by david
+		//printk("AMSDU::rxb->nr_subframes = %d\n",rxb->nr_subframes);
+		//}
+		return rxb->nr_subframes;
+	}
+}
+
+/* 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_4addr *hdr;
+	//struct ieee80211_hdr_3addrqos *hdr;
+	
+	size_t hdrlen;
+	u16 fc, type, stype, sc;
+	struct net_device_stats *stats;
+	unsigned int frag;
+	u8 *payload;
+	u16 ethertype;
+	//added by amy for reorder
+	u8	TID = 0;
+	u16	SeqNum = 0;
+	PRX_TS_RECORD pTS = NULL;
+	//bool bIsAggregateFrame = false;
+	//added by amy for reorder
+#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;
+
+	int i;
+	struct ieee80211_rxb* rxb = NULL;
+	// cheat the the hdr type
+	hdr = (struct ieee80211_hdr_4addr *)skb->data;
+	stats = &ieee->stats;
+
+	if (skb->len < 10) {
+		printk(KERN_INFO "%s: SKB length < 10\n",
+		       dev->name);
+		goto rx_dropped;
+	}
+
+	fc = le16_to_cpu(hdr->frame_ctl);
+	type = WLAN_FC_GET_TYPE(fc);
+	stype = WLAN_FC_GET_STYPE(fc);
+	sc = le16_to_cpu(hdr->seq_ctl);
+	
+	frag = WLAN_GET_SEQ_FRAG(sc);
+	hdrlen = ieee80211_get_hdrlen(fc);
+	
+	if(HTCCheck(ieee, skb->data))
+	{
+		if(net_ratelimit())
+		printk("find HTCControl\n");
+		hdrlen += 4;
+		rx_stats->bContainHTC = 1;
+	} 
+  
+	//IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len);	
+#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->rssi;
+		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;
+		crypt = ieee->crypt[idx];
+#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( (ieee->pHTInfo->bCurRxReorderEnable == false) || !ieee->current_network.qos_data.active|| !IsDataFrame(skb->data) || IsLegacyDataFrame(skb->data)){
+		if (is_duplicate_packet(ieee, hdr))
+		goto rx_dropped;
+
+	}
+	else
+	{
+		PRX_TS_RECORD pRxTS = NULL;
+	#if 0
+		struct ieee80211_hdr_3addr *hdr;
+		u16 fc;
+		hdr = (struct ieee80211_hdr_3addr *)skb->data;
+		fc = le16_to_cpu(hdr->frame_ctl);
+		u8 tmp = (fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS);
+		
+		u8 tid = (*((u8*)skb->data + (((fc& IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))?30:24)))&0xf;	
+		printk("====================>fc:%x, tid:%d, tmp:%d\n", fc, tid, tmp);
+		//u8 tid =  (u8)((frameqos*)(buf + ((fc & IEEE80211_FCTL_TODS)&&(fc & IEEE80211_FCTL_FROMDS))? 30 : 24))->field.tid;
+	#endif
+			//IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): QOS ENABLE AND RECEIVE QOS DATA , we will get Ts, tid:%d\n",__FUNCTION__, tid);
+#if 1 
+		if(GetTs(
+				ieee, 
+				(PTS_COMMON_INFO*) &pRxTS, 
+				hdr->addr2, 
+				(u8)Frame_QoSTID((u8*)(skb->data)), 
+				RX_DIR, 
+				true))
+		{
+			
+		//	IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): pRxTS->RxLastFragNum is %d,frag is %d,pRxTS->RxLastSeqNum is %d,seq is %d\n",__FUNCTION__,pRxTS->RxLastFragNum,frag,pRxTS->RxLastSeqNum,WLAN_GET_SEQ_SEQ(sc));
+			if( 	(fc & (1<<11))  && 
+					(frag == pRxTS->RxLastFragNum) && 
+					(WLAN_GET_SEQ_SEQ(sc) == pRxTS->RxLastSeqNum)	)
+			{
+				goto rx_dropped;
+			}
+			else
+			{
+				pRxTS->RxLastFragNum = frag;
+				pRxTS->RxLastSeqNum = WLAN_GET_SEQ_SEQ(sc);
+			}
+		}
+		else
+		{
+			IEEE80211_DEBUG(IEEE80211_DL_ERR, "%s(): No TS!! Skip the check!!\n",__FUNCTION__);
+			goto rx_dropped;
+		}
+	}
+#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
+		
+	//IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len);	
+		if (ieee80211_rx_frame_mgmt(ieee, skb, rx_stats, type, stype))
+			goto rx_dropped;
+		else
+			goto rx_exit;
+	}
+
+	/* 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
+	//IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len);
+	/* 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 */
+
+	if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
+	    (keyidx = ieee80211_rx_frame_decrypt(ieee, skb, crypt)) < 0)
+	{
+		printk("decrypt frame error\n");
+		goto rx_dropped;
+	}
+
+
+	hdr = (struct ieee80211_hdr_4addr *) 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_4addr *) 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))
+	{
+		printk("==>decrypt msdu error\n");
+		goto rx_dropped;
+	}
+
+	//added by amy for AP roaming
+	ieee->LinkDetectInfo.NumRecvDataInPeriod++;
+	ieee->LinkDetectInfo.NumRxOkInPeriod++;
+	
+	hdr = (struct ieee80211_hdr_4addr *) 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, hdrlen)) {
+			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");
+	}
+*/	
+//added by amy for reorder
+#if 1 
+	if(ieee->current_network.qos_data.active && IsQoSDataFrame(skb->data) 
+		&& !is_multicast_ether_addr(hdr->addr1) && !is_broadcast_ether_addr(hdr->addr1))
+	{
+		TID = Frame_QoSTID(skb->data);
+		SeqNum = WLAN_GET_SEQ_SEQ(sc);
+		GetTs(ieee,(PTS_COMMON_INFO*) &pTS,hdr->addr2,TID,RX_DIR,true);
+		if(TID !=0 && TID !=3)
+		{
+			ieee->bis_any_nonbepkts = true;
+		}
+	}
+#endif
+//added by amy for reorder
+	/* skb: hdr + (possible reassembled) full plaintext payload */
+	payload = skb->data + hdrlen;
+	//ethertype = (payload[6] << 8) | payload[7];
+	rxb = (struct ieee80211_rxb*)kmalloc(sizeof(struct ieee80211_rxb),GFP_ATOMIC);
+	if(rxb == NULL)
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR,"%s(): kmalloc rxb error\n",__FUNCTION__);
+		goto rx_dropped;
+	}
+	/* to parse amsdu packets */
+	/* qos data packets & reserved bit is 1 */
+	if(parse_subframe(skb,rx_stats,rxb,src,dst) == 0) {
+		/* only to free rxb, and not submit the packets to upper layer */
+		for(i =0; i < rxb->nr_subframes; i++) {
+			dev_kfree_skb(rxb->subframes[i]);
+		}
+		kfree(rxb);
+		rxb = NULL;
+		goto rx_dropped;
+	}
+
+//added by amy for reorder
+	if(ieee->pHTInfo->bCurRxReorderEnable == false ||pTS == NULL){
+//added by amy for reorder
+		for(i = 0; i<rxb->nr_subframes; i++) {
+			struct sk_buff *sub_skb = rxb->subframes[i];
+
+			if (sub_skb) {
+				/* convert hdr + possible LLC headers into Ethernet header */
+				ethertype = (sub_skb->data[6] << 8) | sub_skb->data[7];
+				if (sub_skb->len >= 8 &&
+						((memcmp(sub_skb->data, rfc1042_header, SNAP_SIZE) == 0 &&
+						  ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
+						 memcmp(sub_skb->data, bridge_tunnel_header, SNAP_SIZE) == 0)) {
+					/* remove RFC1042 or Bridge-Tunnel encapsulation and
+					 * replace EtherType */
+					skb_pull(sub_skb, SNAP_SIZE);
+					memcpy(skb_push(sub_skb, ETH_ALEN), src, ETH_ALEN);
+					memcpy(skb_push(sub_skb, ETH_ALEN), dst, ETH_ALEN);
+				} else {
+					u16 len;
+					/* Leave Ethernet header part of hdr and full payload */
+					len = htons(sub_skb->len);
+					memcpy(skb_push(sub_skb, 2), &len, 2);
+					memcpy(skb_push(sub_skb, ETH_ALEN), src, ETH_ALEN);
+					memcpy(skb_push(sub_skb, ETH_ALEN), dst, ETH_ALEN);
+				}
+
+				stats->rx_packets++;
+				stats->rx_bytes += sub_skb->len;
+				if(is_multicast_ether_addr(dst)) {
+					stats->multicast++;
+				}
+
+				/* Indicat the packets to upper layer */
+				//printk("0skb_len(%d)\n", skb->len);
+				sub_skb->protocol = eth_type_trans(sub_skb, dev);
+				memset(sub_skb->cb, 0, sizeof(sub_skb->cb));
+				sub_skb->dev = dev;
+				sub_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(sub_skb);
+			}
+		}
+		kfree(rxb);
+		rxb = NULL;
+
+	}
+	else
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): REORDER ENABLE AND PTS not NULL, and we will enter RxReorderIndicatePacket()\n",__FUNCTION__);		
+		RxReorderIndicatePacket(ieee, rxb, pTS, SeqNum);
+	}
+#ifndef JOHN_NOCPY
+	dev_kfree_skb(skb);
+#endif
+
+ rx_exit:
+#ifdef NOT_YET
+	if (sta)
+		hostap_handle_sta_release(sta);
+#endif
+	return 1;
+
+ rx_dropped:
+	if (rxb != NULL)
+	{
+		kfree(rxb);
+		rxb = NULL;
+	}		
+	stats->rx_dropped++;
+
+	/* 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;
+}
+
+#define MGMT_FRAME_FIXED_PART_LENGTH            0x24
+
+static u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 };
+
+/*
+* Make ther structure we read from the beacon packet has
+* the right values
+*/
+static int ieee80211_verify_qos_info(struct ieee80211_qos_information_element
+                                     *info_element, int sub_type)
+{
+
+        if (info_element->qui_subtype != sub_type)
+                return -1;
+        if (memcmp(info_element->qui, qos_oui, QOS_OUI_LEN))
+                return -1;
+        if (info_element->qui_type != QOS_OUI_TYPE)
+                return -1;
+        if (info_element->version != QOS_VERSION_1)
+                return -1;
+
+        return 0;
+}
+
+
+/*
+ * Parse a QoS parameter element
+ */
+static int ieee80211_read_qos_param_element(struct ieee80211_qos_parameter_info
+                                            *element_param, struct ieee80211_info_element
+                                            *info_element)
+{
+        int ret = 0;
+        u16 size = sizeof(struct ieee80211_qos_parameter_info) - 2;
+
+        if ((info_element == NULL) || (element_param == NULL))
+                return -1;
+
+        if (info_element->id == QOS_ELEMENT_ID && info_element->len == size) {
+                memcpy(element_param->info_element.qui, info_element->data,
+                       info_element->len);
+                element_param->info_element.elementID = info_element->id;
+                element_param->info_element.length = info_element->len;
+        } else
+                ret = -1;
+        if (ret == 0)
+                ret = ieee80211_verify_qos_info(&element_param->info_element,
+                                                QOS_OUI_PARAM_SUB_TYPE);
+        return ret;
+}
+
+/*
+ * Parse a QoS information element
+ */
+static int ieee80211_read_qos_info_element(struct
+                                           ieee80211_qos_information_element
+                                           *element_info, struct ieee80211_info_element
+                                           *info_element)
+{
+        int ret = 0;
+        u16 size = sizeof(struct ieee80211_qos_information_element) - 2;
+
+        if (element_info == NULL)
+                return -1;
+        if (info_element == NULL)
+                return -1;
+
+        if ((info_element->id == QOS_ELEMENT_ID) && (info_element->len == size)) {
+                memcpy(element_info->qui, info_element->data,
+                       info_element->len);
+                element_info->elementID = info_element->id;
+                element_info->length = info_element->len;
+        } else
+                ret = -1;
+
+        if (ret == 0)
+                ret = ieee80211_verify_qos_info(element_info,
+                                                QOS_OUI_INFO_SUB_TYPE);
+        return ret;
+}
+
+
+/*
+ * Write QoS parameters from the ac parameters.
+ */
+static int ieee80211_qos_convert_ac_to_parameters(struct
+                                                  ieee80211_qos_parameter_info
+                                                  *param_elm, struct
+                                                  ieee80211_qos_parameters
+                                                  *qos_param)
+{
+        int rc = 0;
+        int i;
+        struct ieee80211_qos_ac_parameter *ac_params;
+	u8 aci;
+        //u8 cw_min;
+        //u8 cw_max;
+
+        for (i = 0; i < QOS_QUEUE_NUM; i++) {
+                ac_params = &(param_elm->ac_params_record[i]);
+
+		aci = (ac_params->aci_aifsn & 0x60) >> 5;
+
+		if(aci >= QOS_QUEUE_NUM)
+			continue;
+                qos_param->aifs[aci] = (ac_params->aci_aifsn) & 0x0f;
+
+		/* WMM spec P.11: The minimum value for AIFSN shall be 2 */
+                qos_param->aifs[aci] = (qos_param->aifs[aci] < 2) ? 2:qos_param->aifs[aci]; 
+
+                qos_param->cw_min[aci] = ac_params->ecw_min_max & 0x0F;
+
+                qos_param->cw_max[aci] = (ac_params->ecw_min_max & 0xF0) >> 4;
+
+                qos_param->flag[aci] =
+                    (ac_params->aci_aifsn & 0x10) ? 0x01 : 0x00;
+                qos_param->tx_op_limit[aci] = le16_to_cpu(ac_params->tx_op_limit);
+        }
+        return rc;
+}
+
+/*
+ * we have a generic data element which it may contain QoS information or
+ * parameters element. check the information element length to decide
+ * which type to read
+ */
+static int ieee80211_parse_qos_info_param_IE(struct ieee80211_info_element
+                                             *info_element,
+                                             struct ieee80211_network *network)
+{
+        int rc = 0;
+        struct ieee80211_qos_parameters *qos_param = NULL;
+        struct ieee80211_qos_information_element qos_info_element;
+
+        rc = ieee80211_read_qos_info_element(&qos_info_element, info_element);
+
+        if (rc == 0) {
+                network->qos_data.param_count = qos_info_element.ac_info & 0x0F;
+                network->flags |= NETWORK_HAS_QOS_INFORMATION;
+        } else {
+                struct ieee80211_qos_parameter_info param_element;
+
+                rc = ieee80211_read_qos_param_element(&param_element,
+                                                      info_element);
+                if (rc == 0) {
+                        qos_param = &(network->qos_data.parameters);
+                        ieee80211_qos_convert_ac_to_parameters(&param_element,
+                                                               qos_param);
+                        network->flags |= NETWORK_HAS_QOS_PARAMETERS;
+                        network->qos_data.param_count =
+                            param_element.info_element.ac_info & 0x0F;
+                }
+        }
+
+        if (rc == 0) {
+                IEEE80211_DEBUG_QOS("QoS is supported\n");
+                network->qos_data.supported = 1;
+        }
+        return rc;
+}
+
+#ifdef CONFIG_IEEE80211_DEBUG
+#define MFIE_STRING(x) case MFIE_TYPE_ ##x: return #x
+
+static const char *get_info_element_string(u16 id)
+{
+        switch (id) {
+                MFIE_STRING(SSID);
+                MFIE_STRING(RATES);
+                MFIE_STRING(FH_SET);
+                MFIE_STRING(DS_SET);
+                MFIE_STRING(CF_SET);
+                MFIE_STRING(TIM);
+                MFIE_STRING(IBSS_SET);
+                MFIE_STRING(COUNTRY);
+                MFIE_STRING(HOP_PARAMS);
+                MFIE_STRING(HOP_TABLE);
+                MFIE_STRING(REQUEST);
+                MFIE_STRING(CHALLENGE);
+                MFIE_STRING(POWER_CONSTRAINT);
+                MFIE_STRING(POWER_CAPABILITY);
+                MFIE_STRING(TPC_REQUEST);
+                MFIE_STRING(TPC_REPORT);
+                MFIE_STRING(SUPP_CHANNELS);
+                MFIE_STRING(CSA);
+                MFIE_STRING(MEASURE_REQUEST);
+                MFIE_STRING(MEASURE_REPORT);
+                MFIE_STRING(QUIET);
+                MFIE_STRING(IBSS_DFS);
+               // MFIE_STRING(ERP_INFO);
+                MFIE_STRING(RSN);
+                MFIE_STRING(RATES_EX);
+                MFIE_STRING(GENERIC);
+                MFIE_STRING(QOS_PARAMETER);
+        default:
+                return "UNKNOWN";
+        }
+}
+#endif
+
+#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(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
+
+int ieee80211_parse_info_param(struct ieee80211_device *ieee,
+		struct ieee80211_info_element *info_element, 
+		u16 length,
+		struct ieee80211_network *network,
+		struct ieee80211_rx_stats *stats)
+{
+	u8 i;
+	short offset;
+        u16	tmp_htcap_len=0;
+	u16	tmp_htinfo_len=0;
+	u16 ht_realtek_agg_len=0;
+	u8  ht_realtek_agg_buf[MAX_IE_LEN];
+//	u16 broadcom_len = 0;
+#ifdef CONFIG_IEEE80211_DEBUG
+	char rates_str[64];
+	char *p;
+#endif
+
+	while (length >= sizeof(*info_element)) {
+		if (sizeof(*info_element) + info_element->len > length) {
+			IEEE80211_DEBUG_MGMT("Info elem: parse failed: "
+					     "info_element->len + 2 > left : "
+					     "info_element->len+2=%zd left=%d, id=%d.\n",
+					     info_element->len +
+					     sizeof(*info_element),
+					     length, info_element->id);
+			/* We stop processing but don't return an error here
+			 * because some misbehaviour APs break this rule. ie.
+			 * Orinoco AP1000. */
+			break;
+		}
+
+		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_MGMT("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_MGMT("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_MGMT("MFIE_TYPE_RATES_EX: '%s' (%d)\n",
+					     rates_str, network->rates_ex_len);
+			break;
+
+		case MFIE_TYPE_DS_SET:
+			IEEE80211_DEBUG_MGMT("MFIE_TYPE_DS_SET: %d\n",
+					     info_element->data[0]);
+			network->channel = info_element->data[0];
+			break;
+
+		case MFIE_TYPE_FH_SET:
+			IEEE80211_DEBUG_MGMT("MFIE_TYPE_FH_SET: ignored\n");
+			break;
+
+		case MFIE_TYPE_CF_SET:
+			IEEE80211_DEBUG_MGMT("MFIE_TYPE_CF_SET: ignored\n");
+			break;
+
+		case MFIE_TYPE_TIM:
+			if(info_element->len < 4) 
+				break;
+
+			network->tim.tim_count = info_element->data[0];
+			network->tim.tim_period = info_element->data[1];
+
+                        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 < 8*offset || 
+                                ieee->assoc_id > 8*(offset + info_element->len -3))
+                                
+                                break;
+
+                        offset = (ieee->assoc_id / 8) - offset;// + ((aid % 8)? 0 : 1) ;
+
+                        if(info_element->data[3+offset] & (1<<(ieee->assoc_id%8)))
+                                network->dtim_data |= IEEE80211_DTIM_UCAST;
+
+			//IEEE80211_DEBUG_MGMT("MFIE_TYPE_TIM: partially ignored\n");
+			break;
+
+		case MFIE_TYPE_ERP:
+			network->erp_value = info_element->data[0];
+			network->flags |= NETWORK_HAS_ERP_VALUE;
+			IEEE80211_DEBUG_MGMT("MFIE_TYPE_ERP_SET: %d\n",
+					     network->erp_value);
+			break;
+		case MFIE_TYPE_IBSS_SET:
+			network->atim_window = info_element->data[0];
+			IEEE80211_DEBUG_MGMT("MFIE_TYPE_IBSS_SET: %d\n",
+					     network->atim_window);
+			break;
+
+		case MFIE_TYPE_CHALLENGE:
+			IEEE80211_DEBUG_MGMT("MFIE_TYPE_CHALLENGE: ignored\n");
+			break;
+
+		case MFIE_TYPE_GENERIC:
+			IEEE80211_DEBUG_MGMT("MFIE_TYPE_GENERIC: %d bytes\n",
+					     info_element->len);
+			if (!ieee80211_parse_qos_info_param_IE(info_element,
+							       network))
+				break;
+
+			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);
+				break;
+			}
+
+#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
+
+                        //for HTcap and HTinfo parameters
+			if(tmp_htcap_len == 0){
+				if(info_element->len >= 4 &&
+				   info_element->data[0] == 0x00 &&
+				   info_element->data[1] == 0x90 &&
+				   info_element->data[2] == 0x4c &&
+				   info_element->data[3] == 0x033){
+				   
+						tmp_htcap_len = min(info_element->len,(u8)MAX_IE_LEN);
+				   		if(tmp_htcap_len != 0){
+				   			network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC;
+							network->bssht.bdHTCapLen = tmp_htcap_len > sizeof(network->bssht.bdHTCapBuf)?\
+								sizeof(network->bssht.bdHTCapBuf):tmp_htcap_len;
+							memcpy(network->bssht.bdHTCapBuf,info_element->data,network->bssht.bdHTCapLen);							
+				   		}
+				}
+				if(tmp_htcap_len != 0)
+					network->bssht.bdSupportHT = true;
+				else
+					network->bssht.bdSupportHT = false;
+			}
+			
+			
+			if(tmp_htinfo_len == 0){
+				if(info_element->len >= 4 &&
+					info_element->data[0] == 0x00 &&
+				   	info_element->data[1] == 0x90 &&
+				   	info_element->data[2] == 0x4c &&
+				   	info_element->data[3] == 0x034){
+
+						tmp_htinfo_len = min(info_element->len,(u8)MAX_IE_LEN);
+						if(tmp_htinfo_len != 0){
+							network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC;
+							if(tmp_htinfo_len){
+								network->bssht.bdHTInfoLen = tmp_htinfo_len > sizeof(network->bssht.bdHTInfoBuf)?\
+									sizeof(network->bssht.bdHTInfoBuf):tmp_htinfo_len;
+								memcpy(network->bssht.bdHTInfoBuf,info_element->data,network->bssht.bdHTInfoLen);
+							}
+							
+						}
+						
+				}
+			}
+
+			if(ieee->aggregation){
+				if(network->bssht.bdSupportHT){
+					if(info_element->len >= 4 &&
+						info_element->data[0] == 0x00 &&
+						info_element->data[1] == 0xe0 &&
+						info_element->data[2] == 0x4c &&
+						info_element->data[3] == 0x02){
+
+						ht_realtek_agg_len = min(info_element->len,(u8)MAX_IE_LEN);
+						memcpy(ht_realtek_agg_buf,info_element->data,info_element->len);
+						
+					}
+					if(ht_realtek_agg_len >= 5){
+						network->bssht.bdRT2RTAggregation = true;
+
+						if((ht_realtek_agg_buf[4] == 1) && (ht_realtek_agg_buf[5] & 0x02))
+						network->bssht.bdRT2RTLongSlotTime = true;
+					}
+				}
+
+			}
+
+			//if(tmp_htcap_len !=0  ||  tmp_htinfo_len != 0)
+			{
+				if((info_element->len >= 3 &&
+					 info_element->data[0] == 0x00 &&
+					 info_element->data[1] == 0x05 &&
+					 info_element->data[2] == 0xb5) || 
+					 (info_element->len >= 3 &&
+					 info_element->data[0] == 0x00 &&
+					 info_element->data[1] == 0x0a &&
+					 info_element->data[2] == 0xf7) ||
+					 (info_element->len >= 3 &&
+					 info_element->data[0] == 0x00 &&
+					 info_element->data[1] == 0x10 &&
+					 info_element->data[2] == 0x18)){
+
+						network->broadcom_cap_exist = true;
+
+				}
+			}
+#if 0	
+			if (tmp_htcap_len !=0)
+				{
+					u16 cap_ext = ((PHT_CAPABILITY_ELE)&info_element->data[0])->ExtHTCapInfo;
+					if ((cap_ext & 0x0c00) == 0x0c00)
+						{
+							network->ralink_cap_exist = true;
+						}
+				}
+#endif
+			if(info_element->len >= 3 &&
+				info_element->data[0] == 0x00 &&
+				info_element->data[1] == 0x0c &&
+				info_element->data[2] == 0x43)
+			{
+				network->ralink_cap_exist = true;
+			}
+			else
+				network->ralink_cap_exist = false;
+			//added by amy for atheros AP
+			if((info_element->len >= 3 && 
+				info_element->data[0] == 0x00 &&
+				info_element->data[1] == 0x03 &&
+				info_element->data[2] == 0x7f) ||
+				(info_element->len >= 3 &&
+				info_element->data[0] == 0x00 &&
+				info_element->data[1] == 0x13 &&
+				info_element->data[2] == 0x74))
+			{
+				printk("========>%s(): athros AP is exist\n",__FUNCTION__);
+				network->atheros_cap_exist = true;
+			}
+			else
+				network->atheros_cap_exist = false;
+
+			if(info_element->len >= 3 &&
+				info_element->data[0] == 0x00 &&
+				info_element->data[1] == 0x40 &&
+				info_element->data[2] == 0x96)
+			{
+				network->cisco_cap_exist = true;
+			}
+			else
+				network->cisco_cap_exist = false;
+			//added by amy for LEAP of cisco
+			if(info_element->len > 4 && 
+				info_element->data[0] == 0x00 &&
+				info_element->data[1] == 0x40 &&
+				info_element->data[2] == 0x96 &&
+				info_element->data[3] == 0x01)
+			{
+				if(info_element->len == 6)
+				{
+					memcpy(network->CcxRmState, &info_element[4], 2);
+					if(network->CcxRmState[0] != 0)
+					{
+						network->bCcxRmEnable = true;
+					}
+					else
+						network->bCcxRmEnable = false;
+					//
+					// CCXv4 Table 59-1 MBSSID Masks. 
+					//
+					network->MBssidMask = network->CcxRmState[1] & 0x07;
+					if(network->MBssidMask != 0)
+					{
+						network->bMBssidValid = true;
+						network->MBssidMask = 0xff << (network->MBssidMask);
+						cpMacAddr(network->MBssid, network->bssid);
+						network->MBssid[5] &= network->MBssidMask;
+					}
+					else
+					{
+						network->bMBssidValid = false;
+					}
+				}
+				else
+				{
+					network->bCcxRmEnable = false;
+				}
+			}
+			if(info_element->len > 4  && 
+				info_element->data[0] == 0x00 &&
+				info_element->data[1] == 0x40 &&
+				info_element->data[2] == 0x96 &&
+				info_element->data[3] == 0x03)
+			{
+				if(info_element->len == 5)
+				{
+					network->bWithCcxVerNum = true;
+					network->BssCcxVerNumber = info_element->data[4];
+				}
+				else
+				{
+					network->bWithCcxVerNum = false;
+					network->BssCcxVerNumber = 0;
+				}
+			}
+			break;
+
+		case MFIE_TYPE_RSN:
+			IEEE80211_DEBUG_MGMT("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;
+
+                        //HT related element.	
+		case MFIE_TYPE_HT_CAP:
+			IEEE80211_DEBUG_SCAN("MFIE_TYPE_HT_CAP: %d bytes\n",
+					     info_element->len);
+			tmp_htcap_len = min(info_element->len,(u8)MAX_IE_LEN);
+			if(tmp_htcap_len != 0){
+				network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC;
+				network->bssht.bdHTCapLen = tmp_htcap_len > sizeof(network->bssht.bdHTCapBuf)?\
+					sizeof(network->bssht.bdHTCapBuf):tmp_htcap_len;
+				memcpy(network->bssht.bdHTCapBuf,info_element->data,network->bssht.bdHTCapLen);
+				
+				//If peer is HT, but not WMM, call QosSetLegacyWMMParamWithHT()
+				// windows driver will update WMM parameters each beacon received once connected
+                                // Linux driver is a bit different.
+				network->bssht.bdSupportHT = true;
+			}
+			else
+				network->bssht.bdSupportHT = false;
+			break;
+
+
+		case MFIE_TYPE_HT_INFO:
+			IEEE80211_DEBUG_SCAN("MFIE_TYPE_HT_INFO: %d bytes\n",
+					     info_element->len);
+			tmp_htinfo_len = min(info_element->len,(u8)MAX_IE_LEN);
+			if(tmp_htinfo_len){
+				network->bssht.bdHTSpecVer = HT_SPEC_VER_IEEE;
+				network->bssht.bdHTInfoLen = tmp_htinfo_len > sizeof(network->bssht.bdHTInfoBuf)?\
+					sizeof(network->bssht.bdHTInfoBuf):tmp_htinfo_len;
+				memcpy(network->bssht.bdHTInfoBuf,info_element->data,network->bssht.bdHTInfoLen);
+			}
+			break;
+
+		case MFIE_TYPE_AIRONET:
+			IEEE80211_DEBUG_SCAN("MFIE_TYPE_AIRONET: %d bytes\n",
+					     info_element->len);
+			if(info_element->len >IE_CISCO_FLAG_POSITION)
+			{
+				network->bWithAironetIE = true;
+
+				// CCX 1 spec v1.13, A01.1 CKIP Negotiation (page23):
+				// "A Cisco access point advertises support for CKIP in beacon and probe response packets,
+				//  by adding an Aironet element and setting one or both of the CKIP negotiation bits."
+				if(	(info_element->data[IE_CISCO_FLAG_POSITION]&SUPPORT_CKIP_MIC)	||
+					(info_element->data[IE_CISCO_FLAG_POSITION]&SUPPORT_CKIP_PK)	)
+				{
+		 			network->bCkipSupported = true;
+				}
+				else
+				{
+					network->bCkipSupported = false;
+				}
+			}
+			else
+			{
+				network->bWithAironetIE = false;
+		 		network->bCkipSupported = false;
+			}
+			break;
+		case MFIE_TYPE_QOS_PARAMETER:
+			printk(KERN_ERR
+			       "QoS Error need to parse QOS_PARAMETER IE\n");
+			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, network->bssid);//addr2 is same as addr3 when from an AP
+			break;
+#endif
+/* TODO */
+#if 0
+			/* 802.11h */
+		case MFIE_TYPE_POWER_CONSTRAINT:
+			network->power_constraint = info_element->data[0];
+			network->flags |= NETWORK_HAS_POWER_CONSTRAINT;
+			break;
+
+		case MFIE_TYPE_CSA:
+			network->power_constraint = info_element->data[0];
+			network->flags |= NETWORK_HAS_CSA;
+			break;
+
+		case MFIE_TYPE_QUIET:
+			network->quiet.count = info_element->data[0];
+			network->quiet.period = info_element->data[1];
+			network->quiet.duration = info_element->data[2];
+			network->quiet.offset = info_element->data[3];
+			network->flags |= NETWORK_HAS_QUIET;
+			break;
+
+		case MFIE_TYPE_IBSS_DFS:
+			if (network->ibss_dfs)
+				break;
+			network->ibss_dfs = kmemdup(info_element->data,
+						    info_element->len,
+						    GFP_ATOMIC);
+			if (!network->ibss_dfs)
+				return 1;
+			network->flags |= NETWORK_HAS_IBSS_DFS;
+			break;
+
+		case MFIE_TYPE_TPC_REPORT:
+			network->tpc_report.transmit_power =
+			    info_element->data[0];
+			network->tpc_report.link_margin = info_element->data[1];
+			network->flags |= NETWORK_HAS_TPC_REPORT;
+			break;
+#endif
+		default:
+			IEEE80211_DEBUG_MGMT
+			    ("Unsupported info element: %s (%d)\n",
+			     get_info_element_string(info_element->id),
+			     info_element->id);
+			break;
+		}
+
+		length -= sizeof(*info_element) + info_element->len;
+		info_element =
+		    (struct ieee80211_info_element *)&info_element->
+		    data[info_element->len];
+	}
+
+	if(!network->atheros_cap_exist && !network->broadcom_cap_exist && 
+		!network->cisco_cap_exist && !network->ralink_cap_exist && !network->bssht.bdRT2RTAggregation)
+	{
+		network->unknown_cap_exist = true;
+	}
+	else
+	{
+		network->unknown_cap_exist = false;
+	}
+	return 0;
+}
+
+static inline u8 ieee80211_SignalStrengthTranslate(
+	u8  CurrSS
+	)
+{
+	u8 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.
+	
+	//RT_TRACE(COMP_DBG, DBG_LOUD, ("$$$$$ After Smoothing:  LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
+
+	return RetSS;
+}
+
+long ieee80211_translate_todbm(u8 signal_strength_index	)// 0-100 index.
+{
+	long	signal_power; // in dBm.
+
+	// Translate to dBm (x=0.5y-95).
+	signal_power = (long)((signal_strength_index + 1) >> 1); 
+	signal_power -= 95; 
+
+	return signal_power;
+}
+
+static 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
+
+        network->qos_data.active = 0;
+        network->qos_data.supported = 0;
+        network->qos_data.param_count = 0;
+        network->qos_data.old_param_count = 0;
+
+	/* Pull out fixed field data */
+	memcpy(network->bssid, beacon->header.addr3, ETH_ALEN);
+	network->capability = le16_to_cpu(beacon->capability);
+	network->last_scanned = jiffies;
+	network->time_stamp[0] = le32_to_cpu(beacon->time_stamp[0]);
+	network->time_stamp[1] = le32_to_cpu(beacon->time_stamp[1]);
+	network->beacon_interval = le32_to_cpu(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->erp_value = (network->capability & WLAN_CAPABILITY_IBSS) ?
+            0x3 : 0x0;
+	network->berp_info_valid = false;
+        network->broadcom_cap_exist = false;
+	network->ralink_cap_exist = false;
+	network->atheros_cap_exist = false;
+	network->cisco_cap_exist = false;
+	network->unknown_cap_exist = false;
+#ifdef THOMAS_TURBO
+	network->Turbo_Enable = 0;
+#endif
+#ifdef ENABLE_DOT11D
+	network->CountryIeLen = 0;
+	memset(network->CountryIeBuf, 0, MAX_IE_LEN);
+#endif
+//Initialize HT parameters
+	//ieee80211_ht_initialize(&network->bssht);	
+	HTInitializeBssDesc(&network->bssht);	
+	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;
+
+        if (ieee80211_parse_info_param
+            (ieee,beacon->info_element, stats->len - sizeof(*beacon), network, stats))
+                return 1;
+
+	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(network->bssht.bdSupportHT){
+		if(network->mode == IEEE_A)
+			network->mode = IEEE_N_5G;
+		else if(network->mode & (IEEE_G | IEEE_B))
+			network->mode = IEEE_N_24G;
+	}
+	if (ieee80211_is_empty_essid(network->ssid, network->ssid_len))
+		network->flags |= NETWORK_EMPTY_ESSID;
+
+#if 1	
+	stats->signal = 30 + (stats->SignalStrength * 70) / 100;
+	//stats->signal = ieee80211_SignalStrengthTranslate(stats->signal);
+	stats->noise = ieee80211_translate_todbm((u8)(100-stats->signal)) -25;
+#endif
+
+	memcpy(&network->stats, stats, sizeof(network->stats));
+
+	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) &&
+		(((src->ssid_len == dst->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) &&
+		(src->channel == dst->channel) &&
+		!memcmp(src->bssid, dst->bssid, ETH_ALEN) &&
+		//!memcmp(src->ssid, dst->ssid, src->ssid_len) &&
+		(!memcmp(src->ssid, dst->ssid, src->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) &&
+		((src->capability & WLAN_CAPABILITY_IBSS) == 
+		(dst->capability & WLAN_CAPABILITY_IBSS)) &&
+		((src->capability & WLAN_CAPABILITY_BSS) == 
+		(dst->capability & WLAN_CAPABILITY_BSS)));
+}
+
+static inline void update_network(struct ieee80211_network *dst,
+				  struct ieee80211_network *src)
+{
+	int qos_active;
+	u8 old_param;
+
+	memcpy(&dst->stats, &src->stats, sizeof(struct ieee80211_rx_stats));
+	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;
+	if(src->ssid_len > 0)
+	{
+		memset(dst->ssid, 0, dst->ssid_len);
+		dst->ssid_len = src->ssid_len;
+		memcpy(dst->ssid, src->ssid, src->ssid_len);
+	}
+	dst->mode = src->mode;
+	dst->flags = src->flags;
+	dst->time_stamp[0] = src->time_stamp[0];
+	dst->time_stamp[1] = src->time_stamp[1];
+	if (src->flags & NETWORK_HAS_ERP_VALUE)
+	{
+		dst->erp_value = src->erp_value;
+		dst->berp_info_valid = src->berp_info_valid = true;
+	}
+	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->tim, &src->tim, sizeof(struct ieee80211_tim_parameters));
+	
+        dst->bssht.bdSupportHT = src->bssht.bdSupportHT;
+	dst->bssht.bdRT2RTAggregation = src->bssht.bdRT2RTAggregation;
+	dst->bssht.bdHTCapLen= src->bssht.bdHTCapLen;
+	memcpy(dst->bssht.bdHTCapBuf,src->bssht.bdHTCapBuf,src->bssht.bdHTCapLen);
+	dst->bssht.bdHTInfoLen= src->bssht.bdHTInfoLen;
+	memcpy(dst->bssht.bdHTInfoBuf,src->bssht.bdHTInfoBuf,src->bssht.bdHTInfoLen);
+	dst->bssht.bdHTSpecVer = src->bssht.bdHTSpecVer;
+	dst->bssht.bdRT2RTLongSlotTime = src->bssht.bdRT2RTLongSlotTime;
+	dst->broadcom_cap_exist = src->broadcom_cap_exist;
+	dst->ralink_cap_exist = src->ralink_cap_exist;
+	dst->atheros_cap_exist = src->atheros_cap_exist;
+	dst->cisco_cap_exist = src->cisco_cap_exist;
+	dst->unknown_cap_exist = src->unknown_cap_exist;
+	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;
+	/* qos related parameters */
+	//qos_active = src->qos_data.active;
+	qos_active = dst->qos_data.active;
+	//old_param = dst->qos_data.old_param_count;
+	old_param = dst->qos_data.param_count;
+	if(dst->flags & NETWORK_HAS_QOS_MASK)
+		memcpy(&dst->qos_data, &src->qos_data,
+			sizeof(struct ieee80211_qos_data));
+	else {
+		dst->qos_data.supported = src->qos_data.supported;
+		dst->qos_data.param_count = src->qos_data.param_count;
+	}
+	
+	if(dst->qos_data.supported == 1) {
+		dst->QoS_Enable = 1;
+		if(dst->ssid_len)
+			IEEE80211_DEBUG_QOS
+				("QoS the network %s is QoS supported\n",
+				dst->ssid);
+		else 
+			IEEE80211_DEBUG_QOS
+				("QoS the network is QoS supported\n");
+	}
+	dst->qos_data.active = qos_active;
+	dst->qos_data.old_param_count = old_param;
+
+	/* dst->last_associate is not overwritten */
+#if 1	
+	dst->wmm_info = src->wmm_info; //sure to exist in beacon or probe response frame.
+	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	
+#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
+
+	//added by amy for LEAP
+	dst->bWithAironetIE = src->bWithAironetIE;
+	dst->bCkipSupported = src->bCkipSupported;
+	memcpy(dst->CcxRmState,src->CcxRmState,2);
+	dst->bCcxRmEnable = src->bCcxRmEnable;
+	dst->MBssidMask = src->MBssidMask;
+	dst->bMBssidValid = src->bMBssidValid;
+	memcpy(dst->MBssid,src->MBssid,6);
+	dst->bWithCcxVerNum = src->bWithCcxVerNum;
+	dst->BssCcxVerNumber = src->BssCcxVerNumber;
+
+}
+
+static inline int is_beacon(__le16 fc) 
+{
+	return (WLAN_FC_GET_STYPE(le16_to_cpu(fc)) == IEEE80211_STYPE_BEACON);
+}
+
+static 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[0];
+#endif
+	unsigned long flags;
+	short renew;
+	//u8 wmm_info;
+	
+	memset(&network, 0, sizeof(struct ieee80211_network));
+	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( !IsLegalChannel(ieee, network.channel) )
+		return;
+	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;
+				}
+			}
+		}
+	}		
+#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)) {
+		update_network(&ieee->current_network, &network);
+		if((ieee->current_network.mode == IEEE_N_24G || ieee->current_network.mode == IEEE_G)
+		&& ieee->current_network.berp_info_valid){
+		if(ieee->current_network.erp_value& ERP_UseProtection)
+			ieee->current_network.buseprotection = true;
+		else
+			ieee->current_network.buseprotection = false;
+		}
+		if(is_beacon(beacon->header.frame_ctl))
+		{
+			if(ieee->state == IEEE80211_LINKED)
+				ieee->LinkDetectInfo.NumRecvBcnInPeriod++;
+		}
+		else //hidden AP
+			network.flags = (~NETWORK_EMPTY_ESSID & network.flags)|(NETWORK_EMPTY_ESSID & ieee->current_network.flags);
+	}
+		
+	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
+		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(beacon->header.frame_ctl) == 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);
+	if (is_beacon(beacon->header.frame_ctl)&&is_same_network(&ieee->current_network, &network, ieee)&&\
+		(ieee->state == IEEE80211_LINKED)) {
+		if(ieee->handle_beacon != NULL) {
+			ieee->handle_beacon(ieee->dev,beacon,&ieee->current_network);
+		}	
+	}
+}
+
+void ieee80211_rx_mgt(struct ieee80211_device *ieee,
+		      struct ieee80211_hdr_4addr *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;
+
+	}
+}
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
+EXPORT_SYMBOL(ieee80211_rx_mgt);
+EXPORT_SYMBOL(ieee80211_rx);
+#else
+EXPORT_SYMBOL_NOVERS(ieee80211_rx_mgt);
+EXPORT_SYMBOL_NOVERS(ieee80211_rx);
+#endif
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c
new file mode 100644
index 0000000..4f063c7
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c
@@ -0,0 +1,3529 @@
+/* IEEE 802.11 SoftMAC layer
+ * Copyright (c) 2005 Andrea Merello <andreamrl at 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++ = 4;
+		*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;
+	}
+	
+	/* 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++ = 8;
+		*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
+		*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
+		*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
+		*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
+		*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
+		*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
+		*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
+		*tag++ = IEEE80211_BASIC_RATE_MASK | 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;
+}
+
+u8 MgntQuery_MgntFrameTxRate(struct ieee80211_device *ieee)
+{
+	PRT_HIGH_THROUGHPUT      pHTInfo = ieee->pHTInfo;
+	u8 rate;
+
+	// 2008/01/25 MH For broadcom, MGNT frame set as OFDM 6M.
+	if(pHTInfo->IOTAction & HT_IOT_ACT_MGNT_USE_CCK_6M)
+		rate = 0x0c;    
+	else
+		rate = ieee->basic_rate & 0x7f;
+
+	if(rate == 0){
+		// 2005.01.26, by rcnjko.
+		if(ieee->mode == IEEE_A||
+		   ieee->mode== IEEE_N_5G||
+		   (ieee->mode== IEEE_N_24G&&!pHTInfo->bCurSuppCCK))
+			rate = 0x0c;
+		else
+			rate = 0x02;
+	}
+
+	/*
+	// Data rate of ProbeReq is already decided. Annie, 2005-03-31
+	if( pMgntInfo->bScanInProgress || (pMgntInfo->bDualModeScanStep!=0) )
+	{
+	if(pMgntInfo->dot11CurrentWirelessMode==WIRELESS_MODE_A)
+	rate = 0x0c;
+	else
+	rate = 0x02;
+	}
+	 */
+	return rate;
+}
+
+
+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;
+
+	cb_desc *tcb_desc = (cb_desc *)(skb->cb + 8);
+	spin_lock_irqsave(&ieee->lock, flags);
+	
+	/* called with 2nd param 0, no mgmt lock required */
+	ieee80211_sta_wakeup(ieee,0);
+	
+	tcb_desc->queue_index = MGNT_QUEUE;
+	tcb_desc->data_rate = MgntQuery_MgntFrameTxRate(ieee);	
+        tcb_desc->RATRIndex = 7;
+        tcb_desc->bTxDisableRateFallBack = 1;
+        tcb_desc->bTxUseDriverAssingedRate = 1;
+	
+	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);
+			//dev_kfree_skb_any(skb);//edit by thomas
+		}
+		
+		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]++;
+
+		/* check wether the managed packet queued greater than 5 */
+		if(!ieee->check_nic_enough_desc(ieee->dev,tcb_desc->queue_index)||\
+				(skb_queue_len(&ieee->skb_waitQ[tcb_desc->queue_index]) != 0)||\
+				(ieee->queue_stop) ) {
+			/* insert the skb packet to the management queue */
+			/* as for the completion function, it does not need 
+			 * to check it any more.
+			 * */
+			printk("%s():insert to waitqueue!\n",__FUNCTION__);
+			skb_queue_tail(&ieee->skb_waitQ[tcb_desc->queue_index], skb);
+		} else {
+			//printk("TX packet!\n");
+			ieee->softmac_hard_start_xmit(skb,ieee->dev);
+			//dev_kfree_skb_any(skb);//edit by thomas
+		}
+		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;
+	
+	len = ieee->current_network.ssid_len;
+	
+	rate_len = ieee80211_MFIE_rate_len(ieee);
+	
+	skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
+			    2 + len + rate_len + ieee->tx_headroom);
+	if (!skb) 
+		return NULL;
+
+	skb_reserve(skb, ieee->tx_headroom);
+	
+	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);
+	return skb;
+}
+
+struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee);
+void ieee80211_send_beacon(struct ieee80211_device *ieee)
+{
+	struct sk_buff *skb;
+	if(!ieee->ieee_up)
+		return;		
+	//unsigned long flags;	
+	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
+	}
+//	ieee->beacon_timer.expires = jiffies + 
+//		(MSECS( ieee->current_network.beacon_interval -5));
+	
+	//spin_lock_irqsave(&ieee->beacon_lock,flags);
+	if(ieee->beacon_txing && ieee->ieee_up){
+//		if(!timer_pending(&ieee->beacon_timer))
+//			add_timer(&ieee->beacon_timer);
+		mod_timer(&ieee->beacon_timer,jiffies+(MSECS(ieee->current_network.beacon_interval-5)));
+	}
+	//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);
+}
+
+
+void ieee80211_send_probe(struct ieee80211_device *ieee)
+{
+	struct sk_buff *skb;
+
+	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
+	
+		/* 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;
+		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->state < IEEE80211_LINKED)
+			;
+		else
+		if (ieee->sync_scan_hurryup)
+			goto out;
+
+
+		msleep_interruptible_rsl(IEEE80211_SOFTMAC_SCAN_TIME);
+		
+	}
+out:
+	if(ieee->state < IEEE80211_LINKED){
+		ieee->actscanning = false;
+		up(&ieee->scan_sem);
+	}
+	else{
+	ieee->sync_scan_hurryup = 0;
+#ifdef ENABLE_DOT11D
+	if(IS_DOT11D_ENABLE(ieee))
+		DOT11D_ScanComplete(ieee);
+#endif	
+	up(&ieee->scan_sem);
+}
+}
+
+#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;
+#ifdef ENABLE_DOT11D
+	u8 channel_map[MAX_CHANNEL_NUMBER+1];
+	memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
+#endif
+	if(!ieee->ieee_up)
+		return;	
+	down(&ieee->scan_sem);
+	do{
+		ieee->current_network.channel = 
+			(ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER;
+		if (watchdog++ > MAX_CHANNEL_NUMBER) 
+		{
+		//if current channel is not in channel map, set to default channel.
+		#ifdef ENABLE_DOT11D
+      			if (!channel_map[ieee->current_network.channel]);
+		#else
+			if (!ieee->channel_map[ieee->current_network.channel]);
+		#endif
+				ieee->current_network.channel = 6;
+				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;
+	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 + MSECS(IEEE80211_SOFTMAC_SCAN_TIME);
+	if (ieee->scanning == 1) 
+		mod_timer(&ieee->scan_timer,(jiffies + MSECS(IEEE80211_SOFTMAC_SCAN_TIME)));
+#endif
+
+	up(&ieee->scan_sem);
+	return;
+out:
+#ifdef ENABLE_DOT11D
+	if(IS_DOT11D_ENABLE(ieee))
+		DOT11D_ScanComplete(ieee);
+#endif	
+        ieee->actscanning = false;
+	watchdog = 0;
+	ieee->scanning = 0;
+	up(&ieee->scan_sem);
+}
+
+#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,ieee->basic_rate);
+	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){
+		ieee->scanning = 0;
+
+#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)
+{
+#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)	
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+			queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, 0);
+#else
+
+			queue_work(ieee->wq, &ieee->softmac_scan_wq);
+#endif
+#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)
+{
+#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);
+		
+}
+
+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;
+	int len = sizeof(struct ieee80211_authentication) + challengelen + ieee->tx_headroom;
+
+
+	skb = dev_alloc_skb(len); 
+	if (!skb) return NULL;
+	
+	skb_reserve(skb, ieee->tx_headroom);
+	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;
+	if(ieee->auth_mode == 0)
+		auth->algorithm = WLAN_AUTH_OPEN;
+	else if(ieee->auth_mode == 1)
+		auth->algorithm = WLAN_AUTH_SHARED_KEY;
+	else if(ieee->auth_mode == 2)
+		auth->algorithm = WLAN_AUTH_OPEN;//0x80;
+	printk("=================>%s():auth->algorithm is %d\n",__FUNCTION__,auth->algorithm);
+	auth->transaction = cpu_to_le16(ieee->associate_seq);
+	ieee->associate_seq++;
+	
+	auth->status = cpu_to_le16(WLAN_STATUS_SUCCESS);
+	
+	return skb;
+	
+}
+
+
+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 = NULL;
+	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 = ieee->wpa_ie_len;
+	u8 erpinfo_content = 0;
+
+	u8* tmp_ht_cap_buf;
+	u8 tmp_ht_cap_len=0;
+	u8* tmp_ht_info_buf;
+	u8 tmp_ht_info_len=0;
+	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
+	u8* tmp_generic_ie_buf=NULL;
+	u8 tmp_generic_ie_len=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 1
+	if(ieee80211_is_54g(ieee->current_network)) 
+		erp_len = 3;
+	else
+		erp_len = 0;
+#else
+      if((ieee->current_network.mode == IEEE_G) 
+	  	||( ieee->current_network.mode == IEEE_N_24G && ieee->pHTInfo->bCurSuppCCK)) {
+	  	erp_len = 3;
+		erpinfo_content = 0;
+		if(ieee->current_network.buseprotection)
+			erpinfo_content |= ERP_UseProtection;
+      	}
+	else
+		erp_len = 0;
+#endif
+
+
+	crypt = ieee->crypt[ieee->tx_keyidx];
+
+	
+	encrypt = ieee->host_encrypt && crypt && crypt->ops && 
+		((0 == strcmp(crypt->ops->name, "WEP") || wpa_ie_len));
+	//HT ralated element	
+#if 1	
+	tmp_ht_cap_buf =(u8*) &(ieee->pHTInfo->SelfHTCap);
+	tmp_ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap);
+	tmp_ht_info_buf =(u8*) &(ieee->pHTInfo->SelfHTInfo);
+	tmp_ht_info_len = sizeof(ieee->pHTInfo->SelfHTInfo);
+	HTConstructCapabilityElement(ieee, tmp_ht_cap_buf, &tmp_ht_cap_len,encrypt);
+	HTConstructInfoElement(ieee,tmp_ht_info_buf,&tmp_ht_info_len, encrypt);
+	
+
+        if(pHTInfo->bRegRT2RTAggregation)
+        {
+        	tmp_generic_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer;
+		tmp_generic_ie_len = sizeof(ieee->pHTInfo->szRT2RTAggBuffer);
+		HTConstructRT2RTAggElement(ieee, tmp_generic_ie_buf, &tmp_generic_ie_len);
+        }
+//	printk("===============>tmp_ht_cap_len is %d,tmp_ht_info_len is %d, tmp_generic_ie_len is %d\n",tmp_ht_cap_len,tmp_ht_info_len,tmp_generic_ie_len);	
+#endif
+	beacon_size = sizeof(struct ieee80211_probe_response)+2+
+		ssid_len
+		+3 //channel
+		+rate_len
+		+rate_ex_len
+		+atim_len
+		+erp_len
+                +wpa_ie_len
+	//	+tmp_ht_cap_len
+	//	+tmp_ht_info_len
+	//	+tmp_generic_ie_len
+//		+wmm_len+2
+		+ieee->tx_headroom;
+	skb = dev_alloc_skb(beacon_size);
+	if (!skb) 
+		return NULL;
+	skb_reserve(skb, ieee->tx_headroom);
+	beacon_buf = (struct ieee80211_probe_response*) skb_put(skb, (beacon_size - ieee->tx_headroom));
+	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);
+	beacon_buf->capability |= 
+		cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE); //add short preamble here
+
+	if(ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT))
+		cpu_to_le16((beacon_buf->capability |= WLAN_CAPABILITY_SHORT_SLOT));		
+	
+	crypt = ieee->crypt[ieee->tx_keyidx];
+#if 0
+	encrypt = ieee->host_encrypt && crypt && crypt->ops && 
+		(0 == strcmp(crypt->ops->name, "WEP"));
+#endif
+	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[0].id = MFIE_TYPE_SSID;	
+	beacon_buf->info_element[0].len = ssid_len;
+	
+	tag = (u8*) beacon_buf->info_element[0].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;
+		//*((u16*)(tag)) = cpu_to_le16(ieee->current_network.atim_window);
+		 val16 = 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++) = erpinfo_content; 
+	}
+#if 0	
+	//Include High Throuput capability 
+	
+	*(tag++) = MFIE_TYPE_HT_CAP;
+	*(tag++) = tmp_ht_cap_len - 2;
+	memcpy(tag, tmp_ht_cap_buf, tmp_ht_cap_len - 2);	
+	tag += tmp_ht_cap_len - 2;
+#endif
+	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 0 
+	//Include High Throuput info
+
+	*(tag++) = MFIE_TYPE_HT_INFO;
+	*(tag++) = tmp_ht_info_len - 2;
+	memcpy(tag, tmp_ht_info_buf, tmp_ht_info_len -2);
+	tag += tmp_ht_info_len - 2;
+#endif
+	if (wpa_ie_len)
+	{	
+		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);
+		tag += wpa_ie_len;
+	}
+
+#if 0 
+	//
+	// Construct Realtek Proprietary Aggregation mode (Set AMPDU Factor to 2, 32k)
+	//
+	if(pHTInfo->bRegRT2RTAggregation)
+	{
+		(*tag++) = 0xdd;
+		(*tag++) = tmp_generic_ie_len - 2;
+		memcpy(tag,tmp_generic_ie_buf,tmp_generic_ie_len -2);
+		tag += tmp_generic_ie_len -2;
+		
+	}
+#endif
+#if 0 
+	if(ieee->qos_support)
+	{
+		(*tag++) = 0xdd;
+		(*tag++) = wmm_len;
+		memcpy(tag,QosOui,wmm_len);
+		tag += wmm_len;
+	}
+#endif
+	//skb->dev = ieee->dev;
+	return skb;
+}
+
+
+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 + ieee->tx_headroom;
+	
+	skb = dev_alloc_skb(len); 
+	
+	if (!skb) 
+		return NULL;
+	
+	skb_reserve(skb, ieee->tx_headroom);
+
+	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)
+		crypt = ieee->crypt[ieee->tx_keyidx];
+	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;
+	int len = ieee->tx_headroom + sizeof(struct ieee80211_authentication)+1;
+	
+	skb = dev_alloc_skb(len); 
+	
+	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);
+	
+	memcpy(auth->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
+	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);
+}
+
+
+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);
+}
+
+
+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);
+}
+
+
+inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beacon,struct ieee80211_device *ieee)
+{
+	struct sk_buff *skb;
+	//unsigned long flags;
+	
+	struct ieee80211_assoc_request_frame *hdr;
+	u8 *tag;//,*rsn_ie;
+	//short info_addr = 0;
+	//int i;
+	//u16 suite_count = 0;
+	//u8 suit_select = 0;
+	//unsigned int wpa_len = beacon->wpa_ie_len;
+	//for HT
+	u8* ht_cap_buf = NULL;
+	u8 ht_cap_len=0;
+	u8* realtek_ie_buf=NULL;
+	u8 realtek_ie_len=0;
+	int wpa_ie_len= ieee->wpa_ie_len;
+	unsigned int ckip_ie_len=0;
+	unsigned int ccxrm_ie_len=0;
+	unsigned int cxvernum_ie_len=0;
+	struct ieee80211_crypt_data* crypt;
+	int encrypt;
+	
+	unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
+	unsigned int wmm_info_len = beacon->qos_data.supported?9:0;
+#ifdef THOMAS_TURBO	
+	unsigned int turbo_info_len = beacon->Turbo_Enable?9:0;
+#endif
+
+	int len = 0; 
+                             
+	crypt = ieee->crypt[ieee->tx_keyidx];
+	encrypt = ieee->host_encrypt && crypt && crypt->ops && ((0 == strcmp(crypt->ops->name,"WEP") || wpa_ie_len));
+
+	//Include High Throuput capability && Realtek proprietary  
+	if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT)
+	{
+		ht_cap_buf = (u8*)&(ieee->pHTInfo->SelfHTCap);
+		ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap);
+		HTConstructCapabilityElement(ieee, ht_cap_buf, &ht_cap_len, encrypt);
+		if(ieee->pHTInfo->bCurrentRT2RTAggregation)
+		{
+			realtek_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer;
+			realtek_ie_len = sizeof( ieee->pHTInfo->szRT2RTAggBuffer);
+			HTConstructRT2RTAggElement(ieee, realtek_ie_buf, &realtek_ie_len);
+       	 			
+		}
+	}
+	if(ieee->qos_support){
+		wmm_info_len = beacon->qos_data.supported?9:0;
+	}
+	
+
+	if(beacon->bCkipSupported)
+	{
+		ckip_ie_len = 30+2;
+	}
+	if(beacon->bCcxRmEnable)
+	{	
+		ccxrm_ie_len = 6+2;
+	}
+	if( beacon->BssCcxVerNumber >= 2 )
+	{	
+		cxvernum_ie_len = 5+2;
+	}
+#ifdef THOMAS_TURBO		
+	len = sizeof(struct ieee80211_assoc_request_frame)+ 2
+		+ beacon->ssid_len//essid tagged val
+		+ rate_len//rates tagged val
+		+ wpa_ie_len
+		+ wmm_info_len
+		+ turbo_info_len
+                + ht_cap_len
+		+ realtek_ie_len
+		+ ckip_ie_len
+		+ ccxrm_ie_len
+		+ cxvernum_ie_len
+		+ ieee->tx_headroom;
+#else
+	len = sizeof(struct ieee80211_assoc_request_frame)+ 2
+		+ beacon->ssid_len//essid tagged val
+		+ rate_len//rates tagged val
+		+ wpa_ie_len
+		+ wmm_info_len
+                + ht_cap_len
+		+ realtek_ie_len
+		+ ckip_ie_len
+		+ ccxrm_ie_len
+		+ cxvernum_ie_len
+		+ ieee->tx_headroom;
+#endif
+	
+	skb = dev_alloc_skb(len);
+	
+	if (!skb) 
+		return NULL;
+
+	skb_reserve(skb, ieee->tx_headroom);
+	
+	hdr = (struct ieee80211_assoc_request_frame *)
+		skb_put(skb, sizeof(struct ieee80211_assoc_request_frame)+2);
+	
+	
+	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); //add short_preamble here
+
+	if(ieee->short_slot)
+		hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
+ 	if (wmm_info_len) //QOS
+	hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_QOS);
+
+	hdr->listen_interval = 0xa; //FIXME
+	
+	hdr->info_element[0].id = MFIE_TYPE_SSID;
+
+	hdr->info_element[0].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);
+	// For CCX 1 S13, CKIP. Added by Annie, 2006-08-14.
+	if( beacon->bCkipSupported )
+	{
+		static u8	AironetIeOui[] = {0x00, 0x01, 0x66}; // "4500-client"
+		u8	CcxAironetBuf[30];
+		OCTET_STRING	osCcxAironetIE;
+
+		memset(CcxAironetBuf, 0,30);
+		osCcxAironetIE.Octet = CcxAironetBuf;
+		osCcxAironetIE.Length = sizeof(CcxAironetBuf);
+		//
+		// Ref. CCX test plan v3.61, 3.2.3.1 step 13. 
+		// We want to make the device type as "4500-client". 060926, by CCW.
+		//
+		memcpy(osCcxAironetIE.Octet, AironetIeOui, sizeof(AironetIeOui));
+
+		// CCX1 spec V1.13, A01.1 CKIP Negotiation (page23):
+		// "The CKIP negotiation is started with the associate request from the client to the access point,
+		//  containing an Aironet element with both the MIC and KP bits set."
+		osCcxAironetIE.Octet[IE_CISCO_FLAG_POSITION] |=  (SUPPORT_CKIP_PK|SUPPORT_CKIP_MIC) ;
+		tag = skb_put(skb, ckip_ie_len);
+		*tag++ = MFIE_TYPE_AIRONET;
+		*tag++ = osCcxAironetIE.Length;
+		memcpy(tag,osCcxAironetIE.Octet,osCcxAironetIE.Length);
+		tag += osCcxAironetIE.Length;
+	}
+
+	if(beacon->bCcxRmEnable)
+	{
+		static u8 CcxRmCapBuf[] = {0x00, 0x40, 0x96, 0x01, 0x01, 0x00};
+		OCTET_STRING osCcxRmCap;
+
+		osCcxRmCap.Octet = CcxRmCapBuf;
+		osCcxRmCap.Length = sizeof(CcxRmCapBuf);
+		tag = skb_put(skb,ccxrm_ie_len);
+		*tag++ = MFIE_TYPE_GENERIC;
+		*tag++ = osCcxRmCap.Length;
+		memcpy(tag,osCcxRmCap.Octet,osCcxRmCap.Length);
+		tag += osCcxRmCap.Length;
+	}
+
+	if( beacon->BssCcxVerNumber >= 2 )
+	{
+		u8			CcxVerNumBuf[] = {0x00, 0x40, 0x96, 0x03, 0x00};
+		OCTET_STRING	osCcxVerNum;
+		CcxVerNumBuf[4] = beacon->BssCcxVerNumber;
+		osCcxVerNum.Octet = CcxVerNumBuf;
+		osCcxVerNum.Length = sizeof(CcxVerNumBuf);
+		tag = skb_put(skb,cxvernum_ie_len);
+		*tag++ = MFIE_TYPE_GENERIC;
+		*tag++ = osCcxVerNum.Length;
+		memcpy(tag,osCcxVerNum.Octet,osCcxVerNum.Length);
+		tag += osCcxVerNum.Length;
+	}
+        //HT cap element
+	if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT){
+		if(ieee->pHTInfo->ePeerHTSpecVer != HT_SPEC_VER_EWC)
+		{
+			tag = skb_put(skb, ht_cap_len);
+			*tag++ = MFIE_TYPE_HT_CAP;
+			*tag++ = ht_cap_len - 2;
+			memcpy(tag, ht_cap_buf,ht_cap_len -2);
+			tag += ht_cap_len -2;
+		}
+	}	         
+
+	
+	//choose what wpa_supplicant gives to associate.
+	tag = skb_put(skb, wpa_ie_len);	
+	if (wpa_ie_len){
+		memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
+	}
+
+	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
+
+	if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT){
+		if(ieee->pHTInfo->ePeerHTSpecVer == HT_SPEC_VER_EWC)
+		{
+			tag = skb_put(skb, ht_cap_len);
+			*tag++ = MFIE_TYPE_GENERIC;
+			*tag++ = ht_cap_len - 2;
+			memcpy(tag, ht_cap_buf,ht_cap_len - 2);
+			tag += ht_cap_len -2;
+		}
+
+		if(ieee->pHTInfo->bCurrentRT2RTAggregation){
+			tag = skb_put(skb, realtek_ie_len);
+			*tag++ = MFIE_TYPE_GENERIC;
+			*tag++ = realtek_ie_len - 2;
+			memcpy(tag, realtek_ie_buf,realtek_ie_len -2 );
+		}
+	}
+//	printk("<=====%s(), %p, %p\n", __FUNCTION__, ieee->dev, ieee->dev->dev_addr);
+//	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len);	
+	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);
+	
+	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);
+		mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
+#if 0
+		ieee->associate_timer.expires = jiffies + (HZ / 2);
+		add_timer(&ieee->associate_timer);
+#endif
+		//dev_kfree_skb_any(skb);//edit by thomas
+	}	
+	kfree(challenge);
+}
+
+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);
+		mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
+#if 0
+		ieee->associate_timer.expires = jiffies + (HZ / 2);
+		add_timer(&ieee->associate_timer);
+#endif
+		//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 = 108;
+		printk(KERN_INFO"Using G rates:%d\n", ieee->rate);
+	}else{
+		ieee->rate = 22;
+		printk(KERN_INFO"Using B rates:%d\n", ieee->rate);
+	}
+	if (ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT)
+	{
+		printk("Successfully associated, ht enabled\n");
+		HTOnAssocRsp(ieee);
+	}
+	else
+	{
+		printk("Successfully associated, ht not enabled(%d, %d)\n", ieee->pHTInfo->bCurrentHTSupport, ieee->pHTInfo->bEnableHT);
+		memset(ieee->dot11HTOperationalRateSet, 0, 16);
+		//HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
+	}
+	ieee->LinkDetectInfo.SlotNum = 2 * (1 + ieee->current_network.beacon_interval/500);
+	// To prevent the immediately calling watch_dog after association.
+	if(ieee->LinkDetectInfo.NumRecvBcnInPeriod==0||ieee->LinkDetectInfo.NumRecvDataInPeriod==0 )
+	{
+		ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1;
+		ieee->LinkDetectInfo.NumRecvDataInPeriod= 1;	
+	}
+	ieee->link_change(ieee->dev);
+	if(ieee->is_silent_reset == 0){
+		printk("============>normal associate\n");
+	notify_wx_assoc_event(ieee); 
+	} 
+	else if(ieee->is_silent_reset == 1)
+	{
+		printk("==================>silent reset associate\n");
+		ieee->is_silent_reset = 0;
+	}
+	
+	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);
+
+#if 0
+	for(i = 0; i < 6; i++) {
+	  ieee->seq_ctrl[i] = 0;
+	}
+#endif	
+	ieee->state = IEEE80211_LINKED;
+#if 0
+	if (ieee->pHTInfo->bCurrentHTSupport)
+	{
+		printk("Successfully associated, ht enabled\n");
+		queue_work(ieee->wq, &ieee->ht_onAssRsp);
+	}
+	else
+	{
+		printk("Successfully associated, ht not enabled\n");
+		memset(ieee->dot11HTOperationalRateSet, 0, 16);
+		HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
+	}
+#endif
+	//ieee->UpdateHalRATRTableHandler(dev, ieee->dot11HTOperationalRateSet); 
+#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(), chan:%d\n", __FUNCTION__, ieee->current_network.channel);	
+	//ieee->set_chan(ieee->dev, ieee->current_network.channel);
+	HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
+	
+	ieee->associate_seq = 1;
+	ieee80211_associate_step1(ieee);
+	
+	up(&ieee->wx_sem);
+}
+
+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;
+	
+	/* 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);
+		ssidmatch = (ieee->current_network.ssid_len == net->ssid_len)&&\
+				(!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)) ) ||  
+			/* 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, qos:%d, myHT:%d, networkHT:%d\n",ieee->current_network.ssid,ieee->current_network.channel, ieee->current_network.qos_data.supported, ieee->pHTInfo->bEnableHT, ieee->current_network.bssht.bdSupportHT);
+
+				//ieee->pHTInfo->IOTAction = 0;
+				HTResetIOTSetting(ieee->pHTInfo);
+				if (ieee->iw_mode == IW_MODE_INFRA){
+					/* Join the network for the first time */
+					ieee->AsocRetryCount = 0;	
+					//for HT by amy 080514 
+					if((ieee->current_network.qos_data.supported == 1) &&
+					  // (ieee->pHTInfo->bEnableHT && ieee->current_network.bssht.bdSupportHT))
+					   ieee->current_network.bssht.bdSupportHT)
+/*WB, 2008.09.09:bCurrentHTSupport and bEnableHT two flags are going to put together to check whether we are in HT now, so needn't to check bEnableHT flags here. That's is to say we will set to HT support whenever joined AP has the ability to support HT. And whether we are in HT or not, please check bCurrentHTSupport&&bEnableHT now please.*/
+					{
+					//	ieee->pHTInfo->bCurrentHTSupport = true;
+						HTResetSelfAndSavePeerSetting(ieee, &(ieee->current_network));
+					}
+					else
+					{
+						ieee->pHTInfo->bCurrentHTSupport = false;
+					}
+
+					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{
+					if(ieee80211_is_54g(ieee->current_network) && 
+						(ieee->modulation & IEEE80211_OFDM_MODULATION)){
+						ieee->rate = 108;
+						ieee->SetWirelessMode(ieee->dev, IEEE_G);
+						printk(KERN_INFO"Using G rates\n");
+					}else{
+						ieee->rate = 22;
+						ieee->SetWirelessMode(ieee->dev, IEEE_B);
+						printk(KERN_INFO"Using B rates\n");
+					}
+					memset(ieee->dot11HTOperationalRateSet, 0, 16);
+					//HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
+					ieee->state = IEEE80211_LINKED;
+				}
+			
+		}
+	}
+
+}
+
+void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee)
+{
+	unsigned long flags;
+	struct ieee80211_network *target;
+
+	spin_lock_irqsave(&ieee->lock, flags);
+			
+	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);
+	
+}
+
+
+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 ieee80211_device *ieee, struct sk_buff *skb, int *aid)
+{
+	struct ieee80211_assoc_response_frame *response_head;
+	u16 status_code;
+
+	if (skb->len <  sizeof(struct ieee80211_assoc_response_frame)){ 
+		IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len);
+		return 0xcafe;
+	}
+	
+	response_head = (struct ieee80211_assoc_response_frame*) skb->data;
+	*aid = le16_to_cpu(response_head->aid) & 0x3fff;
+
+	status_code = le16_to_cpu(response_head->status);
+	if((status_code==WLAN_STATUS_ASSOC_DENIED_RATES || \
+	   status_code==WLAN_STATUS_CAPS_UNSUPPORTED)&&
+	   ((ieee->mode == IEEE_G) && 
+	    (ieee->current_network.mode == IEEE_N_24G) &&
+            (ieee->AsocRetryCount++ < (RT_ASOC_RETRY_LIMIT-1)))) {
+                 ieee->pHTInfo->IOTAction |= HT_IOT_ACT_PURE_N_MODE;
+	}else {
+		 ieee->AsocRetryCount = 0;
+	}
+
+	return le16_to_cpu(response_head->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
+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
+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);
+	
+	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;
+	timeout = ieee->current_network.beacon_interval; //should we use ps_timeout value or beacon_interval
+	//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);
+}
+void ieee80211_process_action(struct ieee80211_device* ieee, struct sk_buff* skb)
+{
+	struct ieee80211_hdr* header = (struct ieee80211_hdr*)skb->data;
+	u8* act = ieee80211_get_payload(header);
+	u8 tmp = 0;
+//	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
+	if (act == NULL)
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "error to get payload of action frame\n");
+		return;
+	}
+	tmp = *act;
+	act ++;
+	switch (tmp) 
+	{
+		case ACT_CAT_BA:
+			if (*act == ACT_ADDBAREQ)
+			ieee80211_rx_ADDBAReq(ieee, skb);
+			else if (*act == ACT_ADDBARSP)
+			ieee80211_rx_ADDBARsp(ieee, skb);
+			else if (*act == ACT_DELBA)
+			ieee80211_rx_DELBA(ieee, skb);
+			break;
+		default:
+//			if (net_ratelimit())
+//			IEEE80211_DEBUG(IEEE80211_DL_BA, "unknown action frame(%d)\n", tmp);
+			break;
+	}
+	return;
+	
+}
+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;
+	int chlen=0;
+	int aid;
+	struct ieee80211_assoc_response_frame *assoc_resp;
+//	struct ieee80211_info_element *info_element;
+	bool bSupportNmode = true, bHalfSupportNmode = false; //default support N mode, disable halfNmode
+	
+	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));
+			if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
+				ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATED && 
+				ieee->iw_mode == IW_MODE_INFRA){
+				struct ieee80211_network network_resp;	
+				struct ieee80211_network *network = &network_resp;
+				
+				if (0 == (errcode=assoc_parse(ieee,skb, &aid))){
+					ieee->state=IEEE80211_LINKED;
+					ieee->assoc_id = aid;
+					ieee->softmac_stats.rx_ass_ok++;
+					/* station support qos */
+					/* Let the register setting defaultly with Legacy station */
+					if(ieee->qos_support) {
+						assoc_resp = (struct ieee80211_assoc_response_frame*)skb->data;
+						memset(network, 0, sizeof(*network));
+						if (ieee80211_parse_info_param(ieee,assoc_resp->info_element,\
+									rx_stats->len - sizeof(*assoc_resp),\
+									network,rx_stats)){
+							return 1;
+						}
+						else
+						{	//filling the PeerHTCap. //maybe not neccesary as we can get its info from current_network.
+							memcpy(ieee->pHTInfo->PeerHTCapBuf, network->bssht.bdHTCapBuf, network->bssht.bdHTCapLen);
+							memcpy(ieee->pHTInfo->PeerHTInfoBuf, network->bssht.bdHTInfoBuf, network->bssht.bdHTInfoLen);
+						}
+						if (ieee->handle_assoc_response != NULL)
+							ieee->handle_assoc_response(ieee->dev, (struct ieee80211_assoc_response_frame*)header, network);
+					}
+					ieee80211_associate_complete(ieee);
+				} else {
+					/* aid could not been allocated */
+					ieee->softmac_stats.rx_ass_err++;
+					printk(
+						"Association response status code 0x%x\n",
+						errcode);
+					IEEE80211_DEBUG_MGMT(
+						"Association response status code 0x%x\n",
+						errcode);
+					if(ieee->AsocRetryCount < RT_ASOC_RETRY_LIMIT) {
+#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 {
+						ieee80211_associate_abort(ieee); 
+					}
+				}
+			}
+			break;
+		
+		case IEEE80211_STYPE_ASSOC_REQ:
+		case IEEE80211_STYPE_REASSOC_REQ:
+		
+			if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
+				ieee->iw_mode == IW_MODE_MASTER)
+					
+				ieee80211_rx_assoc_rq(ieee, skb);
+			break;
+			
+		case IEEE80211_STYPE_AUTH:
+		
+			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++;
+								if(!(ieee->pHTInfo->IOTAction&HT_IOT_ACT_PURE_N_MODE))
+								{
+									if (!ieee->GetNmodeSupportBySecCfg(ieee->dev))
+									{
+												// WEP or TKIP encryption
+										if(IsHTHalfNmodeAPs(ieee))
+										{	
+											bSupportNmode = true;
+											bHalfSupportNmode = true;
+										}
+										else
+										{
+											bSupportNmode = false;
+											bHalfSupportNmode = false;
+										}
+									printk("==========>to link with AP using SEC(%d, %d)", bSupportNmode, bHalfSupportNmode);
+									}
+								}								
+								/* Dummy wirless mode setting to avoid encryption issue */
+								if(bSupportNmode) {
+									//N mode setting
+									ieee->SetWirelessMode(ieee->dev, \
+											ieee->current_network.mode);
+								}else{
+									//b/g mode setting
+									/*TODO*/
+									ieee->SetWirelessMode(ieee->dev, IEEE_G);
+								}
+
+								if (ieee->current_network.mode == IEEE_N_24G && bHalfSupportNmode == true)
+								{
+									printk("===============>entern half N mode\n");
+									ieee->bHalfWirelessN24GMode = true;
+								}
+								else
+									ieee->bHalfWirelessN24GMode = false;
+								
+								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:
+
+			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:
+			/* 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);
+				//HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
+				RemovePeerTS(ieee, header->addr2); 	
+#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;
+		case IEEE80211_STYPE_MANAGE_ACT:
+			ieee80211_process_action(ieee,skb);
+			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 int queue_index = txb->queue_index;
+	unsigned long flags;
+	int  i;
+	cb_desc *tcb_desc = NULL;
+
+	spin_lock_irqsave(&ieee->lock,flags);
+
+	/* called with 2nd parm 0, no tx mgmt lock required */
+	ieee80211_sta_wakeup(ieee,0);
+
+	/* update the tx status */
+	ieee->stats.tx_bytes += txb->payload_size;
+	ieee->stats.tx_packets++;
+	tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
+	if(tcb_desc->bMulticast) {
+		ieee->stats.multicast++;
+	}
+#if 1
+	/* if xmit available, just xmit it immediately, else just insert it to the wait queue */
+	for(i = 0; i < txb->nr_frags; i++) {
+#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
+		if ((skb_queue_len(&ieee->skb_drv_aggQ[queue_index]) != 0) ||
+#else
+		if ((skb_queue_len(&ieee->skb_waitQ[queue_index]) != 0) ||
+#endif
+		(!ieee->check_nic_enough_desc(ieee->dev,queue_index))||\
+		     (ieee->queue_stop)) {
+			/* insert the skb packet to the wait queue */
+			/* as for the completion function, it does not need 
+			 * to check it any more.
+			 * */
+			//printk("error:no descriptor left at queue_index %d\n", queue_index);
+			//ieee80211_stop_queue(ieee);
+#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
+			skb_queue_tail(&ieee->skb_drv_aggQ[queue_index], txb->fragments[i]);
+#else
+			skb_queue_tail(&ieee->skb_waitQ[queue_index], txb->fragments[i]);
+#endif
+		}else{
+			ieee->softmac_data_hard_start_xmit(
+					txb->fragments[i],
+					ieee->dev,ieee->rate);
+			//ieee->stats.tx_packets++;
+			//ieee->stats.tx_bytes += txb->fragments[i]->len;
+			//ieee->dev->trans_start = jiffies; 
+		}
+	}	
+#endif
+	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]++;
+
+			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;
+	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
+	 */
+	if(!ieee->proto_started){
+		printk("==========oh driver down return\n");
+		return;
+	}
+	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;
+	} 
+	
+	/* check if we have this cell in our network list */
+	ieee80211_softmac_check_all_nets(ieee);
+	
+
+#ifdef ENABLE_DOT11D //if creating an ad-hoc, set its channel to 10 temporarily--this is the requirement for ASUS, not 11D, so disable 11d.
+//	if((IS_DOT11D_ENABLE(ieee)) && (ieee->state == IEEE80211_NOLINK))
+	if (ieee->state == IEEE80211_NOLINK)
+		ieee->current_network.channel = 6;
+#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"); 
+		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 = 108;
+		}else{
+			ieee->current_network.rates_ex_len = 0;
+			ieee->rate = 22;
+		}
+
+		// By default, WMM function will be disabled in IBSS mode
+		ieee->current_network.QoS_Enable = 0;
+		ieee->SetWirelessMode(ieee->dev, IEEE_G);	
+		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;
+		
+	ieee->set_chan(ieee->dev, ieee->current_network.channel);
+	ieee->link_change(ieee->dev);
+	
+	notify_wx_assoc_event(ieee);
+	
+	ieee80211_start_send_beacons(ieee);
+	
+	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);
+#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;
+#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	
+	/* 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.
+	 */
+	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){
+		ieee->actscanning = true;
+		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->is_set_key = false;
+	ieee->link_change(ieee->dev);
+	//HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
+	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)
+		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;
+	struct ieee80211_probe_response *b;
+	
+	skb = ieee80211_probe_resp(ieee, broadcast_addr);
+	
+	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;
+	
+	skb = ieee80211_get_beacon_(ieee);
+	if(!skb) 
+		return NULL;
+		
+	b = (struct ieee80211_probe_response *) skb->data;	
+	b->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]++;
+	
+	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;
+	
+	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);
+#endif	
+	ieee80211_stop_scan(ieee);
+
+	ieee80211_disassociate(ieee);
+	RemoveAllTS(ieee); //added as we disconnect from the previous BSS, Remove all TS
+}
+
+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;
+		
+	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;
+//	printk("===>%s(), chan:%d\n", __FUNCTION__, ieee->current_network.channel);	
+//	ieee->set_chan(ieee->dev,ieee->current_network.channel);
+	
+       	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);
+		
+	else if (ieee->iw_mode == IW_MODE_ADHOC)
+		ieee80211_start_ibss(ieee);
+		
+	else if (ieee->iw_mode == IW_MODE_MASTER)
+		ieee80211_start_master_bss(ieee);
+		
+	else if(ieee->iw_mode == IW_MODE_MONITOR)
+		ieee80211_start_monitor_mode(ieee);	
+}
+
+
+#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;
+	}
+#ifdef ENABLE_DOT11D
+	ieee->pDot11dInfo = kmalloc(sizeof(RT_DOT11D_INFO), GFP_ATOMIC);
+	if (!ieee->pDot11dInfo)
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for DOT11D\n");
+	memset(ieee->pDot11dInfo, 0, sizeof(RT_DOT11D_INFO));
+#endif
+	//added for  AP roaming
+	ieee->LinkDetectInfo.SlotNum = 2;
+	ieee->LinkDetectInfo.NumRecvBcnInPeriod=0;
+        ieee->LinkDetectInfo.NumRecvDataInPeriod=0;
+
+	ieee->assoc_id = 0;
+	ieee->queue_stop = 0;
+	ieee->scanning = 0;
+	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 = 22;
+	ieee->ps = IEEE80211_PS_DISABLED;
+	ieee->sta_sleep = 0;
+	ieee->Regdot11HTOperationalRateSet[0]= 0xff;//support MCS 0~7
+	ieee->Regdot11HTOperationalRateSet[1]= 0xff;//support MCS 8~15
+	ieee->Regdot11HTOperationalRateSet[4]= 0x01;
+	//added by amy
+	ieee->actscanning = false;
+	ieee->beinretry = false;
+	ieee->is_set_key = false;
+	init_mgmt_queue(ieee);
+
+	ieee->sta_edca_param[0] = 0x0000A403;
+	ieee->sta_edca_param[1] = 0x0000A427;
+	ieee->sta_edca_param[2] = 0x005E4342;
+	ieee->sta_edca_param[3] = 0x002F3262;
+	ieee->aggregation = true;
+	ieee->enable_rx_imm_BA = 1;
+#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)
+        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);
+
+#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);
+#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);
+#endif
+	sema_init(&ieee->wx_sem, 1);
+	sema_init(&ieee->scan_sem, 1);
+	
+	spin_lock_init(&ieee->mgmt_tx_lock);
+	spin_lock_init(&ieee->beacon_lock);
+	
+	tasklet_init(&ieee->ps_task,
+	     (void(*)(unsigned long)) ieee80211_sta_ps,
+	     (unsigned long)ieee);
+
+}
+
+void ieee80211_softmac_free(struct ieee80211_device *ieee)
+{
+	down(&ieee->wx_sem);
+#ifdef ENABLE_DOT11D
+	if(NULL != ieee->pDot11dInfo)
+	{
+		kfree(ieee->pDot11dInfo);
+		ieee->pDot11dInfo = NULL;
+	}
+#endif
+	del_timer_sync(&ieee->associate_timer);
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)	
+	cancel_delayed_work(&ieee->associate_retry_wq);
+	destroy_workqueue(ieee->wq);
+#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;
+		ieee->auth_mode = 1;
+	} else if (value & AUTH_ALG_OPEN_SYSTEM){
+		sec.auth_mode = WLAN_AUTH_OPEN;
+		ieee->open_wep = 1;
+		ieee->auth_mode = 0;
+	}
+	else if (value & IW_AUTH_ALG_LEAP){
+		sec.auth_mode = WLAN_AUTH_LEAP;
+		ieee->open_wep = 1;
+		ieee->auth_mode = 2;
+	}
+
+
+	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
+		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;
+		crypt = &ieee->crypt[param->u.crypt.idx];
+	} 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);
+		//set WEP40 first, it will be modified according to WEP104 or WEP40 at other place
+	} 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;
+	}
+
+	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;
+	}
+
+ 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);
+
+	/* 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;
+}
+
+inline struct sk_buff *ieee80211_disassociate_skb(
+							struct ieee80211_network *beacon,
+							struct ieee80211_device *ieee,
+							u8	asRsn)
+{
+	struct sk_buff *skb;
+	struct ieee80211_disassoc *disass;
+
+	skb = dev_alloc_skb(sizeof(struct ieee80211_disassoc));
+	if (!skb) 
+		return NULL;
+	
+	disass = (struct ieee80211_disassoc *) skb_put(skb,sizeof(struct ieee80211_disassoc));
+	disass->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_DISASSOC);
+	disass->header.duration_id = 0;
+	
+	memcpy(disass->header.addr1, beacon->bssid, ETH_ALEN);
+	memcpy(disass->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
+	memcpy(disass->header.addr3, beacon->bssid, ETH_ALEN);
+	
+	disass->reason = asRsn;
+	return skb;
+}
+
+
+void
+SendDisassociation(
+		struct ieee80211_device *ieee,
+		u8* 					asSta,
+		u8						asRsn
+)
+{
+		struct ieee80211_network *beacon = &ieee->current_network;
+		struct sk_buff *skb;
+		skb = ieee80211_disassociate_skb(beacon,ieee,asRsn);
+		if (skb){
+				softmac_mgmt_xmit(skb, ieee);
+				//dev_kfree_skb_any(skb);//edit by thomas
+		}
+}
+
+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(ieee80211_softmac_xmit);
+EXPORT_SYMBOL(ieee80211_stop_send_beacons);
+EXPORT_SYMBOL(notify_wx_assoc_event);
+EXPORT_SYMBOL(SendDisassociation);
+EXPORT_SYMBOL(ieee80211_disassociate);
+EXPORT_SYMBOL(ieee80211_start_send_beacons);
+EXPORT_SYMBOL(ieee80211_stop_scan);
+EXPORT_SYMBOL(ieee80211_send_probe_requests);
+EXPORT_SYMBOL(ieee80211_softmac_scan_syncro);
+EXPORT_SYMBOL(ieee80211_start_scan_syncro);
+#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_softmac_xmit);
+EXPORT_SYMBOL_NOVERS(ieee80211_stop_send_beacons);
+EXPORT_SYMBOL_NOVERS(notify_wx_assoc_event);
+EXPORT_SYMBOL_NOVERS(SendDisassociation);
+EXPORT_SYMBOL_NOVERS(ieee80211_disassociate);
+EXPORT_SYMBOL_NOVERS(ieee80211_start_send_beacons);
+EXPORT_SYMBOL_NOVERS(ieee80211_stop_scan);
+EXPORT_SYMBOL_NOVERS(ieee80211_send_probe_requests);
+EXPORT_SYMBOL_NOVERS(ieee80211_softmac_scan_syncro);
+EXPORT_SYMBOL_NOVERS(ieee80211_start_scan_syncro);
+#endif
+//EXPORT_SYMBOL(ieee80211_sta_ps_send_null_frame);
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac_wx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac_wx.c
new file mode 100644
index 0000000..c3a06e0
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac_wx.c
@@ -0,0 +1,693 @@
+/* IEEE 802.11 SoftMAC layer
+ * Copyright (c) 2005 Andrea Merello <andreamrl at 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 (!(GET_DOT11D_INFO(ieee)->channel_map)[fwrq->m]) {
+			ret = -EINVAL;
+			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;
+	//NM 0.7.0 will not accept channel any more.
+	fwrq->m = ieee80211_wlan_frequencies[ieee->current_network.channel-1] * 100000;
+	fwrq->e = 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)
+{
+	u32 tmp_rate;
+#if 0
+	printk("===>mode:%d, halfNmode:%d\n", ieee->mode, ieee->bHalfWirelessN24GMode);
+	if (ieee->mode & (IEEE_A | IEEE_B | IEEE_G))
+		tmp_rate = ieee->rate;
+	else if (ieee->mode & IEEE_N_5G)
+		tmp_rate = 580;
+	else if (ieee->mode & IEEE_N_24G)
+	{
+		if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev))
+			tmp_rate = HTHalfMcsToDataRate(ieee, 15);
+		else
+			tmp_rate = HTMcsToDataRate(ieee, 15);
+	}
+#else
+	tmp_rate = TxCountToDataRate(ieee, ieee->softmac_stats.CurrentShowTxate);
+	
+#endif
+	wrqu->bitrate.value = tmp_rate * 500000;
+	
+	return 0;
+}
+
+
+int ieee80211_wx_set_rts(struct ieee80211_device *ieee, 
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra)
+{
+	if (wrqu->rts.disabled || !wrqu->rts.fixed)
+		ieee->rts = DEFAULT_RTS_THRESHOLD;
+	else
+	{
+		if (wrqu->rts.value < MIN_RTS_THRESHOLD ||
+				wrqu->rts.value > MAX_RTS_THRESHOLD) 
+			return -EINVAL;
+		ieee->rts = wrqu->rts.value;
+	}
+	return 0;
+}
+
+int ieee80211_wx_get_rts(struct ieee80211_device *ieee, 
+			     struct iw_request_info *info, 
+			     union iwreq_data *wrqu, char *extra)
+{
+	wrqu->rts.value = ieee->rts;
+	wrqu->rts.fixed = 0;	/* no auto select */
+	wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD);
+	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);
+	
+	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;
+	HT_EXTCHNL_OFFSET chan_offset=0;
+	HT_CHANNEL_WIDTH bandwidth=0;
+	int b40M = 0;
+	static int count = 0;
+	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);
+	ieee->InitialGainHandler(ieee->dev,IG_Backup);
+	if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT && ieee->pHTInfo->bCurBW40MHz) {
+		b40M = 1;
+		chan_offset = ieee->pHTInfo->CurSTAExtChnlOffset;
+		bandwidth = (HT_CHANNEL_WIDTH)ieee->pHTInfo->bCurBW40MHz;
+		printk("Scan in 40M, force to 20M first:%d, %d\n", chan_offset, bandwidth);
+		ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
+		}
+	ieee80211_start_scan_syncro(ieee);
+	if (b40M) {
+		printk("Scan in 20M, back to 40M\n");
+		if (chan_offset == HT_EXTCHNL_OFFSET_UPPER)
+			ieee->set_chan(ieee->dev, chan + 2);
+		else if (chan_offset == HT_EXTCHNL_OFFSET_LOWER)
+			ieee->set_chan(ieee->dev, chan - 2);
+		else
+			ieee->set_chan(ieee->dev, chan);
+		ieee->SetBWModeHandler(ieee->dev, bandwidth, chan_offset);
+	} else {
+		ieee->set_chan(ieee->dev, chan);
+	}
+	
+	ieee->InitialGainHandler(ieee->dev,IG_Restore);
+	ieee->state = IEEE80211_LINKED;
+	ieee->link_change(ieee->dev);
+	// To prevent the immediately calling watch_dog after scan.
+	if(ieee->LinkDetectInfo.NumRecvBcnInPeriod==0||ieee->LinkDetectInfo.NumRecvDataInPeriod==0 )
+	{
+		ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1;
+		ieee->LinkDetectInfo.NumRecvDataInPeriod= 1;	
+	}
+	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);
+	count = 0;	
+	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);
+	
+	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) {
+		//first flush current network.ssid
+		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;
+#if 0
+		{
+			int i;
+			for (i=0; i<len; i++)
+				printk("%c ", extra[i]);
+			printk("\n");
+		}
+#endif
+#else
+		strncpy(ieee->current_network.ssid, extra, len+1);
+		ieee->current_network.ssid_len = len+1;
+#if 0
+		{
+			int i;
+			for (i=0; i<len + 1; i++)
+				printk("%c ", extra[i]);
+			printk("\n");
+		}
+#endif
+#endif
+		ieee->ssid_set = 1;
+	}
+	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->mode & (IEEE_N_24G | IEEE_N_5G))
+		strcat(wrqu->name, "/n");
+	
+	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 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;
+	}
+#endif	
+	down(&ieee->wx_sem);
+	
+	if (wrqu->power.disabled){
+		ieee->ps = IEEE80211_PS_DISABLED;
+		goto exit;
+	}
+	if (wrqu->power.flags & IW_POWER_TIMEOUT) {
+		//ieee->ps_period = wrqu->power.value / 1000;
+		ieee->ps_timeout = wrqu->power.value / 1000;
+	}
+	
+	if (wrqu->power.flags & IW_POWER_PERIOD) {
+		
+		//ieee->ps_timeout = wrqu->power.value / 1000;
+		ieee->ps_period = wrqu->power.value / 1000;
+		//wrq->value / 1024;
+		
+	}
+	switch (wrqu->power.flags & IW_POWER_MODE) {
+	case IW_POWER_UNICAST_R:
+		ieee->ps = IEEE80211_PS_UNICAST;
+		break;
+	case IW_POWER_MULTICAST_R:
+		ieee->ps = IEEE80211_PS_MBCAST;
+		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;
+		
+	}
+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->ps_period * 1000; 
+//ieee->current_network.dtim_period * ieee->current_network.beacon_interval * 1024;
+	}
+
+       if ((ieee->ps & (IEEE80211_PS_MBCAST | IEEE80211_PS_UNICAST)) == (IEEE80211_PS_MBCAST | IEEE80211_PS_UNICAST))
+	   	wrqu->power.flags |= IW_POWER_ALL_R;
+	else if (ieee->ps & IEEE80211_PS_MBCAST)
+		wrqu->power.flags |= IW_POWER_MULTICAST_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);
+EXPORT_SYMBOL(ieee80211_wx_set_rts);
+EXPORT_SYMBOL(ieee80211_wx_get_rts);
+#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);
+EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_rts);
+EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_rts);
+#endif
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c
new file mode 100644
index 0000000..f3c0603
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c
@@ -0,0 +1,929 @@
+/******************************************************************************
+
+  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 at 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 at 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 = ieee->crypt[ieee->tx_keyidx];
+	int res;
+	
+	if (!(crypt && crypt->ops))
+	{
+		printk("=========>%s(), crypt is null\n", __FUNCTION__);
+		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;
+#if 0
+	for (i = 0; i < txb->nr_frags; i++)
+		if (txb->fragments[i])
+			dev_kfree_skb_any(txb->fragments[i]);
+#endif
+	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;
+		}
+		memset(txb->fragments[i]->cb, 0, sizeof(txb->fragments[i]->cb));
+	}
+	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 ethhdr *eth;
+	struct iphdr *ip;
+	eth = (struct ethhdr *)skb->data;
+	if (eth->h_proto != htons(ETH_P_IP))
+		return 0;
+
+//	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22))
+	ip = ip_hdr(skb);
+#else
+	ip = (struct iphdr*)(skb->data + sizeof(struct ether_header));
+#endif
+	switch (ip->tos & 0xfc) {
+		case 0x20:
+			return 2;
+		case 0x40:
+			return 1;
+		case 0x60:
+			return 3;
+		case 0x80:
+			return 4;
+		case 0xa0:
+			return 5;
+		case 0xc0:
+			return 6;
+		case 0xe0:
+			return 7;
+		default:
+			return 0;
+	}
+}
+
+#define SN_LESS(a, b)		(((a-b)&0x800)!=0)
+void ieee80211_tx_query_agg_cap(struct ieee80211_device* ieee, struct sk_buff* skb, cb_desc* tcb_desc)
+{
+	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
+	PTX_TS_RECORD			pTxTs = NULL;
+	struct ieee80211_hdr_1addr* hdr = (struct ieee80211_hdr_1addr*)skb->data;
+
+	if (!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
+		return;
+	if (!IsQoSDataFrame(skb->data))
+		return;
+
+	if (is_multicast_ether_addr(hdr->addr1) || is_broadcast_ether_addr(hdr->addr1))
+		return;
+	//check packet and mode later
+#ifdef TO_DO_LIST
+	if(pTcb->PacketLength >= 4096)
+		return;
+	// For RTL819X, if pairwisekey = wep/tkip, we don't aggrregation.
+	if(!Adapter->HalFunc.GetNmodeSupportBySecCfgHandler(Adapter))
+		return; 
+#endif
+#if 1
+	if(!ieee->GetNmodeSupportBySecCfg(ieee->dev))
+	{
+		return; 
+	}
+#endif
+	if(pHTInfo->bCurrentAMPDUEnable)
+	{
+		if (!GetTs(ieee, (PTS_COMMON_INFO*)(&pTxTs), hdr->addr1, skb->priority, TX_DIR, true))
+		{
+			printk("===>can't get TS\n");
+			return;
+		}
+		if (pTxTs->TxAdmittedBARecord.bValid == false)
+		{
+			TsStartAddBaProcess(ieee, pTxTs);
+			goto FORCED_AGG_SETTING;
+		}
+		else if (pTxTs->bUsingBa == false)
+		{
+			if (SN_LESS(pTxTs->TxAdmittedBARecord.BaStartSeqCtrl.field.SeqNum, (pTxTs->TxCurSeq+1)%4096))
+				pTxTs->bUsingBa = true;
+			else
+				goto FORCED_AGG_SETTING;
+		}
+
+		if (ieee->iw_mode == IW_MODE_INFRA)
+		{
+			tcb_desc->bAMPDUEnable = true;
+			tcb_desc->ampdu_factor = pHTInfo->CurrentAMPDUFactor;
+			tcb_desc->ampdu_density = pHTInfo->CurrentMPDUDensity;
+		}
+	}
+FORCED_AGG_SETTING:
+	switch(pHTInfo->ForcedAMPDUMode )
+	{
+		case HT_AGG_AUTO:
+			break;
+
+		case HT_AGG_FORCE_ENABLE:
+			tcb_desc->bAMPDUEnable = true;
+			tcb_desc->ampdu_density = pHTInfo->ForcedMPDUDensity;
+			tcb_desc->ampdu_factor = pHTInfo->ForcedAMPDUFactor;
+			break;
+
+		case HT_AGG_FORCE_DISABLE:
+			tcb_desc->bAMPDUEnable = false;
+			tcb_desc->ampdu_density = 0;
+			tcb_desc->ampdu_factor = 0;
+			break;
+
+	}	
+		return;
+}
+
+extern void ieee80211_qurey_ShortPreambleMode(struct ieee80211_device* ieee, cb_desc* tcb_desc)
+{
+	tcb_desc->bUseShortPreamble = false;
+	if (tcb_desc->data_rate == 2)
+	{//// 1M can only use Long Preamble. 11B spec
+		return;
+	}
+	else if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
+	{
+		tcb_desc->bUseShortPreamble = true;
+	}
+	return;	
+}
+extern	void	
+ieee80211_query_HTCapShortGI(struct ieee80211_device *ieee, cb_desc *tcb_desc)
+{
+	PRT_HIGH_THROUGHPUT		pHTInfo = ieee->pHTInfo;
+
+	tcb_desc->bUseShortGI 		= false;
+
+	if(!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
+		return;
+
+	if(pHTInfo->bForcedShortGI)
+	{
+		tcb_desc->bUseShortGI = true;
+		return;
+	}
+
+	if((pHTInfo->bCurBW40MHz==true) && pHTInfo->bCurShortGI40MHz)
+		tcb_desc->bUseShortGI = true;
+	else if((pHTInfo->bCurBW40MHz==false) && pHTInfo->bCurShortGI20MHz)
+		tcb_desc->bUseShortGI = true;
+}
+
+void ieee80211_query_BandwidthMode(struct ieee80211_device* ieee, cb_desc *tcb_desc)
+{
+	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
+
+	tcb_desc->bPacketBW = false;
+
+	if(!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
+		return;
+
+	if(tcb_desc->bMulticast || tcb_desc->bBroadcast)
+		return;
+
+	if((tcb_desc->data_rate & 0x80)==0) // If using legacy rate, it shall use 20MHz channel.
+		return;
+	//BandWidthAutoSwitch is for auto switch to 20 or 40 in long distance
+	if(pHTInfo->bCurBW40MHz && pHTInfo->bCurTxBW40MHz && !ieee->bandwidth_auto_switch.bforced_tx20Mhz)
+		tcb_desc->bPacketBW = true;
+	return;
+}
+
+void ieee80211_query_protectionmode(struct ieee80211_device* ieee, cb_desc* tcb_desc, struct sk_buff* skb)
+{
+	// Common Settings
+	tcb_desc->bRTSSTBC			= false;
+	tcb_desc->bRTSUseShortGI		= false; // Since protection frames are always sent by legacy rate, ShortGI will never be used.
+	tcb_desc->bCTSEnable			= false; // Most of protection using RTS/CTS
+	tcb_desc->RTSSC				= 0;		// 20MHz: Don't care;  40MHz: Duplicate.
+	tcb_desc->bRTSBW			= false; // RTS frame bandwidth is always 20MHz
+	
+	if(tcb_desc->bBroadcast || tcb_desc->bMulticast)//only unicast frame will use rts/cts
+		return;
+	
+	if (is_broadcast_ether_addr(skb->data+16))  //check addr3 as infrastructure add3 is DA.
+		return;
+
+	if (ieee->mode < IEEE_N_24G) //b, g mode
+	{
+			// (1) RTS_Threshold is compared to the MPDU, not MSDU.
+			// (2) If there are more than one frag in  this MSDU, only the first frag uses protection frame.
+			//		Other fragments are protected by previous fragment.
+			//		So we only need to check the length of first fragment.
+		if (skb->len > ieee->rts)
+		{
+			tcb_desc->bRTSEnable = true;
+			tcb_desc->rts_rate = MGN_24M;
+		}
+		else if (ieee->current_network.buseprotection)
+		{
+			// Use CTS-to-SELF in protection mode.
+			tcb_desc->bRTSEnable = true;
+			tcb_desc->bCTSEnable = true;
+			tcb_desc->rts_rate = MGN_24M;
+		}
+		//otherwise return;
+		return;
+	}
+	else
+	{// 11n High throughput case.
+		PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
+		while (true)
+		{
+			//check ERP protection
+			if (ieee->current_network.buseprotection)
+			{// CTS-to-SELF 
+				tcb_desc->bRTSEnable = true;
+				tcb_desc->bCTSEnable = true;
+				tcb_desc->rts_rate = MGN_24M;
+				break;
+			}
+			//check HT op mode
+			if(pHTInfo->bCurrentHTSupport  && pHTInfo->bEnableHT)
+			{
+				u8 HTOpMode = pHTInfo->CurrentOpMode;
+				if((pHTInfo->bCurBW40MHz && (HTOpMode == 2 || HTOpMode == 3)) ||
+							(!pHTInfo->bCurBW40MHz && HTOpMode == 3) )
+				{
+					tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
+					tcb_desc->bRTSEnable = true;
+					break;
+				}
+			}
+			//check rts
+			if (skb->len > ieee->rts)
+			{
+				tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
+				tcb_desc->bRTSEnable = true;
+				break;
+			}
+			//to do list: check MIMO power save condition.
+			//check AMPDU aggregation for TXOP
+			if(tcb_desc->bAMPDUEnable)
+			{
+				tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
+				// According to 8190 design, firmware sends CF-End only if RTS/CTS is enabled. However, it degrads
+				// throughput around 10M, so we disable of this mechanism. 2007.08.03 by Emily
+				tcb_desc->bRTSEnable = false;
+				break;
+			}
+			//check IOT action
+			if(pHTInfo->IOTAction & HT_IOT_ACT_FORCED_CTS2SELF)
+			{
+				tcb_desc->bCTSEnable	= true;
+				tcb_desc->rts_rate  = 	MGN_24M;
+				tcb_desc->bRTSEnable = true;
+				break;
+			}
+			// Totally no protection case!!
+			goto NO_PROTECTION;
+		}
+		}
+	// For test , CTS replace with RTS 
+	if( 0 )
+	{
+		tcb_desc->bCTSEnable	= true;
+		tcb_desc->rts_rate = MGN_24M;
+		tcb_desc->bRTSEnable 	= true;
+	}
+	if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
+		tcb_desc->bUseShortPreamble = true;
+	if (ieee->mode == IW_MODE_MASTER)
+			goto NO_PROTECTION;
+	return;
+NO_PROTECTION:
+	tcb_desc->bRTSEnable	= false;
+	tcb_desc->bCTSEnable	= false;
+	tcb_desc->rts_rate		= 0;
+	tcb_desc->RTSSC		= 0;
+	tcb_desc->bRTSBW		= false;
+}
+
+
+void ieee80211_txrate_selectmode(struct ieee80211_device* ieee, cb_desc* tcb_desc)
+{
+#ifdef TO_DO_LIST	
+	if(!IsDataFrame(pFrame))
+	{
+		pTcb->bTxDisableRateFallBack = TRUE;
+		pTcb->bTxUseDriverAssingedRate = TRUE;
+		pTcb->RATRIndex = 7;
+		return;
+	}
+
+	if(pMgntInfo->ForcedDataRate!= 0)
+	{
+		pTcb->bTxDisableRateFallBack = TRUE;
+		pTcb->bTxUseDriverAssingedRate = TRUE;
+		return;
+	}
+#endif
+	if(ieee->bTxDisableRateFallBack)
+		tcb_desc->bTxDisableRateFallBack = true;
+
+	if(ieee->bTxUseDriverAssingedRate)
+		tcb_desc->bTxUseDriverAssingedRate = true;
+	if(!tcb_desc->bTxDisableRateFallBack || !tcb_desc->bTxUseDriverAssingedRate)
+	{
+		if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC)
+			tcb_desc->RATRIndex = 0;
+	}
+}
+
+void ieee80211_query_seqnum(struct ieee80211_device*ieee, struct sk_buff* skb, u8* dst)
+{
+	if (is_multicast_ether_addr(dst) || is_broadcast_ether_addr(dst))
+		return;
+	if (IsQoSDataFrame(skb->data)) //we deal qos data only
+	{
+		PTX_TS_RECORD pTS = NULL;
+		if (!GetTs(ieee, (PTS_COMMON_INFO*)(&pTS), dst, skb->priority, TX_DIR, true))
+		{
+			return;
+		}
+		pTS->TxCurSeq = (pTS->TxCurSeq+1)%4096;
+	}
+}
+
+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_3addrqos *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 = 0, encrypt;
+	int bytes, fc, qos_ctl = 0, hdr_len;
+	struct sk_buff *skb_frag;
+	struct ieee80211_hdr_3addrqos header = { /* Ensure zero initialized */
+		.duration_id = 0,
+		.seq_ctl = 0,
+		.qos_ctl = 0
+	};
+	u8 dest[ETH_ALEN], src[ETH_ALEN];
+	int qos_actived = ieee->current_network.qos_data.active;
+
+	struct ieee80211_crypt_data* crypt;
+	
+	cb_desc *tcb_desc;
+
+	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;
+	}
+	
+
+	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;
+		}
+	
+		memset(skb->cb, 0, sizeof(skb->cb));
+		ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
+	
+		crypt = ieee->crypt[ieee->tx_keyidx];
+	
+		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 (encrypt)
+			fc = IEEE80211_FTYPE_DATA | IEEE80211_FCTL_WEP;
+		else 
+			
+                        fc = IEEE80211_FTYPE_DATA; 
+		
+		//if(ieee->current_network.QoS_Enable) 
+		if(qos_actived)
+			fc |= IEEE80211_STYPE_QOS_DATA; 
+		else
+			fc |= 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);
+		}
+
+                header.frame_ctl = cpu_to_le16(fc);
+
+		/* Determine fragmentation size based on destination (multicast
+		* and broadcast are not fragmented) */
+		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 {
+			frag_size = ieee->fts;//default:392
+			qos_ctl = 0;
+		}
+	
+		//if (ieee->current_network.QoS_Enable)	
+		if(qos_actived)
+		{
+			hdr_len = IEEE80211_3ADDR_LEN + 2;
+
+			skb->priority = ieee80211_classify(skb, &ieee->current_network);
+			qos_ctl |= skb->priority; //set in the ieee80211_classify 	
+			header.qos_ctl = cpu_to_le16(qos_ctl & IEEE80211_QOS_TID);
+		} else {
+			hdr_len = IEEE80211_3ADDR_LEN;		
+		}
+		/* 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 - 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 + ieee->tx_headroom, 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;
+
+		//if (ieee->current_network.QoS_Enable) 
+		if(qos_actived)
+		{
+			txb->queue_index = UP2AC(skb->priority);
+		} else {
+			txb->queue_index = WME_AC_BK;;
+		}
+
+
+
+		for (i = 0; i < nr_frags; i++) {
+			skb_frag = txb->fragments[i];
+			tcb_desc = (cb_desc *)(skb_frag->cb + MAX_DEV_ADDR_SIZE);
+			if(qos_actived){
+				skb_frag->priority = skb->priority;//UP2AC(skb->priority);	
+				tcb_desc->queue_index =  UP2AC(skb->priority);
+			} else {
+				skb_frag->priority = WME_AC_BK;
+				tcb_desc->queue_index = WME_AC_BK;
+			}
+			skb_reserve(skb_frag, ieee->tx_headroom);
+
+			if (encrypt){
+				if (ieee->hwsec_active)
+					tcb_desc->bHwSec = 1;
+				else
+					tcb_desc->bHwSec = 0;
+				skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
+			}
+			else
+			{
+				tcb_desc->bHwSec = 0;
+			}
+			frag_hdr = (struct ieee80211_hdr_3addrqos *)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) 
+			if(qos_actived)
+			{	
+				// 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);
+			} else {
+				frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<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);
+		}
+
+		if(qos_actived)
+		{
+		  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:
+//WB add to fill data tcb_desc here. only first fragment is considered, need to change, and you may remove to other place.
+	if (txb)
+	{
+#if 1	
+		cb_desc *tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
+		tcb_desc->bTxEnableFwCalcDur = 1;
+		if (is_multicast_ether_addr(header.addr1))
+			tcb_desc->bMulticast = 1;
+		if (is_broadcast_ether_addr(header.addr1))
+			tcb_desc->bBroadcast = 1;
+		ieee80211_txrate_selectmode(ieee, tcb_desc);
+		if ( tcb_desc->bMulticast ||  tcb_desc->bBroadcast)
+			tcb_desc->data_rate = ieee->basic_rate;
+		else
+			//tcb_desc->data_rate = CURRENT_RATE(ieee->current_network.mode, ieee->rate, ieee->HTCurrentOperaRate);
+			tcb_desc->data_rate = CURRENT_RATE(ieee->mode, ieee->rate, ieee->HTCurrentOperaRate);
+		ieee80211_qurey_ShortPreambleMode(ieee, tcb_desc);
+		ieee80211_tx_query_agg_cap(ieee, txb->fragments[0], tcb_desc);
+		ieee80211_query_HTCapShortGI(ieee, tcb_desc); 
+		ieee80211_query_BandwidthMode(ieee, tcb_desc);
+		ieee80211_query_protectionmode(ieee, tcb_desc, txb->fragments[0]);
+		ieee80211_query_seqnum(ieee, txb->fragments[0], header.addr1);
+//		IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, txb->fragments[0]->data, txb->fragments[0]->len);
+		//IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, tcb_desc, sizeof(cb_desc));
+#endif
+	}
+	spin_unlock_irqrestore(&ieee->lock, flags);
+	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);
+	stats->tx_errors++;
+	return 1;
+
+}
+
+EXPORT_SYMBOL(ieee80211_txb_free);
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c
new file mode 100644
index 0000000..f7bcf5a
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c
@@ -0,0 +1,1032 @@
+/******************************************************************************
+
+  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 at cc.hut.fi>
+  Copyright (c) 2002-2003, Jouni Malinen <jkmaline at 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 at 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"
+#if 0
+static const char *ieee80211_modes[] = {
+	"?", "a", "b", "ab", "g", "ag", "bg", "abg"
+};
+#endif
+struct modes_unit {
+	char *mode_string;
+	int mode_size;
+};
+struct modes_unit ieee80211_modes[] = {
+	{"a",1}, 
+	{"b",1}, 
+	{"g",1}, 
+	{"?",1},
+	{"N-24G",5},
+	{"N-5G",4},
+};
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,20)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+static inline char *
+iwe_stream_add_event_rsl(char *     stream,         /* Stream of events */
+                     char *     ends,           /* End of stream */
+                     struct iw_event *iwe,      /* Payload */
+                     int        event_len)      /* Real size of payload */
+{
+        /* Check if it's possible */
+        if((stream + event_len) < ends) {
+                iwe->len = event_len;
+		ndelay(1);   //new
+                memcpy(stream, (char *) iwe, event_len);
+                stream += event_len;
+        }
+        return stream;
+}
+#else
+#define iwe_stream_add_event_rsl iwe_stream_add_event
+#endif
+
+#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 proto_name[IFNAMSIZ];
+	char *pname = proto_name;
+	char *p;
+	struct iw_event iwe;
+	int i, j;
+	u16 max_rate, rate;
+	static u8	EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33};
+
+	/* 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)
+	start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_ADDR_LEN);
+#else
+	start = iwe_stream_add_event_rsl(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;
+//	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)
+                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)
+                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;
+	for(i=0; i<(sizeof(ieee80211_modes)/sizeof(ieee80211_modes[0])); i++) {
+		if(network->mode&(1<<i)) {
+			sprintf(pname,ieee80211_modes[i].mode_string,ieee80211_modes[i].mode_size);
+			pname +=ieee80211_modes[i].mode_size;
+		}	
+	}
+	*pname = '\0';
+	snprintf(iwe.u.name, IFNAMSIZ, "IEEE802.11%s", proto_name);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+        start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_CHAR_LEN);
+#else
+        start = iwe_stream_add_event_rsl(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)
+                start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_UINT_LEN);
+#else
+                start = iwe_stream_add_event_rsl(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)
+        start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_FREQ_LEN);
+#else
+        start = iwe_stream_add_event_rsl(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)
+        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;
+	}
+	
+	if (network->mode >= IEEE_N_24G)//add N rate here;
+	{
+		PHT_CAPABILITY_ELE ht_cap = NULL;
+		bool is40M = false, isShortGI = false;
+		u8 max_mcs = 0;
+		if (!memcmp(network->bssht.bdHTCapBuf, EWC11NHTCap, 4))
+			ht_cap = (PHT_CAPABILITY_ELE)&network->bssht.bdHTCapBuf[4];
+		else
+			ht_cap = (PHT_CAPABILITY_ELE)&network->bssht.bdHTCapBuf[0];
+		is40M = (ht_cap->ChlWidth)?1:0;
+		isShortGI = (ht_cap->ChlWidth)?
+						((ht_cap->ShortGI40Mhz)?1:0):
+						((ht_cap->ShortGI20Mhz)?1:0);
+		
+		max_mcs = HTGetHighestMCSRate(ieee, ht_cap->MCS, MCS_FILTER_ALL);
+		rate = MCS_DATA_RATE[is40M][isShortGI][max_mcs&0x7f];
+		if (rate > max_rate)
+			max_rate = rate;	
+	}
+#if 0	
+	printk("max rate:%d ===basic rate:\n", max_rate);
+	for (i=0;i<network->rates_len;i++)
+		printk(" %x", network->rates[i]);
+	printk("\n=======extend rate\n");
+	for (i=0; i<network->rates_ex_len; i++)
+		printk(" %x", network->rates_ex[i]);
+	printk("\n");
+#endif
+	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)
+        start = iwe_stream_add_event_rsl(info, start, stop, &iwe,
+				     IW_EV_PARAM_LEN);
+#else
+        start = iwe_stream_add_event_rsl(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)
+        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.signal;
+	iwe.u.qual.level = network->stats.rssi;
+	iwe.u.qual.noise = network->stats.noise;
+	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;
+	iwe.u.qual.updated = 7;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+        start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_QUAL_LEN);
+#else
+        start = iwe_stream_add_event_rsl(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)
+            start = iwe_stream_add_point(info, start, stop, &iwe, custom);
+#else
+            start = iwe_stream_add_point(start, stop, &iwe, custom);
+#endif
+#if (WIRELESS_EXT < 18) 
+	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);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+                start = iwe_stream_add_point(info, start, stop, &iwe, buf);
+#else
+                start = iwe_stream_add_point(start, stop, &iwe, buf);
+#endif
+        }
+
+	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]);
+		}
+
+		memset(&iwe, 0, sizeof(iwe));
+		iwe.cmd = IWEVCUSTOM;
+		iwe.u.data.length = strlen(buf);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+                start = iwe_stream_add_point(info, start, stop, &iwe, buf);
+#else
+                start = iwe_stream_add_point(start, stop, &iwe, buf);
+#endif
+        }
+#else
+	memset(&iwe, 0, sizeof(iwe));
+	if (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)
+                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)
+	{
+		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)
+                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)
+            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;
+
+	char *ev = extra;
+//	char *stop = ev + IW_SCAN_MAX_DATA;
+	char *stop = ev + wrqu->data.length;//IW_SCAN_MAX_DATA;
+	//char *stop = ev + IW_SCAN_MAX_DATA;
+	int i = 0;
+	int err = 0;
+	IEEE80211_DEBUG_WX("Getting scan\n");
+	down(&ieee->wx_sem);
+	spin_lock_irqsave(&ieee->lock, flags);
+
+	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");
+	crypt = &ieee->crypt[key];
+
+	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++) {
+			if (ieee->crypt[i] != NULL) {
+				if (key_provided)
+					break;
+				ieee80211_crypt_delayed_deinit(
+					ieee, &ieee->crypt[i]);
+			}
+		}
+
+		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;
+
+	} 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 */
+			printk("Setting key %d to all zero.\n",
+					   key);
+
+			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;
+		}
+	}
+
+ done:
+	ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED);
+	ieee->auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
+	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;
+
+	crypt = ieee->crypt[key];
+	erq->flags = key + 1;
+
+	if (crypt == NULL || crypt->ops == NULL) {
+		erq->length = 0;
+		erq->flags |= IW_ENCODE_DISABLED;
+		return 0;
+	}
+#if 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;
+	}
+#endif
+	len = crypt->ops->get_key(keybuf, SCM_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;
+}
+#if (WIRELESS_EXT >= 18)
+int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
+                               struct iw_request_info *info,
+                               union iwreq_data *wrqu, char *extra)
+{
+	int ret = 0;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+	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;
+        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) {
+
+                crypt = &ieee->crypt[idx];
+
+                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)
+
+                        crypt = &ieee->crypt[idx];
+
+                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++)
+
+			if (ieee->crypt[i] != NULL)
+	
+                                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);
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13))
+                new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
+#else
+                new_crypt = kmalloc(sizeof(*new_crypt), GFP_KERNEL);
+		memset(new_crypt,0,sizeof(*new_crypt));
+#endif
+                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;
+
+ 	}
+
+        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;
+        }
+#endif
+        return ret;
+}
+
+int ieee80211_wx_get_encode_ext(struct ieee80211_device *ieee,
+			       struct iw_request_info *info,
+			       union iwreq_data *wrqu, char *extra)
+{
+	struct iw_point *encoding = &wrqu->encoding;
+	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+	struct ieee80211_crypt_data *crypt;
+	int idx, max_key_len;
+
+	max_key_len = encoding->length - sizeof(*ext);
+	if (max_key_len < 0)
+		return -EINVAL;
+
+	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 &&
+	    ext->alg != IW_ENCODE_ALG_WEP)
+		if (idx != 0 || ieee->iw_mode != IW_MODE_INFRA)
+			return -EINVAL;
+		
+	crypt = ieee->crypt[idx];
+	encoding->flags = idx + 1;
+	memset(ext, 0, sizeof(*ext));
+
+	if (crypt == NULL || crypt->ops == NULL ) {
+		ext->alg = IW_ENCODE_ALG_NONE;
+		ext->key_len = 0;
+		encoding->flags |= IW_ENCODE_DISABLED;
+	} else {
+		if (strcmp(crypt->ops->name, "WEP") == 0 )
+			ext->alg = IW_ENCODE_ALG_WEP;
+		else if (strcmp(crypt->ops->name, "TKIP"))
+			ext->alg = IW_ENCODE_ALG_TKIP;
+		else if (strcmp(crypt->ops->name, "CCMP"))
+			ext->alg = IW_ENCODE_ALG_CCMP;
+		else
+			return -EINVAL;
+		ext->key_len = crypt->ops->get_key(ext->key, SCM_KEY_LEN, NULL, crypt->priv);
+		encoding->flags |= IW_ENCODE_ENABLED;
+		if (ext->key_len &&
+		    (ext->alg == IW_ENCODE_ALG_TKIP ||
+		     ext->alg == IW_ENCODE_ALG_CCMP))
+			ext->ext_flags |= IW_ENCODE_EXT_TX_SEQ_VALID;
+
+	}
+
+	return 0;
+}
+
+int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
+                               struct iw_request_info *info,
+                               union iwreq_data *wrqu, char *extra)
+{
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+	struct iw_mlme *mlme = (struct iw_mlme *) extra;
+	switch (mlme->cmd) {
+        case IW_MLME_DEAUTH:
+	case IW_MLME_DISASSOC:
+		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)
+{
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+	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:
+		//printk("======>%s():data->value is %d\n",__FUNCTION__,data->value);
+	//	ieee->open_wep = (data->value&IW_AUTH_ALG_OPEN_SYSTEM)?1:0;
+		if(data->value & IW_AUTH_ALG_SHARED_KEY){
+			ieee->open_wep = 0;
+			ieee->auth_mode = 1;
+		}
+		else if(data->value & IW_AUTH_ALG_OPEN_SYSTEM){
+			ieee->open_wep = 1;
+			ieee->auth_mode = 0;
+		}
+		else if(data->value & IW_AUTH_ALG_LEAP){
+			ieee->open_wep = 1;
+			ieee->auth_mode = 2;
+			//printk("hahahaa:LEAP\n");
+		}
+		else
+			return -EINVAL;
+		//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;
+	}	
+#endif
+	return 0;
+}
+#endif
+#if 1
+int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len)
+{
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+#if 0
+	printk("====>%s()\n", __FUNCTION__);
+	{
+		int i;
+		for (i=0; i<len; i++)
+		printk("%2x ", ie[i]&0xff);
+		printk("\n");
+	}
+#endif
+	u8 *buf;
+	
+	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", len, ie[1]);
+			return -EINVAL;
+		}
+		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;
+	}
+#endif
+	return 0;
+
+}
+#endif
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
+EXPORT_SYMBOL(ieee80211_wx_set_gen_ie);
+#if (WIRELESS_EXT >= 18)
+EXPORT_SYMBOL(ieee80211_wx_set_mlme);
+EXPORT_SYMBOL(ieee80211_wx_set_auth);
+EXPORT_SYMBOL(ieee80211_wx_set_encode_ext);
+EXPORT_SYMBOL(ieee80211_wx_get_encode_ext);
+#endif
+EXPORT_SYMBOL(ieee80211_wx_get_scan);
+EXPORT_SYMBOL(ieee80211_wx_set_encode);
+EXPORT_SYMBOL(ieee80211_wx_get_encode);
+#else
+EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_gen_ie);
+//EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_mlme);
+//EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_auth);
+//EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_encode_ext);
+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/staging/rtl8192u/ieee80211/internal.h b/drivers/staging/rtl8192u/ieee80211/internal.h
new file mode 100644
index 0000000..189f285
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/internal.h
@@ -0,0 +1,115 @@
+/*
+ * Cryptographic API.
+ *
+ * Copyright (c) 2002 James Morris <jmorris at 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/staging/rtl8192u/ieee80211/kmap_types.h b/drivers/staging/rtl8192u/ieee80211/kmap_types.h
new file mode 100644
index 0000000..de67bb0
--- /dev/null
+++ b/drivers/staging/rtl8192u/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/staging/rtl8192u/ieee80211/michael_mic.c b/drivers/staging/rtl8192u/ieee80211/michael_mic.c
new file mode 100644
index 0000000..df256e4
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/michael_mic.c
@@ -0,0 +1,194 @@
+/*
+ * Cryptographic API
+ *
+ * Michael MIC (IEEE 802.11i/TKIP) keyed digest
+ *
+ * Copyright (c) 2004 Jouni Malinen <jkmaline at 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.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/string.h>
+//#include <linux/crypto.h>
+#include "rtl_crypto.h"
+
+
+struct michael_mic_ctx {
+	u8 pending[4];
+	size_t pending_len;
+
+	u32 l, r;
+};
+
+
+static inline u32 rotl(u32 val, int bits)
+{
+	return (val << bits) | (val >> (32 - bits));
+}
+
+
+static inline u32 rotr(u32 val, int bits)
+{
+	return (val >> bits) | (val << (32 - bits));
+}
+
+
+static inline u32 xswap(u32 val)
+{
+	return ((val & 0x00ff00ff) << 8) | ((val & 0xff00ff00) >> 8);
+}
+
+
+#define michael_block(l, r)	\
+do {				\
+	r ^= rotl(l, 17);	\
+	l += r;			\
+	r ^= xswap(l);		\
+	l += r;			\
+	r ^= rotl(l, 3);	\
+	l += r;			\
+	r ^= rotr(l, 2);	\
+	l += r;			\
+} while (0)
+
+
+static inline u32 get_le32(const u8 *p)
+{
+	return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
+}
+
+
+static inline void put_le32(u8 *p, u32 v)
+{
+	p[0] = v;
+	p[1] = v >> 8;
+	p[2] = v >> 16;
+	p[3] = v >> 24;
+}
+
+
+static void michael_init(void *ctx)
+{
+	struct michael_mic_ctx *mctx = ctx;
+	mctx->pending_len = 0;
+}
+
+
+static void michael_update(void *ctx, const u8 *data, unsigned int len)
+{
+	struct michael_mic_ctx *mctx = ctx;
+
+	if (mctx->pending_len) {
+		int flen = 4 - mctx->pending_len;
+		if (flen > len)
+			flen = len;
+		memcpy(&mctx->pending[mctx->pending_len], data, flen);
+		mctx->pending_len += flen;
+		data += flen;
+		len -= flen;
+
+		if (mctx->pending_len < 4)
+			return;
+
+		mctx->l ^= get_le32(mctx->pending);
+		michael_block(mctx->l, mctx->r);
+		mctx->pending_len = 0;
+	}
+
+	while (len >= 4) {
+		mctx->l ^= get_le32(data);
+		michael_block(mctx->l, mctx->r);
+		data += 4;
+		len -= 4;
+	}
+
+	if (len > 0) {
+		mctx->pending_len = len;
+		memcpy(mctx->pending, data, len);
+	}
+}
+
+
+static void michael_final(void *ctx, u8 *out)
+{
+	struct michael_mic_ctx *mctx = ctx;
+	u8 *data = mctx->pending;
+
+	/* Last block and padding (0x5a, 4..7 x 0) */
+	switch (mctx->pending_len) {
+	case 0:
+		mctx->l ^= 0x5a;
+		break;
+	case 1:
+		mctx->l ^= data[0] | 0x5a00;
+		break;
+	case 2:
+		mctx->l ^= data[0] | (data[1] << 8) | 0x5a0000;
+		break;
+	case 3:
+		mctx->l ^= data[0] | (data[1] << 8) | (data[2] << 16) |
+			0x5a000000;
+		break;
+	}
+	michael_block(mctx->l, mctx->r);
+	/* l ^= 0; */
+	michael_block(mctx->l, mctx->r);
+
+	put_le32(out, mctx->l);
+	put_le32(out + 4, mctx->r);
+}
+
+
+static int michael_setkey(void *ctx, const u8 *key, unsigned int keylen,
+			  u32 *flags)
+{
+	struct michael_mic_ctx *mctx = ctx;
+	if (keylen != 8) {
+		if (flags)
+			*flags = CRYPTO_TFM_RES_BAD_KEY_LEN;
+		return -EINVAL;
+	}
+	mctx->l = get_le32(key);
+	mctx->r = get_le32(key + 4);
+	return 0;
+}
+
+
+static struct crypto_alg michael_mic_alg = {
+	.cra_name	= "michael_mic",
+	.cra_flags	= CRYPTO_ALG_TYPE_DIGEST,
+	.cra_blocksize	= 8,
+	.cra_ctxsize	= sizeof(struct michael_mic_ctx),
+	.cra_module	= THIS_MODULE,
+	.cra_list	= LIST_HEAD_INIT(michael_mic_alg.cra_list),
+	.cra_u		= { .digest = {
+	.dia_digestsize	= 8,
+	.dia_init	= michael_init,
+	.dia_update	= michael_update,
+	.dia_final	= michael_final,
+	.dia_setkey	= michael_setkey } }
+};
+
+
+static int __init michael_mic_init(void)
+{
+	return crypto_register_alg(&michael_mic_alg);
+}
+
+
+static void __exit michael_mic_exit(void)
+{
+	crypto_unregister_alg(&michael_mic_alg);
+}
+
+
+module_init(michael_mic_init);
+module_exit(michael_mic_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Michael MIC");
+MODULE_AUTHOR("Jouni Malinen <jkmaline at cc.hut.fi>");
diff --git a/drivers/staging/rtl8192u/ieee80211/proc.c b/drivers/staging/rtl8192u/ieee80211/proc.c
new file mode 100644
index 0000000..6920fb5
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/proc.c
@@ -0,0 +1,116 @@
+/*
+ * Scatterlist Cryptographic API.
+ *
+ * Procfs information.
+ *
+ * Copyright (c) 2002 James Morris <jmorris at 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.
+ *
+ */
+#include <linux/init.h>
+//#include <linux/crypto.h>
+#include "rtl_crypto.h"
+#include <linux/rwsem.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include "internal.h"
+
+extern struct list_head crypto_alg_list;
+extern struct rw_semaphore crypto_alg_sem;
+
+static void *c_start(struct seq_file *m, loff_t *pos)
+{
+	struct list_head *v;
+	loff_t n = *pos;
+
+	down_read(&crypto_alg_sem);
+	list_for_each(v, &crypto_alg_list)
+		if (!n--)
+			return list_entry(v, struct crypto_alg, cra_list);
+	return NULL;
+}
+
+static void *c_next(struct seq_file *m, void *p, loff_t *pos)
+{
+	struct list_head *v = p;
+	
+	(*pos)++;
+	v = v->next;
+	return (v == &crypto_alg_list) ?
+		NULL : list_entry(v, struct crypto_alg, cra_list);
+}
+
+static void c_stop(struct seq_file *m, void *p)
+{
+	up_read(&crypto_alg_sem);
+}
+
+static int c_show(struct seq_file *m, void *p)
+{
+	struct crypto_alg *alg = (struct crypto_alg *)p;
+	
+	seq_printf(m, "name         : %s\n", alg->cra_name);
+	seq_printf(m, "module       : %s\n",
+		   (alg->cra_module ?
+		    alg->cra_module->name :
+		    "kernel"));
+	
+	switch (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) {
+	case CRYPTO_ALG_TYPE_CIPHER:
+		seq_printf(m, "type         : cipher\n");
+		seq_printf(m, "blocksize    : %u\n", alg->cra_blocksize);
+		seq_printf(m, "min keysize  : %u\n",
+					alg->cra_cipher.cia_min_keysize);
+		seq_printf(m, "max keysize  : %u\n",
+					alg->cra_cipher.cia_max_keysize);
+		break;
+		
+	case CRYPTO_ALG_TYPE_DIGEST:
+		seq_printf(m, "type         : digest\n");
+		seq_printf(m, "blocksize    : %u\n", alg->cra_blocksize);
+		seq_printf(m, "digestsize   : %u\n",
+		           alg->cra_digest.dia_digestsize);
+		break;
+	case CRYPTO_ALG_TYPE_COMPRESS:
+		seq_printf(m, "type         : compression\n");
+		break;
+	default:
+		seq_printf(m, "type         : unknown\n");
+		break;
+	}
+
+	seq_putc(m, '\n');
+	return 0;
+}
+
+static struct seq_operations crypto_seq_ops = {
+	.start		= c_start,
+	.next		= c_next,
+	.stop		= c_stop,
+	.show		= c_show
+};
+
+static int crypto_info_open(struct inode *inode, struct file *file)
+{
+	return seq_open(file, &crypto_seq_ops);
+}
+        
+static struct file_operations proc_crypto_ops = {
+	.open		= crypto_info_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= seq_release
+};
+
+void __init crypto_init_proc(void)
+{
+	struct proc_dir_entry *proc;
+	
+	proc = create_proc_entry("crypto", 0, NULL);
+	if (proc)
+		proc->proc_fops = &proc_crypto_ops;
+}
diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_BA.h b/drivers/staging/rtl8192u/ieee80211/rtl819x_BA.h
new file mode 100644
index 0000000..d0617da
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_BA.h
@@ -0,0 +1,69 @@
+#ifndef _BATYPE_H_
+#define _BATYPE_H_
+
+#define 	TOTAL_TXBA_NUM	16
+#define	TOTAL_RXBA_NUM	16
+
+#define	BA_SETUP_TIMEOUT	200
+#define	BA_INACT_TIMEOUT	60000
+
+#define	BA_POLICY_DELAYED		0
+#define	BA_POLICY_IMMEDIATE	1
+
+#define	ADDBA_STATUS_SUCCESS			0
+#define	ADDBA_STATUS_REFUSED		37
+#define	ADDBA_STATUS_INVALID_PARAM	38
+
+#define	DELBA_REASON_QSTA_LEAVING	36
+#define	DELBA_REASON_END_BA			37
+#define	DELBA_REASON_UNKNOWN_BA	38
+#define	DELBA_REASON_TIMEOUT			39
+/*  whether need define BA Action frames here?
+struct ieee80211_ADDBA_Req{
+	struct ieee80211_header_data header;
+	u8	category;
+	u8
+} __attribute__ ((packed));
+*/
+//Is this need?I put here just to make it easier to define structure BA_RECORD //WB 
+typedef union _SEQUENCE_CONTROL{
+	u16 ShortData;
+	struct
+	{
+		u16	FragNum:4;
+		u16	SeqNum:12;
+	}field;
+}SEQUENCE_CONTROL, *PSEQUENCE_CONTROL;
+
+typedef union _BA_PARAM_SET {
+	u8 charData[2];
+	u16 shortData;
+	struct {
+		u16 AMSDU_Support:1;
+		u16 BAPolicy:1;
+		u16 TID:4;
+		u16 BufferSize:10;
+	} field;
+} BA_PARAM_SET, *PBA_PARAM_SET;
+
+typedef union _DELBA_PARAM_SET {
+	u8 charData[2];
+	u16 shortData;
+	struct {
+		u16 Reserved:11;
+		u16 Initiator:1;
+		u16 TID:4;
+	} field;
+} DELBA_PARAM_SET, *PDELBA_PARAM_SET;
+
+typedef struct _BA_RECORD {
+	struct timer_list		Timer;
+	u8				bValid;
+	u8				DialogToken;
+	BA_PARAM_SET		BaParamSet;
+	u16				BaTimeoutValue;
+	SEQUENCE_CONTROL	BaStartSeqCtrl;
+} BA_RECORD, *PBA_RECORD;
+
+#endif //end _BATYPE_H_
+
diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c
new file mode 100644
index 0000000..cbaff58
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c
@@ -0,0 +1,779 @@
+/********************************************************************************************************************************
+ * This file is created to process BA Action Frame. According to 802.11 spec, there are 3 BA action types at all. And as BA is 
+ * related to TS, this part need some struture defined in QOS side code. Also TX RX is going to be resturctured, so how to send 
+ * ADDBAREQ ADDBARSP and DELBA packet is still on consideration. Temporarily use MANAGE QUEUE instead of Normal Queue.
+ * WB 2008-05-27
+ * *****************************************************************************************************************************/
+#include "ieee80211.h"
+#include "rtl819x_BA.h"
+
+/********************************************************************************************************************
+ *function:  Activate BA entry. And if Time is nozero, start timer.
+ *   input:  PBA_RECORD 		pBA  //BA entry to be enabled
+ *   	     u16 			Time //indicate time delay.
+ *  output:  none
+********************************************************************************************************************/
+void ActivateBAEntry(struct ieee80211_device* ieee, PBA_RECORD pBA, u16 Time)
+{
+	pBA->bValid = true;
+	if(Time != 0)
+		mod_timer(&pBA->Timer, jiffies + MSECS(Time));
+}
+
+/********************************************************************************************************************
+ *function:  deactivate BA entry, including its timer.
+ *   input:  PBA_RECORD 		pBA  //BA entry to be disabled 
+ *  output:  none
+********************************************************************************************************************/
+void DeActivateBAEntry( struct ieee80211_device* ieee, PBA_RECORD pBA)
+{
+	pBA->bValid = false;
+	del_timer_sync(&pBA->Timer);
+}
+/********************************************************************************************************************
+ *function: deactivete BA entry in Tx Ts, and send DELBA.
+ *   input:
+ *   	     PTX_TS_RECORD		pTxTs //Tx Ts which is to deactivate BA entry.
+ *  output:  none
+ *  notice:  As PTX_TS_RECORD structure will be defined in QOS, so wait to be merged. //FIXME
+********************************************************************************************************************/
+u8 TxTsDeleteBA( struct ieee80211_device* ieee, PTX_TS_RECORD	pTxTs)
+{
+	PBA_RECORD		pAdmittedBa = &pTxTs->TxAdmittedBARecord;  //These two BA entries must exist in TS structure
+	PBA_RECORD		pPendingBa = &pTxTs->TxPendingBARecord;
+	u8			bSendDELBA = false;
+
+	// Delete pending BA
+	if(pPendingBa->bValid)
+	{
+		DeActivateBAEntry(ieee, pPendingBa);
+		bSendDELBA = true;
+	}
+
+	// Delete admitted BA
+	if(pAdmittedBa->bValid)
+	{
+		DeActivateBAEntry(ieee, pAdmittedBa);
+		bSendDELBA = true;
+	}
+
+	return bSendDELBA;
+}
+
+/********************************************************************************************************************
+ *function: deactivete BA entry in Tx Ts, and send DELBA.
+ *   input:
+ *   	     PRX_TS_RECORD		pRxTs //Rx Ts which is to deactivate BA entry.
+ *  output:  none
+ *  notice:  As PRX_TS_RECORD structure will be defined in QOS, so wait to be merged. //FIXME, same with above
+********************************************************************************************************************/
+u8 RxTsDeleteBA( struct ieee80211_device* ieee, PRX_TS_RECORD	pRxTs)
+{
+	PBA_RECORD		pBa = &pRxTs->RxAdmittedBARecord;
+	u8			bSendDELBA = false;
+
+	if(pBa->bValid)
+	{
+		DeActivateBAEntry(ieee, pBa);
+		bSendDELBA = true;
+	}
+
+	return bSendDELBA;
+}
+
+/********************************************************************************************************************
+ *function: reset BA entry
+ *   input:
+ *   	     PBA_RECORD		pBA //entry to be reset
+ *  output:  none
+********************************************************************************************************************/
+void ResetBaEntry( PBA_RECORD pBA)
+{
+	pBA->bValid			= false;
+	pBA->BaParamSet.shortData	= 0;
+	pBA->BaTimeoutValue		= 0;
+	pBA->DialogToken		= 0;
+	pBA->BaStartSeqCtrl.ShortData	= 0;
+}
+//These functions need porting here or not?
+/*******************************************************************************************************************************
+ *function:  construct ADDBAREQ and ADDBARSP frame here together.
+ *   input:  u8* 		Dst 	//ADDBA frame's destination 
+ *   	     PBA_RECORD 	pBA	//BA_RECORD entry which stores the necessary information for BA.
+ *   	     u16 		StatusCode  //status code in RSP and I will use it to indicate whether it's RSP or REQ(will I?)
+ *   	     u8			type	//indicate whether it's RSP(ACT_ADDBARSP) ow REQ(ACT_ADDBAREQ)
+ *  output:  none
+ *  return:  sk_buff* 		skb     //return constructed skb to xmit
+*******************************************************************************************************************************/
+static struct sk_buff* ieee80211_ADDBA(struct ieee80211_device* ieee, u8* Dst, PBA_RECORD pBA, u16 StatusCode, u8 type)
+{
+	struct sk_buff *skb = NULL;
+	 struct ieee80211_hdr_3addr* BAReq = NULL;
+	u8* tag = NULL;
+	u16 tmp = 0;
+	u16 len = ieee->tx_headroom + 9;
+	//category(1) + action field(1) + Dialog Token(1) + BA Parameter Set(2) +  BA Timeout Value(2) +  BA Start SeqCtrl(2)(or StatusCode(2))
+	IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), frame(%d) sentd to:"MAC_FMT", ieee->dev:%p\n", __FUNCTION__, type, MAC_ARG(Dst), ieee->dev);
+	if (pBA == NULL||ieee == NULL)
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "pBA(%p) is NULL or ieee(%p) is NULL\n", pBA, ieee);
+		return NULL;
+	}
+	skb = dev_alloc_skb(len + sizeof( struct ieee80211_hdr_3addr)); //need to add something others? FIXME
+	if (skb == NULL)
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc skb for ADDBA_REQ\n");
+		return NULL;
+	}
+
+	memset(skb->data, 0, sizeof( struct ieee80211_hdr_3addr));  	//I wonder whether it's necessary. Apparently kernel will not do it when alloc a skb.
+	skb_reserve(skb, ieee->tx_headroom);
+
+	BAReq = ( struct ieee80211_hdr_3addr *) skb_put(skb,sizeof( struct ieee80211_hdr_3addr));
+
+	memcpy(BAReq->addr1, Dst, ETH_ALEN);
+	memcpy(BAReq->addr2, ieee->dev->dev_addr, ETH_ALEN);
+
+	memcpy(BAReq->addr3, ieee->current_network.bssid, ETH_ALEN);
+
+	BAReq->frame_ctl = cpu_to_le16(IEEE80211_STYPE_MANAGE_ACT); //action frame
+
+	//tag += sizeof( struct ieee80211_hdr_3addr); //move to action field
+	tag = (u8*)skb_put(skb, 9);
+	*tag ++= ACT_CAT_BA;  
+	*tag ++= type;
+	// Dialog Token
+	*tag ++= pBA->DialogToken;
+
+	if (ACT_ADDBARSP == type)
+	{
+		// Status Code
+		printk("=====>to send ADDBARSP\n");
+		tmp = cpu_to_le16(StatusCode);
+		memcpy(tag, (u8*)&tmp, 2);
+		tag += 2;	
+	}
+	// BA Parameter Set
+	tmp = cpu_to_le16(pBA->BaParamSet.shortData);
+	memcpy(tag, (u8*)&tmp, 2);
+	tag += 2;
+	// BA Timeout Value
+	tmp = cpu_to_le16(pBA->BaTimeoutValue);
+	memcpy(tag, (u8*)&tmp, 2);
+	tag += 2;
+	
+	if (ACT_ADDBAREQ == type)
+	{
+	// BA Start SeqCtrl
+		memcpy(tag,(u8*)&(pBA->BaStartSeqCtrl), 2);
+		tag += 2;
+	}
+	
+	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
+	return skb;
+	//return NULL;
+}
+
+#if 0 //I try to merge ADDBA_REQ and ADDBA_RSP frames together..
+/********************************************************************************************************************
+ *function:  construct ADDBAREQ frame
+ *   input:  u8* 		dst 	//ADDBARsp frame's destination 
+ *   	     PBA_RECORD 	pBA	//BA_RECORD entry which stores the necessary information for BA_RSP.
+ *   	     u16 		StatusCode  //status code.
+ *  output:  none
+ *  return:  sk_buff* 		skb     //return constructed skb to xmit 
+********************************************************************************************************************/
+static struct sk_buff* ieee80211_ADDBA_Rsp( IN	struct ieee80211_device* ieee, u8* dst, PBA_RECORD pBA, u16 StatusCode)
+{
+	OCTET_STRING	osADDBAFrame, tmp;
+
+	FillOctetString(osADDBAFrame, Buffer, 0);
+	*pLength = 0;
+
+	ConstructMaFrameHdr(
+					Adapter, 
+					Addr, 
+					ACT_CAT_BA, 
+					ACT_ADDBARSP, 
+					&osADDBAFrame	);
+
+	// Dialog Token
+	FillOctetString(tmp, &pBA->DialogToken, 1);
+	PacketAppendData(&osADDBAFrame, tmp);
+
+	// Status Code
+	FillOctetString(tmp, &StatusCode, 2);
+	PacketAppendData(&osADDBAFrame, tmp);
+
+	// BA Parameter Set
+	FillOctetString(tmp, &pBA->BaParamSet, 2);
+	PacketAppendData(&osADDBAFrame, tmp);
+
+	// BA Timeout Value
+	FillOctetString(tmp, &pBA->BaTimeoutValue, 2);
+	PacketAppendData(&osADDBAFrame, tmp);
+
+	*pLength = osADDBAFrame.Length;
+}
+#endif
+
+/********************************************************************************************************************
+ *function:  construct DELBA frame
+ *   input:  u8* 		dst 	//DELBA frame's destination 
+ *   	     PBA_RECORD 	pBA	//BA_RECORD entry which stores the necessary information for BA
+ *   	     TR_SELECT	        TxRxSelect  //TX RX direction
+ *   	     u16 		ReasonCode  //status code.
+ *  output:  none
+ *  return:  sk_buff* 		skb     //return constructed skb to xmit 
+********************************************************************************************************************/
+static struct sk_buff* ieee80211_DELBA(
+	struct ieee80211_device* ieee,
+	u8*		         dst,
+	PBA_RECORD		 pBA,
+	TR_SELECT		 TxRxSelect,
+	u16			 ReasonCode
+	)
+{
+	DELBA_PARAM_SET	DelbaParamSet;
+	struct sk_buff *skb = NULL;
+	 struct ieee80211_hdr_3addr* Delba = NULL;
+	u8* tag = NULL;
+	u16 tmp = 0;
+	//len = head len + DELBA Parameter Set(2) + Reason Code(2)
+	u16 len = 6 + ieee->tx_headroom;	
+
+	if (net_ratelimit())
+	IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), ReasonCode(%d) sentd to:"MAC_FMT"\n", __FUNCTION__, ReasonCode, MAC_ARG(dst));
+
+	memset(&DelbaParamSet, 0, 2);
+
+	DelbaParamSet.field.Initiator	= (TxRxSelect==TX_DIR)?1:0;
+	DelbaParamSet.field.TID	= pBA->BaParamSet.field.TID;
+	
+	skb = dev_alloc_skb(len + sizeof( struct ieee80211_hdr_3addr)); //need to add something others? FIXME
+	if (skb == NULL)
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc skb for ADDBA_REQ\n");
+		return NULL;
+	}
+//	memset(skb->data, 0, len+sizeof( struct ieee80211_hdr_3addr));  
+	skb_reserve(skb, ieee->tx_headroom);
+	
+	Delba = ( struct ieee80211_hdr_3addr *) skb_put(skb,sizeof( struct ieee80211_hdr_3addr));
+
+	memcpy(Delba->addr1, dst, ETH_ALEN);
+	memcpy(Delba->addr2, ieee->dev->dev_addr, ETH_ALEN);
+	memcpy(Delba->addr3, ieee->current_network.bssid, ETH_ALEN);
+	Delba->frame_ctl = cpu_to_le16(IEEE80211_STYPE_MANAGE_ACT); //action frame
+	
+	tag = (u8*)skb_put(skb, 6);	
+
+	*tag ++= ACT_CAT_BA;  
+	*tag ++= ACT_DELBA;
+
+	// DELBA Parameter Set
+	tmp = cpu_to_le16(DelbaParamSet.shortData);
+	memcpy(tag, (u8*)&tmp, 2);
+	tag += 2;
+	// Reason Code
+	tmp = cpu_to_le16(ReasonCode);
+	memcpy(tag, (u8*)&tmp, 2);
+	tag += 2;
+
+	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
+	if (net_ratelimit())
+	IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "<=====%s()\n", __FUNCTION__);
+	return skb;
+}
+
+/********************************************************************************************************************
+ *function: send ADDBAReq frame out
+ *   input:  u8* 		dst 	//ADDBAReq frame's destination 
+ *   	     PBA_RECORD 	pBA	//BA_RECORD entry which stores the necessary information for BA 
+ *  output:  none
+ *  notice: If any possible, please hide pBA in ieee. And temporarily use Manage Queue as softmac_mgmt_xmit() usually does
+********************************************************************************************************************/
+void ieee80211_send_ADDBAReq(struct ieee80211_device* ieee, u8*	dst, PBA_RECORD	pBA)
+{
+	struct sk_buff *skb = NULL;
+	skb = ieee80211_ADDBA(ieee, dst, pBA, 0, ACT_ADDBAREQ); //construct ACT_ADDBAREQ frames so set statuscode zero.
+
+	if (skb)
+	{
+		softmac_mgmt_xmit(skb, ieee);
+		//add statistic needed here.
+		//and skb will be freed in softmac_mgmt_xmit(), so omit all dev_kfree_skb_any() outside softmac_mgmt_xmit()
+		//WB 
+	}
+	else
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "alloc skb error in function %s()\n", __FUNCTION__);
+	}
+	return;
+}
+
+/********************************************************************************************************************
+ *function: send ADDBARSP frame out
+ *   input:  u8* 		dst 	//DELBA frame's destination 
+ *   	     PBA_RECORD 	pBA	//BA_RECORD entry which stores the necessary information for BA 
+ *   	     u16		StatusCode //RSP StatusCode
+ *  output:  none
+ *  notice: If any possible, please hide pBA in ieee. And temporarily use Manage Queue as softmac_mgmt_xmit() usually does
+********************************************************************************************************************/
+void ieee80211_send_ADDBARsp(struct ieee80211_device* ieee, u8* dst, PBA_RECORD pBA, u16 StatusCode) 
+{
+	struct sk_buff *skb = NULL;
+	skb = ieee80211_ADDBA(ieee, dst, pBA, StatusCode, ACT_ADDBARSP); //construct ACT_ADDBARSP frames
+	if (skb)
+	{
+		softmac_mgmt_xmit(skb, ieee);
+		//same above
+	}
+	else
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "alloc skb error in function %s()\n", __FUNCTION__);
+	}
+
+	return;
+
+}
+/********************************************************************************************************************
+ *function: send ADDBARSP frame out
+ *   input:  u8* 		dst 	//DELBA frame's destination 
+ *   	     PBA_RECORD 	pBA	//BA_RECORD entry which stores the necessary information for BA 
+ *   	     TR_SELECT          TxRxSelect //TX or RX
+ *   	     u16		ReasonCode //DEL ReasonCode
+ *  output:  none
+ *  notice: If any possible, please hide pBA in ieee. And temporarily use Manage Queue as softmac_mgmt_xmit() usually does
+********************************************************************************************************************/
+
+void ieee80211_send_DELBA(struct ieee80211_device* ieee, u8* dst, PBA_RECORD pBA, TR_SELECT TxRxSelect, u16 ReasonCode)
+{
+	struct sk_buff *skb = NULL;
+	skb = ieee80211_DELBA(ieee, dst, pBA, TxRxSelect, ReasonCode); //construct ACT_ADDBARSP frames
+	if (skb)
+	{
+		softmac_mgmt_xmit(skb, ieee);
+		//same above
+	}
+	else
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "alloc skb error in function %s()\n", __FUNCTION__);
+	}
+	return ;
+}
+
+/********************************************************************************************************************
+ *function: RX ADDBAReq
+ *   input:  struct sk_buff *   skb	//incoming ADDBAReq skb.
+ *  return:  0(pass), other(fail)
+ *  notice:  As this function need support of QOS, I comment some code out. And when qos is ready, this code need to be support.
+********************************************************************************************************************/
+int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb)
+{
+	 struct ieee80211_hdr_3addr* req = NULL;
+	u16 rc = 0;
+	u8 * dst = NULL, *pDialogToken = NULL, *tag = NULL;
+	PBA_RECORD pBA = NULL;
+	PBA_PARAM_SET	pBaParamSet = NULL;
+	u16* pBaTimeoutVal = NULL;
+	PSEQUENCE_CONTROL pBaStartSeqCtrl = NULL;
+	PRX_TS_RECORD	pTS = NULL;	
+
+	if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9)
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BAREQ(%d / %d)\n", skb->len, 	(sizeof( struct ieee80211_hdr_3addr) + 9));
+		return -1;
+	}
+
+	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
+	
+	req = ( struct ieee80211_hdr_3addr*) skb->data;
+	tag = (u8*)req;
+	dst = (u8*)(&req->addr2[0]);
+	tag += sizeof( struct ieee80211_hdr_3addr);
+	pDialogToken = tag + 2;  //category+action
+	pBaParamSet = (PBA_PARAM_SET)(tag + 3);   //+DialogToken
+	pBaTimeoutVal = (u16*)(tag + 5); 
+	pBaStartSeqCtrl = (PSEQUENCE_CONTROL)(req + 7);
+	
+	printk("====================>rx ADDBAREQ from :"MAC_FMT"\n", MAC_ARG(dst));	
+//some other capability is not ready now.
+	if(	(ieee->current_network.qos_data.active == 0) ||
+		(ieee->pHTInfo->bCurrentHTSupport == false)) //||
+	//	(ieee->pStaQos->bEnableRxImmBA == false)	)
+	{
+		rc = ADDBA_STATUS_REFUSED;
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "Failed to reply on ADDBA_REQ as some capability is not ready(%d, %d)\n", ieee->current_network.qos_data.active, ieee->pHTInfo->bCurrentHTSupport);
+		goto OnADDBAReq_Fail;
+	}
+	// Search for related traffic stream.
+	// If there is no matched TS, reject the ADDBA request.
+	if(	!GetTs(
+			ieee, 
+			(PTS_COMMON_INFO*)(&pTS), 
+			dst, 
+			(u8)(pBaParamSet->field.TID), 
+			RX_DIR,
+			true)	)
+	{
+		rc = ADDBA_STATUS_REFUSED;
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't get TS in %s()\n", __FUNCTION__);
+		goto OnADDBAReq_Fail;
+	}
+	pBA = &pTS->RxAdmittedBARecord;
+	// To Determine the ADDBA Req content
+	// We can do much more check here, including BufferSize, AMSDU_Support, Policy, StartSeqCtrl...
+	// I want to check StartSeqCtrl to make sure when we start aggregation!!!
+	//
+	if(pBaParamSet->field.BAPolicy == BA_POLICY_DELAYED)
+	{
+		rc = ADDBA_STATUS_INVALID_PARAM;
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "BA Policy is not correct in %s()\n", __FUNCTION__);
+		goto OnADDBAReq_Fail;
+	}
+		// Admit the ADDBA Request
+	//
+	DeActivateBAEntry(ieee, pBA);	
+	pBA->DialogToken = *pDialogToken;
+	pBA->BaParamSet = *pBaParamSet;
+	pBA->BaTimeoutValue = *pBaTimeoutVal;
+	pBA->BaStartSeqCtrl = *pBaStartSeqCtrl;
+	//for half N mode we only aggregate 1 frame
+	if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev))
+	pBA->BaParamSet.field.BufferSize = 1;
+	else
+	pBA->BaParamSet.field.BufferSize = 32;
+	ActivateBAEntry(ieee, pBA, pBA->BaTimeoutValue);
+	ieee80211_send_ADDBARsp(ieee, dst, pBA, ADDBA_STATUS_SUCCESS);
+
+	// End of procedure.
+	return 0;
+	
+OnADDBAReq_Fail:
+	{
+		BA_RECORD	BA;
+		BA.BaParamSet = *pBaParamSet;
+		BA.BaTimeoutValue = *pBaTimeoutVal;
+		BA.DialogToken = *pDialogToken;
+		BA.BaParamSet.field.BAPolicy = BA_POLICY_IMMEDIATE;
+		ieee80211_send_ADDBARsp(ieee, dst, &BA, rc);
+		return 0; //we send RSP out.
+	}
+
+}
+
+/********************************************************************************************************************
+ *function: RX ADDBARSP
+ *   input:  struct sk_buff *   skb	//incoming ADDBAReq skb.
+ *  return:  0(pass), other(fail)
+ *  notice:  As this function need support of QOS, I comment some code out. And when qos is ready, this code need to be support.
+********************************************************************************************************************/
+int ieee80211_rx_ADDBARsp( struct ieee80211_device* ieee, struct sk_buff *skb)
+{
+	 struct ieee80211_hdr_3addr* rsp = NULL;
+	PBA_RECORD		pPendingBA, pAdmittedBA;
+	PTX_TS_RECORD		pTS = NULL;
+	u8* dst = NULL, *pDialogToken = NULL, *tag = NULL;
+	u16* pStatusCode = NULL, *pBaTimeoutVal = NULL;
+	PBA_PARAM_SET		pBaParamSet = NULL;
+	u16			ReasonCode;
+
+	if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9)
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BARSP(%d / %d)\n", skb->len, 	(sizeof( struct ieee80211_hdr_3addr) + 9));
+		return -1;
+	}
+	rsp = ( struct ieee80211_hdr_3addr*)skb->data;
+	tag = (u8*)rsp;
+	dst = (u8*)(&rsp->addr2[0]);
+	tag += sizeof( struct ieee80211_hdr_3addr);
+	pDialogToken = tag + 2;
+	pStatusCode = (u16*)(tag + 3);
+	pBaParamSet = (PBA_PARAM_SET)(tag + 5);
+	pBaTimeoutVal = (u16*)(tag + 7);
+
+	// Check the capability
+	// Since we can always receive A-MPDU, we just check if it is under HT mode.
+	if(     ieee->current_network.qos_data.active == 0  ||
+		ieee->pHTInfo->bCurrentHTSupport == false ||
+		ieee->pHTInfo->bCurrentAMPDUEnable == false )
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "reject to ADDBA_RSP as some capability is not ready(%d, %d, %d)\n",ieee->current_network.qos_data.active, ieee->pHTInfo->bCurrentHTSupport, ieee->pHTInfo->bCurrentAMPDUEnable);
+		ReasonCode = DELBA_REASON_UNKNOWN_BA;
+		goto OnADDBARsp_Reject;
+	}
+
+	
+	//
+	// Search for related TS.
+	// If there is no TS found, we wil reject ADDBA Rsp by sending DELBA frame.
+	//
+	if (!GetTs(
+			ieee, 
+			(PTS_COMMON_INFO*)(&pTS), 
+			dst, 
+			(u8)(pBaParamSet->field.TID), 
+			TX_DIR,
+			false)	)
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't get TS in %s()\n", __FUNCTION__);
+		ReasonCode = DELBA_REASON_UNKNOWN_BA;
+		goto OnADDBARsp_Reject;
+	}
+	
+	pTS->bAddBaReqInProgress = false;
+	pPendingBA = &pTS->TxPendingBARecord;
+	pAdmittedBA = &pTS->TxAdmittedBARecord;
+
+
+	//
+	// Check if related BA is waiting for setup.
+	// If not, reject by sending DELBA frame.
+	//
+	if((pAdmittedBA->bValid==true))
+	{
+		// Since BA is already setup, we ignore all other ADDBA Response.
+		IEEE80211_DEBUG(IEEE80211_DL_BA, "OnADDBARsp(): Recv ADDBA Rsp. Drop because already admit it! \n");
+		return -1;
+	}
+	else if((pPendingBA->bValid == false) ||(*pDialogToken != pPendingBA->DialogToken))
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR,  "OnADDBARsp(): Recv ADDBA Rsp. BA invalid, DELBA! \n");
+		ReasonCode = DELBA_REASON_UNKNOWN_BA;
+		goto OnADDBARsp_Reject;
+	}
+	else
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_BA, "OnADDBARsp(): Recv ADDBA Rsp. BA is admitted! Status code:%X\n", *pStatusCode);
+		DeActivateBAEntry(ieee, pPendingBA);
+	}
+
+
+	if(*pStatusCode == ADDBA_STATUS_SUCCESS)
+	{
+		//
+		// Determine ADDBA Rsp content here.
+		// We can compare the value of BA parameter set that Peer returned and Self sent.
+		// If it is OK, then admitted. Or we can send DELBA to cancel BA mechanism.
+		//
+		if(pBaParamSet->field.BAPolicy == BA_POLICY_DELAYED)
+		{
+			// Since this is a kind of ADDBA failed, we delay next ADDBA process.
+			pTS->bAddBaReqDelayed = true;
+			DeActivateBAEntry(ieee, pAdmittedBA);
+			ReasonCode = DELBA_REASON_END_BA;
+			goto OnADDBARsp_Reject;
+		}
+
+
+		//
+		// Admitted condition
+		//
+		pAdmittedBA->DialogToken = *pDialogToken;
+		pAdmittedBA->BaTimeoutValue = *pBaTimeoutVal;
+		pAdmittedBA->BaStartSeqCtrl = pPendingBA->BaStartSeqCtrl;
+		pAdmittedBA->BaParamSet = *pBaParamSet;
+		DeActivateBAEntry(ieee, pAdmittedBA);
+		ActivateBAEntry(ieee, pAdmittedBA, *pBaTimeoutVal);
+	}
+	else
+	{
+		// Delay next ADDBA process.
+		pTS->bAddBaReqDelayed = true;
+	}
+
+	// End of procedure
+	return 0;
+
+OnADDBARsp_Reject:
+	{
+		BA_RECORD	BA;
+		BA.BaParamSet = *pBaParamSet;
+		ieee80211_send_DELBA(ieee, dst, &BA, TX_DIR, ReasonCode);
+		return 0;
+	}
+	
+}
+
+/********************************************************************************************************************
+ *function: RX DELBA
+ *   input:  struct sk_buff *   skb	//incoming ADDBAReq skb.
+ *  return:  0(pass), other(fail)
+ *  notice:  As this function need support of QOS, I comment some code out. And when qos is ready, this code need to be support.
+********************************************************************************************************************/
+int ieee80211_rx_DELBA(struct ieee80211_device* ieee,struct sk_buff *skb)
+{
+	 struct ieee80211_hdr_3addr* delba = NULL;
+	PDELBA_PARAM_SET	pDelBaParamSet = NULL;
+	u16*			pReasonCode = NULL;
+	u8*			dst = NULL;
+
+	if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 6)
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in DELBA(%d / %d)\n", skb->len, 	(sizeof( struct ieee80211_hdr_3addr) + 6));
+		return -1;
+	}
+	
+	if(ieee->current_network.qos_data.active == 0 ||
+		ieee->pHTInfo->bCurrentHTSupport == false )
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "received DELBA while QOS or HT is not supported(%d, %d)\n",ieee->current_network.qos_data.active, ieee->pHTInfo->bCurrentHTSupport);
+		return -1;
+	}
+	
+	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
+	delba = ( struct ieee80211_hdr_3addr*)skb->data;
+	dst = (u8*)(&delba->addr2[0]);
+	delba += sizeof( struct ieee80211_hdr_3addr);
+	pDelBaParamSet = (PDELBA_PARAM_SET)(delba+2);
+	pReasonCode = (u16*)(delba+4);
+
+	if(pDelBaParamSet->field.Initiator == 1)
+	{
+		PRX_TS_RECORD 	pRxTs;
+
+		if( !GetTs(
+				ieee, 
+				(PTS_COMMON_INFO*)&pRxTs, 
+				dst, 
+				(u8)pDelBaParamSet->field.TID, 
+				RX_DIR,
+				false)	)
+		{
+			IEEE80211_DEBUG(IEEE80211_DL_ERR,  "can't get TS for RXTS in %s()\n", __FUNCTION__);
+			return -1;
+		}
+		
+		RxTsDeleteBA(ieee, pRxTs);
+	}
+	else
+	{
+		PTX_TS_RECORD	pTxTs;
+
+		if(!GetTs(
+			ieee, 
+			(PTS_COMMON_INFO*)&pTxTs, 
+			dst, 
+			(u8)pDelBaParamSet->field.TID, 
+			TX_DIR,
+			false)	)
+		{
+			IEEE80211_DEBUG(IEEE80211_DL_ERR,  "can't get TS for TXTS in %s()\n", __FUNCTION__);
+			return -1;
+		}
+		
+		pTxTs->bUsingBa = false;
+		pTxTs->bAddBaReqInProgress = false;
+		pTxTs->bAddBaReqDelayed = false;
+		del_timer_sync(&pTxTs->TsAddBaTimer);
+		//PlatformCancelTimer(Adapter, &pTxTs->TsAddBaTimer);
+		TxTsDeleteBA(ieee, pTxTs);
+	}
+	return 0;
+}
+
+//
+// ADDBA initiate. This can only be called by TX side.
+//
+void
+TsInitAddBA(
+	struct ieee80211_device* ieee,
+	PTX_TS_RECORD	pTS,
+	u8		Policy,
+	u8		bOverwritePending
+	)
+{
+	PBA_RECORD			pBA = &pTS->TxPendingBARecord;
+
+	if(pBA->bValid==true && bOverwritePending==false)
+		return;
+
+	// Set parameters to "Pending" variable set
+	DeActivateBAEntry(ieee, pBA);
+	
+	pBA->DialogToken++;						// DialogToken: Only keep the latest dialog token
+	pBA->BaParamSet.field.AMSDU_Support = 0;	// Do not support A-MSDU with A-MPDU now!!
+	pBA->BaParamSet.field.BAPolicy = Policy;	// Policy: Delayed or Immediate
+	pBA->BaParamSet.field.TID = pTS->TsCommonInfo.TSpec.f.TSInfo.field.ucTSID;	// TID
+	// BufferSize: This need to be set according to A-MPDU vector
+	pBA->BaParamSet.field.BufferSize = 32;		// BufferSize: This need to be set according to A-MPDU vector
+	pBA->BaTimeoutValue = 0;					// Timeout value: Set 0 to disable Timer
+	pBA->BaStartSeqCtrl.field.SeqNum = (pTS->TxCurSeq + 3) % 4096; 	// Block Ack will start after 3 packets later.
+
+	ActivateBAEntry(ieee, pBA, BA_SETUP_TIMEOUT);
+
+	ieee80211_send_ADDBAReq(ieee, pTS->TsCommonInfo.Addr, pBA);
+}
+
+void
+TsInitDelBA( struct ieee80211_device* ieee, PTS_COMMON_INFO pTsCommonInfo, TR_SELECT TxRxSelect)
+{
+
+	if(TxRxSelect == TX_DIR)
+	{
+		PTX_TS_RECORD	pTxTs = (PTX_TS_RECORD)pTsCommonInfo;
+
+		if(TxTsDeleteBA(ieee, pTxTs))
+			ieee80211_send_DELBA(
+				ieee, 
+				pTsCommonInfo->Addr, 
+				(pTxTs->TxAdmittedBARecord.bValid)?(&pTxTs->TxAdmittedBARecord):(&pTxTs->TxPendingBARecord), 
+				TxRxSelect, 
+				DELBA_REASON_END_BA);
+	}
+	else if(TxRxSelect == RX_DIR)
+	{
+		PRX_TS_RECORD	pRxTs = (PRX_TS_RECORD)pTsCommonInfo;
+		if(RxTsDeleteBA(ieee, pRxTs))
+			ieee80211_send_DELBA(
+				ieee, 
+				pTsCommonInfo->Addr, 
+				&pRxTs->RxAdmittedBARecord, 
+				TxRxSelect, 
+				DELBA_REASON_END_BA	);
+	}
+}
+/********************************************************************************************************************
+ *function:  BA setup timer 
+ *   input:  unsigned long	 data		//acturally we send TX_TS_RECORD or RX_TS_RECORD to these timer
+ *  return:  NULL
+ *  notice:  
+********************************************************************************************************************/
+void BaSetupTimeOut(unsigned long data)
+{
+	PTX_TS_RECORD	pTxTs = (PTX_TS_RECORD)data;
+
+	pTxTs->bAddBaReqInProgress = false;
+	pTxTs->bAddBaReqDelayed = true;
+	pTxTs->TxPendingBARecord.bValid = false;
+}
+
+void TxBaInactTimeout(unsigned long data)
+{
+	PTX_TS_RECORD	pTxTs = (PTX_TS_RECORD)data;
+	struct ieee80211_device *ieee = container_of(pTxTs, struct ieee80211_device, TxTsRecord[pTxTs->num]);
+	TxTsDeleteBA(ieee, pTxTs);
+	ieee80211_send_DELBA(
+		ieee, 
+		pTxTs->TsCommonInfo.Addr, 
+		&pTxTs->TxAdmittedBARecord,
+		TX_DIR, 
+		DELBA_REASON_TIMEOUT);
+}
+
+void RxBaInactTimeout(unsigned long data)
+{
+	PRX_TS_RECORD	pRxTs = (PRX_TS_RECORD)data;
+	struct ieee80211_device *ieee = container_of(pRxTs, struct ieee80211_device, RxTsRecord[pRxTs->num]);
+	
+	RxTsDeleteBA(ieee, pRxTs);
+	ieee80211_send_DELBA(
+		ieee, 
+		pRxTs->TsCommonInfo.Addr, 
+		&pRxTs->RxAdmittedBARecord,
+		RX_DIR, 
+		DELBA_REASON_TIMEOUT);
+	return ;
+}
+
diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_HT.h b/drivers/staging/rtl8192u/ieee80211/rtl819x_HT.h
new file mode 100644
index 0000000..9a5a6f7
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_HT.h
@@ -0,0 +1,481 @@
+#ifndef _RTL819XU_HTTYPE_H_
+#define _RTL819XU_HTTYPE_H_
+
+//------------------------------------------------------------
+// The HT Capability element is present in beacons, association request, 
+//	reassociation request and probe response frames
+//------------------------------------------------------------
+
+//
+// Operation mode value
+//
+#define HT_OPMODE_NO_PROTECT		0
+#define HT_OPMODE_OPTIONAL		1
+#define HT_OPMODE_40MHZ_PROTECT	2
+#define HT_OPMODE_MIXED			3
+
+//
+// MIMO Power Save Setings
+//
+#define MIMO_PS_STATIC				0
+#define MIMO_PS_DYNAMIC			1
+#define MIMO_PS_NOLIMIT			3
+
+
+//
+//	There should be 128 bits to cover all of the MCS rates. However, since
+//	8190 does not support too much rates, one integer is quite enough.
+//
+
+#define sHTCLng	4
+
+
+#define HT_SUPPORTED_MCS_1SS_BITMAP					0x000000ff
+#define HT_SUPPORTED_MCS_2SS_BITMAP					0x0000ff00
+#define HT_SUPPORTED_MCS_1SS_2SS_BITMAP			HT_MCS_1SS_BITMAP|HT_MCS_1SS_2SS_BITMAP
+
+
+typedef enum _HT_MCS_RATE{
+	HT_MCS0   = 0x00000001,
+	HT_MCS1   = 0x00000002,
+	HT_MCS2   = 0x00000004,
+	HT_MCS3   = 0x00000008,
+	HT_MCS4   = 0x00000010,
+	HT_MCS5   = 0x00000020,
+	HT_MCS6   = 0x00000040,
+	HT_MCS7   = 0x00000080,
+	HT_MCS8   = 0x00000100,
+	HT_MCS9   = 0x00000200,
+	HT_MCS10 = 0x00000400,
+	HT_MCS11 = 0x00000800,
+	HT_MCS12 = 0x00001000,
+	HT_MCS13 = 0x00002000,
+	HT_MCS14 = 0x00004000,
+	HT_MCS15 = 0x00008000,	
+	// Do not define MCS32 here although 8190 support MCS32
+}HT_MCS_RATE,*PHT_MCS_RATE;
+
+//
+// Represent Channel Width in HT Capabilities
+//
+typedef enum _HT_CHANNEL_WIDTH{
+	HT_CHANNEL_WIDTH_20 = 0,
+	HT_CHANNEL_WIDTH_20_40 = 1,
+}HT_CHANNEL_WIDTH, *PHT_CHANNEL_WIDTH;
+
+//
+// Represent Extention Channel Offset in HT Capabilities
+// This is available only in 40Mhz mode.
+//
+typedef enum _HT_EXTCHNL_OFFSET{
+	HT_EXTCHNL_OFFSET_NO_EXT = 0,
+	HT_EXTCHNL_OFFSET_UPPER = 1,
+	HT_EXTCHNL_OFFSET_NO_DEF = 2,
+	HT_EXTCHNL_OFFSET_LOWER = 3,
+}HT_EXTCHNL_OFFSET, *PHT_EXTCHNL_OFFSET;
+
+typedef enum _CHNLOP{
+	CHNLOP_NONE = 0, // No Action now
+	CHNLOP_SCAN = 1, // Scan in progress
+	CHNLOP_SWBW = 2, // Bandwidth switching in progress
+	CHNLOP_SWCHNL = 3, // Software Channel switching in progress
+} CHNLOP, *PCHNLOP;
+
+// Determine if the Channel Operation is in progress
+#define CHHLOP_IN_PROGRESS(_pHTInfo)	\
+		((_pHTInfo)->ChnlOp > CHNLOP_NONE) ? TRUE : FALSE
+
+/*
+typedef	union _HT_CAPABILITY{
+	u16	ShortData;
+	u8	CharData[2];
+	struct
+	{
+		u16	AdvCoding:1;
+		u16	ChlWidth:1;
+		u16	MimoPwrSave:2;
+		u16	GreenField:1;
+		u16	ShortGI20Mhz:1;
+		u16	ShortGI40Mhz:1;
+		u16	STBC:1;
+		u16	BeamForm:1;
+		u16	DelayBA:1;
+		u16	MaxAMSDUSize:1;
+		u16	DssCCk:1;
+		u16	PSMP:1;
+		u16	Rsvd:3;
+	}Field;
+}HT_CAPABILITY, *PHT_CAPABILITY;
+
+typedef	union _HT_CAPABILITY_MACPARA{
+	u8	ShortData;
+	u8	CharData[1];
+	struct
+	{
+		u8	MaxRxAMPDU:2;
+		u8	MPDUDensity:2;
+		u8	Rsvd:4;
+	}Field;
+}HT_CAPABILITY_MACPARA, *PHT_CAPABILITY_MACPARA;
+*/
+
+typedef enum _HT_ACTION{
+	ACT_RECOMMAND_WIDTH		= 0,
+	ACT_MIMO_PWR_SAVE 		= 1,
+	ACT_PSMP					= 2,
+	ACT_SET_PCO_PHASE		= 3,
+	ACT_MIMO_CHL_MEASURE	= 4,
+	ACT_RECIPROCITY_CORRECT	= 5,
+	ACT_MIMO_CSI_MATRICS		= 6,
+	ACT_MIMO_NOCOMPR_STEER	= 7,
+	ACT_MIMO_COMPR_STEER		= 8,
+	ACT_ANTENNA_SELECT		= 9,
+} HT_ACTION, *PHT_ACTION;
+
+
+/* 2007/06/07 MH Define sub-carrier mode for 40MHZ. */
+typedef enum _HT_Bandwidth_40MHZ_Sub_Carrier{
+	SC_MODE_DUPLICATE = 0,
+	SC_MODE_LOWER = 1,
+	SC_MODE_UPPER = 2,
+	SC_MODE_FULL40MHZ = 3,
+}HT_BW40_SC_E;
+
+typedef	struct _HT_CAPABILITY_ELE{
+
+	//HT capability info
+	u8	AdvCoding:1;
+	u8	ChlWidth:1;
+	u8	MimoPwrSave:2;
+	u8	GreenField:1;
+	u8	ShortGI20Mhz:1;
+	u8	ShortGI40Mhz:1;
+	u8	TxSTBC:1;
+	u8	RxSTBC:2;
+	u8	DelayBA:1;
+	u8	MaxAMSDUSize:1;
+	u8	DssCCk:1;
+	u8	PSMP:1;
+	u8	Rsvd1:1;
+	u8	LSigTxopProtect:1;
+
+	//MAC HT parameters info
+	u8	MaxRxAMPDUFactor:2;
+	u8	MPDUDensity:3;
+	u8	Rsvd2:3;
+
+	//Supported MCS set
+	u8	MCS[16];
+			
+
+	//Extended HT Capability Info
+	u16	ExtHTCapInfo;
+
+	//TXBF Capabilities
+	u8	TxBFCap[4];
+
+	//Antenna Selection Capabilities
+	u8	ASCap;
+
+} __attribute__ ((packed)) HT_CAPABILITY_ELE, *PHT_CAPABILITY_ELE;
+
+//------------------------------------------------------------
+// The HT Information element is present in beacons 
+// Only AP is required to include this element
+//------------------------------------------------------------
+
+typedef struct _HT_INFORMATION_ELE{
+	u8	ControlChl;
+
+	u8	ExtChlOffset:2;
+	u8	RecommemdedTxWidth:1;
+	u8	RIFS:1;
+	u8	PSMPAccessOnly:1;
+	u8	SrvIntGranularity:3;
+
+	u8	OptMode:2;
+	u8	NonGFDevPresent:1;
+	u8	Revd1:5;
+	u8	Revd2:8;
+
+	u8	Rsvd3:6;
+	u8	DualBeacon:1;
+	u8	DualCTSProtect:1;
+
+	u8	SecondaryBeacon:1;
+	u8	LSigTxopProtectFull:1;
+	u8	PcoActive:1;
+	u8	PcoPhase:1;
+	u8	Rsvd4:4;
+
+	u8	BasicMSC[16];
+} __attribute__ ((packed)) HT_INFORMATION_ELE, *PHT_INFORMATION_ELE;
+
+// 
+// MIMO Power Save control field.
+// This is appear in MIMO Power Save Action Frame
+//
+typedef struct _MIMOPS_CTRL{
+	u8	MimoPsEnable:1;
+	u8	MimoPsMode:1;
+	u8	Reserved:6;
+} MIMOPS_CTRL, *PMIMOPS_CTRL;
+
+typedef enum _HT_SPEC_VER{
+	HT_SPEC_VER_IEEE = 0,
+	HT_SPEC_VER_EWC = 1,
+}HT_SPEC_VER, *PHT_SPEC_VER;
+
+typedef enum _HT_AGGRE_MODE_E{
+	HT_AGG_AUTO = 0,
+	HT_AGG_FORCE_ENABLE = 1,
+	HT_AGG_FORCE_DISABLE = 2,
+}HT_AGGRE_MODE_E, *PHT_AGGRE_MODE_E;
+
+//------------------------------------------------------------
+//  The Data structure is used to keep HT related variables when card is 
+//  configured as non-AP STA mode.  **Note**  Current_xxx should be set 
+//	to default value in HTInitializeHTInfo()
+//------------------------------------------------------------
+
+typedef struct _RT_HIGH_THROUGHPUT{
+	u8				bEnableHT;
+	u8				bCurrentHTSupport;
+
+	u8				bRegBW40MHz;				// Tx 40MHz channel capablity
+	u8				bCurBW40MHz;				// Tx 40MHz channel capability
+
+	u8				bRegShortGI40MHz;			// Tx Short GI for 40Mhz
+	u8				bCurShortGI40MHz;			// Tx Short GI for 40MHz
+
+	u8				bRegShortGI20MHz;			// Tx Short GI for 20MHz
+	u8				bCurShortGI20MHz;			// Tx Short GI for 20MHz
+
+	u8				bRegSuppCCK;				// Tx CCK rate capability
+	u8				bCurSuppCCK;				// Tx CCK rate capability
+
+	// 802.11n spec version for "peer"
+	HT_SPEC_VER			ePeerHTSpecVer;
+	
+
+	// HT related information for "Self"
+	HT_CAPABILITY_ELE	SelfHTCap;		// This is HT cap element sent to peer STA, which also indicate HT Rx capabilities.
+	HT_INFORMATION_ELE	SelfHTInfo;		// This is HT info element sent to peer STA, which also indicate HT Rx capabilities.
+
+	// HT related information for "Peer"
+	u8				PeerHTCapBuf[32];
+	u8				PeerHTInfoBuf[32];
+
+
+	// A-MSDU related
+	u8				bAMSDU_Support;			// This indicates Tx A-MSDU capability
+	u16				nAMSDU_MaxSize;			// This indicates Tx A-MSDU capability
+	u8				bCurrent_AMSDU_Support;	// This indicates Tx A-MSDU capability
+	u16				nCurrent_AMSDU_MaxSize;	// This indicates Tx A-MSDU capability
+	
+
+	// AMPDU  related <2006.08.10 Emily>
+	u8				bAMPDUEnable;				// This indicate Tx A-MPDU capability
+	u8				bCurrentAMPDUEnable;		// This indicate Tx A-MPDU capability		
+	u8				AMPDU_Factor;				// This indicate Tx A-MPDU capability
+	u8				CurrentAMPDUFactor;		// This indicate Tx A-MPDU capability
+	u8				MPDU_Density;				// This indicate Tx A-MPDU capability
+	u8				CurrentMPDUDensity;			// This indicate Tx A-MPDU capability
+
+	// Forced A-MPDU enable
+	HT_AGGRE_MODE_E	ForcedAMPDUMode;
+	u8				ForcedAMPDUFactor;
+	u8				ForcedMPDUDensity;
+
+	// Forced A-MSDU enable
+	HT_AGGRE_MODE_E	ForcedAMSDUMode;
+	u16				ForcedAMSDUMaxSize;
+
+	u8				bForcedShortGI;
+
+	u8				CurrentOpMode;
+
+	// MIMO PS related
+	u8				SelfMimoPs;
+	u8				PeerMimoPs;
+	
+	// 40MHz Channel Offset settings.
+	HT_EXTCHNL_OFFSET	CurSTAExtChnlOffset;
+	u8				bCurTxBW40MHz;	// If we use 40 MHz to Tx
+	u8				PeerBandwidth;
+
+	// For Bandwidth Switching
+	u8				bSwBwInProgress;
+	CHNLOP				ChnlOp; // software switching channel in progress. By Bruce, 2008-02-15.
+	u8				SwBwStep;
+	//struct timer_list		SwBwTimer;  //moved to ieee80211_device. as timer_list need include some header file here.
+
+	// For Realtek proprietary A-MPDU factor for aggregation
+	u8				bRegRT2RTAggregation;
+	u8				bCurrentRT2RTAggregation;
+	u8				bCurrentRT2RTLongSlotTime;
+	u8				szRT2RTAggBuffer[10];
+
+	// Rx Reorder control
+	u8				bRegRxReorderEnable;
+	u8				bCurRxReorderEnable;
+	u8				RxReorderWinSize;
+	u8				RxReorderPendingTime;
+	u16				RxReorderDropCounter;
+
+#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
+	u8				UsbTxAggrNum;
+#endif
+#ifdef USB_RX_AGGREGATION_SUPPORT
+	u8				UsbRxFwAggrEn;
+	u8				UsbRxFwAggrPageNum;
+	u8				UsbRxFwAggrPacketNum;
+	u8				UsbRxFwAggrTimeout;
+#endif
+
+	// Add for Broadcom(Linksys) IOT. Joseph
+	u8				bIsPeerBcm;
+
+	// For IOT issue.
+	u8				IOTPeer;
+	u32				IOTAction;
+} __attribute__ ((packed)) RT_HIGH_THROUGHPUT, *PRT_HIGH_THROUGHPUT;
+
+
+//------------------------------------------------------------
+// The Data structure is used to keep HT related variable for "each Sta"
+// when card is configured as "AP mode"
+//------------------------------------------------------------
+
+typedef struct _RT_HTINFO_STA_ENTRY{
+	u8			bEnableHT;
+	
+	u8			bSupportCck;
+	
+	u16			AMSDU_MaxSize;
+	
+	u8			AMPDU_Factor;
+	u8			MPDU_Density;
+	
+	u8			HTHighestOperaRate;
+
+	u8			bBw40MHz;
+
+	u8			MimoPs;
+
+	u8			McsRateSet[16];
+
+	
+}RT_HTINFO_STA_ENTRY, *PRT_HTINFO_STA_ENTRY;
+
+
+
+
+
+//------------------------------------------------------------
+// The Data structure is used to keep HT related variable for "each AP"
+// when card is configured as "STA mode"
+//------------------------------------------------------------
+
+typedef struct _BSS_HT{
+
+	u8				bdSupportHT;
+
+	// HT related elements
+	u8					bdHTCapBuf[32];
+	u16					bdHTCapLen;
+	u8					bdHTInfoBuf[32];
+	u16					bdHTInfoLen;
+
+	HT_SPEC_VER				bdHTSpecVer;
+	//HT_CAPABILITY_ELE			bdHTCapEle;
+	//HT_INFORMATION_ELE		bdHTInfoEle;
+
+	u8					bdRT2RTAggregation;
+	u8					bdRT2RTLongSlotTime;
+} __attribute__ ((packed)) BSS_HT, *PBSS_HT;
+
+typedef struct _MIMO_RSSI{
+	u32	EnableAntenna;
+	u32	AntennaA;
+	u32 	AntennaB;
+	u32 	AntennaC;
+	u32 	AntennaD;
+	u32	Average;
+}MIMO_RSSI, *PMIMO_RSSI;
+
+typedef struct _MIMO_EVM{
+	u32	EVM1;
+	u32    EVM2;
+}MIMO_EVM, *PMIMO_EVM;
+
+typedef struct _FALSE_ALARM_STATISTICS{
+	u32	Cnt_Parity_Fail;
+	u32    Cnt_Rate_Illegal;
+	u32	Cnt_Crc8_fail;
+	u32	Cnt_all;
+}FALSE_ALARM_STATISTICS, *PFALSE_ALARM_STATISTICS;
+
+
+extern u8 MCS_FILTER_ALL[16];
+extern u8 MCS_FILTER_1SS[16];
+
+/* 2007/07/11 MH Modify the macro. Becaus STA may link with a N-AP. If we set
+   STA in A/B/G mode and AP is still in N mode. The macro will be wrong. We have
+   to add a macro to judge wireless mode. */
+#define PICK_RATE(_nLegacyRate, _nMcsRate)	\
+		(_nMcsRate==0)?(_nLegacyRate&0x7f):(_nMcsRate)
+/* 2007/07/12 MH We only define legacy and HT wireless mode now. */
+#define	LEGACY_WIRELESS_MODE	IEEE_MODE_MASK
+
+#define CURRENT_RATE(WirelessMode, LegacyRate, HTRate)	\
+					((WirelessMode & (LEGACY_WIRELESS_MODE))!=0)?\
+						(LegacyRate):\
+						(PICK_RATE(LegacyRate, HTRate))
+
+
+
+// MCS Bw 40 {1~7, 12~15,32}
+#define	RATE_ADPT_1SS_MASK 		0xFF
+#define	RATE_ADPT_2SS_MASK	   	0xF0 //Skip MCS8~11 because mcs7 > mcs6, 9, 10, 11. 2007.01.16 by Emily
+#define	RATE_ADPT_MCS32_MASK		0x01
+
+#define 	IS_11N_MCS_RATE(rate)		(rate&0x80)
+
+typedef enum _HT_AGGRE_SIZE{
+	HT_AGG_SIZE_8K = 0,
+	HT_AGG_SIZE_16K = 1,
+	HT_AGG_SIZE_32K = 2,
+	HT_AGG_SIZE_64K = 3,
+}HT_AGGRE_SIZE_E, *PHT_AGGRE_SIZE_E;
+
+/* Indicate different AP vendor for IOT issue */
+typedef enum _HT_IOT_PEER
+{
+	HT_IOT_PEER_UNKNOWN = 0,
+	HT_IOT_PEER_REALTEK = 1,
+	HT_IOT_PEER_BROADCOM = 2,
+	HT_IOT_PEER_RALINK = 3,
+	HT_IOT_PEER_ATHEROS = 4,
+	HT_IOT_PEER_CISCO= 5,
+	HT_IOT_PEER_MAX = 6
+}HT_IOT_PEER_E, *PHTIOT_PEER_E;
+
+//
+// IOT Action for different AP
+//
+typedef enum _HT_IOT_ACTION{
+	HT_IOT_ACT_TX_USE_AMSDU_4K = 0x00000001,
+	HT_IOT_ACT_TX_USE_AMSDU_8K = 0x00000002,	
+	HT_IOT_ACT_DISABLE_MCS14 = 0x00000004,
+	HT_IOT_ACT_DISABLE_MCS15 = 0x00000008,
+	HT_IOT_ACT_DISABLE_ALL_2SS = 0x00000010,
+	HT_IOT_ACT_DISABLE_EDCA_TURBO = 0x00000020,
+	HT_IOT_ACT_MGNT_USE_CCK_6M = 0x00000040,
+	HT_IOT_ACT_CDD_FSYNC = 0x00000080,
+	HT_IOT_ACT_PURE_N_MODE = 0x00000100,
+	HT_IOT_ACT_FORCED_CTS2SELF = 0x00000200,
+}HT_IOT_ACTION_E, *PHT_IOT_ACTION_E;
+
+#endif //_RTL819XU_HTTYPE_H_
+
diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c
new file mode 100644
index 0000000..f00524d
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c
@@ -0,0 +1,1719 @@
+
+//As this function is mainly ported from Windows driver, so leave the name little changed. If any confusion caused, tell me. Created by WB. 2008.05.08
+#include "ieee80211.h"
+#include "rtl819x_HT.h"
+u8 MCS_FILTER_ALL[16] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+u8 MCS_FILTER_1SS[16] = {0xff, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+u16 MCS_DATA_RATE[2][2][77] = 
+	{	{	{13, 26, 39, 52, 78, 104, 117, 130, 26, 52, 78 ,104, 156, 208, 234, 260,
+			39, 78, 117, 234, 312, 351, 390, 52, 104, 156, 208, 312, 416, 468, 520, 
+			0, 78, 104, 130, 117, 156, 195, 104, 130, 130, 156, 182, 182, 208, 156, 195,
+			195, 234, 273, 273, 312, 130, 156, 181, 156, 181, 208, 234, 208, 234, 260, 260, 
+			286, 195, 234, 273, 234, 273, 312, 351, 312, 351, 390, 390, 429},			// Long GI, 20MHz
+			{14, 29, 43, 58, 87, 116, 130, 144, 29, 58, 87, 116, 173, 231, 260, 289, 
+			43, 87, 130, 173, 260, 347, 390, 433, 58, 116, 173, 231, 347, 462, 520, 578, 
+			0, 87, 116, 144, 130, 173, 217, 116, 144, 144, 173, 202, 202, 231, 173, 217, 
+			217, 260, 303, 303, 347, 144, 173, 202, 173, 202, 231, 260, 231, 260, 289, 289, 
+			318, 217, 260, 303, 260, 303, 347, 390, 347, 390, 433, 433, 477}	},		// Short GI, 20MHz
+		{	{27, 54, 81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486, 540, 
+			81, 162, 243, 324, 486, 648, 729, 810, 108, 216, 324, 432, 648, 864, 972, 1080, 
+			12, 162, 216, 270, 243, 324, 405, 216, 270, 270, 324, 378, 378, 432, 324, 405, 
+			405, 486, 567, 567, 648, 270, 324, 378, 324, 378, 432, 486, 432, 486, 540, 540, 
+			594, 405, 486, 567, 486, 567, 648, 729, 648, 729, 810, 810, 891}, 	// Long GI, 40MHz
+			{30, 60, 90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, 600, 
+			90, 180, 270, 360, 540, 720, 810, 900, 120, 240, 360, 480, 720, 960, 1080, 1200, 
+			13, 180, 240, 300, 270, 360, 450, 240, 300, 300, 360, 420, 420, 480, 360, 450, 
+			450, 540, 630, 630, 720, 300, 360, 420, 360, 420, 480, 540, 480, 540, 600, 600, 
+			660, 450, 540, 630, 540, 630, 720, 810, 720, 810, 900, 900, 990}	}	// Short GI, 40MHz
+	};
+
+static u8 UNKNOWN_BORADCOM[3] = {0x00, 0x14, 0xbf};
+static u8 LINKSYSWRT330_LINKSYSWRT300_BROADCOM[3] = {0x00, 0x1a, 0x70};
+static u8 LINKSYSWRT350_LINKSYSWRT150_BROADCOM[3] = {0x00, 0x1d, 0x7e};
+static u8 NETGEAR834Bv2_BROADCOM[3] = {0x00, 0x1b, 0x2f};
+static u8 BELKINF5D8233V1_RALINK[3] = {0x00, 0x17, 0x3f};	//cosa 03202008
+static u8 BELKINF5D82334V3_RALINK[3] = {0x00, 0x1c, 0xdf};
+static u8 PCI_RALINK[3] = {0x00, 0x90, 0xcc};
+static u8 EDIMAX_RALINK[3] = {0x00, 0x0e, 0x2e};
+static u8 AIRLINK_RALINK[3] = {0x00, 0x18, 0x02};
+//static u8 DLINK_ATHEROS[3] = {0x00, 0x1c, 0xf0};
+static u8 CISCO_BROADCOM[3] = {0x00, 0x17, 0x94};
+
+// 2008/04/01 MH For Cisco G mode RX TP We need to change FW duration. Shoud we put the
+// code in other place??
+//static u8 WIFI_CISCO_G_AP[3] = {0x00, 0x40, 0x96};
+/********************************************************************************************************************
+ *function:  This function update default settings in pHTInfo structure
+ *   input:  PRT_HIGH_THROUGHPUT	pHTInfo
+ *  output:  none
+ *  return:  none
+ *  notice:  These value need be modified if any changes.
+ * *****************************************************************************************************************/
+void HTUpdateDefaultSetting(struct ieee80211_device* ieee)
+{
+	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
+	//const typeof( ((struct ieee80211_device *)0)->pHTInfo ) *__mptr = &pHTInfo;
+	
+	//printk("pHTinfo:%p, &pHTinfo:%p, mptr:%p,  offsetof:%x\n", pHTInfo, &pHTInfo, __mptr, offsetof(struct ieee80211_device, pHTInfo));
+	//printk("===>ieee:%p,\n", ieee);
+	// ShortGI support
+	pHTInfo->bRegShortGI20MHz= 1;
+	pHTInfo->bRegShortGI40MHz= 1;
+
+	// 40MHz channel support
+	pHTInfo->bRegBW40MHz = 1;
+
+	// CCK rate support in 40MHz channel
+	if(pHTInfo->bRegBW40MHz)
+		pHTInfo->bRegSuppCCK = 1;
+	else
+		pHTInfo->bRegSuppCCK = true;
+
+	// AMSDU related
+	pHTInfo->nAMSDU_MaxSize = 7935UL;
+	pHTInfo->bAMSDU_Support = 0;
+
+	// AMPDU related
+	pHTInfo->bAMPDUEnable = 1;
+	pHTInfo->AMPDU_Factor = 2; //// 0: 2n13(8K), 1:2n14(16K), 2:2n15(32K), 3:2n16(64k)	
+	pHTInfo->MPDU_Density = 0;// 0: No restriction, 1: 1/8usec, 2: 1/4usec, 3: 1/2usec, 4: 1usec, 5: 2usec, 6: 4usec, 7:8usec
+
+	// MIMO Power Save
+	pHTInfo->SelfMimoPs = 3;// 0: Static Mimo Ps, 1: Dynamic Mimo Ps, 3: No Limitation, 2: Reserved(Set to 3 automatically.)
+	if(pHTInfo->SelfMimoPs == 2)
+		pHTInfo->SelfMimoPs = 3;
+	// 8190 only. Assign rate operation mode to firmware
+	ieee->bTxDisableRateFallBack = 0;
+	ieee->bTxUseDriverAssingedRate = 0;	
+
+#ifdef 	TO_DO_LIST
+	// 8190 only. Assign duration operation mode to firmware
+	pMgntInfo->bTxEnableFwCalcDur = (BOOLEAN)pNdisCommon->bRegTxEnableFwCalcDur;	
+#endif
+	// 8190 only, Realtek proprietary aggregation mode
+	// Set MPDUDensity=2,   1: Set MPDUDensity=2(32k)  for Realtek AP and set MPDUDensity=0(8k) for others
+	pHTInfo->bRegRT2RTAggregation = 1;//0: Set MPDUDensity=2,   1: Set MPDUDensity=2(32k)  for Realtek AP and set MPDUDensity=0(8k) for others
+	
+	// For Rx Reorder Control
+	pHTInfo->bRegRxReorderEnable = 1;
+	pHTInfo->RxReorderWinSize = 64;
+	pHTInfo->RxReorderPendingTime = 30;
+
+#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
+	pHTInfo->UsbTxAggrNum = 4;
+#endif
+#ifdef USB_RX_AGGREGATION_SUPPORT
+	pHTInfo->UsbRxFwAggrEn = 1;
+	pHTInfo->UsbRxFwAggrPageNum = 24;
+	pHTInfo->UsbRxFwAggrPacketNum = 8;
+	pHTInfo->UsbRxFwAggrTimeout = 16; ////usb rx FW aggregation timeout threshold.It's in units of 64us 
+#endif
+	
+
+}
+/********************************************************************************************************************
+ *function:  This function print out each field on HT capability IE mainly from (Beacon/ProbeRsp/AssocReq)
+ *   input:  u8*	CapIE       //Capability IE to be printed out
+ *   	     u8* 	TitleString //mainly print out caller function
+ *  output:  none
+ *  return:  none
+ *  notice:  Driver should not print out this message by default.
+ * *****************************************************************************************************************/
+void HTDebugHTCapability(u8* CapIE, u8* TitleString )
+{
+	
+	static u8	EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33};	// For 11n EWC definition, 2007.07.17, by Emily
+	PHT_CAPABILITY_ELE 		pCapELE;
+	
+	if(!memcmp(CapIE, EWC11NHTCap, sizeof(EWC11NHTCap)))
+	{
+		//EWC IE
+		IEEE80211_DEBUG(IEEE80211_DL_HT, "EWC IE in %s()\n", __FUNCTION__);
+		pCapELE = (PHT_CAPABILITY_ELE)(&CapIE[4]);		
+	}else
+		pCapELE = (PHT_CAPABILITY_ELE)(&CapIE[0]);		
+	
+	IEEE80211_DEBUG(IEEE80211_DL_HT, "<Log HT Capability>. Called by %s\n", TitleString );
+
+	IEEE80211_DEBUG(IEEE80211_DL_HT,  "\tSupported Channel Width = %s\n", (pCapELE->ChlWidth)?"20MHz": "20/40MHz");
+	IEEE80211_DEBUG(IEEE80211_DL_HT,  "\tSupport Short GI for 20M = %s\n", (pCapELE->ShortGI20Mhz)?"YES": "NO");
+	IEEE80211_DEBUG(IEEE80211_DL_HT,  "\tSupport Short GI for 40M = %s\n", (pCapELE->ShortGI40Mhz)?"YES": "NO");
+	IEEE80211_DEBUG(IEEE80211_DL_HT,  "\tSupport TX STBC = %s\n", (pCapELE->TxSTBC)?"YES": "NO");
+	IEEE80211_DEBUG(IEEE80211_DL_HT,  "\tMax AMSDU Size = %s\n", (pCapELE->MaxAMSDUSize)?"3839": "7935");
+	IEEE80211_DEBUG(IEEE80211_DL_HT,  "\tSupport CCK in 20/40 mode = %s\n", (pCapELE->DssCCk)?"YES": "NO");
+	IEEE80211_DEBUG(IEEE80211_DL_HT,  "\tMax AMPDU Factor = %d\n", pCapELE->MaxRxAMPDUFactor);
+	IEEE80211_DEBUG(IEEE80211_DL_HT,  "\tMPDU Density = %d\n", pCapELE->MPDUDensity);
+	IEEE80211_DEBUG(IEEE80211_DL_HT,  "\tMCS Rate Set = [%x][%x][%x][%x][%x]\n", pCapELE->MCS[0],\
+				pCapELE->MCS[1], pCapELE->MCS[2], pCapELE->MCS[3], pCapELE->MCS[4]);
+	return;
+		
+}
+/********************************************************************************************************************
+ *function:  This function print out each field on HT Information IE mainly from (Beacon/ProbeRsp)
+ *   input:  u8*	InfoIE       //Capability IE to be printed out
+ *   	     u8* 	TitleString //mainly print out caller function
+ *  output:  none
+ *  return:  none
+ *  notice:  Driver should not print out this message by default.
+ * *****************************************************************************************************************/
+void HTDebugHTInfo(u8*	InfoIE, u8* TitleString)
+{
+	
+	static u8	EWC11NHTInfo[] = {0x00, 0x90, 0x4c, 0x34};	// For 11n EWC definition, 2007.07.17, by Emily
+	PHT_INFORMATION_ELE		pHTInfoEle;
+	
+	if(!memcmp(InfoIE, EWC11NHTInfo, sizeof(EWC11NHTInfo)))
+	{
+		// Not EWC IE
+		IEEE80211_DEBUG(IEEE80211_DL_HT, "EWC IE in %s()\n", __FUNCTION__);
+		pHTInfoEle = (PHT_INFORMATION_ELE)(&InfoIE[4]);			
+	}else
+		pHTInfoEle = (PHT_INFORMATION_ELE)(&InfoIE[0]);
+	
+		
+	IEEE80211_DEBUG(IEEE80211_DL_HT, "<Log HT Information Element>. Called by %s\n", TitleString);
+
+	IEEE80211_DEBUG(IEEE80211_DL_HT, "\tPrimary channel = %d\n", pHTInfoEle->ControlChl);
+	IEEE80211_DEBUG(IEEE80211_DL_HT, "\tSenondary channel =");
+	switch(pHTInfoEle->ExtChlOffset)
+	{
+		case 0:
+			IEEE80211_DEBUG(IEEE80211_DL_HT, "Not Present\n");		
+			break;
+		case 1:
+			IEEE80211_DEBUG(IEEE80211_DL_HT, "Upper channel\n");
+			break;
+		case 2:
+			IEEE80211_DEBUG(IEEE80211_DL_HT, "Reserved. Eooro!!!\n");		
+			break;
+		case 3:
+			IEEE80211_DEBUG(IEEE80211_DL_HT, "Lower Channel\n");		
+			break;
+	}
+	IEEE80211_DEBUG(IEEE80211_DL_HT, "\tRecommended channel width = %s\n", (pHTInfoEle->RecommemdedTxWidth)?"20Mhz": "40Mhz");
+
+	IEEE80211_DEBUG(IEEE80211_DL_HT, "\tOperation mode for protection = ");
+	switch(pHTInfoEle->OptMode)
+	{
+		case 0:
+			IEEE80211_DEBUG(IEEE80211_DL_HT, "No Protection\n");		
+			break;
+		case 1:
+			IEEE80211_DEBUG(IEEE80211_DL_HT, "HT non-member protection mode\n");
+			break;
+		case 2:
+			IEEE80211_DEBUG(IEEE80211_DL_HT, "Suggest to open protection\n");		
+			break;
+		case 3:
+			IEEE80211_DEBUG(IEEE80211_DL_HT, "HT mixed mode\n");		
+			break;
+	}
+
+	IEEE80211_DEBUG(IEEE80211_DL_HT, "\tBasic MCS Rate Set = [%x][%x][%x][%x][%x]\n", pHTInfoEle->BasicMSC[0],\
+				pHTInfoEle->BasicMSC[1], pHTInfoEle->BasicMSC[2], pHTInfoEle->BasicMSC[3], pHTInfoEle->BasicMSC[4]);
+	return;
+}
+
+/*
+*	Return:     	true if station in half n mode and AP supports 40 bw
+*/
+bool IsHTHalfNmode40Bandwidth(struct ieee80211_device* ieee)
+{
+	bool			retValue = false;
+	PRT_HIGH_THROUGHPUT	 pHTInfo = ieee->pHTInfo;
+
+	if(pHTInfo->bCurrentHTSupport == false )	// wireless is n mode
+		retValue = false;
+	else if(pHTInfo->bRegBW40MHz == false)	// station supports 40 bw 
+		retValue = false;
+	else if(!ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) 	// station in half n mode
+		retValue = false;
+	else if(((PHT_CAPABILITY_ELE)(pHTInfo->PeerHTCapBuf))->ChlWidth) // ap support 40 bw
+		retValue = true;
+	else
+		retValue = false;
+
+	return retValue;	
+}
+
+bool IsHTHalfNmodeSGI(struct ieee80211_device* ieee, bool is40MHz)
+{
+	bool			retValue = false;
+	PRT_HIGH_THROUGHPUT	 pHTInfo = ieee->pHTInfo;
+
+	if(pHTInfo->bCurrentHTSupport == false )	// wireless is n mode
+		retValue = false;
+	else if(!ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) 	// station in half n mode
+		retValue = false;
+	else if(is40MHz) // ap support 40 bw
+	{
+		if(((PHT_CAPABILITY_ELE)(pHTInfo->PeerHTCapBuf))->ShortGI40Mhz) // ap support 40 bw short GI
+			retValue = true;
+		else
+			retValue = false;
+	}
+	else
+	{
+		if(((PHT_CAPABILITY_ELE)(pHTInfo->PeerHTCapBuf))->ShortGI20Mhz) // ap support 40 bw short GI
+			retValue = true;
+		else
+			retValue = false;
+	}	
+
+	return retValue;	
+}
+
+u16 HTHalfMcsToDataRate(struct ieee80211_device* ieee, 	u8	nMcsRate)
+{
+	
+	u8	is40MHz;
+	u8	isShortGI;
+	
+	is40MHz  =  (IsHTHalfNmode40Bandwidth(ieee))?1:0;
+	isShortGI = (IsHTHalfNmodeSGI(ieee, is40MHz))? 1:0;
+						
+	return MCS_DATA_RATE[is40MHz][isShortGI][(nMcsRate&0x7f)];
+}
+
+
+u16 HTMcsToDataRate( struct ieee80211_device* ieee, u8 nMcsRate)
+{
+	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
+	
+	u8	is40MHz = (pHTInfo->bCurBW40MHz)?1:0;
+	u8	isShortGI = (pHTInfo->bCurBW40MHz)?
+						((pHTInfo->bCurShortGI40MHz)?1:0):
+						((pHTInfo->bCurShortGI20MHz)?1:0);
+	return MCS_DATA_RATE[is40MHz][isShortGI][(nMcsRate&0x7f)];
+}
+
+/********************************************************************************************************************
+ *function:  This function returns current datarate.
+ *   input:  struct ieee80211_device* 	ieee       
+ *   	     u8 			nDataRate 
+ *  output:  none
+ *  return:  tx rate
+ *  notice:  quite unsure about how to use this function //wb
+ * *****************************************************************************************************************/
+u16  TxCountToDataRate( struct ieee80211_device* ieee, u8 nDataRate)
+{
+	//PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
+	u16		CCKOFDMRate[12] = {0x02 , 0x04 , 0x0b , 0x16 , 0x0c , 0x12 , 0x18 , 0x24 , 0x30 , 0x48 , 0x60 , 0x6c};
+	u8	is40MHz = 0;
+	u8	isShortGI = 0;
+	
+	if(nDataRate < 12)
+	{
+		return CCKOFDMRate[nDataRate];
+	}
+	else
+	{
+		if (nDataRate >= 0x10 && nDataRate <= 0x1f)//if(nDataRate > 11 && nDataRate < 28 )
+		{
+			is40MHz = 0;
+			isShortGI = 0;
+
+		      // nDataRate = nDataRate - 12;
+		}
+		else if(nDataRate >=0x20  && nDataRate <= 0x2f ) //(27, 44)
+		{
+			is40MHz = 1;
+			isShortGI = 0;		
+
+			//nDataRate = nDataRate - 28;
+		}
+		else if(nDataRate >= 0x30  && nDataRate <= 0x3f )  //(43, 60)
+		{
+			is40MHz = 0;
+			isShortGI = 1;		
+
+			//nDataRate = nDataRate - 44;
+		}
+		else if(nDataRate >= 0x40  && nDataRate <= 0x4f ) //(59, 76)
+		{
+			is40MHz = 1;
+			isShortGI = 1;		
+
+			//nDataRate = nDataRate - 60;
+		}
+		return MCS_DATA_RATE[is40MHz][isShortGI][nDataRate&0xf];
+	}
+}
+
+
+
+bool IsHTHalfNmodeAPs(struct ieee80211_device* ieee)
+{
+	bool			retValue = false;
+	struct ieee80211_network* net = &ieee->current_network;
+#if 0
+	if(pMgntInfo->bHalfNMode == false)
+		retValue = false;		
+	else
+#endif		
+	if((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3)==0) ||
+		     (memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3)==0) ||
+		     (memcmp(net->bssid, PCI_RALINK, 3)==0) ||
+		     (memcmp(net->bssid, EDIMAX_RALINK, 3)==0) ||
+		     (memcmp(net->bssid, AIRLINK_RALINK, 3)==0) ||
+		     (net->ralink_cap_exist))
+		retValue = true;
+	else if((memcmp(net->bssid, UNKNOWN_BORADCOM, 3)==0) ||
+    		    (memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0)||
+    		    (memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)==0)||
+    		    (memcmp(net->bssid, NETGEAR834Bv2_BROADCOM, 3)==0) ||
+    		    (net->broadcom_cap_exist))
+    		  retValue = true;
+	else if(net->bssht.bdRT2RTAggregation)
+		retValue = true;
+	else
+		retValue = false;
+
+	return retValue;
+}
+
+/********************************************************************************************************************
+ *function:  This function returns peer IOT.
+ *   input:  struct ieee80211_device* 	ieee       
+ *  output:  none
+ *  return:  
+ *  notice: 
+ * *****************************************************************************************************************/
+void HTIOTPeerDetermine(struct ieee80211_device* ieee)
+{
+	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
+	struct ieee80211_network* net = &ieee->current_network;
+	if(net->bssht.bdRT2RTAggregation)
+		pHTInfo->IOTPeer = HT_IOT_PEER_REALTEK;
+	else if(net->broadcom_cap_exist)
+		pHTInfo->IOTPeer = HT_IOT_PEER_BROADCOM;
+	else if((memcmp(net->bssid, UNKNOWN_BORADCOM, 3)==0) ||
+			(memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0)||
+			(memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)==0)||
+			(memcmp(net->bssid, NETGEAR834Bv2_BROADCOM, 3)==0) )
+		pHTInfo->IOTPeer = HT_IOT_PEER_BROADCOM;
+	else if((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3)==0) ||
+			(memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3)==0) ||
+			(memcmp(net->bssid, PCI_RALINK, 3)==0) ||
+			(memcmp(net->bssid, EDIMAX_RALINK, 3)==0) || 
+			(memcmp(net->bssid, AIRLINK_RALINK, 3)==0) ||
+			 net->ralink_cap_exist)
+		pHTInfo->IOTPeer = HT_IOT_PEER_RALINK;
+	else if(net->atheros_cap_exist)
+		pHTInfo->IOTPeer = HT_IOT_PEER_ATHEROS;
+	else if(memcmp(net->bssid, CISCO_BROADCOM, 3)==0)
+		pHTInfo->IOTPeer = HT_IOT_PEER_CISCO;
+	else
+		pHTInfo->IOTPeer = HT_IOT_PEER_UNKNOWN;
+
+	IEEE80211_DEBUG(IEEE80211_DL_IOT, "Joseph debug!! IOTPEER: %x\n", pHTInfo->IOTPeer);
+}
+/********************************************************************************************************************
+ *function:  Check whether driver should declare received rate up to MCS13 only since some chipset is not good 
+ *	     at receiving MCS14~15 frame from some AP.
+ *   input:  struct ieee80211_device* 	ieee       
+ *   	     u8 *			PeerMacAddr 
+ *  output:  none
+ *  return:  return 1 if driver should declare MCS13 only(otherwise return 0)
+  * *****************************************************************************************************************/
+u8 HTIOTActIsDisableMCS14(struct ieee80211_device* ieee, u8* PeerMacAddr)
+{
+	u8 ret = 0;
+#if 0
+	// Apply for 819u only
+#if (HAL_CODE_BASE==RTL8192 && DEV_BUS_TYPE==USB_INTERFACE)
+	if((memcmp(PeerMacAddr, UNKNOWN_BORADCOM, 3)==0) ||
+    		(memcmp(PeerMacAddr, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0)	
+	    )
+	{
+		ret = 1;
+	}
+
+		
+	if(pHTInfo->bCurrentRT2RTAggregation)
+	{
+		// The parameter of pHTInfo->bCurrentRT2RTAggregation must be decided previously
+		ret = 1;
+	}
+#endif
+#endif		
+	return ret;
+ }
+
+
+/**
+* Function:	HTIOTActIsDisableMCS15
+* 
+* Overview:	Check whether driver should declare capability of receving MCS15
+*			
+* Input:	
+*			PADAPTER		Adapter,
+* 			
+* Output:		None
+* Return:     	true if driver should disable MCS15
+* 2008.04.15	Emily
+*/
+bool HTIOTActIsDisableMCS15(struct ieee80211_device* ieee)
+{
+	bool retValue = false;
+
+#ifdef TODO
+	// Apply for 819u only
+#if (HAL_CODE_BASE==RTL8192)
+
+#if (DEV_BUS_TYPE == USB_INTERFACE)
+	// Alway disable MCS15 by Jerry Chang's request.by Emily, 2008.04.15
+	retValue = true;
+#elif (DEV_BUS_TYPE == PCI_INTERFACE)
+	// Enable MCS15 if the peer is Cisco AP. by Emily, 2008.05.12
+//	if(pBssDesc->bCiscoCapExist)
+//		retValue = false;
+//	else
+		retValue = false;
+#endif
+#endif
+#endif
+	// Jerry Chang suggest that 8190 1x2 does not need to disable MCS15
+	
+	return retValue;
+}
+
+/**
+* Function:	HTIOTActIsDisableMCSTwoSpatialStream
+* 
+* Overview:	Check whether driver should declare capability of receving All 2 ss packets
+*			
+* Input:	
+*			PADAPTER		Adapter,
+* 			
+* Output:		None
+* Return:     	true if driver should disable all two spatial stream packet
+* 2008.04.21	Emily
+*/
+bool HTIOTActIsDisableMCSTwoSpatialStream(struct ieee80211_device* ieee, u8 *PeerMacAddr)
+{
+	bool retValue = false;
+
+#ifdef TODO
+	// Apply for 819u only
+//#if (HAL_CODE_BASE==RTL8192)
+
+	//This rule only apply to Belkin(Ralink) AP
+	if(IS_UNDER_11N_AES_MODE(Adapter))
+	{
+		if((PlatformCompareMemory(PeerMacAddr, BELKINF5D8233V1_RALINK, 3)==0) ||
+				(PlatformCompareMemory(PeerMacAddr, PCI_RALINK, 3)==0) ||
+				(PlatformCompareMemory(PeerMacAddr, EDIMAX_RALINK, 3)==0))
+		{
+			//Set True to disable this function. Disable by default, Emily, 2008.04.23
+			retValue = false;
+		}
+	}
+
+//#endif
+#endif
+	return retValue;
+}
+
+/********************************************************************************************************************
+ *function:  Check whether driver should disable EDCA turbo mode
+ *   input:  struct ieee80211_device* 	ieee       
+ *   	     u8* 			PeerMacAddr 
+ *  output:  none
+ *  return:  return 1 if driver should disable EDCA turbo mode(otherwise return 0)
+  * *****************************************************************************************************************/
+u8 HTIOTActIsDisableEDCATurbo(struct ieee80211_device* 	ieee, u8* PeerMacAddr)
+{
+	u8	retValue = false;	// default enable EDCA Turbo mode.
+	// Set specific EDCA parameter for different AP in DM handler.
+	
+	return retValue;
+#if 0
+	if((memcmp(PeerMacAddr, UNKNOWN_BORADCOM, 3)==0)|| 
+		(memcmp(PeerMacAddr, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0)||
+		(memcmp(PeerMacAddr, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)==0)||
+		(memcmp(PeerMacAddr, NETGEAR834Bv2_BROADCOM, 3)==0))
+
+	{
+		retValue = 1;	//Linksys disable EDCA turbo mode
+	}
+
+	return retValue;
+#endif
+}
+
+/********************************************************************************************************************
+ *function:  Check whether we need to use OFDM to sned MGNT frame for broadcom AP
+ *   input:  struct ieee80211_network *network   //current network we live
+ *  output:  none
+ *  return:  return 1 if true
+  * *****************************************************************************************************************/
+u8 HTIOTActIsMgntUseCCK6M(struct ieee80211_network *network)
+{
+	u8	retValue = 0;
+
+	// 2008/01/25 MH Judeg if we need to use OFDM to sned MGNT frame for broadcom AP.
+	// 2008/01/28 MH We must prevent that we select null bssid to link.
+		
+	if(network->broadcom_cap_exist)
+	{
+		retValue = 1;
+	}	
+
+	return retValue;
+}
+
+u8 HTIOTActIsCCDFsync(u8* PeerMacAddr)
+{
+	u8	retValue = 0;
+	if(	(memcmp(PeerMacAddr, UNKNOWN_BORADCOM, 3)==0) ||
+	    	(memcmp(PeerMacAddr, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0) ||
+	    	(memcmp(PeerMacAddr, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3) ==0))
+	{
+		retValue = 1;
+	}
+	
+	return retValue;
+}
+
+void HTResetIOTSetting(
+	PRT_HIGH_THROUGHPUT		pHTInfo
+)
+{
+	pHTInfo->IOTAction = 0;
+	pHTInfo->IOTPeer = HT_IOT_PEER_UNKNOWN;
+}
+
+
+/********************************************************************************************************************
+ *function:  Construct Capablility Element in Beacon... if HTEnable is turned on
+ *   input:  struct ieee80211_device* 	ieee   
+ *   	     u8* 			posHTCap //pointer to store Capability Ele
+ *   	     u8*			len //store length of CE
+ *   	     u8				IsEncrypt //whether encrypt, needed further
+ *  output:  none
+ *  return:  none
+ *  notice:  posHTCap can't be null and should be initialized before.
+  * *****************************************************************************************************************/
+void HTConstructCapabilityElement(struct ieee80211_device* ieee, u8* posHTCap, u8* len, u8 IsEncrypt)
+{	
+	PRT_HIGH_THROUGHPUT	pHT = ieee->pHTInfo;
+	PHT_CAPABILITY_ELE 	pCapELE = NULL;
+	//u8 bIsDeclareMCS13;
+	
+	if ((posHTCap == NULL) || (pHT == NULL))
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "posHTCap or pHTInfo can't be null in HTConstructCapabilityElement()\n");
+		return;
+	}
+	memset(posHTCap, 0, *len);	
+	if(pHT->ePeerHTSpecVer == HT_SPEC_VER_EWC)
+	{
+		u8	EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33};	// For 11n EWC definition, 2007.07.17, by Emily
+		memcpy(posHTCap, EWC11NHTCap, sizeof(EWC11NHTCap));
+		pCapELE = (PHT_CAPABILITY_ELE)&(posHTCap[4]);
+	}else 
+	{
+		pCapELE = (PHT_CAPABILITY_ELE)posHTCap;
+	}
+
+	
+	//HT capability info
+	pCapELE->AdvCoding 		= 0; // This feature is not supported now!!
+	if(ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev))
+	{
+		pCapELE->ChlWidth = 0;
+	}	
+	else
+	{
+		pCapELE->ChlWidth = (pHT->bRegBW40MHz?1:0);
+	}
+	
+//	pCapELE->ChlWidth 		= (pHT->bRegBW40MHz?1:0);
+	pCapELE->MimoPwrSave 		= pHT->SelfMimoPs;
+	pCapELE->GreenField		= 0; // This feature is not supported now!!
+	pCapELE->ShortGI20Mhz		= 1; // We can receive Short GI!!
+	pCapELE->ShortGI40Mhz		= 1; // We can receive Short GI!!
+	//DbgPrint("TX HT cap/info ele BW=%d SG20=%d SG40=%d\n\r", 
+		//pCapELE->ChlWidth, pCapELE->ShortGI20Mhz, pCapELE->ShortGI40Mhz);
+	pCapELE->TxSTBC 		= 1;
+	pCapELE->RxSTBC 		= 0;
+	pCapELE->DelayBA		= 0;	// Do not support now!!
+	pCapELE->MaxAMSDUSize	= (MAX_RECEIVE_BUFFER_SIZE>=7935)?1:0;
+	pCapELE->DssCCk 		= ((pHT->bRegBW40MHz)?(pHT->bRegSuppCCK?1:0):0);
+	pCapELE->PSMP			= 0; // Do not support now!!
+	pCapELE->LSigTxopProtect	= 0; // Do not support now!!
+
+
+	//MAC HT parameters info
+        // TODO: Nedd to take care of this part
+	IEEE80211_DEBUG(IEEE80211_DL_HT, "TX HT cap/info ele BW=%d MaxAMSDUSize:%d DssCCk:%d\n", pCapELE->ChlWidth, pCapELE->MaxAMSDUSize, pCapELE->DssCCk);
+
+	if( IsEncrypt) 
+	{
+		pCapELE->MPDUDensity 	= 7; // 8us
+		pCapELE->MaxRxAMPDUFactor 	= 2; // 2 is for 32 K and 3 is 64K
+	}
+	else
+	{
+		pCapELE->MaxRxAMPDUFactor 	= 3; // 2 is for 32 K and 3 is 64K
+		pCapELE->MPDUDensity 	= 0; // no density
+	}		
+
+	//Supported MCS set
+	memcpy(pCapELE->MCS, ieee->Regdot11HTOperationalRateSet, 16);
+	if(pHT->IOTAction & HT_IOT_ACT_DISABLE_MCS15)
+		pCapELE->MCS[1] &= 0x7f;
+
+	if(pHT->IOTAction & HT_IOT_ACT_DISABLE_MCS14)
+		pCapELE->MCS[1] &= 0xbf;
+
+	if(pHT->IOTAction & HT_IOT_ACT_DISABLE_ALL_2SS)
+		pCapELE->MCS[1] &= 0x00;
+
+	// 2008.06.12	
+	// For RTL819X, if pairwisekey = wep/tkip, ap is ralink, we support only MCS0~7.
+	if(ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev))
+	{	
+		int i;
+		for(i = 1; i< 16; i++)
+			pCapELE->MCS[i] = 0;
+	}
+	
+	//Extended HT Capability Info
+	memset(&pCapELE->ExtHTCapInfo, 0, 2);
+
+
+	//TXBF Capabilities
+	memset(pCapELE->TxBFCap, 0, 4);
+
+	//Antenna Selection Capabilities
+	pCapELE->ASCap = 0;
+//add 2 to give space for element ID and len when construct frames		
+	if(pHT->ePeerHTSpecVer == HT_SPEC_VER_EWC)
+		*len = 30 + 2;
+	else
+		*len = 26 + 2;
+		
+
+		
+//	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA | IEEE80211_DL_HT, posHTCap, *len -2);
+	
+	//Print each field in detail. Driver should not print out this message by default
+//	HTDebugHTCapability(posHTCap, (u8*)"HTConstructCapability()");
+	return;
+	
+}
+/********************************************************************************************************************
+ *function:  Construct  Information Element in Beacon... if HTEnable is turned on
+ *   input:  struct ieee80211_device* 	ieee   
+ *   	     u8* 			posHTCap //pointer to store Information Ele
+ *   	     u8*			len   //store len of 
+ *   	     u8				IsEncrypt //whether encrypt, needed further
+ *  output:  none
+ *  return:  none
+ *  notice:  posHTCap can't be null and be initialized before. only AP and IBSS sta should do this
+  * *****************************************************************************************************************/
+void HTConstructInfoElement(struct ieee80211_device* ieee, u8* posHTInfo, u8* len, u8 IsEncrypt)
+{
+	PRT_HIGH_THROUGHPUT	pHT = ieee->pHTInfo;	
+	PHT_INFORMATION_ELE		pHTInfoEle = (PHT_INFORMATION_ELE)posHTInfo;
+	if ((posHTInfo == NULL) || (pHTInfoEle == NULL))
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "posHTInfo or pHTInfoEle can't be null in HTConstructInfoElement()\n");
+		return;
+	}
+	
+	memset(posHTInfo, 0, *len);
+	if ( (ieee->iw_mode == IW_MODE_ADHOC) || (ieee->iw_mode == IW_MODE_MASTER)) //ap mode is not currently supported
+	{
+		pHTInfoEle->ControlChl 			= ieee->current_network.channel; 
+		pHTInfoEle->ExtChlOffset 			= ((pHT->bRegBW40MHz == false)?HT_EXTCHNL_OFFSET_NO_EXT:
+											(ieee->current_network.channel<=6)?
+												HT_EXTCHNL_OFFSET_UPPER:HT_EXTCHNL_OFFSET_LOWER);
+		pHTInfoEle->RecommemdedTxWidth	= pHT->bRegBW40MHz;
+		pHTInfoEle->RIFS 					= 0;
+		pHTInfoEle->PSMPAccessOnly		= 0;
+		pHTInfoEle->SrvIntGranularity		= 0;
+		pHTInfoEle->OptMode				= pHT->CurrentOpMode;
+		pHTInfoEle->NonGFDevPresent		= 0;
+		pHTInfoEle->DualBeacon			= 0;
+		pHTInfoEle->SecondaryBeacon		= 0;
+		pHTInfoEle->LSigTxopProtectFull		= 0;
+		pHTInfoEle->PcoActive				= 0;
+		pHTInfoEle->PcoPhase				= 0;
+
+		memset(pHTInfoEle->BasicMSC, 0, 16);
+
+
+		*len = 22 + 2; //same above
+
+	}
+	else
+	{
+		//STA should not generate High Throughput Information Element
+		*len = 0;
+	}	
+	//IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA | IEEE80211_DL_HT, posHTInfo, *len - 2);
+	//HTDebugHTInfo(posHTInfo, "HTConstructInforElement");
+	return;
+}	
+
+/*
+  *  According to experiment, Realtek AP to STA (based on rtl8190) may achieve best performance 
+  *  if both STA and AP set limitation of aggregation size to 32K, that is, set AMPDU density to 2 
+  *  (Ref: IEEE 11n specification). However, if Realtek STA associates to other AP, STA should set 
+  *  limitation of aggregation size to 8K, otherwise, performance of traffic stream from STA to AP 
+  *  will be much less than the traffic stream from AP to STA if both of the stream runs concurrently 
+  *  at the same time.
+  *  
+  *  Frame Format
+  *  Element ID		Length		OUI			Type1		Reserved
+  *  1 byte			1 byte		3 bytes		1 byte		1 byte
+  * 
+  *  OUI 		= 0x00, 0xe0, 0x4c,
+  *  Type 	= 0x02
+  *  Reserved 	= 0x00
+  *
+  *  2007.8.21 by Emily
+*/
+/********************************************************************************************************************
+ *function:  Construct  Information Element in Beacon... in RT2RT condition
+ *   input:  struct ieee80211_device* 	ieee   
+ *   	     u8* 			posRT2RTAgg //pointer to store Information Ele
+ *   	     u8*			len   //store len  
+ *  output:  none
+ *  return:  none
+ *  notice:  
+  * *****************************************************************************************************************/
+void HTConstructRT2RTAggElement(struct ieee80211_device* ieee, u8* posRT2RTAgg, u8* len)
+{
+	if (posRT2RTAgg == NULL) {
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "posRT2RTAgg can't be null in HTConstructRT2RTAggElement()\n");
+		return;
+	}
+	memset(posRT2RTAgg, 0, *len);
+	*posRT2RTAgg++ = 0x00;
+	*posRT2RTAgg++ = 0xe0;
+	*posRT2RTAgg++ = 0x4c;
+	*posRT2RTAgg++ = 0x02;
+	*posRT2RTAgg++ = 0x01;
+	*posRT2RTAgg = 0x10;//*posRT2RTAgg = 0x02;
+	
+	if(ieee->bSupportRemoteWakeUp) {
+		*posRT2RTAgg |= 0x08;//RT_HT_CAP_USE_WOW;
+	}
+
+	*len = 6 + 2;
+	return;
+#ifdef TODO
+#if(HAL_CODE_BASE == RTL8192 && DEV_BUS_TYPE == USB_INTERFACE)
+	/*
+	//Emily. If it is required to Ask Realtek AP to send AMPDU during AES mode, enable this 
+	   section of code.
+	if(IS_UNDER_11N_AES_MODE(Adapter))
+	{
+		posRT2RTAgg->Octet[5] |=RT_HT_CAP_USE_AMPDU;
+	}else
+	{
+		posRT2RTAgg->Octet[5] &= 0xfb;	
+	}
+	*/
+	
+#else
+	// Do Nothing
+#endif
+
+	posRT2RTAgg->Length = 6;
+#endif
+
+
+
+
+}
+
+
+/********************************************************************************************************************
+ *function:  Pick the right Rate Adaptive table to use
+ *   input:  struct ieee80211_device* 	ieee   
+ *   	     u8* 			pOperateMCS //A pointer to MCS rate bitmap
+ *  return:  always we return true
+ *  notice:  
+  * *****************************************************************************************************************/
+u8 HT_PickMCSRate(struct ieee80211_device* ieee, u8* pOperateMCS)
+{
+	u8					i;
+	if (pOperateMCS == NULL)
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "pOperateMCS can't be null in HT_PickMCSRate()\n");
+		return false;
+	}
+
+	switch(ieee->mode)
+	{
+	case IEEE_A:
+	case IEEE_B:
+	case IEEE_G:
+			//legacy rate routine handled at selectedrate
+			
+			//no MCS rate
+			for(i=0;i<=15;i++){
+				pOperateMCS[i] = 0;
+			}
+			break;
+		
+	case IEEE_N_24G:	//assume CCK rate ok
+	case IEEE_N_5G:
+			// Legacy part we only use 6, 5.5,2,1 for N_24G and 6 for N_5G.
+			// Legacy part shall be handled at SelectRateSet().
+			
+			//HT part
+			// TODO: may be different if we have different number of antenna
+			pOperateMCS[0] &=RATE_ADPT_1SS_MASK;	//support MCS 0~7
+			pOperateMCS[1] &=RATE_ADPT_2SS_MASK;
+			pOperateMCS[3] &=RATE_ADPT_MCS32_MASK;
+			break;
+
+	//should never reach here
+	default:
+			
+			break;
+		
+	}
+
+	return true;
+}
+
+/*
+*	Description:
+*		This function will get the highest speed rate in input MCS set.
+*
+*	/param 	Adapter			Pionter to Adapter entity
+*			pMCSRateSet		Pointer to MCS rate bitmap
+*			pMCSFilter		Pointer to MCS rate filter
+*	
+*	/return	Highest MCS rate included in pMCSRateSet and filtered by pMCSFilter.
+*
+*/
+/********************************************************************************************************************
+ *function:  This function will get the highest speed rate in input MCS set.
+ *   input:  struct ieee80211_device* 	ieee   
+ *   	     u8* 			pMCSRateSet //Pointer to MCS rate bitmap
+ *   	     u8*			pMCSFilter //Pointer to MCS rate filter
+ *  return:  Highest MCS rate included in pMCSRateSet and filtered by pMCSFilter
+ *  notice:  
+  * *****************************************************************************************************************/
+u8 HTGetHighestMCSRate(struct ieee80211_device* ieee, u8* pMCSRateSet, u8* pMCSFilter)
+{
+	u8		i, j;
+	u8		bitMap;
+	u8		mcsRate = 0;
+	u8		availableMcsRate[16];
+	if (pMCSRateSet == NULL || pMCSFilter == NULL)
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "pMCSRateSet or pMCSFilter can't be null in HTGetHighestMCSRate()\n");
+		return false;
+	}
+	for(i=0; i<16; i++)
+		availableMcsRate[i] = pMCSRateSet[i] & pMCSFilter[i];
+
+	for(i = 0; i < 16; i++)
+	{
+		if(availableMcsRate[i] != 0)
+			break;
+	}
+	if(i == 16)
+		return false;
+
+	for(i = 0; i < 16; i++)
+	{
+		if(availableMcsRate[i] != 0)
+		{
+			bitMap = availableMcsRate[i];
+			for(j = 0; j < 8; j++)
+			{
+				if((bitMap%2) != 0)
+				{
+					if(HTMcsToDataRate(ieee, (8*i+j)) > HTMcsToDataRate(ieee, mcsRate))
+						mcsRate = (8*i+j);
+				}
+				bitMap = bitMap>>1;
+			}
+		}
+	}
+	return (mcsRate|0x80);
+}
+	
+
+
+/*
+**
+**1.Filter our operation rate set with AP's rate set 
+**2.shall reference channel bandwidth, STBC, Antenna number
+**3.generate rate adative table for firmware
+**David 20060906
+**
+** \pHTSupportedCap: the connected STA's supported rate Capability element
+*/
+u8 HTFilterMCSRate( struct ieee80211_device* ieee, u8* pSupportMCS, u8* pOperateMCS)
+{
+	
+	u8 i=0;
+	
+	// filter out operational rate set not supported by AP, the lenth of it is 16
+	for(i=0;i<=15;i++){
+		pOperateMCS[i] = ieee->Regdot11HTOperationalRateSet[i]&pSupportMCS[i];
+	}
+
+	
+	// TODO: adjust our operational rate set  according to our channel bandwidth, STBC and Antenna number
+
+	// TODO: fill suggested rate adaptive rate index and give firmware info using Tx command packet
+	// we also shall suggested the first start rate set according to our singal strength
+	HT_PickMCSRate(ieee, pOperateMCS);
+
+	// For RTL819X, if pairwisekey = wep/tkip, we support only MCS0~7.
+	if(ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev))
+		pOperateMCS[1] = 0;
+	
+	//
+	// For RTL819X, we support only MCS0~15.
+	// And also, we do not know how to use MCS32 now.
+	//
+	for(i=2; i<=15; i++)
+		pOperateMCS[i] = 0;
+	
+	return true;
+}
+void HTSetConnectBwMode(struct ieee80211_device* ieee, HT_CHANNEL_WIDTH	Bandwidth, HT_EXTCHNL_OFFSET	Offset);
+#if 0
+//I need move this function to other places, such as rx?
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+void HTOnAssocRsp_wq(struct work_struct *work)
+{
+	struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, ht_onAssRsp);
+#else
+void HTOnAssocRsp_wq(struct ieee80211_device *ieee)
+{
+#endif
+#endif
+void HTOnAssocRsp(struct ieee80211_device *ieee)
+{
+	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
+	PHT_CAPABILITY_ELE		pPeerHTCap = NULL;
+	PHT_INFORMATION_ELE		pPeerHTInfo = NULL;
+	u16	nMaxAMSDUSize = 0;
+	u8*	pMcsFilter = NULL;
+
+	static u8				EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33};		// For 11n EWC definition, 2007.07.17, by Emily
+	static u8				EWC11NHTInfo[] = {0x00, 0x90, 0x4c, 0x34};	// For 11n EWC definition, 2007.07.17, by Emily
+	
+	if( pHTInfo->bCurrentHTSupport == false )
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "<=== HTOnAssocRsp(): HT_DISABLE\n");
+		return;
+	}
+	IEEE80211_DEBUG(IEEE80211_DL_HT, "===> HTOnAssocRsp_wq(): HT_ENABLE\n");
+//	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, pHTInfo->PeerHTCapBuf, sizeof(HT_CAPABILITY_ELE));
+//	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, pHTInfo->PeerHTInfoBuf, sizeof(HT_INFORMATION_ELE));
+		
+//	HTDebugHTCapability(pHTInfo->PeerHTCapBuf,"HTOnAssocRsp_wq");
+//	HTDebugHTInfo(pHTInfo->PeerHTInfoBuf,"HTOnAssocRsp_wq");
+	//
+	if(!memcmp(pHTInfo->PeerHTCapBuf,EWC11NHTCap, sizeof(EWC11NHTCap)))
+		pPeerHTCap = (PHT_CAPABILITY_ELE)(&pHTInfo->PeerHTCapBuf[4]);
+	else
+		pPeerHTCap = (PHT_CAPABILITY_ELE)(pHTInfo->PeerHTCapBuf);
+
+	if(!memcmp(pHTInfo->PeerHTInfoBuf, EWC11NHTInfo, sizeof(EWC11NHTInfo)))
+		pPeerHTInfo = (PHT_INFORMATION_ELE)(&pHTInfo->PeerHTInfoBuf[4]);
+	else		
+		pPeerHTInfo = (PHT_INFORMATION_ELE)(pHTInfo->PeerHTInfoBuf);
+	
+
+	////////////////////////////////////////////////////////
+	// Configurations:
+	////////////////////////////////////////////////////////
+	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_HT, pPeerHTCap, sizeof(HT_CAPABILITY_ELE));
+//	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_HT, pPeerHTInfo, sizeof(HT_INFORMATION_ELE));
+	// Config Supported Channel Width setting
+	//
+	HTSetConnectBwMode(ieee, (HT_CHANNEL_WIDTH)(pPeerHTCap->ChlWidth), (HT_EXTCHNL_OFFSET)(pPeerHTInfo->ExtChlOffset));
+
+//	if(pHTInfo->bCurBW40MHz == true)
+		pHTInfo->bCurTxBW40MHz = ((pPeerHTInfo->RecommemdedTxWidth == 1)?true:false);
+
+	//
+	// Update short GI/ long GI setting
+	//
+	// TODO:
+	pHTInfo->bCurShortGI20MHz= 
+		((pHTInfo->bRegShortGI20MHz)?((pPeerHTCap->ShortGI20Mhz==1)?true:false):false);
+	pHTInfo->bCurShortGI40MHz= 
+		((pHTInfo->bRegShortGI40MHz)?((pPeerHTCap->ShortGI40Mhz==1)?true:false):false);
+
+	//
+	// Config TX STBC setting
+	//
+	// TODO:
+
+	//
+	// Config DSSS/CCK  mode in 40MHz mode
+	//
+	// TODO:
+	pHTInfo->bCurSuppCCK = 
+		((pHTInfo->bRegSuppCCK)?((pPeerHTCap->DssCCk==1)?true:false):false);
+
+
+	//
+	// Config and configure A-MSDU setting
+	//
+	pHTInfo->bCurrent_AMSDU_Support = pHTInfo->bAMSDU_Support;
+
+	nMaxAMSDUSize = (pPeerHTCap->MaxAMSDUSize==0)?3839:7935;
+
+	if(pHTInfo->nAMSDU_MaxSize > nMaxAMSDUSize )
+		pHTInfo->nCurrent_AMSDU_MaxSize = nMaxAMSDUSize;
+	else
+		pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize;
+
+
+	//
+	// Config A-MPDU setting
+	//
+	pHTInfo->bCurrentAMPDUEnable = pHTInfo->bAMPDUEnable;
+
+	// <1> Decide AMPDU Factor
+		
+	// By Emily
+	if(!pHTInfo->bRegRT2RTAggregation)
+	{
+		// Decide AMPDU Factor according to protocol handshake
+		if(pHTInfo->AMPDU_Factor > pPeerHTCap->MaxRxAMPDUFactor)
+			pHTInfo->CurrentAMPDUFactor = pPeerHTCap->MaxRxAMPDUFactor;
+		else
+			pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor;
+
+	}else
+	{
+		// Set MPDU density to 2 to Realtek AP, and set it to 0 for others
+		// Replace MPDU factor declared in original association response frame format. 2007.08.20 by Emily		
+#if 0	
+		osTmp= PacketGetElement( asocpdu, EID_Vendor, OUI_SUB_REALTEK_AGG, OUI_SUBTYPE_DONT_CARE);
+		if(osTmp.Length >= 5)	//00:e0:4c:02:00
+#endif
+		if (ieee->current_network.bssht.bdRT2RTAggregation)
+		{
+			if( ieee->pairwise_key_type != KEY_TYPE_NA) 
+				// Realtek may set 32k in security mode and 64k for others			
+				pHTInfo->CurrentAMPDUFactor = pPeerHTCap->MaxRxAMPDUFactor;
+			else
+				pHTInfo->CurrentAMPDUFactor = HT_AGG_SIZE_64K;
+		}else
+		{
+			if(pPeerHTCap->MaxRxAMPDUFactor < HT_AGG_SIZE_32K)
+				pHTInfo->CurrentAMPDUFactor = pPeerHTCap->MaxRxAMPDUFactor;
+			else
+				pHTInfo->CurrentAMPDUFactor = HT_AGG_SIZE_32K;
+		}
+	}
+
+	// <2> Set AMPDU Minimum MPDU Start Spacing
+	// 802.11n 3.0 section 9.7d.3
+#if 1
+	if(pHTInfo->MPDU_Density > pPeerHTCap->MPDUDensity)
+		pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density;
+	else
+		pHTInfo->CurrentMPDUDensity = pPeerHTCap->MPDUDensity;
+	if(ieee->pairwise_key_type != KEY_TYPE_NA ) 
+		pHTInfo->CurrentMPDUDensity 	= 7; // 8us
+#else
+	if(pHTInfo->MPDU_Density > pPeerHTCap->MPDUDensity)
+		pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density;
+	else
+		pHTInfo->CurrentMPDUDensity = pPeerHTCap->MPDUDensity;
+#endif
+	// Force TX AMSDU
+
+	// Lanhsin: mark for tmp to avoid deauth by ap from  s3
+	//if(memcmp(pMgntInfo->Bssid, NETGEAR834Bv2_BROADCOM, 3)==0)
+	if(0)
+		{
+
+			pHTInfo->bCurrentAMPDUEnable = false;
+			pHTInfo->ForcedAMSDUMode = HT_AGG_FORCE_ENABLE;
+			pHTInfo->ForcedAMSDUMaxSize = 7935;
+
+		pHTInfo->IOTAction |=  HT_IOT_ACT_TX_USE_AMSDU_8K;
+	}
+
+	// Rx Reorder Setting
+	pHTInfo->bCurRxReorderEnable = pHTInfo->bRegRxReorderEnable;
+
+	//
+	// Filter out unsupported HT rate for this AP
+	// Update RATR table
+	// This is only for 8190 ,8192 or later product which using firmware to handle rate adaptive mechanism.
+	//
+	
+	// Handle Ralink AP bad MCS rate set condition. Joseph.
+	// This fix the bug of Ralink AP. This may be removed in the future.
+	if(pPeerHTCap->MCS[0] == 0)
+		pPeerHTCap->MCS[0] = 0xff;
+		
+	HTFilterMCSRate(ieee, pPeerHTCap->MCS, ieee->dot11HTOperationalRateSet);
+
+	//
+	// Config MIMO Power Save setting
+	//
+	pHTInfo->PeerMimoPs = pPeerHTCap->MimoPwrSave;
+	if(pHTInfo->PeerMimoPs == MIMO_PS_STATIC)
+		pMcsFilter = MCS_FILTER_1SS;
+	else
+		pMcsFilter = MCS_FILTER_ALL;
+	//WB add for MCS8 bug
+//	pMcsFilter = MCS_FILTER_1SS;
+	ieee->HTHighestOperaRate = HTGetHighestMCSRate(ieee, ieee->dot11HTOperationalRateSet, pMcsFilter);
+	ieee->HTCurrentOperaRate = ieee->HTHighestOperaRate;
+
+	//
+	// Config current operation mode.
+	//
+	pHTInfo->CurrentOpMode = pPeerHTInfo->OptMode;
+
+
+
+}	
+
+void HTSetConnectBwModeCallback(struct ieee80211_device* ieee);
+/********************************************************************************************************************
+ *function:  initialize HT info(struct PRT_HIGH_THROUGHPUT)
+ *   input:  struct ieee80211_device* 	ieee   
+ *  output:  none
+ *  return:  none
+ *  notice: This function is called when *  (1) MPInitialization Phase *  (2) Receiving of Deauthentication from AP 
+********************************************************************************************************************/
+// TODO: Should this funciton be called when receiving of Disassociation?
+void HTInitializeHTInfo(struct ieee80211_device* ieee)
+{
+	PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
+
+	//
+	// These parameters will be reset when receiving deauthentication packet 
+	//
+	IEEE80211_DEBUG(IEEE80211_DL_HT, "===========>%s()\n", __FUNCTION__);
+	pHTInfo->bCurrentHTSupport = false;
+
+	// 40MHz channel support
+	pHTInfo->bCurBW40MHz = false;
+	pHTInfo->bCurTxBW40MHz = false;
+
+	// Short GI support
+	pHTInfo->bCurShortGI20MHz = false;
+	pHTInfo->bCurShortGI40MHz = false;
+	pHTInfo->bForcedShortGI = false;
+
+	// CCK rate support
+	// This flag is set to true to support CCK rate by default.
+	// It will be affected by "pHTInfo->bRegSuppCCK" and AP capabilities only when associate to
+	// 11N BSS.
+	pHTInfo->bCurSuppCCK = true;
+
+	// AMSDU related
+	pHTInfo->bCurrent_AMSDU_Support = false;
+	pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize;
+
+	// AMPUD related
+	pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density;
+	pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor;
+	
+	
+
+	// Initialize all of the parameters related to 11n	
+	memset((void*)(&(pHTInfo->SelfHTCap)), 0, sizeof(pHTInfo->SelfHTCap));
+	memset((void*)(&(pHTInfo->SelfHTInfo)), 0, sizeof(pHTInfo->SelfHTInfo));
+	memset((void*)(&(pHTInfo->PeerHTCapBuf)), 0, sizeof(pHTInfo->PeerHTCapBuf));
+	memset((void*)(&(pHTInfo->PeerHTInfoBuf)), 0, sizeof(pHTInfo->PeerHTInfoBuf));
+
+	pHTInfo->bSwBwInProgress = false;
+	pHTInfo->ChnlOp = CHNLOP_NONE;
+
+	// Set default IEEE spec for Draft N
+	pHTInfo->ePeerHTSpecVer = HT_SPEC_VER_IEEE;
+
+	// Realtek proprietary aggregation mode
+	pHTInfo->bCurrentRT2RTAggregation = false;
+	pHTInfo->bCurrentRT2RTLongSlotTime = false;
+	pHTInfo->IOTPeer = 0;
+	pHTInfo->IOTAction = 0;
+	
+	//MCS rate initialized here
+	{
+		u8* RegHTSuppRateSets = &(ieee->RegHTSuppRateSet[0]);
+		RegHTSuppRateSets[0] = 0xFF;	//support MCS 0~7
+		RegHTSuppRateSets[1] = 0xFF;	//support MCS 8~15
+		RegHTSuppRateSets[4] = 0x01;	//support MCS 32
+	}
+}
+/********************************************************************************************************************
+ *function:  initialize Bss HT structure(struct PBSS_HT)
+ *   input:  PBSS_HT pBssHT //to be initialized 
+ *  output:  none
+ *  return:  none
+ *  notice: This function is called when initialize network structure  
+********************************************************************************************************************/
+void HTInitializeBssDesc(PBSS_HT pBssHT)
+{
+
+	pBssHT->bdSupportHT = false;
+	memset(pBssHT->bdHTCapBuf, 0, sizeof(pBssHT->bdHTCapBuf));
+	pBssHT->bdHTCapLen = 0;
+	memset(pBssHT->bdHTInfoBuf, 0, sizeof(pBssHT->bdHTInfoBuf));
+	pBssHT->bdHTInfoLen = 0;
+
+	pBssHT->bdHTSpecVer= HT_SPEC_VER_IEEE;
+
+	pBssHT->bdRT2RTAggregation = false;
+	pBssHT->bdRT2RTLongSlotTime = false;
+}
+#if 0
+//below function has merged into ieee80211_network_init() in ieee80211_rx.c
+void
+HTParsingHTCapElement(
+	IN	PADAPTER		Adapter,
+	IN	OCTET_STRING	HTCapIE,
+	OUT	PRT_WLAN_BSS	pBssDesc
+)
+{
+	PMGNT_INFO      			pMgntInfo = &Adapter->MgntInfo;
+	
+	if( HTCapIE.Length > sizeof(pBssDesc->BssHT.bdHTCapBuf) )
+	{
+		RT_TRACE( COMP_HT, DBG_LOUD, ("HTParsingHTCapElement(): HT Capability Element length is too long!\n") );
+		return;
+	}
+
+	// TODO: Check the correctness of HT Cap 
+	//Print each field in detail. Driver should not print out this message by default
+	if(!pMgntInfo->mActingAsAp && !pMgntInfo->mAssoc)
+		HTDebugHTCapability(DBG_TRACE, Adapter, &HTCapIE, (pu8)"HTParsingHTCapElement()");
+
+	HTCapIE.Length = HTCapIE.Length > sizeof(pBssDesc->BssHT.bdHTCapBuf)?\
+		sizeof(pBssDesc->BssHT.bdHTCapBuf):HTCapIE.Length;	//prevent from overflow
+		
+	CopyMem(pBssDesc->BssHT.bdHTCapBuf, HTCapIE.Octet, HTCapIE.Length);
+	pBssDesc->BssHT.bdHTCapLen = HTCapIE.Length;
+
+}
+
+
+void
+HTParsingHTInfoElement(
+	PADAPTER		Adapter,
+	OCTET_STRING	HTInfoIE,
+	PRT_WLAN_BSS	pBssDesc
+)
+{
+	PMGNT_INFO      			pMgntInfo = &Adapter->MgntInfo;
+	
+	if( HTInfoIE.Length > sizeof(pBssDesc->BssHT.bdHTInfoBuf))
+	{
+		RT_TRACE( COMP_HT, DBG_LOUD, ("HTParsingHTInfoElement(): HT Information Element length is too long!\n") );
+		return;
+	}
+
+	// TODO: Check the correctness of HT Info 
+	//Print each field in detail. Driver should not print out this message by default
+	if(!pMgntInfo->mActingAsAp && !pMgntInfo->mAssoc)		
+		HTDebugHTInfo(DBG_TRACE, Adapter, &HTInfoIE, (pu8)"HTParsingHTInfoElement()");		
+	
+	HTInfoIE.Length = HTInfoIE.Length > sizeof(pBssDesc->BssHT.bdHTInfoBuf)?\
+		sizeof(pBssDesc->BssHT.bdHTInfoBuf):HTInfoIE.Length;	//prevent from overflow
+		
+	CopyMem( pBssDesc->BssHT.bdHTInfoBuf, HTInfoIE.Octet, HTInfoIE.Length);
+	pBssDesc->BssHT.bdHTInfoLen = HTInfoIE.Length;
+}
+
+/*
+  * Get HT related information from beacon and save it in BssDesc
+  *
+  * (1) Parse HTCap, and HTInfo, and record whether it is 11n AP
+  * (2) If peer is HT, but not WMM, call QosSetLegacyWMMParamWithHT()
+  * (3) Check whether peer is Realtek AP (for Realtek proprietary aggregation mode).
+  * Input:		
+  * 		PADAPTER	Adapter
+  * 			
+  * Output:		
+  *		PRT_TCB		BssDesc
+  *
+*/
+void HTGetValueFromBeaconOrProbeRsp(
+	PADAPTER			Adapter,
+	POCTET_STRING		pSRCmmpdu,
+	PRT_WLAN_BSS		bssDesc
+)
+{
+	PMGNT_INFO      			pMgntInfo = &Adapter->MgntInfo;
+	PRT_HIGH_THROUGHPUT		pHTInfo = GET_HT_INFO(pMgntInfo);
+	OCTET_STRING				HTCapIE, HTInfoIE, HTRealtekAgg, mmpdu;
+	OCTET_STRING				BroadcomElement, CiscoElement;
+
+	mmpdu.Octet = pSRCmmpdu->Octet;
+	mmpdu.Length = pSRCmmpdu->Length;
+		
+	//2Note:  
+	//   Mark for IOT testing using  Linksys WRT350N, This AP does not contain WMM IE  when 
+	//   it is configured at pure-N mode.
+	//	if(bssDesc->BssQos.bdQoSMode & QOS_WMM)
+	//	
+
+	HTInitializeBssDesc (&bssDesc->BssHT);
+
+	//2<1> Parse HTCap, and HTInfo
+	// Get HT Capability IE: (1) Get IEEE Draft N IE or (2) Get EWC IE
+	HTCapIE = PacketGetElement(mmpdu, EID_HTCapability, OUI_SUB_DONT_CARE, OUI_SUBTYPE_DONT_CARE);
+	if(HTCapIE.Length == 0)
+	{
+		HTCapIE = PacketGetElement(mmpdu, EID_Vendor, OUI_SUB_11N_EWC_HT_CAP, OUI_SUBTYPE_DONT_CARE);		
+		if(HTCapIE.Length != 0)
+			bssDesc->BssHT.bdHTSpecVer= HT_SPEC_VER_EWC;
+	}
+	if(HTCapIE.Length != 0)
+		HTParsingHTCapElement(Adapter, HTCapIE, bssDesc);
+
+	// Get HT Information IE: (1) Get IEEE Draft N IE or (2) Get EWC IE
+	HTInfoIE = PacketGetElement(mmpdu, EID_HTInfo, OUI_SUB_DONT_CARE, OUI_SUBTYPE_DONT_CARE);
+	if(HTInfoIE.Length == 0)
+	{
+		HTInfoIE = PacketGetElement(mmpdu, EID_Vendor, OUI_SUB_11N_EWC_HT_INFO, OUI_SUBTYPE_DONT_CARE);
+		if(HTInfoIE.Length != 0)
+				bssDesc->BssHT.bdHTSpecVer  = HT_SPEC_VER_EWC;
+	}
+	if(HTInfoIE.Length != 0)
+		HTParsingHTInfoElement(Adapter, HTInfoIE, bssDesc);
+
+	//2<2>If peer is HT, but not WMM, call QosSetLegacyWMMParamWithHT()
+	if(HTCapIE.Length != 0)
+	{
+		bssDesc->BssHT.bdSupportHT = true;
+		if(bssDesc->BssQos.bdQoSMode == QOS_DISABLE)
+			QosSetLegacyWMMParamWithHT(Adapter, bssDesc);	
+	}
+	else
+	{
+		bssDesc->BssHT.bdSupportHT = false;
+	}
+
+	//2<3>Check whether the peer is Realtek AP/STA
+	if(pHTInfo->bRegRT2RTAggregation)
+	{
+		if(bssDesc->BssHT.bdSupportHT)
+		{
+			HTRealtekAgg = PacketGetElement(mmpdu, EID_Vendor, OUI_SUB_REALTEK_AGG, OUI_SUBTYPE_DONT_CARE);
+			if(HTRealtekAgg.Length >=5 )
+			{
+				bssDesc->BssHT.bdRT2RTAggregation = true;
+
+				if((HTRealtekAgg.Octet[4]==1) && (HTRealtekAgg.Octet[5] & 0x02))
+					bssDesc->BssHT.bdRT2RTLongSlotTime = true;
+			}
+		}
+	}
+
+	//
+	// 2008/01/25 MH Get Broadcom AP IE for manamgent frame CCK rate problem.
+	// AP can not receive CCK managemtn from from 92E.
+	//
+
+	// Initialize every new bss broadcom cap exist as false..	
+	bssDesc->bBroadcomCapExist= false;	
+	
+	if(HTCapIE.Length != 0 || HTInfoIE.Length != 0)
+	{
+		u4Byte	Length = 0;
+
+		FillOctetString(BroadcomElement, NULL, 0);
+
+		BroadcomElement = PacketGetElement( mmpdu, EID_Vendor, OUI_SUB_BROADCOM_IE_1, OUI_SUBTYPE_DONT_CARE);
+		Length += BroadcomElement.Length;
+		BroadcomElement = PacketGetElement( mmpdu, EID_Vendor, OUI_SUB_BROADCOM_IE_2, OUI_SUBTYPE_DONT_CARE);
+		Length += BroadcomElement.Length;
+		BroadcomElement = PacketGetElement( mmpdu, EID_Vendor, OUI_SUB_BROADCOM_IE_3, OUI_SUBTYPE_DONT_CARE);
+		Length += BroadcomElement.Length;
+		
+		if(Length > 0)
+			bssDesc->bBroadcomCapExist = true;	
+	}	
+
+
+	// For Cisco IOT issue
+	CiscoElement = PacketGetElement( mmpdu, EID_Vendor, OUI_SUB_CISCO_IE, OUI_SUBTYPE_DONT_CARE);
+	if(CiscoElement.Length != 0){ // 3: 0x00, 0x40, 0x96 ....
+		bssDesc->bCiscoCapExist = true;
+	}else{
+		bssDesc->bCiscoCapExist = false;
+	}
+}
+
+
+#endif
+/********************************************************************************************************************
+ *function:  initialize Bss HT structure(struct PBSS_HT)
+ *   input:  struct ieee80211_device 	*ieee 
+ *   	     struct ieee80211_network 	*pNetwork //usually current network we are live in
+ *  output:  none
+ *  return:  none
+ *  notice: This function should ONLY be called before association  
+********************************************************************************************************************/
+void HTResetSelfAndSavePeerSetting(struct ieee80211_device* ieee, 	struct ieee80211_network * pNetwork)
+{
+	PRT_HIGH_THROUGHPUT		pHTInfo = ieee->pHTInfo;
+//	u16						nMaxAMSDUSize;
+//	PHT_CAPABILITY_ELE		pPeerHTCap = (PHT_CAPABILITY_ELE)pNetwork->bssht.bdHTCapBuf;
+//	PHT_INFORMATION_ELE		pPeerHTInfo = (PHT_INFORMATION_ELE)pNetwork->bssht.bdHTInfoBuf;
+//	u8*	pMcsFilter;
+	u8	bIOTAction = 0;
+
+	//
+	//  Save Peer Setting before Association
+	//
+	IEEE80211_DEBUG(IEEE80211_DL_HT, "==============>%s()\n", __FUNCTION__);
+	/*unmark bEnableHT flag here is the same reason why unmarked in function ieee80211_softmac_new_net. WB 2008.09.10*/
+//	if( pHTInfo->bEnableHT &&  pNetwork->bssht.bdSupportHT)
+	if (pNetwork->bssht.bdSupportHT)
+	{
+		pHTInfo->bCurrentHTSupport = true;
+		pHTInfo->ePeerHTSpecVer = pNetwork->bssht.bdHTSpecVer;
+
+		// Save HTCap and HTInfo information Element
+		if(pNetwork->bssht.bdHTCapLen > 0 && 	pNetwork->bssht.bdHTCapLen <= sizeof(pHTInfo->PeerHTCapBuf))
+			memcpy(pHTInfo->PeerHTCapBuf, pNetwork->bssht.bdHTCapBuf, pNetwork->bssht.bdHTCapLen);
+
+		if(pNetwork->bssht.bdHTInfoLen > 0 && pNetwork->bssht.bdHTInfoLen <= sizeof(pHTInfo->PeerHTInfoBuf))
+			memcpy(pHTInfo->PeerHTInfoBuf, pNetwork->bssht.bdHTInfoBuf, pNetwork->bssht.bdHTInfoLen);
+
+		// Check whether RT to RT aggregation mode is enabled
+		if(pHTInfo->bRegRT2RTAggregation)
+		{
+			pHTInfo->bCurrentRT2RTAggregation = pNetwork->bssht.bdRT2RTAggregation;
+			pHTInfo->bCurrentRT2RTLongSlotTime = pNetwork->bssht.bdRT2RTLongSlotTime;
+		}
+		else
+		{
+			pHTInfo->bCurrentRT2RTAggregation = false;	
+			pHTInfo->bCurrentRT2RTLongSlotTime = false;
+		}
+	
+		// Determine the IOT Peer Vendor.
+		HTIOTPeerDetermine(ieee);
+				 			
+		// Decide IOT Action
+		// Must be called after the parameter of pHTInfo->bCurrentRT2RTAggregation is decided
+		pHTInfo->IOTAction = 0;
+		bIOTAction = HTIOTActIsDisableMCS14(ieee, pNetwork->bssid);
+		if(bIOTAction)
+			pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_MCS14;
+
+		bIOTAction = HTIOTActIsDisableMCS15(ieee);
+		if(bIOTAction)
+			pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_MCS15;
+
+		bIOTAction = HTIOTActIsDisableMCSTwoSpatialStream(ieee, pNetwork->bssid);
+		if(bIOTAction)
+			pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_ALL_2SS;
+
+
+		bIOTAction = HTIOTActIsDisableEDCATurbo(ieee, pNetwork->bssid);
+		if(bIOTAction)
+			pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_EDCA_TURBO;
+
+		bIOTAction = HTIOTActIsMgntUseCCK6M(pNetwork);
+		if(bIOTAction)
+			pHTInfo->IOTAction |= HT_IOT_ACT_MGNT_USE_CCK_6M;
+
+		bIOTAction = HTIOTActIsCCDFsync(pNetwork->bssid);
+		if(bIOTAction)
+			pHTInfo->IOTAction |= HT_IOT_ACT_CDD_FSYNC;
+
+
+	}
+	else
+	{
+		pHTInfo->bCurrentHTSupport = false;
+		pHTInfo->bCurrentRT2RTAggregation = false;
+		pHTInfo->bCurrentRT2RTLongSlotTime = false;
+
+		pHTInfo->IOTAction = 0;
+	}
+	
+}
+
+void HTUpdateSelfAndPeerSetting(struct ieee80211_device* ieee, 	struct ieee80211_network * pNetwork)
+{
+	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
+//	PHT_CAPABILITY_ELE		pPeerHTCap = (PHT_CAPABILITY_ELE)pNetwork->bssht.bdHTCapBuf;
+	PHT_INFORMATION_ELE		pPeerHTInfo = (PHT_INFORMATION_ELE)pNetwork->bssht.bdHTInfoBuf;
+
+	if(pHTInfo->bCurrentHTSupport)
+	{
+		//
+		// Config current operation mode.
+		//
+		if(pNetwork->bssht.bdHTInfoLen != 0)
+			pHTInfo->CurrentOpMode = pPeerHTInfo->OptMode;
+
+		//
+		// <TODO: Config according to OBSS non-HT STA present!!>
+		//
+	}
+}
+
+void HTUseDefaultSetting(struct ieee80211_device* ieee)
+{
+	PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
+//	u8	regBwOpMode;
+	
+	if(pHTInfo->bEnableHT)
+	{
+		pHTInfo->bCurrentHTSupport = true;
+
+		pHTInfo->bCurSuppCCK = pHTInfo->bRegSuppCCK;
+
+		pHTInfo->bCurBW40MHz = pHTInfo->bRegBW40MHz;
+
+		pHTInfo->bCurShortGI20MHz= pHTInfo->bRegShortGI20MHz;
+
+		pHTInfo->bCurShortGI40MHz= pHTInfo->bRegShortGI40MHz;
+
+		pHTInfo->bCurrent_AMSDU_Support = pHTInfo->bAMSDU_Support;
+
+		pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize;
+
+		pHTInfo->bCurrentAMPDUEnable = pHTInfo->bAMPDUEnable;
+
+		pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor;
+
+		pHTInfo->CurrentMPDUDensity = pHTInfo->CurrentMPDUDensity;
+
+		// Set BWOpMode register
+
+		//update RATR index0
+		HTFilterMCSRate(ieee, ieee->Regdot11HTOperationalRateSet, ieee->dot11HTOperationalRateSet);
+	//function below is not implemented at all. WB
+#ifdef TODO
+		Adapter->HalFunc.InitHalRATRTableHandler( Adapter, &pMgntInfo->dot11OperationalRateSet, pMgntInfo->dot11HTOperationalRateSet);
+#endif
+		ieee->HTHighestOperaRate = HTGetHighestMCSRate(ieee, ieee->dot11HTOperationalRateSet, MCS_FILTER_ALL);
+		ieee->HTCurrentOperaRate = ieee->HTHighestOperaRate;
+
+	}
+	else
+	{
+		pHTInfo->bCurrentHTSupport = false;
+	}
+	return;
+}
+/********************************************************************************************************************
+ *function:  check whether HT control field exists
+ *   input:  struct ieee80211_device 	*ieee 
+ *   	     u8*			pFrame //coming skb->data
+ *  output:  none
+ *  return:  return true if HT control field exists(false otherwise)
+ *  notice: 
+********************************************************************************************************************/
+u8 HTCCheck(struct ieee80211_device* ieee, u8*	pFrame)
+{
+	if(ieee->pHTInfo->bCurrentHTSupport)
+	{
+		if( (IsQoSDataFrame(pFrame) && Frame_Order(pFrame)) == 1)
+		{
+			IEEE80211_DEBUG(IEEE80211_DL_HT, "HT CONTROL FILED EXIST!!\n");
+			return true;
+		}
+	}
+	return false;
+}
+
+//
+// This function set bandwidth mode in protocol layer.
+//
+void HTSetConnectBwMode(struct ieee80211_device* ieee, HT_CHANNEL_WIDTH	Bandwidth, HT_EXTCHNL_OFFSET	Offset)
+{
+	PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
+//	u32 flags = 0;
+
+	if(pHTInfo->bRegBW40MHz == false)
+		return;
+
+
+	
+	// To reduce dummy operation
+//	if((pHTInfo->bCurBW40MHz==false && Bandwidth==HT_CHANNEL_WIDTH_20) ||
+//	   (pHTInfo->bCurBW40MHz==true && Bandwidth==HT_CHANNEL_WIDTH_20_40 && Offset==pHTInfo->CurSTAExtChnlOffset))
+//		return;
+
+//	spin_lock_irqsave(&(ieee->bw_spinlock), flags);
+	if(pHTInfo->bSwBwInProgress) {
+//		spin_unlock_irqrestore(&(ieee->bw_spinlock), flags);
+		return;
+	}
+	//if in half N mode, set to 20M bandwidth please 09.08.2008 WB.
+	if(Bandwidth==HT_CHANNEL_WIDTH_20_40 && (!ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)))
+	 {
+	 		// Handle Illegal extention channel offset!!
+		if(ieee->current_network.channel<2 && Offset==HT_EXTCHNL_OFFSET_LOWER)
+			Offset = HT_EXTCHNL_OFFSET_NO_EXT;
+		if(Offset==HT_EXTCHNL_OFFSET_UPPER || Offset==HT_EXTCHNL_OFFSET_LOWER) {
+			pHTInfo->bCurBW40MHz = true;
+			pHTInfo->CurSTAExtChnlOffset = Offset;
+		} else {
+			pHTInfo->bCurBW40MHz = false;
+			pHTInfo->CurSTAExtChnlOffset = HT_EXTCHNL_OFFSET_NO_EXT;
+		}
+	} else {
+		pHTInfo->bCurBW40MHz = false;
+		pHTInfo->CurSTAExtChnlOffset = HT_EXTCHNL_OFFSET_NO_EXT;
+	}
+
+	pHTInfo->bSwBwInProgress = true;
+
+	// TODO: 2007.7.13 by Emily Wait 2000ms  in order to garantee that switching
+	//   bandwidth is executed after scan is finished. It is a temporal solution
+	//   because software should ganrantee the last operation of switching bandwidth
+	//   is executed properlly.
+	HTSetConnectBwModeCallback(ieee);
+
+//	spin_unlock_irqrestore(&(ieee->bw_spinlock), flags);
+}
+
+void HTSetConnectBwModeCallback(struct ieee80211_device* ieee)
+{
+	PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
+
+	IEEE80211_DEBUG(IEEE80211_DL_HT, "======>%s()\n", __FUNCTION__);
+
+	if(pHTInfo->bCurBW40MHz)
+	{
+		if(pHTInfo->CurSTAExtChnlOffset==HT_EXTCHNL_OFFSET_UPPER)
+			ieee->set_chan(ieee->dev, ieee->current_network.channel+2);
+		else if(pHTInfo->CurSTAExtChnlOffset==HT_EXTCHNL_OFFSET_LOWER)
+			ieee->set_chan(ieee->dev, ieee->current_network.channel-2);
+		else
+			ieee->set_chan(ieee->dev, ieee->current_network.channel);
+		
+		ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20_40, pHTInfo->CurSTAExtChnlOffset);
+	} else {
+		ieee->set_chan(ieee->dev, ieee->current_network.channel);
+		ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
+	}
+
+	pHTInfo->bSwBwInProgress = false;
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+EXPORT_SYMBOL_NOVERS(HTUpdateSelfAndPeerSetting);
+#else
+EXPORT_SYMBOL(HTUpdateSelfAndPeerSetting);
+#endif
diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_Qos.h b/drivers/staging/rtl8192u/ieee80211/rtl819x_Qos.h
new file mode 100644
index 0000000..7635ad5
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_Qos.h
@@ -0,0 +1,749 @@
+#ifndef __INC_QOS_TYPE_H
+#define __INC_QOS_TYPE_H
+
+//#include "EndianFree.h"
+#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
+
+#define	MAX_WMMELE_LENGTH	64
+
+//
+// QoS mode.
+// enum 0, 1, 2, 4: since we can use the OR(|) operation.
+//
+// QOS_MODE is redefined for enum can't be ++, | under C++ compiler, 2006.05.17, by rcnjko.
+//typedef	enum _QOS_MODE{
+//	QOS_DISABLE		= 0,
+//	QOS_WMM			= 1,
+//	QOS_EDCA			= 2,	
+//	QOS_HCCA			= 4,
+//}QOS_MODE,*PQOS_MODE;
+//
+typedef u32 QOS_MODE, *PQOS_MODE;
+#define QOS_DISABLE		0
+#define QOS_WMM			1
+#define QOS_WMMSA		2
+#define QOS_EDCA		4
+#define QOS_HCCA		8
+#define QOS_WMM_UAPSD		16   //WMM Power Save, 2006-06-14 Isaiah 
+
+#define AC_PARAM_SIZE	4
+#define WMM_PARAM_ELE_BODY_LEN	18
+
+//
+// QoS ACK Policy Field Values
+// Ref: WMM spec 2.1.6: QoS Control Field, p.10.
+//
+typedef	enum _ACK_POLICY{
+	eAckPlc0_ACK		= 0x00,
+	eAckPlc1_NoACK		= 0x01,
+}ACK_POLICY,*PACK_POLICY;
+
+#define WMM_PARAM_ELEMENT_SIZE	(8+(4*AC_PARAM_SIZE))
+#if 0
+#define GET_QOS_CTRL(_pStart)	ReadEF2Byte((u8 *)(_pStart) + 24)
+#define SET_QOS_CTRL(_pStart, _value)	WriteEF2Byte((u8 *)(_pStart) + 24, _value)
+
+// WMM control field.
+#define GET_QOS_CTRL_WMM_UP(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 0, 3))
+#define SET_QOS_CTRL_WMM_UP(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 0, 3, (u8)(_value))
+
+#define GET_QOS_CTRL_WMM_EOSP(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 4, 1))
+#define SET_QOS_CTRL_WMM_EOSP(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 4, 1, (u8)(_value))
+
+#define GET_QOS_CTRL_WMM_ACK_POLICY(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 5, 2))
+#define SET_QOS_CTRL_WMM_ACK_POLICY(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 5, 2, (u8)(_value))
+
+// 802.11e control field (by STA, data)
+#define GET_QOS_CTRL_STA_DATA_TID(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 0, 4))
+#define SET_QOS_CTRL_STA_DATA_TID(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 0, 4, (u8)(_value))
+
+#define GET_QOS_CTRL_STA_DATA_QSIZE_FLAG(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 4, 1))
+#define SET_QOS_CTRL_STA_DATA_QSIZE_FLAG(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 4, 1, (u8)(_value))
+
+#define GET_QOS_CTRL_STA_DATA_ACK_POLICY(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 5, 2))
+#define SET_QOS_CTRL_STA_DATA_ACK_POLICY(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 5, 2, (u8)(_value))
+
+#define GET_QOS_CTRL_STA_DATA_TXOP(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 8, 8))
+#define SET_QOS_CTRL_STA_DATA_TXOP(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 8, 8, (u8)(_value))
+
+#define GET_QOS_CTRL_STA_DATA_QSIZE(_pStart)	GET_QOS_CTRL_STA_DATA_TXOP(_pStart)
+#define SET_QOS_CTRL_STA_DATA_QSIZE(_pStart, _value)	SET_QOS_CTRL_STA_DATA_TXOP(_pStart)
+
+// 802.11e control field (by HC, data)
+#define GET_QOS_CTRL_HC_DATA_TID(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 0, 4))
+#define SET_QOS_CTRL_HC_DATA_TID(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 0, 4, (u8)(_value))
+
+#define GET_QOS_CTRL_HC_DATA_EOSP(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 4, 1))
+#define SET_QOS_CTRL_HC_DATA_EOSP(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 4, 1, (u8)(_value))
+
+#define GET_QOS_CTRL_HC_DATA_ACK_POLICY(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 5, 2))
+#define SET_QOS_CTRL_HC_DATA_ACK_POLICY(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 5, 2, (u8)(_value))
+
+#define GET_QOS_CTRL_HC_DATA_PS_BUFSTATE(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 8, 8))
+#define SET_QOS_CTRL_HC_DATA_PS_BUFSTATE(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 8, 8, (u8)(_value))
+
+// 802.11e control field (by HC, CFP)
+#define GET_QOS_CTRL_HC_CFP_TID(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 0, 4))
+#define SET_QOS_CTRL_HC_CFP_TID(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 0, 4, (u8)(_value))
+
+#define GET_QOS_CTRL_HC_CFP_EOSP(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 4, 1))
+#define SET_QOS_CTRL_HC_CFP_EOSP(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 4, 1, (u8)(_value))
+
+#define GET_QOS_CTRL_HC_CFP_ACK_POLICY(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 5, 2))
+#define SET_QOS_CTRL_HC_CFP_ACK_POLICY(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 5, 2, (u8)(_value))
+
+#define GET_QOS_CTRL_HC_CFP_TXOP_LIMIT(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 8, 8))
+#define SET_QOS_CTRL_HC_CFP_TXOP_LIMIT(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 8, 8, (u8)(_value))
+
+#define SET_WMM_QOS_INFO_FIELD(_pStart, _val)	WriteEF1Byte(_pStart, _val)
+
+#define GET_WMM_QOS_INFO_FIELD_PARAMETERSET_COUNT(_pStart)	LE_BITS_TO_1BYTE(_pStart, 0, 4)
+#define SET_WMM_QOS_INFO_FIELD_PARAMETERSET_COUNT(_pStart, _val)	SET_BITS_TO_LE_1BYTE(_pStart, 0, 4, _val)
+
+#define GET_WMM_QOS_INFO_FIELD_AP_UAPSD(_pStart)	LE_BITS_TO_1BYTE(_pStart, 7, 1)
+#define SET_WMM_QOS_INFO_FIELD_AP_UAPSD(_pStart, _val)	SET_BITS_TO_LE_1BYTE(_pStart, 7, 1, _val)
+
+#define GET_WMM_QOS_INFO_FIELD_STA_AC_VO_UAPSD(_pStart)	LE_BITS_TO_1BYTE(_pStart, 0, 1)
+#define SET_WMM_QOS_INFO_FIELD_STA_AC_VO_UAPSD(_pStart, _val)	SET_BITS_TO_LE_1BYTE(_pStart, 0, 1, _val)
+
+#define GET_WMM_QOS_INFO_FIELD_STA_AC_VI_UAPSD(_pStart)	LE_BITS_TO_1BYTE(_pStart, 1, 1)
+#define SET_WMM_QOS_INFO_FIELD_STA_AC_VI_UAPSD(_pStart, _val)	SET_BITS_TO_LE_1BYTE(_pStart, 1, 1, _val)
+
+#define GET_WMM_QOS_INFO_FIELD_STA_AC_BE_UAPSD(_pStart)	LE_BITS_TO_1BYTE(_pStart, 2, 1)
+#define SET_WMM_QOS_INFO_FIELD_STA_AC_BE_UAPSD(_pStart, _val)	SET_BITS_TO_LE_1BYTE(_pStart, 2, 1, _val)
+	
+#define GET_WMM_QOS_INFO_FIELD_STA_AC_BK_UAPSD(_pStart)	LE_BITS_TO_1BYTE(_pStart, 3, 1)
+#define SET_WMM_QOS_INFO_FIELD_STA_AC_BK_UAPSD(_pStart, _val)	SET_BITS_TO_LE_1BYTE(_pStart, 3, 1, _val)
+
+#define GET_WMM_QOS_INFO_FIELD_STA_MAX_SP_LEN(_pStart)	LE_BITS_TO_1BYTE(_pStart, 5, 2)
+#define SET_WMM_QOS_INFO_FIELD_STA_MAX_SP_LEN(_pStart, _val)	SET_BITS_TO_LE_1BYTE(_pStart, 5, 2, _val)
+		
+
+#define WMM_INFO_ELEMENT_SIZE	7
+
+#define GET_WMM_INFO_ELE_OUI(_pStart)	((u8 *)(_pStart))
+#define SET_WMM_INFO_ELE_OUI(_pStart, _pVal)	PlatformMoveMemory(_pStart, _pVal, 3);
+
+#define GET_WMM_INFO_ELE_OUI_TYPE(_pStart)	( EF1Byte( *((u8 *)(_pStart)+3) ) )
+#define SET_WMM_INFO_ELE_OUI_TYPE(_pStart, _val)	( *((u8 *)(_pStart)+3) = EF1Byte(_val) )
+
+#define GET_WMM_INFO_ELE_OUI_SUBTYPE(_pStart)	( EF1Byte( *((u8 *)(_pStart)+4) ) )
+#define SET_WMM_INFO_ELE_OUI_SUBTYPE(_pStart, _val)	( *((u8 *)(_pStart)+4) = EF1Byte(_val) )
+
+#define GET_WMM_INFO_ELE_VERSION(_pStart)	( EF1Byte( *((u8 *)(_pStart)+5) ) )
+#define SET_WMM_INFO_ELE_VERSION(_pStart, _val)	( *((u8 *)(_pStart)+5) = EF1Byte(_val) )
+
+#define GET_WMM_INFO_ELE_QOS_INFO_FIELD(_pStart)	( EF1Byte( *((u8 *)(_pStart)+6) ) )
+#define SET_WMM_INFO_ELE_QOS_INFO_FIELD(_pStart, _val)	( *((u8 *)(_pStart)+6) = EF1Byte(_val) )
+
+	
+
+#define GET_WMM_AC_PARAM_AIFSN(_pStart)	( (u8)LE_BITS_TO_4BYTE(_pStart, 0, 4) )
+#define SET_WMM_AC_PARAM_AIFSN(_pStart, _val)	SET_BITS_TO_LE_4BYTE(_pStart, 0, 4, _val)
+
+#define GET_WMM_AC_PARAM_ACM(_pStart)	( (u8)LE_BITS_TO_4BYTE(_pStart, 4, 1) )
+#define SET_WMM_AC_PARAM_ACM(_pStart, _val)	SET_BITS_TO_LE_4BYTE(_pStart, 4, 1, _val)
+
+#define GET_WMM_AC_PARAM_ACI(_pStart)		( (u8)LE_BITS_TO_4BYTE(_pStart, 5, 2) )
+#define SET_WMM_AC_PARAM_ACI(_pStart, _val)	SET_BITS_TO_LE_4BYTE(_pStart, 5, 2, _val)
+
+#define GET_WMM_AC_PARAM_ACI_AIFSN(_pStart)	( (u8)LE_BITS_TO_4BYTE(_pStart, 0, 8) )
+#define SET_WMM_AC_PARAM_ACI_AIFSN(_pStart, _val)	SET_BTIS_TO_LE_4BYTE(_pStart, 0, 8, _val)
+
+#define GET_WMM_AC_PARAM_ECWMIN(_pStart)	( (u8)LE_BITS_TO_4BYTE(_pStart, 8, 4) )
+#define SET_WMM_AC_PARAM_ECWMIN(_pStart, _val)	SET_BITS_TO_LE_4BYTE(_pStart, 8, 4, _val)
+
+#define GET_WMM_AC_PARAM_ECWMAX(_pStart)	( (u8)LE_BITS_TO_4BYTE(_pStart, 12, 4) )
+#define SET_WMM_AC_PARAM_ECWMAX(_pStart, _val)	SET_BITS_TO_LE_4BYTE(_pStart, 12, 4, _val)
+
+#define GET_WMM_AC_PARAM_TXOP_LIMIT(_pStart)		( (u16)LE_BITS_TO_4BYTE(_pStart, 16, 16) )
+#define SET_WMM_AC_PARAM_TXOP_LIMIT(_pStart, _val)	SET_BITS_TO_LE_4BYTE(_pStart, 16, 16, _val)
+
+
+
+
+#define GET_WMM_PARAM_ELE_OUI(_pStart)	((u8 *)(_pStart))
+#define SET_WMM_PARAM_ELE_OUI(_pStart, _pVal)	PlatformMoveMemory(_pStart, _pVal, 3)
+
+#define GET_WMM_PARAM_ELE_OUI_TYPE(_pStart)	( EF1Byte( *((u8 *)(_pStart)+3) ) )
+#define SET_WMM_PARAM_ELE_OUI_TYPE(_pStart, _val)	( *((u8 *)(_pStart)+3) = EF1Byte(_val) )
+
+#define GET_WMM_PARAM_ELE_OUI_SUBTYPE(_pStart)	( EF1Byte( *((u8 *)(_pStart)+4) ) )
+#define SET_WMM_PARAM_ELE_OUI_SUBTYPE(_pStart, _val)	( *((u8 *)(_pStart)+4) = EF1Byte(_val) )
+
+#define GET_WMM_PARAM_ELE_VERSION(_pStart)	( EF1Byte( *((u8 *)(_pStart)+5) ) )
+#define SET_WMM_PARAM_ELE_VERSION(_pStart, _val)	( *((u8 *)(_pStart)+5) = EF1Byte(_val) )
+
+#define GET_WMM_PARAM_ELE_QOS_INFO_FIELD(_pStart)	( EF1Byte( *((u8 *)(_pStart)+6) ) )
+#define SET_WMM_PARAM_ELE_QOS_INFO_FIELD(_pStart, _val)	( *((u8 *)(_pStart)+6) = EF1Byte(_val) )
+
+#define GET_WMM_PARAM_ELE_AC_PARAM(_pStart)	( (u8 *)(_pStart)+8 )
+#define SET_WMM_PARAM_ELE_AC_PARAM(_pStart, _pVal) PlatformMoveMemory((_pStart)+8, _pVal, 16)
+#endif
+
+//
+// QoS Control Field
+// Ref:
+//	1. WMM spec 2.1.6: QoS Control Field, p.9.
+//	2. 802.11e/D13.0 7.1.3.5, p.26.
+//
+typedef	union _QOS_CTRL_FIELD{
+	u8	charData[2];
+	u16	shortData;
+
+	// WMM spec
+	struct
+	{
+		u8		UP:3;
+		u8		usRsvd1:1;
+		u8		EOSP:1;
+		u8		AckPolicy:2;
+		u8		usRsvd2:1;
+		u8		ucRsvdByte;
+	}WMM;
+
+	// 802.11e: QoS data type frame sent by non-AP QSTAs.
+	struct
+	{
+		u8		TID:4;
+		u8		bIsQsize:1;// 0: BIT[8:15] is TXOP Duration Requested, 1: BIT[8:15] is Queue Size.
+		u8		AckPolicy:2;
+		u8		usRsvd:1;
+		u8		TxopOrQsize;	// (BIT4=0)TXOP Duration Requested or (BIT4=1)Queue Size.
+	}BySta;
+
+	// 802.11e: QoS data, QoS Null, and QoS Data+CF-Ack frames sent by HC.
+	struct
+	{
+		u8		TID:4;
+		u8		EOSP:1;
+		u8		AckPolicy:2;
+		u8		usRsvd:1;
+		u8		PSBufState;		// QAP PS Buffer State.
+	}ByHc_Data;
+
+	// 802.11e: QoS (+) CF-Poll frames sent by HC.
+	struct
+	{
+		u8		TID:4;
+		u8		EOSP:1;
+		u8		AckPolicy:2;
+		u8		usRsvd:1;
+		u8		TxopLimit;		// TXOP Limit.
+	}ByHc_CFP;
+
+}QOS_CTRL_FIELD, *PQOS_CTRL_FIELD;
+
+
+//
+// QoS Info Field
+// Ref:
+//	1. WMM spec 2.2.1: WME Information Element, p.11.
+//	2. 8185 QoS code: QOS_INFO [def. in QoS_mp.h]
+//
+typedef	union _QOS_INFO_FIELD{
+	u8	charData;
+	
+	struct
+	{
+		u8		ucParameterSetCount:4;
+		u8		ucReserved:4;	
+	}WMM;
+
+	struct 
+	{
+		//Ref WMM_Specification_1-1.pdf, 2006-06-13 Isaiah
+		u8		ucAC_VO_UAPSD:1;
+		u8		ucAC_VI_UAPSD:1;
+		u8		ucAC_BE_UAPSD:1;
+		u8		ucAC_BK_UAPSD:1;
+		u8		ucReserved1:1;
+		u8		ucMaxSPLen:2;
+		u8		ucReserved2:1;
+		
+	}ByWmmPsSta;
+
+	struct
+	{
+		//Ref WMM_Specification_1-1.pdf, 2006-06-13 Isaiah
+		u8		ucParameterSetCount:4;
+		u8		ucReserved:3; 
+		u8		ucApUapsd:1;
+	}ByWmmPsAp;
+
+	struct
+	{
+		u8		ucAC3_UAPSD:1;
+		u8		ucAC2_UAPSD:1;
+		u8		ucAC1_UAPSD:1;
+		u8		ucAC0_UAPSD:1;
+		u8		ucQAck:1;
+		u8		ucMaxSPLen:2;
+		u8		ucMoreDataAck:1;
+	} By11eSta;
+
+	struct
+	{
+		u8		ucParameterSetCount:4;
+		u8		ucQAck:1;
+		u8		ucQueueReq:1;
+		u8		ucTXOPReq:1;
+		u8		ucReserved:1;
+	} By11eAp;
+
+	struct
+	{
+		u8		ucReserved1:4;
+		u8		ucQAck:1;
+		u8		ucReserved2:2;
+		u8		ucMoreDataAck:1;
+	} ByWmmsaSta;
+
+	struct
+	{
+		u8		ucReserved1:4;
+		u8		ucQAck:1;
+		u8		ucQueueReq:1;
+		u8		ucTXOPReq:1;
+		u8		ucReserved2:1;	
+	} ByWmmsaAp;
+
+	struct
+	{
+		u8		ucAC3_UAPSD:1;
+		u8		ucAC2_UAPSD:1;
+		u8		ucAC1_UAPSD:1;
+		u8		ucAC0_UAPSD:1;
+		u8		ucQAck:1;
+		u8		ucMaxSPLen:2;
+		u8		ucMoreDataAck:1;	
+	} ByAllSta;
+
+	struct
+	{
+		u8		ucParameterSetCount:4;
+		u8		ucQAck:1;
+		u8		ucQueueReq:1;
+		u8		ucTXOPReq:1;
+		u8		ucApUapsd:1;	
+	} ByAllAp;
+
+}QOS_INFO_FIELD, *PQOS_INFO_FIELD;
+
+#if 0
+//
+// WMM Information Element
+// Ref: WMM spec 2.2.1: WME Information Element, p.10.
+//
+typedef struct _WMM_INFO_ELEMENT{
+//	u8			ElementID;
+//	u8			Length;
+	u8			OUI[3];
+	u8			OUI_Type;
+	u8			OUI_SubType;
+	u8			Version;
+	QOS_INFO_FIELD	QosInfo;
+}WMM_INFO_ELEMENT, *PWMM_INFO_ELEMENT;
+#endif
+
+//
+// ACI to AC coding.
+// Ref: WMM spec 2.2.2: WME Parameter Element, p.13.
+//
+// AC_CODING is redefined for enum can't be ++, | under C++ compiler, 2006.05.17, by rcnjko.
+//typedef	enum _AC_CODING{
+//	AC0_BE	= 0,		// ACI: 0x00	// Best Effort
+//	AC1_BK	= 1,		// ACI: 0x01	// Background
+//	AC2_VI	= 2,		// ACI: 0x10	// Video
+//	AC3_VO	= 3,		// ACI: 0x11	// Voice
+//	AC_MAX = 4,		// Max: define total number; Should not to be used as a real enum.
+//}AC_CODING,*PAC_CODING;
+//
+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.
+
+//
+// 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;
+
+//
+// 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;
+
+//
+// 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;
+
+
+
+//
+// QoS element subtype
+//
+typedef	enum _QOS_ELE_SUBTYPE{
+	QOSELE_TYPE_INFO	= 0x00,		// 0x00: Information element
+	QOSELE_TYPE_PARAM	= 0x01,		// 0x01: parameter element
+}QOS_ELE_SUBTYPE,*PQOS_ELE_SUBTYPE;
+
+
+//
+// Direction Field Values.
+// Ref: WMM spec 2.2.11: WME TSPEC Element, p.18.
+//
+typedef	enum _DIRECTION_VALUE{
+	DIR_UP			= 0,		// 0x00	// UpLink
+	DIR_DOWN		= 1,		// 0x01	// DownLink
+	DIR_DIRECT		= 2,		// 0x10	// DirectLink
+	DIR_BI_DIR		= 3,		// 0x11	// Bi-Direction
+}DIRECTION_VALUE,*PDIRECTION_VALUE;
+
+
+//
+// TS Info field in WMM TSPEC Element.
+// Ref:
+//	1. WMM spec 2.2.11: WME TSPEC Element, p.18.
+//	2. 8185 QoS code: QOS_TSINFO [def. in QoS_mp.h]
+//
+typedef union _QOS_TSINFO{
+	u8		charData[3];
+	struct {
+		u8		ucTrafficType:1;			//WMM is reserved		
+		u8		ucTSID:4;
+		u8		ucDirection:2;
+		u8		ucAccessPolicy:2;	//WMM: bit8=0, bit7=1
+		u8		ucAggregation:1;		//WMM is reserved
+		u8		ucPSB:1;				//WMMSA is APSD
+		u8		ucUP:3;
+		u8		ucTSInfoAckPolicy:2;		//WMM is reserved
+		u8		ucSchedule:1;			//WMM is reserved
+		u8		ucReserved:7;
+	}field;
+}QOS_TSINFO, *PQOS_TSINFO;
+
+//
+// WMM TSPEC Body.
+// Ref: WMM spec 2.2.11: WME TSPEC Element, p.16.
+//
+typedef union _TSPEC_BODY{
+	u8		charData[55];
+	
+	struct
+	{
+		QOS_TSINFO	TSInfo;	//u8	TSInfo[3];
+		u16	NominalMSDUsize;
+		u16	MaxMSDUsize;
+		u32	MinServiceItv;
+		u32	MaxServiceItv;
+		u32	InactivityItv;
+		u32	SuspenItv;
+		u32	ServiceStartTime;
+		u32	MinDataRate;
+		u32	MeanDataRate;
+		u32	PeakDataRate;
+		u32	MaxBurstSize;
+		u32	DelayBound;
+		u32	MinPhyRate;
+		u16	SurplusBandwidthAllowance;
+		u16	MediumTime;
+	} f;	// Field
+}TSPEC_BODY, *PTSPEC_BODY;
+
+
+//
+// WMM TSPEC Element.
+// Ref: WMM spec 2.2.11: WME TSPEC Element, p.16.
+//
+typedef struct _WMM_TSPEC{
+	u8		ID;
+	u8		Length;
+	u8		OUI[3];
+	u8		OUI_Type;
+	u8		OUI_SubType;
+	u8		Version;
+	TSPEC_BODY	Body;
+} WMM_TSPEC, *PWMM_TSPEC;
+
+//
+// ACM implementation method.
+// Annie, 2005-12-13.
+//
+typedef	enum _ACM_METHOD{
+	eAcmWay0_SwAndHw		= 0,		// By SW and HW.
+	eAcmWay1_HW			= 1,		// By HW.
+	eAcmWay2_SW			= 2,		// By SW.
+}ACM_METHOD,*PACM_METHOD;
+
+
+typedef struct _ACM{
+//	u8		RegEnableACM;
+	u64		UsedTime;
+	u64		MediumTime;
+	u8		HwAcmCtl;	// TRUE: UsedTime exceed => Do NOT USE this AC. It wll be written to ACM_CONTROL(0xBF BIT 0/1/2 in 8185B).
+}ACM, *PACM;
+
+typedef	u8		AC_UAPSD, *PAC_UAPSD;
+
+#define	GET_VO_UAPSD(_apsd) ((_apsd) & BIT0)
+#define	SET_VO_UAPSD(_apsd) ((_apsd) |= BIT0)
+	
+#define	GET_VI_UAPSD(_apsd) ((_apsd) & BIT1)
+#define	SET_VI_UAPSD(_apsd) ((_apsd) |= BIT1)
+
+#define	GET_BK_UAPSD(_apsd) ((_apsd) & BIT2)
+#define	SET_BK_UAPSD(_apsd) ((_apsd) |= BIT2)
+
+#define	GET_BE_UAPSD(_apsd) ((_apsd) & BIT3)
+#define	SET_BE_UAPSD(_apsd) ((_apsd) |= BIT3)
+	
+
+//typedef struct _TCLASS{
+// TODO
+//} TCLASS, *PTCLASS;
+typedef union _QOS_TCLAS{
+
+	struct _TYPE_GENERAL{
+		u8		Priority;
+		u8 		ClassifierType;
+		u8 		Mask;
+	} TYPE_GENERAL;
+
+	struct _TYPE0_ETH{
+		u8		Priority;
+		u8 		ClassifierType;
+		u8 		Mask;
+		u8		SrcAddr[6];
+		u8		DstAddr[6];
+		u16		Type;
+	} TYPE0_ETH;
+
+	struct _TYPE1_IPV4{
+		u8		Priority;
+		u8 		ClassifierType;
+		u8 		Mask;
+		u8 		Version;
+		u8		SrcIP[4];
+		u8		DstIP[4];
+		u16		SrcPort;
+		u16		DstPort;
+		u8		DSCP;
+		u8		Protocol;
+		u8		Reserved;
+	} TYPE1_IPV4;
+
+	struct _TYPE1_IPV6{
+		u8		Priority;
+		u8 		ClassifierType;
+		u8 		Mask;
+		u8 		Version;
+		u8		SrcIP[16];
+		u8		DstIP[16];
+		u16		SrcPort;
+		u16		DstPort;
+		u8		FlowLabel[3];
+	} TYPE1_IPV6;
+
+	struct _TYPE2_8021Q{
+		u8		Priority;
+		u8 		ClassifierType;
+		u8 		Mask;
+		u16		TagType;
+	} TYPE2_8021Q;
+} QOS_TCLAS, *PQOS_TCLAS;
+
+//typedef struct _WMM_TSTREAM{
+//
+//- TSPEC
+//- AC (which to mapping)
+//} WMM_TSTREAM, *PWMM_TSTREAM;
+typedef struct _QOS_TSTREAM{
+	u8			AC;
+	WMM_TSPEC		TSpec;
+	QOS_TCLAS		TClass;
+} QOS_TSTREAM, *PQOS_TSTREAM;
+
+//typedef struct _U_APSD{
+//- TriggerEnable [4]
+//- MaxSPLength
+//- HighestAcBuffered
+//} U_APSD, *PU_APSD;
+
+//joseph TODO: 
+//	UAPSD function should be implemented by 2 data structure
+//	"Qos control field" and "Qos info field"
+//typedef struct _QOS_UAPSD{
+//	u8			bTriggerEnable[4];
+//	u8 			MaxSPLength;
+//	u8			HighestBufAC;
+//} QOS_UAPSD, *PQOS_APSD;
+
+//----------------------------------------------------------------------------
+//      802.11 Management frame Status Code field
+//----------------------------------------------------------------------------
+typedef struct _OCTET_STRING{
+        u8        	*Octet;
+        u16             Length;
+}OCTET_STRING, *POCTET_STRING;
+#if 0
+#define FillOctetString(_os,_octet,_len)             \
+        (_os).Octet=(u8 *)(_octet);                  \
+        (_os).Length=(_len);
+
+#define WMM_ELEM_HDR_LEN        		     6
+#define WMMElemSkipHdr(_osWMMElem)                   \
+        (_osWMMElem).Octet += WMM_ELEM_HDR_LEN;      \
+        (_osWMMElem).Length -= WMM_ELEM_HDR_LEN;
+#endif
+//
+// STA QoS data.
+// Ref: DOT11_QOS in 8185 code. [def. in QoS_mp.h]
+//
+typedef struct _STA_QOS{
+	//DECLARE_RT_OBJECT(STA_QOS);
+	u8				WMMIEBuf[MAX_WMMELE_LENGTH];
+	u8*				WMMIE;
+
+	// Part 1. Self QoS Mode.
+	QOS_MODE			QosCapability; //QoS Capability, 2006-06-14 Isaiah 
+	QOS_MODE			CurrentQosMode;
+
+	// For WMM Power Save Mode : 
+	// ACs are trigger/delivery enabled or legacy power save enabled. 2006-06-13 Isaiah
+	AC_UAPSD			b4ac_Uapsd;  //VoUapsd(bit0), ViUapsd(bit1),  BkUapsd(bit2), BeUapsd(bit3),
+	AC_UAPSD			Curr4acUapsd;
+	u8				bInServicePeriod;
+	u8				MaxSPLength;
+	int 				NumBcnBeforeTrigger;
+
+	// Part 2. EDCA Parameter (perAC)
+	u8 *				pWMMInfoEle;
+	u8				WMMParamEle[WMM_PARAM_ELEMENT_SIZE];
+	u8				WMMPELength;
+
+	// <Bruce_Note>
+	//2 ToDo: remove the Qos Info Field and replace it by the above WMM Info element.
+	// By Bruce, 2008-01-30.
+	// Part 2. EDCA Parameter (perAC)
+	QOS_INFO_FIELD			QosInfoField_STA; 	// Maintained by STA
+	QOS_INFO_FIELD			QosInfoField_AP;	// Retrieved from AP
+
+	AC_PARAM			CurAcParameters[4];
+
+	// Part 3. ACM
+	ACM				acm[4];
+	ACM_METHOD			AcmMethod;
+
+	// Part 4. Per TID (Part 5: TCLASS will be described by TStream)
+	QOS_TSTREAM			TStream[16];
+	WMM_TSPEC			TSpec;
+
+	u32				QBssWirelessMode;
+
+	// No Ack Setting
+	u8				bNoAck;
+
+	// Enable/Disable Rx immediate BA capability.
+	u8				bEnableRxImmBA;
+
+}STA_QOS, *PSTA_QOS;
+
+//
+// BSS QOS data.
+// Ref: BssDscr in 8185 code. [def. in BssDscr.h]
+//
+typedef struct _BSS_QOS{
+	QOS_MODE		bdQoSMode;
+
+	u8			bdWMMIEBuf[MAX_WMMELE_LENGTH];
+	u8*		bdWMMIE;
+
+	QOS_ELE_SUBTYPE		EleSubType;
+
+	u8 *			pWMMInfoEle;
+	u8 *			pWMMParamEle;
+	
+	QOS_INFO_FIELD		QosInfoField;
+	AC_PARAM		AcParameter[4];
+}BSS_QOS, *PBSS_QOS;
+
+
+//
+// Ref: sQoSCtlLng and QoSCtl definition in 8185 QoS code.
+//#define QoSCtl   ((	(Adapter->bRegQoS) && (Adapter->dot11QoS.QoSMode &(QOS_EDCA|QOS_HCCA))	  )  ?sQoSCtlLng:0)
+//
+#define sQoSCtlLng			2
+#define	QOS_CTRL_LEN(_QosMode)		((_QosMode > QOS_DISABLE)? sQoSCtlLng : 0)
+
+
+//Added by joseph
+//UP Mapping to AC, using in MgntQuery_SequenceNumber() and maybe for DSCP
+//#define UP2AC(up)			((up<3)?((up==0)?1:0):(up>>1))
+#define IsACValid(ac)			((ac<=7 )?true:false )
+
+#endif // #ifndef __INC_QOS_TYPE_H
diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_TS.h b/drivers/staging/rtl8192u/ieee80211/rtl819x_TS.h
new file mode 100644
index 0000000..64e1e87
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_TS.h
@@ -0,0 +1,56 @@
+#ifndef _TSTYPE_H_
+#define _TSTYPE_H_
+#include "rtl819x_Qos.h"
+#define TS_SETUP_TIMEOUT	60  // In millisecond
+#define TS_INACT_TIMEOUT	60
+#define TS_ADDBA_DELAY		60
+
+#define TOTAL_TS_NUM		16
+#define TCLAS_NUM		4
+
+// This define the Tx/Rx directions
+typedef enum _TR_SELECT {
+	TX_DIR = 0, 
+	RX_DIR = 1,
+} TR_SELECT, *PTR_SELECT;
+
+typedef struct _TS_COMMON_INFO{
+	struct list_head		List;
+	struct timer_list		SetupTimer;
+	struct timer_list		InactTimer;
+	u8				Addr[6];
+	TSPEC_BODY			TSpec;
+	QOS_TCLAS			TClass[TCLAS_NUM];
+	u8				TClasProc;
+	u8				TClasNum;
+} TS_COMMON_INFO, *PTS_COMMON_INFO;
+
+typedef struct _TX_TS_RECORD{
+	TS_COMMON_INFO		TsCommonInfo;
+	u16				TxCurSeq;
+	BA_RECORD			TxPendingBARecord;  	// For BA Originator
+	BA_RECORD			TxAdmittedBARecord;	// For BA Originator
+//	QOS_DL_RECORD		DLRecord;
+	u8				bAddBaReqInProgress;
+	u8				bAddBaReqDelayed;
+	u8				bUsingBa;
+	struct timer_list		TsAddBaTimer;
+	u8				num;
+} TX_TS_RECORD, *PTX_TS_RECORD;
+
+typedef struct _RX_TS_RECORD {
+	TS_COMMON_INFO		TsCommonInfo;
+	u16				RxIndicateSeq;
+	u16				RxTimeoutIndicateSeq;
+	struct list_head		RxPendingPktList;
+	struct timer_list		RxPktPendingTimer;
+	BA_RECORD			RxAdmittedBARecord;	 // For BA Recepient
+	u16				RxLastSeqNum;
+	u8				RxLastFragNum;
+	u8				num;
+//	QOS_DL_RECORD		DLRecord;
+} RX_TS_RECORD, *PRX_TS_RECORD;
+
+
+#endif
+
diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c
new file mode 100644
index 0000000..ebfe284
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c
@@ -0,0 +1,654 @@
+#include "ieee80211.h"
+#include <linux/etherdevice.h>
+#include "rtl819x_TS.h"
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+#define list_for_each_entry_safe(pos, n, head, member) \
+	for (pos = list_entry((head)->next, typeof(*pos), member), \
+		n = list_entry(pos->member.next, typeof(*pos), member); \
+		&pos->member != (head); \
+		pos = n, n = list_entry(n->member.next, typeof(*n), member))
+#endif
+void TsSetupTimeOut(unsigned long data)
+{
+	// Not implement yet
+	// This is used for WMMSA and ACM , that would send ADDTSReq frame.
+}
+
+void TsInactTimeout(unsigned long data)
+{
+	// Not implement yet
+	// This is used for WMMSA and ACM.
+	// This function would be call when TS is no Tx/Rx for some period of time.
+}
+
+/********************************************************************************************************************
+ *function:  I still not understand this function, so wait for further implementation
+ *   input:  unsigned long	 data		//acturally we send TX_TS_RECORD or RX_TS_RECORD to these timer
+ *  return:  NULL
+ *  notice:  
+********************************************************************************************************************/
+#if 1
+void RxPktPendingTimeout(unsigned long data)
+{
+	PRX_TS_RECORD	pRxTs = (PRX_TS_RECORD)data;
+	struct ieee80211_device *ieee = container_of(pRxTs, struct ieee80211_device, RxTsRecord[pRxTs->num]);
+	
+	PRX_REORDER_ENTRY 	pReorderEntry = NULL;
+
+	//u32 flags = 0;
+	unsigned long flags = 0;
+	struct ieee80211_rxb *stats_IndicateArray[REORDER_WIN_SIZE];
+	u8 index = 0;
+	bool bPktInBuf = false;
+
+
+	spin_lock_irqsave(&(ieee->reorder_spinlock), flags);
+	//PlatformAcquireSpinLock(Adapter, RT_RX_SPINLOCK);
+	IEEE80211_DEBUG(IEEE80211_DL_REORDER,"==================>%s()\n",__FUNCTION__);
+	if(pRxTs->RxTimeoutIndicateSeq != 0xffff)
+	{
+		// Indicate the pending packets sequentially according to SeqNum until meet the gap.
+		while(!list_empty(&pRxTs->RxPendingPktList))
+		{
+			pReorderEntry = (PRX_REORDER_ENTRY)list_entry(pRxTs->RxPendingPktList.prev,RX_REORDER_ENTRY,List);
+			if(index == 0)
+				pRxTs->RxIndicateSeq = pReorderEntry->SeqNum;
+
+			if( SN_LESS(pReorderEntry->SeqNum, pRxTs->RxIndicateSeq) || 
+				SN_EQUAL(pReorderEntry->SeqNum, pRxTs->RxIndicateSeq)	)
+			{
+				list_del_init(&pReorderEntry->List);
+			
+				if(SN_EQUAL(pReorderEntry->SeqNum, pRxTs->RxIndicateSeq))
+					pRxTs->RxIndicateSeq = (pRxTs->RxIndicateSeq + 1) % 4096;
+
+				IEEE80211_DEBUG(IEEE80211_DL_REORDER,"RxPktPendingTimeout(): IndicateSeq: %d\n", pReorderEntry->SeqNum);
+				stats_IndicateArray[index] = pReorderEntry->prxb;
+				index++;
+				
+				list_add_tail(&pReorderEntry->List, &ieee->RxReorder_Unused_List);
+			}
+			else
+			{
+				bPktInBuf = true;
+				break;
+			}
+		}
+	}
+
+	if(index>0)
+	{
+		// Set RxTimeoutIndicateSeq to 0xffff to indicate no pending packets in buffer now.
+		pRxTs->RxTimeoutIndicateSeq = 0xffff;
+	
+		// Indicate packets
+		if(index > REORDER_WIN_SIZE){
+			IEEE80211_DEBUG(IEEE80211_DL_ERR, "RxReorderIndicatePacket(): Rx Reorer buffer full!! \n");
+			spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
+			return;
+		}
+		ieee80211_indicate_packets(ieee, stats_IndicateArray, index);
+	}
+
+	if(bPktInBuf && (pRxTs->RxTimeoutIndicateSeq==0xffff))
+	{
+		pRxTs->RxTimeoutIndicateSeq = pRxTs->RxIndicateSeq;
+		if(timer_pending(&pRxTs->RxPktPendingTimer))
+			del_timer_sync(&pRxTs->RxPktPendingTimer);
+		pRxTs->RxPktPendingTimer.expires = jiffies + ieee->pHTInfo->RxReorderPendingTime;
+		add_timer(&pRxTs->RxPktPendingTimer);
+	}
+	spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
+	//PlatformReleaseSpinLock(Adapter, RT_RX_SPINLOCK);
+}
+#endif
+
+/********************************************************************************************************************
+ *function:  Add BA timer function  
+ *   input:  unsigned long	 data		//acturally we send TX_TS_RECORD or RX_TS_RECORD to these timer
+ *  return:  NULL
+ *  notice:  
+********************************************************************************************************************/
+void TsAddBaProcess(unsigned long data)
+{
+	PTX_TS_RECORD	pTxTs = (PTX_TS_RECORD)data;
+	u8 num = pTxTs->num;
+	struct ieee80211_device *ieee = container_of(pTxTs, struct ieee80211_device, TxTsRecord[num]);
+
+	TsInitAddBA(ieee, pTxTs, BA_POLICY_IMMEDIATE, false);
+	IEEE80211_DEBUG(IEEE80211_DL_BA, "TsAddBaProcess(): ADDBA Req is started!! \n");
+}
+
+
+void ResetTsCommonInfo(PTS_COMMON_INFO	pTsCommonInfo)
+{
+	memset(pTsCommonInfo->Addr, 0, 6);
+	memset(&pTsCommonInfo->TSpec, 0, sizeof(TSPEC_BODY));
+	memset(&pTsCommonInfo->TClass, 0, sizeof(QOS_TCLAS)*TCLAS_NUM);
+	pTsCommonInfo->TClasProc = 0;
+	pTsCommonInfo->TClasNum = 0;
+}
+
+void ResetTxTsEntry(PTX_TS_RECORD pTS)
+{
+	ResetTsCommonInfo(&pTS->TsCommonInfo);
+	pTS->TxCurSeq = 0;
+	pTS->bAddBaReqInProgress = false;
+	pTS->bAddBaReqDelayed = false;
+	pTS->bUsingBa = false;
+	ResetBaEntry(&pTS->TxAdmittedBARecord); //For BA Originator
+	ResetBaEntry(&pTS->TxPendingBARecord);
+}
+
+void ResetRxTsEntry(PRX_TS_RECORD pTS)
+{
+	ResetTsCommonInfo(&pTS->TsCommonInfo);
+	pTS->RxIndicateSeq = 0xffff; // This indicate the RxIndicateSeq is not used now!!
+	pTS->RxTimeoutIndicateSeq = 0xffff; // This indicate the RxTimeoutIndicateSeq is not used now!!
+	ResetBaEntry(&pTS->RxAdmittedBARecord);	  // For BA Recepient
+}
+
+void TSInitialize(struct ieee80211_device *ieee)
+{
+	PTX_TS_RECORD		pTxTS  = ieee->TxTsRecord;
+	PRX_TS_RECORD		pRxTS  = ieee->RxTsRecord;
+	PRX_REORDER_ENTRY	pRxReorderEntry = ieee->RxReorderEntry;
+	u8				count = 0;
+	IEEE80211_DEBUG(IEEE80211_DL_TS, "==========>%s()\n", __FUNCTION__);
+	// Initialize Tx TS related info.
+	INIT_LIST_HEAD(&ieee->Tx_TS_Admit_List);
+	INIT_LIST_HEAD(&ieee->Tx_TS_Pending_List);
+	INIT_LIST_HEAD(&ieee->Tx_TS_Unused_List);
+
+	for(count = 0; count < TOTAL_TS_NUM; count++)
+	{
+		//
+		pTxTS->num = count;
+		// The timers for the operation of Traffic Stream and Block Ack.
+		// DLS related timer will be add here in the future!!
+		init_timer(&pTxTS->TsCommonInfo.SetupTimer);
+		pTxTS->TsCommonInfo.SetupTimer.data = (unsigned long)pTxTS;
+		pTxTS->TsCommonInfo.SetupTimer.function = TsSetupTimeOut;
+	
+		init_timer(&pTxTS->TsCommonInfo.InactTimer);
+		pTxTS->TsCommonInfo.InactTimer.data = (unsigned long)pTxTS;
+		pTxTS->TsCommonInfo.InactTimer.function = TsInactTimeout;
+		
+		init_timer(&pTxTS->TsAddBaTimer);
+		pTxTS->TsAddBaTimer.data = (unsigned long)pTxTS;
+		pTxTS->TsAddBaTimer.function = TsAddBaProcess;
+		
+		init_timer(&pTxTS->TxPendingBARecord.Timer);
+		pTxTS->TxPendingBARecord.Timer.data = (unsigned long)pTxTS;
+		pTxTS->TxPendingBARecord.Timer.function = BaSetupTimeOut;
+
+		init_timer(&pTxTS->TxAdmittedBARecord.Timer);
+		pTxTS->TxAdmittedBARecord.Timer.data = (unsigned long)pTxTS;
+		pTxTS->TxAdmittedBARecord.Timer.function = TxBaInactTimeout;
+		
+		ResetTxTsEntry(pTxTS);
+		list_add_tail(&pTxTS->TsCommonInfo.List, &ieee->Tx_TS_Unused_List); 
+		pTxTS++;
+	}
+
+	// Initialize Rx TS related info.
+	INIT_LIST_HEAD(&ieee->Rx_TS_Admit_List);
+	INIT_LIST_HEAD(&ieee->Rx_TS_Pending_List);
+	INIT_LIST_HEAD(&ieee->Rx_TS_Unused_List);
+	for(count = 0; count < TOTAL_TS_NUM; count++)
+	{
+		pRxTS->num = count;
+		INIT_LIST_HEAD(&pRxTS->RxPendingPktList);
+		
+		init_timer(&pRxTS->TsCommonInfo.SetupTimer);
+		pRxTS->TsCommonInfo.SetupTimer.data = (unsigned long)pRxTS;
+		pRxTS->TsCommonInfo.SetupTimer.function = TsSetupTimeOut;
+	
+		init_timer(&pRxTS->TsCommonInfo.InactTimer);
+		pRxTS->TsCommonInfo.InactTimer.data = (unsigned long)pRxTS;
+		pRxTS->TsCommonInfo.InactTimer.function = TsInactTimeout;
+
+		init_timer(&pRxTS->RxAdmittedBARecord.Timer);
+		pRxTS->RxAdmittedBARecord.Timer.data = (unsigned long)pRxTS;
+		pRxTS->RxAdmittedBARecord.Timer.function = RxBaInactTimeout;
+		
+		init_timer(&pRxTS->RxPktPendingTimer);
+		pRxTS->RxPktPendingTimer.data = (unsigned long)pRxTS;
+		pRxTS->RxPktPendingTimer.function = RxPktPendingTimeout;
+		
+		ResetRxTsEntry(pRxTS);
+		list_add_tail(&pRxTS->TsCommonInfo.List, &ieee->Rx_TS_Unused_List);
+		pRxTS++;
+	}
+	// Initialize unused Rx Reorder List.
+	INIT_LIST_HEAD(&ieee->RxReorder_Unused_List);
+//#ifdef TO_DO_LIST
+	for(count = 0; count < REORDER_ENTRY_NUM; count++)
+	{
+		list_add_tail( &pRxReorderEntry->List,&ieee->RxReorder_Unused_List);
+		if(count == (REORDER_ENTRY_NUM-1))
+			break;
+		pRxReorderEntry = &ieee->RxReorderEntry[count+1];
+	}
+//#endif
+
+}
+
+void AdmitTS(struct ieee80211_device *ieee, PTS_COMMON_INFO pTsCommonInfo, u32 InactTime)
+{
+	del_timer_sync(&pTsCommonInfo->SetupTimer);
+	del_timer_sync(&pTsCommonInfo->InactTimer);
+
+	if(InactTime!=0)
+		mod_timer(&pTsCommonInfo->InactTimer, jiffies + MSECS(InactTime));
+}
+
+
+PTS_COMMON_INFO SearchAdmitTRStream(struct ieee80211_device *ieee, u8*	Addr, u8 TID, TR_SELECT	TxRxSelect)
+{
+	//DIRECTION_VALUE 	dir;
+	u8 	dir;
+	bool				search_dir[4] = {0, 0, 0, 0};
+	struct list_head*		psearch_list; //FIXME
+	PTS_COMMON_INFO	pRet = NULL;
+	if(ieee->iw_mode == IW_MODE_MASTER) //ap mode
+	{
+		if(TxRxSelect == TX_DIR)
+		{
+			search_dir[DIR_DOWN] = true;
+			search_dir[DIR_BI_DIR]= true;
+		}
+		else
+		{
+			search_dir[DIR_UP] 	= true;
+			search_dir[DIR_BI_DIR]= true;
+		}
+	}
+	else if(ieee->iw_mode == IW_MODE_ADHOC)
+	{
+		if(TxRxSelect == TX_DIR)
+			search_dir[DIR_UP] 	= true;
+		else
+			search_dir[DIR_DOWN] = true;
+	}
+	else
+	{
+		if(TxRxSelect == TX_DIR)
+		{
+			search_dir[DIR_UP] 	= true;
+			search_dir[DIR_BI_DIR]= true;
+			search_dir[DIR_DIRECT]= true;
+		}
+		else
+		{
+			search_dir[DIR_DOWN] = true;
+			search_dir[DIR_BI_DIR]= true;
+			search_dir[DIR_DIRECT]= true;
+		}
+	}
+
+	if(TxRxSelect == TX_DIR)
+		psearch_list = &ieee->Tx_TS_Admit_List;
+	else
+		psearch_list = &ieee->Rx_TS_Admit_List;
+	
+	//for(dir = DIR_UP; dir <= DIR_BI_DIR; dir++)
+	for(dir = 0; dir <= DIR_BI_DIR; dir++)
+	{
+		if(search_dir[dir] ==false )
+			continue;
+		list_for_each_entry(pRet, psearch_list, List){
+	//		IEEE80211_DEBUG(IEEE80211_DL_TS, "ADD:"MAC_FMT", TID:%d, dir:%d\n", MAC_ARG(pRet->Addr), pRet->TSpec.f.TSInfo.field.ucTSID, pRet->TSpec.f.TSInfo.field.ucDirection);
+			if (memcmp(pRet->Addr, Addr, 6) == 0)
+				if (pRet->TSpec.f.TSInfo.field.ucTSID == TID)
+					if(pRet->TSpec.f.TSInfo.field.ucDirection == dir)
+					{
+	//					printk("Bingo! got it\n");
+						break;
+					}
+					
+		}	
+		if(&pRet->List  != psearch_list)
+			break;
+	}
+
+	if(&pRet->List  != psearch_list){
+		return pRet ;
+	}
+	else 
+		return NULL;
+}
+
+void MakeTSEntry(
+		PTS_COMMON_INFO	pTsCommonInfo,
+		u8*		Addr,
+		PTSPEC_BODY	pTSPEC,
+		PQOS_TCLAS	pTCLAS,
+		u8		TCLAS_Num,
+		u8		TCLAS_Proc
+	)
+{
+	u8	count;
+
+	if(pTsCommonInfo == NULL)
+		return;
+	
+	memcpy(pTsCommonInfo->Addr, Addr, 6);
+
+	if(pTSPEC != NULL)
+		memcpy((u8*)(&(pTsCommonInfo->TSpec)), (u8*)pTSPEC, sizeof(TSPEC_BODY));
+
+	for(count = 0; count < TCLAS_Num; count++)
+		memcpy((u8*)(&(pTsCommonInfo->TClass[count])), (u8*)pTCLAS, sizeof(QOS_TCLAS));
+
+	pTsCommonInfo->TClasProc = TCLAS_Proc;
+	pTsCommonInfo->TClasNum = TCLAS_Num;
+}
+
+
+bool GetTs(
+	struct ieee80211_device*	ieee,
+	PTS_COMMON_INFO			*ppTS,
+	u8*				Addr,
+	u8				TID,
+	TR_SELECT			TxRxSelect,  //Rx:1, Tx:0
+	bool				bAddNewTs
+	)
+{
+	u8	UP = 0;
+	//
+	// We do not build any TS for Broadcast or Multicast stream.
+	// So reject these kinds of search here.
+	//
+	if(is_broadcast_ether_addr(Addr) || is_multicast_ether_addr(Addr))
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "get TS for Broadcast or Multicast\n");
+		return false;
+	}
+#if 0
+	if(ieee->pStaQos->CurrentQosMode == QOS_DISABLE)
+	{	UP = 0; } //only use one TS
+	else if(ieee->pStaQos->CurrentQosMode & QOS_WMM)
+	{
+#else
+	if (ieee->current_network.qos_data.supported == 0)
+		UP = 0;
+	else
+	{
+#endif
+		// In WMM case: we use 4 TID only
+		if (!IsACValid(TID))
+		{
+			IEEE80211_DEBUG(IEEE80211_DL_ERR, " in %s(), TID(%d) is not valid\n", __FUNCTION__, TID);
+			return false;
+		}
+
+		switch(TID)
+		{
+		case 0:
+		case 3:
+			UP = 0;
+			break;
+
+		case 1:
+		case 2:
+			UP = 2;
+			break;
+			
+		case 4:
+		case 5:
+			UP = 5;
+			break;
+			
+		case 6:
+		case 7:
+			UP = 7;
+			break;
+		}
+	}
+
+	*ppTS = SearchAdmitTRStream(
+			ieee, 
+			Addr,
+			UP, 
+			TxRxSelect);
+	if(*ppTS != NULL)
+	{
+		return true;
+	}
+	else
+	{
+		if(bAddNewTs == false)
+		{
+			IEEE80211_DEBUG(IEEE80211_DL_TS, "add new TS failed(tid:%d)\n", UP);
+			return false;
+		}
+		else
+		{
+			// 
+			// Create a new Traffic stream for current Tx/Rx
+			// This is for EDCA and WMM to add a new TS.
+			// For HCCA or WMMSA, TS cannot be addmit without negotiation.
+			//
+			TSPEC_BODY	TSpec;
+			PQOS_TSINFO		pTSInfo = &TSpec.f.TSInfo;
+			struct list_head*	pUnusedList = 
+								(TxRxSelect == TX_DIR)?
+								(&ieee->Tx_TS_Unused_List):
+								(&ieee->Rx_TS_Unused_List);
+								
+			struct list_head*	pAddmitList = 
+								(TxRxSelect == TX_DIR)?
+								(&ieee->Tx_TS_Admit_List):
+								(&ieee->Rx_TS_Admit_List);
+
+			DIRECTION_VALUE		Dir =		(ieee->iw_mode == IW_MODE_MASTER)? 
+								((TxRxSelect==TX_DIR)?DIR_DOWN:DIR_UP):
+								((TxRxSelect==TX_DIR)?DIR_UP:DIR_DOWN);
+			IEEE80211_DEBUG(IEEE80211_DL_TS, "to add Ts\n");
+			if(!list_empty(pUnusedList))
+			{
+				(*ppTS) = list_entry(pUnusedList->next, TS_COMMON_INFO, List);
+				list_del_init(&(*ppTS)->List);	
+				if(TxRxSelect==TX_DIR)
+				{
+					PTX_TS_RECORD tmp = container_of(*ppTS, TX_TS_RECORD, TsCommonInfo);
+					ResetTxTsEntry(tmp);
+				}
+				else{
+					PRX_TS_RECORD tmp = container_of(*ppTS, RX_TS_RECORD, TsCommonInfo);	
+					ResetRxTsEntry(tmp);
+				}
+				
+				IEEE80211_DEBUG(IEEE80211_DL_TS, "to init current TS, UP:%d, Dir:%d, addr:"MAC_FMT"\n", UP, Dir, MAC_ARG(Addr));
+				// Prepare TS Info releated field
+				pTSInfo->field.ucTrafficType = 0;			// Traffic type: WMM is reserved in this field
+				pTSInfo->field.ucTSID = UP;			// TSID
+				pTSInfo->field.ucDirection = Dir;			// Direction: if there is DirectLink, this need additional consideration.
+				pTSInfo->field.ucAccessPolicy = 1;		// Access policy
+				pTSInfo->field.ucAggregation = 0; 		// Aggregation
+				pTSInfo->field.ucPSB = 0; 				// Aggregation
+				pTSInfo->field.ucUP = UP;				// User priority
+				pTSInfo->field.ucTSInfoAckPolicy = 0;		// Ack policy
+				pTSInfo->field.ucSchedule = 0;			// Schedule
+					
+				MakeTSEntry(*ppTS, Addr, &TSpec, NULL, 0, 0);
+				AdmitTS(ieee, *ppTS, 0);
+				list_add_tail(&((*ppTS)->List), pAddmitList);
+				// if there is DirectLink, we need to do additional operation here!!
+
+				return true;
+			}
+			else
+			{
+				IEEE80211_DEBUG(IEEE80211_DL_ERR, "in function %s() There is not enough TS record to be used!!", __FUNCTION__);
+				return false;
+			}		
+		}		
+	}
+}
+
+void RemoveTsEntry(
+	struct ieee80211_device*	ieee,
+	PTS_COMMON_INFO			pTs,
+	TR_SELECT			TxRxSelect
+	)
+{
+	//u32 flags = 0;
+	unsigned long flags = 0;
+	del_timer_sync(&pTs->SetupTimer);
+	del_timer_sync(&pTs->InactTimer);
+	TsInitDelBA(ieee, pTs, TxRxSelect);
+
+	if(TxRxSelect == RX_DIR)
+	{
+//#ifdef TO_DO_LIST
+		PRX_REORDER_ENTRY	pRxReorderEntry;
+		PRX_TS_RECORD 		pRxTS = (PRX_TS_RECORD)pTs;
+		if(timer_pending(&pRxTS->RxPktPendingTimer))	
+			del_timer_sync(&pRxTS->RxPktPendingTimer);
+
+                while(!list_empty(&pRxTS->RxPendingPktList))
+                {
+                //      PlatformAcquireSpinLock(Adapter, RT_RX_SPINLOCK);
+                        spin_lock_irqsave(&(ieee->reorder_spinlock), flags);
+                        //pRxReorderEntry = list_entry(&pRxTS->RxPendingPktList.prev,RX_REORDER_ENTRY,List);
+			pRxReorderEntry = (PRX_REORDER_ENTRY)list_entry(pRxTS->RxPendingPktList.prev,RX_REORDER_ENTRY,List);
+                        list_del_init(&pRxReorderEntry->List);
+                        {
+                                int i = 0;
+                                struct ieee80211_rxb * prxb = pRxReorderEntry->prxb;
+				if (unlikely(!prxb))
+				{
+					spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
+					return;
+				}
+                                for(i =0; i < prxb->nr_subframes; i++) {
+                                        dev_kfree_skb(prxb->subframes[i]);
+                                }
+                                kfree(prxb);
+                                prxb = NULL;
+                        }
+                        list_add_tail(&pRxReorderEntry->List,&ieee->RxReorder_Unused_List);
+                        //PlatformReleaseSpinLock(Adapter, RT_RX_SPINLOCK);
+                        spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
+                }
+
+//#endif
+	}
+	else
+	{
+		PTX_TS_RECORD pTxTS = (PTX_TS_RECORD)pTs;
+		del_timer_sync(&pTxTS->TsAddBaTimer);
+	}
+}
+
+void RemovePeerTS(struct ieee80211_device* ieee, u8* Addr)
+{
+	PTS_COMMON_INFO	pTS, pTmpTS;
+	printk("===========>RemovePeerTS,"MAC_FMT"\n", MAC_ARG(Addr));
+#if 1
+	list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List)
+	{
+		if (memcmp(pTS->Addr, Addr, 6) == 0)
+		{
+			RemoveTsEntry(ieee, pTS, TX_DIR);
+			list_del_init(&pTS->List);
+			list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List);
+		}
+	}
+	
+	list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Admit_List, List)
+	{
+		if (memcmp(pTS->Addr, Addr, 6) == 0)
+		{
+			printk("====>remove Tx_TS_admin_list\n");
+			RemoveTsEntry(ieee, pTS, TX_DIR);
+			list_del_init(&pTS->List);
+			list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List);
+		}
+	}
+	
+	list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Pending_List, List)
+	{
+		if (memcmp(pTS->Addr, Addr, 6) == 0)
+		{
+			RemoveTsEntry(ieee, pTS, RX_DIR);
+			list_del_init(&pTS->List);
+			list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List);
+		}
+	}
+
+	list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Admit_List, List)
+	{
+		if (memcmp(pTS->Addr, Addr, 6) == 0)
+		{
+			RemoveTsEntry(ieee, pTS, RX_DIR);
+			list_del_init(&pTS->List);
+			list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List);
+		}
+	}
+#endif
+}
+
+void RemoveAllTS(struct ieee80211_device* ieee)
+{
+	PTS_COMMON_INFO pTS, pTmpTS;
+#if 1	
+	list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List)
+	{
+		RemoveTsEntry(ieee, pTS, TX_DIR);
+		list_del_init(&pTS->List);
+		list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List);	
+	}
+
+	list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Admit_List, List)
+	{
+		RemoveTsEntry(ieee, pTS, TX_DIR);
+		list_del_init(&pTS->List);
+		list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List);
+	}
+	
+	list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Pending_List, List)
+	{
+		RemoveTsEntry(ieee, pTS, RX_DIR);
+		list_del_init(&pTS->List);
+		list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List);
+	}
+
+	list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Admit_List, List)
+	{
+		RemoveTsEntry(ieee, pTS, RX_DIR);
+		list_del_init(&pTS->List);
+		list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List);
+	}
+#endif
+}
+
+void TsStartAddBaProcess(struct ieee80211_device* ieee, PTX_TS_RECORD	pTxTS)
+{
+	if(pTxTS->bAddBaReqInProgress == false)
+	{
+		pTxTS->bAddBaReqInProgress = true;
+#if 1
+		if(pTxTS->bAddBaReqDelayed)
+		{
+			IEEE80211_DEBUG(IEEE80211_DL_BA, "TsStartAddBaProcess(): Delayed Start ADDBA after 60 sec!!\n");
+			mod_timer(&pTxTS->TsAddBaTimer, jiffies + MSECS(TS_ADDBA_DELAY));
+		}
+		else
+		{
+			IEEE80211_DEBUG(IEEE80211_DL_BA,"TsStartAddBaProcess(): Immediately Start ADDBA now!!\n");
+			mod_timer(&pTxTS->TsAddBaTimer, jiffies+10); //set 10 ticks
+		}
+#endif
+	}
+	else
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "%s()==>BA timer is already added\n", __FUNCTION__);
+}
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+EXPORT_SYMBOL_NOVERS(RemovePeerTS);
+#else
+EXPORT_SYMBOL(RemovePeerTS);
+#endif
diff --git a/drivers/staging/rtl8192u/ieee80211/rtl_crypto.h b/drivers/staging/rtl8192u/ieee80211/rtl_crypto.h
new file mode 100644
index 0000000..491c505
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/rtl_crypto.h
@@ -0,0 +1,399 @@
+/*
+ * Scatterlist Cryptographic API.
+ *
+ * Copyright (c) 2002 James Morris <jmorris at intercode.com.au>
+ * Copyright (c) 2002 David S. Miller (davem at redhat.com)
+ *
+ * Portions derived from Cryptoapi, by Alexander Kjeldaas <astor at 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_rsl
+#define crypto_unregister_alg crypto_unregister_alg_rsl
+#define crypto_alloc_tfm crypto_alloc_tfm_rsl
+#define crypto_free_tfm crypto_free_tfm_rsl
+#define crypto_alg_available crypto_alg_available_rsl
+
+/*
+ * 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/staging/rtl8192u/ieee80211/scatterwalk.c b/drivers/staging/rtl8192u/ieee80211/scatterwalk.c
new file mode 100644
index 0000000..49f401f
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/scatterwalk.c
@@ -0,0 +1,126 @@
+/*
+ * Cryptographic API.
+ *
+ * Cipher operations.
+ *
+ * Copyright (c) 2002 James Morris <jmorris at intercode.com.au>
+ *               2002 Adam J. Richter <adam at yggdrasil.com>
+ *               2004 Jean-Luc Cooke <jlcooke at 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.
+ *
+ */
+#include "kmap_types.h"
+
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/pagemap.h>
+#include <linux/highmem.h>
+#include <asm/scatterlist.h>
+#include "internal.h"
+#include "scatterwalk.h"
+
+enum km_type crypto_km_types[] = {
+	KM_USER0,
+	KM_USER1,
+	KM_SOFTIRQ0,
+	KM_SOFTIRQ1,
+};
+
+void *scatterwalk_whichbuf(struct scatter_walk *walk, unsigned int nbytes, void *scratch)
+{
+	if (nbytes <= walk->len_this_page &&
+	    (((unsigned long)walk->data) & (PAGE_CACHE_SIZE - 1)) + nbytes <=
+	    PAGE_CACHE_SIZE)
+		return walk->data;
+	else
+		return scratch;
+}
+
+static void memcpy_dir(void *buf, void *sgdata, size_t nbytes, int out)
+{
+	if (out)
+		memcpy(sgdata, buf, nbytes);
+	else
+		memcpy(buf, sgdata, nbytes);
+}
+
+void scatterwalk_start(struct scatter_walk *walk, struct scatterlist *sg)
+{
+	unsigned int rest_of_page;
+
+	walk->sg = sg;
+
+	walk->page = sg->page;
+	walk->len_this_segment = sg->length;
+
+	rest_of_page = PAGE_CACHE_SIZE - (sg->offset & (PAGE_CACHE_SIZE - 1));
+	walk->len_this_page = min(sg->length, rest_of_page);
+	walk->offset = sg->offset;
+}
+
+void scatterwalk_map(struct scatter_walk *walk, int out)
+{
+	walk->data = crypto_kmap(walk->page, out) + walk->offset;
+}
+
+static void scatterwalk_pagedone(struct scatter_walk *walk, int out,
+				 unsigned int more)
+{
+	/* walk->data may be pointing the first byte of the next page;
+	   however, we know we transfered at least one byte.  So,
+	   walk->data - 1 will be a virtual address in the mapped page. */
+
+	if (out)
+		flush_dcache_page(walk->page);
+
+	if (more) {
+		walk->len_this_segment -= walk->len_this_page;
+
+		if (walk->len_this_segment) {
+			walk->page++;
+			walk->len_this_page = min(walk->len_this_segment,
+						  (unsigned)PAGE_CACHE_SIZE);
+			walk->offset = 0;
+		}
+		else
+			scatterwalk_start(walk, sg_next(walk->sg));
+	}
+}
+
+void scatterwalk_done(struct scatter_walk *walk, int out, int more)
+{
+	crypto_kunmap(walk->data, out);
+	if (walk->len_this_page == 0 || !more)
+		scatterwalk_pagedone(walk, out, more);
+}
+
+/*
+ * Do not call this unless the total length of all of the fragments
+ * has been verified as multiple of the block size.
+ */
+int scatterwalk_copychunks(void *buf, struct scatter_walk *walk,
+			   size_t nbytes, int out)
+{
+	if (buf != walk->data) {
+		while (nbytes > walk->len_this_page) {
+			memcpy_dir(buf, walk->data, walk->len_this_page, out);
+			buf += walk->len_this_page;
+			nbytes -= walk->len_this_page;
+
+			crypto_kunmap(walk->data, out);
+			scatterwalk_pagedone(walk, out, 1);
+			scatterwalk_map(walk, out);
+		}
+
+		memcpy_dir(buf, walk->data, nbytes, out);
+	}
+
+	walk->offset += nbytes;
+	walk->len_this_page -= nbytes;
+	walk->len_this_segment -= nbytes;
+	return 0;
+}
diff --git a/drivers/staging/rtl8192u/ieee80211/scatterwalk.h b/drivers/staging/rtl8192u/ieee80211/scatterwalk.h
new file mode 100644
index 0000000..b164465
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/scatterwalk.h
@@ -0,0 +1,51 @@
+/*
+ * Cryptographic API.
+ *
+ * Copyright (c) 2002 James Morris <jmorris at intercode.com.au>
+ * Copyright (c) 2002 Adam J. Richter <adam at yggdrasil.com>
+ * Copyright (c) 2004 Jean-Luc Cooke <jlcooke at 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/staging/rtl8192u/ieee80211_crypt.h b/drivers/staging/rtl8192u/ieee80211_crypt.h
new file mode 100644
index 0000000..b58a3bc
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211_crypt.h
@@ -0,0 +1,86 @@
+/*
+ * 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 at cc.hut.fi>
+ * Copyright (c) 2002-2003, Jouni Malinen <jkmaline at cc.hut.fi>
+ *
+ * Adaption to a generic IEEE 802.11 stack by James Ketrenos
+ * <jketreno at 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);
+
+#endif
diff --git a/drivers/staging/rtl8192u/r8180_93cx6.c b/drivers/staging/rtl8192u/r8180_93cx6.c
new file mode 100644
index 0000000..1842d7b
--- /dev/null
+++ b/drivers/staging/rtl8192u/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 at 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_E(dev, EPROM_CMD,
+			       (1<<EPROM_CS_SHIFT) | \
+			       read_nic_byte_E(dev, EPROM_CMD)); //enable EPROM
+	else
+		write_nic_byte_E(dev, EPROM_CMD, read_nic_byte_E(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_E(dev, EPROM_CMD,
+		       (1<<EPROM_CK_SHIFT) | read_nic_byte_E(dev,EPROM_CMD)); 
+	force_pci_posting(dev);
+	udelay(EPROM_DELAY);
+	write_nic_byte_E(dev, EPROM_CMD, 
+		       read_nic_byte_E(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_E(dev, EPROM_CMD, (1<<EPROM_W_SHIFT) | \
+			       read_nic_byte_E(dev,EPROM_CMD)); 
+	else
+		write_nic_byte_E(dev, EPROM_CMD, read_nic_byte_E(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_E(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 r8192_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_E(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_E(dev, EPROM_CMD,
+		       (EPROM_CMD_NORMAL<<EPROM_CMD_OPERATING_MODE_SHIFT)); 
+	return ret;
+}
diff --git a/drivers/staging/rtl8192u/r8180_93cx6.h b/drivers/staging/rtl8192u/r8180_93cx6.h
new file mode 100644
index 0000000..936be05
--- /dev/null
+++ b/drivers/staging/rtl8192u/r8180_93cx6.h
@@ -0,0 +1,40 @@
+/* 
+	This is part of rtl8187 OpenSource driver
+	Copyright (C) Andrea Merello 2004-2005  <andreamrl at 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 "r8192U.h"
+#include "r8192U_hw.h"
+
+#define EPROM_DELAY 10
+
+#define EPROM_ANAPARAM_ADDRLWORD 0xd 
+#define EPROM_ANAPARAM_ADDRHWORD 0xe 
+
+#define EPROM_RFCHIPID 0x6
+#define EPROM_TXPW_BASE 0x05
+#define EPROM_RFCHIPID_RTL8225U 5 
+#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/staging/rtl8192u/r8180_pm.c b/drivers/staging/rtl8192u/r8180_pm.c
new file mode 100644
index 0000000..74992ef
--- /dev/null
+++ b/drivers/staging/rtl8192u/r8180_pm.c
@@ -0,0 +1,48 @@
+/* 
+   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 at tiscali.it> 
+   Released under the terms of GPL (General Public Licence)	
+*/
+
+#ifdef CONFIG_RTL8180_PM
+
+
+#include "r8180_hw.h"
+#include "r8180_pm.h"
+
+int rtl8180_save_state (struct pci_dev *dev, u32 state)
+{
+        printk(KERN_NOTICE "r8180 save state call (state %u).\n", state);
+	return(-EAGAIN);
+}
+
+
+int rtl8180_suspend (struct pci_dev *dev, u32 state)
+{
+        printk(KERN_NOTICE "r8180 suspend call (state %u).\n", state);
+	return(-EAGAIN);
+}
+
+
+int rtl8180_resume (struct pci_dev *dev)
+{
+        printk(KERN_NOTICE "r8180 resume call.\n");
+	return(-EAGAIN);
+}
+
+
+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(-EAGAIN);
+}
+
+
+
+#endif //CONFIG_RTL8180_PM
diff --git a/drivers/staging/rtl8192u/r8180_pm.h b/drivers/staging/rtl8192u/r8180_pm.h
new file mode 100644
index 0000000..4173164
--- /dev/null
+++ b/drivers/staging/rtl8192u/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 at 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/pci.h>
+
+int rtl8180_save_state (struct pci_dev *dev, u32 state);
+int rtl8180_suspend (struct pci_dev *dev, u32 state);
+int rtl8180_resume (struct pci_dev *dev);
+int rtl8180_enable_wake (struct pci_dev *dev, u32 state, int enable);
+
+#endif //R8180_PM_H
+
+#endif // CONFIG_RTL8180_PM
diff --git a/drivers/staging/rtl8192u/r8190_rtl8256.c b/drivers/staging/rtl8192u/r8190_rtl8256.c
new file mode 100644
index 0000000..12f250b
--- /dev/null
+++ b/drivers/staging/rtl8192u/r8190_rtl8256.c
@@ -0,0 +1,312 @@
+/*
+  This is part of the rtl8192 driver
+  released under the GPL (See file COPYING for details).
+  
+  This files contains programming code for the rtl8256 
+  radio frontend.
+  
+  *Many* thanks to Realtek Corp. for their great support!
+  
+*/
+
+#include "r8192U.h"
+#include "r8192U_hw.h"
+#include "r819xU_phyreg.h"
+#include "r819xU_phy.h"
+#include "r8190_rtl8256.h"
+
+/*--------------------------------------------------------------------------
+ * Overview:   	set RF band width (20M or 40M) 
+ * Input:       struct net_device*	dev 				
+ * 		WIRELESS_BANDWIDTH_E	Bandwidth	//20M or 40M
+ * Output:      NONE
+ * Return:      NONE
+ * Note:	8226 support both 20M  and 40 MHz
+ *---------------------------------------------------------------------------*/
+void PHY_SetRF8256Bandwidth(struct net_device* dev , HT_CHANNEL_WIDTH Bandwidth)	//20M or 40M
+{
+	u8	eRFPath;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	//for(eRFPath = RF90_PATH_A; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
+	for(eRFPath = 0; eRFPath <RF90_PATH_MAX; eRFPath++)
+	{
+		if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath))		
+				continue;
+		
+		switch(Bandwidth)
+		{
+			case HT_CHANNEL_WIDTH_20:
+				if(priv->card_8192_version == VERSION_819xU_A || priv->card_8192_version == VERSION_819xU_B)// 8256 D-cut, E-cut, xiong: consider it later!
+				{	
+					rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x0b, bMask12Bits, 0x100); //phy para:1ba
+					rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x2c, bMask12Bits, 0x3d7);
+					rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x0e, bMask12Bits, 0x021);
+
+					//cosa add for sd3's request 01/23/2008
+					rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x14, bMask12Bits, 0x5ab);
+				}
+				else
+				{
+					RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown hardware version\n");
+				}
+
+				break;
+			case HT_CHANNEL_WIDTH_20_40:
+				if(priv->card_8192_version == VERSION_819xU_A ||priv->card_8192_version == VERSION_819xU_B)// 8256 D-cut, E-cut, xiong: consider it later!
+				{	
+					rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x0b, bMask12Bits, 0x300); //phy para:3ba
+					rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x2c, bMask12Bits, 0x3df);
+					rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x0e, bMask12Bits, 0x0a1);
+
+					//cosa add for sd3's request 01/23/2008
+					if(priv->chan == 3 || priv->chan == 9) //I need to set priv->chan whenever current channel changes
+						rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x14, bMask12Bits, 0x59b); 
+					else
+						rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x14, bMask12Bits, 0x5ab);
+				}
+				else
+				{
+					RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown hardware version\n");
+				}
+
+
+				break;
+			default:
+				RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown Bandwidth: %#X\n",Bandwidth );
+				break;
+				
+		}
+	}
+	return;
+}
+/*--------------------------------------------------------------------------
+ * Overview:    Interface to config 8256
+ * Input:       struct net_device*	dev 				
+ * Output:      NONE
+ * Return:      NONE
+ *---------------------------------------------------------------------------*/
+void PHY_RF8256_Config(struct net_device* dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);	
+	// Initialize general global value
+	//
+	// TODO: Extend RF_PATH_C and RF_PATH_D in the future
+	priv->NumTotalRFPath = RTL819X_TOTAL_RF_PATH;
+	// Config BB and RF
+	phy_RF8256_Config_ParaFile(dev);
+	
+	return;
+}
+/*--------------------------------------------------------------------------
+ * Overview:    Interface to config 8256
+ * Input:       struct net_device*	dev 				
+ * Output:      NONE
+ * Return:      NONE
+ *---------------------------------------------------------------------------*/
+void phy_RF8256_Config_ParaFile(struct net_device* dev)
+{
+	u32 	u4RegValue = 0;
+	//static s1Byte				szRadioAFile[] = RTL819X_PHY_RADIO_A;
+	//static s1Byte				szRadioBFile[] = RTL819X_PHY_RADIO_B;
+	//static s1Byte				szRadioCFile[] = RTL819X_PHY_RADIO_C;
+	//static s1Byte				szRadioDFile[] = RTL819X_PHY_RADIO_D;
+	u8 	eRFPath;
+	BB_REGISTER_DEFINITION_T	*pPhyReg;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u32	RegOffSetToBeCheck = 0x3;
+	u32 	RegValueToBeCheck = 0x7f1;
+	u32	RF3_Final_Value = 0;
+	u8	ConstRetryTimes = 5, RetryTimes = 5;
+	u8 ret = 0;
+	//3//-----------------------------------------------------------------
+	//3// <2> Initialize RF
+	//3//-----------------------------------------------------------------
+	for(eRFPath = (RF90_RADIO_PATH_E)RF90_PATH_A; eRFPath <priv->NumTotalRFPath; eRFPath++)
+	{
+		if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath))		
+				continue;
+		
+		pPhyReg = &priv->PHYRegDef[eRFPath];
+
+		// Joseph test for shorten RF config
+	//	pHalData->RfReg0Value[eRFPath] =  rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, rGlobalCtrl, bMaskDWord);
+		
+		/*----Store original RFENV control type----*/
+		switch(eRFPath)
+		{
+		case RF90_PATH_A:
+		case RF90_PATH_C:
+			u4RegValue = rtl8192_QueryBBReg(dev, pPhyReg->rfintfs, bRFSI_RFENV);
+			break;
+		case RF90_PATH_B :
+		case RF90_PATH_D:
+			u4RegValue = rtl8192_QueryBBReg(dev, pPhyReg->rfintfs, bRFSI_RFENV<<16);
+			break;
+		}
+
+		/*----Set RF_ENV enable----*/		
+		rtl8192_setBBreg(dev, pPhyReg->rfintfe, bRFSI_RFENV<<16, 0x1);
+		
+		/*----Set RF_ENV output high----*/
+		rtl8192_setBBreg(dev, pPhyReg->rfintfo, bRFSI_RFENV, 0x1);
+
+		/* Set bit number of Address and Data for RF register */
+		rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, b3WireAddressLength, 0x0); 	// Set 0 to 4 bits for Z-serial and set 1 to 6 bits for 8258
+		rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, b3WireDataLength, 0x0);	// Set 0 to 12 bits for Z-serial and 8258, and set 1 to 14 bits for ???
+
+		rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E) eRFPath, 0x0, bMask12Bits, 0xbf);
+
+		/*----Check RF block (for FPGA platform only)----*/
+		// TODO: this function should be removed on ASIC , Emily 2007.2.2
+		if (rtl8192_phy_checkBBAndRF(dev, HW90_BLOCK_RF, (RF90_RADIO_PATH_E)eRFPath))
+		{
+			RT_TRACE(COMP_ERR, "PHY_RF8256_Config():Check Radio[%d] Fail!!\n", eRFPath);
+			goto phy_RF8256_Config_ParaFile_Fail;
+		}
+
+		RetryTimes = ConstRetryTimes;
+		RF3_Final_Value = 0;
+		/*----Initialize RF fom connfiguration file----*/
+		switch(eRFPath)
+		{
+		case RF90_PATH_A:
+			while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0)
+			{
+				ret = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath);
+				RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits);
+				RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value);
+				RetryTimes--;
+			}	
+			break;
+		case RF90_PATH_B:
+			while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0)
+			{
+				ret = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath);
+				RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits);
+				RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value);
+				RetryTimes--;
+			}
+			break;
+		case RF90_PATH_C:
+			while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0)
+			{
+				ret = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath);
+				RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits);
+				RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value);
+				RetryTimes--;
+			}				
+			break;
+		case RF90_PATH_D:
+			while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0)
+			{
+				ret = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath);
+				RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits);
+				RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value);
+				RetryTimes--;
+			}				
+			break;
+		}
+
+		/*----Restore RFENV control type----*/;
+		switch(eRFPath)
+		{
+		case RF90_PATH_A:
+		case RF90_PATH_C:
+			rtl8192_setBBreg(dev, pPhyReg->rfintfs, bRFSI_RFENV, u4RegValue);
+			break;
+		case RF90_PATH_B :
+		case RF90_PATH_D:
+			rtl8192_setBBreg(dev, pPhyReg->rfintfs, bRFSI_RFENV<<16, u4RegValue);
+			break;
+		}
+	
+		if(ret){
+			RT_TRACE(COMP_ERR, "phy_RF8256_Config_ParaFile():Radio[%d] Fail!!", eRFPath);
+			goto phy_RF8256_Config_ParaFile_Fail;
+		}
+			
+	}
+
+	RT_TRACE(COMP_PHY, "PHY Initialization Success\n") ;	
+	return ;
+	
+phy_RF8256_Config_ParaFile_Fail:	
+	RT_TRACE(COMP_ERR, "PHY Initialization failed\n") ;
+	return ;
+}
+
+
+void PHY_SetRF8256CCKTxPower(struct net_device*	dev, u8	powerlevel)
+{
+	u32	TxAGC=0;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	//modified by vivi, 20080109
+	TxAGC = powerlevel;
+
+	if(priv->bDynamicTxLowPower == TRUE ) //cosa 05/22/2008 for scan
+	{
+		if(priv->CustomerID == RT_CID_819x_Netcore)
+			TxAGC = 0x22;
+		else
+		TxAGC += priv->CckPwEnl;
+	}
+	
+	if(TxAGC > 0x24)
+		TxAGC = 0x24;
+	rtl8192_setBBreg(dev, rTxAGC_CCK_Mcs32, bTxAGCRateCCK, TxAGC);
+}
+
+
+void PHY_SetRF8256OFDMTxPower(struct net_device* dev, u8 powerlevel)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);	
+	//Joseph TxPower for 8192 testing
+	u32 writeVal, powerBase0, powerBase1, writeVal_tmp;
+	u8 index = 0;
+	u16 RegOffset[6] = {0xe00, 0xe04, 0xe10, 0xe14, 0xe18, 0xe1c};
+	u8 byte0, byte1, byte2, byte3;
+
+	powerBase0 = powerlevel + priv->TxPowerDiff;	//OFDM rates
+	powerBase0 = (powerBase0<<24) | (powerBase0<<16) |(powerBase0<<8) |powerBase0;
+	powerBase1 = powerlevel;							//MCS rates
+	powerBase1 = (powerBase1<<24) | (powerBase1<<16) |(powerBase1<<8) |powerBase1;
+
+	for(index=0; index<6; index++)
+	{
+		writeVal = priv->MCSTxPowerLevelOriginalOffset[index] + ((index<2)?powerBase0:powerBase1);
+		byte0 = (u8)(writeVal & 0x7f);
+		byte1 = (u8)((writeVal & 0x7f00)>>8);
+		byte2 = (u8)((writeVal & 0x7f0000)>>16);
+		byte3 = (u8)((writeVal & 0x7f000000)>>24);
+		if(byte0 > 0x24)	// Max power index = 0x24
+			byte0 = 0x24;
+		if(byte1 > 0x24)
+			byte1 = 0x24;
+		if(byte2 > 0x24)
+			byte2 = 0x24;
+		if(byte3 > 0x24)
+			byte3 = 0x24;
+
+		//for tx power track
+		if(index == 3)
+		{
+			writeVal_tmp = (byte3<<24) | (byte2<<16) |(byte1<<8) |byte0;
+			priv->Pwr_Track = writeVal_tmp;
+		}
+
+		if(priv->bDynamicTxHighPower == TRUE)     //Add by Jacken 2008/03/06
+		{
+			// Emily, 20080613. Set low tx power for both MCS and legacy OFDM
+			writeVal = 0x03030303;
+		}
+		else
+		{
+			writeVal = (byte3<<24) | (byte2<<16) |(byte1<<8) |byte0;
+		}
+		rtl8192_setBBreg(dev, RegOffset[index], 0x7f7f7f7f, writeVal);
+	}
+	return;
+
+}
+
diff --git a/drivers/staging/rtl8192u/r8190_rtl8256.h b/drivers/staging/rtl8192u/r8190_rtl8256.h
new file mode 100644
index 0000000..37bf96d
--- /dev/null
+++ b/drivers/staging/rtl8192u/r8190_rtl8256.h
@@ -0,0 +1,27 @@
+/*
+  This is part of the rtl8180-sa2400 driver
+  released under the GPL (See file COPYING for details).
+  Copyright (c) 2005 Andrea Merello <andreamrl at tiscali.it>
+  
+  This files contains programming code for the rtl8256 
+  radio frontend.
+  
+  *Many* thanks to Realtek Corp. for their great support!
+  
+*/
+
+#ifndef RTL8225H
+#define RTL8225H
+
+#ifdef RTL8190P
+#define RTL819X_TOTAL_RF_PATH 4 //for 90P
+#else
+#define RTL819X_TOTAL_RF_PATH 2 //for 8192U
+#endif
+extern void PHY_SetRF8256Bandwidth(struct net_device* dev , HT_CHANNEL_WIDTH Bandwidth);
+extern void PHY_RF8256_Config(struct net_device* dev);
+extern void phy_RF8256_Config_ParaFile(struct net_device* dev);
+extern void PHY_SetRF8256CCKTxPower(struct net_device*	dev, u8	powerlevel);
+extern void PHY_SetRF8256OFDMTxPower(struct net_device* dev, u8 powerlevel);
+
+#endif
diff --git a/drivers/staging/rtl8192u/r8192U.h b/drivers/staging/rtl8192u/r8192U.h
new file mode 100644
index 0000000..6761305
--- /dev/null
+++ b/drivers/staging/rtl8192u/r8192U.h
@@ -0,0 +1,1367 @@
+/* 
+   This is part of rtl8187 OpenSource driver.
+   Copyright (C) Andrea Merello 2004-2005  <andreamrl at 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 rtl8192 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 R819xU_H
+#define R819xU_H
+
+#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.h"
+
+#define RTL8192U
+#define RTL819xU_MODULE_NAME "rtl819xU"
+//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 
+
+// Rx smooth factor
+#define	Rx_Smooth_Factor		20
+#if 0 //we need to use RT_TRACE instead DMESG as RT_TRACE will clearly show debug level wb.
+#define DMESG(x,a...) printk(KERN_INFO RTL819xU_MODULE_NAME ": " x "\n", ## a)
+#define DMESGW(x,a...) printk(KERN_WARNING RTL819xU_MODULE_NAME ": WW:" x "\n", ## a)
+#define DMESGE(x,a...) printk(KERN_WARNING RTL819xU_MODULE_NAME ": EE:" x "\n", ## a)
+#else
+#define DMESG(x,a...)
+#define DMESGW(x,a...)
+#define DMESGE(x,a...)
+extern u32 rt_global_debug_component;
+#define RT_TRACE(component, x, args...) \
+do { if(rt_global_debug_component & component) \
+	printk(KERN_DEBUG RTL819xU_MODULE_NAME ":" x "\n" , \
+	       ##args);\
+}while(0);
+
+#define COMP_TRACE				BIT0		// For function call tracing.
+#define COMP_DBG				BIT1		// Only for temporary debug message.
+#define COMP_INIT				BIT2		// during driver initialization / halt / reset.
+
+
+#define COMP_RECV				BIT3		// Reveive part data path.
+#define COMP_SEND				BIT4		// Send part path.
+#define COMP_IO					BIT5		// I/O Related. Added by Annie, 2006-03-02.
+#define COMP_POWER				BIT6		// 802.11 Power Save mode or System/Device Power state related.
+#define COMP_EPROM				BIT7		// 802.11 link related: join/start BSS, leave BSS.
+#define COMP_SWBW				BIT8	// For bandwidth switch.
+#define COMP_POWER_TRACKING			BIT9	//FOR 8190 TX POWER TRACKING
+#define COMP_TURBO				BIT10	// For Turbo Mode related. By Annie, 2005-10-21.
+#define COMP_QOS				BIT11	// For QoS.
+#define COMP_RATE				BIT12	// For Rate Adaptive mechanism, 2006.07.02, by rcnjko.
+#define COMP_RM					BIT13	// For Radio Measurement. 
+#define COMP_DIG				BIT14	// For DIG, 2006.09.25, by rcnjko.
+#define COMP_PHY	 			BIT15	
+#define COMP_CH					BIT16	//channel setting debug
+#define COMP_TXAGC				BIT17	// For Tx power, 060928, by rcnjko. 
+#define COMP_HIPWR				BIT18	// For High Power Mechanism, 060928, by rcnjko. 
+#define COMP_HALDM				BIT19	// For HW Dynamic Mechanism, 061010, by rcnjko. 
+#define COMP_SEC			        BIT20	// Event handling
+#define COMP_LED				BIT21	// For LED.
+#define COMP_RF					BIT22	// For RF.
+//1!!!!!!!!!!!!!!!!!!!!!!!!!!!
+#define COMP_RXDESC				BIT23	// Show Rx desc information for SD3 debug. Added by Annie, 2006-07-15.
+//1//1Attention Please!!!<11n or 8190 specific code should be put below this line>
+//1!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+#define COMP_FIRMWARE				BIT24	//for firmware downloading
+#define COMP_HT					BIT25	// For 802.11n HT related information. by Emily 2006-8-11
+#define COMP_AMSDU				BIT26	// For A-MSDU Debugging
+
+#define COMP_SCAN				BIT27	
+//#define COMP_RESET				BIT28
+#define COMP_DOWN				BIT29  //for rm driver module
+#define COMP_RESET				BIT30  //for silent reset
+#define COMP_ERR				BIT31 //for error out, always on
+#endif
+
+#define RTL819x_DEBUG
+#ifdef RTL819x_DEBUG
+#define assert(expr) \
+        if (!(expr)) {                                  \
+                printk( "Assertion failed! %s,%s,%s,line=%d\n", \
+                #expr,__FILE__,__FUNCTION__,__LINE__);          \
+        }
+//wb added to debug out data buf
+//if you want print DATA buffer related BA, please set ieee80211_debug_level to DATA|BA
+#define RT_DEBUG_DATA(level, data, datalen)      \
+        do{ if ((rt_global_debug_component & (level)) == (level))   \
+                {       \
+                        int i;                                  \
+                        u8* pdata = (u8*) data;                 \
+                        printk(KERN_DEBUG RTL819xU_MODULE_NAME ": %s()\n", __FUNCTION__);   \
+                        for(i=0; i<(int)(datalen); i++)                 \
+                        {                                               \
+                                printk("%2x ", pdata[i]);               \
+                                if ((i+1)%16 == 0) printk("\n");        \
+                        }                               \
+                        printk("\n");                   \
+                }                                       \
+        } while (0)  
+#else
+#define assert(expr) do {} while (0)
+#define RT_DEBUG_DATA(level, data, datalen) do {} while(0)
+#endif /* RTL8169_DEBUG */
+
+
+//
+// Queue Select Value in TxDesc
+//
+#define QSLT_BK                                 0x1
+#define QSLT_BE                                 0x0
+#define QSLT_VI                                 0x4
+#define QSLT_VO                                 0x6
+#define QSLT_BEACON                             0x10
+#define QSLT_HIGH                               0x11
+#define QSLT_MGNT                               0x12
+#define QSLT_CMD                                0x13
+
+#define DESC90_RATE1M                           0x00
+#define DESC90_RATE2M                           0x01
+#define DESC90_RATE5_5M                         0x02
+#define DESC90_RATE11M                          0x03
+#define DESC90_RATE6M                           0x04
+#define DESC90_RATE9M                           0x05
+#define DESC90_RATE12M                          0x06
+#define DESC90_RATE18M                          0x07
+#define DESC90_RATE24M                          0x08
+#define DESC90_RATE36M                          0x09
+#define DESC90_RATE48M                          0x0a
+#define DESC90_RATE54M                          0x0b
+#define DESC90_RATEMCS0                         0x00
+#define DESC90_RATEMCS1                         0x01
+#define DESC90_RATEMCS2                         0x02
+#define DESC90_RATEMCS3                         0x03
+#define DESC90_RATEMCS4                         0x04
+#define DESC90_RATEMCS5                         0x05
+#define DESC90_RATEMCS6                         0x06
+#define DESC90_RATEMCS7                         0x07
+#define DESC90_RATEMCS8                         0x08
+#define DESC90_RATEMCS9                         0x09
+#define DESC90_RATEMCS10                        0x0a
+#define DESC90_RATEMCS11                        0x0b
+#define DESC90_RATEMCS12                        0x0c
+#define DESC90_RATEMCS13                        0x0d
+#define DESC90_RATEMCS14                        0x0e
+#define DESC90_RATEMCS15                        0x0f
+#define DESC90_RATEMCS32                        0x20
+
+#define RTL819X_DEFAULT_RF_TYPE RF_1T2R
+
+#define IEEE80211_WATCH_DOG_TIME    2000
+#define		PHY_Beacon_RSSI_SLID_WIN_MAX		10
+//for txpowertracking by amy
+#define 	OFDM_Table_Length	19
+#define	CCK_Table_length	12
+
+/* for rtl819x */
+typedef struct _tx_desc_819x_usb {
+        //DWORD 0
+        u16	PktSize;
+        u8	Offset;
+        u8	Reserved0:3;
+        u8	CmdInit:1;
+        u8	LastSeg:1;
+        u8	FirstSeg:1;
+        u8	LINIP:1;
+        u8	OWN:1;
+
+        //DWORD 1
+        u8	TxFWInfoSize;
+        u8	RATid:3;
+        u8	DISFB:1;
+        u8	USERATE:1;
+        u8	MOREFRAG:1;
+        u8	NoEnc:1;
+        u8	PIFS:1;
+        u8	QueueSelect:5;
+        u8	NoACM:1;
+        u8	Reserved1:2;
+        u8	SecCAMID:5;
+        u8	SecDescAssign:1;
+        u8	SecType:2;
+
+        //DWORD 2
+        u16	TxBufferSize;
+        //u16 Reserved2;
+        u8	ResvForPaddingLen:7;
+        u8	Reserved3:1;
+        u8	Reserved4;
+
+        //DWORD 3, 4, 5
+        u32	Reserved5;
+        u32	Reserved6;
+        u32	Reserved7;
+}tx_desc_819x_usb, *ptx_desc_819x_usb;
+
+#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
+typedef struct _tx_desc_819x_usb_aggr_subframe {
+	//DWORD 0
+	u16	PktSize;
+	u8	Offset;
+	u8	TxFWInfoSize;
+
+	//DWORD 1
+	u8	RATid:3;
+	u8	DISFB:1;
+	u8	USERATE:1;
+	u8	MOREFRAG:1;
+	u8	NoEnc:1;
+	u8	PIFS:1;
+	u8	QueueSelect:5;
+	u8	NoACM:1;
+	u8	Reserved1:2;
+	u8	SecCAMID:5;
+	u8	SecDescAssign:1;
+	u8	SecType:2;
+	u8	PacketID:7;
+	u8	OWN:1;
+}tx_desc_819x_usb_aggr_subframe, *ptx_desc_819x_usb_aggr_subframe;
+#endif
+
+
+
+typedef struct _tx_desc_cmd_819x_usb {
+        //DWORD 0
+	u16	Reserved0;
+	u8	Reserved1;
+	u8	Reserved2:3;
+	u8	CmdInit:1;
+	u8	LastSeg:1;
+	u8	FirstSeg:1;
+	u8	LINIP:1;
+	u8	OWN:1;
+
+        //DOWRD 1
+	//u32	Reserved3;
+	u8	TxFWInfoSize;
+	u8	Reserved3;
+	u8	QueueSelect;
+	u8	Reserved4;
+
+        //DOWRD 2
+	u16 	TxBufferSize;
+	u16	Reserved5;
+	
+       //DWORD 3,4,5
+	//u32	TxBufferAddr;
+	//u32	NextDescAddress;
+	u32	Reserved6;
+	u32	Reserved7;
+	u32	Reserved8;
+}tx_desc_cmd_819x_usb, *ptx_desc_cmd_819x_usb;
+
+
+typedef struct _tx_fwinfo_819x_usb {
+        //DOWRD 0
+        u8		TxRate:7;
+        u8		CtsEnable:1;
+        u8		RtsRate:7;
+        u8		RtsEnable:1;
+        u8		TxHT:1;
+        u8		Short:1;                //Short PLCP for CCK, or short GI for 11n MCS
+        u8		TxBandwidth:1;          // This is used for HT MCS rate only.
+        u8		TxSubCarrier:2;         // This is used for legacy OFDM rate only.
+        u8		STBC:2;
+        u8		AllowAggregation:1;
+        u8		RtsHT:1;                //Interpre RtsRate field as high throughput data rate
+        u8		RtsShort:1;             //Short PLCP for CCK, or short GI for 11n MCS
+        u8		RtsBandwidth:1;         // This is used for HT MCS rate only.
+        u8		RtsSubcarrier:2;        // This is used for legacy OFDM rate only.
+        u8		RtsSTBC:2;
+        u8		EnableCPUDur:1;         //Enable firmware to recalculate and assign packet duration
+
+        //DWORD 1
+        u32		RxMF:2;
+        u32		RxAMD:3;
+        u32		TxPerPktInfoFeedback:1;//1 indicate Tx info gathtered by firmware and returned by Rx Cmd
+        u32		Reserved1:2;
+        u32		TxAGCOffSet:4;
+        u32		TxAGCSign:1;
+        u32		Tx_INFO_RSVD:6;
+	u32		PacketID:13;
+        //u32                Reserved;
+}tx_fwinfo_819x_usb, *ptx_fwinfo_819x_usb;
+
+typedef struct rtl8192_rx_info {
+	struct urb *urb;
+	struct net_device *dev;
+	u8 out_pipe;
+}rtl8192_rx_info ;
+
+typedef struct rx_desc_819x_usb{
+	//DOWRD 0
+	u16                 Length:14;
+	u16                 CRC32:1;
+	u16                 ICV:1;
+	u8                  RxDrvInfoSize;
+	u8                  Shift:2;
+	u8                  PHYStatus:1;
+	u8                  SWDec:1;
+	//u8                LastSeg:1;
+	//u8                FirstSeg:1;
+	//u8                EOR:1;
+	//u8                OWN:1;
+	u8                  Reserved1:4;
+
+	//DWORD 1
+	u32                 Reserved2;
+
+	//DWORD 2
+	//u32               Reserved3;
+
+	//DWORD 3
+	//u32                BufferAddress;
+
+}rx_desc_819x_usb, *prx_desc_819x_usb;
+
+#ifdef USB_RX_AGGREGATION_SUPPORT
+typedef struct _rx_desc_819x_usb_aggr_subframe{
+	//DOWRD 0
+	u16			Length:14;
+	u16			CRC32:1;
+	u16			ICV:1;
+	u8			Offset;
+	u8			RxDrvInfoSize;
+	//DOWRD 1
+	u8			Shift:2;
+	u8			PHYStatus:1;
+	u8			SWDec:1;
+	u8			Reserved1:4;
+	u8			Reserved2;
+	u16			Reserved3;
+	//DWORD 2
+	//u4Byte		Reserved3;
+	//DWORD 3
+	//u4Byte           	BufferAddress;
+}rx_desc_819x_usb_aggr_subframe, *prx_desc_819x_usb_aggr_subframe;
+#endif
+
+typedef struct rx_drvinfo_819x_usb{
+	//DWORD 0
+	u16                 Reserved1:12;
+	u16                 PartAggr:1;
+	u16                 FirstAGGR:1;
+	u16                 Reserved2:2;
+
+	u8                  RxRate:7;
+	u8                  RxHT:1;
+
+	u8                  BW:1;
+	u8                  SPLCP:1;
+	u8                  Reserved3:2;
+	u8                  PAM:1;
+	u8                  Mcast:1;
+	u8                  Bcast:1;
+	u8                  Reserved4:1;
+
+	//DWORD 1
+	u32                  TSFL;
+
+}rx_drvinfo_819x_usb, *prx_drvinfo_819x_usb;
+
+
+#define MAX_DEV_ADDR_SIZE		8  /* support till 64 bit bus width OS */
+#define MAX_FIRMWARE_INFORMATION_SIZE   32 /*2006/04/30 by Emily forRTL8190*/
+#define MAX_802_11_HEADER_LENGTH        (40 + MAX_FIRMWARE_INFORMATION_SIZE)
+#define ENCRYPTION_MAX_OVERHEAD		128
+#define	USB_HWDESC_HEADER_LEN		sizeof(tx_desc_819x_usb)
+#define TX_PACKET_SHIFT_BYTES 	  	(USB_HWDESC_HEADER_LEN + sizeof(tx_fwinfo_819x_usb)) 
+#define MAX_FRAGMENT_COUNT		8
+#ifdef RTL8192U
+#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
+#define MAX_TRANSMIT_BUFFER_SIZE			32000
+#else
+#define MAX_TRANSMIT_BUFFER_SIZE			8000
+#endif	
+#else
+#define MAX_TRANSMIT_BUFFER_SIZE  	(1600+(MAX_802_11_HEADER_LENGTH+ENCRYPTION_MAX_OVERHEAD)*MAX_FRAGMENT_COUNT) 
+#endif
+#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
+#define TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES (sizeof(tx_desc_819x_usb_aggr_subframe) + sizeof(tx_fwinfo_819x_usb))
+#endif
+#define scrclng					4		// octets for crc32 (FCS, ICV)
+
+typedef enum rf_optype
+{
+	RF_OP_By_SW_3wire = 0,
+	RF_OP_By_FW,
+	RF_OP_MAX
+}rf_op_type;
+/* 8190 Loopback Mode definition */
+typedef enum _rtl819xUsb_loopback{
+	RTL819xU_NO_LOOPBACK = 0,
+	RTL819xU_MAC_LOOPBACK = 1,
+	RTL819xU_DMA_LOOPBACK = 2,
+	RTL819xU_CCK_LOOPBACK = 3,
+}rtl819xUsb_loopback_e;
+
+/* due to rtl8192 firmware */
+typedef enum _desc_packet_type_e{
+	DESC_PACKET_TYPE_INIT = 0,
+	DESC_PACKET_TYPE_NORMAL = 1,	
+}desc_packet_type_e;
+
+typedef enum _firmware_source{
+	FW_SOURCE_IMG_FILE = 0,
+	FW_SOURCE_HEADER_FILE = 1,		//from header file
+}firmware_source_e, *pfirmware_source_e;
+
+typedef enum _firmware_status{
+	FW_STATUS_0_INIT = 0,
+	FW_STATUS_1_MOVE_BOOT_CODE = 1,
+	FW_STATUS_2_MOVE_MAIN_CODE = 2,
+	FW_STATUS_3_TURNON_CPU = 3,
+	FW_STATUS_4_MOVE_DATA_CODE = 4,
+	FW_STATUS_5_READY = 5,
+}firmware_status_e;
+
+typedef struct _rt_firmare_seg_container {
+	u16	seg_size;
+	u8	*seg_ptr;
+}fw_seg_container, *pfw_seg_container;
+typedef struct _rt_firmware{
+	firmware_status_e firmware_status;
+	u16               cmdpacket_frag_thresold;
+#define RTL8190_MAX_FIRMWARE_CODE_SIZE  64000   //64k
+	u8                firmware_buf[RTL8190_MAX_FIRMWARE_CODE_SIZE];
+	u16               firmware_buf_size;
+}rt_firmware, *prt_firmware;
+
+//+by amy 080507
+#define MAX_RECEIVE_BUFFER_SIZE	9100	// Add this to 9100 bytes to receive A-MSDU from RT-AP
+
+typedef struct _rt_firmware_info_819xUsb{
+	u8		sz_info[16];
+}rt_firmware_info_819xUsb, *prt_firmware_info_819xUsb;
+
+/* Firmware Queue Layout */
+#define NUM_OF_FIRMWARE_QUEUE		10
+#define NUM_OF_PAGES_IN_FW		0x100
+
+#ifdef USE_ONE_PIPE
+#define NUM_OF_PAGE_IN_FW_QUEUE_BE	0x000
+#define NUM_OF_PAGE_IN_FW_QUEUE_BK	0x000
+#define NUM_OF_PAGE_IN_FW_QUEUE_VI	0x0ff
+#define NUM_OF_PAGE_IN_FW_QUEUE_VO	0x000
+#define NUM_OF_PAGE_IN_FW_QUEUE_HCCA	0
+#define NUM_OF_PAGE_IN_FW_QUEUE_CMD	0x0
+#define NUM_OF_PAGE_IN_FW_QUEUE_MGNT	0x00
+#define NUM_OF_PAGE_IN_FW_QUEUE_HIGH	0
+#define NUM_OF_PAGE_IN_FW_QUEUE_BCN	0x0
+#define NUM_OF_PAGE_IN_FW_QUEUE_PUB	0x00
+#else
+
+#define NUM_OF_PAGE_IN_FW_QUEUE_BE	0x020
+#define NUM_OF_PAGE_IN_FW_QUEUE_BK	0x020
+#define NUM_OF_PAGE_IN_FW_QUEUE_VI	0x040
+#define NUM_OF_PAGE_IN_FW_QUEUE_VO	0x040
+#define NUM_OF_PAGE_IN_FW_QUEUE_HCCA	0
+#define NUM_OF_PAGE_IN_FW_QUEUE_CMD	0x4
+#define NUM_OF_PAGE_IN_FW_QUEUE_MGNT	0x20
+#define NUM_OF_PAGE_IN_FW_QUEUE_HIGH	0
+#define NUM_OF_PAGE_IN_FW_QUEUE_BCN	0x4
+#define NUM_OF_PAGE_IN_FW_QUEUE_PUB	0x18
+
+#endif
+
+#define APPLIED_RESERVED_QUEUE_IN_FW	0x80000000
+#define RSVD_FW_QUEUE_PAGE_BK_SHIFT	0x00
+#define RSVD_FW_QUEUE_PAGE_BE_SHIFT	0x08
+#define RSVD_FW_QUEUE_PAGE_VI_SHIFT	0x10
+#define RSVD_FW_QUEUE_PAGE_VO_SHIFT	0x18
+#define RSVD_FW_QUEUE_PAGE_MGNT_SHIFT	0x10
+#define RSVD_FW_QUEUE_PAGE_CMD_SHIFT	0x08
+#define RSVD_FW_QUEUE_PAGE_BCN_SHIFT	0x00
+#define RSVD_FW_QUEUE_PAGE_PUB_SHIFT	0x08
+//=================================================================
+//=================================================================
+
+#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 "Rtl819xU"
+
+#define DEFAULT_SSID ""
+#define DEFAULT_RETRY_RTS 7
+#define DEFAULT_RETRY_DATA 7
+#define PRISM_HDR_SIZE 64
+
+#define		PHY_RSSI_SLID_WIN_MAX				100
+
+
+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_N_24G = 0x10,
+	WIRELESS_MODE_N_5G = 0x20
+} WIRELESS_MODE;
+
+
+#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;
+
+
+
+
+
+#if 0
+
+typedef struct tx_pendingbuf
+{
+	struct ieee80211_txb *txb;
+	short ispending;
+	short descfrag;
+} tx_pendigbuf;
+
+#endif
+
+typedef struct _rt_9x_tx_rate_history {
+	u32             cck[4];
+	u32             ofdm[8];
+	// HT_MCS[0][]: BW=0 SG=0
+	// HT_MCS[1][]: BW=1 SG=0
+	// HT_MCS[2][]: BW=0 SG=1
+	// HT_MCS[3][]: BW=1 SG=1
+	u32             ht_mcs[4][16];
+}rt_tx_rahis_t, *prt_tx_rahis_t;
+typedef struct _RT_SMOOTH_DATA_4RF {
+	char    elements[4][100];//array to store values
+	u32     index;                  //index to current array to store
+	u32     TotalNum;               //num of valid elements
+	u32     TotalVal[4];            //sum of valid elements
+}RT_SMOOTH_DATA_4RF, *PRT_SMOOTH_DATA_4RF;
+
+#define MAX_8192U_RX_SIZE			8192    // This maybe changed for D-cut larger aggregation size
+//stats seems messed up, clean it ASAP
+typedef struct Stats
+{
+	unsigned long txrdu;
+//	unsigned long rxrdu;
+	//unsigned long rxnolast;
+	//unsigned long rxnodata;
+//	unsigned long rxreset;
+//	unsigned long rxnopointer;
+	unsigned long rxok;
+	unsigned long rxframgment;
+	unsigned long rxcmdpkt[4];		//08/05/08 amy rx cmd element txfeedback/bcn report/cfg set/query
+	unsigned long rxurberr;
+	unsigned long rxstaterr;
+	unsigned long received_rate_histogram[4][32];	//0: Total, 1:OK, 2:CRC, 3:ICV, 2007 07 03 cosa
+	unsigned long received_preamble_GI[2][32];		//0: Long preamble/GI, 1:Short preamble/GI
+	unsigned long rx_AMPDUsize_histogram[5]; // level: (<4K), (4K~8K), (8K~16K), (16K~32K), (32K~64K)
+	unsigned long rx_AMPDUnum_histogram[5]; // level: (<5), (5~10), (10~20), (20~40), (>40)
+	unsigned long numpacket_matchbssid;	// debug use only.
+	unsigned long numpacket_toself;		// debug use only.
+	unsigned long num_process_phyinfo;		// debug use only.
+	unsigned long numqry_phystatus;
+	unsigned long numqry_phystatusCCK;
+	unsigned long numqry_phystatusHT;
+	unsigned long received_bwtype[5];              //0: 20M, 1: funn40M, 2: upper20M, 3: lower20M, 4: duplicate
+	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;
+	unsigned long txfeedback;
+	unsigned long txfeedbackok;
+
+	unsigned long txoktotal;
+	unsigned long txokbytestotal;
+	unsigned long txokinperiod;
+	unsigned long txmulticast;
+	unsigned long txbytesmulticast;
+	unsigned long txbroadcast;
+	unsigned long txbytesbroadcast;
+	unsigned long txunicast;
+	unsigned long txbytesunicast;
+
+	unsigned long rxoktotal;
+	unsigned long rxbytesunicast;
+	unsigned long txfeedbackfail;
+	unsigned long txerrtotal;
+	unsigned long txerrbytestotal;
+	unsigned long txerrmulticast;
+	unsigned long txerrbroadcast;
+	unsigned long txerrunicast;
+	unsigned long txretrycount;
+	unsigned long txfeedbackretry;
+	u8	      last_packet_rate;
+	unsigned long slide_signal_strength[100];
+	unsigned long slide_evm[100];
+	unsigned long slide_rssi_total;	// For recording sliding window's RSSI value
+	unsigned long slide_evm_total;	// For recording sliding window's EVM value
+	long signal_strength; // Transformed, in dbm. Beautified signal strength for UI, not correct.
+	long signal_quality;
+	long last_signal_strength_inpercent;
+	long recv_signal_power;	// Correct smoothed ss in Dbm, only used in driver to report real power now.
+	u8 rx_rssi_percentage[4];
+	u8 rx_evm_percentage[2];
+	long rxSNRdB[4];
+	rt_tx_rahis_t txrate;
+	u32 Slide_Beacon_pwdb[100];     //cosa add for beacon rssi
+	u32 Slide_Beacon_Total;         //cosa add for beacon rssi
+	RT_SMOOTH_DATA_4RF              cck_adc_pwdb;
+
+	u32	CurrentShowTxate;
+} Stats;
+
+
+// Bandwidth Offset                     	
+#define HAL_PRIME_CHNL_OFFSET_DONT_CARE		0
+#define HAL_PRIME_CHNL_OFFSET_LOWER			1
+#define HAL_PRIME_CHNL_OFFSET_UPPER			2
+
+//+by amy 080507
+
+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 struct _BB_REGISTER_DEFINITION{
+	u32 rfintfs; 			// set software control: //		0x870~0x877[8 bytes]
+	u32 rfintfi; 			// readback data: //		0x8e0~0x8e7[8 bytes]
+	u32 rfintfo; 			// output data: //		0x860~0x86f [16 bytes]
+	u32 rfintfe; 			// output enable: //		0x860~0x86f [16 bytes]
+	u32 rf3wireOffset; 		// LSSI data: //		0x840~0x84f [16 bytes]
+	u32 rfLSSI_Select; 		// BB Band Select: //		0x878~0x87f [8 bytes]
+	u32 rfTxGainStage;		// Tx gain stage: //		0x80c~0x80f [4 bytes]
+	u32 rfHSSIPara1; 		// wire parameter control1 : //		0x820~0x823,0x828~0x82b, 0x830~0x833, 0x838~0x83b [16 bytes]
+	u32 rfHSSIPara2; 		// wire parameter control2 : //		0x824~0x827,0x82c~0x82f, 0x834~0x837, 0x83c~0x83f [16 bytes]
+	u32 rfSwitchControl; 	//Tx Rx antenna control : //		0x858~0x85f [16 bytes]
+	u32 rfAGCControl1; 	//AGC parameter control1 : //		0xc50~0xc53,0xc58~0xc5b, 0xc60~0xc63, 0xc68~0xc6b [16 bytes] 
+	u32 rfAGCControl2; 	//AGC parameter control2 : //		0xc54~0xc57,0xc5c~0xc5f, 0xc64~0xc67, 0xc6c~0xc6f [16 bytes] 
+	u32 rfRxIQImbalance; 	//OFDM Rx IQ imbalance matrix : //		0xc14~0xc17,0xc1c~0xc1f, 0xc24~0xc27, 0xc2c~0xc2f [16 bytes]
+	u32 rfRxAFE;  			//Rx IQ DC ofset and Rx digital filter, Rx DC notch filter : //		0xc10~0xc13,0xc18~0xc1b, 0xc20~0xc23, 0xc28~0xc2b [16 bytes]
+	u32 rfTxIQImbalance; 	//OFDM Tx IQ imbalance matrix //		0xc80~0xc83,0xc88~0xc8b, 0xc90~0xc93, 0xc98~0xc9b [16 bytes]
+	u32 rfTxAFE; 			//Tx IQ DC Offset and Tx DFIR type //		0xc84~0xc87,0xc8c~0xc8f, 0xc94~0xc97, 0xc9c~0xc9f [16 bytes]
+	u32 rfLSSIReadBack; 	//LSSI RF readback data //		0x8a0~0x8af [16 bytes]
+}BB_REGISTER_DEFINITION_T, *PBB_REGISTER_DEFINITION_T;
+
+typedef enum _RT_RF_TYPE_819xU{
+        RF_TYPE_MIN = 0,
+        RF_8225,
+        RF_8256,
+        RF_8258,
+        RF_PSEUDO_11N = 4,
+}RT_RF_TYPE_819xU, *PRT_RF_TYPE_819xU;
+
+typedef struct _rate_adaptive
+{
+	u8				rate_adaptive_disabled;
+	u8				ratr_state;
+	u16				reserve;	
+	
+	u32				high_rssi_thresh_for_ra;
+	u32				high2low_rssi_thresh_for_ra;
+	u8				low2high_rssi_thresh_for_ra40M;
+	u32				low_rssi_thresh_for_ra40M;
+	u8				low2high_rssi_thresh_for_ra20M;
+	u32				low_rssi_thresh_for_ra20M;
+	u32				upper_rssi_threshold_ratr;
+	u32				middle_rssi_threshold_ratr;
+	u32				low_rssi_threshold_ratr;
+	u32				low_rssi_threshold_ratr_40M;
+	u32				low_rssi_threshold_ratr_20M;
+	u8				ping_rssi_enable;	//cosa add for test
+	u32				ping_rssi_ratr;	//cosa add for test
+	u32				ping_rssi_thresh_for_ra;//cosa add for test
+	u32				last_ratr;
+	
+} rate_adaptive, *prate_adaptive;
+
+#define TxBBGainTableLength 37
+#define	CCKTxBBGainTableLength 23
+
+typedef struct _txbbgain_struct
+{
+	long	txbb_iq_amplifygain;
+	u32	txbbgain_value;
+} txbbgain_struct, *ptxbbgain_struct;
+
+typedef struct _ccktxbbgain_struct
+{
+	//The Value is from a22 to a29 one Byte one time is much Safer 
+	u8	ccktxbb_valuearray[8];
+} ccktxbbgain_struct,*pccktxbbgain_struct;
+
+
+typedef struct _init_gain
+{
+	u8				xaagccore1;
+	u8				xbagccore1;
+	u8				xcagccore1;
+	u8				xdagccore1;
+	u8				cca;
+
+} init_gain, *pinit_gain;
+//by amy 0606
+
+typedef struct _phy_ofdm_rx_status_report_819xusb
+{	
+	u8	trsw_gain_X[4];	
+	u8	pwdb_all;
+	u8	cfosho_X[4];
+	u8	cfotail_X[4];
+	u8	rxevm_X[2];
+	u8	rxsnr_X[4];
+	u8	pdsnr_X[2];
+	u8	csi_current_X[2];
+	u8	csi_target_X[2];
+	u8	sigevm;
+	u8	max_ex_pwr;
+	u8	sgi_en;
+	u8  rxsc_sgien_exflg;
+}phy_sts_ofdm_819xusb_t;
+
+typedef struct _phy_cck_rx_status_report_819xusb
+{
+	/* For CCK rate descriptor. This is a unsigned 8:1 variable. LSB bit presend
+	   0.5. And MSB 7 bts presend a signed value. Range from -64~+63.5. */
+	u8	adc_pwdb_X[4];
+	u8	sq_rpt;	
+	u8	cck_agc_rpt;
+}phy_sts_cck_819xusb_t;
+
+
+typedef struct _phy_ofdm_rx_status_rxsc_sgien_exintfflag{
+	u8			reserved:4;
+	u8			rxsc:2;	
+	u8			sgi_en:1;	
+	u8			ex_intf_flag:1;	
+}phy_ofdm_rx_status_rxsc_sgien_exintfflag;
+
+typedef enum _RT_CUSTOMER_ID
+{
+	RT_CID_DEFAULT = 0,
+	RT_CID_8187_ALPHA0 = 1,
+	RT_CID_8187_SERCOMM_PS = 2,
+	RT_CID_8187_HW_LED = 3,
+	RT_CID_8187_NETGEAR = 4,
+	RT_CID_WHQL = 5,
+	RT_CID_819x_CAMEO  = 6, 
+	RT_CID_819x_RUNTOP = 7,
+	RT_CID_819x_Senao = 8,
+	RT_CID_TOSHIBA = 9,	// Merge by Jacken, 2008/01/31.
+	RT_CID_819x_Netcore = 10,
+	RT_CID_Nettronix = 11,
+	RT_CID_DLINK = 12,
+	RT_CID_PRONET = 13,
+}RT_CUSTOMER_ID, *PRT_CUSTOMER_ID;
+
+//================================================================================
+// LED customization.
+//================================================================================
+
+typedef	enum _LED_STRATEGY_8190{
+	SW_LED_MODE0, // SW control 1 LED via GPIO0. It is default option.
+	SW_LED_MODE1, // SW control for PCI Express
+	SW_LED_MODE2, // SW control for Cameo.
+	SW_LED_MODE3, // SW contorl for RunTop.
+	SW_LED_MODE4, // SW control for Netcore
+	HW_LED, // HW control 2 LEDs, LED0 and LED1 (there are 4 different control modes)
+}LED_STRATEGY_8190, *PLED_STRATEGY_8190;
+
+typedef enum _RESET_TYPE {
+	RESET_TYPE_NORESET = 0x00,
+	RESET_TYPE_NORMAL = 0x01,
+	RESET_TYPE_SILENT = 0x02
+} RESET_TYPE;
+
+/* The simple tx command OP code. */
+typedef enum _tag_TxCmd_Config_Index{
+	TXCMD_TXRA_HISTORY_CTRL				= 0xFF900000,
+	TXCMD_RESET_TX_PKT_BUFF				= 0xFF900001,
+	TXCMD_RESET_RX_PKT_BUFF				= 0xFF900002,
+	TXCMD_SET_TX_DURATION				= 0xFF900003,
+	TXCMD_SET_RX_RSSI						= 0xFF900004,
+	TXCMD_SET_TX_PWR_TRACKING			= 0xFF900005,
+	TXCMD_XXXX_CTRL,
+}DCMD_TXCMD_OP;
+
+typedef struct r8192_priv
+{
+	struct usb_device *udev;
+	//added for maintain info from eeprom
+	short epromtype;
+	u16 eeprom_vid;
+	u16 eeprom_pid;
+	u8  eeprom_CustomerID;
+	u8  eeprom_ChannelPlan;
+	RT_CUSTOMER_ID CustomerID;
+	LED_STRATEGY_8190	LedStrategy;  
+	u8  txqueue_to_outpipemap[9];	
+	int irq;
+	struct ieee80211_device *ieee80211;
+	
+	short card_8192; /* O: rtl8192, 1:rtl8185 V B/C, 2:rtl8185 V D */
+	u8 card_8192_version; /* 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}card_type;
+	short hw_plcp_len;
+	short plcp_preamble_mode;
+		
+	spinlock_t irq_lock;
+//	spinlock_t irq_th_lock;
+	spinlock_t tx_lock;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16))
+	struct semaphore mutex;
+#else
+        struct mutex mutex;
+#endif
+	//spinlock_t rf_lock; //used to lock rf write operation added by wb
+
+	u16 irq_mask;
+//	short irq_enabled;
+//	struct net_device *dev; //comment this out.
+	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 rf_sem; //used to lock rf write operation added by wb, modified by david
+//	short hw_wep;
+		
+//	short digphy;
+//	short antb;
+//	short diversity;
+//	u8 cs_treshold;
+//	short rcr_csense;
+	u8 rf_type; //0 means 1T2R, 1 means 2T4R
+	RT_RF_TYPE_819xU rf_chip;
+	
+//	u32 key0[4];
+	short (*rf_set_sens)(struct net_device *dev,short sens);
+	u8 (*rf_set_chan)(struct net_device *dev,u8 ch);
+	void (*rf_close)(struct net_device *dev);
+	void (*rf_init)(struct net_device *dev);
+	//short rate;
+	short promisc;	
+	/*stats*/
+	struct Stats stats;
+	struct iw_statistics wstats;
+	struct proc_dir_entry *dir_dev;
+	
+	/*RX stuff*/
+//	u32 *rxring;
+//	u32 *rxringtail;
+//	dma_addr_t rxringdma;
+	struct urb **rx_urb;
+	struct urb **rx_cmd_urb;
+#ifdef THOMAS_BEACON
+	u32 *oldaddr;
+#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
+
+/* modified by davad for Rx process */
+       struct sk_buff_head rx_queue;
+       struct sk_buff_head skb_queue;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+	struct tq_struct qos_activate;
+#else
+       struct work_struct qos_activate;
+#endif
+	short  tx_urb_index;
+	atomic_t tx_pending[0x10];//UART_PRIORITY+1
+
+
+	struct tasklet_struct irq_rx_tasklet;
+	struct urb *rxurb_task;
+
+	//2 Tx Related variables
+	u16	ShortRetryLimit;
+	u16	LongRetryLimit;
+	u32	TransmitConfig;
+	u8	RegCWinMin;		// For turbo mode CW adaptive. Added by Annie, 2005-10-27.
+
+	u32     LastRxDescTSFHigh;
+	u32     LastRxDescTSFLow;
+
+
+	//2 Rx Related variables
+	u16	EarlyRxThreshold;
+	u32	ReceiveConfig;
+	u8	AcmControl;
+
+	u8	RFProgType;
+	
+	u8 retry_data;
+	u8 retry_rts;
+	u16 rts;
+
+	struct 	ChnlAccessSetting  ChannelAccessSetting;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)	
+	struct work_struct reset_wq;
+#else
+	struct tq_struct reset_wq;
+#endif
+
+/**********************************************************/
+	//for rtl819xUsb
+	u16     basic_rate;
+	u8      short_preamble;
+	u8      slot_time;
+	bool 	bDcut;
+	bool bCurrentRxAggrEnable;
+	u8 Rf_Mode; //add for Firmware RF -R/W switch
+	prt_firmware		pFirmware;
+	rtl819xUsb_loopback_e	LoopbackMode;
+	firmware_source_e	firmware_source;
+	u16 EEPROMTxPowerDiff;
+	u8 EEPROMThermalMeter;
+	u8 EEPROMPwDiff;
+	u8 EEPROMCrystalCap;
+	u8 EEPROM_Def_Ver;
+	u8 EEPROMTxPowerLevelCCK;// CCK channel 1~14
+	u8 EEPROMTxPowerLevelCCK_V1[3];
+	u8 EEPROMTxPowerLevelOFDM24G[3]; // OFDM 2.4G channel 1~14
+	u8 EEPROMTxPowerLevelOFDM5G[24];	// OFDM 5G
+	
+/*PHY related*/
+	BB_REGISTER_DEFINITION_T	PHYRegDef[4];	//Radio A/B/C/D
+	// Read/write are allow for following hardware information variables
+	u32	MCSTxPowerLevelOriginalOffset[6];
+	u32	CCKTxPowerLevelOriginalOffset;
+	u8	TxPowerLevelCCK[14];			// CCK channel 1~14
+	u8	TxPowerLevelOFDM24G[14];		// OFDM 2.4G channel 1~14
+	u8	TxPowerLevelOFDM5G[14];			// OFDM 5G
+	u32	Pwr_Track;
+	u8	TxPowerDiff;
+	u8	AntennaTxPwDiff[2];				// Antenna gain offset, index 0 for B, 1 for C, and 2 for D
+	u8	CrystalCap;						// CrystalCap.
+	u8	ThermalMeter[2];				// ThermalMeter, index 0 for RFIC0, and 1 for RFIC1
+
+	u8	CckPwEnl;
+	// Use to calculate PWBD.
+	u8	bCckHighPower;
+	long	undecorated_smoothed_pwdb;
+
+	//for set channel 
+	u8	SwChnlInProgress;
+	u8 	SwChnlStage;
+	u8	SwChnlStep;
+	u8	SetBWModeInProgress;
+	HT_CHANNEL_WIDTH		CurrentChannelBW;
+	u8      ChannelPlan;
+	// 8190 40MHz mode
+	//
+	u8	nCur40MhzPrimeSC;	// Control channel sub-carrier
+	// Joseph test for shorten RF configuration time.
+	// We save RF reg0 in this variable to reduce RF reading.
+	//
+	u32					RfReg0Value[4];
+	u8 					NumTotalRFPath;	
+	bool 				brfpath_rxenable[4];
+	//RF set related
+	bool				SetRFPowerStateInProgress;
+//+by amy 080507
+	struct timer_list watch_dog_timer;	
+
+//+by amy 080515 for dynamic mechenism
+	//Add by amy Tx Power Control for Near/Far Range 2008/05/15
+	bool	bdynamic_txpower;  //bDynamicTxPower
+	bool	bDynamicTxHighPower;  // Tx high power state
+	bool	bDynamicTxLowPower;  // Tx low power state
+	bool	bLastDTPFlag_High;
+	bool	bLastDTPFlag_Low;
+	
+	bool	bstore_last_dtpflag;
+	bool	bstart_txctrl_bydtp;   //Define to discriminate on High power State or on sitesuvey to change Tx gain index	
+	//Add by amy for Rate Adaptive
+	rate_adaptive rate_adaptive;
+	//Add by amy for TX power tracking
+	//2008/05/15  Mars OPEN/CLOSE TX POWER TRACKING
+       txbbgain_struct txbbgain_table[TxBBGainTableLength];
+	u8			   txpower_count;//For 6 sec do tracking again
+	bool			   btxpower_trackingInit;
+	u8			   OFDM_index;
+	u8			   CCK_index;
+	//2007/09/10 Mars Add CCK TX Power Tracking
+	ccktxbbgain_struct	cck_txbbgain_table[CCKTxBBGainTableLength];
+	ccktxbbgain_struct	cck_txbbgain_ch14_table[CCKTxBBGainTableLength];
+	u8 rfa_txpowertrackingindex;
+	u8 rfa_txpowertrackingindex_real;
+	u8 rfa_txpowertracking_default;
+	u8 rfc_txpowertrackingindex;
+	u8 rfc_txpowertrackingindex_real;
+
+	s8 cck_present_attentuation;
+	u8 cck_present_attentuation_20Mdefault;
+	u8 cck_present_attentuation_40Mdefault;
+	char cck_present_attentuation_difference;
+	bool btxpower_tracking;
+	bool bcck_in_ch14;
+	bool btxpowerdata_readfromEEPORM;
+	u16 	TSSI_13dBm;
+	//For Backup Initial Gain
+	init_gain initgain_backup;
+	u8 DefaultInitialGain[4];
+	// For EDCA Turbo mode, Added by amy 080515.
+	bool		bis_any_nonbepkts;
+	bool		bcurrent_turbo_EDCA;
+	bool		bis_cur_rdlstate;
+	struct timer_list fsync_timer;
+	bool bfsync_processing;	// 500ms Fsync timer is active or not
+	u32 	rate_record;
+	u32 	rateCountDiffRecord;
+	u32	ContiuneDiffCount;
+	bool bswitch_fsync;
+
+	u8	framesync;
+	u32 	framesyncC34;
+	u8   	framesyncMonitor;
+        	//Added by amy 080516  for RX related
+	u16 	nrxAMPDU_size;
+	u8 	nrxAMPDU_aggr_num;
+
+	//by amy for gpio
+	 bool bHwRadioOff;
+
+	//by amy for reset_count
+	u32 reset_count;
+	bool bpbc_pressed;
+	//by amy for debug
+	u32 txpower_checkcnt;
+	u32 txpower_tracking_callback_cnt;
+	u8 thermal_read_val[40];
+	u8 thermal_readback_index;
+	u32 ccktxpower_adjustcnt_not_ch14;
+	u32 ccktxpower_adjustcnt_ch14;
+	u8 tx_fwinfo_force_subcarriermode;
+	u8 tx_fwinfo_force_subcarrierval;
+	//by amy for silent reset
+	RESET_TYPE	ResetProgress;
+	bool		bForcedSilentReset;
+	bool		bDisableNormalResetCheck;
+	u16		TxCounter;
+	u16		RxCounter;
+	int		IrpPendingCount;
+	bool		bResetInProgress;
+	bool		force_reset;
+	u8		InitialGainOperateType;
+	
+	u16		SifsTime;
+	
+	//define work item by amy 080526
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)  
+        
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)    
+	struct delayed_work update_beacon_wq;
+	struct delayed_work watch_dog_wq;    
+	struct delayed_work txpower_tracking_wq;
+	struct delayed_work rfpath_check_wq;
+	struct delayed_work gpio_change_rf_wq;
+	struct delayed_work initialgain_operate_wq;
+#else
+	struct work_struct update_beacon_wq;
+	struct work_struct watch_dog_wq;
+	struct work_struct txpower_tracking_wq;
+	struct work_struct rfpath_check_wq;
+	struct work_struct gpio_change_rf_wq;
+	struct work_struct initialgain_operate_wq;
+#endif
+	struct workqueue_struct *priv_wq;
+#else
+	/* used for periodly scan */
+	struct tq_struct update_beacon_wq;
+	struct tq_struct txpower_tracking_wq;
+	struct tq_struct rfpath_check_wq;
+	struct tq_struct watch_dog_wq;
+	struct tq_struct gpio_change_rf_wq;
+	struct tq_struct initialgain_operate_wq;
+#endif
+}r8192_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_8192U = 1,
+	NIC_8190P = 2,
+	NIC_8192E = 3,
+	} nic_t;
+
+
+#if 0 //defined in Qos.h
+//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;
+
+#endif
+#ifdef JOHN_HWSEC
+struct ssid_thread {
+	struct net_device *dev;
+       	u8 name[IW_ESSID_MAX_SIZE + 1];
+};
+#endif
+
+bool init_firmware(struct net_device *dev);
+short rtl819xU_tx_cmd(struct net_device *dev, struct sk_buff *skb);
+short rtl8192_tx(struct net_device *dev, struct sk_buff* skb);
+
+u32 read_cam(struct net_device *dev, u8 addr);
+void write_cam(struct net_device *dev, u8 addr, u32 data);
+
+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 rtl8192_rtx_disable(struct net_device *);
+void rtl8192_rx_enable(struct net_device *);
+void rtl8192_tx_enable(struct net_device *);
+
+void rtl8192_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 rtl8192_set_anaparam(struct net_device *dev,u32 a);
+void rtl8185_set_anaparam2(struct net_device *dev,u32 a);
+void rtl8192_update_msr(struct net_device *dev);
+int rtl8192_down(struct net_device *dev);
+int rtl8192_up(struct net_device *dev);
+void rtl8192_commit(struct net_device *dev);
+void rtl8192_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 rtl8192_set_rxconf(struct net_device *dev);
+//short check_nic_enough_desc(struct net_device *dev, priority_t priority);
+extern void rtl819xusb_beacon_tx(struct net_device *dev,u16  tx_rate);
+
+void EnableHWSecurityConfig8192(struct net_device *dev);
+void setKey(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType, u8 *MacAddr, u8 DefaultKey, u32 *KeyContent );
+
+
+#endif
diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c
new file mode 100644
index 0000000..ade628b
--- /dev/null
+++ b/drivers/staging/rtl8192u/r8192U_core.c
@@ -0,0 +1,7134 @@
+/******************************************************************************
+ * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
+ * Linux device driver for RTL8192U 
+ *
+ * Based on the r8187 driver, which is:
+ * Copyright 2004-2005 Andrea Merello <andreamrl at tiscali.it>, et al.
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * Jerry chuang <wlanfae at realtek.com>
+ */
+
+#ifndef CONFIG_FORCE_HARD_FLOAT
+double __floatsidf (int i) { return i; }
+unsigned int __fixunsdfsi (double d) { return d; }
+double __adddf3(double a, double b) { return a+b; }
+double __addsf3(float a, float b) { return a+b; }
+double __subdf3(double a, double b) { return a-b; }
+double __extendsfdf2(float a) {return a;}
+#endif
+
+#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
+
+#define CONFIG_RTL8192_IO_MAP
+
+#include <asm/uaccess.h>
+#include "r8192U_hw.h"
+#include "r8192U.h"
+#include "r8190_rtl8256.h" /* RTL8225 Radio frontend */
+#include "r8180_93cx6.h"   /* Card EEPROM */
+#include "r8192U_wx.h"
+#include "r819xU_phy.h" //added by WB 4.30.2008
+#include "r819xU_phyreg.h"
+#include "r819xU_cmdpkt.h"
+#include "r8192U_dm.h"
+//#include "r8192xU_phyreg.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_RTL8192_PM
+#include "r8192_pm.h"
+#endif
+
+#ifdef ENABLE_DOT11D
+#include "dot11d.h"
+#endif
+//set here to open your trace code. //WB
+u32 rt_global_debug_component = \
+			//	COMP_INIT    	|
+//				COMP_DBG	|
+			//	COMP_EPROM   	|
+//				COMP_PHY	|
+			//	COMP_RF		|
+//				COMP_FIRMWARE	|
+//				COMP_CH		|
+			//	COMP_POWER_TRACKING |
+//				COMP_RATE	|
+			//	COMP_TXAGC	|
+		//		COMP_TRACE	|
+				COMP_DOWN	|
+		//		COMP_RECV	|
+                //              COMP_SWBW	|
+				COMP_SEC	|
+	//			COMP_RESET	|
+		//		COMP_SEND	|
+			//	COMP_EVENTS	|
+				COMP_ERR ; //always open err flags on
+
+#define TOTAL_CAM_ENTRY 32
+#define CAM_CONTENT_COUNT 8
+
+static struct usb_device_id rtl8192_usb_id_tbl[] = {
+	/* Realtek */
+	{USB_DEVICE(0x0bda, 0x8192)},
+	{USB_DEVICE(0x0bda, 0x8709)},
+	/* Corega */
+	{USB_DEVICE(0x07aa, 0x0043)},
+	/* Belkin */
+	{USB_DEVICE(0x050d, 0x805E)},
+	/* Sitecom */
+	{USB_DEVICE(0x0df6, 0x0031)},
+	/* EnGenius */
+	{USB_DEVICE(0x1740, 0x9201)},
+	/* Dlink */
+	{USB_DEVICE(0x2001, 0x3301)},
+	/* Zinwell */
+	{USB_DEVICE(0x5a57, 0x0290)},
+	{}
+};
+
+MODULE_LICENSE("GPL");
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
+MODULE_VERSION("V 1.1");
+#endif
+MODULE_DEVICE_TABLE(usb, rtl8192_usb_id_tbl);
+MODULE_DESCRIPTION("Linux driver for Realtek RTL8192 USB WiFi cards");
+
+static char* ifname = "wlan%d";
+#if 0
+static int hwseqnum = 0;
+static int hwwep = 0;
+#endif
+static int hwwep = 1;  //default use hw. set 0 to use software security
+static int channels = 0x3fff;
+
+
+
+#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(ifname," 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 security support. ");
+MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI");
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+static int __devinit rtl8192_usb_probe(struct usb_interface *intf,
+			 const struct usb_device_id *id);
+static void __devexit rtl8192_usb_disconnect(struct usb_interface *intf);
+#else
+static void *__devinit rtl8192_usb_probe(struct usb_device *udev,unsigned int ifnum,
+			 const struct usb_device_id *id);
+static void __devexit rtl8192_usb_disconnect(struct usb_device *udev, void *ptr);
+#endif
+		 
+
+static struct usb_driver rtl8192_usb_driver = {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 15)
+	.owner		= THIS_MODULE,
+#endif
+	.name		= RTL819xU_MODULE_NAME,	          /* Driver name   */
+	.id_table	= rtl8192_usb_id_tbl,	          /* PCI_ID table  */
+	.probe		= rtl8192_usb_probe,	          /* probe fn      */
+	.disconnect	= rtl8192_usb_disconnect,	  /* remove fn     */
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)
+#ifdef CONFIG_RTL8192_PM
+	.suspend	= rtl8192_suspend,	          /* PM suspend fn */
+	.resume		= rtl8192_resume,                 /* PM resume fn  */
+#else
+	.suspend	= NULL,			          /* PM suspend fn */
+	.resume      	= NULL,			          /* PM resume fn  */
+#endif
+#endif
+};
+
+#ifdef ENABLE_DOT11D
+
+typedef struct _CHANNEL_LIST
+{
+	u8	Channel[32];
+	u8	Len;
+}CHANNEL_LIST, *PCHANNEL_LIST;
+
+static CHANNEL_LIST ChannelPlan[] = {
+	{{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64,149,153,157,161,165},24},  		//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},13},    //Spain. Change to ETSI. 
+	{{1,2,3,4,5,6,7,8,9,10,11,12,13},13},  	//France. Change to ETSI.
+	{{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22},	//MKK					//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},13},	//Israel.
+	{{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22},			// For 11a , TELEC
+	{{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64}, 22},    //MIC
+	{{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
+};
+
+static void rtl819x_set_channel_map(u8 channel_plan, struct r8192_priv* priv)
+{
+	int i, max_chan=-1, min_chan=-1;
+	struct ieee80211_device* ieee = priv->ieee80211;
+	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:
+		case COUNTRY_CODE_MIC:
+		{
+			Dot11d_Init(ieee);
+			ieee->bGlobalDomain = false;
+			//acturally 8225 & 8256 rf chip only support B,G,24N mode
+			if ((priv->rf_chip == RF_8225) || (priv->rf_chip == RF_8256))
+			{
+				min_chan = 1;
+				max_chan = 14;
+			}
+			else
+			{
+				RT_TRACE(COMP_ERR, "unknown rf chip, can't set channel map in function:%s()\n", __FUNCTION__);
+			}
+			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] < min_chan || ChannelPlan[channel_plan].Channel[i] > max_chan)
+					break; 	
+					GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 1;
+				}
+			}
+			break;
+		}
+		case COUNTRY_CODE_GLOBAL_DOMAIN:
+		{
+			GET_DOT11D_INFO(ieee)->bEnabled = 0;//this flag enabled to follow 11d country IE setting, otherwise, it shall follow global domain settings.
+			Dot11d_Reset(ieee);
+			ieee->bGlobalDomain = true;
+			break;
+		}
+		default:
+			break;
+	}
+	return;
+}
+#endif
+
+#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 	rx_hal_is_cck_rate(_pdrvinfo)\
+			(_pdrvinfo->RxRate == DESC90_RATE1M ||\
+			_pdrvinfo->RxRate == DESC90_RATE2M ||\
+			_pdrvinfo->RxRate == DESC90_RATE5_5M ||\
+			_pdrvinfo->RxRate == DESC90_RATE11M) &&\
+			!_pdrvinfo->RxHT\
+ 
+
+void CamResetAllEntry(struct net_device *dev)
+{
+#if 1
+	u32 ulcommand = 0;
+        //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");
+	ulcommand |= BIT31|BIT30;
+	write_nic_dword(dev, RWCAM, ulcommand); 
+#else
+        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);
+#endif
+
+}
+
+
+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);
+}
+
+void write_nic_byte_E(struct net_device *dev, int indx, u8 data)
+{
+	int status;	
+	struct r8192_priv *priv = (struct r8192_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! status:%d\n", status);
+	}	
+}
+
+u8 read_nic_byte_E(struct net_device *dev, int indx)
+{
+	int status;
+	u8 data;
+	struct r8192_priv *priv = (struct r8192_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, &data, 1, HZ / 2);
+
+        if (status < 0)
+        {
+                printk("read_nic_byte_E TimeOut! status:%d\n", status);
+        }
+
+	return data;
+}
+//as 92U has extend page from 4 to 16, so modify functions below.
+void write_nic_byte(struct net_device *dev, int indx, u8 data)
+{
+	int status;
+	
+	struct r8192_priv *priv = (struct r8192_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)&0x0f, &data, 1, HZ / 2);
+
+        if (status < 0)
+        {
+                printk("write_nic_byte TimeOut! status:%d\n", status);
+        }
+
+
+}
+
+
+void write_nic_word(struct net_device *dev, int indx, u16 data)
+{
+	
+	int status;
+	
+	struct r8192_priv *priv = (struct r8192_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)&0x0f, &data, 2, HZ / 2);
+
+        if (status < 0)
+        {
+                printk("write_nic_word TimeOut! status:%d\n", status);
+        }
+
+}
+
+
+void write_nic_dword(struct net_device *dev, int indx, u32 data)
+{
+
+	int status;
+	
+	struct r8192_priv *priv = (struct r8192_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)&0x0f, &data, 4, HZ / 2);
+
+
+        if (status < 0)
+        {
+                printk("write_nic_dword TimeOut! status:%d\n", status);
+        }
+
+}
+ 
+ 
+ 
+u8 read_nic_byte(struct net_device *dev, int indx)
+{
+	u8 data;
+	int status;
+	struct r8192_priv *priv = (struct r8192_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)&0x0f, &data, 1, HZ / 2);
+	
+        if (status < 0)
+        {
+                printk("read_nic_byte TimeOut! status:%d\n", status);
+        }
+
+	return data;
+}
+
+
+ 
+u16 read_nic_word(struct net_device *dev, int indx)
+{
+	u16 data;
+	int status;
+	struct r8192_priv *priv = (struct r8192_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)&0x0f, &data, 2, HZ / 2);
+	
+        if (status < 0)
+        {
+                printk("read_nic_word TimeOut! status:%d\n", status);
+        }
+
+
+	return data;
+}
+
+u16 read_nic_word_E(struct net_device *dev, int indx)
+{
+	u16 data;
+	int status;
+	struct r8192_priv *priv = (struct r8192_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, &data, 2, HZ / 2);
+	
+        if (status < 0)
+        {
+                printk("read_nic_word TimeOut! status:%d\n", status);
+        }
+
+
+	return data;
+}
+
+u32 read_nic_dword(struct net_device *dev, int indx)
+{
+	u32 data;
+	int status;
+//	int result;
+	
+	struct r8192_priv *priv = (struct r8192_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)&0x0f, &data, 4, HZ / 2);
+//	if(0 != result) {
+//	  printk(KERN_WARNING "read size of data = %d\, date = %d\n", result, data);
+//	}
+	
+        if (status < 0)
+        {
+                printk("read_nic_dword TimeOut! status:%d\n", status);
+        }
+
+
+
+	return data;
+}
+
+
+//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/rtl8192 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 *rtl8192_stats(struct net_device *dev);
+void rtl8192_commit(struct net_device *dev);
+//void rtl8192_restart(struct net_device *dev);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+void rtl8192_restart(struct work_struct *work);
+//void rtl8192_rq_tx_ack(struct work_struct *work);
+#else 
+ void rtl8192_restart(struct net_device *dev);
+// //void rtl8192_rq_tx_ack(struct net_device *dev);
+ #endif
+
+void watch_dog_timer_callback(unsigned long data);
+
+/****************************************************************************
+   -----------------------------PROCFS STUFF-------------------------
+*****************************************************************************/
+
+static struct proc_dir_entry *rtl8192_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 r8192_priv *priv = (struct r8192_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);
+
+		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;
+//	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	
+	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,0x000|n));
+
+		//	printk("%2x ",read_nic_byte(dev,n));
+	}
+#if 1
+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 3##################\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,0x300|n));
+
+                //      printk("%2x ",read_nic_byte(dev,n));
+        }
+
+#endif
+		
+	len += snprintf(page + len, count - len,"\n");
+	*eof = 1;
+	return len;
+
+}
+
+
+#if 0
+static int proc_get_cck_reg(char *page, char **start,
+			  off_t offset, int count,
+			  int *eof, void *data)
+{
+	struct net_device *dev = data;
+//	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	
+	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;
+}
+
+#endif
+
+#if 0
+static int proc_get_ofdm_reg(char *page, char **start,
+			  off_t offset, int count,
+			  int *eof, void *data)
+{
+	struct net_device *dev = data;
+//	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	
+	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;
+}
+
+#endif
+
+#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 r8192_priv *priv = (struct r8192_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 r8192_priv *priv = (struct r8192_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 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])),
+//		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 r8192_priv *priv = (struct r8192_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.rxoktotal,
+		priv->stats.rxstaterr,
+		priv->stats.rxurberr);
+			
+	*eof = 1;
+	return len;
+}		
+#if 0
+#if WIRELESS_EXT >= 12 && WIRELESS_EXT < 17
+
+static struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev)
+{
+       struct r8192_priv *priv = ieee80211_priv(dev);
+
+       return &priv->wstats;
+}
+#endif
+#endif
+void rtl8192_proc_module_init(void)
+{	
+	RT_TRACE(COMP_INIT, "Initializing proc filesystem");
+#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
+	rtl8192_proc=create_proc_entry(RTL819xU_MODULE_NAME, S_IFDIR, proc_net);
+#else
+	rtl8192_proc=create_proc_entry(RTL819xU_MODULE_NAME, S_IFDIR, init_net.proc_net);
+#endif
+}
+
+
+void rtl8192_proc_module_remove(void)
+{
+#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
+	remove_proc_entry(RTL819xU_MODULE_NAME, proc_net);
+#else
+	remove_proc_entry(RTL819xU_MODULE_NAME, init_net.proc_net);
+#endif
+}
+
+
+void rtl8192_proc_remove_one(struct net_device *dev)
+{
+	struct r8192_priv *priv = (struct r8192_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, rtl8192_proc);
+		remove_proc_entry("wlan0", rtl8192_proc);
+		priv->dir_dev = NULL;
+	}
+}
+
+
+void rtl8192_proc_init_one(struct net_device *dev)
+{
+	struct proc_dir_entry *e;
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	priv->dir_dev = create_proc_entry(dev->name, 
+					  S_IFDIR | S_IRUGO | S_IXUGO, 
+					  rtl8192_proc);
+	if (!priv->dir_dev) {
+		RT_TRACE(COMP_ERR, "Unable to initialize /proc/net/rtl8192/%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/rtl8192/%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) {
+		RT_TRACE(COMP_ERR,"Unable to initialize "
+		      "/proc/net/rtl8192/%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) {
+		RT_TRACE(COMP_ERR, "Unable to initialize "
+		      "/proc/net/rtl8192/%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/rtl8192/%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) {
+		RT_TRACE(COMP_ERR, "Unable to initialize "
+		      "/proc/net/rtl8192/%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) {
+		RT_TRACE(COMP_ERR, "Unable to initialize "
+		      "/proc/net/rtl8192/%s/registers\n",
+		      dev->name);
+	}
+#if 0
+	e = create_proc_read_entry("cck-registers", S_IFREG | S_IRUGO,
+				   priv->dir_dev, proc_get_cck_reg, dev);
+	if (!e) {
+		RT_TRACE(COMP_ERR, "Unable to initialize "
+		      "/proc/net/rtl8192/%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) {
+		RT_TRACE(COMP_ERR, "Unable to initialize "
+		      "/proc/net/rtl8192/%s/ofdm-registers\n",
+		      dev->name);
+	}
+#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_enough_desc(struct net_device *dev, priority_t priority)
+short check_nic_enough_desc(struct net_device *dev,int queue_index)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	int used = atomic_read(&priv->tx_pending[queue_index]); 
+	
+	return (used < MAX_TX_URB);
+}
+
+void tx_timeout(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	//rtl8192_commit(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++)
+		RT_TRACE(COMP_EPROM, "EEPROM addr %x : %x", i, eprom_read(dev,i));
+}
+
+/* this is only for debug */
+void rtl8192_dump_reg(struct net_device *dev)
+{
+	int i;
+	int n;
+	int max=0x1ff;
+	
+	RT_TRACE(COMP_PHY, "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---------------------------
+*****************************************************************************/
+
+#if 0
+void rtl8192_irq_enable(struct net_device *dev)
+{
+	struct r8192_priv *priv = (struct r8192_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 rtl8192_irq_disable(struct net_device *dev)
+{
+//	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);	
+
+	write_nic_word(dev,INTA_MASK,0);
+	force_pci_posting(dev);
+//	priv->irq_enabled = 0;
+}
+#endif
+
+void rtl8192_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 rtl8192_update_msr(struct net_device *dev)
+{
+	struct r8192_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 rtl8192_set_chan(struct net_device *dev,short ch)
+{
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+//	u32 tx;
+	RT_TRACE(COMP_CH, "=====>%s()====ch:%d\n", __FUNCTION__, ch);	
+	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;
+			rtl8192_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));
+
+	//need to implement rf set channel here WB
+
+	if (priv->rf_set_chan)
+	priv->rf_set_chan(dev,priv->chan);
+	mdelay(10);
+//	write_nic_dword(dev,TX_CONF,tx | (TX_LOOPBACK_NONE<<TX_LOOPBACK_SHIFT));
+#endif
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+static void rtl8192_rx_isr(struct urb *urb, struct pt_regs *regs);
+#else
+static void rtl8192_rx_isr(struct urb *urb);
+#endif
+//static void rtl8192_rx_isr(struct urb *rx_urb);
+
+u32 get_rxpacket_shiftbytes_819xusb(struct ieee80211_rx_stats *pstats)
+{
+
+#ifdef USB_RX_AGGREGATION_SUPPORT
+	if (pstats->bisrxaggrsubframe)
+		return (sizeof(rx_desc_819x_usb) + pstats->RxDrvInfoSize
+			+ pstats->RxBufShift + 8);
+	else
+#endif	
+		return (sizeof(rx_desc_819x_usb) + pstats->RxDrvInfoSize 
+				+ pstats->RxBufShift);
+
+}
+static int rtl8192_rx_initiate(struct net_device*dev)
+{
+        struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+        struct urb *entry;
+        struct sk_buff *skb;
+        struct rtl8192_rx_info *info;
+
+	/* nomal packet rx procedure */
+        while (skb_queue_len(&priv->rx_queue) < MAX_RX_URB) {
+                skb = __dev_alloc_skb(RX_URB_SIZE, GFP_KERNEL);
+                if (!skb)
+                        break;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) 
+	        entry = usb_alloc_urb(0, GFP_KERNEL);
+#else
+	        entry = usb_alloc_urb(0);
+#endif
+                if (!entry) {
+                        kfree_skb(skb);
+                        break;
+                }
+//		printk("nomal packet IN request!\n");
+                usb_fill_bulk_urb(entry, priv->udev,
+                                  usb_rcvbulkpipe(priv->udev, 3), skb->tail,
+                                  RX_URB_SIZE, rtl8192_rx_isr, skb);
+                info = (struct rtl8192_rx_info *) skb->cb;
+                info->urb = entry;
+                info->dev = dev;
+		info->out_pipe = 3; //denote rx normal packet queue
+                skb_queue_tail(&priv->rx_queue, skb);
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+                usb_submit_urb(entry, GFP_KERNEL);
+#else
+                usb_submit_urb(entry);
+#endif
+        }
+
+	/* command packet rx procedure */
+        while (skb_queue_len(&priv->rx_queue) < MAX_RX_URB + 3) {
+//		printk("command packet IN request!\n");
+                skb = __dev_alloc_skb(RX_URB_SIZE ,GFP_KERNEL);
+                if (!skb)
+                        break;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+                entry = usb_alloc_urb(0, GFP_KERNEL);
+#else
+                entry = usb_alloc_urb(0);
+#endif
+                if (!entry) {
+                        kfree_skb(skb);
+                        break;
+                }
+                usb_fill_bulk_urb(entry, priv->udev,
+                                  usb_rcvbulkpipe(priv->udev, 9), skb->tail,
+                                  RX_URB_SIZE, rtl8192_rx_isr, skb);
+                info = (struct rtl8192_rx_info *) skb->cb;
+                info->urb = entry;
+                info->dev = dev;
+		   info->out_pipe = 9; //denote rx cmd packet queue
+                skb_queue_tail(&priv->rx_queue, skb);
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+		usb_submit_urb(entry, GFP_KERNEL);
+#else
+		usb_submit_urb(entry);
+#endif
+        }
+
+        return 0;
+}
+
+void rtl8192_set_rxconf(struct net_device *dev)
+{
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	u32 rxconf;
+	
+	rxconf=read_nic_dword(dev,RCR);
+	rxconf = rxconf &~ MAC_FILTER_MASK;
+	rxconf = rxconf | RCR_AMF;
+	rxconf = rxconf | RCR_ADF;
+	rxconf = rxconf | RCR_AB;
+	rxconf = rxconf | RCR_AM;
+	//rxconf = rxconf | RCR_ACF;	
+
+	if (dev->flags & IFF_PROMISC) {DMESG ("NIC in promisc mode");}
+	
+	if(priv->ieee80211->iw_mode == IW_MODE_MONITOR || \
+	   dev->flags & IFF_PROMISC){
+		rxconf = rxconf | RCR_AAP;
+	} /*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 | RCR_APM;
+		rxconf = rxconf | RCR_CBSSID;
+	}
+	
+	
+	if(priv->ieee80211->iw_mode == IW_MODE_MONITOR){
+		rxconf = rxconf | RCR_AICV;
+		rxconf = rxconf | RCR_APWRMGT;
+	}
+	
+	if( priv->crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR)
+		rxconf = rxconf | RCR_ACRC32;
+	
+	
+	rxconf = rxconf &~ RX_FIFO_THRESHOLD_MASK;
+	rxconf = rxconf | (RX_FIFO_THRESHOLD_NONE<<RX_FIFO_THRESHOLD_SHIFT);
+	rxconf = rxconf &~ MAX_RX_DMA_MASK;
+	rxconf = rxconf | ((u32)7<<RCR_MXDMA_OFFSET);
+
+//	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, RCR, rxconf);	
+	
+	#ifdef DEBUG_RX
+	DMESG("rxconf: %x %x",rxconf ,read_nic_dword(dev,RCR));
+	#endif
+}
+//wait to be removed
+void rtl8192_rx_enable(struct net_device *dev)
+{
+	//u8 cmd;
+
+	//struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+
+	rtl8192_rx_initiate(dev);	
+	
+//	rtl8192_set_rxconf(dev);	
+#if 0
+	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, RX_CONF, priv->ReceiveConfig);
+	}
+#endif
+}
+
+
+void rtl8192_tx_enable(struct net_device *dev)
+{
+#if 0
+	u8 cmd;
+	u8 byte;
+	u32 txconf;
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	//test loopback
+	//	priv->TransmitConfig |= (TX_LOOPBACK_BASEBAND<<TX_LOOPBACK_SHIFT);
+	if(NIC_8187B == priv->card_8187){
+		write_nic_dword(dev, TX_CONF, priv->TransmitConfig);	
+		byte = read_nic_byte(dev, MSR);
+		byte |= MSR_LINK_ENEDCA;
+		write_nic_byte(dev, MSR, byte);
+	} 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));		
+	}
+#endif
+}
+
+#if 0
+void rtl8192_beacon_tx_enable(struct net_device *dev)
+{
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	priv->dma_poll_mask &=~(1<<TX_DMA_STOP_BEACON_SHIFT);
+	rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
+	write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);	
+	rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
+}
+
+
+void rtl8192_
+_disable(struct net_device *dev) 
+{
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	priv->dma_poll_mask |= (1<<TX_DMA_STOP_BEACON_SHIFT);
+	rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
+	write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
+	rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
+}
+
+#endif
+
+
+void rtl8192_rtx_disable(struct net_device *dev)
+{
+	u8 cmd;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	struct sk_buff *skb;
+	struct rtl8192_rx_info *info;
+
+	cmd=read_nic_byte(dev,CMDR);
+	write_nic_byte(dev, CMDR, cmd &~ \
+		(CR_TE|CR_RE));	
+	force_pci_posting(dev);
+	mdelay(10);
+
+	while ((skb = __skb_dequeue(&priv->rx_queue))) {
+		info = (struct rtl8192_rx_info *) skb->cb;
+		if (!info->urb)
+			continue;
+
+		usb_kill_urb(info->urb);
+		kfree_skb(skb);
+	}
+
+	if (skb_queue_len(&priv->skb_queue)) {
+		printk(KERN_WARNING "skb_queue not empty\n");
+	}
+
+	skb_queue_purge(&priv->skb_queue);
+	return;
+}
+
+
+int alloc_tx_beacon_desc_ring(struct net_device *dev, int count)
+{
+	#if 0
+	int i;
+	u32 *tmp;
+	struct r8192_priv *priv = (struct r8192_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;
+}
+
+#if 0
+void rtl8192_reset(struct net_device *dev)
+{
+	
+	//struct r8192_priv *priv = ieee80211_priv(dev);
+	//u8 cr;
+
+
+	/* make sure the analog power is on before
+	 * reset, otherwise reset may fail
+	 */
+#if 0
+	if(NIC_8187 == priv->card_8187) {
+		rtl8192_set_anaparam(dev, RTL8225_ANAPARAM_ON);
+		rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_ON);
+		rtl8192_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);
+	}
+#endif
+	printk("=====>reset?\n");
+#if 0
+	cr=read_nic_byte(dev,CMD);
+	cr = cr & 2;
+	cr = cr | (1<<CMD_RST_SHIFT);
+	write_nic_byte(dev,CMD,cr);
+	
+	force_pci_posting(dev);
+	
+	mdelay(200);
+	
+	if(read_nic_byte(dev,CMD) & (1<<CMD_RST_SHIFT)) 
+		RT_TRACE(COMP_ERR, "Card reset timeout!\n");
+	else 
+		RT_TRACE(COMP_DOWN, "Card successfully reset\n");
+#endif
+#if 0	
+	if(NIC_8187 == priv->card_8187) {
+
+		printk("This is RTL8187 Reset procedure\n");
+		rtl8192_set_mode(dev,EPROM_CMD_LOAD);
+		force_pci_posting(dev);
+		mdelay(200);
+
+		/* after the eeprom load cycle, make sure we have
+		 * correct anaparams
+		 */
+		rtl8192_set_anaparam(dev, RTL8225_ANAPARAM_ON);
+		rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_ON);
+	}
+	else
+#endif
+		printk("This is RTL8187B Reset procedure\n");
+
+}
+#endif
+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};
+inline u16 rtl8192_rate2rate(short rate)
+{
+	if (rate >11) return 0;
+	return rtl_rate[rate]; 
+}
+		
+
+/* The protype of rx_isr has changed since one verion of Linux Kernel */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+static void rtl8192_rx_isr(struct urb *urb, struct pt_regs *regs)
+#else
+static void rtl8192_rx_isr(struct urb *urb)
+#endif
+{
+        struct sk_buff *skb = (struct sk_buff *) urb->context;
+        struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
+        struct net_device *dev = info->dev;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	int out_pipe = info->out_pipe;
+	int err;	
+	if(!priv->up)
+		return;	
+        if (unlikely(urb->status)) {
+                info->urb = NULL;
+                priv->stats.rxstaterr++;
+                priv->ieee80211->stats.rx_errors++;
+                usb_free_urb(urb);
+	//	printk("%s():rx status err\n",__FUNCTION__);
+                return;
+        }
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)
+        skb_unlink(skb, &priv->rx_queue);
+#else
+        __skb_unlink(skb,&priv->rx_queue);
+#endif
+        skb_put(skb, urb->actual_length);
+
+	skb_queue_tail(&priv->skb_queue, skb);
+	tasklet_schedule(&priv->irq_rx_tasklet);
+
+        skb = dev_alloc_skb(RX_URB_SIZE);
+        if (unlikely(!skb)) {
+                usb_free_urb(urb);
+		printk("%s():can,t alloc skb\n",__FUNCTION__);
+                /* TODO check rx queue length and refill *somewhere* */
+                return;
+        }
+	
+	usb_fill_bulk_urb(urb, priv->udev,
+			usb_rcvbulkpipe(priv->udev, out_pipe), skb->tail,
+			RX_URB_SIZE, rtl8192_rx_isr, skb);
+
+        info = (struct rtl8192_rx_info *) skb->cb;
+        info->urb = urb;
+        info->dev = dev;
+	info->out_pipe = out_pipe;
+
+        urb->transfer_buffer = skb->tail;
+        urb->context = skb;
+        skb_queue_tail(&priv->rx_queue, skb);
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+        err = usb_submit_urb(urb, GFP_ATOMIC);
+#else
+        err = usb_submit_urb(urb);
+#endif
+	if(err && err != EPERM)
+		printk("can not submit rxurb, err is %x,URB status is %x\n",err,urb->status);	
+}
+
+u32	
+rtl819xusb_rx_command_packet(
+	struct net_device *dev,
+	struct ieee80211_rx_stats *pstats
+	)
+{	
+	u32	status;
+
+	//RT_TRACE(COMP_RECV, DBG_TRACE, ("---> RxCommandPacketHandle819xUsb()\n"));
+
+	status = cmpk_message_handle_rx(dev, pstats);
+	if (status) 
+	{
+		DMESG("rxcommandpackethandle819xusb: It is a command packet\n");
+	}
+	else
+	{
+		//RT_TRACE(COMP_RECV, DBG_TRACE, ("RxCommandPacketHandle819xUsb: It is not a command packet\n"));
+	}
+	
+	//RT_TRACE(COMP_RECV, DBG_TRACE, ("<--- RxCommandPacketHandle819xUsb()\n"));
+	return status;
+}
+
+#if 0
+void rtl8192_tx_queues_stop(struct net_device *dev)
+{
+	//struct r8192_priv *priv = (struct r8192_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);
+
+	rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
+	write_nic_byte(dev,TX_DMA_POLLING,dma_poll_mask);
+	rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
+}
+#endif
+
+void rtl8192_data_hard_stop(struct net_device *dev)
+{
+	//FIXME !!
+	#if 0
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	priv->dma_poll_mask |= (1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
+	rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
+	write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
+	rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
+	#endif
+}
+
+
+void rtl8192_data_hard_resume(struct net_device *dev)
+{
+	// FIXME !!
+	#if 0
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	priv->dma_poll_mask &= ~(1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
+	rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
+	write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
+	rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
+	#endif
+}
+
+/* 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 rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, int rate)
+{
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	int ret;
+	unsigned long flags;
+	cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
+	u8 queue_index = tcb_desc->queue_index;
+	
+	/* shall not be referred by command packet */
+	assert(queue_index != TXCMD_QUEUE);
+
+	spin_lock_irqsave(&priv->tx_lock,flags);
+
+        memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
+//	tcb_desc->RATRIndex = 7;
+//	tcb_desc->bTxDisableRateFallBack = 1;
+//	tcb_desc->bTxUseDriverAssingedRate = 1;
+	tcb_desc->bTxEnableFwCalcDur = 1;
+	skb_push(skb, priv->ieee80211->tx_headroom);
+	ret = rtl8192_tx(dev, skb);
+
+	//priv->ieee80211->stats.tx_bytes+=(skb->len - priv->ieee80211->tx_headroom);
+	//priv->ieee80211->stats.tx_packets++;
+
+	spin_unlock_irqrestore(&priv->tx_lock,flags);
+
+//	return ret;
+	return;
+}
+
+/* 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 rtl8192_hard_start_xmit(struct sk_buff *skb,struct net_device *dev)
+{
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	int ret;
+	unsigned long flags;
+        cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
+        u8 queue_index = tcb_desc->queue_index;
+
+
+	spin_lock_irqsave(&priv->tx_lock,flags);
+	
+        memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
+	if(queue_index == TXCMD_QUEUE) {
+		skb_push(skb, USB_HWDESC_HEADER_LEN);
+		rtl819xU_tx_cmd(dev, skb);
+		ret = 1;
+	        spin_unlock_irqrestore(&priv->tx_lock,flags);	
+		return ret;
+	} else {
+		skb_push(skb, priv->ieee80211->tx_headroom);
+		ret = rtl8192_tx(dev, skb);
+	}
+	
+	spin_unlock_irqrestore(&priv->tx_lock,flags);	
+	
+	return ret;
+}
+
+
+void rtl8192_try_wake_queue(struct net_device *dev, int pri);
+
+#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
+u16 DrvAggr_PaddingAdd(struct net_device *dev, struct sk_buff *skb)
+{
+	u16     PaddingNum =  256 - ((skb->len + TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES) % 256);
+	return  (PaddingNum&0xff);
+}
+
+u8 MRateToHwRate8190Pci(u8 rate);
+u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc);
+u8 MapHwQueueToFirmwareQueue(u8 QueueID);
+struct sk_buff *DrvAggr_Aggregation(struct net_device *dev, struct ieee80211_drv_agg_txb *pSendList)
+{
+#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 r8192_priv *priv = ieee80211_priv(dev);
+	cb_desc 	*tcb_desc = NULL;
+	u8 		i;
+	u32		TotalLength;
+	struct sk_buff	*skb;
+	struct sk_buff  *agg_skb;
+	tx_desc_819x_usb_aggr_subframe *tx_agg_desc = NULL;	
+	tx_fwinfo_819x_usb	       *tx_fwinfo = NULL;
+
+	// 
+	// Local variable initialization.
+	//
+	/* first skb initialization */
+	skb = pSendList->tx_agg_frames[0];
+	TotalLength = skb->len;
+
+	/* Get the total aggregation length including the padding space and 
+	 * sub frame header.
+	 */
+	for(i = 1; i < pSendList->nr_drv_agg_frames; i++) {
+		TotalLength += DrvAggr_PaddingAdd(dev, skb);
+		skb = pSendList->tx_agg_frames[i];
+		TotalLength += (skb->len + TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES); 
+	}
+
+	/* allocate skb to contain the aggregated packets */
+	agg_skb = dev_alloc_skb(TotalLength + ieee->tx_headroom); 
+	memset(agg_skb->data, 0, agg_skb->len);
+	skb_reserve(agg_skb, ieee->tx_headroom);
+
+//	RT_DEBUG_DATA(COMP_SEND, skb->cb, sizeof(skb->cb));
+	/* reserve info for first subframe Tx descriptor to be set in the tx function */
+	skb = pSendList->tx_agg_frames[0];
+	tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
+	tcb_desc->drv_agg_enable = 1;
+	tcb_desc->pkt_size = skb->len;
+ 	tcb_desc->DrvAggrNum = pSendList->nr_drv_agg_frames;
+	printk("DrvAggNum = %d\n", tcb_desc->DrvAggrNum);
+//	RT_DEBUG_DATA(COMP_SEND, skb->cb, sizeof(skb->cb));
+//	printk("========>skb->data ======> \n");
+//	RT_DEBUG_DATA(COMP_SEND, skb->data, skb->len);
+	memcpy(agg_skb->cb, skb->cb, sizeof(skb->cb));
+	memcpy(skb_put(agg_skb,skb->len),skb->data,skb->len);
+
+	for(i = 1; i < pSendList->nr_drv_agg_frames; i++) {
+		/* push the next sub frame to be 256 byte aline */
+		skb_put(agg_skb,DrvAggr_PaddingAdd(dev,skb));
+
+		/* Subframe drv Tx descriptor and firmware info setting */
+		skb = pSendList->tx_agg_frames[i];
+		tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);	
+		tx_agg_desc = (tx_desc_819x_usb_aggr_subframe *)agg_skb->tail;
+		tx_fwinfo = (tx_fwinfo_819x_usb *)(agg_skb->tail + sizeof(tx_desc_819x_usb_aggr_subframe));
+
+		memset(tx_fwinfo,0,sizeof(tx_fwinfo_819x_usb));
+		/* DWORD 0 */
+		tx_fwinfo->TxHT = (tcb_desc->data_rate&0x80)?1:0;
+		tx_fwinfo->TxRate = MRateToHwRate8190Pci(tcb_desc->data_rate);
+		tx_fwinfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;     
+		tx_fwinfo->Short = QueryIsShort(tx_fwinfo->TxHT, tx_fwinfo->TxRate, tcb_desc);
+		if(tcb_desc->bAMPDUEnable) {//AMPDU enabled
+			tx_fwinfo->AllowAggregation = 1;
+			/* DWORD 1 */
+			tx_fwinfo->RxMF = tcb_desc->ampdu_factor;
+			tx_fwinfo->RxAMD = tcb_desc->ampdu_density&0x07;//ampdudensity 
+		} else {
+			tx_fwinfo->AllowAggregation = 0;
+			/* DWORD 1 */
+			tx_fwinfo->RxMF = 0;
+			tx_fwinfo->RxAMD = 0;
+		}
+
+		/* Protection mode related */
+		tx_fwinfo->RtsEnable = (tcb_desc->bRTSEnable)?1:0;
+		tx_fwinfo->CtsEnable = (tcb_desc->bCTSEnable)?1:0;
+		tx_fwinfo->RtsSTBC = (tcb_desc->bRTSSTBC)?1:0;
+		tx_fwinfo->RtsHT = (tcb_desc->rts_rate&0x80)?1:0;
+		tx_fwinfo->RtsRate =  MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
+		tx_fwinfo->RtsSubcarrier = (tx_fwinfo->RtsHT==0)?(tcb_desc->RTSSC):0;
+		tx_fwinfo->RtsBandwidth = (tx_fwinfo->RtsHT==1)?((tcb_desc->bRTSBW)?1:0):0;
+		tx_fwinfo->RtsShort = (tx_fwinfo->RtsHT==0)?(tcb_desc->bRTSUseShortPreamble?1:0):\
+				      (tcb_desc->bRTSUseShortGI?1:0);
+
+		/* Set Bandwidth and sub-channel settings. */
+		if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
+		{
+			if(tcb_desc->bPacketBW) {
+				tx_fwinfo->TxBandwidth = 1;
+				tx_fwinfo->TxSubCarrier = 0;    //By SD3's Jerry suggestion, use duplicated mode
+			} else {
+				tx_fwinfo->TxBandwidth = 0;
+				tx_fwinfo->TxSubCarrier = priv->nCur40MhzPrimeSC;
+			}
+		} else {
+			tx_fwinfo->TxBandwidth = 0;
+			tx_fwinfo->TxSubCarrier = 0;
+		}
+
+		/* Fill Tx descriptor */
+		memset(tx_agg_desc, 0, sizeof(tx_desc_819x_usb_aggr_subframe));
+		/* DWORD 0 */
+		//tx_agg_desc->LINIP = 0;
+		//tx_agg_desc->CmdInit = 1; 
+		tx_agg_desc->Offset =  sizeof(tx_fwinfo_819x_usb) + 8;
+		/* already raw data, need not to substract header length */
+		tx_agg_desc->PktSize = skb->len & 0xffff;
+
+		/*DWORD 1*/
+		tx_agg_desc->SecCAMID= 0;
+		tx_agg_desc->RATid = tcb_desc->RATRIndex;
+#if 0
+		/* Fill security related */
+		if( pTcb->bEncrypt && !Adapter->MgntInfo.SecurityInfo.SWTxEncryptFlag)
+		{
+			EncAlg = SecGetEncryptionOverhead(
+					Adapter,
+					&EncryptionMPDUHeadOverhead,
+					&EncryptionMPDUTailOverhead,
+					NULL,
+					NULL,
+					FALSE,
+					FALSE);
+			//2004/07/22, kcwu, EncryptionMPDUHeadOverhead has been added in previous code
+			//MPDUOverhead = EncryptionMPDUHeadOverhead + EncryptionMPDUTailOverhead;
+			MPDUOverhead = EncryptionMPDUTailOverhead;
+			tx_agg_desc->NoEnc = 0;
+			RT_TRACE(COMP_SEC, DBG_LOUD, ("******We in the loop SecCAMID is %d SecDescAssign is %d The Sec is %d********\n",tx_agg_desc->SecCAMID,tx_agg_desc->SecDescAssign,EncAlg));
+			//CamDumpAll(Adapter);
+		}
+		else
+#endif
+		{
+			//MPDUOverhead = 0;
+			tx_agg_desc->NoEnc = 1;
+		}
+#if 0
+		switch(EncAlg){
+			case NO_Encryption:
+				tx_agg_desc->SecType = 0x0;
+				break;
+			case WEP40_Encryption:
+			case WEP104_Encryption:
+				tx_agg_desc->SecType = 0x1;
+				break;
+			case TKIP_Encryption:
+				tx_agg_desc->SecType = 0x2;
+				break;
+			case AESCCMP_Encryption:
+				tx_agg_desc->SecType = 0x3;
+				break;
+			default:
+				tx_agg_desc->SecType = 0x0;
+				break;
+		}
+#else
+		tx_agg_desc->SecType = 0x0;
+#endif
+
+		if (tcb_desc->bHwSec) {
+			switch (priv->ieee80211->pairwise_key_type)
+			{
+				case KEY_TYPE_WEP40:
+				case KEY_TYPE_WEP104:
+					tx_agg_desc->SecType = 0x1;
+					tx_agg_desc->NoEnc = 0;
+					break;
+				case KEY_TYPE_TKIP:
+					tx_agg_desc->SecType = 0x2;
+					tx_agg_desc->NoEnc = 0;
+					break;
+				case KEY_TYPE_CCMP:
+					tx_agg_desc->SecType = 0x3;
+					tx_agg_desc->NoEnc = 0;
+					break;
+				case KEY_TYPE_NA:
+					tx_agg_desc->SecType = 0x0;
+					tx_agg_desc->NoEnc = 1;
+					break;
+			}
+		}
+
+		tx_agg_desc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
+		tx_agg_desc->TxFWInfoSize =  sizeof(tx_fwinfo_819x_usb);
+
+		tx_agg_desc->DISFB = tcb_desc->bTxDisableRateFallBack;
+		tx_agg_desc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
+
+		tx_agg_desc->OWN = 1;
+
+		//DWORD 2
+		/* According windows driver, it seems that there no need to fill this field */
+		//tx_agg_desc->TxBufferSize= (u32)(skb->len - USB_HWDESC_HEADER_LEN);
+
+		/* to fill next packet */
+		skb_put(agg_skb,TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES);
+		memcpy(skb_put(agg_skb,skb->len),skb->data,skb->len);
+	}
+
+	for(i = 0; i < pSendList->nr_drv_agg_frames; i++) {
+		dev_kfree_skb_any(pSendList->tx_agg_frames[i]);
+	}
+
+	return agg_skb;
+}
+
+/* NOTE:
+	This function return a list of PTCB which is proper to be aggregate with the input TCB. 
+	If no proper TCB is found to do aggregation, SendList will only contain the input TCB.
+*/
+u8 DrvAggr_GetAggregatibleList(struct net_device *dev, struct sk_buff *skb, 
+		struct ieee80211_drv_agg_txb *pSendList)
+{
+#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	
+	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
+	u16		nMaxAggrNum = pHTInfo->UsbTxAggrNum;
+	cb_desc 	*tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
+	u8		QueueID = tcb_desc->queue_index;
+
+	do {
+		pSendList->tx_agg_frames[pSendList->nr_drv_agg_frames++] = skb;
+		if(pSendList->nr_drv_agg_frames >= nMaxAggrNum) {
+			break;
+		}
+
+	} while((skb = skb_dequeue(&ieee->skb_drv_aggQ[QueueID])));
+
+	RT_TRACE(COMP_AMSDU, "DrvAggr_GetAggregatibleList, nAggrTcbNum = %d \n", pSendList->nr_drv_agg_frames);
+	return pSendList->nr_drv_agg_frames;
+}
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+static void rtl8192_tx_isr(struct urb *tx_urb, struct pt_regs *reg)
+#else
+static void rtl8192_tx_isr(struct urb *tx_urb)
+#endif
+{
+	struct sk_buff *skb = (struct sk_buff*)tx_urb->context;
+	struct net_device *dev = NULL;
+	struct r8192_priv *priv = NULL;
+	cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
+	u8  queue_index = tcb_desc->queue_index;
+//	bool bToSend0Byte;
+//	u16 BufLen = skb->len;
+
+	memcpy(&dev,(struct net_device*)(skb->cb),sizeof(struct net_device*));
+	priv = ieee80211_priv(dev);
+
+	if(tcb_desc->queue_index != TXCMD_QUEUE) {
+		if(tx_urb->status == 0) {
+			dev->trans_start = jiffies;
+			// As act as station mode, destion shall be  unicast address.
+			//priv->ieee80211->stats.tx_bytes+=(skb->len - priv->ieee80211->tx_headroom);
+			//priv->ieee80211->stats.tx_packets++;
+			priv->stats.txoktotal++;
+			priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
+			priv->stats.txbytesunicast += (skb->len - priv->ieee80211->tx_headroom);
+		} else {
+			priv->ieee80211->stats.tx_errors++;
+			//priv->stats.txmanageerr++;
+			/* TODO */
+		}
+	}
+
+	/* free skb and tx_urb */
+	if(skb != NULL) {
+		dev_kfree_skb_any(skb);
+		usb_free_urb(tx_urb);
+		atomic_dec(&priv->tx_pending[queue_index]);
+	}
+
+#if 0  //we need to send zero byte packet just after 512 byte(64 byte)packet is transmitted, or we will halt. It will greatly reduced available page in FW, and ruin our throughput. WB 2008.08.27
+	if(BufLen > 0 && ((BufLen % 512 == 0)||(BufLen % 64 == 0))) {
+		bToSend0Byte = true;
+	}
+
+	bToSend0Byte = false;
+	//
+	// Note that, we at most handle 1 MPDU to send here, either 
+	// fragment or MPDU in wait queue.
+	//
+	if(!bToSend0Byte)
+#endif
+	{
+		//
+		// Handle HW Beacon: 
+		// We had transfer our beacon frame to host controler at this moment.
+		//
+#if 0
+		if(tcb_desc->tx_queue == BEACON_QUEUE)
+		{
+			priv->bSendingBeacon = FALSE;
+		}
+#endif
+		//
+		// Caution:
+		// Handling the wait queue of command packets.
+		// For Tx command packets, we must not do TCB fragment because it is not handled right now.
+		// We must cut the packets to match the size of TX_CMD_PKT before we send it.
+		//
+
+		/* Handle MPDU in wait queue. */
+		if(queue_index != BEACON_QUEUE) {
+			/* Don't send data frame during scanning.*/
+			if((skb_queue_len(&priv->ieee80211->skb_waitQ[queue_index]) != 0)&&\
+					(!(priv->ieee80211->queue_stop))) {
+				if(NULL != (skb = skb_dequeue(&(priv->ieee80211->skb_waitQ[queue_index]))))
+					priv->ieee80211->softmac_hard_start_xmit(skb, dev);
+
+				return; //modified by david to avoid further processing AMSDU 
+			}
+#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
+			else if ((skb_queue_len(&priv->ieee80211->skb_drv_aggQ[queue_index])!= 0)&&\
+ 				(!(priv->ieee80211->queue_stop))) {
+				// Tx Driver Aggregation process 
+				/* The driver will aggregation the packets according to the following stets  
+				 * 1. check whether there's tx irq available, for it's a completion return 
+				 *    function, it should contain enough tx irq;
+				 * 2. check pakcet type;
+				 * 3. intialize sendlist, check whether the to-be send packet no greater than 1 
+				 * 4. aggregation the packets, and fill firmware info and tx desc to it, etc.
+				 * 5. check whehter the packet could be sent, otherwise just insert to wait head 
+				 * */
+				skb = skb_dequeue(&priv->ieee80211->skb_drv_aggQ[queue_index]);
+				if(!check_nic_enough_desc(dev, queue_index)) {
+					skb_queue_head(&(priv->ieee80211->skb_drv_aggQ[queue_index]), skb);
+					return;
+				}
+
+				{
+					/*TODO*/
+					/*
+					u8* pHeader = skb->data;
+					
+					if(IsMgntQosData(pHeader) || 
+				            IsMgntQData_Ack(pHeader) || 
+					    IsMgntQData_Poll(pHeader) || 
+					    IsMgntQData_Poll_Ack(pHeader) 
+					  ) 
+					*/
+					{
+						struct ieee80211_drv_agg_txb SendList;
+
+						memset(&SendList, 0, sizeof(struct ieee80211_drv_agg_txb));
+						if(DrvAggr_GetAggregatibleList(dev, skb, &SendList) > 1) {
+							skb = DrvAggr_Aggregation(dev, &SendList);
+
+#if 0
+						printk("=============>to send aggregated packet!\n");
+						RT_DEBUG_DATA(COMP_SEND, skb->cb, sizeof(skb->cb));
+						printk("\n=================skb->len = %d\n", skb->len);	
+						RT_DEBUG_DATA(COMP_SEND, skb->data, skb->len);
+#endif
+						}
+					}
+					priv->ieee80211->softmac_hard_start_xmit(skb, dev);
+				}
+			}
+#endif
+		}
+	}
+
+#if 0
+	else
+	{
+		RT_TRACE( COMP_SEND,"HalUsbOutComplete(%d): bToSend0Byte.\n", PipeIndex);
+
+		//
+		// In this case, we don't return skb now. 
+		// It will be returned when the 0-byte request completed.
+		//
+
+		//
+		// Bulk out an 0-byte padding transfer.
+		//
+		HalUsbOut0Byte(pAdapter, PipeIndex, skb);
+	}
+
+#endif
+}
+
+void rtl8192_beacon_stop(struct net_device *dev)
+{
+	u8 msr, msrm, msr2;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	msr  = read_nic_byte(dev, MSR);
+	msrm = msr & MSR_LINK_MASK;
+	msr2 = msr & ~MSR_LINK_MASK;
+
+	if(NIC_8192U == priv->card_8192) {
+		usb_kill_urb(priv->rx_urb[MAX_RX_URB]);
+	}
+	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 rtl8192_config_rate(struct net_device* dev, u16* rate_config)
+{
+	 struct r8192_priv *priv = ieee80211_priv(dev);
+	 struct ieee80211_network *net;
+	 u8 i=0, basic_rate = 0;
+	 net = & priv->ieee80211->current_network;
+	 
+	 for (i=0; i<net->rates_len; i++)
+	 {
+		 basic_rate = net->rates[i]&0x7f;
+		 switch(basic_rate)
+		 {
+			 case MGN_1M:	*rate_config |= RRSR_1M;	break;
+			 case MGN_2M:	*rate_config |= RRSR_2M;	break;
+			 case MGN_5_5M:	*rate_config |= RRSR_5_5M;	break;
+			 case MGN_11M:	*rate_config |= RRSR_11M;	break;
+			 case MGN_6M:	*rate_config |= RRSR_6M;	break;
+			 case MGN_9M:	*rate_config |= RRSR_9M;	break;
+			 case MGN_12M:	*rate_config |= RRSR_12M;	break;
+			 case MGN_18M:	*rate_config |= RRSR_18M;	break;
+			 case MGN_24M:	*rate_config |= RRSR_24M;	break;
+			 case MGN_36M:	*rate_config |= RRSR_36M;	break;
+			 case MGN_48M:	*rate_config |= RRSR_48M;	break;
+			 case MGN_54M:	*rate_config |= RRSR_54M;	break;
+		 }
+	 }
+	 for (i=0; i<net->rates_ex_len; i++)
+	 {
+		 basic_rate = net->rates_ex[i]&0x7f;
+		 switch(basic_rate)
+		 {
+			 case MGN_1M:	*rate_config |= RRSR_1M;	break;
+			 case MGN_2M:	*rate_config |= RRSR_2M;	break;
+			 case MGN_5_5M:	*rate_config |= RRSR_5_5M;	break;
+			 case MGN_11M:	*rate_config |= RRSR_11M;	break;
+			 case MGN_6M:	*rate_config |= RRSR_6M;	break;
+			 case MGN_9M:	*rate_config |= RRSR_9M;	break;
+			 case MGN_12M:	*rate_config |= RRSR_12M;	break;
+			 case MGN_18M:	*rate_config |= RRSR_18M;	break;
+			 case MGN_24M:	*rate_config |= RRSR_24M;	break;
+			 case MGN_36M:	*rate_config |= RRSR_36M;	break;
+			 case MGN_48M:	*rate_config |= RRSR_48M;	break;
+			 case MGN_54M:	*rate_config |= RRSR_54M;	break;
+		 }
+	 }
+}
+			 
+	 
+#define SHORT_SLOT_TIME 9
+#define NON_SHORT_SLOT_TIME 20
+
+void rtl8192_update_cap(struct net_device* dev, u16 cap)
+{
+	u32 tmp = 0;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	struct ieee80211_network *net = &priv->ieee80211->current_network;
+	priv->short_preamble = cap & WLAN_CAPABILITY_SHORT_PREAMBLE;
+	tmp = priv->basic_rate;
+	if (priv->short_preamble)
+		tmp |= BRSR_AckShortPmb;
+	write_nic_dword(dev, RRSR, tmp);
+
+	if (net->mode & (IEEE_G|IEEE_N_24G))
+	{
+		u8 slot_time = 0;
+		if ((cap & WLAN_CAPABILITY_SHORT_SLOT)&&(!priv->ieee80211->pHTInfo->bCurrentRT2RTLongSlotTime))
+		{//short slot time
+			slot_time = SHORT_SLOT_TIME;
+		}
+		else //long slot time
+			slot_time = NON_SHORT_SLOT_TIME;
+		priv->slot_time = slot_time;
+		write_nic_byte(dev, SLOT_TIME, slot_time);
+	}
+
+}
+void rtl8192_net_update(struct net_device *dev)
+{
+
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	struct ieee80211_network *net;
+	u16 BcnTimeCfg = 0, BcnCW = 6, BcnIFS = 0xf;
+	u16 rate_config = 0;
+	net = & priv->ieee80211->current_network;
+	
+	rtl8192_config_rate(dev, &rate_config);	
+	priv->basic_rate = rate_config &= 0x15f;
+
+	write_nic_dword(dev,BSSIDR,((u32*)net->bssid)[0]);
+	write_nic_word(dev,BSSIDR+4,((u16*)net->bssid)[2]);
+	//for(i=0;i<ETH_ALEN;i++)
+	//	write_nic_byte(dev,BSSID+i,net->bssid[i]);
+
+	rtl8192_update_msr(dev);
+//	rtl8192_update_cap(dev, net->capability);
+	if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
+	{
+	write_nic_word(dev, ATIMWND, 2);
+	write_nic_word(dev, BCN_DMATIME, 1023);	
+	write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
+//	write_nic_word(dev, BcnIntTime, 100);
+	write_nic_word(dev, BCN_DRV_EARLY_INT, 1);
+	write_nic_byte(dev, BCN_ERR_THRESH, 100);
+		BcnTimeCfg |= (BcnCW<<BCN_TCFG_CW_SHIFT);
+	// TODO: BcnIFS may required to be changed on ASIC
+	 	BcnTimeCfg |= BcnIFS<<BCN_TCFG_IFS;
+
+	write_nic_word(dev, BCN_TCFG, BcnTimeCfg);
+	}
+
+	
+
+}
+
+//temporary hw beacon is not used any more.
+//open it when necessary
+#if 1
+void rtl819xusb_beacon_tx(struct net_device *dev,u16  tx_rate)
+{
+
+#if 0
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	struct sk_buff *skb;
+	int i = 0;
+	//u8 cr;
+
+	rtl8192_net_update(dev);
+
+	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 ;
+			}
+		}
+	skb->cb[0] = NORM_PRIORITY;
+	skb->cb[1] = 0; //morefragment = 0
+	skb->cb[2] = ieeerate2rtlrate(tx_rate);
+
+	rtl8192_tx(dev,skb);
+
+#endif
+}
+#endif
+inline u8 rtl8192_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( rtl8192_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;
+}
+
+void rtl819xU_cmd_isr(struct urb *tx_cmd_urb, struct pt_regs *regs)
+{
+#if 0
+	struct net_device *dev = (struct net_device*)tx_cmd_urb->context;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	int		   last_init_packet = 0;
+	u8		   *ptr_cmd_buf;
+	u16		    cmd_buf_len;
+
+	if(tx_cmd_urb->status != 0) {
+		priv->pFirmware.firmware_seg_index = 0; //only begin transter, should it can be set to 1
+	}
+	
+	/* Free the urb and the corresponding buf for common Tx cmd packet, or
+	 * last segment of each firmware img.
+	 */
+	if((priv->pFirmware.firmware_seg_index == 0) ||(priv->pFirmware.firmware_seg_index == priv->pFirmware.firmware_seg_maxnum)) {
+		priv->pFirmware.firmware_seg_index = 0;//only begin transter, should it can be set to 1
+	} else {
+		/* prepare for last transfer */
+		/* update some infomation for */
+		/* last segment of the firmware img need indicate to device */
+		priv->pFirmware.firmware_seg_index++;
+		if(priv->pFirmware.firmware_seg_index == priv->pFirmware.firmware_seg_maxnum) {
+			last_init_packet = 1;
+		}
+		
+		cmd_buf_len = priv->pFirmware.firmware_seg_container[priv->pFirmware.firmware_seg_index-1].seg_size;
+		ptr_cmd_buf = priv->pFfirmware.firmware_seg_container[priv->pFfirmware.firmware_seg_index-1].seg_ptr;
+		rtl819xU_tx_cmd(dev, ptr_cmd_buf, cmd_buf_len, last_init_packet, DESC_PACKET_TYPE_INIT);
+	}
+
+	kfree(tx_cmd_urb->transfer_buffer);
+#endif
+	usb_free_urb(tx_cmd_urb);
+}
+
+unsigned int txqueue2outpipe(struct r8192_priv* priv,unsigned int tx_queue) {
+
+	if(tx_queue >= 9)
+	{
+		RT_TRACE(COMP_ERR,"%s():Unknown queue ID!!!\n",__FUNCTION__);
+		return 0x04;
+	}
+	return priv->txqueue_to_outpipemap[tx_queue];
+}
+
+short rtl819xU_tx_cmd(struct net_device *dev, struct sk_buff *skb)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	//u8			*tx;
+	int			status;
+	struct urb		*tx_urb;
+	//int			urb_buf_len;
+	unsigned int 		idx_pipe;
+	tx_desc_cmd_819x_usb *pdesc = (tx_desc_cmd_819x_usb *)skb->data; 
+	cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
+	u8 queue_index = tcb_desc->queue_index;
+	
+	//printk("\n %s::queue_index = %d\n",__FUNCTION__, queue_index);
+	atomic_inc(&priv->tx_pending[queue_index]);
+#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){
+		dev_kfree_skb(skb);
+		return -ENOMEM;
+	}
+	
+	memset(pdesc, 0, USB_HWDESC_HEADER_LEN);
+	/* Tx descriptor ought to be set according to the skb->cb */
+	pdesc->FirstSeg = 1;//bFirstSeg;
+	pdesc->LastSeg = 1;//bLastSeg;
+	pdesc->CmdInit = tcb_desc->bCmdOrInit;
+	pdesc->TxBufferSize = tcb_desc->txbuf_size;
+	pdesc->OWN = 1;
+	pdesc->LINIP = tcb_desc->bLastIniPkt;
+
+	//----------------------------------------------------------------------------
+	// Fill up USB_OUT_CONTEXT.
+	//----------------------------------------------------------------------------
+	// Get index to out pipe from specified QueueID.
+#ifndef USE_ONE_PIPE
+	idx_pipe = txqueue2outpipe(priv,queue_index);
+#else
+	idx_pipe = 0x04;
+#endif
+#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
+	usb_fill_bulk_urb(tx_urb,priv->udev, usb_sndbulkpipe(priv->udev,idx_pipe), \
+			skb->data, skb->len, rtl8192_tx_isr, skb);
+
+#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){
+		return 0;
+	}else{
+		DMESGE("Error TX CMD URB, error %d",
+				status);
+		return -1;
+	}
+}
+
+/*
+ * Mapping Software/Hardware descriptor queue id to "Queue Select Field"
+ * in TxFwInfo data structure
+ * 2006.10.30 by Emily
+ *
+ * \param QUEUEID       Software Queue       
+*/
+u8 MapHwQueueToFirmwareQueue(u8 QueueID)
+{
+	u8 QueueSelect = 0x0;       //defualt set to 
+
+	switch(QueueID) {
+		case BE_QUEUE:
+			QueueSelect = QSLT_BE;  //or QSelect = pTcb->priority;
+			break;
+
+		case BK_QUEUE:
+			QueueSelect = QSLT_BK;  //or QSelect = pTcb->priority;
+			break;
+
+		case VO_QUEUE:
+			QueueSelect = QSLT_VO;  //or QSelect = pTcb->priority;
+			break;
+
+		case VI_QUEUE:
+			QueueSelect = QSLT_VI;  //or QSelect = pTcb->priority;  
+			break;
+		case MGNT_QUEUE:
+			QueueSelect = QSLT_MGNT;
+			break;
+
+		case BEACON_QUEUE:
+			QueueSelect = QSLT_BEACON;
+			break;
+
+			// TODO: 2006.10.30 mark other queue selection until we verify it is OK
+			// TODO: Remove Assertions 
+//#if (RTL819X_FPGA_VER & RTL819X_FPGA_GUANGAN_070502)
+		case TXCMD_QUEUE:
+			QueueSelect = QSLT_CMD;
+			break;
+//#endif
+		case HIGH_QUEUE:
+			QueueSelect = QSLT_HIGH;
+			break;
+
+		default:
+			RT_TRACE(COMP_ERR, "TransmitTCB(): Impossible Queue Selection: %d \n", QueueID);
+			break;
+	}
+	return QueueSelect;
+}
+
+u8 MRateToHwRate8190Pci(u8 rate)
+{
+	u8  ret = DESC90_RATE1M;
+
+	switch(rate) {
+		case MGN_1M:    ret = DESC90_RATE1M;    break;
+		case MGN_2M:    ret = DESC90_RATE2M;    break;
+		case MGN_5_5M:  ret = DESC90_RATE5_5M;  break;
+		case MGN_11M:   ret = DESC90_RATE11M;   break;
+		case MGN_6M:    ret = DESC90_RATE6M;    break;
+		case MGN_9M:    ret = DESC90_RATE9M;    break;
+		case MGN_12M:   ret = DESC90_RATE12M;   break;
+		case MGN_18M:   ret = DESC90_RATE18M;   break;
+		case MGN_24M:   ret = DESC90_RATE24M;   break;
+		case MGN_36M:   ret = DESC90_RATE36M;   break;
+		case MGN_48M:   ret = DESC90_RATE48M;   break;
+		case MGN_54M:   ret = DESC90_RATE54M;   break;
+
+		// HT rate since here
+		case MGN_MCS0:  ret = DESC90_RATEMCS0;  break;
+		case MGN_MCS1:  ret = DESC90_RATEMCS1;  break;
+		case MGN_MCS2:  ret = DESC90_RATEMCS2;  break;
+		case MGN_MCS3:  ret = DESC90_RATEMCS3;  break;
+		case MGN_MCS4:  ret = DESC90_RATEMCS4;  break;
+		case MGN_MCS5:  ret = DESC90_RATEMCS5;  break;
+		case MGN_MCS6:  ret = DESC90_RATEMCS6;  break;
+		case MGN_MCS7:  ret = DESC90_RATEMCS7;  break;
+		case MGN_MCS8:  ret = DESC90_RATEMCS8;  break;
+		case MGN_MCS9:  ret = DESC90_RATEMCS9;  break;
+		case MGN_MCS10: ret = DESC90_RATEMCS10; break;
+		case MGN_MCS11: ret = DESC90_RATEMCS11; break;
+		case MGN_MCS12: ret = DESC90_RATEMCS12; break;
+		case MGN_MCS13: ret = DESC90_RATEMCS13; break;
+		case MGN_MCS14: ret = DESC90_RATEMCS14; break;
+		case MGN_MCS15: ret = DESC90_RATEMCS15; break;
+		case (0x80|0x20): ret = DESC90_RATEMCS32; break;
+
+		default:       break;
+	}
+	return ret;
+}
+
+
+u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc)
+{
+	u8   tmp_Short;
+
+	tmp_Short = (TxHT==1)?((tcb_desc->bUseShortGI)?1:0):((tcb_desc->bUseShortPreamble)?1:0);
+
+	if(TxHT==1 && TxRate != DESC90_RATEMCS15)
+		tmp_Short = 0;
+
+	return tmp_Short;
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+static void tx_zero_isr(struct urb *tx_urb, struct pt_regs *reg)
+#else
+static void tx_zero_isr(struct urb *tx_urb)
+#endif
+{
+	return;
+}
+
+/* 
+ * The tx procedure is just as following, 
+ * skb->cb will contain all the following information,
+ * priority, morefrag, rate, &dev.
+ * */
+short rtl8192_tx(struct net_device *dev, struct sk_buff* skb)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
+	tx_desc_819x_usb *tx_desc = (tx_desc_819x_usb *)skb->data;
+	tx_fwinfo_819x_usb *tx_fwinfo = (tx_fwinfo_819x_usb *)(skb->data + USB_HWDESC_HEADER_LEN);
+	struct usb_device *udev = priv->udev;
+	int pend;
+	int status;
+	struct urb *tx_urb = NULL, *tx_urb_zero = NULL;
+	//int urb_len;		
+	unsigned int idx_pipe;
+//	RT_DEBUG_DATA(COMP_SEND, tcb_desc, sizeof(cb_desc));
+#if 0
+	/* Added by Annie for filling Len_Adjust field. 2005-12-14. */
+        RT_ENC_ALG  EncAlg = NO_Encryption; 
+#endif
+//	printk("=============> %s\n", __FUNCTION__);
+	pend = atomic_read(&priv->tx_pending[tcb_desc->queue_index]);
+	/* we are locked here so the two atomic_read and inc are executed 
+	 * without interleaves 
+	 * !!! For debug purpose 	 
+	 */
+	if( pend > MAX_TX_URB){
+#if 0
+		switch (tcb_desc->queue_index) {
+			case VO_PRIORITY:
+				priv->stats.txvodrop++;
+				break;
+			case VI_PRIORITY:
+				priv->stats.txvidrop++;
+				break;
+			case BE_PRIORITY:
+				priv->stats.txbedrop++;
+				break;
+			default://BK_PRIORITY
+				priv->stats.txbkdrop++;
+				break;	
+		}
+#endif	
+		printk("To discard skb packet!\n");
+		dev_kfree_skb_any(skb);
+		return -1;
+	}
+
+#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){
+		dev_kfree_skb_any(skb);
+		return -ENOMEM;
+	}
+
+	/* Fill Tx firmware info */
+	memset(tx_fwinfo,0,sizeof(tx_fwinfo_819x_usb));
+	/* DWORD 0 */
+	tx_fwinfo->TxHT = (tcb_desc->data_rate&0x80)?1:0;
+	tx_fwinfo->TxRate = MRateToHwRate8190Pci(tcb_desc->data_rate);
+	tx_fwinfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;     
+	tx_fwinfo->Short = QueryIsShort(tx_fwinfo->TxHT, tx_fwinfo->TxRate, tcb_desc);
+	if(tcb_desc->bAMPDUEnable) {//AMPDU enabled
+		tx_fwinfo->AllowAggregation = 1;
+		/* DWORD 1 */
+		tx_fwinfo->RxMF = tcb_desc->ampdu_factor;
+		tx_fwinfo->RxAMD = tcb_desc->ampdu_density&0x07;//ampdudensity 
+	} else {
+		tx_fwinfo->AllowAggregation = 0;
+		/* DWORD 1 */
+		tx_fwinfo->RxMF = 0;
+		tx_fwinfo->RxAMD = 0;
+	}
+
+	/* Protection mode related */
+	tx_fwinfo->RtsEnable = (tcb_desc->bRTSEnable)?1:0;
+	tx_fwinfo->CtsEnable = (tcb_desc->bCTSEnable)?1:0;
+	tx_fwinfo->RtsSTBC = (tcb_desc->bRTSSTBC)?1:0;
+	tx_fwinfo->RtsHT = (tcb_desc->rts_rate&0x80)?1:0;
+	tx_fwinfo->RtsRate =  MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
+	tx_fwinfo->RtsSubcarrier = (tx_fwinfo->RtsHT==0)?(tcb_desc->RTSSC):0;
+	tx_fwinfo->RtsBandwidth = (tx_fwinfo->RtsHT==1)?((tcb_desc->bRTSBW)?1:0):0;
+	tx_fwinfo->RtsShort = (tx_fwinfo->RtsHT==0)?(tcb_desc->bRTSUseShortPreamble?1:0):\
+				(tcb_desc->bRTSUseShortGI?1:0);
+
+	/* Set Bandwidth and sub-channel settings. */
+	if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
+	{
+		if(tcb_desc->bPacketBW) {
+			tx_fwinfo->TxBandwidth = 1;
+			tx_fwinfo->TxSubCarrier = 0;    //By SD3's Jerry suggestion, use duplicated mode
+		} else {
+			tx_fwinfo->TxBandwidth = 0;
+			tx_fwinfo->TxSubCarrier = priv->nCur40MhzPrimeSC;
+		}
+	} else {
+		tx_fwinfo->TxBandwidth = 0;
+		tx_fwinfo->TxSubCarrier = 0;
+	}
+
+#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
+	if (tcb_desc->drv_agg_enable)
+	{
+		tx_fwinfo->Tx_INFO_RSVD = (tcb_desc->DrvAggrNum & 0x1f) << 1;
+	}
+#endif
+	/* Fill Tx descriptor */
+	memset(tx_desc, 0, sizeof(tx_desc_819x_usb));
+	/* DWORD 0 */
+        tx_desc->LINIP = 0;
+        tx_desc->CmdInit = 1; 
+        tx_desc->Offset =  sizeof(tx_fwinfo_819x_usb) + 8;
+
+#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
+	if (tcb_desc->drv_agg_enable) {
+		tx_desc->PktSize = tcb_desc->pkt_size;
+	} else
+#endif
+	{
+		tx_desc->PktSize = (skb->len - TX_PACKET_SHIFT_BYTES) & 0xffff;
+	}
+
+	/*DWORD 1*/
+	tx_desc->SecCAMID= 0;
+	tx_desc->RATid = tcb_desc->RATRIndex;
+#if 0
+	/* Fill security related */
+	if( pTcb->bEncrypt && !Adapter->MgntInfo.SecurityInfo.SWTxEncryptFlag)
+	{
+		EncAlg = SecGetEncryptionOverhead(
+				Adapter,
+				&EncryptionMPDUHeadOverhead,
+				&EncryptionMPDUTailOverhead,
+				NULL,
+				NULL,
+				FALSE,
+				FALSE);
+		//2004/07/22, kcwu, EncryptionMPDUHeadOverhead has been added in previous code
+		//MPDUOverhead = EncryptionMPDUHeadOverhead + EncryptionMPDUTailOverhead;
+		MPDUOverhead = EncryptionMPDUTailOverhead;
+		tx_desc->NoEnc = 0;
+		RT_TRACE(COMP_SEC, DBG_LOUD, ("******We in the loop SecCAMID is %d SecDescAssign is %d The Sec is %d********\n",tx_desc->SecCAMID,tx_desc->SecDescAssign,EncAlg));
+		//CamDumpAll(Adapter);
+	}
+	else
+#endif
+	{
+		//MPDUOverhead = 0;
+		tx_desc->NoEnc = 1;
+	}
+#if 0
+	switch(EncAlg){
+		case NO_Encryption:
+			tx_desc->SecType = 0x0;
+			break;
+		case WEP40_Encryption:
+		case WEP104_Encryption:
+			tx_desc->SecType = 0x1;
+			break;
+		case TKIP_Encryption:
+			tx_desc->SecType = 0x2;
+			break;
+		case AESCCMP_Encryption:
+			tx_desc->SecType = 0x3;
+			break;
+		default:
+			tx_desc->SecType = 0x0;
+			break;
+	}
+#else
+	tx_desc->SecType = 0x0;
+#endif
+		if (tcb_desc->bHwSec)
+			{
+				switch (priv->ieee80211->pairwise_key_type)
+				{
+					case KEY_TYPE_WEP40:
+					case KEY_TYPE_WEP104:
+						 tx_desc->SecType = 0x1;
+						 tx_desc->NoEnc = 0;
+						 break;
+					case KEY_TYPE_TKIP:
+						 tx_desc->SecType = 0x2;
+						 tx_desc->NoEnc = 0;
+						 break;
+					case KEY_TYPE_CCMP:
+						 tx_desc->SecType = 0x3;
+						 tx_desc->NoEnc = 0;
+						 break;
+					case KEY_TYPE_NA:
+						 tx_desc->SecType = 0x0;
+						 tx_desc->NoEnc = 1;
+						 break;
+				}
+			}
+
+	tx_desc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
+	tx_desc->TxFWInfoSize =  sizeof(tx_fwinfo_819x_usb);
+
+	tx_desc->DISFB = tcb_desc->bTxDisableRateFallBack;
+	tx_desc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
+
+        /* Fill fields that are required to be initialized in all of the descriptors */
+        //DWORD 0
+#if 0	
+        tx_desc->FirstSeg = (tcb_desc->bFirstSeg)? 1:0;
+        tx_desc->LastSeg = (tcb_desc->bLastSeg)?1:0;
+#else 
+        tx_desc->FirstSeg = 1;
+        tx_desc->LastSeg = 1;
+#endif
+        tx_desc->OWN = 1;
+
+#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE	
+	if (tcb_desc->drv_agg_enable) {
+		tx_desc->TxBufferSize = tcb_desc->pkt_size + sizeof(tx_fwinfo_819x_usb);
+	} else
+#endif
+	{
+		//DWORD 2
+		tx_desc->TxBufferSize = (u32)(skb->len - USB_HWDESC_HEADER_LEN);
+	}
+	/* Get index to out pipe from specified QueueID */
+#ifndef USE_ONE_PIPE
+	idx_pipe = txqueue2outpipe(priv,tcb_desc->queue_index);
+#else
+	idx_pipe = 0x5;
+#endif
+
+	//RT_DEBUG_DATA(COMP_SEND,tx_fwinfo,sizeof(tx_fwinfo_819x_usb));
+	//RT_DEBUG_DATA(COMP_SEND,tx_desc,sizeof(tx_desc_819x_usb));
+
+	/* To submit bulk urb */
+	usb_fill_bulk_urb(tx_urb,udev,
+			usb_sndbulkpipe(udev,idx_pipe), skb->data,
+			skb->len, rtl8192_tx_isr, skb);
+
+#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){
+//we need to send 0 byte packet whenever 512N bytes/64N(HIGN SPEED/NORMAL SPEED) bytes packet has been transmitted. Otherwise, it will be halt to wait for another packet. WB. 2008.08.27
+		bool bSend0Byte = false;
+		u8 zero = 0;
+		if(udev->speed == USB_SPEED_HIGH)
+		{
+			if (skb->len > 0 && skb->len % 512 == 0)
+				bSend0Byte = true;
+		}
+		else
+		{
+			if (skb->len > 0 && skb->len % 64 == 0)
+				bSend0Byte = true;
+		} 
+		if (bSend0Byte)
+		{
+#if 1
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+			tx_urb_zero = usb_alloc_urb(0,GFP_ATOMIC);
+#else
+			tx_urb_zero = usb_alloc_urb(0);
+#endif
+			if(!tx_urb_zero){
+				RT_TRACE(COMP_ERR, "can't alloc urb for zero byte\n");
+				return -ENOMEM;
+			}
+			usb_fill_bulk_urb(tx_urb_zero,udev,
+					usb_sndbulkpipe(udev,idx_pipe), &zero,
+					0, tx_zero_isr, dev);
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+			status = usb_submit_urb(tx_urb_zero, GFP_ATOMIC);
+#else
+			status = usb_submit_urb(tx_urb_zero);
+#endif
+			if (status){
+			RT_TRACE(COMP_ERR, "Error TX URB for zero byte %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]), status);
+			return -1;
+			}
+#endif
+		}
+		dev->trans_start = jiffies;
+		atomic_inc(&priv->tx_pending[tcb_desc->queue_index]);
+		return 0;
+	}else{
+		RT_TRACE(COMP_ERR, "Error TX URB %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]),
+				status);
+		return -1;
+	}
+}
+
+short rtl8192_usb_initendpoints(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	
+	priv->rx_urb = (struct urb**) kmalloc (sizeof(struct urb*) * (MAX_RX_URB+1), GFP_KERNEL);
+
+#ifndef JACKSON_NEW_RX
+	for(i=0;i<(MAX_RX_URB+1);i++){
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+		priv->rx_urb[i] = usb_alloc_urb(0,GFP_KERNEL);
+#else
+		priv->rx_urb[i] = usb_alloc_urb(0);
+#endif
+
+		priv->rx_urb[i]->transfer_buffer = kmalloc(RX_URB_SIZE, GFP_KERNEL);
+			
+		priv->rx_urb[i]->transfer_buffer_length = RX_URB_SIZE;
+	}
+#endif
+
+#ifdef THOMAS_BEACON
+{	
+	int align = 0;
+	u32 oldaddr,newaddr;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+	priv->rx_urb[16] = usb_alloc_urb(0, GFP_KERNEL);		
+#else
+	priv->rx_urb[16] = usb_alloc_urb(0);		
+#endif
+	priv->oldaddr = kmalloc(16, GFP_KERNEL);
+	oldaddr = (u32)priv->oldaddr;
+	align = oldaddr&3;
+	if(align != 0 ){
+		newaddr = oldaddr + 4 - align;
+		priv->rx_urb[16]->transfer_buffer_length = 16-4+align;
+	}	
+	else{
+		newaddr = oldaddr;
+		priv->rx_urb[16]->transfer_buffer_length = 16;
+	}
+	priv->rx_urb[16]->transfer_buffer = (u32*)newaddr;
+}
+#endif
+       
+        memset(priv->rx_urb, 0, sizeof(struct urb*) * MAX_RX_URB);
+        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);
+
+        goto _middle;
+
+
+destroy:
+        if (priv->pp_rxskb) {
+                kfree(priv->pp_rxskb);
+        }
+        if (priv->rx_urb) {
+                kfree(priv->rx_urb);
+        }
+
+        priv->pp_rxskb = NULL;
+	priv->rx_urb = NULL;
+
+        DMESGE("Endpoint Alloc Failure");
+        return -ENOMEM;
+	
+
+_middle:
+
+	printk("End of initendpoints\n");
+	return 0;
+	
+}
+#ifdef THOMAS_BEACON
+void rtl8192_usb_deleteendpoints(struct net_device *dev)
+{	
+	int i;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	
+	if(priv->rx_urb){
+		for(i=0;i<(MAX_RX_URB+1);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;
+	}
+}
+#else
+void rtl8192_usb_deleteendpoints(struct net_device *dev)
+{
+	int i;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+#ifndef JACKSON_NEW_RX
+	
+	if(priv->rx_urb){
+		for(i=0;i<(MAX_RX_URB+1);i++){
+			usb_kill_urb(priv->rx_urb[i]);
+			kfree(priv->rx_urb[i]->transfer_buffer);
+			usb_free_urb(priv->rx_urb[i]);
+		}
+		kfree(priv->rx_urb);
+		priv->rx_urb = NULL;
+		
+	}
+#else
+	if(priv->rx_urb){
+                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	
+}
+#endif
+
+#if 0
+void rtl8192_set_rate(struct net_device *dev)
+{
+	int i;
+	u16 word;
+	int basic_rate,min_rr_rate,max_rr_rate;
+
+//	struct r8192_priv *priv = ieee80211_priv(dev);
+	
+	//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);
+	//DMESG("RR:%x BRSR: %x", read_nic_byte(dev,RESP_RATE), read_nic_word(dev,BRSR));
+}
+#endif
+extern void rtl8192_update_ratr_table(struct net_device* dev);
+void rtl8192_link_change(struct net_device *dev)
+{
+//	int i;
+	
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	struct ieee80211_device* ieee = priv->ieee80211;
+	//write_nic_word(dev, BCN_INTR_ITV, net->beacon_interval);
+	if (ieee->state == IEEE80211_LINKED)
+	{
+		rtl8192_net_update(dev);
+		rtl8192_update_ratr_table(dev);
+#if 1
+		//add this as in pure N mode, wep encryption will use software way, but there is no chance to set this as wep will not set group key in wext. WB.2008.07.08
+		if ((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type))
+		EnableHWSecurityConfig8192(dev);
+#endif
+	}
+	/*update timing params*/
+//	RT_TRACE(COMP_CH, "========>%s(), chan:%d\n", __FUNCTION__, priv->chan);
+//	rtl8192_set_chan(dev, priv->chan);
+	 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC)
+        {
+                u32 reg = 0;
+                reg = read_nic_dword(dev, RCR);
+                if (priv->ieee80211->state == IEEE80211_LINKED)
+                        priv->ReceiveConfig = reg |= RCR_CBSSID;
+                else
+                        priv->ReceiveConfig = reg &= ~RCR_CBSSID;
+                write_nic_dword(dev, RCR, reg);
+        }
+
+//	rtl8192_set_rxconf(dev);
+}
+
+static struct ieee80211_qos_parameters def_qos_parameters = {
+        {3,3,3,3},/* cw_min */
+        {7,7,7,7},/* cw_max */
+        {2,2,2,2},/* aifs */ 
+        {0,0,0,0},/* flags */ 
+        {0,0,0,0} /* tx_op_limit */
+};
+
+
+#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
+void rtl8192_update_beacon(struct work_struct * work)
+{
+        struct r8192_priv *priv = container_of(work, struct r8192_priv, update_beacon_wq.work);
+        struct net_device *dev = priv->ieee80211->dev;
+#else
+void rtl8192_update_beacon(struct net_device *dev)
+{
+        struct r8192_priv *priv = ieee80211_priv(dev);
+#endif
+ 	struct ieee80211_device* ieee = priv->ieee80211;
+	struct ieee80211_network* net = &ieee->current_network;
+
+	if (ieee->pHTInfo->bCurrentHTSupport)
+		HTUpdateSelfAndPeerSetting(ieee, net);
+	ieee->pHTInfo->bCurrentRT2RTLongSlotTime = net->bssht.bdRT2RTLongSlotTime;
+	rtl8192_update_cap(dev, net->capability);
+}
+/*
+* background support to run QoS activate functionality
+*/
+int WDCAPARA_ADD[] = {EDCAPARA_BE,EDCAPARA_BK,EDCAPARA_VI,EDCAPARA_VO};
+#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
+void rtl8192_qos_activate(struct work_struct * work)
+{
+        struct r8192_priv *priv = container_of(work, struct r8192_priv, qos_activate);
+        struct net_device *dev = priv->ieee80211->dev;
+#else
+void rtl8192_qos_activate(struct net_device *dev)
+{
+        struct r8192_priv *priv = ieee80211_priv(dev);
+#endif
+        struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
+        u8 mode = priv->ieee80211->current_network.mode;
+        //u32 size = sizeof(struct ieee80211_qos_parameters);
+	u8  u1bAIFS;
+	u32 u4bAcParam;
+        int i;
+
+        if (priv == NULL)
+                return;
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16))
+	down(&priv->mutex);
+#else
+       mutex_lock(&priv->mutex);
+#endif
+        if(priv->ieee80211->state != IEEE80211_LINKED)
+		goto success;
+	RT_TRACE(COMP_QOS,"qos active process with associate response received\n");
+	/* It better set slot time at first */
+	/* For we just support b/g mode at present, let the slot time at 9/20 selection */	
+	/* update the ac parameter to related registers */
+	for(i = 0; i <  QOS_QUEUE_NUM; i++) {
+		//Mode G/A: slotTimeTimer = 9; Mode B: 20
+		u1bAIFS = qos_parameters->aifs[i] * ((mode&(IEEE_G|IEEE_N_24G)) ?9:20) + aSifsTime; 
+		u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[i]))<< AC_PARAM_TXOP_LIMIT_OFFSET)|
+				(((u32)(qos_parameters->cw_max[i]))<< AC_PARAM_ECW_MAX_OFFSET)|
+				(((u32)(qos_parameters->cw_min[i]))<< AC_PARAM_ECW_MIN_OFFSET)|
+				((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
+
+		write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);
+		//write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332);
+	}
+
+success:
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16))
+	up(&priv->mutex);
+#else
+       mutex_unlock(&priv->mutex);
+#endif
+}
+
+static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv,
+		int active_network,
+		struct ieee80211_network *network)
+{
+	int ret = 0;
+	u32 size = sizeof(struct ieee80211_qos_parameters);
+
+	if(priv->ieee80211->state !=IEEE80211_LINKED)
+                return ret;
+
+        if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
+                return ret;
+
+	if (network->flags & NETWORK_HAS_QOS_MASK) {
+		if (active_network &&
+				(network->flags & NETWORK_HAS_QOS_PARAMETERS))
+			network->qos_data.active = network->qos_data.supported;
+
+		if ((network->qos_data.active == 1) && (active_network == 1) &&
+				(network->flags & NETWORK_HAS_QOS_PARAMETERS) &&
+				(network->qos_data.old_param_count !=
+				 network->qos_data.param_count)) {
+			network->qos_data.old_param_count =
+				network->qos_data.param_count;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)  
+			queue_work(priv->priv_wq, &priv->qos_activate);
+#else
+			schedule_task(&priv->qos_activate);
+#endif
+			RT_TRACE (COMP_QOS, "QoS parameters change call "
+					"qos_activate\n");
+		}
+	} else {
+		memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
+		       &def_qos_parameters, size);
+
+		if ((network->qos_data.active == 1) && (active_network == 1)) {
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)  
+			queue_work(priv->priv_wq, &priv->qos_activate);
+#else
+			schedule_task(&priv->qos_activate);
+#endif
+			RT_TRACE(COMP_QOS, "QoS was disabled call qos_activate \n");
+		}
+		network->qos_data.active = 0;
+		network->qos_data.supported = 0;
+	}
+
+	return 0;
+}
+
+/* handle manage frame frame beacon and probe response */
+static int rtl8192_handle_beacon(struct net_device * dev,
+                              struct ieee80211_beacon * beacon,
+                              struct ieee80211_network * network)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	rtl8192_qos_handle_probe_response(priv,1,network);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+	queue_delayed_work(priv->priv_wq, &priv->update_beacon_wq, 0);
+#else
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+	schedule_task(&priv->update_beacon_wq);
+#else
+	queue_work(priv->priv_wq, &priv->update_beacon_wq);
+#endif
+
+#endif
+	return 0;
+
+}
+
+/*
+* handling the beaconing responses. if we get different QoS setting
+* off the network from the associated setting, adjust the QoS
+* setting
+*/
+static int rtl8192_qos_association_resp(struct r8192_priv *priv,
+                                    struct ieee80211_network *network)
+{
+        int ret = 0;
+        unsigned long flags;
+        u32 size = sizeof(struct ieee80211_qos_parameters);
+        int set_qos_param = 0;
+
+        if ((priv == NULL) || (network == NULL))
+                return ret;
+
+	if(priv->ieee80211->state !=IEEE80211_LINKED)
+                return ret;
+
+        if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
+                return ret;
+
+        spin_lock_irqsave(&priv->ieee80211->lock, flags);
+	if(network->flags & NETWORK_HAS_QOS_PARAMETERS) {
+		memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
+			 &network->qos_data.parameters,\
+			sizeof(struct ieee80211_qos_parameters));
+		priv->ieee80211->current_network.qos_data.active = 1;
+#if 0
+		if((priv->ieee80211->current_network.qos_data.param_count != \
+					network->qos_data.param_count))
+#endif
+		 {
+                        set_qos_param = 1;
+			/* update qos parameter for current network */
+			priv->ieee80211->current_network.qos_data.old_param_count = \
+				 priv->ieee80211->current_network.qos_data.param_count;
+			priv->ieee80211->current_network.qos_data.param_count = \
+			     	 network->qos_data.param_count;
+		}
+        } else {
+		memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
+		       &def_qos_parameters, size);
+		priv->ieee80211->current_network.qos_data.active = 0;
+		priv->ieee80211->current_network.qos_data.supported = 0;
+                set_qos_param = 1;
+        }
+
+        spin_unlock_irqrestore(&priv->ieee80211->lock, flags);
+
+	RT_TRACE(COMP_QOS, "%s: network->flags = %d,%d\n",__FUNCTION__,network->flags ,priv->ieee80211->current_network.qos_data.active);
+	if (set_qos_param == 1)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)  
+		queue_work(priv->priv_wq, &priv->qos_activate);
+#else
+		schedule_task(&priv->qos_activate);
+#endif
+
+
+        return ret;
+}
+
+
+static int rtl8192_handle_assoc_response(struct net_device *dev,
+                                     struct ieee80211_assoc_response_frame *resp,
+                                     struct ieee80211_network *network)
+{
+        struct r8192_priv *priv = ieee80211_priv(dev);
+        rtl8192_qos_association_resp(priv, network);
+        return 0;
+}
+
+
+void rtl8192_update_ratr_table(struct net_device* dev)
+	//	POCTET_STRING	posLegacyRate,
+	//	u8*			pMcsRate)
+	//	PRT_WLAN_STA	pEntry)
+{
+	struct r8192_priv* priv = ieee80211_priv(dev);
+	struct ieee80211_device* ieee = priv->ieee80211;
+	u8* pMcsRate = ieee->dot11HTOperationalRateSet;
+	//struct ieee80211_network *net = &ieee->current_network;
+	u32 ratr_value = 0;
+	u8 rate_index = 0;
+	rtl8192_config_rate(dev, (u16*)(&ratr_value));
+	ratr_value |= (*(u16*)(pMcsRate)) << 12;
+//	switch (net->mode)
+	switch (ieee->mode)
+	{
+		case IEEE_A:
+			ratr_value &= 0x00000FF0;
+			break;
+		case IEEE_B:
+			ratr_value &= 0x0000000F;
+			break;
+		case IEEE_G:
+			ratr_value &= 0x00000FF7;
+			break;
+		case IEEE_N_24G:
+		case IEEE_N_5G:
+			if (ieee->pHTInfo->PeerMimoPs == 0) //MIMO_PS_STATIC
+				ratr_value &= 0x0007F007;
+			else{
+				if (priv->rf_type == RF_1T2R)
+					ratr_value &= 0x000FF007;
+				else
+					ratr_value &= 0x0F81F007;
+			}
+			break;
+		default:
+			break; 
+	}
+	ratr_value &= 0x0FFFFFFF;
+	if(ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI40MHz){
+		ratr_value |= 0x80000000;
+	}else if(!ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI20MHz){
+		ratr_value |= 0x80000000;
+	}	
+	write_nic_dword(dev, RATR0+rate_index*4, ratr_value);
+	write_nic_byte(dev, UFWP, 1);
+}
+
+static u8 ccmp_ie[4] = {0x00,0x50,0xf2,0x04};
+static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
+bool GetNmodeSupportBySecCfg8192(struct net_device*dev)
+{
+#if 1
+	struct r8192_priv* priv = ieee80211_priv(dev);
+	struct ieee80211_device* ieee = priv->ieee80211;
+	struct ieee80211_network * network = &ieee->current_network;
+        int wpa_ie_len= ieee->wpa_ie_len;
+        struct ieee80211_crypt_data* crypt;
+        int encrypt;
+                             
+        crypt = ieee->crypt[ieee->tx_keyidx];
+	//we use connecting AP's capability instead of only security config on our driver to distinguish whether it should use N mode or G mode
+        encrypt = (network->capability & WLAN_CAPABILITY_PRIVACY) || (ieee->host_encrypt && crypt && crypt->ops && (0 == strcmp(crypt->ops->name,"WEP")));
+
+	/* simply judge  */
+	if(encrypt && (wpa_ie_len == 0)) {
+		/* wep encryption, no N mode setting */
+		return false;
+//	} else if((wpa_ie_len != 0)&&(memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) {
+	} else if((wpa_ie_len != 0)) {
+		/* parse pairwise key type */
+		//if((pairwisekey = WEP40)||(pairwisekey = WEP104)||(pairwisekey = TKIP)) 
+		if (((ieee->wpa_ie[0] == 0xdd) && (!memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) || ((ieee->wpa_ie[0] == 0x30) && (!memcmp(&ieee->wpa_ie[10],ccmp_rsn_ie, 4))))
+			return true;
+		else
+			return false;
+	} else {
+		return true;
+	}
+	
+#if 0
+        //In here we discuss with SD4 David. He think we still can send TKIP in broadcast group key in MCS rate.
+        //We can't force in G mode if Pairwie key is AES and group key is TKIP
+        if((pSecInfo->GroupEncAlgorithm == WEP104_Encryption) || (pSecInfo->GroupEncAlgorithm == WEP40_Encryption)  ||
+           (pSecInfo->PairwiseEncAlgorithm == WEP104_Encryption) ||
+           (pSecInfo->PairwiseEncAlgorithm == WEP40_Encryption) || (pSecInfo->PairwiseEncAlgorithm == TKIP_Encryption))
+        {
+                return  false;
+        }
+        else
+                return true;
+#endif
+	return true;
+#endif
+}
+
+bool GetHalfNmodeSupportByAPs819xUsb(struct net_device* dev)
+{
+	bool			Reval;
+	struct r8192_priv* priv = ieee80211_priv(dev);
+	struct ieee80211_device* ieee = priv->ieee80211;
+	
+	if(ieee->bHalfWirelessN24GMode == true)
+		Reval = true;
+	else
+		Reval =  false;
+
+	return Reval;
+}
+
+void rtl8192_refresh_supportrate(struct r8192_priv* priv)
+{
+	struct ieee80211_device* ieee = priv->ieee80211;
+	//we donot consider set support rate for ABG mode, only HT MCS rate is set here.
+	if (ieee->mode == WIRELESS_MODE_N_24G || ieee->mode == WIRELESS_MODE_N_5G)
+	{
+		memcpy(ieee->Regdot11HTOperationalRateSet, ieee->RegHTSuppRateSet, 16);
+		//RT_DEBUG_DATA(COMP_INIT, ieee->RegHTSuppRateSet, 16);
+		//RT_DEBUG_DATA(COMP_INIT, ieee->Regdot11HTOperationalRateSet, 16);
+	}
+	else
+		memset(ieee->Regdot11HTOperationalRateSet, 0, 16);
+	return;
+}
+
+u8 rtl8192_getSupportedWireleeMode(struct net_device*dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u8 ret = 0;
+	switch(priv->rf_chip)
+	{
+		case RF_8225:
+		case RF_8256:
+		case RF_PSEUDO_11N:
+			ret = (WIRELESS_MODE_N_24G|WIRELESS_MODE_G|WIRELESS_MODE_B);
+			break;
+		case RF_8258:
+			ret = (WIRELESS_MODE_A|WIRELESS_MODE_N_5G);
+			break;
+		default:
+			ret = WIRELESS_MODE_B;
+			break;
+	}
+	return ret;
+}
+void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u8 bSupportMode = rtl8192_getSupportedWireleeMode(dev);
+
+#if 1  
+	if ((wireless_mode == WIRELESS_MODE_AUTO) || ((wireless_mode&bSupportMode)==0))
+	{
+		if(bSupportMode & WIRELESS_MODE_N_24G)
+		{
+			wireless_mode = WIRELESS_MODE_N_24G;
+		}
+		else if(bSupportMode & WIRELESS_MODE_N_5G)
+		{
+			wireless_mode = WIRELESS_MODE_N_5G;
+		}
+		else if((bSupportMode & WIRELESS_MODE_A))
+		{
+			wireless_mode = WIRELESS_MODE_A;
+		}
+		else if((bSupportMode & WIRELESS_MODE_G))
+		{
+			wireless_mode = WIRELESS_MODE_G;
+		}
+		else if((bSupportMode & WIRELESS_MODE_B))
+		{
+			wireless_mode = WIRELESS_MODE_B;
+		}
+		else{
+			RT_TRACE(COMP_ERR, "%s(), No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n", __FUNCTION__,bSupportMode);
+			wireless_mode = WIRELESS_MODE_B;
+		}
+	}
+#ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we shoud wait for FPGA
+	ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting );
+#endif
+	priv->ieee80211->mode = wireless_mode;
+	
+	if ((wireless_mode == WIRELESS_MODE_N_24G) ||  (wireless_mode == WIRELESS_MODE_N_5G))
+		priv->ieee80211->pHTInfo->bEnableHT = 1;	
+	else
+		priv->ieee80211->pHTInfo->bEnableHT = 0;
+	RT_TRACE(COMP_INIT, "Current Wireless Mode is %x\n", wireless_mode);
+	rtl8192_refresh_supportrate(priv);
+#endif	
+
+}
+//init priv variables here. only non_zero value should be initialized here.
+static void rtl8192_init_priv_variable(struct net_device* dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u8 i;
+	priv->card_8192 = NIC_8192U;
+	priv->chan = 1; //set to channel 1
+	priv->ieee80211->mode = WIRELESS_MODE_AUTO; //SET AUTO 
+	priv->ieee80211->iw_mode = IW_MODE_INFRA;
+	priv->ieee80211->ieee_up=0;
+	priv->retry_rts = DEFAULT_RETRY_RTS;
+	priv->retry_data = DEFAULT_RETRY_DATA;
+	priv->ieee80211->rts = DEFAULT_RTS_THRESHOLD;
+	priv->ieee80211->rate = 110; //11 mbps
+	priv->ieee80211->short_slot = 1;
+	priv->promisc = (dev->flags & IFF_PROMISC) ? 1:0;
+	priv->CckPwEnl = 6;
+	//for silent reset
+	priv->IrpPendingCount = 1;
+	priv->ResetProgress = RESET_TYPE_NORESET;
+	priv->bForcedSilentReset = 0;
+	priv->bDisableNormalResetCheck = false;
+	priv->force_reset = false;
+
+	priv->ieee80211->FwRWRF = 0; 	//we don't use FW read/write RF until stable firmware is available.
+	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 | 
+		IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE |
+		IEEE_SOFTMAC_BEACONS;//added by amy 080604 //|  //IEEE_SOFTMAC_SINGLE_QUEUE;
+	
+	priv->ieee80211->active_scan = 1;
+	priv->ieee80211->modulation = IEEE80211_CCK_MODULATION | IEEE80211_OFDM_MODULATION;
+	priv->ieee80211->host_encrypt = 1;
+	priv->ieee80211->host_decrypt = 1;
+	priv->ieee80211->start_send_beacons = NULL;//rtl819xusb_beacon_tx;//-by amy 080604
+	priv->ieee80211->stop_send_beacons = NULL;//rtl8192_beacon_stop;//-by amy 080604
+	priv->ieee80211->softmac_hard_start_xmit = rtl8192_hard_start_xmit;
+	priv->ieee80211->set_chan = rtl8192_set_chan;
+	priv->ieee80211->link_change = rtl8192_link_change;
+	priv->ieee80211->softmac_data_hard_start_xmit = rtl8192_hard_data_xmit;
+	priv->ieee80211->data_hard_stop = rtl8192_data_hard_stop;
+	priv->ieee80211->data_hard_resume = rtl8192_data_hard_resume;
+	priv->ieee80211->init_wmmparam_flag = 0;
+	priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
+	priv->ieee80211->check_nic_enough_desc = check_nic_enough_desc;	
+	priv->ieee80211->tx_headroom = TX_PACKET_SHIFT_BYTES;
+	priv->ieee80211->qos_support = 1;
+
+	//added by WB
+//	priv->ieee80211->SwChnlByTimerHandler = rtl8192_phy_SwChnl;
+	priv->ieee80211->SetBWModeHandler = rtl8192_SetBWMode;
+	priv->ieee80211->handle_assoc_response = rtl8192_handle_assoc_response;
+	priv->ieee80211->handle_beacon = rtl8192_handle_beacon;
+	//added by david
+	priv->ieee80211->GetNmodeSupportBySecCfg = GetNmodeSupportBySecCfg8192;
+	priv->ieee80211->GetHalfNmodeSupportByAPsHandler = GetHalfNmodeSupportByAPs819xUsb;
+	priv->ieee80211->SetWirelessMode = rtl8192_SetWirelessMode;
+	//added by amy
+	priv->ieee80211->InitialGainHandler = InitialGain819xUsb;
+	priv->card_type = USB;
+#ifdef TO_DO_LIST
+	if(Adapter->bInHctTest)
+  	{
+		pHalData->ShortRetryLimit = 7;
+		pHalData->LongRetryLimit = 7;
+  	}
+#endif
+	{
+		priv->ShortRetryLimit = 0x30;
+		priv->LongRetryLimit = 0x30;
+	}
+	priv->EarlyRxThreshold = 7;
+	priv->enable_gpio0 = 0;
+	priv->TransmitConfig = 
+	//	TCR_DurProcMode |	//for RTL8185B, duration setting by HW
+	//?	TCR_DISReqQsize |
+                (TCR_MXDMA_2048<<TCR_MXDMA_OFFSET)|  // Max DMA Burst Size per Tx DMA Burst, 7: reservied.
+		(priv->ShortRetryLimit<<TCR_SRL_OFFSET)|	// Short retry limit
+		(priv->LongRetryLimit<<TCR_LRL_OFFSET) |	// Long retry limit
+		(false ? TCR_SAT: 0);	// FALSE: HW provies PLCP length and LENGEXT, TURE: SW proiveds them
+#ifdef TO_DO_LIST
+	if(Adapter->bInHctTest)
+		pHalData->ReceiveConfig	=	pHalData->CSMethod |
+						RCR_AMF | RCR_ADF |	//RCR_AAP | 	//accept management/data
+						//guangan200710
+						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
+						((u32)7<<RCR_MXDMA_OFFSET) | // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
+						(pHalData->EarlyRxThreshold<<RCR_FIFO_OFFSET) | // Rx FIFO Threshold, 7: No Rx threshold.
+						(pHalData->EarlyRxThreshold == 7 ? RCR_OnlyErlPkt:0);
+	else
+			
+#endif
+	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
+		((u32)7<<RCR_MXDMA_OFFSET)| // 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->pFirmware = (rt_firmware*)kmalloc(sizeof(rt_firmware), GFP_KERNEL);
+	if (priv->pFirmware)
+	memset(priv->pFirmware, 0, sizeof(rt_firmware));
+
+	/* rx related queue */
+        skb_queue_head_init(&priv->rx_queue);
+	skb_queue_head_init(&priv->skb_queue);
+
+	/* Tx related queue */
+	for(i = 0; i < MAX_QUEUE_SIZE; i++) {
+		skb_queue_head_init(&priv->ieee80211->skb_waitQ [i]);
+	}
+	for(i = 0; i < MAX_QUEUE_SIZE; i++) {
+		skb_queue_head_init(&priv->ieee80211->skb_aggQ [i]);
+	}
+	for(i = 0; i < MAX_QUEUE_SIZE; i++) {
+		skb_queue_head_init(&priv->ieee80211->skb_drv_aggQ [i]);
+	}
+	priv->rf_set_chan = rtl8192_phy_SwChnl;	
+}	
+
+//init lock here
+static void rtl8192_init_priv_lock(struct r8192_priv* priv)
+{
+	spin_lock_init(&priv->tx_lock);
+	spin_lock_init(&priv->irq_lock);//added by thomas
+	//spin_lock_init(&priv->rf_lock);
+	sema_init(&priv->wx_sem,1);
+	sema_init(&priv->rf_sem,1);
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16))
+	sema_init(&priv->mutex, 1);
+#else
+	mutex_init(&priv->mutex);
+#endif
+}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+extern  void    rtl819x_watchdog_wqcallback(struct work_struct *work);
+#else
+extern  void    rtl819x_watchdog_wqcallback(struct net_device *dev);
+#endif
+
+void rtl8192_irq_rx_tasklet(struct r8192_priv *priv);
+//init tasklet and wait_queue here. only 2.6 above kernel is considered
+#define DRV_NAME "wlan0"
+static void rtl8192_init_priv_task(struct net_device* dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);	
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)	
+#ifdef PF_SYNCTHREAD
+	priv->priv_wq = create_workqueue(DRV_NAME,0);
+#else	
+	priv->priv_wq = create_workqueue(DRV_NAME);
+#endif
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+	INIT_WORK(&priv->reset_wq, rtl8192_restart);
+
+	//INIT_DELAYED_WORK(&priv->watch_dog_wq, hal_dm_watchdog);
+	INIT_DELAYED_WORK(&priv->watch_dog_wq, rtl819x_watchdog_wqcallback);
+	INIT_DELAYED_WORK(&priv->txpower_tracking_wq,  dm_txpower_trackingcallback);
+//	INIT_DELAYED_WORK(&priv->gpio_change_rf_wq,  dm_gpio_change_rf_callback);
+	INIT_DELAYED_WORK(&priv->rfpath_check_wq,  dm_rf_pathcheck_workitemcallback);
+	INIT_DELAYED_WORK(&priv->update_beacon_wq, rtl8192_update_beacon);
+	INIT_DELAYED_WORK(&priv->initialgain_operate_wq, InitialGainOperateWorkItemCallBack);
+	//INIT_WORK(&priv->SwChnlWorkItem,  rtl8192_SwChnl_WorkItem);
+	//INIT_WORK(&priv->SetBWModeWorkItem,  rtl8192_SetBWModeWorkItem);
+	INIT_WORK(&priv->qos_activate, rtl8192_qos_activate);
+#else
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+	tq_init(&priv->reset_wq, (void*)rtl8192_restart, dev);
+	tq_init(&priv->watch_dog_wq, (void*)rtl819x_watchdog_wqcallback, dev);
+	tq_init(&priv->txpower_tracking_wq, (void*)dm_txpower_trackingcallback, dev);
+	tq_init(&priv->rfpath_check_wq, (void*)dm_rf_pathcheck_workitemcallback, dev);
+	tq_init(&priv->update_beacon_wq, (void*)rtl8192_update_beacon, dev);
+	//tq_init(&priv->SwChnlWorkItem, (void*) rtl8192_SwChnl_WorkItem, dev);
+	//tq_init(&priv->SetBWModeWorkItem, (void*)rtl8192_SetBWModeWorkItem, dev);
+	tq_init(&priv->qos_activate, (void *)rtl8192_qos_activate, dev);
+#else
+	INIT_WORK(&priv->reset_wq,(void(*)(void*)) rtl8192_restart,dev);
+	//INIT_WORK(&priv->watch_dog_wq, (void(*)(void*)) hal_dm_watchdog,dev);
+	INIT_WORK(&priv->watch_dog_wq, (void(*)(void*)) rtl819x_watchdog_wqcallback,dev);
+	INIT_WORK(&priv->txpower_tracking_wq, (void(*)(void*)) dm_txpower_trackingcallback,dev);
+//	INIT_WORK(&priv->gpio_change_rf_wq, (void(*)(void*)) dm_gpio_change_rf_callback,dev);
+	INIT_WORK(&priv->rfpath_check_wq, (void(*)(void*)) dm_rf_pathcheck_workitemcallback,dev);
+	INIT_WORK(&priv->update_beacon_wq, (void(*)(void*))rtl8192_update_beacon,dev);
+	INIT_WORK(&priv->initialgain_operate_wq, (void(*)(void*))InitialGainOperateWorkItemCallBack,dev);
+	//INIT_WORK(&priv->SwChnlWorkItem, (void(*)(void*)) rtl8192_SwChnl_WorkItem, dev);
+	//INIT_WORK(&priv->SetBWModeWorkItem, (void(*)(void*)) rtl8192_SetBWModeWorkItem, dev);
+	INIT_WORK(&priv->qos_activate, (void(*)(void *))rtl8192_qos_activate, dev);
+#endif
+#endif
+
+	tasklet_init(&priv->irq_rx_tasklet,
+	     (void(*)(unsigned long))rtl8192_irq_rx_tasklet,
+	     (unsigned long)priv);
+}
+
+static void rtl8192_get_eeprom_size(struct net_device* dev)
+{
+	u16 curCR = 0;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	RT_TRACE(COMP_EPROM, "===========>%s()\n", __FUNCTION__);	
+	curCR = read_nic_word_E(dev,EPROM_CMD);
+	RT_TRACE(COMP_EPROM, "read from Reg EPROM_CMD(%x):%x\n", EPROM_CMD, curCR);
+	//whether need I consider BIT5?	
+	priv->epromtype = (curCR & Cmd9346CR_9356SEL) ? EPROM_93c56 : EPROM_93c46;
+	RT_TRACE(COMP_EPROM, "<===========%s(), epromtype:%d\n", __FUNCTION__, priv->epromtype);	
+}
+
+//used to swap endian. as ntohl & htonl are not neccessary to swap endian, so use this instead.
+static inline u16 endian_swap(u16* data)
+{
+	u16 tmp = *data;
+	*data = (tmp >> 8) | (tmp << 8);
+	return *data;	
+}
+static void rtl8192_read_eeprom_info(struct net_device* dev)
+{
+	u16 wEPROM_ID = 0;
+	u8 bMac_Tmp_Addr[6] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x02};
+	u8 bLoad_From_EEPOM = false;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u16 tmpValue = 0;
+	RT_TRACE(COMP_EPROM, "===========>%s()\n", __FUNCTION__);	
+	wEPROM_ID = eprom_read(dev, 0); //first read EEPROM ID out;
+	RT_TRACE(COMP_EPROM, "EEPROM ID is 0x%x\n", wEPROM_ID);
+	
+	if (wEPROM_ID != RTL8190_EEPROM_ID)
+	{
+		RT_TRACE(COMP_ERR, "EEPROM ID is invalid(is 0x%x(should be 0x%x)\n", wEPROM_ID, RTL8190_EEPROM_ID);
+	}
+	else
+		bLoad_From_EEPOM = true;
+
+	if (bLoad_From_EEPOM)
+	{
+		tmpValue = eprom_read(dev, (EEPROM_VID>>1));
+		priv->eeprom_vid = endian_swap(&tmpValue);
+		priv->eeprom_pid = eprom_read(dev, (EEPROM_PID>>1));
+		tmpValue = eprom_read(dev, (EEPROM_ChannelPlan>>1));
+		priv->eeprom_ChannelPlan =((tmpValue&0xff00)>>8);
+		priv->btxpowerdata_readfromEEPORM = true;
+		priv->eeprom_CustomerID = eprom_read(dev, (EEPROM_Customer_ID>>1)) >>8;
+	}
+	else
+	{
+		priv->eeprom_vid = 0;
+		priv->eeprom_pid = 0;
+		priv->card_8192_version = VERSION_819xU_B;
+		priv->eeprom_ChannelPlan = 0;
+		priv->eeprom_CustomerID = 0;
+	}
+	RT_TRACE(COMP_EPROM, "vid:0x%4x, pid:0x%4x, CustomID:0x%2x, ChanPlan:0x%x\n", priv->eeprom_vid, priv->eeprom_pid, priv->eeprom_CustomerID, priv->eeprom_ChannelPlan);
+	//set channelplan from eeprom
+	priv->ChannelPlan = priv->eeprom_ChannelPlan;
+	if (bLoad_From_EEPOM)
+	{
+		int i;
+		for (i=0; i<6; i+=2)
+		{
+			u16 tmp = 0;
+			tmp = eprom_read(dev, (u16)((EEPROM_NODE_ADDRESS_BYTE_0 + i)>>1));
+			*(u16*)(&dev->dev_addr[i]) = tmp;
+		}
+	}	
+	else
+	{
+		memcpy(dev->dev_addr, bMac_Tmp_Addr, 6);
+		//should I set IDR0 here?
+	}
+	RT_TRACE(COMP_EPROM, "MAC addr:"MAC_FMT"\n", MAC_ARG(dev->dev_addr));
+	priv->rf_type = RTL819X_DEFAULT_RF_TYPE; //default 1T2R
+	priv->rf_chip = RF_8256;
+	
+	if (priv->card_8192_version == (u8)VERSION_819xU_A)
+	{
+		//read Tx power gain offset of legacy OFDM to HT rate
+		if (bLoad_From_EEPOM)
+			priv->EEPROMTxPowerDiff = (eprom_read(dev, (EEPROM_TxPowerDiff>>1))&0xff00) >> 8;
+		else
+			priv->EEPROMTxPowerDiff = EEPROM_Default_TxPower;
+		RT_TRACE(COMP_EPROM, "TxPowerDiff:%d\n", priv->EEPROMTxPowerDiff);
+		//read ThermalMeter from EEPROM
+		if (bLoad_From_EEPOM)
+			priv->EEPROMThermalMeter = (u8)(eprom_read(dev, (EEPROM_ThermalMeter>>1))&0x00ff);
+		else
+			priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
+		RT_TRACE(COMP_EPROM, "ThermalMeter:%d\n", priv->EEPROMThermalMeter);
+		//vivi, for tx power track
+		priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
+		//read antenna tx power offset of B/C/D to A from EEPROM
+		if (bLoad_From_EEPOM)
+			priv->EEPROMPwDiff = (eprom_read(dev, (EEPROM_PwDiff>>1))&0x0f00)>>8;
+		else
+			priv->EEPROMPwDiff = EEPROM_Default_PwDiff;
+		RT_TRACE(COMP_EPROM, "TxPwDiff:%d\n", priv->EEPROMPwDiff);
+		// Read CrystalCap from EEPROM
+		if (bLoad_From_EEPOM)
+			priv->EEPROMCrystalCap = (eprom_read(dev, (EEPROM_CrystalCap>>1))&0x0f);
+		else
+			priv->EEPROMCrystalCap = EEPROM_Default_CrystalCap;
+		RT_TRACE(COMP_EPROM, "CrystalCap = %d\n", priv->EEPROMCrystalCap);
+		//get per-channel Tx power level
+		if (bLoad_From_EEPOM)
+			priv->EEPROM_Def_Ver = (eprom_read(dev, (EEPROM_TxPwIndex_Ver>>1))&0xff00)>>8;
+		else
+			priv->EEPROM_Def_Ver = 1;
+		RT_TRACE(COMP_EPROM, "EEPROM_DEF_VER:%d\n", priv->EEPROM_Def_Ver);
+		if (priv->EEPROM_Def_Ver == 0) //old eeprom definition
+		{
+			int i;
+			if (bLoad_From_EEPOM)
+				priv->EEPROMTxPowerLevelCCK = (eprom_read(dev, (EEPROM_TxPwIndex_CCK>>1))&0xff) >> 8; 
+			else
+				priv->EEPROMTxPowerLevelCCK = 0x10;
+			RT_TRACE(COMP_EPROM, "CCK Tx Power Levl: 0x%02x\n", priv->EEPROMTxPowerLevelCCK);
+			for (i=0; i<3; i++)
+			{
+				if (bLoad_From_EEPOM)
+				{
+					tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G+i)>>1);
+					if (((EEPROM_TxPwIndex_OFDM_24G+i) % 2) == 0)
+						tmpValue = tmpValue & 0x00ff;
+					else
+						tmpValue = (tmpValue & 0xff00) >> 8;
+				}
+				else
+					tmpValue = 0x10;
+				priv->EEPROMTxPowerLevelOFDM24G[i] = (u8) tmpValue;
+				RT_TRACE(COMP_EPROM, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelCCK);
+			}
+		}//end if EEPROM_DEF_VER == 0
+		else if (priv->EEPROM_Def_Ver == 1)
+		{
+			if (bLoad_From_EEPOM)
+			{
+				tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_CCK_V1>>1));
+				tmpValue = (tmpValue & 0xff00) >> 8;
+			}
+			else
+				tmpValue = 0x10;
+			priv->EEPROMTxPowerLevelCCK_V1[0] = (u8)tmpValue;
+
+			if (bLoad_From_EEPOM)
+				tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_CCK_V1 + 2)>>1);
+			else
+				tmpValue = 0x1010;
+			*((u16*)(&priv->EEPROMTxPowerLevelCCK_V1[1])) = tmpValue;
+			if (bLoad_From_EEPOM)
+				tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G_V1>>1));
+			else
+				tmpValue = 0x1010;
+			*((u16*)(&priv->EEPROMTxPowerLevelOFDM24G[0])) = tmpValue;
+			if (bLoad_From_EEPOM)
+				tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G_V1+2)>>1);
+			else
+				tmpValue = 0x10;
+			priv->EEPROMTxPowerLevelOFDM24G[2] = (u8)tmpValue;
+		}//endif EEPROM_Def_Ver == 1
+
+		//update HAL variables
+		//
+		{
+			int i;
+			for (i=0; i<14; i++)
+			{
+				if (i<=3)
+					priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[0];
+				else if (i>=4 && i<=9)
+					priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[1];
+				else 
+					priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[2];
+			}
+			
+			for (i=0; i<14; i++)
+			{
+				if (priv->EEPROM_Def_Ver == 0)
+				{
+					if (i<=3)
+						priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelOFDM24G[0] + (priv->EEPROMTxPowerLevelCCK - priv->EEPROMTxPowerLevelOFDM24G[1]);
+					else if (i>=4 && i<=9)
+						priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK;
+					else
+						priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelOFDM24G[2] + (priv->EEPROMTxPowerLevelCCK - priv->EEPROMTxPowerLevelOFDM24G[1]);
+				}
+				else if (priv->EEPROM_Def_Ver == 1)
+				{
+					if (i<=3)
+						priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[0];
+					else if (i>=4 && i<=9)
+						priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[1];
+					else 
+						priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[2];
+				}
+			}
+		}//end update HAL variables
+		priv->TxPowerDiff = priv->EEPROMPwDiff;
+// Antenna B gain offset to antenna A, bit0~3
+		priv->AntennaTxPwDiff[0] = (priv->EEPROMTxPowerDiff & 0xf);
+		// Antenna C gain offset to antenna A, bit4~7
+		priv->AntennaTxPwDiff[1] = ((priv->EEPROMTxPowerDiff & 0xf0)>>4);
+		// CrystalCap, bit12~15
+		priv->CrystalCap = priv->EEPROMCrystalCap;
+		// ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
+		// 92U does not enable TX power tracking.
+		priv->ThermalMeter[0] = priv->EEPROMThermalMeter;
+	}//end if VersionID == VERSION_819xU_A
+
+//added by vivi, for dlink led, 20080416
+	switch(priv->eeprom_CustomerID)
+	{
+		case EEPROM_CID_RUNTOP:
+			priv->CustomerID = RT_CID_819x_RUNTOP;
+			break;
+			
+		case EEPROM_CID_DLINK:
+			priv->CustomerID = RT_CID_DLINK;
+			break;
+			
+		default:
+			priv->CustomerID = RT_CID_DEFAULT;
+			break;
+			
+	}
+
+	switch(priv->CustomerID)
+	{
+		case RT_CID_819x_RUNTOP:
+			priv->LedStrategy = SW_LED_MODE2;
+			break;
+			
+ 		case RT_CID_DLINK:
+			priv->LedStrategy = SW_LED_MODE4;
+			break;
+
+		default:
+			priv->LedStrategy = SW_LED_MODE0;
+			break;
+			
+	}
+
+
+	if(priv->rf_type == RF_1T2R)
+	{		
+		RT_TRACE(COMP_EPROM, "\n1T2R config\n");
+	}
+	else
+	{
+		RT_TRACE(COMP_EPROM, "\n2T4R config\n");
+	}
+	
+	// 2008/01/16 MH We can only know RF type in the function. So we have to init
+	// DIG RATR table again.
+	init_rate_adaptive(dev);
+	//we need init DIG RATR table here again.
+
+	RT_TRACE(COMP_EPROM, "<===========%s()\n", __FUNCTION__);
+	return;	
+}
+
+short rtl8192_get_channel_map(struct net_device * dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+#ifdef ENABLE_DOT11D
+	if(priv->ChannelPlan > COUNTRY_CODE_GLOBAL_DOMAIN){
+		printk("rtl8180_init:Error channel plan! Set to default.\n");
+		priv->ChannelPlan= 0;
+	}
+	RT_TRACE(COMP_INIT, "Channel plan is %d\n",priv->ChannelPlan);
+		
+	rtl819x_set_channel_map(priv->ChannelPlan, priv);
+#else
+	int ch,i;
+	//Set Default Channel Plan
+	if(!channels){
+		DMESG("No channels, aborting");
+		return -1;
+	}
+	ch=channels;
+	priv->ChannelPlan= 0;//hikaru
+	 // 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
+	return 0;
+}
+
+short rtl8192_init(struct net_device *dev)
+{
+		
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	memset(&(priv->stats),0,sizeof(struct Stats));
+	memset(priv->txqueue_to_outpipemap,0,9);
+#ifdef PIPE12
+	{
+		int i=0;
+		u8 queuetopipe[]={3,2,1,0,4,8,7,6,5}; 
+		memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
+/*		for(i=0;i<9;i++)
+			printk("%d ",priv->txqueue_to_outpipemap[i]);
+		printk("\n");*/
+	}
+#else
+	{	
+		u8 queuetopipe[]={3,2,1,0,4,4,0,4,4};
+		memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
+/*		for(i=0;i<9;i++)
+			printk("%d ",priv->txqueue_to_outpipemap[i]);
+		printk("\n");*/
+	}
+#endif
+	rtl8192_init_priv_variable(dev);
+	rtl8192_init_priv_lock(priv);
+	rtl8192_init_priv_task(dev);
+	rtl8192_get_eeprom_size(dev);
+	rtl8192_read_eeprom_info(dev);
+	rtl8192_get_channel_map(dev);
+	init_hal_dm(dev);
+	init_timer(&priv->watch_dog_timer);
+	priv->watch_dog_timer.data = (unsigned long)dev;
+	priv->watch_dog_timer.function = watch_dog_timer_callback;
+	if(rtl8192_usb_initendpoints(dev)!=0){ 
+		DMESG("Endopoints initialization failed");
+		return -ENOMEM;
+	}
+	
+	//rtl8192_adapter_start(dev);
+#ifdef DEBUG_EPROM
+	dump_eprom(dev);
+#endif 
+	return 0;
+}
+
+/******************************************************************************
+ *function:  This function actually only set RRSR, RATR and BW_OPMODE registers 
+ *	     not to do all the hw config as its name says
+ *   input:  net_device dev
+ *  output:  none
+ *  return:  none
+ *  notice:  This part need to modified according to the rate set we filtered
+ * ****************************************************************************/
+void rtl8192_hwconfig(struct net_device* dev)
+{
+	u32 regRATR = 0, regRRSR = 0;
+	u8 regBwOpMode = 0, regTmp = 0;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+// Set RRSR, RATR, and BW_OPMODE registers
+	//
+	switch(priv->ieee80211->mode)
+	{
+	case WIRELESS_MODE_B:
+		regBwOpMode = BW_OPMODE_20MHZ;
+		regRATR = RATE_ALL_CCK;
+		regRRSR = RATE_ALL_CCK;
+		break;
+	case WIRELESS_MODE_A:
+		regBwOpMode = BW_OPMODE_5G |BW_OPMODE_20MHZ;
+		regRATR = RATE_ALL_OFDM_AG;
+		regRRSR = RATE_ALL_OFDM_AG;
+		break;
+	case WIRELESS_MODE_G:
+		regBwOpMode = BW_OPMODE_20MHZ;
+		regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
+		regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
+		break;
+	case WIRELESS_MODE_AUTO:
+#ifdef TO_DO_LIST
+		if (Adapter->bInHctTest)
+		{
+		    regBwOpMode = BW_OPMODE_20MHZ;
+		    regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
+		    regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
+		}
+		else
+#endif
+		{
+		    regBwOpMode = BW_OPMODE_20MHZ;
+		    regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
+		    regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
+		}
+		break;
+	case WIRELESS_MODE_N_24G:
+		// It support CCK rate by default.
+		// CCK rate will be filtered out only when associated AP does not support it.
+		regBwOpMode = BW_OPMODE_20MHZ;
+			regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
+			regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
+		break;
+	case WIRELESS_MODE_N_5G:
+		regBwOpMode = BW_OPMODE_5G;
+		regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
+		regRRSR = RATE_ALL_OFDM_AG;
+		break;
+	}
+
+	write_nic_byte(dev, BW_OPMODE, regBwOpMode);
+	{
+		u32 ratr_value = 0;
+		ratr_value = regRATR;
+		if (priv->rf_type == RF_1T2R)
+		{
+			ratr_value &= ~(RATE_ALL_OFDM_2SS);
+		}
+		write_nic_dword(dev, RATR0, ratr_value);
+		write_nic_byte(dev, UFWP, 1);
+	}	
+	regTmp = read_nic_byte(dev, 0x313);
+	regRRSR = ((regTmp) << 24) | (regRRSR & 0x00ffffff);
+	write_nic_dword(dev, RRSR, regRRSR);
+
+	//
+	// Set Retry Limit here
+	//
+	write_nic_word(dev, RETRY_LIMIT, 
+			priv->ShortRetryLimit << RETRY_LIMIT_SHORT_SHIFT | \
+			priv->LongRetryLimit << RETRY_LIMIT_LONG_SHIFT);
+	// Set Contention Window here		
+
+	// Set Tx AGC
+
+	// Set Tx Antenna including Feedback control
+		
+	// Set Auto Rate fallback control
+	
+	
+}
+
+
+//InitializeAdapter and PhyCfg
+bool rtl8192_adapter_start(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u32 dwRegRead = 0;
+	bool init_status = true;
+	RT_TRACE(COMP_INIT, "====>%s()\n", __FUNCTION__);
+	priv->Rf_Mode = RF_OP_By_SW_3wire;
+	//for ASIC power on sequence
+	write_nic_byte_E(dev, 0x5f, 0x80);
+	mdelay(50);
+	write_nic_byte_E(dev, 0x5f, 0xf0);
+	write_nic_byte_E(dev, 0x5d, 0x00);
+	write_nic_byte_E(dev, 0x5e, 0x80);
+	write_nic_byte(dev, 0x17, 0x37);
+	mdelay(10);
+//#ifdef TO_DO_LIST
+	priv->pFirmware->firmware_status = FW_STATUS_0_INIT;
+	//config CPUReset Register
+	//Firmware Reset or not?
+	dwRegRead = read_nic_dword(dev, CPU_GEN);
+	if (priv->pFirmware->firmware_status == FW_STATUS_0_INIT)
+		dwRegRead |= CPU_GEN_SYSTEM_RESET; //do nothing here?
+	else if (priv->pFirmware->firmware_status == FW_STATUS_5_READY)
+		dwRegRead |= CPU_GEN_FIRMWARE_RESET;
+	else
+		RT_TRACE(COMP_ERR, "ERROR in %s(): undefined firmware state(%d)\n", __FUNCTION__,   priv->pFirmware->firmware_status);
+
+	write_nic_dword(dev, CPU_GEN, dwRegRead);
+	//mdelay(30);
+	//config BB.
+	rtl8192_BBConfig(dev);
+
+#if 1
+	//Loopback mode or not
+	priv->LoopbackMode = RTL819xU_NO_LOOPBACK;
+//	priv->LoopbackMode = RTL819xU_MAC_LOOPBACK;
+
+	dwRegRead = read_nic_dword(dev, CPU_GEN);
+	if (priv->LoopbackMode == RTL819xU_NO_LOOPBACK)
+		dwRegRead = ((dwRegRead & CPU_GEN_NO_LOOPBACK_MSK) | CPU_GEN_NO_LOOPBACK_SET);
+	else if (priv->LoopbackMode == RTL819xU_MAC_LOOPBACK)
+		dwRegRead |= CPU_CCK_LOOPBACK;
+	else
+		RT_TRACE(COMP_ERR, "Serious error in %s(): wrong loopback mode setting(%d)\n", __FUNCTION__,  priv->LoopbackMode);
+	
+	write_nic_dword(dev, CPU_GEN, dwRegRead);
+
+	//after reset cpu, we need wait for a seconds to write in register.
+	udelay(500);
+
+	//xiong add for new bitfile:usb suspend reset pin set to 1. //do we need?
+	write_nic_byte_E(dev, 0x5f, (read_nic_byte_E(dev, 0x5f)|0x20));
+
+	//Set Hardware
+	rtl8192_hwconfig(dev);
+
+	//turn on Tx/Rx
+	write_nic_byte(dev, CMDR, CR_RE|CR_TE);
+	
+	//set IDR0 here
+	write_nic_dword(dev, MAC0, ((u32*)dev->dev_addr)[0]);
+	write_nic_word(dev, MAC4, ((u16*)(dev->dev_addr + 4))[0]);
+
+	//set RCR
+	write_nic_dword(dev, RCR, priv->ReceiveConfig);
+
+	//Initialize Number of Reserved Pages in Firmware Queue
+	write_nic_dword(dev, RQPN1,  NUM_OF_PAGE_IN_FW_QUEUE_BK << RSVD_FW_QUEUE_PAGE_BK_SHIFT |\
+						NUM_OF_PAGE_IN_FW_QUEUE_BE << RSVD_FW_QUEUE_PAGE_BE_SHIFT | \
+						NUM_OF_PAGE_IN_FW_QUEUE_VI << RSVD_FW_QUEUE_PAGE_VI_SHIFT | \
+						NUM_OF_PA