[PATCH 051/641] Staging: Add pristine upstream vt6656 driver sources to drivers/staging/vt6656.

Greg Kroah-Hartman gregkh at suse.de
Tue Sep 15 12:04:42 PDT 2009


From: Forest Bond <forest at alittletooquiet.net>

Add pristine upstream vt6656 driver sources to drivers/staging/vt6656.  These
files were copied from the driver directory in the upstream source archive,
available here:

  http://www.viaarena.com/Driver/VT6656_Linux_src_v1.19_12_x86.zip

After copying, trailing whitespace was stripped.  This is GPL-licensed code.

Signed-off-by: Forest Bond <forest at alittletooquiet.net>
Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de>
---
 drivers/staging/vt6656/80211hdr.h           |  358 ++
 drivers/staging/vt6656/80211mgr.c           | 1050 ++++++
 drivers/staging/vt6656/80211mgr.h           |  867 +++++
 drivers/staging/vt6656/Makefile             |  204 ++
 drivers/staging/vt6656/aes_ccmp.c           |  410 +++
 drivers/staging/vt6656/aes_ccmp.h           |   48 +
 drivers/staging/vt6656/baseband.c           | 2129 ++++++++++++
 drivers/staging/vt6656/baseband.h           |  163 +
 drivers/staging/vt6656/bssdb.c              | 1777 ++++++++++
 drivers/staging/vt6656/bssdb.h              |  370 ++
 drivers/staging/vt6656/card.c               | 1147 ++++++
 drivers/staging/vt6656/card.h               |  109 +
 drivers/staging/vt6656/channel.c            |  535 +++
 drivers/staging/vt6656/channel.h            |   58 +
 drivers/staging/vt6656/control.c            |  116 +
 drivers/staging/vt6656/control.h            |  103 +
 drivers/staging/vt6656/country.h            |  163 +
 drivers/staging/vt6656/datarate.c           |  518 +++
 drivers/staging/vt6656/datarate.h           |  110 +
 drivers/staging/vt6656/desc.h               |  453 +++
 drivers/staging/vt6656/device.h             |  988 ++++++
 drivers/staging/vt6656/dpc.c                | 1673 +++++++++
 drivers/staging/vt6656/dpc.h                |   94 +
 drivers/staging/vt6656/firmware.c           |  887 +++++
 drivers/staging/vt6656/firmware.h           |   66 +
 drivers/staging/vt6656/hostap.c             |  881 +++++
 drivers/staging/vt6656/hostap.h             |   94 +
 drivers/staging/vt6656/int.c                |  214 ++
 drivers/staging/vt6656/int.h                |  101 +
 drivers/staging/vt6656/ioctl.c              |  724 ++++
 drivers/staging/vt6656/ioctl.h              |   74 +
 drivers/staging/vt6656/iwctl.c              | 2355 +++++++++++++
 drivers/staging/vt6656/iwctl.h              |  332 ++
 drivers/staging/vt6656/kcompat.h            |  315 ++
 drivers/staging/vt6656/key.c                |  886 +++++
 drivers/staging/vt6656/key.h                |  196 ++
 drivers/staging/vt6656/mac.c                |  500 +++
 drivers/staging/vt6656/mac.h                |  458 +++
 drivers/staging/vt6656/main_usb.c           | 2398 +++++++++++++
 drivers/staging/vt6656/mib.c                |  592 ++++
 drivers/staging/vt6656/mib.h                |  445 +++
 drivers/staging/vt6656/michael.c            |  188 +
 drivers/staging/vt6656/michael.h            |   62 +
 drivers/staging/vt6656/power.c              |  458 +++
 drivers/staging/vt6656/power.h              |   84 +
 drivers/staging/vt6656/rc4.c                |   89 +
 drivers/staging/vt6656/rc4.h                |   51 +
 drivers/staging/vt6656/rf.c                 | 1163 +++++++
 drivers/staging/vt6656/rf.h                 |  112 +
 drivers/staging/vt6656/rndis.h              |  162 +
 drivers/staging/vt6656/rxtx.c               | 3280 ++++++++++++++++++
 drivers/staging/vt6656/rxtx.h               |  716 ++++
 drivers/staging/vt6656/srom.h               |  144 +
 drivers/staging/vt6656/tbit.h               |   78 +
 drivers/staging/vt6656/tcrc.c               |  207 ++
 drivers/staging/vt6656/tcrc.h               |   71 +
 drivers/staging/vt6656/tether.c             |  123 +
 drivers/staging/vt6656/tether.h             |  256 ++
 drivers/staging/vt6656/tkip.c               |  284 ++
 drivers/staging/vt6656/tkip.h               |   76 +
 drivers/staging/vt6656/tmacro.h             |  152 +
 drivers/staging/vt6656/tpci.h               |  119 +
 drivers/staging/vt6656/ttype.h              |  394 +++
 drivers/staging/vt6656/umem.h               |   75 +
 drivers/staging/vt6656/upc.h                |  171 +
 drivers/staging/vt6656/usbpipe.c            |  989 ++++++
 drivers/staging/vt6656/usbpipe.h            |  116 +
 drivers/staging/vt6656/vntconfiguration.dat |    6 +
 drivers/staging/vt6656/wcmd.c               | 1402 ++++++++
 drivers/staging/vt6656/wcmd.h               |  156 +
 drivers/staging/vt6656/wctl.c               |  263 ++
 drivers/staging/vt6656/wctl.h               |  127 +
 drivers/staging/vt6656/wmgr.c               | 5008 +++++++++++++++++++++++++++
 drivers/staging/vt6656/wmgr.h               |  519 +++
 drivers/staging/vt6656/wpa.c                |  339 ++
 drivers/staging/vt6656/wpa.h                |   98 +
 drivers/staging/vt6656/wpa2.c               |  373 ++
 drivers/staging/vt6656/wpa2.h               |   99 +
 drivers/staging/vt6656/wpactl.c             | 1028 ++++++
 drivers/staging/vt6656/wpactl.h             |   90 +
 80 files changed, 44089 insertions(+), 0 deletions(-)
 create mode 100644 drivers/staging/vt6656/80211hdr.h
 create mode 100644 drivers/staging/vt6656/80211mgr.c
 create mode 100644 drivers/staging/vt6656/80211mgr.h
 create mode 100644 drivers/staging/vt6656/Makefile
 create mode 100644 drivers/staging/vt6656/aes_ccmp.c
 create mode 100644 drivers/staging/vt6656/aes_ccmp.h
 create mode 100644 drivers/staging/vt6656/baseband.c
 create mode 100644 drivers/staging/vt6656/baseband.h
 create mode 100644 drivers/staging/vt6656/bssdb.c
 create mode 100644 drivers/staging/vt6656/bssdb.h
 create mode 100644 drivers/staging/vt6656/card.c
 create mode 100644 drivers/staging/vt6656/card.h
 create mode 100644 drivers/staging/vt6656/channel.c
 create mode 100644 drivers/staging/vt6656/channel.h
 create mode 100644 drivers/staging/vt6656/control.c
 create mode 100644 drivers/staging/vt6656/control.h
 create mode 100644 drivers/staging/vt6656/country.h
 create mode 100644 drivers/staging/vt6656/datarate.c
 create mode 100644 drivers/staging/vt6656/datarate.h
 create mode 100644 drivers/staging/vt6656/desc.h
 create mode 100644 drivers/staging/vt6656/device.h
 create mode 100644 drivers/staging/vt6656/dpc.c
 create mode 100644 drivers/staging/vt6656/dpc.h
 create mode 100644 drivers/staging/vt6656/firmware.c
 create mode 100644 drivers/staging/vt6656/firmware.h
 create mode 100644 drivers/staging/vt6656/hostap.c
 create mode 100644 drivers/staging/vt6656/hostap.h
 create mode 100644 drivers/staging/vt6656/int.c
 create mode 100644 drivers/staging/vt6656/int.h
 create mode 100644 drivers/staging/vt6656/ioctl.c
 create mode 100644 drivers/staging/vt6656/ioctl.h
 create mode 100644 drivers/staging/vt6656/iwctl.c
 create mode 100644 drivers/staging/vt6656/iwctl.h
 create mode 100644 drivers/staging/vt6656/kcompat.h
 create mode 100644 drivers/staging/vt6656/key.c
 create mode 100644 drivers/staging/vt6656/key.h
 create mode 100644 drivers/staging/vt6656/mac.c
 create mode 100644 drivers/staging/vt6656/mac.h
 create mode 100644 drivers/staging/vt6656/main_usb.c
 create mode 100644 drivers/staging/vt6656/mib.c
 create mode 100644 drivers/staging/vt6656/mib.h
 create mode 100644 drivers/staging/vt6656/michael.c
 create mode 100644 drivers/staging/vt6656/michael.h
 create mode 100644 drivers/staging/vt6656/power.c
 create mode 100644 drivers/staging/vt6656/power.h
 create mode 100644 drivers/staging/vt6656/rc4.c
 create mode 100644 drivers/staging/vt6656/rc4.h
 create mode 100644 drivers/staging/vt6656/rf.c
 create mode 100644 drivers/staging/vt6656/rf.h
 create mode 100644 drivers/staging/vt6656/rndis.h
 create mode 100644 drivers/staging/vt6656/rxtx.c
 create mode 100644 drivers/staging/vt6656/rxtx.h
 create mode 100644 drivers/staging/vt6656/srom.h
 create mode 100644 drivers/staging/vt6656/tbit.h
 create mode 100644 drivers/staging/vt6656/tcrc.c
 create mode 100644 drivers/staging/vt6656/tcrc.h
 create mode 100644 drivers/staging/vt6656/tether.c
 create mode 100644 drivers/staging/vt6656/tether.h
 create mode 100644 drivers/staging/vt6656/tkip.c
 create mode 100644 drivers/staging/vt6656/tkip.h
 create mode 100644 drivers/staging/vt6656/tmacro.h
 create mode 100644 drivers/staging/vt6656/tpci.h
 create mode 100644 drivers/staging/vt6656/ttype.h
 create mode 100644 drivers/staging/vt6656/umem.h
 create mode 100644 drivers/staging/vt6656/upc.h
 create mode 100644 drivers/staging/vt6656/usbpipe.c
 create mode 100644 drivers/staging/vt6656/usbpipe.h
 create mode 100644 drivers/staging/vt6656/vntconfiguration.dat
 create mode 100644 drivers/staging/vt6656/wcmd.c
 create mode 100644 drivers/staging/vt6656/wcmd.h
 create mode 100644 drivers/staging/vt6656/wctl.c
 create mode 100644 drivers/staging/vt6656/wctl.h
 create mode 100644 drivers/staging/vt6656/wmgr.c
 create mode 100644 drivers/staging/vt6656/wmgr.h
 create mode 100644 drivers/staging/vt6656/wpa.c
 create mode 100644 drivers/staging/vt6656/wpa.h
 create mode 100644 drivers/staging/vt6656/wpa2.c
 create mode 100644 drivers/staging/vt6656/wpa2.h
 create mode 100644 drivers/staging/vt6656/wpactl.c
 create mode 100644 drivers/staging/vt6656/wpactl.h

diff --git a/drivers/staging/vt6656/80211hdr.h b/drivers/staging/vt6656/80211hdr.h
new file mode 100644
index 0000000..84cb1d0
--- /dev/null
+++ b/drivers/staging/vt6656/80211hdr.h
@@ -0,0 +1,358 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: 80211hdr.h
+ *
+ * Purpose: 802.11 MAC headers related pre-defines and macros.
+ *
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: Apr 8, 2002
+ *
+ */
+
+
+
+#ifndef __80211HDR_H__
+#define __80211HDR_H__
+
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+
+/*---------------------  Export Definitions -------------------------*/
+// bit type
+#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
+
+// 802.11 frame related, defined as 802.11 spec
+#define WLAN_ADDR_LEN               6
+#define WLAN_CRC_LEN                4
+#define WLAN_CRC32_LEN              4
+#define WLAN_FCS_LEN                4
+#define WLAN_BSSID_LEN              6
+#define WLAN_BSS_TS_LEN             8
+#define WLAN_HDR_ADDR2_LEN          16
+#define WLAN_HDR_ADDR3_LEN          24
+#define WLAN_HDR_ADDR4_LEN          30
+#define WLAN_IEHDR_LEN              2
+#define WLAN_SSID_MAXLEN            32
+//#define WLAN_RATES_MAXLEN           255
+#define WLAN_RATES_MAXLEN           16
+#define WLAN_RATES_MAXLEN_11B       4
+#define WLAN_RSN_MAXLEN             32
+#define WLAN_DATA_MAXLEN            2312
+#define WLAN_A3FR_MAXLEN            (WLAN_HDR_ADDR3_LEN + WLAN_DATA_MAXLEN + WLAN_CRC_LEN)
+
+
+#define WLAN_BEACON_FR_MAXLEN       WLAN_A3FR_MAXLEN
+#define WLAN_ATIM_FR_MAXLEN         (WLAN_HDR_ADDR3_LEN + 0)
+#define WLAN_NULLDATA_FR_MAXLEN     (WLAN_HDR_ADDR3_LEN + 0)
+#define WLAN_DISASSOC_FR_MAXLEN     (WLAN_HDR_ADDR3_LEN + 2)
+#define WLAN_ASSOCREQ_FR_MAXLEN     WLAN_A3FR_MAXLEN
+#define WLAN_ASSOCRESP_FR_MAXLEN    WLAN_A3FR_MAXLEN
+#define WLAN_REASSOCREQ_FR_MAXLEN   WLAN_A3FR_MAXLEN
+#define WLAN_REASSOCRESP_FR_MAXLEN  WLAN_A3FR_MAXLEN
+#define WLAN_PROBEREQ_FR_MAXLEN     WLAN_A3FR_MAXLEN
+#define WLAN_PROBERESP_FR_MAXLEN    WLAN_A3FR_MAXLEN
+#define WLAN_AUTHEN_FR_MAXLEN       WLAN_A3FR_MAXLEN
+#define WLAN_DEAUTHEN_FR_MAXLEN     (WLAN_HDR_ADDR3_LEN + 2)
+
+
+#define WLAN_WEP_NKEYS              4
+#define WLAN_WEP40_KEYLEN           5
+#define WLAN_WEP104_KEYLEN          13
+#define WLAN_WEP232_KEYLEN          29
+//#define WLAN_WEPMAX_KEYLEN          29
+#define WLAN_WEPMAX_KEYLEN          32
+#define WLAN_CHALLENGE_IE_MAXLEN    255
+#define WLAN_CHALLENGE_IE_LEN       130
+#define WLAN_CHALLENGE_LEN          128
+#define WLAN_WEP_IV_LEN             4
+#define WLAN_WEP_ICV_LEN            4
+#define WLAN_FRAGS_MAX              16
+
+// Frame Type
+#define WLAN_TYPE_MGR 0x00
+#define WLAN_TYPE_CTL  0x01
+#define WLAN_TYPE_DATA 0x02
+
+#define WLAN_FTYPE_MGMT 0x00
+#define WLAN_FTYPE_CTL  0x01
+#define WLAN_FTYPE_DATA 0x02
+
+
+// Frame Subtypes
+#define WLAN_FSTYPE_ASSOCREQ        0x00
+#define WLAN_FSTYPE_ASSOCRESP       0x01
+#define WLAN_FSTYPE_REASSOCREQ      0x02
+#define WLAN_FSTYPE_REASSOCRESP     0x03
+#define WLAN_FSTYPE_PROBEREQ        0x04
+#define WLAN_FSTYPE_PROBERESP       0x05
+#define WLAN_FSTYPE_BEACON          0x08
+#define WLAN_FSTYPE_ATIM            0x09
+#define WLAN_FSTYPE_DISASSOC        0x0a
+#define WLAN_FSTYPE_AUTHEN          0x0b
+#define WLAN_FSTYPE_DEAUTHEN        0x0c
+#define WLAN_FSTYPE_ACTION          0x0d
+
+// Control
+#define WLAN_FSTYPE_PSPOLL          0x0a
+#define WLAN_FSTYPE_RTS             0x0b
+#define WLAN_FSTYPE_CTS             0x0c
+#define WLAN_FSTYPE_ACK             0x0d
+#define WLAN_FSTYPE_CFEND           0x0e
+#define WLAN_FSTYPE_CFENDCFACK      0x0f
+
+// Data
+#define WLAN_FSTYPE_DATAONLY        0x00
+#define WLAN_FSTYPE_DATA_CFACK      0x01
+#define WLAN_FSTYPE_DATA_CFPOLL     0x02
+#define WLAN_FSTYPE_DATA_CFACK_CFPOLL   0x03
+#define WLAN_FSTYPE_NULL            0x04
+#define WLAN_FSTYPE_CFACK           0x05
+#define WLAN_FSTYPE_CFPOLL          0x06
+#define WLAN_FSTYPE_CFACK_CFPOLL    0x07
+
+
+#ifdef __BIG_ENDIAN
+
+// GET & SET Frame Control bit
+#define WLAN_GET_FC_PRVER(n)    ((((WORD)(n) >> 8) & (BIT0 | BIT1))
+#define WLAN_GET_FC_FTYPE(n)    ((((WORD)(n) >> 8) & (BIT2 | BIT3)) >> 2)
+#define WLAN_GET_FC_FSTYPE(n)   ((((WORD)(n) >> 8) & (BIT4|BIT5|BIT6|BIT7)) >> 4)
+#define WLAN_GET_FC_TODS(n)     ((((WORD)(n) << 8) & (BIT8)) >> 8)
+#define WLAN_GET_FC_FROMDS(n)   ((((WORD)(n) << 8) & (BIT9)) >> 9)
+#define WLAN_GET_FC_MOREFRAG(n) ((((WORD)(n) << 8) & (BIT10)) >> 10)
+#define WLAN_GET_FC_RETRY(n)    ((((WORD)(n) << 8) & (BIT11)) >> 11)
+#define WLAN_GET_FC_PWRMGT(n)   ((((WORD)(n) << 8) & (BIT12)) >> 12)
+#define WLAN_GET_FC_MOREDATA(n) ((((WORD)(n) << 8) & (BIT13)) >> 13)
+#define WLAN_GET_FC_ISWEP(n)    ((((WORD)(n) << 8) & (BIT14)) >> 14)
+#define WLAN_GET_FC_ORDER(n)    ((((WORD)(n) << 8) & (BIT15)) >> 15)
+
+// Sequence Field bit
+#define WLAN_GET_SEQ_FRGNUM(n) (((WORD)(n) >> 8) & (BIT0|BIT1|BIT2|BIT3))
+#define WLAN_GET_SEQ_SEQNUM(n) ((((WORD)(n) >> 8) & (~(BIT0|BIT1|BIT2|BIT3))) >> 4)
+
+
+// Capability Field bit
+#define WLAN_GET_CAP_INFO_ESS(n)           (((n) >> 8) & BIT0)
+#define WLAN_GET_CAP_INFO_IBSS(n)          ((((n) >> 8) & BIT1) >> 1)
+#define WLAN_GET_CAP_INFO_CFPOLLABLE(n)    ((((n) >> 8) & BIT2) >> 2)
+#define WLAN_GET_CAP_INFO_CFPOLLREQ(n)     ((((n) >> 8) & BIT3) >> 3)
+#define WLAN_GET_CAP_INFO_PRIVACY(n)       ((((n) >> 8) & BIT4) >> 4)
+#define WLAN_GET_CAP_INFO_SHORTPREAMBLE(n) ((((n) >> 8) & BIT5) >> 5)
+#define WLAN_GET_CAP_INFO_PBCC(n)          ((((n) >> 8) & BIT6) >> 6)
+#define WLAN_GET_CAP_INFO_AGILITY(n)       ((((n) >> 8) & BIT7) >> 7)
+#define WLAN_GET_CAP_INFO_SPECTRUMMNG(n)   ((((n))      & BIT8) >> 10)
+#define WLAN_GET_CAP_INFO_SHORTSLOTTIME(n) ((((n))      & BIT10) >> 10)
+#define WLAN_GET_CAP_INFO_DSSSOFDM(n)      ((((n))      & BIT13) >> 13)
+#define WLAN_GET_CAP_INFO_GRPACK(n)        ((((n))      & BIT14) >> 14)
+
+
+#else
+
+// GET & SET Frame Control bit
+#define WLAN_GET_FC_PRVER(n)    (((WORD)(n)) & (BIT0 | BIT1))
+#define WLAN_GET_FC_FTYPE(n)    ((((WORD)(n)) & (BIT2 | BIT3)) >> 2)
+#define WLAN_GET_FC_FSTYPE(n)   ((((WORD)(n)) & (BIT4|BIT5|BIT6|BIT7)) >> 4)
+#define WLAN_GET_FC_TODS(n)     ((((WORD)(n)) & (BIT8)) >> 8)
+#define WLAN_GET_FC_FROMDS(n)   ((((WORD)(n)) & (BIT9)) >> 9)
+#define WLAN_GET_FC_MOREFRAG(n) ((((WORD)(n)) & (BIT10)) >> 10)
+#define WLAN_GET_FC_RETRY(n)    ((((WORD)(n)) & (BIT11)) >> 11)
+#define WLAN_GET_FC_PWRMGT(n)   ((((WORD)(n)) & (BIT12)) >> 12)
+#define WLAN_GET_FC_MOREDATA(n) ((((WORD)(n)) & (BIT13)) >> 13)
+#define WLAN_GET_FC_ISWEP(n)    ((((WORD)(n)) & (BIT14)) >> 14)
+#define WLAN_GET_FC_ORDER(n)    ((((WORD)(n)) & (BIT15)) >> 15)
+
+
+// Sequence Field bit
+#define WLAN_GET_SEQ_FRGNUM(n) (((WORD)(n)) & (BIT0|BIT1|BIT2|BIT3))
+#define WLAN_GET_SEQ_SEQNUM(n) ((((WORD)(n)) & (~(BIT0|BIT1|BIT2|BIT3))) >> 4)
+
+
+// Capability Field bit
+#define WLAN_GET_CAP_INFO_ESS(n)           ((n) & BIT0)
+#define WLAN_GET_CAP_INFO_IBSS(n)          (((n) & BIT1) >> 1)
+#define WLAN_GET_CAP_INFO_CFPOLLABLE(n)    (((n) & BIT2) >> 2)
+#define WLAN_GET_CAP_INFO_CFPOLLREQ(n)     (((n) & BIT3) >> 3)
+#define WLAN_GET_CAP_INFO_PRIVACY(n)       (((n) & BIT4) >> 4)
+#define WLAN_GET_CAP_INFO_SHORTPREAMBLE(n) (((n) & BIT5) >> 5)
+#define WLAN_GET_CAP_INFO_PBCC(n)          (((n) & BIT6) >> 6)
+#define WLAN_GET_CAP_INFO_AGILITY(n)       (((n) & BIT7) >> 7)
+#define WLAN_GET_CAP_INFO_SPECTRUMMNG(n)   (((n) & BIT8) >> 10)
+#define WLAN_GET_CAP_INFO_SHORTSLOTTIME(n) (((n) & BIT10) >> 10)
+#define WLAN_GET_CAP_INFO_DSSSOFDM(n)      (((n) & BIT13) >> 13)
+#define WLAN_GET_CAP_INFO_GRPACK(n)        (((n) & BIT14) >> 14)
+
+
+#endif //#ifdef __BIG_ENDIAN
+
+
+#define WLAN_SET_CAP_INFO_ESS(n)           (n)
+#define WLAN_SET_CAP_INFO_IBSS(n)          ((n) << 1)
+#define WLAN_SET_CAP_INFO_CFPOLLABLE(n)    ((n) << 2)
+#define WLAN_SET_CAP_INFO_CFPOLLREQ(n)     ((n) << 3)
+#define WLAN_SET_CAP_INFO_PRIVACY(n)       ((n) << 4)
+#define WLAN_SET_CAP_INFO_SHORTPREAMBLE(n) ((n) << 5)
+#define WLAN_SET_CAP_INFO_SPECTRUMMNG(n)   ((n) << 8)
+#define WLAN_SET_CAP_INFO_PBCC(n)          ((n) << 6)
+#define WLAN_SET_CAP_INFO_AGILITY(n)       ((n) << 7)
+#define WLAN_SET_CAP_INFO_SHORTSLOTTIME(n) ((n) << 10)
+#define WLAN_SET_CAP_INFO_DSSSOFDM(n)      ((n) << 13)
+#define WLAN_SET_CAP_INFO_GRPACK(n)        ((n) << 14)
+
+
+#define WLAN_SET_FC_PRVER(n)    ((WORD)(n))
+#define WLAN_SET_FC_FTYPE(n)    (((WORD)(n)) << 2)
+#define WLAN_SET_FC_FSTYPE(n)   (((WORD)(n)) << 4)
+#define WLAN_SET_FC_TODS(n)     (((WORD)(n)) << 8)
+#define WLAN_SET_FC_FROMDS(n)   (((WORD)(n)) << 9)
+#define WLAN_SET_FC_MOREFRAG(n) (((WORD)(n)) << 10)
+#define WLAN_SET_FC_RETRY(n)    (((WORD)(n)) << 11)
+#define WLAN_SET_FC_PWRMGT(n)   (((WORD)(n)) << 12)
+#define WLAN_SET_FC_MOREDATA(n) (((WORD)(n)) << 13)
+#define WLAN_SET_FC_ISWEP(n)    (((WORD)(n)) << 14)
+#define WLAN_SET_FC_ORDER(n)    (((WORD)(n)) << 15)
+
+#define WLAN_SET_SEQ_FRGNUM(n) ((WORD)(n))
+#define WLAN_SET_SEQ_SEQNUM(n) (((WORD)(n)) << 4)
+
+// ERP Field bit
+
+#define WLAN_GET_ERP_NONERP_PRESENT(n)     ((n) & BIT0)
+#define WLAN_GET_ERP_USE_PROTECTION(n)     (((n) & BIT1) >> 1)
+#define WLAN_GET_ERP_BARKER_MODE(n)        (((n) & BIT2) >> 2)
+
+#define WLAN_SET_ERP_NONERP_PRESENT(n)     (n)
+#define WLAN_SET_ERP_USE_PROTECTION(n)     ((n) << 1)
+#define WLAN_SET_ERP_BARKER_MODE(n)        ((n) << 2)
+
+
+
+// Support & Basic Rates field
+#define WLAN_MGMT_IS_BASICRATE(b)    ((b) & BIT7)
+#define WLAN_MGMT_GET_RATE(b)        ((b) & ~BIT7)
+
+// TIM field
+#define WLAN_MGMT_IS_MULTICAST_TIM(b)   ((b) & BIT0)
+#define WLAN_MGMT_GET_TIM_OFFSET(b)     (((b) & ~BIT0) >> 1)
+
+// 3-Addr & 4-Addr
+#define WLAN_HDR_A3_DATA_PTR(p) (((PBYTE)(p)) + WLAN_HDR_ADDR3_LEN)
+#define WLAN_HDR_A4_DATA_PTR(p) (((PBYTE)(p)) + WLAN_HDR_ADDR4_LEN)
+
+// IEEE ADDR
+#define IEEE_ADDR_UNIVERSAL         0x02
+#define IEEE_ADDR_GROUP             0x01
+
+typedef struct {
+    BYTE            abyAddr[6];
+} IEEE_ADDR, *PIEEE_ADDR;
+
+// 802.11 Header Format
+
+typedef struct tagWLAN_80211HDR_A2 {
+
+    WORD    wFrameCtl;
+    WORD    wDurationID;
+    BYTE    abyAddr1[WLAN_ADDR_LEN];
+    BYTE    abyAddr2[WLAN_ADDR_LEN];
+
+}__attribute__ ((__packed__))
+WLAN_80211HDR_A2, *PWLAN_80211HDR_A2;
+
+typedef struct tagWLAN_80211HDR_A3 {
+
+    WORD    wFrameCtl;
+    WORD    wDurationID;
+    BYTE    abyAddr1[WLAN_ADDR_LEN];
+    BYTE    abyAddr2[WLAN_ADDR_LEN];
+    BYTE    abyAddr3[WLAN_ADDR_LEN];
+    WORD    wSeqCtl;
+
+}__attribute__ ((__packed__))
+WLAN_80211HDR_A3, *PWLAN_80211HDR_A3;
+
+typedef struct tagWLAN_80211HDR_A4 {
+
+    WORD    wFrameCtl;
+    WORD    wDurationID;
+    BYTE    abyAddr1[WLAN_ADDR_LEN];
+    BYTE    abyAddr2[WLAN_ADDR_LEN];
+    BYTE    abyAddr3[WLAN_ADDR_LEN];
+    WORD    wSeqCtl;
+    BYTE    abyAddr4[WLAN_ADDR_LEN];
+
+}__attribute__ ((__packed__))
+WLAN_80211HDR_A4, *PWLAN_80211HDR_A4;
+
+
+typedef union tagUWLAN_80211HDR {
+
+    WLAN_80211HDR_A2        sA2;
+    WLAN_80211HDR_A3        sA3;
+    WLAN_80211HDR_A4        sA4;
+
+} UWLAN_80211HDR, *PUWLAN_80211HDR;
+
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+
+#endif // __80211HDR_H__
+
+
diff --git a/drivers/staging/vt6656/80211mgr.c b/drivers/staging/vt6656/80211mgr.c
new file mode 100644
index 0000000..fda7224
--- /dev/null
+++ b/drivers/staging/vt6656/80211mgr.c
@@ -0,0 +1,1050 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: 80211mgr.c
+ *
+ * Purpose: Handles the managment frame parsing functions
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: May 8, 2002
+ *
+ * Functions:
+ *      vMgrEncodeBeacon - Encode the Beacon frame
+ *      vMgrDecodeBeacon - Decode the Beacon frame
+ *      vMgrEncodeIBSSATIM - Encode the IBSS ATIM frame
+ *      vMgrDecodeIBSSATIM - Decode the IBSS ATIM frame
+ *      vMgrEncodeDisassociation - Encode the Disassociation frame
+ *      vMgrDecodeDisassociation - Decode the Disassociation frame
+ *      vMgrEncodeAssocRequest - Encode the Association request frame
+ *      vMgrDecodeAssocRequest - Decode the Association request frame
+ *      vMgrEncodeAssocResponse - Encode the Association response frame
+ *      vMgrDecodeAssocResponse - Decode the Association response frame
+ *      vMgrEncodeReAssocRequest - Encode the ReAssociation request frame
+ *      vMgrDecodeReAssocRequest - Decode the ReAssociation request frame
+ *      vMgrEncodeProbeRequest - Encode the Probe request frame
+ *      vMgrDecodeProbeRequest - Decode the Probe request frame
+ *      vMgrEncodeProbeResponse - Encode the Probe response frame
+ *      vMgrDecodeProbeResponse - Decode the Probe response frame
+ *      vMgrEncodeAuthen - Encode the Authentication frame
+ *      vMgrDecodeAuthen - Decode the Authentication frame
+ *      vMgrEncodeDeauthen - Encode the DeAuthentication frame
+ *      vMgrDecodeDeauthen - Decode the DeAuthentication frame
+ *      vMgrEncodeReassocResponse - Encode the Reassociation response frame
+ *      vMgrDecodeReassocResponse - Decode the Reassociation response frame
+ *
+ * Revision History:
+ *
+ */
+
+
+
+#if !defined(__TMACRO_H__)
+#include "tmacro.h"
+#endif
+#if !defined(__TETHER_H__)
+#include "tether.h"
+#endif
+#if !defined(__80211MGR_H__)
+#include "80211mgr.h"
+#endif
+#if !defined(__80211HDR_H__)
+#include "80211hdr.h"
+#endif
+#if !defined(__DEVICE_H__)
+#include "device.h"
+#endif
+#if !defined(__WPA_H__)
+#include "wpa.h"
+#endif
+
+
+
+/*---------------------  Static Definitions -------------------------*/
+
+
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+
+static int          msglevel                =MSG_LEVEL_INFO;
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+/*---------------------  Static Functions  --------------------------*/
+
+
+
+/*---------------------  Export Variables  --------------------------*/
+
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+/*+
+ *
+ * Routine Description:
+ * Encode Beacon frame body offset
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+VOID
+vMgrEncodeBeacon(
+    IN  PWLAN_FR_BEACON  pFrame
+     )
+{
+    pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+    // Fixed Fields
+    pFrame->pqwTimestamp = (PQWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                    + WLAN_BEACON_OFF_TS);
+    pFrame->pwBeaconInterval = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                       + WLAN_BEACON_OFF_BCN_INT);
+    pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                + WLAN_BEACON_OFF_CAPINFO);
+
+    pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_BEACON_OFF_SSID;
+
+    return;
+}
+
+/*+
+ *
+ * Routine Description:
+ * Decode Beacon frame body offset
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+
+VOID
+vMgrDecodeBeacon(
+    IN  PWLAN_FR_BEACON  pFrame
+    )
+{
+    PWLAN_IE        pItem;
+
+    pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+    // Fixed Fields
+    pFrame->pqwTimestamp = (PQWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                    + WLAN_BEACON_OFF_TS);
+    pFrame->pwBeaconInterval = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                       + WLAN_BEACON_OFF_BCN_INT);
+    pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                + WLAN_BEACON_OFF_CAPINFO);
+
+    // Information elements
+    pItem = (PWLAN_IE)((PBYTE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)))
+                       + WLAN_BEACON_OFF_SSID);
+    while( ((PBYTE)pItem) < (pFrame->pBuf + pFrame->len) ){
+
+        switch (pItem->byElementID) {
+            case WLAN_EID_SSID:
+                if (pFrame->pSSID == NULL)
+                    pFrame->pSSID = (PWLAN_IE_SSID)pItem;
+                break;
+            case WLAN_EID_SUPP_RATES:
+                if (pFrame->pSuppRates == NULL)
+                    pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
+                break;
+            case WLAN_EID_FH_PARMS:
+                //pFrame->pFHParms = (PWLAN_IE_FH_PARMS)pItem;
+                break;
+            case WLAN_EID_DS_PARMS:
+                if (pFrame->pDSParms == NULL)
+                    pFrame->pDSParms = (PWLAN_IE_DS_PARMS)pItem;
+                break;
+            case WLAN_EID_CF_PARMS:
+                if (pFrame->pCFParms == NULL)
+                    pFrame->pCFParms = (PWLAN_IE_CF_PARMS)pItem;
+                break;
+            case WLAN_EID_IBSS_PARMS:
+                if (pFrame->pIBSSParms == NULL)
+                    pFrame->pIBSSParms = (PWLAN_IE_IBSS_PARMS)pItem;
+                break;
+            case WLAN_EID_TIM:
+                if (pFrame->pTIM == NULL)
+                    pFrame->pTIM = (PWLAN_IE_TIM)pItem;
+                break;
+
+            case WLAN_EID_RSN:
+                if (pFrame->pRSN == NULL) {
+                    pFrame->pRSN = (PWLAN_IE_RSN)pItem;
+                }
+                break;
+            case WLAN_EID_RSN_WPA:
+                if (pFrame->pRSNWPA == NULL) {
+                    if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == TRUE)
+                        pFrame->pRSNWPA = (PWLAN_IE_RSN_EXT)pItem;
+                }
+                break;
+
+            case WLAN_EID_ERP:
+                if (pFrame->pERP == NULL)
+                    pFrame->pERP = (PWLAN_IE_ERP)pItem;
+                break;
+            case WLAN_EID_EXTSUPP_RATES:
+                if (pFrame->pExtSuppRates == NULL)
+                    pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
+                break;
+
+            case WLAN_EID_COUNTRY:      //7
+                if (pFrame->pIE_Country == NULL)
+                    pFrame->pIE_Country = (PWLAN_IE_COUNTRY)pItem;
+                break;
+
+            case WLAN_EID_PWR_CONSTRAINT:   //32
+                if (pFrame->pIE_PowerConstraint == NULL)
+                    pFrame->pIE_PowerConstraint = (PWLAN_IE_PW_CONST)pItem;
+                break;
+
+            case WLAN_EID_CH_SWITCH:    //37
+                if (pFrame->pIE_CHSW == NULL)
+                    pFrame->pIE_CHSW = (PWLAN_IE_CH_SW)pItem;
+                break;
+
+            case WLAN_EID_QUIET:        //40
+                if (pFrame->pIE_Quiet == NULL)
+                    pFrame->pIE_Quiet = (PWLAN_IE_QUIET)pItem;
+                break;
+
+            case WLAN_EID_IBSS_DFS:
+                if (pFrame->pIE_IBSSDFS == NULL)
+                    pFrame->pIE_IBSSDFS = (PWLAN_IE_IBSS_DFS)pItem;
+                break;
+
+            default:
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Unrecognized EID=%dd in beacon decode.\n", pItem->byElementID);
+                break;
+
+        }
+        pItem = (PWLAN_IE)(((PBYTE)pItem) + 2 + pItem->len);
+    }
+
+    return;
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *  Encode IBSS ATIM
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+
+VOID
+vMgrEncodeIBSSATIM(
+    IN  PWLAN_FR_IBSSATIM   pFrame
+    )
+{
+    pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+    pFrame->len = WLAN_HDR_ADDR3_LEN;
+
+    return;
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *  Decode IBSS ATIM
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+VOID
+vMgrDecodeIBSSATIM(
+    IN  PWLAN_FR_IBSSATIM   pFrame
+    )
+{
+    pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+    return;
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *  Encode Disassociation
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+VOID
+vMgrEncodeDisassociation(
+    IN  PWLAN_FR_DISASSOC  pFrame
+    )
+{
+    pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+
+    // Fixed Fields
+    pFrame->pwReason = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                               + WLAN_DISASSOC_OFF_REASON);
+    pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_DISASSOC_OFF_REASON + sizeof(*(pFrame->pwReason));
+
+    return;
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *  Decode Disassociation
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+VOID
+vMgrDecodeDisassociation(
+    IN  PWLAN_FR_DISASSOC  pFrame
+    )
+{
+    pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+    // Fixed Fields
+    pFrame->pwReason = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                               + WLAN_DISASSOC_OFF_REASON);
+
+    return;
+}
+
+/*+
+ *
+ * Routine Description:
+ *  Encode Association Request
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+
+VOID
+vMgrEncodeAssocRequest(
+    IN  PWLAN_FR_ASSOCREQ  pFrame
+    )
+{
+    pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+    // Fixed Fields
+    pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                + WLAN_ASSOCREQ_OFF_CAP_INFO);
+    pFrame->pwListenInterval = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                       + WLAN_ASSOCREQ_OFF_LISTEN_INT);
+    pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_ASSOCREQ_OFF_LISTEN_INT + sizeof(*(pFrame->pwListenInterval));
+    return;
+}
+
+
+/*+
+ *
+ * Routine Description: (AP)
+ *  Decode Association Request
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+VOID
+vMgrDecodeAssocRequest(
+    IN  PWLAN_FR_ASSOCREQ  pFrame
+    )
+{
+    PWLAN_IE   pItem;
+
+    pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+    // Fixed Fields
+    pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                + WLAN_ASSOCREQ_OFF_CAP_INFO);
+    pFrame->pwListenInterval = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                + WLAN_ASSOCREQ_OFF_LISTEN_INT);
+
+    // Information elements
+    pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                            + WLAN_ASSOCREQ_OFF_SSID);
+
+    while (((PBYTE)pItem) < (pFrame->pBuf + pFrame->len)) {
+        switch (pItem->byElementID){
+            case WLAN_EID_SSID:
+                if (pFrame->pSSID == NULL)
+                    pFrame->pSSID = (PWLAN_IE_SSID)pItem;
+                break;
+            case WLAN_EID_SUPP_RATES:
+                if (pFrame->pSuppRates == NULL)
+                    pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
+                break;
+
+            case WLAN_EID_RSN:
+                if (pFrame->pRSN == NULL) {
+                    pFrame->pRSN = (PWLAN_IE_RSN)pItem;
+                }
+                break;
+            case WLAN_EID_RSN_WPA:
+                if (pFrame->pRSNWPA == NULL) {
+                    if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == TRUE)
+                        pFrame->pRSNWPA = (PWLAN_IE_RSN_EXT)pItem;
+                }
+                break;
+            case WLAN_EID_EXTSUPP_RATES:
+                if (pFrame->pExtSuppRates == NULL)
+                    pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
+                break;
+
+            default:
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Unrecognized EID=%dd in assocreq decode.\n",
+                        pItem->byElementID);
+                break;
+        }
+        pItem = (PWLAN_IE)(((PBYTE)pItem) + 2 + pItem->len);
+    }
+    return;
+}
+
+/*+
+ *
+ * Routine Description: (AP)
+ *  Encode Association Response
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+VOID
+vMgrEncodeAssocResponse(
+    IN  PWLAN_FR_ASSOCRESP  pFrame
+     )
+{
+    pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+    // Fixed Fields
+    pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                + WLAN_ASSOCRESP_OFF_CAP_INFO);
+    pFrame->pwStatus = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                               + WLAN_ASSOCRESP_OFF_STATUS);
+    pFrame->pwAid = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                            + WLAN_ASSOCRESP_OFF_AID);
+    pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_ASSOCRESP_OFF_AID
+                  + sizeof(*(pFrame->pwAid));
+
+    return;
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *  Decode Association Response
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+VOID
+vMgrDecodeAssocResponse(
+    IN PWLAN_FR_ASSOCRESP  pFrame
+     )
+{
+    PWLAN_IE   pItem;
+
+    pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+    // Fixed Fields
+    pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                + WLAN_ASSOCRESP_OFF_CAP_INFO);
+    pFrame->pwStatus = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                               + WLAN_ASSOCRESP_OFF_STATUS);
+    pFrame->pwAid = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                            + WLAN_ASSOCRESP_OFF_AID);
+
+    // Information elements
+    pFrame->pSuppRates  = (PWLAN_IE_SUPP_RATES)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                           + WLAN_ASSOCRESP_OFF_SUPP_RATES);
+
+    pItem = (PWLAN_IE)(pFrame->pSuppRates);
+    pItem = (PWLAN_IE)(((PBYTE)pItem) + 2 + pItem->len);
+
+    if ((((PBYTE)pItem) < (pFrame->pBuf + pFrame->len)) && (pItem->byElementID == WLAN_EID_EXTSUPP_RATES)) {
+        pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pFrame->pExtSuppRates=[%p].\n", pItem);
+    }
+    else {
+        pFrame->pExtSuppRates = NULL;
+    }
+    return;
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *  Encode Reassociation Request
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+VOID
+vMgrEncodeReassocRequest(
+    IN  PWLAN_FR_REASSOCREQ  pFrame
+     )
+{
+    pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+    // Fixed Fields
+    pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                + WLAN_REASSOCREQ_OFF_CAP_INFO);
+    pFrame->pwListenInterval = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                      + WLAN_REASSOCREQ_OFF_LISTEN_INT);
+    pFrame->pAddrCurrAP = (PIEEE_ADDR)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                       + WLAN_REASSOCREQ_OFF_CURR_AP);
+    pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_REASSOCREQ_OFF_CURR_AP + sizeof(*(pFrame->pAddrCurrAP));
+
+    return;
+}
+
+
+/*+
+ *
+ * Routine Description: (AP)
+ *  Decode Reassociation Request
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+
+VOID
+vMgrDecodeReassocRequest(
+    IN  PWLAN_FR_REASSOCREQ  pFrame
+     )
+{
+    PWLAN_IE   pItem;
+    pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+    // Fixed Fields
+    pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                + WLAN_REASSOCREQ_OFF_CAP_INFO);
+    pFrame->pwListenInterval = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                      + WLAN_REASSOCREQ_OFF_LISTEN_INT);
+    pFrame->pAddrCurrAP = (PIEEE_ADDR)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                       + WLAN_REASSOCREQ_OFF_CURR_AP);
+
+    // Information elements
+    pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                       + WLAN_REASSOCREQ_OFF_SSID);
+
+    while(((PBYTE)pItem) < (pFrame->pBuf + pFrame->len)) {
+
+        switch (pItem->byElementID){
+            case WLAN_EID_SSID:
+                if (pFrame->pSSID == NULL)
+                    pFrame->pSSID = (PWLAN_IE_SSID)pItem;
+                break;
+            case WLAN_EID_SUPP_RATES:
+                if (pFrame->pSuppRates == NULL)
+                    pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
+                break;
+
+            case WLAN_EID_RSN:
+                if (pFrame->pRSN == NULL) {
+                    pFrame->pRSN = (PWLAN_IE_RSN)pItem;
+                }
+                break;
+            case WLAN_EID_RSN_WPA:
+                if (pFrame->pRSNWPA == NULL) {
+                    if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == TRUE)
+                        pFrame->pRSNWPA = (PWLAN_IE_RSN_EXT)pItem;
+                }
+                break;
+
+            case WLAN_EID_EXTSUPP_RATES:
+                if (pFrame->pExtSuppRates == NULL)
+                    pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
+                break;
+            default:
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Unrecognized EID=%dd in reassocreq decode.\n",
+                            pItem->byElementID);
+                break;
+        }
+        pItem = (PWLAN_IE)(((PBYTE)pItem) + 2 + pItem->len);
+    }
+    return;
+}
+
+
+
+/*+
+ *
+ * Routine Description:
+ *  Encode Probe Request
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+
+VOID
+vMgrEncodeProbeRequest(
+    IN PWLAN_FR_PROBEREQ  pFrame
+     )
+{
+    pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+    pFrame->len = WLAN_HDR_ADDR3_LEN;
+    return;
+}
+
+/*+
+ *
+ * Routine Description:
+ *  Decode Probe Request
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+VOID
+vMgrDecodeProbeRequest(
+    IN PWLAN_FR_PROBEREQ  pFrame
+     )
+{
+    PWLAN_IE   pItem;
+
+    pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+    // Information elements
+    pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)));
+
+    while( ((PBYTE)pItem) < (pFrame->pBuf + pFrame->len) ) {
+
+        switch (pItem->byElementID) {
+            case WLAN_EID_SSID:
+                if (pFrame->pSSID == NULL)
+                    pFrame->pSSID = (PWLAN_IE_SSID)pItem;
+                break;
+
+            case WLAN_EID_SUPP_RATES:
+                if (pFrame->pSuppRates == NULL)
+                    pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
+                break;
+
+            case WLAN_EID_EXTSUPP_RATES:
+                if (pFrame->pExtSuppRates == NULL)
+                    pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
+                break;
+
+            default:
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Bad EID=%dd in probereq\n", pItem->byElementID);
+                break;
+        }
+
+        pItem = (PWLAN_IE)(((PBYTE)pItem) + 2 +  pItem->len);
+    }
+    return;
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *  Encode Probe Response
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+
+VOID
+vMgrEncodeProbeResponse(
+    IN PWLAN_FR_PROBERESP  pFrame
+    )
+{
+    pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+    // Fixed Fields
+    pFrame->pqwTimestamp = (PQWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                    + WLAN_PROBERESP_OFF_TS);
+    pFrame->pwBeaconInterval = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                       + WLAN_PROBERESP_OFF_BCN_INT);
+    pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                + WLAN_PROBERESP_OFF_CAP_INFO);
+
+    pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_PROBERESP_OFF_CAP_INFO +
+                  sizeof(*(pFrame->pwCapInfo));
+
+    return;
+}
+
+
+
+/*+
+ *
+ * Routine Description:
+ *  Decode Probe Response
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+VOID
+vMgrDecodeProbeResponse(
+    IN PWLAN_FR_PROBERESP  pFrame
+    )
+{
+    PWLAN_IE    pItem;
+  //  BYTE        byCheckEID = 0;
+
+
+    pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+    // Fixed Fields
+    pFrame->pqwTimestamp = (PQWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                    + WLAN_PROBERESP_OFF_TS);
+    pFrame->pwBeaconInterval = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                       + WLAN_PROBERESP_OFF_BCN_INT);
+    pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                + WLAN_PROBERESP_OFF_CAP_INFO);
+
+    // Information elements
+    pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                       + WLAN_PROBERESP_OFF_SSID);
+
+    while( ((PBYTE)pItem) < (pFrame->pBuf + pFrame->len) ) {
+
+	  //20080701-01,<Remark> by Mike Liu
+      //  if (pItem->byElementID < byCheckEID)
+        //    break;
+        //else
+            //byCheckEID = pItem->byElementID;
+
+        switch (pItem->byElementID) {
+            case WLAN_EID_SSID:
+                if (pFrame->pSSID == NULL)
+                pFrame->pSSID = (PWLAN_IE_SSID)pItem;
+                break;
+            case WLAN_EID_SUPP_RATES:
+                if (pFrame->pSuppRates == NULL)
+                pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
+                break;
+            case WLAN_EID_FH_PARMS:
+                break;
+            case WLAN_EID_DS_PARMS:
+                if (pFrame->pDSParms == NULL)
+                    pFrame->pDSParms = (PWLAN_IE_DS_PARMS)pItem;
+                break;
+            case WLAN_EID_CF_PARMS:
+                if (pFrame->pCFParms == NULL)
+                    pFrame->pCFParms = (PWLAN_IE_CF_PARMS)pItem;
+                break;
+            case WLAN_EID_IBSS_PARMS:
+                if (pFrame->pIBSSParms == NULL)
+                    pFrame->pIBSSParms = (PWLAN_IE_IBSS_PARMS)pItem;
+                break;
+
+            case WLAN_EID_RSN:
+                if (pFrame->pRSN == NULL) {
+                    pFrame->pRSN = (PWLAN_IE_RSN)pItem;
+                }
+                break;
+            case WLAN_EID_RSN_WPA:
+                if (pFrame->pRSNWPA == NULL) {
+                    if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == TRUE)
+                        pFrame->pRSNWPA = (PWLAN_IE_RSN_EXT)pItem;
+                }
+                break;
+            case WLAN_EID_ERP:
+                if (pFrame->pERP == NULL)
+                    pFrame->pERP = (PWLAN_IE_ERP)pItem;
+                break;
+            case WLAN_EID_EXTSUPP_RATES:
+                if (pFrame->pExtSuppRates == NULL)
+                    pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
+                break;
+
+            case WLAN_EID_COUNTRY:      //7
+                if (pFrame->pIE_Country == NULL)
+                    pFrame->pIE_Country = (PWLAN_IE_COUNTRY)pItem;
+                break;
+
+            case WLAN_EID_PWR_CONSTRAINT:   //32
+                if (pFrame->pIE_PowerConstraint == NULL)
+                    pFrame->pIE_PowerConstraint = (PWLAN_IE_PW_CONST)pItem;
+                break;
+
+            case WLAN_EID_CH_SWITCH:    //37
+                if (pFrame->pIE_CHSW == NULL)
+                    pFrame->pIE_CHSW = (PWLAN_IE_CH_SW)pItem;
+                break;
+
+            case WLAN_EID_QUIET:        //40
+                if (pFrame->pIE_Quiet == NULL)
+                    pFrame->pIE_Quiet = (PWLAN_IE_QUIET)pItem;
+                break;
+
+            case WLAN_EID_IBSS_DFS:
+                if (pFrame->pIE_IBSSDFS == NULL)
+                    pFrame->pIE_IBSSDFS = (PWLAN_IE_IBSS_DFS)pItem;
+                break;
+
+            default:
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Bad EID=%dd in proberesp\n", pItem->byElementID);
+                break;
+        }
+
+        pItem = (PWLAN_IE)(((PBYTE)pItem) + 2 +  pItem->len);
+    }
+    return;
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *     Encode Authentication frame
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+VOID
+vMgrEncodeAuthen(
+    IN  PWLAN_FR_AUTHEN  pFrame
+    )
+{
+    pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+    // Fixed Fields
+    pFrame->pwAuthAlgorithm = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                      + WLAN_AUTHEN_OFF_AUTH_ALG);
+    pFrame->pwAuthSequence = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                     + WLAN_AUTHEN_OFF_AUTH_SEQ);
+    pFrame->pwStatus = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                               + WLAN_AUTHEN_OFF_STATUS);
+    pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_AUTHEN_OFF_STATUS + sizeof(*(pFrame->pwStatus));
+
+    return;
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *   Decode Authentication
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+VOID
+vMgrDecodeAuthen(
+    IN  PWLAN_FR_AUTHEN  pFrame
+    )
+{
+    PWLAN_IE    pItem;
+
+    pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+    // Fixed Fields
+    pFrame->pwAuthAlgorithm = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                      + WLAN_AUTHEN_OFF_AUTH_ALG);
+    pFrame->pwAuthSequence = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                     + WLAN_AUTHEN_OFF_AUTH_SEQ);
+    pFrame->pwStatus = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                               + WLAN_AUTHEN_OFF_STATUS);
+
+    // Information elements
+    pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                       + WLAN_AUTHEN_OFF_CHALLENGE);
+
+    if ((((PBYTE)pItem) < (pFrame->pBuf + pFrame->len)) && (pItem->byElementID == WLAN_EID_CHALLENGE)) {
+        pFrame->pChallenge = (PWLAN_IE_CHALLENGE)pItem;
+    }
+
+    return;
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *   Encode Authentication
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+VOID
+vMgrEncodeDeauthen(
+    IN  PWLAN_FR_DEAUTHEN  pFrame
+    )
+{
+    pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+    // Fixed Fields
+    pFrame->pwReason = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                               + WLAN_DEAUTHEN_OFF_REASON);
+    pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_DEAUTHEN_OFF_REASON + sizeof(*(pFrame->pwReason));
+
+    return;
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *   Decode Deauthentication
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+VOID
+vMgrDecodeDeauthen(
+    IN  PWLAN_FR_DEAUTHEN  pFrame
+    )
+{
+    pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+    // Fixed Fields
+    pFrame->pwReason = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                               + WLAN_DEAUTHEN_OFF_REASON);
+
+    return;
+}
+
+
+/*+
+ *
+ * Routine Description: (AP)
+ *   Encode Reassociation Response
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+VOID
+vMgrEncodeReassocResponse(
+    IN  PWLAN_FR_REASSOCRESP  pFrame
+     )
+{
+    pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+    // Fixed Fields
+    pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                + WLAN_REASSOCRESP_OFF_CAP_INFO);
+    pFrame->pwStatus = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                               + WLAN_REASSOCRESP_OFF_STATUS);
+    pFrame->pwAid = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                            + WLAN_REASSOCRESP_OFF_AID);
+
+    pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_REASSOCRESP_OFF_AID + sizeof(*(pFrame->pwAid));
+
+    return;
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *   Decode Reassociation Response
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+
+VOID
+vMgrDecodeReassocResponse(
+    IN  PWLAN_FR_REASSOCRESP  pFrame
+     )
+{
+    PWLAN_IE   pItem;
+
+    pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+    // Fixed Fields
+    pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                + WLAN_REASSOCRESP_OFF_CAP_INFO);
+    pFrame->pwStatus = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                               + WLAN_REASSOCRESP_OFF_STATUS);
+    pFrame->pwAid = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                            + WLAN_REASSOCRESP_OFF_AID);
+
+    //Information elements
+    pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                               + WLAN_REASSOCRESP_OFF_SUPP_RATES);
+
+    pItem = (PWLAN_IE)(pFrame->pSuppRates);
+    pItem = (PWLAN_IE)(((PBYTE)pItem) + 2 + pItem->len);
+
+    if ((((PBYTE)pItem) < (pFrame->pBuf + pFrame->len)) && (pItem->byElementID == WLAN_EID_EXTSUPP_RATES)) {
+        pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
+    }
+    return;
+}
diff --git a/drivers/staging/vt6656/80211mgr.h b/drivers/staging/vt6656/80211mgr.h
new file mode 100644
index 0000000..d94bfb9
--- /dev/null
+++ b/drivers/staging/vt6656/80211mgr.h
@@ -0,0 +1,867 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: 80211mgr.h
+ *
+ * Purpose: 802.11 managment frames pre-defines.
+ *
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: May 8, 2002
+ *
+ */
+
+
+#ifndef __80211MGR_H__
+#define __80211MGR_H__
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+#if !defined(__80211HDR_H__)
+#include "80211hdr.h"
+#endif
+
+
+/*---------------------  Export Definitions -------------------------*/
+
+#define WLAN_MIN_ARRAY          1
+
+// Information Element ID value
+#define WLAN_EID_SSID           0
+#define WLAN_EID_SUPP_RATES     1
+#define WLAN_EID_FH_PARMS       2
+#define WLAN_EID_DS_PARMS       3
+#define WLAN_EID_CF_PARMS       4
+#define WLAN_EID_TIM            5
+#define WLAN_EID_IBSS_PARMS     6
+#define WLAN_EID_COUNTRY        7
+#define WLAN_EID_CHALLENGE      16
+#define WLAN_EID_PWR_CONSTRAINT 32
+#define WLAN_EID_PWR_CAPABILITY 33
+#define WLAN_EID_TPC_REQ        34
+#define WLAN_EID_TPC_REP        35
+#define WLAN_EID_SUPP_CH        36
+#define WLAN_EID_CH_SWITCH      37
+#define WLAN_EID_MEASURE_REQ    38
+#define WLAN_EID_MEASURE_REP    39
+#define WLAN_EID_QUIET          40
+#define WLAN_EID_IBSS_DFS       41
+#define WLAN_EID_ERP            42
+// reference 802.11i 7.3.2 table 20
+#define WLAN_EID_RSN            48
+#define WLAN_EID_EXTSUPP_RATES  50
+// reference WiFi WPA spec.
+#define WLAN_EID_RSN_WPA        221
+
+#ifdef Cisco_ccx
+#define WLAN_EID_CCX        133            //DavidWang
+#define WLAN_EID_CCX_IP        149            //DavidWang
+#define WLAN_EID_CCX_Ver        221            //DavidWang
+#endif
+
+#define WLAN_EID_ERP_NONERP_PRESENT             0x01
+#define WLAN_EID_ERP_USE_PROTECTION             0x02
+#define WLAN_EID_ERP_BARKER_MODE                0x04
+
+// Reason Codes
+#define WLAN_MGMT_REASON_RSVD                       0
+#define WLAN_MGMT_REASON_UNSPEC                     1
+#define WLAN_MGMT_REASON_PRIOR_AUTH_INVALID         2
+#define WLAN_MGMT_REASON_DEAUTH_LEAVING             3
+#define WLAN_MGMT_REASON_DISASSOC_INACTIVE          4
+#define WLAN_MGMT_REASON_DISASSOC_AP_BUSY           5
+#define WLAN_MGMT_REASON_CLASS2_NONAUTH             6
+#define WLAN_MGMT_REASON_CLASS3_NONASSOC            7
+#define WLAN_MGMT_REASON_DISASSOC_STA_HASLEFT       8
+#define WLAN_MGMT_REASON_CANT_ASSOC_NONAUTH         9
+#define WLAN_MGMT_REASON_DISASSOC_PWR_CAP_UNACCEPT      10
+#define WLAN_MGMT_REASON_DISASSOC_SUPP_CH_UNACCEPT      11
+#define WLAN_MGMT_REASON_INVALID_IE                 13
+#define WLAN_MGMT_REASON_MIC_FAILURE                14
+#define WLAN_MGMT_REASON_4WAY_HANDSHAKE_TIMEOUT     15
+#define WLAN_MGMT_REASON_GRPKEY_UPDATE_TIMEOUT      16
+#define WLAN_MGMT_REASON_4WAY_INFO_DIFFERENT        17
+#define WLAN_MGMT_REASON_MULTCAST_CIPHER_INVALID    18
+#define WLAN_MGMT_REASON_UNCAST_CIPHER_INVALID      19
+#define WLAN_MGMT_REASON_AKMP_INVALID               20
+#define WLAN_MGMT_REASON_RSNE_UNSUPPORTED           21
+#define WLAN_MGMT_REASON_RSNE_CAP_INVALID           22
+#define WLAN_MGMT_REASON_80211X_AUTH_FAILED         23
+
+// Status Codes
+#define WLAN_MGMT_STATUS_SUCCESS                        0
+#define WLAN_MGMT_STATUS_UNSPEC_FAILURE                 1
+#define WLAN_MGMT_STATUS_CAPS_UNSUPPORTED               10
+#define WLAN_MGMT_STATUS_REASSOC_NO_ASSOC               11
+#define WLAN_MGMT_STATUS_ASSOC_DENIED_UNSPEC            12
+#define WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG            13
+#define WLAN_MGMT_STATUS_RX_AUTH_NOSEQ                  14
+#define WLAN_MGMT_STATUS_CHALLENGE_FAIL                 15
+#define WLAN_MGMT_STATUS_AUTH_TIMEOUT                   16
+#define WLAN_MGMT_STATUS_ASSOC_DENIED_BUSY              17
+#define WLAN_MGMT_STATUS_ASSOC_DENIED_RATES             18
+#define WLAN_MGMT_STATUS_ASSOC_DENIED_SHORTPREAMBLE     19
+#define WLAN_MGMT_STATUS_ASSOC_DENIED_PBCC              20
+#define WLAN_MGMT_STATUS_ASSOC_DENIED_AGILITY           21
+
+// reference 802.11h 7.3.1.9
+//
+#define WLAN_MGMT_STATUS_ASSOC_REJECT_BCS_SPECTRUM_MNG  22
+#define WLAN_MGMT_STATUS_ASSOC_REJECT_BCS_PWR_CAP       23
+#define WLAN_MGMT_STATUS_ASSOC_REJECT_BCS_SUPP_CH       24
+//
+// reference 802.11g 7.3.1.9
+//
+#define WLAN_MGMT_STATUS_SHORTSLOTTIME_UNSUPPORTED      25
+#define WLAN_MGMT_STATUS_DSSSOFDM_UNSUPPORTED           26
+//
+// reference 802.11i 7.3.1.9 table 19
+//
+#define WLAN_MGMT_STATUS_INVALID_IE                     40
+#define WLAN_MGMT_STATUS_GROUP_CIPHER_INVALID           41
+#define WLAN_MGMT_STATUS_PAIRWISE_CIPHER_INVALID        42
+#define WLAN_MGMT_STATUS_AKMP_INVALID                   43
+#define WLAN_MGMT_STATUS_UNSUPPORT_RSN_IE_VER           44
+#define WLAN_MGMT_STATUS_INVALID_RSN_IE_CAP             45
+#define WLAN_MGMT_STATUS_CIPHER_REJECT                  46
+
+
+
+// Auth Algorithm
+#define WLAN_AUTH_ALG_OPENSYSTEM                0
+#define WLAN_AUTH_ALG_SHAREDKEY                 1
+
+
+
+// Management Frame Field Offsets
+// Note: Not all fields are listed because of variable lengths.
+// Note: These offsets are from the start of the frame data
+
+#define WLAN_BEACON_OFF_TS                  0
+#define WLAN_BEACON_OFF_BCN_INT             8
+#define WLAN_BEACON_OFF_CAPINFO             10
+#define WLAN_BEACON_OFF_SSID                12
+
+#define WLAN_DISASSOC_OFF_REASON            0
+
+#define WLAN_ASSOCREQ_OFF_CAP_INFO          0
+#define WLAN_ASSOCREQ_OFF_LISTEN_INT        2
+#define WLAN_ASSOCREQ_OFF_SSID              4
+
+#define WLAN_ASSOCRESP_OFF_CAP_INFO         0
+#define WLAN_ASSOCRESP_OFF_STATUS           2
+#define WLAN_ASSOCRESP_OFF_AID              4
+#define WLAN_ASSOCRESP_OFF_SUPP_RATES       6
+
+#define WLAN_REASSOCREQ_OFF_CAP_INFO        0
+#define WLAN_REASSOCREQ_OFF_LISTEN_INT      2
+#define WLAN_REASSOCREQ_OFF_CURR_AP         4
+#define WLAN_REASSOCREQ_OFF_SSID            10
+
+#define WLAN_REASSOCRESP_OFF_CAP_INFO       0
+#define WLAN_REASSOCRESP_OFF_STATUS         2
+#define WLAN_REASSOCRESP_OFF_AID            4
+#define WLAN_REASSOCRESP_OFF_SUPP_RATES     6
+
+#define WLAN_PROBEREQ_OFF_SSID              0
+
+#define WLAN_PROBERESP_OFF_TS               0
+#define WLAN_PROBERESP_OFF_BCN_INT          8
+#define WLAN_PROBERESP_OFF_CAP_INFO         10
+#define WLAN_PROBERESP_OFF_SSID             12
+
+#define WLAN_AUTHEN_OFF_AUTH_ALG            0
+#define WLAN_AUTHEN_OFF_AUTH_SEQ            2
+#define WLAN_AUTHEN_OFF_STATUS              4
+#define WLAN_AUTHEN_OFF_CHALLENGE           6
+
+#define WLAN_DEAUTHEN_OFF_REASON            0
+
+
+//
+// Cipher Suite Selectors defiened in 802.11i
+//
+#define WLAN_11i_CSS_USE_GROUP              0
+#define WLAN_11i_CSS_WEP40                  1
+#define WLAN_11i_CSS_TKIP                   2
+#define WLAN_11i_CSS_CCMP                   4
+#define WLAN_11i_CSS_WEP104                 5
+#define WLAN_11i_CSS_UNKNOWN                255
+
+//
+// Authentication and Key Management Suite Selectors defined in 802.11i
+//
+#define WLAN_11i_AKMSS_802_1X               1
+#define WLAN_11i_AKMSS_PSK                  2
+#define WLAN_11i_AKMSS_UNKNOWN              255
+
+// Measurement type definitions reference ieee 802.11h Table 20b
+#define MEASURE_TYPE_BASIC      0
+#define MEASURE_TYPE_CCA        1
+#define MEASURE_TYPE_RPI        2
+
+// Measurement request mode definitions reference ieee 802.11h Figure 46h
+#define MEASURE_MODE_ENABLE     0x02
+#define MEASURE_MODE_REQ        0x04
+#define MEASURE_MODE_REP        0x08
+
+// Measurement report mode definitions reference ieee 802.11h Figure 46m
+#define MEASURE_MODE_LATE       0x01
+#define MEASURE_MODE_INCAPABLE  0x02
+#define MEASURE_MODE_REFUSED    0x04
+
+
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Types  ------------------------------*/
+
+
+// Information Element Types
+
+#pragma pack(1)
+typedef struct tagWLAN_IE {
+    BYTE   byElementID;
+    BYTE   len;
+}__attribute__ ((__packed__))
+WLAN_IE, *PWLAN_IE;
+
+
+// Service Set Identity (SSID)
+#pragma pack(1)
+typedef struct tagWLAN_IE_SSID {
+    BYTE   byElementID;
+    BYTE   len;
+    BYTE   abySSID[1];
+}__attribute__ ((__packed__))
+WLAN_IE_SSID, *PWLAN_IE_SSID;
+
+
+// Supported Rates
+#pragma pack(1)
+typedef struct tagWLAN_IE_SUPP_RATES {
+    BYTE   byElementID;
+    BYTE   len;
+    BYTE   abyRates[1];
+}__attribute__ ((__packed__))
+WLAN_IE_SUPP_RATES,  *PWLAN_IE_SUPP_RATES;
+
+
+
+// FH Parameter Set
+#pragma pack(1)
+typedef struct _WLAN_IE_FH_PARMS {
+    BYTE    byElementID;
+    BYTE    len;
+    WORD    wDwellTime;
+    BYTE    byHopSet;
+    BYTE    byHopPattern;
+    BYTE    byHopIndex;
+} WLAN_IE_FH_PARMS,  *PWLAN_IE_FH_PARMS;
+
+// DS Parameter Set
+#pragma pack(1)
+typedef struct tagWLAN_IE_DS_PARMS {
+    BYTE   byElementID;
+    BYTE   len;
+    BYTE   byCurrChannel;
+}__attribute__ ((__packed__))
+WLAN_IE_DS_PARMS,  *PWLAN_IE_DS_PARMS;
+
+
+// CF Parameter Set
+#pragma pack(1)
+typedef struct tagWLAN_IE_CF_PARMS {
+    BYTE   byElementID;
+    BYTE   len;
+    BYTE   byCFPCount;
+    BYTE   byCFPPeriod;
+    WORD   wCFPMaxDuration;
+    WORD   wCFPDurRemaining;
+}__attribute__ ((__packed__))
+WLAN_IE_CF_PARMS,  *PWLAN_IE_CF_PARMS;
+
+
+// TIM
+#pragma pack(1)
+typedef struct tagWLAN_IE_TIM {
+    BYTE   byElementID;
+    BYTE   len;
+    BYTE   byDTIMCount;
+    BYTE   byDTIMPeriod;
+    BYTE   byBitMapCtl;
+    BYTE   byVirtBitMap[1];
+}__attribute__ ((__packed__))
+WLAN_IE_TIM,  *PWLAN_IE_TIM;
+
+
+// IBSS Parameter Set
+#pragma pack(1)
+typedef struct tagWLAN_IE_IBSS_PARMS {
+    BYTE   byElementID;
+    BYTE   len;
+    WORD   wATIMWindow;
+}__attribute__ ((__packed__))
+WLAN_IE_IBSS_PARMS, *PWLAN_IE_IBSS_PARMS;
+
+
+// Challenge Text
+#pragma pack(1)
+typedef struct tagWLAN_IE_CHALLENGE {
+    BYTE   byElementID;
+    BYTE   len;
+    BYTE   abyChallenge[1];
+}__attribute__ ((__packed__))
+WLAN_IE_CHALLENGE,  *PWLAN_IE_CHALLENGE;
+
+
+#pragma pack(1)
+typedef struct tagWLAN_IE_RSN_EXT {
+    BYTE byElementID;
+    BYTE len;
+    BYTE abyOUI[4];
+    WORD wVersion;
+    BYTE abyMulticast[4];
+    WORD wPKCount;
+    struct {
+        BYTE abyOUI[4];
+    } PKSList[1]; // the rest is variable so need to
+    // overlay ieauth structure
+} WLAN_IE_RSN_EXT, *PWLAN_IE_RSN_EXT;
+
+#pragma pack(1)
+typedef struct tagWLAN_IE_RSN_AUTH {
+    WORD wAuthCount;
+    struct {
+        BYTE abyOUI[4];
+    } AuthKSList[1];
+} WLAN_IE_RSN_AUTH, *PWLAN_IE_RSN_AUTH;
+
+// RSN Identity
+#pragma pack(1)
+typedef struct tagWLAN_IE_RSN {
+    BYTE   byElementID;
+    BYTE   len;
+    WORD   wVersion;
+    BYTE   abyRSN[WLAN_MIN_ARRAY];
+} WLAN_IE_RSN, *PWLAN_IE_RSN;
+
+//DavidWang
+// CCX Identity DavidWang
+#pragma pack(1)
+typedef struct tagWLAN_IE_CCX {
+BYTE   byElementID;
+BYTE   len;
+BYTE   abyCCX[30];
+} WLAN_IE_CCX, *PWLAN_IE_CCX;
+#pragma pack(1)
+typedef struct tagWLAN_IE_CCX_IP {
+BYTE   byElementID;
+BYTE   len;
+BYTE   abyCCXOUI[4];
+BYTE   abyCCXIP[4];
+BYTE   abyCCXREV[2];
+} WLAN_IE_CCX_IP, *PWLAN_IE_CCX_IP;
+#pragma pack(1)
+typedef struct tagWLAN_IE_CCX_Ver {
+BYTE   byElementID;
+BYTE   len;
+BYTE   abyCCXVer[5];
+} WLAN_IE_CCX_Ver, *PWLAN_IE_CCX_Ver;
+
+//DavidWang
+
+// ERP
+#pragma pack(1)
+typedef struct tagWLAN_IE_ERP {
+    BYTE   byElementID;
+    BYTE   len;
+    BYTE   byContext;
+}__attribute__ ((__packed__))
+WLAN_IE_ERP,  *PWLAN_IE_ERP;
+
+
+#pragma pack(1)
+typedef struct _MEASEURE_REQ {
+    BYTE                byChannel;
+    BYTE                abyStartTime[8];
+    BYTE                abyDuration[2];
+} MEASEURE_REQ, *PMEASEURE_REQ,
+  MEASEURE_REQ_BASIC, *PMEASEURE_REQ_BASIC,
+  MEASEURE_REQ_CCA, *PMEASEURE_REQ_CCA,
+  MEASEURE_REQ_RPI, *PMEASEURE_REQ_RPI;
+
+typedef struct _MEASEURE_REP_BASIC {
+    BYTE                byChannel;
+    BYTE                abyStartTime[8];
+    BYTE                abyDuration[2];
+    BYTE                byMap;
+} MEASEURE_REP_BASIC, *PMEASEURE_REP_BASIC;
+
+typedef struct _MEASEURE_REP_CCA {
+    BYTE                byChannel;
+    BYTE                abyStartTime[8];
+    BYTE                abyDuration[2];
+    BYTE                byCCABusyFraction;
+} MEASEURE_REP_CCA, *PMEASEURE_REP_CCA;
+
+typedef struct _MEASEURE_REP_RPI {
+    BYTE                byChannel;
+    BYTE                abyStartTime[8];
+    BYTE                abyDuration[2];
+    BYTE                abyRPIdensity[8];
+} MEASEURE_REP_RPI, *PMEASEURE_REP_RPI;
+
+typedef union _MEASEURE_REP {
+
+    MEASEURE_REP_BASIC  sBasic;
+    MEASEURE_REP_CCA    sCCA;
+    MEASEURE_REP_RPI    sRPI;
+
+} MEASEURE_REP, *PMEASEURE_REP;
+
+typedef struct _WLAN_IE_MEASURE_REQ {
+    BYTE                byElementID;
+    BYTE                len;
+    BYTE                byToken;
+    BYTE                byMode;
+    BYTE                byType;
+    MEASEURE_REQ        sReq;
+} WLAN_IE_MEASURE_REQ, *PWLAN_IE_MEASURE_REQ;
+
+typedef struct _WLAN_IE_MEASURE_REP {
+    BYTE                byElementID;
+    BYTE                len;
+    BYTE                byToken;
+    BYTE                byMode;
+    BYTE                byType;
+    MEASEURE_REP        sRep;
+} WLAN_IE_MEASURE_REP, *PWLAN_IE_MEASURE_REP;
+
+typedef struct _WLAN_IE_CH_SW {
+    BYTE                byElementID;
+    BYTE                len;
+    BYTE                byMode;
+    BYTE                byChannel;
+    BYTE                byCount;
+} WLAN_IE_CH_SW, *PWLAN_IE_CH_SW;
+
+typedef struct _WLAN_IE_QUIET {
+    BYTE                byElementID;
+    BYTE                len;
+    BYTE                byQuietCount;
+    BYTE                byQuietPeriod;
+    BYTE                abyQuietDuration[2];
+    BYTE                abyQuietOffset[2];
+} WLAN_IE_QUIET, *PWLAN_IE_QUIET;
+
+typedef struct _WLAN_IE_COUNTRY {
+    BYTE                byElementID;
+    BYTE                len;
+    BYTE                abyCountryString[3];
+    BYTE                abyCountryInfo[3];
+} WLAN_IE_COUNTRY, *PWLAN_IE_COUNTRY;
+
+typedef struct _WLAN_IE_PW_CONST {
+    BYTE                byElementID;
+    BYTE                len;
+    BYTE                byPower;
+} WLAN_IE_PW_CONST, *PWLAN_IE_PW_CONST;
+
+typedef struct _WLAN_IE_PW_CAP {
+    BYTE                byElementID;
+    BYTE                len;
+    BYTE                byMinPower;
+    BYTE                byMaxPower;
+} WLAN_IE_PW_CAP, *PWLAN_IE_PW_CAP;
+
+typedef struct _WLAN_IE_SUPP_CH {
+    BYTE                byElementID;
+    BYTE                len;
+    BYTE                abyChannelTuple[2];
+} WLAN_IE_SUPP_CH, *PWLAN_IE_SUPP_CH;
+
+typedef struct _WLAN_IE_TPC_REQ {
+    BYTE                byElementID;
+    BYTE                len;
+} WLAN_IE_TPC_REQ, *PWLAN_IE_TPC_REQ;
+
+typedef struct _WLAN_IE_TPC_REP {
+    BYTE                byElementID;
+    BYTE                len;
+    BYTE                byTxPower;
+    BYTE                byLinkMargin;
+} WLAN_IE_TPC_REP, *PWLAN_IE_TPC_REP;
+
+
+typedef struct _WLAN_IE_IBSS_DFS {
+    BYTE                byElementID;
+    BYTE                len;
+    BYTE                abyDFSOwner[6];
+    BYTE                byDFSRecovery;
+    BYTE                abyChannelMap[2];
+} WLAN_IE_IBSS_DFS, *PWLAN_IE_IBSS_DFS;
+
+#pragma pack()
+
+
+
+// Frame Types
+// prototype structure, all mgmt frame types will start with these members
+typedef struct tagWLAN_FR_MGMT {
+
+    UINT                  uType;
+    UINT                  len;
+    PBYTE                 pBuf;
+    PUWLAN_80211HDR       pHdr;
+
+} WLAN_FR_MGMT,  *PWLAN_FR_MGMT;
+
+// Beacon frame
+typedef struct tagWLAN_FR_BEACON {
+
+    UINT                    uType;
+    UINT                    len;
+    PBYTE                   pBuf;
+    PUWLAN_80211HDR         pHdr;
+    // fixed fields
+    PQWORD                  pqwTimestamp;
+    PWORD                   pwBeaconInterval;
+    PWORD                   pwCapInfo;
+    /*-- info elements ----------*/
+    PWLAN_IE_SSID           pSSID;
+    PWLAN_IE_SUPP_RATES     pSuppRates;
+//  PWLAN_IE_FH_PARMS       pFHParms;
+    PWLAN_IE_DS_PARMS       pDSParms;
+    PWLAN_IE_CF_PARMS       pCFParms;
+    PWLAN_IE_TIM            pTIM;
+    PWLAN_IE_IBSS_PARMS     pIBSSParms;
+    PWLAN_IE_RSN            pRSN;
+    PWLAN_IE_RSN_EXT        pRSNWPA;
+    PWLAN_IE_ERP            pERP;
+    PWLAN_IE_SUPP_RATES     pExtSuppRates;
+    PWLAN_IE_COUNTRY        pIE_Country;
+    PWLAN_IE_PW_CONST       pIE_PowerConstraint;
+    PWLAN_IE_CH_SW          pIE_CHSW;
+    PWLAN_IE_IBSS_DFS       pIE_IBSSDFS;
+    PWLAN_IE_QUIET          pIE_Quiet;
+
+} WLAN_FR_BEACON, *PWLAN_FR_BEACON;
+
+
+// IBSS ATIM frame
+typedef struct tagWLAN_FR_IBSSATIM {
+
+    UINT                    uType;
+    UINT                    len;
+    PBYTE                   pBuf;
+    PUWLAN_80211HDR         pHdr;
+
+    // fixed fields
+    // info elements
+    // this frame type has a null body
+
+} WLAN_FR_IBSSATIM, *PWLAN_FR_IBSSATIM;
+
+// Disassociation
+typedef struct tagWLAN_FR_DISASSOC {
+
+    UINT                    uType;
+    UINT                    len;
+    PBYTE                   pBuf;
+    PUWLAN_80211HDR         pHdr;
+    /*-- fixed fields -----------*/
+    PWORD                   pwReason;
+    /*-- info elements ----------*/
+
+} WLAN_FR_DISASSOC, *PWLAN_FR_DISASSOC;
+
+// Association Request
+typedef struct tagWLAN_FR_ASSOCREQ {
+
+    UINT                    uType;
+    UINT                    len;
+    PBYTE                   pBuf;
+    PUWLAN_80211HDR         pHdr;
+    /*-- fixed fields -----------*/
+    PWORD                   pwCapInfo;
+    PWORD                   pwListenInterval;
+    /*-- info elements ----------*/
+    PWLAN_IE_SSID           pSSID;
+    PWLAN_IE_SUPP_RATES     pSuppRates;
+    PWLAN_IE_RSN            pRSN;
+    PWLAN_IE_CCX            pCCX;
+    PWLAN_IE_CCX_IP            pCCXIP;
+    PWLAN_IE_CCX_Ver            pCCXVER;
+    PWLAN_IE_RSN_EXT        pRSNWPA;
+    PWLAN_IE_SUPP_RATES     pExtSuppRates;
+    PWLAN_IE_PW_CAP         pCurrPowerCap;
+    PWLAN_IE_SUPP_CH        pCurrSuppCh;
+
+} WLAN_FR_ASSOCREQ, *PWLAN_FR_ASSOCREQ;
+
+// Association Response
+typedef struct tagWLAN_FR_ASSOCRESP {
+
+    UINT                    uType;
+    UINT                    len;
+    PBYTE                   pBuf;
+    PUWLAN_80211HDR         pHdr;
+    /*-- fixed fields -----------*/
+    PWORD                   pwCapInfo;
+    PWORD                   pwStatus;
+    PWORD                   pwAid;
+    /*-- info elements ----------*/
+    PWLAN_IE_SUPP_RATES     pSuppRates;
+    PWLAN_IE_SUPP_RATES     pExtSuppRates;
+
+} WLAN_FR_ASSOCRESP, *PWLAN_FR_ASSOCRESP;
+
+// Reassociation Request
+typedef struct tagWLAN_FR_REASSOCREQ {
+
+    UINT                    uType;
+    UINT                    len;
+    PBYTE                   pBuf;
+    PUWLAN_80211HDR         pHdr;
+
+    /*-- fixed fields -----------*/
+    PWORD                   pwCapInfo;
+    PWORD                   pwListenInterval;
+    PIEEE_ADDR              pAddrCurrAP;
+
+    /*-- info elements ----------*/
+    PWLAN_IE_SSID           pSSID;
+    PWLAN_IE_SUPP_RATES     pSuppRates;
+    PWLAN_IE_RSN            pRSN;
+    PWLAN_IE_CCX            pCCX;
+    PWLAN_IE_CCX_IP            pCCXIP;
+    PWLAN_IE_CCX_Ver            pCCXVER;
+    PWLAN_IE_RSN_EXT        pRSNWPA;
+    PWLAN_IE_SUPP_RATES     pExtSuppRates;
+
+} WLAN_FR_REASSOCREQ, *PWLAN_FR_REASSOCREQ;
+
+// Reassociation Response
+typedef struct tagWLAN_FR_REASSOCRESP {
+
+    UINT                    uType;
+    UINT                    len;
+    PBYTE                   pBuf;
+    PUWLAN_80211HDR         pHdr;
+    /*-- fixed fields -----------*/
+    PWORD                   pwCapInfo;
+    PWORD                   pwStatus;
+    PWORD                   pwAid;
+    /*-- info elements ----------*/
+    PWLAN_IE_SUPP_RATES     pSuppRates;
+    PWLAN_IE_SUPP_RATES     pExtSuppRates;
+
+} WLAN_FR_REASSOCRESP, *PWLAN_FR_REASSOCRESP;
+
+// Probe Request
+typedef struct tagWLAN_FR_PROBEREQ {
+
+    UINT                    uType;
+    UINT                    len;
+    PBYTE                   pBuf;
+    PUWLAN_80211HDR         pHdr;
+    /*-- fixed fields -----------*/
+    /*-- info elements ----------*/
+    PWLAN_IE_SSID           pSSID;
+    PWLAN_IE_SUPP_RATES     pSuppRates;
+    PWLAN_IE_SUPP_RATES     pExtSuppRates;
+
+} WLAN_FR_PROBEREQ, *PWLAN_FR_PROBEREQ;
+
+// Probe Response
+typedef struct tagWLAN_FR_PROBERESP {
+
+    UINT                    uType;
+    UINT                    len;
+    PBYTE                   pBuf;
+    PUWLAN_80211HDR         pHdr;
+    /*-- fixed fields -----------*/
+    PQWORD                  pqwTimestamp;
+    PWORD                   pwBeaconInterval;
+    PWORD                   pwCapInfo;
+    /*-- info elements ----------*/
+    PWLAN_IE_SSID           pSSID;
+    PWLAN_IE_SUPP_RATES     pSuppRates;
+    PWLAN_IE_DS_PARMS       pDSParms;
+    PWLAN_IE_CF_PARMS       pCFParms;
+    PWLAN_IE_IBSS_PARMS     pIBSSParms;
+    PWLAN_IE_RSN            pRSN;
+    PWLAN_IE_RSN_EXT        pRSNWPA;
+    PWLAN_IE_ERP            pERP;
+    PWLAN_IE_SUPP_RATES     pExtSuppRates;
+    PWLAN_IE_COUNTRY        pIE_Country;
+    PWLAN_IE_PW_CONST       pIE_PowerConstraint;
+    PWLAN_IE_CH_SW          pIE_CHSW;
+    PWLAN_IE_IBSS_DFS       pIE_IBSSDFS;
+    PWLAN_IE_QUIET          pIE_Quiet;
+
+} WLAN_FR_PROBERESP, *PWLAN_FR_PROBERESP;
+
+// Authentication
+typedef struct tagWLAN_FR_AUTHEN {
+
+    UINT                    uType;
+    UINT                    len;
+    PBYTE                   pBuf;
+    PUWLAN_80211HDR         pHdr;
+    /*-- fixed fields -----------*/
+    PWORD                   pwAuthAlgorithm;
+    PWORD                   pwAuthSequence;
+    PWORD                   pwStatus;
+    /*-- info elements ----------*/
+    PWLAN_IE_CHALLENGE      pChallenge;
+
+} WLAN_FR_AUTHEN, *PWLAN_FR_AUTHEN;
+
+// Deauthenication
+typedef struct tagWLAN_FR_DEAUTHEN {
+
+    UINT                    uType;
+    UINT                    len;
+    PBYTE                   pBuf;
+    PUWLAN_80211HDR         pHdr;
+    /*-- fixed fields -----------*/
+    PWORD                   pwReason;
+
+    /*-- info elements ----------*/
+
+} WLAN_FR_DEAUTHEN, *PWLAN_FR_DEAUTHEN;
+
+/*---------------------  Export Functions  --------------------------*/
+VOID
+vMgrEncodeBeacon(
+    IN  PWLAN_FR_BEACON  pFrame
+     );
+
+VOID
+vMgrDecodeBeacon(
+    IN  PWLAN_FR_BEACON  pFrame
+    );
+
+VOID
+vMgrEncodeIBSSATIM(
+    IN  PWLAN_FR_IBSSATIM   pFrame
+    );
+
+VOID
+vMgrDecodeIBSSATIM(
+    IN  PWLAN_FR_IBSSATIM   pFrame
+    );
+
+VOID
+vMgrEncodeDisassociation(
+    IN  PWLAN_FR_DISASSOC  pFrame
+    );
+
+VOID
+vMgrDecodeDisassociation(
+    IN  PWLAN_FR_DISASSOC  pFrame
+    );
+
+VOID
+vMgrEncodeAssocRequest(
+    IN  PWLAN_FR_ASSOCREQ  pFrame
+    );
+
+VOID
+vMgrDecodeAssocRequest(
+    IN  PWLAN_FR_ASSOCREQ  pFrame
+    );
+
+VOID
+vMgrEncodeAssocResponse(
+    IN  PWLAN_FR_ASSOCRESP  pFrame
+    );
+
+VOID
+vMgrDecodeAssocResponse(
+    IN PWLAN_FR_ASSOCRESP  pFrame
+    );
+
+VOID
+vMgrEncodeReassocRequest(
+    IN  PWLAN_FR_REASSOCREQ  pFrame
+    );
+
+VOID
+vMgrDecodeReassocRequest(
+    IN  PWLAN_FR_REASSOCREQ  pFrame
+    );
+
+VOID
+vMgrEncodeProbeRequest(
+    IN PWLAN_FR_PROBEREQ  pFrame
+    );
+
+VOID
+vMgrDecodeProbeRequest(
+    IN PWLAN_FR_PROBEREQ  pFrame
+    );
+
+VOID
+vMgrEncodeProbeResponse(
+    IN PWLAN_FR_PROBERESP  pFrame
+    );
+
+VOID
+vMgrDecodeProbeResponse(
+    IN PWLAN_FR_PROBERESP  pFrame
+    );
+
+VOID
+vMgrEncodeAuthen(
+    IN  PWLAN_FR_AUTHEN  pFrame
+    );
+
+VOID
+vMgrDecodeAuthen(
+    IN  PWLAN_FR_AUTHEN  pFrame
+    );
+
+VOID
+vMgrEncodeDeauthen(
+    IN  PWLAN_FR_DEAUTHEN  pFrame
+    );
+
+VOID
+vMgrDecodeDeauthen(
+    IN  PWLAN_FR_DEAUTHEN  pFrame
+    );
+
+VOID
+vMgrEncodeReassocResponse(
+    IN  PWLAN_FR_REASSOCRESP  pFrame
+    );
+
+VOID
+vMgrDecodeReassocResponse(
+    IN  PWLAN_FR_REASSOCRESP  pFrame
+    );
+
+#endif// __80211MGR_H__
diff --git a/drivers/staging/vt6656/Makefile b/drivers/staging/vt6656/Makefile
new file mode 100644
index 0000000..7d20efe
--- /dev/null
+++ b/drivers/staging/vt6656/Makefile
@@ -0,0 +1,204 @@
+#
+# Build options:
+#
+#
+
+HOSTAP := 1
+
+
+KSP := 	/lib/modules/$(shell uname -r)/build \
+	/usr/src/linux-$(shell uname -r) \
+	/usr/src/linux-$(shell uname -r | sed 's/-.*//') \
+	/usr/src/kernel-headers-$(shell uname -r) \
+	/usr/src/kernel-source-$(shell uname -r) \
+	/usr/src/linux-$(shell uname -r | sed 's/\([0-9]*\.[0-9]*\)\..*/\1/') \
+	/usr/src/linux
+
+test_dir = $(shell [ -e $(dir)/include/linux ] && echo $(dir))
+KSP := $(foreach dir, $(KSP), $(test_dir))
+
+KSRC := $(firstword $(KSP))
+
+ifeq (,$(KSRC))
+  $(error Linux kernel source not found)
+endif
+
+# check kernel version
+KVER := $(shell uname -r | cut -c1-3 | sed 's/2\.[56]/2\.6/')
+KERVER2=$(shell uname -r | cut -d. -f2)
+
+ifeq ($(KVER), 2.6)
+# 2.6 kernel
+TARGET = vntwusb.ko
+
+else
+TARGET = vntwusb.o
+
+endif
+
+INSTDIR	:= $(shell find /lib/modules/$(shell uname -r) -name $(TARGET) -printf "%h\n" | sort | head -1)
+ifeq (,$(INSTDIR))
+	ifeq (,$(KERVER2))
+		ifneq (,$(wildcard /lib/modules/$(shell uname -r)/kernel))
+			INSTDIR := /lib/modules/$(shell uname -r)/kernel/drivers/net
+		else
+			INSTDIR := /lib/modules/$(shell uname -r)/net
+		endif
+	else
+		ifneq ($(KERVER2),2)
+			INSTDIR := /lib/modules/$(shell uname -r)/kernel/drivers/net
+		else
+			INSTDIR := /lib/modules/$(shell uname -r)/net
+		endif
+	endif
+endif
+
+
+SRC = main_usb.c card.c mac.c baseband.c wctl.c 80211mgr.c \
+      wcmd.c wmgr.c bssdb.c  wpa2.c rxtx.c dpc.c power.c datarate.c \
+      mib.c rc4.c tether.c tcrc.c ioctl.c hostap.c wpa.c key.c \
+      tkip.c michael.c rf.c iwctl.c wpactl.c aes_ccmp.c \
+      usbpipe.c channel.c control.c firmware.c int.c
+
+
+ifeq ($(HOSTAP), 1)
+#  CFLAGS += -DHOSTAP
+  EXTRA_CFLAGS += -DHOSTAP
+endif
+
+
+#CFLAGS += -I$(PWD) -I$(PWD)/../include -I$(PWD)/include
+EXTRA_CFLAGS += -I$(PWD) -I$(PWD)/../include -I$(PWD)/include
+
+# build rule
+ifeq ($(KVER), 2.6)
+# 2.6 kernel
+
+ifndef KERNEL_CONF
+KERNEL_CONF=	$(KSRC)/.config
+endif
+
+include ${KERNEL_CONF}
+
+obj-m += vntwusb.o
+
+vntwusb-objs :=	main_usb.o card.o mac.o baseband.o wctl.o 80211mgr.o \
+	wcmd.o wmgr.o bssdb.o rxtx.o dpc.o power.o datarate.o  \
+	mib.o rc4.o tether.o tcrc.o ioctl.o hostap.o wpa.o key.o tkip.o \
+	michael.o rf.o iwctl.o wpactl.o wpa2.o aes_ccmp.o  \
+	usbpipe.o channel.o control.o firmware.o int.o
+
+.c.o:
+#	$(CC) $(CFLAGS) -o $@ $<
+	$(CC) $(EXTRA_CFLAGS) -o $@ $<
+
+default:
+	make -C $(KSRC) SUBDIRS=$(shell pwd) modules
+
+else
+
+# 2.2/2.4 kernel
+OBJS :=	main_usb.o card.o mac.o baseband.o wctl.o 80211mgr.o \
+	wcmd.o wmgr.o bssdb.o rxtx.o dpc.o power.o datarate.o \
+	mib.o rc4.o tether.o tcrc.o ioctl.o hostap.o wpa.o key.o tkip.o \
+	michael.o rf.o iwctl.o wpactl.o wpa2.o aes_ccmp.o  \
+	usbpipe.o channel.o control.o
+
+VERSION_FILE := $(KSRC)/include/linux/version.h
+CONFIG_FILE  := $(KSRC)/include/linux/config.h
+
+
+ifeq (,$(wildcard $(VERSION_FILE)))
+  $(error Linux kernel source not configured - missing version.h)
+endif
+
+ifeq (,$(wildcard $(CONFIG_FILE)))
+  $(error Linux kernel source not configured - missing config.h)
+endif
+
+ifneq (,$(findstring egcs-2.91.66, $(shell cat /proc/version)))
+  CC := kgcc gcc cc
+else
+  CC := gcc cc
+endif
+
+test_cc = $(shell which $(cc) > /dev/null 2>&1 && echo $(cc))
+CC := $(foreach cc, $(CC), $(test_cc))
+CC := $(firstword $(CC))
+
+#CFLAGS += -Wall -DLINUX -D__KERNEL__ -DMODULE  -DEXPORT_SYMTAB -D__NO_VERSION__ -O2 -pipe
+#CFLAGS += -I$(KSRC)/include -Wstrict-prototypes -fomit-frame-pointer -fno-strict-aliasing
+#CFLAGS += $(shell [ -f $(KSRC)/include/linux/modversions.h ] && \
+#            echo "-DMODVERSIONS -include $(KSRC)/include/linux/modversions.h")
+EXTRA_CFLAGS += -Wall -DLINUX -D__KERNEL__ -DMODULE  -DEXPORT_SYMTAB -D__NO_VERSION__ -O2 -pipe
+EXTRA_CFLAGS += -I$(KSRC)/include -Wstrict-prototypes -fomit-frame-pointer -fno-strict-aliasing
+EXTRA_CFLAGS += $(shell [ -f $(KSRC)/include/linux/modversions.h ] && \
+            echo "-DMODVERSIONS -include $(KSRC)/include/linux/modversions.h")
+
+.SILENT: $(TARGET) clean
+
+
+# look for SMP in config.h
+#SMP := $(shell $(CC) $(CFLAGS) -E -dM $(CONFIG_FILE) | \
+#         grep CONFIG_SMP | awk '{ print $$3 }')
+SMP := $(shell $(CC) $(EXTRA_CFLAGS) -E -dM $(CONFIG_FILE) | \
+         grep CONFIG_SMP | awk '{ print $$3 }')
+ifneq ($(SMP),1)
+  SMP := 0
+endif
+
+
+ifeq ($(SMP), 1)
+#  CFLAGS += -D__SMP__
+  EXTRA_CFLAGS += -D__SMP__
+endif
+
+
+
+# check x86_64
+SUBARCH := $(shell uname -m)
+ifeq ($(SUBARCH),x86_64)
+#    CFLAGS += -mcmodel=kernel -mno-red-zone
+    EXTRA_CFLAGS += -mcmodel=kernel -mno-red-zone
+endif
+
+
+$(TARGET): $(filter-out $(TARGET), $(SRC:.c=.o))
+	$(LD) -r $^ -o $@
+	echo; echo
+	echo "**************************************************"
+	echo "Build options:"
+	echo "   VERSION    $(KVER)"
+	echo -n "   SMP             "
+	if [ "$(SMP)" = "1" ]; \
+		then echo "Enabled"; else echo "Disabled"; fi
+
+
+
+endif # ifeq ($(KVER),2.6)
+
+
+ifeq ($(KVER), 2.6)
+install: default
+else
+install: clean $(TARGET)
+endif
+	mkdir -p $(MOD_ROOT)$(INSTDIR)
+	install -m 644 -o root $(TARGET) $(MOD_ROOT)$(INSTDIR)
+
+ifeq (,$(MOD_ROOT))
+	/sbin/depmod -a || true
+else
+	/sbin/depmod -b $(MOD_ROOT) -a || true
+endif
+
+
+uninstall:
+	rm -f $(INSTDIR)/$(TARGET)
+	/sbin/depmod -a
+
+clean:
+	rm -f $(TARGET) $(SRC:.c=.o) *~  *.o
+	rm -f .*.o.d .*.o.cmd .*.ko.cmd *.mod.c *.mod.o
+
+-include .depend.mak
diff --git a/drivers/staging/vt6656/aes_ccmp.c b/drivers/staging/vt6656/aes_ccmp.c
new file mode 100644
index 0000000..59cc018
--- /dev/null
+++ b/drivers/staging/vt6656/aes_ccmp.c
@@ -0,0 +1,410 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: aes_ccmp.c
+ *
+ * Purpose: AES_CCMP decryption
+ *
+ * Author: Warren Hsu
+ *
+ * Date: Feb 15, 2005
+ *
+ * Functions:
+ *      AESbGenCCMP - Parsing RX-packet
+ *
+ *
+ * Revision History:
+ *
+ */
+
+#if !defined(__UMEM_H__)
+#include "umem.h"
+#endif
+#if !defined(__DEVICE_H__)
+#include "device.h"
+#endif
+#if !defined(__80211HDR_H__)
+#include "80211hdr.h"
+#endif
+
+
+/*---------------------  Static Definitions -------------------------*/
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+
+/*
+ * SBOX Table
+ */
+
+BYTE sbox_table[256] =
+{
+0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
+0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
+0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
+0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
+0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
+0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
+0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
+0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
+0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
+0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
+0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
+0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
+0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
+0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
+0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
+0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
+};
+
+BYTE dot2_table[256] = {
+0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
+0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e,
+0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
+0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e,
+0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e,
+0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe,
+0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
+0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe,
+0x1b, 0x19, 0x1f, 0x1d, 0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05,
+0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d, 0x23, 0x21, 0x27, 0x25,
+0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55, 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45,
+0x7b, 0x79, 0x7f, 0x7d, 0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65,
+0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85,
+0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5,
+0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5,
+0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5
+};
+
+BYTE dot3_table[256] = {
+0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11,
+0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21,
+0x60, 0x63, 0x66, 0x65, 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71,
+0x50, 0x53, 0x56, 0x55, 0x5c, 0x5f, 0x5a, 0x59, 0x48, 0x4b, 0x4e, 0x4d, 0x44, 0x47, 0x42, 0x41,
+0xc0, 0xc3, 0xc6, 0xc5, 0xcc, 0xcf, 0xca, 0xc9, 0xd8, 0xdb, 0xde, 0xdd, 0xd4, 0xd7, 0xd2, 0xd1,
+0xf0, 0xf3, 0xf6, 0xf5, 0xfc, 0xff, 0xfa, 0xf9, 0xe8, 0xeb, 0xee, 0xed, 0xe4, 0xe7, 0xe2, 0xe1,
+0xa0, 0xa3, 0xa6, 0xa5, 0xac, 0xaf, 0xaa, 0xa9, 0xb8, 0xbb, 0xbe, 0xbd, 0xb4, 0xb7, 0xb2, 0xb1,
+0x90, 0x93, 0x96, 0x95, 0x9c, 0x9f, 0x9a, 0x99, 0x88, 0x8b, 0x8e, 0x8d, 0x84, 0x87, 0x82, 0x81,
+0x9b, 0x98, 0x9d, 0x9e, 0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8f, 0x8c, 0x89, 0x8a,
+0xab, 0xa8, 0xad, 0xae, 0xa7, 0xa4, 0xa1, 0xa2, 0xb3, 0xb0, 0xb5, 0xb6, 0xbf, 0xbc, 0xb9, 0xba,
+0xfb, 0xf8, 0xfd, 0xfe, 0xf7, 0xf4, 0xf1, 0xf2, 0xe3, 0xe0, 0xe5, 0xe6, 0xef, 0xec, 0xe9, 0xea,
+0xcb, 0xc8, 0xcd, 0xce, 0xc7, 0xc4, 0xc1, 0xc2, 0xd3, 0xd0, 0xd5, 0xd6, 0xdf, 0xdc, 0xd9, 0xda,
+0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46, 0x4f, 0x4c, 0x49, 0x4a,
+0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62, 0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a,
+0x3b, 0x38, 0x3d, 0x3e, 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a,
+0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a
+};
+
+/*---------------------  Static Functions  --------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+void xor_128(BYTE *a, BYTE *b, BYTE *out)
+{
+PDWORD dwPtrA = (PDWORD) a;
+PDWORD dwPtrB = (PDWORD) b;
+PDWORD dwPtrOut =(PDWORD) out;
+
+    (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
+    (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
+    (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
+    (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
+}
+
+
+void xor_32(BYTE *a, BYTE *b, BYTE *out)
+{
+PDWORD dwPtrA = (PDWORD) a;
+PDWORD dwPtrB = (PDWORD) b;
+PDWORD dwPtrOut =(PDWORD) out;
+
+    (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
+}
+
+void AddRoundKey(BYTE *key, int round)
+{
+BYTE sbox_key[4];
+BYTE rcon_table[10] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36};
+
+    sbox_key[0] = sbox_table[key[13]];
+    sbox_key[1] = sbox_table[key[14]];
+    sbox_key[2] = sbox_table[key[15]];
+    sbox_key[3] = sbox_table[key[12]];
+
+    key[0] = key[0] ^ rcon_table[round];
+    xor_32(&key[0], sbox_key, &key[0]);
+
+    xor_32(&key[4], &key[0], &key[4]);
+    xor_32(&key[8], &key[4], &key[8]);
+    xor_32(&key[12], &key[8], &key[12]);
+}
+
+void SubBytes(BYTE *in, BYTE *out)
+{
+int i;
+
+    for (i=0; i< 16; i++)
+    {
+        out[i] = sbox_table[in[i]];
+    }
+}
+
+void ShiftRows(BYTE *in, BYTE *out)
+{
+    out[0]  = in[0];
+    out[1]  = in[5];
+    out[2]  = in[10];
+    out[3]  = in[15];
+    out[4]  = in[4];
+    out[5]  = in[9];
+    out[6]  = in[14];
+    out[7]  = in[3];
+    out[8]  = in[8];
+    out[9]  = in[13];
+    out[10] = in[2];
+    out[11] = in[7];
+    out[12] = in[12];
+    out[13] = in[1];
+    out[14] = in[6];
+    out[15] = in[11];
+}
+
+void MixColumns(BYTE *in, BYTE *out)
+{
+
+    out[0] = dot2_table[in[0]] ^ dot3_table[in[1]] ^ in[2] ^ in[3];
+    out[1] = in[0] ^ dot2_table[in[1]] ^ dot3_table[in[2]] ^ in[3];
+    out[2] = in[0] ^ in[1] ^ dot2_table[in[2]] ^ dot3_table[in[3]];
+    out[3] = dot3_table[in[0]] ^ in[1] ^ in[2] ^ dot2_table[in[3]];
+}
+
+
+void AESv128(BYTE *key, BYTE *data, BYTE *ciphertext)
+{
+int  i;
+int  round;
+BYTE TmpdataA[16];
+BYTE TmpdataB[16];
+BYTE abyRoundKey[16];
+
+    for(i=0; i<16; i++)
+        abyRoundKey[i] = key[i];
+
+    for (round = 0; round < 11; round++)
+    {
+        if (round == 0)
+        {
+            xor_128(abyRoundKey, data, ciphertext);
+            AddRoundKey(abyRoundKey, round);
+        }
+        else if (round == 10)
+        {
+            SubBytes(ciphertext, TmpdataA);
+            ShiftRows(TmpdataA, TmpdataB);
+            xor_128(TmpdataB, abyRoundKey, ciphertext);
+        }
+        else // round 1 ~ 9
+        {
+            SubBytes(ciphertext, TmpdataA);
+            ShiftRows(TmpdataA, TmpdataB);
+            MixColumns(&TmpdataB[0], &TmpdataA[0]);
+            MixColumns(&TmpdataB[4], &TmpdataA[4]);
+            MixColumns(&TmpdataB[8], &TmpdataA[8]);
+            MixColumns(&TmpdataB[12], &TmpdataA[12]);
+            xor_128(TmpdataA, abyRoundKey, ciphertext);
+            AddRoundKey(abyRoundKey, round);
+        }
+    }
+
+}
+
+/*
+ * Description: AES decryption
+ *
+ * Parameters:
+ *  In:
+ *      pbyRxKey            - The key used to decrypt
+ *      pbyFrame            - Starting address of packet header
+ *      wFrameSize          - Total packet size including CRC
+ *  Out:
+ *      none
+ *
+ * Return Value: MIC compare result
+ *
+ */
+BOOL AESbGenCCMP(PBYTE pbyRxKey, PBYTE pbyFrame, WORD wFrameSize)
+{
+BYTE            abyNonce[13];
+BYTE            MIC_IV[16];
+BYTE            MIC_HDR1[16];
+BYTE            MIC_HDR2[16];
+BYTE            abyMIC[16];
+BYTE            abyCTRPLD[16];
+BYTE            abyTmp[16];
+BYTE            abyPlainText[16];
+BYTE            abyLastCipher[16];
+
+PS802_11Header  pMACHeader = (PS802_11Header) pbyFrame;
+PBYTE           pbyIV;
+PBYTE           pbyPayload;
+WORD            wHLen = 22;
+WORD            wPayloadSize = wFrameSize - 8 - 8 - 4 - WLAN_HDR_ADDR3_LEN;//8 is IV, 8 is MIC, 4 is CRC
+BOOL            bA4 = FALSE;
+BYTE            byTmp;
+WORD            wCnt;
+int             ii,jj,kk;
+
+
+    pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN;
+    if ( WLAN_GET_FC_TODS(*(PWORD)pbyFrame) &&
+         WLAN_GET_FC_FROMDS(*(PWORD)pbyFrame) ) {
+         bA4 = TRUE;
+         pbyIV += 6;             // 6 is 802.11 address4
+         wHLen += 6;
+         wPayloadSize -= 6;
+    }
+    pbyPayload = pbyIV + 8; //IV-length
+
+    abyNonce[0]  = 0x00; //now is 0, if Qos here will be priority
+    MEMvCopy(&(abyNonce[1]), pMACHeader->abyAddr2, U_ETHER_ADDR_LEN);
+    abyNonce[7]  = pbyIV[7];
+    abyNonce[8]  = pbyIV[6];
+    abyNonce[9]  = pbyIV[5];
+    abyNonce[10] = pbyIV[4];
+    abyNonce[11] = pbyIV[1];
+    abyNonce[12] = pbyIV[0];
+
+    //MIC_IV
+    MIC_IV[0] = 0x59;
+    MEMvCopy(&(MIC_IV[1]), &(abyNonce[0]), 13);
+    MIC_IV[14] = (BYTE)(wPayloadSize >> 8);
+    MIC_IV[15] = (BYTE)(wPayloadSize & 0xff);
+
+    //MIC_HDR1
+    MIC_HDR1[0] = (BYTE)(wHLen >> 8);
+    MIC_HDR1[1] = (BYTE)(wHLen & 0xff);
+    byTmp = (BYTE)(pMACHeader->wFrameCtl & 0xff);
+    MIC_HDR1[2] = byTmp & 0x8f;
+    byTmp = (BYTE)(pMACHeader->wFrameCtl >> 8);
+    byTmp &= 0x87;
+    MIC_HDR1[3] = byTmp | 0x40;
+    MEMvCopy(&(MIC_HDR1[4]), pMACHeader->abyAddr1, U_ETHER_ADDR_LEN);
+    MEMvCopy(&(MIC_HDR1[10]), pMACHeader->abyAddr2, U_ETHER_ADDR_LEN);
+
+    //MIC_HDR2
+    MEMvCopy(&(MIC_HDR2[0]), pMACHeader->abyAddr3, U_ETHER_ADDR_LEN);
+    byTmp = (BYTE)(pMACHeader->wSeqCtl & 0xff);
+    MIC_HDR2[6] = byTmp & 0x0f;
+    MIC_HDR2[7] = 0;
+    if ( bA4 ) {
+        MEMvCopy(&(MIC_HDR2[8]), pMACHeader->abyAddr4, U_ETHER_ADDR_LEN);
+    } else {
+        MIC_HDR2[8]  = 0x00;
+        MIC_HDR2[9]  = 0x00;
+        MIC_HDR2[10] = 0x00;
+        MIC_HDR2[11] = 0x00;
+        MIC_HDR2[12] = 0x00;
+        MIC_HDR2[13] = 0x00;
+    }
+    MIC_HDR2[14] = 0x00;
+    MIC_HDR2[15] = 0x00;
+
+    //CCMP
+    AESv128(pbyRxKey,MIC_IV,abyMIC);
+    for ( kk=0; kk<16; kk++ ) {
+        abyTmp[kk] = MIC_HDR1[kk] ^ abyMIC[kk];
+    }
+    AESv128(pbyRxKey,abyTmp,abyMIC);
+    for ( kk=0; kk<16; kk++ ) {
+        abyTmp[kk] = MIC_HDR2[kk] ^ abyMIC[kk];
+    }
+    AESv128(pbyRxKey,abyTmp,abyMIC);
+
+    wCnt = 1;
+    abyCTRPLD[0] = 0x01;
+    MEMvCopy(&(abyCTRPLD[1]), &(abyNonce[0]), 13);
+
+    for(jj=wPayloadSize; jj>16; jj=jj-16) {
+
+        abyCTRPLD[14] = (BYTE) (wCnt >> 8);
+        abyCTRPLD[15] = (BYTE) (wCnt & 0xff);
+
+        AESv128(pbyRxKey,abyCTRPLD,abyTmp);
+
+        for ( kk=0; kk<16; kk++ ) {
+            abyPlainText[kk] = abyTmp[kk] ^ pbyPayload[kk];
+        }
+        for ( kk=0; kk<16; kk++ ) {
+            abyTmp[kk] = abyMIC[kk] ^ abyPlainText[kk];
+        }
+        AESv128(pbyRxKey,abyTmp,abyMIC);
+
+        MEMvCopy(pbyPayload, abyPlainText, 16);
+        wCnt++;
+        pbyPayload += 16;
+    } //for wPayloadSize
+
+    //last payload
+    MEMvCopy(&(abyLastCipher[0]), pbyPayload, jj);
+    for ( ii=jj; ii<16; ii++ ) {
+        abyLastCipher[ii] = 0x00;
+    }
+
+    abyCTRPLD[14] = (BYTE) (wCnt >> 8);
+    abyCTRPLD[15] = (BYTE) (wCnt & 0xff);
+
+    AESv128(pbyRxKey,abyCTRPLD,abyTmp);
+    for ( kk=0; kk<16; kk++ ) {
+        abyPlainText[kk] = abyTmp[kk] ^ abyLastCipher[kk];
+    }
+    MEMvCopy(pbyPayload, abyPlainText, jj);
+    pbyPayload += jj;
+
+    //for MIC calculation
+    for ( ii=jj; ii<16; ii++ ) {
+        abyPlainText[ii] = 0x00;
+    }
+    for ( kk=0; kk<16; kk++ ) {
+        abyTmp[kk] = abyMIC[kk] ^ abyPlainText[kk];
+    }
+    AESv128(pbyRxKey,abyTmp,abyMIC);
+
+    //=>above is the calculate MIC
+    //--------------------------------------------
+
+    wCnt = 0;
+    abyCTRPLD[14] = (BYTE) (wCnt >> 8);
+    abyCTRPLD[15] = (BYTE) (wCnt & 0xff);
+    AESv128(pbyRxKey,abyCTRPLD,abyTmp);
+    for ( kk=0; kk<8; kk++ ) {
+        abyTmp[kk] = abyTmp[kk] ^ pbyPayload[kk];
+    }
+    //=>above is the dec-MIC from packet
+    //--------------------------------------------
+
+    if ( MEMEqualMemory(abyMIC,abyTmp,8) ) {
+        return TRUE;
+    } else {
+        return FALSE;
+    }
+
+}
diff --git a/drivers/staging/vt6656/aes_ccmp.h b/drivers/staging/vt6656/aes_ccmp.h
new file mode 100644
index 0000000..2b1920f
--- /dev/null
+++ b/drivers/staging/vt6656/aes_ccmp.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: aes_ccmp.h
+ *
+ * Purpose: AES_CCMP Decryption
+ *
+ * Author: Warren Hsu
+ *
+ * Date: Feb 15, 2005
+ *
+ */
+
+#ifndef __AES_H__
+#define __AES_H__
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+
+/*---------------------  Export Definitions -------------------------*/
+
+/*---------------------  Export Types  ------------------------------*/
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+BOOL AESbGenCCMP(PBYTE pbyRxKey, PBYTE pbyFrame, WORD wFrameSize);
+
+#endif //__AES_H__
diff --git a/drivers/staging/vt6656/baseband.c b/drivers/staging/vt6656/baseband.c
new file mode 100644
index 0000000..7b43cea
--- /dev/null
+++ b/drivers/staging/vt6656/baseband.c
@@ -0,0 +1,2129 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: baseband.c
+ *
+ * Purpose: Implement functions to access baseband
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Jun. 5, 2002
+ *
+ * Functions:
+ *      BBuGetFrameTime        - Calculate data frame transmitting time
+ *      BBvCaculateParameter   - Caculate PhyLength, PhyService and Phy Signal parameter for baseband Tx
+ *      BBbVT3184Init          - VIA VT3184 baseband chip init code
+ *      BBvLoopbackOn          - Turn on BaseBand Loopback mode
+ *      BBvLoopbackOff         - Turn off BaseBand Loopback mode
+ *
+ * Revision History:
+ *
+ *
+ */
+
+
+#if !defined(__TMACRO_H__)
+#include "tmacro.h"
+#endif
+#if !defined(__TBIT_H__)
+#include "tbit.h"
+#endif
+#if !defined(__TETHER_H__)
+#include "tether.h"
+#endif
+#if !defined(__MAC_H__)
+#include "mac.h"
+#endif
+#if !defined(__BASEBAND_H__)
+#include "baseband.h"
+#endif
+#if !defined(__RF_H__)
+#include "rf.h"
+#endif
+#if !defined(__SROM_H__)
+#include "srom.h"
+#endif
+#if !defined(__CONTROL_H__)
+#include "control.h"
+#endif
+#if !defined(__DATARATE_H__)
+#include "datarate.h"
+#endif
+#if !defined(__RNDIS_H__)
+#include "rndis.h"
+#endif
+#if !defined(__CONTROL_H__)
+#include "control.h"
+#endif
+
+/*---------------------  Static Definitions -------------------------*/
+static int          msglevel                =MSG_LEVEL_INFO;
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+
+/*---------------------  Static Functions  --------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Static Definitions -------------------------*/
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+
+
+BYTE abyVT3184_AGC[] = {
+    0x00,   //0
+    0x00,   //1
+    0x02,   //2
+    0x02,   //3  //RobertYu:20060505, 0x04,   //3
+    0x04,   //4
+    0x04,   //5  //RobertYu:20060505, 0x06,   //5
+    0x06,   //6
+    0x06,   //7
+    0x08,   //8
+    0x08,   //9
+    0x0A,   //A
+    0x0A,   //B
+    0x0C,   //C
+    0x0C,   //D
+    0x0E,   //E
+    0x0E,   //F
+    0x10,   //10
+    0x10,   //11
+    0x12,   //12
+    0x12,   //13
+    0x14,   //14
+    0x14,   //15
+    0x16,   //16
+    0x16,   //17
+    0x18,   //18
+    0x18,   //19
+    0x1A,   //1A
+    0x1A,   //1B
+    0x1C,   //1C
+    0x1C,   //1D
+    0x1E,   //1E
+    0x1E,   //1F
+    0x20,   //20
+    0x20,   //21
+    0x22,   //22
+    0x22,   //23
+    0x24,   //24
+    0x24,   //25
+    0x26,   //26
+    0x26,   //27
+    0x28,   //28
+    0x28,   //29
+    0x2A,   //2A
+    0x2A,   //2B
+    0x2C,   //2C
+    0x2C,   //2D
+    0x2E,   //2E
+    0x2E,   //2F
+    0x30,   //30
+    0x30,   //31
+    0x32,   //32
+    0x32,   //33
+    0x34,   //34
+    0x34,   //35
+    0x36,   //36
+    0x36,   //37
+    0x38,   //38
+    0x38,   //39
+    0x3A,   //3A
+    0x3A,   //3B
+    0x3C,   //3C
+    0x3C,   //3D
+    0x3E,   //3E
+    0x3E    //3F
+};
+
+
+BYTE abyVT3184_AL2230[] = {
+        0x31,//00
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x80,
+        0x00,
+        0x00,
+        0x70,
+        0x45,//tx   //0x64 for FPGA
+        0x2A,
+        0x76,
+        0x00,
+        0x00,
+        0x80,
+        0x00,
+        0x00,//10
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x8e,       //RobertYu:20060522, //0x8d,
+        0x0a,       //RobertYu:20060515, //0x09,
+        0x00,
+        0x00,
+        0x00,
+        0x00,//20
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x4a,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x4a,
+        0x00,
+        0x0c,       //RobertYu:20060522, //0x10,
+        0x26,//30
+        0x5b,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0xaa,
+        0xaa,
+        0xff,
+        0xff,
+        0x79,
+        0x00,
+        0x00,
+        0x0b,
+        0x48,
+        0x04,
+        0x00,//40
+        0x08,
+        0x00,
+        0x08,
+        0x08,
+        0x14,
+        0x05,
+        0x09,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x09,
+        0x73,
+        0x00,
+        0xc5,
+        0x00,//50   //RobertYu:20060505, //0x15,//50
+        0x19,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0xd0,       //RobertYu:20060505, //0xb0,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0xe4,//60
+        0x80,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x98,
+        0x0a,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,       //0x80 for FPGA
+        0x03,
+        0x01,
+        0x00,
+        0x00,//70
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x8c,//80
+        0x01,
+        0x09,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x08,
+        0x00,
+        0x1f,       //RobertYu:20060516, //0x0f,
+        0xb7,
+        0x88,
+        0x47,
+        0xaa,
+        0x00,       //RobertYu:20060505, //0x02,
+        0x20,//90   //RobertYu:20060505, //0x22,//90
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0xeb,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x01,
+        0x00,//a0
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x10,
+        0x00,
+        0x18,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x15,       //RobertYu:20060516, //0x00,
+        0x00,
+        0x18,
+        0x38,//b0
+        0x30,
+        0x00,
+        0x00,
+        0xff,
+        0x0f,
+        0xe4,
+        0xe2,
+        0x00,
+        0x00,
+        0x00,
+        0x03,
+        0x01,
+        0x00,
+        0x00,
+        0x00,
+        0x18,//c0
+        0x20,
+        0x07,
+        0x18,
+        0xff,
+        0xff,       //RobertYu:20060509, //0x2c,
+        0x0e,       //RobertYu:20060530, //0x0c,
+        0x0a,
+        0x0e,
+        0x00,       //RobertYu:20060505, //0x01,
+        0x82,       //RobertYu:20060516, //0x8f,
+        0xa7,
+        0x3c,
+        0x10,
+        0x30,       //RobertYu:20060627, //0x0b,
+        0x05,       //RobertYu:20060516, //0x25,
+        0x40,//d0
+        0x12,
+        0x00,
+        0x00,
+        0x10,
+        0x28,
+        0x80,
+        0x2A,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,//e0
+        0xf3,       //RobertYu:20060516, //0xd3,
+        0x00,
+        0x00,
+        0x00,
+        0x10,
+        0x00,
+        0x12,       //RobertYu:20060627, //0x10,
+        0x00,
+        0xf4,
+        0x00,
+        0xff,
+        0x79,
+        0x20,
+        0x30,
+        0x05,       //RobertYu:20060516, //0x0c,
+        0x00,//f0
+        0x3e,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00
+};
+
+
+
+//{{RobertYu:20060515, new BB setting for VT3226D0
+BYTE abyVT3184_VT3226D0[] = {
+        0x31,//00
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x80,
+        0x00,
+        0x00,
+        0x70,
+        0x45,//tx   //0x64 for FPGA
+        0x2A,
+        0x76,
+        0x00,
+        0x00,
+        0x80,
+        0x00,
+        0x00,//10
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x8e,       //RobertYu:20060525, //0x8d,
+        0x0a,       //RobertYu:20060515, //0x09,
+        0x00,
+        0x00,
+        0x00,
+        0x00,//20
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x4a,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x4a,
+        0x00,
+        0x0c,       //RobertYu:20060525, //0x10,
+        0x26,//30
+        0x5b,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0xaa,
+        0xaa,
+        0xff,
+        0xff,
+        0x79,
+        0x00,
+        0x00,
+        0x0b,
+        0x48,
+        0x04,
+        0x00,//40
+        0x08,
+        0x00,
+        0x08,
+        0x08,
+        0x14,
+        0x05,
+        0x09,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x09,
+        0x73,
+        0x00,
+        0xc5,
+        0x00,//50   //RobertYu:20060505, //0x15,//50
+        0x19,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0xd0,       //RobertYu:20060505, //0xb0,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0xe4,//60
+        0x80,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x98,
+        0x0a,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,       //0x80 for FPGA
+        0x03,
+        0x01,
+        0x00,
+        0x00,//70
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x8c,//80
+        0x01,
+        0x09,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x08,
+        0x00,
+        0x1f,       //RobertYu:20060515, //0x0f,
+        0xb7,
+        0x88,
+        0x47,
+        0xaa,
+        0x00,       //RobertYu:20060505, //0x02,
+        0x20,//90   //RobertYu:20060505, //0x22,//90
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0xeb,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x01,
+        0x00,//a0
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x10,
+        0x00,
+        0x18,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x18,
+        0x38,//b0
+        0x30,
+        0x00,
+        0x00,
+        0xff,
+        0x0f,
+        0xe4,
+        0xe2,
+        0x00,
+        0x00,
+        0x00,
+        0x03,
+        0x01,
+        0x00,
+        0x00,
+        0x00,
+        0x18,//c0
+        0x20,
+        0x07,
+        0x18,
+        0xff,
+        0xff,       //RobertYu:20060509, //0x2c,
+        0x10,       //RobertYu:20060525, //0x0c,
+        0x0a,
+        0x0e,
+        0x00,       //RobertYu:20060505, //0x01,
+        0x84,       //RobertYu:20060525, //0x8f,
+        0xa7,
+        0x3c,
+        0x10,
+        0x24,       //RobertYu:20060627, //0x18,
+        0x05,       //RobertYu:20060515, //0x25,
+        0x40,//d0
+        0x12,
+        0x00,
+        0x00,
+        0x10,
+        0x28,
+        0x80,
+        0x2A,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,//e0
+        0xf3,       //RobertYu:20060515, //0xd3,
+        0x00,
+        0x00,
+        0x00,
+        0x10,
+        0x00,
+        0x10,       //RobertYu:20060627, //0x0e,
+        0x00,
+        0xf4,
+        0x00,
+        0xff,
+        0x79,
+        0x20,
+        0x30,
+        0x08,       //RobertYu:20060515, //0x0c,
+        0x00,//f0
+        0x3e,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+};
+
+const WORD awcFrameTime[MAX_RATE] =
+{10, 20, 55, 110, 24, 36, 48, 72, 96, 144, 192, 216};
+
+/*---------------------  Static Functions  --------------------------*/
+
+/*
+static
+ULONG
+s_ulGetLowSQ3(PSDevice pDevice);
+
+static
+ULONG
+s_ulGetRatio(PSDevice pDevice);
+
+static
+void
+s_vClearSQ3Value(PSDevice pDevice);
+*/
+
+/*---------------------  Export Variables  --------------------------*/
+/*
+ * Description: Calculate data frame transmitting time
+ *
+ * Parameters:
+ *  In:
+ *      byPreambleType  - Preamble Type
+ *      byPktType        - PK_TYPE_11A, PK_TYPE_11B, PK_TYPE_11GB, PK_TYPE_11GA
+ *      cbFrameLength   - Baseband Type
+ *      wRate           - Tx Rate
+ *  Out:
+ *
+ * Return Value: FrameTime
+ *
+ */
+UINT
+BBuGetFrameTime (
+    IN BYTE byPreambleType,
+    IN BYTE byPktType,
+    IN UINT cbFrameLength,
+    IN WORD wRate
+    )
+{
+    UINT uFrameTime;
+    UINT uPreamble;
+    UINT uTmp;
+    UINT uRateIdx = (UINT)wRate;
+    UINT uRate = 0;
+
+
+    if (uRateIdx > RATE_54M) {
+        ASSERT(0);
+        return 0;
+    }
+
+    uRate = (UINT)awcFrameTime[uRateIdx];
+
+    if (uRateIdx <= 3) {          //CCK mode
+
+        if (byPreambleType == 1) {//Short
+            uPreamble = 96;
+        } else {
+            uPreamble = 192;
+        }
+        uFrameTime = (cbFrameLength * 80) / uRate;
+        uTmp = (uFrameTime * uRate) / 80;
+        if (cbFrameLength != uTmp) {
+            uFrameTime ++;
+        }
+
+        return (uPreamble + uFrameTime);
+    }
+    else {
+        uFrameTime = (cbFrameLength * 8 + 22) / uRate;
+        uTmp = ((uFrameTime * uRate) - 22) / 8;
+        if(cbFrameLength != uTmp) {
+            uFrameTime ++;
+        }
+        uFrameTime = uFrameTime * 4;
+        if(byPktType != PK_TYPE_11A) {
+            uFrameTime += 6;
+        }
+        return (20 + uFrameTime);
+    }
+}
+
+/*
+ * Description: Caculate Length, Service, and Signal fields of Phy for Tx
+ *
+ * Parameters:
+ *  In:
+ *      pDevice         - Device Structure
+ *      cbFrameLength   - Tx Frame Length
+ *      wRate           - Tx Rate
+ *  Out:
+ *      pwPhyLen        - pointer to Phy Length field
+ *      pbyPhySrv       - pointer to Phy Service field
+ *      pbyPhySgn       - pointer to Phy Signal field
+ *
+ * Return Value: none
+ *
+ */
+VOID
+BBvCaculateParameter (
+    IN  PSDevice pDevice,
+    IN  UINT cbFrameLength,
+    IN  WORD wRate,
+    IN  BYTE byPacketType,
+    OUT PWORD pwPhyLen,
+    OUT PBYTE pbyPhySrv,
+    OUT PBYTE pbyPhySgn
+    )
+{
+    UINT cbBitCount;
+    UINT cbUsCount = 0;
+    UINT cbTmp;
+    BOOL bExtBit;
+    BYTE byPreambleType = pDevice->byPreambleType;
+    BOOL bCCK = pDevice->bCCK;
+
+    cbBitCount = cbFrameLength * 8;
+    bExtBit = FALSE;
+
+    switch (wRate) {
+    case RATE_1M :
+        cbUsCount = cbBitCount;
+        *pbyPhySgn = 0x00;
+        break;
+
+    case RATE_2M :
+        cbUsCount = cbBitCount / 2;
+        if (byPreambleType == 1)
+            *pbyPhySgn = 0x09;
+        else // long preamble
+            *pbyPhySgn = 0x01;
+        break;
+
+    case RATE_5M :
+        if (bCCK == FALSE)
+            cbBitCount ++;
+        cbUsCount = (cbBitCount * 10) / 55;
+        cbTmp = (cbUsCount * 55) / 10;
+        if (cbTmp != cbBitCount)
+            cbUsCount ++;
+        if (byPreambleType == 1)
+            *pbyPhySgn = 0x0a;
+        else // long preamble
+            *pbyPhySgn = 0x02;
+        break;
+
+    case RATE_11M :
+
+        if (bCCK == FALSE)
+            cbBitCount ++;
+        cbUsCount = cbBitCount / 11;
+        cbTmp = cbUsCount * 11;
+        if (cbTmp != cbBitCount) {
+            cbUsCount ++;
+            if ((cbBitCount - cbTmp) <= 3)
+                bExtBit = TRUE;
+        }
+        if (byPreambleType == 1)
+            *pbyPhySgn = 0x0b;
+        else // long preamble
+            *pbyPhySgn = 0x03;
+        break;
+
+    case RATE_6M :
+        if(byPacketType == PK_TYPE_11A) {//11a, 5GHZ
+            *pbyPhySgn = 0x9B; //1001 1011
+        }
+        else {//11g, 2.4GHZ
+            *pbyPhySgn = 0x8B; //1000 1011
+        }
+        break;
+
+    case RATE_9M :
+        if(byPacketType == PK_TYPE_11A) {//11a, 5GHZ
+            *pbyPhySgn = 0x9F; //1001 1111
+        }
+        else {//11g, 2.4GHZ
+            *pbyPhySgn = 0x8F; //1000 1111
+        }
+        break;
+
+    case RATE_12M :
+        if(byPacketType == PK_TYPE_11A) {//11a, 5GHZ
+            *pbyPhySgn = 0x9A; //1001 1010
+        }
+        else {//11g, 2.4GHZ
+            *pbyPhySgn = 0x8A; //1000 1010
+        }
+        break;
+
+    case RATE_18M :
+        if(byPacketType == PK_TYPE_11A) {//11a, 5GHZ
+            *pbyPhySgn = 0x9E; //1001 1110
+        }
+        else {//11g, 2.4GHZ
+            *pbyPhySgn = 0x8E; //1000 1110
+        }
+        break;
+
+    case RATE_24M :
+        if(byPacketType == PK_TYPE_11A) {//11a, 5GHZ
+            *pbyPhySgn = 0x99; //1001 1001
+        }
+        else {//11g, 2.4GHZ
+            *pbyPhySgn = 0x89; //1000 1001
+        }
+        break;
+
+    case RATE_36M :
+        if(byPacketType == PK_TYPE_11A) {//11a, 5GHZ
+            *pbyPhySgn = 0x9D; //1001 1101
+        }
+        else {//11g, 2.4GHZ
+            *pbyPhySgn = 0x8D; //1000 1101
+        }
+        break;
+
+    case RATE_48M :
+        if(byPacketType == PK_TYPE_11A) {//11a, 5GHZ
+            *pbyPhySgn = 0x98; //1001 1000
+        }
+        else {//11g, 2.4GHZ
+            *pbyPhySgn = 0x88; //1000 1000
+        }
+        break;
+
+    case RATE_54M :
+        if (byPacketType == PK_TYPE_11A) {//11a, 5GHZ
+            *pbyPhySgn = 0x9C; //1001 1100
+        }
+        else {//11g, 2.4GHZ
+            *pbyPhySgn = 0x8C; //1000 1100
+        }
+        break;
+
+    default :
+        if (byPacketType == PK_TYPE_11A) {//11a, 5GHZ
+            *pbyPhySgn = 0x9C; //1001 1100
+        }
+        else {//11g, 2.4GHZ
+            *pbyPhySgn = 0x8C; //1000 1100
+        }
+        break;
+    }
+
+    if (byPacketType == PK_TYPE_11B) {
+        *pbyPhySrv = 0x00;
+        if (bExtBit)
+            *pbyPhySrv = *pbyPhySrv | 0x80;
+        *pwPhyLen = (WORD) cbUsCount;
+    }
+    else {
+        *pbyPhySrv = 0x00;
+        *pwPhyLen = (WORD)cbFrameLength;
+    }
+}
+
+
+/*
+ * Description: Set Antenna mode
+ *
+ * Parameters:
+ *  In:
+ *      pDevice          - Device Structure
+ *      byAntennaMode    - Antenna Mode
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+VOID
+BBvSetAntennaMode (PSDevice pDevice, BYTE byAntennaMode)
+{
+    //{{ RobertYu: 20041124, ABG Mode, VC1/VC2 define, make the ANT_A, ANT_B inverted
+    /*if ( (pDevice->byRFType == RF_MAXIM2829) ||
+         (pDevice->byRFType == RF_UW2452) ||
+         (pDevice->byRFType == RF_AIROHA7230) ) { // RobertYu: 20041210, 20050104
+
+        switch (byAntennaMode) {
+            case ANT_TXA:
+                byAntennaMode = ANT_TXB;
+                break;
+            case ANT_TXB:
+                byAntennaMode = ANT_TXA;
+                break;
+            case ANT_RXA:
+                byAntennaMode = ANT_RXB;
+                break;
+            case ANT_RXB:
+                byAntennaMode = ANT_RXA;
+                break;
+        }
+    }*/
+
+    switch (byAntennaMode) {
+        case ANT_TXA:
+            break;
+        case ANT_TXB:
+            break;
+        case ANT_RXA:
+            pDevice->byBBRxConf &= 0xFC;
+            break;
+        case ANT_RXB:
+            pDevice->byBBRxConf &= 0xFE;
+            pDevice->byBBRxConf |= 0x02;;
+            break;
+    }
+
+
+    CONTROLnsRequestOut(pDevice,
+                    MESSAGE_TYPE_SET_ANTMD,
+                    (WORD) byAntennaMode,
+                    0,
+                    0,
+                    NULL);
+}
+
+/*
+ * Description: Set Antenna mode
+ *
+ * Parameters:
+ *  In:
+ *      pDevice          - Device Structure
+ *      byAntennaMode    - Antenna Mode
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+BOOL
+BBbVT3184Init (PSDevice pDevice)
+{
+    NTSTATUS                ntStatus;
+    WORD                    wLength;
+    PBYTE                   pbyAddr;
+    PBYTE                   pbyAgc;
+    WORD                    wLengthAgc;
+    BYTE                    abyArray[256];
+
+    ntStatus = CONTROLnsRequestIn(pDevice,
+                                  MESSAGE_TYPE_READ,
+                                  0,
+                                  MESSAGE_REQUEST_EEPROM,
+                                  EEP_MAX_CONTEXT_SIZE,
+                                  pDevice->abyEEPROM);
+    if (ntStatus != STATUS_SUCCESS) {
+        return FALSE;
+    }
+
+
+    //20080215-01,<Add> by Mike Liu
+//    if ((pDevice->abyEEPROM[EEP_OFS_RADIOCTL]&0x06)==0x04)
+//        return FALSE;
+
+//20080804-01,<Add> by Mike Liu
+//zonetype initial
+ pDevice->byOriginalZonetype = pDevice->abyEEPROM[EEP_OFS_ZONETYPE];
+ if(pDevice->config_file.ZoneType >= 0) {         //read zonetype file ok!
+  if ((pDevice->config_file.ZoneType == 0)&&
+        (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] !=0x00)){          //for USA
+    pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0;
+    pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0B;
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Init Zone Type :USA\n");
+  }
+ else if((pDevice->config_file.ZoneType == 1)&&
+ 	     (pDevice->abyEEPROM[EEP_OFS_ZONETYPE]!=0x01)){   //for Japan
+    pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0x01;
+    pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0D;
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Init Zone Type :Japan\n");
+  }
+ else if((pDevice->config_file.ZoneType == 2)&&
+ 	     (pDevice->abyEEPROM[EEP_OFS_ZONETYPE]!=0x02)){   //for Europe
+    pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0x02;
+    pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0D;
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Init Zone Type :Europe\n");
+  }
+else {
+   if(pDevice->config_file.ZoneType !=pDevice->abyEEPROM[EEP_OFS_ZONETYPE])
+      printk("zonetype in file[%02x] mismatch with in EEPROM[%02x]\n",pDevice->config_file.ZoneType,pDevice->abyEEPROM[EEP_OFS_ZONETYPE]);
+   else
+      printk("Read Zonetype file sucess,use default zonetype setting[%02x]\n",pDevice->config_file.ZoneType);
+ }
+}
+
+    if ( !pDevice->bZoneRegExist ) {
+        pDevice->byZoneType = pDevice->abyEEPROM[EEP_OFS_ZONETYPE];
+    }
+    pDevice->byRFType = pDevice->abyEEPROM[EEP_OFS_RFTYPE];
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Zone Type %x\n", pDevice->byZoneType);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"RF Type %d\n", pDevice->byRFType);
+
+    if ((pDevice->byRFType == RF_AL2230) || (pDevice->byRFType == RF_AL2230S)) {
+        pDevice->byBBRxConf = abyVT3184_AL2230[10];
+        wLength = sizeof(abyVT3184_AL2230);
+        pbyAddr = abyVT3184_AL2230;
+        pbyAgc = abyVT3184_AGC;
+        wLengthAgc = sizeof(abyVT3184_AGC);
+
+        pDevice->abyBBVGA[0] = 0x1C;
+        pDevice->abyBBVGA[1] = 0x10;
+        pDevice->abyBBVGA[2] = 0x0;
+        pDevice->abyBBVGA[3] = 0x0;
+        pDevice->ldBmThreshold[0] = -70;
+        pDevice->ldBmThreshold[1] = -48;
+        pDevice->ldBmThreshold[2] = 0;
+        pDevice->ldBmThreshold[3] = 0;
+    }
+    else if (pDevice->byRFType == RF_AIROHA7230) {
+        pDevice->byBBRxConf = abyVT3184_AL2230[10];
+        wLength = sizeof(abyVT3184_AL2230);
+        pbyAddr = abyVT3184_AL2230;
+        pbyAgc = abyVT3184_AGC;
+        wLengthAgc = sizeof(abyVT3184_AGC);
+
+        // Init ANT B select,TX Config CR09 = 0x61->0x45, 0x45->0x41(VC1/VC2 define, make the ANT_A, ANT_B inverted)
+        //pbyAddr[0x09] = 0x41;
+        // Init ANT B select,RX Config CR10 = 0x28->0x2A, 0x2A->0x28(VC1/VC2 define, make the ANT_A, ANT_B inverted)
+        //pbyAddr[0x0a] = 0x28;
+        // Select VC1/VC2, CR215 = 0x02->0x06
+        pbyAddr[0xd7] = 0x06;
+
+        pDevice->abyBBVGA[0] = 0x1C;
+        pDevice->abyBBVGA[1] = 0x10;
+        pDevice->abyBBVGA[2] = 0x0;
+        pDevice->abyBBVGA[3] = 0x0;
+        pDevice->ldBmThreshold[0] = -70;
+        pDevice->ldBmThreshold[1] = -48;
+        pDevice->ldBmThreshold[2] = 0;
+        pDevice->ldBmThreshold[3] = 0;
+    }
+    else if ( (pDevice->byRFType == RF_VT3226) || (pDevice->byRFType == RF_VT3226D0) ) {
+        pDevice->byBBRxConf = abyVT3184_VT3226D0[10];   //RobertYu:20060515
+        wLength = sizeof(abyVT3184_VT3226D0);           //RobertYu:20060515
+        pbyAddr = abyVT3184_VT3226D0;                   //RobertYu:20060515
+        pbyAgc = abyVT3184_AGC;
+        wLengthAgc = sizeof(abyVT3184_AGC);
+
+        pDevice->abyBBVGA[0] = 0x20; //RobertYu:20060104, reguest by Jack
+        pDevice->abyBBVGA[1] = 0x10;
+        pDevice->abyBBVGA[2] = 0x0;
+        pDevice->abyBBVGA[3] = 0x0;
+        pDevice->ldBmThreshold[0] = -70;
+        pDevice->ldBmThreshold[1] = -48;
+        pDevice->ldBmThreshold[2] = 0;
+        pDevice->ldBmThreshold[3] = 0;
+        // Fix VT3226 DFC system timing issue
+        MACvRegBitsOn(pDevice, MAC_REG_SOFTPWRCTL2, SOFTPWRCTL_RFLEOPT);
+    //}}
+    //{{RobertYu:20060609
+    } else if ( (pDevice->byRFType == RF_VT3342A0) ) {
+        pDevice->byBBRxConf = abyVT3184_VT3226D0[10];
+        wLength = sizeof(abyVT3184_VT3226D0);
+        pbyAddr = abyVT3184_VT3226D0;
+        pbyAgc = abyVT3184_AGC;
+        wLengthAgc = sizeof(abyVT3184_AGC);
+
+        pDevice->abyBBVGA[0] = 0x20;
+        pDevice->abyBBVGA[1] = 0x10;
+        pDevice->abyBBVGA[2] = 0x0;
+        pDevice->abyBBVGA[3] = 0x0;
+        pDevice->ldBmThreshold[0] = -70;
+        pDevice->ldBmThreshold[1] = -48;
+        pDevice->ldBmThreshold[2] = 0;
+        pDevice->ldBmThreshold[3] = 0;
+        // Fix VT3226 DFC system timing issue
+        MACvRegBitsOn(pDevice, MAC_REG_SOFTPWRCTL2, SOFTPWRCTL_RFLEOPT);
+    //}}
+    } else {
+        return TRUE;
+    }
+
+   memcpy(abyArray, pbyAddr, wLength);
+   CONTROLnsRequestOut(pDevice,
+                    MESSAGE_TYPE_WRITE,
+                    0,
+                    MESSAGE_REQUEST_BBREG,
+                    wLength,
+                    abyArray
+                    );
+
+   memcpy(abyArray, pbyAgc, wLengthAgc);
+   CONTROLnsRequestOut(pDevice,
+                    MESSAGE_TYPE_WRITE,
+                    0,
+                    MESSAGE_REQUEST_BBAGC,
+                    wLengthAgc,
+                    abyArray
+                    );
+
+
+    if ((pDevice->byRFType == RF_VT3226) || //RobertYu:20051116, 20060111 remove VT3226D0
+         (pDevice->byRFType == RF_VT3342A0)  //RobertYu:20060609
+         ) {
+        ControlvWriteByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_ITRTMSET,0x23);
+        MACvRegBitsOn(pDevice,MAC_REG_PAPEDELAY,0x01);
+    }
+    else if (pDevice->byRFType == RF_VT3226D0)
+    {
+        ControlvWriteByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_ITRTMSET,0x11);
+        MACvRegBitsOn(pDevice,MAC_REG_PAPEDELAY,0x01);
+    }
+
+
+    ControlvWriteByte(pDevice,MESSAGE_REQUEST_BBREG,0x04,0x7F);
+    ControlvWriteByte(pDevice,MESSAGE_REQUEST_BBREG,0x0D,0x01);
+
+    RFbRFTableDownload(pDevice);
+    return TRUE;//ntStatus;
+}
+
+
+/*
+ * Description: Turn on BaseBand Loopback mode
+ *
+ * Parameters:
+ *  In:
+ *      pDevice         - Device Structure
+ *
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void BBvLoopbackOn (PSDevice pDevice)
+{
+    BYTE      byData;
+
+    //CR C9 = 0x00
+    ControlvReadByte (pDevice, MESSAGE_REQUEST_BBREG, 0xC9, &pDevice->byBBCRc9);//CR201
+    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0);
+    ControlvReadByte (pDevice, MESSAGE_REQUEST_BBREG, 0x4D, &pDevice->byBBCR4d);//CR77
+    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x4D, 0x90);
+
+    //CR 88 = 0x02(CCK), 0x03(OFDM)
+    ControlvReadByte (pDevice, MESSAGE_REQUEST_BBREG, 0x88, &pDevice->byBBCR88);//CR136
+
+    if (pDevice->wCurrentRate <= RATE_11M) { //CCK
+        // Enable internal digital loopback: CR33 |= 0000 0001
+        ControlvReadByte (pDevice, MESSAGE_REQUEST_BBREG, 0x21, &byData);//CR33
+        ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x21, (BYTE)(byData | 0x01));//CR33
+        // CR154 = 0x00
+        ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x9A, 0);   //CR154
+
+        ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x88, 0x02);//CR239
+    }
+    else { //OFDM
+        // Enable internal digital loopback:CR154 |= 0000 0001
+        ControlvReadByte (pDevice, MESSAGE_REQUEST_BBREG, 0x9A, &byData);//CR154
+        ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x9A, (BYTE)(byData | 0x01));//CR154
+        // CR33 = 0x00
+        ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x21, 0);   //CR33
+
+        ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x88, 0x03);//CR239
+    }
+
+    //CR14 = 0x00
+    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x0E, 0);//CR14
+
+    // Disable TX_IQUN
+    ControlvReadByte (pDevice, MESSAGE_REQUEST_BBREG, 0x09, &pDevice->byBBCR09);
+    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x09, (BYTE)(pDevice->byBBCR09 & 0xDE));
+}
+
+/*
+ * Description: Turn off BaseBand Loopback mode
+ *
+ * Parameters:
+ *  In:
+ *      pDevice         - Device Structure
+ *
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void BBvLoopbackOff (PSDevice pDevice)
+{
+    BYTE      byData;
+
+    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, pDevice->byBBCRc9);//CR201
+    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x88, pDevice->byBBCR88);//CR136
+    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x09, pDevice->byBBCR09);//CR136
+    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x4D, pDevice->byBBCR4d);//CR77
+
+    if (pDevice->wCurrentRate <= RATE_11M) { // CCK
+        // Set the CR33 Bit2 to disable internal Loopback.
+        ControlvReadByte (pDevice, MESSAGE_REQUEST_BBREG, 0x21, &byData);//CR33
+        ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x21, (BYTE)(byData & 0xFE));//CR33
+    }
+    else { // OFDM
+        ControlvReadByte (pDevice, MESSAGE_REQUEST_BBREG, 0x9A, &byData);//CR154
+        ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x9A, (BYTE)(byData & 0xFE));//CR154
+    }
+    ControlvReadByte (pDevice, MESSAGE_REQUEST_BBREG, 0x0E, &byData);//CR14
+    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x0E, (BYTE)(byData | 0x80));//CR14
+
+}
+
+
+/*
+ * Description: Set ShortSlotTime mode
+ *
+ * Parameters:
+ *  In:
+ *      pDevice     - Device Structure
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+VOID
+BBvSetShortSlotTime (PSDevice pDevice)
+{
+    BYTE byBBVGA=0;
+
+    if (pDevice->bShortSlotTime) {
+        pDevice->byBBRxConf &= 0xDF;//1101 1111
+    } else {
+        pDevice->byBBRxConf |= 0x20;//0010 0000
+    }
+
+    ControlvReadByte (pDevice, MESSAGE_REQUEST_BBREG, 0xE7, &byBBVGA);
+    if (byBBVGA == pDevice->abyBBVGA[0]) {
+        pDevice->byBBRxConf |= 0x20;//0010 0000
+    }
+
+    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x0A, pDevice->byBBRxConf);
+
+}
+
+
+VOID BBvSetVGAGainOffset(PSDevice pDevice, BYTE byData)
+{
+
+    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xE7, byData);
+
+    // patch for 3253B0 Baseband with Cardbus module
+    if (byData == pDevice->abyBBVGA[0]) {
+        pDevice->byBBRxConf |= 0x20;//0010 0000
+    } else if (pDevice->bShortSlotTime) {
+        pDevice->byBBRxConf &= 0xDF;//1101 1111
+    } else {
+        pDevice->byBBRxConf |= 0x20;//0010 0000
+    }
+    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x0A, pDevice->byBBRxConf);//CR10
+}
+
+
+/*
+ * Description: Baseband SoftwareReset
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - I/O base address
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+VOID
+BBvSoftwareReset (PSDevice pDevice)
+{
+    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x50, 0x40);
+    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x50, 0);
+    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x9C, 0x01);
+    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x9C, 0);
+}
+
+/*
+ * Description: BBvSetDeepSleep
+ *
+ * Parameters:
+ *  In:
+ *      pDevice          - Device Structure
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+VOID
+BBvSetDeepSleep (PSDevice pDevice)
+{
+    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x0c, 0x17);//CR12
+    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x0D, 0xB9);//CR13
+}
+
+VOID
+BBvExitDeepSleep (PSDevice pDevice)
+{
+    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x0C, 0x00);//CR12
+    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x0D, 0x01);//CR13
+}
+
+
+static
+ULONG
+s_ulGetLowSQ3(PSDevice pDevice)
+{
+int   ii;
+ULONG ulSQ3 = 0;
+ULONG ulMaxPacket;
+
+    ulMaxPacket = pDevice->aulPktNum[RATE_54M];
+    if ( pDevice->aulPktNum[RATE_54M] != 0 ) {
+        ulSQ3 = pDevice->aulSQ3Val[RATE_54M] / pDevice->aulPktNum[RATE_54M];
+    }
+    for ( ii=RATE_48M;ii>=RATE_6M;ii-- ) {
+        if ( pDevice->aulPktNum[ii] > ulMaxPacket ) {
+            ulMaxPacket = pDevice->aulPktNum[ii];
+            ulSQ3 = pDevice->aulSQ3Val[ii] / pDevice->aulPktNum[ii];
+        }
+    }
+
+    return ulSQ3;
+}
+
+
+
+static
+ULONG
+s_ulGetRatio (PSDevice pDevice)
+{
+int     ii,jj;
+ULONG   ulRatio = 0;
+ULONG   ulMaxPacket;
+ULONG   ulPacketNum;
+
+    //This is a thousand-ratio
+    ulMaxPacket = pDevice->aulPktNum[RATE_54M];
+    if ( pDevice->aulPktNum[RATE_54M] != 0 ) {
+        ulPacketNum = pDevice->aulPktNum[RATE_54M];
+        ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt);
+        ulRatio += TOP_RATE_54M;
+    }
+    for ( ii=RATE_48M;ii>=RATE_1M;ii-- ) {
+        if ( pDevice->aulPktNum[ii] > ulMaxPacket ) {
+            ulPacketNum = 0;
+            for ( jj=RATE_54M;jj>=ii;jj--)
+                ulPacketNum += pDevice->aulPktNum[jj];
+            ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt);
+            ulRatio += TOP_RATE_48M;
+            ulMaxPacket = pDevice->aulPktNum[ii];
+        }
+
+    }
+
+    return ulRatio;
+}
+
+
+static
+void
+s_vClearSQ3Value (PSDevice pDevice)
+{
+    int ii;
+    pDevice->uDiversityCnt = 0;
+
+    for ( ii=RATE_1M;ii<MAX_RATE;ii++) {
+        pDevice->aulPktNum[ii] = 0;
+        pDevice->aulSQ3Val[ii] = 0;
+    }
+}
+
+
+/*
+ * Description: Antenna Diversity
+ *
+ * Parameters:
+ *  In:
+ *      pDevice          - Device Structure
+ *      byRSR            - RSR from received packet
+ *      bySQ3            - SQ3 value from received packet
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+
+VOID
+BBvAntennaDiversity (PSDevice pDevice, BYTE byRxRate, BYTE bySQ3)
+{
+
+    pDevice->uDiversityCnt++;
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pDevice->uDiversityCnt = %d\n", (int)pDevice->uDiversityCnt);
+
+    if (byRxRate == 2) {
+        pDevice->aulPktNum[RATE_1M]++;
+    }
+    else if (byRxRate==4) {
+        pDevice->aulPktNum[RATE_2M]++;
+    }
+    else if (byRxRate==11) {
+        pDevice->aulPktNum[RATE_5M]++;
+    }
+    else if (byRxRate==22) {
+        pDevice->aulPktNum[RATE_11M]++;
+    }
+    else if(byRxRate==12){
+        pDevice->aulPktNum[RATE_6M]++;
+        pDevice->aulSQ3Val[RATE_6M] += bySQ3;
+    }
+    else if(byRxRate==18){
+        pDevice->aulPktNum[RATE_9M]++;
+        pDevice->aulSQ3Val[RATE_9M] += bySQ3;
+    }
+    else if(byRxRate==24){
+        pDevice->aulPktNum[RATE_12M]++;
+        pDevice->aulSQ3Val[RATE_12M] += bySQ3;
+    }
+    else if(byRxRate==36){
+        pDevice->aulPktNum[RATE_18M]++;
+        pDevice->aulSQ3Val[RATE_18M] += bySQ3;
+    }
+    else if(byRxRate==48){
+        pDevice->aulPktNum[RATE_24M]++;
+        pDevice->aulSQ3Val[RATE_24M] += bySQ3;
+    }
+    else if(byRxRate==72){
+        pDevice->aulPktNum[RATE_36M]++;
+        pDevice->aulSQ3Val[RATE_36M] += bySQ3;
+    }
+    else if(byRxRate==96){
+        pDevice->aulPktNum[RATE_48M]++;
+        pDevice->aulSQ3Val[RATE_48M] += bySQ3;
+    }
+    else if(byRxRate==108){
+        pDevice->aulPktNum[RATE_54M]++;
+        pDevice->aulSQ3Val[RATE_54M] += bySQ3;
+    }
+
+    if (pDevice->byAntennaState == 0) {
+
+        if (pDevice->uDiversityCnt > pDevice->ulDiversityNValue) {
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ulDiversityNValue=[%d],54M-[%d]\n",(int)pDevice->ulDiversityNValue, (int)pDevice->aulPktNum[RATE_54M]);
+
+            pDevice->ulSQ3_State0 = s_ulGetLowSQ3(pDevice);
+            pDevice->ulRatio_State0 = s_ulGetRatio(pDevice);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"SQ3_State0, SQ3= [%08x] rate = [%08x]\n",(int)pDevice->ulSQ3_State0,(int)pDevice->ulRatio_State0);
+
+            if ( ((pDevice->aulPktNum[RATE_54M] < pDevice->ulDiversityNValue/2) &&
+                  (pDevice->ulSQ3_State0 > pDevice->ulSQ3TH) ) ||
+                 (pDevice->ulSQ3_State0 == 0 ) )  {
+
+                if ( pDevice->byTMax == 0 )
+                    return;
+
+                bScheduleCommand((HANDLE) pDevice, WLAN_CMD_CHANGE_ANTENNA, NULL);
+
+                pDevice->byAntennaState = 1;
+
+                del_timer(&pDevice->TimerSQ3Tmax3);
+                del_timer(&pDevice->TimerSQ3Tmax2);
+                pDevice->TimerSQ3Tmax1.expires =  RUN_AT(pDevice->byTMax * HZ);
+                add_timer(&pDevice->TimerSQ3Tmax1);
+
+            } else {
+                pDevice->TimerSQ3Tmax3.expires =  RUN_AT(pDevice->byTMax3 * HZ);
+                add_timer(&pDevice->TimerSQ3Tmax3);
+            }
+            s_vClearSQ3Value(pDevice);
+
+        }
+    } else { //byAntennaState == 1
+
+        if (pDevice->uDiversityCnt > pDevice->ulDiversityMValue) {
+
+            del_timer(&pDevice->TimerSQ3Tmax1);
+            pDevice->ulSQ3_State1 = s_ulGetLowSQ3(pDevice);
+            pDevice->ulRatio_State1 = s_ulGetRatio(pDevice);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"SQ3_State1, rate0 = %08x,rate1 = %08x\n",(int)pDevice->ulRatio_State0,(int)pDevice->ulRatio_State1);
+
+            if ( ((pDevice->ulSQ3_State1 == 0) && (pDevice->ulSQ3_State0 != 0)) ||
+                 ((pDevice->ulSQ3_State1 == 0) && (pDevice->ulSQ3_State0 == 0) && (pDevice->ulRatio_State1 < pDevice->ulRatio_State0)) ||
+                 ((pDevice->ulSQ3_State1 != 0) && (pDevice->ulSQ3_State0 != 0) && (pDevice->ulSQ3_State0 < pDevice->ulSQ3_State1))
+               ) {
+
+                bScheduleCommand((HANDLE) pDevice, WLAN_CMD_CHANGE_ANTENNA, NULL);
+
+                pDevice->TimerSQ3Tmax3.expires =  RUN_AT(pDevice->byTMax3 * HZ);
+                pDevice->TimerSQ3Tmax2.expires =  RUN_AT(pDevice->byTMax2 * HZ);
+                add_timer(&pDevice->TimerSQ3Tmax3);
+                add_timer(&pDevice->TimerSQ3Tmax2);
+
+            }
+            pDevice->byAntennaState = 0;
+            s_vClearSQ3Value(pDevice);
+        }
+    } //byAntennaState
+}
+
+
+/*+
+ *
+ * Description:
+ *  Timer for SQ3 antenna diversity
+ *
+ * Parameters:
+ *  In:
+ *      pvSysSpec1
+ *      hDeviceContext - Pointer to the adapter
+ *      pvSysSpec2
+ *      pvSysSpec3
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+-*/
+
+VOID
+TimerSQ3CallBack (
+    IN  HANDLE      hDeviceContext
+    )
+{
+    PSDevice        pDevice = (PSDevice)hDeviceContext;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"TimerSQ3CallBack...");
+    spin_lock_irq(&pDevice->lock);
+
+    bScheduleCommand((HANDLE) pDevice, WLAN_CMD_CHANGE_ANTENNA, NULL);
+    pDevice->byAntennaState = 0;
+    s_vClearSQ3Value(pDevice);
+    pDevice->TimerSQ3Tmax3.expires =  RUN_AT(pDevice->byTMax3 * HZ);
+    pDevice->TimerSQ3Tmax2.expires =  RUN_AT(pDevice->byTMax2 * HZ);
+    add_timer(&pDevice->TimerSQ3Tmax3);
+    add_timer(&pDevice->TimerSQ3Tmax2);
+
+
+    spin_unlock_irq(&pDevice->lock);
+    return;
+}
+
+
+/*+
+ *
+ * Description:
+ *  Timer for SQ3 antenna diversity
+ *
+ * Parameters:
+ *  In:
+ *      pvSysSpec1
+ *      hDeviceContext - Pointer to the adapter
+ *      pvSysSpec2
+ *      pvSysSpec3
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+-*/
+
+VOID
+TimerSQ3Tmax3CallBack (
+    IN  HANDLE      hDeviceContext
+    )
+{
+    PSDevice        pDevice = (PSDevice)hDeviceContext;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"TimerSQ3Tmax3CallBack...");
+    spin_lock_irq(&pDevice->lock);
+
+    pDevice->ulRatio_State0 = s_ulGetRatio(pDevice);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"SQ3_State0 = [%08x]\n",(int)pDevice->ulRatio_State0);
+
+    s_vClearSQ3Value(pDevice);
+    if ( pDevice->byTMax == 0 ) {
+        pDevice->TimerSQ3Tmax3.expires =  RUN_AT(pDevice->byTMax3 * HZ);
+        add_timer(&pDevice->TimerSQ3Tmax3);
+        spin_unlock_irq(&pDevice->lock);
+        return;
+    }
+
+    bScheduleCommand((HANDLE) pDevice, WLAN_CMD_CHANGE_ANTENNA, NULL);
+    pDevice->byAntennaState = 1;
+    del_timer(&pDevice->TimerSQ3Tmax3);
+    del_timer(&pDevice->TimerSQ3Tmax2);
+    pDevice->TimerSQ3Tmax1.expires =  RUN_AT(pDevice->byTMax * HZ);
+    add_timer(&pDevice->TimerSQ3Tmax1);
+
+    spin_unlock_irq(&pDevice->lock);
+    return;
+}
+
+VOID
+BBvUpdatePreEDThreshold(
+    IN  PSDevice    pDevice,
+    IN  BOOL        bScanning)
+{
+
+
+    switch(pDevice->byRFType)
+    {
+        case RF_AL2230:
+        case RF_AL2230S:
+        case RF_AIROHA7230:
+            //RobertYu:20060627, update new table
+
+            if( bScanning )
+            {   // need Max sensitivity //RSSI -69, -70,....
+                if(pDevice->byBBPreEDIndex == 0) break;
+                pDevice->byBBPreEDIndex = 0;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x30); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -69, -70, -71,...\n");
+                break;
+            }
+
+            if(pDevice->byBBPreEDRSSI <= 45) { // RSSI 0, -1,-2,....-45
+                if(pDevice->byBBPreEDIndex == 20) break;
+                pDevice->byBBPreEDIndex = 20;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0xFF); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI 0, -1,-2,..-45\n");
+            } else if(pDevice->byBBPreEDRSSI <= 46)  { //RSSI -46
+                if(pDevice->byBBPreEDIndex == 19) break;
+                pDevice->byBBPreEDIndex = 19;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x1A); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -46\n");
+            } else if(pDevice->byBBPreEDRSSI <= 47)  { //RSSI -47
+                if(pDevice->byBBPreEDIndex == 18) break;
+                pDevice->byBBPreEDIndex = 18;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x15); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -47\n");
+            } else if(pDevice->byBBPreEDRSSI <= 49)  { //RSSI -48, -49
+                if(pDevice->byBBPreEDIndex == 17) break;
+                pDevice->byBBPreEDIndex = 17;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x0E); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -48,-49\n");
+            } else if(pDevice->byBBPreEDRSSI <= 51)  { //RSSI -50, -51
+                if(pDevice->byBBPreEDIndex == 16) break;
+                pDevice->byBBPreEDIndex = 16;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x09); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -50,-51\n");
+            } else if(pDevice->byBBPreEDRSSI <= 53)  { //RSSI -52, -53
+                if(pDevice->byBBPreEDIndex == 15) break;
+                pDevice->byBBPreEDIndex = 15;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x06); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -52,-53\n");
+            } else if(pDevice->byBBPreEDRSSI <= 55)  { //RSSI -54, -55
+                if(pDevice->byBBPreEDIndex == 14) break;
+                pDevice->byBBPreEDIndex = 14;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x03); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -54,-55\n");
+            } else if(pDevice->byBBPreEDRSSI <= 56)  { //RSSI -56
+                if(pDevice->byBBPreEDIndex == 13) break;
+                pDevice->byBBPreEDIndex = 13;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x02); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0xA0); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -56\n");
+            } else if(pDevice->byBBPreEDRSSI <= 57)  { //RSSI -57
+                if(pDevice->byBBPreEDIndex == 12) break;
+                pDevice->byBBPreEDIndex = 12;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x02); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x20); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -57\n");
+            } else if(pDevice->byBBPreEDRSSI <= 58)  { //RSSI -58
+                if(pDevice->byBBPreEDIndex == 11) break;
+                pDevice->byBBPreEDIndex = 11;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x01); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0xA0); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -58\n");
+            } else if(pDevice->byBBPreEDRSSI <= 59)  { //RSSI -59
+                if(pDevice->byBBPreEDIndex == 10) break;
+                pDevice->byBBPreEDIndex = 10;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x01); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x54); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -59\n");
+            } else if(pDevice->byBBPreEDRSSI <= 60)  { //RSSI -60
+                if(pDevice->byBBPreEDIndex == 9) break;
+                pDevice->byBBPreEDIndex = 9;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x01); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x18); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -60\n");
+            } else if(pDevice->byBBPreEDRSSI <= 61)  { //RSSI -61
+                if(pDevice->byBBPreEDIndex == 8) break;
+                pDevice->byBBPreEDIndex = 8;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0xE3); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -61\n");
+            } else if(pDevice->byBBPreEDRSSI <= 62)  { //RSSI -62
+                if(pDevice->byBBPreEDIndex == 7) break;
+                pDevice->byBBPreEDIndex = 7;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0xB9); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -62\n");
+            } else if(pDevice->byBBPreEDRSSI <= 63)  { //RSSI -63
+                if(pDevice->byBBPreEDIndex == 6) break;
+                pDevice->byBBPreEDIndex = 6;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x93); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -63\n");
+            } else if(pDevice->byBBPreEDRSSI <= 64)  { //RSSI -64
+                if(pDevice->byBBPreEDIndex == 5) break;
+                pDevice->byBBPreEDIndex = 5;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x79); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -64\n");
+            } else if(pDevice->byBBPreEDRSSI <= 65)  { //RSSI -65
+                if(pDevice->byBBPreEDIndex == 4) break;
+                pDevice->byBBPreEDIndex = 4;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x62); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -65\n");
+            } else if(pDevice->byBBPreEDRSSI <= 66)  { //RSSI -66
+                if(pDevice->byBBPreEDIndex == 3) break;
+                pDevice->byBBPreEDIndex = 3;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x51); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -66\n");
+            } else if(pDevice->byBBPreEDRSSI <= 67)  { //RSSI -67
+                if(pDevice->byBBPreEDIndex == 2) break;
+                pDevice->byBBPreEDIndex = 2;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x43); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -67\n");
+            } else if(pDevice->byBBPreEDRSSI <= 68)  { //RSSI -68
+                if(pDevice->byBBPreEDIndex == 1) break;
+                pDevice->byBBPreEDIndex = 1;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x36); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -68\n");
+            } else { //RSSI -69, -70,....
+                if(pDevice->byBBPreEDIndex == 0) break;
+                pDevice->byBBPreEDIndex = 0;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x30); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -69, -70,...\n");
+            }
+            break;
+
+        case RF_VT3226:
+        case RF_VT3226D0:
+            //RobertYu:20060627, update new table
+
+            if( bScanning )
+            {   // need Max sensitivity  //RSSI -69, -70, ...
+                if(pDevice->byBBPreEDIndex == 0) break;
+                pDevice->byBBPreEDIndex = 0;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x24); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -69, -70,..\n");
+                break;
+            }
+
+            if(pDevice->byBBPreEDRSSI <= 41) { // RSSI 0, -1,-2,....-41
+                if(pDevice->byBBPreEDIndex == 22) break;
+                pDevice->byBBPreEDIndex = 22;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0xFF); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI 0, -1,-2,..-41\n");
+            } else if(pDevice->byBBPreEDRSSI <= 42)  { //RSSI -42
+                if(pDevice->byBBPreEDIndex == 21) break;
+                pDevice->byBBPreEDIndex = 21;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x36); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -42\n");
+            } else if(pDevice->byBBPreEDRSSI <= 43)  { //RSSI -43
+                if(pDevice->byBBPreEDIndex == 20) break;
+                pDevice->byBBPreEDIndex = 20;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x26); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -43\n");
+            } else if(pDevice->byBBPreEDRSSI <= 45)  { //RSSI -44, -45
+                if(pDevice->byBBPreEDIndex == 19) break;
+                pDevice->byBBPreEDIndex = 19;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x18); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -44,-45\n");
+            } else if(pDevice->byBBPreEDRSSI <= 47)  { //RSSI -46, -47
+                if(pDevice->byBBPreEDIndex == 18) break;
+                pDevice->byBBPreEDIndex = 18;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x11); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -46,-47\n");
+            } else if(pDevice->byBBPreEDRSSI <= 49)  { //RSSI -48, -49
+                if(pDevice->byBBPreEDIndex == 17) break;
+                pDevice->byBBPreEDIndex = 17;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x0a); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -48,-49\n");
+            } else if(pDevice->byBBPreEDRSSI <= 51)  { //RSSI -50, -51
+                if(pDevice->byBBPreEDIndex == 16) break;
+                pDevice->byBBPreEDIndex = 16;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x07); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -50,-51\n");
+            } else if(pDevice->byBBPreEDRSSI <= 53)  { //RSSI -52, -53
+                if(pDevice->byBBPreEDIndex == 15) break;
+                pDevice->byBBPreEDIndex = 15;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x04); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -52,-53\n");
+            } else if(pDevice->byBBPreEDRSSI <= 55)  { //RSSI -54, -55
+                if(pDevice->byBBPreEDIndex == 14) break;
+                pDevice->byBBPreEDIndex = 14;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x02); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0xC0); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -54,-55\n");
+            } else if(pDevice->byBBPreEDRSSI <= 56)  { //RSSI -56
+                if(pDevice->byBBPreEDIndex == 13) break;
+                pDevice->byBBPreEDIndex = 13;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x02); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x30); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -56\n");
+            } else if(pDevice->byBBPreEDRSSI <= 57)  { //RSSI -57
+                if(pDevice->byBBPreEDIndex == 12) break;
+                pDevice->byBBPreEDIndex = 12;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x01); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0xB0); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -57\n");
+            } else if(pDevice->byBBPreEDRSSI <= 58)  { //RSSI -58
+                if(pDevice->byBBPreEDIndex == 11) break;
+                pDevice->byBBPreEDIndex = 11;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x01); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x70); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -58\n");
+            } else if(pDevice->byBBPreEDRSSI <= 59)  { //RSSI -59
+                if(pDevice->byBBPreEDIndex == 10) break;
+                pDevice->byBBPreEDIndex = 10;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x01); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x30); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -59\n");
+            } else if(pDevice->byBBPreEDRSSI <= 60)  { //RSSI -60
+                if(pDevice->byBBPreEDIndex == 9) break;
+                pDevice->byBBPreEDIndex = 9;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0xEA); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -60\n");
+            } else if(pDevice->byBBPreEDRSSI <= 61)  { //RSSI -61
+                if(pDevice->byBBPreEDIndex == 8) break;
+                pDevice->byBBPreEDIndex = 8;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0xC0); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -61\n");
+            } else if(pDevice->byBBPreEDRSSI <= 62)  { //RSSI -62
+                if(pDevice->byBBPreEDIndex == 7) break;
+                pDevice->byBBPreEDIndex = 7;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x9C); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -62\n");
+            } else if(pDevice->byBBPreEDRSSI <= 63)  { //RSSI -63
+                if(pDevice->byBBPreEDIndex == 6) break;
+                pDevice->byBBPreEDIndex = 6;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x80); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -63\n");
+            } else if(pDevice->byBBPreEDRSSI <= 64)  { //RSSI -64
+                if(pDevice->byBBPreEDIndex == 5) break;
+                pDevice->byBBPreEDIndex = 5;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x68); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -64\n");
+            } else if(pDevice->byBBPreEDRSSI <= 65)  { //RSSI -65
+                if(pDevice->byBBPreEDIndex == 4) break;
+                pDevice->byBBPreEDIndex = 4;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x52); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -65\n");
+            } else if(pDevice->byBBPreEDRSSI <= 66)  { //RSSI -66
+                if(pDevice->byBBPreEDIndex == 3) break;
+                pDevice->byBBPreEDIndex = 3;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x43); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -66\n");
+            } else if(pDevice->byBBPreEDRSSI <= 67)  { //RSSI -67
+                if(pDevice->byBBPreEDIndex == 2) break;
+                pDevice->byBBPreEDIndex = 2;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x36); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -67\n");
+            } else if(pDevice->byBBPreEDRSSI <= 68)  { //RSSI -68
+                if(pDevice->byBBPreEDIndex == 1) break;
+                pDevice->byBBPreEDIndex = 1;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x2D); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -68\n");
+            } else { //RSSI -69, -70, ...
+                if(pDevice->byBBPreEDIndex == 0) break;
+                pDevice->byBBPreEDIndex = 0;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x24); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -69, -70,..\n");
+            }
+            break;
+
+        case RF_VT3342A0: //RobertYu:20060627, testing table
+            if( bScanning )
+            {   // need Max sensitivity  //RSSI -67, -68, ...
+                if(pDevice->byBBPreEDIndex == 0) break;
+                pDevice->byBBPreEDIndex = 0;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x38); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -67, -68,..\n");
+                break;
+            }
+
+            if(pDevice->byBBPreEDRSSI <= 41) { // RSSI 0, -1,-2,....-41
+                if(pDevice->byBBPreEDIndex == 20) break;
+                pDevice->byBBPreEDIndex = 20;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0xFF); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI 0, -1,-2,..-41\n");
+            } else if(pDevice->byBBPreEDRSSI <= 42)  { //RSSI -42
+                if(pDevice->byBBPreEDIndex == 19) break;
+                pDevice->byBBPreEDIndex = 19;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x36); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -42\n");
+            } else if(pDevice->byBBPreEDRSSI <= 43)  { //RSSI -43
+                if(pDevice->byBBPreEDIndex == 18) break;
+                pDevice->byBBPreEDIndex = 18;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x26); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -43\n");
+            } else if(pDevice->byBBPreEDRSSI <= 45)  { //RSSI -44, -45
+                if(pDevice->byBBPreEDIndex == 17) break;
+                pDevice->byBBPreEDIndex = 17;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x18); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -44,-45\n");
+            } else if(pDevice->byBBPreEDRSSI <= 47)  { //RSSI -46, -47
+                if(pDevice->byBBPreEDIndex == 16) break;
+                pDevice->byBBPreEDIndex = 16;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x11); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -46,-47\n");
+            } else if(pDevice->byBBPreEDRSSI <= 49)  { //RSSI -48, -49
+                if(pDevice->byBBPreEDIndex == 15) break;
+                pDevice->byBBPreEDIndex = 15;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x0a); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -48,-49\n");
+            } else if(pDevice->byBBPreEDRSSI <= 51)  { //RSSI -50, -51
+                if(pDevice->byBBPreEDIndex == 14) break;
+                pDevice->byBBPreEDIndex = 14;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x07); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -50,-51\n");
+            } else if(pDevice->byBBPreEDRSSI <= 53)  { //RSSI -52, -53
+                if(pDevice->byBBPreEDIndex == 13) break;
+                pDevice->byBBPreEDIndex = 13;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x04); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -52,-53\n");
+            } else if(pDevice->byBBPreEDRSSI <= 55)  { //RSSI -54, -55
+                if(pDevice->byBBPreEDIndex == 12) break;
+                pDevice->byBBPreEDIndex = 12;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x02); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0xC0); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -54,-55\n");
+            } else if(pDevice->byBBPreEDRSSI <= 56)  { //RSSI -56
+                if(pDevice->byBBPreEDIndex == 11) break;
+                pDevice->byBBPreEDIndex = 11;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x02); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x30); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -56\n");
+            } else if(pDevice->byBBPreEDRSSI <= 57)  { //RSSI -57
+                if(pDevice->byBBPreEDIndex == 10) break;
+                pDevice->byBBPreEDIndex = 10;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x01); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0xB0); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -57\n");
+            } else if(pDevice->byBBPreEDRSSI <= 58)  { //RSSI -58
+                if(pDevice->byBBPreEDIndex == 9) break;
+                pDevice->byBBPreEDIndex = 9;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x01); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x70); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -58\n");
+            } else if(pDevice->byBBPreEDRSSI <= 59)  { //RSSI -59
+                if(pDevice->byBBPreEDIndex == 8) break;
+                pDevice->byBBPreEDIndex = 8;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x01); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x30); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -59\n");
+            } else if(pDevice->byBBPreEDRSSI <= 60)  { //RSSI -60
+                if(pDevice->byBBPreEDIndex == 7) break;
+                pDevice->byBBPreEDIndex = 7;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0xEA); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -60\n");
+            } else if(pDevice->byBBPreEDRSSI <= 61)  { //RSSI -61
+                if(pDevice->byBBPreEDIndex == 6) break;
+                pDevice->byBBPreEDIndex = 6;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0xC0); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -61\n");
+            } else if(pDevice->byBBPreEDRSSI <= 62)  { //RSSI -62
+                if(pDevice->byBBPreEDIndex == 5) break;
+                pDevice->byBBPreEDIndex = 5;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x9C); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -62\n");
+            } else if(pDevice->byBBPreEDRSSI <= 63)  { //RSSI -63
+                if(pDevice->byBBPreEDIndex == 4) break;
+                pDevice->byBBPreEDIndex = 4;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x80); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -63\n");
+            } else if(pDevice->byBBPreEDRSSI <= 64)  { //RSSI -64
+                if(pDevice->byBBPreEDIndex == 3) break;
+                pDevice->byBBPreEDIndex = 3;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x68); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -64\n");
+            } else if(pDevice->byBBPreEDRSSI <= 65)  { //RSSI -65
+                if(pDevice->byBBPreEDIndex == 2) break;
+                pDevice->byBBPreEDIndex = 2;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x52); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -65\n");
+            } else if(pDevice->byBBPreEDRSSI <= 66)  { //RSSI -66
+                if(pDevice->byBBPreEDIndex == 1) break;
+                pDevice->byBBPreEDIndex = 1;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x43); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -66\n");
+            } else { //RSSI -67, -68, ...
+                if(pDevice->byBBPreEDIndex == 0) break;
+                pDevice->byBBPreEDIndex = 0;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x38); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -67, -68,..\n");
+            }
+            break;
+
+    }
+
+}
+
diff --git a/drivers/staging/vt6656/baseband.h b/drivers/staging/vt6656/baseband.h
new file mode 100644
index 0000000..9cad837
--- /dev/null
+++ b/drivers/staging/vt6656/baseband.h
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: baseband.h
+ *
+ * Purpose: Implement functions to access baseband
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Jun. 5, 2002
+ *
+ * Revision History:
+ *      06-10-2003 Bryan YC Fan:  Re-write codes to support VT3253 spec.
+ *      08-26-2003 Kyle Hsu    :  Add defines of packet type and TX rate.
+ */
+
+#ifndef __BASEBAND_H__
+#define __BASEBAND_H__
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+
+#if !defined(__TETHER_H__)
+#include "tether.h"
+#endif
+
+#if !defined(__DEVICE_H__)
+#include "device.h"
+#endif
+
+
+/*---------------------  Export Definitions -------------------------*/
+
+#define PREAMBLE_LONG   0
+#define PREAMBLE_SHORT  1
+
+//
+// Registers in the BASEBAND
+//
+#define BB_MAX_CONTEXT_SIZE 256
+
+#define C_SIFS_A      16      // micro sec.
+#define C_SIFS_BG     10
+
+#define C_EIFS      80      // micro sec.
+
+
+#define C_SLOT_SHORT   9      // micro sec.
+#define C_SLOT_LONG   20
+
+#define C_CWMIN_A     15       // slot time
+#define C_CWMIN_B     31
+
+#define C_CWMAX      1023     // slot time
+
+//0:11A 1:11B 2:11G
+#define BB_TYPE_11A    0
+#define BB_TYPE_11B    1
+#define BB_TYPE_11G    2
+
+//0:11a,1:11b,2:11gb(only CCK in BasicRate),3:11ga(OFDM in Basic Rate)
+#define PK_TYPE_11A     0
+#define PK_TYPE_11B     1
+#define PK_TYPE_11GB    2
+#define PK_TYPE_11GA    3
+
+#define TOP_RATE_54M        0x80000000
+#define TOP_RATE_48M        0x40000000
+#define TOP_RATE_36M        0x20000000
+#define TOP_RATE_24M        0x10000000
+#define TOP_RATE_18M        0x08000000
+#define TOP_RATE_12M        0x04000000
+#define TOP_RATE_11M        0x02000000
+#define TOP_RATE_9M         0x01000000
+#define TOP_RATE_6M         0x00800000
+#define TOP_RATE_55M        0x00400000
+#define TOP_RATE_2M         0x00200000
+#define TOP_RATE_1M         0x00100000
+
+
+/*---------------------  Export Types  ------------------------------*/
+
+/*---------------------  Export Macros ------------------------------*/
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+#ifdef __cplusplus
+extern "C" {                            /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+UINT
+BBuGetFrameTime(
+    IN BYTE byPreambleType,
+    IN BYTE byFreqType,
+    IN UINT cbFrameLength,
+    IN WORD wRate
+    );
+
+VOID
+BBvCaculateParameter (
+    IN  PSDevice pDevice,
+    IN  UINT cbFrameLength,
+    IN  WORD wRate,
+    IN  BYTE byPacketType,
+    OUT PWORD pwPhyLen,
+    OUT PBYTE pbyPhySrv,
+    OUT PBYTE pbyPhySgn
+    );
+
+// timer for antenna diversity
+
+VOID
+TimerSQ3CallBack (
+    IN  HANDLE      hDeviceContext
+    );
+
+VOID
+TimerSQ3Tmax3CallBack (
+    IN  HANDLE      hDeviceContext
+    );
+
+VOID BBvAntennaDiversity (PSDevice pDevice, BYTE byRxRate, BYTE bySQ3);
+void BBvLoopbackOn (PSDevice pDevice);
+void BBvLoopbackOff (PSDevice pDevice);
+void BBvSoftwareReset (PSDevice pDevice);
+
+void BBvSetShortSlotTime(PSDevice pDevice);
+VOID BBvSetVGAGainOffset(PSDevice pDevice, BYTE byData);
+void BBvSetAntennaMode(PSDevice pDevice, BYTE byAntennaMode);
+BOOL BBbVT3184Init (PSDevice pDevice);
+VOID BBvSetDeepSleep (PSDevice pDevice);
+VOID BBvExitDeepSleep (PSDevice pDevice);
+VOID BBvUpdatePreEDThreshold(
+     IN  PSDevice    pDevice,
+     IN  BOOL        bScanning
+     );
+
+#ifdef __cplusplus
+}                                       /* End of extern "C" { */
+#endif /* __cplusplus */
+
+
+#endif // __BASEBAND_H__
diff --git a/drivers/staging/vt6656/bssdb.c b/drivers/staging/vt6656/bssdb.c
new file mode 100644
index 0000000..563fddc
--- /dev/null
+++ b/drivers/staging/vt6656/bssdb.c
@@ -0,0 +1,1777 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: bssdb.c
+ *
+ * Purpose: Handles the Basic Service Set & Node Database functions
+ *
+ * Functions:
+ *      BSSpSearchBSSList - Search known BSS list for Desire SSID or BSSID
+ *      BSSvClearBSSList - Clear BSS List
+ *      BSSbInsertToBSSList - Insert a BSS set into known BSS list
+ *      BSSbUpdateToBSSList - Update BSS set in known BSS list
+ *      BSSbIsSTAInNodeDB - Search Node DB table to find the index of matched DstAddr
+ *      BSSvCreateOneNode - Allocate an Node for Node DB
+ *      BSSvUpdateAPNode - Update AP Node content in Index 0 of KnownNodeDB
+ *      BSSvSecondCallBack - One second timer callback function to update Node DB info & AP link status
+ *      BSSvUpdateNodeTxCounter - Update Tx attemps, Tx failure counter in Node DB for auto-fall back rate control
+ *
+ * Revision History:
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: July 17, 2002
+ *
+ */
+
+
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+#if !defined(__TMACRO_H__)
+#include "tmacro.h"
+#endif
+#if !defined(__TETHER_H__)
+#include "tether.h"
+#endif
+#if !defined(__DEVICE_H__)
+#include "device.h"
+#endif
+#if !defined(__80211HDR_H__)
+#include "80211hdr.h"
+#endif
+#if !defined(__BSSDB_H__)
+#include "bssdb.h"
+#endif
+#if !defined(__WMGR_H__)
+#include "wmgr.h"
+#endif
+#if !defined(__DATARATE_H__)
+#include "datarate.h"
+#endif
+#if !defined(__DESC_H__)
+#include "desc.h"
+#endif
+#if !defined(__WCMD_H__)
+#include "wcmd.h"
+#endif
+#if !defined(__WPA_H__)
+#include "wpa.h"
+#endif
+#if !defined(__BASEBAND_H__)
+#include "baseband.h"
+#endif
+#if !defined(__RF_H__)
+#include "rf.h"
+#endif
+#if !defined(__CARD_H__)
+#include "card.h"
+#endif
+#if !defined(__MAC_H__)
+#include "mac.h"
+#endif
+#if !defined(__WPA2_H__)
+#include "wpa2.h"
+#endif
+#if !defined(__UMEM_H__)
+#include "umem.h"
+#endif
+#if !defined(__TBIT_H__)
+#include "tbit.h"
+#endif
+#if !defined(__CONTROL_H__)
+#include "control.h"
+#endif
+#if !defined(__RNDIS_H__)
+#include "rndis.h"
+#endif
+//DavidWang
+#if !defined(__IOWPA_H__)
+#include "iowpa.h"
+#endif
+
+/*---------------------  Static Definitions -------------------------*/
+
+
+
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+static int          msglevel                =MSG_LEVEL_INFO;
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+
+
+
+const WORD             awHWRetry0[5][5] = {
+                                            {RATE_18M, RATE_18M, RATE_12M, RATE_12M, RATE_12M},
+                                            {RATE_24M, RATE_24M, RATE_18M, RATE_12M, RATE_12M},
+                                            {RATE_36M, RATE_36M, RATE_24M, RATE_18M, RATE_18M},
+                                            {RATE_48M, RATE_48M, RATE_36M, RATE_24M, RATE_24M},
+                                            {RATE_54M, RATE_54M, RATE_48M, RATE_36M, RATE_36M}
+                                           };
+const WORD             awHWRetry1[5][5] = {
+                                            {RATE_18M, RATE_18M, RATE_12M, RATE_6M, RATE_6M},
+                                            {RATE_24M, RATE_24M, RATE_18M, RATE_6M, RATE_6M},
+                                            {RATE_36M, RATE_36M, RATE_24M, RATE_12M, RATE_12M},
+                                            {RATE_48M, RATE_48M, RATE_24M, RATE_12M, RATE_12M},
+                                            {RATE_54M, RATE_54M, RATE_36M, RATE_18M, RATE_18M}
+                                           };
+
+
+
+/*---------------------  Static Functions  --------------------------*/
+
+VOID s_vCheckSensitivity(
+    IN HANDLE hDeviceContext
+    );
+
+VOID s_vCheckPreEDThreshold(
+    IN HANDLE hDeviceContext
+    );
+
+#ifdef Calcu_LinkQual
+VOID s_uCalculateLinkQual(
+    IN HANDLE hDeviceContext
+    );
+#endif
+/*---------------------  Export Variables  --------------------------*/
+
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+
+
+
+/*+
+ *
+ * Routine Description:
+ *    Search known BSS list for Desire SSID or BSSID.
+ *
+ * Return Value:
+ *    PTR to KnownBSS or NULL
+ *
+-*/
+
+PKnownBSS
+BSSpSearchBSSList(
+    IN HANDLE hDeviceContext,
+    IN PBYTE pbyDesireBSSID,
+    IN PBYTE pbyDesireSSID,
+    IN CARD_PHY_TYPE  ePhyType
+    )
+{
+    PSDevice        pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    PBYTE           pbyBSSID = NULL;
+    PWLAN_IE_SSID   pSSID = NULL;
+    PKnownBSS       pCurrBSS = NULL;
+    PKnownBSS       pSelect = NULL;
+    BYTE                 ZeroBSSID[WLAN_BSSID_LEN]={0x00,0x00,0x00,0x00,0x00,0x00};
+    UINT            ii = 0;
+    UINT            jj = 0;   //DavidWang
+    if (pbyDesireBSSID != NULL) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BSSpSearchBSSList BSSID[%02X %02X %02X-%02X %02X %02X]\n",
+                            *pbyDesireBSSID,*(pbyDesireBSSID+1),*(pbyDesireBSSID+2),
+                            *(pbyDesireBSSID+3),*(pbyDesireBSSID+4),*(pbyDesireBSSID+5));
+        if ((!IS_BROADCAST_ADDRESS(pbyDesireBSSID)) &&
+	     (memcmp(pbyDesireBSSID, ZeroBSSID, 6)!= 0)){
+            pbyBSSID = pbyDesireBSSID;
+        }
+    }
+    if (pbyDesireSSID != NULL) {
+        if (((PWLAN_IE_SSID)pbyDesireSSID)->len != 0) {
+            pSSID = (PWLAN_IE_SSID) pbyDesireSSID;
+        }
+    }
+
+    if ((pbyBSSID != NULL)&&(pDevice->bRoaming == FALSE)) {
+        // match BSSID first
+        for (ii = 0; ii <MAX_BSS_NUM; ii++) {
+            pCurrBSS = &(pMgmt->sBSSList[ii]);
+
+	//2008-0718-01<Add>by MikeLiu
+	   pCurrBSS->bSelected = FALSE;
+
+            if ((pCurrBSS->bActive) &&
+                (pCurrBSS->bSelected == FALSE)) {
+                if (IS_ETH_ADDRESS_EQUAL(pCurrBSS->abyBSSID, pbyBSSID)) {
+                    if (pSSID != NULL) {
+                        // compare ssid
+                        if (MEMEqualMemory(pSSID->abySSID,
+                            ((PWLAN_IE_SSID)pCurrBSS->abySSID)->abySSID,
+                            pSSID->len)) {
+                            if ((pMgmt->eConfigMode == WMAC_CONFIG_AUTO) ||
+                                ((pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) && WLAN_GET_CAP_INFO_IBSS(pCurrBSS->wCapInfo)) ||
+                                ((pMgmt->eConfigMode == WMAC_CONFIG_ESS_STA) && WLAN_GET_CAP_INFO_ESS(pCurrBSS->wCapInfo))
+                                ) {
+                                pCurrBSS->bSelected = TRUE;
+                                return(pCurrBSS);
+                            }
+                        }
+                    } else {
+                        if ((pMgmt->eConfigMode == WMAC_CONFIG_AUTO) ||
+                            ((pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) && WLAN_GET_CAP_INFO_IBSS(pCurrBSS->wCapInfo)) ||
+                            ((pMgmt->eConfigMode == WMAC_CONFIG_ESS_STA) && WLAN_GET_CAP_INFO_ESS(pCurrBSS->wCapInfo))
+                            ) {
+                            pCurrBSS->bSelected = TRUE;
+                            return(pCurrBSS);
+                        }
+                    }
+                }
+            }
+        }
+    } else {
+        // ignore BSSID
+        for (ii = 0; ii <MAX_BSS_NUM; ii++) {
+            pCurrBSS = &(pMgmt->sBSSList[ii]);
+
+           //2007-0721-01<Mark>by MikeLiu
+         //   if ((pCurrBSS->bActive) &&
+         //       (pCurrBSS->bSelected == FALSE)) {
+
+	//2007-0721-01<Add>by MikeLiu
+	  pCurrBSS->bSelected = FALSE;
+          if (pCurrBSS->bActive) {
+
+                if (pSSID != NULL) {
+                    // matched SSID
+                    if (!MEMEqualMemory(pSSID->abySSID,
+                        ((PWLAN_IE_SSID)pCurrBSS->abySSID)->abySSID,
+                        pSSID->len) ||
+                        (pSSID->len != ((PWLAN_IE_SSID)pCurrBSS->abySSID)->len)) {
+                        // SSID not match skip this BSS
+                        continue;
+                      }
+                }
+                if (((pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) && WLAN_GET_CAP_INFO_ESS(pCurrBSS->wCapInfo)) ||
+                    ((pMgmt->eConfigMode == WMAC_CONFIG_ESS_STA) && WLAN_GET_CAP_INFO_IBSS(pCurrBSS->wCapInfo))
+                    ){
+                    // Type not match skip this BSS
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BSS type mismatch.... Config[%d] BSS[0x%04x]\n", pMgmt->eConfigMode, pCurrBSS->wCapInfo);
+                    continue;
+                }
+
+                if (ePhyType != PHY_TYPE_AUTO) {
+                    if (((ePhyType == PHY_TYPE_11A) && (PHY_TYPE_11A != pCurrBSS->eNetworkTypeInUse)) ||
+                        ((ePhyType != PHY_TYPE_11A) && (PHY_TYPE_11A == pCurrBSS->eNetworkTypeInUse))) {
+                        // PhyType not match skip this BSS
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Physical type mismatch.... ePhyType[%d] BSS[%d]\n", ePhyType, pCurrBSS->eNetworkTypeInUse);
+                        continue;
+                    }
+                }
+/*
+                if (pMgmt->eAuthenMode < WMAC_AUTH_WPA) {
+                    if (pCurrBSS->bWPAValid == TRUE) {
+                        // WPA AP will reject connection of station without WPA enable.
+                        continue;
+                    }
+                } else if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA) ||
+                           (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK)) {
+                    if (pCurrBSS->bWPAValid == FALSE) {
+                        // station with WPA enable can't join NonWPA AP.
+                        continue;
+                    }
+                } else if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) ||
+                           (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) {
+                    if (pCurrBSS->bWPA2Valid == FALSE) {
+                        // station with WPA2 enable can't join NonWPA2 AP.
+                        continue;
+                    }
+                }
+*/
+//DavidWang
+        pMgmt->pSameBSS[jj].uChannel = pCurrBSS->uChannel;
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BSSpSearchBSSList pSelect1[%02X %02X %02X-%02X %02X %02X]\n",*pCurrBSS->abyBSSID,*(pCurrBSS->abyBSSID+1),*(pCurrBSS->abyBSSID+2),*(pCurrBSS->abyBSSID+3),*(pCurrBSS->abyBSSID+4),*(pCurrBSS->abyBSSID+5));
+        jj++;
+
+//DavidWang
+                if (pSelect == NULL) {
+                    pSelect = pCurrBSS;
+                } else {
+                    // compare RSSI, select signal strong one
+                    if (pCurrBSS->uRSSI < pSelect->uRSSI) {
+                        pSelect = pCurrBSS;
+                    }
+                }
+            }
+        }
+//DavidWang
+pDevice->bSameBSSMaxNum = jj;
+//DavidWang
+        if (pSelect != NULL) {
+            pSelect->bSelected = TRUE;
+                        if (pDevice->bRoaming == FALSE)  {
+	//       Einsn Add @20070907
+			ZERO_MEMORY(pbyDesireSSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+			MEMvCopy(pbyDesireSSID,pCurrBSS->abySSID,WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1) ;
+                                                }
+
+            return(pSelect);
+        }
+    }
+    return(NULL);
+
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *    Clear BSS List
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+
+VOID
+BSSvClearBSSList(
+    IN HANDLE hDeviceContext,
+    IN BOOL bKeepCurrBSSID
+    )
+{
+    PSDevice     pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    UINT            ii;
+
+    for (ii = 0; ii < MAX_BSS_NUM; ii++) {
+        if (bKeepCurrBSSID) {
+            if (pMgmt->sBSSList[ii].bActive &&
+                IS_ETH_ADDRESS_EQUAL(pMgmt->sBSSList[ii].abyBSSID, pMgmt->abyCurrBSSID)) {
+ //mike mark: there are two same BSSID in list if that AP is in hidden ssid mode,one 's SSID is null,
+ //                 but other's is obvious, so if it acssociate with your STA  exactly,you must keep two
+ //                 of them!!!!!!!!!
+               // bKeepCurrBSSID = FALSE;
+                continue;
+            }
+        }
+/*
+        if ((pMgmt->sBSSList[ii].bActive) && (pMgmt->sBSSList[ii].uClearCount < BSS_CLEAR_COUNT)) {
+             pMgmt->sBSSList[ii].uClearCount ++;
+             continue;
+        }
+*/
+        pMgmt->sBSSList[ii].bActive = FALSE;
+        memset(&pMgmt->sBSSList[ii], 0, sizeof(KnownBSS));
+    }
+    BSSvClearAnyBSSJoinRecord(pDevice);
+
+    return;
+}
+
+
+
+/*+
+ *
+ * Routine Description:
+ *    search BSS list by BSSID & SSID if matched
+ *
+ * Return Value:
+ *    TRUE if found.
+ *
+-*/
+PKnownBSS
+BSSpAddrIsInBSSList(
+    IN HANDLE hDeviceContext,
+    IN PBYTE abyBSSID,
+    IN PWLAN_IE_SSID pSSID
+    )
+{
+    PSDevice     pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    PKnownBSS       pBSSList = NULL;
+    UINT            ii;
+
+    for (ii = 0; ii < MAX_BSS_NUM; ii++) {
+        pBSSList = &(pMgmt->sBSSList[ii]);
+        if (pBSSList->bActive) {
+            if (IS_ETH_ADDRESS_EQUAL(pBSSList->abyBSSID, abyBSSID)) {
+                if (pSSID->len == ((PWLAN_IE_SSID)pBSSList->abySSID)->len){
+                    if (memcmp(pSSID->abySSID,
+                            ((PWLAN_IE_SSID)pBSSList->abySSID)->abySSID,
+                            pSSID->len) == 0)
+                        return pBSSList;
+                }
+            }
+        }
+    }
+
+    return NULL;
+};
+
+
+
+/*+
+ *
+ * Routine Description:
+ *    Insert a BSS set into known BSS list
+ *
+ * Return Value:
+ *    TRUE if success.
+ *
+-*/
+
+BOOL
+BSSbInsertToBSSList (
+    IN HANDLE hDeviceContext,
+    IN PBYTE abyBSSIDAddr,
+    IN QWORD qwTimestamp,
+    IN WORD wBeaconInterval,
+    IN WORD wCapInfo,
+    IN BYTE byCurrChannel,
+    IN PWLAN_IE_SSID pSSID,
+    IN PWLAN_IE_SUPP_RATES pSuppRates,
+    IN PWLAN_IE_SUPP_RATES pExtSuppRates,
+    IN PERPObject psERP,
+    IN PWLAN_IE_RSN pRSN,
+    IN PWLAN_IE_RSN_EXT pRSNWPA,
+    IN PWLAN_IE_COUNTRY pIE_Country,
+    IN PWLAN_IE_QUIET pIE_Quiet,
+    IN UINT uIELength,
+    IN PBYTE pbyIEs,
+    IN HANDLE pRxPacketContext
+    )
+{
+
+    PSDevice     pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    PSRxMgmtPacket  pRxPacket = (PSRxMgmtPacket)pRxPacketContext;
+    PKnownBSS       pBSSList = NULL;
+    UINT            ii;
+    BOOL            bParsingQuiet = FALSE;
+
+
+
+    pBSSList = (PKnownBSS)&(pMgmt->sBSSList[0]);
+
+    for (ii = 0; ii < MAX_BSS_NUM; ii++) {
+        pBSSList = (PKnownBSS)&(pMgmt->sBSSList[ii]);
+        if (!pBSSList->bActive)
+                break;
+    }
+
+    if (ii == MAX_BSS_NUM){
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Get free KnowBSS node failed.\n");
+        return FALSE;
+    }
+    // save the BSS info
+    pBSSList->bActive = TRUE;
+    memcpy( pBSSList->abyBSSID, abyBSSIDAddr, WLAN_BSSID_LEN);
+    HIDWORD(pBSSList->qwBSSTimestamp) = cpu_to_le32(HIDWORD(qwTimestamp));
+    LODWORD(pBSSList->qwBSSTimestamp) = cpu_to_le32(LODWORD(qwTimestamp));
+    pBSSList->wBeaconInterval = cpu_to_le16(wBeaconInterval);
+    pBSSList->wCapInfo = cpu_to_le16(wCapInfo);
+    pBSSList->uClearCount = 0;
+
+    if (pSSID->len > WLAN_SSID_MAXLEN)
+        pSSID->len = WLAN_SSID_MAXLEN;
+    memcpy( pBSSList->abySSID, pSSID, pSSID->len + WLAN_IEHDR_LEN);
+
+    pBSSList->uChannel = byCurrChannel;
+
+    if (pSuppRates->len > WLAN_RATES_MAXLEN)
+        pSuppRates->len = WLAN_RATES_MAXLEN;
+    memcpy( pBSSList->abySuppRates, pSuppRates, pSuppRates->len + WLAN_IEHDR_LEN);
+
+    if (pExtSuppRates != NULL) {
+        if (pExtSuppRates->len > WLAN_RATES_MAXLEN)
+            pExtSuppRates->len = WLAN_RATES_MAXLEN;
+        memcpy(pBSSList->abyExtSuppRates, pExtSuppRates, pExtSuppRates->len + WLAN_IEHDR_LEN);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BSSbInsertToBSSList: pExtSuppRates->len = %d\n", pExtSuppRates->len);
+
+    } else {
+        memset(pBSSList->abyExtSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1);
+    }
+    pBSSList->sERP.byERP = psERP->byERP;
+    pBSSList->sERP.bERPExist = psERP->bERPExist;
+
+    // Check if BSS is 802.11a/b/g
+    if (pBSSList->uChannel > CB_MAX_CHANNEL_24G) {
+        pBSSList->eNetworkTypeInUse = PHY_TYPE_11A;
+    } else {
+        if (pBSSList->sERP.bERPExist == TRUE) {
+            pBSSList->eNetworkTypeInUse = PHY_TYPE_11G;
+        } else {
+            pBSSList->eNetworkTypeInUse = PHY_TYPE_11B;
+        }
+    }
+
+    pBSSList->byRxRate = pRxPacket->byRxRate;
+    pBSSList->qwLocalTSF = pRxPacket->qwLocalTSF;
+    pBSSList->uRSSI = pRxPacket->uRSSI;
+    pBSSList->bySQ = pRxPacket->bySQ;
+
+   if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
+        (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
+        // assoc with BSS
+        if (pBSSList == pMgmt->pCurrBSS) {
+            bParsingQuiet = TRUE;
+        }
+    }
+
+    WPA_ClearRSN(pBSSList);
+
+    if (pRSNWPA != NULL) {
+        UINT uLen = pRSNWPA->len + 2;
+
+        if (uLen <= (uIELength - (UINT)(ULONG_PTR)((PBYTE)pRSNWPA - pbyIEs))) {
+            pBSSList->wWPALen = uLen;
+            memcpy(pBSSList->byWPAIE, pRSNWPA, uLen);
+            WPA_ParseRSN(pBSSList, pRSNWPA);
+        }
+    }
+
+    WPA2_ClearRSN(pBSSList);
+
+    if (pRSN != NULL) {
+        UINT uLen = pRSN->len + 2;
+        if (uLen <= (uIELength - (UINT)(ULONG_PTR)((PBYTE)pRSN - pbyIEs))) {
+            pBSSList->wRSNLen = uLen;
+            memcpy(pBSSList->byRSNIE, pRSN, uLen);
+            WPA2vParseRSN(pBSSList, pRSN);
+        }
+    }
+
+    if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || (pBSSList->bWPA2Valid == TRUE)) {
+
+        PSKeyItem  pTransmitKey = NULL;
+        BOOL       bIs802_1x = FALSE;
+
+        for (ii = 0; ii < pBSSList->wAKMSSAuthCount; ii ++) {
+            if (pBSSList->abyAKMSSAuthType[ii] == WLAN_11i_AKMSS_802_1X) {
+                bIs802_1x = TRUE;
+                break;
+            }
+        }
+        if ((bIs802_1x == TRUE) && (pSSID->len == ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->len) &&
+            (MEMEqualMemory(pSSID->abySSID, ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySSID, pSSID->len))) {
+
+            bAdd_PMKID_Candidate((HANDLE)pDevice, pBSSList->abyBSSID, &pBSSList->sRSNCapObj);
+
+            if ((pDevice->bLinkPass == TRUE) && (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
+                if ((KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBSSID, PAIRWISE_KEY, &pTransmitKey) == TRUE) ||
+                    (KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBSSID, GROUP_KEY, &pTransmitKey) == TRUE)) {
+                    pDevice->gsPMKIDCandidate.StatusType = Ndis802_11StatusType_PMKID_CandidateList;
+                    pDevice->gsPMKIDCandidate.Version = 1;
+
+                }
+
+            }
+        }
+    }
+
+    if (pDevice->bUpdateBBVGA) {
+        // Moniter if RSSI is too strong.
+        pBSSList->byRSSIStatCnt = 0;
+        RFvRSSITodBm(pDevice, (BYTE)(pRxPacket->uRSSI), &pBSSList->ldBmMAX);
+        pBSSList->ldBmAverage[0] = pBSSList->ldBmMAX;
+        pBSSList->ldBmAverRange = pBSSList->ldBmMAX;
+        for (ii = 1; ii < RSSI_STAT_COUNT; ii++)
+            pBSSList->ldBmAverage[ii] = 0;
+    }
+
+/*
+    if ((pIE_Country != NULL) &&
+        (pMgmt->b11hEnable == TRUE)) {
+        CARDvSetCountryInfo(pMgmt->pAdapter,
+                            pBSSList->eNetworkTypeInUse,
+                            pIE_Country);
+    }
+
+    if ((bParsingQuiet == TRUE) && (pIE_Quiet != NULL)) {
+        if ((((PWLAN_IE_QUIET)pIE_Quiet)->len == 8) &&
+            (((PWLAN_IE_QUIET)pIE_Quiet)->byQuietCount != 0)) {
+            // valid EID
+            if (pQuiet == NULL) {
+                pQuiet = (PWLAN_IE_QUIET)pIE_Quiet;
+                CARDbSetQuiet(  pMgmt->pAdapter,
+                                TRUE,
+                                pQuiet->byQuietCount,
+                                pQuiet->byQuietPeriod,
+                                *((PWORD)pQuiet->abyQuietDuration),
+                                *((PWORD)pQuiet->abyQuietOffset)
+                                );
+            } else {
+                pQuiet = (PWLAN_IE_QUIET)pIE_Quiet;
+                CARDbSetQuiet(  pMgmt->pAdapter,
+                                FALSE,
+                                pQuiet->byQuietCount,
+                                pQuiet->byQuietPeriod,
+                                *((PWORD)pQuiet->abyQuietDuration),
+                                *((PWORD)pQuiet->abyQuietOffset)
+                                );
+            }
+        }
+    }
+
+    if ((bParsingQuiet == TRUE) &&
+        (pQuiet != NULL)) {
+        CARDbStartQuiet(pMgmt->pAdapter);
+    }
+*/
+
+    pBSSList->uIELength = uIELength;
+    if (pBSSList->uIELength > WLAN_BEACON_FR_MAXLEN)
+        pBSSList->uIELength = WLAN_BEACON_FR_MAXLEN;
+    MEMvCopy(pBSSList->abyIEs, pbyIEs, pBSSList->uIELength);
+
+    return TRUE;
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *    Update BSS set in known BSS list
+ *
+ * Return Value:
+ *    TRUE if success.
+ *
+-*/
+// TODO: input structure modify
+
+BOOL
+BSSbUpdateToBSSList (
+    IN HANDLE hDeviceContext,
+    IN QWORD qwTimestamp,
+    IN WORD wBeaconInterval,
+    IN WORD wCapInfo,
+    IN BYTE byCurrChannel,
+    IN BOOL bChannelHit,
+    IN PWLAN_IE_SSID pSSID,
+    IN PWLAN_IE_SUPP_RATES pSuppRates,
+    IN PWLAN_IE_SUPP_RATES pExtSuppRates,
+    IN PERPObject psERP,
+    IN PWLAN_IE_RSN pRSN,
+    IN PWLAN_IE_RSN_EXT pRSNWPA,
+    IN PWLAN_IE_COUNTRY pIE_Country,
+    IN PWLAN_IE_QUIET pIE_Quiet,
+    IN PKnownBSS pBSSList,
+    IN UINT uIELength,
+    IN PBYTE pbyIEs,
+    IN HANDLE pRxPacketContext
+    )
+{
+    int             ii, jj;
+    PSDevice        pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    PSRxMgmtPacket  pRxPacket = (PSRxMgmtPacket)pRxPacketContext;
+    LONG            ldBm, ldBmSum;
+    BOOL            bParsingQuiet = FALSE;
+  //  BYTE            abyTmpSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
+
+
+    if (pBSSList == NULL)
+        return FALSE;
+
+
+    HIDWORD(pBSSList->qwBSSTimestamp) = cpu_to_le32(HIDWORD(qwTimestamp));
+    LODWORD(pBSSList->qwBSSTimestamp) = cpu_to_le32(LODWORD(qwTimestamp));
+    pBSSList->wBeaconInterval = cpu_to_le16(wBeaconInterval);
+    pBSSList->wCapInfo = cpu_to_le16(wCapInfo);
+    pBSSList->uClearCount = 0;
+    pBSSList->uChannel = byCurrChannel;
+//    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BSSbUpdateToBSSList: pBSSList->uChannel: %d\n", pBSSList->uChannel);
+
+    if (pSSID->len > WLAN_SSID_MAXLEN)
+        pSSID->len = WLAN_SSID_MAXLEN;
+
+    if ((pSSID->len != 0) && (pSSID->abySSID[0] != 0))
+        memcpy(pBSSList->abySSID, pSSID, pSSID->len + WLAN_IEHDR_LEN);
+    memcpy(pBSSList->abySuppRates, pSuppRates,pSuppRates->len + WLAN_IEHDR_LEN);
+
+    if (pExtSuppRates != NULL) {
+        memcpy(pBSSList->abyExtSuppRates, pExtSuppRates,pExtSuppRates->len + WLAN_IEHDR_LEN);
+    } else {
+        memset(pBSSList->abyExtSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1);
+    }
+    pBSSList->sERP.byERP = psERP->byERP;
+    pBSSList->sERP.bERPExist = psERP->bERPExist;
+
+    // Check if BSS is 802.11a/b/g
+    if (pBSSList->uChannel > CB_MAX_CHANNEL_24G) {
+        pBSSList->eNetworkTypeInUse = PHY_TYPE_11A;
+    } else {
+        if (pBSSList->sERP.bERPExist == TRUE) {
+            pBSSList->eNetworkTypeInUse = PHY_TYPE_11G;
+        } else {
+            pBSSList->eNetworkTypeInUse = PHY_TYPE_11B;
+        }
+    }
+
+    pBSSList->byRxRate = pRxPacket->byRxRate;
+    pBSSList->qwLocalTSF = pRxPacket->qwLocalTSF;
+    if(bChannelHit)
+        pBSSList->uRSSI = pRxPacket->uRSSI;
+    pBSSList->bySQ = pRxPacket->bySQ;
+
+   if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
+        (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
+        // assoc with BSS
+        if (pBSSList == pMgmt->pCurrBSS) {
+            bParsingQuiet = TRUE;
+        }
+    }
+
+   WPA_ClearRSN(pBSSList);         //mike update
+
+    if (pRSNWPA != NULL) {
+        UINT uLen = pRSNWPA->len + 2;
+        if (uLen <= (uIELength - (UINT)(ULONG_PTR)((PBYTE)pRSNWPA - pbyIEs))) {
+            pBSSList->wWPALen = uLen;
+            memcpy(pBSSList->byWPAIE, pRSNWPA, uLen);
+            WPA_ParseRSN(pBSSList, pRSNWPA);
+        }
+    }
+
+   WPA2_ClearRSN(pBSSList);  //mike update
+
+    if (pRSN != NULL) {
+        UINT uLen = pRSN->len + 2;
+        if (uLen <= (uIELength - (UINT)(ULONG_PTR)((PBYTE)pRSN - pbyIEs))) {
+            pBSSList->wRSNLen = uLen;
+            memcpy(pBSSList->byRSNIE, pRSN, uLen);
+            WPA2vParseRSN(pBSSList, pRSN);
+        }
+    }
+
+    if (pRxPacket->uRSSI != 0) {
+        RFvRSSITodBm(pDevice, (BYTE)(pRxPacket->uRSSI), &ldBm);
+        // Moniter if RSSI is too strong.
+        pBSSList->byRSSIStatCnt++;
+        pBSSList->byRSSIStatCnt %= RSSI_STAT_COUNT;
+        pBSSList->ldBmAverage[pBSSList->byRSSIStatCnt] = ldBm;
+        ldBmSum = 0;
+        for(ii=0, jj=0;ii<RSSI_STAT_COUNT;ii++) {
+            if (pBSSList->ldBmAverage[ii] != 0) {
+                pBSSList->ldBmMAX = max(pBSSList->ldBmAverage[ii], ldBm);
+                ldBmSum += pBSSList->ldBmAverage[ii];
+                jj++;
+            }
+        }
+        pBSSList->ldBmAverRange = ldBmSum /jj;
+    }
+
+    pBSSList->uIELength = uIELength;
+    if (pBSSList->uIELength > WLAN_BEACON_FR_MAXLEN)
+        pBSSList->uIELength = WLAN_BEACON_FR_MAXLEN;
+    memcpy(pBSSList->abyIEs, pbyIEs, pBSSList->uIELength);
+
+//mike add: if  the AP in this pBSSList is hidden ssid and we can find two of them,
+//                  you need upgrade the other related pBSSList of which ssid is obvious,
+//                  for these two AP is the same one!!!!
+/********judge by:BSSID is the same,but ssid is different!*****************/
+#if 0
+   for (ii = 0; ii < MAX_BSS_NUM; ii++) {
+      if (IS_ETH_ADDRESS_EQUAL(pMgmt->sBSSList[ii].abyBSSID, pBSSList->abyBSSID)) {   //BSSID is the same!
+         if (memcmp(((PWLAN_IE_SSID)pMgmt->sBSSList[ii].abySSID)->abySSID,                  //ssid is different??
+		 	      ((PWLAN_IE_SSID)pBSSList->abySSID)->abySSID,
+		 	      ((PWLAN_IE_SSID)pBSSList->abySSID)->len) != 0) {
+                  //reserve temp
+               memset(abyTmpSSID,0,sizeof(abyTmpSSID));
+	      memcpy(abyTmpSSID,pMgmt->sBSSList[ii].abySSID,sizeof(abyTmpSSID));
+		  //upgrade the other one pBSSList
+	      memcpy(&(pMgmt->sBSSList[ii]),pBSSList,sizeof(KnownBSS));
+		  //recover ssid info
+	      memcpy(pMgmt->sBSSList[ii].abySSID,abyTmpSSID,sizeof(abyTmpSSID));
+           }
+       }
+    }
+#endif
+
+    return TRUE;
+}
+
+
+
+
+
+/*+
+ *
+ * Routine Description:
+ *    Search Node DB table to find the index of matched DstAddr
+ *
+ * Return Value:
+ *    None
+ *
+-*/
+
+BOOL
+BSSbIsSTAInNodeDB(
+    IN HANDLE hDeviceContext,
+    IN PBYTE abyDstAddr,
+    OUT PUINT puNodeIndex
+    )
+{
+    PSDevice        pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    UINT            ii;
+
+    // Index = 0 reserved for AP Node
+    for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) {
+        if (pMgmt->sNodeDBTable[ii].bActive) {
+            if (IS_ETH_ADDRESS_EQUAL(abyDstAddr, pMgmt->sNodeDBTable[ii].abyMACAddr)) {
+                *puNodeIndex = ii;
+                return TRUE;
+            }
+        }
+    }
+
+   return FALSE;
+};
+
+
+
+/*+
+ *
+ * Routine Description:
+ *    Find an empty node and allocated; if no empty found,
+ *    instand used of most inactive one.
+ *
+ * Return Value:
+ *    None
+ *
+-*/
+VOID
+BSSvCreateOneNode(
+    IN HANDLE hDeviceContext,
+    OUT PUINT puNodeIndex
+    )
+{
+
+    PSDevice     pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    UINT            ii;
+    UINT            BigestCount = 0;
+    UINT            SelectIndex;
+    struct sk_buff  *skb;
+    // Index = 0 reserved for AP Node (In STA mode)
+    // Index = 0 reserved for Broadcast/MultiCast (In AP mode)
+    SelectIndex = 1;
+    for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) {
+        if (pMgmt->sNodeDBTable[ii].bActive) {
+            if (pMgmt->sNodeDBTable[ii].uInActiveCount > BigestCount) {
+                BigestCount = pMgmt->sNodeDBTable[ii].uInActiveCount;
+                SelectIndex = ii;
+            }
+        }
+        else {
+            break;
+        }
+    }
+
+    // if not found replace uInActiveCount is largest one.
+    if ( ii == (MAX_NODE_NUM + 1)) {
+        *puNodeIndex = SelectIndex;
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Replace inactive node = %d\n", SelectIndex);
+        // clear ps buffer
+        if (pMgmt->sNodeDBTable[*puNodeIndex].sTxPSQueue.next != NULL) {
+      	    while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[*puNodeIndex].sTxPSQueue)) != NULL)
+            dev_kfree_skb(skb);
+        }
+    }
+    else {
+        *puNodeIndex = ii;
+    }
+
+    memset(&pMgmt->sNodeDBTable[*puNodeIndex], 0, sizeof(KnownNodeDB));
+    pMgmt->sNodeDBTable[*puNodeIndex].bActive = TRUE;
+    pMgmt->sNodeDBTable[*puNodeIndex].uRatePollTimeout = FALLBACK_POLL_SECOND;
+    // for AP mode PS queue
+    skb_queue_head_init(&pMgmt->sNodeDBTable[*puNodeIndex].sTxPSQueue);
+    pMgmt->sNodeDBTable[*puNodeIndex].byAuthSequence = 0;
+    pMgmt->sNodeDBTable[*puNodeIndex].wEnQueueCnt = 0;
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Create node index = %d\n", ii);
+    return;
+};
+
+
+
+/*+
+ *
+ * Routine Description:
+ *    Remove Node by NodeIndex
+ *
+ *
+ * Return Value:
+ *    None
+ *
+-*/
+VOID
+BSSvRemoveOneNode(
+    IN HANDLE hDeviceContext,
+    IN UINT uNodeIndex
+    )
+{
+
+    PSDevice        pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    BYTE            byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
+    struct sk_buff  *skb;
+
+
+    while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[uNodeIndex].sTxPSQueue)) != NULL)
+            dev_kfree_skb(skb);
+    // clear context
+    memset(&pMgmt->sNodeDBTable[uNodeIndex], 0, sizeof(KnownNodeDB));
+    // clear tx bit map
+    pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[uNodeIndex].wAID >> 3] &=  ~byMask[pMgmt->sNodeDBTable[uNodeIndex].wAID & 7];
+
+    return;
+};
+/*+
+ *
+ * Routine Description:
+ *    Update AP Node content in Index 0 of KnownNodeDB
+ *
+ *
+ * Return Value:
+ *    None
+ *
+-*/
+
+VOID
+BSSvUpdateAPNode(
+    IN HANDLE hDeviceContext,
+    IN PWORD pwCapInfo,
+    IN PWLAN_IE_SUPP_RATES pSuppRates,
+    IN PWLAN_IE_SUPP_RATES pExtSuppRates
+    )
+{
+    PSDevice     pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    UINT            uRateLen = WLAN_RATES_MAXLEN;
+
+    memset(&pMgmt->sNodeDBTable[0], 0, sizeof(KnownNodeDB));
+
+    pMgmt->sNodeDBTable[0].bActive = TRUE;
+    if (pDevice->byBBType == BB_TYPE_11B) {
+        uRateLen = WLAN_RATES_MAXLEN_11B;
+    }
+    pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pSuppRates,
+                                            (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
+                                            uRateLen);
+    pMgmt->abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pExtSuppRates,
+                                            (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates,
+                                            uRateLen);
+    RATEvParseMaxRate((PVOID) pDevice,
+                       (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
+                       (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates,
+                       TRUE,
+                       &(pMgmt->sNodeDBTable[0].wMaxBasicRate),
+                       &(pMgmt->sNodeDBTable[0].wMaxSuppRate),
+                       &(pMgmt->sNodeDBTable[0].wSuppRate),
+                       &(pMgmt->sNodeDBTable[0].byTopCCKBasicRate),
+                       &(pMgmt->sNodeDBTable[0].byTopOFDMBasicRate)
+                      );
+    memcpy(pMgmt->sNodeDBTable[0].abyMACAddr, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN);
+    pMgmt->sNodeDBTable[0].wTxDataRate = pMgmt->sNodeDBTable[0].wMaxSuppRate;
+    pMgmt->sNodeDBTable[0].bShortPreamble = WLAN_GET_CAP_INFO_SHORTPREAMBLE(*pwCapInfo);
+    pMgmt->sNodeDBTable[0].uRatePollTimeout = FALLBACK_POLL_SECOND;
+    // Auto rate fallback function initiation.
+    // RATEbInit(pDevice);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pMgmt->sNodeDBTable[0].wTxDataRate = %d \n", pMgmt->sNodeDBTable[0].wTxDataRate);
+
+};
+
+
+
+
+
+/*+
+ *
+ * Routine Description:
+ *    Add Multicast Node content in Index 0 of KnownNodeDB
+ *
+ *
+ * Return Value:
+ *    None
+ *
+-*/
+
+
+VOID
+BSSvAddMulticastNode(
+    IN HANDLE hDeviceContext
+    )
+{
+    PSDevice     pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+
+    if (!pDevice->bEnableHostWEP)
+        memset(&pMgmt->sNodeDBTable[0], 0, sizeof(KnownNodeDB));
+    memset(pMgmt->sNodeDBTable[0].abyMACAddr, 0xff, WLAN_ADDR_LEN);
+    pMgmt->sNodeDBTable[0].bActive = TRUE;
+    pMgmt->sNodeDBTable[0].bPSEnable = FALSE;
+    skb_queue_head_init(&pMgmt->sNodeDBTable[0].sTxPSQueue);
+    RATEvParseMaxRate((PVOID) pDevice,
+                      (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
+                      (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates,
+                      TRUE,
+                      &(pMgmt->sNodeDBTable[0].wMaxBasicRate),
+                      &(pMgmt->sNodeDBTable[0].wMaxSuppRate),
+                       &(pMgmt->sNodeDBTable[0].wSuppRate),
+                      &(pMgmt->sNodeDBTable[0].byTopCCKBasicRate),
+                      &(pMgmt->sNodeDBTable[0].byTopOFDMBasicRate)
+                     );
+    pMgmt->sNodeDBTable[0].wTxDataRate = pMgmt->sNodeDBTable[0].wMaxBasicRate;
+    pMgmt->sNodeDBTable[0].uRatePollTimeout = FALLBACK_POLL_SECOND;
+
+};
+
+
+
+
+
+/*+
+ *
+ * Routine Description:
+ *
+ *
+ *  Second call back function to update Node DB info & AP link status
+ *
+ *
+ * Return Value:
+ *    none.
+ *
+-*/
+
+
+VOID
+BSSvSecondCallBack(
+    IN  HANDLE hDeviceContext
+    )
+{
+    PSDevice        pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    UINT            ii;
+    PWLAN_IE_SSID   pItemSSID, pCurrSSID;
+    UINT            uSleepySTACnt = 0;
+    UINT            uNonShortSlotSTACnt = 0;
+    UINT            uLongPreambleSTACnt = 0;
+    viawget_wpa_header *wpahdr;  //DavidWang
+
+    spin_lock_irq(&pDevice->lock);
+
+    pDevice->uAssocCount = 0;
+
+    //Power Saving Mode Tx Burst
+    if ( pDevice->bEnablePSMode == TRUE ) {
+        pDevice->ulPSModeWaitTx++;
+        if ( pDevice->ulPSModeWaitTx >= 2 ) {
+            pDevice->ulPSModeWaitTx = 0;
+            pDevice->bPSModeTxBurst = FALSE;
+        }
+    }
+
+    pDevice->byERPFlag &=
+        ~(WLAN_SET_ERP_BARKER_MODE(1) | WLAN_SET_ERP_NONERP_PRESENT(1));
+
+    if (pDevice->wUseProtectCntDown > 0) {
+        pDevice->wUseProtectCntDown --;
+    }
+    else {
+        // disable protect mode
+        pDevice->byERPFlag &= ~(WLAN_SET_ERP_USE_PROTECTION(1));
+    }
+
+if(pDevice->byReAssocCount > 0) {
+       pDevice->byReAssocCount++;
+   if((pDevice->byReAssocCount > 10) && (pDevice->bLinkPass != TRUE)) {  //10 sec timeout
+                     printk("Re-association timeout!!!\n");
+		   pDevice->byReAssocCount = 0;
+                     #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+                    // if(pDevice->bWPASuppWextEnabled == TRUE)
+                        {
+                  	union iwreq_data  wrqu;
+                  	memset(&wrqu, 0, sizeof (wrqu));
+                          wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+                  	PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n");
+                  	wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
+                       }
+                    #endif
+     }
+   else if(pDevice->bLinkPass == TRUE)
+   	pDevice->byReAssocCount = 0;
+}
+
+#ifdef SndEvt_ToAPI
+if((pMgmt->eCurrState!=WMAC_STATE_ASSOC) &&
+     (pMgmt->eLastState==WMAC_STATE_ASSOC))
+{
+  union iwreq_data      wrqu;
+  memset(&wrqu, 0, sizeof(wrqu));
+  wrqu.data.flags = RT_DISCONNECTED_EVENT_FLAG;
+  wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, NULL);
+}
+ pMgmt->eLastState = pMgmt->eCurrState ;
+#endif
+
+#ifdef Calcu_LinkQual
+   s_uCalculateLinkQual((HANDLE)pDevice);
+#endif
+
+    for (ii = 0; ii < (MAX_NODE_NUM + 1); ii++) {
+
+        if (pMgmt->sNodeDBTable[ii].bActive) {
+            // Increase in-activity counter
+            pMgmt->sNodeDBTable[ii].uInActiveCount++;
+
+            if (ii > 0) {
+                if (pMgmt->sNodeDBTable[ii].uInActiveCount > MAX_INACTIVE_COUNT) {
+                    BSSvRemoveOneNode(pDevice, ii);
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
+                        "Inactive timeout [%d] sec, STA index = [%d] remove\n", MAX_INACTIVE_COUNT, ii);
+                    continue;
+                }
+
+                if (pMgmt->sNodeDBTable[ii].eNodeState >= NODE_ASSOC) {
+
+                    pDevice->uAssocCount++;
+
+                    // check if Non ERP exist
+                    if (pMgmt->sNodeDBTable[ii].uInActiveCount < ERP_RECOVER_COUNT) {
+                        if (!pMgmt->sNodeDBTable[ii].bShortPreamble) {
+                            pDevice->byERPFlag |= WLAN_SET_ERP_BARKER_MODE(1);
+                            uLongPreambleSTACnt ++;
+                        }
+                        if (!pMgmt->sNodeDBTable[ii].bERPExist) {
+                            pDevice->byERPFlag |= WLAN_SET_ERP_NONERP_PRESENT(1);
+                            pDevice->byERPFlag |= WLAN_SET_ERP_USE_PROTECTION(1);
+                        }
+                        if (!pMgmt->sNodeDBTable[ii].bShortSlotTime)
+                            uNonShortSlotSTACnt++;
+                    }
+                }
+
+                // check if any STA in PS mode
+                if (pMgmt->sNodeDBTable[ii].bPSEnable)
+                    uSleepySTACnt++;
+
+
+            }
+
+            // Rate fallback check
+            if (!pDevice->bFixRate) {
+/*
+                if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (ii == 0))
+                    RATEvTxRateFallBack(pDevice, &(pMgmt->sNodeDBTable[ii]));
+*/
+                if (ii > 0) {
+                    // ii = 0 for multicast node (AP & Adhoc)
+                    RATEvTxRateFallBack((PVOID)pDevice, &(pMgmt->sNodeDBTable[ii]));
+                }
+                else {
+                    // ii = 0 reserved for unicast AP node (Infra STA)
+                    if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA)
+                        RATEvTxRateFallBack((PVOID)pDevice, &(pMgmt->sNodeDBTable[ii]));
+                }
+
+            }
+
+            // check if pending PS queue
+            if (pMgmt->sNodeDBTable[ii].wEnQueueCnt != 0) {
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index= %d, Queue = %d pending \n",
+                           ii, pMgmt->sNodeDBTable[ii].wEnQueueCnt);
+                if ((ii >0) && (pMgmt->sNodeDBTable[ii].wEnQueueCnt > 15)) {
+                    BSSvRemoveOneNode(pDevice, ii);
+                    DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Pending many queues PS STA Index = %d remove \n", ii);
+                    continue;
+                }
+            }
+        }
+
+    }
+
+
+    if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && (pDevice->byBBType == BB_TYPE_11G)) {
+
+        // on/off protect mode
+        if (WLAN_GET_ERP_USE_PROTECTION(pDevice->byERPFlag)) {
+            if (!pDevice->bProtectMode) {
+                MACvEnableProtectMD(pDevice);
+                pDevice->bProtectMode = TRUE;
+            }
+        }
+        else {
+            if (pDevice->bProtectMode) {
+                MACvDisableProtectMD(pDevice);
+                pDevice->bProtectMode = FALSE;
+            }
+        }
+        // on/off short slot time
+
+        if (uNonShortSlotSTACnt > 0) {
+            if (pDevice->bShortSlotTime) {
+                pDevice->bShortSlotTime = FALSE;
+                BBvSetShortSlotTime(pDevice);
+                vUpdateIFS((PVOID)pDevice);
+            }
+        }
+        else {
+            if (!pDevice->bShortSlotTime) {
+                pDevice->bShortSlotTime = TRUE;
+                BBvSetShortSlotTime(pDevice);
+                vUpdateIFS((PVOID)pDevice);
+            }
+        }
+
+        // on/off barker long preamble mode
+
+        if (uLongPreambleSTACnt > 0) {
+            if (!pDevice->bBarkerPreambleMd) {
+                MACvEnableBarkerPreambleMd(pDevice);
+                pDevice->bBarkerPreambleMd = TRUE;
+            }
+        }
+        else {
+            if (pDevice->bBarkerPreambleMd) {
+                MACvDisableBarkerPreambleMd(pDevice);
+                pDevice->bBarkerPreambleMd = FALSE;
+            }
+        }
+
+    }
+
+
+    // Check if any STA in PS mode, enable DTIM multicast deliver
+    if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
+        if (uSleepySTACnt > 0)
+            pMgmt->sNodeDBTable[0].bPSEnable = TRUE;
+        else
+            pMgmt->sNodeDBTable[0].bPSEnable = FALSE;
+    }
+
+    pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
+    pCurrSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
+
+    if ((pMgmt->eCurrMode == WMAC_MODE_STANDBY) ||
+        (pMgmt->eCurrMode == WMAC_MODE_ESS_STA)) {
+
+        if (pMgmt->sNodeDBTable[0].bActive) { // Assoc with BSS
+           // DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Callback inactive Count = [%d]\n", pMgmt->sNodeDBTable[0].uInActiveCount);
+
+            if (pDevice->bUpdateBBVGA) {
+               // s_vCheckSensitivity((HANDLE) pDevice);
+               s_vCheckPreEDThreshold((HANDLE)pDevice);
+            }
+
+    	    if ((pMgmt->sNodeDBTable[0].uInActiveCount >= (LOST_BEACON_COUNT/2)) &&
+    	        (pDevice->byBBVGACurrent != pDevice->abyBBVGA[0]) ) {
+    	        pDevice->byBBVGANew = pDevice->abyBBVGA[0];
+                bScheduleCommand((HANDLE) pDevice, WLAN_CMD_CHANGE_BBSENSITIVITY, NULL);
+    	    }
+
+        	if (pMgmt->sNodeDBTable[0].uInActiveCount >= LOST_BEACON_COUNT) {
+                pMgmt->sNodeDBTable[0].bActive = FALSE;
+                pMgmt->eCurrMode = WMAC_MODE_STANDBY;
+                pMgmt->eCurrState = WMAC_STATE_IDLE;
+                netif_stop_queue(pDevice->dev);
+                pDevice->bLinkPass = FALSE;
+                ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW);
+                pDevice->bRoaming = TRUE;
+                pDevice->bIsRoaming = FALSE;
+
+                DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Lost AP beacon [%d] sec, disconnected !\n", pMgmt->sNodeDBTable[0].uInActiveCount);
+	//let wpa supplicant know AP may disconnect.//20080717-01,<Add> by James Li
+        if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) {
+             wpahdr = (viawget_wpa_header *)pDevice->skb->data;
+             wpahdr->type = VIAWGET_DISASSOC_MSG;
+             wpahdr->resp_ie_len = 0;
+             wpahdr->req_ie_len = 0;
+             skb_put(pDevice->skb, sizeof(viawget_wpa_header));
+             pDevice->skb->dev = pDevice->wpadev;
+//2008-4-3 modify by Chester for wpa
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
+             pDevice->skb->mac_header = pDevice->skb->data;
+#else
+            pDevice->skb->mac.raw = pDevice->skb->data;
+#endif
+             pDevice->skb->pkt_type = PACKET_HOST;
+             pDevice->skb->protocol = htons(ETH_P_802_2);
+             memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
+             netif_rx(pDevice->skb);
+             pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
+         };
+   #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+  // if(pDevice->bWPASuppWextEnabled == TRUE)
+      {
+	union iwreq_data  wrqu;
+	memset(&wrqu, 0, sizeof (wrqu));
+        wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+	PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n");
+	wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
+     }
+  #endif
+            }
+        }
+        else if (pItemSSID->len != 0) {
+//Davidwang
+      if ((pDevice->bEnableRoaming == TRUE)&&(!(pMgmt->Cisco_cckm))) {
+DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "bRoaming %d, !\n", pDevice->bRoaming );
+DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "bIsRoaming %d, !\n", pDevice->bIsRoaming );
+          if ((pDevice->bRoaming == TRUE)&&(pDevice->bIsRoaming == TRUE)){
+	    	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Fast   Roaming ...\n");
+                BSSvClearBSSList((HANDLE)pDevice, pDevice->bLinkPass);
+                bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID);
+                bScheduleCommand((HANDLE) pDevice, WLAN_CMD_SSID, pMgmt->abyDesireSSID);
+                pDevice->uAutoReConnectTime = 0;
+                pDevice->uIsroamingTime = 0;
+                pDevice->bRoaming = FALSE;
+
+//            if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) {
+             wpahdr = (viawget_wpa_header *)pDevice->skb->data;
+             wpahdr->type = VIAWGET_CCKM_ROAM_MSG;
+             wpahdr->resp_ie_len = 0;
+             wpahdr->req_ie_len = 0;
+             skb_put(pDevice->skb, sizeof(viawget_wpa_header));
+             pDevice->skb->dev = pDevice->wpadev;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
+                pDevice->skb->mac_header = pDevice->skb->data;
+#else
+                pDevice->skb->mac.raw = pDevice->skb->data;
+#endif
+             pDevice->skb->pkt_type = PACKET_HOST;
+             pDevice->skb->protocol = htons(ETH_P_802_2);
+             memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
+             netif_rx(pDevice->skb);
+            pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
+
+//         }
+          }
+      else if ((pDevice->bRoaming == FALSE)&&(pDevice->bIsRoaming == TRUE)) {
+                            pDevice->uIsroamingTime++;
+       if (pDevice->uIsroamingTime >= 20)
+            pDevice->bIsRoaming = FALSE;
+         }
+
+   }
+else {
+            if (pDevice->uAutoReConnectTime < 10) {
+                pDevice->uAutoReConnectTime++;
+               #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+                //network manager support need not do Roaming scan???
+                if(pDevice->bWPASuppWextEnabled ==TRUE)
+		 pDevice->uAutoReConnectTime = 0;
+	     #endif
+            }
+            else {
+	    //mike use old encryption status for wpa reauthen
+	      if(pDevice->bWPADEVUp)
+	          pDevice->eEncryptionStatus = pDevice->eOldEncryptionStatus;
+
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Roaming ...\n");
+                BSSvClearBSSList((HANDLE)pDevice, pDevice->bLinkPass);
+	       pMgmt->eScanType = WMAC_SCAN_ACTIVE;
+                bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID);
+                bScheduleCommand((HANDLE) pDevice, WLAN_CMD_SSID, pMgmt->abyDesireSSID);
+                pDevice->uAutoReConnectTime = 0;
+            }
+        }
+    }
+    }
+
+    if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
+        // if adhoc started which essid is NULL string, rescaning.
+        if ((pMgmt->eCurrState == WMAC_STATE_STARTED) && (pCurrSSID->len == 0)) {
+            if (pDevice->uAutoReConnectTime < 10) {
+                pDevice->uAutoReConnectTime++;
+            }
+            else {
+                DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Adhoc re-scaning ...\n");
+	       pMgmt->eScanType = WMAC_SCAN_ACTIVE;
+                bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, NULL);
+                bScheduleCommand((HANDLE) pDevice, WLAN_CMD_SSID, NULL);
+                pDevice->uAutoReConnectTime = 0;
+            };
+        }
+        if (pMgmt->eCurrState == WMAC_STATE_JOINTED) {
+
+            if (pDevice->bUpdateBBVGA) {
+               //s_vCheckSensitivity((HANDLE) pDevice);
+               s_vCheckPreEDThreshold((HANDLE)pDevice);
+            }
+        	if (pMgmt->sNodeDBTable[0].uInActiveCount >=ADHOC_LOST_BEACON_COUNT) {
+        	    DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Lost other STA beacon [%d] sec, started !\n", pMgmt->sNodeDBTable[0].uInActiveCount);
+                pMgmt->sNodeDBTable[0].uInActiveCount = 0;
+                pMgmt->eCurrState = WMAC_STATE_STARTED;
+                netif_stop_queue(pDevice->dev);
+                pDevice->bLinkPass = FALSE;
+                ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW);
+            }
+        }
+    }
+
+    if (pDevice->bLinkPass == TRUE) {
+        if (netif_queue_stopped(pDevice->dev))
+            netif_wake_queue(pDevice->dev);
+    }
+
+    spin_unlock_irq(&pDevice->lock);
+
+    pMgmt->sTimerSecondCallback.expires = RUN_AT(HZ);
+    add_timer(&pMgmt->sTimerSecondCallback);
+    return;
+}
+
+
+
+
+/*+
+ *
+ * Routine Description:
+ *
+ *
+ *  Update Tx attemps, Tx failure counter in Node DB
+ *
+ *
+ * Return Value:
+ *    none.
+ *
+-*/
+
+
+
+VOID
+BSSvUpdateNodeTxCounter(
+    IN HANDLE      hDeviceContext,
+    IN PSStatCounter    pStatistic,
+    IN BYTE             byTSR,
+    IN BYTE             byPktNO
+    )
+{
+    PSDevice        pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    UINT            uNodeIndex = 0;
+    BYTE            byTxRetry;
+    WORD            wRate;
+    WORD            wFallBackRate = RATE_1M;
+    BYTE            byFallBack;
+    UINT            ii;
+    PBYTE           pbyDestAddr;
+    BYTE            byPktNum;
+    WORD            wFIFOCtl;
+
+
+
+    byPktNum = (byPktNO & 0x0F) >> 4;
+    byTxRetry = (byTSR & 0xF0) >> 4;
+    wRate = (WORD) (byPktNO & 0xF0) >> 4;
+    wFIFOCtl = pStatistic->abyTxPktInfo[byPktNum].wFIFOCtl;
+    pbyDestAddr = (PBYTE) &( pStatistic->abyTxPktInfo[byPktNum].abyDestAddr[0]);
+
+    if (wFIFOCtl & FIFOCTL_AUTO_FB_0) {
+        byFallBack = AUTO_FB_0;
+    } else if (wFIFOCtl & FIFOCTL_AUTO_FB_1) {
+        byFallBack = AUTO_FB_1;
+    } else {
+        byFallBack = AUTO_FB_NONE;
+    }
+
+    // Only Unicast using support rates
+    if (wFIFOCtl & FIFOCTL_NEEDACK) {
+        //DBG_PRN_GRP21(("Device %08X, wRate %04X, byTSR %02X\n", hDeviceContext, wRate, byTSR));
+        if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) {
+            pMgmt->sNodeDBTable[0].uTxAttempts += 1;
+            if (BITbIsAllBitsOff(byTSR, (TSR_TMO | TSR_RETRYTMO))) {
+                // transmit success, TxAttempts at least plus one
+                pMgmt->sNodeDBTable[0].uTxOk[MAX_RATE]++;
+                if ( (byFallBack == AUTO_FB_NONE) ||
+                     (wRate < RATE_18M) ) {
+                    wFallBackRate = wRate;
+                } else if (byFallBack == AUTO_FB_0) {
+                    if (byTxRetry < 5)
+                        wFallBackRate = awHWRetry0[wRate-RATE_18M][byTxRetry];
+                    else
+                        wFallBackRate = awHWRetry0[wRate-RATE_18M][4];
+                } else if (byFallBack == AUTO_FB_1) {
+                    if (byTxRetry < 5)
+                        wFallBackRate = awHWRetry1[wRate-RATE_18M][byTxRetry];
+                    else
+                        wFallBackRate = awHWRetry1[wRate-RATE_18M][4];
+                }
+                pMgmt->sNodeDBTable[0].uTxOk[wFallBackRate]++;
+            } else {
+                pMgmt->sNodeDBTable[0].uTxFailures ++;
+            }
+            pMgmt->sNodeDBTable[0].uTxRetry += byTxRetry;
+            if (byTxRetry != 0) {
+                pMgmt->sNodeDBTable[0].uTxFail[MAX_RATE]+=byTxRetry;
+                if ( (byFallBack == AUTO_FB_NONE) ||
+                     (wRate < RATE_18M) ) {
+                    pMgmt->sNodeDBTable[0].uTxFail[wRate]+=byTxRetry;
+                } else if (byFallBack == AUTO_FB_0) {
+                    for(ii=0;ii<byTxRetry;ii++) {
+                        if (ii < 5)
+                            wFallBackRate = awHWRetry0[wRate-RATE_18M][ii];
+                        else
+                            wFallBackRate = awHWRetry0[wRate-RATE_18M][4];
+                        pMgmt->sNodeDBTable[0].uTxFail[wFallBackRate]++;
+                    }
+                } else if (byFallBack == AUTO_FB_1) {
+                    for(ii=0;ii<byTxRetry;ii++) {
+                        if (ii < 5)
+                            wFallBackRate = awHWRetry1[wRate-RATE_18M][ii];
+                        else
+                            wFallBackRate = awHWRetry1[wRate-RATE_18M][4];
+                        pMgmt->sNodeDBTable[0].uTxFail[wFallBackRate]++;
+                    }
+                }
+            }
+        };
+
+        if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) ||
+            (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)) {
+
+            if (BSSbIsSTAInNodeDB((HANDLE)pDevice, pbyDestAddr, &uNodeIndex)){
+                pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts += 1;
+                if (BITbIsAllBitsOff(byTSR, (TSR_TMO | TSR_RETRYTMO))) {
+                    // transmit success, TxAttempts at least plus one
+                    pMgmt->sNodeDBTable[uNodeIndex].uTxOk[MAX_RATE]++;
+                    if ( (byFallBack == AUTO_FB_NONE) ||
+                         (wRate < RATE_18M) ) {
+                        wFallBackRate = wRate;
+                    } else if (byFallBack == AUTO_FB_0) {
+                        if (byTxRetry < 5)
+                            wFallBackRate = awHWRetry0[wRate-RATE_18M][byTxRetry];
+                        else
+                            wFallBackRate = awHWRetry0[wRate-RATE_18M][4];
+                    } else if (byFallBack == AUTO_FB_1) {
+                        if (byTxRetry < 5)
+                            wFallBackRate = awHWRetry1[wRate-RATE_18M][byTxRetry];
+                        else
+                            wFallBackRate = awHWRetry1[wRate-RATE_18M][4];
+                    }
+                    pMgmt->sNodeDBTable[uNodeIndex].uTxOk[wFallBackRate]++;
+                } else {
+                    pMgmt->sNodeDBTable[uNodeIndex].uTxFailures ++;
+                }
+                pMgmt->sNodeDBTable[uNodeIndex].uTxRetry += byTxRetry;
+                if (byTxRetry != 0) {
+                    pMgmt->sNodeDBTable[uNodeIndex].uTxFail[MAX_RATE]+=byTxRetry;
+                    if ( (byFallBack == AUTO_FB_NONE) ||
+                         (wRate < RATE_18M) ) {
+                        pMgmt->sNodeDBTable[uNodeIndex].uTxFail[wRate]+=byTxRetry;
+                    } else if (byFallBack == AUTO_FB_0) {
+                        for(ii=0;ii<byTxRetry;ii++) {
+                            if (ii < 5)
+                                wFallBackRate = awHWRetry0[wRate-RATE_18M][ii];
+                            else
+                                wFallBackRate = awHWRetry0[wRate-RATE_18M][4];
+                            pMgmt->sNodeDBTable[uNodeIndex].uTxFail[wFallBackRate]++;
+                        }
+                    } else if (byFallBack == AUTO_FB_1) {
+                        for(ii=0;ii<byTxRetry;ii++) {
+                            if (ii < 5)
+                                wFallBackRate = awHWRetry1[wRate-RATE_18M][ii];
+                            else
+                                wFallBackRate = awHWRetry1[wRate-RATE_18M][4];
+                            pMgmt->sNodeDBTable[uNodeIndex].uTxFail[wFallBackRate]++;
+                        }
+                    }
+                }
+            };
+        }
+    };
+
+    return;
+
+
+}
+
+
+
+
+/*+
+ *
+ * Routine Description:
+ *    Clear Nodes & skb in DB Table
+ *
+ *
+ * Parameters:
+ *  In:
+ *      hDeviceContext        - The adapter context.
+ *      uStartIndex           - starting index
+ *  Out:
+ *      none
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+
+VOID
+BSSvClearNodeDBTable(
+    IN HANDLE hDeviceContext,
+    IN UINT uStartIndex
+    )
+
+{
+    PSDevice     pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    struct sk_buff  *skb;
+    UINT            ii;
+
+    for (ii = uStartIndex; ii < (MAX_NODE_NUM + 1); ii++) {
+        if (pMgmt->sNodeDBTable[ii].bActive) {
+            // check if sTxPSQueue has been initial
+            if (pMgmt->sNodeDBTable[ii].sTxPSQueue.next != NULL) {
+                while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) != NULL){
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "PS skb != NULL %d\n", ii);
+                        dev_kfree_skb(skb);
+                }
+            }
+            memset(&pMgmt->sNodeDBTable[ii], 0, sizeof(KnownNodeDB));
+        }
+    }
+
+    return;
+};
+
+
+VOID s_vCheckSensitivity(
+    IN HANDLE hDeviceContext
+    )
+{
+    PSDevice        pDevice = (PSDevice)hDeviceContext;
+    PKnownBSS       pBSSList = NULL;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    int             ii;
+
+    if ((pMgmt->eCurrState == WMAC_STATE_ASSOC) ||
+        ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED))) {
+        pBSSList = BSSpAddrIsInBSSList(pDevice, pMgmt->abyCurrBSSID, (PWLAN_IE_SSID)pMgmt->abyCurrSSID);
+        if (pBSSList != NULL) {
+            // Updata BB Reg if RSSI is too strong.
+            LONG    LocalldBmAverage = 0;
+            LONG    uNumofdBm = 0;
+            for (ii = 0; ii < RSSI_STAT_COUNT; ii++) {
+                if (pBSSList->ldBmAverage[ii] != 0) {
+                    uNumofdBm ++;
+                    LocalldBmAverage += pBSSList->ldBmAverage[ii];
+                }
+            }
+            if (uNumofdBm > 0) {
+                LocalldBmAverage = LocalldBmAverage/uNumofdBm;
+                for (ii=0;ii<BB_VGA_LEVEL;ii++) {
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"LocalldBmAverage:%ld, %ld %02x\n", LocalldBmAverage, pDevice->ldBmThreshold[ii], pDevice->abyBBVGA[ii]);
+                    if (LocalldBmAverage < pDevice->ldBmThreshold[ii]) {
+                	    pDevice->byBBVGANew = pDevice->abyBBVGA[ii];
+                        break;
+                    }
+                }
+                if (pDevice->byBBVGANew != pDevice->byBBVGACurrent) {
+                    pDevice->uBBVGADiffCount++;
+                    if (pDevice->uBBVGADiffCount >= BB_VGA_CHANGE_THRESHOLD)
+                        bScheduleCommand((HANDLE) pDevice, WLAN_CMD_CHANGE_BBSENSITIVITY, NULL);
+                } else {
+                    pDevice->uBBVGADiffCount = 0;
+                }
+            }
+        }
+    }
+}
+
+#ifdef Calcu_LinkQual
+VOID s_uCalculateLinkQual(
+    IN HANDLE hDeviceContext
+    )
+{
+   PSDevice        pDevice = (PSDevice)hDeviceContext;
+   ULONG TxOkRatio, TxCnt;
+   ULONG RxOkRatio,RxCnt;
+   ULONG RssiRatio;
+   long ldBm;
+
+TxCnt = pDevice->scStatistic.TxNoRetryOkCount +
+	      pDevice->scStatistic.TxRetryOkCount +
+	      pDevice->scStatistic.TxFailCount;
+RxCnt = pDevice->scStatistic.RxFcsErrCnt +
+	      pDevice->scStatistic.RxOkCnt;
+TxOkRatio = (TxCnt < 6) ? 4000:((pDevice->scStatistic.TxNoRetryOkCount * 4000) / TxCnt);
+RxOkRatio = (RxCnt < 6) ? 2000:((pDevice->scStatistic.RxOkCnt * 2000) / RxCnt);
+//decide link quality
+if(pDevice->bLinkPass !=TRUE)
+{
+ //  printk("s_uCalculateLinkQual-->Link disconnect and Poor quality**\n");
+   pDevice->scStatistic.LinkQuality = 0;
+   pDevice->scStatistic.SignalStren = 0;
+}
+else
+{
+   RFvRSSITodBm(pDevice, (BYTE)(pDevice->uCurrRSSI), &ldBm);
+   if(-ldBm < 50)  {
+   	RssiRatio = 4000;
+     }
+   else if(-ldBm > 90) {
+   	RssiRatio = 0;
+     }
+   else {
+   	RssiRatio = (40-(-ldBm-50))*4000/40;
+     }
+   pDevice->scStatistic.SignalStren = RssiRatio/40;
+   pDevice->scStatistic.LinkQuality = (RssiRatio+TxOkRatio+RxOkRatio)/100;
+}
+   pDevice->scStatistic.RxFcsErrCnt = 0;
+   pDevice->scStatistic.RxOkCnt = 0;
+   pDevice->scStatistic.TxFailCount = 0;
+   pDevice->scStatistic.TxNoRetryOkCount = 0;
+   pDevice->scStatistic.TxRetryOkCount = 0;
+   return;
+}
+#endif
+
+VOID
+BSSvClearAnyBSSJoinRecord (
+    IN HANDLE hDeviceContext
+    )
+{
+    PSDevice        pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    UINT            ii;
+
+    for (ii = 0; ii < MAX_BSS_NUM; ii++) {
+        pMgmt->sBSSList[ii].bSelected = FALSE;
+    }
+    return;
+}
+
+VOID s_vCheckPreEDThreshold(
+    IN HANDLE hDeviceContext
+    )
+{
+    PSDevice        pDevice = (PSDevice)hDeviceContext;
+    PKnownBSS       pBSSList = NULL;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+
+    if ((pMgmt->eCurrState == WMAC_STATE_ASSOC) ||
+        ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED))) {
+        pBSSList = BSSpAddrIsInBSSList(pDevice, pMgmt->abyCurrBSSID, (PWLAN_IE_SSID)pMgmt->abyCurrSSID);
+        if (pBSSList != NULL) {
+            pDevice->byBBPreEDRSSI = (BYTE) (~(pBSSList->ldBmAverRange) + 1);
+            BBvUpdatePreEDThreshold(pDevice, FALSE);
+        }
+    }
+    return;
+}
+
diff --git a/drivers/staging/vt6656/bssdb.h b/drivers/staging/vt6656/bssdb.h
new file mode 100644
index 0000000..bcea3ad
--- /dev/null
+++ b/drivers/staging/vt6656/bssdb.h
@@ -0,0 +1,370 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: bssdb.h
+ *
+ * Purpose: Handles the Basic Service Set & Node Database functions
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: July 16, 2002
+ *
+ */
+
+#ifndef __BSSDB_H__
+#define __BSSDB_H__
+
+
+#include <linux/skbuff.h>
+
+#if !defined(__80211HDR_H__)
+#include "80211hdr.h"
+#endif
+#if !defined(__80211MGR_H__)
+#include "80211mgr.h"
+#endif
+#if !defined(__CARD_H__)
+#include "card.h"
+#endif
+#if !defined(__MIB_H__)
+#include "mib.h"
+#endif
+
+
+/*---------------------  Export Definitions -------------------------*/
+
+#define MAX_NODE_NUM             64
+#define MAX_BSS_NUM              42
+#define LOST_BEACON_COUNT      	 10   // 10 sec, XP defined
+#define MAX_PS_TX_BUF            32   // sta max power saving tx buf
+#define ADHOC_LOST_BEACON_COUNT  30   // 30 sec, beacon lost for adhoc only
+#define MAX_INACTIVE_COUNT       300  // 300 sec, inactive STA node refresh
+
+#define USE_PROTECT_PERIOD       10   // 10 sec, Use protect mode check period
+#define ERP_RECOVER_COUNT        30   // 30 sec, ERP support callback check
+#define BSS_CLEAR_COUNT           1
+
+#define RSSI_STAT_COUNT          10
+#define MAX_CHECK_RSSI_COUNT     8
+
+// STA dwflags
+#define WLAN_STA_AUTH            BIT0
+#define WLAN_STA_ASSOC           BIT1
+#define WLAN_STA_PS              BIT2
+#define WLAN_STA_TIM             BIT3
+// permanent; do not remove entry on expiration
+#define WLAN_STA_PERM            BIT4
+// If 802.1X is used, this flag is
+// controlling whether STA is authorized to
+// send and receive non-IEEE 802.1X frames
+#define WLAN_STA_AUTHORIZED      BIT5
+
+//#define MAX_RATE            12
+
+#define MAX_WPA_IE_LEN      64
+
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+
+/*---------------------  Export Types  ------------------------------*/
+
+//
+// IEEE 802.11 Structures and definitions
+//
+
+typedef struct tagSERPObject {
+    BOOL    bERPExist;
+    BYTE    byERP;
+}ERPObject, DEF* PERPObject;
+
+
+typedef struct tagSRSNCapObject {
+    BOOL    bRSNCapExist;
+    WORD    wRSNCap;
+}SRSNCapObject, DEF* PSRSNCapObject;
+
+// BSS info(AP)
+#pragma pack(1)
+typedef struct tagKnownBSS {
+    // BSS info
+    BOOL            bActive;
+    BYTE            abyBSSID[WLAN_BSSID_LEN];
+    UINT            uChannel;
+    BYTE            abySuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
+    BYTE            abyExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
+    UINT            uRSSI;
+    BYTE            bySQ;
+    WORD            wBeaconInterval;
+    WORD            wCapInfo;
+    BYTE            abySSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
+    BYTE            byRxRate;
+
+//    WORD            wATIMWindow;
+    BYTE            byRSSIStatCnt;
+    LONG            ldBmMAX;
+    LONG            ldBmAverage[RSSI_STAT_COUNT];
+    LONG            ldBmAverRange;
+    //For any BSSID selection improvment
+    BOOL            bSelected;
+
+    //++ WPA informations
+    BOOL            bWPAValid;
+    BYTE            byGKType;
+    BYTE            abyPKType[4];
+    WORD            wPKCount;
+    BYTE            abyAuthType[4];
+    WORD            wAuthCount;
+    BYTE            byDefaultK_as_PK;
+    BYTE            byReplayIdx;
+    //--
+
+    //++ WPA2 informations
+    BOOL            bWPA2Valid;
+    BYTE            byCSSGK;
+    WORD            wCSSPKCount;
+    BYTE            abyCSSPK[4];
+    WORD            wAKMSSAuthCount;
+    BYTE            abyAKMSSAuthType[4];
+
+    //++  wpactl
+    BYTE            byWPAIE[MAX_WPA_IE_LEN];
+    BYTE            byRSNIE[MAX_WPA_IE_LEN];
+    WORD            wWPALen;
+    WORD            wRSNLen;
+
+    // Clear count
+    UINT            uClearCount;
+//    BYTE            abyIEs[WLAN_BEACON_FR_MAXLEN];
+    UINT            uIELength;
+    QWORD           qwBSSTimestamp;
+    QWORD           qwLocalTSF;     // local TSF timer
+
+    CARD_PHY_TYPE   eNetworkTypeInUse;
+
+    ERPObject       sERP;
+    SRSNCapObject   sRSNCapObj;
+    BYTE            abyIEs[1024];   // don't move this field !!
+
+}__attribute__ ((__packed__))
+KnownBSS , DEF* PKnownBSS;
+
+
+
+typedef enum tagNODE_STATE {
+    NODE_FREE,
+    NODE_AGED,
+    NODE_KNOWN,
+    NODE_AUTH,
+    NODE_ASSOC
+} NODE_STATE, *PNODE_STATE;
+
+
+// STA node info
+typedef struct tagKnownNodeDB {
+    // STA info
+    BOOL            bActive;
+    BYTE            abyMACAddr[WLAN_ADDR_LEN];
+    BYTE            abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN];
+    BYTE            abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN];
+    WORD            wTxDataRate;
+    BOOL            bShortPreamble;
+    BOOL            bERPExist;
+    BOOL            bShortSlotTime;
+    UINT            uInActiveCount;
+    WORD            wMaxBasicRate;     //Get from byTopOFDMBasicRate or byTopCCKBasicRate which depends on packetTyp.
+    WORD            wMaxSuppRate;      //Records the highest supported rate getting from SuppRates IE and ExtSuppRates IE in Beacon.
+    WORD            wSuppRate;
+    BYTE            byTopOFDMBasicRate;//Records the highest basic rate in OFDM mode
+    BYTE            byTopCCKBasicRate; //Records the highest basic rate in CCK mode
+
+    // For AP mode
+    struct sk_buff_head sTxPSQueue;
+    WORD            wCapInfo;
+    WORD            wListenInterval;
+    WORD            wAID;
+    NODE_STATE      eNodeState;
+    BOOL            bPSEnable;
+    BOOL            bRxPSPoll;
+    BYTE            byAuthSequence;
+    ULONG           ulLastRxJiffer;
+    BYTE            bySuppRate;
+    DWORD           dwFlags;
+    WORD            wEnQueueCnt;
+
+    BOOL            bOnFly;
+    ULONGLONG       KeyRSC;
+    BYTE            byKeyIndex;
+    DWORD           dwKeyIndex;
+    BYTE            byCipherSuite;
+    DWORD           dwTSC47_16;
+    WORD            wTSC15_0;
+    UINT            uWepKeyLength;
+    BYTE            abyWepKey[WLAN_WEPMAX_KEYLEN];
+    //
+    // Auto rate fallback vars
+    BOOL            bIsInFallback;
+    UINT            uAverageRSSI;
+    UINT            uRateRecoveryTimeout;
+    UINT            uRatePollTimeout;
+    UINT            uTxFailures;
+    UINT            uTxAttempts;
+
+    UINT            uTxRetry;
+    UINT            uFailureRatio;
+    UINT            uRetryRatio;
+    UINT            uTxOk[MAX_RATE+1];
+    UINT            uTxFail[MAX_RATE+1];
+    UINT            uTimeCount;
+
+} KnownNodeDB, DEF* PKnownNodeDB;
+
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+
+PKnownBSS
+BSSpSearchBSSList(
+    IN HANDLE hDeviceContext,
+    IN PBYTE pbyDesireBSSID,
+    IN PBYTE pbyDesireSSID,
+    IN CARD_PHY_TYPE ePhyType
+    );
+
+PKnownBSS
+BSSpAddrIsInBSSList(
+    IN HANDLE hDeviceContext,
+    IN PBYTE abyBSSID,
+    IN PWLAN_IE_SSID pSSID
+    );
+
+VOID
+BSSvClearBSSList(
+    IN HANDLE hDeviceContext,
+    IN BOOL bKeepCurrBSSID
+    );
+
+BOOL
+BSSbInsertToBSSList(
+    IN HANDLE hDeviceContext,
+    IN PBYTE abyBSSIDAddr,
+    IN QWORD qwTimestamp,
+    IN WORD wBeaconInterval,
+    IN WORD wCapInfo,
+    IN BYTE byCurrChannel,
+    IN PWLAN_IE_SSID pSSID,
+    IN PWLAN_IE_SUPP_RATES pSuppRates,
+    IN PWLAN_IE_SUPP_RATES pExtSuppRates,
+    IN PERPObject psERP,
+    IN PWLAN_IE_RSN pRSN,
+    IN PWLAN_IE_RSN_EXT pRSNWPA,
+    IN PWLAN_IE_COUNTRY pIE_Country,
+    IN PWLAN_IE_QUIET pIE_Quiet,
+    IN UINT uIELength,
+    IN PBYTE pbyIEs,
+    IN HANDLE pRxPacketContext
+    );
+
+
+BOOL
+BSSbUpdateToBSSList(
+    IN HANDLE hDeviceContext,
+    IN QWORD qwTimestamp,
+    IN WORD wBeaconInterval,
+    IN WORD wCapInfo,
+    IN BYTE byCurrChannel,
+    IN BOOL bChannelHit,
+    IN PWLAN_IE_SSID pSSID,
+    IN PWLAN_IE_SUPP_RATES pSuppRates,
+    IN PWLAN_IE_SUPP_RATES pExtSuppRates,
+    IN PERPObject psERP,
+    IN PWLAN_IE_RSN pRSN,
+    IN PWLAN_IE_RSN_EXT pRSNWPA,
+    IN PWLAN_IE_COUNTRY pIE_Country,
+    IN PWLAN_IE_QUIET pIE_Quiet,
+    IN PKnownBSS pBSSList,
+    IN UINT uIELength,
+    IN PBYTE pbyIEs,
+    IN HANDLE pRxPacketContext
+    );
+
+
+BOOL
+BSSbIsSTAInNodeDB(
+    IN HANDLE hDeviceContext,
+    IN PBYTE abyDstAddr,
+    OUT PUINT puNodeIndex
+    );
+
+VOID
+BSSvCreateOneNode(
+    IN HANDLE hDeviceContext,
+    OUT PUINT puNodeIndex
+    );
+
+VOID
+BSSvUpdateAPNode(
+    IN HANDLE hDeviceContext,
+    IN PWORD pwCapInfo,
+    IN PWLAN_IE_SUPP_RATES pItemRates,
+    IN PWLAN_IE_SUPP_RATES pExtSuppRates
+    );
+
+
+VOID
+BSSvSecondCallBack(
+    IN HANDLE hDeviceContext
+    );
+
+
+VOID
+BSSvUpdateNodeTxCounter(
+    IN HANDLE      hDeviceContext,
+    IN PSStatCounter    pStatistic,
+    IN BYTE             byTSR,
+    IN BYTE             byPktNO
+    );
+
+VOID
+BSSvRemoveOneNode(
+    IN HANDLE hDeviceContext,
+    IN UINT uNodeIndex
+    );
+
+VOID
+BSSvAddMulticastNode(
+    IN HANDLE hDeviceContext
+    );
+
+
+VOID
+BSSvClearNodeDBTable(
+    IN HANDLE hDeviceContext,
+    IN UINT uStartIndex
+    );
+
+VOID
+BSSvClearAnyBSSJoinRecord(
+    IN HANDLE hDeviceContext
+    );
+
+#endif //__BSSDB_H__
diff --git a/drivers/staging/vt6656/card.c b/drivers/staging/vt6656/card.c
new file mode 100644
index 0000000..f1f5f35
--- /dev/null
+++ b/drivers/staging/vt6656/card.c
@@ -0,0 +1,1147 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: card.c
+ * Purpose: Provide functions to setup NIC operation mode
+ * Functions:
+ *      s_vSafeResetTx - Rest Tx
+ *      CARDvSetRSPINF - Set RSPINF
+ *      vUpdateIFS - Update slotTime,SIFS,DIFS, and EIFS
+ *      CARDvUpdateBasicTopRate - Update BasicTopRate
+ *      CARDbAddBasicRate - Add to BasicRateSet
+ *      CARDbSetBasicRate - Set Basic Tx Rate
+ *      CARDbIsOFDMinBasicRate - Check if any OFDM rate is in BasicRateSet
+ *      CARDvSetLoopbackMode - Set Loopback mode
+ *      CARDbSoftwareReset - Sortware reset NIC
+ *      CARDqGetTSFOffset - Caculate TSFOffset
+ *      CARDbGetCurrentTSF - Read Current NIC TSF counter
+ *      CARDqGetNextTBTT - Caculate Next Beacon TSF counter
+ *      CARDvSetFirstNextTBTT - Set NIC Beacon time
+ *      CARDvUpdateNextTBTT - Sync. NIC Beacon time
+ *      CARDbRadioPowerOff - Turn Off NIC Radio Power
+ *      CARDbRadioPowerOn - Turn On NIC Radio Power
+ *      CARDbSetWEPMode - Set NIC Wep mode
+ *      CARDbSetTxPower - Set NIC tx power
+ *
+ * Revision History:
+ *      06-10-2003 Bryan YC Fan:  Re-write codes to support VT3253 spec.
+ *      08-26-2003 Kyle Hsu:      Modify the defination type of dwIoBase.
+ *      09-01-2003 Bryan YC Fan:  Add vUpdateIFS().
+ *
+ */
+
+#if !defined(__TMACRO_H__)
+#include "tmacro.h"
+#endif
+#if !defined(__CARD_H__)
+#include "card.h"
+#endif
+#if !defined(__TBIT_H__)
+#include "tbit.h"
+#endif
+#if !defined(__BASEBAND_H__)
+#include "baseband.h"
+#endif
+#if !defined(__MAC_H__)
+#include "mac.h"
+#endif
+#if !defined(__DESC_H__)
+#include "desc.h"
+#endif
+#if !defined(__RF_H__)
+#include "rf.h"
+#endif
+#if !defined(__POWER_H__)
+#include "power.h"
+#endif
+#if !defined(__KEY_H__)
+#include "key.h"
+#endif
+#if !defined(__RC4_H__)
+#include "rc4.h"
+#endif
+#if !defined(__COUNTRY_H__)
+#include "country.h"
+#endif
+#if !defined(__UMEM_H__)
+#include "umem.h"
+#endif
+#if !defined(__DATARATE_H__)
+#include "datarate.h"
+#endif
+#if !defined(__RNDIS_H__)
+#include "rndis.h"
+#endif
+#if !defined(__CONTROL_H__)
+#include "control.h"
+#endif
+
+
+
+/*---------------------  Static Definitions -------------------------*/
+
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+static int          msglevel                =MSG_LEVEL_INFO;
+
+
+/*---------------------  Static Definitions -------------------------*/
+#define CB_TXPOWER_LEVEL            6
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+//const WORD cwRXBCNTSFOff[MAX_RATE] =
+//{17, 34, 96, 192, 34, 23, 17, 11, 8, 5, 4, 3};
+
+const WORD cwRXBCNTSFOff[MAX_RATE] =
+{192, 96, 34, 17, 34, 23, 17, 11, 8, 5, 4, 3};
+
+/*---------------------  Static Functions  --------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+/*
+ * Description: Set NIC media channel
+ *
+ * Parameters:
+ *  In:
+ *      pDevice             - The adapter to be set
+ *      uConnectionChannel  - Channel to be set
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if succeeded; FALSE if failed.
+ *
+ */
+BOOL CARDbSetMediaChannel (PVOID pDeviceHandler, UINT uConnectionChannel)
+{
+PSDevice            pDevice = (PSDevice) pDeviceHandler;
+BOOL                bResult = TRUE;
+
+
+    if (pDevice->byBBType == BB_TYPE_11A) { // 15 ~ 38
+        if ((uConnectionChannel < (CB_MAX_CHANNEL_24G+1)) || (uConnectionChannel > CB_MAX_CHANNEL))
+            uConnectionChannel = (CB_MAX_CHANNEL_24G+1);
+    } else {
+        if ((uConnectionChannel > CB_MAX_CHANNEL_24G) || (uConnectionChannel == 0)) // 1 ~ 14
+            uConnectionChannel = 1;
+    }
+
+    // clear NAV
+    MACvRegBitsOn(pDevice, MAC_REG_MACCR, MACCR_CLRNAV);
+
+    // Set Channel[7] = 0 to tell H/W channel is changing now.
+    MACvRegBitsOff(pDevice, MAC_REG_CHANNEL, 0x80);
+
+    //if (pMgmt->uCurrChannel == uConnectionChannel)
+    //    return bResult;
+
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_SELECT_CHANNLE,
+                        (WORD) uConnectionChannel,
+                        0,
+                        0,
+                        NULL
+                        );
+
+    //{{ RobertYu: 20041202
+    //// TX_PE will reserve 3 us for MAX2829 A mode only, it is for better TX throughput
+
+    if (pDevice->byBBType == BB_TYPE_11A) {
+        pDevice->byCurPwr = 0xFF;
+        RFbRawSetPower(pDevice, pDevice->abyOFDMAPwrTbl[uConnectionChannel-15], RATE_54M);
+    } else if (pDevice->byBBType == BB_TYPE_11G) {
+        pDevice->byCurPwr = 0xFF;
+        RFbRawSetPower(pDevice, pDevice->abyOFDMPwrTbl[uConnectionChannel-1], RATE_54M);
+    } else {
+        pDevice->byCurPwr = 0xFF;
+        RFbRawSetPower(pDevice, pDevice->abyCCKPwrTbl[uConnectionChannel-1], RATE_1M);
+    }
+    ControlvWriteByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_CHANNEL,(BYTE)(uConnectionChannel|0x80));
+    return(bResult);
+}
+
+/*
+ * Description: Get CCK mode basic rate
+ *
+ * Parameters:
+ *  In:
+ *      pDevice             - The adapter to be set
+ *      wRateIdx            - Receiving data rate
+ *  Out:
+ *      none
+ *
+ * Return Value: response Control frame rate
+ *
+ */
+static
+WORD swGetCCKControlRate(PVOID pDeviceHandler, WORD wRateIdx)
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+    UINT ui = (UINT)wRateIdx;
+    while (ui > RATE_1M) {
+        if (pDevice->wBasicRate & ((WORD)1 << ui)) {
+            return (WORD)ui;
+        }
+        ui --;
+    }
+    return (WORD)RATE_1M;
+}
+
+/*
+ * Description: Get OFDM mode basic rate
+ *
+ * Parameters:
+ *  In:
+ *      pDevice             - The adapter to be set
+ *      wRateIdx            - Receiving data rate
+ *  Out:
+ *      none
+ *
+ * Return Value: response Control frame rate
+ *
+ */
+static
+WORD swGetOFDMControlRate (PVOID pDeviceHandler, WORD wRateIdx)
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+    UINT ui = (UINT)wRateIdx;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BASIC RATE: %X\n", pDevice->wBasicRate);
+
+    if (!CARDbIsOFDMinBasicRate(pDevice)) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"swGetOFDMControlRate:(NO OFDM) %d\n", wRateIdx);
+        if (wRateIdx > RATE_24M)
+            wRateIdx = RATE_24M;
+        return wRateIdx;
+    }
+    while (ui > RATE_11M) {
+        if (pDevice->wBasicRate & ((WORD)1 << ui)) {
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"swGetOFDMControlRate : %d\n", ui);
+            return (WORD)ui;
+        }
+        ui --;
+    }
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"swGetOFDMControlRate: 6M\n");
+    return (WORD)RATE_24M;
+}
+
+/*
+ * Description: Caculate TxRate and RsvTime fields for RSPINF in OFDM mode.
+ *
+ * Parameters:
+ *  In:
+ *      wRate           - Tx Rate
+ *      byPktType       - Tx Packet type
+ *  Out:
+ *      pbyTxRate       - pointer to RSPINF TxRate field
+ *      pbyRsvTime      - pointer to RSPINF RsvTime field
+ *
+ * Return Value: none
+ *
+ */
+VOID
+CARDvCaculateOFDMRParameter (
+    IN  WORD wRate,
+    IN  BYTE byBBType,
+    OUT PBYTE pbyTxRate,
+    OUT PBYTE pbyRsvTime
+    )
+{
+    switch (wRate) {
+    case RATE_6M :
+        if (byBBType == BB_TYPE_11A) {//5GHZ
+            *pbyTxRate = 0x9B;
+            *pbyRsvTime = 24;
+        }
+        else {
+            *pbyTxRate = 0x8B;
+            *pbyRsvTime = 30;
+        }
+        break;
+
+    case RATE_9M :
+        if (byBBType == BB_TYPE_11A) {//5GHZ
+            *pbyTxRate = 0x9F;
+            *pbyRsvTime = 16;
+        }
+        else {
+            *pbyTxRate = 0x8F;
+            *pbyRsvTime = 22;
+        }
+        break;
+
+   case RATE_12M :
+        if (byBBType == BB_TYPE_11A) {//5GHZ
+            *pbyTxRate = 0x9A;
+            *pbyRsvTime = 12;
+        }
+        else {
+            *pbyTxRate = 0x8A;
+            *pbyRsvTime = 18;
+        }
+        break;
+
+   case RATE_18M :
+        if (byBBType == BB_TYPE_11A) {//5GHZ
+            *pbyTxRate = 0x9E;
+            *pbyRsvTime = 8;
+        }
+        else {
+            *pbyTxRate = 0x8E;
+            *pbyRsvTime = 14;
+        }
+        break;
+
+    case RATE_36M :
+        if (byBBType == BB_TYPE_11A) {//5GHZ
+            *pbyTxRate = 0x9D;
+            *pbyRsvTime = 4;
+        }
+        else {
+            *pbyTxRate = 0x8D;
+            *pbyRsvTime = 10;
+        }
+        break;
+
+    case RATE_48M :
+        if (byBBType == BB_TYPE_11A) {//5GHZ
+            *pbyTxRate = 0x98;
+            *pbyRsvTime = 4;
+        }
+        else {
+            *pbyTxRate = 0x88;
+            *pbyRsvTime = 10;
+        }
+        break;
+
+    case RATE_54M :
+        if (byBBType == BB_TYPE_11A) {//5GHZ
+            *pbyTxRate = 0x9C;
+            *pbyRsvTime = 4;
+        }
+        else {
+            *pbyTxRate = 0x8C;
+            *pbyRsvTime = 10;
+        }
+        break;
+
+    case RATE_24M :
+    default :
+        if (byBBType == BB_TYPE_11A) {//5GHZ
+            *pbyTxRate = 0x99;
+            *pbyRsvTime = 8;
+        }
+        else {
+            *pbyTxRate = 0x89;
+            *pbyRsvTime = 14;
+        }
+        break;
+    }
+}
+
+/*
+ * Description: Set RSPINF
+ *
+ * Parameters:
+ *  In:
+ *      pDevice             - The adapter to be set
+ *  Out:
+ *      none
+ *
+ * Return Value: None.
+ *
+ */
+void CARDvSetRSPINF (PVOID pDeviceHandler, BYTE byBBType)
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+    BYTE    abyServ[4] = {0,0,0,0};             // For CCK
+    BYTE    abySignal[4] = {0,0,0,0};
+    WORD    awLen[4] = {0,0,0,0};
+    BYTE    abyTxRate[9] = {0,0,0,0,0,0,0,0,0}; // For OFDM
+    BYTE    abyRsvTime[9] = {0,0,0,0,0,0,0,0,0};
+    BYTE    abyData[34];
+    int     i;
+
+    //RSPINF_b_1
+    BBvCaculateParameter(pDevice,
+                         14,
+                         swGetCCKControlRate(pDevice, RATE_1M),
+                         PK_TYPE_11B,
+                         &awLen[0],
+                         &abyServ[0],
+                         &abySignal[0]
+    );
+
+    ///RSPINF_b_2
+    BBvCaculateParameter(pDevice,
+                         14,
+                         swGetCCKControlRate(pDevice, RATE_2M),
+                         PK_TYPE_11B,
+                         &awLen[1],
+                         &abyServ[1],
+                         &abySignal[1]
+    );
+
+    //RSPINF_b_5
+    BBvCaculateParameter(pDevice,
+                         14,
+                         swGetCCKControlRate(pDevice, RATE_5M),
+                         PK_TYPE_11B,
+                         &awLen[2],
+                         &abyServ[2],
+                         &abySignal[2]
+    );
+
+    //RSPINF_b_11
+    BBvCaculateParameter(pDevice,
+                         14,
+                         swGetCCKControlRate(pDevice, RATE_11M),
+                         PK_TYPE_11B,
+                         &awLen[3],
+                         &abyServ[3],
+                         &abySignal[3]
+    );
+
+    //RSPINF_a_6
+    CARDvCaculateOFDMRParameter (RATE_6M,
+                                 byBBType,
+                                 &abyTxRate[0],
+                                 &abyRsvTime[0]);
+
+    //RSPINF_a_9
+    CARDvCaculateOFDMRParameter (RATE_9M,
+                                 byBBType,
+                                 &abyTxRate[1],
+                                 &abyRsvTime[1]);
+
+    //RSPINF_a_12
+    CARDvCaculateOFDMRParameter (RATE_12M,
+                                 byBBType,
+                                 &abyTxRate[2],
+                                 &abyRsvTime[2]);
+
+    //RSPINF_a_18
+    CARDvCaculateOFDMRParameter (RATE_18M,
+                                 byBBType,
+                                 &abyTxRate[3],
+                                 &abyRsvTime[3]);
+
+    //RSPINF_a_24
+    CARDvCaculateOFDMRParameter (RATE_24M,
+                                 byBBType,
+                                 &abyTxRate[4],
+                                 &abyRsvTime[4]);
+
+    //RSPINF_a_36
+    CARDvCaculateOFDMRParameter (swGetOFDMControlRate(pDevice, RATE_36M),
+                                 byBBType,
+                                 &abyTxRate[5],
+                                 &abyRsvTime[5]);
+
+    //RSPINF_a_48
+    CARDvCaculateOFDMRParameter (swGetOFDMControlRate(pDevice, RATE_48M),
+                                 byBBType,
+                                 &abyTxRate[6],
+                                 &abyRsvTime[6]);
+
+    //RSPINF_a_54
+    CARDvCaculateOFDMRParameter (swGetOFDMControlRate(pDevice, RATE_54M),
+                                 byBBType,
+                                 &abyTxRate[7],
+                                 &abyRsvTime[7]);
+
+    //RSPINF_a_72
+    CARDvCaculateOFDMRParameter (swGetOFDMControlRate(pDevice, RATE_54M),
+                                 byBBType,
+                                 &abyTxRate[8],
+                                 &abyRsvTime[8]);
+
+    abyData[0] = (BYTE)(awLen[0]&0xFF);
+    abyData[1] = (BYTE)(awLen[0]>>8);
+    abyData[2] = abySignal[0];
+    abyData[3] = abyServ[0];
+
+    abyData[4] = (BYTE)(awLen[1]&0xFF);
+    abyData[5] = (BYTE)(awLen[1]>>8);
+    abyData[6] = abySignal[1];
+    abyData[7] = abyServ[1];
+
+    abyData[8] = (BYTE)(awLen[2]&0xFF);
+    abyData[9] = (BYTE)(awLen[2]>>8);
+    abyData[10] = abySignal[2];
+    abyData[11] = abyServ[2];
+
+    abyData[12] = (BYTE)(awLen[3]&0xFF);
+    abyData[13] = (BYTE)(awLen[3]>>8);
+    abyData[14] = abySignal[3];
+    abyData[15] = abyServ[3];
+
+    for(i=0;i<9;i++) {
+        abyData[16+i*2] = abyTxRate[i];
+        abyData[16+i*2+1] = abyRsvTime[i];
+    }
+
+
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_WRITE,
+                        MAC_REG_RSPINF_B_1,
+                        MESSAGE_REQUEST_MACREG,
+                        34,
+                        &abyData[0]);
+
+}
+
+/*
+ * Description: Update IFS
+ *
+ * Parameters:
+ *  In:
+ *      pDevice             - The adapter to be set
+ *  Out:
+ *      none
+ *
+ * Return Value: None.
+ *
+ */
+void vUpdateIFS (PVOID pDeviceHandler)
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+    //Set SIFS, DIFS, EIFS, SlotTime, CwMin
+    BYTE byMaxMin = 0;
+    BYTE byData[4];
+
+    if (pDevice->byPacketType==PK_TYPE_11A) {//0000 0000 0000 0000,11a
+        pDevice->uSlot = C_SLOT_SHORT;
+        pDevice->uSIFS = C_SIFS_A;
+        pDevice->uDIFS = C_SIFS_A + 2*C_SLOT_SHORT;
+        pDevice->uCwMin = C_CWMIN_A;
+        byMaxMin = 4;
+    }
+    else if (pDevice->byPacketType==PK_TYPE_11B) {//0000 0001 0000 0000,11b
+        pDevice->uSlot = C_SLOT_LONG;
+        pDevice->uSIFS = C_SIFS_BG;
+        pDevice->uDIFS = C_SIFS_BG + 2*C_SLOT_LONG;
+          pDevice->uCwMin = C_CWMIN_B;
+        byMaxMin = 5;
+    }
+    else {// PK_TYPE_11GA & PK_TYPE_11GB
+        BYTE byRate = 0;
+        BOOL bOFDMRate = FALSE;
+        UINT ii = 0;
+        PWLAN_IE_SUPP_RATES pItemRates = NULL;
+
+        pDevice->uSIFS = C_SIFS_BG;
+        if (pDevice->bShortSlotTime) {
+            pDevice->uSlot = C_SLOT_SHORT;
+        } else {
+            pDevice->uSlot = C_SLOT_LONG;
+        }
+        pDevice->uDIFS = C_SIFS_BG + 2*pDevice->uSlot;
+
+        pItemRates = (PWLAN_IE_SUPP_RATES)pDevice->sMgmtObj.abyCurrSuppRates;
+        for (ii = 0; ii < pItemRates->len; ii++) {
+            byRate = (BYTE)(pItemRates->abyRates[ii]&0x7F);
+            if (RATEwGetRateIdx(byRate) > RATE_11M) {
+                bOFDMRate = TRUE;
+                break;
+            }
+        }
+        if (bOFDMRate == FALSE) {
+            pItemRates = (PWLAN_IE_SUPP_RATES)pDevice->sMgmtObj.abyCurrExtSuppRates;
+            for (ii = 0; ii < pItemRates->len; ii++) {
+                byRate = (BYTE)(pItemRates->abyRates[ii]&0x7F);
+                if (RATEwGetRateIdx(byRate) > RATE_11M) {
+                    bOFDMRate = TRUE;
+                    break;
+                }
+            }
+        }
+        if (bOFDMRate == TRUE) {
+            pDevice->uCwMin = C_CWMIN_A;
+            byMaxMin = 4;
+        } else {
+            pDevice->uCwMin = C_CWMIN_B;
+            byMaxMin = 5;
+        }
+    }
+
+    pDevice->uCwMax = C_CWMAX;
+    pDevice->uEIFS = C_EIFS;
+
+    byData[0] = (BYTE)pDevice->uSIFS;
+    byData[1] = (BYTE)pDevice->uDIFS;
+    byData[2] = (BYTE)pDevice->uEIFS;
+    byData[3] = (BYTE)pDevice->uSlot;
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_WRITE,
+                        MAC_REG_SIFS,
+                        MESSAGE_REQUEST_MACREG,
+                        4,
+                        &byData[0]);
+
+    byMaxMin |= 0xA0;//1010 1111,C_CWMAX = 1023
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_WRITE,
+                        MAC_REG_CWMAXMIN0,
+                        MESSAGE_REQUEST_MACREG,
+                        1,
+                        &byMaxMin);
+}
+
+void CARDvUpdateBasicTopRate (PVOID pDeviceHandler)
+{
+PSDevice    pDevice = (PSDevice) pDeviceHandler;
+BYTE byTopOFDM = RATE_24M, byTopCCK = RATE_1M;
+BYTE ii;
+
+     //Determines the highest basic rate.
+     for (ii = RATE_54M; ii >= RATE_6M; ii --) {
+         if ( (pDevice->wBasicRate) & ((WORD)(1<<ii)) ) {
+             byTopOFDM = ii;
+             break;
+         }
+     }
+     pDevice->byTopOFDMBasicRate = byTopOFDM;
+
+     for (ii = RATE_11M;; ii --) {
+         if ( (pDevice->wBasicRate) & ((WORD)(1<<ii)) ) {
+             byTopCCK = ii;
+             break;
+         }
+         if (ii == RATE_1M)
+            break;
+     }
+     pDevice->byTopCCKBasicRate = byTopCCK;
+ }
+
+/*
+ * Description: Set NIC Tx Basic Rate
+ *
+ * Parameters:
+ *  In:
+ *      pDevice         - The adapter to be set
+ *      wBasicRate      - Basic Rate to be set
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if succeeded; FALSE if failed.
+ *
+ */
+BOOL CARDbAddBasicRate (PVOID pDeviceHandler, WORD wRateIdx)
+{
+PSDevice    pDevice = (PSDevice) pDeviceHandler;
+WORD wRate = (WORD)(1<<wRateIdx);
+
+    pDevice->wBasicRate |= wRate;
+
+    //Determines the highest basic rate.
+    CARDvUpdateBasicTopRate(pDevice);
+
+    return(TRUE);
+}
+
+BOOL CARDbIsOFDMinBasicRate (PVOID pDeviceHandler)
+{
+PSDevice    pDevice = (PSDevice) pDeviceHandler;
+int ii;
+
+    for (ii = RATE_54M; ii >= RATE_6M; ii --) {
+        if ((pDevice->wBasicRate) & ((WORD)(1<<ii)))
+            return TRUE;
+    }
+    return FALSE;
+}
+
+BYTE CARDbyGetPktType (PVOID pDeviceHandler)
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+
+    if (pDevice->byBBType == BB_TYPE_11A || pDevice->byBBType == BB_TYPE_11B) {
+        return (BYTE)pDevice->byBBType;
+    }
+    else if (CARDbIsOFDMinBasicRate(pDevice)) {
+        return PK_TYPE_11GA;
+    }
+    else {
+        return PK_TYPE_11GB;
+    }
+}
+
+
+/*
+ * Description: Caculate TSF offset of two TSF input
+ *              Get TSF Offset from RxBCN's TSF and local TSF
+ *
+ * Parameters:
+ *  In:
+ *      pDevice         - The adapter to be sync.
+ *      qwTSF1          - Rx BCN's TSF
+ *      qwTSF2          - Local TSF
+ *  Out:
+ *      none
+ *
+ * Return Value: TSF Offset value
+ *
+ */
+QWORD CARDqGetTSFOffset (BYTE byRxRate, QWORD qwTSF1, QWORD qwTSF2)
+{
+    QWORD   qwTSFOffset;
+    WORD    wRxBcnTSFOffst = 0;
+
+    HIDWORD(qwTSFOffset) = 0;
+    LODWORD(qwTSFOffset) = 0;
+
+    wRxBcnTSFOffst = cwRXBCNTSFOff[byRxRate%MAX_RATE];
+    (qwTSF2).u.dwLowDword += (DWORD)(wRxBcnTSFOffst);
+    if ((qwTSF2).u.dwLowDword < (DWORD)(wRxBcnTSFOffst)) {
+        (qwTSF2).u.dwHighDword++;
+    }
+    LODWORD(qwTSFOffset) = LODWORD(qwTSF1) - LODWORD(qwTSF2);
+    if (LODWORD(qwTSF1) < LODWORD(qwTSF2)) {
+        // if borrow needed
+        HIDWORD(qwTSFOffset) = HIDWORD(qwTSF1) - HIDWORD(qwTSF2) - 1 ;
+    }
+    else {
+        HIDWORD(qwTSFOffset) = HIDWORD(qwTSF1) - HIDWORD(qwTSF2);
+    };
+    return (qwTSFOffset);
+}
+
+
+
+/*
+ * Description: Sync. TSF counter to BSS
+ *              Get TSF offset and write to HW
+ *
+ * Parameters:
+ *  In:
+ *      pDevice         - The adapter to be sync.
+ *      qwBSSTimestamp  - Rx BCN's TSF
+ *      qwLocalTSF      - Local TSF
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void CARDvAdjustTSF (PVOID pDeviceHandler, BYTE byRxRate, QWORD qwBSSTimestamp, QWORD qwLocalTSF)
+{
+
+    PSDevice        pDevice = (PSDevice) pDeviceHandler;
+    QWORD           qwTSFOffset;
+    DWORD           dwTSFOffset1,dwTSFOffset2;
+    BYTE            pbyData[8];
+
+    HIDWORD(qwTSFOffset) = 0;
+    LODWORD(qwTSFOffset) = 0;
+
+    qwTSFOffset = CARDqGetTSFOffset(byRxRate, qwBSSTimestamp, qwLocalTSF);
+    // adjust TSF
+    // HW's TSF add TSF Offset reg
+    dwTSFOffset1 = LODWORD(qwTSFOffset);
+    dwTSFOffset2 = HIDWORD(qwTSFOffset);
+
+
+    pbyData[0] = (BYTE)dwTSFOffset1;
+    pbyData[1] = (BYTE)(dwTSFOffset1>>8);
+    pbyData[2] = (BYTE)(dwTSFOffset1>>16);
+    pbyData[3] = (BYTE)(dwTSFOffset1>>24);
+    pbyData[4] = (BYTE)dwTSFOffset2;
+    pbyData[5] = (BYTE)(dwTSFOffset2>>8);
+    pbyData[6] = (BYTE)(dwTSFOffset2>>16);
+    pbyData[7] = (BYTE)(dwTSFOffset2>>24);
+
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_SET_TSFTBTT,
+                        MESSAGE_REQUEST_TSF,
+                        0,
+                        8,
+                        pbyData
+                        );
+
+}
+/*
+ * Description: Read NIC TSF counter
+ *              Get local TSF counter
+ *
+ * Parameters:
+ *  In:
+ *      pDevice         - The adapter to be read
+ *  Out:
+ *      qwCurrTSF       - Current TSF counter
+ *
+ * Return Value: TRUE if success; otherwise FALSE
+ *
+ */
+BOOL CARDbGetCurrentTSF (PVOID pDeviceHandler, PQWORD pqwCurrTSF)
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+
+    LODWORD(*pqwCurrTSF) = LODWORD(pDevice->qwCurrTSF);
+    HIDWORD(*pqwCurrTSF) = HIDWORD(pDevice->qwCurrTSF);
+
+    return(TRUE);
+}
+
+
+/*
+ * Description: Clear NIC TSF counter
+ *              Clear local TSF counter
+ *
+ * Parameters:
+ *  In:
+ *      pDevice         - The adapter to be read
+ *
+ * Return Value: TRUE if success; otherwise FALSE
+ *
+ */
+BOOL CARDbClearCurrentTSF(PVOID pDeviceHandler)
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+
+    MACvRegBitsOn(pDevice,MAC_REG_TFTCTL,TFTCTL_TSFCNTRST);
+
+    LODWORD(pDevice->qwCurrTSF) = 0;
+    HIDWORD(pDevice->qwCurrTSF) = 0;
+
+    return(TRUE);
+}
+
+/*
+ * Description: Read NIC TSF counter
+ *              Get NEXTTBTT from adjusted TSF and Beacon Interval
+ *
+ * Parameters:
+ *  In:
+ *      qwTSF           - Current TSF counter
+ *      wbeaconInterval - Beacon Interval
+ *  Out:
+ *      qwCurrTSF       - Current TSF counter
+ *
+ * Return Value: TSF value of next Beacon
+ *
+ */
+QWORD CARDqGetNextTBTT (QWORD qwTSF, WORD wBeaconInterval)
+{
+
+    UINT    uLowNextTBTT;
+    UINT    uHighRemain, uLowRemain;
+    UINT    uBeaconInterval;
+
+    uBeaconInterval = wBeaconInterval * 1024;
+    // Next TBTT = ((local_current_TSF / beacon_interval) + 1 ) * beacon_interval
+    uLowNextTBTT = (LODWORD(qwTSF) >> 10) << 10;
+    uLowRemain = (uLowNextTBTT) % uBeaconInterval;
+    uHighRemain = ((0x80000000 % uBeaconInterval)* 2 * HIDWORD(qwTSF))
+                  % uBeaconInterval;
+    uLowRemain = (uHighRemain + uLowRemain) % uBeaconInterval;
+    uLowRemain = uBeaconInterval - uLowRemain;
+
+    // check if carry when add one beacon interval
+    if ((~uLowNextTBTT) < uLowRemain)
+        HIDWORD(qwTSF) ++ ;
+
+    LODWORD(qwTSF) = uLowNextTBTT + uLowRemain;
+
+    return (qwTSF);
+}
+
+
+/*
+ * Description: Set NIC TSF counter for first Beacon time
+ *              Get NEXTTBTT from adjusted TSF and Beacon Interval
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase        - IO Base
+ *      wBeaconInterval - Beacon Interval
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void CARDvSetFirstNextTBTT (PVOID pDeviceHandler, WORD wBeaconInterval)
+{
+
+    PSDevice        pDevice = (PSDevice) pDeviceHandler;
+    QWORD           qwNextTBTT;
+    DWORD           dwLoTBTT,dwHiTBTT;
+    BYTE            pbyData[8];
+
+    HIDWORD(qwNextTBTT) = 0;
+    LODWORD(qwNextTBTT) = 0;
+    CARDbClearCurrentTSF(pDevice);
+    //CARDbGetCurrentTSF(pDevice, &qwNextTBTT); //Get Local TSF counter
+    qwNextTBTT = CARDqGetNextTBTT(qwNextTBTT, wBeaconInterval);
+    // Set NextTBTT
+
+    dwLoTBTT = LODWORD(qwNextTBTT);
+    dwHiTBTT = HIDWORD(qwNextTBTT);
+
+    pbyData[0] = (BYTE)dwLoTBTT;
+    pbyData[1] = (BYTE)(dwLoTBTT>>8);
+    pbyData[2] = (BYTE)(dwLoTBTT>>16);
+    pbyData[3] = (BYTE)(dwLoTBTT>>24);
+    pbyData[4] = (BYTE)dwHiTBTT;
+    pbyData[5] = (BYTE)(dwHiTBTT>>8);
+    pbyData[6] = (BYTE)(dwHiTBTT>>16);
+    pbyData[7] = (BYTE)(dwHiTBTT>>24);
+
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_SET_TSFTBTT,
+                        MESSAGE_REQUEST_TBTT,
+                        0,
+                        8,
+                        pbyData
+                        );
+
+    return;
+}
+
+
+/*
+ * Description: Sync NIC TSF counter for Beacon time
+ *              Get NEXTTBTT and write to HW
+ *
+ * Parameters:
+ *  In:
+ *      pDevice         - The adapter to be set
+ *      qwTSF           - Current TSF counter
+ *      wBeaconInterval - Beacon Interval
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void CARDvUpdateNextTBTT (PVOID pDeviceHandler, QWORD qwTSF, WORD wBeaconInterval)
+{
+    PSDevice        pDevice = (PSDevice) pDeviceHandler;
+    DWORD           dwLoTBTT,dwHiTBTT;
+    BYTE            pbyData[8];
+
+    qwTSF = CARDqGetNextTBTT(qwTSF, wBeaconInterval);
+
+    // Set NextTBTT
+    dwLoTBTT = LODWORD(qwTSF);
+    dwHiTBTT = HIDWORD(qwTSF);
+
+    pbyData[0] = (BYTE)dwLoTBTT;
+    pbyData[1] = (BYTE)(dwLoTBTT>>8);
+    pbyData[2] = (BYTE)(dwLoTBTT>>16);
+    pbyData[3] = (BYTE)(dwLoTBTT>>24);
+    pbyData[4] = (BYTE)dwHiTBTT;
+    pbyData[5] = (BYTE)(dwHiTBTT>>8);
+    pbyData[6] = (BYTE)(dwHiTBTT>>16);
+    pbyData[7] = (BYTE)(dwHiTBTT>>24);
+
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_SET_TSFTBTT,
+                        MESSAGE_REQUEST_TBTT,
+                        0,
+                        8,
+                        pbyData
+                        );
+
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Card:Update Next TBTT[%8xh:%8xh] \n",(int)HIDWORD(qwTSF), (int)LODWORD(qwTSF));
+
+    return;
+}
+
+/*
+ * Description: Turn off Radio power
+ *
+ * Parameters:
+ *  In:
+ *      pDevice         - The adapter to be turned off
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if success; otherwise FALSE
+ *
+ */
+BOOL CARDbRadioPowerOff (PVOID pDeviceHandler)
+{
+PSDevice    pDevice = (PSDevice) pDeviceHandler;
+BOOL bResult = TRUE;
+
+    //if (pDevice->bRadioOff == TRUE)
+    //    return TRUE;
+
+    pDevice->bRadioOff = TRUE;
+
+    switch (pDevice->byRFType) {
+        case RF_AL2230:
+        case RF_AL2230S:
+        case RF_AIROHA7230:
+        case RF_VT3226:     //RobertYu:20051111
+        case RF_VT3226D0:
+        case RF_VT3342A0:   //RobertYu:20060609
+            MACvRegBitsOff(pDevice, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPE2 | SOFTPWRCTL_SWPE3));
+            break;
+    }
+
+    MACvRegBitsOff(pDevice, MAC_REG_HOSTCR, HOSTCR_RXON);
+
+    BBvSetDeepSleep(pDevice);
+
+    return bResult;
+}
+
+
+/*
+ * Description: Turn on Radio power
+ *
+ * Parameters:
+ *  In:
+ *      pDevice         - The adapter to be turned on
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if success; otherwise FALSE
+ *
+ */
+BOOL CARDbRadioPowerOn (PVOID pDeviceHandler)
+{
+PSDevice    pDevice = (PSDevice) pDeviceHandler;
+BOOL bResult = TRUE;
+
+
+    if ((pDevice->bHWRadioOff == TRUE) || (pDevice->bRadioControlOff == TRUE)) {
+        return FALSE;
+    }
+
+    //if (pDevice->bRadioOff == FALSE)
+    //    return TRUE;
+
+    pDevice->bRadioOff = FALSE;
+
+    BBvExitDeepSleep(pDevice);
+
+    MACvRegBitsOn(pDevice, MAC_REG_HOSTCR, HOSTCR_RXON);
+
+    switch (pDevice->byRFType) {
+        case RF_AL2230:
+        case RF_AL2230S:
+        case RF_AIROHA7230:
+        case RF_VT3226:     //RobertYu:20051111
+        case RF_VT3226D0:
+        case RF_VT3342A0:   //RobertYu:20060609
+            MACvRegBitsOn(pDevice, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPE2 | SOFTPWRCTL_SWPE3));
+            break;
+    }
+
+    return bResult;
+}
+
+void CARDvSetBSSMode (PVOID pDeviceHandler)
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+    // Set BB and packet type at the same time.//{{RobertYu:20050222, AL7230 have two TX PA output, only connet to b/g now
+    // so in 11a mode need to set the MAC Reg0x4C to 11b/g mode to turn on PA
+    if( (pDevice->byRFType == RF_AIROHA7230 ) && (pDevice->byBBType == BB_TYPE_11A) )
+    {
+        MACvSetBBType(pDevice, BB_TYPE_11G);
+    }
+    else
+    {
+        MACvSetBBType(pDevice, pDevice->byBBType);
+    }
+    pDevice->byPacketType = CARDbyGetPktType(pDevice);
+
+    if (pDevice->byBBType == BB_TYPE_11A) {
+        ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x88, 0x03);
+    } else if (pDevice->byBBType == BB_TYPE_11B) {
+        ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x88, 0x02);
+    } else if (pDevice->byBBType == BB_TYPE_11G) {
+        ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x88, 0x08);
+    }
+
+    vUpdateIFS(pDevice);
+    CARDvSetRSPINF(pDevice, (BYTE)pDevice->byBBType);
+
+    if ( pDevice->byBBType == BB_TYPE_11A ) {
+        //request by Jack 2005-04-26
+        if (pDevice->byRFType == RF_AIROHA7230) {
+            pDevice->abyBBVGA[0] = 0x20;
+            ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xE7, pDevice->abyBBVGA[0]);
+        }
+        pDevice->abyBBVGA[2] = 0x10;
+        pDevice->abyBBVGA[3] = 0x10;
+    } else {
+        //request by Jack 2005-04-26
+        if (pDevice->byRFType == RF_AIROHA7230) {
+            pDevice->abyBBVGA[0] = 0x1C;
+            ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xE7, pDevice->abyBBVGA[0]);
+        }
+        pDevice->abyBBVGA[2] = 0x0;
+        pDevice->abyBBVGA[3] = 0x0;
+    }
+}
+
+/*
+ *
+ * Description:
+ *    Do Channel Switch defined in 802.11h
+ *
+ * Parameters:
+ *  In:
+ *      hDeviceContext - device structure point
+ *  Out:
+ *      none
+ *
+ * Return Value: none.
+ *
+-*/
+BOOL
+CARDbChannelSwitch (
+    IN PVOID            pDeviceHandler,
+    IN BYTE             byMode,
+    IN BYTE             byNewChannel,
+    IN BYTE             byCount
+    )
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+    BOOL        bResult = TRUE;
+
+    if (byCount == 0) {
+        pDevice->sMgmtObj.uCurrChannel = byNewChannel;
+        bResult = CARDbSetMediaChannel(pDevice, byNewChannel);
+
+        return(bResult);
+    }
+    pDevice->byChannelSwitchCount = byCount;
+    pDevice->byNewChannel = byNewChannel;
+    pDevice->bChannelSwitch = TRUE;
+
+    if (byMode == 1) {
+        //bResult=CARDbStopTxPacket(pDevice, PKT_TYPE_802_11_ALL);
+        pDevice->bStopDataPkt = TRUE;
+    }
+    return (bResult);
+}
+
+
+
+
+
+
diff --git a/drivers/staging/vt6656/card.h b/drivers/staging/vt6656/card.h
new file mode 100644
index 0000000..6d623be
--- /dev/null
+++ b/drivers/staging/vt6656/card.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: card.h
+ *
+ * Purpose: Provide functions to setup NIC operation mode
+ *
+ * Author: Tevin Chen
+ *
+ * Date: May 21, 1996
+ *
+ */
+
+
+#ifndef __CARD_H__
+#define __CARD_H__
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+
+
+/*---------------------  Export Definitions -------------------------*/
+
+
+/*---------------------  Export Classes  ----------------------------*/
+
+// Init card type
+
+typedef enum _CARD_PHY_TYPE {
+
+    PHY_TYPE_AUTO=0,
+    PHY_TYPE_11B,
+    PHY_TYPE_11G,
+    PHY_TYPE_11A
+} CARD_PHY_TYPE, DEF* PCARD_PHY_TYPE;
+
+typedef enum _CARD_OP_MODE {
+
+    OP_MODE_INFRASTRUCTURE=0,
+    OP_MODE_ADHOC,
+    OP_MODE_AP,
+    OP_MODE_UNKNOWN
+} CARD_OP_MODE, *PCARD_OP_MODE;
+
+#define CB_MAX_CHANNEL_24G  14
+//#define CB_MAX_CHANNEL_5G   24
+#define CB_MAX_CHANNEL_5G       42 //[20050104] add channel9(5045MHz), 41==>42
+#define CB_MAX_CHANNEL      (CB_MAX_CHANNEL_24G+CB_MAX_CHANNEL_5G)
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+#ifdef __cplusplus
+extern "C" {                            /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+
+BOOL CARDbSetMediaChannel(PVOID pDeviceHandler, UINT uConnectionChannel);
+void CARDvSetRSPINF(PVOID pDeviceHandler, BYTE byBBType);
+void vUpdateIFS(PVOID pDeviceHandler);
+void CARDvUpdateBasicTopRate(PVOID pDeviceHandler);
+BOOL CARDbAddBasicRate(PVOID pDeviceHandler, WORD wRateIdx);
+BOOL CARDbIsOFDMinBasicRate(PVOID pDeviceHandler);
+void CARDvAdjustTSF(PVOID pDeviceHandler, BYTE byRxRate, QWORD qwBSSTimestamp, QWORD qwLocalTSF);
+BOOL CARDbGetCurrentTSF (PVOID pDeviceHandler, PQWORD pqwCurrTSF);
+BOOL CARDbClearCurrentTSF(PVOID pDeviceHandler);
+void CARDvSetFirstNextTBTT(PVOID pDeviceHandler, WORD wBeaconInterval);
+void CARDvUpdateNextTBTT(PVOID pDeviceHandler, QWORD qwTSF, WORD wBeaconInterval);
+QWORD CARDqGetNextTBTT(QWORD qwTSF, WORD wBeaconInterval);
+QWORD CARDqGetTSFOffset(BYTE byRxRate, QWORD qwTSF1, QWORD qwTSF2);
+BOOL CARDbRadioPowerOff(PVOID pDeviceHandler);
+BOOL CARDbRadioPowerOn(PVOID pDeviceHandler);
+BYTE CARDbyGetPktType(PVOID pDeviceHandler);
+void CARDvSetBSSMode(PVOID pDeviceHandler);
+
+BOOL
+CARDbChannelSwitch (
+    IN PVOID            pDeviceHandler,
+    IN BYTE             byMode,
+    IN BYTE             byNewChannel,
+    IN BYTE             byCount
+    );
+
+
+#ifdef __cplusplus
+}                                       /* End of extern "C" { */
+#endif /* __cplusplus */
+
+
+#endif // __CARD_H__
+
+
+
diff --git a/drivers/staging/vt6656/channel.c b/drivers/staging/vt6656/channel.c
new file mode 100644
index 0000000..56308b0
--- /dev/null
+++ b/drivers/staging/vt6656/channel.c
@@ -0,0 +1,535 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: channel.c
+ *
+ * Purpose: Channel number maping
+ *
+ * Author: Lucas Lin
+ *
+ * Date: Dec 24, 2004
+ *
+ *
+ *
+ * Revision History:
+ *      01-18-2005      RobertYu:  remove the for loop searching in ChannelValid,
+ *                                 change ChannelRuleTab to lookup-type, reorder table items.
+ *
+ *
+ */
+
+#if !defined (_COUNTRY_H_)
+#include "country.h"
+#endif
+#if !defined (_CHANNEL_H_)
+#include "channel.h"
+#endif
+#if !defined(__RF_H__)
+#include "rf.h"
+#endif
+#if !defined(__UMEM_H__)
+#include "umem.h"
+#endif
+
+
+/*---------------------  Static Definitions -------------------------*/
+static int          msglevel                =MSG_LEVEL_INFO;
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Export Definitions -------------------------*/
+
+
+static SChannelTblElement sChannelTbl[CB_MAX_CHANNEL+1] =
+{
+  {0,   0,    FALSE},
+  {1,   2412, TRUE},
+  {2,   2417, TRUE},
+  {3,   2422, TRUE},
+  {4,   2427, TRUE},
+  {5,   2432, TRUE},
+  {6,   2437, TRUE},
+  {7,   2442, TRUE},
+  {8,   2447, TRUE},
+  {9,   2452, TRUE},
+  {10,  2457, TRUE},
+  {11,  2462, TRUE},
+  {12,  2467, TRUE},
+  {13,  2472, TRUE},
+  {14,  2484, TRUE},
+  {183, 4915, TRUE}, //15
+  {184, 4920, TRUE}, //16
+  {185, 4925, TRUE}, //17
+  {187, 4935, TRUE}, //18
+  {188, 4940, TRUE}, //19
+  {189, 4945, TRUE}, //20
+  {192, 4960, TRUE}, //21
+  {196, 4980, TRUE}, //22
+  {7,   5035, TRUE}, //23
+  {8,   5040, TRUE}, //24
+  {9,   5045, TRUE}, //25
+  {11,  5055, TRUE}, //26
+  {12,  5060, TRUE}, //27
+  {16,  5080, TRUE}, //28
+  {34,  5170, TRUE}, //29
+  {36,  5180, TRUE}, //30
+  {38,  5190, TRUE}, //31
+  {40,  5200, TRUE}, //32
+  {42,  5210, TRUE}, //33
+  {44,  5220, TRUE}, //34
+  {46,  5230, TRUE}, //35
+  {48,  5240, TRUE}, //36
+  {52,  5260, TRUE}, //37
+  {56,  5280, TRUE}, //38
+  {60,  5300, TRUE}, //39
+  {64,  5320, TRUE}, //40
+  {100, 5500, TRUE}, //41
+  {104, 5520, TRUE}, //42
+  {108, 5540, TRUE}, //43
+  {112, 5560, TRUE}, //44
+  {116, 5580, TRUE}, //45
+  {120, 5600, TRUE}, //46
+  {124, 5620, TRUE}, //47
+  {128, 5640, TRUE}, //48
+  {132, 5660, TRUE}, //49
+  {136, 5680, TRUE}, //50
+  {140, 5700, TRUE}, //51
+  {149, 5745, TRUE}, //52
+  {153, 5765, TRUE}, //53
+  {157, 5785, TRUE}, //54
+  {161, 5805, TRUE}, //55
+  {165, 5825, TRUE}  //56
+};
+
+
+
+/************************************************************************
+ * The Radar regulation rules for each country
+ ************************************************************************/
+static  struct
+{
+    BYTE    byChannelCountryCode;             /* The country code         */
+    CHAR    chCountryCode[2];
+    BYTE    bChannelIdxList[CB_MAX_CHANNEL];  /* Available channels Index */
+    BYTE    byPower[CB_MAX_CHANNEL];
+}   ChannelRuleTab[] =
+{
+/************************************************************************
+ * This table is based on Athero driver rules
+ ************************************************************************/
+/* Country          Available channels, ended with 0                    */
+/*                                           1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51  52  53  54  55  56  */
+{CCODE_FCC,                     {'U','S'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                      ,  {  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17,  0, 17,  0, 17,  0, 17, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_TELEC,                   {'J','P'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  1,  0,  0,  1,  0,  1,  1,  0,  1,  0,  0,  1,  1,  1,  0,  1,  0,  1,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0, 23,  0,  0, 23,  0, 23, 23,  0, 23,  0,  0, 23, 23, 23,  0, 23,  0, 23,  0, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_ETSI,                    {'E','U'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_RESV3,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_RESV4,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_RESV5,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_RESV6,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_RESV7,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_RESV8,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_RESV9,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_RESVa,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_RESVb,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_RESVc,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_RESVd,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_RESVe,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_ALLBAND,                 {' ',' '},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_ALBANIA,                 {'A','L'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_ALGERIA,                 {'D','Z'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_ARGENTINA,               {'A','R'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17, 17, 17,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30,  0}  },
+{CCODE_ARMENIA,                 {'A','M'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 18,  0, 18,  0, 18,  0, 18, 18, 18, 18, 18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_AUSTRALIA,               {'A','U'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23,  0, 23,  0, 23,  0, 23, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_AUSTRIA,                 {'A','T'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 15,  0, 15,  0, 15,  0, 15,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_AZERBAIJAN,              {'A','Z'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 18,  0, 18,  0, 18,  0, 18, 18, 18, 18, 18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_BAHRAIN,                 {'B','H'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_BELARUS,                 {'B','Y'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_BELGIUM,                 {'B','E'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 18,  0, 18,  0, 18,  0, 18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_BELIZE,                  {'B','Z'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                      ,  {  30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_BOLIVIA,                 {'B','O'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                      ,  {  30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_BRAZIL,                  {'B','R'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_BRUNEI_DARUSSALAM,       {'B','N'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_BULGARIA,                {'B','G'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  0,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23,  0, 23,  0, 23,  0, 23, 23, 23,  0,  0, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,  0,  0,  0,  0,  0}  },
+{CCODE_CANADA,                  {'C','A'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                      ,  {  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17,  0, 17,  0, 17,  0, 17, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_CHILE,                   {'C','L'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17, 17, 17, 17, 17}  },
+{CCODE_CHINA,                   {'C','N'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_COLOMBIA,                {'C','O'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                      ,  {  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17,  0, 17,  0, 17,  0, 17, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_COSTA_RICA,              {'C','R'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_CROATIA,                 {'H','R'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_CYPRUS,                  {'C','Y'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_CZECH,                   {'C','Z'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_DENMARK,                 {'D','K'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_DOMINICAN_REPUBLIC,      {'D','O'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                      ,  {  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17,  0, 17,  0, 17,  0, 17, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_ECUADOR,                 {'E','C'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_EGYPT,                   {'E','G'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_EL_SALVADOR,             {'S','V'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_ESTONIA,                 {'E','E'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_FINLAND,                 {'F','I'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_FRANCE,                  {'F','R'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_GERMANY,                 {'D','E'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_GREECE,                  {'G','R'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_GEORGIA,                 {'G','E'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 18,  0, 18,  0, 18,  0, 18, 18, 18, 18, 18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_GUATEMALA,               {'G','T'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                      ,  {  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17,  0, 17,  0, 17,  0, 17, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_HONDURAS,                {'H','N'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_HONG_KONG,               {'H','K'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23,  0, 23,  0, 23,  0, 23, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_HUNGARY,                 {'H','U'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 18,  0, 18,  0, 18,  0, 18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_ICELAND,                 {'I','S'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_INDIA,                   {'I','N'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_INDONESIA,               {'I','D'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_IRAN,                    {'I','R'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_IRELAND,                 {'I','E'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_ITALY,                   {'I','T'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_ISRAEL,                  {'I','L'},  {   0,  0,  0,  0,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_JAPAN,                   {'J','P'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23,  0, 23,  0, 23,  0, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_JORDAN,                  {'J','O'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_KAZAKHSTAN,              {'K','Z'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_KUWAIT,                  {'K','W'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_LATVIA,                  {'L','V'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_LEBANON,                 {'L','B'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_LEICHTENSTEIN,           {'L','I'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 18,  0, 18,  0, 18,  0, 18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_LITHUANIA,               {'L','T'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_LUXEMBURG,               {'L','U'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_MACAU,                   {'M','O'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23,  0, 23,  0, 23,  0, 23, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_MACEDONIA,               {'M','K'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_MALTA,                   {'M','T'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0}
+                                      ,  {  23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 16,  0, 16,  0, 16,  0, 16, 16, 16, 16, 16,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 16, 16, 16, 16,  0}  },
+{CCODE_MALAYSIA,                {'M','Y'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_MEXICO,                  {'M','X'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                      ,  {  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17,  0, 17,  0, 17,  0, 17, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_MONACO,                  {'M','C'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 18,  0, 18,  0, 18,  0, 18, 18, 18, 18, 18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_MOROCCO,                 {'M','A'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_NETHERLANDS,             {'N','L'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_NEW_ZEALAND,             {'N','Z'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                      ,  {  30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23,  0, 23,  0, 23,  0, 23, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_NORTH_KOREA,             {'K','P'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23, 23, 23, 23,  0}  },
+{CCODE_NORWAY,                  {'N','O'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_OMAN,                    {'O','M'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_PAKISTAN,                {'P','K'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_PANAMA,                  {'P','A'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                      ,  {  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17,  0, 17,  0, 17,  0, 17, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_PERU,                    {'P','E'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_PHILIPPINES,             {'P','H'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17,  0, 17,  0, 17,  0, 17, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_POLAND,                  {'P','L'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_PORTUGAL,                {'P','T'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_PUERTO_RICO,             {'P','R'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                      ,  {  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17,  0, 17,  0, 17,  0, 17, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_QATAR,                   {'Q','A'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_ROMANIA,                 {'R','O'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_RUSSIA,                  {'R','U'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_SAUDI_ARABIA,            {'S','A'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_SINGAPORE,               {'S','G'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20, 20, 20, 20, 20}  },
+{CCODE_SLOVAKIA,                {'S','K'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0}
+                                      ,  {  23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 16,  0, 16,  0, 16,  0, 16, 16, 16, 16, 16,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 16, 16, 16, 16,  0}  },
+{CCODE_SLOVENIA,                {'S','I'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_SOUTH_AFRICA,            {'Z','A'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_SOUTH_KOREA,             {'K','R'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23, 23, 23, 23,  0}  },
+{CCODE_SPAIN,                   {'E','S'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0}
+                                      ,  {  23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 16,  0, 16,  0, 16,  0, 16, 16, 16, 16, 16,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 16, 16, 16, 16,  0}  },
+{CCODE_SWEDEN,                  {'S','E'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_SWITZERLAND,             {'C','H'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 18,  0, 18,  0, 18,  0, 18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_SYRIA,                   {'S','Y'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_TAIWAN,                  {'T','W'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17, 17, 17,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30,  0}  },
+{CCODE_THAILAND,                {'T','H'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23, 23, 23, 23,  0}  },
+{CCODE_TRINIDAD_TOBAGO,         {'T','T'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 18,  0, 18,  0, 18,  0, 18, 18, 18, 18, 18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_TUNISIA,                 {'T','N'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_TURKEY,                  {'T','R'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_UK,                      {'G','B'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_UKRAINE,                 {'U','A'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_UNITED_ARAB_EMIRATES,    {'A','E'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_UNITED_STATES,           {'U','S'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                      ,  {  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17,  0, 17,  0, 17,  0, 17, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_URUGUAY,                 {'U','Y'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23, 23, 23, 23,  0}  },
+{CCODE_UZBEKISTAN,              {'U','Z'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_VENEZUELA,               {'V','E'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23, 23, 23, 23,  0}  },
+{CCODE_VIETNAM,                 {'V','N'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_YEMEN,                   {'Y','E'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_ZIMBABWE,                {'Z','W'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_JAPAN_W52_W53,           {'J','J'},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_MAX,                     {'U','N'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  }
+/*                                           1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51  52  53  54  55  56  */
+};
+
+#define NUM_RULES	(sizeof(ChannelRuleTab) / sizeof(ChannelRuleTab[0]))
+
+/*---------------------  Export function  -------------------------*/
+/************************************************************************
+ * Country Channel Valid
+ *  Input:  CountryCode, ChannelNum
+ *          ChanneIndex is defined as VT3253 MAC channel:
+ *              1   = 2.4G channel 1
+ *              2   = 2.4G channel 2
+ *              ...
+ *              14  = 2.4G channel 14
+ *              15  = 4.9G channel 183
+ *              16  = 4.9G channel 184
+ *              .....
+ *  Output: TRUE if the specified 5GHz band is allowed to be used.
+            False otherwise.
+// 4.9G => Ch 183, 184, 185, 187, 188, 189, 192, 196 (Value:15 ~ 22)
+
+// 5G => Ch 7, 8, 9, 11, 12, 16, 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64,
+// 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165 (Value 23 ~ 56)
+ ************************************************************************/
+BOOL
+ChannelValid(UINT CountryCode, UINT ChannelIndex)
+{
+    BOOL    bValid;
+
+    bValid = FALSE;
+    /*
+     * If Channel Index is invalid, return invalid
+     */
+    if ((ChannelIndex > CB_MAX_CHANNEL) ||
+        (ChannelIndex == 0))
+    {
+        bValid = FALSE;
+        goto exit;
+    }
+
+    bValid = sChannelTbl[ChannelIndex].bValid;
+
+exit:
+    return (bValid);
+
+} /* end ChannelValid */
+
+/************************************************************************
+ * CHvChannelGetList
+ * Get Available Channel List for a given country
+ * Input:
+ *      CountryCode     =   The country code defined in country.h
+ * Output:
+ *      ChannelBitMask  =   (QWORD *) correspondent bit mask
+ *                          of available channels
+ *                          0x0000000000000001 means channel 1 is supported
+ *                          0x0000000000000003 means channel 1,2 are supported
+ *                          0x000000000000000F means channel 1,2,..15 are supported
+ ************************************************************************/
+BOOL
+CHvChannelGetList (
+    IN  UINT       uCountryCodeIdx,
+    OUT PBYTE      pbyChannelTable
+    )
+{
+    if (uCountryCodeIdx >= CCODE_MAX) {
+        return (FALSE);
+    }
+    MEMvCopy(pbyChannelTable, ChannelRuleTab[uCountryCodeIdx].bChannelIdxList, CB_MAX_CHANNEL);
+    return (TRUE);
+}
+
+
+VOID CHvInitChannelTable (PVOID pDeviceHandler)
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+    BOOL        bMultiBand = FALSE;
+    UINT        ii;
+
+    for(ii=1;ii<=CB_MAX_CHANNEL;ii++) {
+        sChannelTbl[ii].bValid = FALSE;
+    }
+
+    switch (pDevice->byRFType) {
+        case RF_AL2230:
+        case RF_AL2230S:
+        case RF_VT3226:
+        case RF_VT3226D0:
+            bMultiBand = FALSE;
+            break;
+        case RF_AIROHA7230:
+        case RF_VT3342A0:
+        default :
+            bMultiBand = TRUE;
+            break;
+    }
+
+    if ((pDevice->dwDiagRefCount != 0) ||
+        (pDevice->b11hEable == TRUE)) {
+        if (bMultiBand == TRUE) {
+            for(ii=0;ii<CB_MAX_CHANNEL;ii++) {
+                sChannelTbl[ii+1].bValid = TRUE;
+                //pDevice->abyRegPwr[ii+1] = pDevice->abyOFDMDefaultPwr[ii+1];
+                //pDevice->abyLocalPwr[ii+1] = pDevice->abyOFDMDefaultPwr[ii+1];
+            }
+            for(ii=0;ii<CB_MAX_CHANNEL_24G;ii++) {
+                //pDevice->abyRegPwr[ii+1] = pDevice->abyCCKDefaultPwr[ii+1];
+                //pDevice->abyLocalPwr[ii+1] = pDevice->abyCCKDefaultPwr[ii+1];
+            }
+        } else {
+            for(ii=0;ii<CB_MAX_CHANNEL_24G;ii++) {
+                sChannelTbl[ii+1].bValid = TRUE;
+                //pDevice->abyRegPwr[ii+1] = pDevice->abyCCKDefaultPwr[ii+1];
+                //pDevice->abyLocalPwr[ii+1] = pDevice->abyCCKDefaultPwr[ii+1];
+            }
+        }
+    } else if (pDevice->byZoneType <= CCODE_MAX) {
+        if (bMultiBand == TRUE) {
+            for(ii=0;ii<CB_MAX_CHANNEL;ii++) {
+                if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] != 0) {
+                    sChannelTbl[ii+1].bValid = TRUE;
+                    //pDevice->abyRegPwr[ii+1] = ChannelRuleTab[pDevice->byZoneType].byPower[ii];
+                    //pDevice->abyLocalPwr[ii+1] = ChannelRuleTab[pDevice->byZoneType].byPower[ii];
+                }
+            }
+        } else {
+            for(ii=0;ii<CB_MAX_CHANNEL_24G;ii++) {
+                if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] != 0) {
+                    sChannelTbl[ii+1].bValid = TRUE;
+                    //pDevice->abyRegPwr[ii+1] = ChannelRuleTab[pDevice->byZoneType].byPower[ii];
+                    //pDevice->abyLocalPwr[ii+1] = ChannelRuleTab[pDevice->byZoneType].byPower[ii];
+                }
+            }
+        }
+    }
+    DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO"Zone=[%d][%c][%c]!!\n",pDevice->byZoneType,ChannelRuleTab[pDevice->byZoneType].chCountryCode[0],ChannelRuleTab[pDevice->byZoneType].chCountryCode[1]);
+    for(ii=0;ii<CB_MAX_CHANNEL;ii++) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Channel[%d] is [%d]\n",sChannelTbl[ii].byChannelNumber,sChannelTbl[ii+1].bValid);
+        /*if (pDevice->abyRegPwr[ii+1] == 0) {
+            pDevice->abyRegPwr[ii+1] = pDevice->abyOFDMDefaultPwr[ii+1];
+        }
+        if (pDevice->abyLocalPwr[ii+1] == 0) {
+            pDevice->abyLocalPwr[ii+1] = pDevice->abyOFDMDefaultPwr[ii+1];
+        }*/
+    }
+}
+
+BYTE CHbyGetChannelMapping(BYTE byChannelNumber)
+{
+BYTE    ii;
+BYTE    byCHMapping = 0;
+
+    for (ii=1; ii<=CB_MAX_CHANNEL; ii++ ) {
+        if ( sChannelTbl[ii].byChannelNumber == byChannelNumber ) {
+            byCHMapping = ii;
+        }
+    }
+    return byCHMapping;
+}
diff --git a/drivers/staging/vt6656/channel.h b/drivers/staging/vt6656/channel.h
new file mode 100644
index 0000000..29b6ec5
--- /dev/null
+++ b/drivers/staging/vt6656/channel.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: channel.h
+ *
+ * Purpose: Country Regulation Rules header file
+ *
+ * Author: Lucas Lin
+ *
+ * Date: Dec 23, 2004
+ *
+ */
+
+#ifndef _CHANNEL_H_
+#define _CHANNEL_H_
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+
+/*---------------------  Export Definitions -------------------------*/
+
+/*---------------------  Export Classes  ----------------------------*/
+typedef struct tagSChannelTblElement {
+    BYTE    byChannelNumber;
+    UINT    uFrequency;
+    BOOL    bValid;
+}SChannelTblElement, DEF* PSChannelTblElement;
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+BOOL    ChannelValid(UINT CountryCode, UINT ChannelNum);
+VOID    CHvInitChannelTable (PVOID pDeviceHandler);
+BYTE    CHbyGetChannelMapping(BYTE byChannelNumber);
+
+BOOL
+CHvChannelGetList (
+    IN  UINT       uCountryCodeIdx,
+    OUT PBYTE      pbyChannelTable
+    );
+#endif  /* _REGULATE_H_ */
diff --git a/drivers/staging/vt6656/control.c b/drivers/staging/vt6656/control.c
new file mode 100644
index 0000000..ee54125
--- /dev/null
+++ b/drivers/staging/vt6656/control.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: control.c
+ *
+ * Purpose: Handle USB control endpoint
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Apr. 5, 2004
+ *
+ * Functions:
+ *      CONTROLnsRequestOut - Write variable length bytes to MEM/BB/MAC/EEPROM
+ *      CONTROLnsRequestIn - Read variable length bytes from MEM/BB/MAC/EEPROM
+ *      ControlvWriteByte - Write one byte to MEM/BB/MAC/EEPROM
+ *      ControlvReadByte - Read one byte from MEM/BB/MAC/EEPROM
+ *      ControlvMaskByte - Read one byte from MEM/BB/MAC/EEPROM and clear/set some bits in the same address
+ *
+ * Revision History:
+ *      04-05-2004 Jerry Chen:  Initial release
+ *      11-24-2004 Warren Hsu: Add ControlvWriteByte,ControlvReadByte,ControlvMaskByte
+ *
+ */
+
+#if !defined(__CONTROL_H__)
+#include "control.h"
+#endif
+#if !defined(__UMEM_H__)
+#include "umem.h"
+#endif
+#if !defined(__RNDIS_H__)
+#include "rndis.h"
+#endif
+
+/*---------------------  Static Definitions -------------------------*/
+//static int          msglevel                =MSG_LEVEL_INFO;
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+
+/*---------------------  Static Functions  --------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+void ControlvWriteByte(PSDevice pDevice, BYTE byRegType, BYTE byRegOfs, BYTE byData)
+{
+BYTE            byData1;
+
+    byData1 = byData;
+
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_WRITE,
+                        byRegOfs,
+                        byRegType,
+                        1,
+                        &byData1
+                        );
+
+}
+
+
+void ControlvReadByte(PSDevice pDevice, BYTE byRegType, BYTE byRegOfs, PBYTE pbyData)
+{
+NTSTATUS        ntStatus;
+BYTE            byData1;
+
+
+    ntStatus = CONTROLnsRequestIn(pDevice,
+                                    MESSAGE_TYPE_READ,
+                                    byRegOfs,
+                                    byRegType,
+                                    1,
+                                    &byData1);
+
+    *pbyData = byData1;
+
+}
+
+
+
+void ControlvMaskByte(PSDevice pDevice, BYTE byRegType, BYTE byRegOfs, BYTE byMask, BYTE byData)
+{
+BYTE            pbyData[2];
+
+    pbyData[0] = byData;
+    pbyData[1] = byMask;
+
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_WRITE_MASK,
+                        byRegOfs,
+                        byRegType,
+                        2,
+                        pbyData
+                        );
+
+}
diff --git a/drivers/staging/vt6656/control.h b/drivers/staging/vt6656/control.h
new file mode 100644
index 0000000..c208eb5
--- /dev/null
+++ b/drivers/staging/vt6656/control.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: control.h
+ *
+ * Purpose:
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Apr. 5, 2004
+ *
+ */
+
+
+#ifndef __CONTROL_H__
+#define __CONTROL_H__
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+#if !defined(__DEVICE_H__)
+#include "device.h"
+#endif
+#if !defined(__USBPIPE_H__)
+#include "usbpipe.h"
+#endif
+
+
+
+/*---------------------  Export Definitions -------------------------*/
+
+
+#define CONTROLnsRequestOut( Device,Request,Value,Index,Length,Buffer) \
+        PIPEnsControlOut( Device,Request,Value,Index,Length,Buffer)
+
+#define CONTROLnsRequestOutAsyn( Device,Request,Value,Index,Length,Buffer) \
+        PIPEnsControlOutAsyn( Device,Request,Value,Index,Length,Buffer)
+
+#define CONTROLnsRequestIn( Device,Request,Value,Index,Length,Buffer) \
+        PIPEnsControlIn( Device,Request,Value,Index,Length,Buffer)
+
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+#ifdef __cplusplus
+extern "C" {                            /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+
+void ControlvWriteByte(
+    IN PSDevice pDevice,
+    IN BYTE byRegType,
+    IN BYTE byRegOfs,
+    IN BYTE byData
+    );
+
+
+void ControlvReadByte(
+    IN PSDevice pDevice,
+    IN BYTE byRegType,
+    IN BYTE byRegOfs,
+    IN PBYTE pbyData
+    );
+
+
+void ControlvMaskByte(
+    IN PSDevice pDevice,
+    IN BYTE byRegType,
+    IN BYTE byRegOfs,
+    IN BYTE byMask,
+    IN BYTE byData
+    );
+
+#ifdef __cplusplus
+}                                       /* End of extern "C" { */
+#endif /* __cplusplus */
+
+
+
+
+#endif // __RCV_H__
+
+
+
diff --git a/drivers/staging/vt6656/country.h b/drivers/staging/vt6656/country.h
new file mode 100644
index 0000000..7bdc8d4
--- /dev/null
+++ b/drivers/staging/vt6656/country.h
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: country.h
+ *
+ * Purpose: Country Code information
+ *
+ * Author: Lucas Lin
+ *
+ * Date: Dec 23, 2004
+ *
+ */
+
+#ifndef __COUNTRY_H__
+#define __COUNTRY_H__
+
+/************************************************************************
+ * The definition here should be complied with the INF country order
+ * Please check with VNWL.inf/VNWL64.inf/VNWL*.inf
+ ************************************************************************/
+typedef enum _COUNTRY_CODE {
+    CCODE_FCC = 0,
+    CCODE_TELEC,
+    CCODE_ETSI,
+    CCODE_RESV3,
+    CCODE_RESV4,
+    CCODE_RESV5,
+    CCODE_RESV6,
+    CCODE_RESV7,
+    CCODE_RESV8,
+    CCODE_RESV9,
+    CCODE_RESVa,
+    CCODE_RESVb,
+    CCODE_RESVc,
+    CCODE_RESVd,
+    CCODE_RESVe,
+    CCODE_ALLBAND,
+    CCODE_ALBANIA,
+    CCODE_ALGERIA,
+    CCODE_ARGENTINA,
+    CCODE_ARMENIA,
+    CCODE_AUSTRALIA,
+    CCODE_AUSTRIA,
+    CCODE_AZERBAIJAN,
+    CCODE_BAHRAIN,
+    CCODE_BELARUS,
+    CCODE_BELGIUM,
+    CCODE_BELIZE,
+    CCODE_BOLIVIA,
+    CCODE_BRAZIL,
+    CCODE_BRUNEI_DARUSSALAM,
+    CCODE_BULGARIA,
+    CCODE_CANADA,
+    CCODE_CHILE,
+    CCODE_CHINA,
+    CCODE_COLOMBIA,
+    CCODE_COSTA_RICA,
+    CCODE_CROATIA,
+    CCODE_CYPRUS,
+    CCODE_CZECH,
+    CCODE_DENMARK,
+    CCODE_DOMINICAN_REPUBLIC,
+    CCODE_ECUADOR,
+    CCODE_EGYPT,
+    CCODE_EL_SALVADOR,
+    CCODE_ESTONIA,
+    CCODE_FINLAND,
+    CCODE_FRANCE,
+    CCODE_GERMANY,
+    CCODE_GREECE,
+    CCODE_GEORGIA,
+    CCODE_GUATEMALA,
+    CCODE_HONDURAS,
+    CCODE_HONG_KONG,
+    CCODE_HUNGARY,
+    CCODE_ICELAND,
+    CCODE_INDIA,
+    CCODE_INDONESIA,
+    CCODE_IRAN,
+    CCODE_IRELAND,
+    CCODE_ITALY,
+    CCODE_ISRAEL,
+    CCODE_JAPAN,
+    CCODE_JORDAN,
+    CCODE_KAZAKHSTAN,
+    CCODE_KUWAIT,
+    CCODE_LATVIA,
+    CCODE_LEBANON,
+    CCODE_LEICHTENSTEIN,
+    CCODE_LITHUANIA,
+    CCODE_LUXEMBURG,
+    CCODE_MACAU,
+    CCODE_MACEDONIA,
+    CCODE_MALTA,
+    CCODE_MALAYSIA,
+    CCODE_MEXICO,
+    CCODE_MONACO,
+    CCODE_MOROCCO,
+    CCODE_NETHERLANDS,
+    CCODE_NEW_ZEALAND,
+    CCODE_NORTH_KOREA,
+    CCODE_NORWAY,
+    CCODE_OMAN,
+    CCODE_PAKISTAN,
+    CCODE_PANAMA,
+    CCODE_PERU,
+    CCODE_PHILIPPINES,
+    CCODE_POLAND,
+    CCODE_PORTUGAL,
+    CCODE_PUERTO_RICO,
+    CCODE_QATAR,
+    CCODE_ROMANIA,
+    CCODE_RUSSIA,
+    CCODE_SAUDI_ARABIA,
+    CCODE_SINGAPORE,
+    CCODE_SLOVAKIA,
+    CCODE_SLOVENIA,
+    CCODE_SOUTH_AFRICA,
+    CCODE_SOUTH_KOREA,
+    CCODE_SPAIN,
+    CCODE_SWEDEN,
+    CCODE_SWITZERLAND,
+    CCODE_SYRIA,
+    CCODE_TAIWAN,
+    CCODE_THAILAND,
+    CCODE_TRINIDAD_TOBAGO,
+    CCODE_TUNISIA,
+    CCODE_TURKEY,
+    CCODE_UK,
+    CCODE_UKRAINE,
+    CCODE_UNITED_ARAB_EMIRATES,
+    CCODE_UNITED_STATES,
+    CCODE_URUGUAY,
+    CCODE_UZBEKISTAN,
+    CCODE_VENEZUELA,
+    CCODE_VIETNAM,
+    CCODE_YEMEN,
+    CCODE_ZIMBABWE,
+    CCODE_JAPAN_W52_W53,
+    CCODE_MAX
+} COUNTRY_CODE;
+
+
+/************************************************************************
+ * Function prototype
+ ************************************************************************/
+#endif  /* __COUNTRY_H__ */
diff --git a/drivers/staging/vt6656/datarate.c b/drivers/staging/vt6656/datarate.c
new file mode 100644
index 0000000..ad1ed50
--- /dev/null
+++ b/drivers/staging/vt6656/datarate.c
@@ -0,0 +1,518 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: datarate.c
+ *
+ * Purpose: Handles the auto fallback & data rates functions
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: July 17, 2002
+ *
+ * Functions:
+ *      RATEvParseMaxRate - Parsing the highest basic & support rate in rate field of frame
+ *      RATEvTxRateFallBack - Rate fallback Algorithm Implementaion
+ *      RATEuSetIE- Set rate IE field.
+ *
+ * Revision History:
+ *
+ */
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+#if !defined(__TMACRO_H__)
+#include "tmacro.h"
+#endif
+#if !defined(__MAC_H__)
+#include "mac.h"
+#endif
+#if !defined(__80211MGR_H__)
+#include "80211mgr.h"
+#endif
+#if !defined(__BSSDB_H__)
+#include "bssdb.h"
+#endif
+#if !defined(__DATARATE_H__)
+#include "datarate.h"
+#endif
+#if !defined(__CARD_H__)
+#include "card.h"
+#endif
+#if !defined(__BASEBAND_H__)
+#include "baseband.h"
+#endif
+#if !defined(__SROM_H__)
+#include "srom.h"
+#endif
+#if !defined(__RF_H__)
+#include "rf.h"
+#endif
+/*---------------------  Static Definitions -------------------------*/
+
+
+
+
+/*---------------------  Static Classes  ----------------------------*/
+
+
+
+/*---------------------  Static Variables  --------------------------*/
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+static int          msglevel                =MSG_LEVEL_INFO;
+const BYTE acbyIERate[MAX_RATE] =
+{0x02, 0x04, 0x0B, 0x16, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C};
+
+#define AUTORATE_TXOK_CNT       0x0400
+#define AUTORATE_TXFAIL_CNT     0x0064
+#define AUTORATE_TIMEOUT        10
+
+/*---------------------  Static Functions  --------------------------*/
+
+VOID s_vResetCounter (
+    IN PKnownNodeDB psNodeDBTable
+    );
+
+
+
+VOID
+s_vResetCounter (
+    IN PKnownNodeDB psNodeDBTable
+    )
+{
+    BYTE            ii;
+
+    // clear statistic counter for auto_rate
+    for(ii=0;ii<=MAX_RATE;ii++) {
+        psNodeDBTable->uTxOk[ii] = 0;
+        psNodeDBTable->uTxFail[ii] = 0;
+    }
+}
+
+/*---------------------  Export Variables  --------------------------*/
+
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+/*+
+ *
+ * Description:
+ *      Get RateIdx from the value in SuppRates IE or ExtSuppRates IE
+ *
+ * Parameters:
+ *  In:
+ *      BYTE    - Rate value in SuppRates IE or ExtSuppRates IE
+ *  Out:
+ *      none
+ *
+ * Return Value: RateIdx
+ *
+-*/
+BYTE
+DATARATEbyGetRateIdx (
+    IN BYTE byRate
+    )
+{
+    BYTE    ii;
+
+    //Erase basicRate flag.
+    byRate = byRate & 0x7F;//0111 1111
+
+    for (ii = 0; ii < MAX_RATE; ii ++) {
+        if (acbyIERate[ii] == byRate)
+            return ii;
+    }
+    return 0;
+}
+
+
+
+/*+
+ *
+ * Routine Description:
+ *      Rate fallback Algorithm Implementaion
+ *
+ * Parameters:
+ *  In:
+ *      pDevice         - Pointer to the adapter
+ *      psNodeDBTable   - Pointer to Node Data Base
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+-*/
+#define AUTORATE_TXCNT_THRESHOLD        20
+#define AUTORATE_INC_THRESHOLD          30
+
+
+
+
+/*+
+ *
+ * Description:
+ *      Get RateIdx from the value in SuppRates IE or ExtSuppRates IE
+ *
+ * Parameters:
+ *  In:
+ *      BYTE    - Rate value in SuppRates IE or ExtSuppRates IE
+ *  Out:
+ *      none
+ *
+ * Return Value: RateIdx
+ *
+-*/
+WORD
+RATEwGetRateIdx(
+    IN BYTE byRate
+    )
+{
+    WORD    ii;
+
+    //Erase basicRate flag.
+    byRate = byRate & 0x7F;//0111 1111
+
+    for (ii = 0; ii < MAX_RATE; ii ++) {
+        if (acbyIERate[ii] == byRate)
+            return ii;
+    }
+    return 0;
+}
+
+/*+
+ *
+ * Description:
+ *      Parsing the highest basic & support rate in rate field of frame.
+ *
+ * Parameters:
+ *  In:
+ *      pDevice         - Pointer to the adapter
+ *      pItemRates      - Pointer to Rate field defined in 802.11 spec.
+ *      pItemExtRates      - Pointer to Extended Rate field defined in 802.11 spec.
+ *  Out:
+ *      pwMaxBasicRate  - Maximum Basic Rate
+ *      pwMaxSuppRate   - Maximum Supported Rate
+ *      pbyTopCCKRate   - Maximum Basic Rate in CCK mode
+ *      pbyTopOFDMRate  - Maximum Basic Rate in OFDM mode
+ *
+ * Return Value: none
+ *
+-*/
+VOID
+RATEvParseMaxRate (
+    IN PVOID pDeviceHandler,
+    IN PWLAN_IE_SUPP_RATES pItemRates,
+    IN PWLAN_IE_SUPP_RATES pItemExtRates,
+    IN BOOL bUpdateBasicRate,
+    OUT PWORD pwMaxBasicRate,
+    OUT PWORD pwMaxSuppRate,
+    OUT PWORD pwSuppRate,
+    OUT PBYTE pbyTopCCKRate,
+    OUT PBYTE pbyTopOFDMRate
+    )
+{
+PSDevice  pDevice = (PSDevice) pDeviceHandler;
+UINT  ii;
+BYTE  byHighSuppRate = 0;
+BYTE  byRate = 0;
+WORD  wOldBasicRate = pDevice->wBasicRate;
+UINT  uRateLen;
+
+
+    if (pItemRates == NULL)
+        return;
+
+    *pwSuppRate = 0;
+    uRateLen = pItemRates->len;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ParseMaxRate Len: %d\n", uRateLen);
+    if (pDevice->byBBType != BB_TYPE_11B) {
+        if (uRateLen > WLAN_RATES_MAXLEN)
+            uRateLen = WLAN_RATES_MAXLEN;
+    } else {
+        if (uRateLen > WLAN_RATES_MAXLEN_11B)
+            uRateLen = WLAN_RATES_MAXLEN_11B;
+    }
+
+    for (ii = 0; ii < uRateLen; ii++) {
+    	byRate = (BYTE)(pItemRates->abyRates[ii]);
+        if (WLAN_MGMT_IS_BASICRATE(byRate) &&
+            (bUpdateBasicRate == TRUE))  {
+            // Add to basic rate set, update pDevice->byTopCCKBasicRate and pDevice->byTopOFDMBasicRate
+            CARDbAddBasicRate((PVOID)pDevice, RATEwGetRateIdx(byRate));
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ParseMaxRate AddBasicRate: %d\n", RATEwGetRateIdx(byRate));
+        }
+        byRate = (BYTE)(pItemRates->abyRates[ii]&0x7F);
+        if (byHighSuppRate == 0)
+            byHighSuppRate = byRate;
+        if (byRate > byHighSuppRate)
+            byHighSuppRate = byRate;
+        *pwSuppRate |= (1<<RATEwGetRateIdx(byRate));
+    }
+    if ((pItemExtRates != NULL) && (pItemExtRates->byElementID == WLAN_EID_EXTSUPP_RATES) &&
+        (pDevice->byBBType != BB_TYPE_11B)) {
+
+        UINT  uExtRateLen = pItemExtRates->len;
+
+        if (uExtRateLen > WLAN_RATES_MAXLEN)
+            uExtRateLen = WLAN_RATES_MAXLEN;
+
+        for (ii = 0; ii < uExtRateLen ; ii++) {
+            byRate = (BYTE)(pItemExtRates->abyRates[ii]);
+            // select highest basic rate
+            if (WLAN_MGMT_IS_BASICRATE(pItemExtRates->abyRates[ii])) {
+            	// Add to basic rate set, update pDevice->byTopCCKBasicRate and pDevice->byTopOFDMBasicRate
+                CARDbAddBasicRate((PVOID)pDevice, RATEwGetRateIdx(byRate));
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ParseMaxRate AddBasicRate: %d\n", RATEwGetRateIdx(byRate));
+            }
+            byRate = (BYTE)(pItemExtRates->abyRates[ii]&0x7F);
+            if (byHighSuppRate == 0)
+                byHighSuppRate = byRate;
+            if (byRate > byHighSuppRate)
+                byHighSuppRate = byRate;
+            *pwSuppRate |= (1<<RATEwGetRateIdx(byRate));
+            //DBG_PRN_GRP09(("ParseMaxRate : HighSuppRate: %d, %X\n", RATEwGetRateIdx(byRate), byRate));
+        }
+    } //if(pItemExtRates != NULL)
+
+    if ((pDevice->byPacketType == PK_TYPE_11GB) && CARDbIsOFDMinBasicRate((PVOID)pDevice)) {
+        pDevice->byPacketType = PK_TYPE_11GA;
+    }
+
+    *pbyTopCCKRate = pDevice->byTopCCKBasicRate;
+    *pbyTopOFDMRate = pDevice->byTopOFDMBasicRate;
+    *pwMaxSuppRate = RATEwGetRateIdx(byHighSuppRate);
+    if ((pDevice->byPacketType==PK_TYPE_11B) || (pDevice->byPacketType==PK_TYPE_11GB))
+       *pwMaxBasicRate = pDevice->byTopCCKBasicRate;
+    else
+       *pwMaxBasicRate = pDevice->byTopOFDMBasicRate;
+    if (wOldBasicRate != pDevice->wBasicRate)
+        CARDvSetRSPINF((PVOID)pDevice, pDevice->byBBType);
+
+     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Exit ParseMaxRate\n");
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *      Rate fallback Algorithm Implementaion
+ *
+ * Parameters:
+ *  In:
+ *      pDevice         - Pointer to the adapter
+ *      psNodeDBTable   - Pointer to Node Data Base
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+-*/
+#define AUTORATE_TXCNT_THRESHOLD        20
+#define AUTORATE_INC_THRESHOLD          30
+
+VOID
+RATEvTxRateFallBack (
+    IN PVOID pDeviceHandler,
+    IN PKnownNodeDB psNodeDBTable
+    )
+{
+PSDevice        pDevice = (PSDevice) pDeviceHandler;
+PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+#if 1  //mike fixed old: use packet lose ratio algorithm to control rate
+WORD            wIdxDownRate = 0;
+UINT            ii;
+BOOL            bAutoRate[MAX_RATE]    = {TRUE,TRUE,TRUE,TRUE,FALSE,FALSE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE};
+DWORD           dwThroughputTbl[MAX_RATE] = {10, 20, 55, 110, 60, 90, 120, 180, 240, 360, 480, 540};
+DWORD           dwThroughput = 0;
+WORD            wIdxUpRate = 0;
+DWORD           dwTxDiff = 0;
+
+    if (pMgmt->eScanState != WMAC_NO_SCANNING) {
+        // Don't do Fallback when scanning Channel
+        return;
+    }
+    psNodeDBTable->uTimeCount ++;
+
+    if (psNodeDBTable->uTxFail[MAX_RATE] > psNodeDBTable->uTxOk[MAX_RATE])
+        dwTxDiff = psNodeDBTable->uTxFail[MAX_RATE] - psNodeDBTable->uTxOk[MAX_RATE];
+
+    if ((psNodeDBTable->uTxOk[MAX_RATE] < AUTORATE_TXOK_CNT) &&
+        (dwTxDiff < AUTORATE_TXFAIL_CNT) &&
+        (psNodeDBTable->uTimeCount < AUTORATE_TIMEOUT)) {
+        return;
+    }
+
+    if (psNodeDBTable->uTimeCount >= AUTORATE_TIMEOUT) {
+        psNodeDBTable->uTimeCount = 0;
+    }
+
+    for(ii=0;ii<MAX_RATE;ii++) {
+        if (psNodeDBTable->wSuppRate & (0x0001<<ii)) {
+            if (bAutoRate[ii] == TRUE) {
+                wIdxUpRate = (WORD) ii;
+            }
+        } else {
+            bAutoRate[ii] = FALSE;
+        }
+    }
+
+    for(ii=0;ii<=psNodeDBTable->wTxDataRate;ii++) {
+        if ( (psNodeDBTable->uTxOk[ii] != 0) ||
+             (psNodeDBTable->uTxFail[ii] != 0) ) {
+            dwThroughputTbl[ii] *= psNodeDBTable->uTxOk[ii];
+            if (ii < RATE_11M) {
+                psNodeDBTable->uTxFail[ii] *= 4;
+            }
+            dwThroughputTbl[ii] /= (psNodeDBTable->uTxOk[ii] + psNodeDBTable->uTxFail[ii]);
+        }
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Rate %d,Ok: %d, Fail:%d, Throughput:%d\n",
+                       ii, (int)psNodeDBTable->uTxOk[ii], (int)psNodeDBTable->uTxFail[ii], (int)dwThroughputTbl[ii]);
+    }
+    dwThroughput = dwThroughputTbl[psNodeDBTable->wTxDataRate];
+
+    wIdxDownRate = psNodeDBTable->wTxDataRate;
+    for(ii = psNodeDBTable->wTxDataRate; ii > 0;) {
+        ii--;
+        if ( (dwThroughputTbl[ii] > dwThroughput) &&
+             (bAutoRate[ii]==TRUE) ) {
+            dwThroughput = dwThroughputTbl[ii];
+            wIdxDownRate = (WORD) ii;
+        }
+    }
+    psNodeDBTable->wTxDataRate = wIdxDownRate;
+    if (psNodeDBTable->uTxOk[MAX_RATE]) {
+        if (psNodeDBTable->uTxOk[MAX_RATE] >
+           (psNodeDBTable->uTxFail[MAX_RATE] * 4) ) {
+            psNodeDBTable->wTxDataRate = wIdxUpRate;
+        }
+    }else { // adhoc, if uTxOk(total) =0 & uTxFail(total) = 0
+        if (psNodeDBTable->uTxFail[MAX_RATE] == 0)
+            psNodeDBTable->wTxDataRate = wIdxUpRate;
+    }
+
+    if (pDevice->byBBType == BB_TYPE_11A) {
+        if (psNodeDBTable->wTxDataRate <= RATE_11M)
+            psNodeDBTable->wTxDataRate = RATE_6M;
+    }
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"uTxOk[MAX_RATE] %d, uTxFail[MAX_RATE]:%d\n",(int)psNodeDBTable->uTxOk[MAX_RATE], (int)psNodeDBTable->uTxFail[MAX_RATE]);
+    s_vResetCounter(psNodeDBTable);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Rate: %d, U:%d, D:%d\n", (int)psNodeDBTable->wTxDataRate, (int)wIdxUpRate, (int)wIdxDownRate);
+    return;
+#else  //mike fixed new: use differ-signal strength to control rate
+WORD            wIdxUpRate = 0;
+BOOL            bAutoRate[MAX_RATE]    = {TRUE,TRUE,TRUE,TRUE,FALSE,FALSE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE};
+UINT            ii;
+long  ldBm;
+
+    if (pMgmt->eScanState != WMAC_NO_SCANNING) {
+        // Don't do Fallback when scanning Channel
+        return;
+    }
+
+    for(ii=0;ii<MAX_RATE;ii++) {
+        if (psNodeDBTable->wSuppRate & (0x0001<<ii)) {
+            if (bAutoRate[ii] == TRUE) {
+                wIdxUpRate = (WORD) ii;
+            }
+        } else {
+            bAutoRate[ii] = FALSE;
+        }
+    }
+
+         RFvRSSITodBm(pDevice, (BYTE)(pDevice->uCurrRSSI), &ldBm);
+
+	if (ldBm > -55) {
+		if ( psNodeDBTable->wSuppRate & (0x0001<<RATE_54M) )  //11a/g
+      		{
+	  		psNodeDBTable->wTxDataRate = RATE_54M;
+		}
+		else{ //11b
+	  		psNodeDBTable->wTxDataRate = RATE_11M;
+		}
+	}
+
+if (wIdxUpRate == RATE_54M ) {     //11a/g
+		if (ldBm > -56 )
+			psNodeDBTable->wTxDataRate = RATE_54M;
+		else if (ldBm > -61 )
+			psNodeDBTable->wTxDataRate = RATE_48M;
+		else if (ldBm > -66 )
+			psNodeDBTable->wTxDataRate = RATE_36M;
+		else if (ldBm > -72 )
+			psNodeDBTable->wTxDataRate = RATE_24M;
+		else if (ldBm > -80 )
+			psNodeDBTable->wTxDataRate = RATE_5M;
+		else {
+			psNodeDBTable->wTxDataRate = RATE_1M;
+			//increasingVGA = TRUE;
+		}
+	}
+	else {  //11b
+		if (ldBm > -65 )
+			psNodeDBTable->wTxDataRate = RATE_11M;
+		else if (ldBm > -75 )
+			psNodeDBTable->wTxDataRate = RATE_5M;
+		else
+			psNodeDBTable->wTxDataRate = RATE_1M;
+	}
+
+   return;
+#endif
+}
+
+/*+
+ *
+ * Description:
+ *    This routine is used to assemble available Rate IE.
+ *
+ * Parameters:
+ *  In:
+ *    pDevice
+ *  Out:
+ *
+ * Return Value: None
+ *
+-*/
+BYTE
+RATEuSetIE (
+    IN PWLAN_IE_SUPP_RATES pSrcRates,
+    IN PWLAN_IE_SUPP_RATES pDstRates,
+    IN UINT                uRateLen
+    )
+{
+    UINT ii, uu, uRateCnt = 0;
+
+    if ((pSrcRates == NULL) || (pDstRates == NULL))
+        return 0;
+
+    if (pSrcRates->len == 0)
+        return 0;
+
+    for (ii = 0; ii < uRateLen; ii++) {
+        for (uu = 0; uu < pSrcRates->len; uu++) {
+            if ((pSrcRates->abyRates[uu] & 0x7F) == acbyIERate[ii]) {
+                pDstRates->abyRates[uRateCnt ++] = pSrcRates->abyRates[uu];
+                break;
+            }
+        }
+    }
+    return (BYTE)uRateCnt;
+}
+
diff --git a/drivers/staging/vt6656/datarate.h b/drivers/staging/vt6656/datarate.h
new file mode 100644
index 0000000..68f206e
--- /dev/null
+++ b/drivers/staging/vt6656/datarate.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: datarate.h
+ *
+ * Purpose: Handles the auto fallback & data rates functions
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: July 16, 2002
+ *
+ */
+#ifndef __DATARATE_H__
+#define __DATARATE_H__
+
+/*---------------------  Export Definitions -------------------------*/
+
+#define FALLBACK_PKT_COLLECT_TR_H  50   // pkts
+#define FALLBACK_PKT_COLLECT_TR_L  10   // pkts
+#define FALLBACK_POLL_SECOND       5    // 5 sec
+#define FALLBACK_RECOVER_SECOND    30   // 30 sec
+#define FALLBACK_THRESHOLD         15   // percent
+#define UPGRADE_THRESHOLD          5    // percent
+#define UPGRADE_CNT_THRD           3    // times
+#define RETRY_TIMES_THRD_H         2    // times
+#define RETRY_TIMES_THRD_L         1    // times
+
+
+#define RATE_1M         0
+#define RATE_2M         1
+#define RATE_5M         2
+#define RATE_11M        3
+#define RATE_6M         4
+#define RATE_9M         5
+#define RATE_12M        6
+#define RATE_18M        7
+#define RATE_24M        8
+#define RATE_36M        9
+#define RATE_48M       10
+#define RATE_54M       11
+#define RATE_AUTO      12
+#define MAX_RATE       12
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+
+/*---------------------  Export Types  ------------------------------*/
+
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+
+VOID
+RATEvParseMaxRate(
+    IN PVOID pDeviceHandler,
+    IN PWLAN_IE_SUPP_RATES pItemRates,
+    IN PWLAN_IE_SUPP_RATES pItemExtRates,
+    IN BOOL bUpdateBasicRate,
+    OUT PWORD pwMaxBasicRate,
+    OUT PWORD pwMaxSuppRate,
+    OUT PWORD pwSuppRate,
+    OUT PBYTE pbyTopCCKRate,
+    OUT PBYTE pbyTopOFDMRate
+    );
+
+VOID
+RATEvTxRateFallBack(
+    IN PVOID pDeviceHandler,
+    IN PKnownNodeDB psNodeDBTable
+    );
+
+BYTE
+RATEuSetIE(
+    IN PWLAN_IE_SUPP_RATES pSrcRates,
+    IN PWLAN_IE_SUPP_RATES pDstRates,
+    IN UINT                uRateLen
+    );
+
+WORD
+RATEwGetRateIdx(
+    IN BYTE byRate
+    );
+
+
+BYTE
+DATARATEbyGetRateIdx(
+    IN BYTE byRate
+    );
+
+
+#endif //__DATARATE_H__
diff --git a/drivers/staging/vt6656/desc.h b/drivers/staging/vt6656/desc.h
new file mode 100644
index 0000000..87e5c8c
--- /dev/null
+++ b/drivers/staging/vt6656/desc.h
@@ -0,0 +1,453 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: desc.h
+ *
+ * Purpose:The header file of descriptor
+ *
+ * Revision History:
+ *
+ * Author: Tevin Chen
+ *
+ * Date: May 21, 1996
+ *
+ */
+
+
+#ifndef __DESC_H__
+#define __DESC_H__
+
+#include <linux/types.h>
+#include <linux/mm.h>
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+#if !defined(__TETHER_H__)
+#include "tether.h"
+#endif
+
+
+
+
+
+/*---------------------  Export Definitions -------------------------*/
+
+// max transmit or receive buffer size
+#define CB_MAX_BUF_SIZE     2900U       // max buffer size
+                                        // NOTE: must be multiple of 4
+
+#define CB_MAX_TX_BUF_SIZE          CB_MAX_BUF_SIZE // max Tx buffer size
+#define CB_MAX_RX_BUF_SIZE_NORMAL   CB_MAX_BUF_SIZE // max Rx buffer size when not use Multi-RD
+
+#define CB_BEACON_BUF_SIZE  512U        // default beacon buffer size
+
+#define MAX_TOTAL_SIZE_WITH_ALL_HEADERS CB_MAX_BUF_SIZE
+
+#define MAX_INTERRUPT_SIZE              32
+
+
+#define RX_BLOCKS           64          // form 0x60 to 0xA0
+#define TX_BLOCKS           32          // from 0xA0 to 0xC0
+
+#define CB_MAX_RX_DESC      128         // max # of descriptor
+#define CB_MIN_RX_DESC      16          // min # of rx descriptor
+#define CB_MAX_TX_DESC      128         // max # of descriptor
+#define CB_MIN_TX_DESC      16          // min # of tx descriptor
+
+#define CB_RD_NUM           64          // default # of RD
+#define CB_TD_NUM           64          // default # of TD
+
+
+
+//
+// Bits in the RSR register
+//
+#define RSR_ADDRBROAD       0x80        // 1000 0000
+#define RSR_ADDRMULTI       0x40        // 0100 0000
+#define RSR_ADDRUNI         0x00        // 0000 0000
+#define RSR_IVLDTYP         0x20        // 0010 0000 , invalid packet type
+#define RSR_IVLDLEN         0x10        // 0001 0000 , invalid len (> 2312 byte)
+#define RSR_BSSIDOK         0x08        // 0000 1000
+#define RSR_CRCOK           0x04        // 0000 0100
+#define RSR_BCNSSIDOK       0x02        // 0000 0010
+#define RSR_ADDROK          0x01        // 0000 0001
+
+//
+// Bits in the new RSR register
+//
+#define NEWRSR_DECRYPTOK    0x10        // 0001 0000
+#define NEWRSR_CFPIND       0x08        // 0000 1000
+#define NEWRSR_HWUTSF       0x04        // 0000 0100
+#define NEWRSR_BCNHITAID    0x02        // 0000 0010
+#define NEWRSR_BCNHITAID0   0x01        // 0000 0001
+
+
+//
+// Bits in the TSR register
+//
+#define TSR_RETRYTMO        0x08        // 0000 1000
+#define TSR_TMO             0x04        // 0000 0100
+#define TSR_ACKDATA         0x02        // 0000 0010
+#define TSR_VALID           0x01        // 0000 0001
+
+
+#define CB_PROTOCOL_RESERVED_SECTION    16
+
+
+
+// if retrys excess 15 times , tx will abort, and
+// if tx fifo underflow, tx will fail
+// we should try to resend it
+#define CB_MAX_TX_ABORT_RETRY   3
+
+
+#define FIFOCTL_AUTO_FB_1   0x1000 // 0001 0000 0000 0000
+#define FIFOCTL_AUTO_FB_0   0x0800 // 0000 1000 0000 0000
+#define FIFOCTL_GRPACK      0x0400 // 0000 0100 0000 0000
+#define FIFOCTL_11GA        0x0300 // 0000 0011 0000 0000
+#define FIFOCTL_11GB        0x0200 // 0000 0010 0000 0000
+#define FIFOCTL_11B         0x0100 // 0000 0001 0000 0000
+#define FIFOCTL_11A         0x0000 // 0000 0000 0000 0000
+#define FIFOCTL_RTS         0x0080 // 0000 0000 1000 0000
+#define FIFOCTL_ISDMA0      0x0040 // 0000 0000 0100 0000
+#define FIFOCTL_GENINT      0x0020 // 0000 0000 0010 0000
+#define FIFOCTL_TMOEN       0x0010 // 0000 0000 0001 0000
+#define FIFOCTL_LRETRY      0x0008 // 0000 0000 0000 1000
+#define FIFOCTL_CRCDIS      0x0004 // 0000 0000 0000 0100
+#define FIFOCTL_NEEDACK     0x0002 // 0000 0000 0000 0010
+#define FIFOCTL_LHEAD       0x0001 // 0000 0000 0000 0001
+
+//WMAC definition Frag Control
+#define FRAGCTL_AES         0x0300 // 0000 0011 0000 0000
+#define FRAGCTL_TKIP        0x0200 // 0000 0010 0000 0000
+#define FRAGCTL_LEGACY      0x0100 // 0000 0001 0000 0000
+#define FRAGCTL_NONENCRYPT  0x0000 // 0000 0000 0000 0000
+//#define FRAGCTL_AC3         0x000C // 0000 0000 0000 1100
+//#define FRAGCTL_AC2         0x0008 // 0000 0000 0000 1000
+//#define FRAGCTL_AC1         0x0004 // 0000 0000 0000 0100
+//#define FRAGCTL_AC0         0x0000 // 0000 0000 0000 0000
+#define FRAGCTL_ENDFRAG     0x0003 // 0000 0000 0000 0011
+#define FRAGCTL_MIDFRAG     0x0002 // 0000 0000 0000 0010
+#define FRAGCTL_STAFRAG     0x0001 // 0000 0000 0000 0001
+#define FRAGCTL_NONFRAG     0x0000 // 0000 0000 0000 0000
+
+
+//#define TYPE_AC0DMA     0
+//#define TYPE_TXDMA0     1
+#define TYPE_TXDMA0     0
+#define TYPE_AC0DMA     1
+#define TYPE_ATIMDMA    2
+#define TYPE_SYNCDMA    3
+#define TYPE_MAXTD      2
+
+#define TYPE_BEACONDMA  4
+
+#define TYPE_RXDMA0     0
+#define TYPE_RXDMA1     1
+#define TYPE_MAXRD      2
+
+
+
+// TD_INFO flags control bit
+#define TD_FLAGS_NETIF_SKB               0x01       // check if need release skb
+#define TD_FLAGS_PRIV_SKB                0x02       // check if called from private skb(hostap)
+#define TD_FLAGS_PS_RETRY                0x04       // check if PS STA frame re-transmit
+//#define TD_FLAGS_NETIF_SKB                0x04
+
+/*---------------------  Export Types  ------------------------------*/
+
+
+//
+// RsvTime buffer header
+//
+typedef struct tagSRrvTime_gRTS {
+    WORD        wRTSTxRrvTime_ba;
+    WORD        wRTSTxRrvTime_aa;
+    WORD        wRTSTxRrvTime_bb;
+    WORD        wReserved;
+    WORD        wTxRrvTime_b;
+    WORD        wTxRrvTime_a;
+}__attribute__ ((__packed__))
+SRrvTime_gRTS, DEF* PSRrvTime_gRTS;
+typedef const SRrvTime_gRTS DEF*     PCSRrvTime_gRTS;
+
+typedef struct tagSRrvTime_gCTS {
+    WORD        wCTSTxRrvTime_ba;
+    WORD        wReserved;
+    WORD        wTxRrvTime_b;
+    WORD        wTxRrvTime_a;
+}__attribute__ ((__packed__))
+SRrvTime_gCTS, DEF* PSRrvTime_gCTS;
+typedef const SRrvTime_gCTS DEF*     PCSRrvTime_gCTS;
+
+typedef struct tagSRrvTime_ab {
+    WORD        wRTSTxRrvTime;
+    WORD        wTxRrvTime;
+}__attribute__ ((__packed__))
+SRrvTime_ab, DEF* PSRrvTime_ab;
+typedef const SRrvTime_ab DEF*     PCSRrvTime_ab;
+
+typedef struct tagSRrvTime_atim {
+    WORD        wCTSTxRrvTime_ba;
+    WORD        wTxRrvTime_a;
+}__attribute__ ((__packed__))
+SRrvTime_atim, DEF* PSRrvTime_atim;
+typedef const SRrvTime_atim DEF*     PCSRrvTime_atim;
+
+//
+// RTS buffer header
+//
+typedef struct tagSRTSData {
+    WORD    wFrameControl;
+    WORD    wDurationID;
+    BYTE    abyRA[U_ETHER_ADDR_LEN];
+    BYTE    abyTA[U_ETHER_ADDR_LEN];
+}__attribute__ ((__packed__))
+SRTSData, DEF* PSRTSData;
+typedef const SRTSData DEF*      PCSRTSData;
+
+typedef struct tagSRTS_g {
+    BYTE        bySignalField_b;
+    BYTE        byServiceField_b;
+    WORD        wTransmitLength_b;
+    BYTE        bySignalField_a;
+    BYTE        byServiceField_a;
+    WORD        wTransmitLength_a;
+    WORD        wDuration_ba;
+    WORD        wDuration_aa;
+    WORD        wDuration_bb;
+    WORD        wReserved;
+    SRTSData    Data;
+}__attribute__ ((__packed__))
+SRTS_g, DEF* PSRTS_g;
+typedef const SRTS_g DEF*     PCSRTS_g;
+
+
+typedef struct tagSRTS_g_FB {
+    BYTE        bySignalField_b;
+    BYTE        byServiceField_b;
+    WORD        wTransmitLength_b;
+    BYTE        bySignalField_a;
+    BYTE        byServiceField_a;
+    WORD        wTransmitLength_a;
+    WORD        wDuration_ba;
+    WORD        wDuration_aa;
+    WORD        wDuration_bb;
+    WORD        wReserved;
+    WORD        wRTSDuration_ba_f0;
+    WORD        wRTSDuration_aa_f0;
+    WORD        wRTSDuration_ba_f1;
+    WORD        wRTSDuration_aa_f1;
+    SRTSData    Data;
+}__attribute__ ((__packed__))
+SRTS_g_FB, DEF* PSRTS_g_FB;
+typedef const SRTS_g_FB DEF*     PCSRTS_g_FB;
+
+
+typedef struct tagSRTS_ab {
+    BYTE        bySignalField;
+    BYTE        byServiceField;
+    WORD        wTransmitLength;
+    WORD        wDuration;
+    WORD        wReserved;
+    SRTSData    Data;
+}__attribute__ ((__packed__))
+SRTS_ab, DEF* PSRTS_ab;
+typedef const SRTS_ab DEF*     PCSRTS_ab;
+
+
+typedef struct tagSRTS_a_FB {
+    BYTE        bySignalField;
+    BYTE        byServiceField;
+    WORD        wTransmitLength;
+    WORD        wDuration;
+    WORD        wReserved;
+    WORD        wRTSDuration_f0;
+    WORD        wRTSDuration_f1;
+    SRTSData    Data;
+}__attribute__ ((__packed__))
+SRTS_a_FB, DEF* PSRTS_a_FB;
+typedef const SRTS_a_FB DEF*     PCSRTS_a_FB;
+
+
+//
+// CTS buffer header
+//
+typedef struct tagSCTSData {
+    WORD    wFrameControl;
+    WORD    wDurationID;
+    BYTE    abyRA[U_ETHER_ADDR_LEN];
+    WORD    wReserved;
+}__attribute__ ((__packed__))
+SCTSData, DEF* PSCTSData;
+
+typedef struct tagSCTS {
+    BYTE        bySignalField_b;
+    BYTE        byServiceField_b;
+    WORD        wTransmitLength_b;
+    WORD        wDuration_ba;
+    WORD        wReserved;
+    SCTSData    Data;
+}__attribute__ ((__packed__))
+SCTS, DEF* PSCTS;
+typedef const SCTS DEF*     PCSCTS;
+
+typedef struct tagSCTS_FB {
+    BYTE        bySignalField_b;
+    BYTE        byServiceField_b;
+    WORD        wTransmitLength_b;
+    WORD        wDuration_ba;
+    WORD        wReserved;
+    WORD        wCTSDuration_ba_f0;
+    WORD        wCTSDuration_ba_f1;
+    SCTSData    Data;
+}__attribute__ ((__packed__))
+SCTS_FB, DEF* PSCTS_FB;
+typedef const SCTS_FB DEF*     PCSCTS_FB;
+
+
+//
+// Tx FIFO header
+//
+typedef struct tagSTxBufHead {
+    DWORD   adwTxKey[4];
+    WORD    wFIFOCtl;
+    WORD    wTimeStamp;
+    WORD    wFragCtl;
+    WORD    wReserved;
+}__attribute__ ((__packed__))
+STxBufHead, DEF* PSTxBufHead;
+typedef const STxBufHead DEF*   PCSTxBufHead;
+
+typedef struct tagSTxShortBufHead {
+    WORD    wFIFOCtl;
+    WORD    wTimeStamp;
+}__attribute__ ((__packed__))
+STxShortBufHead, DEF* PSTxShortBufHead;
+typedef const STxShortBufHead DEF*   PCSTxShortBufHead;
+
+//
+// Tx data header
+//
+typedef struct tagSTxDataHead_g {
+    BYTE    bySignalField_b;
+    BYTE    byServiceField_b;
+    WORD    wTransmitLength_b;
+    BYTE    bySignalField_a;
+    BYTE    byServiceField_a;
+    WORD    wTransmitLength_a;
+    WORD    wDuration_b;
+    WORD    wDuration_a;
+    WORD    wTimeStampOff_b;
+    WORD    wTimeStampOff_a;
+}__attribute__ ((__packed__))
+STxDataHead_g, DEF* PSTxDataHead_g;
+typedef const STxDataHead_g DEF*  PCSTxDataHead_g;
+
+typedef struct tagSTxDataHead_g_FB {
+    BYTE    bySignalField_b;
+    BYTE    byServiceField_b;
+    WORD    wTransmitLength_b;
+    BYTE    bySignalField_a;
+    BYTE    byServiceField_a;
+    WORD    wTransmitLength_a;
+    WORD    wDuration_b;
+    WORD    wDuration_a;
+    WORD    wDuration_a_f0;
+    WORD    wDuration_a_f1;
+    WORD    wTimeStampOff_b;
+    WORD    wTimeStampOff_a;
+}__attribute__ ((__packed__))
+STxDataHead_g_FB, DEF* PSTxDataHead_g_FB;
+typedef const STxDataHead_g_FB DEF*  PCSTxDataHead_g_FB;
+
+
+typedef struct tagSTxDataHead_ab {
+    BYTE    bySignalField;
+    BYTE    byServiceField;
+    WORD    wTransmitLength;
+    WORD    wDuration;
+    WORD    wTimeStampOff;
+}__attribute__ ((__packed__))
+STxDataHead_ab, DEF* PSTxDataHead_ab;
+typedef const STxDataHead_ab DEF*  PCSTxDataHead_ab;
+
+
+typedef struct tagSTxDataHead_a_FB {
+    BYTE    bySignalField;
+    BYTE    byServiceField;
+    WORD    wTransmitLength;
+    WORD    wDuration;
+    WORD    wTimeStampOff;
+    WORD    wDuration_f0;
+    WORD    wDuration_f1;
+}__attribute__ ((__packed__))
+STxDataHead_a_FB, DEF* PSTxDataHead_a_FB;
+typedef const STxDataHead_a_FB DEF*  PCSTxDataHead_a_FB;
+
+//
+// MICHDR data header
+//
+typedef struct tagSMICHDRHead {
+    DWORD   adwHDR0[4];
+    DWORD   adwHDR1[4];
+    DWORD   adwHDR2[4];
+}__attribute__ ((__packed__))
+SMICHDRHead, DEF* PSMICHDRHead;
+typedef const SMICHDRHead DEF*   PCSMICHDRHead;
+
+typedef struct tagSBEACONCtl {
+    DWORD   BufReady : 1;
+    DWORD   TSF      : 15;
+    DWORD   BufLen   : 11;
+    DWORD   Reserved : 5;
+}__attribute__ ((__packed__))
+SBEACONCtl;
+
+
+typedef struct tagSSecretKey {
+    DWORD   dwLowDword;
+    BYTE    byHighByte;
+}__attribute__ ((__packed__))
+SSecretKey;
+
+typedef struct tagSKeyEntry {
+    BYTE  abyAddrHi[2];
+    WORD  wKCTL;
+    BYTE  abyAddrLo[4];
+    DWORD dwKey0[4];
+    DWORD dwKey1[4];
+    DWORD dwKey2[4];
+    DWORD dwKey3[4];
+    DWORD dwKey4[4];
+}__attribute__ ((__packed__))
+SKeyEntry;
+/*---------------------  Export Macros ------------------------------*/
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+
+
+#endif // __DESC_H__
+
diff --git a/drivers/staging/vt6656/device.h b/drivers/staging/vt6656/device.h
new file mode 100644
index 0000000..143aa76
--- /dev/null
+++ b/drivers/staging/vt6656/device.h
@@ -0,0 +1,988 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: device.h
+ *
+ * Purpose: MAC Data structure
+ *
+ * Author: Tevin Chen
+ *
+ * Date: Mar 17, 1997
+ *
+ */
+
+#ifndef __DEVICE_H__
+#define __DEVICE_H__
+
+#ifdef MODULE
+#ifdef MODVERSIONS
+#include <linux/modversions.h>
+#endif /* MODVERSIONS */
+#include <linux/module.h>
+#endif /* MODULE */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/version.h>
+#include <linux/string.h>
+#include <linux/wait.h>
+#include <linux/if_arp.h>
+#include <linux/sched.h>
+#include <linux/if.h>
+#include <linux/rtnetlink.h>//James
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
+#include <linux/config.h>
+#endif
+
+#include <linux/proc_fs.h>
+#include <linux/inetdevice.h>
+#include <linux/reboot.h>
+#include <linux/usb.h>
+#include <linux/signal.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#ifdef SIOCETHTOOL
+#define DEVICE_ETHTOOL_IOCTL_SUPPORT
+#include <linux/ethtool.h>
+#else
+#undef DEVICE_ETHTOOL_IOCTL_SUPPORT
+#endif
+/* Include Wireless Extension definition and check version - Jean II */
+#include <linux/wireless.h>
+#if WIRELESS_EXT > 12
+#include <net/iw_handler.h>	// New driver API
+#endif	/* WIRELESS_EXT > 12 */
+
+//2008-0409-07, <Add> by Einsn Liu
+#if WIRELESS_EXT > 17
+#ifndef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+#define WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+#endif
+#endif
+
+//2007-0920-01<Add>by MikeLiu
+#ifndef SndEvt_ToAPI
+#define SndEvt_ToAPI
+//please copy below macro to driver_event.c for API
+#define RT_INSMOD_EVENT_FLAG                             0x0101
+#define RT_UPDEV_EVENT_FLAG                               0x0102
+#define RT_DISCONNECTED_EVENT_FLAG               0x0103
+#define RT_WPACONNECTED_EVENT_FLAG             0x0104
+#define RT_DOWNDEV_EVENT_FLAG                        0x0105
+#define RT_RMMOD_EVENT_FLAG                              0x0106
+#endif
+
+//
+// device specific
+//
+
+#if !defined(_KCOMPAT_H)
+#include "kcompat.h"
+#endif
+
+#if !defined(__DEVICE_CONFIG_H)
+#include "device_cfg.h"
+#endif
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+#if !defined(__80211HDR_H__)
+#include "80211hdr.h"
+#endif
+#if !defined(__TETHER_H__)
+#include "tether.h"
+#endif
+#if !defined(__WMGR_H__)
+#include "wmgr.h"
+#endif
+#if !defined(__WCMD_H__)
+#include "wcmd.h"
+#endif
+#if !defined(__MIB_H__)
+#include "mib.h"
+#endif
+#if !defined(__SROM_H__)
+#include "srom.h"
+#endif
+#if !defined(__RC4_H__)
+#include "rc4.h"
+#endif
+#if !defined(__TPCI_H__)
+#include "tpci.h"
+#endif
+#if !defined(__DESC_H__)
+#include "desc.h"
+#endif
+#if !defined(__KEY_H__)
+#include "key.h"
+#endif
+#if !defined(__CARD_H__)
+#include "card.h"
+#endif
+
+/*---------------------  Export Definitions -------------------------*/
+#define VNT_USB_VENDOR_ID                     0x160A
+#define VNT_USB_PRODUCT_ID                    0x3184
+
+#define MAC_MAX_CONTEXT_REG     (256+128)
+
+#define MAX_MULTICAST_ADDRESS_NUM       32
+#define MULTICAST_ADDRESS_LIST_SIZE     (MAX_MULTICAST_ADDRESS_NUM * U_ETHER_ADDR_LEN)
+
+
+//#define OP_MODE_INFRASTRUCTURE  0
+//#define OP_MODE_ADHOC           1
+//#define OP_MODE_AP              2
+
+#define DUPLICATE_RX_CACHE_LENGTH       5
+
+#define NUM_KEY_ENTRY                   11
+
+#define TX_WEP_NONE                     0
+#define TX_WEP_OTF                      1
+#define TX_WEP_SW                       2
+#define TX_WEP_SWOTP                    3
+#define TX_WEP_OTPSW                    4
+#define TX_WEP_SW232                    5
+
+#define KEYSEL_WEP40                    0
+#define KEYSEL_WEP104                   1
+#define KEYSEL_TKIP                     2
+#define KEYSEL_CCMP                     3
+
+
+
+#define AUTO_FB_NONE            0
+#define AUTO_FB_0               1
+#define AUTO_FB_1               2
+
+#define FB_RATE0                0
+#define FB_RATE1                1
+
+// Antenna Mode
+#define ANT_A                   0
+#define ANT_B                   1
+#define ANT_DIVERSITY           2
+#define ANT_RXD_TXA             3
+#define ANT_RXD_TXB             4
+#define ANT_UNKNOWN             0xFF
+#define ANT_TXA                 0
+#define ANT_TXB                 1
+#define ANT_RXA                 2
+#define ANT_RXB                 3
+
+
+#define MAXCHECKHANGCNT         4
+
+//Packet type
+#define TX_PKT_UNI              0x00
+#define TX_PKT_MULTI            0x01
+#define TX_PKT_BROAD            0x02
+
+#define BB_VGA_LEVEL            4
+#define BB_VGA_CHANGE_THRESHOLD 3
+
+
+
+#ifndef RUN_AT
+#define RUN_AT(x)                       (jiffies+(x))
+#endif
+
+// DMA related
+#define RESERV_AC0DMA                   4
+
+#define PRIVATE_Message                 0
+
+/*---------------------  Export Types  ------------------------------*/
+
+#define DBG_PRT(l, p, args...) {if (l<=msglevel) printk( p ,##args);}
+#define PRINT_K(p, args...) {if (PRIVATE_Message) printk( p ,##args);}
+
+typedef enum __device_msg_level {
+    MSG_LEVEL_ERR=0,            //Errors that will cause abnormal operation.
+    MSG_LEVEL_NOTICE=1,         //Some errors need users to be notified.
+    MSG_LEVEL_INFO=2,           //Normal message.
+    MSG_LEVEL_VERBOSE=3,        //Will report all trival errors.
+    MSG_LEVEL_DEBUG=4           //Only for debug purpose.
+} DEVICE_MSG_LEVEL, *PDEVICE_MSG_LEVEL;
+
+typedef enum __device_init_type {
+    DEVICE_INIT_COLD=0,         // cold init
+    DEVICE_INIT_RESET,          // reset init or Dx to D0 power remain init
+    DEVICE_INIT_DXPL            // Dx to D0 power lost init
+} DEVICE_INIT_TYPE, *PDEVICE_INIT_TYPE;
+
+
+//USB
+
+//
+// Enum of context types for SendPacket
+//
+typedef enum _CONTEXT_TYPE {
+    CONTEXT_DATA_PACKET = 1,
+    CONTEXT_MGMT_PACKET
+} CONTEXT_TYPE;
+
+
+
+
+// RCB (Receive Control Block)
+typedef struct _RCB
+{
+    PVOID                   Next;
+    LONG                    Ref;
+    PVOID                   pDevice;
+    struct urb              *pUrb;
+    SRxMgmtPacket           sMngPacket;
+    struct sk_buff*         skb;
+    BOOL                    bBoolInUse;
+
+} RCB, *PRCB;
+
+
+// used to track bulk out irps
+typedef struct _USB_SEND_CONTEXT {
+    PVOID           pDevice;
+    struct sk_buff *pPacket;
+    struct urb      *pUrb;
+    UINT            uBufLen;
+    CONTEXT_TYPE    Type;
+    SEthernetHeader sEthHeader;
+    PVOID           Next;
+    BOOL            bBoolInUse;
+    UCHAR           Data[MAX_TOTAL_SIZE_WITH_ALL_HEADERS];
+} USB_SEND_CONTEXT, *PUSB_SEND_CONTEXT;
+
+
+//structure got from configuration file as user desired default setting.
+typedef struct _DEFAULT_CONFIG{
+    INT    ZoneType;
+    INT    eConfigMode;
+    INT    eAuthenMode;    //open/wep/wpa
+    INT    bShareKeyAlgorithm;  //open-open/open-sharekey/wep-sharekey
+    INT    keyidx;               //wepkey index
+    INT    eEncryptionStatus;
+
+}DEFAULT_CONFIG,*PDEFAULT_CONFIG;
+
+//
+// Structure to keep track of usb interrupt packets
+//
+typedef struct {
+    UINT            uDataLen;
+    PBYTE           pDataBuf;
+//    struct urb      *pUrb;
+    BOOL            bInUse;
+} INT_BUFFER, *PINT_BUFFER;
+
+
+
+//0:11A 1:11B 2:11G
+typedef enum _VIA_BB_TYPE
+{
+    BB_TYPE_11A=0,
+    BB_TYPE_11B,
+    BB_TYPE_11G
+} VIA_BB_TYPE, *PVIA_BB_TYPE;
+
+//0:11a,1:11b,2:11gb(only CCK in BasicRate),3:11ga(OFDM in Basic Rate)
+typedef enum _VIA_PKT_TYPE
+{
+    PK_TYPE_11A=0,
+    PK_TYPE_11B,
+    PK_TYPE_11GB,
+    PK_TYPE_11GA
+} VIA_PKT_TYPE, *PVIA_PKT_TYPE;
+
+
+
+
+//++ NDIS related
+
+#define NDIS_STATUS     int
+#define NTSTATUS        int
+
+typedef enum __DEVICE_NDIS_STATUS {
+    STATUS_SUCCESS=0,
+    STATUS_FAILURE,
+    STATUS_RESOURCES,
+    STATUS_PENDING,
+} DEVICE_NDIS_STATUS, *PDEVICE_NDIS_STATUS;
+
+
+#define MAX_BSSIDINFO_4_PMKID   16
+#define MAX_PMKIDLIST           5
+//Flags for PMKID Candidate list structure
+#define NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED	0x01
+
+// PMKID Structures
+typedef UCHAR   NDIS_802_11_PMKID_VALUE[16];
+
+
+typedef enum _NDIS_802_11_WEP_STATUS
+{
+    Ndis802_11WEPEnabled,
+    Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled,
+    Ndis802_11WEPDisabled,
+    Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled,
+    Ndis802_11WEPKeyAbsent,
+    Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent,
+    Ndis802_11WEPNotSupported,
+    Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported,
+    Ndis802_11Encryption2Enabled,
+    Ndis802_11Encryption2KeyAbsent,
+    Ndis802_11Encryption3Enabled,
+    Ndis802_11Encryption3KeyAbsent
+} NDIS_802_11_WEP_STATUS, *PNDIS_802_11_WEP_STATUS,
+  NDIS_802_11_ENCRYPTION_STATUS, *PNDIS_802_11_ENCRYPTION_STATUS;
+
+
+typedef enum _NDIS_802_11_STATUS_TYPE
+{
+    Ndis802_11StatusType_Authentication,
+    Ndis802_11StatusType_MediaStreamMode,
+    Ndis802_11StatusType_PMKID_CandidateList,
+    Ndis802_11StatusTypeMax    // not a real type, defined as an upper bound
+} NDIS_802_11_STATUS_TYPE, *PNDIS_802_11_STATUS_TYPE;
+
+//Added new types for PMKID Candidate lists.
+typedef struct _PMKID_CANDIDATE {
+    NDIS_802_11_MAC_ADDRESS BSSID;
+    ULONG Flags;
+} PMKID_CANDIDATE, *PPMKID_CANDIDATE;
+
+
+typedef struct _BSSID_INFO
+{
+    NDIS_802_11_MAC_ADDRESS BSSID;
+    NDIS_802_11_PMKID_VALUE PMKID;
+} BSSID_INFO, *PBSSID_INFO;
+
+typedef struct tagSPMKID {
+    ULONG Length;
+    ULONG BSSIDInfoCount;
+    BSSID_INFO BSSIDInfo[MAX_BSSIDINFO_4_PMKID];
+} SPMKID, *PSPMKID;
+
+typedef struct tagSPMKIDCandidateEvent {
+    NDIS_802_11_STATUS_TYPE     StatusType;
+    ULONG Version;       // Version of the structure
+    ULONG NumCandidates; // No. of pmkid candidates
+    PMKID_CANDIDATE CandidateList[MAX_PMKIDLIST];
+} SPMKIDCandidateEvent, DEF* PSPMKIDCandidateEvent;
+
+//--
+
+//++ 802.11h related
+#define MAX_QUIET_COUNT     8
+
+typedef struct tagSQuietControl {
+    BOOL        bEnable;
+    DWORD       dwStartTime;
+    BYTE        byPeriod;
+    WORD        wDuration;
+} SQuietControl, DEF* PSQuietControl;
+
+//--
+
+
+// The receive duplicate detection cache entry
+typedef struct tagSCacheEntry{
+    WORD        wFmSequence;
+    BYTE        abyAddr2[U_ETHER_ADDR_LEN];
+    WORD        wFrameCtl;
+} SCacheEntry, *PSCacheEntry;
+
+typedef struct tagSCache{
+/* The receive cache is updated circularly.  The next entry to be written is
+ * indexed by the "InPtr".
+*/
+    UINT            uInPtr;         // Place to use next
+    SCacheEntry     asCacheEntry[DUPLICATE_RX_CACHE_LENGTH];
+} SCache, *PSCache;
+
+#define CB_MAX_RX_FRAG                 64
+// DeFragment Control Block, used for collecting fragments prior to reassembly
+typedef struct tagSDeFragControlBlock
+{
+    WORD            wSequence;
+    WORD            wFragNum;
+    BYTE            abyAddr2[U_ETHER_ADDR_LEN];
+	UINT            uLifetime;
+    struct sk_buff* skb;
+    PBYTE           pbyRxBuffer;
+    UINT            cbFrameLength;
+    BOOL            bInUse;
+} SDeFragControlBlock, DEF* PSDeFragControlBlock;
+
+
+
+//flags for options
+#define     DEVICE_FLAGS_UNPLUG          0x00000001UL
+#define     DEVICE_FLAGS_PREAMBLE_TYPE   0x00000002UL
+#define     DEVICE_FLAGS_OP_MODE         0x00000004UL
+#define     DEVICE_FLAGS_PS_MODE         0x00000008UL
+#define		DEVICE_FLAGS_80211h_MODE	 0x00000010UL
+
+//flags for driver status
+#define     DEVICE_FLAGS_OPENED          0x00010000UL
+#define     DEVICE_FLAGS_WOL_ENABLED     0x00080000UL
+//flags for capbilities
+#define     DEVICE_FLAGS_TX_ALIGN        0x01000000UL
+#define     DEVICE_FLAGS_HAVE_CAM        0x02000000UL
+#define     DEVICE_FLAGS_FLOW_CTRL       0x04000000UL
+
+//flags for MII status
+#define     DEVICE_LINK_FAIL             0x00000001UL
+#define     DEVICE_SPEED_10              0x00000002UL
+#define     DEVICE_SPEED_100             0x00000004UL
+#define     DEVICE_SPEED_1000            0x00000008UL
+#define     DEVICE_DUPLEX_FULL           0x00000010UL
+#define     DEVICE_AUTONEG_ENABLE        0x00000020UL
+#define     DEVICE_FORCED_BY_EEPROM      0x00000040UL
+//for device_set_media_duplex
+#define     DEVICE_LINK_CHANGE           0x00000001UL
+
+
+typedef struct __device_opt {
+    int         nRxDescs0;    //Number of RX descriptors0
+    int         nTxDescs0;    //Number of TX descriptors 0, 1, 2, 3
+    int         rts_thresh;   //rts threshold
+    int         frag_thresh;
+    int         OpMode;
+    int         data_rate;
+    int         channel_num;
+    int         short_retry;
+    int         long_retry;
+    int         bbp_type;
+    U32         flags;
+} OPTIONS, *POPTIONS;
+
+
+typedef struct __device_info {
+
+// netdev
+	struct usb_device*          usb;
+    struct net_device*          dev;
+    struct net_device_stats     stats;
+
+    OPTIONS                     sOpts;
+
+	struct tasklet_struct       CmdWorkItem;
+	struct tasklet_struct       EventWorkItem;
+	struct tasklet_struct       ReadWorkItem;
+	struct tasklet_struct       RxMngWorkItem;
+
+    U32                         rx_buf_sz;
+    int                         multicast_limit;
+    BYTE                        byRxMode;
+
+    spinlock_t                  lock;
+
+    U32                         rx_bytes;
+
+    BYTE                        byRevId;
+
+    U32                         flags;
+    ULONG                       Flags;
+
+    SCache                      sDupRxCache;
+
+    SDeFragControlBlock         sRxDFCB[CB_MAX_RX_FRAG];
+    UINT                        cbDFCB;
+    UINT                        cbFreeDFCB;
+    UINT                        uCurrentDFCBIdx;
+
+    // +++USB
+
+    struct urb                  *pControlURB;
+    struct urb                  *pInterruptURB;
+	struct usb_ctrlrequest      sUsbCtlRequest;
+
+    UINT                        int_interval;
+    //
+    // Variables to track resources for the BULK In Pipe
+    //
+    PRCB                        pRCBMem;
+    PRCB                        apRCB[CB_MAX_RX_DESC];
+    UINT                        cbRD;
+    PRCB                        FirstRecvFreeList;
+    PRCB                        LastRecvFreeList;
+    UINT                        NumRecvFreeList;
+    PRCB                        FirstRecvMngList;
+    PRCB                        LastRecvMngList;
+    UINT                        NumRecvMngList;
+    BOOL                        bIsRxWorkItemQueued;
+    BOOL                        bIsRxMngWorkItemQueued;
+    ULONG                       ulRcvRefCount;      // number of packets that have not been returned back
+
+    //
+    //  Variables to track resources for the BULK Out Pipe
+    //
+
+    PUSB_SEND_CONTEXT           apTD[CB_MAX_TX_DESC];
+    UINT                        cbTD;
+
+    //
+    //  Variables to track resources for the Interript In Pipe
+    //
+    INT_BUFFER                  intBuf;
+    BOOL                        fKillEventPollingThread;
+    BOOL                        bEventAvailable;
+
+
+  //default config from file by user setting
+    DEFAULT_CONFIG    config_file;
+
+
+    //
+    // Statistic for USB
+    // protect with spinlock
+    ULONG                       ulBulkInPosted;
+    ULONG                       ulBulkInError;
+    ULONG                       ulBulkInContCRCError;
+    ULONG                       ulBulkInBytesRead;
+
+    ULONG                       ulBulkOutPosted;
+    ULONG                       ulBulkOutError;
+    ULONG                       ulBulkOutContCRCError;
+    ULONG                       ulBulkOutBytesWrite;
+
+    ULONG                       ulIntInPosted;
+    ULONG                       ulIntInError;
+    ULONG                       ulIntInContCRCError;
+    ULONG                       ulIntInBytesRead;
+
+
+    // Version control
+    WORD                        wFirmwareVersion;
+    BYTE                        byLocalID;
+    BYTE                        byRFType;
+    BYTE                        byBBRxConf;
+
+
+    BYTE                        byZoneType;
+    BOOL                        bZoneRegExist;
+
+    BYTE                        byOriginalZonetype;
+
+    BOOL                        bLinkPass;          // link status: OK or fail
+    BYTE                        abyCurrentNetAddr[U_ETHER_ADDR_LEN];
+    BYTE                        abyPermanentNetAddr[U_ETHER_ADDR_LEN];
+    // SW network address
+//    BYTE                        abySoftwareNetAddr[U_ETHER_ADDR_LEN];
+    BOOL                        bExistSWNetAddr;
+
+    // Adapter statistics
+    SStatCounter                scStatistic;
+    // 802.11 counter
+    SDot11Counters              s802_11Counter;
+
+    //
+    // Maintain statistical debug info.
+    //
+    ULONG                       packetsReceived;
+    ULONG                       packetsReceivedDropped;
+    ULONG                       packetsReceivedOverflow;
+    ULONG                       packetsSent;
+    ULONG                       packetsSentDropped;
+    ULONG                       SendContextsInUse;
+    ULONG                       RcvBuffersInUse;
+
+
+    // 802.11 management
+    SMgmtObject                 sMgmtObj;
+
+    QWORD                       qwCurrTSF;
+    UINT                        cbBulkInMax;
+    BOOL                        bPSRxBeacon;
+
+    // 802.11 MAC specific
+    UINT                        uCurrRSSI;
+    BYTE                        byCurrSQ;
+
+
+    //Antenna Diversity
+    BOOL                        bTxRxAntInv;
+    DWORD                       dwRxAntennaSel;
+    DWORD                       dwTxAntennaSel;
+    BYTE                        byAntennaCount;
+    BYTE                        byRxAntennaMode;
+    BYTE                        byTxAntennaMode;
+    BYTE                        byRadioCtl;
+    BYTE                        bHWRadioOff;
+
+    //SQ3 functions for antenna diversity
+    struct timer_list           TimerSQ3Tmax1;
+    struct timer_list           TimerSQ3Tmax2;
+    struct timer_list           TimerSQ3Tmax3;
+
+    BOOL                        bDiversityRegCtlON;
+    BOOL                        bDiversityEnable;
+    ULONG                       ulDiversityNValue;
+    ULONG                       ulDiversityMValue;
+    BYTE                        byTMax;
+    BYTE                        byTMax2;
+    BYTE                        byTMax3;
+    ULONG                       ulSQ3TH;
+
+    ULONG                       uDiversityCnt;
+    BYTE                        byAntennaState;
+    ULONG                       ulRatio_State0;
+    ULONG                       ulRatio_State1;
+    ULONG                       ulSQ3_State0;
+    ULONG                       ulSQ3_State1;
+
+    ULONG                       aulSQ3Val[MAX_RATE];
+    ULONG                       aulPktNum[MAX_RATE];
+
+    // IFS & Cw
+    UINT                        uSIFS;    //Current SIFS
+    UINT                        uDIFS;    //Current DIFS
+    UINT                        uEIFS;    //Current EIFS
+    UINT                        uSlot;    //Current SlotTime
+    UINT                        uCwMin;   //Current CwMin
+    UINT                        uCwMax;   //CwMax is fixed on 1023.
+    // PHY parameter
+    BYTE                        bySIFS;
+    BYTE                        byDIFS;
+    BYTE                        byEIFS;
+    BYTE                        bySlot;
+    BYTE                        byCWMaxMin;
+
+    // Rate
+    VIA_BB_TYPE                 byBBType; //0: 11A, 1:11B, 2:11G
+    VIA_PKT_TYPE                byPacketType; //0:11a,1:11b,2:11gb(only CCK in BasicRate),3:11ga(OFDM in Basic Rate)
+    WORD                        wBasicRate;
+    BYTE                        byACKRate;
+    BYTE                        byTopOFDMBasicRate;
+    BYTE                        byTopCCKBasicRate;
+
+
+    DWORD                       dwAotoRateTxOkCnt;
+    DWORD                       dwAotoRateTxFailCnt;
+    DWORD                       dwErrorRateThreshold[13];
+    DWORD                       dwTPTable[MAX_RATE];
+    BYTE                        abyEEPROM[EEP_MAX_CONTEXT_SIZE];  //DWORD alignment
+
+    BYTE                        byMinChannel;
+    BYTE                        byMaxChannel;
+    UINT                        uConnectionRate;
+
+    BYTE                        byPreambleType;
+    BYTE                        byShortPreamble;
+    // CARD_PHY_TYPE
+    BYTE                        eConfigPHYMode;
+
+    // For RF Power table
+    BYTE                        byCCKPwr;
+    BYTE                        byOFDMPwrG;
+    BYTE                        byOFDMPwrA;
+    BYTE                        byCurPwr;
+    BYTE                        abyCCKPwrTbl[14];
+    BYTE                        abyOFDMPwrTbl[14];
+    BYTE                        abyOFDMAPwrTbl[42];
+
+    WORD                        wCurrentRate;
+    WORD                        wRTSThreshold;
+    WORD                        wFragmentationThreshold;
+    BYTE                        byShortRetryLimit;
+    BYTE                        byLongRetryLimit;
+    CARD_OP_MODE                eOPMode;
+    BOOL                        bBSSIDFilter;
+    WORD                        wMaxTransmitMSDULifetime;
+    BYTE                        abyBSSID[U_ETHER_ADDR_LEN];
+    BYTE                        abyDesireBSSID[U_ETHER_ADDR_LEN];
+    WORD                        wCTSDuration;       // update while speed change
+    WORD                        wACKDuration;       // update while speed change
+    WORD                        wRTSTransmitLen;    // update while speed change
+    BYTE                        byRTSServiceField;  // update while speed change
+    BYTE                        byRTSSignalField;   // update while speed change
+
+    DWORD                       dwMaxReceiveLifetime;       // dot11MaxReceiveLifetime
+
+    BOOL                        bCCK;
+    BOOL                        bEncryptionEnable;
+    BOOL                        bLongHeader;
+    BOOL                        bSoftwareGenCrcErr;
+    BOOL                        bShortSlotTime;
+    BOOL                        bProtectMode;
+    BOOL                        bNonERPPresent;
+    BOOL                        bBarkerPreambleMd;
+
+    BYTE                        byERPFlag;
+    WORD                        wUseProtectCntDown;
+
+    BOOL                        bRadioControlOff;
+    BOOL                        bRadioOff;
+
+    // Power save
+    BOOL                        bEnablePSMode;
+    WORD                        wListenInterval;
+    BOOL                        bPWBitOn;
+    WMAC_POWER_MODE             ePSMode;
+    ULONG                       ulPSModeWaitTx;
+    BOOL                        bPSModeTxBurst;
+
+    // Beacon releated
+    WORD                    wSeqCounter;
+    BOOL                    bBeaconBufReady;
+    BOOL                    bBeaconSent;
+    BOOL                    bFixRate;
+    BYTE                    byCurrentCh;
+    UINT                    uScanTime;
+
+    CMD_STATE               eCommandState;
+
+    CMD_CODE                eCommand;
+    BOOL                    bBeaconTx;
+    BYTE                    byScanBBType;
+
+    BOOL                    bStopBeacon;
+    BOOL                    bStopDataPkt;
+    BOOL                    bStopTx0Pkt;
+    UINT                    uAutoReConnectTime;
+    UINT                    uIsroamingTime;
+
+    // 802.11 counter
+
+    CMD_ITEM                eCmdQueue[CMD_Q_SIZE];
+    UINT                    uCmdDequeueIdx;
+    UINT                    uCmdEnqueueIdx;
+    UINT                    cbFreeCmdQueue;
+    BOOL                    bCmdRunning;
+    BOOL                    bCmdClear;
+    BOOL                    bNeedRadioOFF;
+
+    BOOL                    bEnableRoaming;  //DavidWang
+    BOOL                    bIsRoaming;  //DavidWang
+    BOOL                    bFastRoaming;  //DavidWang
+    BYTE                    bSameBSSMaxNum;  //Davidwang
+    BYTE                    bSameBSSCurNum;  //DavidWang
+    BOOL                    bRoaming;
+    BOOL                    b11hEable;
+    ULONG                   ulTxPower;
+
+    // Encryption
+    NDIS_802_11_WEP_STATUS  eEncryptionStatus;
+    BOOL                    bTransmitKey;
+
+//2007-0925-01<Add>by MikeLiu
+//mike add :save old Encryption
+    NDIS_802_11_WEP_STATUS  eOldEncryptionStatus;
+
+    SKeyManagement          sKey;
+    DWORD                   dwIVCounter;
+
+
+    RC4Ext                  SBox;
+    BYTE                    abyPRNG[WLAN_WEPMAX_KEYLEN+3];
+    BYTE                    byKeyIndex;
+
+    BOOL                    bAES;
+    BYTE                    byCntMeasure;
+
+    UINT                    uKeyLength;
+    BYTE                    abyKey[WLAN_WEP232_KEYLEN];
+
+    // for AP mode
+    UINT                    uAssocCount;
+    BOOL                    bMoreData;
+
+    // QoS
+    BOOL                    bGrpAckPolicy;
+
+
+    BYTE                    byAutoFBCtrl;
+
+    BOOL                    bTxMICFail;
+    BOOL                    bRxMICFail;
+
+
+    // For Update BaseBand VGA Gain Offset
+    BOOL                    bUpdateBBVGA;
+    UINT                    uBBVGADiffCount;
+    BYTE                    byBBVGANew;
+    BYTE                    byBBVGACurrent;
+    BYTE                    abyBBVGA[BB_VGA_LEVEL];
+    LONG                    ldBmThreshold[BB_VGA_LEVEL];
+
+    BYTE                    byBBPreEDRSSI;
+    BYTE                    byBBPreEDIndex;
+
+
+    BOOL                    bRadioCmd;
+    DWORD                   dwDiagRefCount;
+
+    // For FOE Tuning
+    BYTE                    byFOETuning;
+
+    // For Auto Power Tunning
+
+    BYTE                    byAutoPwrTunning;
+
+    // BaseBand Loopback Use
+    BYTE                    byBBCR4d;
+    BYTE                    byBBCRc9;
+    BYTE                    byBBCR88;
+    BYTE                    byBBCR09;
+
+    // command timer
+    struct timer_list       sTimerCommand;
+
+//2007-0115-01<Add>by MikeLiu
+#ifdef TxInSleep
+     struct timer_list       sTimerTxData;
+     ULONG                       nTxDataTimeCout;
+     BOOL  fTxDataInSleep;
+     BOOL  IsTxDataTrigger;
+#endif
+
+#ifdef WPA_SM_Transtatus
+    BOOL  fWPA_Authened;           //is WPA/WPA-PSK or WPA2/WPA2-PSK authen??
+#endif
+    BYTE            byReAssocCount;   //mike add:re-association retry times!
+    BYTE            byLinkWaitCount;
+
+    SEthernetHeader         sTxEthHeader;
+    SEthernetHeader         sRxEthHeader;
+    BYTE                    abyBroadcastAddr[U_ETHER_ADDR_LEN];
+    BYTE                    abySNAP_RFC1042[U_ETHER_ADDR_LEN];
+    BYTE                    abySNAP_Bridgetunnel[U_ETHER_ADDR_LEN];
+
+    // Pre-Authentication & PMK cache
+    SPMKID                  gsPMKID;
+    SPMKIDCandidateEvent    gsPMKIDCandidate;
+
+
+    // for 802.11h
+    BOOL                    b11hEnable;
+
+    BOOL                    bChannelSwitch;
+    BYTE                    byNewChannel;
+    BYTE                    byChannelSwitchCount;
+
+    //WPA supplicant daemon
+	struct net_device       *wpadev;
+	BOOL                    bWPADEVUp;
+    struct sk_buff          *skb;
+    //--
+
+#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+        BOOL                 bwextstep0;
+        BOOL                 bwextstep1;
+        BOOL                 bwextstep2;
+        BOOL                 bwextstep3;
+        BOOL                 bWPASuppWextEnabled;
+#endif
+
+#ifdef HOSTAP
+    // user space daemon: hostapd, is used for HOSTAP
+	BOOL                    bEnableHostapd;
+	BOOL                    bEnable8021x;
+	BOOL                    bEnableHostWEP;
+	struct net_device       *apdev;
+	int (*tx_80211)(struct sk_buff *skb, struct net_device *dev);
+#endif
+    UINT                    uChannel;
+
+#ifdef WIRELESS_EXT
+	struct iw_statistics	wstats;		// wireless stats
+#endif /* WIRELESS_EXT */
+    BOOL                    bCommit;
+
+} DEVICE_INFO, *PSDevice;
+
+
+
+
+#define EnqueueRCB(_Head, _Tail, _RCB)                  \
+{                                                       \
+    if (!_Head) {                                       \
+        _Head = _RCB;                                   \
+    }                                                   \
+    else {                                              \
+        _Tail->Next = _RCB;                             \
+    }                                                   \
+    _RCB->Next = NULL;                                  \
+    _Tail = _RCB;                                       \
+}
+
+#define DequeueRCB(Head, Tail)                          \
+{                                                       \
+    PRCB   RCB = Head;                                  \
+    if (!RCB->Next) {                                   \
+        Tail = NULL;                                    \
+    }                                                   \
+    Head = RCB->Next;                                   \
+}
+
+
+#define ADD_ONE_WITH_WRAP_AROUND(uVar, uModulo) {   \
+    if ((uVar) >= ((uModulo) - 1))                  \
+        (uVar) = 0;                                 \
+    else                                            \
+        (uVar)++;                                   \
+}
+
+
+#define fMP_RESET_IN_PROGRESS               0x00000001
+#define fMP_DISCONNECTED                    0x00000002
+#define fMP_HALT_IN_PROGRESS                0x00000004
+#define fMP_SURPRISE_REMOVED                0x00000008
+#define fMP_RECV_LOOKASIDE                  0x00000010
+#define fMP_INIT_IN_PROGRESS                0x00000020
+#define fMP_SEND_SIDE_RESOURCE_ALLOCATED    0x00000040
+#define fMP_RECV_SIDE_RESOURCE_ALLOCATED    0x00000080
+#define fMP_POST_READS                      0x00000100
+#define fMP_POST_WRITES                     0x00000200
+#define fMP_CONTROL_READS                   0x00000400
+#define fMP_CONTROL_WRITES                  0x00000800
+
+
+
+#define MP_SET_FLAG(_M, _F)             ((_M)->Flags |= (_F))
+#define MP_CLEAR_FLAG(_M, _F)            ((_M)->Flags &= ~(_F))
+#define MP_TEST_FLAG(_M, _F)            (((_M)->Flags & (_F)) != 0)
+#define MP_TEST_FLAGS(_M, _F)            (((_M)->Flags & (_F)) == (_F))
+
+#define MP_IS_READY(_M)        (((_M)->Flags & \
+                                 (fMP_DISCONNECTED | fMP_RESET_IN_PROGRESS | fMP_HALT_IN_PROGRESS | fMP_INIT_IN_PROGRESS | fMP_SURPRISE_REMOVED)) == 0)
+
+/*---------------------  Export Functions  --------------------------*/
+
+//BOOL device_dma0_xmit(PSDevice pDevice, struct sk_buff *skb, UINT uNodeIndex);
+BOOL device_alloc_frag_buf(PSDevice pDevice, PSDeFragControlBlock pDeF);
+
+#endif
+
+
diff --git a/drivers/staging/vt6656/dpc.c b/drivers/staging/vt6656/dpc.c
new file mode 100644
index 0000000..702304b
--- /dev/null
+++ b/drivers/staging/vt6656/dpc.c
@@ -0,0 +1,1673 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: dpc.c
+ *
+ * Purpose: handle dpc rx functions
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: May 20, 2003
+ *
+ * Functions:
+ *      device_receive_frame - Rcv 802.11 frame function
+ *      s_bAPModeRxCtl- AP Rcv frame filer Ctl.
+ *      s_bAPModeRxData- AP Rcv data frame handle
+ *      s_bHandleRxEncryption- Rcv decrypted data via on-fly
+ *      s_bHostWepRxEncryption- Rcv encrypted data via host
+ *      s_byGetRateIdx- get rate index
+ *      s_vGetDASA- get data offset
+ *      s_vProcessRxMACHeader- Rcv 802.11 and translate to 802.3
+ *
+ * Revision History:
+ *
+ */
+
+
+#if !defined(__DEVICE_H__)
+#include "device.h"
+#endif
+#if !defined(__RXTX_H__)
+#include "rxtx.h"
+#endif
+#if !defined(__TETHER_H__)
+#include "tether.h"
+#endif
+#if !defined(__CARD_H__)
+#include "card.h"
+#endif
+#if !defined(__BSSDB_H__)
+#include "bssdb.h"
+#endif
+#if !defined(__MAC_H__)
+#include "mac.h"
+#endif
+#if !defined(__BASEBAND_H__)
+#include "baseband.h"
+#endif
+#if !defined(__UMEM_H__)
+#include "umem.h"
+#endif
+#if !defined(__MICHAEL_H__)
+#include "michael.h"
+#endif
+#if !defined(__TKIP_H__)
+#include "tkip.h"
+#endif
+#if !defined(__TCRC_H__)
+#include "tcrc.h"
+#endif
+#if !defined(__WCTL_H__)
+#include "wctl.h"
+#endif
+#if !defined(__TBIT_H__)
+#include "tbit.h"
+#endif
+#if !defined(__HOSTAP_H__)
+#include "hostap.h"
+#endif
+#if !defined(__RF_H__)
+#include "rf.h"
+#endif
+#if !defined(__IOWPA_H__)
+#include "iowpa.h"
+#endif
+#if !defined(__AES_H__)
+#include "aes_ccmp.h"
+#endif
+#if !defined(__DATARATE_H__)
+#include "datarate.h"
+#endif
+#if !defined(__USBPIPE_H__)
+#include "usbpipe.h"
+#endif
+
+
+/*---------------------  Static Definitions -------------------------*/
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+static int          msglevel                =MSG_LEVEL_INFO;
+
+const BYTE acbyRxRate[MAX_RATE] =
+{2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108};
+
+
+/*---------------------  Static Functions  --------------------------*/
+
+/*---------------------  Static Definitions -------------------------*/
+
+/*---------------------  Static Functions  --------------------------*/
+
+static BYTE s_byGetRateIdx(IN BYTE byRate);
+
+
+static
+VOID
+s_vGetDASA(
+    IN  PBYTE pbyRxBufferAddr,
+    OUT PUINT pcbHeaderSize,
+    OUT PSEthernetHeader psEthHeader
+    );
+
+static
+VOID
+s_vProcessRxMACHeader (
+    IN  PSDevice pDevice,
+    IN  PBYTE pbyRxBufferAddr,
+    IN  UINT cbPacketSize,
+    IN  BOOL bIsWEP,
+    IN  BOOL bExtIV,
+    OUT PUINT pcbHeadSize
+    );
+
+static BOOL s_bAPModeRxCtl(
+    IN PSDevice pDevice,
+    IN PBYTE    pbyFrame,
+    IN INT      iSANodeIndex
+    );
+
+
+
+static BOOL s_bAPModeRxData (
+    IN PSDevice pDevice,
+    IN struct sk_buff* skb,
+    IN UINT     FrameSize,
+    IN UINT     cbHeaderOffset,
+    IN INT      iSANodeIndex,
+    IN INT      iDANodeIndex
+    );
+
+
+static BOOL s_bHandleRxEncryption(
+    IN PSDevice     pDevice,
+    IN PBYTE        pbyFrame,
+    IN UINT         FrameSize,
+    IN PBYTE        pbyRsr,
+    OUT PBYTE       pbyNewRsr,
+    OUT PSKeyItem   *pKeyOut,
+    OUT PBOOL       pbExtIV,
+    OUT PWORD       pwRxTSC15_0,
+    OUT PDWORD      pdwRxTSC47_16
+    );
+
+static BOOL s_bHostWepRxEncryption(
+
+    IN PSDevice     pDevice,
+    IN PBYTE        pbyFrame,
+    IN UINT         FrameSize,
+    IN PBYTE        pbyRsr,
+    IN BOOL         bOnFly,
+    IN PSKeyItem    pKey,
+    OUT PBYTE       pbyNewRsr,
+    OUT PBOOL       pbExtIV,
+    OUT PWORD       pwRxTSC15_0,
+    OUT PDWORD      pdwRxTSC47_16
+
+    );
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*+
+ *
+ * Description:
+ *    Translate Rcv 802.11 header to 802.3 header with Rx buffer
+ *
+ * Parameters:
+ *  In:
+ *      pDevice
+ *      dwRxBufferAddr  - Address of Rcv Buffer
+ *      cbPacketSize    - Rcv Packet size
+ *      bIsWEP          - If Rcv with WEP
+ *  Out:
+ *      pcbHeaderSize   - 802.11 header size
+ *
+ * Return Value: None
+ *
+-*/
+static
+VOID
+s_vProcessRxMACHeader (
+    IN  PSDevice pDevice,
+    IN  PBYTE pbyRxBufferAddr,
+    IN  UINT cbPacketSize,
+    IN  BOOL bIsWEP,
+    IN  BOOL bExtIV,
+    OUT PUINT pcbHeadSize
+    )
+{
+    PBYTE           pbyRxBuffer;
+    UINT            cbHeaderSize = 0;
+    PWORD           pwType;
+    PS802_11Header  pMACHeader;
+    int             ii;
+
+
+    pMACHeader = (PS802_11Header) (pbyRxBufferAddr + cbHeaderSize);
+
+    s_vGetDASA((PBYTE)pMACHeader, &cbHeaderSize, &pDevice->sRxEthHeader);
+
+    if (bIsWEP) {
+        if (bExtIV) {
+            // strip IV&ExtIV , add 8 byte
+            cbHeaderSize += (WLAN_HDR_ADDR3_LEN + 8);
+        } else {
+            // strip IV , add 4 byte
+            cbHeaderSize += (WLAN_HDR_ADDR3_LEN + 4);
+        }
+    }
+    else {
+        cbHeaderSize += WLAN_HDR_ADDR3_LEN;
+    };
+
+    pbyRxBuffer = (PBYTE) (pbyRxBufferAddr + cbHeaderSize);
+    if (IS_ETH_ADDRESS_EQUAL(pbyRxBuffer, &pDevice->abySNAP_Bridgetunnel[0])) {
+        cbHeaderSize += 6;
+    }
+    else if (IS_ETH_ADDRESS_EQUAL(pbyRxBuffer, &pDevice->abySNAP_RFC1042[0])) {
+        cbHeaderSize += 6;
+        pwType = (PWORD) (pbyRxBufferAddr + cbHeaderSize);
+        if ((*pwType!= TYPE_PKT_IPX) && (*pwType != cpu_to_le16(0xF380))) {
+        }
+        else {
+            cbHeaderSize -= 8;
+            pwType = (PWORD) (pbyRxBufferAddr + cbHeaderSize);
+            if (bIsWEP) {
+                if (bExtIV) {
+                    *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 8);    // 8 is IV&ExtIV
+                } else {
+                    *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 4);    // 4 is IV
+                }
+            }
+            else {
+                *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN);
+            }
+        }
+    }
+    else {
+        cbHeaderSize -= 2;
+        pwType = (PWORD) (pbyRxBufferAddr + cbHeaderSize);
+        if (bIsWEP) {
+            if (bExtIV) {
+                *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 8);    // 8 is IV&ExtIV
+            } else {
+                *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 4);    // 4 is IV
+            }
+        }
+        else {
+            *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN);
+        }
+    }
+
+    cbHeaderSize -= (U_ETHER_ADDR_LEN * 2);
+    pbyRxBuffer = (PBYTE) (pbyRxBufferAddr + cbHeaderSize);
+    for(ii=0;ii<U_ETHER_ADDR_LEN;ii++)
+        *pbyRxBuffer++ = pDevice->sRxEthHeader.abyDstAddr[ii];
+    for(ii=0;ii<U_ETHER_ADDR_LEN;ii++)
+        *pbyRxBuffer++ = pDevice->sRxEthHeader.abySrcAddr[ii];
+
+    *pcbHeadSize = cbHeaderSize;
+}
+
+
+
+
+static BYTE s_byGetRateIdx (IN BYTE byRate)
+{
+    BYTE    byRateIdx;
+
+    for (byRateIdx = 0; byRateIdx <MAX_RATE ; byRateIdx++) {
+        if (acbyRxRate[byRateIdx%MAX_RATE] == byRate)
+            return byRateIdx;
+    }
+    return 0;
+}
+
+
+static
+VOID
+s_vGetDASA (
+    IN  PBYTE pbyRxBufferAddr,
+    OUT PUINT pcbHeaderSize,
+    OUT PSEthernetHeader psEthHeader
+    )
+{
+    UINT            cbHeaderSize = 0;
+    PS802_11Header  pMACHeader;
+    int             ii;
+
+    pMACHeader = (PS802_11Header) (pbyRxBufferAddr + cbHeaderSize);
+
+    if ((pMACHeader->wFrameCtl & FC_TODS) == 0) {
+        if (pMACHeader->wFrameCtl & FC_FROMDS) {
+            for(ii=0;ii<U_ETHER_ADDR_LEN;ii++) {
+                psEthHeader->abyDstAddr[ii] = pMACHeader->abyAddr1[ii];
+                psEthHeader->abySrcAddr[ii] = pMACHeader->abyAddr3[ii];
+            }
+        }
+        else {
+            // IBSS mode
+            for(ii=0;ii<U_ETHER_ADDR_LEN;ii++) {
+                psEthHeader->abyDstAddr[ii] = pMACHeader->abyAddr1[ii];
+                psEthHeader->abySrcAddr[ii] = pMACHeader->abyAddr2[ii];
+            }
+        }
+    }
+    else {
+        // Is AP mode..
+        if (pMACHeader->wFrameCtl & FC_FROMDS) {
+            for(ii=0;ii<U_ETHER_ADDR_LEN;ii++) {
+                psEthHeader->abyDstAddr[ii] = pMACHeader->abyAddr3[ii];
+                psEthHeader->abySrcAddr[ii] = pMACHeader->abyAddr4[ii];
+                cbHeaderSize += 6;
+            }
+        }
+        else {
+            for(ii=0;ii<U_ETHER_ADDR_LEN;ii++) {
+                psEthHeader->abyDstAddr[ii] = pMACHeader->abyAddr3[ii];
+                psEthHeader->abySrcAddr[ii] = pMACHeader->abyAddr2[ii];
+            }
+        }
+    };
+    *pcbHeaderSize = cbHeaderSize;
+}
+
+
+
+
+BOOL
+RXbBulkInProcessData (
+    IN PSDevice         pDevice,
+    IN PRCB             pRCB,
+    IN ULONG            BytesToIndicate
+    )
+{
+
+    struct net_device_stats* pStats=&pDevice->stats;
+    struct sk_buff* skb;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    PSRxMgmtPacket  pRxPacket = &(pMgmt->sRxPacket);
+    PS802_11Header  p802_11Header;
+    PBYTE           pbyRsr;
+    PBYTE           pbyNewRsr;
+    PBYTE           pbyRSSI;
+    PQWORD          pqwTSFTime;
+    PBYTE           pbyFrame;
+    BOOL            bDeFragRx = FALSE;
+    UINT            cbHeaderOffset;
+    UINT            FrameSize;
+    WORD            wEtherType = 0;
+    INT             iSANodeIndex = -1;
+    INT             iDANodeIndex = -1;
+    UINT            ii;
+    UINT            cbIVOffset;
+    PBYTE           pbyRxSts;
+    PBYTE           pbyRxRate;
+    PBYTE           pbySQ;
+#ifdef Calcu_LinkQual
+    PBYTE           pby3SQ;
+#endif
+    UINT            cbHeaderSize;
+    PSKeyItem       pKey = NULL;
+    WORD            wRxTSC15_0 = 0;
+    DWORD           dwRxTSC47_16 = 0;
+    SKeyItem        STempKey;
+    // 802.11h RPI
+    //LONG            ldBm = 0;
+    BOOL            bIsWEP = FALSE;
+    BOOL            bExtIV = FALSE;
+    DWORD           dwWbkStatus;
+    PRCB            pRCBIndicate = pRCB;
+    PBYTE           pbyDAddress;
+    PWORD           pwPLCP_Length;
+    BYTE            abyVaildRate[MAX_RATE] = {2,4,11,22,12,18,24,36,48,72,96,108};
+    WORD            wPLCPwithPadding;
+    PS802_11Header  pMACHeader;
+    BOOL            bRxeapol_key = FALSE;
+
+
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---------- RXbBulkInProcessData---\n");
+
+    skb = pRCB->skb;
+
+    //[31:16]RcvByteCount ( not include 4-byte Status )
+    dwWbkStatus =  *( (PDWORD)(skb->data) );
+    FrameSize = (UINT)(dwWbkStatus >> 16);
+    FrameSize += 4;
+
+    if (BytesToIndicate != FrameSize) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---------- WRONG Length 1 \n");
+        return FALSE;
+    }
+
+    if ((BytesToIndicate > 2372)||(BytesToIndicate <= 40)) {
+        // Frame Size error drop this packet.
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---------- WRONG Length 2 \n");
+        return FALSE;
+    }
+
+    pbyDAddress = (PBYTE)(skb->data);
+    pbyRxSts = pbyDAddress+4;
+    pbyRxRate = pbyDAddress+5;
+
+    //real Frame Size = USBFrameSize -4WbkStatus - 4RxStatus - 8TSF - 4RSR - 4SQ3 - ?Padding
+    //if SQ3 the range is 24~27, if no SQ3 the range is 20~23
+    //real Frame size in PLCPLength field.
+    pwPLCP_Length = (PWORD) (pbyDAddress + 6);
+    //Fix hardware bug => PLCP_Length error
+    if ( ((BytesToIndicate - (*pwPLCP_Length)) > 27) ||
+         ((BytesToIndicate - (*pwPLCP_Length)) < 24) ||
+         (BytesToIndicate < (*pwPLCP_Length)) ) {
+
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Wrong PLCP Length %x\n", (int) *pwPLCP_Length);
+        ASSERT(0);
+        return FALSE;
+    }
+    for ( ii=RATE_1M;ii<MAX_RATE;ii++) {
+        if ( *pbyRxRate == abyVaildRate[ii] ) {
+            break;
+        }
+    }
+    if ( ii==MAX_RATE ) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Wrong RxRate %x\n",(int) *pbyRxRate);
+        return FALSE;
+    }
+
+    wPLCPwithPadding = ( (*pwPLCP_Length / 4) + ( (*pwPLCP_Length % 4) ? 1:0 ) ) *4;
+
+    pqwTSFTime = (PQWORD) (pbyDAddress + 8 + wPLCPwithPadding);
+#ifdef Calcu_LinkQual
+  if(pDevice->byBBType == BB_TYPE_11G)  {
+      pby3SQ = pbyDAddress + 8 + wPLCPwithPadding + 12;
+      pbySQ = pby3SQ;
+    }
+  else {
+   pbySQ = pbyDAddress + 8 + wPLCPwithPadding + 8;
+   pby3SQ = pbySQ;
+  }
+#else
+    pbySQ = pbyDAddress + 8 + wPLCPwithPadding + 8;
+#endif
+    pbyNewRsr = pbyDAddress + 8 + wPLCPwithPadding + 9;
+    pbyRSSI = pbyDAddress + 8 + wPLCPwithPadding + 10;
+    pbyRsr = pbyDAddress + 8 + wPLCPwithPadding + 11;
+
+    FrameSize = *pwPLCP_Length;
+
+    pbyFrame = pbyDAddress + 8;
+    // update receive statistic counter
+
+    STAvUpdateRDStatCounter(&pDevice->scStatistic,
+                            *pbyRsr,
+                            *pbyNewRsr,
+                            *pbyRxSts,
+                            *pbyRxRate,
+                            pbyFrame,
+                            FrameSize
+                            );
+
+
+    pMACHeader = (PS802_11Header) pbyFrame;
+
+//mike add: to judge if current AP is activated?
+    if ((pMgmt->eCurrMode == WMAC_MODE_STANDBY) ||
+        (pMgmt->eCurrMode == WMAC_MODE_ESS_STA)) {
+       if (pMgmt->sNodeDBTable[0].bActive) {
+         if(IS_ETH_ADDRESS_EQUAL (pMgmt->abyCurrBSSID, pMACHeader->abyAddr2) ) {
+	    if (pMgmt->sNodeDBTable[0].uInActiveCount != 0)
+                  pMgmt->sNodeDBTable[0].uInActiveCount = 0;
+           }
+       }
+    }
+
+    if (!IS_MULTICAST_ADDRESS(pMACHeader->abyAddr1) && !IS_BROADCAST_ADDRESS(pMACHeader->abyAddr1)) {
+        if ( WCTLbIsDuplicate(&(pDevice->sDupRxCache), (PS802_11Header) pbyFrame) ) {
+            pDevice->s802_11Counter.FrameDuplicateCount++;
+            return FALSE;
+        }
+
+        if ( !IS_ETH_ADDRESS_EQUAL (pDevice->abyCurrentNetAddr, pMACHeader->abyAddr1) ) {
+            return FALSE;
+        }
+    }
+
+
+    // Use for TKIP MIC
+    s_vGetDASA(pbyFrame, &cbHeaderSize, &pDevice->sRxEthHeader);
+
+    if (IS_ETH_ADDRESS_EQUAL((PBYTE)&(pDevice->sRxEthHeader.abySrcAddr[0]), pDevice->abyCurrentNetAddr))
+        return FALSE;
+
+    if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) || (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) {
+        if (IS_CTL_PSPOLL(pbyFrame) || !IS_TYPE_CONTROL(pbyFrame)) {
+            p802_11Header = (PS802_11Header) (pbyFrame);
+            // get SA NodeIndex
+            if (BSSbIsSTAInNodeDB(pDevice, (PBYTE)(p802_11Header->abyAddr2), &iSANodeIndex)) {
+                pMgmt->sNodeDBTable[iSANodeIndex].ulLastRxJiffer = jiffies;
+                pMgmt->sNodeDBTable[iSANodeIndex].uInActiveCount = 0;
+            }
+        }
+    }
+
+    if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
+        if (s_bAPModeRxCtl(pDevice, pbyFrame, iSANodeIndex) == TRUE) {
+            return FALSE;
+        }
+    }
+
+
+    if (IS_FC_WEP(pbyFrame)) {
+        BOOL     bRxDecryOK = FALSE;
+
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"rx WEP pkt\n");
+        bIsWEP = TRUE;
+        if ((pDevice->bEnableHostWEP) && (iSANodeIndex >= 0)) {
+            pKey = &STempKey;
+            pKey->byCipherSuite = pMgmt->sNodeDBTable[iSANodeIndex].byCipherSuite;
+            pKey->dwKeyIndex = pMgmt->sNodeDBTable[iSANodeIndex].dwKeyIndex;
+            pKey->uKeyLength = pMgmt->sNodeDBTable[iSANodeIndex].uWepKeyLength;
+            pKey->dwTSC47_16 = pMgmt->sNodeDBTable[iSANodeIndex].dwTSC47_16;
+            pKey->wTSC15_0 = pMgmt->sNodeDBTable[iSANodeIndex].wTSC15_0;
+            memcpy(pKey->abyKey,
+                &pMgmt->sNodeDBTable[iSANodeIndex].abyWepKey[0],
+                pKey->uKeyLength
+                );
+
+            bRxDecryOK = s_bHostWepRxEncryption(pDevice,
+                                                pbyFrame,
+                                                FrameSize,
+                                                pbyRsr,
+                                                pMgmt->sNodeDBTable[iSANodeIndex].bOnFly,
+                                                pKey,
+                                                pbyNewRsr,
+                                                &bExtIV,
+                                                &wRxTSC15_0,
+                                                &dwRxTSC47_16);
+        } else {
+            bRxDecryOK = s_bHandleRxEncryption(pDevice,
+                                                pbyFrame,
+                                                FrameSize,
+                                                pbyRsr,
+                                                pbyNewRsr,
+                                                &pKey,
+                                                &bExtIV,
+                                                &wRxTSC15_0,
+                                                &dwRxTSC47_16);
+        }
+
+        if (bRxDecryOK) {
+            if ((*pbyNewRsr & NEWRSR_DECRYPTOK) == 0) {
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV Fail\n");
+                if ( (pMgmt->eAuthenMode == WMAC_AUTH_WPA) ||
+                    (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) ||
+                    (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) ||
+                    (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) ||
+                    (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) {
+
+                    if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_TKIP)) {
+                        pDevice->s802_11Counter.TKIPICVErrors++;
+                    } else if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_CCMP)) {
+                        pDevice->s802_11Counter.CCMPDecryptErrors++;
+                    } else if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_WEP)) {
+//                      pDevice->s802_11Counter.WEPICVErrorCount.QuadPart++;
+                    }
+                }
+                return FALSE;
+            }
+        } else {
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"WEP Func Fail\n");
+            return FALSE;
+        }
+        if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_CCMP))
+            FrameSize -= 8;         // Message Integrity Code
+        else
+            FrameSize -= 4;         // 4 is ICV
+    }
+
+
+    //
+    // RX OK
+    //
+    //remove the CRC length
+    FrameSize -= U_CRC_LEN;
+
+    if ((BITbIsAllBitsOff(*pbyRsr, (RSR_ADDRBROAD | RSR_ADDRMULTI))) && // unicast address
+        (IS_FRAGMENT_PKT((pbyFrame)))
+        ) {
+        // defragment
+        bDeFragRx = WCTLbHandleFragment(pDevice, (PS802_11Header) (pbyFrame), FrameSize, bIsWEP, bExtIV);
+        pDevice->s802_11Counter.ReceivedFragmentCount++;
+        if (bDeFragRx) {
+            // defrag complete
+            // TODO skb, pbyFrame
+            skb = pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].skb;
+            FrameSize = pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength;
+            pbyFrame = skb->data + 8;
+        }
+        else {
+            return FALSE;
+        }
+    }
+
+    //
+    // Management & Control frame Handle
+    //
+    if ((IS_TYPE_DATA((pbyFrame))) == FALSE) {
+        // Handle Control & Manage Frame
+
+        if (IS_TYPE_MGMT((pbyFrame))) {
+            PBYTE pbyData1;
+            PBYTE pbyData2;
+
+            pRxPacket = &(pRCB->sMngPacket);
+            pRxPacket->p80211Header = (PUWLAN_80211HDR)(pbyFrame);
+            pRxPacket->cbMPDULen = FrameSize;
+            pRxPacket->uRSSI = *pbyRSSI;
+            pRxPacket->bySQ = *pbySQ;
+            HIDWORD(pRxPacket->qwLocalTSF) = cpu_to_le32(HIDWORD(*pqwTSFTime));
+            LODWORD(pRxPacket->qwLocalTSF) = cpu_to_le32(LODWORD(*pqwTSFTime));
+            if (bIsWEP) {
+                // strip IV
+                pbyData1 = WLAN_HDR_A3_DATA_PTR(pbyFrame);
+                pbyData2 = WLAN_HDR_A3_DATA_PTR(pbyFrame) + 4;
+                for (ii = 0; ii < (FrameSize - 4); ii++) {
+                    *pbyData1 = *pbyData2;
+                     pbyData1++;
+                     pbyData2++;
+                }
+            }
+
+            pRxPacket->byRxRate = s_byGetRateIdx(*pbyRxRate);
+
+            if ( *pbyRxSts == 0 ) {
+                //Discard beacon packet which channel is 0
+                if ( (WLAN_GET_FC_FSTYPE((pRxPacket->p80211Header->sA3.wFrameCtl)) == WLAN_FSTYPE_BEACON) ||
+                     (WLAN_GET_FC_FSTYPE((pRxPacket->p80211Header->sA3.wFrameCtl)) == WLAN_FSTYPE_PROBERESP) ) {
+                    return TRUE;
+                }
+            }
+            pRxPacket->byRxChannel = (*pbyRxSts) >> 2;
+
+            // hostap Deamon handle 802.11 management
+            if (pDevice->bEnableHostapd) {
+	            skb->dev = pDevice->apdev;
+	            //skb->data += 4;
+	            //skb->tail += 4;
+	            skb->data += 8;
+	            skb->tail += 8;
+                skb_put(skb, FrameSize);
+//2008-4-3 modify by Chester for wpa
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
+	            skb->mac_header = skb->data;
+#else
+                    skb->mac.raw = skb->data;
+#endif
+	            skb->pkt_type = PACKET_OTHERHOST;
+    	        skb->protocol = htons(ETH_P_802_2);
+	            memset(skb->cb, 0, sizeof(skb->cb));
+	            netif_rx(skb);
+                return TRUE;
+	        }
+
+            //
+            // Insert the RCB in the Recv Mng list
+            //
+            EnqueueRCB(pDevice->FirstRecvMngList, pDevice->LastRecvMngList, pRCBIndicate);
+            pDevice->NumRecvMngList++;
+            if ( bDeFragRx == FALSE) {
+                pRCB->Ref++;
+            }
+            if (pDevice->bIsRxMngWorkItemQueued == FALSE) {
+                pDevice->bIsRxMngWorkItemQueued = TRUE;
+                tasklet_schedule(&pDevice->RxMngWorkItem);
+            }
+
+        }
+        else {
+            // Control Frame
+        };
+        return FALSE;
+    }
+    else {
+        if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
+            //In AP mode, hw only check addr1(BSSID or RA) if equal to local MAC.
+            if (BITbIsBitOff(*pbyRsr, RSR_BSSIDOK)) {
+                if (bDeFragRx) {
+                    if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
+                        DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
+                        pDevice->dev->name);
+                    }
+                }
+                return FALSE;
+            }
+        }
+        else {
+            // discard DATA packet while not associate || BSSID error
+            if ((pDevice->bLinkPass == FALSE) ||
+                BITbIsBitOff(*pbyRsr, RSR_BSSIDOK)) {
+                if (bDeFragRx) {
+                    if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
+                        DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
+                        pDevice->dev->name);
+                    }
+                }
+                return FALSE;
+            }
+   //mike add:station mode check eapol-key challenge--->
+   	  {
+   	    BYTE  Protocol_Version;    //802.1x Authentication
+	    BYTE  Packet_Type;           //802.1x Authentication
+	    BYTE  Descriptor_type;
+             WORD Key_info;
+              if (bIsWEP)
+                  cbIVOffset = 8;
+              else
+                  cbIVOffset = 0;
+              wEtherType = (skb->data[cbIVOffset + 8 + 24 + 6] << 8) |
+                          skb->data[cbIVOffset + 8 + 24 + 6 + 1];
+	      Protocol_Version = skb->data[cbIVOffset + 8 + 24 + 6 + 1 +1];
+	      Packet_Type = skb->data[cbIVOffset + 8 + 24 + 6 + 1 +1+1];
+	     if (wEtherType == ETH_P_PAE) {         //Protocol Type in LLC-Header
+                  if(((Protocol_Version==1) ||(Protocol_Version==2)) &&
+		     (Packet_Type==3)) {  //802.1x OR eapol-key challenge frame receive
+                        bRxeapol_key = TRUE;
+		      Descriptor_type = skb->data[cbIVOffset + 8 + 24 + 6 + 1 +1+1+1+2];
+		      Key_info = (skb->data[cbIVOffset + 8 + 24 + 6 + 1 +1+1+1+2+1]<<8) |skb->data[cbIVOffset + 8 + 24 + 6 + 1 +1+1+1+2+2] ;
+		      if(Descriptor_type==2) {    //RSN
+                         //  printk("WPA2_Rx_eapol-key_info<-----:%x\n",Key_info);
+		      }
+		     else  if(Descriptor_type==254) {
+                        //  printk("WPA_Rx_eapol-key_info<-----:%x\n",Key_info);
+		     }
+                  }
+	      }
+   	  }
+    //mike add:station mode check eapol-key challenge<---
+        }
+    }
+
+
+// Data frame Handle
+
+
+    if (pDevice->bEnablePSMode) {
+        if (IS_FC_MOREDATA((pbyFrame))) {
+            if (BITbIsBitOn(*pbyRsr, RSR_ADDROK)) {
+                //PSbSendPSPOLL((PSDevice)pDevice);
+            }
+        }
+        else {
+            if (pMgmt->bInTIMWake == TRUE) {
+                pMgmt->bInTIMWake = FALSE;
+            }
+        }
+    };
+
+    // Now it only supports 802.11g Infrastructure Mode, and support rate must up to 54 Mbps
+    if (pDevice->bDiversityEnable && (FrameSize>50) &&
+       (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) &&
+       (pDevice->bLinkPass == TRUE)) {
+        BBvAntennaDiversity(pDevice, s_byGetRateIdx(*pbyRxRate), 0);
+    }
+
+    // ++++++++ For BaseBand Algorithm +++++++++++++++
+    pDevice->uCurrRSSI = *pbyRSSI;
+    pDevice->byCurrSQ = *pbySQ;
+
+    // todo
+/*
+    if ((*pbyRSSI != 0) &&
+        (pMgmt->pCurrBSS!=NULL)) {
+        RFvRSSITodBm(pDevice, *pbyRSSI, &ldBm);
+        // Moniter if RSSI is too strong.
+        pMgmt->pCurrBSS->byRSSIStatCnt++;
+        pMgmt->pCurrBSS->byRSSIStatCnt %= RSSI_STAT_COUNT;
+        pMgmt->pCurrBSS->ldBmAverage[pMgmt->pCurrBSS->byRSSIStatCnt] = ldBm;
+        for(ii=0;ii<RSSI_STAT_COUNT;ii++) {
+            if (pMgmt->pCurrBSS->ldBmAverage[ii] != 0) {
+            pMgmt->pCurrBSS->ldBmMAX = max(pMgmt->pCurrBSS->ldBmAverage[ii], ldBm);
+            }
+        }
+    }
+*/
+
+
+    // -----------------------------------------------
+
+    if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && (pDevice->bEnable8021x == TRUE)){
+        BYTE    abyMacHdr[24];
+
+        // Only 802.1x packet incoming allowed
+        if (bIsWEP)
+            cbIVOffset = 8;
+        else
+            cbIVOffset = 0;
+        wEtherType = (skb->data[cbIVOffset + 8 + 24 + 6] << 8) |
+                    skb->data[cbIVOffset + 8 + 24 + 6 + 1];
+
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wEtherType = %04x \n", wEtherType);
+        if (wEtherType == ETH_P_PAE) {
+            skb->dev = pDevice->apdev;
+
+            if (bIsWEP == TRUE) {
+                // strip IV header(8)
+                memcpy(&abyMacHdr[0], (skb->data + 8), 24);
+                memcpy((skb->data + 8 + cbIVOffset), &abyMacHdr[0], 24);
+            }
+
+            skb->data +=  (cbIVOffset + 8);
+            skb->tail +=  (cbIVOffset + 8);
+            skb_put(skb, FrameSize);
+//2008-4-3 modify by Chester for wpa
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
+            skb->mac_header = skb->data;
+#else
+           skb->mac.raw = skb->data;
+#endif
+            skb->pkt_type = PACKET_OTHERHOST;
+            skb->protocol = htons(ETH_P_802_2);
+            memset(skb->cb, 0, sizeof(skb->cb));
+            netif_rx(skb);
+            return TRUE;
+
+        }
+        // check if 802.1x authorized
+        if (!(pMgmt->sNodeDBTable[iSANodeIndex].dwFlags & WLAN_STA_AUTHORIZED))
+            return FALSE;
+    }
+
+
+    if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_TKIP)) {
+        if (bIsWEP) {
+            FrameSize -= 8;  //MIC
+        }
+    }
+
+    //--------------------------------------------------------------------------------
+    // Soft MIC
+    if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_TKIP)) {
+        if (bIsWEP) {
+            PDWORD          pdwMIC_L;
+            PDWORD          pdwMIC_R;
+            DWORD           dwMIC_Priority;
+            DWORD           dwMICKey0 = 0, dwMICKey1 = 0;
+            DWORD           dwLocalMIC_L = 0;
+            DWORD           dwLocalMIC_R = 0;
+            viawget_wpa_header *wpahdr;
+
+
+            if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
+                dwMICKey0 = cpu_to_le32(*(PDWORD)(&pKey->abyKey[24]));
+                dwMICKey1 = cpu_to_le32(*(PDWORD)(&pKey->abyKey[28]));
+            }
+            else {
+                if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
+                    dwMICKey0 = cpu_to_le32(*(PDWORD)(&pKey->abyKey[16]));
+                    dwMICKey1 = cpu_to_le32(*(PDWORD)(&pKey->abyKey[20]));
+                } else if ((pKey->dwKeyIndex & BIT28) == 0) {
+                    dwMICKey0 = cpu_to_le32(*(PDWORD)(&pKey->abyKey[16]));
+                    dwMICKey1 = cpu_to_le32(*(PDWORD)(&pKey->abyKey[20]));
+                } else {
+                    dwMICKey0 = cpu_to_le32(*(PDWORD)(&pKey->abyKey[24]));
+                    dwMICKey1 = cpu_to_le32(*(PDWORD)(&pKey->abyKey[28]));
+                }
+            }
+
+            MIC_vInit(dwMICKey0, dwMICKey1);
+            MIC_vAppend((PBYTE)&(pDevice->sRxEthHeader.abyDstAddr[0]), 12);
+            dwMIC_Priority = 0;
+            MIC_vAppend((PBYTE)&dwMIC_Priority, 4);
+            // 4 is Rcv buffer header, 24 is MAC Header, and 8 is IV and Ext IV.
+            MIC_vAppend((PBYTE)(skb->data + 8 + WLAN_HDR_ADDR3_LEN + 8),
+                        FrameSize - WLAN_HDR_ADDR3_LEN - 8);
+            MIC_vGetMIC(&dwLocalMIC_L, &dwLocalMIC_R);
+            MIC_vUnInit();
+
+            pdwMIC_L = (PDWORD)(skb->data + 8 + FrameSize);
+            pdwMIC_R = (PDWORD)(skb->data + 8 + FrameSize + 4);
+
+
+            if ((cpu_to_le32(*pdwMIC_L) != dwLocalMIC_L) || (cpu_to_le32(*pdwMIC_R) != dwLocalMIC_R) ||
+                (pDevice->bRxMICFail == TRUE)) {
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC comparison is fail!\n");
+                pDevice->bRxMICFail = FALSE;
+                //pDevice->s802_11Counter.TKIPLocalMICFailures.QuadPart++;
+                pDevice->s802_11Counter.TKIPLocalMICFailures++;
+                if (bDeFragRx) {
+                    if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
+                        DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
+                            pDevice->dev->name);
+                    }
+                }
+		//2008-0409-07, <Add> by Einsn Liu
+       #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+				//send event to wpa_supplicant
+				//if(pDevice->bWPASuppWextEnabled == TRUE)
+				{
+					union iwreq_data wrqu;
+					struct iw_michaelmicfailure ev;
+					int keyidx = pbyFrame[cbHeaderSize+3] >> 6; //top two-bits
+					memset(&ev, 0, sizeof(ev));
+					ev.flags = keyidx & IW_MICFAILURE_KEY_ID;
+					if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
+							(pMgmt->eCurrState == WMAC_STATE_ASSOC) &&
+								(*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI)) == 0) {
+						ev.flags |= IW_MICFAILURE_PAIRWISE;
+					} else {
+						ev.flags |= IW_MICFAILURE_GROUP;
+					}
+
+					ev.src_addr.sa_family = ARPHRD_ETHER;
+					memcpy(ev.src_addr.sa_data, pMACHeader->abyAddr2, ETH_ALEN);
+					memset(&wrqu, 0, sizeof(wrqu));
+					wrqu.data.length = sizeof(ev);
+			PRINT_K("wireless_send_event--->IWEVMICHAELMICFAILURE\n");
+					wireless_send_event(pDevice->dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&ev);
+
+				}
+         #endif
+
+
+                if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) {
+                     wpahdr = (viawget_wpa_header *)pDevice->skb->data;
+                     if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
+                         (pMgmt->eCurrState == WMAC_STATE_ASSOC) &&
+                         (*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI)) == 0) {
+                         //s802_11_Status.Flags = NDIS_802_11_AUTH_REQUEST_PAIRWISE_ERROR;
+                         wpahdr->type = VIAWGET_PTK_MIC_MSG;
+                     } else {
+                         //s802_11_Status.Flags = NDIS_802_11_AUTH_REQUEST_GROUP_ERROR;
+                         wpahdr->type = VIAWGET_GTK_MIC_MSG;
+                     }
+                     wpahdr->resp_ie_len = 0;
+                     wpahdr->req_ie_len = 0;
+                     skb_put(pDevice->skb, sizeof(viawget_wpa_header));
+                     pDevice->skb->dev = pDevice->wpadev;
+//2008-4-3 modify by Chester for wpa
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
+                   pDevice->skb->mac_header = pDevice->skb->data;
+#else
+                   pDevice->skb->mac.raw = pDevice->skb->data;
+#endif
+                     pDevice->skb->pkt_type = PACKET_HOST;
+                     pDevice->skb->protocol = htons(ETH_P_802_2);
+                     memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
+                     netif_rx(pDevice->skb);
+                     pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
+                 };
+
+                return FALSE;
+
+            }
+        }
+    } //---end of SOFT MIC-----------------------------------------------------------------------
+
+    // ++++++++++ Reply Counter Check +++++++++++++
+
+    if ((pKey != NULL) && ((pKey->byCipherSuite == KEY_CTL_TKIP) ||
+                           (pKey->byCipherSuite == KEY_CTL_CCMP))) {
+        if (bIsWEP) {
+            WORD        wLocalTSC15_0 = 0;
+            DWORD       dwLocalTSC47_16 = 0;
+            ULONGLONG       RSC = 0;
+            // endian issues
+            RSC = *((ULONGLONG *) &(pKey->KeyRSC));
+            wLocalTSC15_0 = (WORD) RSC;
+            dwLocalTSC47_16 = (DWORD) (RSC>>16);
+
+            RSC = dwRxTSC47_16;
+            RSC <<= 16;
+            RSC += wRxTSC15_0;
+            MEMvCopy(&(pKey->KeyRSC), &RSC,  sizeof(QWORD));
+
+            if ( (pDevice->sMgmtObj.eCurrMode == WMAC_MODE_ESS_STA) &&
+                 (pDevice->sMgmtObj.eCurrState == WMAC_STATE_ASSOC)) {
+                // check RSC
+                if ( (wRxTSC15_0 < wLocalTSC15_0) &&
+                     (dwRxTSC47_16 <= dwLocalTSC47_16) &&
+                     !((dwRxTSC47_16 == 0) && (dwLocalTSC47_16 == 0xFFFFFFFF))) {
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"TSC is illegal~~!\n ");
+                    if (pKey->byCipherSuite == KEY_CTL_TKIP)
+                        //pDevice->s802_11Counter.TKIPReplays.QuadPart++;
+                        pDevice->s802_11Counter.TKIPReplays++;
+                    else
+                        //pDevice->s802_11Counter.CCMPReplays.QuadPart++;
+                        pDevice->s802_11Counter.CCMPReplays++;
+
+                    if (bDeFragRx) {
+                        if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
+                            DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
+                                pDevice->dev->name);
+                        }
+                    }
+                    return FALSE;
+                }
+            }
+        }
+    } // ----- End of Reply Counter Check --------------------------
+
+
+    s_vProcessRxMACHeader(pDevice, (PBYTE)(skb->data+8), FrameSize, bIsWEP, bExtIV, &cbHeaderOffset);
+    FrameSize -= cbHeaderOffset;
+    cbHeaderOffset += 8;        // 8 is Rcv buffer header
+
+    // Null data, framesize = 12
+    if (FrameSize < 12)
+        return FALSE;
+
+    if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
+        if (s_bAPModeRxData(pDevice,
+                            skb,
+                            FrameSize,
+                            cbHeaderOffset,
+                            iSANodeIndex,
+                            iDANodeIndex
+                            ) == FALSE) {
+
+            if (bDeFragRx) {
+                if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
+                    DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
+                    pDevice->dev->name);
+                }
+            }
+            return FALSE;
+        }
+
+    }
+
+	skb->data += cbHeaderOffset;
+	skb->tail += cbHeaderOffset;
+    skb_put(skb, FrameSize);
+    skb->protocol=eth_type_trans(skb, skb->dev);
+    skb->ip_summed=CHECKSUM_NONE;
+    pStats->rx_bytes +=skb->len;
+    pStats->rx_packets++;
+    netif_rx(skb);
+    if (bDeFragRx) {
+        if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
+            DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
+                pDevice->dev->name);
+        }
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+
+static BOOL s_bAPModeRxCtl (
+    IN PSDevice pDevice,
+    IN PBYTE    pbyFrame,
+    IN INT      iSANodeIndex
+    )
+{
+    PS802_11Header      p802_11Header;
+    CMD_STATUS          Status;
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+
+
+    if (IS_CTL_PSPOLL(pbyFrame) || !IS_TYPE_CONTROL(pbyFrame)) {
+
+        p802_11Header = (PS802_11Header) (pbyFrame);
+        if (!IS_TYPE_MGMT(pbyFrame)) {
+
+            // Data & PS-Poll packet
+            // check frame class
+            if (iSANodeIndex > 0) {
+                // frame class 3 fliter & checking
+                if (pMgmt->sNodeDBTable[iSANodeIndex].eNodeState < NODE_AUTH) {
+                    // send deauth notification
+                    // reason = (6) class 2 received from nonauth sta
+                    vMgrDeAuthenBeginSta(pDevice,
+                                         pMgmt,
+                                         (PBYTE)(p802_11Header->abyAddr2),
+                                         (WLAN_MGMT_REASON_CLASS2_NONAUTH),
+                                         &Status
+                                         );
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: send vMgrDeAuthenBeginSta 1\n");
+                    return TRUE;
+                };
+                if (pMgmt->sNodeDBTable[iSANodeIndex].eNodeState < NODE_ASSOC) {
+                    // send deassoc notification
+                    // reason = (7) class 3 received from nonassoc sta
+                    vMgrDisassocBeginSta(pDevice,
+                                         pMgmt,
+                                         (PBYTE)(p802_11Header->abyAddr2),
+                                         (WLAN_MGMT_REASON_CLASS3_NONASSOC),
+                                         &Status
+                                         );
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: send vMgrDisassocBeginSta 2\n");
+                    return TRUE;
+                };
+
+                if (pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable) {
+                    // delcare received ps-poll event
+                    if (IS_CTL_PSPOLL(pbyFrame)) {
+                        pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = TRUE;
+                        bScheduleCommand((HANDLE)pDevice, WLAN_CMD_RX_PSPOLL, NULL);
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: WLAN_CMD_RX_PSPOLL 1\n");
+                    }
+                    else {
+                        // check Data PS state
+                        // if PW bit off, send out all PS bufferring packets.
+                        if (!IS_FC_POWERMGT(pbyFrame)) {
+                            pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = FALSE;
+                            pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = TRUE;
+                            bScheduleCommand((HANDLE)pDevice, WLAN_CMD_RX_PSPOLL, NULL);
+                            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: WLAN_CMD_RX_PSPOLL 2\n");
+                        }
+                    }
+                }
+                else {
+                   if (IS_FC_POWERMGT(pbyFrame)) {
+                       pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = TRUE;
+                       // Once if STA in PS state, enable multicast bufferring
+                       pMgmt->sNodeDBTable[0].bPSEnable = TRUE;
+                   }
+                   else {
+                      // clear all pending PS frame.
+                      if (pMgmt->sNodeDBTable[iSANodeIndex].wEnQueueCnt > 0) {
+                          pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = FALSE;
+                          pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = TRUE;
+                          bScheduleCommand((HANDLE)pDevice, WLAN_CMD_RX_PSPOLL, NULL);
+                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: WLAN_CMD_RX_PSPOLL 3\n");
+
+                      }
+                   }
+                }
+            }
+            else {
+                  vMgrDeAuthenBeginSta(pDevice,
+                                       pMgmt,
+                                       (PBYTE)(p802_11Header->abyAddr2),
+                                       (WLAN_MGMT_REASON_CLASS2_NONAUTH),
+                                       &Status
+                                       );
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: send vMgrDeAuthenBeginSta 3\n");
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BSSID:%02x-%02x-%02x=%02x-%02x-%02x \n",
+                                p802_11Header->abyAddr3[0],
+                                p802_11Header->abyAddr3[1],
+                                p802_11Header->abyAddr3[2],
+                                p802_11Header->abyAddr3[3],
+                                p802_11Header->abyAddr3[4],
+                                p802_11Header->abyAddr3[5]
+                               );
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ADDR2:%02x-%02x-%02x=%02x-%02x-%02x \n",
+                                p802_11Header->abyAddr2[0],
+                                p802_11Header->abyAddr2[1],
+                                p802_11Header->abyAddr2[2],
+                                p802_11Header->abyAddr2[3],
+                                p802_11Header->abyAddr2[4],
+                                p802_11Header->abyAddr2[5]
+                               );
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ADDR1:%02x-%02x-%02x=%02x-%02x-%02x \n",
+                                p802_11Header->abyAddr1[0],
+                                p802_11Header->abyAddr1[1],
+                                p802_11Header->abyAddr1[2],
+                                p802_11Header->abyAddr1[3],
+                                p802_11Header->abyAddr1[4],
+                                p802_11Header->abyAddr1[5]
+                               );
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: wFrameCtl= %x\n", p802_11Header->wFrameCtl );
+                    return TRUE;
+            }
+        }
+    }
+    return FALSE;
+
+}
+
+static BOOL s_bHandleRxEncryption (
+    IN PSDevice     pDevice,
+    IN PBYTE        pbyFrame,
+    IN UINT         FrameSize,
+    IN PBYTE        pbyRsr,
+    OUT PBYTE       pbyNewRsr,
+    OUT PSKeyItem   *pKeyOut,
+    OUT PBOOL       pbExtIV,
+    OUT PWORD       pwRxTSC15_0,
+    OUT PDWORD      pdwRxTSC47_16
+    )
+{
+    UINT            PayloadLen = FrameSize;
+    PBYTE           pbyIV;
+    BYTE            byKeyIdx;
+    PSKeyItem       pKey = NULL;
+    BYTE            byDecMode = KEY_CTL_WEP;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+
+
+    *pwRxTSC15_0 = 0;
+    *pdwRxTSC47_16 = 0;
+
+    pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN;
+    if ( WLAN_GET_FC_TODS(*(PWORD)pbyFrame) &&
+         WLAN_GET_FC_FROMDS(*(PWORD)pbyFrame) ) {
+         pbyIV += 6;             // 6 is 802.11 address4
+         PayloadLen -= 6;
+    }
+    byKeyIdx = (*(pbyIV+3) & 0xc0);
+    byKeyIdx >>= 6;
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\nKeyIdx: %d\n", byKeyIdx);
+
+    if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA) ||
+        (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) ||
+        (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) ||
+        (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) ||
+        (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) {
+        if (((*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI)) == 0) &&
+            (pMgmt->byCSSPK != KEY_CTL_NONE)) {
+            // unicast pkt use pairwise key
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"unicast pkt\n");
+            if (KeybGetKey(&(pDevice->sKey), pDevice->abyBSSID, 0xFFFFFFFF, &pKey) == TRUE) {
+                if (pMgmt->byCSSPK == KEY_CTL_TKIP)
+                    byDecMode = KEY_CTL_TKIP;
+                else if (pMgmt->byCSSPK == KEY_CTL_CCMP)
+                    byDecMode = KEY_CTL_CCMP;
+            }
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"unicast pkt: %d, %p\n", byDecMode, pKey);
+        } else {
+            // use group key
+            KeybGetKey(&(pDevice->sKey), pDevice->abyBSSID, byKeyIdx, &pKey);
+            if (pMgmt->byCSSGK == KEY_CTL_TKIP)
+                byDecMode = KEY_CTL_TKIP;
+            else if (pMgmt->byCSSGK == KEY_CTL_CCMP)
+                byDecMode = KEY_CTL_CCMP;
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"group pkt: %d, %d, %p\n", byKeyIdx, byDecMode, pKey);
+        }
+    }
+    // our WEP only support Default Key
+    if (pKey == NULL) {
+        // use default group key
+        KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, byKeyIdx, &pKey);
+        if (pMgmt->byCSSGK == KEY_CTL_TKIP)
+            byDecMode = KEY_CTL_TKIP;
+        else if (pMgmt->byCSSGK == KEY_CTL_CCMP)
+            byDecMode = KEY_CTL_CCMP;
+    }
+    *pKeyOut = pKey;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"AES:%d %d %d\n", pMgmt->byCSSPK, pMgmt->byCSSGK, byDecMode);
+
+    if (pKey == NULL) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey == NULL\n");
+        if (byDecMode == KEY_CTL_WEP) {
+//            pDevice->s802_11Counter.WEPUndecryptableCount.QuadPart++;
+        } else if (pDevice->bLinkPass == TRUE) {
+//            pDevice->s802_11Counter.DecryptFailureCount.QuadPart++;
+        }
+        return FALSE;
+    }
+    if (byDecMode != pKey->byCipherSuite) {
+        if (byDecMode == KEY_CTL_WEP) {
+//            pDevice->s802_11Counter.WEPUndecryptableCount.QuadPart++;
+        } else if (pDevice->bLinkPass == TRUE) {
+//            pDevice->s802_11Counter.DecryptFailureCount.QuadPart++;
+        }
+        *pKeyOut = NULL;
+        return FALSE;
+    }
+    if (byDecMode == KEY_CTL_WEP) {
+        // handle WEP
+        if ((pDevice->byLocalID <= REV_ID_VT3253_A1) ||
+            (((PSKeyTable)(pKey->pvKeyTable))->bSoftWEP == TRUE)) {
+            // Software WEP
+            // 1. 3253A
+            // 2. WEP 256
+
+            PayloadLen -= (WLAN_HDR_ADDR3_LEN + 4 + 4); // 24 is 802.11 header,4 is IV, 4 is crc
+            MEMvCopy(pDevice->abyPRNG, pbyIV, 3);
+            MEMvCopy(pDevice->abyPRNG + 3, pKey->abyKey, pKey->uKeyLength);
+            rc4_init(&pDevice->SBox, pDevice->abyPRNG, pKey->uKeyLength + 3);
+            rc4_encrypt(&pDevice->SBox, pbyIV+4, pbyIV+4, PayloadLen);
+
+            if (ETHbIsBufferCrc32Ok(pbyIV+4, PayloadLen)) {
+                *pbyNewRsr |= NEWRSR_DECRYPTOK;
+            }
+        }
+    } else if ((byDecMode == KEY_CTL_TKIP) ||
+               (byDecMode == KEY_CTL_CCMP)) {
+        // TKIP/AES
+
+        PayloadLen -= (WLAN_HDR_ADDR3_LEN + 8 + 4); // 24 is 802.11 header, 8 is IV&ExtIV, 4 is crc
+        *pdwRxTSC47_16 = cpu_to_le32(*(PDWORD)(pbyIV + 4));
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ExtIV: %lx\n",*pdwRxTSC47_16);
+        if (byDecMode == KEY_CTL_TKIP) {
+            *pwRxTSC15_0 = cpu_to_le16(MAKEWORD(*(pbyIV+2), *pbyIV));
+        } else {
+            *pwRxTSC15_0 = cpu_to_le16(*(PWORD)pbyIV);
+        }
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"TSC0_15: %x\n", *pwRxTSC15_0);
+
+        if ((byDecMode == KEY_CTL_TKIP) &&
+            (pDevice->byLocalID <= REV_ID_VT3253_A1)) {
+            // Software TKIP
+            // 1. 3253 A
+            PS802_11Header  pMACHeader = (PS802_11Header) (pbyFrame);
+            TKIPvMixKey(pKey->abyKey, pMACHeader->abyAddr2, *pwRxTSC15_0, *pdwRxTSC47_16, pDevice->abyPRNG);
+            rc4_init(&pDevice->SBox, pDevice->abyPRNG, TKIP_KEY_LEN);
+            rc4_encrypt(&pDevice->SBox, pbyIV+8, pbyIV+8, PayloadLen);
+            if (ETHbIsBufferCrc32Ok(pbyIV+8, PayloadLen)) {
+                *pbyNewRsr |= NEWRSR_DECRYPTOK;
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV OK!\n");
+            } else {
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV FAIL!!!\n");
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"PayloadLen = %d\n", PayloadLen);
+            }
+        }
+    }// end of TKIP/AES
+
+    if ((*(pbyIV+3) & 0x20) != 0)
+        *pbExtIV = TRUE;
+    return TRUE;
+}
+
+
+static BOOL s_bHostWepRxEncryption (
+    IN PSDevice     pDevice,
+    IN PBYTE        pbyFrame,
+    IN UINT         FrameSize,
+    IN PBYTE        pbyRsr,
+    IN BOOL         bOnFly,
+    IN PSKeyItem    pKey,
+    OUT PBYTE       pbyNewRsr,
+    OUT PBOOL       pbExtIV,
+    OUT PWORD       pwRxTSC15_0,
+    OUT PDWORD      pdwRxTSC47_16
+    )
+{
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    UINT            PayloadLen = FrameSize;
+    PBYTE           pbyIV;
+    BYTE            byKeyIdx;
+    BYTE            byDecMode = KEY_CTL_WEP;
+    PS802_11Header  pMACHeader;
+
+
+
+    *pwRxTSC15_0 = 0;
+    *pdwRxTSC47_16 = 0;
+
+    pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN;
+    if ( WLAN_GET_FC_TODS(*(PWORD)pbyFrame) &&
+         WLAN_GET_FC_FROMDS(*(PWORD)pbyFrame) ) {
+         pbyIV += 6;             // 6 is 802.11 address4
+         PayloadLen -= 6;
+    }
+    byKeyIdx = (*(pbyIV+3) & 0xc0);
+    byKeyIdx >>= 6;
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\nKeyIdx: %d\n", byKeyIdx);
+
+
+    if (pMgmt->byCSSGK == KEY_CTL_TKIP)
+        byDecMode = KEY_CTL_TKIP;
+    else if (pMgmt->byCSSGK == KEY_CTL_CCMP)
+        byDecMode = KEY_CTL_CCMP;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"AES:%d %d %d\n", pMgmt->byCSSPK, pMgmt->byCSSGK, byDecMode);
+
+    if (byDecMode != pKey->byCipherSuite) {
+        if (byDecMode == KEY_CTL_WEP) {
+//            pDevice->s802_11Counter.WEPUndecryptableCount.QuadPart++;
+        } else if (pDevice->bLinkPass == TRUE) {
+//            pDevice->s802_11Counter.DecryptFailureCount.QuadPart++;
+        }
+        return FALSE;
+    }
+
+    if (byDecMode == KEY_CTL_WEP) {
+        // handle WEP
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"byDecMode == KEY_CTL_WEP \n");
+        if ((pDevice->byLocalID <= REV_ID_VT3253_A1) ||
+            (((PSKeyTable)(pKey->pvKeyTable))->bSoftWEP == TRUE) ||
+            (bOnFly == FALSE)) {
+            // Software WEP
+            // 1. 3253A
+            // 2. WEP 256
+            // 3. NotOnFly
+
+            PayloadLen -= (WLAN_HDR_ADDR3_LEN + 4 + 4); // 24 is 802.11 header,4 is IV, 4 is crc
+            MEMvCopy(pDevice->abyPRNG, pbyIV, 3);
+            MEMvCopy(pDevice->abyPRNG + 3, pKey->abyKey, pKey->uKeyLength);
+            rc4_init(&pDevice->SBox, pDevice->abyPRNG, pKey->uKeyLength + 3);
+            rc4_encrypt(&pDevice->SBox, pbyIV+4, pbyIV+4, PayloadLen);
+
+            if (ETHbIsBufferCrc32Ok(pbyIV+4, PayloadLen)) {
+                *pbyNewRsr |= NEWRSR_DECRYPTOK;
+            }
+        }
+    } else if ((byDecMode == KEY_CTL_TKIP) ||
+               (byDecMode == KEY_CTL_CCMP)) {
+        // TKIP/AES
+
+        PayloadLen -= (WLAN_HDR_ADDR3_LEN + 8 + 4); // 24 is 802.11 header, 8 is IV&ExtIV, 4 is crc
+        *pdwRxTSC47_16 = cpu_to_le32(*(PDWORD)(pbyIV + 4));
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ExtIV: %lx\n",*pdwRxTSC47_16);
+
+        if (byDecMode == KEY_CTL_TKIP) {
+            *pwRxTSC15_0 = cpu_to_le16(MAKEWORD(*(pbyIV+2), *pbyIV));
+        } else {
+            *pwRxTSC15_0 = cpu_to_le16(*(PWORD)pbyIV);
+        }
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"TSC0_15: %x\n", *pwRxTSC15_0);
+
+        if (byDecMode == KEY_CTL_TKIP) {
+
+            if ((pDevice->byLocalID <= REV_ID_VT3253_A1) || (bOnFly == FALSE)) {
+                // Software TKIP
+                // 1. 3253 A
+                // 2. NotOnFly
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"soft KEY_CTL_TKIP \n");
+                pMACHeader = (PS802_11Header) (pbyFrame);
+                TKIPvMixKey(pKey->abyKey, pMACHeader->abyAddr2, *pwRxTSC15_0, *pdwRxTSC47_16, pDevice->abyPRNG);
+                rc4_init(&pDevice->SBox, pDevice->abyPRNG, TKIP_KEY_LEN);
+                rc4_encrypt(&pDevice->SBox, pbyIV+8, pbyIV+8, PayloadLen);
+                if (ETHbIsBufferCrc32Ok(pbyIV+8, PayloadLen)) {
+                    *pbyNewRsr |= NEWRSR_DECRYPTOK;
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV OK!\n");
+                } else {
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV FAIL!!!\n");
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"PayloadLen = %d\n", PayloadLen);
+                }
+            }
+        }
+
+        if (byDecMode == KEY_CTL_CCMP) {
+            if (bOnFly == FALSE) {
+                // Software CCMP
+                // NotOnFly
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"soft KEY_CTL_CCMP\n");
+                if (AESbGenCCMP(pKey->abyKey, pbyFrame, FrameSize)) {
+                    *pbyNewRsr |= NEWRSR_DECRYPTOK;
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"CCMP MIC compare OK!\n");
+                } else {
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"CCMP MIC fail!\n");
+                }
+            }
+        }
+
+    }// end of TKIP/AES
+
+    if ((*(pbyIV+3) & 0x20) != 0)
+        *pbExtIV = TRUE;
+    return TRUE;
+}
+
+
+
+static BOOL s_bAPModeRxData (
+    IN PSDevice pDevice,
+    IN struct sk_buff* skb,
+    IN UINT     FrameSize,
+    IN UINT     cbHeaderOffset,
+    IN INT      iSANodeIndex,
+    IN INT      iDANodeIndex
+    )
+
+{
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+    BOOL                bRelayAndForward = FALSE;
+    BOOL                bRelayOnly = FALSE;
+    BYTE                byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
+    WORD                wAID;
+
+
+    struct sk_buff* skbcpy = NULL;
+
+    if (FrameSize > CB_MAX_BUF_SIZE)
+        return FALSE;
+    // check DA
+    if(IS_MULTICAST_ADDRESS((PBYTE)(skb->data+cbHeaderOffset))) {
+       if (pMgmt->sNodeDBTable[0].bPSEnable) {
+
+           skbcpy = dev_alloc_skb((int)pDevice->rx_buf_sz);
+
+        // if any node in PS mode, buffer packet until DTIM.
+           if (skbcpy == NULL) {
+               DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "relay multicast no skb available \n");
+           }
+           else {
+               skbcpy->dev = pDevice->dev;
+               skbcpy->len = FrameSize;
+               memcpy(skbcpy->data, skb->data+cbHeaderOffset, FrameSize);
+               skb_queue_tail(&(pMgmt->sNodeDBTable[0].sTxPSQueue), skbcpy);
+               pMgmt->sNodeDBTable[0].wEnQueueCnt++;
+               // set tx map
+               pMgmt->abyPSTxMap[0] |= byMask[0];
+           }
+       }
+       else {
+           bRelayAndForward = TRUE;
+       }
+    }
+    else {
+        // check if relay
+        if (BSSbIsSTAInNodeDB(pDevice, (PBYTE)(skb->data+cbHeaderOffset), &iDANodeIndex)) {
+            if (pMgmt->sNodeDBTable[iDANodeIndex].eNodeState >= NODE_ASSOC) {
+                if (pMgmt->sNodeDBTable[iDANodeIndex].bPSEnable) {
+                    // queue this skb until next PS tx, and then release.
+
+	                skb->data += cbHeaderOffset;
+	                skb->tail += cbHeaderOffset;
+                    skb_put(skb, FrameSize);
+                    skb_queue_tail(&pMgmt->sNodeDBTable[iDANodeIndex].sTxPSQueue, skb);
+
+                    pMgmt->sNodeDBTable[iDANodeIndex].wEnQueueCnt++;
+                    wAID = pMgmt->sNodeDBTable[iDANodeIndex].wAID;
+                    pMgmt->abyPSTxMap[wAID >> 3] |=  byMask[wAID & 7];
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "relay: index= %d, pMgmt->abyPSTxMap[%d]= %d\n",
+                               iDANodeIndex, (wAID >> 3), pMgmt->abyPSTxMap[wAID >> 3]);
+                    return TRUE;
+                }
+                else {
+                    bRelayOnly = TRUE;
+                }
+            }
+        };
+    }
+
+    if (bRelayOnly || bRelayAndForward) {
+        // relay this packet right now
+        if (bRelayAndForward)
+            iDANodeIndex = 0;
+
+        if ((pDevice->uAssocCount > 1) && (iDANodeIndex >= 0)) {
+            bRelayPacketSend(pDevice, (PBYTE)(skb->data + cbHeaderOffset), FrameSize, (UINT)iDANodeIndex);
+        }
+
+        if (bRelayOnly)
+            return FALSE;
+    }
+    // none associate, don't forward
+    if (pDevice->uAssocCount == 0)
+        return FALSE;
+
+    return TRUE;
+}
+
+
+
+
+VOID
+RXvWorkItem(
+    PVOID Context
+    )
+{
+    PSDevice pDevice = (PSDevice) Context;
+    NTSTATUS        ntStatus;
+    PRCB            pRCB=NULL;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Rx Polling Thread\n");
+    spin_lock_irq(&pDevice->lock);
+    while ( MP_TEST_FLAG(pDevice, fMP_POST_READS) &&
+            MP_IS_READY(pDevice) &&
+            (pDevice->NumRecvFreeList != 0) ) {
+        pRCB = pDevice->FirstRecvFreeList;
+        pDevice->NumRecvFreeList--;
+        ASSERT(pRCB);// cannot be NULL
+        DequeueRCB(pDevice->FirstRecvFreeList, pDevice->LastRecvFreeList);
+        ntStatus = PIPEnsBulkInUsbRead(pDevice, pRCB);
+    }
+    pDevice->bIsRxWorkItemQueued = FALSE;
+    spin_unlock_irq(&pDevice->lock);
+
+}
+
+
+VOID
+RXvFreeRCB(
+    IN PRCB pRCB,
+    IN BOOL bReAllocSkb
+    )
+{
+    PSDevice pDevice = (PSDevice)pRCB->pDevice;
+
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->RXvFreeRCB\n");
+
+    ASSERT(!pRCB->Ref);     // should be 0
+    ASSERT(pRCB->pDevice);  // shouldn't be NULL
+
+    if (bReAllocSkb == TRUE) {
+        pRCB->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
+        // todo error handling
+        if (pRCB->skb == NULL) {
+            DBG_PRT(MSG_LEVEL_ERR,KERN_ERR" Failed to re-alloc rx skb\n");
+        }else {
+            pRCB->skb->dev = pDevice->dev;
+        }
+    }
+    //
+    // Insert the RCB back in the Recv free list
+    //
+    EnqueueRCB(pDevice->FirstRecvFreeList, pDevice->LastRecvFreeList, pRCB);
+    pDevice->NumRecvFreeList++;
+
+
+    if (MP_TEST_FLAG(pDevice, fMP_POST_READS) && MP_IS_READY(pDevice) &&
+        (pDevice->bIsRxWorkItemQueued == FALSE) ) {
+
+        pDevice->bIsRxWorkItemQueued = TRUE;
+        tasklet_schedule(&pDevice->ReadWorkItem);
+    }
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"<----RXFreeRCB %d %d\n",pDevice->NumRecvFreeList, pDevice->NumRecvMngList);
+}
+
+
+VOID
+RXvMngWorkItem(
+    PVOID Context
+    )
+{
+    PSDevice pDevice = (PSDevice) Context;
+    PRCB            pRCB=NULL;
+    PSRxMgmtPacket  pRxPacket;
+    BOOL            bReAllocSkb = FALSE;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Rx Mng Thread\n");
+
+    spin_lock_irq(&pDevice->lock);
+    while (pDevice->NumRecvMngList!=0)
+    {
+        pRCB = pDevice->FirstRecvMngList;
+        pDevice->NumRecvMngList--;
+        DequeueRCB(pDevice->FirstRecvMngList, pDevice->LastRecvMngList);
+        if(!pRCB){
+            break;
+        }
+        ASSERT(pRCB);// cannot be NULL
+        pRxPacket = &(pRCB->sMngPacket);
+        vMgrRxManagePacket((HANDLE)pDevice, &(pDevice->sMgmtObj), pRxPacket);
+        pRCB->Ref--;
+        if(pRCB->Ref == 0) {
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"RxvFreeMng %d %d\n",pDevice->NumRecvFreeList, pDevice->NumRecvMngList);
+            RXvFreeRCB(pRCB, bReAllocSkb);
+        } else {
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Rx Mng Only we have the right to free RCB\n");
+        }
+    }
+
+    pDevice->bIsRxMngWorkItemQueued = FALSE;
+    spin_unlock_irq(&pDevice->lock);
+
+}
+
+
diff --git a/drivers/staging/vt6656/dpc.h b/drivers/staging/vt6656/dpc.h
new file mode 100644
index 0000000..eb4677f
--- /dev/null
+++ b/drivers/staging/vt6656/dpc.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: dpc.h
+ *
+ * Purpose:
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Jun. 27, 2002
+ *
+ */
+
+
+#ifndef __DPC_H__
+#define __DPC_H__
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+#if !defined(__DEVICE_H__)
+#include "device.h"
+#endif
+#if !defined(__WCMD_H__)
+#include "wcmd.h"
+#endif
+
+
+/*---------------------  Export Definitions -------------------------*/
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+#ifdef __cplusplus
+extern "C" {                            /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+
+
+
+VOID
+RXvWorkItem(
+    PVOID Context
+    );
+
+VOID
+RXvMngWorkItem(
+    PVOID Context
+    );
+
+VOID
+RXvFreeRCB(
+    IN PRCB pRCB,
+    IN BOOL bReAllocSkb
+    );
+
+BOOL
+RXbBulkInProcessData(
+    IN PSDevice         pDevice,
+    IN PRCB             pRCB,
+    IN ULONG            BytesToIndicate
+    );
+
+
+#ifdef __cplusplus
+}                                       /* End of extern "C" { */
+#endif /* __cplusplus */
+
+
+
+
+#endif // __RXTX_H__
+
+
+
diff --git a/drivers/staging/vt6656/firmware.c b/drivers/staging/vt6656/firmware.c
new file mode 100644
index 0000000..e315a46
--- /dev/null
+++ b/drivers/staging/vt6656/firmware.c
@@ -0,0 +1,887 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: baseband.c
+ *
+ * Purpose: Implement functions to access baseband
+ *
+ * Author: Yiching Chen
+ *
+ * Date: May 20, 2004
+ *
+ * Functions:
+ *
+ * Revision History:
+ *
+ */
+
+
+#if !defined(__UMEM_H__)
+#include "umem.h"
+#endif
+#if !defined(__FIRMWARE_H__)
+#include "firmware.h"
+#endif
+#if !defined(__CONTROL_H__)
+#include "control.h"
+#endif
+#if !defined(__RNDIS_H__)
+#include "rndis.h"
+#endif
+
+
+/*---------------------  Static Definitions -------------------------*/
+
+static int          msglevel                =MSG_LEVEL_INFO;
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+
+/*---------------------  Static Functions  --------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*
+ *  This is firmware version 1.51
+ */
+#define FIRMWARE_VERSION        0x133
+
+const BYTE abyFirmware[] = {
+
+0x02, 0x35, 0x62, 0x02, 0x3B, 0xED, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x02, 0x3E, 0x21, 0xD2, 0x04,
+0x90, 0x06, 0x24, 0x74, 0x08, 0xF0, 0x90, 0x06, 0x21, 0xE0, 0x90, 0x45, 0x39, 0xF0, 0xE0, 0x90,
+0x06, 0x21, 0xF0, 0x90, 0x06, 0x10, 0xE0, 0x54, 0x60, 0x60, 0x03, 0x02, 0x1A, 0xE9, 0xA3, 0xE0,
+0x12, 0x28, 0x7E, 0x18, 0x15, 0x00, 0x18, 0xF6, 0x01, 0x19, 0xD1, 0x03, 0x16, 0x79, 0x05, 0x12,
+0x52, 0x06, 0x17, 0xE5, 0x08, 0x16, 0xAF, 0x09, 0x17, 0x33, 0x0A, 0x17, 0x91, 0x0B, 0x00, 0x00,
+0x1A, 0xE1, 0x90, 0x06, 0x17, 0xE0, 0xFE, 0x90, 0x06, 0x16, 0xE0, 0xFD, 0xEE, 0x90, 0x45, 0x31,
+0xF0, 0xED, 0xA3, 0xF0, 0x90, 0x10, 0x3D, 0x74, 0x05, 0xF0, 0x90, 0x06, 0x24, 0x74, 0x08, 0xF0,
+0x90, 0x06, 0x13, 0xE0, 0x24, 0xFE, 0x60, 0x47, 0x14, 0x70, 0x03, 0x02, 0x14, 0x79, 0x24, 0xFD,
+0x60, 0x25, 0x14, 0x70, 0x03, 0x02, 0x13, 0x9C, 0x24, 0x06, 0x60, 0x03, 0x02, 0x16, 0x54, 0x7B,
+0x01, 0x7A, 0x10, 0x79, 0x8B, 0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0x90, 0x10, 0x4C, 0xE4, 0xF0,
+0xA3, 0x74, 0x12, 0xF0, 0x02, 0x16, 0x5C, 0x7B, 0x01, 0x7A, 0x10, 0x79, 0x81, 0x90, 0x10, 0x46,
+0x12, 0x27, 0xBA, 0x90, 0x10, 0x4C, 0xE4, 0xF0, 0xA3, 0x74, 0x0A, 0xF0, 0x02, 0x16, 0x5C, 0x7B,
+0x01, 0x7A, 0x10, 0x79, 0x51, 0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0x90, 0x10, 0x52, 0x74, 0x02,
+0xF0, 0x90, 0x10, 0x54, 0xE0, 0xFE, 0x90, 0x10, 0x53, 0xE0, 0xFD, 0xEE, 0x90, 0x10, 0x4C, 0xF0,
+0xED, 0xA3, 0xF0, 0x30, 0x06, 0x5A, 0xE0, 0xFD, 0x24, 0x47, 0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5,
+0x83, 0xE4, 0xF0, 0x74, 0x48, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0x74, 0x02, 0xF0,
+0x74, 0x4E, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0xE4, 0xF0, 0x74, 0x4F, 0x2D, 0xF5,
+0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0x74, 0x02, 0xF0, 0x90, 0x10, 0x98, 0xE0, 0xFE, 0x90, 0x10,
+0x97, 0xE0, 0xFB, 0xEE, 0xEB, 0xC3, 0x94, 0x20, 0xEE, 0x94, 0x01, 0x40, 0x03, 0x02, 0x16, 0x5C,
+0x74, 0x50, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0x74, 0x01, 0xF0, 0x02, 0x16, 0x5C,
+0x90, 0x10, 0x4D, 0xE0, 0xFD, 0x24, 0x47, 0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0x74, 0x40,
+0xF0, 0x74, 0x48, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0xE4, 0xF0, 0x74, 0x4E, 0x2D,
+0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0x74, 0x40, 0xF0, 0x74, 0x4F, 0x2D, 0xF5, 0x82, 0xE4,
+0x34, 0x10, 0xF5, 0x83, 0xE4, 0xF0, 0x90, 0x10, 0x98, 0xE0, 0xFE, 0x90, 0x10, 0x97, 0xE0, 0xFB,
+0xEE, 0xEB, 0xC3, 0x94, 0x20, 0xEE, 0x94, 0x01, 0x40, 0x03, 0x02, 0x16, 0x5C, 0x74, 0x50, 0x2D,
+0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0xE4, 0xF0, 0x02, 0x16, 0x5C, 0x7B, 0x01, 0x7A, 0x10,
+0x79, 0x51, 0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0x90, 0x10, 0x52, 0x74, 0x07, 0xF0, 0x90, 0x10,
+0x54, 0xE0, 0xFE, 0x90, 0x10, 0x53, 0xE0, 0xFD, 0xEE, 0x90, 0x10, 0x4C, 0xF0, 0xED, 0xA3, 0xF0,
+0x30, 0x06, 0x59, 0xE0, 0xFD, 0x24, 0x47, 0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0x74, 0x40,
+0xF0, 0x74, 0x48, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0xE4, 0xF0, 0x74, 0x4E, 0x2D,
+0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0x74, 0x40, 0xF0, 0x74, 0x4F, 0x2D, 0xF5, 0x82, 0xE4,
+0x34, 0x10, 0xF5, 0x83, 0xE4, 0xF0, 0x90, 0x10, 0x98, 0xE0, 0xFE, 0x90, 0x10, 0x97, 0xE0, 0xFB,
+0xEE, 0xEB, 0xC3, 0x94, 0x20, 0xEE, 0x94, 0x01, 0x40, 0x03, 0x02, 0x16, 0x5C, 0x74, 0x50, 0x2D,
+0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0xE4, 0xF0, 0x02, 0x16, 0x5C, 0x90, 0x10, 0x4D, 0xE0,
+0xFD, 0x24, 0x47, 0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0xE4, 0xF0, 0x74, 0x48, 0x2D, 0xF5,
+0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0x74, 0x02, 0xF0, 0x74, 0x4E, 0x2D, 0xF5, 0x82, 0xE4, 0x34,
+0x10, 0xF5, 0x83, 0xE4, 0xF0, 0x74, 0x4F, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0x74,
+0x02, 0xF0, 0x90, 0x10, 0x98, 0xE0, 0xFE, 0x90, 0x10, 0x97, 0xE0, 0xFB, 0xEE, 0xEB, 0xC3, 0x94,
+0x20, 0xEE, 0x94, 0x01, 0x40, 0x03, 0x02, 0x16, 0x5C, 0x74, 0x50, 0x2D, 0xF5, 0x82, 0xE4, 0x34,
+0x10, 0xF5, 0x83, 0x74, 0x01, 0xF0, 0x02, 0x16, 0x5C, 0x90, 0x06, 0x12, 0xE0, 0x14, 0x60, 0x2F,
+0x14, 0x70, 0x03, 0x02, 0x15, 0x34, 0x14, 0x70, 0x03, 0x02, 0x15, 0xD5, 0x24, 0x03, 0x60, 0x03,
+0x02, 0x16, 0x4C, 0x7B, 0x01, 0x7A, 0x43, 0x79, 0x1A, 0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0x90,
+0x43, 0x1A, 0xE0, 0xFF, 0x90, 0x10, 0x4C, 0xE4, 0xF0, 0xA3, 0xEF, 0xF0, 0x02, 0x16, 0x5C, 0x90,
+0x10, 0x98, 0xE0, 0xFE, 0x90, 0x10, 0x97, 0xE0, 0xFD, 0xEE, 0xED, 0xC3, 0x94, 0x20, 0xEE, 0x94,
+0x01, 0x50, 0x1C, 0x7B, 0x01, 0x7A, 0x10, 0x79, 0x14, 0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0x90,
+0x10, 0x14, 0xE0, 0xFF, 0x90, 0x10, 0x4C, 0xE4, 0xF0, 0xA3, 0xEF, 0xF0, 0x02, 0x16, 0x5C, 0x90,
+0x10, 0x3C, 0xE0, 0xC3, 0x94, 0x01, 0x50, 0x08, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22,
+0x90, 0x10, 0x0D, 0xE0, 0x20, 0xE0, 0x1C, 0x7B, 0x01, 0x7A, 0x10, 0x79, 0x14, 0x90, 0x10, 0x46,
+0x12, 0x27, 0xBA, 0x90, 0x10, 0x14, 0xE0, 0xFF, 0x90, 0x10, 0x4C, 0xE4, 0xF0, 0xA3, 0xEF, 0xF0,
+0x02, 0x16, 0x5C, 0x90, 0x10, 0x2E, 0x12, 0x27, 0x9A, 0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0x90,
+0x10, 0x2E, 0x12, 0x27, 0x9A, 0x12, 0x26, 0x36, 0xFF, 0x90, 0x10, 0x4C, 0xE4, 0xF0, 0xA3, 0xEF,
+0xF0, 0x02, 0x16, 0x5C, 0x90, 0x10, 0x98, 0xE0, 0xFE, 0x90, 0x10, 0x97, 0xE0, 0xFD, 0xEE, 0xED,
+0xC3, 0x94, 0x20, 0xEE, 0x94, 0x01, 0x50, 0x33, 0x90, 0x10, 0x99, 0xE0, 0x70, 0x0C, 0xA3, 0xE0,
+0x70, 0x08, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x10, 0x2E, 0x12, 0x27, 0x9A,
+0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0x90, 0x10, 0x2E, 0x12, 0x27, 0x9A, 0x12, 0x26, 0x36, 0xFF,
+0x90, 0x10, 0x4C, 0xE4, 0xF0, 0xA3, 0xEF, 0xF0, 0x02, 0x16, 0x5C, 0x90, 0x10, 0x3C, 0xE0, 0xC3,
+0x94, 0x02, 0x50, 0x08, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x10, 0x0D, 0xE0,
+0x20, 0xE0, 0x21, 0x90, 0x10, 0x2E, 0x12, 0x27, 0x9A, 0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0x90,
+0x10, 0x2E, 0x12, 0x27, 0x9A, 0x12, 0x26, 0x36, 0xFF, 0x90, 0x10, 0x4C, 0xE4, 0xF0, 0xA3, 0xEF,
+0xF0, 0x02, 0x16, 0x5C, 0x90, 0x10, 0x31, 0x12, 0x27, 0x9A, 0x90, 0x10, 0x46, 0x12, 0x27, 0xBA,
+0x90, 0x10, 0x31, 0x12, 0x27, 0x9A, 0x12, 0x26, 0x36, 0xFF, 0x90, 0x10, 0x4C, 0xE4, 0xF0, 0xA3,
+0xEF, 0xF0, 0x02, 0x16, 0x5C, 0x90, 0x10, 0x98, 0xE0, 0xFE, 0x90, 0x10, 0x97, 0xE0, 0xFD, 0xEE,
+0xED, 0xC3, 0x94, 0x20, 0xEE, 0x94, 0x01, 0x50, 0x32, 0x90, 0x10, 0x99, 0xE0, 0x60, 0x04, 0xA3,
+0xE0, 0x70, 0x08, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x10, 0x31, 0x12, 0x27,
+0x9A, 0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0x90, 0x10, 0x31, 0x12, 0x27, 0x9A, 0x12, 0x26, 0x36,
+0xFF, 0x90, 0x10, 0x4C, 0xE4, 0xF0, 0xA3, 0xEF, 0xF0, 0x80, 0x41, 0x90, 0x10, 0x3C, 0xE0, 0xC3,
+0x94, 0x03, 0x50, 0x08, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x10, 0x31, 0x12,
+0x27, 0x9A, 0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0x90, 0x10, 0x31, 0x12, 0x27, 0x9A, 0x12, 0x26,
+0x36, 0xFF, 0x90, 0x10, 0x4C, 0xE4, 0xF0, 0xA3, 0xEF, 0xF0, 0x80, 0x10, 0x90, 0x06, 0x22, 0xE0,
+0x44, 0x08, 0xF0, 0x22, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x45, 0x31, 0xE0,
+0xFE, 0xA3, 0xE0, 0xFF, 0xD3, 0x90, 0x10, 0x4D, 0xE0, 0x9F, 0x90, 0x10, 0x4C, 0xE0, 0x9E, 0x40,
+0x05, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x02, 0x33, 0xF6, 0x90, 0x06, 0x12, 0xE0, 0x90, 0x10, 0x3E,
+0xF0, 0x90, 0x10, 0x3D, 0x74, 0x04, 0xF0, 0x90, 0x06, 0x23, 0x74, 0x80, 0xF0, 0xA3, 0x74, 0x08,
+0xF0, 0xA3, 0xF0, 0x90, 0x10, 0x3E, 0xE0, 0xFF, 0x44, 0x80, 0x90, 0x06, 0x06, 0xF0, 0xEF, 0x70,
+0x07, 0x90, 0x10, 0x38, 0x74, 0x07, 0xF0, 0x22, 0x90, 0x10, 0x38, 0x74, 0x0F, 0xF0, 0x22, 0x90,
+0x06, 0x13, 0xE0, 0xFE, 0x90, 0x06, 0x12, 0xE0, 0xFD, 0xEE, 0x90, 0x45, 0x35, 0xF0, 0xED, 0xA3,
+0xF0, 0x90, 0x45, 0x35, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x64, 0x01, 0x4E, 0x60, 0x0C, 0xEF, 0x4E,
+0x60, 0x08, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x06, 0x12, 0xE0, 0x90, 0x10,
+0x3A, 0xF0, 0x90, 0x10, 0x3D, 0x74, 0x08, 0xF0, 0x90, 0x06, 0x08, 0x74, 0x02, 0xF0, 0xA3, 0x04,
+0xF0, 0xA3, 0x74, 0x01, 0xF0, 0x90, 0x06, 0x23, 0x74, 0x80, 0xF0, 0xA3, 0x74, 0x08, 0xF0, 0xA3,
+0xF0, 0x90, 0x10, 0x3A, 0xE0, 0x70, 0x0D, 0x90, 0x10, 0x38, 0x74, 0x0F, 0xF0, 0x90, 0x06, 0x07,
+0x74, 0x02, 0xF0, 0x22, 0x90, 0x10, 0x38, 0x74, 0x1F, 0xF0, 0x90, 0x06, 0x07, 0xE0, 0x44, 0x1C,
+0xF0, 0x90, 0x06, 0x0B, 0x74, 0x70, 0xF0, 0xE4, 0x90, 0x10, 0x34, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0,
+0xA3, 0xF0, 0x22, 0x90, 0x10, 0x38, 0xE0, 0x64, 0x1F, 0x70, 0x4E, 0x90, 0x06, 0x15, 0xE0, 0xFE,
+0x90, 0x06, 0x14, 0xE0, 0xFD, 0xEE, 0x90, 0x45, 0x33, 0xF0, 0xED, 0xA3, 0xF0, 0x90, 0x10, 0x55,
+0xE0, 0xFF, 0xC3, 0x90, 0x45, 0x34, 0xE0, 0x9F, 0x90, 0x45, 0x33, 0xE0, 0x94, 0x00, 0x50, 0x21,
+0xE4, 0x90, 0x06, 0x60, 0xF0, 0x90, 0x10, 0x3D, 0x74, 0x09, 0xF0, 0xE4, 0x90, 0x10, 0x4C, 0xF0,
+0xA3, 0xF0, 0xC2, 0x04, 0x90, 0x06, 0x23, 0x74, 0x81, 0xF0, 0xA3, 0x74, 0x08, 0xF0, 0xA3, 0xF0,
+0x22, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0,
+0x22, 0x90, 0x06, 0x13, 0xE0, 0xFE, 0x90, 0x06, 0x12, 0xE0, 0xFD, 0xEE, 0x90, 0x45, 0x35, 0xF0,
+0xED, 0xA3, 0xF0, 0x90, 0x06, 0x15, 0xE0, 0xFE, 0x90, 0x06, 0x14, 0xE0, 0xFD, 0xEE, 0x90, 0x45,
+0x33, 0xF0, 0xED, 0xA3, 0xF0, 0xA3, 0xE0, 0x70, 0x02, 0xA3, 0xE0, 0x70, 0x13, 0x90, 0x10, 0x55,
+0xE0, 0xFF, 0xC3, 0x90, 0x45, 0x34, 0xE0, 0x9F, 0x90, 0x45, 0x33, 0xE0, 0x94, 0x00, 0x40, 0x08,
+0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x06, 0x23, 0x74, 0x80, 0xF0, 0xA3, 0x74,
+0x08, 0xF0, 0xA3, 0xF0, 0x22, 0x90, 0x10, 0x38, 0xE0, 0xB4, 0x1F, 0x08, 0x90, 0x06, 0x60, 0x74,
+0x01, 0xF0, 0x80, 0x05, 0xE4, 0x90, 0x06, 0x60, 0xF0, 0x90, 0x10, 0x3D, 0x74, 0x07, 0xF0, 0xE4,
+0x90, 0x10, 0x4C, 0xF0, 0xA3, 0xF0, 0xC2, 0x04, 0x90, 0x06, 0x23, 0x74, 0x81, 0xF0, 0xA3, 0x74,
+0x08, 0xF0, 0xA3, 0xF0, 0x22, 0x90, 0x06, 0x10, 0xE0, 0x24, 0x7F, 0x60, 0x14, 0x14, 0x60, 0x4E,
+0x24, 0x02, 0x60, 0x03, 0x02, 0x18, 0xD2, 0xE4, 0x90, 0x06, 0x60, 0xF0, 0xA3, 0xF0, 0x02, 0x18,
+0xDA, 0x90, 0x06, 0x15, 0xE0, 0xFE, 0x90, 0x06, 0x14, 0xE0, 0xFD, 0xEE, 0x90, 0x45, 0x33, 0xF0,
+0xED, 0xA3, 0xF0, 0x90, 0x10, 0x55, 0xE0, 0xFF, 0xC3, 0x90, 0x45, 0x34, 0xE0, 0x9F, 0x90, 0x45,
+0x33, 0xE0, 0x94, 0x00, 0x50, 0x07, 0x90, 0x10, 0x38, 0xE0, 0xB4, 0x0F, 0x08, 0x90, 0x06, 0x22,
+0xE0, 0x44, 0x08, 0xF0, 0x22, 0xE4, 0x90, 0x06, 0x60, 0xF0, 0xA3, 0xF0, 0x80, 0x6C, 0x90, 0x06,
+0x15, 0xE0, 0xFE, 0x90, 0x06, 0x14, 0xE0, 0xFD, 0xEE, 0x90, 0x45, 0x33, 0xF0, 0xED, 0xA3, 0xF0,
+0x90, 0x45, 0x33, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x64, 0x81, 0x4E, 0x60, 0x0C, 0xEF, 0x64, 0x82,
+0x4E, 0x60, 0x06, 0xEF, 0x64, 0x03, 0x4E, 0x70, 0x0B, 0x90, 0x10, 0x38, 0xE0, 0xB4, 0x0F, 0x0C,
+0xEF, 0x4E, 0x60, 0x08, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x7E, 0x00, 0xEF, 0x54,
+0x7F, 0x24, 0x34, 0xF5, 0x82, 0xEE, 0x34, 0x10, 0xF5, 0x83, 0xE0, 0xB4, 0x01, 0x08, 0x90, 0x06,
+0x60, 0x74, 0x01, 0xF0, 0x80, 0x05, 0xE4, 0x90, 0x06, 0x60, 0xF0, 0xE4, 0x90, 0x06, 0x61, 0xF0,
+0x80, 0x08, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x10, 0x3D, 0x74, 0x01, 0xF0,
+0xE4, 0x90, 0x10, 0x4C, 0xF0, 0xA3, 0xF0, 0xC2, 0x04, 0x90, 0x06, 0x23, 0x74, 0x82, 0xF0, 0xA3,
+0x74, 0x08, 0xF0, 0xA3, 0xF0, 0x22, 0x90, 0x06, 0x10, 0xE0, 0x24, 0xFE, 0x60, 0x03, 0x02, 0x19,
+0xBA, 0x90, 0x06, 0x15, 0xE0, 0xFE, 0x90, 0x06, 0x14, 0xE0, 0xFD, 0xEE, 0x90, 0x45, 0x33, 0xF0,
+0xED, 0xA3, 0xF0, 0x90, 0x06, 0x13, 0xE0, 0xFE, 0x90, 0x06, 0x12, 0xE0, 0xFD, 0xEE, 0x90, 0x45,
+0x35, 0xF0, 0xED, 0xA3, 0xF0, 0x90, 0x10, 0x38, 0xE0, 0xF9, 0x64, 0x1F, 0x70, 0x76, 0x90, 0x45,
+0x33, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x64, 0x81, 0x4E, 0x70, 0x19, 0x90, 0x06, 0x0B, 0xE0, 0x54,
+0xFB, 0xF0, 0x7C, 0x00, 0xEF, 0x54, 0x7F, 0x24, 0x34, 0xF5, 0x82, 0xEC, 0x34, 0x10, 0xF5, 0x83,
+0xE4, 0xF0, 0x80, 0x6E, 0xEF, 0x64, 0x82, 0x4E, 0x70, 0x1C, 0x90, 0x06, 0x0B, 0xE0, 0x54, 0xFE,
+0xF0, 0x7E, 0x00, 0x90, 0x45, 0x34, 0xE0, 0x54, 0x7F, 0x24, 0x34, 0xF5, 0x82, 0xEE, 0x34, 0x10,
+0xF5, 0x83, 0xE4, 0xF0, 0x80, 0x4C, 0x90, 0x45, 0x33, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x64, 0x03,
+0x4E, 0x70, 0x19, 0x90, 0x06, 0x0B, 0xE0, 0x54, 0xFD, 0xF0, 0x7E, 0x00, 0xEF, 0x54, 0x7F, 0x24,
+0x34, 0xF5, 0x82, 0xEE, 0x34, 0x10, 0xF5, 0x83, 0xE4, 0xF0, 0x80, 0x26, 0x90, 0x06, 0x22, 0xE0,
+0x44, 0x08, 0xF0, 0x22, 0xE9, 0xB4, 0x0F, 0x1A, 0x90, 0x45, 0x33, 0xE0, 0x70, 0x02, 0xA3, 0xE0,
+0x60, 0x10, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08,
+0xF0, 0x22, 0xC2, 0x04, 0x90, 0x06, 0x23, 0x74, 0x80, 0xF0, 0xA3, 0x74, 0x08, 0xF0, 0xA3, 0xF0,
+0x22, 0x90, 0x06, 0x10, 0xE0, 0x24, 0xFE, 0x60, 0x44, 0x24, 0x02, 0x60, 0x03, 0x02, 0x1A, 0xCA,
+0x90, 0x06, 0x13, 0xE0, 0xFE, 0x90, 0x06, 0x12, 0xE0, 0xFD, 0xEE, 0x90, 0x45, 0x35, 0xF0, 0xED,
+0xA3, 0xF0, 0x90, 0x45, 0x35, 0xE0, 0x70, 0x04, 0xA3, 0xE0, 0x64, 0x02, 0x70, 0x17, 0x90, 0x06,
+0x14, 0xE0, 0x70, 0x11, 0x90, 0x10, 0x3D, 0x74, 0x0F, 0xF0, 0x90, 0x06, 0x15, 0xE0, 0x90, 0x10,
+0x50, 0xF0, 0x02, 0x1A, 0xD2, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x06, 0x15,
+0xE0, 0xFE, 0x90, 0x06, 0x14, 0xE0, 0xFD, 0xEE, 0x90, 0x45, 0x33, 0xF0, 0xED, 0xA3, 0xF0, 0x90,
+0x06, 0x13, 0xE0, 0xFE, 0x90, 0x06, 0x12, 0xE0, 0xFD, 0xEE, 0x90, 0x45, 0x35, 0xF0, 0xED, 0xA3,
+0xF0, 0x90, 0x10, 0x38, 0xE0, 0x64, 0x1F, 0x70, 0x79, 0x90, 0x45, 0x33, 0xE0, 0xFE, 0xA3, 0xE0,
+0xFF, 0x64, 0x81, 0x4E, 0x70, 0x1A, 0x90, 0x06, 0x0B, 0xE0, 0x44, 0x04, 0xF0, 0x7C, 0x00, 0xEF,
+0x54, 0x7F, 0x24, 0x34, 0xF5, 0x82, 0xEC, 0x34, 0x10, 0xF5, 0x83, 0x74, 0x01, 0xF0, 0x80, 0x62,
+0xEF, 0x64, 0x82, 0x4E, 0x70, 0x1D, 0x90, 0x06, 0x0B, 0xE0, 0x44, 0x01, 0xF0, 0x7E, 0x00, 0x90,
+0x45, 0x34, 0xE0, 0x54, 0x7F, 0x24, 0x34, 0xF5, 0x82, 0xEE, 0x34, 0x10, 0xF5, 0x83, 0x74, 0x01,
+0xF0, 0x80, 0x3F, 0x90, 0x45, 0x33, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x64, 0x03, 0x4E, 0x70, 0x1A,
+0x90, 0x06, 0x0B, 0xE0, 0x44, 0x02, 0xF0, 0x7E, 0x00, 0xEF, 0x54, 0x7F, 0x24, 0x34, 0xF5, 0x82,
+0xEE, 0x34, 0x10, 0xF5, 0x83, 0x74, 0x01, 0xF0, 0x80, 0x18, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08,
+0xF0, 0x22, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08,
+0xF0, 0x22, 0xC2, 0x04, 0x90, 0x06, 0x23, 0x74, 0x80, 0xF0, 0xA3, 0x74, 0x08, 0xF0, 0xA3, 0xF0,
+0x22, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x06, 0x10, 0xE0, 0x64, 0x40, 0x60,
+0x03, 0x02, 0x1C, 0xA2, 0xE0, 0x90, 0x43, 0x1E, 0xF0, 0x90, 0x06, 0x11, 0xE0, 0x90, 0x43, 0x1F,
+0xF0, 0x90, 0x06, 0x13, 0xE0, 0xFE, 0x90, 0x06, 0x12, 0xE0, 0xFD, 0xEE, 0x90, 0x43, 0x20, 0xF0,
+0xED, 0xA3, 0xF0, 0x90, 0x06, 0x15, 0xE0, 0xFE, 0x90, 0x06, 0x14, 0xE0, 0xFD, 0xEE, 0x90, 0x43,
+0x22, 0xF0, 0xED, 0xA3, 0xF0, 0x90, 0x06, 0x17, 0xE0, 0xFE, 0x90, 0x06, 0x16, 0xE0, 0xFD, 0xEE,
+0x90, 0x43, 0x24, 0xF0, 0xED, 0xA3, 0xF0, 0xE4, 0x90, 0x10, 0x44, 0xF0, 0xA3, 0xF0, 0x90, 0x43,
+0x24, 0xE0, 0xFF, 0xA3, 0xE0, 0x90, 0x10, 0x42, 0xCF, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x43, 0x1F,
+0xE0, 0x12, 0x28, 0x7E, 0x1B, 0x70, 0x00, 0x1B, 0xE6, 0x01, 0x1B, 0x79, 0x07, 0x1B, 0x8F, 0x0B,
+0x1B, 0xAF, 0x0C, 0x1B, 0xC9, 0x10, 0x1B, 0xD9, 0x12, 0x1B, 0xFE, 0x13, 0x00, 0x00, 0x1C, 0x6A,
+0x90, 0x10, 0x3D, 0x74, 0x0B, 0xF0, 0x02, 0x1C, 0x8E, 0x90, 0x10, 0x3D, 0x74, 0x0B, 0xF0, 0x12,
+0x3D, 0x31, 0x90, 0x06, 0x23, 0x74, 0x80, 0xF0, 0xA3, 0x74, 0x08, 0xF0, 0xA3, 0xF0, 0x22, 0x90,
+0x10, 0x3D, 0x74, 0x0B, 0xF0, 0x90, 0x43, 0x21, 0xE0, 0xFF, 0x90, 0x45, 0x45, 0xE0, 0xFD, 0x12,
+0x39, 0xB4, 0x90, 0x06, 0x23, 0x74, 0x80, 0xF0, 0xA3, 0x74, 0x08, 0xF0, 0xA3, 0xF0, 0x22, 0x90,
+0x45, 0x45, 0xE0, 0xFF, 0x90, 0x06, 0x12, 0xE0, 0xFD, 0x12, 0x39, 0x2D, 0x90, 0x06, 0x23, 0x74,
+0x80, 0xF0, 0xA3, 0x74, 0x08, 0xF0, 0xA3, 0xF0, 0x22, 0x12, 0x3E, 0x03, 0x90, 0x06, 0x23, 0x74,
+0x80, 0xF0, 0xA3, 0x74, 0x08, 0xF0, 0xA3, 0xF0, 0x22, 0x90, 0x06, 0x23, 0x74, 0x80, 0xF0, 0xA3,
+0x74, 0x08, 0xF0, 0xA3, 0xF0, 0x22, 0x90, 0x10, 0x3D, 0x74, 0x10, 0xF0, 0x90, 0x06, 0x23, 0x74,
+0x80, 0xF0, 0xA3, 0x74, 0x08, 0xF0, 0xA3, 0xF0, 0x12, 0x3D, 0xBA, 0x02, 0x1C, 0x8E, 0x90, 0x06,
+0x23, 0x74, 0x80, 0xF0, 0xA3, 0x74, 0x08, 0xF0, 0xA3, 0xF0, 0x90, 0x04, 0x7A, 0xE0, 0x90, 0x45,
+0x39, 0xF0, 0xE0, 0x54, 0x7F, 0xF0, 0x44, 0x80, 0xF0, 0x90, 0x04, 0x7A, 0xF0, 0x7D, 0x17, 0x7F,
+0x0C, 0x12, 0x3D, 0x00, 0x7D, 0xB9, 0x7F, 0x0D, 0x12, 0x3D, 0x00, 0x90, 0x04, 0x54, 0x74, 0x01,
+0xF0, 0xE4, 0x90, 0x04, 0x78, 0xF0, 0xA3, 0xF0, 0x90, 0x06, 0x20, 0x74, 0x20, 0xF0, 0x90, 0x04,
+0x59, 0x74, 0x10, 0xF0, 0xE4, 0x90, 0x06, 0x05, 0xF0, 0x90, 0x06, 0x07, 0x74, 0x03, 0xF0, 0x75,
+0xA8, 0x81, 0x43, 0x87, 0x01, 0x90, 0x06, 0x20, 0x74, 0x21, 0xF0, 0x90, 0x04, 0x58, 0x74, 0x14,
+0xF0, 0xA3, 0x74, 0x50, 0xF0, 0x43, 0xA8, 0x81, 0x80, 0x24, 0x90, 0x10, 0x3D, 0x74, 0x0D, 0xF0,
+0x7B, 0x01, 0x7A, 0x43, 0x79, 0x26, 0x90, 0x10, 0x3F, 0x12, 0x27, 0xBA, 0x90, 0x06, 0x17, 0xE0,
+0xFE, 0x90, 0x06, 0x16, 0xE0, 0xFD, 0xEE, 0x90, 0x10, 0x42, 0xF0, 0xED, 0xA3, 0xF0, 0xE4, 0x90,
+0x06, 0x24, 0xF0, 0x90, 0x06, 0x23, 0x74, 0xC0, 0xF0, 0x90, 0x06, 0x25, 0x74, 0x08, 0xF0, 0xC2,
+0x04, 0x22, 0x90, 0x06, 0x10, 0xE0, 0x64, 0xC0, 0x60, 0x03, 0x02, 0x1E, 0x86, 0xE0, 0x90, 0x43,
+0x1E, 0xF0, 0x90, 0x06, 0x11, 0xE0, 0x90, 0x43, 0x1F, 0xF0, 0x90, 0x06, 0x13, 0xE0, 0xFE, 0x90,
+0x06, 0x12, 0xE0, 0xFD, 0xEE, 0x90, 0x43, 0x20, 0xF0, 0xED, 0xA3, 0xF0, 0x90, 0x06, 0x15, 0xE0,
+0xFE, 0x90, 0x06, 0x14, 0xE0, 0xFD, 0xEE, 0x90, 0x43, 0x22, 0xF0, 0xED, 0xA3, 0xF0, 0x90, 0x06,
+0x17, 0xE0, 0xFE, 0x90, 0x06, 0x16, 0xE0, 0xFD, 0xEE, 0x90, 0x43, 0x24, 0xF0, 0xED, 0xA3, 0xF0,
+0x90, 0x43, 0x24, 0xE0, 0xFF, 0xA3, 0xE0, 0x90, 0x10, 0x4C, 0xCF, 0xF0, 0xA3, 0xEF, 0xF0, 0x90,
+0x43, 0x1F, 0xE0, 0x24, 0xFA, 0x70, 0x03, 0x02, 0x1E, 0x58, 0x24, 0x05, 0x60, 0x03, 0x02, 0x1E,
+0x6F, 0x90, 0x43, 0x22, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xEE, 0x60, 0x03, 0x02, 0x1E, 0x50, 0xEF,
+0x24, 0xFE, 0x70, 0x03, 0x02, 0x1D, 0xCD, 0x14, 0x60, 0x31, 0x14, 0x60, 0x4E, 0x24, 0xFC, 0x70,
+0x03, 0x02, 0x1E, 0x1A, 0x24, 0x07, 0x60, 0x03, 0x02, 0x1E, 0x50, 0x7B, 0x01, 0x7A, 0x00, 0x79,
+0x00, 0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0x90, 0x43, 0x20, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x90,
+0x10, 0x47, 0xEE, 0x8F, 0xF0, 0x12, 0x26, 0xB0, 0x02, 0x1E, 0x77, 0x7B, 0x01, 0x7A, 0x04, 0x79,
+0x00, 0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0x90, 0x43, 0x20, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x90,
+0x10, 0x47, 0xEE, 0x8F, 0xF0, 0x12, 0x26, 0xB0, 0x02, 0x1E, 0x77, 0x7B, 0x01, 0x7A, 0x43, 0x79,
+0x26, 0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0xE4, 0x90, 0x45, 0x37, 0xF0, 0xA3, 0xF0, 0x90, 0x43,
+0x24, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xC3, 0x90, 0x45, 0x38, 0xE0, 0x9F, 0x90, 0x45, 0x37, 0xE0,
+0x9E, 0x40, 0x03, 0x02, 0x1E, 0x77, 0xA3, 0xE0, 0xFF, 0x90, 0x43, 0x21, 0xE0, 0x2F, 0xFF, 0x12,
+0x3B, 0x25, 0x90, 0x45, 0x38, 0xE0, 0x24, 0x26, 0xF5, 0x82, 0xE4, 0x34, 0x43, 0xF5, 0x83, 0xEF,
+0xF0, 0x90, 0x45, 0x37, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xB0, 0x80, 0xC1, 0x7B, 0x01, 0x7A,
+0x43, 0x79, 0x26, 0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0xE4, 0x90, 0x45, 0x37, 0xF0, 0xA3, 0xF0,
+0x90, 0x43, 0x24, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xC3, 0x90, 0x45, 0x38, 0xE0, 0x9F, 0x90, 0x45,
+0x37, 0xE0, 0x9E, 0x40, 0x03, 0x02, 0x1E, 0x77, 0xA3, 0xE0, 0xFE, 0x90, 0x43, 0x21, 0xE0, 0x2E,
+0xFF, 0x74, 0x26, 0x2E, 0xF9, 0xE4, 0x34, 0x43, 0xFA, 0x7B, 0x01, 0x12, 0x3C, 0xCD, 0x90, 0x45,
+0x37, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xB0, 0x80, 0xC6, 0x7B, 0x01, 0x7A, 0x43, 0x79, 0x26,
+0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0xD3, 0x90, 0x43, 0x25, 0xE0, 0x94, 0x02, 0x90, 0x43, 0x24,
+0xE0, 0x94, 0x00, 0x40, 0x0F, 0xE4, 0xF0, 0xA3, 0x74, 0x02, 0xF0, 0x90, 0x10, 0x4C, 0xE4, 0xF0,
+0xA3, 0x74, 0x02, 0xF0, 0x90, 0x43, 0x26, 0x74, 0x33, 0xF0, 0xA3, 0x74, 0x01, 0xF0, 0x80, 0x27,
+0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x7B, 0x01, 0x7A, 0x44, 0x79, 0x2E, 0x90, 0x10,
+0x46, 0x12, 0x27, 0xBA, 0x90, 0x10, 0x4C, 0xE4, 0xF0, 0xA3, 0x74, 0x0A, 0xF0, 0x80, 0x08, 0x90,
+0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x06, 0x24, 0x74, 0x08, 0xF0, 0x12, 0x33, 0xF6,
+0x90, 0x10, 0x3D, 0x74, 0x0C, 0xF0, 0x22, 0xD2, 0x00, 0x90, 0x43, 0x1F, 0xE0, 0x12, 0x28, 0x7E,
+0x1E, 0xAF, 0x04, 0x1F, 0xB1, 0x05, 0x1F, 0xC4, 0x08, 0x20, 0xE2, 0x09, 0x21, 0x37, 0x0A, 0x21,
+0xE9, 0x0D, 0x22, 0x7F, 0x0E, 0x22, 0xB1, 0x0F, 0x23, 0x3B, 0x11, 0x00, 0x00, 0x23, 0x4F, 0x90,
+0x43, 0x22, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xEE, 0x60, 0x03, 0x02, 0x23, 0x4F, 0xEF, 0x24, 0xFE,
+0x70, 0x03, 0x02, 0x1F, 0x7D, 0x14, 0x60, 0x4B, 0x14, 0x70, 0x03, 0x02, 0x1F, 0x51, 0x24, 0x03,
+0x60, 0x03, 0x02, 0x23, 0x4F, 0x90, 0x43, 0x21, 0xE0, 0xFF, 0x24, 0x00, 0xF5, 0x82, 0xE4, 0x34,
+0x00, 0xF5, 0x83, 0xC0, 0x83, 0xC0, 0x82, 0xE0, 0xFE, 0x90, 0x43, 0x27, 0xE0, 0xF4, 0xFD, 0xEE,
+0x5D, 0xD0, 0x82, 0xD0, 0x83, 0xF0, 0x74, 0x00, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x00, 0xF5, 0x83,
+0xC0, 0x83, 0xC0, 0x82, 0xE0, 0xFF, 0x90, 0x43, 0x26, 0xE0, 0xFE, 0xEF, 0x4E, 0xD0, 0x82, 0xD0,
+0x83, 0xF0, 0x22, 0x90, 0x43, 0x21, 0xE0, 0xFF, 0x24, 0x00, 0xF5, 0x82, 0xE4, 0x34, 0x04, 0xF5,
+0x83, 0xC0, 0x83, 0xC0, 0x82, 0xE0, 0xFE, 0x90, 0x43, 0x27, 0xE0, 0xF4, 0xFD, 0xEE, 0x5D, 0xD0,
+0x82, 0xD0, 0x83, 0xF0, 0x74, 0x00, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x04, 0xF5, 0x83, 0xC0, 0x83,
+0xC0, 0x82, 0xE0, 0xFF, 0x90, 0x43, 0x26, 0xE0, 0xFE, 0xEF, 0x4E, 0xD0, 0x82, 0xD0, 0x83, 0xF0,
+0x22, 0x90, 0x43, 0x21, 0xE0, 0xFF, 0x12, 0x3B, 0x25, 0x90, 0x45, 0x37, 0xEF, 0xF0, 0x90, 0x43,
+0x27, 0xE0, 0xF4, 0x5F, 0xFF, 0x90, 0x45, 0x37, 0xF0, 0xFE, 0x90, 0x43, 0x21, 0xE0, 0xFF, 0x90,
+0x43, 0x26, 0xE0, 0x4E, 0xFD, 0x12, 0x3A, 0x33, 0x72, 0x00, 0x92, 0x00, 0x22, 0x90, 0x43, 0x21,
+0xE0, 0xFF, 0x7B, 0x01, 0x7A, 0x45, 0x79, 0x37, 0x12, 0x3C, 0xCD, 0x90, 0x45, 0x37, 0xE0, 0xFF,
+0x90, 0x43, 0x27, 0xE0, 0xF4, 0xFE, 0xEF, 0x5E, 0xFF, 0x90, 0x45, 0x37, 0xF0, 0xFE, 0x90, 0x43,
+0x21, 0xE0, 0xFF, 0x90, 0x43, 0x26, 0xE0, 0x4E, 0xFD, 0x12, 0x3D, 0x00, 0x72, 0x00, 0x92, 0x00,
+0x22, 0x7B, 0x01, 0x7A, 0x44, 0x79, 0x2E, 0x90, 0x45, 0x3B, 0x12, 0x27, 0xBA, 0x7A, 0x43, 0x79,
+0x26, 0x02, 0x2A, 0xF6, 0x90, 0x43, 0x21, 0xE0, 0xFD, 0x90, 0x04, 0xBC, 0xF0, 0x90, 0x43, 0x20,
+0xE0, 0xFA, 0xA3, 0xE0, 0xFB, 0xEA, 0x90, 0x04, 0xBD, 0xF0, 0x90, 0x43, 0x26, 0xE0, 0x90, 0x04,
+0xC0, 0xF0, 0x90, 0x43, 0x27, 0xE0, 0x90, 0x04, 0xC1, 0xF0, 0x90, 0x43, 0x28, 0xE0, 0x90, 0x04,
+0xC2, 0xF0, 0x90, 0x43, 0x29, 0xE0, 0x90, 0x04, 0xC3, 0xF0, 0x90, 0x04, 0xBE, 0x74, 0x01, 0xF0,
+0xED, 0x04, 0x90, 0x04, 0xBC, 0xF0, 0xEB, 0x24, 0x01, 0xE4, 0x3A, 0xA3, 0xF0, 0x90, 0x43, 0x2A,
+0xE0, 0x90, 0x04, 0xC0, 0xF0, 0x90, 0x43, 0x2B, 0xE0, 0x90, 0x04, 0xC1, 0xF0, 0x90, 0x43, 0x2C,
+0xE0, 0x90, 0x04, 0xC2, 0xF0, 0x90, 0x43, 0x2D, 0xE0, 0x90, 0x04, 0xC3, 0xF0, 0x90, 0x04, 0xBE,
+0x74, 0x01, 0xF0, 0xE4, 0x90, 0x45, 0x35, 0xF0, 0xA3, 0xF0, 0x90, 0x45, 0x35, 0xE0, 0xFE, 0xA3,
+0xE0, 0xFF, 0xC3, 0x94, 0x04, 0xEE, 0x64, 0x80, 0x94, 0x80, 0x40, 0x03, 0x02, 0x23, 0x4F, 0x90,
+0x43, 0x21, 0xE0, 0x24, 0x02, 0xFD, 0x90, 0x45, 0x36, 0xE0, 0xF9, 0x2D, 0xFD, 0x90, 0x43, 0x23,
+0xE0, 0x25, 0xE0, 0x25, 0xE0, 0x2D, 0x90, 0x04, 0xBC, 0xF0, 0x90, 0x43, 0x21, 0xE0, 0x24, 0x02,
+0xFD, 0x90, 0x43, 0x20, 0xE0, 0x34, 0x00, 0xCD, 0x2F, 0xCD, 0x3E, 0xFC, 0x90, 0x43, 0x22, 0xE0,
+0xFE, 0xA3, 0xE0, 0x78, 0x02, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0x2D, 0xEC, 0x3E, 0x90,
+0x04, 0xBD, 0xF0, 0x75, 0xF0, 0x04, 0xE9, 0x90, 0x43, 0x2E, 0x12, 0x27, 0x8E, 0xE0, 0x90, 0x04,
+0xC0, 0xF0, 0x75, 0xF0, 0x04, 0xE9, 0x90, 0x43, 0x2F, 0x12, 0x27, 0x8E, 0xE0, 0x90, 0x04, 0xC1,
+0xF0, 0x75, 0xF0, 0x04, 0xE9, 0x90, 0x43, 0x30, 0x12, 0x27, 0x8E, 0xE0, 0x90, 0x04, 0xC2, 0xF0,
+0x75, 0xF0, 0x04, 0xE9, 0x90, 0x43, 0x31, 0x12, 0x27, 0x8E, 0xE0, 0x90, 0x04, 0xC3, 0xF0, 0x90,
+0x04, 0xBE, 0x74, 0x01, 0xF0, 0x90, 0x45, 0x35, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xB0, 0x02,
+0x20, 0x3A, 0xE4, 0x90, 0x04, 0xBD, 0xF0, 0x90, 0x04, 0xC0, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3,
+0xF0, 0x90, 0x45, 0x35, 0xF0, 0xA3, 0xF0, 0x90, 0x43, 0x24, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xC3,
+0x90, 0x45, 0x36, 0xE0, 0x9F, 0x90, 0x45, 0x35, 0xE0, 0x9E, 0x40, 0x03, 0x02, 0x23, 0x4F, 0xA3,
+0xE0, 0x24, 0x26, 0xF5, 0x82, 0xE4, 0x34, 0x43, 0xF5, 0x83, 0xE0, 0x75, 0xF0, 0x16, 0xA4, 0x24,
+0x20, 0x90, 0x04, 0xBC, 0xF0, 0x90, 0x04, 0xBE, 0x74, 0x01, 0xF0, 0x90, 0x45, 0x35, 0xE4, 0x75,
+0xF0, 0x01, 0x12, 0x26, 0xB0, 0x80, 0xC0, 0xE4, 0x90, 0x45, 0x35, 0xF0, 0xA3, 0xF0, 0xFD, 0xFC,
+0x90, 0x43, 0x24, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xC3, 0x90, 0x45, 0x36, 0xE0, 0x9F, 0x90, 0x45,
+0x35, 0xE0, 0x9E, 0x40, 0x03, 0x02, 0x23, 0x4F, 0x90, 0x43, 0x21, 0xE0, 0x2D, 0x90, 0x04, 0xBC,
+0xF0, 0x90, 0x43, 0x21, 0xE0, 0x2D, 0x90, 0x43, 0x20, 0xE0, 0x3C, 0x90, 0x04, 0xBD, 0xF0, 0x90,
+0x45, 0x35, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xC6, 0xFE, 0x74, 0x26, 0x25, 0xF0, 0xF5, 0x82,
+0x74, 0x43, 0x3E, 0xF5, 0x83, 0xE0, 0x90, 0x04, 0xC0, 0xF0, 0x90, 0x45, 0x35, 0xE4, 0x75, 0xF0,
+0x01, 0x12, 0x26, 0xC6, 0xFE, 0x74, 0x26, 0x25, 0xF0, 0xF5, 0x82, 0x74, 0x43, 0x3E, 0xF5, 0x83,
+0xE0, 0x90, 0x04, 0xC1, 0xF0, 0x90, 0x45, 0x35, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xC6, 0xFE,
+0x74, 0x26, 0x25, 0xF0, 0xF5, 0x82, 0x74, 0x43, 0x3E, 0xF5, 0x83, 0xE0, 0x90, 0x04, 0xC2, 0xF0,
+0x90, 0x45, 0x35, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xC6, 0xFE, 0x74, 0x26, 0x25, 0xF0, 0xF5,
+0x82, 0x74, 0x43, 0x3E, 0xF5, 0x83, 0xE0, 0x90, 0x04, 0xC3, 0xF0, 0x90, 0x04, 0xBE, 0x74, 0x01,
+0xF0, 0x0D, 0xBD, 0x00, 0x01, 0x0C, 0x02, 0x21, 0x40, 0x90, 0x43, 0x20, 0xE0, 0xFE, 0xA3, 0xE0,
+0xFF, 0x64, 0x05, 0x4E, 0x70, 0x40, 0x90, 0x45, 0x35, 0xF0, 0xA3, 0xF0, 0x90, 0x45, 0x36, 0xE0,
+0xFD, 0x24, 0x26, 0xF5, 0x82, 0xE4, 0x34, 0x43, 0xF5, 0x83, 0xE0, 0xFC, 0x74, 0x40, 0x2D, 0xF5,
+0x82, 0xE4, 0x34, 0x04, 0xF5, 0x83, 0xEC, 0xF0, 0x90, 0x45, 0x35, 0xE4, 0x75, 0xF0, 0x01, 0x12,
+0x26, 0xB0, 0x90, 0x45, 0x35, 0xE0, 0x70, 0x04, 0xA3, 0xE0, 0x64, 0x08, 0x70, 0xCE, 0x90, 0x04,
+0x48, 0xE0, 0x44, 0x04, 0xF0, 0x22, 0xEF, 0x64, 0x06, 0x4E, 0x60, 0x03, 0x02, 0x23, 0x4F, 0x90,
+0x45, 0x35, 0xF0, 0xA3, 0xF0, 0x90, 0x45, 0x36, 0xE0, 0xFF, 0x24, 0x26, 0xF5, 0x82, 0xE4, 0x34,
+0x43, 0xF5, 0x83, 0xE0, 0xFE, 0x74, 0x38, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x04, 0xF5, 0x83, 0xEE,
+0xF0, 0x90, 0x45, 0x35, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xB0, 0x90, 0x45, 0x35, 0xE0, 0x70,
+0x04, 0xA3, 0xE0, 0x64, 0x08, 0x70, 0xCE, 0x90, 0x04, 0x48, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90,
+0x43, 0x26, 0xE0, 0x90, 0x04, 0x22, 0xF0, 0x90, 0x43, 0x27, 0xE0, 0x90, 0x04, 0x23, 0xF0, 0x90,
+0x43, 0x28, 0xE0, 0x90, 0x04, 0x24, 0xF0, 0x90, 0x43, 0x29, 0xE0, 0x90, 0x04, 0x25, 0xF0, 0x90,
+0x43, 0x2A, 0xE0, 0x90, 0x04, 0x28, 0xF0, 0x90, 0x43, 0x2B, 0xE0, 0xFD, 0x7F, 0x0A, 0x02, 0x3D,
+0x00, 0x90, 0x43, 0x26, 0xE0, 0x90, 0x04, 0x22, 0xF0, 0x90, 0x43, 0x27, 0xE0, 0x90, 0x04, 0x23,
+0xF0, 0x90, 0x43, 0x28, 0xE0, 0x90, 0x04, 0x24, 0xF0, 0x90, 0x43, 0x29, 0xE0, 0x90, 0x04, 0x25,
+0xF0, 0x90, 0x43, 0x2A, 0xE0, 0x90, 0x04, 0x28, 0xF0, 0x90, 0x43, 0x2B, 0xE0, 0xFD, 0x7F, 0x0A,
+0x12, 0x3D, 0x00, 0x90, 0x43, 0x2C, 0xE0, 0xFD, 0x7F, 0x88, 0x12, 0x3D, 0x00, 0x90, 0x04, 0x4C,
+0xE0, 0x54, 0xFC, 0xF0, 0xE0, 0xFF, 0x90, 0x43, 0x2D, 0xE0, 0xFE, 0xEF, 0x4E, 0x90, 0x04, 0x4C,
+0xF0, 0xE4, 0x90, 0x45, 0x35, 0xF0, 0xA3, 0xF0, 0x90, 0x45, 0x36, 0xE0, 0xFF, 0x24, 0x2E, 0xF5,
+0x82, 0xE4, 0x34, 0x43, 0xF5, 0x83, 0xE0, 0xFE, 0x74, 0xDC, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x04,
+0xF5, 0x83, 0xEE, 0xF0, 0x90, 0x45, 0x35, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xB0, 0x90, 0x45,
+0x35, 0xE0, 0x70, 0x04, 0xA3, 0xE0, 0x64, 0x22, 0x70, 0xCE, 0x22, 0x90, 0x43, 0x26, 0xE0, 0xFF,
+0xA3, 0xE0, 0xFD, 0xA3, 0xE0, 0xFB, 0xA3, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x12, 0x3C, 0x90, 0x22,
+0x90, 0x06, 0x30, 0x74, 0x70, 0xF0, 0x90, 0x06, 0x31, 0x74, 0xA0, 0xF0, 0xE0, 0x90, 0x06, 0x35,
+0xF0, 0x90, 0x06, 0x36, 0x74, 0xC0, 0xF0, 0x90, 0x06, 0x37, 0x74, 0x08, 0xF0, 0xE4, 0x90, 0x45,
+0x46, 0xF0, 0xA3, 0xF0, 0xC2, 0x05, 0x90, 0x06, 0x20, 0x74, 0x21, 0xF0, 0x90, 0x04, 0x58, 0x74,
+0x14, 0xF0, 0xA3, 0x74, 0x50, 0xF0, 0x12, 0x3C, 0x43, 0x75, 0xA8, 0x81, 0x90, 0x06, 0x05, 0x74,
+0x04, 0xF0, 0x90, 0x06, 0x0F, 0xE0, 0x30, 0xE4, 0x04, 0xD2, 0x06, 0x80, 0x02, 0xC2, 0x06, 0xE4,
+0x90, 0x43, 0x19, 0xF0, 0x20, 0x05, 0x03, 0x02, 0x25, 0xFB, 0xC2, 0x05, 0x90, 0x10, 0x39, 0xE0,
+0xFF, 0x20, 0xE5, 0x03, 0x02, 0x24, 0xCD, 0x54, 0xDF, 0xF0, 0x90, 0x06, 0x0E, 0xE0, 0x20, 0xE0,
+0x03, 0x02, 0x24, 0x4D, 0x7D, 0x17, 0x7F, 0x0C, 0x12, 0x3D, 0x00, 0x7D, 0xB9, 0x7F, 0x0D, 0x12,
+0x3D, 0x00, 0x90, 0x04, 0x54, 0x74, 0x01, 0xF0, 0xE4, 0x90, 0x45, 0x2F, 0xF0, 0xA3, 0xF0, 0x90,
+0x04, 0x54, 0xE0, 0x30, 0xE0, 0x16, 0x90, 0x45, 0x2F, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xB0,
+0x90, 0x45, 0x2F, 0xE0, 0xB4, 0x07, 0xE8, 0xA3, 0xE0, 0xB4, 0xFF, 0xE3, 0xE4, 0x90, 0x04, 0x78,
+0xF0, 0xA3, 0x74, 0x11, 0xF0, 0x90, 0x06, 0x0E, 0xE0, 0x54, 0x01, 0xF0, 0x90, 0x06, 0x30, 0x74,
+0x70, 0xF0, 0x90, 0x06, 0x31, 0x74, 0xA0, 0xF0, 0xE0, 0x90, 0x06, 0x35, 0xF0, 0x90, 0x06, 0x36,
+0x74, 0xC0, 0xF0, 0x90, 0x06, 0x37, 0x74, 0x08, 0xF0, 0x90, 0x06, 0x38, 0x74, 0x03, 0xF0, 0x90,
+0x06, 0x01, 0xE0, 0x44, 0x20, 0xF0, 0x90, 0x06, 0x07, 0x74, 0x02, 0xF0, 0x90, 0x10, 0x38, 0x74,
+0x07, 0xF0, 0x90, 0x06, 0x0E, 0xE0, 0x30, 0xE1, 0x04, 0xE0, 0x54, 0x02, 0xF0, 0x90, 0x06, 0x0E,
+0xE0, 0x30, 0xE3, 0x11, 0xE0, 0x54, 0x08, 0xF0, 0x90, 0x06, 0x0F, 0xE0, 0x30, 0xE4, 0x04, 0xD2,
+0x06, 0x80, 0x02, 0xC2, 0x06, 0x90, 0x06, 0x0E, 0xE0, 0x30, 0xE2, 0x0A, 0xE0, 0x54, 0x04, 0xF0,
+0x90, 0x04, 0x79, 0x74, 0x11, 0xF0, 0x90, 0x06, 0x0E, 0xE0, 0x30, 0xE1, 0x50, 0xE0, 0x20, 0xE0,
+0x4C, 0x7D, 0x17, 0x7F, 0x0C, 0x12, 0x3D, 0x00, 0x7D, 0xB9, 0x7F, 0x0D, 0x12, 0x3D, 0x00, 0x90,
+0x04, 0x54, 0x74, 0x01, 0xF0, 0xE4, 0x90, 0x04, 0x78, 0xF0, 0xA3, 0xF0, 0x90, 0x06, 0x0E, 0xE0,
+0x54, 0x02, 0xF0, 0x90, 0x06, 0x20, 0x74, 0x20, 0xF0, 0xE4, 0x90, 0x04, 0x58, 0xF0, 0x90, 0x06,
+0x07, 0x74, 0x03, 0xF0, 0x90, 0x04, 0x7A, 0xE0, 0x90, 0x45, 0x2E, 0xF0, 0xE0, 0x54, 0xF9, 0xF0,
+0x44, 0x02, 0xF0, 0x90, 0x04, 0x7A, 0xF0, 0x43, 0xA8, 0x81, 0x43, 0x87, 0x01, 0x90, 0x10, 0x39,
+0xE0, 0x30, 0xE0, 0x22, 0x90, 0x06, 0x24, 0xE0, 0x30, 0xE4, 0x05, 0x12, 0x12, 0x0E, 0x80, 0x0F,
+0x90, 0x06, 0x24, 0xE0, 0x30, 0xE3, 0x05, 0x12, 0x34, 0xB9, 0x80, 0x03, 0x12, 0x28, 0xF4, 0x90,
+0x10, 0x39, 0xE0, 0x54, 0xFE, 0xF0, 0x90, 0x45, 0x46, 0xE0, 0x54, 0x14, 0x70, 0x09, 0xA3, 0xE0,
+0xFF, 0x20, 0xE6, 0x03, 0x30, 0xE3, 0x4F, 0x7B, 0x01, 0x7A, 0x06, 0x79, 0x40, 0x12, 0x33, 0x2B,
+0x90, 0x45, 0x46, 0xE0, 0xFF, 0x90, 0x06, 0x48, 0xF0, 0x90, 0x45, 0x47, 0xE0, 0x90, 0x06, 0x49,
+0xF0, 0x90, 0x04, 0x2C, 0xE0, 0x90, 0x06, 0x4A, 0xF0, 0x90, 0x04, 0x2D, 0xE0, 0x90, 0x06, 0x4B,
+0xF0, 0x90, 0x04, 0x2E, 0xE0, 0x90, 0x06, 0x4C, 0xF0, 0x90, 0x04, 0x2F, 0xE0, 0x90, 0x06, 0x4D,
+0xF0, 0x90, 0x06, 0x3F, 0x74, 0x01, 0xF0, 0xEF, 0x54, 0xEB, 0x90, 0x45, 0x46, 0xF0, 0xA3, 0xE0,
+0x54, 0xBF, 0xF0, 0x54, 0xF7, 0xF0, 0x90, 0x45, 0x47, 0xE0, 0xFF, 0x20, 0xE4, 0x03, 0x02, 0x25,
+0xE8, 0x90, 0x04, 0x7A, 0xE0, 0x54, 0xDF, 0xF0, 0xE0, 0x90, 0x45, 0x2E, 0xF0, 0xE0, 0x20, 0xE6,
+0x54, 0x90, 0x04, 0x7A, 0xE0, 0x90, 0x45, 0x2E, 0xF0, 0xE0, 0x54, 0x7F, 0xF0, 0x44, 0x80, 0xF0,
+0x90, 0x04, 0x7A, 0xF0, 0xEF, 0x54, 0xEF, 0x90, 0x45, 0x47, 0xF0, 0x7D, 0x17, 0x7F, 0x0C, 0x12,
+0x3D, 0x00, 0x7D, 0xB9, 0x7F, 0x0D, 0x12, 0x3D, 0x00, 0x90, 0x04, 0x54, 0x74, 0x01, 0xF0, 0xE4,
+0x90, 0x04, 0x78, 0xF0, 0xA3, 0xF0, 0x90, 0x06, 0x20, 0x74, 0x20, 0xF0, 0x90, 0x04, 0x59, 0x74,
+0x10, 0xF0, 0xE4, 0x90, 0x06, 0x05, 0xF0, 0x90, 0x06, 0x07, 0x74, 0x03, 0xF0, 0x75, 0xA8, 0x81,
+0x43, 0x87, 0x01, 0x80, 0x23, 0x90, 0x04, 0x7A, 0xE0, 0x90, 0x45, 0x2E, 0xF0, 0xE0, 0x54, 0x7F,
+0xF0, 0x90, 0x04, 0x7A, 0xF0, 0x90, 0x10, 0x38, 0x74, 0x07, 0xF0, 0x90, 0x06, 0x05, 0x74, 0x04,
+0xF0, 0x90, 0x45, 0x47, 0xE0, 0x54, 0xEF, 0xF0, 0x90, 0x06, 0x20, 0x74, 0x21, 0xF0, 0x90, 0x04,
+0x58, 0x74, 0x14, 0xF0, 0xA3, 0x74, 0x50, 0xF0, 0x43, 0xA8, 0x81, 0x90, 0x43, 0x19, 0xE0, 0x64,
+0x01, 0x60, 0x03, 0x02, 0x23, 0xA4, 0xF0, 0x90, 0x06, 0x24, 0xE0, 0x30, 0xE3, 0x03, 0x02, 0x23,
+0xA4, 0x90, 0x06, 0x25, 0xE0, 0x54, 0xF7, 0xF0, 0x30, 0x04, 0x07, 0xE4, 0x90, 0x06, 0x23, 0xF0,
+0x80, 0x06, 0x90, 0x06, 0x23, 0x74, 0x80, 0xF0, 0x90, 0x06, 0x24, 0x74, 0x08, 0xF0, 0x90, 0x06,
+0x25, 0xF0, 0x02, 0x23, 0xA4, 0x22, 0xBB, 0x01, 0x06, 0x89, 0x82, 0x8A, 0x83, 0xE0, 0x22, 0x50,
+0x02, 0xE7, 0x22, 0xBB, 0xFE, 0x02, 0xE3, 0x22, 0x89, 0x82, 0x8A, 0x83, 0xE4, 0x93, 0x22, 0xBB,
+0x01, 0x0C, 0xE5, 0x82, 0x29, 0xF5, 0x82, 0xE5, 0x83, 0x3A, 0xF5, 0x83, 0xE0, 0x22, 0x50, 0x06,
+0xE9, 0x25, 0x82, 0xF8, 0xE6, 0x22, 0xBB, 0xFE, 0x06, 0xE9, 0x25, 0x82, 0xF8, 0xE2, 0x22, 0xE5,
+0x82, 0x29, 0xF5, 0x82, 0xE5, 0x83, 0x3A, 0xF5, 0x83, 0xE4, 0x93, 0x22, 0xBB, 0x01, 0x06, 0x89,
+0x82, 0x8A, 0x83, 0xF0, 0x22, 0x50, 0x02, 0xF7, 0x22, 0xBB, 0xFE, 0x01, 0xF3, 0x22, 0xF8, 0xBB,
+0x01, 0x0D, 0xE5, 0x82, 0x29, 0xF5, 0x82, 0xE5, 0x83, 0x3A, 0xF5, 0x83, 0xE8, 0xF0, 0x22, 0x50,
+0x06, 0xE9, 0x25, 0x82, 0xC8, 0xF6, 0x22, 0xBB, 0xFE, 0x05, 0xE9, 0x25, 0x82, 0xC8, 0xF2, 0x22,
+0xC5, 0xF0, 0xF8, 0xA3, 0xE0, 0x28, 0xF0, 0xC5, 0xF0, 0xF8, 0xE5, 0x82, 0x15, 0x82, 0x70, 0x02,
+0x15, 0x83, 0xE0, 0x38, 0xF0, 0x22, 0xA3, 0xF8, 0xE0, 0xC5, 0xF0, 0x25, 0xF0, 0xF0, 0xE5, 0x82,
+0x15, 0x82, 0x70, 0x02, 0x15, 0x83, 0xE0, 0xC8, 0x38, 0xF0, 0xE8, 0x22, 0xBB, 0x01, 0x10, 0xE5,
+0x82, 0x29, 0xF5, 0x82, 0xE5, 0x83, 0x3A, 0xF5, 0x83, 0xE0, 0xF5, 0xF0, 0xA3, 0xE0, 0x22, 0x50,
+0x09, 0xE9, 0x25, 0x82, 0xF8, 0x86, 0xF0, 0x08, 0xE6, 0x22, 0xBB, 0xFE, 0x0A, 0xE9, 0x25, 0x82,
+0xF8, 0xE2, 0xF5, 0xF0, 0x08, 0xE2, 0x22, 0xE5, 0x83, 0x2A, 0xF5, 0x83, 0xE9, 0x93, 0xF5, 0xF0,
+0xA3, 0xE9, 0x93, 0x22, 0xBB, 0x01, 0x0D, 0xC5, 0x82, 0x29, 0xC5, 0x82, 0xC5, 0x83, 0x3A, 0xC5,
+0x83, 0x02, 0x26, 0xB0, 0x50, 0x11, 0xC5, 0x82, 0x29, 0xF8, 0x08, 0xE5, 0xF0, 0x26, 0xF6, 0x18,
+0xF5, 0xF0, 0xE5, 0x82, 0x36, 0xF6, 0x22, 0xBB, 0xFE, 0x11, 0xC5, 0x82, 0x29, 0xF8, 0x08, 0xE2,
+0x25, 0xF0, 0xF5, 0xF0, 0xF2, 0x18, 0xE2, 0x35, 0x82, 0xF2, 0x22, 0xF8, 0xE5, 0x82, 0x29, 0xF5,
+0x82, 0xE5, 0x83, 0x2A, 0xF5, 0x83, 0x74, 0x01, 0x93, 0x25, 0xF0, 0xF5, 0xF0, 0xE4, 0x93, 0x38,
+0x22, 0xF8, 0xBB, 0x01, 0x11, 0xE5, 0x82, 0x29, 0xF5, 0x82, 0xE5, 0x83, 0x3A, 0xF5, 0x83, 0xE8,
+0xF0, 0xE5, 0xF0, 0xA3, 0xF0, 0x22, 0x50, 0x09, 0xE9, 0x25, 0x82, 0xC8, 0xF6, 0x08, 0xA6, 0xF0,
+0x22, 0xBB, 0xFE, 0x09, 0xE9, 0x25, 0x82, 0xC8, 0xF2, 0xE5, 0xF0, 0x08, 0xF2, 0x22, 0xA4, 0x25,
+0x82, 0xF5, 0x82, 0xE5, 0xF0, 0x35, 0x83, 0xF5, 0x83, 0x22, 0xE0, 0xFB, 0xA3, 0xE0, 0xFA, 0xA3,
+0xE0, 0xF9, 0x22, 0xF8, 0xE0, 0xFB, 0xA3, 0xA3, 0xE0, 0xF9, 0x25, 0xF0, 0xF0, 0xE5, 0x82, 0x15,
+0x82, 0x70, 0x02, 0x15, 0x83, 0xE0, 0xFA, 0x38, 0xF0, 0x22, 0xEB, 0xF0, 0xA3, 0xEA, 0xF0, 0xA3,
+0xE9, 0xF0, 0x22, 0xBB, 0x01, 0x0D, 0xE5, 0x82, 0x29, 0xF5, 0x82, 0xE5, 0x83, 0x3A, 0xF5, 0x83,
+0x02, 0x27, 0x9A, 0x50, 0x07, 0xE9, 0x25, 0x82, 0xF8, 0x02, 0x28, 0xA4, 0xBB, 0xFE, 0x07, 0xE9,
+0x25, 0x82, 0xF8, 0x02, 0x28, 0xC6, 0xE5, 0x82, 0x29, 0xF5, 0x82, 0xE5, 0x83, 0x3A, 0xF5, 0x83,
+0x02, 0x28, 0xE8, 0xBB, 0x01, 0x0D, 0xC5, 0x82, 0x29, 0xC5, 0x82, 0xC5, 0x83, 0x3A, 0xC5, 0x83,
+0x02, 0x27, 0xA3, 0x50, 0x08, 0xF8, 0xE9, 0x25, 0x82, 0xC8, 0x02, 0x28, 0xAD, 0xBB, 0xFE, 0x08,
+0xF8, 0xE9, 0x25, 0x82, 0xC8, 0x02, 0x28, 0xCF, 0xC5, 0x82, 0x29, 0xC5, 0x82, 0xC5, 0x83, 0x3A,
+0xC5, 0x83, 0x02, 0x28, 0xE8, 0xBB, 0x01, 0x20, 0xE5, 0x82, 0x29, 0xF5, 0x82, 0xE5, 0x83, 0x3A,
+0xF5, 0x83, 0xD0, 0xF0, 0xD0, 0xE0, 0xF8, 0xD0, 0xE0, 0xF9, 0xD0, 0xE0, 0xFA, 0xD0, 0xE0, 0xFB,
+0xE8, 0xC0, 0xE0, 0xC0, 0xF0, 0x02, 0x27, 0xBA, 0x50, 0x18, 0xE9, 0x25, 0x82, 0xF8, 0xD0, 0x83,
+0xD0, 0x82, 0xD0, 0xE0, 0xF9, 0xD0, 0xE0, 0xFA, 0xD0, 0xE0, 0xFB, 0xC0, 0x82, 0xC0, 0x83, 0x02,
+0x28, 0xBD, 0xBB, 0xFE, 0x18, 0xE9, 0x25, 0x82, 0xF8, 0xD0, 0x83, 0xD0, 0x82, 0xD0, 0xE0, 0xF9,
+0xD0, 0xE0, 0xFA, 0xD0, 0xE0, 0xFB, 0xC0, 0x82, 0xC0, 0x83, 0x02, 0x28, 0xDF, 0x22, 0xD0, 0x83,
+0xD0, 0x82, 0xF8, 0xE4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70, 0x0D, 0xA3, 0xA3, 0x93, 0xF8,
+0x74, 0x01, 0x93, 0xF5, 0x82, 0x88, 0x83, 0xE4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60, 0xEF, 0xA3,
+0xA3, 0xA3, 0x80, 0xDF, 0xE6, 0xFB, 0x08, 0xE6, 0xFA, 0x08, 0xE6, 0xF9, 0x22, 0xFA, 0xE6, 0xFB,
+0x08, 0x08, 0xE6, 0xF9, 0x25, 0xF0, 0xF6, 0x18, 0xE6, 0xCA, 0x3A, 0xF6, 0x22, 0xEB, 0xF6, 0x08,
+0xEA, 0xF6, 0x08, 0xE9, 0xF6, 0x22, 0xE2, 0xFB, 0x08, 0xE2, 0xFA, 0x08, 0xE2, 0xF9, 0x22, 0xFA,
+0xE2, 0xFB, 0x08, 0x08, 0xE2, 0xF9, 0x25, 0xF0, 0xF2, 0x18, 0xE2, 0xCA, 0x3A, 0xF2, 0x22, 0xEB,
+0xF2, 0x08, 0xEA, 0xF2, 0x08, 0xE9, 0xF2, 0x22, 0xE4, 0x93, 0xFB, 0x74, 0x01, 0x93, 0xFA, 0x74,
+0x02, 0x93, 0xF9, 0x22, 0x90, 0x06, 0x23, 0xE0, 0x54, 0x7F, 0xFF, 0xC3, 0x74, 0x40, 0x9F, 0x90,
+0x45, 0x31, 0xF0, 0xE4, 0xA3, 0xF0, 0x90, 0x10, 0x3D, 0xE0, 0x64, 0x0B, 0x60, 0x03, 0x02, 0x2A,
+0x60, 0x90, 0x10, 0x44, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x90, 0x43, 0x21, 0xE0, 0x2F, 0x90, 0x45,
+0x34, 0xF0, 0x90, 0x43, 0x20, 0xE0, 0x3E, 0x90, 0x45, 0x33, 0xF0, 0x90, 0x45, 0x31, 0xE0, 0x70,
+0x03, 0x02, 0x2A, 0xA6, 0x14, 0xF0, 0x90, 0x43, 0x22, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xEE, 0x60,
+0x03, 0x02, 0x2A, 0x57, 0xEF, 0x12, 0x28, 0x7E, 0x29, 0x6A, 0x01, 0x29, 0x94, 0x02, 0x29, 0xB5,
+0x03, 0x29, 0xDE, 0x04, 0x29, 0xFE, 0x07, 0x2A, 0x31, 0x09, 0x2A, 0x31, 0x0A, 0x2A, 0x31, 0x0B,
+0x2A, 0x31, 0x0C, 0x2A, 0x31, 0x0D, 0x00, 0x00, 0x2A, 0x57, 0x90, 0x45, 0x32, 0xE0, 0x24, 0x60,
+0xF5, 0x82, 0xE4, 0x34, 0x06, 0xF5, 0x83, 0xE0, 0xFF, 0x90, 0x45, 0x33, 0xE4, 0x75, 0xF0, 0x01,
+0x12, 0x26, 0xC6, 0xFC, 0x74, 0x00, 0x25, 0xF0, 0xF5, 0x82, 0x74, 0x00, 0x3C, 0xF5, 0x83, 0xEF,
+0xF0, 0x02, 0x2A, 0x57, 0x90, 0x45, 0x33, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xC6, 0xAF, 0xF0,
+0x90, 0x45, 0x32, 0xE0, 0x24, 0x60, 0xF5, 0x82, 0xE4, 0x34, 0x06, 0xF5, 0x83, 0xE0, 0xFD, 0x12,
+0x3D, 0x00, 0x02, 0x2A, 0x57, 0x90, 0x45, 0x32, 0xE0, 0x24, 0x60, 0xF5, 0x82, 0xE4, 0x34, 0x06,
+0xF5, 0x83, 0xE0, 0xFF, 0x90, 0x45, 0x33, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xC6, 0xFC, 0x74,
+0x00, 0x25, 0xF0, 0xF5, 0x82, 0x74, 0x04, 0x3C, 0xF5, 0x83, 0xEF, 0xF0, 0x80, 0x79, 0x90, 0x45,
+0x33, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xC6, 0xAF, 0xF0, 0x90, 0x45, 0x32, 0xE0, 0x24, 0x60,
+0xF5, 0x82, 0xE4, 0x34, 0x06, 0xF5, 0x83, 0xE0, 0xFD, 0x12, 0x3A, 0x33, 0x80, 0x59, 0x90, 0x45,
+0x32, 0xE0, 0x24, 0x60, 0xF5, 0x82, 0xE4, 0x34, 0x06, 0xF5, 0x83, 0xE0, 0xFD, 0x7F, 0xF1, 0x12,
+0x3D, 0x00, 0x90, 0x45, 0x34, 0xE0, 0x44, 0x80, 0xFD, 0x7F, 0xF0, 0x12, 0x3D, 0x00, 0x90, 0x45,
+0x33, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xC6, 0xAD, 0xF0, 0x7F, 0xF0, 0x12, 0x3D, 0x00, 0x80,
+0x26, 0x90, 0x43, 0x22, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x90, 0x45, 0x33, 0xE4, 0x75, 0xF0, 0x01,
+0x12, 0x26, 0xC6, 0xAD, 0xF0, 0x90, 0x45, 0x32, 0xE0, 0x24, 0x60, 0xF5, 0x82, 0xE4, 0x34, 0x06,
+0xF5, 0x83, 0xE0, 0xFB, 0x12, 0x3A, 0xAE, 0x90, 0x45, 0x32, 0xE0, 0x04, 0xF0, 0x02, 0x29, 0x2B,
+0x90, 0x10, 0x3D, 0xE0, 0xFF, 0xB4, 0x0D, 0x2D, 0x90, 0x45, 0x31, 0xE0, 0x60, 0x38, 0xA3, 0xE0,
+0xFE, 0x04, 0xF0, 0x74, 0x60, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0x06, 0xF5, 0x83, 0xE0, 0xFE, 0x90,
+0x10, 0x3F, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x27, 0xA3, 0xEE, 0x12, 0x26, 0x7C, 0x90, 0x45, 0x31,
+0xE0, 0x14, 0xF0, 0x80, 0xD3, 0xEF, 0xB4, 0x0C, 0x07, 0xC2, 0x8C, 0xE4, 0x90, 0x43, 0x19, 0xF0,
+0xE4, 0x90, 0x10, 0x3D, 0xF0, 0x22, 0x30, 0x04, 0x0A, 0xC2, 0x04, 0x90, 0x06, 0x23, 0x74, 0xC0,
+0xF0, 0x80, 0x08, 0xD2, 0x04, 0x90, 0x06, 0x23, 0x74, 0x40, 0xF0, 0x90, 0x45, 0x32, 0xE0, 0xFF,
+0x90, 0x10, 0x44, 0xE4, 0x8F, 0xF0, 0x12, 0x26, 0xB0, 0x90, 0x10, 0x42, 0xE0, 0xFE, 0xA3, 0xE0,
+0xFF, 0xA3, 0xE0, 0xB5, 0x06, 0x19, 0xA3, 0xE0, 0xB5, 0x07, 0x14, 0x90, 0x10, 0x3D, 0xE0, 0xB4,
+0x0D, 0x03, 0x12, 0x1E, 0x87, 0x90, 0x06, 0x23, 0x74, 0x80, 0xF0, 0xA3, 0x74, 0x08, 0xF0, 0x90,
+0x06, 0x25, 0x74, 0x08, 0xF0, 0x22, 0x90, 0x45, 0x38, 0x12, 0x27, 0xBA, 0x12, 0x26, 0x36, 0x60,
+0x03, 0x02, 0x2B, 0x8F, 0x7F, 0x1C, 0x12, 0x3B, 0x25, 0x90, 0x45, 0x3B, 0x12, 0x27, 0x9A, 0x90,
+0x00, 0x08, 0xEF, 0x12, 0x26, 0x8E, 0x7F, 0x1D, 0x12, 0x3B, 0x25, 0x90, 0x45, 0x3B, 0x12, 0x27,
+0x9A, 0x90, 0x00, 0x09, 0xEF, 0x12, 0x26, 0x8E, 0x7F, 0x1B, 0x12, 0x3B, 0x25, 0x90, 0x45, 0x3B,
+0x12, 0x27, 0x9A, 0x90, 0x00, 0x07, 0xEF, 0x12, 0x26, 0x8E, 0xE9, 0x24, 0x07, 0xF9, 0xE4, 0x3A,
+0xFA, 0x12, 0x26, 0x36, 0x54, 0x7F, 0x12, 0x26, 0x7C, 0x90, 0x45, 0x3B, 0x12, 0x27, 0x9A, 0x90,
+0x00, 0x07, 0x12, 0x26, 0x4F, 0x90, 0x45, 0x45, 0xF0, 0x90, 0x04, 0x2B, 0x74, 0xFF, 0xF0, 0x12,
+0x3C, 0x43, 0x90, 0x45, 0x3B, 0x12, 0x27, 0x9A, 0x90, 0x00, 0x07, 0x12, 0x26, 0x4F, 0xFF, 0x12,
+0x3D, 0x62, 0x90, 0x45, 0x3B, 0x12, 0x27, 0x9A, 0x90, 0x00, 0x08, 0x12, 0x26, 0x4F, 0xFD, 0x90,
+0x40, 0xC0, 0xF0, 0x90, 0x00, 0x07, 0x12, 0x26, 0x4F, 0xFF, 0x12, 0x39, 0x2D, 0x80, 0x1B, 0x12,
+0x3D, 0xE2, 0x90, 0x04, 0x54, 0xE0, 0x54, 0xFB, 0xF0, 0x90, 0x06, 0x38, 0x74, 0x03, 0xF0, 0x12,
+0x3D, 0x31, 0x90, 0x04, 0x48, 0x74, 0x02, 0xF0, 0x14, 0xF0, 0xE4, 0xFF, 0xFE, 0x74, 0xC4, 0x2F,
+0xF5, 0x82, 0xE4, 0x34, 0x04, 0xF5, 0x83, 0xE0, 0xFD, 0x90, 0x45, 0x3B, 0x12, 0x27, 0x9A, 0xE9,
+0x24, 0x01, 0xF9, 0xE4, 0x3A, 0xFA, 0xE9, 0x2F, 0xF9, 0xEA, 0x3E, 0xFA, 0xED, 0x12, 0x26, 0x7C,
+0x0F, 0xBF, 0x00, 0x01, 0x0E, 0xEF, 0x64, 0x06, 0x4E, 0x70, 0xD2, 0x90, 0x45, 0x38, 0x12, 0x27,
+0x9A, 0x90, 0x00, 0x01, 0x12, 0x26, 0x4F, 0x60, 0x31, 0xE4, 0xFE, 0xFF, 0x90, 0x45, 0x38, 0x12,
+0x27, 0x9A, 0xE9, 0x24, 0x02, 0xF9, 0xE4, 0x3A, 0xFA, 0xE9, 0x2F, 0xF9, 0xEA, 0x3E, 0xFA, 0x12,
+0x26, 0x36, 0xFD, 0x74, 0xC4, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x04, 0xF5, 0x83, 0xED, 0xF0, 0x0F,
+0xBF, 0x00, 0x01, 0x0E, 0xEF, 0x64, 0x06, 0x4E, 0x70, 0xD2, 0x90, 0x45, 0x38, 0x12, 0x27, 0x9A,
+0x90, 0x00, 0x08, 0x12, 0x26, 0x4F, 0x90, 0x04, 0x21, 0xF0, 0x90, 0x00, 0x09, 0x12, 0x26, 0x4F,
+0x90, 0x04, 0x20, 0xF0, 0x90, 0x04, 0x50, 0xE0, 0x44, 0x82, 0xF0, 0x90, 0x04, 0x54, 0x74, 0x0E,
+0xF0, 0x90, 0x45, 0x3B, 0x12, 0x27, 0x9A, 0xE4, 0x12, 0x26, 0x7C, 0xD3, 0x22, 0xAC, 0x07, 0xAA,
+0x05, 0xD2, 0x03, 0x90, 0x04, 0x78, 0xE0, 0x54, 0xFE, 0xF0, 0xEC, 0xD3, 0x94, 0x0E, 0x40, 0x03,
+0x02, 0x2C, 0xFA, 0xEA, 0x94, 0x0E, 0x50, 0x03, 0x02, 0x2C, 0xFA, 0x90, 0x40, 0xC9, 0xE0, 0xFD,
+0x90, 0x40, 0xC8, 0xE0, 0xFB, 0x90, 0x40, 0xC7, 0x12, 0x3C, 0x89, 0x82, 0x03, 0x92, 0x03, 0x90,
+0x40, 0xCC, 0xE0, 0xFD, 0x90, 0x40, 0xCB, 0xE0, 0xFB, 0x90, 0x40, 0xCA, 0x12, 0x3C, 0x89, 0x82,
+0x03, 0x92, 0x03, 0x90, 0x40, 0xD2, 0xE0, 0xFD, 0x90, 0x40, 0xD1, 0xE0, 0xFB, 0x90, 0x40, 0xD0,
+0x12, 0x3C, 0x89, 0x82, 0x03, 0x92, 0x03, 0x90, 0x40, 0xD8, 0xE0, 0xFD, 0x90, 0x40, 0xD7, 0xE0,
+0xFB, 0x90, 0x40, 0xD6, 0x12, 0x3C, 0x89, 0x82, 0x03, 0x92, 0x03, 0x90, 0x40, 0xE1, 0xE0, 0xFD,
+0x90, 0x40, 0xE0, 0xE0, 0xFB, 0x90, 0x40, 0xDF, 0x12, 0x3C, 0x89, 0x82, 0x03, 0x92, 0x03, 0x90,
+0x40, 0xE7, 0xE0, 0xFD, 0x90, 0x40, 0xE6, 0xE0, 0xFB, 0x90, 0x40, 0xE5, 0x12, 0x3C, 0x89, 0x82,
+0x03, 0x92, 0x03, 0x90, 0x40, 0xF0, 0xE0, 0xFD, 0x90, 0x40, 0xEF, 0xE0, 0xFB, 0x90, 0x40, 0xEE,
+0x12, 0x3C, 0x89, 0x82, 0x03, 0x92, 0x03, 0x02, 0x2D, 0x98, 0xEC, 0xD3, 0x94, 0x0E, 0x50, 0x03,
+0x02, 0x2D, 0x98, 0xEA, 0xD3, 0x94, 0x0E, 0x40, 0x03, 0x02, 0x2D, 0x98, 0x90, 0x42, 0xF1, 0xE0,
+0xFD, 0x90, 0x42, 0xF0, 0xE0, 0xFB, 0x90, 0x42, 0xEF, 0x12, 0x3C, 0x89, 0x82, 0x03, 0x92, 0x03,
+0x90, 0x42, 0xF4, 0xE0, 0xFD, 0x90, 0x42, 0xF3, 0xE0, 0xFB, 0x90, 0x42, 0xF2, 0x12, 0x3C, 0x89,
+0x82, 0x03, 0x92, 0x03, 0x90, 0x42, 0xFA, 0xE0, 0xFD, 0x90, 0x42, 0xF9, 0xE0, 0xFB, 0x90, 0x42,
+0xF8, 0x12, 0x3C, 0x89, 0x82, 0x03, 0x92, 0x03, 0x90, 0x43, 0x00, 0xE0, 0xFD, 0x90, 0x42, 0xFF,
+0xE0, 0xFB, 0x90, 0x42, 0xFE, 0x12, 0x3C, 0x89, 0x82, 0x03, 0x92, 0x03, 0x90, 0x43, 0x09, 0xE0,
+0xFD, 0x90, 0x43, 0x08, 0xE0, 0xFB, 0x90, 0x43, 0x07, 0x12, 0x3C, 0x89, 0x82, 0x03, 0x92, 0x03,
+0x90, 0x43, 0x0F, 0xE0, 0xFD, 0x90, 0x43, 0x0E, 0xE0, 0xFB, 0x90, 0x43, 0x0D, 0x12, 0x3C, 0x89,
+0x82, 0x03, 0x92, 0x03, 0x90, 0x43, 0x18, 0xE0, 0xFD, 0x90, 0x43, 0x17, 0xE0, 0xFB, 0x90, 0x43,
+0x16, 0x12, 0x3C, 0x89, 0x82, 0x03, 0x92, 0x03, 0x90, 0x04, 0x78, 0xE0, 0x44, 0x01, 0xF0, 0xA2,
+0x03, 0x22, 0xAC, 0x07, 0xAA, 0x05, 0xD2, 0x03, 0xEC, 0xD3, 0x94, 0x0E, 0x40, 0x03, 0x02, 0x2E,
+0x43, 0xEA, 0x94, 0x0E, 0x50, 0x03, 0x02, 0x2E, 0x43, 0x90, 0x40, 0xC9, 0xE0, 0xFD, 0x90, 0x40,
+0xC8, 0xE0, 0xFB, 0x90, 0x40, 0xC7, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90,
+0x82, 0x03, 0x92, 0x03, 0x90, 0x40, 0xD8, 0xE0, 0xFD, 0x90, 0x40, 0xD7, 0xE0, 0xFB, 0x90, 0x40,
+0xD6, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x03, 0x92, 0x03, 0x90,
+0x40, 0xDE, 0xE0, 0xFD, 0x90, 0x40, 0xDD, 0xE0, 0xFB, 0x90, 0x40, 0xDC, 0xE0, 0x90, 0x45, 0x44,
+0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x03, 0x92, 0x03, 0x90, 0x40, 0xE7, 0xE0, 0xFD, 0x90,
+0x40, 0xE6, 0xE0, 0xFB, 0x90, 0x40, 0xE5, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C,
+0x90, 0x82, 0x03, 0x92, 0x03, 0x90, 0x40, 0xED, 0xE0, 0xFD, 0x90, 0x40, 0xEC, 0xE0, 0xFB, 0x90,
+0x40, 0xEB, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x03, 0x92, 0x03,
+0x02, 0x2E, 0xDC, 0xEC, 0xD3, 0x94, 0x0E, 0x50, 0x03, 0x02, 0x2E, 0xDC, 0xEA, 0xD3, 0x94, 0x0E,
+0x40, 0x03, 0x02, 0x2E, 0xDC, 0x90, 0x42, 0xF1, 0xE0, 0xFD, 0x90, 0x42, 0xF0, 0xE0, 0xFB, 0x90,
+0x42, 0xEF, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x03, 0x92, 0x03,
+0x90, 0x43, 0x00, 0xE0, 0xFD, 0x90, 0x42, 0xFF, 0xE0, 0xFB, 0x90, 0x42, 0xFE, 0xE0, 0x90, 0x45,
+0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x03, 0x92, 0x03, 0x90, 0x43, 0x06, 0xE0, 0xFD,
+0x90, 0x43, 0x05, 0xE0, 0xFB, 0x90, 0x43, 0x04, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12,
+0x3C, 0x90, 0x82, 0x03, 0x92, 0x03, 0x90, 0x43, 0x0F, 0xE0, 0xFD, 0x90, 0x43, 0x0E, 0xE0, 0xFB,
+0x90, 0x43, 0x0D, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x03, 0x92,
+0x03, 0x90, 0x43, 0x15, 0xE0, 0xFD, 0x90, 0x43, 0x14, 0xE0, 0xFB, 0x90, 0x43, 0x13, 0xE0, 0x90,
+0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x03, 0x92, 0x03, 0xA2, 0x03, 0x22, 0x90,
+0x45, 0x40, 0xEF, 0xF0, 0xD2, 0x02, 0x90, 0x40, 0xC0, 0xE0, 0xFF, 0x90, 0x45, 0x40, 0xE0, 0xFD,
+0x12, 0x2D, 0xA2, 0x82, 0x02, 0x92, 0x02, 0x90, 0x45, 0x40, 0xE0, 0xFC, 0xD3, 0x94, 0x0E, 0x50,
+0x10, 0xE4, 0x90, 0x45, 0x44, 0xF0, 0x7B, 0x8A, 0x7D, 0xF1, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x80,
+0x3A, 0xEC, 0xD3, 0x94, 0x28, 0x50, 0x10, 0xE4, 0x90, 0x45, 0x44, 0xF0, 0x7B, 0x8B, 0x7D, 0xF1,
+0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x80, 0x24, 0xEC, 0xD3, 0x94, 0x33, 0x50, 0x10, 0xE4, 0x90, 0x45,
+0x44, 0xF0, 0x7B, 0x8B, 0x7D, 0xB1, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x80, 0x0E, 0xE4, 0x90, 0x45,
+0x44, 0xF0, 0x7B, 0x8B, 0x7D, 0x91, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x90, 0x45, 0x40, 0xE0, 0xFF,
+0x75, 0xF0, 0x03, 0xA4, 0x24, 0xF0, 0xF5, 0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83, 0xE0, 0xFD, 0xEF,
+0x75, 0xF0, 0x03, 0xA4, 0x24, 0xEF, 0xF5, 0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83, 0xE0, 0xFB, 0xEF,
+0x75, 0xF0, 0x03, 0xA4, 0x24, 0xEE, 0xF5, 0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83, 0xE0, 0x90, 0x45,
+0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x02, 0x92, 0x02, 0x90, 0x45, 0x40, 0xE0, 0xFF,
+0x75, 0xF0, 0x03, 0xA4, 0x24, 0x98, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE0, 0xFD, 0xEF,
+0x75, 0xF0, 0x03, 0xA4, 0x24, 0x97, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE0, 0xFB, 0xEF,
+0x75, 0xF0, 0x03, 0xA4, 0x24, 0x96, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE0, 0x90, 0x45,
+0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x02, 0x92, 0x02, 0x90, 0x45, 0x40, 0xE0, 0xFF,
+0x75, 0xF0, 0x03, 0xA4, 0x24, 0x40, 0xF5, 0x82, 0xE4, 0x34, 0x42, 0xF5, 0x83, 0xE0, 0xFD, 0xEF,
+0x75, 0xF0, 0x03, 0xA4, 0x24, 0x3F, 0xF5, 0x82, 0xE4, 0x34, 0x42, 0xF5, 0x83, 0xE0, 0xFB, 0xEF,
+0x75, 0xF0, 0x03, 0xA4, 0x24, 0x3E, 0xF5, 0x82, 0xE4, 0x34, 0x42, 0xF5, 0x83, 0xE0, 0x90, 0x45,
+0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x02, 0x92, 0x02, 0xE4, 0x90, 0x45, 0x44, 0xF0,
+0xFB, 0xFD, 0x7F, 0xC8, 0x12, 0x3D, 0x90, 0xA2, 0x02, 0x22, 0xD2, 0x01, 0xE4, 0x90, 0x04, 0x78,
+0xF0, 0xA3, 0x74, 0x13, 0xF0, 0x7B, 0x01, 0x7A, 0x45, 0x79, 0x40, 0x7F, 0x0D, 0x12, 0x3C, 0xCD,
+0x90, 0x45, 0x40, 0xE0, 0x54, 0xFE, 0xFF, 0xF0, 0xFD, 0x7F, 0x0D, 0x12, 0x3D, 0x00, 0xE4, 0x90,
+0x45, 0x3E, 0xF0, 0xA3, 0xF0, 0x90, 0x45, 0x3E, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xC3, 0x94, 0x10,
+0xEE, 0x64, 0x80, 0x94, 0x80, 0x50, 0x57, 0x90, 0x42, 0xEB, 0x75, 0xF0, 0x03, 0xEF, 0x12, 0x27,
+0x8E, 0xEE, 0x75, 0xF0, 0x03, 0xA4, 0x25, 0x83, 0xF5, 0x83, 0xE0, 0xFD, 0x90, 0x42, 0xEA, 0x75,
+0xF0, 0x03, 0xEF, 0x12, 0x27, 0x8E, 0xEE, 0x75, 0xF0, 0x03, 0xA4, 0x25, 0x83, 0xF5, 0x83, 0xE0,
+0xFB, 0x90, 0x42, 0xE9, 0x75, 0xF0, 0x03, 0xEF, 0x12, 0x27, 0x8E, 0xEE, 0x75, 0xF0, 0x03, 0xA4,
+0x25, 0x83, 0xF5, 0x83, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x01,
+0x92, 0x01, 0x90, 0x45, 0x3E, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xB0, 0x80, 0x97, 0x90, 0x04,
+0x78, 0x74, 0x01, 0xF0, 0xE4, 0x90, 0x45, 0x44, 0xF0, 0xFB, 0xFD, 0x7F, 0x96, 0x12, 0x3D, 0x90,
+0x90, 0x45, 0x44, 0x74, 0x9A, 0xF0, 0x7B, 0xBA, 0x7D, 0x8F, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82,
+0x01, 0x92, 0x01, 0xE4, 0x90, 0x45, 0x44, 0xF0, 0xFB, 0xFD, 0x7F, 0x1E, 0x12, 0x3D, 0x90, 0x90,
+0x45, 0x44, 0x74, 0x3A, 0xF0, 0x7B, 0xBA, 0x7D, 0x8F, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x01,
+0x92, 0x01, 0xE4, 0x90, 0x45, 0x44, 0xF0, 0xFB, 0xFD, 0x7F, 0x1E, 0x12, 0x3D, 0x90, 0x90, 0x43,
+0x18, 0xE0, 0xFD, 0x90, 0x43, 0x17, 0xE0, 0xFB, 0x90, 0x43, 0x16, 0xE0, 0x90, 0x45, 0x44, 0xF0,
+0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x01, 0x92, 0x01, 0x90, 0x04, 0x79, 0x74, 0x13, 0xF0, 0x90,
+0x04, 0x78, 0x74, 0x05, 0xF0, 0x7B, 0x01, 0x7A, 0x45, 0x79, 0x40, 0x7F, 0x0D, 0x12, 0x3C, 0xCD,
+0x90, 0x45, 0x40, 0xE0, 0x44, 0x01, 0xFF, 0xF0, 0xFD, 0x7F, 0x0D, 0x12, 0x3D, 0x00, 0x90, 0x04,
+0x62, 0x74, 0xC0, 0xF0, 0xA2, 0x01, 0x22, 0xD2, 0x01, 0xE4, 0x90, 0x04, 0x78, 0xF0, 0xA3, 0x74,
+0x13, 0xF0, 0xE4, 0x90, 0x45, 0x3E, 0xF0, 0xA3, 0xF0, 0x90, 0x45, 0x3E, 0xE0, 0xFE, 0xA3, 0xE0,
+0xFF, 0xC3, 0x94, 0x0F, 0xEE, 0x64, 0x80, 0x94, 0x80, 0x50, 0x57, 0x90, 0x42, 0xEB, 0x75, 0xF0,
+0x03, 0xEF, 0x12, 0x27, 0x8E, 0xEE, 0x75, 0xF0, 0x03, 0xA4, 0x25, 0x83, 0xF5, 0x83, 0xE0, 0xFD,
+0x90, 0x42, 0xEA, 0x75, 0xF0, 0x03, 0xEF, 0x12, 0x27, 0x8E, 0xEE, 0x75, 0xF0, 0x03, 0xA4, 0x25,
+0x83, 0xF5, 0x83, 0xE0, 0xFB, 0x90, 0x42, 0xE9, 0x75, 0xF0, 0x03, 0xEF, 0x12, 0x27, 0x8E, 0xEE,
+0x75, 0xF0, 0x03, 0xA4, 0x25, 0x83, 0xF5, 0x83, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12,
+0x3C, 0x90, 0x82, 0x01, 0x92, 0x01, 0x90, 0x45, 0x3E, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xB0,
+0x80, 0x97, 0x90, 0x04, 0x78, 0x74, 0x01, 0xF0, 0xE4, 0x90, 0x45, 0x44, 0xF0, 0xFB, 0xFD, 0x7F,
+0x96, 0x12, 0x3D, 0x90, 0xE4, 0x90, 0x45, 0x44, 0xF0, 0x7B, 0xD8, 0x7D, 0x0F, 0x7F, 0xB9, 0x12,
+0x3C, 0x90, 0x82, 0x01, 0x92, 0x01, 0xE4, 0x90, 0x45, 0x44, 0xF0, 0xFB, 0xFD, 0x7F, 0x1E, 0x12,
+0x3D, 0x90, 0xE4, 0x90, 0x45, 0x44, 0xF0, 0x7B, 0x78, 0x7D, 0x0F, 0x7F, 0xB9, 0x12, 0x3C, 0x90,
+0x82, 0x01, 0x92, 0x01, 0xE4, 0x90, 0x45, 0x44, 0xF0, 0xFB, 0xFD, 0x7F, 0x1E, 0x12, 0x3D, 0x90,
+0x90, 0x43, 0x15, 0xE0, 0xFD, 0x90, 0x43, 0x14, 0xE0, 0xFB, 0x90, 0x43, 0x13, 0xE0, 0x90, 0x45,
+0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x01, 0x92, 0x01, 0x90, 0x04, 0x78, 0x74, 0x05,
+0xF0, 0x90, 0x04, 0x62, 0x74, 0xC0, 0xF0, 0xA2, 0x01, 0x22, 0x90, 0x45, 0x40, 0xEF, 0xF0, 0xD2,
+0x02, 0x90, 0x04, 0x78, 0xE0, 0x54, 0xFE, 0xF0, 0x90, 0x45, 0x40, 0xE0, 0xFF, 0x75, 0xF0, 0x03,
+0xA4, 0x24, 0xF0, 0xF5, 0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83, 0xE0, 0xFD, 0xEF, 0x75, 0xF0, 0x03,
+0xA4, 0x24, 0xEF, 0xF5, 0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83, 0xE0, 0xFB, 0xEF, 0x75, 0xF0, 0x03,
+0xA4, 0x24, 0xEE, 0xF5, 0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F,
+0xB9, 0x12, 0x3C, 0x90, 0x82, 0x02, 0x92, 0x02, 0x90, 0x45, 0x40, 0xE0, 0xFF, 0x75, 0xF0, 0x03,
+0xA4, 0x24, 0x98, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE0, 0xFD, 0xEF, 0x75, 0xF0, 0x03,
+0xA4, 0x24, 0x97, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE0, 0xFB, 0xEF, 0x75, 0xF0, 0x03,
+0xA4, 0x24, 0x96, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F,
+0xB9, 0x12, 0x3C, 0x90, 0x82, 0x02, 0x92, 0x02, 0x90, 0x45, 0x40, 0xE0, 0xFF, 0x75, 0xF0, 0x03,
+0xA4, 0x24, 0x40, 0xF5, 0x82, 0xE4, 0x34, 0x42, 0xF5, 0x83, 0xE0, 0xFD, 0xEF, 0x75, 0xF0, 0x03,
+0xA4, 0x24, 0x3F, 0xF5, 0x82, 0xE4, 0x34, 0x42, 0xF5, 0x83, 0xE0, 0xFB, 0xEF, 0x75, 0xF0, 0x03,
+0xA4, 0x24, 0x3E, 0xF5, 0x82, 0xE4, 0x34, 0x42, 0xF5, 0x83, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F,
+0xB9, 0x12, 0x3C, 0x90, 0x82, 0x02, 0x92, 0x02, 0x90, 0x04, 0x78, 0xE0, 0x44, 0x01, 0xF0, 0xE4,
+0x90, 0x45, 0x44, 0xF0, 0xFB, 0xFD, 0x7F, 0xC8, 0x12, 0x3D, 0x90, 0x90, 0x40, 0xC0, 0xE0, 0xFF,
+0x90, 0x45, 0x40, 0xE0, 0xFD, 0x12, 0x2C, 0x4D, 0xA2, 0x02, 0x22, 0x90, 0x45, 0x31, 0x12, 0x27,
+0xBA, 0xE4, 0xFF, 0x90, 0x04, 0x48, 0xE0, 0x44, 0x10, 0xF0, 0xE4, 0xFD, 0xFC, 0x90, 0x04, 0x48,
+0xE0, 0xFF, 0x30, 0xE4, 0x0B, 0x0D, 0xBD, 0x00, 0x01, 0x0C, 0xBC, 0x07, 0xF0, 0xBD, 0xFF, 0xED,
+0xAE, 0x04, 0xAF, 0x05, 0xBE, 0x07, 0x05, 0xBF, 0xFF, 0x02, 0xC3, 0x22, 0x90, 0x04, 0x30, 0xE0,
+0xFF, 0x90, 0x45, 0x31, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x27, 0xA3, 0xEF, 0x12, 0x26, 0x7C, 0x90,
+0x04, 0x31, 0xE0, 0xFF, 0x90, 0x45, 0x31, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x27, 0xA3, 0xEF, 0x12,
+0x26, 0x7C, 0x90, 0x04, 0x32, 0xE0, 0xFF, 0x90, 0x45, 0x31, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x27,
+0xA3, 0xEF, 0x12, 0x26, 0x7C, 0x90, 0x04, 0x33, 0xE0, 0xFF, 0x90, 0x45, 0x31, 0xE4, 0x75, 0xF0,
+0x01, 0x12, 0x27, 0xA3, 0xEF, 0x12, 0x26, 0x7C, 0x90, 0x04, 0x34, 0xE0, 0xFF, 0x90, 0x45, 0x31,
+0xE4, 0x75, 0xF0, 0x01, 0x12, 0x27, 0xA3, 0xEF, 0x12, 0x26, 0x7C, 0x90, 0x04, 0x35, 0xE0, 0xFF,
+0x90, 0x45, 0x31, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x27, 0xA3, 0xEF, 0x12, 0x26, 0x7C, 0x90, 0x04,
+0x36, 0xE0, 0xFF, 0x90, 0x45, 0x31, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x27, 0xA3, 0xEF, 0x12, 0x26,
+0x7C, 0x90, 0x04, 0x37, 0xE0, 0xFF, 0x90, 0x45, 0x31, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x27, 0xA3,
+0xEF, 0x12, 0x26, 0x7C, 0xD3, 0x22, 0x7B, 0x01, 0x7A, 0x10, 0x79, 0x34, 0x90, 0x45, 0x3A, 0x12,
+0x27, 0xBA, 0x90, 0x45, 0x3A, 0x12, 0x27, 0x9A, 0x90, 0x00, 0x12, 0x12, 0x27, 0xC3, 0xC0, 0x03,
+0xC0, 0x02, 0xC0, 0x01, 0x90, 0x45, 0x3A, 0x12, 0x27, 0x9A, 0x90, 0x00, 0x15, 0x12, 0x28, 0x25,
+0x90, 0x45, 0x3A, 0x12, 0x27, 0x9A, 0x90, 0x00, 0x18, 0x12, 0x26, 0xDC, 0xFF, 0x90, 0x00, 0x1A,
+0xE5, 0xF0, 0x8F, 0xF0, 0x12, 0x27, 0x61, 0xE4, 0xFF, 0xEF, 0xC3, 0x94, 0x40, 0x50, 0x44, 0x90,
+0x45, 0x3A, 0x12, 0x27, 0x9A, 0x90, 0x00, 0x18, 0x12, 0x26, 0xDC, 0xD3, 0x94, 0x00, 0xE5, 0xF0,
+0x94, 0x00, 0x40, 0x2F, 0x90, 0x00, 0x12, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x27, 0xF3, 0x12, 0x26,
+0x36, 0xFE, 0xAD, 0x07, 0x0F, 0x74, 0x60, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x06, 0xF5, 0x83, 0xEE,
+0xF0, 0x90, 0x45, 0x3A, 0x12, 0x27, 0x9A, 0x90, 0x00, 0x18, 0x74, 0xFF, 0xF5, 0xF0, 0x12, 0x27,
+0x14, 0x80, 0xB6, 0xEF, 0x70, 0x17, 0x90, 0x06, 0x23, 0x74, 0x80, 0xF0, 0xE4, 0xA3, 0xF0, 0x90,
+0x10, 0x3D, 0xE0, 0xB4, 0x0C, 0x1C, 0x12, 0x3E, 0x36, 0xD2, 0x8C, 0x80, 0x15, 0x30, 0x04, 0x0B,
+0xC2, 0x04, 0xEF, 0x44, 0x80, 0x90, 0x06, 0x23, 0xF0, 0x80, 0x07, 0xD2, 0x04, 0x90, 0x06, 0x23,
+0xEF, 0xF0, 0x90, 0x06, 0x25, 0x74, 0x08, 0xF0, 0x22, 0x90, 0x06, 0x25, 0xE0, 0x30, 0xE0, 0x2F,
+0x90, 0x10, 0x3D, 0xE0, 0x24, 0xFB, 0x70, 0x1D, 0x90, 0x10, 0x49, 0x12, 0x27, 0x9A, 0x90, 0x10,
+0x46, 0x12, 0x27, 0xBA, 0x90, 0x10, 0x4E, 0xE0, 0xFF, 0xA3, 0xE0, 0x90, 0x10, 0x4C, 0xCF, 0xF0,
+0xA3, 0xEF, 0xF0, 0x80, 0x07, 0xE4, 0x90, 0x10, 0x4C, 0xF0, 0xA3, 0xF0, 0x02, 0x33, 0xF6, 0x90,
+0x10, 0x3D, 0xE0, 0x12, 0x28, 0x7E, 0x35, 0x12, 0x01, 0x35, 0x12, 0x05, 0x35, 0x12, 0x07, 0x35,
+0x12, 0x09, 0x35, 0x15, 0x0B, 0x35, 0x12, 0x0C, 0x35, 0x1B, 0x0D, 0x35, 0x21, 0x0F, 0x00, 0x00,
+0x35, 0x5C, 0x02, 0x33, 0xF6, 0xE4, 0x90, 0x10, 0x3D, 0xF0, 0x22, 0xE4, 0x90, 0x10, 0x3D, 0xF0,
+0x22, 0x90, 0x10, 0x50, 0xE0, 0xFF, 0xB4, 0x01, 0x07, 0x90, 0x06, 0x07, 0x74, 0x20, 0xF0, 0x22,
+0xEF, 0xB4, 0x02, 0x07, 0x90, 0x06, 0x07, 0x74, 0x40, 0xF0, 0x22, 0xEF, 0xB4, 0x03, 0x07, 0x90,
+0x06, 0x07, 0x74, 0x60, 0xF0, 0x22, 0xEF, 0xB4, 0x04, 0x07, 0x90, 0x06, 0x07, 0x74, 0x80, 0xF0,
+0x22, 0xEF, 0xB4, 0x05, 0x0C, 0x90, 0x06, 0x07, 0x74, 0xA0, 0xF0, 0x22, 0xE4, 0x90, 0x10, 0x3D,
+0xF0, 0x22, 0x78, 0x7F, 0xE4, 0xF6, 0xD8, 0xFD, 0x75, 0x81, 0x20, 0x02, 0x35, 0xA9, 0x02, 0x23,
+0x50, 0xE4, 0x93, 0xA3, 0xF8, 0xE4, 0x93, 0xA3, 0x40, 0x03, 0xF6, 0x80, 0x01, 0xF2, 0x08, 0xDF,
+0xF4, 0x80, 0x29, 0xE4, 0x93, 0xA3, 0xF8, 0x54, 0x07, 0x24, 0x0C, 0xC8, 0xC3, 0x33, 0xC4, 0x54,
+0x0F, 0x44, 0x20, 0xC8, 0x83, 0x40, 0x04, 0xF4, 0x56, 0x80, 0x01, 0x46, 0xF6, 0xDF, 0xE4, 0x80,
+0x0B, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x3E, 0x45, 0xE4, 0x7E, 0x01, 0x93,
+0x60, 0xBC, 0xA3, 0xFF, 0x54, 0x3F, 0x30, 0xE5, 0x09, 0x54, 0x1F, 0xFE, 0xE4, 0x93, 0xA3, 0x60,
+0x01, 0x0E, 0xCF, 0x54, 0xC0, 0x25, 0xE0, 0x60, 0xA8, 0x40, 0xB8, 0xE4, 0x93, 0xA3, 0xFA, 0xE4,
+0x93, 0xA3, 0xF8, 0xE4, 0x93, 0xA3, 0xC8, 0xC5, 0x82, 0xC8, 0xCA, 0xC5, 0x83, 0xCA, 0xF0, 0xA3,
+0xC8, 0xC5, 0x82, 0xC8, 0xCA, 0xC5, 0x83, 0xCA, 0xDF, 0xE9, 0xDE, 0xE7, 0x80, 0xBE, 0xAC, 0x07,
+0xD2, 0x02, 0xEC, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0xF0, 0xF5, 0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83,
+0xE0, 0xFD, 0xEC, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0xEF, 0xF5, 0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83,
+0xE0, 0xFB, 0xEC, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0xEE, 0xF5, 0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83,
+0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x02, 0x92, 0x02, 0xEC, 0x75,
+0xF0, 0x03, 0xA4, 0x24, 0x98, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE0, 0xFD, 0xEC, 0x75,
+0xF0, 0x03, 0xA4, 0x24, 0x97, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE0, 0xFB, 0xEC, 0x75,
+0xF0, 0x03, 0xA4, 0x24, 0x96, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE0, 0x90, 0x45, 0x44,
+0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x02, 0x92, 0x02, 0xE4, 0x90, 0x45, 0x44, 0xF0, 0xFB,
+0xFD, 0x7F, 0xC8, 0x12, 0x3D, 0x90, 0xA2, 0x02, 0x22, 0xAC, 0x07, 0xD2, 0x02, 0xEC, 0x75, 0xF0,
+0x03, 0xA4, 0x24, 0xF0, 0xF5, 0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83, 0xE0, 0xFD, 0xEC, 0x75, 0xF0,
+0x03, 0xA4, 0x24, 0xEF, 0xF5, 0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83, 0xE0, 0xFB, 0xEC, 0x75, 0xF0,
+0x03, 0xA4, 0x24, 0xEE, 0xF5, 0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83, 0xE0, 0x90, 0x45, 0x44, 0xF0,
+0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x02, 0x92, 0x02, 0xEC, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0x98,
+0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE0, 0xFD, 0xEC, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0x97,
+0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE0, 0xFB, 0xEC, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0x96,
+0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C,
+0x90, 0x82, 0x02, 0x92, 0x02, 0xE4, 0x90, 0x45, 0x44, 0xF0, 0xFB, 0xFD, 0x7F, 0xC8, 0x12, 0x3D,
+0x90, 0xA2, 0x02, 0x22, 0xAC, 0x07, 0xD2, 0x02, 0xEC, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0xF0, 0xF5,
+0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83, 0xE0, 0xFD, 0xEC, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0xEF, 0xF5,
+0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83, 0xE0, 0xFB, 0xEC, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0xEE, 0xF5,
+0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90,
+0x82, 0x02, 0x92, 0x02, 0xEC, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0x98, 0xF5, 0x82, 0xE4, 0x34, 0x41,
+0xF5, 0x83, 0xE0, 0xFD, 0xEC, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0x97, 0xF5, 0x82, 0xE4, 0x34, 0x41,
+0xF5, 0x83, 0xE0, 0xFB, 0xEC, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0x96, 0xF5, 0x82, 0xE4, 0x34, 0x41,
+0xF5, 0x83, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x02, 0x92, 0x02,
+0xE4, 0x90, 0x45, 0x44, 0xF0, 0xFB, 0xFD, 0x7F, 0xC8, 0x12, 0x3D, 0x90, 0xA2, 0x02, 0x22, 0xD2,
+0x01, 0xE4, 0x90, 0x04, 0x78, 0xF0, 0xA3, 0x74, 0x1B, 0xF0, 0x90, 0x04, 0x78, 0x74, 0x05, 0xF0,
+0xE4, 0x90, 0x45, 0x3E, 0xF0, 0xA3, 0xF0, 0x90, 0x45, 0x3E, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xC3,
+0x94, 0x0B, 0xEE, 0x64, 0x80, 0x94, 0x80, 0x50, 0x57, 0x90, 0x42, 0xEB, 0x75, 0xF0, 0x03, 0xEF,
+0x12, 0x27, 0x8E, 0xEE, 0x75, 0xF0, 0x03, 0xA4, 0x25, 0x83, 0xF5, 0x83, 0xE0, 0xFD, 0x90, 0x42,
+0xEA, 0x75, 0xF0, 0x03, 0xEF, 0x12, 0x27, 0x8E, 0xEE, 0x75, 0xF0, 0x03, 0xA4, 0x25, 0x83, 0xF5,
+0x83, 0xE0, 0xFB, 0x90, 0x42, 0xE9, 0x75, 0xF0, 0x03, 0xEF, 0x12, 0x27, 0x8E, 0xEE, 0x75, 0xF0,
+0x03, 0xA4, 0x25, 0x83, 0xF5, 0x83, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90,
+0x82, 0x01, 0x92, 0x01, 0x90, 0x45, 0x3E, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xB0, 0x80, 0x97,
+0x90, 0x04, 0x62, 0x74, 0xC0, 0xF0, 0xA2, 0x01, 0x22, 0xD2, 0x01, 0xE4, 0x90, 0x04, 0x78, 0xF0,
+0xA3, 0x74, 0x1B, 0xF0, 0x90, 0x04, 0x78, 0x74, 0x05, 0xF0, 0xE4, 0x90, 0x45, 0x3E, 0xF0, 0xA3,
+0xF0, 0x90, 0x45, 0x3E, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xC3, 0x94, 0x0D, 0xEE, 0x64, 0x80, 0x94,
+0x80, 0x50, 0x57, 0x90, 0x42, 0xEB, 0x75, 0xF0, 0x03, 0xEF, 0x12, 0x27, 0x8E, 0xEE, 0x75, 0xF0,
+0x03, 0xA4, 0x25, 0x83, 0xF5, 0x83, 0xE0, 0xFD, 0x90, 0x42, 0xEA, 0x75, 0xF0, 0x03, 0xEF, 0x12,
+0x27, 0x8E, 0xEE, 0x75, 0xF0, 0x03, 0xA4, 0x25, 0x83, 0xF5, 0x83, 0xE0, 0xFB, 0x90, 0x42, 0xE9,
+0x75, 0xF0, 0x03, 0xEF, 0x12, 0x27, 0x8E, 0xEE, 0x75, 0xF0, 0x03, 0xA4, 0x25, 0x83, 0xF5, 0x83,
+0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x01, 0x92, 0x01, 0x90, 0x45,
+0x3E, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xB0, 0x80, 0x97, 0x90, 0x04, 0x62, 0x74, 0xC0, 0xF0,
+0xA2, 0x01, 0x22, 0xD2, 0x01, 0xE4, 0x90, 0x04, 0x78, 0xF0, 0xA3, 0x74, 0x1B, 0xF0, 0x90, 0x04,
+0x78, 0x74, 0x05, 0xF0, 0xE4, 0x90, 0x45, 0x3E, 0xF0, 0xA3, 0xF0, 0x90, 0x45, 0x3E, 0xE0, 0xFE,
+0xA3, 0xE0, 0xFF, 0xC3, 0x94, 0x0F, 0xEE, 0x64, 0x80, 0x94, 0x80, 0x50, 0x57, 0x90, 0x42, 0xEB,
+0x75, 0xF0, 0x03, 0xEF, 0x12, 0x27, 0x8E, 0xEE, 0x75, 0xF0, 0x03, 0xA4, 0x25, 0x83, 0xF5, 0x83,
+0xE0, 0xFD, 0x90, 0x42, 0xEA, 0x75, 0xF0, 0x03, 0xEF, 0x12, 0x27, 0x8E, 0xEE, 0x75, 0xF0, 0x03,
+0xA4, 0x25, 0x83, 0xF5, 0x83, 0xE0, 0xFB, 0x90, 0x42, 0xE9, 0x75, 0xF0, 0x03, 0xEF, 0x12, 0x27,
+0x8E, 0xEE, 0x75, 0xF0, 0x03, 0xA4, 0x25, 0x83, 0xF5, 0x83, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F,
+0xB9, 0x12, 0x3C, 0x90, 0x82, 0x01, 0x92, 0x01, 0x90, 0x45, 0x3E, 0xE4, 0x75, 0xF0, 0x01, 0x12,
+0x26, 0xB0, 0x80, 0x97, 0x90, 0x04, 0x62, 0x74, 0xC0, 0xF0, 0xA2, 0x01, 0x22, 0x90, 0x45, 0x3E,
+0xED, 0xF0, 0xD2, 0x01, 0x90, 0x04, 0x57, 0xE0, 0x90, 0x45, 0x3F, 0xF0, 0x90, 0x04, 0x57, 0xE0,
+0x54, 0xFE, 0xF0, 0xEF, 0x12, 0x28, 0x7E, 0x39, 0x60, 0x03, 0x39, 0x78, 0x09, 0x39, 0x6C, 0x0A,
+0x39, 0x78, 0x0C, 0x39, 0x84, 0x0D, 0x39, 0x60, 0x0E, 0x39, 0x90, 0x0F, 0x00, 0x00, 0x39, 0x9C,
+0x90, 0x45, 0x3E, 0xE0, 0xFF, 0x12, 0x35, 0xEE, 0x92, 0x01, 0x80, 0x32, 0x90, 0x45, 0x3E, 0xE0,
+0xFF, 0x12, 0x32, 0x3A, 0x92, 0x01, 0x80, 0x26, 0x90, 0x45, 0x3E, 0xE0, 0xFF, 0x12, 0x36, 0x79,
+0x92, 0x01, 0x80, 0x1A, 0x90, 0x45, 0x3E, 0xE0, 0xFF, 0x12, 0x37, 0x04, 0x92, 0x01, 0x80, 0x0E,
+0x90, 0x45, 0x3E, 0xE0, 0xFF, 0x12, 0x2E, 0xDF, 0x92, 0x01, 0x80, 0x02, 0xC2, 0x01, 0x12, 0x3D,
+0xE2, 0x90, 0x45, 0x3F, 0xE0, 0x90, 0x04, 0x57, 0xF0, 0x90, 0x45, 0x3E, 0xE0, 0x90, 0x40, 0xC0,
+0xF0, 0xA2, 0x01, 0x22, 0xAC, 0x07, 0xE4, 0x90, 0x45, 0x3A, 0xF0, 0xA3, 0xF0, 0xD2, 0x00, 0x7D,
+0x03, 0xEC, 0x70, 0x13, 0x12, 0x3C, 0xC5, 0x90, 0x45, 0x3B, 0xE0, 0x54, 0xF9, 0xFF, 0xF0, 0xFD,
+0x7F, 0x09, 0x12, 0x3D, 0x00, 0x80, 0x59, 0xEC, 0xB4, 0x01, 0x16, 0x12, 0x3C, 0xC5, 0x90, 0x45,
+0x3B, 0xE0, 0x54, 0xFD, 0xF0, 0x44, 0x04, 0xFF, 0xF0, 0xFD, 0x7F, 0x09, 0x12, 0x3D, 0x00, 0x80,
+0x3F, 0xEC, 0xB4, 0x02, 0x1B, 0x7B, 0x01, 0x7A, 0x45, 0x79, 0x3A, 0x7F, 0x0A, 0x12, 0x3C, 0xCD,
+0x90, 0x45, 0x3A, 0xE0, 0x54, 0xFC, 0xFF, 0xF0, 0xFD, 0x7F, 0x0A, 0x12, 0x3D, 0x00, 0x80, 0x20,
+0xEC, 0xB4, 0x03, 0x1C, 0x7B, 0x01, 0x7A, 0x45, 0x79, 0x3A, 0x7F, 0x0A, 0x12, 0x3C, 0xCD, 0x90,
+0x45, 0x3A, 0xE0, 0x54, 0xFE, 0xF0, 0x44, 0x02, 0xFF, 0xF0, 0xFD, 0x7F, 0x0A, 0x12, 0x3D, 0x00,
+0xA2, 0x00, 0x22, 0x90, 0x45, 0x38, 0xEF, 0xF0, 0xA3, 0xED, 0xF0, 0x90, 0x04, 0x0B, 0xE0, 0xF9,
+0x54, 0xFB, 0xF0, 0xE4, 0xFF, 0xFE, 0x90, 0x04, 0x09, 0x74, 0x50, 0xF0, 0x90, 0x45, 0x38, 0xE0,
+0x90, 0x04, 0x0A, 0xF0, 0x90, 0x45, 0x39, 0xE0, 0x90, 0x04, 0x0E, 0xF0, 0x90, 0x04, 0x08, 0x74,
+0x80, 0xF0, 0xE4, 0xFD, 0xFC, 0x90, 0x04, 0x08, 0xE0, 0x90, 0x45, 0x3A, 0xF0, 0xE0, 0x54, 0x03,
+0x70, 0x0B, 0x0D, 0xBD, 0x00, 0x01, 0x0C, 0xBC, 0x07, 0xEB, 0xBD, 0xFF, 0xE8, 0xC3, 0xED, 0x94,
+0xFF, 0xEC, 0x94, 0x07, 0x50, 0x07, 0x90, 0x45, 0x3A, 0xE0, 0x30, 0xE1, 0x0B, 0x0F, 0xBF, 0x00,
+0x01, 0x0E, 0xBE, 0x07, 0xB1, 0xBF, 0xFF, 0xAE, 0xBE, 0x07, 0x0A, 0xBF, 0xFF, 0x07, 0x90, 0x04,
+0x0B, 0xE9, 0xF0, 0xC3, 0x22, 0xAF, 0x01, 0x90, 0x04, 0x0B, 0xE9, 0xF0, 0xD3, 0x22, 0x90, 0x45,
+0x35, 0xED, 0xF0, 0xA3, 0xEB, 0xF0, 0xEE, 0x70, 0x56, 0xEF, 0x24, 0xF6, 0x60, 0x1B, 0x14, 0x60,
+0x26, 0x14, 0x60, 0x31, 0x14, 0x60, 0x3C, 0x24, 0x04, 0x70, 0x44, 0x7B, 0x01, 0x7A, 0x42, 0x79,
+0xE9, 0x90, 0x45, 0x37, 0x12, 0x27, 0xBA, 0x80, 0x36, 0x7B, 0x01, 0x7A, 0x40, 0x79, 0xC1, 0x90,
+0x45, 0x37, 0x12, 0x27, 0xBA, 0x80, 0x28, 0x7B, 0x01, 0x7A, 0x40, 0x79, 0xF1, 0x90, 0x45, 0x37,
+0x12, 0x27, 0xBA, 0x80, 0x1A, 0x7B, 0x01, 0x7A, 0x41, 0x79, 0x99, 0x90, 0x45, 0x37, 0x12, 0x27,
+0xBA, 0x80, 0x0C, 0x7B, 0x01, 0x7A, 0x42, 0x79, 0x41, 0x90, 0x45, 0x37, 0x12, 0x27, 0xBA, 0x90,
+0x45, 0x36, 0xE0, 0xFF, 0xA3, 0x12, 0x27, 0x9A, 0x90, 0x45, 0x35, 0xE0, 0xF5, 0x82, 0x75, 0x83,
+0x00, 0xEF, 0x02, 0x26, 0x8E, 0x90, 0x45, 0x3F, 0xEF, 0xF0, 0xA3, 0x74, 0xFF, 0xF0, 0x90, 0x04,
+0x0B, 0xE0, 0x90, 0x45, 0x41, 0xF0, 0xE4, 0xFF, 0xFE, 0x90, 0x04, 0x09, 0x74, 0x50, 0xF0, 0x90,
+0x45, 0x3F, 0xE0, 0x90, 0x04, 0x0A, 0xF0, 0x90, 0x04, 0x08, 0x74, 0x40, 0xF0, 0xE4, 0xFD, 0xFC,
+0x90, 0x04, 0x08, 0xE0, 0xF9, 0x54, 0x03, 0x70, 0x0B, 0x0D, 0xBD, 0x00, 0x01, 0x0C, 0xBC, 0x07,
+0xEF, 0xBD, 0xFF, 0xEC, 0xC3, 0xED, 0x94, 0xFF, 0xEC, 0x94, 0x07, 0x50, 0x04, 0xE9, 0x30, 0xE1,
+0x0B, 0x0F, 0xBF, 0x00, 0x01, 0x0E, 0xBE, 0x07, 0xC0, 0xBF, 0xFF, 0xBD, 0x90, 0x04, 0x0C, 0xE0,
+0x90, 0x45, 0x40, 0xF0, 0xA3, 0xE0, 0x90, 0x04, 0x0B, 0xF0, 0x90, 0x45, 0x40, 0xE0, 0xFF, 0x22,
+0xE4, 0xFE, 0xEF, 0x30, 0xE5, 0x11, 0xE4, 0xFC, 0xFD, 0x7C, 0x08, 0x90, 0x04, 0xD4, 0xE4, 0xF0,
+0xA3, 0xDC, 0xFC, 0x7C, 0x00, 0x7D, 0x08, 0xEF, 0x54, 0xC0, 0x60, 0x12, 0xE4, 0xFC, 0xFD, 0x7C,
+0x08, 0x90, 0x04, 0xD4, 0x74, 0xFF, 0xF0, 0xA3, 0xDC, 0xFC, 0x7C, 0x00, 0x7D, 0x08, 0xEF, 0x30,
+0xE6, 0x07, 0xEE, 0x44, 0x78, 0xFE, 0x54, 0xFE, 0xFE, 0xEF, 0x54, 0x88, 0x60, 0x04, 0xEE, 0x44,
+0x08, 0xFE, 0xEF, 0x30, 0xE4, 0x04, 0xEE, 0x44, 0x10, 0xFE, 0xEF, 0x30, 0xE1, 0x04, 0xEE, 0x44,
+0x02, 0xFE, 0x90, 0x04, 0x56, 0xE0, 0xFF, 0x6E, 0x60, 0x02, 0xEE, 0xF0, 0x22, 0xC0, 0xE0, 0xC0,
+0x83, 0xC0, 0x82, 0xC0, 0xD0, 0x75, 0xD0, 0x00, 0xC0, 0x07, 0xD2, 0x05, 0x53, 0xA8, 0xFE, 0x90,
+0x06, 0x20, 0xE4, 0xF0, 0x90, 0x04, 0x58, 0xF0, 0xA3, 0xF0, 0x90, 0x06, 0x21, 0xE0, 0xFF, 0x90,
+0x10, 0x39, 0xE0, 0x4F, 0xF0, 0x90, 0x06, 0x21, 0xEF, 0xF0, 0x90, 0x04, 0x5C, 0xE0, 0xFF, 0x90,
+0x45, 0x46, 0xE0, 0x4F, 0xF0, 0x90, 0x04, 0x5C, 0xEF, 0xF0, 0xA3, 0xE0, 0xFF, 0x90, 0x45, 0x47,
+0xE0, 0x4F, 0xF0, 0x90, 0x04, 0x5D, 0xEF, 0xF0, 0xD0, 0x07, 0xD0, 0xD0, 0xD0, 0x82, 0xD0, 0x83,
+0xD0, 0xE0, 0x32, 0x90, 0x04, 0x79, 0x74, 0x11, 0xF0, 0x12, 0x3D, 0x31, 0xE4, 0x90, 0x45, 0x3E,
+0xF0, 0x90, 0x45, 0x3E, 0xE0, 0xFF, 0xC3, 0x94, 0x06, 0x50, 0x1A, 0x12, 0x3B, 0x25, 0x90, 0x45,
+0x3E, 0xE0, 0x24, 0xC4, 0xF5, 0x82, 0xE4, 0x34, 0x04, 0xF5, 0x83, 0xEF, 0xF0, 0x90, 0x45, 0x3E,
+0xE0, 0x04, 0xF0, 0x80, 0xDC, 0x90, 0x04, 0x48, 0x74, 0x02, 0xF0, 0x14, 0xF0, 0x7F, 0x30, 0x12,
+0x3B, 0x90, 0x90, 0x04, 0x54, 0x74, 0x02, 0xF0, 0x22, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9,
+0x90, 0x04, 0x71, 0xED, 0xF0, 0xA3, 0xEB, 0xF0, 0x90, 0x45, 0x44, 0xE0, 0x90, 0x04, 0x73, 0xF0,
+0x90, 0x04, 0x70, 0xEF, 0xF0, 0xE4, 0xFF, 0xFE, 0x90, 0x04, 0x70, 0xE0, 0xFD, 0x20, 0xE2, 0x0B,
+0x0F, 0xBF, 0x00, 0x01, 0x0E, 0xBE, 0x07, 0xF0, 0xBF, 0xFF, 0xED, 0xBE, 0x07, 0x05, 0xBF, 0xFF,
+0x02, 0xC3, 0x22, 0xD3, 0x22, 0x7B, 0x01, 0x7A, 0x45, 0x79, 0x3B, 0x7F, 0x09, 0x90, 0x04, 0x6E,
+0xEF, 0xF0, 0x90, 0x04, 0x6C, 0xE0, 0x44, 0x02, 0xF0, 0xE4, 0xFF, 0xFE, 0x90, 0x04, 0x6C, 0xE0,
+0xFD, 0x20, 0xE2, 0x0B, 0x0F, 0xBF, 0x00, 0x01, 0x0E, 0xBE, 0x07, 0xF0, 0xBF, 0xFF, 0xED, 0x90,
+0x04, 0x6F, 0xE0, 0x12, 0x26, 0x7C, 0xBE, 0x07, 0x05, 0xBF, 0xFF, 0x02, 0xC3, 0x22, 0xD3, 0x22,
+0x90, 0x04, 0x6E, 0xEF, 0xF0, 0x90, 0x04, 0x6F, 0xED, 0xF0, 0x90, 0x04, 0x6C, 0xE0, 0x44, 0x01,
+0xF0, 0xE4, 0xFF, 0xFE, 0x90, 0x04, 0x6C, 0xE0, 0xFD, 0x20, 0xE2, 0x0B, 0x0F, 0xBF, 0x00, 0x01,
+0x0E, 0xBE, 0x07, 0xF0, 0xBF, 0xFF, 0xED, 0xBE, 0x07, 0x05, 0xBF, 0xFF, 0x02, 0xC3, 0x22, 0xD3,
+0x22, 0x90, 0x04, 0x54, 0x74, 0x01, 0xF0, 0xE4, 0xFF, 0xFE, 0x90, 0x04, 0x54, 0xE0, 0xFD, 0x30,
+0xE0, 0x0B, 0x0F, 0xBF, 0x00, 0x01, 0x0E, 0xBE, 0x07, 0xF0, 0xBF, 0xFF, 0xED, 0xBE, 0x07, 0x05,
+0xBF, 0xFF, 0x02, 0xC3, 0x22, 0x90, 0x06, 0x38, 0xE0, 0x44, 0x02, 0xF0, 0xE0, 0x44, 0x01, 0xF0,
+0xD3, 0x22, 0xEF, 0x12, 0x28, 0x7E, 0x3D, 0x7F, 0x03, 0x3D, 0x85, 0x09, 0x3D, 0x82, 0x0A, 0x3D,
+0x85, 0x0C, 0x3D, 0x88, 0x0D, 0x3D, 0x7F, 0x0E, 0x3D, 0x8B, 0x0F, 0x00, 0x00, 0x3D, 0x8E, 0x02,
+0x31, 0x47, 0x02, 0x30, 0x1A, 0x02, 0x37, 0x8F, 0x02, 0x38, 0x19, 0x02, 0x38, 0xA3, 0xC3, 0x22,
+0x90, 0x04, 0x1C, 0xEF, 0xF0, 0xA3, 0xED, 0xF0, 0xA3, 0xEB, 0xF0, 0x90, 0x45, 0x44, 0xE0, 0x90,
+0x04, 0x1F, 0xF0, 0x90, 0x04, 0x18, 0x74, 0x03, 0xF0, 0x90, 0x04, 0x18, 0xE0, 0xFF, 0x60, 0x04,
+0xEF, 0x30, 0xE2, 0xF5, 0xE4, 0x90, 0x04, 0x18, 0xF0, 0x22, 0x7F, 0xFF, 0x90, 0x04, 0x14, 0xE0,
+0xFF, 0x14, 0x60, 0x0E, 0x14, 0x60, 0x0F, 0x14, 0x60, 0x10, 0x24, 0x03, 0x70, 0x10, 0x02, 0x0B,
+0xBE, 0x22, 0x02, 0x0B, 0xB5, 0x22, 0x02, 0x0B, 0xAE, 0x22, 0x02, 0x0B, 0xEF, 0x22, 0x02, 0x00,
+0x00, 0x22, 0xD2, 0x02, 0x7D, 0x40, 0x7F, 0x50, 0x12, 0x3D, 0x00, 0xE4, 0xFD, 0x7F, 0x50, 0x12,
+0x3D, 0x00, 0x7D, 0x01, 0x7F, 0x9C, 0x12, 0x3D, 0x00, 0xE4, 0xFD, 0x7F, 0x9C, 0x12, 0x3D, 0x00,
+0xA2, 0x02, 0x22, 0x90, 0x04, 0x61, 0xE0, 0x54, 0xFE, 0xF0, 0xE4, 0xFF, 0xFE, 0x90, 0x04, 0x61,
+0xE0, 0xFD, 0x20, 0xE5, 0x0B, 0x0F, 0xBF, 0x00, 0x01, 0x0E, 0xBE, 0x07, 0xF0, 0xBF, 0xFF, 0xED,
+0x22, 0xC0, 0xE0, 0xC0, 0x83, 0xC0, 0x82, 0xC2, 0x8C, 0x90, 0x43, 0x19, 0x74, 0x01, 0xF0, 0xD0,
+0x82, 0xD0, 0x83, 0xD0, 0xE0, 0x32, 0xC2, 0x8C, 0x75, 0x89, 0x01, 0x75, 0x8C, 0xF9, 0x75, 0x8A,
+0x7E, 0x43, 0xA8, 0x02, 0x22, 0x44, 0x43, 0x1A, 0x04, 0x03, 0x09, 0x04, 0x00,
+};
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+BOOLEAN
+FIRMWAREbDownload(
+    IN PSDevice pDevice
+    )
+{
+    NDIS_STATUS NdisStatus;
+    PBYTE       pBuffer = NULL;
+    WORD        wLength;
+    int         ii;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Download firmware\n");
+    spin_unlock_irq(&pDevice->lock);
+    pBuffer = kmalloc(sizeof(abyFirmware), GFP_KERNEL);
+    if (pBuffer != NULL) {
+
+        for (ii=0;ii<sizeof(abyFirmware);ii++)
+            pBuffer[ii] = abyFirmware[ii];
+
+        for (ii=0;ii<sizeof(abyFirmware);ii+=0x400) {
+
+            if ((sizeof(abyFirmware) - ii) < 0x400)
+                wLength = (sizeof(abyFirmware) - ii);
+            else
+                wLength = 0x400;
+
+            NdisStatus = CONTROLnsRequestOutAsyn(pDevice,
+                                            0,
+                                            0x1200+ii,
+                                            0x0000,
+                                            wLength,
+                                            &(pBuffer[ii])
+                                            );
+
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Download firmware...%d %d\n", ii, sizeof(abyFirmware));
+            if (NdisStatus != STATUS_SUCCESS) {
+                if (pBuffer)
+                    kfree(pBuffer);
+                spin_lock_irq(&pDevice->lock);
+                return (FALSE);
+            }
+        }
+    }
+
+    if (pBuffer)
+        kfree(pBuffer);
+
+    spin_lock_irq(&pDevice->lock);
+    return (TRUE);
+}
+
+BOOLEAN
+FIRMWAREbBrach2Sram(
+    IN PSDevice pDevice
+    )
+{
+    NDIS_STATUS NdisStatus;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Branch to Sram\n");
+
+    NdisStatus = CONTROLnsRequestOut(pDevice,
+                                    1,
+                                    0x1200,
+                                    0x0000,
+                                    0,
+                                    NULL
+                                    );
+
+    if (NdisStatus != STATUS_SUCCESS) {
+        return (FALSE);
+    } else {
+        return (TRUE);
+    }
+}
+
+
+BOOLEAN
+FIRMWAREbCheckVersion(
+    IN PSDevice pDevice
+    )
+{
+    NTSTATUS                ntStatus;
+
+    ntStatus = CONTROLnsRequestIn(pDevice,
+                                    MESSAGE_TYPE_READ,
+                                    0,
+                                    MESSAGE_REQUEST_VERSION,
+                                    2,
+                                    (PBYTE) &(pDevice->wFirmwareVersion));
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Firmware Version [%04x]\n", pDevice->wFirmwareVersion);
+    if (ntStatus != STATUS_SUCCESS) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Firmware Invalid.\n");
+        return FALSE;
+    }
+    if (pDevice->wFirmwareVersion == 0xFFFF) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"In Loader.\n");
+        return FALSE;
+    }
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Firmware Version [%04x]\n", pDevice->wFirmwareVersion);
+    if (pDevice->wFirmwareVersion != FIRMWARE_VERSION) {
+        // branch to loader for download new firmware
+        FIRMWAREbBrach2Sram(pDevice);
+        return FALSE;
+    }
+    return TRUE;
+}
diff --git a/drivers/staging/vt6656/firmware.h b/drivers/staging/vt6656/firmware.h
new file mode 100644
index 0000000..fdc380a
--- /dev/null
+++ b/drivers/staging/vt6656/firmware.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: firmware.h
+ *
+ * Purpose: Version and Release Information
+ *
+ * Author: Yiching Chen
+ *
+ * Date: May 20, 2004
+ *
+ */
+
+
+#ifndef __FIRMWARE_H__
+#define __FIRMWARE_H__
+
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+#if !defined(__DEVICE_H__)
+#include "device.h"
+#endif
+
+/*---------------------  Export Definitions -------------------------*/
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+BOOL
+FIRMWAREbDownload(
+    IN PSDevice pDevice
+    );
+
+BOOL
+FIRMWAREbBrach2Sram(
+    IN PSDevice pDevice
+    );
+
+BOOL
+FIRMWAREbCheckVersion(
+    IN PSDevice pDevice
+    );
+
+
+#endif // __FIRMWARE_H__
diff --git a/drivers/staging/vt6656/hostap.c b/drivers/staging/vt6656/hostap.c
new file mode 100644
index 0000000..78312f8
--- /dev/null
+++ b/drivers/staging/vt6656/hostap.c
@@ -0,0 +1,881 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: hostap.c
+ *
+ * Purpose: handle hostap deamon ioctl input/out functions
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: Oct. 20, 2003
+ *
+ * Functions:
+ *
+ * Revision History:
+ *
+ */
+
+
+#if !defined(__HOSTAP_H__)
+#include "hostap.h"
+#endif
+#if !defined(__IOCMD_H__)
+#include "iocmd.h"
+#endif
+#if !defined(__MAC_H__)
+#include "mac.h"
+#endif
+#if !defined(__CARD_H__)
+#include "card.h"
+#endif
+#if !defined(__BASEBAND_H__)
+#include "baseband.h"
+#endif
+#if !defined(__WPACTL_H__)
+#include "wpactl.h"
+#endif
+#if !defined(__KEY_H__)
+#include "key.h"
+#endif
+#if !defined(__MAC_H__)
+#include "mac.h"
+#endif
+#if !defined(__DATARATE_H__)
+#include "datarate.h"
+#endif
+
+
+#define VIAWGET_HOSTAPD_MAX_BUF_SIZE 1024
+#define HOSTAP_CRYPT_FLAG_SET_TX_KEY BIT0
+#define HOSTAP_CRYPT_FLAG_PERMANENT BIT1
+#define HOSTAP_CRYPT_ERR_UNKNOWN_ALG 2
+#define HOSTAP_CRYPT_ERR_UNKNOWN_ADDR 3
+#define HOSTAP_CRYPT_ERR_CRYPT_INIT_FAILED 4
+#define HOSTAP_CRYPT_ERR_KEY_SET_FAILED 5
+#define HOSTAP_CRYPT_ERR_TX_KEY_SET_FAILED 6
+#define HOSTAP_CRYPT_ERR_CARD_CONF_FAILED 7
+
+
+/*---------------------  Static Definitions -------------------------*/
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+static int          msglevel                =MSG_LEVEL_INFO;
+
+/*---------------------  Static Functions  --------------------------*/
+
+
+
+
+/*---------------------  Export Variables  --------------------------*/
+
+
+/*
+ * Description:
+ *      register net_device (AP) for hostap deamon
+ *
+ * Parameters:
+ *  In:
+ *      pDevice             -
+ *      rtnl_locked         -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+
+static int hostap_enable_hostapd(PSDevice pDevice, int rtnl_locked)
+{
+	struct net_device *dev = pDevice->dev;
+	int ret;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Enabling hostapd mode\n", dev->name);
+
+	pDevice->apdev = (struct net_device *)kmalloc(sizeof(struct net_device), GFP_KERNEL);
+    if (pDevice->apdev == NULL)
+		return -ENOMEM;
+	memset(pDevice->apdev, 0, sizeof(struct net_device));
+
+	pDevice->apdev->priv = pDevice;
+	memcpy(pDevice->apdev->dev_addr, dev->dev_addr, ETH_ALEN);
+	pDevice->apdev->hard_start_xmit = pDevice->tx_80211;
+	pDevice->apdev->type = ARPHRD_IEEE80211;
+
+	pDevice->apdev->base_addr = dev->base_addr;
+	pDevice->apdev->irq = dev->irq;
+	pDevice->apdev->mem_start = dev->mem_start;
+	pDevice->apdev->mem_end = dev->mem_end;
+	sprintf(pDevice->apdev->name, "%sap", dev->name);
+	if (rtnl_locked)
+		ret = register_netdevice(pDevice->apdev);
+	else
+		ret = register_netdev(pDevice->apdev);
+	if (ret) {
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: register_netdevice(AP) failed!\n",
+		       dev->name);
+		return -1;
+	}
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Registered netdevice %s for AP management\n",
+	       dev->name, pDevice->apdev->name);
+
+    KeyvInitTable(pDevice,&pDevice->sKey);
+
+	return 0;
+}
+
+/*
+ * Description:
+ *      unregister net_device(AP)
+ *
+ * Parameters:
+ *  In:
+ *      pDevice             -
+ *      rtnl_locked         -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+
+static int hostap_disable_hostapd(PSDevice pDevice, int rtnl_locked)
+{
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: disabling hostapd mode\n", pDevice->dev->name);
+
+    if (pDevice->apdev && pDevice->apdev->name && pDevice->apdev->name[0]) {
+		if (rtnl_locked)
+			unregister_netdevice(pDevice->apdev);
+		else
+			unregister_netdev(pDevice->apdev);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Netdevice %s unregistered\n",
+		       pDevice->dev->name, pDevice->apdev->name);
+	}
+	kfree(pDevice->apdev);
+	pDevice->apdev = NULL;
+    pDevice->bEnable8021x = FALSE;
+    pDevice->bEnableHostWEP = FALSE;
+    pDevice->bEncryptionEnable = FALSE;
+
+	return 0;
+}
+
+
+/*
+ * Description:
+ *      Set enable/disable hostapd mode
+ *
+ * Parameters:
+ *  In:
+ *      pDevice             -
+ *      rtnl_locked         -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+
+int hostap_set_hostapd(PSDevice pDevice, int val, int rtnl_locked)
+{
+	if (val < 0 || val > 1)
+		return -EINVAL;
+
+	if (pDevice->bEnableHostapd == val)
+		return 0;
+
+	pDevice->bEnableHostapd = val;
+
+	if (val)
+		return hostap_enable_hostapd(pDevice, rtnl_locked);
+	else
+		return hostap_disable_hostapd(pDevice, rtnl_locked);
+}
+
+
+/*
+ * Description:
+ *      remove station function supported for hostap deamon
+ *
+ * Parameters:
+ *  In:
+ *      pDevice   -
+ *      param     -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+static int hostap_remove_sta(PSDevice pDevice,
+				     struct viawget_hostapd_param *param)
+{
+	UINT uNodeIndex;
+
+
+    if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &uNodeIndex)) {
+        BSSvRemoveOneNode(pDevice, uNodeIndex);
+    }
+    else {
+        return -ENOENT;
+    }
+	return 0;
+}
+
+/*
+ * Description:
+ *      add a station from hostap deamon
+ *
+ * Parameters:
+ *  In:
+ *      pDevice   -
+ *      param     -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+static int hostap_add_sta(PSDevice pDevice,
+				  struct viawget_hostapd_param *param)
+{
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+	UINT uNodeIndex;
+
+
+    if (!BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &uNodeIndex)) {
+        BSSvCreateOneNode((PSDevice)pDevice, &uNodeIndex);
+    }
+    memcpy(pMgmt->sNodeDBTable[uNodeIndex].abyMACAddr, param->sta_addr, WLAN_ADDR_LEN);
+    pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_ASSOC;
+    pMgmt->sNodeDBTable[uNodeIndex].wCapInfo = param->u.add_sta.capability;
+// TODO listenInterval
+//    pMgmt->sNodeDBTable[uNodeIndex].wListenInterval = 1;
+    pMgmt->sNodeDBTable[uNodeIndex].bPSEnable = FALSE;
+    pMgmt->sNodeDBTable[uNodeIndex].bySuppRate = param->u.add_sta.tx_supp_rates;
+
+    // set max tx rate
+    pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate =
+           pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate;
+    // set max basic rate
+    pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate = RATE_2M;
+    // Todo: check sta preamble, if ap can't support, set status code
+    pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble =
+            WLAN_GET_CAP_INFO_SHORTPREAMBLE(pMgmt->sNodeDBTable[uNodeIndex].wCapInfo);
+
+    pMgmt->sNodeDBTable[uNodeIndex].wAID = (WORD)param->u.add_sta.aid;
+
+    pMgmt->sNodeDBTable[uNodeIndex].ulLastRxJiffer = jiffies;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Add STA AID= %d \n", pMgmt->sNodeDBTable[uNodeIndex].wAID);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X \n",
+               param->sta_addr[0],
+               param->sta_addr[1],
+               param->sta_addr[2],
+               param->sta_addr[3],
+               param->sta_addr[4],
+               param->sta_addr[5]
+              ) ;
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Max Support rate = %d \n",
+               pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate);
+
+	return 0;
+}
+
+/*
+ * Description:
+ *      get station info
+ *
+ * Parameters:
+ *  In:
+ *      pDevice   -
+ *      param     -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+
+static int hostap_get_info_sta(PSDevice pDevice,
+				       struct viawget_hostapd_param *param)
+{
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+	UINT uNodeIndex;
+
+    if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &uNodeIndex)) {
+	    param->u.get_info_sta.inactive_sec =
+	        (jiffies - pMgmt->sNodeDBTable[uNodeIndex].ulLastRxJiffer) / HZ;
+
+	    //param->u.get_info_sta.txexc = pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts;
+	}
+	else {
+	    return -ENOENT;
+	}
+
+	return 0;
+}
+
+/*
+ * Description:
+ *      reset txexec
+ *
+ * Parameters:
+ *  In:
+ *      pDevice   -
+ *      param     -
+ *  Out:
+ *      TURE, FALSE
+ *
+ * Return Value:
+ *
+ */
+/*
+static int hostap_reset_txexc_sta(PSDevice pDevice,
+					  struct viawget_hostapd_param *param)
+{
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+	UINT uNodeIndex;
+
+    if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &uNodeIndex)) {
+        pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts = 0;
+	}
+	else {
+	    return -ENOENT;
+	}
+
+	return 0;
+}
+*/
+
+/*
+ * Description:
+ *      set station flag
+ *
+ * Parameters:
+ *  In:
+ *      pDevice   -
+ *      param     -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+static int hostap_set_flags_sta(PSDevice pDevice,
+					struct viawget_hostapd_param *param)
+{
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+	UINT uNodeIndex;
+
+    if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &uNodeIndex)) {
+		pMgmt->sNodeDBTable[uNodeIndex].dwFlags |= param->u.set_flags_sta.flags_or;
+		pMgmt->sNodeDBTable[uNodeIndex].dwFlags &= param->u.set_flags_sta.flags_and;
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " dwFlags = %x \n",
+		            (UINT)pMgmt->sNodeDBTable[uNodeIndex].dwFlags);
+	}
+	else {
+	    return -ENOENT;
+	}
+
+	return 0;
+}
+
+
+
+/*
+ * Description:
+ *      set generic element (wpa ie)
+ *
+ * Parameters:
+ *  In:
+ *      pDevice   -
+ *      param     -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+static int hostap_set_generic_element(PSDevice pDevice,
+					struct viawget_hostapd_param *param)
+{
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+
+
+
+    memcpy( pMgmt->abyWPAIE,
+            param->u.generic_elem.data,
+            param->u.generic_elem.len
+           );
+
+    pMgmt->wWPAIELen = 	param->u.generic_elem.len;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pMgmt->wWPAIELen = %d\n",  pMgmt->wWPAIELen);
+
+    // disable wpa
+    if (pMgmt->wWPAIELen == 0) {
+        pMgmt->eAuthenMode = WMAC_AUTH_OPEN;
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " No WPAIE, Disable WPA \n");
+    } else  {
+        // enable wpa
+        if ((pMgmt->abyWPAIE[0] == WLAN_EID_RSN_WPA) ||
+             (pMgmt->abyWPAIE[0] == WLAN_EID_RSN)) {
+              pMgmt->eAuthenMode = WMAC_AUTH_WPANONE;
+               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set WPAIE enable WPA\n");
+        } else
+            return -EINVAL;
+    }
+
+	return 0;
+}
+
+/*
+ * Description:
+ *      flush station nodes table.
+ *
+ * Parameters:
+ *  In:
+ *      pDevice   -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+
+static void hostap_flush_sta(PSDevice pDevice)
+{
+    // reserved node index =0 for multicast node.
+    BSSvClearNodeDBTable(pDevice, 1);
+    pDevice->uAssocCount = 0;
+
+    return;
+}
+
+/*
+ * Description:
+ *      set each stations encryption key
+ *
+ * Parameters:
+ *  In:
+ *      pDevice   -
+ *      param     -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+static int hostap_set_encryption(PSDevice pDevice,
+				       struct viawget_hostapd_param *param,
+				       int param_len)
+{
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    DWORD   dwKeyIndex = 0;
+    BYTE    abyKey[MAX_KEY_LEN];
+    BYTE    abySeq[MAX_KEY_LEN];
+    NDIS_802_11_KEY_RSC   KeyRSC;
+    BYTE    byKeyDecMode = KEY_CTL_WEP;
+	int     ret = 0;
+	int     iNodeIndex = -1;
+	int     ii;
+	BOOL    bKeyTableFull = FALSE;
+	WORD    wKeyCtl = 0;
+
+
+	param->u.crypt.err = 0;
+/*
+	if (param_len !=
+	    (int) ((char *) param->u.crypt.key - (char *) param) +
+	    param->u.crypt.key_len)
+		return -EINVAL;
+*/
+
+	if (param->u.crypt.alg > WPA_ALG_CCMP)
+		return -EINVAL;
+
+
+	if ((param->u.crypt.idx > 3) || (param->u.crypt.key_len > MAX_KEY_LEN)) {
+		param->u.crypt.err = HOSTAP_CRYPT_ERR_KEY_SET_FAILED;
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " HOSTAP_CRYPT_ERR_KEY_SET_FAILED\n");
+		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 >= MAX_GROUP_KEY)
+			return -EINVAL;
+        iNodeIndex = 0;
+
+	} else {
+	    if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &iNodeIndex) == FALSE) {
+	        param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR;
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " HOSTAP_CRYPT_ERR_UNKNOWN_ADDR\n");
+	        return -EINVAL;
+	    }
+	}
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " hostap_set_encryption: sta_index %d \n", iNodeIndex);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " hostap_set_encryption: alg %d \n", param->u.crypt.alg);
+
+	if (param->u.crypt.alg == WPA_ALG_NONE) {
+
+        if (pMgmt->sNodeDBTable[iNodeIndex].bOnFly == TRUE) {
+            if (KeybRemoveKey( pDevice,
+                               &(pDevice->sKey),
+                               param->sta_addr,
+                               pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex
+                              ) == FALSE) {
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybRemoveKey fail \n");
+            }
+            pMgmt->sNodeDBTable[iNodeIndex].bOnFly = FALSE;
+        }
+        pMgmt->sNodeDBTable[iNodeIndex].byKeyIndex = 0;
+        pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex = 0;
+        pMgmt->sNodeDBTable[iNodeIndex].uWepKeyLength = 0;
+        pMgmt->sNodeDBTable[iNodeIndex].KeyRSC = 0;
+        pMgmt->sNodeDBTable[iNodeIndex].dwTSC47_16 = 0;
+        pMgmt->sNodeDBTable[iNodeIndex].wTSC15_0 = 0;
+        pMgmt->sNodeDBTable[iNodeIndex].byCipherSuite = 0;
+        memset(&pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[0],
+                0,
+                MAX_KEY_LEN
+               );
+
+        return ret;
+	}
+
+    memcpy(abyKey, param->u.crypt.key, param->u.crypt.key_len);
+    // copy to node key tbl
+    pMgmt->sNodeDBTable[iNodeIndex].byKeyIndex = param->u.crypt.idx;
+    pMgmt->sNodeDBTable[iNodeIndex].uWepKeyLength = param->u.crypt.key_len;
+    memcpy(&pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[0],
+            param->u.crypt.key,
+            param->u.crypt.key_len
+           );
+
+    dwKeyIndex = (DWORD)(param->u.crypt.idx);
+    if (param->u.crypt.flags & HOSTAP_CRYPT_FLAG_SET_TX_KEY) {
+        pDevice->byKeyIndex = (BYTE)dwKeyIndex;
+        pDevice->bTransmitKey = TRUE;
+        dwKeyIndex |= (1 << 31);
+    }
+
+	if (param->u.crypt.alg == WPA_ALG_WEP) {
+
+        if ((pDevice->bEnable8021x == FALSE) || (iNodeIndex == 0)) {
+            KeybSetDefaultKey(  pDevice,
+                                &(pDevice->sKey),
+                                dwKeyIndex & ~(BIT30 | USE_KEYRSC),
+                                param->u.crypt.key_len,
+                                NULL,
+                                abyKey,
+                                KEY_CTL_WEP
+                             );
+
+        } else {
+            // 8021x enable, individual key
+            dwKeyIndex |= (1 << 30); // set pairwise key
+            if (KeybSetKey(pDevice,
+                           &(pDevice->sKey),
+                           &param->sta_addr[0],
+                           dwKeyIndex & ~(USE_KEYRSC),
+                           param->u.crypt.key_len,
+                           (PQWORD) &(KeyRSC),
+                           (PBYTE)abyKey,
+                            KEY_CTL_WEP
+                           ) == TRUE) {
+
+
+                pMgmt->sNodeDBTable[iNodeIndex].bOnFly = TRUE;
+
+            } else {
+                // Key Table Full
+                pMgmt->sNodeDBTable[iNodeIndex].bOnFly = FALSE;
+                bKeyTableFull = TRUE;
+            }
+        }
+        pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
+        pDevice->bEncryptionEnable = TRUE;
+        pMgmt->byCSSPK = KEY_CTL_WEP;
+        pMgmt->byCSSGK = KEY_CTL_WEP;
+        pMgmt->sNodeDBTable[iNodeIndex].byCipherSuite = KEY_CTL_WEP;
+        pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex = dwKeyIndex;
+        return ret;
+	}
+
+	if (param->u.crypt.seq) {
+	    memcpy(&abySeq, param->u.crypt.seq, 8);
+		for (ii = 0 ; ii < 8 ; ii++) {
+	         KeyRSC |= (abySeq[ii] << (ii * 8));
+		}
+		dwKeyIndex |= 1 << 29;
+		pMgmt->sNodeDBTable[iNodeIndex].KeyRSC = KeyRSC;
+	}
+
+	if (param->u.crypt.alg == WPA_ALG_TKIP) {
+	    if (param->u.crypt.key_len != MAX_KEY_LEN)
+	        return -EINVAL;
+	    pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
+        byKeyDecMode = KEY_CTL_TKIP;
+        pMgmt->byCSSPK = KEY_CTL_TKIP;
+        pMgmt->byCSSGK = KEY_CTL_TKIP;
+	}
+
+	if (param->u.crypt.alg == WPA_ALG_CCMP) {
+	    if ((param->u.crypt.key_len != AES_KEY_LEN) ||
+	        (pDevice->byLocalID <= REV_ID_VT3253_A1))
+	        return -EINVAL;
+        pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
+        byKeyDecMode = KEY_CTL_CCMP;
+        pMgmt->byCSSPK = KEY_CTL_CCMP;
+        pMgmt->byCSSGK = KEY_CTL_CCMP;
+    }
+
+
+    if (iNodeIndex == 0) {
+       KeybSetDefaultKey(  pDevice,
+                           &(pDevice->sKey),
+                           dwKeyIndex,
+                           param->u.crypt.key_len,
+                           (PQWORD) &(KeyRSC),
+                           abyKey,
+                           byKeyDecMode
+                          );
+       pMgmt->sNodeDBTable[iNodeIndex].bOnFly = TRUE;
+
+    } else {
+        dwKeyIndex |= (1 << 30); // set pairwise key
+        if (KeybSetKey(pDevice,
+                       &(pDevice->sKey),
+                       &param->sta_addr[0],
+                       dwKeyIndex,
+                       param->u.crypt.key_len,
+                       (PQWORD) &(KeyRSC),
+                       (PBYTE)abyKey,
+                        byKeyDecMode
+                       ) == TRUE) {
+
+            pMgmt->sNodeDBTable[iNodeIndex].bOnFly = TRUE;
+
+        } else {
+            // Key Table Full
+            pMgmt->sNodeDBTable[iNodeIndex].bOnFly = FALSE;
+            bKeyTableFull = TRUE;
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Key Table Full\n");
+        }
+
+    }
+
+    if (bKeyTableFull == TRUE) {
+        wKeyCtl &= 0x7F00;              // clear all key control filed
+        wKeyCtl |= (byKeyDecMode << 4);
+        wKeyCtl |= (byKeyDecMode);
+        wKeyCtl |= 0x0044;              // use group key for all address
+        wKeyCtl |= 0x4000;              // disable KeyTable[MAX_KEY_TABLE-1] on-fly to genernate rx int
+// Todo.. xxxxxx
+        //MACvSetDefaultKeyCtl(pDevice->PortOffset, wKeyCtl, MAX_KEY_TABLE-1, pDevice->byLocalID);
+    }
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Set key sta_index= %d \n", iNodeIndex);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " tx_index=%d len=%d \n", param->u.crypt.idx,
+               param->u.crypt.key_len );
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " key=%x-%x-%x-%x-%x-xxxxx \n",
+               pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[0],
+               pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[1],
+               pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[2],
+               pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[3],
+               pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[4]
+              );
+
+	// set wep key
+    pDevice->bEncryptionEnable = TRUE;
+    pMgmt->sNodeDBTable[iNodeIndex].byCipherSuite = byKeyDecMode;
+    pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex = dwKeyIndex;
+    pMgmt->sNodeDBTable[iNodeIndex].dwTSC47_16 = 0;
+    pMgmt->sNodeDBTable[iNodeIndex].wTSC15_0 = 0;
+
+	return ret;
+}
+
+
+
+/*
+ * Description:
+ *      get each stations encryption key
+ *
+ * Parameters:
+ *  In:
+ *      pDevice   -
+ *      param     -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+static int hostap_get_encryption(PSDevice pDevice,
+				       struct viawget_hostapd_param *param,
+				       int param_len)
+{
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+	int     ret = 0;
+	int     ii;
+	int     iNodeIndex =0;
+
+
+	param->u.crypt.err = 0;
+
+	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) {
+        iNodeIndex = 0;
+	} else {
+	    if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &iNodeIndex) == FALSE) {
+	        param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR;
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "hostap_get_encryption: HOSTAP_CRYPT_ERR_UNKNOWN_ADDR\n");
+	        return -EINVAL;
+	    }
+	}
+	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "hostap_get_encryption: %d\n", iNodeIndex);
+    memset(param->u.crypt.seq, 0, 8);
+    for (ii = 0 ; ii < 8 ; ii++) {
+        param->u.crypt.seq[ii] = (BYTE)pMgmt->sNodeDBTable[iNodeIndex].KeyRSC >> (ii * 8);
+    }
+
+	return ret;
+}
+
+
+/*
+ * Description:
+ *      hostap_ioctl main function supported for hostap deamon.
+ *
+ * Parameters:
+ *  In:
+ *      pDevice   -
+ *      iw_point  -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+
+int hostap_ioctl(PSDevice pDevice, struct iw_point *p)
+{
+	struct viawget_hostapd_param *param;
+	int ret = 0;
+	int ap_ioctl = 0;
+
+	if (p->length < sizeof(struct viawget_hostapd_param) ||
+	    p->length > VIAWGET_HOSTAPD_MAX_BUF_SIZE || !p->pointer)
+		return -EINVAL;
+
+	param = (struct viawget_hostapd_param *) kmalloc((int)p->length, (int)GFP_KERNEL);
+	if (param == NULL)
+		return -ENOMEM;
+
+	if (copy_from_user(param, p->pointer, p->length)) {
+		ret = -EFAULT;
+		goto out;
+	}
+
+	switch (param->cmd) {
+	case VIAWGET_HOSTAPD_SET_ENCRYPTION:
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_ENCRYPTION \n");
+        spin_lock_irq(&pDevice->lock);
+		ret = hostap_set_encryption(pDevice, param, p->length);
+        spin_unlock_irq(&pDevice->lock);
+		break;
+	case VIAWGET_HOSTAPD_GET_ENCRYPTION:
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_GET_ENCRYPTION \n");
+        spin_lock_irq(&pDevice->lock);
+		ret = hostap_get_encryption(pDevice, param, p->length);
+        spin_unlock_irq(&pDevice->lock);
+		break;
+	case VIAWGET_HOSTAPD_SET_ASSOC_AP_ADDR:
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_ASSOC_AP_ADDR \n");
+		return -EOPNOTSUPP;
+		break;
+	case VIAWGET_HOSTAPD_FLUSH:
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_FLUSH \n");
+        spin_lock_irq(&pDevice->lock);
+    	hostap_flush_sta(pDevice);
+        spin_unlock_irq(&pDevice->lock);
+		break;
+	case VIAWGET_HOSTAPD_ADD_STA:
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_ADD_STA \n");
+         spin_lock_irq(&pDevice->lock);
+		 ret = hostap_add_sta(pDevice, param);
+         spin_unlock_irq(&pDevice->lock);
+		break;
+	case VIAWGET_HOSTAPD_REMOVE_STA:
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_REMOVE_STA \n");
+         spin_lock_irq(&pDevice->lock);
+		 ret = hostap_remove_sta(pDevice, param);
+         spin_unlock_irq(&pDevice->lock);
+		break;
+	case VIAWGET_HOSTAPD_GET_INFO_STA:
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_GET_INFO_STA \n");
+		 ret = hostap_get_info_sta(pDevice, param);
+		 ap_ioctl = 1;
+		break;
+/*
+	case VIAWGET_HOSTAPD_RESET_TXEXC_STA:
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_RESET_TXEXC_STA \n");
+		 ret = hostap_reset_txexc_sta(pDevice, param);
+		break;
+*/
+	case VIAWGET_HOSTAPD_SET_FLAGS_STA:
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_FLAGS_STA \n");
+		 ret = hostap_set_flags_sta(pDevice, param);
+		break;
+
+	case VIAWGET_HOSTAPD_MLME:
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_MLME \n");
+	    return -EOPNOTSUPP;
+
+	case VIAWGET_HOSTAPD_SET_GENERIC_ELEMENT:
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_GENERIC_ELEMENT \n");
+		ret = hostap_set_generic_element(pDevice, param);
+		break;
+
+	case VIAWGET_HOSTAPD_SCAN_REQ:
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SCAN_REQ \n");
+	    return -EOPNOTSUPP;
+
+	case VIAWGET_HOSTAPD_STA_CLEAR_STATS:
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_STA_CLEAR_STATS \n");
+	    return -EOPNOTSUPP;
+
+	default:
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "hostap_ioctl: unknown cmd=%d\n",
+		       (int)param->cmd);
+		return -EOPNOTSUPP;
+		break;
+	}
+
+
+	if ((ret == 0) && ap_ioctl) {
+		if (copy_to_user(p->pointer, param, p->length)) {
+			ret = -EFAULT;
+			goto out;
+		}
+	}
+
+ out:
+	if (param != NULL)
+		kfree(param);
+
+	return ret;
+}
+
diff --git a/drivers/staging/vt6656/hostap.h b/drivers/staging/vt6656/hostap.h
new file mode 100644
index 0000000..1fcb2f0
--- /dev/null
+++ b/drivers/staging/vt6656/hostap.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: hostap.h
+ *
+ * Purpose:
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: May 21, 2003
+ *
+ */
+
+
+#ifndef __HOSTAP_H__
+#define __HOSTAP_H__
+
+#if !defined(__DEVICE_H__)
+#include "device.h"
+#endif
+
+
+/*---------------------  Export Definitions -------------------------*/
+
+#if WIRELESS_EXT < 9
+struct iw_point {
+	caddr_t pointer;
+	__u16 length;
+	__u16 flags;
+};
+#endif /* WIRELESS_EXT < 9 */
+
+#define WLAN_RATE_1M    BIT0
+#define WLAN_RATE_2M    BIT1
+#define WLAN_RATE_5M5   BIT2
+#define WLAN_RATE_11M   BIT3
+#define WLAN_RATE_6M    BIT4
+#define WLAN_RATE_9M    BIT5
+#define WLAN_RATE_12M   BIT6
+#define WLAN_RATE_18M   BIT7
+#define WLAN_RATE_24M   BIT8
+#define WLAN_RATE_36M   BIT9
+#define WLAN_RATE_48M   BIT10
+#define WLAN_RATE_54M   BIT11
+
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+#ifdef __cplusplus
+extern "C" {                            /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+#ifndef ETH_P_PAE
+#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
+#endif /* ETH_P_PAE */
+
+#ifndef ARPHRD_IEEE80211
+#define ARPHRD_IEEE80211 801
+#endif
+
+int hostap_set_hostapd(PSDevice pDevice, int val, int rtnl_locked);
+int hostap_ioctl(PSDevice pDevice, struct iw_point *p);
+
+#ifdef __cplusplus
+}                                       /* End of extern "C" { */
+#endif /* __cplusplus */
+
+
+
+
+#endif // __HOSTAP_H__
+
+
+
diff --git a/drivers/staging/vt6656/int.c b/drivers/staging/vt6656/int.c
new file mode 100644
index 0000000..158a4cc
--- /dev/null
+++ b/drivers/staging/vt6656/int.c
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: int.c
+ *
+ * Purpose: Handle USB interrupt endpoint
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Apr. 2, 2004
+ *
+ * Functions:
+ *
+ * Revision History:
+ *      04-02-2004 Jerry Chen:  Initial release
+ *
+ */
+
+
+#if !defined(__INT_H__)
+#include "int.h"
+#endif
+#if !defined(__MIB_H__)
+#include "mib.h"
+#endif
+#if !defined(__TBIT_H__)
+#include "tbit.h"
+#endif
+#if !defined(__TMACRO_H__)
+#include "tmacro.h"
+#endif
+#if !defined(__MAC_H__)
+#include "mac.h"
+#endif
+#if !defined(__POWER_H__)
+#include "power.h"
+#endif
+#if !defined(__BSSDB_H__)
+#include "bssdb.h"
+#endif
+#if !defined(__UMEM_H__)
+#include "umem.h"
+#endif
+#if !defined(__USBPIPE_H__)
+#include "usbpipe.h"
+#endif
+
+/*---------------------  Static Definitions -------------------------*/
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+static int          msglevel                =MSG_LEVEL_INFO;
+
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+
+/*---------------------  Static Functions  --------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+/*+
+ *
+ *  Function:   InterruptPollingThread
+ *
+ *  Synopsis:   Thread running at IRQL PASSIVE_LEVEL.
+ *
+ *  Arguments: Device Extension
+ *
+ *  Returns:
+ *
+ *  Algorithm:  Call USBD for input data;
+ *
+ *  History:    dd-mm-yyyy   Author    Comment
+ *
+ *
+ *  Notes:
+ *
+ *  USB reads are by nature 'Blocking', and when in a read, the device looks like it's
+ *  in a 'stall' condition, so we deliberately time out every second if we've gotten no data
+ *
+-*/
+VOID
+INTvWorkItem(
+    PVOID Context
+    )
+{
+    PSDevice pDevice = (PSDevice) Context;
+    NTSTATUS ntStatus;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Interrupt Polling Thread\n");
+
+    spin_lock_irq(&pDevice->lock);
+    if (pDevice->fKillEventPollingThread != TRUE) {
+        ntStatus = PIPEnsInterruptRead(pDevice);
+    }
+    spin_unlock_irq(&pDevice->lock);
+
+ }
+
+
+NTSTATUS
+INTnsProcessData(
+    IN  PSDevice pDevice
+    )
+{
+    NTSTATUS        status = STATUS_SUCCESS;
+    PSINTData       pINTData;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    struct net_device_stats* pStats = &pDevice->stats;
+
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsInterruptProcessData\n");
+
+    pINTData = (PSINTData) pDevice->intBuf.pDataBuf;
+    if (BITbIsBitOn(pINTData->byTSR0, TSR_VALID)) {
+        STAvUpdateTDStatCounter (&(pDevice->scStatistic), (BYTE) (pINTData->byPkt0 & 0x0F), (BYTE) (pINTData->byPkt0>>4), pINTData->byTSR0);
+        BSSvUpdateNodeTxCounter (pDevice, &(pDevice->scStatistic),  pINTData->byTSR0, pINTData->byPkt0);
+        //DBG_PRN_GRP01(("TSR0 %02x\n", pINTData->byTSR0));
+    }
+    if (BITbIsBitOn(pINTData->byTSR1, TSR_VALID)) {
+        STAvUpdateTDStatCounter (&(pDevice->scStatistic), (BYTE) (pINTData->byPkt1 & 0x0F), (BYTE) (pINTData->byPkt1>>4), pINTData->byTSR1);
+        BSSvUpdateNodeTxCounter (pDevice, &(pDevice->scStatistic),  pINTData->byTSR1, pINTData->byPkt1);
+        //DBG_PRN_GRP01(("TSR1 %02x\n", pINTData->byTSR1));
+    }
+    if (BITbIsBitOn(pINTData->byTSR2, TSR_VALID)) {
+        STAvUpdateTDStatCounter (&(pDevice->scStatistic), (BYTE) (pINTData->byPkt2 & 0x0F), (BYTE) (pINTData->byPkt2>>4), pINTData->byTSR2);
+        BSSvUpdateNodeTxCounter (pDevice, &(pDevice->scStatistic),  pINTData->byTSR2, pINTData->byPkt2);
+        //DBG_PRN_GRP01(("TSR2 %02x\n", pINTData->byTSR2));
+    }
+    if (BITbIsBitOn(pINTData->byTSR3, TSR_VALID)) {
+        STAvUpdateTDStatCounter (&(pDevice->scStatistic), (BYTE) (pINTData->byPkt3 & 0x0F), (BYTE) (pINTData->byPkt3>>4), pINTData->byTSR3);
+        BSSvUpdateNodeTxCounter (pDevice, &(pDevice->scStatistic),  pINTData->byTSR3, pINTData->byPkt3);
+        //DBG_PRN_GRP01(("TSR3 %02x\n", pINTData->byTSR3));
+    }
+    if ( pINTData->byISR0 != 0 ) {
+        if ( BITbIsBitOn(pINTData->byISR0, ISR_BNTX) ) {
+
+            if (pDevice->eOPMode == OP_MODE_AP) {
+                if(pMgmt->byDTIMCount > 0) {
+                    pMgmt->byDTIMCount --;
+                    pMgmt->sNodeDBTable[0].bRxPSPoll = FALSE;
+                } else if(pMgmt->byDTIMCount == 0) {
+                    // check if mutltcast tx bufferring
+                    pMgmt->byDTIMCount = pMgmt->byDTIMPeriod - 1;
+                    pMgmt->sNodeDBTable[0].bRxPSPoll = TRUE;
+                    if (pMgmt->sNodeDBTable[0].bPSEnable) {
+                        bScheduleCommand((HANDLE)pDevice, WLAN_CMD_RX_PSPOLL, NULL);
+                    }
+                }
+                bScheduleCommand((HANDLE)pDevice, WLAN_CMD_BECON_SEND, NULL);
+            } // if (pDevice->eOPMode == OP_MODE_AP)
+
+            pDevice->bBeaconSent = TRUE;
+        } else {
+            pDevice->bBeaconSent = FALSE;
+        }
+        if ( BITbIsBitOn(pINTData->byISR0, ISR_TBTT) ) {
+            if ( pDevice->bEnablePSMode ) {
+                bScheduleCommand((HANDLE) pDevice, WLAN_CMD_TBTT_WAKEUP, NULL);
+            }
+            if ( pDevice->bChannelSwitch ) {
+                pDevice->byChannelSwitchCount--;
+                if ( pDevice->byChannelSwitchCount == 0 ) {
+                    bScheduleCommand((HANDLE) pDevice, WLAN_CMD_11H_CHSW, NULL);
+                }
+            }
+        }
+        LODWORD(pDevice->qwCurrTSF) = pINTData->dwLoTSF;
+        HIDWORD(pDevice->qwCurrTSF) = pINTData->dwHiTSF;
+        //DBG_PRN_GRP01(("ISR0 = %02x ,LoTsf =  %08x,HiTsf =  %08x\n", pINTData->byISR0, pINTData->dwLoTSF,pINTData->dwHiTSF));
+
+        STAvUpdate802_11Counter(&pDevice->s802_11Counter, &pDevice->scStatistic, pINTData->byRTSSuccess,
+                                pINTData->byRTSFail, pINTData->byACKFail, pINTData->byFCSErr );
+        STAvUpdateIsrStatCounter(&pDevice->scStatistic, pINTData->byISR0, pINTData->byISR1);
+
+    }
+
+    if ( pINTData->byISR1 != 0 ) {
+        if ( BITbIsBitOn(pINTData->byISR1, ISR_GPIO3) ) {
+            bScheduleCommand((HANDLE) pDevice, WLAN_CMD_RADIO, NULL);
+        }
+    }
+    pDevice->intBuf.uDataLen = 0;
+    pDevice->intBuf.bInUse = FALSE;
+
+    pStats->tx_packets = pDevice->scStatistic.ullTsrOK;
+    pStats->tx_bytes = pDevice->scStatistic.ullTxDirectedBytes +
+                       pDevice->scStatistic.ullTxMulticastBytes +
+                       pDevice->scStatistic.ullTxBroadcastBytes;
+    pStats->tx_errors = pDevice->scStatistic.dwTsrErr;
+    pStats->tx_dropped = pDevice->scStatistic.dwTsrErr;
+
+    return status;
+}
diff --git a/drivers/staging/vt6656/int.h b/drivers/staging/vt6656/int.h
new file mode 100644
index 0000000..bfbf667
--- /dev/null
+++ b/drivers/staging/vt6656/int.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: int.h
+ *
+ * Purpose:
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Apr. 2, 2004
+ *
+ */
+
+
+#ifndef __INT_H__
+#define __INT_H__
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+#if !defined(__DEVICE_H__)
+#include "device.h"
+#endif
+
+
+
+/*---------------------  Export Definitions -------------------------*/
+#pragma pack(1)
+typedef struct tagSINTData {
+    BYTE    byTSR0;
+    BYTE    byPkt0;
+    WORD    wTime0;
+    BYTE    byTSR1;
+    BYTE    byPkt1;
+    WORD    wTime1;
+    BYTE    byTSR2;
+    BYTE    byPkt2;
+    WORD    wTime2;
+    BYTE    byTSR3;
+    BYTE    byPkt3;
+    WORD    wTime3;
+    DWORD   dwLoTSF;
+    DWORD   dwHiTSF;
+    BYTE    byISR0;
+    BYTE    byISR1;
+    BYTE    byRTSSuccess;
+    BYTE    byRTSFail;
+    BYTE    byACKFail;
+    BYTE    byFCSErr;
+    BYTE    abySW[2];
+}__attribute__ ((__packed__))
+SINTData, DEF* PSINTData;
+
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+#ifdef __cplusplus
+extern "C" {                            /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+VOID
+INTvWorkItem(
+    PVOID Context
+    );
+
+NTSTATUS
+INTnsProcessData(
+    IN  PSDevice pDevice
+    );
+
+
+#ifdef __cplusplus
+}                                       /* End of extern "C" { */
+#endif /* __cplusplus */
+
+
+
+
+#endif // __INT_H__
+
+
+
diff --git a/drivers/staging/vt6656/ioctl.c b/drivers/staging/vt6656/ioctl.c
new file mode 100644
index 0000000..8e9762b
--- /dev/null
+++ b/drivers/staging/vt6656/ioctl.c
@@ -0,0 +1,724 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: ioctl.c
+ *
+ * Purpose:  private ioctl functions
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: Auguest 20, 2003
+ *
+ * Functions:
+ *
+ * Revision History:
+ *
+ */
+
+
+#if !defined(__IOCTL_H__)
+#include "ioctl.h"
+#endif
+#if !defined(__IOCMD_H__)
+#include "iocmd.h"
+#endif
+#if !defined(__MAC_H__)
+#include "mac.h"
+#endif
+#if !defined(__CARD_H__)
+#include "card.h"
+#endif
+#if !defined(__HOSTAP_H__)
+#include "hostap.h"
+#endif
+#if !defined(__UMEM_H__)
+#include "umem.h"
+#endif
+#if !defined(__WPACTL_H__)
+#include "wpactl.h"
+#endif
+#if !defined(__CONTROL_H__)
+#include "control.h"
+#endif
+#if !defined(__RNDIS_H__)
+#include "rndis.h"
+#endif
+#if !defined(__RF_H__)
+#include "rf.h"
+#endif
+
+
+/*---------------------  Static Definitions -------------------------*/
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+static int          msglevel                =MSG_LEVEL_INFO;
+
+#ifdef WPA_SM_Transtatus
+    SWPAResult wpa_Result;
+#endif
+
+/*---------------------  Static Functions  --------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
+
+	PSCmdRequest        pReq = (PSCmdRequest)rq;
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+	int 		        result = 0;
+    PWLAN_IE_SSID       pItemSSID;
+    SCmdBSSJoin         sJoinCmd;
+    SCmdZoneTypeSet sZoneTypeCmd;
+    SCmdScan            sScanCmd;
+    SCmdStartAP         sStartAPCmd;
+    SCmdSetWEP          sWEPCmd;
+    SCmdValue           sValue;
+    SBSSIDList          sList;
+    SNodeList           sNodeList;
+    PSBSSIDList         pList;
+    PSNodeList          pNodeList;
+    UINT                cbListCount;
+    PKnownBSS           pBSS;
+    PKnownNodeDB        pNode;
+    UINT                ii, jj;
+    SCmdLinkStatus      sLinkStatus;
+    BYTE                abySuppRates[] = {WLAN_EID_SUPP_RATES, 4, 0x02, 0x04, 0x0B, 0x16};
+    BYTE                abyNullAddr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+    DWORD               dwKeyIndex= 0;
+    BYTE                abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
+    LONG                ldBm;
+
+    pReq->wResult = 0;
+
+    switch(pReq->wCmdCode) {
+
+    case WLAN_CMD_BSS_SCAN:
+
+        if (copy_from_user(&sScanCmd, pReq->data, sizeof(SCmdScan))) {
+			result = -EFAULT;
+			break;
+		};
+
+        pItemSSID = (PWLAN_IE_SSID)sScanCmd.ssid;
+        if (pItemSSID->len != 0) {
+            memset(abyScanSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+            memcpy(abyScanSSID, pItemSSID, pItemSSID->len + WLAN_IEHDR_LEN);
+        }
+        spin_lock_irq(&pDevice->lock);
+        if (memcmp(pMgmt->abyCurrBSSID, &abyNullAddr[0], 6) == 0)
+            BSSvClearBSSList((HANDLE)pDevice, FALSE);
+        else
+            BSSvClearBSSList((HANDLE)pDevice, pDevice->bLinkPass);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_BSS_SCAN..begin \n");
+
+        if (pItemSSID->len != 0)
+            bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, abyScanSSID);
+        else
+            bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, NULL);
+        spin_unlock_irq(&pDevice->lock);
+        break;
+
+    case WLAN_CMD_ZONETYPE_SET:
+	//mike add :cann't support.
+           result=-EOPNOTSUPP;
+	  break;
+
+        if (copy_from_user(&sZoneTypeCmd, pReq->data, sizeof(SCmdZoneTypeSet))) {
+			result = -EFAULT;
+			break;
+		};
+
+          if(sZoneTypeCmd.bWrite==TRUE) {
+	  //////write zonetype
+                if(sZoneTypeCmd.ZoneType == ZoneType_USA) {
+                  //set to USA
+                   printk("set_ZoneType:USA\n");
+		}
+                else if(sZoneTypeCmd.ZoneType == ZoneType_Japan) {
+                  //set to Japan
+                  printk("set_ZoneType:Japan\n");
+		}
+	       else if(sZoneTypeCmd.ZoneType == ZoneType_Europe) {
+                  //set to Europe
+                  printk("set_ZoneType:Europe\n");
+		}
+            }
+	else {
+          ///////read zonetype
+	  BYTE                       zonetype=0;
+
+
+           if(zonetype == 0x00)  { //USA
+             sZoneTypeCmd.ZoneType = ZoneType_USA;
+           }
+	 else if(zonetype == 0x01) { //Japan
+             sZoneTypeCmd.ZoneType = ZoneType_Japan;
+	  }
+	 else if(zonetype == 0x02) { //Europe
+             sZoneTypeCmd.ZoneType = ZoneType_Europe;
+	 }
+	 else { //Unknow ZoneType
+	        printk("Error:ZoneType[%x] Unknown ???\n",zonetype);
+	         result = -EFAULT;
+		break;
+	 }
+	   if (copy_to_user(pReq->data, &sZoneTypeCmd, sizeof(SCmdZoneTypeSet))) {
+			result = -EFAULT;
+			break;
+		};
+	}
+
+	     break;
+
+    case WLAN_CMD_BSS_JOIN:
+
+        if (copy_from_user(&sJoinCmd, pReq->data, sizeof(SCmdBSSJoin))) {
+			result = -EFAULT;
+			break;
+		};
+
+        pItemSSID = (PWLAN_IE_SSID)sJoinCmd.ssid;
+        memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+		memcpy(pMgmt->abyDesireSSID, pItemSSID, pItemSSID->len + WLAN_IEHDR_LEN);
+	    if (sJoinCmd.wBSSType == ADHOC) {
+	        pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA;
+	        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ioct set to adhoc mode\n");
+	    }
+	    else {
+	        pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA;
+	        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ioct set to STA mode\n");
+	    }
+	    if (sJoinCmd.bPSEnable == TRUE) {
+            pDevice->ePSMode = WMAC_POWER_FAST;
+//            pDevice->ePSMode = WMAC_POWER_MAX;
+            pMgmt->wListenInterval = 2;
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Power Saving On\n");
+        }
+        else {
+            pDevice->ePSMode = WMAC_POWER_CAM;
+            pMgmt->wListenInterval = 1;
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Power Saving Off \n");
+        }
+
+        if (sJoinCmd.bShareKeyAuth == TRUE){
+            pMgmt->bShareKeyAlgorithm = TRUE;
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Share Key \n");
+        }
+        else {
+            pMgmt->bShareKeyAlgorithm = FALSE;
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Open System \n");
+        }
+	    pDevice->uChannel = sJoinCmd.uChannel;
+        netif_stop_queue(pDevice->dev);
+        spin_lock_irq(&pDevice->lock);
+        pMgmt->eCurrState = WMAC_STATE_IDLE;
+        bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID);
+        bScheduleCommand((HANDLE) pDevice, WLAN_CMD_SSID, NULL);
+        spin_unlock_irq(&pDevice->lock);
+        break;
+
+    case WLAN_CMD_SET_WEP:
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_WEP Key. \n");
+        memset(&sWEPCmd, 0 ,sizeof(SCmdSetWEP));
+        if (copy_from_user(&sWEPCmd, pReq->data, sizeof(SCmdSetWEP))) {
+			result = -EFAULT;
+			break;
+		};
+	    if (sWEPCmd.bEnableWep != TRUE) {
+	        int uu;
+
+            pDevice->bEncryptionEnable = FALSE;
+            pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
+            spin_lock_irq(&pDevice->lock);
+            for(uu=0;uu<MAX_KEY_TABLE;uu++)
+                MACvDisableKeyEntry(pDevice,uu);
+            spin_unlock_irq(&pDevice->lock);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WEP function disable. \n");
+            break;
+        }
+
+        for (ii = 0; ii < WLAN_WEP_NKEYS; ii ++) {
+            if (sWEPCmd.bWepKeyAvailable[ii]) {
+                if (ii == sWEPCmd.byKeyIndex)
+//2006-1207-01<Modify>by Einsn Liu
+//		    dwKeyIndex|= (1 << 31);
+                    dwKeyIndex=ii|(1 << 31);
+                else
+                    dwKeyIndex = ii;
+                spin_lock_irq(&pDevice->lock);
+                KeybSetDefaultKey(  pDevice,
+                                    &(pDevice->sKey),
+                                    dwKeyIndex,
+                                    sWEPCmd.auWepKeyLength[ii],
+                                    NULL,
+                                    (PBYTE)&sWEPCmd.abyWepKey[ii][0],
+                                    KEY_CTL_WEP
+                                  );
+               spin_unlock_irq(&pDevice->lock);
+
+            }
+        }
+        pDevice->byKeyIndex = sWEPCmd.byKeyIndex;
+        pDevice->bTransmitKey = TRUE;
+        pDevice->bEncryptionEnable = TRUE;
+        pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
+
+        break;
+
+    case WLAN_CMD_GET_LINK:
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_GET_LINK status. \n");
+
+        memset(sLinkStatus.abySSID, 0 , WLAN_SSID_MAXLEN + 1);
+
+        if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)
+            sLinkStatus.wBSSType = ADHOC;
+        else
+            sLinkStatus.wBSSType = INFRA;
+
+        if (pMgmt->eCurrState == WMAC_STATE_JOINTED)
+            sLinkStatus.byState = ADHOC_JOINTED;
+        else
+            sLinkStatus.byState = ADHOC_STARTED;
+
+        sLinkStatus.uChannel = pMgmt->uCurrChannel;
+        if (pDevice->bLinkPass == TRUE) {
+            sLinkStatus.bLink = TRUE;
+ 		    pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
+		    memcpy(sLinkStatus.abySSID, pItemSSID->abySSID, pItemSSID->len);
+		    memcpy(sLinkStatus.abyBSSID, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
+		    sLinkStatus.uLinkRate = pMgmt->sNodeDBTable[0].wTxDataRate;
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Link Success ! \n");
+        }
+        else {
+            sLinkStatus.bLink = FALSE;
+        }
+        if (copy_to_user(pReq->data, &sLinkStatus, sizeof(SCmdLinkStatus))) {
+			result = -EFAULT;
+			break;
+		};
+
+        break;
+
+    case WLAN_CMD_GET_LISTLEN:
+		cbListCount = 0;
+		pBSS = &(pMgmt->sBSSList[0]);
+        for (ii = 0; ii < MAX_BSS_NUM; ii++) {
+            pBSS = &(pMgmt->sBSSList[ii]);
+            if (!pBSS->bActive)
+                continue;
+            cbListCount++;
+        };
+        sList.uItem = cbListCount;
+        if (copy_to_user(pReq->data, &sList, sizeof(SBSSIDList))) {
+			result = -EFAULT;
+			break;
+		};
+        pReq->wResult = 0;
+        break;
+
+    case WLAN_CMD_GET_LIST:
+        if (copy_from_user(&sList, pReq->data, sizeof(SBSSIDList))) {
+			result = -EFAULT;
+			break;
+		};
+        pList = (PSBSSIDList)kmalloc(sizeof(SBSSIDList) + (sList.uItem * sizeof(SBSSIDItem)), (int)GFP_ATOMIC);
+        if (pList == NULL) {
+            result = -ENOMEM;
+            break;
+        }
+		pList->uItem = sList.uItem;
+		pBSS = &(pMgmt->sBSSList[0]);
+        for (ii = 0, jj = 0; jj < MAX_BSS_NUM ; jj++) {
+            pBSS = &(pMgmt->sBSSList[jj]);
+            if (pBSS->bActive) {
+    		    pList->sBSSIDList[ii].uChannel = pBSS->uChannel;
+    		    pList->sBSSIDList[ii].wBeaconInterval = pBSS->wBeaconInterval;
+    		    pList->sBSSIDList[ii].wCapInfo = pBSS->wCapInfo;
+    		    RFvRSSITodBm(pDevice, (BYTE)(pBSS->uRSSI), &ldBm);
+    		    pList->sBSSIDList[ii].uRSSI = (UINT)ldBm;
+//    		    pList->sBSSIDList[ii].uRSSI = pBSS->uRSSI;
+    		    memcpy(pList->sBSSIDList[ii].abyBSSID, pBSS->abyBSSID, WLAN_BSSID_LEN);
+    		    pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID;
+    		    memset(pList->sBSSIDList[ii].abySSID, 0, WLAN_SSID_MAXLEN + 1);
+    		    memcpy(pList->sBSSIDList[ii].abySSID, pItemSSID->abySSID, pItemSSID->len);
+                if (WLAN_GET_CAP_INFO_ESS(pBSS->wCapInfo)) {
+    		        pList->sBSSIDList[ii].byNetType = INFRA;
+                }
+                else {
+    		        pList->sBSSIDList[ii].byNetType = ADHOC;
+    		    }
+    		    if (WLAN_GET_CAP_INFO_PRIVACY(pBSS->wCapInfo)) {
+    		        pList->sBSSIDList[ii].bWEPOn = TRUE;
+                }
+                else {
+    		        pList->sBSSIDList[ii].bWEPOn = FALSE;
+    		    }
+    		    ii ++;
+    		    if (ii >= pList->uItem)
+    		        break;
+            }
+        }
+
+        if (copy_to_user(pReq->data, pList, sizeof(SBSSIDList) + (sList.uItem * sizeof(SBSSIDItem)))) {
+			result = -EFAULT;
+			break;
+		};
+        kfree(pList);
+        pReq->wResult = 0;
+        break;
+
+    case WLAN_CMD_GET_MIB:
+        if (copy_to_user(pReq->data, &(pDevice->s802_11Counter), sizeof(SDot11MIBCount))) {
+			result = -EFAULT;
+			break;
+		};
+        break;
+
+    case WLAN_CMD_GET_STAT:
+        if (copy_to_user(pReq->data, &(pDevice->scStatistic), sizeof(SStatCounter))) {
+			result = -EFAULT;
+			break;
+		};
+        break;
+    case WLAN_CMD_STOP_MAC:
+
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_STOP_MAC\n");
+        // Todo xxxxxx
+        netif_stop_queue(pDevice->dev);
+        spin_lock_irq(&pDevice->lock);
+        if (pDevice->bRadioOff == FALSE) {
+            CARDbRadioPowerOff(pDevice);
+        }
+        pDevice->bLinkPass = FALSE;
+        ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW);
+        memset(pMgmt->abyCurrBSSID, 0, 6);
+        pMgmt->eCurrState = WMAC_STATE_IDLE;
+//        del_timer(&pDevice->sTimerCommand);
+//        del_timer(&pMgmt->sTimerSecondCallback);
+        pDevice->bCmdRunning = FALSE;
+        spin_unlock_irq(&pDevice->lock);
+
+        break;
+
+    case WLAN_CMD_START_MAC:
+
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_START_MAC\n");
+        // Todo xxxxxxx
+        if (pDevice->bRadioOff == TRUE)
+            CARDbRadioPowerOn(pDevice);
+        break;
+
+    case WLAN_CMD_SET_HOSTAPD:
+
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_HOSTAPD\n");
+
+        if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) {
+			result = -EFAULT;
+			break;
+		};
+		if (sValue.dwValue == 1) {
+            if (hostap_set_hostapd(pDevice, 1, 1) == 0){
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable HOSTAP\n");
+            }
+            else {
+			    result = -EFAULT;
+			    break;
+			}
+        }
+        else {
+            hostap_set_hostapd(pDevice, 0, 1);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable HOSTAP\n");
+        }
+
+        break;
+
+    case WLAN_CMD_SET_HOSTAPD_STA:
+
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_HOSTAPD_STA\n");
+
+        break;
+    case WLAN_CMD_SET_802_1X:
+
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_802_1X\n");
+        if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) {
+			result = -EFAULT;
+			break;
+		};
+
+		if (sValue.dwValue == 1) {
+            pDevice->bEnable8021x = TRUE;
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable 802.1x\n");
+        }
+        else {
+            pDevice->bEnable8021x = FALSE;
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable 802.1x\n");
+        }
+
+        break;
+
+
+    case WLAN_CMD_SET_HOST_WEP:
+
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_HOST_WEP\n");
+        if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) {
+			result = -EFAULT;
+			break;
+		};
+
+		if (sValue.dwValue == 1) {
+            pDevice->bEnableHostWEP = TRUE;
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable HostWEP\n");
+        }
+        else {
+            pDevice->bEnableHostWEP = FALSE;
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable HostWEP\n");
+        }
+
+        break;
+
+    case WLAN_CMD_SET_WPA:
+         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_WPA\n");
+
+        if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) {
+			result = -EFAULT;
+			break;
+		};
+		if (sValue.dwValue == 1) {
+                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "up wpadev\n");
+		   memcpy(pDevice->wpadev->dev_addr, pDevice->dev->dev_addr, U_ETHER_ADDR_LEN);
+		   pDevice->bWPADEVUp = TRUE;
+        }
+        else {
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "close wpadev\n");
+	   pDevice->bWPADEVUp = FALSE;
+        }
+
+        break;
+
+    case WLAN_CMD_AP_START:
+
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_AP_START\n");
+        if (pDevice->bRadioOff == TRUE) {
+            CARDbRadioPowerOn(pDevice);
+            add_timer(&pMgmt->sTimerSecondCallback);
+        }
+        if (copy_from_user(&sStartAPCmd, pReq->data, sizeof(SCmdStartAP))) {
+			result = -EFAULT;
+			break;
+		};
+
+	    if (sStartAPCmd.wBSSType == AP) {
+	        pMgmt->eConfigMode = WMAC_CONFIG_AP;
+	        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ioct set to AP mode\n");
+	    }
+	    else {
+	        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ioct BSS type not set to AP mode\n");
+			result = -EFAULT;
+			break;
+	    }
+
+
+	    if (sStartAPCmd.wBBPType == PHY80211g) {
+            pMgmt->byAPBBType = PHY_TYPE_11G;
+        }
+        else if (sStartAPCmd.wBBPType == PHY80211a) {
+                 pMgmt->byAPBBType = PHY_TYPE_11A;
+        }
+        else {
+            pMgmt->byAPBBType = PHY_TYPE_11B;
+        }
+
+        pItemSSID = (PWLAN_IE_SSID)sStartAPCmd.ssid;
+        memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+		memcpy(pMgmt->abyDesireSSID, pItemSSID, pItemSSID->len + WLAN_IEHDR_LEN);
+
+	    if ((sStartAPCmd.uChannel > 0)&&(sStartAPCmd.uChannel <= 14))
+	        pDevice->uChannel = sStartAPCmd.uChannel;
+
+	    if ((sStartAPCmd.uBeaconInt >= 20) && (sStartAPCmd.uBeaconInt <= 1000))
+            pMgmt->wIBSSBeaconPeriod = sStartAPCmd.uBeaconInt;
+        else
+            pMgmt->wIBSSBeaconPeriod = 100;
+
+        if (sStartAPCmd.bShareKeyAuth == TRUE){
+            pMgmt->bShareKeyAlgorithm = TRUE;
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Share Key \n");
+        }
+        else {
+            pMgmt->bShareKeyAlgorithm = FALSE;
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Open System \n");
+        }
+        memcpy(pMgmt->abyIBSSSuppRates, abySuppRates, 6);
+
+        if (sStartAPCmd.byBasicRate & BIT3) {
+            pMgmt->abyIBSSSuppRates[2] |= BIT7;
+            pMgmt->abyIBSSSuppRates[3] |= BIT7;
+            pMgmt->abyIBSSSuppRates[4] |= BIT7;
+            pMgmt->abyIBSSSuppRates[5] |= BIT7;
+        }else if (sStartAPCmd.byBasicRate & BIT2) {
+             pMgmt->abyIBSSSuppRates[2] |= BIT7;
+             pMgmt->abyIBSSSuppRates[3] |= BIT7;
+             pMgmt->abyIBSSSuppRates[4] |= BIT7;
+        }else if (sStartAPCmd.byBasicRate & BIT1) {
+             pMgmt->abyIBSSSuppRates[2] |= BIT7;
+             pMgmt->abyIBSSSuppRates[3] |= BIT7;
+        }else if (sStartAPCmd.byBasicRate & BIT1) {
+             pMgmt->abyIBSSSuppRates[2] |= BIT7;
+        }else {
+            //default 1,2M
+             pMgmt->abyIBSSSuppRates[2] |= BIT7;
+             pMgmt->abyIBSSSuppRates[3] |= BIT7;
+        }
+
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Support Rate= %x %x %x %x\n",
+                pMgmt->abyIBSSSuppRates[2],
+                pMgmt->abyIBSSSuppRates[3],
+                pMgmt->abyIBSSSuppRates[4],
+                pMgmt->abyIBSSSuppRates[5]
+                );
+
+        netif_stop_queue(pDevice->dev);
+        spin_lock_irq(&pDevice->lock);
+        bScheduleCommand((HANDLE)pDevice, WLAN_CMD_RUN_AP, NULL);
+        spin_unlock_irq(&pDevice->lock);
+        break;
+
+    case WLAN_CMD_GET_NODE_CNT:
+
+		cbListCount = 0;
+		pNode = &(pMgmt->sNodeDBTable[0]);
+        for (ii = 0; ii < (MAX_NODE_NUM + 1); ii++) {
+            pNode = &(pMgmt->sNodeDBTable[ii]);
+            if (!pNode->bActive)
+                continue;
+            cbListCount++;
+        };
+
+        sNodeList.uItem = cbListCount;
+        if (copy_to_user(pReq->data, &sNodeList, sizeof(SNodeList))) {
+			result = -EFAULT;
+			break;
+		};
+        pReq->wResult = 0;
+        break;
+
+    case WLAN_CMD_GET_NODE_LIST:
+
+        if (copy_from_user(&sNodeList, pReq->data, sizeof(SNodeList))) {
+			result = -EFAULT;
+			break;
+		};
+        pNodeList = (PSNodeList)kmalloc(sizeof(SNodeList) + (sNodeList.uItem * sizeof(SNodeItem)), (int)GFP_ATOMIC);
+        if (pNodeList == NULL) {
+            result = -ENOMEM;
+            break;
+        }
+		pNodeList->uItem = sNodeList.uItem;
+		pNode = &(pMgmt->sNodeDBTable[0]);
+        for (ii = 0, jj = 0; ii < (MAX_NODE_NUM + 1); ii++) {
+            pNode = &(pMgmt->sNodeDBTable[ii]);
+            if (pNode->bActive) {
+    		    pNodeList->sNodeList[jj].wAID = pNode->wAID;
+    		    memcpy(pNodeList->sNodeList[jj].abyMACAddr, pNode->abyMACAddr, WLAN_ADDR_LEN);
+    		    pNodeList->sNodeList[jj].wTxDataRate = pNode->wTxDataRate;
+    		    pNodeList->sNodeList[jj].wInActiveCount = (WORD)pNode->uInActiveCount;
+    		    pNodeList->sNodeList[jj].wEnQueueCnt = (WORD)pNode->wEnQueueCnt;
+    		    pNodeList->sNodeList[jj].wFlags = (WORD)pNode->dwFlags;
+    		    pNodeList->sNodeList[jj].bPWBitOn = pNode->bPSEnable;
+    		    pNodeList->sNodeList[jj].byKeyIndex = pNode->byKeyIndex;
+    		    pNodeList->sNodeList[jj].wWepKeyLength = pNode->uWepKeyLength;
+    		    memcpy(&(pNodeList->sNodeList[jj].abyWepKey[0]), &(pNode->abyWepKey[0]), WEP_KEYMAXLEN);
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "key= %2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
+                            pNodeList->sNodeList[jj].abyWepKey[0],
+                            pNodeList->sNodeList[jj].abyWepKey[1],
+                            pNodeList->sNodeList[jj].abyWepKey[2],
+                            pNodeList->sNodeList[jj].abyWepKey[3],
+                            pNodeList->sNodeList[jj].abyWepKey[4]
+                           );
+    		    pNodeList->sNodeList[jj].bIsInFallback = pNode->bIsInFallback;
+    		    pNodeList->sNodeList[jj].uTxFailures = pNode->uTxFailures;
+    		    pNodeList->sNodeList[jj].uTxAttempts = pNode->uTxAttempts;
+    		    pNodeList->sNodeList[jj].wFailureRatio = (WORD)pNode->uFailureRatio;
+    		    jj ++;
+    		    if (jj >= pNodeList->uItem)
+    		        break;
+    		}
+		};
+        if (copy_to_user(pReq->data, pNodeList, sizeof(SNodeList) + (sNodeList.uItem * sizeof(SNodeItem)))) {
+			result = -EFAULT;
+			break;
+		};
+        kfree(pNodeList);
+        pReq->wResult = 0;
+        break;
+
+#ifdef WPA_SM_Transtatus
+    case 0xFF:
+        memset(wpa_Result.ifname,0,sizeof(wpa_Result.ifname));
+	    wpa_Result.proto = 0;
+	    wpa_Result.key_mgmt = 0;
+	    wpa_Result.eap_type = 0;
+	    wpa_Result.authenticated = FALSE;
+	      pDevice->fWPA_Authened = FALSE;
+        if (copy_from_user(&wpa_Result, pReq->data, sizeof(wpa_Result))) {
+            result = -EFAULT;
+			break;
+		}
+//DavidWang  for some AP maybe good authenticate
+   if(wpa_Result.key_mgmt==0x20)
+      pMgmt->Cisco_cckm =1;
+    else
+    pMgmt->Cisco_cckm =0;
+//DavidWang
+
+if(wpa_Result.authenticated==TRUE) {
+   #ifdef SndEvt_ToAPI
+   {
+     union iwreq_data      wrqu;
+
+     pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
+
+     memset(&wrqu, 0, sizeof(wrqu));
+     wrqu.data.flags = RT_WPACONNECTED_EVENT_FLAG;
+     wrqu.data.length =pItemSSID->len;
+     wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, pItemSSID->abySSID);
+   }
+   #endif
+         pDevice->fWPA_Authened = TRUE;           //is sucessful peer to wpa_Result.authenticated?
+}
+
+        //printk("get private wpa_supplicant announce WPA SM\n");
+	//printk("wpa-->ifname=%s\n",wpa_Result.ifname);
+	//printk("wpa-->proto=%d\n",wpa_Result.proto);
+	//printk("wpa-->key-mgmt=%d\n",wpa_Result.key_mgmt);
+	//printk("wpa-->eap_type=%d\n",wpa_Result.eap_type);
+	//printk("wpa-->authenticated is %s\n",(wpa_Result.authenticated==TRUE)?"TRUE":"FALSE");
+
+	pReq->wResult = 0;
+        break;
+#endif
+
+    default:
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Private command not support..\n");
+    }
+
+    return result;
+}
diff --git a/drivers/staging/vt6656/ioctl.h b/drivers/staging/vt6656/ioctl.h
new file mode 100644
index 0000000..9c6816e
--- /dev/null
+++ b/drivers/staging/vt6656/ioctl.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: hostap.h
+ *
+ * Purpose:
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: May 21, 2003
+ *
+ */
+
+
+#ifndef __IOCTL_H__
+#define __IOCTL_H__
+
+#if !defined(__DEVICE_H__)
+#include "device.h"
+#endif
+
+
+/*---------------------  Export Definitions -------------------------*/
+
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+#ifdef __cplusplus
+extern "C" {                            /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+
+int private_ioctl(PSDevice pDevice, struct ifreq *rq);
+
+/*
+VOID vConfigWEPKey (
+    IN PSDevice pDevice,
+    IN DWORD    dwKeyIndex,
+    IN PBYTE    pbyKey,
+    IN ULONG    uKeyLength
+    );
+*/
+
+#ifdef __cplusplus
+}                                       /* End of extern "C" { */
+#endif /* __cplusplus */
+
+
+
+
+#endif // __IOCTL_H__
+
+
+
diff --git a/drivers/staging/vt6656/iwctl.c b/drivers/staging/vt6656/iwctl.c
new file mode 100644
index 0000000..a2ca0e1
--- /dev/null
+++ b/drivers/staging/vt6656/iwctl.c
@@ -0,0 +1,2355 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: iwctl.c
+ *
+ * Purpose:  wireless ext & ioctl functions
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: July 5, 2006
+ *
+ * Functions:
+ *
+ * Revision History:
+ *
+ */
+
+
+#if !defined(__DEVICE_H__)
+#include "device.h"
+#endif
+#if !defined(__IOCTL_H__)
+#include "ioctl.h"
+#endif
+#if !defined(__IOCMD_H__)
+#include "iocmd.h"
+#endif
+#if !defined(__MAC_H__)
+#include "mac.h"
+#endif
+#if !defined(__CARD_H__)
+#include "card.h"
+#endif
+#if !defined(__HOSTAP_H__)
+#include "hostap.h"
+#endif
+#if !defined(__UMEM_H__)
+#include "umem.h"
+#endif
+#if !defined(__POWER_H__)
+#include "power.h"
+#endif
+#if !defined(__RF_H__)
+#include "rf.h"
+#endif
+
+#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+#if !defined(__IOWPA_H__)
+#include "iowpa.h"
+#endif
+#if !defined(__WPACTL_H__)
+#include "wpactl.h"
+#endif
+#endif
+
+#if WIRELESS_EXT > 12
+#include <net/iw_handler.h>
+#endif
+
+
+/*---------------------  Static Definitions -------------------------*/
+
+//2008-0409-07, <Add> by Einsn Liu
+#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+#define SUPPORTED_WIRELESS_EXT                  18
+#else
+#define SUPPORTED_WIRELESS_EXT                  17
+#endif
+
+#ifdef WIRELESS_EXT
+
+static const long frequency_list[] = {
+    2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467, 2472, 2484,
+    4915, 4920, 4925, 4935, 4940, 4945, 4960, 4980,
+    5035, 5040, 5045, 5055, 5060, 5080, 5170, 5180, 5190, 5200, 5210, 5220, 5230, 5240,
+    5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680,
+    5700, 5745, 5765, 5785, 5805, 5825
+	};
+
+#endif
+
+
+/*---------------------  Static Classes  ----------------------------*/
+
+
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+static int          msglevel                =MSG_LEVEL_INFO;
+
+
+/*---------------------  Static Variables  --------------------------*/
+/*---------------------  Static Functions  --------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+#ifdef WIRELESS_EXT
+
+#if WIRELESS_EXT > 12
+
+struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev)
+{
+	PSDevice pDevice = dev->priv;
+	long ldBm;
+
+	pDevice->wstats.status = pDevice->eOPMode;
+	#ifdef Calcu_LinkQual
+	 #if 0
+	  if(pDevice->byBBType == BB_TYPE_11B) {
+	     if(pDevice->byCurrSQ > 120)
+                  pDevice->scStatistic.LinkQuality = 100;
+	     else
+		 pDevice->scStatistic.LinkQuality = pDevice->byCurrSQ*100/120;
+	    }
+	  else if(pDevice->byBBType == BB_TYPE_11G) {
+                if(pDevice->byCurrSQ < 20)
+		   pDevice->scStatistic.LinkQuality = 100;
+	       else if(pDevice->byCurrSQ >96)
+		   pDevice->scStatistic.LinkQuality  = 0;
+	       else
+		   pDevice->scStatistic.LinkQuality = (96-pDevice->byCurrSQ)*100/76;
+	   }
+	   if(pDevice->bLinkPass !=TRUE)
+	       pDevice->scStatistic.LinkQuality = 0;
+	  #endif
+	   if(pDevice->scStatistic.LinkQuality > 100)
+   	       pDevice->scStatistic.LinkQuality = 100;
+               pDevice->wstats.qual.qual =(BYTE) pDevice->scStatistic.LinkQuality;
+	#else
+	pDevice->wstats.qual.qual = pDevice->byCurrSQ;
+	#endif
+	RFvRSSITodBm(pDevice, (BYTE)(pDevice->uCurrRSSI), &ldBm);
+	pDevice->wstats.qual.level = ldBm;
+	//pDevice->wstats.qual.level = 0x100 - pDevice->uCurrRSSI;
+	pDevice->wstats.qual.noise = 0;
+	pDevice->wstats.qual.updated = 1;
+	pDevice->wstats.discard.nwid = 0;
+	pDevice->wstats.discard.code = 0;
+	pDevice->wstats.discard.fragment = 0;
+	pDevice->wstats.discard.retries = pDevice->scStatistic.dwTsrErr;
+	pDevice->wstats.discard.misc = 0;
+	pDevice->wstats.miss.beacon = 0;
+
+	return &pDevice->wstats;
+}
+
+#endif
+
+
+
+/*------------------------------------------------------------------*/
+
+
+static int iwctl_commit(struct net_device *dev,
+			      struct iw_request_info *info,
+			      void *wrq,
+			      char *extra)
+{
+//2008-0409-02, <Mark> by Einsn Liu
+/*
+#ifdef Safe_Close
+  PSDevice	        pDevice = (PSDevice)dev->priv;
+  if (!(pDevice->flags & DEVICE_FLAGS_OPENED))
+        return -EINVAL;
+#endif
+*/
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWCOMMIT \n");
+
+	return 0;
+
+}
+
+/*
+ * Wireless Handler : get protocol name
+ */
+
+int iwctl_giwname(struct net_device *dev,
+			 struct iw_request_info *info,
+			 char *wrq,
+			 char *extra)
+{
+	strcpy(wrq, "802.11-a/b/g");
+	return 0;
+}
+
+int iwctl_giwnwid(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_param *wrq,
+                   char *extra)
+{
+ 	//wrq->value = 0x100;
+	//wrq->disabled = 0;
+	//wrq->fixed = 1;
+	//return 0;
+  return -EOPNOTSUPP;
+}
+#if WIRELESS_EXT > 13
+
+/*
+ * Wireless Handler : set scan
+ */
+
+int iwctl_siwscan(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_point *wrq,
+             char *extra)
+{
+	PSDevice	        pDevice = (PSDevice)dev->priv;
+	 PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+	struct iw_scan_req  *req = (struct iw_scan_req *)extra;
+	BYTE                abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
+	PWLAN_IE_SSID       pItemSSID=NULL;
+
+//2008-0920-01<Add>by MikeLiu
+  if (!(pDevice->flags & DEVICE_FLAGS_OPENED))
+        return -EINVAL;
+
+    PRINT_K(" SIOCSIWSCAN \n");
+
+if (pMgmt->eScanState ==  WMAC_IS_SCANNING) {
+        // In scanning..
+     PRINT_K("SIOCSIWSCAN(overlap??)-->In scanning...\n");
+     return -EAGAIN;
+  }
+
+if(pDevice->byReAssocCount > 0) {   //reject scan when re-associating!
+//send scan event to wpa_Supplicant
+  union iwreq_data wrqu;
+ PRINT_K("wireless_send_event--->SIOCGIWSCAN(scan done)\n");
+ memset(&wrqu, 0, sizeof(wrqu));
+ wireless_send_event(pDevice->dev, SIOCGIWSCAN, &wrqu, NULL);
+  return 0;
+}
+
+	spin_lock_irq(&pDevice->lock);
+
+   #ifdef update_BssList
+        BSSvClearBSSList((HANDLE)pDevice, pDevice->bLinkPass);
+   #endif
+
+//mike add: active scan OR passive scan OR desire_ssid scan
+ if(wrq->length == sizeof(struct iw_scan_req)) {
+   if (wrq->flags & IW_SCAN_THIS_ESSID)  {                               //desire_ssid scan
+       memset(abyScanSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+       pItemSSID = (PWLAN_IE_SSID)abyScanSSID;
+       pItemSSID->byElementID = WLAN_EID_SSID;
+       memcpy(pItemSSID->abySSID, req->essid, (int)req->essid_len);
+         if (pItemSSID->abySSID[req->essid_len - 1] == '\0') {
+           if(req->essid_len>0)
+		pItemSSID->len = req->essid_len - 1;
+         }
+	else
+	  pItemSSID->len = req->essid_len;
+	  pMgmt->eScanType = WMAC_SCAN_PASSIVE;
+         PRINT_K("SIOCSIWSCAN:[desired_ssid=%s,len=%d]\n",((PWLAN_IE_SSID)abyScanSSID)->abySSID,
+		 	                                                                                ((PWLAN_IE_SSID)abyScanSSID)->len);
+	bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, abyScanSSID);
+	spin_unlock_irq(&pDevice->lock);
+
+	return 0;
+   }
+   else if(req->scan_type == IW_SCAN_TYPE_PASSIVE) {          //passive scan
+       pMgmt->eScanType = WMAC_SCAN_PASSIVE;
+   }
+ }
+ else {           //active scan
+     pMgmt->eScanType = WMAC_SCAN_ACTIVE;
+ }
+
+	 pMgmt->eScanType = WMAC_SCAN_PASSIVE;
+         //printk("SIOCSIWSCAN:WLAN_CMD_BSSID_SCAN\n");
+	bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, NULL);
+	spin_unlock_irq(&pDevice->lock);
+
+	return 0;
+}
+
+
+/*
+ * Wireless Handler : get scan results
+ */
+
+int iwctl_giwscan(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_point *wrq,
+             char *extra)
+{
+    int ii, jj, kk;
+	PSDevice	        pDevice = (PSDevice)dev->priv;
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+    PKnownBSS           pBSS;
+    PWLAN_IE_SSID       pItemSSID;
+    PWLAN_IE_SUPP_RATES pSuppRates, pExtSuppRates;
+	char *current_ev = extra;
+	char *end_buf = extra + IW_SCAN_MAX_DATA;
+	char *current_val = NULL;
+	struct iw_event iwe;
+	long ldBm;
+#if WIRELESS_EXT > 14
+	char buf[MAX_WPA_IE_LEN * 2 + 30];
+#endif /* WIRELESS_EXT > 14 */
+
+//2008-0409-02, <Mark> by Einsn Liu
+/*
+#ifdef Safe_Close
+  if (!(pDevice->flags & DEVICE_FLAGS_OPENED))
+        return -EINVAL;
+#endif
+*/
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSCAN \n");
+
+    if (pMgmt->eScanState ==  WMAC_IS_SCANNING) {
+        // In scanning..
+		return -EAGAIN;
+	}
+	pBSS = &(pMgmt->sBSSList[0]);
+    for (ii = 0, jj = 0; jj < MAX_BSS_NUM ; jj++) {
+		if (current_ev >= end_buf)
+			break;
+        pBSS = &(pMgmt->sBSSList[jj]);
+        if (pBSS->bActive) {
+		//ADD mac address
+		    memset(&iwe, 0, sizeof(iwe));
+		    iwe.cmd = SIOCGIWAP;
+		    iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+			memcpy(iwe.u.ap_addr.sa_data, pBSS->abyBSSID, WLAN_BSSID_LEN);
+			#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)   //mike add
+                           current_ev = iwe_stream_add_event(info,current_ev,end_buf, &iwe, IW_EV_ADDR_LEN);
+			#else
+			current_ev = iwe_stream_add_event(current_ev,end_buf, &iwe, IW_EV_ADDR_LEN);
+			#endif
+                 //ADD ssid
+	             memset(&iwe, 0, sizeof(iwe));
+                      iwe.cmd = SIOCGIWESSID;
+                      pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID;
+                       iwe.u.data.length = pItemSSID->len;
+                       iwe.u.data.flags = 1;
+		  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)   //mike add
+                      current_ev = iwe_stream_add_point(info,current_ev,end_buf, &iwe, pItemSSID->abySSID);
+		  #else
+       		    current_ev = iwe_stream_add_point(current_ev,end_buf, &iwe, pItemSSID->abySSID);
+		  #endif
+		//ADD mode
+		    memset(&iwe, 0, sizeof(iwe));
+		    iwe.cmd = SIOCGIWMODE;
+            if (WLAN_GET_CAP_INFO_ESS(pBSS->wCapInfo)) {
+		        iwe.u.mode = IW_MODE_INFRA;
+            }
+            else {
+                iwe.u.mode = IW_MODE_ADHOC;
+		    }
+	        iwe.len = IW_EV_UINT_LEN;
+		 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)   //mike add
+                      current_ev = iwe_stream_add_event(info,current_ev, end_buf, &iwe,  IW_EV_UINT_LEN);
+		 #else
+		    current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,  IW_EV_UINT_LEN);
+		 #endif
+           //ADD frequency
+            pSuppRates = (PWLAN_IE_SUPP_RATES)pBSS->abySuppRates;
+            pExtSuppRates = (PWLAN_IE_SUPP_RATES)pBSS->abyExtSuppRates;
+            memset(&iwe, 0, sizeof(iwe));
+           	iwe.cmd = SIOCGIWFREQ;
+           	iwe.u.freq.m = pBSS->uChannel;
+           	iwe.u.freq.e = 0;
+           	iwe.u.freq.i = 0;
+	     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)   //mike add
+                  current_ev = iwe_stream_add_event(info,current_ev,end_buf, &iwe, IW_EV_FREQ_LEN);
+	     #else
+           	current_ev = iwe_stream_add_event(current_ev,end_buf, &iwe, IW_EV_FREQ_LEN);
+	     #endif
+            //2008-0409-04, <Add> by Einsn Liu
+			{
+			int f = (int)pBSS->uChannel - 1;
+			if(f < 0)f = 0;
+			iwe.u.freq.m = frequency_list[f] * 100000;
+			iwe.u.freq.e = 1;
+			}
+	     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)   //mike add
+                  current_ev = iwe_stream_add_event(info,current_ev,end_buf, &iwe, IW_EV_FREQ_LEN);
+	     #else
+           	current_ev = iwe_stream_add_event(current_ev,end_buf, &iwe, IW_EV_FREQ_LEN);
+	     #endif
+       		//ADD quality
+            memset(&iwe, 0, sizeof(iwe));
+	        iwe.cmd = IWEVQUAL;
+	        RFvRSSITodBm(pDevice, (BYTE)(pBSS->uRSSI), &ldBm);
+		    iwe.u.qual.level = ldBm;
+	        iwe.u.qual.noise = 0;
+//2008-0409-01, <Add> by Einsn Liu
+			if(-ldBm<50){
+				iwe.u.qual.qual = 100;
+			}else  if(-ldBm > 90) {
+				 iwe.u.qual.qual = 0;
+			}else {
+				iwe.u.qual.qual=(40-(-ldBm-50))*100/40;
+			}
+			iwe.u.qual.updated=7;
+
+//2008-0409-01, <Mark> by Einsn Liu
+/*
+//2008-0220-03, <Modify>  by Einsn Liu
+	if(pDevice->bLinkPass== TRUE && IS_ETH_ADDRESS_EQUAL(pBSS->abyBSSID, pMgmt->abyCurrBSSID)){
+	#ifdef Calcu_LinkQual
+	 #if 0
+	  if(pDevice->byBBType == BB_TYPE_11B) {
+	     if(pDevice->byCurrSQ > 120)
+                  pDevice->scStatistic.LinkQuality = 100;
+	     else
+		 pDevice->scStatistic.LinkQuality = pDevice->byCurrSQ*100/120;
+	    }
+	  else if(pDevice->byBBType == BB_TYPE_11G) {
+                if(pDevice->byCurrSQ < 20)
+		   pDevice->scStatistic.LinkQuality = 100;
+	       else if(pDevice->byCurrSQ >96)
+		   pDevice->scStatistic.LinkQuality  = 0;
+	       else
+		   pDevice->scStatistic.LinkQuality = (96-pDevice->byCurrSQ)*100/76;
+	   }
+	   if(pDevice->bLinkPass !=TRUE)
+	       pDevice->scStatistic.LinkQuality = 0;
+	  #endif
+	   if(pDevice->scStatistic.LinkQuality > 100)
+   	       pDevice->scStatistic.LinkQuality = 100;
+              iwe.u.qual.qual =(BYTE) pDevice->scStatistic.LinkQuality;
+	#else
+	iwe.u.qual.qual = pDevice->byCurrSQ;
+	#endif
+		}else {
+	        iwe.u.qual.qual = 0;
+		}
+*/
+            #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)   //mike add
+                 current_ev = iwe_stream_add_event(info,current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
+	   #else
+	        current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
+	   #endif
+       	//ADD encryption
+            memset(&iwe, 0, sizeof(iwe));
+            iwe.cmd = SIOCGIWENCODE;
+            iwe.u.data.length = 0;
+            if (WLAN_GET_CAP_INFO_PRIVACY(pBSS->wCapInfo)) {
+                iwe.u.data.flags =IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+            }else {
+                iwe.u.data.flags = IW_ENCODE_DISABLED;
+            }
+	#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)   //mike add
+            current_ev = iwe_stream_add_point(info,current_ev,end_buf, &iwe, pItemSSID->abySSID);
+	#else
+            current_ev = iwe_stream_add_point(current_ev,end_buf, &iwe, pItemSSID->abySSID);
+	#endif
+
+            memset(&iwe, 0, sizeof(iwe));
+            iwe.cmd = SIOCGIWRATE;
+           	iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
+      		current_val = current_ev + IW_EV_LCP_LEN;
+
+       		for (kk = 0 ; kk < 12 ; kk++) {
+		        if (pSuppRates->abyRates[kk] == 0)
+			        break;
+		        // Bit rate given in 500 kb/s units (+ 0x80)
+		        iwe.u.bitrate.value = ((pSuppRates->abyRates[kk] & 0x7f) * 500000);
+		     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)   //mike add
+                          current_val = iwe_stream_add_value(info,current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
+		     #else
+		        current_val = iwe_stream_add_value(current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
+		     #endif
+	        }
+       		for (kk = 0 ; kk < 8 ; kk++) {
+		        if (pExtSuppRates->abyRates[kk] == 0)
+			        break;
+		        // Bit rate given in 500 kb/s units (+ 0x80)
+		        iwe.u.bitrate.value = ((pExtSuppRates->abyRates[kk] & 0x7f) * 500000);
+		    #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)   //mike add
+                         current_val = iwe_stream_add_value(info,current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
+		    #else
+		        current_val = iwe_stream_add_value(current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
+		   #endif
+	        }
+
+	        if((current_val - current_ev) > IW_EV_LCP_LEN)
+		        current_ev = current_val;
+
+#if WIRELESS_EXT > 14
+            memset(&iwe, 0, sizeof(iwe));
+            iwe.cmd = IWEVCUSTOM;
+            sprintf(buf, "bcn_int=%d", pBSS->wBeaconInterval);
+            iwe.u.data.length = strlen(buf);
+     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)   //mike add
+             current_ev = iwe_stream_add_point(info,current_ev, end_buf, &iwe, buf);
+    #else
+            current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, buf);
+    #endif
+
+#if WIRELESS_EXT > 17
+            if ((pBSS->wWPALen > 0) && (pBSS->wWPALen <= MAX_WPA_IE_LEN)) {
+                memset(&iwe, 0, sizeof(iwe));
+                iwe.cmd = IWEVGENIE;
+                iwe.u.data.length = pBSS->wWPALen;
+	    #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)   //mike add
+                current_ev = iwe_stream_add_point(info,current_ev, end_buf, &iwe, pBSS->byWPAIE);
+	   #else
+                current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, pBSS->byWPAIE);
+	   #endif
+            }
+
+            if ((pBSS->wRSNLen > 0) && (pBSS->wRSNLen <= MAX_WPA_IE_LEN)) {
+                memset(&iwe, 0, sizeof(iwe));
+                iwe.cmd = IWEVGENIE;
+                iwe.u.data.length = pBSS->wRSNLen;
+	   #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)   //mike add
+                current_ev = iwe_stream_add_point(info,current_ev, end_buf, &iwe, pBSS->byRSNIE);
+	   #else
+                current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, pBSS->byRSNIE);
+	   #endif
+            }
+
+#else // WIRELESS_EXT > 17
+            if ((pBSS->wWPALen > 0) && (pBSS->wWPALen <= MAX_WPA_IE_LEN)) {
+                u8 *p = buf;
+                memset(&iwe, 0, sizeof(iwe));
+                iwe.cmd = IWEVCUSTOM;
+		        p += sprintf(p, "wpa_ie=");
+		        for (ii = 0; ii < pBSS->wWPALen; ii++) {
+			        p += sprintf(p, "%02x", pBSS->byWPAIE[ii]);
+		        }
+		        iwe.u.data.length = strlen(buf);
+		     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)   //mike add
+                          current_ev = iwe_stream_add_point(info,current_ev, end_buf, &iwe, buf);
+		     #else
+		        current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, buf);
+		     #endif
+		    }
+
+
+            if ((pBSS->wRSNLen > 0) && (pBSS->wRSNLen <= MAX_WPA_IE_LEN)) {
+                u8 *p = buf;
+                memset(&iwe, 0, sizeof(iwe));
+                iwe.cmd = IWEVCUSTOM;
+		        p += sprintf(p, "rsn_ie=");
+		        for (ii = 0; ii < pBSS->wRSNLen; ii++) {
+			        p += sprintf(p, "%02x", pBSS->byRSNIE[ii]);
+		        }
+		        iwe.u.data.length = strlen(buf);
+		     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)   //mike add
+                          current_ev = iwe_stream_add_point(info,current_ev, end_buf, &iwe, buf);
+		     #else
+		        current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, buf);
+		     #endif
+		    }
+#endif
+#endif
+        }
+    }// for
+
+	wrq->length = current_ev - extra;
+	return 0;
+
+}
+
+#endif	/* WIRELESS_EXT > 13 */
+
+
+/*
+ * Wireless Handler : set frequence or channel
+ */
+
+int iwctl_siwfreq(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_freq *wrq,
+             char *extra)
+{
+	PSDevice	        pDevice = (PSDevice)dev->priv;
+	int rc = 0;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFREQ \n");
+
+	// If setting by frequency, convert to a channel
+	if((wrq->e == 1) &&
+	   (wrq->m >= (int) 2.412e8) &&
+	   (wrq->m <= (int) 2.487e8)) {
+		int f = wrq->m / 100000;
+		int c = 0;
+		while((c < 14) && (f != frequency_list[c]))
+			c++;
+		wrq->e = 0;
+		wrq->m = c + 1;
+	}
+	// Setting by channel number
+	if((wrq->m > 14) || (wrq->e > 0))
+		rc = -EOPNOTSUPP;
+	else {
+		int channel = wrq->m;
+		if((channel < 1) || (channel > 14)) {
+			DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: New channel value of %d is invalid!\n", dev->name, wrq->m);
+			rc = -EINVAL;
+		} else {
+			  // Yes ! We can set it !!!
+              DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Set to channel = %d\n", channel);
+			  pDevice->uChannel = channel;
+		}
+	}
+
+	return rc;
+}
+
+/*
+ * Wireless Handler : get frequence or channel
+ */
+
+int iwctl_giwfreq(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_freq *wrq,
+             char *extra)
+{
+	PSDevice	        pDevice = (PSDevice)dev->priv;
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFREQ \n");
+
+#ifdef WEXT_USECHANNELS
+	wrq->m = (int)pMgmt->uCurrChannel;
+	wrq->e = 0;
+#else
+	{
+		int f = (int)pMgmt->uCurrChannel - 1;
+		if(f < 0)
+		   f = 0;
+		wrq->m = frequency_list[f] * 100000;
+		wrq->e = 1;
+	}
+#endif
+
+	return 0;
+}
+
+/*
+ * Wireless Handler : set operation mode
+ */
+
+int iwctl_siwmode(struct net_device *dev,
+             struct iw_request_info *info,
+             __u32 *wmode,
+             char *extra)
+{
+	PSDevice	        pDevice = (PSDevice)dev->priv;
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+    int rc = 0;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMODE \n");
+
+    if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP && pDevice->bEnableHostapd) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Can't set operation mode, hostapd is running \n");
+        return rc;
+    }
+
+	switch(*wmode) {
+
+	case IW_MODE_ADHOC:
+	    if (pMgmt->eConfigMode != WMAC_CONFIG_IBSS_STA) {
+            pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA;
+            if (pDevice->flags & DEVICE_FLAGS_OPENED) {
+		        pDevice->bCommit = TRUE;
+   		    }
+		}
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to ad-hoc \n");
+		break;
+	case IW_MODE_AUTO:
+	case IW_MODE_INFRA:
+	    if (pMgmt->eConfigMode != WMAC_CONFIG_ESS_STA) {
+            pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA;
+            if (pDevice->flags & DEVICE_FLAGS_OPENED) {
+		        pDevice->bCommit = TRUE;
+   		    }
+		}
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to infrastructure \n");
+		break;
+	case IW_MODE_MASTER:
+
+        pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA;
+		rc = -EOPNOTSUPP;
+		break;
+
+	    if (pMgmt->eConfigMode != WMAC_CONFIG_AP) {
+            pMgmt->eConfigMode = WMAC_CONFIG_AP;
+            if (pDevice->flags & DEVICE_FLAGS_OPENED) {
+		        pDevice->bCommit = TRUE;
+   		    }
+		}
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to Access Point \n");
+		break;
+
+	case IW_MODE_REPEAT:
+        pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA;
+		rc = -EOPNOTSUPP;
+		break;
+	default:
+		rc = -EINVAL;
+	}
+
+	return rc;
+}
+
+/*
+ * Wireless Handler : get operation mode
+ */
+
+int iwctl_giwmode(struct net_device *dev,
+             struct iw_request_info *info,
+             __u32 *wmode,
+             char *extra)
+{
+	PSDevice	        pDevice = (PSDevice)dev->priv;
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWMODE \n");
+	// If not managed, assume it's ad-hoc
+	switch (pMgmt->eConfigMode) {
+	case WMAC_CONFIG_ESS_STA:
+		*wmode = IW_MODE_INFRA;
+		break;
+	case WMAC_CONFIG_IBSS_STA:
+        *wmode = IW_MODE_ADHOC;
+		break;
+	case WMAC_CONFIG_AUTO:
+		*wmode = IW_MODE_INFRA;
+		break;
+	case WMAC_CONFIG_AP:
+		*wmode = IW_MODE_MASTER;
+		break;
+	default:
+		*wmode = IW_MODE_ADHOC;
+	}
+
+	return 0;
+}
+
+
+/*
+ * Wireless Handler : get capability range
+ */
+
+int iwctl_giwrange(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_point *wrq,
+             char *extra)
+{
+	struct iw_range *range = (struct iw_range *) extra;
+	int		i,k;
+    BYTE abySupportedRates[13]= {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90};
+//2008-0409-02, <Mark> by Einsn Liu
+/*
+ #ifdef Safe_Close
+  PSDevice	        pDevice = (PSDevice)dev->priv;
+  if (!(pDevice->flags & DEVICE_FLAGS_OPENED))
+        return -EINVAL;
+#endif
+ */
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRANGE \n");
+	if (wrq->pointer) {
+		wrq->length = sizeof(struct iw_range);
+		memset(range, 0, sizeof(struct iw_range));
+		range->min_nwid = 0x0000;
+		range->max_nwid = 0x0000;
+		range->num_channels = 14;
+		// Should be based on cap_rid.country to give only
+		//  what the current card support
+		k = 0;
+		for(i = 0; i < 14; i++) {
+			range->freq[k].i = i + 1; // List index
+			range->freq[k].m = frequency_list[i] * 100000;
+			range->freq[k++].e = 1;	// Values in table in MHz -> * 10^5 * 10
+		}
+		range->num_frequency = k;
+		// Hum... Should put the right values there
+	     #ifdef Calcu_LinkQual
+                 range->max_qual.qual = 100;
+	     #else
+		range->max_qual.qual = 255;
+	     #endif
+		range->max_qual.level = 0;
+		range->max_qual.noise = 0;
+		range->sensitivity = 255;
+
+		for(i = 0 ; i < 13 ; i++) {
+			range->bitrate[i] = abySupportedRates[i] * 500000;
+			if(range->bitrate[i] == 0)
+				break;
+		}
+		range->num_bitrates = i;
+
+		// Set an indication of the max TCP throughput
+		// in bit/s that we can expect using this interface.
+		//  May be use for QoS stuff... Jean II
+		if(i > 2)
+			range->throughput = 5 * 1000 * 1000;
+		else
+			range->throughput = 1.5 * 1000 * 1000;
+
+		range->min_rts = 0;
+		range->max_rts = 2312;
+		range->min_frag = 256;
+		range->max_frag = 2312;
+
+
+	    // the encoding capabilities
+	    range->num_encoding_sizes = 3;
+	    // 64(40) bits WEP
+	    range->encoding_size[0] = 5;
+	    // 128(104) bits WEP
+	    range->encoding_size[1] = 13;
+	    // 256 bits for WPA-PSK
+	    range->encoding_size[2] = 32;
+	    // 4 keys are allowed
+	    range->max_encoding_tokens = 4;
+
+#if WIRELESS_EXT > 17
+	    range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
+		    IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
+#endif
+
+#if WIRELESS_EXT > 9
+		range->min_pmp = 0;
+		range->max_pmp = 1000000;// 1 secs
+		range->min_pmt = 0;
+		range->max_pmt = 1000000;// 1 secs
+		range->pmp_flags = IW_POWER_PERIOD;
+		range->pmt_flags = IW_POWER_TIMEOUT;
+		range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
+
+		// Transmit Power - values are in mW
+
+        range->txpower[0] = 100;
+		range->num_txpower = 1;
+		range->txpower_capa = IW_TXPOW_MWATT;
+#endif // WIRELESS_EXT > 9
+#if WIRELESS_EXT > 10
+		range->we_version_source = SUPPORTED_WIRELESS_EXT;
+		range->we_version_compiled = WIRELESS_EXT;
+		range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
+		range->retry_flags = IW_RETRY_LIMIT;
+		range->r_time_flags = IW_RETRY_LIFETIME;
+		range->min_retry = 1;
+		range->max_retry = 65535;
+		range->min_r_time = 1024;
+		range->max_r_time = 65535 * 1024;
+#endif // WIRELESS_EXT > 10
+#if WIRELESS_EXT > 11
+		// Experimental measurements - boundary 11/5.5 Mb/s
+		// Note : with or without the (local->rssi), results
+		//  are somewhat different. - Jean II
+		range->avg_qual.qual = 6;
+		range->avg_qual.level = 176;	// -80 dBm
+		range->avg_qual.noise = 0;
+#endif // WIRELESS_EXT > 11
+	}
+
+
+	return 0;
+}
+
+
+/*
+ * Wireless Handler : set ap mac address
+ */
+
+int iwctl_siwap(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct sockaddr *wrq,
+             char *extra)
+{
+	PSDevice	        pDevice = (PSDevice)dev->priv;
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+    int rc = 0;
+    BYTE                 ZeroBSSID[WLAN_BSSID_LEN]={0x00,0x00,0x00,0x00,0x00,0x00};
+
+   PRINT_K(" SIOCSIWAP \n");
+
+	if (wrq->sa_family != ARPHRD_ETHER)
+		rc = -EINVAL;
+	else {
+		memset(pMgmt->abyDesireBSSID, 0xFF, 6);
+		memcpy(pMgmt->abyDesireBSSID, wrq->sa_data, 6);
+
+	//mike :add
+	 if ((IS_BROADCAST_ADDRESS(pMgmt->abyDesireBSSID)) ||
+	     (memcmp(pMgmt->abyDesireBSSID, ZeroBSSID, 6) == 0)){
+	      PRINT_K("SIOCSIWAP:invalid desired BSSID return!\n");
+               return rc;
+         }
+       //mike add: if desired AP is hidden ssid(there are two same BSSID in list),
+       //                  then ignore,because you don't known which one to be connect with??
+       	{
+           UINT            ii , uSameBssidNum=0;
+                  for (ii = 0; ii < MAX_BSS_NUM; ii++) {
+                     if (pMgmt->sBSSList[ii].bActive &&
+                        IS_ETH_ADDRESS_EQUAL(pMgmt->sBSSList[ii].abyBSSID,pMgmt->abyDesireBSSID)) {
+                        uSameBssidNum++;
+                     }
+                  }
+	     if(uSameBssidNum >= 2) {  //hit: desired AP is in hidden ssid mode!!!
+                 PRINT_K("SIOCSIWAP:ignore for desired AP in hidden mode\n");
+	        return rc;
+	     }
+       	}
+
+        if (pDevice->flags & DEVICE_FLAGS_OPENED) {
+		    pDevice->bCommit = TRUE;
+   		}
+	}
+	return rc;
+}
+
+/*
+ * Wireless Handler : get ap mac address
+ */
+
+int iwctl_giwap(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct sockaddr *wrq,
+             char *extra)
+{
+	PSDevice	        pDevice = (PSDevice)dev->priv;
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAP \n");
+
+    memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6);
+
+//20080123-02,<Modify> by Einsn Liu
+ if ((pDevice->bLinkPass == FALSE) && (pMgmt->eCurrMode != WMAC_MODE_ESS_AP))
+ //   if ((pDevice->bLinkPass == FALSE) && (pMgmt->eCurrMode == WMAC_MODE_ESS_STA))
+        memset(wrq->sa_data, 0, 6);
+
+    if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
+        memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6);
+    }
+
+	wrq->sa_family = ARPHRD_ETHER;
+
+	return 0;
+
+}
+
+
+/*
+ * Wireless Handler : get ap list
+ */
+
+int iwctl_giwaplist(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_point *wrq,
+             char *extra)
+{
+	int ii,jj, rc = 0;
+	struct sockaddr sock[IW_MAX_AP];
+	struct iw_quality qual[IW_MAX_AP];
+	PSDevice	        pDevice = (PSDevice)dev->priv;
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAPLIST \n");
+	// Only super-user can see AP list
+
+	if (!capable(CAP_NET_ADMIN)) {
+		rc = -EPERM;
+		return rc;
+	}
+
+	if (wrq->pointer) {
+
+		PKnownBSS pBSS = &(pMgmt->sBSSList[0]);
+
+		for (ii = 0, jj= 0; ii < MAX_BSS_NUM; ii++) {
+		    pBSS = &(pMgmt->sBSSList[ii]);
+            if (!pBSS->bActive)
+                continue;
+            if ( jj >= IW_MAX_AP)
+                break;
+			memcpy(sock[jj].sa_data, pBSS->abyBSSID, 6);
+			sock[jj].sa_family = ARPHRD_ETHER;
+			qual[jj].level = pBSS->uRSSI;
+			qual[jj].qual = qual[jj].noise = 0;
+			qual[jj].updated = 2;
+			jj++;
+		}
+
+		wrq->flags = 1; // Should be define'd
+		wrq->length = jj;
+		memcpy(extra, sock, sizeof(struct sockaddr)*jj);
+		memcpy(extra + sizeof(struct sockaddr)*jj, qual, sizeof(struct iw_quality)*jj);
+	}
+
+	return rc;
+}
+
+
+/*
+ * Wireless Handler : set essid
+ */
+
+int iwctl_siwessid(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_point *wrq,
+             char *extra)
+{
+	PSDevice	        pDevice = (PSDevice)dev->priv;
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+    PWLAN_IE_SSID       pItemSSID;
+
+//2008-0920-01<Add>by MikeLiu
+  if (!(pDevice->flags & DEVICE_FLAGS_OPENED))
+        return -EINVAL;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWESSID :\n");
+
+         pDevice->fWPA_Authened = FALSE;
+	// Check if we asked for `any'
+	if(wrq->flags == 0) {
+		// Just send an empty SSID list
+		memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+                  memset(pMgmt->abyDesireBSSID, 0xFF,6);
+	    PRINT_K("set essid to 'any' \n");
+           #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+             //Unknown desired AP,so here need not associate??
+                  return 0;
+            #endif
+	} else {
+		// Set the SSID
+		memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+        pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
+        pItemSSID->byElementID = WLAN_EID_SSID;
+
+		memcpy(pItemSSID->abySSID, extra, wrq->length);
+         if (pItemSSID->abySSID[wrq->length - 1] == '\0') {
+           if(wrq->length>0)
+		pItemSSID->len = wrq->length - 1;
+         }
+	else
+	  pItemSSID->len = wrq->length;
+	PRINT_K("set essid to %s \n",pItemSSID->abySSID);
+
+     //mike:need clear desiredBSSID
+     if(pItemSSID->len==0) {
+        memset(pMgmt->abyDesireBSSID, 0xFF,6);
+        return 0;
+     }
+
+#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+ //Wext wil order another command of siwap to link with desired AP,
+ //so here need not associate??
+  if(pDevice->bWPASuppWextEnabled == TRUE)  {
+        /*******search if  in hidden ssid mode ****/
+        {
+           PKnownBSS       pCurr = NULL;
+           BYTE                   abyTmpDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
+	  UINT            ii , uSameBssidNum=0;
+
+	  memset(abyTmpDesireSSID,0,sizeof(abyTmpDesireSSID));
+	  memcpy(abyTmpDesireSSID,pMgmt->abyDesireSSID,sizeof(abyTmpDesireSSID));
+            pCurr = BSSpSearchBSSList(pDevice,
+                                      NULL,
+                                      abyTmpDesireSSID,
+                                      pDevice->eConfigPHYMode
+                                      );
+
+            if (pCurr == NULL){
+               PRINT_K("SIOCSIWESSID:hidden ssid site survey before associate.......\n");
+	      vResetCommandTimer((HANDLE) pDevice);
+	      pMgmt->eScanType = WMAC_SCAN_ACTIVE;
+               bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID);
+	      bScheduleCommand((HANDLE) pDevice, WLAN_CMD_SSID, pMgmt->abyDesireSSID);
+          }
+	 else {  //mike:to find out if that desired SSID is a hidden-ssid AP ,
+                     //         by means of judging if there are two same BSSID exist in list ?
+                  for (ii = 0; ii < MAX_BSS_NUM; ii++) {
+                     if (pMgmt->sBSSList[ii].bActive &&
+                        IS_ETH_ADDRESS_EQUAL(pMgmt->sBSSList[ii].abyBSSID, pCurr->abyBSSID)) {
+                        uSameBssidNum++;
+                     }
+                  }
+	     if(uSameBssidNum >= 2) {  //hit: desired AP is in hidden ssid mode!!!
+                 PRINT_K("SIOCSIWESSID:hidden ssid directly associate.......\n");
+	        vResetCommandTimer((HANDLE) pDevice);
+	        pMgmt->eScanType = WMAC_SCAN_PASSIVE;          //this scan type,you'll submit scan result!
+	        bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID);
+	        bScheduleCommand((HANDLE) pDevice, WLAN_CMD_SSID, pMgmt->abyDesireSSID);
+	     }
+	 }
+        }
+     return 0;
+  }
+	     #endif
+
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set essid = %s \n", pItemSSID->abySSID);
+	}
+
+    if (pDevice->flags & DEVICE_FLAGS_OPENED) {
+	    pDevice->bCommit = TRUE;
+	}
+
+
+	return 0;
+}
+
+
+/*
+ * Wireless Handler : get essid
+ */
+
+int iwctl_giwessid(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_point *wrq,
+             char *extra)
+{
+
+	PSDevice	        pDevice = (PSDevice)dev->priv;
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+	PWLAN_IE_SSID       pItemSSID;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWESSID \n");
+
+	// Note : if wrq->u.data.flags != 0, we should
+	// get the relevant SSID from the SSID list...
+
+	// Get the current SSID
+    pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
+	//pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
+	memcpy(extra, pItemSSID->abySSID , pItemSSID->len);
+	extra[pItemSSID->len] = '\0';
+        //2008-0409-03, <Add> by Einsn Liu
+        #if WIRELESS_EXT < 21
+	wrq->length = pItemSSID->len + 1;
+        #else
+        wrq->length = pItemSSID->len;
+        #endif
+	wrq->flags = 1; // active
+
+
+	return 0;
+}
+
+/*
+ * Wireless Handler : set data rate
+ */
+
+int iwctl_siwrate(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_param *wrq,
+             char *extra)
+{
+	PSDevice	        pDevice = (PSDevice)dev->priv;
+    int rc = 0;
+	u8	brate = 0;
+	int	i;
+	BYTE abySupportedRates[13]= {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90};
+
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRATE \n");
+    if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
+        rc = -EINVAL;
+        return rc;
+    }
+
+	// First : get a valid bit rate value
+
+	// Which type of value
+	if((wrq->value < 13) &&
+	   (wrq->value >= 0)) {
+		// Setting by rate index
+		// Find value in the magic rate table
+		brate = wrq->value;
+	} else {
+		// Setting by frequency value
+		u8	normvalue = (u8) (wrq->value/500000);
+
+		// Check if rate is valid
+		for(i = 0 ; i < 13 ; i++) {
+			if(normvalue == abySupportedRates[i]) {
+				brate = i;
+				break;
+			}
+		}
+	}
+	// -1 designed the max rate (mostly auto mode)
+	if(wrq->value == -1) {
+		// Get the highest available rate
+		for(i = 0 ; i < 13 ; i++) {
+			if(abySupportedRates[i] == 0)
+				break;
+		}
+		if(i != 0)
+			brate = i - 1;
+
+	}
+	// Check that it is valid
+	// brate is index of abySupportedRates[]
+	if(brate > 13 ) {
+		rc = -EINVAL;
+		return rc;
+	}
+
+	// Now, check if we want a fixed or auto value
+	if(wrq->fixed != 0) {
+		// Fixed mode
+		// One rate, fixed
+		pDevice->bFixRate = TRUE;
+        if ((pDevice->byBBType == BB_TYPE_11B)&& (brate > 3)) {
+            pDevice->uConnectionRate = 3;
+        }
+        else {
+            pDevice->uConnectionRate = brate;
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Fixed to Rate %d \n", pDevice->uConnectionRate);
+        }
+
+	}
+	else {
+        pDevice->bFixRate = FALSE;
+        pDevice->uConnectionRate = 13;
+    }
+
+	return rc;
+}
+
+/*
+ * Wireless Handler : get data rate
+ */
+
+int iwctl_giwrate(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_param *wrq,
+             char *extra)
+{
+	PSDevice	        pDevice = (PSDevice)dev->priv;
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRATE \n");
+    {
+        BYTE abySupportedRates[13]= {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90};
+	    int brate = 0;
+		if (pDevice->uConnectionRate < 13) {
+	        brate = abySupportedRates[pDevice->uConnectionRate];
+	    }else {
+            if (pDevice->byBBType == BB_TYPE_11B)
+	            brate = 0x16;
+            if (pDevice->byBBType == BB_TYPE_11G)
+	            brate = 0x6C;
+            if (pDevice->byBBType == BB_TYPE_11A)
+	            brate = 0x6C;
+	    }
+
+	    if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
+            if (pDevice->byBBType == BB_TYPE_11B)
+	            brate = 0x16;
+            if (pDevice->byBBType == BB_TYPE_11G)
+	            brate = 0x6C;
+            if (pDevice->byBBType == BB_TYPE_11A)
+	            brate = 0x6C;
+	    }
+    		if (pDevice->uConnectionRate == 13)
+                brate = abySupportedRates[pDevice->wCurrentRate];
+	    wrq->value = brate * 500000;
+	    // If more than one rate, set auto
+	    if (pDevice->bFixRate == TRUE)
+	        wrq->fixed = TRUE;
+    }
+
+
+	return 0;
+}
+
+
+
+/*
+ * Wireless Handler : set rts threshold
+ */
+
+int iwctl_siwrts(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_param *wrq,
+             char *extra)
+{
+	PSDevice	        pDevice = (PSDevice)dev->priv;
+	int rc = 0;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRTS \n");
+
+	{
+	    int rthr = wrq->value;
+	    if(wrq->disabled)
+			rthr = 2312;
+	    if((rthr < 0) || (rthr > 2312)) {
+			rc = -EINVAL;
+    	}else {
+		    pDevice->wRTSThreshold = rthr;
+	    }
+    }
+
+	return 0;
+}
+
+/*
+ * Wireless Handler : get rts
+ */
+
+int iwctl_giwrts(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_param *wrq,
+             char *extra)
+{
+	PSDevice	        pDevice = (PSDevice)dev->priv;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRTS \n");
+	wrq->value = pDevice->wRTSThreshold;
+	wrq->disabled = (wrq->value >= 2312);
+	wrq->fixed = 1;
+
+	return 0;
+}
+
+/*
+ * Wireless Handler : set fragment threshold
+ */
+
+int iwctl_siwfrag(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_param *wrq,
+             char *extra)
+{
+    PSDevice	        pDevice = (PSDevice)dev->priv;
+    int rc = 0;
+    int fthr = wrq->value;
+
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFRAG \n");
+
+
+    if (wrq->disabled)
+		fthr = 2312;
+    if((fthr < 256) || (fthr > 2312)) {
+		rc = -EINVAL;
+    }else {
+		 fthr &= ~0x1;	// Get an even value
+	     pDevice->wFragmentationThreshold = (u16)fthr;
+    }
+
+	return rc;
+}
+
+/*
+ * Wireless Handler : get fragment threshold
+ */
+
+int iwctl_giwfrag(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_param *wrq,
+             char *extra)
+{
+    PSDevice	        pDevice = (PSDevice)dev->priv;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFRAG \n");
+	wrq->value = pDevice->wFragmentationThreshold;
+	wrq->disabled = (wrq->value >= 2312);
+	wrq->fixed = 1;
+
+	return 0;
+}
+
+
+
+/*
+ * Wireless Handler : set retry threshold
+ */
+int iwctl_siwretry(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_param *wrq,
+             char *extra)
+{
+    PSDevice	        pDevice = (PSDevice)dev->priv;
+    int rc = 0;
+
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRETRY \n");
+
+	if (wrq->disabled) {
+		rc = -EINVAL;
+		return rc;
+	}
+
+	if (wrq->flags & IW_RETRY_LIMIT) {
+		if(wrq->flags & IW_RETRY_MAX)
+			pDevice->byLongRetryLimit = wrq->value;
+		else if (wrq->flags & IW_RETRY_MIN)
+			pDevice->byShortRetryLimit = wrq->value;
+		else {
+			// No modifier : set both
+			pDevice->byShortRetryLimit = wrq->value;
+			pDevice->byLongRetryLimit = wrq->value;
+		}
+	}
+	if (wrq->flags & IW_RETRY_LIFETIME) {
+		pDevice->wMaxTransmitMSDULifetime = wrq->value;
+	}
+
+
+	return rc;
+}
+
+/*
+ * Wireless Handler : get retry threshold
+ */
+int iwctl_giwretry(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_param *wrq,
+             char *extra)
+{
+    PSDevice	        pDevice = (PSDevice)dev->priv;
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRETRY \n");
+	wrq->disabled = 0;      // Can't be disabled
+
+	// Note : by default, display the min retry number
+	if((wrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
+		wrq->flags = IW_RETRY_LIFETIME;
+		wrq->value = (int)pDevice->wMaxTransmitMSDULifetime; //ms
+	} else if((wrq->flags & IW_RETRY_MAX)) {
+		wrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
+		wrq->value = (int)pDevice->byLongRetryLimit;
+	} else {
+		wrq->flags = IW_RETRY_LIMIT;
+		wrq->value = (int)pDevice->byShortRetryLimit;
+		if((int)pDevice->byShortRetryLimit != (int)pDevice->byLongRetryLimit)
+			wrq->flags |= IW_RETRY_MIN;
+	}
+
+
+	return 0;
+}
+
+
+/*
+ * Wireless Handler : set encode mode
+ */
+int iwctl_siwencode(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_point *wrq,
+             char *extra)
+{
+    PSDevice	        pDevice = (PSDevice)dev->priv;
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+	DWORD dwKeyIndex = (DWORD)(wrq->flags & IW_ENCODE_INDEX);
+	int ii,uu, rc = 0;
+	int index = (wrq->flags & IW_ENCODE_INDEX);
+
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODE \n");
+
+	// Check the size of the key
+	if (wrq->length > WLAN_WEP232_KEYLEN) {
+		rc = -EINVAL;
+        return rc;
+	}
+
+	if (dwKeyIndex > WLAN_WEP_NKEYS) {
+		rc = -EINVAL;
+        return rc;
+    }
+
+    if (dwKeyIndex > 0)
+		dwKeyIndex--;
+
+	// Send the key to the card
+	if (wrq->length > 0) {
+
+        if (wrq->length ==  WLAN_WEP232_KEYLEN) {
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 232 bit wep key\n");
+        }
+        else if (wrq->length ==  WLAN_WEP104_KEYLEN) {
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 104 bit wep key\n");
+        }
+        else if (wrq->length == WLAN_WEP40_KEYLEN) {
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 40 bit wep key, index= %d\n", (int)dwKeyIndex);
+        }
+        memset(pDevice->abyKey, 0, WLAN_WEP232_KEYLEN);
+        memcpy(pDevice->abyKey, extra, wrq->length);
+
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"abyKey: ");
+        for (ii = 0; ii < wrq->length; ii++) {
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pDevice->abyKey[ii]);
+        }
+
+        if (pDevice->flags & DEVICE_FLAGS_OPENED) {
+            spin_lock_irq(&pDevice->lock);
+            KeybSetDefaultKey(  pDevice,
+                                &(pDevice->sKey),
+                                dwKeyIndex | (1 << 31),
+                                wrq->length,
+                                NULL,
+                                pDevice->abyKey,
+                                KEY_CTL_WEP
+                              );
+            spin_unlock_irq(&pDevice->lock);
+        }
+        pDevice->byKeyIndex = (BYTE)dwKeyIndex;
+        pDevice->uKeyLength = wrq->length;
+        pDevice->bTransmitKey = TRUE;
+        pDevice->bEncryptionEnable = TRUE;
+        pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
+
+		// Do we want to just set the transmit key index ?
+		if ( index < 4 ) {
+		    pDevice->byKeyIndex = index;
+		}
+		else if(!wrq->flags & IW_ENCODE_MODE) {
+				rc = -EINVAL;
+				return rc;
+	    }
+	}
+	// Read the flags
+	if(wrq->flags & IW_ENCODE_DISABLED){
+
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable WEP function\n");
+		pMgmt->bShareKeyAlgorithm = FALSE;
+        pDevice->bEncryptionEnable = FALSE;
+        pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
+        if (pDevice->flags & DEVICE_FLAGS_OPENED) {
+            spin_lock_irq(&pDevice->lock);
+            for(uu=0;uu<MAX_KEY_TABLE;uu++)
+                MACvDisableKeyEntry(pDevice,uu);
+            spin_unlock_irq(&pDevice->lock);
+        }
+	}
+	if(wrq->flags & IW_ENCODE_RESTRICTED) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable WEP & ShareKey System\n");
+		pMgmt->bShareKeyAlgorithm = TRUE;
+	}
+	if(wrq->flags & IW_ENCODE_OPEN) {
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable WEP & Open System\n");
+		pMgmt->bShareKeyAlgorithm = FALSE;
+	}
+
+#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+	   memset(pMgmt->abyDesireBSSID, 0xFF,6);
+#endif
+
+	return rc;
+}
+
+/*
+ * Wireless Handler : get encode mode
+ */
+//2008-0409-06, <Mark> by Einsn Liu
+ /*
+int iwctl_giwencode(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_point *wrq,
+             char *extra)
+{
+    PSDevice	        pDevice = (PSDevice)dev->priv;
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+    int rc = 0;
+    char abyKey[WLAN_WEP232_KEYLEN];
+	UINT index = (UINT)(wrq->flags & IW_ENCODE_INDEX);
+	PSKeyItem   pKey = NULL;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODE\n");
+
+
+	memset(abyKey, 0, sizeof(abyKey));
+	// Check encryption mode
+	wrq->flags = IW_ENCODE_NOKEY;
+	// Is WEP enabled ???
+	if (pDevice->bEncryptionEnable)
+		wrq->flags |=  IW_ENCODE_ENABLED;
+    else
+		wrq->flags |=  IW_ENCODE_DISABLED;
+
+    if (pMgmt->bShareKeyAlgorithm)
+		wrq->flags |=  IW_ENCODE_RESTRICTED;
+	else
+		wrq->flags |=  IW_ENCODE_OPEN;
+
+	if (KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, (BYTE)index , &pKey)){
+        wrq->length = pKey->uKeyLength;
+        memcpy(abyKey, pKey->abyKey,  pKey->uKeyLength);
+    }
+    else {
+        rc = -EINVAL;
+        return rc;
+    }
+	wrq->flags |= index;
+	// Copy the key to the user buffer
+	memcpy(extra,  abyKey, WLAN_WEP232_KEYLEN);
+	return 0;
+}
+*/
+
+//2008-0409-06, <Add> by Einsn Liu
+
+int iwctl_giwencode(struct net_device *dev,
+			struct iw_request_info *info,
+			struct iw_point *wrq,
+			char *extra)
+{
+	PSDevice			pDevice = (PSDevice)dev->priv;
+	PSMgmtObject		pMgmt = &(pDevice->sMgmtObj);
+	char abyKey[WLAN_WEP232_KEYLEN];
+
+	UINT index = (UINT)(wrq->flags & IW_ENCODE_INDEX);
+	PSKeyItem	pKey = NULL;
+
+	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODE\n");
+
+	if (index > WLAN_WEP_NKEYS) {
+		return	-EINVAL;
+	}
+	if(index<1){//get default key
+		if(pDevice->byKeyIndex<WLAN_WEP_NKEYS){
+			index=pDevice->byKeyIndex;
+         	} else
+                      index=0;
+	}else
+             index--;
+
+	memset(abyKey, 0, WLAN_WEP232_KEYLEN);
+	// Check encryption mode
+	wrq->flags = IW_ENCODE_NOKEY;
+	// Is WEP enabled ???
+	if (pDevice->bEncryptionEnable)
+		wrq->flags |=  IW_ENCODE_ENABLED;
+	else
+		wrq->flags |=  IW_ENCODE_DISABLED;
+
+	if (pMgmt->bShareKeyAlgorithm)
+		wrq->flags |=  IW_ENCODE_RESTRICTED;
+	else
+		wrq->flags |=  IW_ENCODE_OPEN;
+		wrq->length=0;
+
+	if((index==0)&&(pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled||
+		pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled)){//get wpa pairwise  key
+			if (KeybGetKey(&(pDevice->sKey),pMgmt->abyCurrBSSID, 0xffffffff, &pKey)){
+			   wrq->length = pKey->uKeyLength;
+				  memcpy(abyKey, pKey->abyKey,	pKey->uKeyLength);
+				  memcpy(extra,  abyKey, WLAN_WEP232_KEYLEN);
+			   }
+	}else if (KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, (BYTE)index , &pKey)){
+			wrq->length = pKey->uKeyLength;
+			memcpy(abyKey, pKey->abyKey,  pKey->uKeyLength);
+		memcpy(extra,  abyKey, WLAN_WEP232_KEYLEN);
+	}
+
+	wrq->flags |= index+1;
+
+	return 0;
+}
+
+
+/*
+ * Wireless Handler : set power mode
+ */
+int iwctl_siwpower(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_param *wrq,
+             char *extra)
+{
+    PSDevice            pDevice = (PSDevice)dev->priv;
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+    int rc = 0;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER \n");
+
+    if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
+		 rc = -EINVAL;
+		 return rc;
+	}
+
+	if (wrq->disabled) {
+		pDevice->ePSMode = WMAC_POWER_CAM;
+		PSvDisablePowerSaving(pDevice);
+		return rc;
+	}
+	if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
+         pDevice->ePSMode = WMAC_POWER_FAST;
+         PSvEnablePowerSaving((HANDLE)pDevice, pMgmt->wListenInterval);
+
+	} else if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) {
+	     pDevice->ePSMode = WMAC_POWER_FAST;
+         PSvEnablePowerSaving((HANDLE)pDevice, pMgmt->wListenInterval);
+	}
+	switch (wrq->flags & IW_POWER_MODE) {
+	case IW_POWER_UNICAST_R:
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_UNICAST_R \n");
+		rc = -EINVAL;
+		break;
+	case IW_POWER_ALL_R:
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ALL_R \n");
+		rc = -EINVAL;
+	case IW_POWER_ON:
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ON \n");
+		break;
+	default:
+		rc = -EINVAL;
+	}
+
+	return rc;
+}
+
+/*
+ * Wireless Handler : get power mode
+ */
+int iwctl_giwpower(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_param *wrq,
+             char *extra)
+{
+    PSDevice            pDevice = (PSDevice)dev->priv;
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+    int mode = pDevice->ePSMode;
+
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPOWER \n");
+
+
+	if ((wrq->disabled = (mode == WMAC_POWER_CAM)))
+	    return 0;
+
+	if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
+		wrq->value = (int)((pMgmt->wListenInterval * pMgmt->wCurrBeaconPeriod) << 10);
+		wrq->flags = IW_POWER_TIMEOUT;
+	} else {
+		wrq->value = (int)((pMgmt->wListenInterval * pMgmt->wCurrBeaconPeriod) << 10);
+		wrq->flags = IW_POWER_PERIOD;
+	}
+	wrq->flags |= IW_POWER_ALL_R;
+
+	return 0;
+}
+
+
+/*
+ * Wireless Handler : get Sensitivity
+ */
+int iwctl_giwsens(struct net_device *dev,
+			 struct iw_request_info *info,
+			 struct iw_param *wrq,
+			 char *extra)
+{
+    PSDevice	        pDevice = (PSDevice)dev->priv;
+    long ldBm;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSENS \n");
+    if (pDevice->bLinkPass == TRUE) {
+        RFvRSSITodBm(pDevice, (BYTE)(pDevice->uCurrRSSI), &ldBm);
+	    wrq->value = ldBm;
+	}
+	else {
+	    wrq->value = 0;
+    };
+	wrq->disabled = (wrq->value == 0);
+	wrq->fixed = 1;
+
+
+	return 0;
+}
+
+//2008-0409-07, <Add> by Einsn Liu
+#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+
+int iwctl_siwauth(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_param *wrq,
+			  char *extra)
+{
+	PSDevice			pDevice = (PSDevice)dev->priv;
+	PSMgmtObject	pMgmt = &(pDevice->sMgmtObj);
+	int ret=0;
+	static int wpa_version=0;  //must be static to save the last value,einsn liu
+	static int pairwise=0;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH \n");
+	switch (wrq->flags & IW_AUTH_INDEX) {
+	case IW_AUTH_WPA_VERSION:
+		wpa_version = wrq->value;
+		if(wrq->value == IW_AUTH_WPA_VERSION_DISABLED) {
+		       PRINT_K("iwctl_siwauth:set WPADEV to disable at 1??????\n");
+			//pDevice->bWPADEVUp = FALSE;
+		}
+		else if(wrq->value == IW_AUTH_WPA_VERSION_WPA) {
+                          PRINT_K("iwctl_siwauth:set WPADEV to WPA1******\n");
+		}
+		else {
+                          PRINT_K("iwctl_siwauth:set WPADEV to WPA2******\n");
+		}
+		//pDevice->bWPASuppWextEnabled =TRUE;
+		break;
+	case IW_AUTH_CIPHER_PAIRWISE:
+		pairwise = wrq->value;
+                   PRINT_K("iwctl_siwauth:set pairwise=%d\n",pairwise);
+		if(pairwise == IW_AUTH_CIPHER_CCMP){
+			pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
+		}else if(pairwise == IW_AUTH_CIPHER_TKIP){
+			pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
+		}else if(pairwise == IW_AUTH_CIPHER_WEP40||pairwise == IW_AUTH_CIPHER_WEP104){
+			pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
+		}else if(pairwise == IW_AUTH_CIPHER_NONE){
+			//do nothing,einsn liu
+		}else pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
+
+		break;
+	case IW_AUTH_CIPHER_GROUP:
+		 PRINT_K("iwctl_siwauth:set GROUP=%d\n",wrq->value);
+		if(wpa_version == IW_AUTH_WPA_VERSION_DISABLED)
+			break;
+		if(pairwise == IW_AUTH_CIPHER_NONE){
+			if(wrq->value == IW_AUTH_CIPHER_CCMP){
+				pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
+			}else {
+				pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
+			}
+		}
+		break;
+	case IW_AUTH_KEY_MGMT:
+                    PRINT_K("iwctl_siwauth(wpa_version=%d):set KEY_MGMT=%d\n",wpa_version,wrq->value);
+		if(wpa_version == IW_AUTH_WPA_VERSION_WPA2){
+			if(wrq->value == IW_AUTH_KEY_MGMT_PSK)
+				pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK;
+			else pMgmt->eAuthenMode = WMAC_AUTH_WPA2;
+		}else if(wpa_version == IW_AUTH_WPA_VERSION_WPA){
+			if(wrq->value == 0){
+				pMgmt->eAuthenMode = WMAC_AUTH_WPANONE;
+			}else if(wrq->value == IW_AUTH_KEY_MGMT_PSK)
+				pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK;
+			else pMgmt->eAuthenMode = WMAC_AUTH_WPA;
+		}
+
+		break;
+	case IW_AUTH_TKIP_COUNTERMEASURES:
+		break;		/* FIXME */
+	case IW_AUTH_DROP_UNENCRYPTED:
+		break;
+	case IW_AUTH_80211_AUTH_ALG:
+		 PRINT_K("iwctl_siwauth:set AUTH_ALG=%d\n",wrq->value);
+		if(wrq->value==IW_AUTH_ALG_OPEN_SYSTEM){
+			pMgmt->bShareKeyAlgorithm=FALSE;
+		}else if(wrq->value==IW_AUTH_ALG_SHARED_KEY){
+			pMgmt->bShareKeyAlgorithm=TRUE;
+		}
+		break;
+	case IW_AUTH_WPA_ENABLED:
+		//pDevice->bWPADEVUp = !! wrq->value;
+		//if(pDevice->bWPADEVUp==TRUE)
+		  // printk("iwctl_siwauth:set WPADEV to enable sucessful*******\n");
+		//else
+		 //  printk("iwctl_siwauth:set WPADEV to enable fail?????\n");
+		break;
+	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+		break;
+	case IW_AUTH_ROAMING_CONTROL:
+		ret = -EOPNOTSUPP;
+		break;
+	case IW_AUTH_PRIVACY_INVOKED:
+		pDevice->bEncryptionEnable = !!wrq->value;
+		if(pDevice->bEncryptionEnable == FALSE){
+			wpa_version = 0;
+			pairwise = 0;
+			pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
+			pMgmt->bShareKeyAlgorithm = FALSE;
+			pMgmt->eAuthenMode = WMAC_AUTH_OPEN;
+			//pDevice->bWPADEVUp = FALSE;
+			 PRINT_K("iwctl_siwauth:set WPADEV to disaable at 2?????\n");
+		}
+
+		break;
+	default:
+		ret = -EOPNOTSUPP;
+		break;
+	}
+/*
+	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_version = %d\n",wpa_version);
+	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pairwise = %d\n",pairwise);
+	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->eEncryptionStatus = %d\n",pDevice->eEncryptionStatus);
+	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pMgmt->eAuthenMode  = %d\n",pMgmt->eAuthenMode);
+	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pMgmt->bShareKeyAlgorithm = %s\n",pMgmt->bShareKeyAlgorithm?"TRUE":"FALSE");
+	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->bEncryptionEnable = %s\n",pDevice->bEncryptionEnable?"TRUE":"FALSE");
+	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->bWPADEVUp = %s\n",pDevice->bWPADEVUp?"TRUE":"FALSE");
+*/
+   return ret;
+}
+
+
+int iwctl_giwauth(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_param *wrq,
+			  char *extra)
+{
+	return -EOPNOTSUPP;
+}
+
+
+
+int iwctl_siwgenie(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_point *wrq,
+			  char *extra)
+{
+	PSDevice			pDevice = (PSDevice)dev->priv;
+	PSMgmtObject	pMgmt = &(pDevice->sMgmtObj);
+	int ret=0;
+
+	if(wrq->length){
+		if ((wrq->length < 2) || (extra[1]+2 != wrq->length)) {
+			ret = -EINVAL;
+			goto out;
+		}
+		if(wrq->length > MAX_WPA_IE_LEN){
+			ret = -ENOMEM;
+			goto out;
+		}
+		memset(pMgmt->abyWPAIE, 0, MAX_WPA_IE_LEN);
+		if(copy_from_user(pMgmt->abyWPAIE, extra, wrq->length)){
+			ret = -EFAULT;
+			goto out;
+		}
+		pMgmt->wWPAIELen = wrq->length;
+	}else {
+		memset(pMgmt->abyWPAIE, 0, MAX_WPA_IE_LEN);
+		pMgmt->wWPAIELen = 0;
+	}
+
+	out://not completely ...not necessary in wpa_supplicant 0.5.8
+	return 0;
+}
+
+int iwctl_giwgenie(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_point *wrq,
+			  char *extra)
+{
+	PSDevice			pDevice = (PSDevice)dev->priv;
+	PSMgmtObject	pMgmt = &(pDevice->sMgmtObj);
+	int ret=0;
+	int space = wrq->length;
+
+	wrq->length = 0;
+	if(pMgmt->wWPAIELen > 0){
+		wrq->length = pMgmt->wWPAIELen;
+		if(pMgmt->wWPAIELen <= space){
+			if(copy_to_user(extra, pMgmt->abyWPAIE, pMgmt->wWPAIELen)){
+				ret = -EFAULT;
+			}
+		}else
+			ret = -E2BIG;
+	}
+
+	return ret;
+}
+
+
+int iwctl_siwencodeext(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_point *wrq,
+             char *extra)
+{
+    PSDevice	        pDevice = (PSDevice)dev->priv;
+    PSMgmtObject	pMgmt = &(pDevice->sMgmtObj);
+	struct iw_encode_ext *ext = (struct iw_encode_ext*)extra;
+    struct viawget_wpa_param *param=NULL;
+//original member
+    wpa_alg alg_name;
+    u8  addr[6];
+    int key_idx, set_tx=0;
+    u8  seq[IW_ENCODE_SEQ_MAX_SIZE];
+    u8 key[64];
+    size_t seq_len=0,key_len=0;
+//
+   // int ii;
+    u8 *buf;
+    size_t blen;
+    u8 key_array[64];
+    int ret=0;
+
+PRINT_K("SIOCSIWENCODEEXT...... \n");
+
+blen = sizeof(*param);
+buf = kmalloc((int)blen, (int)GFP_KERNEL);
+if (buf == NULL)
+    return -ENOMEM;
+memset(buf, 0, blen);
+param = (struct viawget_wpa_param *) buf;
+
+//recover alg_name
+switch (ext->alg) {
+    case IW_ENCODE_ALG_NONE:
+                  alg_name = WPA_ALG_NONE;
+		break;
+    case IW_ENCODE_ALG_WEP:
+                  alg_name = WPA_ALG_WEP;
+		break;
+    case IW_ENCODE_ALG_TKIP:
+                  alg_name = WPA_ALG_TKIP;
+		break;
+    case IW_ENCODE_ALG_CCMP:
+                  alg_name = WPA_ALG_CCMP;
+		break;
+    default:
+		PRINT_K("Unknown alg = %d\n",ext->alg);
+		ret= -ENOMEM;
+		goto error;
+		}
+//recover addr
+ memcpy(addr, ext->addr.sa_data, ETH_ALEN);
+//recover key_idx
+  key_idx = (wrq->flags&IW_ENCODE_INDEX) - 1;
+//recover set_tx
+if(ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
+   set_tx = 1;
+//recover seq,seq_len
+	if(ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
+   seq_len=IW_ENCODE_SEQ_MAX_SIZE;
+   memcpy(seq, ext->rx_seq, seq_len);
+		}
+//recover key,key_len
+if(ext->key_len) {
+  key_len=ext->key_len;
+  memcpy(key, &ext->key[0], key_len);
+	}
+
+memset(key_array, 0, 64);
+if ( key_len > 0) {
+     memcpy(key_array, key, key_len);
+    if (key_len == 32) {
+          // notice ! the oder
+	  memcpy(&key_array[16], &key[24], 8);
+	  memcpy(&key_array[24], &key[16], 8);
+	}
+	}
+
+/**************Translate iw_encode_ext to viawget_wpa_param****************/
+memcpy(param->addr, addr, ETH_ALEN);
+param->u.wpa_key.alg_name = (int)alg_name;
+param->u.wpa_key.set_tx = set_tx;
+param->u.wpa_key.key_index = key_idx;
+param->u.wpa_key.key_len = key_len;
+param->u.wpa_key.key = (u8 *)key_array;
+param->u.wpa_key.seq = (u8 *)seq;
+param->u.wpa_key.seq_len = seq_len;
+
+#if 0
+printk("param->u.wpa_key.alg_name =%d\n",param->u.wpa_key.alg_name);
+printk("param->addr=%02x:%02x:%02x:%02x:%02x:%02x\n",
+	      param->addr[0],param->addr[1],param->addr[2],
+	      param->addr[3],param->addr[4],param->addr[5]);
+printk("param->u.wpa_key.set_tx =%d\n",param->u.wpa_key.set_tx);
+printk("param->u.wpa_key.key_index =%d\n",param->u.wpa_key.key_index);
+printk("param->u.wpa_key.key_len =%d\n",param->u.wpa_key.key_len);
+printk("param->u.wpa_key.key =");
+for(ii=0;ii<param->u.wpa_key.key_len;ii++)
+	printk("%02x:",param->u.wpa_key.key[ii]);
+         printk("\n");
+printk("param->u.wpa_key.seq_len =%d\n",param->u.wpa_key.seq_len);
+printk("param->u.wpa_key.seq =");
+for(ii=0;ii<param->u.wpa_key.seq_len;ii++)
+	printk("%02x:",param->u.wpa_key.seq[ii]);
+         printk("\n");
+
+printk("...........\n");
+#endif
+//****set if current action is Network Manager count??
+//****this method is so foolish,but there is no other way???
+if(param->u.wpa_key.alg_name == WPA_ALG_NONE) {
+   if(param->u.wpa_key.key_index ==0) {
+     pDevice->bwextstep0 = TRUE;
+    }
+   if((pDevice->bwextstep0 = TRUE)&&(param->u.wpa_key.key_index ==1)) {
+     pDevice->bwextstep0 = FALSE;
+     pDevice->bwextstep1 = TRUE;
+    }
+   if((pDevice->bwextstep1 = TRUE)&&(param->u.wpa_key.key_index ==2)) {
+     pDevice->bwextstep1 = FALSE;
+     pDevice->bwextstep2 = TRUE;
+	}
+   if((pDevice->bwextstep2 = TRUE)&&(param->u.wpa_key.key_index ==3)) {
+     pDevice->bwextstep2 = FALSE;
+     pDevice->bwextstep3 = TRUE;
+        }
+		 }
+if(pDevice->bwextstep3 == TRUE) {
+    PRINT_K("SIOCSIWENCODEEXT:Enable WPA WEXT SUPPORT!!!!!\n");
+     pDevice->bwextstep0 = FALSE;
+     pDevice->bwextstep1 = FALSE;
+     pDevice->bwextstep2 = FALSE;
+     pDevice->bwextstep3 = FALSE;
+     pDevice->bWPASuppWextEnabled = TRUE;
+     memset(pMgmt->abyDesireBSSID, 0xFF,6);
+     KeyvInitTable(pDevice,&pDevice->sKey);
+		 }
+//******
+
+		spin_lock_irq(&pDevice->lock);
+ ret = wpa_set_keys(pDevice, param, TRUE);
+		spin_unlock_irq(&pDevice->lock);
+
+error:
+kfree(param);
+	return ret;
+}
+
+
+
+int iwctl_giwencodeext(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_point *wrq,
+             char *extra)
+{
+		return -EOPNOTSUPP;;
+}
+
+int iwctl_siwmlme(struct net_device *dev,
+				struct iw_request_info * info,
+				struct iw_point *wrq,
+				char *extra)
+{
+	PSDevice			pDevice = (PSDevice)dev->priv;
+	PSMgmtObject	pMgmt = &(pDevice->sMgmtObj);
+	struct iw_mlme *mlme = (struct iw_mlme *)extra;
+	//u16 reason = cpu_to_le16(mlme->reason_code);
+	int ret = 0;
+
+	if(memcmp(pMgmt->abyCurrBSSID, mlme->addr.sa_data, ETH_ALEN)){
+		ret = -EINVAL;
+		return ret;
+	}
+	switch(mlme->cmd){
+	case IW_MLME_DEAUTH:
+		//this command seems to be not complete,please test it --einsnliu
+		//printk("iwctl_siwmlme--->send DEAUTH\n");
+		//bScheduleCommand((HANDLE) pDevice, WLAN_CMD_DEAUTH, (PBYTE)&reason);
+		//break;
+	case IW_MLME_DISASSOC:
+		if(pDevice->bLinkPass == TRUE){
+		  PRINT_K("iwctl_siwmlme--->send DISASSOCIATE\n");
+		  bScheduleCommand((HANDLE)pDevice, WLAN_CMD_DISASSOCIATE, NULL);
+		}
+		break;
+	default:
+		ret = -EOPNOTSUPP;
+	}
+
+	return ret;
+
+}
+
+#endif
+//End Add --//2008-0409-07, <Add> by Einsn Liu
+
+
+
+/*------------------------------------------------------------------*/
+/*
+ * Structures to export the Wireless Handlers
+ */
+
+
+#if WIRELESS_EXT > 12
+
+/*
+static const iw_handler		iwctl_handler[] =
+{
+	(iw_handler) iwctl_commit,      // SIOCSIWCOMMIT
+	(iw_handler) iwctl_giwname,     // SIOCGIWNAME
+	(iw_handler) NULL,				// SIOCSIWNWID
+	(iw_handler) NULL,				// SIOCGIWNWID
+	(iw_handler) iwctl_siwfreq,		// SIOCSIWFREQ
+	(iw_handler) iwctl_giwfreq,		// SIOCGIWFREQ
+	(iw_handler) iwctl_siwmode,		// SIOCSIWMODE
+	(iw_handler) iwctl_giwmode,		// SIOCGIWMODE
+	(iw_handler) NULL,		        // SIOCSIWSENS
+	(iw_handler) iwctl_giwsens,		        // SIOCGIWSENS
+	(iw_handler) NULL, 		        // SIOCSIWRANGE
+	(iw_handler) iwctl_giwrange,		// SIOCGIWRANGE
+	(iw_handler) NULL,         		    // SIOCSIWPRIV
+	(iw_handler) NULL,             		// SIOCGIWPRIV
+	(iw_handler) NULL,             		// SIOCSIWSTATS
+	(iw_handler) NULL,                  // SIOCGIWSTATS
+    (iw_handler) NULL,                  // SIOCSIWSPY
+	(iw_handler) NULL,		            // SIOCGIWSPY
+	(iw_handler) NULL,				    // -- hole --
+	(iw_handler) NULL,				    // -- hole --
+	(iw_handler) iwctl_siwap,		    // SIOCSIWAP
+	(iw_handler) iwctl_giwap,		    // SIOCGIWAP
+	(iw_handler) NULL,				    // -- hole -- 0x16
+	(iw_handler) iwctl_giwaplist,       // SIOCGIWAPLIST
+#if WIRELESS_EXT > 13
+	(iw_handler) iwctl_siwscan,         // SIOCSIWSCAN
+	(iw_handler) iwctl_giwscan,         // SIOCGIWSCAN
+#else
+	(iw_handler) NULL,
+	(iw_handler) NULL,
+#endif
+	(iw_handler) iwctl_siwessid,		// SIOCSIWESSID
+	(iw_handler) iwctl_giwessid,		// SIOCGIWESSID
+	(iw_handler) NULL,		// SIOCSIWNICKN
+	(iw_handler) NULL,		// SIOCGIWNICKN
+	(iw_handler) NULL,				    // -- hole --
+	(iw_handler) NULL,				    // -- hole --
+	(iw_handler) iwctl_siwrate,		// SIOCSIWRATE 0x20
+	(iw_handler) iwctl_giwrate,		// SIOCGIWRATE
+	(iw_handler) iwctl_siwrts,		// SIOCSIWRTS
+	(iw_handler) iwctl_giwrts,		// SIOCGIWRTS
+	(iw_handler) iwctl_siwfrag,		// SIOCSIWFRAG
+	(iw_handler) iwctl_giwfrag,		// SIOCGIWFRAG
+	(iw_handler) NULL,		// SIOCSIWTXPOW
+	(iw_handler) NULL,		// SIOCGIWTXPOW
+	(iw_handler) iwctl_siwretry,		// SIOCSIWRETRY
+	(iw_handler) iwctl_giwretry,		// SIOCGIWRETRY
+	(iw_handler) iwctl_siwencode,		// SIOCSIWENCODE
+	(iw_handler) iwctl_giwencode,		// SIOCGIWENCODE
+	(iw_handler) iwctl_siwpower,		// SIOCSIWPOWER
+	(iw_handler) iwctl_giwpower,		// SIOCGIWPOWER
+#if WIRELESS_EXT > 17
+	(iw_handler) NULL,			// -- hole --
+	(iw_handler) NULL,			// -- hole --
+	(iw_handler) iwctl_siwgenie,    // SIOCSIWGENIE
+	(iw_handler) iwctl_giwgenie,    // SIOCGIWGENIE
+	(iw_handler) iwctl_siwauth,		// SIOCSIWAUTH
+	(iw_handler) iwctl_giwauth,		// SIOCGIWAUTH
+	(iw_handler) iwctl_siwencodeext,		// SIOCSIWENCODEEXT
+	(iw_handler) iwctl_giwencodeext,		// SIOCGIWENCODEEXT
+	(iw_handler) NULL,				// SIOCSIWPMKSA
+	(iw_handler) NULL,				// -- hole --
+#endif // WIRELESS_EXT > 17
+
+};
+*/
+
+static const iw_handler		iwctl_handler[] =
+{
+	(iw_handler) iwctl_commit,      // SIOCSIWCOMMIT
+	(iw_handler) NULL,      // SIOCGIWNAME
+	(iw_handler) NULL,				// SIOCSIWNWID
+	(iw_handler) NULL,				// SIOCGIWNWID
+	(iw_handler) NULL,		// SIOCSIWFREQ
+	(iw_handler) NULL,		// SIOCGIWFREQ
+	(iw_handler) NULL,		// SIOCSIWMODE
+	(iw_handler) NULL,		// SIOCGIWMODE
+	(iw_handler) NULL,		        // SIOCSIWSENS
+	(iw_handler) NULL,		        // SIOCGIWSENS
+	(iw_handler) NULL, 		        // SIOCSIWRANGE
+	(iw_handler) iwctl_giwrange,		// SIOCGIWRANGE
+	(iw_handler) NULL,         		    // SIOCSIWPRIV
+	(iw_handler) NULL,             		// SIOCGIWPRIV
+	(iw_handler) NULL,             		// SIOCSIWSTATS
+	(iw_handler) NULL,                  // SIOCGIWSTATS
+    (iw_handler) NULL,                  // SIOCSIWSPY
+	(iw_handler) NULL,		            // SIOCGIWSPY
+	(iw_handler) NULL,				    // -- hole --
+	(iw_handler) NULL,				    // -- hole --
+	(iw_handler) NULL,		    // SIOCSIWAP
+	(iw_handler) NULL,		    // SIOCGIWAP
+	(iw_handler) NULL,				    // -- hole -- 0x16
+	(iw_handler) NULL,       // SIOCGIWAPLIST
+#if WIRELESS_EXT > 13
+	(iw_handler) iwctl_siwscan,         // SIOCSIWSCAN
+	(iw_handler) iwctl_giwscan,         // SIOCGIWSCAN
+#else
+	(iw_handler) NULL,
+	(iw_handler) NULL,
+#endif
+	(iw_handler) NULL,		// SIOCSIWESSID
+	(iw_handler) NULL,		// SIOCGIWESSID
+	(iw_handler) NULL,		// SIOCSIWNICKN
+	(iw_handler) NULL,		// SIOCGIWNICKN
+	(iw_handler) NULL,		// -- hole --
+	(iw_handler) NULL,		// -- hole --
+	(iw_handler) NULL,		// SIOCSIWRATE 0x20
+	(iw_handler) NULL,		// SIOCGIWRATE
+	(iw_handler) NULL,		// SIOCSIWRTS
+	(iw_handler) NULL,		// SIOCGIWRTS
+	(iw_handler) NULL,		// SIOCSIWFRAG
+	(iw_handler) NULL,		// SIOCGIWFRAG
+	(iw_handler) NULL,		// SIOCSIWTXPOW
+	(iw_handler) NULL,		// SIOCGIWTXPOW
+	(iw_handler) NULL,		// SIOCSIWRETRY
+	(iw_handler) NULL,		// SIOCGIWRETRY
+	(iw_handler) NULL,		// SIOCSIWENCODE
+	(iw_handler) NULL,		// SIOCGIWENCODE
+	(iw_handler) NULL,		// SIOCSIWPOWER
+	(iw_handler) NULL,		// SIOCGIWPOWER
+//2008-0409-07, <Add> by Einsn Liu
+#if WIRELESS_EXT > 17
+	(iw_handler) NULL,			// -- hole --
+	(iw_handler) NULL,			// -- hole --
+	(iw_handler) NULL,    // SIOCSIWGENIE
+	(iw_handler) NULL,    // SIOCGIWGENIE
+	(iw_handler) NULL,		// SIOCSIWAUTH
+	(iw_handler) NULL,		// SIOCGIWAUTH
+	(iw_handler) NULL,		// SIOCSIWENCODEEXT
+	(iw_handler) NULL,		// SIOCGIWENCODEEXT
+	(iw_handler) NULL,				// SIOCSIWPMKSA
+	(iw_handler) NULL,				// -- hole --
+#endif // WIRELESS_EXT > 17
+};
+
+
+static const iw_handler		iwctl_private_handler[] =
+{
+	NULL,				// SIOCIWFIRSTPRIV
+};
+
+
+struct iw_priv_args iwctl_private_args[] = {
+{ IOCTL_CMD_SET,
+  IW_PRIV_TYPE_CHAR | 1024, 0,
+  "set"},
+};
+
+
+
+const struct iw_handler_def	iwctl_handler_def =
+{
+#if WIRELESS_EXT > 16
+	.get_wireless_stats = &iwctl_get_wireless_stats,
+#endif
+	.num_standard	= sizeof(iwctl_handler)/sizeof(iw_handler),
+//	.num_private	= sizeof(iwctl_private_handler)/sizeof(iw_handler),
+//	.num_private_args = sizeof(iwctl_private_args)/sizeof(struct iw_priv_args),
+	.num_private	= 0,
+	.num_private_args = 0,
+	.standard	= (iw_handler *) iwctl_handler,
+//	.private	= (iw_handler *) iwctl_private_handler,
+//	.private_args	= (struct iw_priv_args *)iwctl_private_args,
+	.private	= NULL,
+	.private_args	= NULL,
+};
+
+
+#endif // WIRELESS_EXT > 12
+
+
+#endif // WIRELESS_EXT
diff --git a/drivers/staging/vt6656/iwctl.h b/drivers/staging/vt6656/iwctl.h
new file mode 100644
index 0000000..e98b0de
--- /dev/null
+++ b/drivers/staging/vt6656/iwctl.h
@@ -0,0 +1,332 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: iwctl.h
+ *
+ * Purpose:
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: May 21, 2004
+ *
+ */
+
+
+#ifndef __IWCTL_H__
+#define __IWCTL_H__
+
+#if !defined(__DEVICE_H__)
+#include "device.h"
+#endif
+
+
+/*---------------------  Export Definitions -------------------------*/
+
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+#ifdef __cplusplus
+extern "C" {                            /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+
+#if WIRELESS_EXT < 18
+
+
+#define SIOCSIWMLME	        0x8B16
+#define SIOCSIWGENIE	    0x8B30
+
+// WPA : Authentication mode parameters
+#define SIOCSIWAUTH	        0x8B32
+#define SIOCGIWAUTH	        0x8B33
+
+// WPA : Extended version of encoding configuration
+#define SIOCSIWENCODEEXT    0x8B34
+#define SIOCGIWENCODEEXT    0x8B35
+
+#define IW_AUTH_WPA_VERSION		0
+#define IW_AUTH_CIPHER_PAIRWISE		1
+#define IW_AUTH_CIPHER_GROUP		2
+#define IW_AUTH_KEY_MGMT		3
+#define IW_AUTH_TKIP_COUNTERMEASURES	4
+#define IW_AUTH_DROP_UNENCRYPTED	5
+#define IW_AUTH_80211_AUTH_ALG		6
+#define IW_AUTH_WPA_ENABLED		7
+#define IW_AUTH_RX_UNENCRYPTED_EAPOL	8
+#define IW_AUTH_ROAMING_CONTROL		9
+#define IW_AUTH_PRIVACY_INVOKED		10
+
+#define IW_AUTH_WPA_VERSION_DISABLED	0x00000001
+#define IW_AUTH_WPA_VERSION_WPA		0x00000002
+#define IW_AUTH_WPA_VERSION_WPA2	0x00000004
+
+#define IW_AUTH_CIPHER_NONE	    0x00000001
+#define IW_AUTH_CIPHER_WEP40	0x00000002
+#define IW_AUTH_CIPHER_TKIP	    0x00000004
+#define IW_AUTH_CIPHER_CCMP	    0x00000008
+#define IW_AUTH_CIPHER_WEP104	0x00000010
+
+#define IW_AUTH_KEY_MGMT_802_1X	1
+#define IW_AUTH_KEY_MGMT_PSK	2
+
+#define IW_AUTH_ALG_OPEN_SYSTEM	0x00000001
+#define IW_AUTH_ALG_SHARED_KEY	0x00000002
+#define IW_AUTH_ALG_LEAP	0x00000004
+
+#define IW_AUTH_ROAMING_ENABLE	0
+#define IW_AUTH_ROAMING_DISABLE	1
+
+#define IW_ENCODE_SEQ_MAX_SIZE	8
+
+#define IW_ENCODE_ALG_NONE	0
+#define IW_ENCODE_ALG_WEP	1
+#define IW_ENCODE_ALG_TKIP	2
+#define IW_ENCODE_ALG_CCMP	3
+
+
+struct	iw_encode_ext
+{
+	__u32		ext_flags; // IW_ENCODE_EXT_*
+	__u8		tx_seq[IW_ENCODE_SEQ_MAX_SIZE]; // LSB first
+	__u8		rx_seq[IW_ENCODE_SEQ_MAX_SIZE]; // LSB first
+	struct sockaddr	addr; // ff:ff:ff:ff:ff:ff for broadcast/multicast
+			              // (group) keys or unicast address for
+			              // individual keys
+	__u16		alg; // IW_ENCODE_ALG_*
+	__u16		key_len;
+	__u8		key[0];
+};
+
+
+struct	iw_mlme
+{
+	__u16		cmd; /* IW_MLME_* */
+	__u16		reason_code;
+	struct sockaddr	addr;
+};
+
+#endif // WIRELESS_EXT < 18
+
+
+
+#ifdef WIRELESS_EXT
+
+struct iw_statistics *iwctl_get_wireless_stats (struct net_device *dev);
+
+
+int iwctl_siwap(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct sockaddr *wrq,
+             char *extra);
+
+int iwctl_giwrange(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_point *wrq,
+             char *extra);
+
+
+int iwctl_giwmode(struct net_device *dev,
+             struct iw_request_info *info,
+             __u32 *wmode,
+             char *extra);
+
+int iwctl_siwmode(struct net_device *dev,
+             struct iw_request_info *info,
+             __u32 *wmode,
+             char *extra);
+
+int iwctl_giwfreq(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_freq *wrq,
+             char *extra);
+
+int iwctl_siwfreq(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_freq *wrq,
+             char *extra);
+
+int iwctl_giwname(struct net_device *dev,
+			 struct iw_request_info *info,
+			 char *wrq,
+			 char *extra);
+
+int iwctl_giwnwid(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_param *wrq,
+                   char *extra) ;
+
+int iwctl_giwsens(struct net_device *dev,
+			 struct iw_request_info *info,
+			 struct iw_param *wrq,
+			 char *extra);
+
+int iwctl_giwap(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct sockaddr *wrq,
+             char *extra);
+
+int iwctl_giwaplist(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_point *wrq,
+             char *extra);
+
+int iwctl_siwessid(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_point *wrq,
+             char *extra);
+
+int iwctl_giwessid(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_point *wrq,
+             char *extra);
+
+int iwctl_siwrate(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_param *wrq,
+             char *extra);
+
+int iwctl_giwrate(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_param *wrq,
+             char *extra);
+
+int iwctl_siwrts(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_param *wrq,
+             char *extra);
+
+
+int iwctl_giwrts(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_param *wrq,
+             char *extra);
+
+int iwctl_siwfrag(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_param *wrq,
+             char *extra);
+
+int iwctl_giwfrag(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_param *wrq,
+             char *extra);
+
+int iwctl_siwretry(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_param *wrq,
+             char *extra);
+
+int iwctl_giwretry(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_param *wrq,
+             char *extra);
+
+int iwctl_siwencode(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_point *wrq,
+             char *extra);
+
+int iwctl_giwencode(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_point *wrq,
+             char *extra);
+
+int iwctl_siwpower(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_param *wrq,
+             char *extra);
+
+int iwctl_giwpower(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_param *wrq,
+             char *extra);
+
+int iwctl_giwscan(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_point *wrq,
+             char *extra);
+
+int iwctl_siwscan(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_param *wrq,
+             char *extra);
+
+//2008-0409-07, <Add> by Einsn Liu
+#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+int iwctl_siwauth(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_param *wrq,
+			  char *extra);
+
+int iwctl_giwauth(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_param *wrq,
+			  char *extra);
+
+int iwctl_siwgenie(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_point *wrq,
+			  char *extra);
+
+int iwctl_giwgenie(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_point *wrq,
+			  char *extra);
+
+int iwctl_siwencodeext(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_point *wrq,
+             char *extra);
+
+int iwctl_giwencodeext(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_point *wrq,
+             char *extra);
+
+int iwctl_siwmlme(struct net_device *dev,
+			struct iw_request_info * info,
+			struct iw_point *wrq,
+			char *extra);
+#endif // #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+#endif
+//End Add -- //2008-0409-07, <Add> by Einsn Liu
+
+
+#if WIRELESS_EXT > 12
+extern const struct iw_handler_def	iwctl_handler_def;
+extern const struct iw_priv_args	iwctl_private_args;
+#else
+struct iw_request_info {};
+#endif	//WIRELESS_EXT > 12
+
+#ifdef __cplusplus
+}                                       /* End of extern "C" { */
+#endif /* __cplusplus */
+
+
+
+
+#endif // __IWCTL_H__
+
+
+
diff --git a/drivers/staging/vt6656/kcompat.h b/drivers/staging/vt6656/kcompat.h
new file mode 100644
index 0000000..370483d
--- /dev/null
+++ b/drivers/staging/vt6656/kcompat.h
@@ -0,0 +1,315 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: kcompat.h
+ *
+ * Purpose: define kernel compatibility header
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: Apr 8, 2002
+ *
+ */
+#ifndef _KCOMPAT_H
+#define _KCOMPAT_H
+
+#include <linux/version.h>
+
+#ifndef __init
+#define __init
+#endif
+
+#ifndef __exit
+#define __exit
+#endif
+
+#ifndef __devexit
+#define __devexit
+#endif
+
+#ifndef __devinitdata
+#define __devinitdata
+#endif
+
+#ifndef MODULE_LICENSE
+#define MODULE_LICENSE(license)
+#endif
+
+#ifndef MOD_INC_USE_COUNT
+#define MOD_INC_USE_COUNT do {} while (0)
+#endif
+
+#ifndef MOD_DEC_USE_COUNT
+#define MOD_DEC_USE_COUNT do {} while (0)
+#endif
+
+#ifndef HAVE_NETDEV_PRIV
+#define netdev_priv(dev) (dev->priv)
+#endif
+
+#ifndef IRQ_RETVAL
+typedef void irqreturn_t;
+
+
+#define IRQ_RETVAL(x)
+
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+
+#define vntwusb_submit_urb(val) usb_submit_urb(val, GFP_ATOMIC)
+#define vntwusb_alloc_urb(val)  usb_alloc_urb(val, GFP_ATOMIC)
+#else
+#define vntwusb_alloc_urb(val)  usb_alloc_urb(val)
+#define vntwusb_submit_urb(val) usb_submit_urb(val)
+
+#endif
+
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
+
+#define vntwusb_unlink_urb(val) usb_kill_urb(val)
+
+#else
+#define vntwusb_unlink_urb(val) usb_unlink_urb(val)
+
+#endif
+
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18)
+
+typedef unsigned long dma_addr_t;
+typedef struct wait_queue *wait_queue_head_t;
+#define init_waitqueue_head(x)                  *(x)=NULL
+#define set_current_state(status)       { current->state = (status); mb(); }
+
+#ifdef MODULE
+
+#define module_init(fn) int  init_module   (void) { return fn(); }
+#define module_exit(fn) void cleanup_module(void) { return fn(); }
+
+#else /* MODULE */
+
+#define module_init(fn) int  e100_probe    (void) { return fn(); }
+#define module_exit(fn)  /* NOTHING */
+
+#endif /* MODULE */
+
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18) */
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
+
+#ifdef MODVERSIONS
+#include <linux/modversions.h>
+#endif
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <asm/io.h>
+
+#define pci_resource_start(dev, bar)                            \
+    (((dev)->base_address[(bar)] & PCI_BASE_ADDRESS_SPACE_IO) ? \
+    ((dev)->base_address[(bar)] & PCI_BASE_ADDRESS_IO_MASK) :   \
+    ((dev)->base_address[(bar)] & PCI_BASE_ADDRESS_MEM_MASK))
+
+static inline int pci_enable_device(struct pci_dev *dev) { return 0; }
+#define __constant_cpu_to_le32 cpu_to_le32
+#define __constant_cpu_to_le16 cpu_to_le16
+
+#define PCI_DMA_TODEVICE   1
+#define PCI_DMA_FROMDEVICE 2
+
+extern inline void *pci_alloc_consistent (struct pci_dev *dev,
+                                          size_t size,
+                                          dma_addr_t *dma_handle) {
+    void *vaddr = kmalloc(size, GFP_ATOMIC);
+    if(vaddr != NULL) {
+        *dma_handle = virt_to_bus(vaddr);
+    }
+    return vaddr;
+}
+
+#define pci_dma_sync_single(dev,dma_handle,size,direction)   do{} while(0)
+#define pci_dma_supported(dev, addr_mask)                    (1)
+#define pci_free_consistent(dev, size, cpu_addr, dma_handle) kfree(cpu_addr)
+#define pci_map_single(dev, addr, size, direction)           virt_to_bus(addr)
+#define pci_unmap_single(dev, dma_handle, size, direction)   do{} while(0)
+
+
+#define spin_lock_bh            spin_lock_irq
+#define spin_unlock_bh          spin_unlock_irq
+#define del_timer_sync(timer)   del_timer(timer)
+#define net_device              device
+
+#define netif_start_queue(dev)   ( clear_bit(0, &(dev)->tbusy))
+#define netif_stop_queue(dev)    (   set_bit(0, &(dev)->tbusy))
+#define netif_wake_queue(dev)    { clear_bit(0, &(dev)->tbusy); \
+                                   mark_bh(NET_BH); }
+#define netif_running(dev)       (  test_bit(0, &(dev)->start))
+#define netif_queue_stopped(dev) (  test_bit(0, &(dev)->tbusy))
+
+#define netif_device_attach(dev) \
+    do{ (dev)->start = 1; netif_start_queue(dev); } while (0)
+#define netif_device_detach(dev) \
+    do{ (dev)->start = 0; netif_stop_queue(dev); } while (0)
+
+#define dev_kfree_skb_irq(skb) dev_kfree_skb(skb)
+
+#define netif_carrier_on(dev)  do {} while (0)
+#define netif_carrier_off(dev) do {} while (0)
+
+
+#define PCI_ANY_ID (~0U)
+
+struct pci_device_id {
+    unsigned int vendor, device;
+    unsigned int subvendor, subdevice;
+    unsigned int class, classmask;
+    unsigned long driver_data;
+};
+
+#define MODULE_DEVICE_TABLE(bus, dev_table)
+#define PCI_MAX_NUM_NICS 256
+
+struct pci_driver {
+    char *name;
+    struct pci_device_id *id_table;
+    int (*probe)(struct pci_dev *dev, const struct pci_device_id *id);
+    void (*remove)(struct pci_dev *dev);
+    void (*suspend)(struct pci_dev *dev);
+    void (*resume)(struct pci_dev *dev);
+    struct pci_dev *pcimap[PCI_MAX_NUM_NICS];
+};
+
+static inline int pci_module_init(struct pci_driver *drv)
+{
+    struct pci_dev *pdev;
+    struct pci_device_id *pcid;
+    uint16_t subvendor, subdevice;
+    int board_count = 0;
+
+    /* walk the global pci device list looking for matches */
+    for (pdev = pci_devices; pdev && (board_count < PCI_MAX_NUM_NICS); pdev = pdev->next) {
+
+        pcid = &drv->id_table[0];
+        pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &subvendor);
+        pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subdevice);
+
+        while (pcid->vendor != 0) {
+            if (((pcid->vendor == pdev->vendor) || (pcid->vendor == PCI_ANY_ID)) &&
+                ((pcid->device == pdev->device) || (pcid->device == PCI_ANY_ID)) &&
+                ((pcid->subvendor == subvendor) || (pcid->subvendor == PCI_ANY_ID)) &&
+                ((pcid->subdevice == subdevice) || (pcid->subdevice == PCI_ANY_ID))) {
+
+                if (drv->probe(pdev, pcid) == 0) {
+                    drv->pcimap[board_count] = pdev;
+                    board_count++;
+                }
+                break;
+            }
+            pcid++;
+        }
+    }
+
+    if (board_count < PCI_MAX_NUM_NICS) {
+        drv->pcimap[board_count] = NULL;
+    }
+
+    return (board_count > 0) ? 0 : -ENODEV;
+}
+
+static inline void pci_unregister_driver(struct pci_driver *drv)
+{
+    int i;
+
+    for (i = 0; i < PCI_MAX_NUM_NICS; i++) {
+        if (!drv->pcimap[i])
+            break;
+
+        drv->remove(drv->pcimap[i]);
+    }
+}
+
+
+#define pci_set_drvdata(pcid, data)
+
+#define pci_get_drvdata(pcid) ({                            \
+    PSDevice pInfo;                                         \
+    for (pInfo = pDevice_Infos;                             \
+        pInfo; pInfo = pInfo->next) {                       \
+        if (pInfo->pcid == pcid)                            \
+            break;                                          \
+    }                                                       \
+    pInfo; })
+
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) */
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,5)
+
+#define skb_linearize(skb, gfp_mask) ({     \
+    struct sk_buff *tmp_skb;                \
+    tmp_skb = skb;                          \
+    skb = skb_copy(tmp_skb, gfp_mask);      \
+    dev_kfree_skb_irq(tmp_skb); })
+
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,4,5) */
+
+#ifndef MODULE_LICESEN
+#define MODULE_LICESEN(x)
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,6)
+
+#include <linux/types.h>
+#include <linux/pci.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,2)
+static inline int pci_set_power_state(struct pci_dev* pcid, int state) { return 0; }
+#endif
+
+#define PMCSR       0xe0
+#define PM_ENABLE_BIT   0x0100
+#define PM_CLEAR_BIT    0x8000
+#define PM_STATE_MASK   0xFFFC
+#define PM_STATE_D1 0x0001
+
+static inline int
+pci_enable_wake(struct pci_dev *dev, u32 state, int enable)
+{
+    u16 p_state;
+
+    pci_read_config_word(dev, PMCSR, &p_state);
+    pci_write_config_word(dev, PMCSR, p_state | PM_CLEAR_BIT);
+
+    if (enable == 0) {
+        p_state &= ~PM_ENABLE_BIT;
+    } else {
+        p_state |= PM_ENABLE_BIT;
+    }
+    p_state &= PM_STATE_MASK;
+    p_state |= state;
+
+    pci_write_config_word(dev, PMCSR, p_state);
+
+    return 0;
+}
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,4,6) */
+
+#endif
+
diff --git a/drivers/staging/vt6656/key.c b/drivers/staging/vt6656/key.c
new file mode 100644
index 0000000..bd0f29c
--- /dev/null
+++ b/drivers/staging/vt6656/key.c
@@ -0,0 +1,886 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: key.c
+ *
+ * Purpose: Implement functions for 802.11i Key management
+ *
+ * Author: Jerry Chen
+ *
+ * Date: May 29, 2003
+ *
+ * Functions:
+ *      KeyvInitTable - Init Key management table
+ *      KeybGetKey - Get Key from table
+ *      KeybSetKey - Set Key to table
+ *      KeybRemoveKey - Remove Key from table
+ *      KeybGetTransmitKey - Get Transmit Key from table
+ *
+ * Revision History:
+ *
+ */
+
+
+#if !defined(__TMACRO_H__)
+#include "tmacro.h"
+#endif
+#if !defined(__TBIT_H__)
+#include "tbit.h"
+#endif
+#if !defined(__KEY_H__)
+#include "key.h"
+#endif
+#if !defined(__UMEM_H__)
+#include "umem.h"
+#endif
+#if !defined(__MAC_H__)
+#include "mac.h"
+#endif
+#if !defined(__RNDIS_H__)
+#include "rndis.h"
+#endif
+#if !defined(__CONTROL_H__)
+#include "control.h"
+#endif
+
+/*---------------------  Static Definitions -------------------------*/
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+static int          msglevel                =MSG_LEVEL_INFO;
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+/*---------------------  Static Functions  --------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Static Definitions -------------------------*/
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+
+/*---------------------  Static Functions  --------------------------*/
+static VOID
+s_vCheckKeyTableValid (PVOID pDeviceHandler, PSKeyManagement pTable)
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+    int         i;
+    WORD        wLength = 0;
+    BYTE        pbyData[MAX_KEY_TABLE];
+
+    for (i=0;i<MAX_KEY_TABLE;i++) {
+        if ((pTable->KeyTable[i].bInUse == TRUE) &&
+            (pTable->KeyTable[i].PairwiseKey.bKeyValid == FALSE) &&
+            (pTable->KeyTable[i].GroupKey[0].bKeyValid == FALSE) &&
+            (pTable->KeyTable[i].GroupKey[1].bKeyValid == FALSE) &&
+            (pTable->KeyTable[i].GroupKey[2].bKeyValid == FALSE) &&
+            (pTable->KeyTable[i].GroupKey[3].bKeyValid == FALSE)
+            ) {
+
+            pTable->KeyTable[i].bInUse = FALSE;
+            pTable->KeyTable[i].wKeyCtl = 0;
+            pTable->KeyTable[i].bSoftWEP = FALSE;
+            pbyData[wLength++] = (BYTE) i;
+            //MACvDisableKeyEntry(pDevice, i);
+        }
+    }
+    if ( wLength != 0 ) {
+        CONTROLnsRequestOut(pDevice,
+                            MESSAGE_TYPE_CLRKEYENTRY,
+                            0,
+                            0,
+                            wLength,
+                            pbyData
+                            );
+    }
+
+}
+
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+/*
+ * Description: Init Key management table
+ *
+ * Parameters:
+ *  In:
+ *      pTable          - Pointer to Key table
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+VOID KeyvInitTable(PVOID pDeviceHandler, PSKeyManagement pTable)
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+    int i;
+    int jj;
+    BYTE       pbyData[MAX_KEY_TABLE+1];
+
+    spin_lock_irq(&pDevice->lock);
+    for (i=0;i<MAX_KEY_TABLE;i++) {
+        pTable->KeyTable[i].bInUse = FALSE;
+        pTable->KeyTable[i].PairwiseKey.bKeyValid = FALSE;
+        pTable->KeyTable[i].PairwiseKey.pvKeyTable = (PVOID)&pTable->KeyTable[i];
+        for (jj=0; jj < MAX_GROUP_KEY; jj++) {
+            pTable->KeyTable[i].GroupKey[jj].bKeyValid = FALSE;
+            pTable->KeyTable[i].GroupKey[jj].pvKeyTable = (PVOID) &(pTable->KeyTable[i]);
+        }
+        pTable->KeyTable[i].wKeyCtl = 0;
+        pTable->KeyTable[i].dwGTKeyIndex = 0;
+        pTable->KeyTable[i].bSoftWEP = FALSE;
+        pbyData[i] = (BYTE) i;
+    }
+    pbyData[i] = (BYTE) i;
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_CLRKEYENTRY,
+                        0,
+                        0,
+                        11,
+                        pbyData
+                        );
+
+    spin_unlock_irq(&pDevice->lock);
+
+    return;
+}
+
+
+/*
+ * Description: Get Key from table
+ *
+ * Parameters:
+ *  In:
+ *      pTable          - Pointer to Key table
+ *      pbyBSSID        - BSSID of Key
+ *      dwKeyIndex      - Key Index (0xFFFFFFFF means pairwise key)
+ *  Out:
+ *      pKey            - Key return
+ *
+ * Return Value: TRUE if found otherwise FALSE
+ *
+ */
+BOOL KeybGetKey (
+    IN  PSKeyManagement pTable,
+    IN  PBYTE           pbyBSSID,
+    IN  DWORD           dwKeyIndex,
+    OUT PSKeyItem       *pKey
+    )
+{
+    int i;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybGetKey() \n");
+
+    *pKey = NULL;
+    for (i=0;i<MAX_KEY_TABLE;i++) {
+        if ((pTable->KeyTable[i].bInUse == TRUE) &&
+            IS_ETH_ADDRESS_EQUAL(pTable->KeyTable[i].abyBSSID,pbyBSSID)) {
+            if (dwKeyIndex == 0xFFFFFFFF) {
+                if (pTable->KeyTable[i].PairwiseKey.bKeyValid == TRUE) {
+                    *pKey = &(pTable->KeyTable[i].PairwiseKey);
+                    return (TRUE);
+                }
+                else {
+                    return (FALSE);
+                }
+            } else if (dwKeyIndex < MAX_GROUP_KEY) {
+                if (pTable->KeyTable[i].GroupKey[dwKeyIndex].bKeyValid == TRUE) {
+                    *pKey = &(pTable->KeyTable[i].GroupKey[dwKeyIndex]);
+                    return (TRUE);
+                }
+                else {
+                    return (FALSE);
+                }
+            }
+            else {
+                return (FALSE);
+            }
+        }
+    }
+    return (FALSE);
+}
+
+
+/*
+ * Description: Set Key to table
+ *
+ * Parameters:
+ *  In:
+ *      pTable          - Pointer to Key table
+ *      pbyBSSID        - BSSID of Key
+ *      dwKeyIndex      - Key index (reference to NDIS DDK)
+ *      uKeyLength      - Key length
+ *      KeyRSC          - Key RSC
+ *      pbyKey          - Pointer to key
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if success otherwise FALSE
+ *
+ */
+BOOL KeybSetKey (
+    PVOID           pDeviceHandler,
+    PSKeyManagement pTable,
+    PBYTE           pbyBSSID,
+    DWORD           dwKeyIndex,
+    ULONG           uKeyLength,
+    PQWORD          pKeyRSC,
+    PBYTE           pbyKey,
+    BYTE            byKeyDecMode
+    )
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+    int         i,j;
+    UINT        ii;
+    PSKeyItem   pKey;
+    UINT        uKeyIdx;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Enter KeybSetKey: %lX\n", dwKeyIndex);
+
+    j = (MAX_KEY_TABLE-1);
+    for (i=0;i<(MAX_KEY_TABLE-1);i++) {
+        if ((pTable->KeyTable[i].bInUse == FALSE) &&
+            (j == (MAX_KEY_TABLE-1))) {
+            // found empty table
+            j = i;
+        }
+        if ((pTable->KeyTable[i].bInUse == TRUE) &&
+            IS_ETH_ADDRESS_EQUAL(pTable->KeyTable[i].abyBSSID,pbyBSSID)) {
+            // found table already exist
+            if ((dwKeyIndex & PAIRWISE_KEY) != 0) {
+                // Pairwise key
+                pKey = &(pTable->KeyTable[i].PairwiseKey);
+                pTable->KeyTable[i].wKeyCtl &= 0xFFF0;          // clear pairwise key control filed
+                pTable->KeyTable[i].wKeyCtl |= byKeyDecMode;
+                uKeyIdx = 4;                                    // use HW key entry 4 for pairwise key
+            } else {
+                // Group key
+                if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY)
+                    return (FALSE);
+                pKey = &(pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF]);
+                if ((dwKeyIndex & TRANSMIT_KEY) != 0)  {
+                    // Group transmit key
+                    pTable->KeyTable[i].dwGTKeyIndex = dwKeyIndex;
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Group transmit key(R)[%lX]: %d\n", pTable->KeyTable[i].dwGTKeyIndex, i);
+                }
+                pTable->KeyTable[i].wKeyCtl &= 0xFF0F;          // clear group key control filed
+                pTable->KeyTable[i].wKeyCtl |= (byKeyDecMode << 4);
+                pTable->KeyTable[i].wKeyCtl |= 0x0040;          // use group key for group address
+                uKeyIdx = (dwKeyIndex & 0x000000FF);
+            }
+            pTable->KeyTable[i].wKeyCtl |= 0x8000;              // enable on-fly
+
+            pKey->bKeyValid = TRUE;
+            pKey->uKeyLength = uKeyLength;
+            pKey->dwKeyIndex = dwKeyIndex;
+            pKey->byCipherSuite = byKeyDecMode;
+            MEMvCopy(pKey->abyKey, pbyKey, uKeyLength);
+            if (byKeyDecMode == KEY_CTL_WEP) {
+                if (uKeyLength == WLAN_WEP40_KEYLEN)
+                    pKey->abyKey[15] &= 0x7F;
+                if (uKeyLength == WLAN_WEP104_KEYLEN)
+                    pKey->abyKey[15] |= 0x80;
+            }
+            MACvSetKeyEntry(pDevice, pTable->KeyTable[i].wKeyCtl, i, uKeyIdx, pbyBSSID, (PDWORD)pKey->abyKey);
+
+            if ((dwKeyIndex & USE_KEYRSC) == 0) {
+                // RSC set by NIC
+                ZERO_MEMORY(&(pKey->KeyRSC), sizeof(QWORD));
+            }
+            else {
+                MEMvCopy(&(pKey->KeyRSC), pKeyRSC,  sizeof(QWORD));
+            }
+            pKey->dwTSC47_16 = 0;
+            pKey->wTSC15_0 = 0;
+
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybSetKey(R): \n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->bKeyValid: %d\n ", pKey->bKeyValid);
+            //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->uKeyLength: %d\n ", pKey->uKeyLength);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->abyKey: ");
+            for (ii = 0; ii < pKey->uKeyLength; ii++) {
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pKey->abyKey[ii]);
+            }
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %lx\n ", pKey->dwTSC47_16);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n ", pKey->wTSC15_0);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %lx\n ", pKey->dwKeyIndex);
+
+            return (TRUE);
+        }
+    }
+    if (j < (MAX_KEY_TABLE-1)) {
+        MEMvCopy(pTable->KeyTable[j].abyBSSID,pbyBSSID,U_ETHER_ADDR_LEN);
+        pTable->KeyTable[j].bInUse = TRUE;
+        if ((dwKeyIndex & PAIRWISE_KEY) != 0)  {
+            // Pairwise key
+            pKey = &(pTable->KeyTable[j].PairwiseKey);
+            pTable->KeyTable[j].wKeyCtl &= 0xFFF0;          // clear pairwise key control filed
+            pTable->KeyTable[j].wKeyCtl |= byKeyDecMode;
+            uKeyIdx = 4;                                    // use HW key entry 4 for pairwise key
+        } else {
+            // Group key
+            if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY)
+                return (FALSE);
+            pKey = &(pTable->KeyTable[j].GroupKey[dwKeyIndex & 0x000000FF]);
+            if ((dwKeyIndex & TRANSMIT_KEY) != 0)  {
+                // Group transmit key
+                pTable->KeyTable[j].dwGTKeyIndex = dwKeyIndex;
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Group transmit key(N)[%lX]: %d\n", pTable->KeyTable[j].dwGTKeyIndex, j);
+            }
+            pTable->KeyTable[j].wKeyCtl &= 0xFF0F;          // clear group key control filed
+            pTable->KeyTable[j].wKeyCtl |= (byKeyDecMode << 4);
+            pTable->KeyTable[j].wKeyCtl |= 0x0040;          // use group key for group address
+            uKeyIdx = (dwKeyIndex & 0x000000FF);
+        }
+        pTable->KeyTable[j].wKeyCtl |= 0x8000;              // enable on-fly
+
+        pKey->bKeyValid = TRUE;
+        pKey->uKeyLength = uKeyLength;
+        pKey->dwKeyIndex = dwKeyIndex;
+        pKey->byCipherSuite = byKeyDecMode;
+        MEMvCopy(pKey->abyKey, pbyKey, uKeyLength);
+        if (byKeyDecMode == KEY_CTL_WEP) {
+            if (uKeyLength == WLAN_WEP40_KEYLEN)
+                pKey->abyKey[15] &= 0x7F;
+            if (uKeyLength == WLAN_WEP104_KEYLEN)
+                pKey->abyKey[15] |= 0x80;
+        }
+        MACvSetKeyEntry(pDevice, pTable->KeyTable[j].wKeyCtl, j, uKeyIdx, pbyBSSID, (PDWORD)pKey->abyKey);
+
+        if ((dwKeyIndex & USE_KEYRSC) == 0) {
+            // RSC set by NIC
+            ZERO_MEMORY(&(pKey->KeyRSC), sizeof(QWORD));
+        }
+        else {
+            MEMvCopy(&(pKey->KeyRSC), pKeyRSC,  sizeof(QWORD));
+        }
+        pKey->dwTSC47_16 = 0;
+        pKey->wTSC15_0 = 0;
+
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybSetKey(N): \n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->bKeyValid: %d\n ", pKey->bKeyValid);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->uKeyLength: %d\n ", (int)pKey->uKeyLength);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->abyKey: ");
+        for (ii = 0; ii < pKey->uKeyLength; ii++) {
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pKey->abyKey[ii]);
+        }
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %lx\n ", pKey->dwTSC47_16);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n ", pKey->wTSC15_0);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %lx\n ", pKey->dwKeyIndex);
+
+        return (TRUE);
+    }
+    return (FALSE);
+}
+
+
+/*
+ * Description: Remove Key from table
+ *
+ * Parameters:
+ *  In:
+ *      pTable          - Pointer to Key table
+ *      pbyBSSID        - BSSID of Key
+ *      dwKeyIndex      - Key Index (reference to NDIS DDK)
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if success otherwise FALSE
+ *
+ */
+BOOL KeybRemoveKey (
+    PVOID           pDeviceHandler,
+    PSKeyManagement pTable,
+    PBYTE           pbyBSSID,
+    DWORD           dwKeyIndex
+    )
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+    int     i;
+    BOOL    bReturnValue = FALSE;
+
+    if (IS_BROADCAST_ADDRESS(pbyBSSID)) {
+        // dealte all key
+        if ((dwKeyIndex & PAIRWISE_KEY) != 0) {
+            for (i=0;i<MAX_KEY_TABLE;i++) {
+                pTable->KeyTable[i].PairwiseKey.bKeyValid = FALSE;
+            }
+            bReturnValue =  TRUE;
+        }
+        else if ((dwKeyIndex & 0x000000FF) < MAX_GROUP_KEY) {
+            for (i=0;i<MAX_KEY_TABLE;i++) {
+                pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF].bKeyValid = FALSE;
+                if ((dwKeyIndex & 0x7FFFFFFF) == (pTable->KeyTable[i].dwGTKeyIndex & 0x7FFFFFFF)) {
+                    // remove Group transmit key
+                    pTable->KeyTable[i].dwGTKeyIndex = 0;
+                }
+            }
+            bReturnValue = TRUE;
+        }
+        else {
+            bReturnValue = FALSE;
+        }
+
+    } else {
+        for (i=0;i<MAX_KEY_TABLE;i++) {
+            if ( (pTable->KeyTable[i].bInUse == TRUE) &&
+                 IS_ETH_ADDRESS_EQUAL(pTable->KeyTable[i].abyBSSID,pbyBSSID)) {
+
+                if ((dwKeyIndex & PAIRWISE_KEY) != 0) {
+                    pTable->KeyTable[i].PairwiseKey.bKeyValid = FALSE;
+                    bReturnValue = TRUE;
+                    break;
+                }
+                else if ((dwKeyIndex & 0x000000FF) < MAX_GROUP_KEY) {
+                    pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF].bKeyValid = FALSE;
+                    if ((dwKeyIndex & 0x7FFFFFFF) == (pTable->KeyTable[i].dwGTKeyIndex & 0x7FFFFFFF)) {
+                        // remove Group transmit key
+                        pTable->KeyTable[i].dwGTKeyIndex = 0;
+                    }
+                    bReturnValue = TRUE;
+                    break;
+                }
+                else {
+                    bReturnValue = FALSE;
+                    break;
+                }
+            } //pTable->KeyTable[i].bInUse == TRUE
+        }  //for
+        bReturnValue = TRUE;
+    }
+
+    s_vCheckKeyTableValid(pDevice,pTable);
+    return bReturnValue;
+
+
+}
+
+
+/*
+ * Description: Remove Key from table
+ *
+ * Parameters:
+ *  In:
+ *      pTable          - Pointer to Key table
+ *      pbyBSSID        - BSSID of Key
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if success otherwise FALSE
+ *
+ */
+BOOL KeybRemoveAllKey (
+    PVOID           pDeviceHandler,
+    PSKeyManagement pTable,
+    PBYTE           pbyBSSID
+    )
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+    int  i,u;
+
+    for (i=0;i<MAX_KEY_TABLE;i++) {
+        if ((pTable->KeyTable[i].bInUse == TRUE) &&
+            IS_ETH_ADDRESS_EQUAL(pTable->KeyTable[i].abyBSSID,pbyBSSID)) {
+            pTable->KeyTable[i].PairwiseKey.bKeyValid = FALSE;
+            for(u=0;u<MAX_GROUP_KEY;u++) {
+                pTable->KeyTable[i].GroupKey[u].bKeyValid = FALSE;
+            }
+            pTable->KeyTable[i].dwGTKeyIndex = 0;
+            s_vCheckKeyTableValid(pDevice, pTable);
+            return (TRUE);
+        }
+    }
+    return (FALSE);
+}
+
+/*
+ * Description: Remove WEP Key from table
+ *
+ * Parameters:
+ *  In:
+ *      pTable          - Pointer to Key table
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if success otherwise FALSE
+ *
+ */
+VOID KeyvRemoveWEPKey (
+    PVOID           pDeviceHandler,
+    PSKeyManagement pTable,
+    DWORD           dwKeyIndex
+    )
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+
+   if ((dwKeyIndex & 0x000000FF) < MAX_GROUP_KEY) {
+        if (pTable->KeyTable[MAX_KEY_TABLE-1].bInUse == TRUE) {
+            if (pTable->KeyTable[MAX_KEY_TABLE-1].GroupKey[dwKeyIndex & 0x000000FF].byCipherSuite == KEY_CTL_WEP) {
+                pTable->KeyTable[MAX_KEY_TABLE-1].GroupKey[dwKeyIndex & 0x000000FF].bKeyValid = FALSE;
+                if ((dwKeyIndex & 0x7FFFFFFF) == (pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex & 0x7FFFFFFF)) {
+                    // remove Group transmit key
+                    pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex = 0;
+                }
+            }
+        }
+        s_vCheckKeyTableValid(pDevice, pTable);
+    }
+    return;
+}
+
+VOID KeyvRemoveAllWEPKey (
+    PVOID           pDeviceHandler,
+    PSKeyManagement pTable
+    )
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+
+    int i;
+
+    for(i=0;i<MAX_GROUP_KEY;i++) {
+        KeyvRemoveWEPKey(pDevice,pTable, i);
+    }
+
+}
+
+/*
+ * Description: Get Transmit Key from table
+ *
+ * Parameters:
+ *  In:
+ *      pTable          - Pointer to Key table
+ *      pbyBSSID        - BSSID of Key
+ *  Out:
+ *      pKey            - Key return
+ *
+ * Return Value: TRUE if found otherwise FALSE
+ *
+ */
+BOOL KeybGetTransmitKey (
+    IN  PSKeyManagement pTable,
+    IN  PBYTE           pbyBSSID,
+    IN  DWORD           dwKeyType,
+    OUT PSKeyItem       *pKey
+    )
+{
+    int i, ii;
+
+    *pKey = NULL;
+    for (i=0;i<MAX_KEY_TABLE;i++) {
+        if ((pTable->KeyTable[i].bInUse == TRUE) &&
+            IS_ETH_ADDRESS_EQUAL(pTable->KeyTable[i].abyBSSID,pbyBSSID)) {
+
+            if (dwKeyType == PAIRWISE_KEY) {
+
+                if (pTable->KeyTable[i].PairwiseKey.bKeyValid == TRUE) {
+                    *pKey = &(pTable->KeyTable[i].PairwiseKey);
+
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybGetTransmitKey:");
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"PAIRWISE_KEY: KeyTable.abyBSSID: ");
+                    for (ii = 0; ii < 6; ii++) {
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%x ", pTable->KeyTable[i].abyBSSID[ii]);
+                    }
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+
+
+                    return (TRUE);
+                }
+                else {
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"PairwiseKey.bKeyValid == FALSE\n");
+                    return (FALSE);
+                }
+            } // End of Type == PAIRWISE
+            else {
+                if (pTable->KeyTable[i].dwGTKeyIndex == 0) {
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ERROR: dwGTKeyIndex == 0 !!!\n");
+                    return FALSE;
+                }
+                if (pTable->KeyTable[i].GroupKey[(pTable->KeyTable[i].dwGTKeyIndex&0x000000FF)].bKeyValid == TRUE) {
+                    *pKey = &(pTable->KeyTable[i].GroupKey[(pTable->KeyTable[i].dwGTKeyIndex&0x000000FF)]);
+
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybGetTransmitKey:");
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"GROUP_KEY: KeyTable.abyBSSID\n");
+                        for (ii = 0; ii < 6; ii++) {
+                            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%x ", pTable->KeyTable[i].abyBSSID[ii]);
+                        }
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"dwGTKeyIndex: %lX\n", pTable->KeyTable[i].dwGTKeyIndex);
+
+                    return (TRUE);
+                }
+                else {
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"GroupKey.bKeyValid == FALSE\n");
+                    return (FALSE);
+                }
+            } // End of Type = GROUP
+        } // BSSID match
+    }
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ERROR: NO Match BSSID !!! ");
+    for (ii = 0; ii < 6; ii++) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *(pbyBSSID+ii));
+    }
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+    return (FALSE);
+}
+
+
+/*
+ * Description: Check Pairewise Key
+ *
+ * Parameters:
+ *  In:
+ *      pTable          - Pointer to Key table
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if found otherwise FALSE
+ *
+ */
+BOOL KeybCheckPairewiseKey (
+    IN  PSKeyManagement pTable,
+    OUT PSKeyItem       *pKey
+    )
+{
+    int i;
+
+    *pKey = NULL;
+    for (i=0;i<MAX_KEY_TABLE;i++) {
+        if ((pTable->KeyTable[i].bInUse == TRUE) &&
+            (pTable->KeyTable[i].PairwiseKey.bKeyValid == TRUE)) {
+            *pKey = &(pTable->KeyTable[i].PairwiseKey);
+            return (TRUE);
+        }
+    }
+    return (FALSE);
+}
+
+/*
+ * Description: Set Key to table
+ *
+ * Parameters:
+ *  In:
+ *      pTable          - Pointer to Key table
+ *      dwKeyIndex      - Key index (reference to NDIS DDK)
+ *      uKeyLength      - Key length
+ *      KeyRSC          - Key RSC
+ *      pbyKey          - Pointer to key
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if success otherwise FALSE
+ *
+ */
+BOOL KeybSetDefaultKey (
+    PVOID           pDeviceHandler,
+    PSKeyManagement pTable,
+    DWORD           dwKeyIndex,
+    ULONG           uKeyLength,
+    PQWORD          pKeyRSC,
+    PBYTE           pbyKey,
+    BYTE            byKeyDecMode
+    )
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+    UINT        ii;
+    PSKeyItem   pKey;
+    UINT        uKeyIdx;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Enter KeybSetDefaultKey: %1x, %d \n", (int)dwKeyIndex, (int)uKeyLength);
+
+
+    if ((dwKeyIndex & PAIRWISE_KEY) != 0) {                  // Pairwise key
+        return (FALSE);
+    } else if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY) {
+        return (FALSE);
+    }
+
+    pTable->KeyTable[MAX_KEY_TABLE-1].bInUse = TRUE;
+    for(ii=0;ii<U_ETHER_ADDR_LEN;ii++)
+        pTable->KeyTable[MAX_KEY_TABLE-1].abyBSSID[ii] = 0xFF;
+
+    // Group key
+    pKey = &(pTable->KeyTable[MAX_KEY_TABLE-1].GroupKey[dwKeyIndex & 0x000000FF]);
+    if ((dwKeyIndex & TRANSMIT_KEY) != 0)  {
+        // Group transmit key
+        pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex = dwKeyIndex;
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Group transmit key(R)[%lX]: %d\n", pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex, MAX_KEY_TABLE-1);
+
+    }
+    pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl &= 0x7F00;          // clear all key control filed
+    pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= (byKeyDecMode << 4);
+    pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= (byKeyDecMode);
+    pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= 0x0044;          // use group key for all address
+    uKeyIdx = (dwKeyIndex & 0x000000FF);
+
+    if ((uKeyLength == WLAN_WEP232_KEYLEN) &&
+        (byKeyDecMode == KEY_CTL_WEP)) {
+        pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= 0x4000;              // disable on-fly disable address match
+        pTable->KeyTable[MAX_KEY_TABLE-1].bSoftWEP = TRUE;
+    } else {
+        if (pTable->KeyTable[MAX_KEY_TABLE-1].bSoftWEP == FALSE)
+            pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= 0xC000;          // enable on-fly disable address match
+    }
+
+    pKey->bKeyValid = TRUE;
+    pKey->uKeyLength = uKeyLength;
+    pKey->dwKeyIndex = dwKeyIndex;
+    pKey->byCipherSuite = byKeyDecMode;
+    MEMvCopy(pKey->abyKey, pbyKey, uKeyLength);
+    if (byKeyDecMode == KEY_CTL_WEP) {
+        if (uKeyLength == WLAN_WEP40_KEYLEN)
+            pKey->abyKey[15] &= 0x7F;
+        if (uKeyLength == WLAN_WEP104_KEYLEN)
+            pKey->abyKey[15] |= 0x80;
+    }
+
+    MACvSetKeyEntry(pDevice, pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl, MAX_KEY_TABLE-1, uKeyIdx, pTable->KeyTable[MAX_KEY_TABLE-1].abyBSSID, (PDWORD) pKey->abyKey);
+
+    if ((dwKeyIndex & USE_KEYRSC) == 0) {
+        // RSC set by NIC
+        ZERO_MEMORY(&(pKey->KeyRSC), sizeof(QWORD));
+    } else {
+        MEMvCopy(&(pKey->KeyRSC), pKeyRSC,  sizeof(QWORD));
+    }
+    pKey->dwTSC47_16 = 0;
+    pKey->wTSC15_0 = 0;
+
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybSetKey(R): \n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->bKeyValid: %d\n", pKey->bKeyValid);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->uKeyLength: %d\n", (int)pKey->uKeyLength);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->abyKey: \n");
+    for (ii = 0; ii < pKey->uKeyLength; ii++) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%x", pKey->abyKey[ii]);
+    }
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %lx\n", pKey->dwTSC47_16);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n", pKey->wTSC15_0);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %lx\n", pKey->dwKeyIndex);
+
+    return (TRUE);
+}
+
+
+/*
+ * Description: Set Key to table
+ *
+ * Parameters:
+ *  In:
+ *      pTable          - Pointer to Key table
+ *      dwKeyIndex      - Key index (reference to NDIS DDK)
+ *      uKeyLength      - Key length
+ *      KeyRSC          - Key RSC
+ *      pbyKey          - Pointer to key
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if success otherwise FALSE
+ *
+ */
+BOOL KeybSetAllGroupKey (
+    PVOID           pDeviceHandler,
+    PSKeyManagement pTable,
+    DWORD           dwKeyIndex,
+    ULONG           uKeyLength,
+    PQWORD          pKeyRSC,
+    PBYTE           pbyKey,
+    BYTE            byKeyDecMode
+    )
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+    int         i;
+    UINT        ii;
+    PSKeyItem   pKey;
+    UINT        uKeyIdx;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Enter KeybSetAllGroupKey: %lX\n", dwKeyIndex);
+
+
+    if ((dwKeyIndex & PAIRWISE_KEY) != 0) {                  // Pairwise key
+        return (FALSE);
+    } else if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY) {
+        return (FALSE);
+    }
+
+    for (i=0; i < MAX_KEY_TABLE-1; i++) {
+        if (pTable->KeyTable[i].bInUse == TRUE) {
+            // found table already exist
+            // Group key
+            pKey = &(pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF]);
+            if ((dwKeyIndex & TRANSMIT_KEY) != 0)  {
+                // Group transmit key
+                pTable->KeyTable[i].dwGTKeyIndex = dwKeyIndex;
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Group transmit key(R)[%lX]: %d\n", pTable->KeyTable[i].dwGTKeyIndex, i);
+
+            }
+            pTable->KeyTable[i].wKeyCtl &= 0xFF0F;          // clear group key control filed
+            pTable->KeyTable[i].wKeyCtl |= (byKeyDecMode << 4);
+            pTable->KeyTable[i].wKeyCtl |= 0x0040;          // use group key for group address
+            uKeyIdx = (dwKeyIndex & 0x000000FF);
+
+            pTable->KeyTable[i].wKeyCtl |= 0x8000;              // enable on-fly
+
+            pKey->bKeyValid = TRUE;
+            pKey->uKeyLength = uKeyLength;
+            pKey->dwKeyIndex = dwKeyIndex;
+            pKey->byCipherSuite = byKeyDecMode;
+            MEMvCopy(pKey->abyKey, pbyKey, uKeyLength);
+            if (byKeyDecMode == KEY_CTL_WEP) {
+                if (uKeyLength == WLAN_WEP40_KEYLEN)
+                    pKey->abyKey[15] &= 0x7F;
+                if (uKeyLength == WLAN_WEP104_KEYLEN)
+                    pKey->abyKey[15] |= 0x80;
+            }
+
+            MACvSetKeyEntry(pDevice, pTable->KeyTable[i].wKeyCtl, i, uKeyIdx, pTable->KeyTable[i].abyBSSID, (PDWORD) pKey->abyKey);
+
+            if ((dwKeyIndex & USE_KEYRSC) == 0) {
+                // RSC set by NIC
+                ZERO_MEMORY(&(pKey->KeyRSC), sizeof(QWORD));
+            }
+            else {
+                MEMvCopy(&(pKey->KeyRSC), pKeyRSC,  sizeof(QWORD));
+            }
+            pKey->dwTSC47_16 = 0;
+            pKey->wTSC15_0 = 0;
+
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybSetKey(R): \n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->bKeyValid: %d\n ", pKey->bKeyValid);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->uKeyLength: %d\n ", (int)pKey->uKeyLength);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->abyKey: ");
+            for (ii = 0; ii < pKey->uKeyLength; ii++) {
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", pKey->abyKey[ii]);
+            }
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+
+            //DBG_PRN_GRP12(("pKey->dwTSC47_16: %lX\n ", pKey->dwTSC47_16));
+            //DBG_PRN_GRP12(("pKey->wTSC15_0: %X\n ", pKey->wTSC15_0));
+            //DBG_PRN_GRP12(("pKey->dwKeyIndex: %lX\n ", pKey->dwKeyIndex));
+
+        } // (pTable->KeyTable[i].bInUse == TRUE)
+    }
+    return (TRUE);
+}
diff --git a/drivers/staging/vt6656/key.h b/drivers/staging/vt6656/key.h
new file mode 100644
index 0000000..6777406
--- /dev/null
+++ b/drivers/staging/vt6656/key.h
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: key.h
+ *
+ * Purpose: Implement functions for 802.11i Key management
+ *
+ * Author: Jerry Chen
+ *
+ * Date: May 29, 2003
+ *
+ */
+
+
+#ifndef __KEY_H__
+#define __KEY_H__
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+
+#if !defined(__TETHER_H__)
+#include "tether.h"
+#endif
+
+#if !defined(__80211MGR_H__)
+#include "80211mgr.h"
+#endif
+
+/*---------------------  Export Definitions -------------------------*/
+#define MAX_GROUP_KEY       4
+#define MAX_KEY_TABLE       11
+#define MAX_KEY_LEN         32
+#define AES_KEY_LEN         16
+
+
+#define AUTHENTICATOR_KEY   0x10000000
+#define USE_KEYRSC          0x20000000
+#define PAIRWISE_KEY        0x40000000
+#define TRANSMIT_KEY        0x80000000
+
+#define GROUP_KEY           0x00000000
+
+#define KEY_CTL_WEP         0x00
+#define KEY_CTL_NONE        0x01
+#define KEY_CTL_TKIP        0x02
+#define KEY_CTL_CCMP        0x03
+#define KEY_CTL_INVALID     0xFF
+
+
+typedef struct tagSKeyItem
+{
+    BOOL        bKeyValid;
+    ULONG       uKeyLength;
+    BYTE        abyKey[MAX_KEY_LEN];
+    QWORD       KeyRSC;
+    DWORD       dwTSC47_16;
+    WORD        wTSC15_0;
+    BYTE        byCipherSuite;
+    BYTE        byReserved0;
+    DWORD       dwKeyIndex;
+    PVOID       pvKeyTable;
+} SKeyItem, DEF* PSKeyItem; //64
+
+typedef struct tagSKeyTable
+{
+    BYTE        abyBSSID[U_ETHER_ADDR_LEN];  //6
+    BYTE        byReserved0[2];              //8
+    SKeyItem    PairwiseKey;
+    SKeyItem    GroupKey[MAX_GROUP_KEY]; //64*5 = 320, 320+8=328
+    DWORD       dwGTKeyIndex;            // GroupTransmitKey Index
+    BOOL        bInUse;
+    WORD        wKeyCtl;
+    BOOL        bSoftWEP;
+    BYTE        byReserved1[6];
+} SKeyTable, DEF* PSKeyTable; //352
+
+typedef struct tagSKeyManagement
+{
+    SKeyTable   KeyTable[MAX_KEY_TABLE];
+} SKeyManagement, DEF* PSKeyManagement;
+
+/*---------------------  Export Types  ------------------------------*/
+
+/*---------------------  Export Macros ------------------------------*/
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+#ifdef __cplusplus
+extern "C" {                            /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+VOID KeyvInitTable(PVOID pDeviceHandler, PSKeyManagement pTable);
+
+BOOL KeybGetKey(
+    IN  PSKeyManagement pTable,
+    IN  PBYTE           pbyBSSID,
+    IN  DWORD           dwKeyIndex,
+    OUT PSKeyItem       *pKey
+    );
+
+BOOL KeybSetKey(
+    PVOID           pDeviceHandler,
+    PSKeyManagement pTable,
+    PBYTE           pbyBSSID,
+    DWORD           dwKeyIndex,
+    ULONG           uKeyLength,
+    PQWORD          pKeyRSC,
+    PBYTE           pbyKey,
+    BYTE            byKeyDecMode
+    );
+
+BOOL KeybRemoveKey(
+    PVOID           pDeviceHandler,
+    PSKeyManagement pTable,
+    PBYTE           pbyBSSID,
+    DWORD           dwKeyIndex
+    );
+
+BOOL KeybRemoveAllKey (
+    PVOID           pDeviceHandler,
+    PSKeyManagement pTable,
+    PBYTE           pbyBSSID
+    );
+
+VOID KeyvRemoveWEPKey(
+    PVOID           pDeviceHandler,
+    PSKeyManagement pTable,
+    DWORD           dwKeyIndex
+    );
+
+VOID KeyvRemoveAllWEPKey(
+    PVOID           pDeviceHandler,
+    PSKeyManagement pTable
+    );
+
+BOOL KeybGetTransmitKey(
+    IN  PSKeyManagement pTable,
+    IN  PBYTE           pbyBSSID,
+    IN  DWORD           dwKeyType,
+    OUT PSKeyItem       *pKey
+    );
+
+BOOL KeybCheckPairewiseKey(
+    IN  PSKeyManagement pTable,
+    OUT PSKeyItem       *pKey
+    );
+
+BOOL KeybSetDefaultKey (
+    PVOID           pDeviceHandler,
+    PSKeyManagement pTable,
+    DWORD           dwKeyIndex,
+    ULONG           uKeyLength,
+    PQWORD          pKeyRSC,
+    PBYTE           pbyKey,
+    BYTE            byKeyDecMode
+    );
+
+BOOL KeybSetAllGroupKey (
+    PVOID           pDeviceHandler,
+    PSKeyManagement pTable,
+    DWORD           dwKeyIndex,
+    ULONG           uKeyLength,
+    PQWORD          pKeyRSC,
+    PBYTE           pbyKey,
+    BYTE            byKeyDecMode
+    );
+
+
+#ifdef __cplusplus
+}                                       /* End of extern "C" { */
+
+#endif /* __cplusplus */
+
+
+#endif // __KEY_H__
+
diff --git a/drivers/staging/vt6656/mac.c b/drivers/staging/vt6656/mac.c
new file mode 100644
index 0000000..ff83ef4
--- /dev/null
+++ b/drivers/staging/vt6656/mac.c
@@ -0,0 +1,500 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: mac.c
+ *
+ * Purpose:  MAC routines
+ *
+ * Author: Tevin Chen
+ *
+ * Date: May 21, 1996
+ *
+ * Functions:
+ *
+ * Revision History:
+ */
+
+
+
+#if !defined(__TMACRO_H__)
+#include "tmacro.h"
+#endif
+#if !defined(__TBIT_H__)
+#include "tbit.h"
+#endif
+#if !defined(__TETHER_H__)
+#include "tether.h"
+#endif
+#if !defined(__DESC_H__)
+#include "desc.h"
+#endif
+#if !defined(__MAC_H__)
+#include "mac.h"
+#endif
+#if !defined(__80211hdr_H__)
+#include "80211hdr.h"
+#endif
+#if !defined(__RNDIS_H__)
+#include "rndis.h"
+#endif
+#if !defined(__CONTROL_H__)
+#include "control.h"
+#endif
+/*---------------------  Static Definitions -------------------------*/
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+static int          msglevel                =MSG_LEVEL_INFO;
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+
+/*---------------------  Static Functions  --------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+
+
+
+/*
+ * Description:
+ *      Set this hash index into multicast address register bit
+ *
+ * Parameters:
+ *  In:
+ *      byHashIdx   - Hash index to set
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void MACvSetMultiAddrByHash (PSDevice pDevice, BYTE byHashIdx)
+{
+    UINT            uByteIdx;
+    BYTE            byBitMask;
+    BYTE            pbyData[2];
+
+
+    // calculate byte position
+    uByteIdx = byHashIdx / 8;
+
+    // calculate bit position
+    byBitMask = 1;
+    byBitMask <<= (byHashIdx % 8);
+    // turn on the bit
+
+    pbyData[0] = byBitMask;
+    pbyData[1] = byBitMask;
+
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_WRITE_MASK,
+                        (WORD) (MAC_REG_MAR0 + uByteIdx),
+                        MESSAGE_REQUEST_MACREG,
+                        2,
+                        pbyData);
+}
+
+
+
+/*
+ * Description:
+ *      Write MAC Multicast Address Mask
+ *
+ * Parameters:
+ *  In:
+ *      uByteidx    - Index of Mask
+ *      byData      - Mask Value to write
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+VOID MACvWriteMultiAddr (PSDevice pDevice, UINT uByteIdx, BYTE byData)
+{
+    BYTE            byData1;
+
+    byData1 = byData;
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_WRITE,
+                        (WORD) (MAC_REG_MAR0 + uByteIdx),
+                        MESSAGE_REQUEST_MACREG,
+                        1,
+                        &byData1);
+}
+
+
+/*
+ * Description:
+ *      Shut Down MAC
+ *
+ * Parameters:
+ *  In:
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if success; otherwise FALSE
+ *
+ */
+BOOL MACbShutdown (PSDevice pDevice)
+{
+    CONTROLnsRequestOutAsyn(pDevice,
+                        MESSAGE_TYPE_MACSHUTDOWN,
+                        0,
+                        0,
+                        0,
+                        NULL
+                        );
+    return TRUE;
+}
+
+void MACvSetBBType(PSDevice pDevice,BYTE byType)
+{
+BYTE            pbyData[2];
+
+
+    pbyData[0] = byType;
+    pbyData[1] = EnCFG_BBType_MASK;
+
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_WRITE_MASK,
+                        MAC_REG_ENCFG0,
+                        MESSAGE_REQUEST_MACREG,
+                        2,
+                        pbyData
+                        );
+}
+
+void MACvSetMISCFifo (PSDevice pDevice, WORD wOffset, DWORD dwData)
+{
+BYTE    pbyData[4];
+
+    if (wOffset > 273)
+        return;
+    pbyData[0] = (BYTE)dwData;
+    pbyData[1] = (BYTE)(dwData>>8);
+    pbyData[2] = (BYTE)(dwData>>16);
+    pbyData[3] = (BYTE)(dwData>>24);
+
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_WRITE_MISCFF,
+                        wOffset,
+                        0,
+                        4,
+                        pbyData
+                        );
+}
+
+/*
+ * Description:
+ *      Disable the Key Entry by MISCFIFO
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase        - Base Address for MAC
+ *
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void MACvDisableKeyEntry (PSDevice pDevice, UINT uEntryIdx)
+{
+WORD    wOffset;
+BYTE            byData;
+
+
+    byData = (BYTE) uEntryIdx;
+
+    wOffset = MISCFIFO_KEYETRY0;
+    wOffset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE);
+
+    //VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
+    //VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, 0);
+    //VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
+
+    //issue write misc fifo command to device
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_CLRKEYENTRY,
+                        0,
+                        0,
+                        1,
+                        &byData
+                        );
+}
+
+
+/*
+ * Description:
+ *      Set the Key by MISCFIFO
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase        - Base Address for MAC
+ *
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void MACvSetKeyEntry (PSDevice pDevice, WORD wKeyCtl, UINT uEntryIdx, UINT uKeyIdx, PBYTE pbyAddr, PDWORD pdwKey)
+{
+PBYTE           pbyKey;
+WORD            wOffset;
+DWORD           dwData1,dwData2;
+int             ii;
+BYTE            pbyData[24];
+
+
+
+
+
+    if ( pDevice->byLocalID <= MAC_REVISION_A1 ) {
+        if ( pDevice->sMgmtObj.byCSSPK == KEY_CTL_CCMP )
+            return;
+    }
+
+    wOffset = MISCFIFO_KEYETRY0;
+    wOffset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE);
+
+    dwData1 = 0;
+    dwData1 |= wKeyCtl;
+    dwData1 <<= 16;
+    dwData1 |= MAKEWORD(*(pbyAddr+4), *(pbyAddr+5));
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"1. wOffset: %d, Data: %lX, KeyCtl:%X\n", wOffset, dwData1, wKeyCtl);
+
+    //VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
+    //VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
+    //VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
+
+    //wOffset++;
+
+    dwData2 = 0;
+    dwData2 |= *(pbyAddr+3);
+    dwData2 <<= 8;
+    dwData2 |= *(pbyAddr+2);
+    dwData2 <<= 8;
+    dwData2 |= *(pbyAddr+1);
+    dwData2 <<= 8;
+    dwData2 |= *(pbyAddr+0);
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"2. wOffset: %d, Data: %lX\n", wOffset, dwData2);
+
+    //VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
+    //VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
+    //VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
+
+    //wOffset++;
+
+    //wOffset += (uKeyIdx * 4);
+/*    for (ii=0;ii<4;ii++) {
+        // alway push 128 bits
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"3.(%d) wOffset: %d, Data: %lX\n", ii, wOffset+ii, *pdwKey);
+        VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset+ii);
+        VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, *pdwKey++);
+        VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
+    }
+*/
+    pbyKey = (PBYTE)pdwKey;
+
+    pbyData[0] = (BYTE)dwData1;
+    pbyData[1] = (BYTE)(dwData1>>8);
+    pbyData[2] = (BYTE)(dwData1>>16);
+    pbyData[3] = (BYTE)(dwData1>>24);
+    pbyData[4] = (BYTE)dwData2;
+    pbyData[5] = (BYTE)(dwData2>>8);
+    pbyData[6] = (BYTE)(dwData2>>16);
+    pbyData[7] = (BYTE)(dwData2>>24);
+    for(ii=8;ii<24;ii++)
+        pbyData[ii] = *pbyKey++;
+
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_SETKEY,
+                        wOffset,
+                        (WORD)uKeyIdx,
+                        24,
+                        pbyData
+                        );
+
+
+}
+
+
+void MACvRegBitsOff(PSDevice pDevice, BYTE byRegOfs, BYTE byBits)
+{
+BYTE            pbyData[2];
+
+    pbyData[0] = 0;
+    pbyData[1] = byBits;
+
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_WRITE_MASK,
+                        byRegOfs,
+                        MESSAGE_REQUEST_MACREG,
+                        2,
+                        pbyData
+                        );
+}
+
+
+void MACvRegBitsOn(PSDevice pDevice, BYTE byRegOfs, BYTE byBits)
+{
+BYTE            pbyData[2];
+
+
+    pbyData[0] = byBits;
+    pbyData[1] = byBits;
+
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_WRITE_MASK,
+                        byRegOfs,
+                        MESSAGE_REQUEST_MACREG,
+                        2,
+                        pbyData
+                        );
+}
+
+void MACvWriteWord(PSDevice pDevice, BYTE byRegOfs, WORD wData)
+{
+BYTE            pbyData[2];
+
+
+    pbyData[0] = (BYTE)(wData & 0xff);
+    pbyData[1] = (BYTE)(wData >> 8);
+
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_WRITE,
+                        byRegOfs,
+                        MESSAGE_REQUEST_MACREG,
+                        2,
+                        pbyData
+                        );
+
+}
+
+void MACvWriteBSSIDAddress(PSDevice pDevice, PBYTE pbyEtherAddr)
+{
+BYTE            pbyData[6];
+
+
+    pbyData[0] = *((PBYTE)pbyEtherAddr);
+    pbyData[1] = *((PBYTE)pbyEtherAddr+1);
+    pbyData[2] = *((PBYTE)pbyEtherAddr+2);
+    pbyData[3] = *((PBYTE)pbyEtherAddr+3);
+    pbyData[4] = *((PBYTE)pbyEtherAddr+4);
+    pbyData[5] = *((PBYTE)pbyEtherAddr+5);
+
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_WRITE,
+                        MAC_REG_BSSID0,
+                        MESSAGE_REQUEST_MACREG,
+                        6,
+                        pbyData
+                        );
+}
+
+void MACvEnableProtectMD(PSDevice pDevice)
+{
+BYTE            pbyData[2];
+
+
+    pbyData[0] = EnCFG_ProtectMd;
+    pbyData[1] = EnCFG_ProtectMd;
+
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_WRITE_MASK,
+                        MAC_REG_ENCFG0,
+                        MESSAGE_REQUEST_MACREG,
+                        2,
+                        pbyData
+                        );
+}
+
+void MACvDisableProtectMD(PSDevice pDevice)
+{
+BYTE            pbyData[2];
+
+
+    pbyData[0] = 0;
+    pbyData[1] = EnCFG_ProtectMd;
+
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_WRITE_MASK,
+                        MAC_REG_ENCFG0,
+                        MESSAGE_REQUEST_MACREG,
+                        2,
+                        pbyData
+                        );
+}
+
+void MACvEnableBarkerPreambleMd(PSDevice pDevice)
+{
+BYTE            pbyData[2];
+
+
+    pbyData[0] = EnCFG_BarkerPream;
+    pbyData[1] = EnCFG_BarkerPream;
+
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_WRITE_MASK,
+                        MAC_REG_ENCFG2,
+                        MESSAGE_REQUEST_MACREG,
+                        2,
+                        pbyData
+                        );
+}
+
+void MACvDisableBarkerPreambleMd(PSDevice pDevice)
+{
+BYTE            pbyData[2];
+
+
+    pbyData[0] = 0;
+    pbyData[1] = EnCFG_BarkerPream;
+
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_WRITE_MASK,
+                        MAC_REG_ENCFG2,
+                        MESSAGE_REQUEST_MACREG,
+                        2,
+                        pbyData
+                        );
+}
+
+
+void MACvWriteBeaconInterval(PSDevice pDevice, WORD wInterval)
+{
+BYTE            pbyData[2];
+
+    pbyData[0] = (BYTE) (wInterval & 0xff);
+    pbyData[1] = (BYTE) (wInterval >> 8);
+
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_WRITE,
+                        MAC_REG_BI,
+                        MESSAGE_REQUEST_MACREG,
+                        2,
+                        pbyData
+                        );
+}
diff --git a/drivers/staging/vt6656/mac.h b/drivers/staging/vt6656/mac.h
new file mode 100644
index 0000000..78ba7fc
--- /dev/null
+++ b/drivers/staging/vt6656/mac.h
@@ -0,0 +1,458 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: mac.h
+ *
+ * Purpose: MAC routines
+ *
+ * Author: Tevin Chen
+ *
+ * Date: May 21, 1996
+ *
+ * Revision History:
+ *      07-01-2003 Bryan YC Fan:  Re-write codes to support VT3253 spec.
+ *      08-25-2003 Kyle Hsu:      Porting MAC functions from sim53.
+ *      09-03-2003 Bryan YC Fan:  Add MACvDisableProtectMD & MACvEnableProtectMD
+ */
+
+#ifndef __MAC_H__
+#define __MAC_H__
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+#if !defined(__DEVICE_H__)
+#include "device.h"
+#endif
+#if !defined(__TMACRO_H__)
+#include "tmacro.h"
+#endif
+#if !defined(__UMEM_H__)
+#include "umem.h"
+#endif
+
+/*---------------------  Export Definitions -------------------------*/
+
+#define REV_ID_VT3253_A0    0x00
+#define REV_ID_VT3253_A1    0x01
+#define REV_ID_VT3253_B0    0x08
+#define REV_ID_VT3253_B1    0x09
+
+//
+// Registers in the MAC
+//
+#define MAC_REG_BISTCMD     0x04
+#define MAC_REG_BISTSR0     0x05
+#define MAC_REG_BISTSR1     0x06
+#define MAC_REG_BISTSR2     0x07
+#define MAC_REG_I2MCSR      0x08
+#define MAC_REG_I2MTGID     0x09
+#define MAC_REG_I2MTGAD     0x0A
+#define MAC_REG_I2MCFG      0x0B
+#define MAC_REG_I2MDIPT     0x0C
+#define MAC_REG_I2MDOPT     0x0E
+#define MAC_REG_USBSUS      0x0F
+
+#define MAC_REG_LOCALID     0x14
+#define MAC_REG_TESTCFG     0x15
+#define MAC_REG_JUMPER0     0x16
+#define MAC_REG_JUMPER1     0x17
+#define MAC_REG_TMCTL       0x18
+#define MAC_REG_TMDATA0     0x1C
+#define MAC_REG_TMDATA1     0x1D
+#define MAC_REG_TMDATA2     0x1E
+#define MAC_REG_TMDATA3     0x1F
+
+// MAC Parameter related
+#define MAC_REG_LRT         0x20        //
+#define MAC_REG_SRT         0x21        //
+#define MAC_REG_SIFS        0x22        //
+#define MAC_REG_DIFS        0x23        //
+#define MAC_REG_EIFS        0x24        //
+#define MAC_REG_SLOT        0x25        //
+#define MAC_REG_BI          0x26        //
+#define MAC_REG_CWMAXMIN0   0x28        //
+#define MAC_REG_LINKOFFTOTM 0x2A
+#define MAC_REG_SWTMOT      0x2B
+#define MAC_REG_RTSOKCNT    0x2C
+#define MAC_REG_RTSFAILCNT  0x2D
+#define MAC_REG_ACKFAILCNT  0x2E
+#define MAC_REG_FCSERRCNT   0x2F
+// TSF Related
+#define MAC_REG_TSFCNTR     0x30        //
+#define MAC_REG_NEXTTBTT    0x38        //
+#define MAC_REG_TSFOFST     0x40        //
+#define MAC_REG_TFTCTL      0x48        //
+// WMAC Control/Status Related
+#define MAC_REG_ENCFG0      0x4C        //
+#define MAC_REG_ENCFG1      0x4D        //
+#define MAC_REG_ENCFG2      0x4E        //
+
+#define MAC_REG_CFG         0x50        //
+#define MAC_REG_TEST        0x52        //
+#define MAC_REG_HOSTCR      0x54        //
+#define MAC_REG_MACCR       0x55        //
+#define MAC_REG_RCR         0x56        //
+#define MAC_REG_TCR         0x57        //
+#define MAC_REG_IMR         0x58        //
+#define MAC_REG_ISR         0x5C
+#define MAC_REG_ISR1        0x5D
+// Power Saving Related
+#define MAC_REG_PSCFG       0x60        //
+#define MAC_REG_PSCTL       0x61        //
+#define MAC_REG_PSPWRSIG    0x62        //
+#define MAC_REG_BBCR13      0x63
+#define MAC_REG_AIDATIM     0x64
+#define MAC_REG_PWBT        0x66
+#define MAC_REG_WAKEOKTMR   0x68
+#define MAC_REG_CALTMR      0x69
+#define MAC_REG_SYNSPACCNT  0x6A
+#define MAC_REG_WAKSYNOPT   0x6B
+// Baseband/IF Control Group
+#define MAC_REG_BBREGCTL    0x6C        //
+#define MAC_REG_CHANNEL     0x6D
+#define MAC_REG_BBREGADR    0x6E
+#define MAC_REG_BBREGDATA   0x6F
+#define MAC_REG_IFREGCTL    0x70        //
+#define MAC_REG_IFDATA      0x71        //
+#define MAC_REG_ITRTMSET    0x74        //
+#define MAC_REG_PAPEDELAY   0x77
+#define MAC_REG_SOFTPWRCTL  0x78        //
+#define MAC_REG_SOFTPWRCTL2 0x79        //
+#define MAC_REG_GPIOCTL0    0x7A        //
+#define MAC_REG_GPIOCTL1    0x7B        //
+
+// MiscFF PIO related
+#define MAC_REG_MISCFFNDEX  0xBC
+#define MAC_REG_MISCFFCTL   0xBE
+#define MAC_REG_MISCFFDATA  0xC0
+
+// MAC Configuration Group
+#define MAC_REG_PAR0        0xC4
+#define MAC_REG_PAR4        0xC8
+#define MAC_REG_BSSID0      0xCC
+#define MAC_REG_BSSID4      0xD0
+#define MAC_REG_MAR0        0xD4
+#define MAC_REG_MAR4        0xD8
+// MAC RSPPKT INFO Group
+#define MAC_REG_RSPINF_B_1  0xDC
+#define MAC_REG_RSPINF_B_2  0xE0
+#define MAC_REG_RSPINF_B_5  0xE4
+#define MAC_REG_RSPINF_B_11 0xE8
+#define MAC_REG_RSPINF_A_6  0xEC
+#define MAC_REG_RSPINF_A_9  0xEE
+#define MAC_REG_RSPINF_A_12 0xF0
+#define MAC_REG_RSPINF_A_18 0xF2
+#define MAC_REG_RSPINF_A_24 0xF4
+#define MAC_REG_RSPINF_A_36 0xF6
+#define MAC_REG_RSPINF_A_48 0xF8
+#define MAC_REG_RSPINF_A_54 0xFA
+#define MAC_REG_RSPINF_A_72 0xFC
+
+
+//
+// Bits in the I2MCFG EEPROM register
+//
+#define I2MCFG_BOUNDCTL     0x80
+#define I2MCFG_WAITCTL      0x20
+#define I2MCFG_SCLOECTL     0x10
+#define I2MCFG_WBUSYCTL     0x08
+#define I2MCFG_NORETRY      0x04
+#define I2MCFG_I2MLDSEQ     0x02
+#define I2MCFG_I2CMFAST     0x01
+
+//
+// Bits in the I2MCSR EEPROM register
+//
+#define I2MCSR_EEMW         0x80
+#define I2MCSR_EEMR         0x40
+#define I2MCSR_AUTOLD       0x08
+#define I2MCSR_NACK         0x02
+#define I2MCSR_DONE         0x01
+
+//
+// Bits in the TMCTL register
+//
+#define TMCTL_TSUSP         0x04
+#define TMCTL_TMD           0x02
+#define TMCTL_TE            0x01
+
+//
+// Bits in the TFTCTL register
+//
+#define TFTCTL_HWUTSF       0x80        //
+#define TFTCTL_TBTTSYNC     0x40
+#define TFTCTL_HWUTSFEN     0x20
+#define TFTCTL_TSFCNTRRD    0x10        //
+#define TFTCTL_TBTTSYNCEN   0x08        //
+#define TFTCTL_TSFSYNCEN    0x04        //
+#define TFTCTL_TSFCNTRST    0x02        //
+#define TFTCTL_TSFCNTREN    0x01        //
+
+//
+// Bits in the EnhanceCFG_0 register
+//
+#define EnCFG_BBType_a      0x00
+#define EnCFG_BBType_b      0x01
+#define EnCFG_BBType_g      0x02
+#define EnCFG_BBType_MASK   0x03
+#define EnCFG_ProtectMd     0x20
+
+//
+// Bits in the EnhanceCFG_1 register
+//
+#define EnCFG_BcnSusInd     0x01
+#define EnCFG_BcnSusClr     0x02
+
+//
+// Bits in the EnhanceCFG_2 register
+//
+#define EnCFG_NXTBTTCFPSTR  0x01
+#define EnCFG_BarkerPream   0x02
+#define EnCFG_PktBurstMode  0x04
+
+//
+// Bits in the CFG register
+//
+#define CFG_TKIPOPT         0x80
+#define CFG_RXDMAOPT        0x40
+#define CFG_TMOT_SW         0x20
+#define CFG_TMOT_HWLONG     0x10
+#define CFG_TMOT_HW         0x00
+#define CFG_CFPENDOPT       0x08
+#define CFG_BCNSUSEN        0x04
+#define CFG_NOTXTIMEOUT     0x02
+#define CFG_NOBUFOPT        0x01
+
+//
+// Bits in the TEST register
+//
+#define TEST_LBEXT          0x80        //
+#define TEST_LBINT          0x40        //
+#define TEST_LBNONE         0x00        //
+#define TEST_SOFTINT        0x20        //
+#define TEST_CONTTX         0x10        //
+#define TEST_TXPE           0x08        //
+#define TEST_NAVDIS         0x04        //
+#define TEST_NOCTS          0x02        //
+#define TEST_NOACK          0x01        //
+
+//
+// Bits in the HOSTCR register
+//
+#define HOSTCR_TXONST       0x80        //
+#define HOSTCR_RXONST       0x40        //
+#define HOSTCR_ADHOC        0x20        // Network Type 1 = Ad-hoc
+#define HOSTCR_AP           0x10        // Port Type 1 = AP
+#define HOSTCR_TXON         0x08        //0000 1000
+#define HOSTCR_RXON         0x04        //0000 0100
+#define HOSTCR_MACEN        0x02        //0000 0010
+#define HOSTCR_SOFTRST      0x01        //0000 0001
+
+//
+// Bits in the MACCR register
+//
+#define MACCR_SYNCFLUSHOK   0x04        //
+#define MACCR_SYNCFLUSH     0x02        //
+#define MACCR_CLRNAV        0x01        //
+
+//
+// Bits in the RCR register
+//
+#define RCR_SSID            0x80
+#define RCR_RXALLTYPE       0x40        //
+#define RCR_UNICAST         0x20        //
+#define RCR_BROADCAST       0x10        //
+#define RCR_MULTICAST       0x08        //
+#define RCR_WPAERR          0x04        //
+#define RCR_ERRCRC          0x02        //
+#define RCR_BSSID           0x01        //
+
+//
+// Bits in the TCR register
+//
+#define TCR_SYNCDCFOPT      0x02        //
+#define TCR_AUTOBCNTX       0x01        // Beacon automatically transmit enable
+
+
+//ISR1
+#define ISR_GPIO3           0x40
+#define ISR_RXNOBUF         0x08
+#define ISR_MIBNEARFULL     0x04
+#define ISR_SOFTINT         0x02
+#define ISR_FETALERR        0x01
+
+#define LEDSTS_STS          0x06
+#define LEDSTS_TMLEN        0x78
+#define LEDSTS_OFF          0x00
+#define LEDSTS_ON           0x02
+#define LEDSTS_SLOW         0x04
+#define LEDSTS_INTER        0x06
+
+//ISR0
+#define ISR_WATCHDOG        0x80
+#define ISR_SOFTTIMER       0x40
+#define ISR_GPIO0           0x20
+#define ISR_TBTT            0x10
+#define ISR_RXDMA0          0x08
+#define ISR_BNTX            0x04
+#define ISR_ACTX            0x01
+
+//
+// Bits in the PSCFG register
+//
+#define PSCFG_PHILIPMD      0x40        //
+#define PSCFG_WAKECALEN     0x20        //
+#define PSCFG_WAKETMREN     0x10        //
+#define PSCFG_BBPSPROG      0x08        //
+#define PSCFG_WAKESYN       0x04        //
+#define PSCFG_SLEEPSYN      0x02        //
+#define PSCFG_AUTOSLEEP     0x01        //
+
+//
+// Bits in the PSCTL register
+//
+#define PSCTL_WAKEDONE      0x20        //
+#define PSCTL_PS            0x10        //
+#define PSCTL_GO2DOZE       0x08        //
+#define PSCTL_LNBCN         0x04        //
+#define PSCTL_ALBCN         0x02        //
+#define PSCTL_PSEN          0x01        //
+
+//
+// Bits in the PSPWSIG register
+//
+#define PSSIG_WPE3          0x80        //
+#define PSSIG_WPE2          0x40        //
+#define PSSIG_WPE1          0x20        //
+#define PSSIG_WRADIOPE      0x10        //
+#define PSSIG_SPE3          0x08        //
+#define PSSIG_SPE2          0x04        //
+#define PSSIG_SPE1          0x02        //
+#define PSSIG_SRADIOPE      0x01        //
+
+//
+// Bits in the BBREGCTL register
+//
+#define BBREGCTL_DONE       0x04        //
+#define BBREGCTL_REGR       0x02        //
+#define BBREGCTL_REGW       0x01        //
+
+//
+// Bits in the IFREGCTL register
+//
+#define IFREGCTL_DONE       0x04        //
+#define IFREGCTL_IFRF       0x02        //
+#define IFREGCTL_REGW       0x01        //
+
+//
+// Bits in the SOFTPWRCTL register
+//
+#define SOFTPWRCTL_RFLEOPT      0x08  //
+#define SOFTPWRCTL_TXPEINV      0x02  //
+#define SOFTPWRCTL_SWPECTI      0x01  //
+#define SOFTPWRCTL_SWPAPE       0x20  //
+#define SOFTPWRCTL_SWCALEN      0x10  //
+#define SOFTPWRCTL_SWRADIO_PE   0x08  //
+#define SOFTPWRCTL_SWPE2        0x04  //
+#define SOFTPWRCTL_SWPE1        0x02  //
+#define SOFTPWRCTL_SWPE3        0x01  //
+
+//
+// Bits in the GPIOCTL1 register
+//
+#define GPIO3_MD                0x20    //
+#define GPIO3_DATA              0x40    //
+#define GPIO3_INTMD             0x80    //
+
+//
+// Bits in the MISCFFCTL register
+//
+#define MISCFFCTL_WRITE     0x0001      //
+
+
+// Loopback mode
+#define MAC_LB_EXT          0x02        //
+#define MAC_LB_INTERNAL     0x01        //
+#define MAC_LB_NONE         0x00        //
+
+// Ethernet address filter type
+#define PKT_TYPE_NONE           0x00    // turn off receiver
+#define PKT_TYPE_ALL_MULTICAST  0x80
+#define PKT_TYPE_PROMISCUOUS    0x40
+#define PKT_TYPE_DIRECTED       0x20    // obselete, directed address is always accepted
+#define PKT_TYPE_BROADCAST      0x10
+#define PKT_TYPE_MULTICAST      0x08
+#define PKT_TYPE_ERROR_WPA      0x04
+#define PKT_TYPE_ERROR_CRC      0x02
+#define PKT_TYPE_BSSID          0x01
+
+#define Default_BI              0x200
+
+// MiscFIFO Offset
+#define MISCFIFO_KEYETRY0       32
+#define MISCFIFO_KEYENTRYSIZE   22
+
+// max time out delay time
+#define W_MAX_TIMEOUT       0xFFF0U     //
+
+// wait time within loop
+#define CB_DELAY_LOOP_WAIT  10          // 10ms
+
+#define MAC_REVISION_A0     0x00
+#define MAC_REVISION_A1     0x01
+
+
+/*---------------------  Export Types  ------------------------------*/
+
+/*---------------------  Export Macros ------------------------------*/
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+#ifdef __cplusplus
+extern "C" {                            /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+void MACvSetMultiAddrByHash (PSDevice pDevice, BYTE byHashIdx);
+VOID MACvWriteMultiAddr (PSDevice pDevice, UINT uByteIdx, BYTE byData);
+BOOL MACbShutdown(PSDevice pDevice);;
+void MACvSetBBType(PSDevice pDevice,BYTE byType);
+void MACvSetMISCFifo (PSDevice pDevice, WORD wOffset, DWORD dwData);
+void MACvDisableKeyEntry(PSDevice pDevice, UINT uEntryIdx);
+void MACvSetKeyEntry(PSDevice pDevice, WORD wKeyCtl, UINT uEntryIdx, UINT uKeyIdx, PBYTE pbyAddr, PDWORD pdwKey);
+
+void MACvRegBitsOff(PSDevice pDevice, BYTE byRegOfs, BYTE byBits);
+void MACvRegBitsOn(PSDevice pDevice, BYTE byRegOfs, BYTE byBits);
+void MACvWriteWord(PSDevice pDevice, BYTE byRegOfs, WORD wData);
+
+void MACvWriteBSSIDAddress(PSDevice pDevice, PBYTE pbyEtherAddr);
+void MACvEnableProtectMD(PSDevice pDevice);
+void MACvDisableProtectMD(PSDevice pDevice);
+void MACvEnableBarkerPreambleMd(PSDevice pDevice);
+void MACvDisableBarkerPreambleMd(PSDevice pDevice);
+void MACvWriteBeaconInterval(PSDevice pDevice, WORD wInterval);
+
+#ifdef __cplusplus
+}                                       /* End of extern "C" { */
+#endif /* __cplusplus */
+
+#endif // __MAC_H__
diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c
new file mode 100644
index 0000000..3368e83
--- /dev/null
+++ b/drivers/staging/vt6656/main_usb.c
@@ -0,0 +1,2398 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: main_usb.c
+ *
+ * Purpose: driver entry for initial, open, close, tx and rx.
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: Dec 8, 2005
+ *
+ * Functions:
+ *
+ *   vntwusb_found1 - module initial (insmod) driver entry
+ *   device_remove1 - module remove entry
+ *   device_open - allocate dma/descripter resource & initial mac/bbp function
+ *   device_xmit - asynchrous data tx function
+ *   device_set_multi - set mac filter
+ *   device_ioctl - ioctl entry
+ *   device_close - shutdown mac/bbp & free dma/descripter resource
+ *   device_alloc_frag_buf - rx fragement pre-allocated function
+ *   device_free_tx_bufs - free tx buffer function
+ *   device_dma0_tx_80211- tx 802.11 frame via dma0
+ *   device_dma0_xmit- tx PS bufferred frame via dma0
+ *   device_init_registers- initial MAC & BBP & RF internal registers.
+ *   device_init_rings- initial tx/rx ring buffer
+ *   device_init_defrag_cb- initial & allocate de-fragement buffer.
+ *   device_tx_srv- tx interrupt service function
+ *
+ * Revision History:
+ */
+#undef __NO_VERSION__
+
+#if !defined(__DEVICE_H__)
+#include "device.h"
+#endif
+#if !defined(__CARD_H__)
+#include "card.h"
+#endif
+#if !defined(__TBIT_H__)
+#include "tbit.h"
+#endif
+#if !defined(__BASEBAND_H__)
+#include "baseband.h"
+#endif
+#if !defined(__MAC_H__)
+#include "mac.h"
+#endif
+#if !defined(__TETHER_H__)
+#include "tether.h"
+#endif
+#if !defined(__WMGR_H__)
+#include "wmgr.h"
+#endif
+#if !defined(__WCTL_H__)
+#include "wctl.h"
+#endif
+#if !defined(__POWER_H__)
+#include "power.h"
+#endif
+#if !defined(__WCMD_H__)
+#include "wcmd.h"
+#endif
+#if !defined(__IOCMD_H__)
+#include "iocmd.h"
+#endif
+#if !defined(__TCRC_H__)
+#include "tcrc.h"
+#endif
+#if !defined(__RXTX_H__)
+#include "rxtx.h"
+#endif
+#if !defined(__BSSDB_H__)
+#include "bssdb.h"
+#endif
+#if !defined(__HOSTAP_H__)
+#include "hostap.h"
+#endif
+#if !defined(__WPACTL_H__)
+#include "wpactl.h"
+#endif
+#if !defined(__IOCTL_H__)
+#include "ioctl.h"
+#endif
+#if !defined(__IWCTL_H__)
+#include "iwctl.h"
+#endif
+#if !defined(__DPC_H__)
+#include "dpc.h"
+#endif
+#if !defined(__IOCMD_H__)
+#include "iocmd.h"
+#endif
+#if !defined(__DATARATE_H__)
+#include "datarate.h"
+#endif
+#if !defined(__RF_H__)
+#include "rf.h"
+#endif
+#if !defined(__FIRMWARE_H__)
+#include "firmware.h"
+#endif
+
+#if !defined(__MAC_H__)
+#include "mac.h"
+#endif
+
+#if !defined(__RNDIS_H__)
+#include "rndis.h"
+#endif
+#if !defined(__CONTROL_H__)
+#include "control.h"
+#endif
+#if !defined (_CHANNEL_H_)
+#include "channel.h"
+#endif
+#if !defined(__INT_H__)
+#include "int.h"
+#endif
+#if !defined(__IOWPA_H__)
+#include "iowpa.h"
+#endif
+
+/*---------------------  Static Definitions -------------------------*/
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+static int          msglevel                =MSG_LEVEL_INFO;
+
+//
+// Define module options
+//
+
+// Version Information
+#define DRIVER_AUTHOR "VIA Networking Technologies, Inc., <lyndonchen at vntek.com.tw>"
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION(DEVICE_FULL_DRV_NAM);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
+#define DEVICE_PARAM(N,D) \
+        static int N[MAX_UINTS]=OPTION_DEFAULT;\
+        module_param_array(N, int, NULL, 0);\
+        MODULE_PARM_DESC(N, D);
+
+#else
+#define DEVICE_PARAM(N,D) \
+        static const int N[MAX_UINTS]=OPTION_DEFAULT;\
+        MODULE_PARM(N, "1-" __MODULE_STRING(MAX_UINTS) "i");\
+        MODULE_PARM_DESC(N, D);
+#endif
+
+#define RX_DESC_MIN0     16
+#define RX_DESC_MAX0     128
+#define RX_DESC_DEF0     64
+DEVICE_PARAM(RxDescriptors0,"Number of receive usb desc buffer");
+
+
+#define TX_DESC_MIN0     16
+#define TX_DESC_MAX0     128
+#define TX_DESC_DEF0     64
+DEVICE_PARAM(TxDescriptors0,"Number of transmit usb desc buffer");
+
+
+#define CHANNEL_MIN     1
+#define CHANNEL_MAX     14
+#define CHANNEL_DEF     6
+
+DEVICE_PARAM(Channel, "Channel number");
+
+
+/* PreambleType[] is the preamble length used for transmit.
+   0: indicate allows long preamble type
+   1: indicate allows short preamble type
+*/
+
+#define PREAMBLE_TYPE_DEF     1
+
+DEVICE_PARAM(PreambleType, "Preamble Type");
+
+
+#define RTS_THRESH_MIN     512
+#define RTS_THRESH_MAX     2347
+#define RTS_THRESH_DEF     2347
+
+DEVICE_PARAM(RTSThreshold, "RTS threshold");
+
+
+#define FRAG_THRESH_MIN     256
+#define FRAG_THRESH_MAX     2346
+#define FRAG_THRESH_DEF     2346
+
+DEVICE_PARAM(FragThreshold, "Fragmentation threshold");
+
+
+#define DATA_RATE_MIN     0
+#define DATA_RATE_MAX     13
+#define DATA_RATE_DEF     13
+/* datarate[] index
+   0: indicate 1 Mbps   0x02
+   1: indicate 2 Mbps   0x04
+   2: indicate 5.5 Mbps 0x0B
+   3: indicate 11 Mbps  0x16
+   4: indicate 6 Mbps   0x0c
+   5: indicate 9 Mbps   0x12
+   6: indicate 12 Mbps  0x18
+   7: indicate 18 Mbps  0x24
+   8: indicate 24 Mbps  0x30
+   9: indicate 36 Mbps  0x48
+  10: indicate 48 Mbps  0x60
+  11: indicate 54 Mbps  0x6c
+  12: indicate 72 Mbps  0x90
+  13: indicate auto rate
+*/
+
+DEVICE_PARAM(ConnectionRate, "Connection data rate");
+
+#define OP_MODE_MAX     2
+#define OP_MODE_DEF     0
+#define OP_MODE_MIN     0
+
+DEVICE_PARAM(OPMode, "Infrastruct, adhoc, AP mode ");
+
+/* OpMode[] is used for transmit.
+   0: indicate infrastruct mode used
+   1: indicate adhoc mode used
+   2: indicate AP mode used
+*/
+
+
+/* PSMode[]
+   0: indicate disable power saving mode
+   1: indicate enable power saving mode
+*/
+
+#define PS_MODE_DEF     0
+
+DEVICE_PARAM(PSMode, "Power saving mode");
+
+
+#define SHORT_RETRY_MIN     0
+#define SHORT_RETRY_MAX     31
+#define SHORT_RETRY_DEF     8
+
+
+DEVICE_PARAM(ShortRetryLimit, "Short frame retry limits");
+
+#define LONG_RETRY_MIN     0
+#define LONG_RETRY_MAX     15
+#define LONG_RETRY_DEF     4
+
+
+DEVICE_PARAM(LongRetryLimit, "long frame retry limits");
+
+
+/* BasebandType[] baseband type selected
+   0: indicate 802.11a type
+   1: indicate 802.11b type
+   2: indicate 802.11g type
+*/
+#define BBP_TYPE_MIN     0
+#define BBP_TYPE_MAX     2
+#define BBP_TYPE_DEF     2
+
+DEVICE_PARAM(BasebandType, "baseband type");
+
+
+
+/* 80211hEnable[]
+   0: indicate disable 802.11h
+   1: indicate enable 802.11h
+*/
+
+#define X80211h_MODE_DEF     0
+
+DEVICE_PARAM(b80211hEnable, "802.11h mode");
+
+
+//
+// Static vars definitions
+//
+
+
+
+static struct usb_device_id vntwusb_table[] = {
+	{USB_DEVICE(VNT_USB_VENDOR_ID, VNT_USB_PRODUCT_ID)},
+	{}
+};
+
+
+
+#ifdef WIRELESS_EXT
+// Frequency list (map channels to frequencies)
+/*
+static const long frequency_list[] = {
+    2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467, 2472, 2484,
+    4915, 4920, 4925, 4935, 4940, 4945, 4960, 4980,
+    5035, 5040, 5045, 5055, 5060, 5080, 5170, 5180, 5190, 5200, 5210, 5220, 5230, 5240,
+    5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680,
+    5700, 5745, 5765, 5785, 5805, 5825
+	};
+
+
+#ifndef IW_ENCODE_NOKEY
+#define IW_ENCODE_NOKEY         0x0800
+#define IW_ENCODE_MODE  (IW_ENCODE_DISABLED | IW_ENCODE_RESTRICTED | IW_ENCODE_OPEN)
+#endif
+
+#if WIRELESS_EXT > 12
+static const struct iw_handler_def	iwctl_handler_def;
+#else
+struct iw_request_info {};
+#endif	//WIRELESS_EXT > 12
+*/
+
+#endif /* WIRELESS_EXT */
+
+
+
+/*---------------------  Static Functions  --------------------------*/
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+
+static int vntwusb_found1(struct usb_interface *intf, const struct usb_device_id *id);
+static void vntwusb_disconnect(struct usb_interface *intf);
+#ifdef CONFIG_PM	/* Minimal support for suspend and resume */
+static int vntwusb_suspend(struct usb_interface *intf, pm_message_t message);
+static int vntwusb_resume(struct usb_interface *intf);
+#endif
+#else
+
+static void* vntwusb_found1(struct usb_device *udev, UINT interface, const struct usb_device_id *id);
+static void vntwusb_disconnect(struct usb_device *udev, void *ptr);
+#endif
+static struct net_device_stats *device_get_stats(struct net_device *dev);
+static int  device_open(struct net_device *dev);
+static int  device_xmit(struct sk_buff *skb, struct net_device *dev);
+static void device_set_multi(struct net_device *dev);
+static int  device_close(struct net_device *dev);
+static int  device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+
+static BOOL device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType);
+static BOOL device_init_defrag_cb(PSDevice pDevice);
+static void device_init_diversity_timer(PSDevice pDevice);
+static int  device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev);
+
+static int  ethtool_ioctl(struct net_device *dev, void *useraddr);
+static void device_free_tx_bufs(PSDevice pDevice);
+static void device_free_rx_bufs(PSDevice pDevice);
+static void device_free_int_bufs(PSDevice pDevice);
+static void device_free_frag_bufs(PSDevice pDevice);
+static BOOL device_alloc_bufs(PSDevice pDevice);
+
+static int Read_config_file(PSDevice pDevice);
+static UCHAR *Config_FileOperation(PSDevice pDevice);
+static int Config_FileGetParameter(UCHAR *string, UCHAR *dest,UCHAR *source);
+
+//2008-0714<Add>by Mike Liu
+static BOOL device_release_WPADEV(PSDevice pDevice);
+
+//2007-1107-01<Add>by MikeLiu
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
+static void usb_device_reset(PSDevice pDevice);
+#endif
+
+
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+static void
+device_set_options(PSDevice pDevice) {
+
+    BYTE    abyBroadcastAddr[U_ETHER_ADDR_LEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+    BYTE    abySNAP_RFC1042[U_ETHER_ADDR_LEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00};
+    BYTE    abySNAP_Bridgetunnel[U_ETHER_ADDR_LEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8};
+
+
+    memcpy(pDevice->abyBroadcastAddr, abyBroadcastAddr, U_ETHER_ADDR_LEN);
+    memcpy(pDevice->abySNAP_RFC1042, abySNAP_RFC1042, U_ETHER_ADDR_LEN);
+    memcpy(pDevice->abySNAP_Bridgetunnel, abySNAP_Bridgetunnel, U_ETHER_ADDR_LEN);
+
+    pDevice->cbTD = TX_DESC_DEF0;
+    pDevice->cbRD = RX_DESC_DEF0;
+    pDevice->uChannel = CHANNEL_DEF;
+    pDevice->wRTSThreshold = RTS_THRESH_DEF;
+    pDevice->wFragmentationThreshold = FRAG_THRESH_DEF;
+    pDevice->byShortRetryLimit = SHORT_RETRY_DEF;
+    pDevice->byLongRetryLimit = LONG_RETRY_DEF;
+    pDevice->wMaxTransmitMSDULifetime = DEFAULT_MSDU_LIFETIME;
+    pDevice->byShortPreamble = PREAMBLE_TYPE_DEF;
+    pDevice->ePSMode = PS_MODE_DEF;
+    pDevice->b11hEnable = X80211h_MODE_DEF;
+    pDevice->eOPMode = OP_MODE_DEF;
+    pDevice->uConnectionRate = DATA_RATE_DEF;
+    if (pDevice->uConnectionRate < RATE_AUTO) pDevice->bFixRate = TRUE;
+    pDevice->byBBType = BBP_TYPE_DEF;
+    pDevice->byPacketType = pDevice->byBBType;
+    pDevice->byAutoFBCtrl = AUTO_FB_0;
+    pDevice->bUpdateBBVGA = TRUE;
+    pDevice->byFOETuning = 0;
+    pDevice->byAutoPwrTunning = 0;
+    pDevice->wCTSDuration = 0;
+    pDevice->byPreambleType = 0;
+    pDevice->bExistSWNetAddr = FALSE;
+//    pDevice->bDiversityRegCtlON = TRUE;
+    pDevice->bDiversityRegCtlON = FALSE;
+}
+
+
+static VOID device_init_diversity_timer(PSDevice pDevice) {
+
+    init_timer(&pDevice->TimerSQ3Tmax1);
+    pDevice->TimerSQ3Tmax1.data = (ULONG)pDevice;
+    pDevice->TimerSQ3Tmax1.function = (TimerFunction)TimerSQ3CallBack;
+    pDevice->TimerSQ3Tmax1.expires = RUN_AT(HZ);
+
+    init_timer(&pDevice->TimerSQ3Tmax2);
+    pDevice->TimerSQ3Tmax2.data = (ULONG)pDevice;
+    pDevice->TimerSQ3Tmax2.function = (TimerFunction)TimerSQ3CallBack;
+    pDevice->TimerSQ3Tmax2.expires = RUN_AT(HZ);
+
+    init_timer(&pDevice->TimerSQ3Tmax3);
+    pDevice->TimerSQ3Tmax3.data = (ULONG)pDevice;
+    pDevice->TimerSQ3Tmax3.function = (TimerFunction)TimerSQ3Tmax3CallBack;
+    pDevice->TimerSQ3Tmax3.expires = RUN_AT(HZ);
+
+    return;
+}
+
+
+//
+// Initialiation of MAC & BBP registers
+//
+
+static BOOL device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType)
+{
+    BYTE            abyBroadcastAddr[U_ETHER_ADDR_LEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+    BYTE            abySNAP_RFC1042[U_ETHER_ADDR_LEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00};
+    BYTE            abySNAP_Bridgetunnel[U_ETHER_ADDR_LEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8};
+    BYTE            byAntenna;
+    UINT            ii;
+    CMD_CARD_INIT   sInitCmd;
+    NTSTATUS        ntStatus = STATUS_SUCCESS;
+    RSP_CARD_INIT   sInitRsp;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    BYTE            byTmp;
+    BYTE            byCalibTXIQ = 0;
+    BYTE            byCalibTXDC = 0;
+    BYTE            byCalibRXIQ = 0;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "---->INIbInitAdapter. [%d][%d]\n", InitType, pDevice->byPacketType);
+	spin_lock_irq(&pDevice->lock);
+    if (InitType == DEVICE_INIT_COLD) {
+        memcpy(pDevice->abyBroadcastAddr, abyBroadcastAddr, U_ETHER_ADDR_LEN);
+        memcpy(pDevice->abySNAP_RFC1042, abySNAP_RFC1042, U_ETHER_ADDR_LEN);
+        memcpy(pDevice->abySNAP_Bridgetunnel, abySNAP_Bridgetunnel, U_ETHER_ADDR_LEN);
+
+        if ( !FIRMWAREbCheckVersion(pDevice) ) {
+            if (FIRMWAREbDownload(pDevice) == TRUE) {
+                if (FIRMWAREbBrach2Sram(pDevice) == FALSE) {
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" FIRMWAREbBrach2Sram fail \n");
+                  	spin_unlock_irq(&pDevice->lock);
+                    return FALSE;
+                }
+            } else {
+
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" FIRMWAREbDownload fail \n");
+                spin_unlock_irq(&pDevice->lock);
+                return FALSE;
+            }
+        }
+
+        if ( !BBbVT3184Init(pDevice) ) {
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" BBbVT3184Init fail \n");
+            spin_unlock_irq(&pDevice->lock);
+            return FALSE;
+        }
+    }
+
+    sInitCmd.byInitClass = (BYTE)InitType;
+    sInitCmd.bExistSWNetAddr = (BYTE) pDevice->bExistSWNetAddr;
+    for(ii=0;ii<6;ii++)
+        sInitCmd.bySWNetAddr[ii] = pDevice->abyCurrentNetAddr[ii];
+    sInitCmd.byShortRetryLimit = pDevice->byShortRetryLimit;
+    sInitCmd.byLongRetryLimit = pDevice->byLongRetryLimit;
+
+    //issue Card_init command to device
+    ntStatus = CONTROLnsRequestOut(pDevice,
+                                    MESSAGE_TYPE_CARDINIT,
+                                    0,
+                                    0,
+                                    sizeof(CMD_CARD_INIT),
+                                    (PBYTE) &(sInitCmd));
+
+    if ( ntStatus != STATUS_SUCCESS ) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Issue Card init fail \n");
+        spin_unlock_irq(&pDevice->lock);
+        return FALSE;
+    }
+    if (InitType == DEVICE_INIT_COLD) {
+
+        ntStatus = CONTROLnsRequestIn(pDevice,MESSAGE_TYPE_INIT_RSP,0,0,sizeof(RSP_CARD_INIT), (PBYTE) &(sInitRsp));
+
+        if (ntStatus != STATUS_SUCCESS) {
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Cardinit request in status fail!\n");
+            spin_unlock_irq(&pDevice->lock);
+            return FALSE;
+        }
+
+        //Local ID for AES functions
+        ntStatus = CONTROLnsRequestIn(pDevice,
+                                    MESSAGE_TYPE_READ,
+                                    MAC_REG_LOCALID,
+                                    MESSAGE_REQUEST_MACREG,
+                                    1,
+                                    &pDevice->byLocalID);
+
+        if ( ntStatus != STATUS_SUCCESS ) {
+            spin_unlock_irq(&pDevice->lock);
+            return FALSE;
+        }
+
+        // Do MACbSoftwareReset in MACvInitialize
+        // force CCK
+        pDevice->bCCK = TRUE;
+        pDevice->bProtectMode = FALSE;          //Only used in 11g type, sync with ERP IE
+        pDevice->bNonERPPresent = FALSE;
+        pDevice->bBarkerPreambleMd = FALSE;
+        if ( pDevice->bFixRate ) {
+            pDevice->wCurrentRate = (WORD) pDevice->uConnectionRate;
+        } else {
+            if ( pDevice->byBBType == BB_TYPE_11B )
+                pDevice->wCurrentRate = RATE_11M;
+            else
+                pDevice->wCurrentRate = RATE_54M;
+        }
+
+        CHvInitChannelTable(pDevice);
+
+        pDevice->byTopOFDMBasicRate = RATE_24M;
+        pDevice->byTopCCKBasicRate = RATE_1M;
+        pDevice->byRevId = 0;                   //Target to IF pin while programming to RF chip.
+        pDevice->byCurPwr = 0xFF;
+
+        pDevice->byCCKPwr = pDevice->abyEEPROM[EEP_OFS_PWR_CCK];
+        pDevice->byOFDMPwrG = pDevice->abyEEPROM[EEP_OFS_PWR_OFDMG];
+        // Load power Table
+        for (ii=0;ii<14;ii++) {
+            pDevice->abyCCKPwrTbl[ii] = pDevice->abyEEPROM[ii + EEP_OFS_CCK_PWR_TBL];
+            if (pDevice->abyCCKPwrTbl[ii] == 0)
+                pDevice->abyCCKPwrTbl[ii] = pDevice->byCCKPwr;
+            pDevice->abyOFDMPwrTbl[ii] = pDevice->abyEEPROM[ii + EEP_OFS_OFDM_PWR_TBL];
+            if (pDevice->abyOFDMPwrTbl[ii] == 0)
+                pDevice->abyOFDMPwrTbl[ii] = pDevice->byOFDMPwrG;
+        }
+
+	  //original zonetype is USA,but customize zonetype is europe,
+	  // then need recover 12,13 ,14 channel  with 11 channel
+          if(((pDevice->abyEEPROM[EEP_OFS_ZONETYPE] == ZoneType_Japan) ||
+	        (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] == ZoneType_Europe))&&
+	     (pDevice->byOriginalZonetype == ZoneType_USA)) {
+	    for(ii=11;ii<14;ii++) {
+                pDevice->abyCCKPwrTbl[ii] = pDevice->abyCCKPwrTbl[10];
+	       pDevice->abyOFDMPwrTbl[ii] = pDevice->abyOFDMPwrTbl[10];
+	    }
+	  }
+
+        //{{ RobertYu: 20041124
+        pDevice->byOFDMPwrA = 0x34; // same as RFbMA2829SelectChannel
+        // Load OFDM A Power Table
+        for (ii=0;ii<CB_MAX_CHANNEL_5G;ii++) { //RobertYu:20041224, bug using CB_MAX_CHANNEL
+            pDevice->abyOFDMAPwrTbl[ii] = pDevice->abyEEPROM[ii + EEP_OFS_OFDMA_PWR_TBL];
+            if (pDevice->abyOFDMAPwrTbl[ii] == 0)
+                pDevice->abyOFDMAPwrTbl[ii] = pDevice->byOFDMPwrA;
+        }
+        //}} RobertYu
+
+        byAntenna = pDevice->abyEEPROM[EEP_OFS_ANTENNA];
+        if (byAntenna & EEP_ANTINV)
+            pDevice->bTxRxAntInv = TRUE;
+        else
+            pDevice->bTxRxAntInv = FALSE;
+
+        byAntenna &= (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN);
+
+        if (byAntenna == 0) // if not set default is All
+            byAntenna = (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN);
+
+        if (byAntenna == (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN)) {
+            pDevice->byAntennaCount = 2;
+            pDevice->byTxAntennaMode = ANT_B;
+            pDevice->dwTxAntennaSel = 1;
+            pDevice->dwRxAntennaSel = 1;
+            if (pDevice->bTxRxAntInv == TRUE)
+                pDevice->byRxAntennaMode = ANT_A;
+            else
+                pDevice->byRxAntennaMode = ANT_B;
+
+            if (pDevice->bDiversityRegCtlON)
+                pDevice->bDiversityEnable = TRUE;
+            else
+                pDevice->bDiversityEnable = FALSE;
+        } else  {
+            pDevice->bDiversityEnable = FALSE;
+            pDevice->byAntennaCount = 1;
+            pDevice->dwTxAntennaSel = 0;
+            pDevice->dwRxAntennaSel = 0;
+            if (byAntenna & EEP_ANTENNA_AUX) {
+                pDevice->byTxAntennaMode = ANT_A;
+                if (pDevice->bTxRxAntInv == TRUE)
+                    pDevice->byRxAntennaMode = ANT_B;
+                else
+                    pDevice->byRxAntennaMode = ANT_A;
+            } else {
+                pDevice->byTxAntennaMode = ANT_B;
+                if (pDevice->bTxRxAntInv == TRUE)
+                    pDevice->byRxAntennaMode = ANT_A;
+                else
+                    pDevice->byRxAntennaMode = ANT_B;
+            }
+        }
+        pDevice->ulDiversityNValue = 100*255;
+        pDevice->ulDiversityMValue = 100*16;
+        pDevice->byTMax = 1;
+        pDevice->byTMax2 = 4;
+        pDevice->ulSQ3TH = 0;
+        pDevice->byTMax3 = 64;
+        // -----------------------------------------------------------------
+
+        //Get Auto Fall Back Type
+        pDevice->byAutoFBCtrl = AUTO_FB_0;
+
+        // Set SCAN Time
+        pDevice->uScanTime = WLAN_SCAN_MINITIME;
+
+        // default Auto Mode
+        //pDevice->NetworkType = Ndis802_11Automode;
+        pDevice->eConfigPHYMode = PHY_TYPE_AUTO;
+        pDevice->byBBType = BB_TYPE_11G;
+
+        // initialize BBP registers
+        pDevice->ulTxPower = 25;
+
+        // Get Channel range
+        pDevice->byMinChannel = 1;
+        pDevice->byMaxChannel = CB_MAX_CHANNEL;
+
+        // Get RFType
+        pDevice->byRFType = sInitRsp.byRFType;
+
+        if ((pDevice->byRFType & RF_EMU) != 0) {
+            // force change RevID for VT3253 emu
+            pDevice->byRevId = 0x80;
+        }
+
+        // Load EEPROM calibrated vt3266 parameters
+        if (pDevice->byRFType == RF_VT3226D0) {
+            if((pDevice->abyEEPROM[EEP_OFS_MAJOR_VER] == 0x1) &&
+                (pDevice->abyEEPROM[EEP_OFS_MINOR_VER] >= 0x4)) {
+                byCalibTXIQ = pDevice->abyEEPROM[EEP_OFS_CALIB_TX_IQ];
+                byCalibTXDC = pDevice->abyEEPROM[EEP_OFS_CALIB_TX_DC];
+                byCalibRXIQ = pDevice->abyEEPROM[EEP_OFS_CALIB_RX_IQ];
+                if( (byCalibTXIQ || byCalibTXDC || byCalibRXIQ) ) {
+                    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xFF, 0x03); // CR255, Set BB to support TX/RX IQ and DC compensation Mode
+                    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xFB, byCalibTXIQ); // CR251, TX I/Q Imbalance Calibration
+                    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xFC, byCalibTXDC); // CR252, TX DC-Offset Calibration
+                    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xFD, byCalibRXIQ); // CR253, RX I/Q Imbalance Calibration
+                } else {
+                // turn off BB Calibration compensation
+                    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xFF, 0x0); // CR255
+                }
+            }
+        }
+        pMgmt->eScanType = WMAC_SCAN_PASSIVE;
+        pMgmt->uCurrChannel = pDevice->uChannel;
+        pMgmt->uIBSSChannel = pDevice->uChannel;
+        CARDbSetMediaChannel(pDevice, pMgmt->uCurrChannel);
+
+        // get Permanent network address
+        MEMvCopy(pDevice->abyPermanentNetAddr,&(sInitRsp.byNetAddr[0]),6)
+        MEMvCopy(pDevice->abyCurrentNetAddr, pDevice->abyPermanentNetAddr, U_ETHER_ADDR_LEN);
+
+        // if exist SW network address, use SW network address.
+
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Network address = %02x-%02x-%02x=%02x-%02x-%02x\n",
+            pDevice->abyCurrentNetAddr[0],
+            pDevice->abyCurrentNetAddr[1],
+            pDevice->abyCurrentNetAddr[2],
+            pDevice->abyCurrentNetAddr[3],
+            pDevice->abyCurrentNetAddr[4],
+            pDevice->abyCurrentNetAddr[5]);
+    }
+
+
+
+    // Set BB and packet type at the same time.
+    // Set Short Slot Time, xIFS, and RSPINF.
+    if (pDevice->byBBType == BB_TYPE_11A) {
+        CARDbAddBasicRate(pDevice, RATE_6M);
+        pDevice->bShortSlotTime = TRUE;
+    } else {
+        CARDbAddBasicRate(pDevice, RATE_1M);
+        pDevice->bShortSlotTime = FALSE;
+    }
+    BBvSetShortSlotTime(pDevice);
+    CARDvSetBSSMode(pDevice);
+
+    if (pDevice->bUpdateBBVGA) {
+        pDevice->byBBVGACurrent = pDevice->abyBBVGA[0];
+        pDevice->byBBVGANew = pDevice->byBBVGACurrent;
+        BBvSetVGAGainOffset(pDevice, pDevice->abyBBVGA[0]);
+    }
+
+    pDevice->byRadioCtl = pDevice->abyEEPROM[EEP_OFS_RADIOCTL];
+    pDevice->bHWRadioOff = FALSE;
+    if ( (pDevice->byRadioCtl & EEP_RADIOCTL_ENABLE) != 0 ) {
+        ntStatus = CONTROLnsRequestIn(pDevice,
+                                    MESSAGE_TYPE_READ,
+                                    MAC_REG_GPIOCTL1,
+                                    MESSAGE_REQUEST_MACREG,
+                                    1,
+                                    &byTmp);
+
+        if ( ntStatus != STATUS_SUCCESS ) {
+            spin_unlock_irq(&pDevice->lock);
+            return FALSE;
+        }
+        if ( (byTmp & GPIO3_DATA) == 0 ) {
+            pDevice->bHWRadioOff = TRUE;
+            MACvRegBitsOn(pDevice,MAC_REG_GPIOCTL1,GPIO3_INTMD);
+        } else {
+            MACvRegBitsOff(pDevice,MAC_REG_GPIOCTL1,GPIO3_INTMD);
+            pDevice->bHWRadioOff = FALSE;
+        }
+
+    } //EEP_RADIOCTL_ENABLE
+
+    ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_TMLEN,0x38);
+    ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW);
+    MACvRegBitsOn(pDevice,MAC_REG_GPIOCTL0,0x01);
+
+    if ((pDevice->bHWRadioOff == TRUE) || (pDevice->bRadioControlOff == TRUE)) {
+        CARDbRadioPowerOff(pDevice);
+    } else {
+        CARDbRadioPowerOn(pDevice);
+    }
+
+    spin_unlock_irq(&pDevice->lock);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"<----INIbInitAdapter Exit\n");
+    return TRUE;
+}
+
+static BOOL device_release_WPADEV(PSDevice pDevice)
+{
+  viawget_wpa_header *wpahdr;
+  int ii=0;
+ // wait_queue_head_t	Set_wait;
+  //send device close to wpa_supplicnat layer
+    if (pDevice->bWPADEVUp==TRUE) {
+                 wpahdr = (viawget_wpa_header *)pDevice->skb->data;
+                 wpahdr->type = VIAWGET_DEVICECLOSE_MSG;
+                 wpahdr->resp_ie_len = 0;
+                 wpahdr->req_ie_len = 0;
+                 skb_put(pDevice->skb, sizeof(viawget_wpa_header));
+                 pDevice->skb->dev = pDevice->wpadev;
+//2008-4-3 modify by Chester for wpa
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
+                 pDevice->skb->mac_header = pDevice->skb->data;
+#else
+                 pDevice->skb->mac.raw = pDevice->skb->data;
+#endif
+                 pDevice->skb->pkt_type = PACKET_HOST;
+                 pDevice->skb->protocol = htons(ETH_P_802_2);
+                 memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
+                 netif_rx(pDevice->skb);
+                 pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
+
+ //wait release WPADEV
+              //    init_waitqueue_head(&Set_wait);
+              //    wait_event_timeout(Set_wait, ((pDevice->wpadev==NULL)&&(pDevice->skb == NULL)),5*HZ);    //1s wait
+              while(pDevice->bWPADEVUp==TRUE) {
+	        set_current_state(TASK_UNINTERRUPTIBLE);
+                 schedule_timeout (HZ/20);          //wait 50ms
+                 ii++;
+	        if(ii>20)
+		  break;
+              }
+           };
+    return TRUE;
+}
+
+#ifdef CONFIG_PM	/* Minimal support for suspend and resume */
+static int vntwusb_suspend(struct usb_interface *intf, pm_message_t message)
+{
+ PSDevice  pDevice = usb_get_intfdata(intf);
+ struct net_device *dev = pDevice->dev;
+
+ printk("VNTWUSB Suspend Start======>\n");
+if(dev != NULL) {
+  if(pDevice->flags & DEVICE_FLAGS_OPENED)
+     device_close(dev);
+}
+
+ usb_put_dev(interface_to_usbdev(intf));
+ return 0;
+}
+
+static int vntwusb_resume(struct usb_interface *intf)
+{
+ PSDevice  pDevice = usb_get_intfdata(intf);
+ struct net_device *dev = pDevice->dev;
+
+ printk("VNTWUSB Resume Start======>\n");
+ if(dev != NULL) {
+  usb_get_dev(interface_to_usbdev(intf));
+  if(!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
+    if(device_open(dev)!=0)
+        printk("VNTWUSB Resume Start======>open fail\n");
+   }
+ }
+ return 0;
+}
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+
+static int
+vntwusb_found1(struct usb_interface *intf, const struct usb_device_id *id)
+#else
+
+static void *
+vntwusb_found1(struct usb_device *udev, UINT interface, const struct usb_device_id *id)
+#endif
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
+   BYTE            fake_mac[U_ETHER_ADDR_LEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x01};//fake MAC address
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+	struct usb_device *udev = interface_to_usbdev(intf);
+    int         rc = 0;
+#endif
+    struct net_device *netdev = NULL;
+    PSDevice    pDevice = NULL;
+
+
+    printk(KERN_NOTICE "%s Ver. %s\n",DEVICE_FULL_DRV_NAM, DEVICE_VERSION);
+    printk(KERN_NOTICE "Copyright (c) 2004 VIA Networking Technologies, Inc.\n");
+
+//2008-0922-01<Add>by MikeLiu, add usb counter.
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+  udev = usb_get_dev(udev);
+#endif
+
+	pDevice = kmalloc(sizeof(DEVICE_INFO), GFP_KERNEL);
+	if (pDevice == NULL) {
+	    printk(KERN_ERR DEVICE_NAME ": allocate usb device failed \n");
+	    goto err_nomem;
+	}
+    memset(pDevice, 0, sizeof(DEVICE_INFO));
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+    netdev = alloc_etherdev(0);
+#else
+    netdev = init_etherdev(netdev, 0);
+#endif
+
+    if (netdev == NULL) {
+        printk(KERN_ERR DEVICE_NAME ": allocate net device failed \n");
+        kfree(pDevice);
+	    goto err_nomem;
+    }
+    pDevice->dev = netdev;
+    pDevice->usb = udev;
+
+    // Chain it all together
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
+    SET_MODULE_OWNER(netdev);
+#endif
+
+    // Set initial settings
+    device_set_options(pDevice);
+    spin_lock_init(&pDevice->lock);
+
+    pDevice->tx_80211 = device_dma0_tx_80211;
+    pDevice->sMgmtObj.pAdapter = (PVOID)pDevice;
+
+	netdev->priv               = pDevice;
+    netdev->open               = device_open;
+    netdev->hard_start_xmit    = device_xmit;
+    netdev->stop               = device_close;
+    netdev->get_stats          = device_get_stats;
+    netdev->set_multicast_list = device_set_multi;
+    netdev->do_ioctl           = device_ioctl;
+#ifdef WIRELESS_EXT
+
+//2007-0508-01<Add>by MikeLiu
+  #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+	netdev->get_wireless_stats = iwctl_get_wireless_stats;
+  #endif
+
+#if WIRELESS_EXT > 12
+	netdev->wireless_handlers = (struct iw_handler_def *)&iwctl_handler_def;
+//	netdev->wireless_handlers = NULL;
+#endif /* WIRELESS_EXT > 12 */
+#endif /* WIRELESS_EXT */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+
+   //2008-0623-01<Remark>by MikeLiu
+  //2007-0821-01<Add>by MikeLiu
+  // #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
+         usb_set_intfdata(intf, pDevice);
+	SET_NETDEV_DEV(netdev, &intf->dev);
+   //#endif
+   #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
+    memcpy(pDevice->dev->dev_addr, fake_mac, U_ETHER_ADDR_LEN); //use fake mac address
+   #endif
+    rc = register_netdev(netdev);
+    if (rc != 0) {
+        printk(KERN_ERR DEVICE_NAME " Failed to register netdev\n");
+		free_netdev(netdev);
+        kfree(pDevice);
+        return -ENODEV;
+    }
+	//2008-0623-02<Remark>by MikeLiu
+        //2007-0821-01<Add>by MikeLiu
+       //#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)
+  	//usb_set_intfdata(intf, pDevice);
+	//SET_NETDEV_DEV(netdev, &intf->dev);
+       //#endif
+
+//2008-07-21-01<Add>by MikeLiu
+//register wpadev
+   if(wpa_set_wpadev(pDevice, 1)!=0) {
+     printk("Fail to Register WPADEV?\n");
+        unregister_netdev(pDevice->dev);
+        free_netdev(netdev);
+        kfree(pDevice);
+   }
+
+//2007-1107-03<Add>by MikeLiu
+   #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
+         usb_device_reset(pDevice);
+   #endif
+
+#ifdef SndEvt_ToAPI
+{
+  union iwreq_data      wrqu;
+  memset(&wrqu, 0, sizeof(wrqu));
+  wrqu.data.flags = RT_INSMOD_EVENT_FLAG;
+  wrqu.data.length =IFNAMSIZ;
+  wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, pDevice->dev->name);
+}
+#endif
+
+	return 0;
+#else
+    return pDevice;
+#endif
+
+
+err_nomem:
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+
+ //2008-0922-01<Add>by MikeLiu, decrease usb counter.
+    usb_put_dev(udev);
+
+    return -ENOMEM;
+#else
+    return NULL;
+#endif
+}
+
+
+static VOID device_free_tx_bufs(PSDevice pDevice) {
+    PUSB_SEND_CONTEXT pTxContext;
+    int ii;
+
+    for (ii = 0; ii < pDevice->cbTD; ii++) {
+
+        pTxContext = pDevice->apTD[ii];
+        //de-allocate URBs
+        if (pTxContext->pUrb) {
+            vntwusb_unlink_urb(pTxContext->pUrb);
+            usb_free_urb(pTxContext->pUrb);
+        }
+        if (pTxContext)
+            kfree(pTxContext);
+    }
+    return;
+}
+
+
+static VOID device_free_rx_bufs(PSDevice pDevice) {
+    PRCB pRCB;
+    int ii;
+
+    for (ii = 0; ii < pDevice->cbRD; ii++) {
+
+        pRCB = pDevice->apRCB[ii];
+        //de-allocate URBs
+        if (pRCB->pUrb) {
+            vntwusb_unlink_urb(pRCB->pUrb);
+            usb_free_urb(pRCB->pUrb);
+        }
+        //de-allocate skb
+        if (pRCB->skb)
+            dev_kfree_skb(pRCB->skb);
+    }
+    if (pDevice->pRCBMem)
+        kfree(pDevice->pRCBMem);
+
+    return;
+}
+
+//2007-1107-02<Add>by MikeLiu
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
+static void usb_device_reset(PSDevice pDevice)
+{
+ int status;
+ status = usb_reset_device(pDevice->usb);
+	if (status)
+            printk("usb_device_reset fail status=%d\n",status);
+	return ;
+}
+#endif
+
+static VOID device_free_int_bufs(PSDevice pDevice) {
+
+    if (pDevice->intBuf.pDataBuf != NULL)
+        kfree(pDevice->intBuf.pDataBuf);
+    return;
+}
+
+
+static BOOL device_alloc_bufs(PSDevice pDevice) {
+
+    PUSB_SEND_CONTEXT pTxContext;
+    PRCB pRCB;
+    int ii;
+
+
+    for (ii = 0; ii < pDevice->cbTD; ii++) {
+
+        pTxContext = kmalloc(sizeof(USB_SEND_CONTEXT), GFP_KERNEL);
+        if (pTxContext == NULL) {
+            DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s : allocate tx usb context failed\n", pDevice->dev->name);
+            goto free_tx;
+        }
+        pDevice->apTD[ii] = pTxContext;
+        pTxContext->pDevice = (PVOID) pDevice;
+        //allocate URBs
+        pTxContext->pUrb = vntwusb_alloc_urb(0);;
+        if (pTxContext->pUrb == NULL) {
+            DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "alloc tx urb failed\n");
+            goto free_tx;
+        }
+        pTxContext->bBoolInUse = FALSE;
+    }
+
+    // allocate rcb mem
+    pDevice->pRCBMem = kmalloc((sizeof(RCB) * pDevice->cbRD), GFP_KERNEL);
+    if (pDevice->pRCBMem == NULL) {
+        DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s : alloc rx usb context failed\n", pDevice->dev->name);
+        goto free_tx;
+    }
+
+
+    pDevice->FirstRecvFreeList = NULL;
+    pDevice->LastRecvFreeList = NULL;
+    pDevice->FirstRecvMngList = NULL;
+    pDevice->LastRecvMngList = NULL;
+    pDevice->NumRecvFreeList = 0;
+    memset(pDevice->pRCBMem, 0, (sizeof(RCB) * pDevice->cbRD));
+    pRCB = (PRCB) pDevice->pRCBMem;
+
+    for (ii = 0; ii < pDevice->cbRD; ii++) {
+
+        pDevice->apRCB[ii] = pRCB;
+        pRCB->pDevice = (PVOID) pDevice;
+        //allocate URBs
+        pRCB->pUrb = vntwusb_alloc_urb(0);
+
+        if (pRCB->pUrb == NULL) {
+            DBG_PRT(MSG_LEVEL_ERR,KERN_ERR" Failed to alloc rx urb\n");
+            goto free_rx_tx;
+        }
+        pRCB->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
+        if (pRCB->skb == NULL) {
+            DBG_PRT(MSG_LEVEL_ERR,KERN_ERR" Failed to alloc rx skb\n");
+            goto free_rx_tx;
+        }
+        pRCB->skb->dev = pDevice->dev;
+        pRCB->bBoolInUse = FALSE;
+        EnqueueRCB(pDevice->FirstRecvFreeList, pDevice->LastRecvFreeList, pRCB);
+        pDevice->NumRecvFreeList++;
+        pRCB++;
+    }
+
+
+	pDevice->pControlURB = vntwusb_alloc_urb(0);
+	if (pDevice->pControlURB == NULL) {
+	    DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc control urb\n");
+	    goto free_rx_tx;
+	}
+
+	pDevice->pInterruptURB = vntwusb_alloc_urb(0);
+	if (pDevice->pInterruptURB == NULL) {
+	    DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc int urb\n");
+   	    vntwusb_unlink_urb(pDevice->pControlURB);
+	    usb_free_urb(pDevice->pControlURB);
+	    goto free_rx_tx;
+	}
+
+    pDevice->intBuf.pDataBuf = kmalloc(MAX_INTERRUPT_SIZE, GFP_KERNEL);
+	if (pDevice->intBuf.pDataBuf == NULL) {
+	    DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc int buf\n");
+   	    vntwusb_unlink_urb(pDevice->pControlURB);
+   	    vntwusb_unlink_urb(pDevice->pInterruptURB);
+	    usb_free_urb(pDevice->pControlURB);
+	    usb_free_urb(pDevice->pInterruptURB);
+	    goto free_rx_tx;
+	}
+
+    return TRUE;
+
+free_rx_tx:
+    device_free_rx_bufs(pDevice);
+
+free_tx:
+    device_free_tx_bufs(pDevice);
+
+	return FALSE;
+}
+
+
+
+
+static BOOL device_init_defrag_cb(PSDevice pDevice) {
+    int i;
+    PSDeFragControlBlock pDeF;
+
+    /* Init the fragment ctl entries */
+    for (i = 0; i < CB_MAX_RX_FRAG; i++) {
+        pDeF = &(pDevice->sRxDFCB[i]);
+        if (!device_alloc_frag_buf(pDevice, pDeF)) {
+            DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc frag bufs\n",
+                pDevice->dev->name);
+            goto free_frag;
+        };
+    }
+    pDevice->cbDFCB = CB_MAX_RX_FRAG;
+    pDevice->cbFreeDFCB = pDevice->cbDFCB;
+    return TRUE;
+
+free_frag:
+    device_free_frag_bufs(pDevice);
+    return FALSE;
+}
+
+
+
+static void device_free_frag_bufs(PSDevice pDevice) {
+    PSDeFragControlBlock pDeF;
+    int i;
+
+    for (i = 0; i < CB_MAX_RX_FRAG; i++) {
+
+        pDeF = &(pDevice->sRxDFCB[i]);
+
+        if (pDeF->skb)
+            dev_kfree_skb(pDeF->skb);
+    }
+}
+
+
+
+BOOL device_alloc_frag_buf(PSDevice pDevice, PSDeFragControlBlock pDeF) {
+
+    pDeF->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
+    if (pDeF->skb == NULL)
+        return FALSE;
+    ASSERT(pDeF->skb);
+    pDeF->skb->dev = pDevice->dev;
+
+    return TRUE;
+}
+
+
+/*-----------------------------------------------------------------*/
+
+static int  device_open(struct net_device *dev) {
+    PSDevice    pDevice=(PSDevice) dev->priv;
+
+#ifdef WPA_SM_Transtatus
+     extern SWPAResult wpa_Result;
+     memset(wpa_Result.ifname,0,sizeof(wpa_Result.ifname));
+     wpa_Result.proto = 0;
+     wpa_Result.key_mgmt = 0;
+     wpa_Result.eap_type = 0;
+     wpa_Result.authenticated = FALSE;
+     pDevice->fWPA_Authened = FALSE;
+#endif
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " device_open...\n");
+
+
+    pDevice->rx_buf_sz = MAX_TOTAL_SIZE_WITH_ALL_HEADERS;
+
+    if (device_alloc_bufs(pDevice) == FALSE) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " device_alloc_bufs fail... \n");
+        return -ENOMEM;
+    }
+
+    if (device_init_defrag_cb(pDevice)== FALSE) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Initial defragement cb fail \n");
+        goto free_rx_tx;
+    }
+
+    MP_CLEAR_FLAG(pDevice, fMP_DISCONNECTED);
+    MP_CLEAR_FLAG(pDevice, fMP_CONTROL_READS);
+    MP_CLEAR_FLAG(pDevice, fMP_CONTROL_WRITES);
+    MP_SET_FLAG(pDevice, fMP_POST_READS);
+    MP_SET_FLAG(pDevice, fMP_POST_WRITES);
+
+   //read config file
+    Read_config_file(pDevice);
+
+    if (device_init_registers(pDevice, DEVICE_INIT_COLD) == FALSE) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " init register fail\n");
+        goto free_all;
+    }
+
+    device_set_multi(pDevice->dev);
+    // Init for Key Management
+
+    KeyvInitTable(pDevice,&pDevice->sKey);
+    memcpy(pDevice->sMgmtObj.abyMACAddr, pDevice->abyCurrentNetAddr, U_ETHER_ADDR_LEN);
+    memcpy(pDevice->dev->dev_addr, pDevice->abyCurrentNetAddr, U_ETHER_ADDR_LEN);
+    pDevice->bStopTx0Pkt = FALSE;
+    pDevice->bStopDataPkt = FALSE;
+    pDevice->bRoaming = FALSE;  //DavidWang
+    pDevice->bIsRoaming = FALSE;//DavidWang
+    pDevice->bEnableRoaming = FALSE;
+    if (pDevice->bDiversityRegCtlON) {
+        device_init_diversity_timer(pDevice);
+    }
+
+    vMgrObjectInit(pDevice);
+    tasklet_init(&pDevice->RxMngWorkItem, (void *)RXvMngWorkItem, (unsigned long)pDevice);
+    tasklet_init(&pDevice->ReadWorkItem, (void *)RXvWorkItem, (unsigned long)pDevice);
+    tasklet_init(&pDevice->EventWorkItem, (void *)INTvWorkItem, (unsigned long)pDevice);
+    add_timer(&(pDevice->sMgmtObj.sTimerSecondCallback));
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+    pDevice->int_interval = 100;  //Max 100 microframes.
+#else
+    pDevice->int_interval = 0x10; //16 microframes interval(~2ms) for usb 2.0
+#endif
+    pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
+
+    pDevice->bIsRxWorkItemQueued = TRUE;
+    pDevice->fKillEventPollingThread = FALSE;
+    pDevice->bEventAvailable = FALSE;
+
+   pDevice->bWPADEVUp = FALSE;
+#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+     pDevice->bwextstep0 = FALSE;
+     pDevice->bwextstep1 = FALSE;
+     pDevice->bwextstep2 = FALSE;
+     pDevice->bwextstep3 = FALSE;
+     pDevice->bWPASuppWextEnabled = FALSE;
+#endif
+    pDevice->byReAssocCount = 0;
+
+    RXvWorkItem(pDevice);
+    INTvWorkItem(pDevice);
+
+    // Patch: if WEP key already set by iwconfig but device not yet open
+    if ((pDevice->bEncryptionEnable == TRUE) && (pDevice->bTransmitKey == TRUE)) {
+         spin_lock_irq(&pDevice->lock);
+         KeybSetDefaultKey( pDevice,
+                            &(pDevice->sKey),
+                            pDevice->byKeyIndex | (1 << 31),
+                            pDevice->uKeyLength,
+                            NULL,
+                            pDevice->abyKey,
+                            KEY_CTL_WEP
+                          );
+         spin_unlock_irq(&pDevice->lock);
+         pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
+    }
+
+    if (pDevice->sMgmtObj.eConfigMode == WMAC_CONFIG_AP) {
+        bScheduleCommand((HANDLE)pDevice, WLAN_CMD_RUN_AP, NULL);
+	}
+	else {
+	//mike:mark at 2008-11-10
+            bScheduleCommand((HANDLE)pDevice, WLAN_CMD_BSSID_SCAN, NULL);
+        //bScheduleCommand((HANDLE)pDevice, WLAN_CMD_SSID, NULL);
+    }
+
+
+    netif_stop_queue(pDevice->dev);
+    pDevice->flags |= DEVICE_FLAGS_OPENED;
+
+#ifdef SndEvt_ToAPI
+{
+  union iwreq_data      wrqu;
+  memset(&wrqu, 0, sizeof(wrqu));
+  wrqu.data.flags = RT_UPDEV_EVENT_FLAG;
+  wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, NULL);
+}
+#endif
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_open success.. \n");
+    return 0;
+
+free_all:
+    device_free_frag_bufs(pDevice);
+free_rx_tx:
+    device_free_rx_bufs(pDevice);
+    device_free_tx_bufs(pDevice);
+    device_free_int_bufs(pDevice);
+	vntwusb_unlink_urb(pDevice->pControlURB);
+	vntwusb_unlink_urb(pDevice->pInterruptURB);
+    usb_free_urb(pDevice->pControlURB);
+    usb_free_urb(pDevice->pInterruptURB);
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_open fail.. \n");
+    return -ENOMEM;
+}
+
+
+
+static int  device_close(struct net_device *dev) {
+    PSDevice    pDevice=(PSDevice) dev->priv;
+    PSMgmtObject     pMgmt = &(pDevice->sMgmtObj);
+
+   #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
+        int uu;
+   #endif
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_close1 \n");
+    if (pDevice == NULL)
+        return -ENODEV;
+
+#ifdef SndEvt_ToAPI
+{
+  union iwreq_data      wrqu;
+  memset(&wrqu, 0, sizeof(wrqu));
+  wrqu.data.flags = RT_DOWNDEV_EVENT_FLAG;
+  wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, NULL);
+}
+#endif
+
+//2007-1121-02<Add>by EinsnLiu
+    if (pDevice->bLinkPass) {
+	bScheduleCommand((HANDLE)pDevice, WLAN_CMD_DISASSOCIATE, NULL);
+        mdelay(30);
+    }
+//End Add
+
+//2008-0714-01<Add>by MikeLiu
+device_release_WPADEV(pDevice);
+
+ //2007-0821-01<Add>by MikeLiu
+   #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
+        memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+        pMgmt->bShareKeyAlgorithm = FALSE;
+        pDevice->bEncryptionEnable = FALSE;
+        pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
+            spin_lock_irq(&pDevice->lock);
+            for(uu=0;uu<MAX_KEY_TABLE;uu++)
+                MACvDisableKeyEntry(pDevice,uu);
+            spin_unlock_irq(&pDevice->lock);
+   #endif
+
+    if ((pDevice->flags & DEVICE_FLAGS_UNPLUG) == FALSE) {
+        MACbShutdown(pDevice);
+    }
+    netif_stop_queue(pDevice->dev);
+    MP_SET_FLAG(pDevice, fMP_DISCONNECTED);
+    MP_CLEAR_FLAG(pDevice, fMP_POST_WRITES);
+    MP_CLEAR_FLAG(pDevice, fMP_POST_READS);
+    pDevice->fKillEventPollingThread = TRUE;
+    del_timer(&pDevice->sTimerCommand);
+    del_timer(&pMgmt->sTimerSecondCallback);
+
+//2007-0115-02<Add>by MikeLiu
+#ifdef TxInSleep
+    del_timer(&pDevice->sTimerTxData);
+#endif
+
+    if (pDevice->bDiversityRegCtlON) {
+        del_timer(&pDevice->TimerSQ3Tmax1);
+        del_timer(&pDevice->TimerSQ3Tmax2);
+        del_timer(&pDevice->TimerSQ3Tmax3);
+    }
+    tasklet_kill(&pDevice->RxMngWorkItem);
+    tasklet_kill(&pDevice->ReadWorkItem);
+    tasklet_kill(&pDevice->EventWorkItem);
+
+   pDevice->bRoaming = FALSE;  //DavidWang
+   pDevice->bIsRoaming = FALSE;//DavidWang
+   pDevice->bEnableRoaming = FALSE;
+    pDevice->bCmdRunning = FALSE;
+    pDevice->bLinkPass = FALSE;
+    memset(pMgmt->abyCurrBSSID, 0, 6);
+    pMgmt->eCurrState = WMAC_STATE_IDLE;
+
+    device_free_tx_bufs(pDevice);
+    device_free_rx_bufs(pDevice);
+    device_free_int_bufs(pDevice);
+    device_free_frag_bufs(pDevice);
+
+	vntwusb_unlink_urb(pDevice->pControlURB);
+	vntwusb_unlink_urb(pDevice->pInterruptURB);
+    usb_free_urb(pDevice->pControlURB);
+    usb_free_urb(pDevice->pInterruptURB);
+
+    BSSvClearNodeDBTable(pDevice, 0);
+    pDevice->flags &=(~DEVICE_FLAGS_OPENED);
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_close2 \n");
+
+    return 0;
+}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+
+static void vntwusb_disconnect(struct usb_interface *intf)
+
+#else
+
+static void vntwusb_disconnect(struct usb_device *udev, void *ptr)
+#endif
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+
+	PSDevice  pDevice = usb_get_intfdata(intf);
+#else
+	PSDevice  pDevice = (PSDevice)ptr;
+#endif
+
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_disconnect1.. \n");
+    if (pDevice == NULL)
+        return;
+
+#ifdef SndEvt_ToAPI
+{
+  union iwreq_data      wrqu;
+  memset(&wrqu, 0, sizeof(wrqu));
+  wrqu.data.flags = RT_RMMOD_EVENT_FLAG;
+  wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, NULL);
+}
+#endif
+
+//2008-0714-01<Add>by MikeLiu
+device_release_WPADEV(pDevice);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+
+	usb_set_intfdata(intf, NULL);
+//2008-0922-01<Add>by MikeLiu, decrease usb counter.
+     usb_put_dev(interface_to_usbdev(intf));
+
+#endif
+
+    pDevice->flags |= DEVICE_FLAGS_UNPLUG;
+    if (pDevice->dev != NULL) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "unregister_netdev..\n");
+        unregister_netdev(pDevice->dev);
+
+//2008-07-21-01<Add>by MikeLiu
+//unregister wpadev
+   if(wpa_set_wpadev(pDevice, 0)!=0)
+     printk("unregister wpadev fail?\n");
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+        free_netdev(pDevice->dev);
+#else
+	    kfree(pDevice->dev);
+#endif
+    }
+
+	kfree(pDevice);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_disconnect3.. \n");
+}
+
+
+
+
+static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev) {
+    PSDevice        pDevice=dev->priv;
+    PBYTE           pbMPDU;
+    UINT            cbMPDULen = 0;
+
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_tx_80211\n");
+    spin_lock_irq(&pDevice->lock);
+
+    if (pDevice->bStopTx0Pkt == TRUE) {
+        dev_kfree_skb_irq(skb);
+        spin_unlock_irq(&pDevice->lock);
+        return 0;
+    };
+
+
+    cbMPDULen = skb->len;
+    pbMPDU = skb->data;
+
+    vDMA0_tx_80211(pDevice, skb);
+
+    spin_unlock_irq(&pDevice->lock);
+
+    return 0;
+
+}
+
+
+static int  device_xmit(struct sk_buff *skb, struct net_device *dev) {
+    PSDevice    pDevice=dev->priv;
+    struct net_device_stats* pStats = &pDevice->stats;
+
+
+    spin_lock_irq(&pDevice->lock);
+
+    netif_stop_queue(pDevice->dev);
+
+    if (pDevice->bLinkPass == FALSE) {
+        dev_kfree_skb_irq(skb);
+        spin_unlock_irq(&pDevice->lock);
+        return 0;
+    }
+    if (pDevice->bStopDataPkt == TRUE) {
+        dev_kfree_skb_irq(skb);
+        pStats->tx_dropped++;
+        spin_unlock_irq(&pDevice->lock);
+        return 0;
+    }
+
+    if(nsDMA_tx_packet(pDevice, TYPE_AC0DMA, skb) !=0) {  //mike add:xmit fail!
+         if (netif_queue_stopped(pDevice->dev))
+              netif_wake_queue(pDevice->dev);
+    }
+
+    spin_unlock_irq(&pDevice->lock);
+
+    return 0;
+}
+
+
+
+static unsigned const ethernet_polynomial = 0x04c11db7U;
+static inline u32 ether_crc(int length, unsigned char *data)
+{
+    int crc = -1;
+
+    while(--length >= 0) {
+        unsigned char current_octet = *data++;
+        int bit;
+        for (bit = 0; bit < 8; bit++, current_octet >>= 1) {
+            crc = (crc << 1) ^
+                ((crc < 0) ^ (current_octet & 1) ? ethernet_polynomial : 0);
+        }
+    }
+    return crc;
+}
+
+//find out  the start  position of str2 from str1
+static UCHAR *kstrstr(const UCHAR *str1,const UCHAR *str2) {
+  int str1_len=strlen(str1);
+  int str2_len=strlen(str2);
+
+  while (str1_len >= str2_len) {
+       str1_len--;
+      if(memcmp(str1,str2,str2_len)==0)
+         return (UCHAR *)str1;
+        str1++;
+  }
+  return NULL;
+}
+
+static int Config_FileGetParameter(UCHAR *string, UCHAR *dest,UCHAR *source)
+{
+  UCHAR buf1[100];
+  UCHAR buf2[100];
+  UCHAR *start_p=NULL,*end_p=NULL,*tmp_p=NULL;
+  int ii;
+
+    memset(buf1,0,100);
+    strcat(buf1, string);
+    strcat(buf1, "=");
+    source+=strlen(buf1);
+
+//find target string start point
+    if((start_p = kstrstr(source,buf1))==NULL)
+	return FALSE;
+
+//check if current config line is marked by "#" ??
+for(ii=1;;ii++) {
+  if(memcmp(start_p-ii,"\n",1)==0)
+      break;
+  if(memcmp(start_p-ii,"#",1)==0)
+      return FALSE;
+}
+
+//find target string end point
+     if((end_p = kstrstr(start_p,"\n"))==NULL) {       //cann't find "\n",but don't care
+          end_p=start_p+strlen(start_p);   //no include "\n"
+       }
+
+   memset(buf2,0,100);
+   memcpy(buf2,start_p,end_p-start_p);    //get the tartget line
+   buf2[end_p-start_p]='\0';
+
+   //find value
+   if((start_p = kstrstr(buf2,"="))==NULL)
+      return FALSE;
+   memset(buf1,0,100);
+   strcpy(buf1,start_p+1);
+
+  //except space
+  tmp_p = buf1;
+  while(*tmp_p != 0x00) {
+  	if(*tmp_p==' ')
+	    tmp_p++;
+         else
+	  break;
+  }
+
+   memcpy(dest,tmp_p,strlen(tmp_p));
+ return TRUE;
+}
+
+//if read fail,return NULL,or return data pointer;
+static UCHAR *Config_FileOperation(PSDevice pDevice) {
+    UCHAR    *config_path=CONFIG_PATH;
+    UCHAR    *buffer=NULL;
+    struct file   *filp=NULL;
+    mm_segment_t old_fs = get_fs();
+    int oldfsuid=0,oldfsgid=0;
+    int result=0;
+
+    set_fs (KERNEL_DS);
+//Make sure a caller can read or write power as root
+   oldfsuid=current->fsuid;
+   oldfsgid=current->fsgid;
+    current->fsuid = 0;
+    current->fsgid = 0;
+
+    //open file
+      filp = filp_open(config_path, O_RDWR, 0);
+        if (IS_ERR(filp)) {
+	     printk("Config_FileOperation file Not exist\n");
+	     result=-1;
+             goto error2;
+	  }
+
+     if(!(filp->f_op) || !(filp->f_op->read) ||!(filp->f_op->write)) {
+           printk("file %s cann't readable or writable?\n",config_path);
+	  result = -1;
+	  goto error1;
+     	}
+
+    buffer = (UCHAR *)kmalloc(1024, GFP_KERNEL);
+    if(buffer==NULL) {
+      printk("alllocate mem for file fail?\n");
+      result = -1;
+      goto error1;
+    }
+
+    if(filp->f_op->read(filp, buffer, 1024, &filp->f_pos)<0) {
+     printk("read file error?\n");
+     result = -1;
+    }
+
+error1:
+  if(filp_close(filp,NULL))
+       printk("Config_FileOperation:close file fail\n");
+
+error2:
+  set_fs (old_fs);
+  current->fsuid=oldfsuid;
+  current->fsgid=oldfsgid;
+
+if(result!=0) {
+    if(buffer)
+  	 kfree(buffer);
+    buffer=NULL;
+}
+  return buffer;
+}
+
+//return --->-1:fail;  >=0:sucessful
+static int Read_config_file(PSDevice pDevice) {
+  int result=0;
+  UCHAR      tmpbuffer[100];
+  UCHAR *buffer=NULL;
+
+  //init config setting
+ pDevice->config_file.ZoneType = -1;
+ pDevice->config_file.eAuthenMode = -1;
+ pDevice->config_file.eEncryptionStatus = -1;
+
+  if((buffer=Config_FileOperation(pDevice)) ==NULL) {
+     result =-1;
+     return result;
+  }
+
+//get zonetype
+{
+    memset(tmpbuffer,0,sizeof(tmpbuffer));
+    if(Config_FileGetParameter("ZONETYPE",tmpbuffer,buffer) ==TRUE) {
+    if(memcmp(tmpbuffer,"USA",3)==0) {
+      pDevice->config_file.ZoneType=ZoneType_USA;
+    }
+    else if(memcmp(tmpbuffer,"JAPAN",5)==0) {
+      pDevice->config_file.ZoneType=ZoneType_Japan;
+    }
+    else if(memcmp(tmpbuffer,"EUROPE",6)==0) {
+     pDevice->config_file.ZoneType=ZoneType_Europe;
+    }
+    else {
+      printk("Unknown Zonetype[%s]?\n",tmpbuffer);
+   }
+ }
+}
+
+#if 1
+//get other parameter
+  {
+	memset(tmpbuffer,0,sizeof(tmpbuffer));
+       if(Config_FileGetParameter("AUTHENMODE",tmpbuffer,buffer)==TRUE) {
+	 pDevice->config_file.eAuthenMode = (int) simple_strtol(tmpbuffer, NULL, 10);
+       }
+
+	memset(tmpbuffer,0,sizeof(tmpbuffer));
+       if(Config_FileGetParameter("ENCRYPTIONMODE",tmpbuffer,buffer)==TRUE) {
+	 pDevice->config_file.eEncryptionStatus= (int) simple_strtol(tmpbuffer, NULL, 10);
+       }
+  }
+#endif
+
+  kfree(buffer);
+  return result;
+}
+
+static void device_set_multi(struct net_device *dev) {
+    PSDevice         pDevice = (PSDevice) dev->priv;
+    PSMgmtObject     pMgmt = &(pDevice->sMgmtObj);
+    u32              mc_filter[2];
+    int              ii;
+    struct dev_mc_list  *mclist;
+    BYTE             pbyData[8] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
+    BYTE             byTmpMode = 0;
+    int              rc;
+
+
+	spin_lock_irq(&pDevice->lock);
+    rc = CONTROLnsRequestIn(pDevice,
+                            MESSAGE_TYPE_READ,
+                            MAC_REG_RCR,
+                            MESSAGE_REQUEST_MACREG,
+                            1,
+                            &byTmpMode
+                            );
+    if (rc == 0) pDevice->byRxMode = byTmpMode;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRxMode in= %x\n", pDevice->byRxMode);
+
+    if (dev->flags & IFF_PROMISC) {         // Set promiscuous.
+        DBG_PRT(MSG_LEVEL_ERR,KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name);
+        // Unconditionally log net taps.
+        pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST|RCR_UNICAST);
+    }
+    else if ((dev->mc_count > pDevice->multicast_limit) || (dev->flags & IFF_ALLMULTI)) {
+        CONTROLnsRequestOut(pDevice,
+                            MESSAGE_TYPE_WRITE,
+                            MAC_REG_MAR0,
+                            MESSAGE_REQUEST_MACREG,
+                            8,
+                            pbyData
+                            );
+        pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
+    }
+    else {
+        memset(mc_filter, 0, sizeof(mc_filter));
+        for (ii = 0, mclist = dev->mc_list; mclist && ii < dev->mc_count;
+             ii++, mclist = mclist->next) {
+            int bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
+            mc_filter[bit_nr >> 5] |= cpu_to_le32(1 << (bit_nr & 31));
+        }
+        for (ii = 0; ii < 4; ii++) {
+             MACvWriteMultiAddr(pDevice, ii, *((PBYTE)&mc_filter[0] + ii));
+             MACvWriteMultiAddr(pDevice, ii+ 4, *((PBYTE)&mc_filter[1] + ii));
+        }
+        pDevice->byRxMode &= ~(RCR_UNICAST);
+        pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
+    }
+
+    if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
+        // If AP mode, don't enable RCR_UNICAST. Since hw only compare addr1 with local mac.
+        pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
+        pDevice->byRxMode &= ~(RCR_UNICAST);
+    }
+    ControlvWriteByte(pDevice, MESSAGE_REQUEST_MACREG, MAC_REG_RCR, pDevice->byRxMode);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRxMode out= %x\n", pDevice->byRxMode);
+	spin_unlock_irq(&pDevice->lock);
+
+}
+
+
+static struct net_device_stats *device_get_stats(struct net_device *dev) {
+    PSDevice pDevice=(PSDevice) dev->priv;
+
+    return &pDevice->stats;
+}
+
+
+static int  device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
+	PSDevice	        pDevice = (PSDevice)dev->priv;
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+    PSCmdRequest        pReq;
+    //BOOL                bCommit = FALSE;
+#ifdef WIRELESS_EXT
+	struct iwreq *wrq = (struct iwreq *) rq;
+	int                 rc =0;
+#endif //WIRELESS_EXT
+
+
+    if (pMgmt == NULL) {
+        rc = -EFAULT;
+        return rc;
+    }
+
+    switch(cmd) {
+
+#ifdef WIRELESS_EXT
+//#if WIRELESS_EXT < 13
+
+	case SIOCGIWNAME:
+		rc = iwctl_giwname(dev, NULL, (char *)&(wrq->u.name), NULL);
+		break;
+
+	case SIOCSIWNWID:
+        rc = -EOPNOTSUPP;
+		break;
+
+	case SIOCGIWNWID:     //0x8b03  support
+	#ifdef  WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+          rc = iwctl_giwnwid(dev, NULL, &(wrq->u.nwid), NULL);
+	#else
+        rc = -EOPNOTSUPP;
+	#endif
+		break;
+
+		// Set frequency/channel
+	case SIOCSIWFREQ:
+	    rc = iwctl_siwfreq(dev, NULL, &(wrq->u.freq), NULL);
+		break;
+
+		// Get frequency/channel
+	case SIOCGIWFREQ:
+		rc = iwctl_giwfreq(dev, NULL, &(wrq->u.freq), NULL);
+		break;
+
+		// Set desired network name (ESSID)
+	case SIOCSIWESSID:
+
+		{
+			char essid[IW_ESSID_MAX_SIZE+1];
+			if (wrq->u.essid.length > IW_ESSID_MAX_SIZE) {
+				rc = -E2BIG;
+				break;
+			}
+			if (copy_from_user(essid, wrq->u.essid.pointer,
+					   wrq->u.essid.length)) {
+				rc = -EFAULT;
+				break;
+			}
+			rc = iwctl_siwessid(dev, NULL,
+					    &(wrq->u.essid), essid);
+		}
+		break;
+
+
+		// Get current network name (ESSID)
+	case SIOCGIWESSID:
+
+		{
+			char essid[IW_ESSID_MAX_SIZE+1];
+			if (wrq->u.essid.pointer)
+				rc = iwctl_giwessid(dev, NULL,
+						    &(wrq->u.essid), essid);
+				if (copy_to_user(wrq->u.essid.pointer,
+						         essid,
+						         wrq->u.essid.length) )
+					rc = -EFAULT;
+		}
+		break;
+
+	case SIOCSIWAP:
+
+		rc = iwctl_siwap(dev, NULL, &(wrq->u.ap_addr), NULL);
+		break;
+
+
+		// Get current Access Point (BSSID)
+	case SIOCGIWAP:
+		rc = iwctl_giwap(dev, NULL, &(wrq->u.ap_addr), NULL);
+		break;
+
+
+		// Set desired station name
+	case SIOCSIWNICKN:
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWNICKN \n");
+        rc = -EOPNOTSUPP;
+		break;
+
+		// Get current station name
+	case SIOCGIWNICKN:
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWNICKN \n");
+        rc = -EOPNOTSUPP;
+		break;
+
+		// Set the desired bit-rate
+	case SIOCSIWRATE:
+		rc = iwctl_siwrate(dev, NULL, &(wrq->u.bitrate), NULL);
+		break;
+
+	// Get the current bit-rate
+	case SIOCGIWRATE:
+
+		rc = iwctl_giwrate(dev, NULL, &(wrq->u.bitrate), NULL);
+		break;
+
+	// Set the desired RTS threshold
+	case SIOCSIWRTS:
+
+		rc = iwctl_siwrts(dev, NULL, &(wrq->u.rts), NULL);
+		break;
+
+	// Get the current RTS threshold
+	case SIOCGIWRTS:
+
+		rc = iwctl_giwrts(dev, NULL, &(wrq->u.rts), NULL);
+		break;
+
+		// Set the desired fragmentation threshold
+	case SIOCSIWFRAG:
+
+		rc = iwctl_siwfrag(dev, NULL, &(wrq->u.frag), NULL);
+	    break;
+
+	// Get the current fragmentation threshold
+	case SIOCGIWFRAG:
+
+		rc = iwctl_giwfrag(dev, NULL, &(wrq->u.frag), NULL);
+		break;
+
+		// Set mode of operation
+	case SIOCSIWMODE:
+    	rc = iwctl_siwmode(dev, NULL, &(wrq->u.mode), NULL);
+		break;
+
+		// Get mode of operation
+	case SIOCGIWMODE:
+		rc = iwctl_giwmode(dev, NULL, &(wrq->u.mode), NULL);
+		break;
+
+		// Set WEP keys and mode
+	case SIOCSIWENCODE:
+		{
+            char abyKey[WLAN_WEP232_KEYLEN];
+
+			if (wrq->u.encoding.pointer) {
+
+
+				if (wrq->u.encoding.length > WLAN_WEP232_KEYLEN) {
+					rc = -E2BIG;
+					break;
+				}
+				memset(abyKey, 0, WLAN_WEP232_KEYLEN);
+				if (copy_from_user(abyKey,
+				                  wrq->u.encoding.pointer,
+				                  wrq->u.encoding.length)) {
+					rc = -EFAULT;
+					break;
+				}
+			} else if (wrq->u.encoding.length != 0) {
+				rc = -EINVAL;
+				break;
+			}
+			rc = iwctl_siwencode(dev, NULL, &(wrq->u.encoding), abyKey);
+		}
+		break;
+
+		// Get the WEP keys and mode
+	case SIOCGIWENCODE:
+
+		if (!capable(CAP_NET_ADMIN)) {
+			rc = -EPERM;
+			break;
+		}
+		{
+		    char abyKey[WLAN_WEP232_KEYLEN];
+
+		    rc = iwctl_giwencode(dev, NULL, &(wrq->u.encoding), abyKey);
+		    if (rc != 0) break;
+			if (wrq->u.encoding.pointer) {
+				if (copy_to_user(wrq->u.encoding.pointer,
+						        abyKey,
+						        wrq->u.encoding.length))
+					rc = -EFAULT;
+			}
+		}
+		break;
+
+#if WIRELESS_EXT > 9
+		// Get the current Tx-Power
+	case SIOCGIWTXPOW:
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWTXPOW \n");
+        rc = -EOPNOTSUPP;
+		break;
+
+	case SIOCSIWTXPOW:
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWTXPOW \n");
+        rc = -EOPNOTSUPP;
+		break;
+
+#endif // WIRELESS_EXT > 9
+
+#if WIRELESS_EXT > 10
+	case SIOCSIWRETRY:
+
+		rc = iwctl_siwretry(dev, NULL, &(wrq->u.retry), NULL);
+		break;
+
+	case SIOCGIWRETRY:
+
+		rc = iwctl_giwretry(dev, NULL, &(wrq->u.retry), NULL);
+		break;
+
+#endif // WIRELESS_EXT > 10
+
+		// Get range of parameters
+	case SIOCGIWRANGE:
+
+		{
+			struct iw_range range;
+
+			rc = iwctl_giwrange(dev, NULL, &(wrq->u.data), (char *) &range);
+			if (copy_to_user(wrq->u.data.pointer, &range, sizeof(struct iw_range)))
+				rc = -EFAULT;
+		}
+
+		break;
+
+	case SIOCGIWPOWER:
+
+		rc = iwctl_giwpower(dev, NULL, &(wrq->u.power), NULL);
+		break;
+
+
+	case SIOCSIWPOWER:
+
+		rc = iwctl_siwpower(dev, NULL, &(wrq->u.power), NULL);
+		break;
+
+
+	case SIOCGIWSENS:
+
+	    rc = iwctl_giwsens(dev, NULL, &(wrq->u.sens), NULL);
+		break;
+
+	case SIOCSIWSENS:
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSENS \n");
+		rc = -EOPNOTSUPP;
+		break;
+
+	case SIOCGIWAPLIST:
+	    {
+            char buffer[IW_MAX_AP * (sizeof(struct sockaddr) + sizeof(struct iw_quality))];
+
+		    if (wrq->u.data.pointer) {
+		        rc = iwctl_giwaplist(dev, NULL, &(wrq->u.data), buffer);
+		        if (rc == 0) {
+                    if (copy_to_user(wrq->u.data.pointer,
+					                buffer,
+					               (wrq->u.data.length * (sizeof(struct sockaddr) +  sizeof(struct iw_quality)))
+				        ))
+				    rc = -EFAULT;
+		        }
+            }
+        }
+		break;
+
+
+#ifdef WIRELESS_SPY
+		// Set the spy list
+	case SIOCSIWSPY:
+
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSPY \n");
+		rc = -EOPNOTSUPP;
+		break;
+
+		// Get the spy list
+	case SIOCGIWSPY:
+
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSPY \n");
+		rc = -EOPNOTSUPP;
+		break;
+
+#endif // WIRELESS_SPY
+
+	case SIOCGIWPRIV:
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPRIV \n");
+		rc = -EOPNOTSUPP;
+/*
+		if(wrq->u.data.pointer) {
+			wrq->u.data.length = sizeof(iwctl_private_args) / sizeof( iwctl_private_args[0]);
+
+			if(copy_to_user(wrq->u.data.pointer,
+					(u_char *) iwctl_private_args,
+					sizeof(iwctl_private_args)))
+				rc = -EFAULT;
+		}
+*/
+		break;
+
+
+//#endif // WIRELESS_EXT < 13
+
+//2008-0409-07, <Add> by Einsn Liu
+#ifdef  WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+	case SIOCSIWAUTH:
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH \n");
+		rc = iwctl_siwauth(dev, NULL, &(wrq->u.param), NULL);
+		break;
+
+	case SIOCGIWAUTH:
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAUTH \n");
+		rc = iwctl_giwauth(dev, NULL, &(wrq->u.param), NULL);
+		break;
+
+	case SIOCSIWGENIE:
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWGENIE \n");
+		rc = iwctl_siwgenie(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
+		break;
+
+	case SIOCGIWGENIE:
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWGENIE \n");
+		rc = iwctl_giwgenie(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
+		break;
+
+	case SIOCSIWENCODEEXT:
+		{
+			char extra[sizeof(struct iw_encode_ext)+MAX_KEY_LEN+1];
+			DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODEEXT \n");
+			if(wrq->u.encoding.pointer){
+				memset(extra, 0, sizeof(struct iw_encode_ext)+MAX_KEY_LEN+1);
+				if(wrq->u.encoding.length > (sizeof(struct iw_encode_ext)+ MAX_KEY_LEN)){
+					rc = -E2BIG;
+					break;
+				}
+				if(copy_from_user(extra, wrq->u.encoding.pointer,wrq->u.encoding.length)){
+					rc = -EFAULT;
+					break;
+				}
+			}else if(wrq->u.encoding.length != 0){
+				rc = -EINVAL;
+				break;
+			}
+			rc = iwctl_siwencodeext(dev, NULL, &(wrq->u.encoding), extra);
+		}
+		break;
+
+	case SIOCGIWENCODEEXT:
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODEEXT \n");
+		rc = iwctl_giwencodeext(dev, NULL, &(wrq->u.encoding), NULL);
+		break;
+
+	case SIOCSIWMLME:
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMLME \n");
+		rc = iwctl_siwmlme(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
+		break;
+
+#endif // #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+//End Add -- //2008-0409-07, <Add> by Einsn Liu
+
+#endif // WIRELESS_EXT
+
+    case IOCTL_CMD_TEST:
+
+		if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
+		    rc = -EFAULT;
+		    break;
+		} else {
+		    rc = 0;
+		}
+        pReq = (PSCmdRequest)rq;
+
+   //20080130-01,<Remark> by Mike Liu
+      // if(pDevice->bLinkPass==TRUE)
+          pReq->wResult = MAGIC_CODE;         //Linking status:0x3142
+   //20080130-02,<Remark> by Mike Liu
+      //  else
+      //	 pReq->wResult = MAGIC_CODE+1;    //disconnect status:0x3143
+        break;
+
+    case IOCTL_CMD_SET:
+		if (!(pDevice->flags & DEVICE_FLAGS_OPENED) &&
+		       (((PSCmdRequest)rq)->wCmdCode !=WLAN_CMD_SET_WPA))
+		{
+		    rc = -EFAULT;
+		    break;
+		} else {
+		    rc = 0;
+		}
+
+	    if (test_and_set_bit( 0, (void*)&(pMgmt->uCmdBusy))) {
+		    return -EBUSY;
+	    }
+        rc = private_ioctl(pDevice, rq);
+        clear_bit( 0, (void*)&(pMgmt->uCmdBusy));
+        break;
+
+    case IOCTL_CMD_HOSTAPD:
+
+		if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
+		    rc = -EFAULT;
+		    break;
+		} else {
+		    rc = 0;
+		}
+
+#if WIRELESS_EXT > 8
+		rc = hostap_ioctl(pDevice, &wrq->u.data);
+#else // WIRELESS_EXT > 8
+		rc = hostap_ioctl(pDevice, (struct iw_point *) &wrq->u.data);
+#endif // WIRELESS_EXT > 8
+        break;
+
+    case IOCTL_CMD_WPA:
+
+		if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
+		    rc = -EFAULT;
+		    break;
+		} else {
+		    rc = 0;
+		}
+
+#if WIRELESS_EXT > 8
+		rc = wpa_ioctl(pDevice, &wrq->u.data);
+#else // WIRELESS_EXT > 8
+		rc = wpa_ioctl(pDevice, (struct iw_point *) &wrq->u.data);
+#endif // WIRELESS_EXT > 8
+        break;
+
+	case SIOCETHTOOL:
+        return ethtool_ioctl(dev, (void *) rq->ifr_data);
+	// All other calls are currently unsupported
+
+	default:
+		rc = -EOPNOTSUPP;
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Ioctl command not support..%x\n", cmd);
+
+
+    }
+
+    if (pDevice->bCommit) {
+       if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
+           netif_stop_queue(pDevice->dev);
+           spin_lock_irq(&pDevice->lock);
+           bScheduleCommand((HANDLE)pDevice, WLAN_CMD_RUN_AP, NULL);
+           spin_unlock_irq(&pDevice->lock);
+       }
+       else {
+           DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Commit the settings\n");
+           spin_lock_irq(&pDevice->lock);
+//2007-1121-01<Modify>by EinsnLiu
+	    if (pDevice->bLinkPass&&
+		  memcmp(pMgmt->abyCurrSSID,pMgmt->abyDesireSSID,WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN)) {
+      		  bScheduleCommand((HANDLE)pDevice, WLAN_CMD_DISASSOCIATE, NULL);
+	     } else {
+           pDevice->bLinkPass = FALSE;
+	   pMgmt->eCurrState = WMAC_STATE_IDLE;
+	   memset(pMgmt->abyCurrBSSID, 0, 6);
+		 }
+           ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW);
+//End Modify
+           netif_stop_queue(pDevice->dev);
+#ifdef  WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+           pMgmt->eScanType = WMAC_SCAN_ACTIVE;
+           if(pDevice->bWPASuppWextEnabled !=TRUE)
+#endif
+           bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID);
+           bScheduleCommand((HANDLE) pDevice, WLAN_CMD_SSID, NULL);
+           spin_unlock_irq(&pDevice->lock);
+      }
+      pDevice->bCommit = FALSE;
+    }
+
+
+    return rc;
+}
+
+
+static int ethtool_ioctl(struct net_device *dev, void *useraddr)
+{
+	u32 ethcmd;
+
+	if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
+		return -EFAULT;
+
+        switch (ethcmd) {
+	case ETHTOOL_GDRVINFO: {
+		struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
+		strncpy(info.driver, DEVICE_NAME, sizeof(info.driver)-1);
+		strncpy(info.version, DEVICE_VERSION, sizeof(info.version)-1);
+		if (copy_to_user(useraddr, &info, sizeof(info)))
+			return -EFAULT;
+		return 0;
+	}
+
+        }
+
+	return -EOPNOTSUPP;
+}
+
+
+/*------------------------------------------------------------------*/
+
+
+MODULE_DEVICE_TABLE(usb, vntwusb_table);
+
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+
+static struct usb_driver vntwusb_driver = {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
+	    .owner =	THIS_MODULE,
+#endif
+	    .name =		DEVICE_NAME,
+	    .probe =	vntwusb_found1,
+	    .disconnect =	vntwusb_disconnect,
+	    .id_table =	vntwusb_table,
+
+//2008-0920-01<Add>by MikeLiu
+//for supporting S3 & S4 function
+#ifdef CONFIG_PM
+	   .suspend = vntwusb_suspend,
+	   .resume = vntwusb_resume,
+#endif
+};
+
+#else
+
+static struct usb_driver vntwusb_driver = {
+	    name:   DEVICE_NAME,
+	    probe:  vntwusb_found1,
+	    disconnect: vntwusb_disconnect,
+	    id_table:   vntwusb_table,
+};
+
+#endif
+
+static int __init vntwusb_init_module(void)
+{
+	info(DEVICE_FULL_DRV_NAM " " DEVICE_VERSION);
+    return usb_register(&vntwusb_driver);
+}
+
+static void __exit vntwusb_cleanup_module(void)
+{
+	usb_deregister(&vntwusb_driver);
+}
+
+module_init(vntwusb_init_module);
+module_exit(vntwusb_cleanup_module);
+
diff --git a/drivers/staging/vt6656/mib.c b/drivers/staging/vt6656/mib.c
new file mode 100644
index 0000000..35b6c2b
--- /dev/null
+++ b/drivers/staging/vt6656/mib.c
@@ -0,0 +1,592 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: mib.c
+ *
+ * Purpose: Implement MIB Data Structure
+ *
+ * Author: Tevin Chen
+ *
+ * Date: May 21, 1996
+ *
+ * Functions:
+ *      STAvClearAllCounter - Clear All MIB Counter
+ *      STAvUpdateIstStatCounter - Update ISR statistic counter
+ *      STAvUpdateRDStatCounter - Update Rx statistic counter
+ *      STAvUpdateRDStatCounterEx - Update Rx statistic counter and copy rcv data
+ *      STAvUpdateTDStatCounter - Update Tx statistic counter
+ *      STAvUpdateTDStatCounterEx - Update Tx statistic counter and copy tx data
+ *      STAvUpdate802_11Counter - Update 802.11 mib counter
+ *
+ * Revision History:
+ *
+ */
+
+
+#if !defined(__UPC_H__)
+#include "upc.h"
+#endif
+#if !defined(__MAC_H__)
+#include "mac.h"
+#endif
+#if !defined(__TBIT_H__)
+#include "tbit.h"
+#endif
+#if !defined(__TETHER_H__)
+#include "tether.h"
+#endif
+#if !defined(__MIB_H__)
+#include "mib.h"
+#endif
+#if !defined(__WCTL_H__)
+#include "wctl.h"
+#endif
+#if !defined(__UMEM_H__)
+#include "umem.h"
+#endif
+#if !defined(__BASEBAND_H__)
+#include "baseband.h"
+#endif
+
+/*---------------------  Static Definitions -------------------------*/
+static int          msglevel                =MSG_LEVEL_INFO;
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+
+/*---------------------  Static Functions  --------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+
+/*
+ * Description: Clear All Statistic Counter
+ *
+ * Parameters:
+ *  In:
+ *      pStatistic  - Pointer to Statistic Counter Data Structure
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void STAvClearAllCounter (PSStatCounter pStatistic)
+{
+    // set memory to zero
+    ZERO_MEMORY(pStatistic, sizeof(SStatCounter));
+}
+
+
+/*
+ * Description: Update Isr Statistic Counter
+ *
+ * Parameters:
+ *  In:
+ *      pStatistic  - Pointer to Statistic Counter Data Structure
+ *      wisr        - Interrupt status
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void STAvUpdateIsrStatCounter (PSStatCounter pStatistic, BYTE byIsr0, BYTE byIsr1)
+{
+    /**********************/
+    /* ABNORMAL interrupt */
+    /**********************/
+    // not any IMR bit invoke irq
+    if (byIsr0 == 0) {
+        pStatistic->ISRStat.dwIsrUnknown++;
+        return;
+    }
+
+
+    if (BITbIsBitOn(byIsr0, ISR_ACTX))              // ISR, bit0
+        pStatistic->ISRStat.dwIsrTx0OK++;           // TXDMA0 successful
+
+    if (BITbIsBitOn(byIsr0, ISR_BNTX))              // ISR, bit2
+        pStatistic->ISRStat.dwIsrBeaconTxOK++;      // BeaconTx successful
+
+    if (BITbIsBitOn(byIsr0, ISR_RXDMA0))            // ISR, bit3
+        pStatistic->ISRStat.dwIsrRx0OK++;           // Rx0 successful
+
+    if (BITbIsBitOn(byIsr0, ISR_TBTT))              // ISR, bit4
+        pStatistic->ISRStat.dwIsrTBTTInt++;         // TBTT successful
+
+    if (BITbIsBitOn(byIsr0, ISR_SOFTTIMER))         // ISR, bit6
+        pStatistic->ISRStat.dwIsrSTIMERInt++;
+
+    if (BITbIsBitOn(byIsr0, ISR_WATCHDOG))          // ISR, bit7
+        pStatistic->ISRStat.dwIsrWatchDog++;
+
+
+    if (BITbIsBitOn(byIsr1, ISR_FETALERR))              // ISR, bit8
+        pStatistic->ISRStat.dwIsrUnrecoverableError++;
+
+    if (BITbIsBitOn(byIsr1, ISR_SOFTINT))               // ISR, bit9
+        pStatistic->ISRStat.dwIsrSoftInterrupt++;       // software interrupt
+
+    if (BITbIsBitOn(byIsr1, ISR_MIBNEARFULL))           // ISR, bit10
+        pStatistic->ISRStat.dwIsrMIBNearfull++;
+
+    if (BITbIsBitOn(byIsr1, ISR_RXNOBUF))               // ISR, bit11
+        pStatistic->ISRStat.dwIsrRxNoBuf++;             // Rx No Buff
+
+}
+
+
+/*
+ * Description: Update Rx Statistic Counter
+ *
+ * Parameters:
+ *  In:
+ *      pStatistic      - Pointer to Statistic Counter Data Structure
+ *      byRSR           - Rx Status
+ *      byNewRSR        - Rx Status
+ *      pbyBuffer       - Rx Buffer
+ *      cbFrameLength   - Rx Length
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void STAvUpdateRDStatCounter (PSStatCounter pStatistic,
+                              BYTE byRSR, BYTE byNewRSR, BYTE byRxSts, BYTE byRxRate,
+                              PBYTE pbyBuffer, UINT cbFrameLength)
+{
+    //need change
+    PS802_11Header pHeader = (PS802_11Header)pbyBuffer;
+
+    if (BITbIsBitOn(byRSR, RSR_ADDROK))
+        pStatistic->dwRsrADDROk++;
+    if (BITbIsBitOn(byRSR, RSR_CRCOK)) {
+        pStatistic->dwRsrCRCOk++;
+
+        pStatistic->ullRsrOK++;
+
+        if (cbFrameLength >= U_ETHER_ADDR_LEN) {
+            // update counters in case that successful transmit
+            if (BITbIsBitOn(byRSR, RSR_ADDRBROAD)) {
+                pStatistic->ullRxBroadcastFrames++;
+                pStatistic->ullRxBroadcastBytes += (ULONGLONG)cbFrameLength;
+            }
+            else if (BITbIsBitOn(byRSR, RSR_ADDRMULTI)) {
+                pStatistic->ullRxMulticastFrames++;
+                pStatistic->ullRxMulticastBytes += (ULONGLONG)cbFrameLength;
+            }
+            else {
+                pStatistic->ullRxDirectedFrames++;
+                pStatistic->ullRxDirectedBytes += (ULONGLONG)cbFrameLength;
+            }
+        }
+    }
+
+    if(byRxRate==22) {
+        pStatistic->CustomStat.ullRsr11M++;
+        if(BITbIsBitOn(byRSR, RSR_CRCOK)) {
+            pStatistic->CustomStat.ullRsr11MCRCOk++;
+        }
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"11M: ALL[%d], OK[%d]:[%02x]\n", (INT)pStatistic->CustomStat.ullRsr11M, (INT)pStatistic->CustomStat.ullRsr11MCRCOk, byRSR);
+    }
+    else if(byRxRate==11) {
+        pStatistic->CustomStat.ullRsr5M++;
+        if(BITbIsBitOn(byRSR, RSR_CRCOK)) {
+            pStatistic->CustomStat.ullRsr5MCRCOk++;
+        }
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" 5M: ALL[%d], OK[%d]:[%02x]\n", (INT)pStatistic->CustomStat.ullRsr5M, (INT)pStatistic->CustomStat.ullRsr5MCRCOk, byRSR);
+    }
+    else if(byRxRate==4) {
+        pStatistic->CustomStat.ullRsr2M++;
+        if(BITbIsBitOn(byRSR, RSR_CRCOK)) {
+            pStatistic->CustomStat.ullRsr2MCRCOk++;
+        }
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" 2M: ALL[%d], OK[%d]:[%02x]\n", (INT)pStatistic->CustomStat.ullRsr2M, (INT)pStatistic->CustomStat.ullRsr2MCRCOk, byRSR);
+    }
+    else if(byRxRate==2){
+        pStatistic->CustomStat.ullRsr1M++;
+        if(BITbIsBitOn(byRSR, RSR_CRCOK)) {
+            pStatistic->CustomStat.ullRsr1MCRCOk++;
+        }
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" 1M: ALL[%d], OK[%d]:[%02x]\n", (INT)pStatistic->CustomStat.ullRsr1M, (INT)pStatistic->CustomStat.ullRsr1MCRCOk, byRSR);
+    }
+    else if(byRxRate==12){
+        pStatistic->CustomStat.ullRsr6M++;
+        if(BITbIsBitOn(byRSR, RSR_CRCOK)) {
+            pStatistic->CustomStat.ullRsr6MCRCOk++;
+        }
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" 6M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr6M, (INT)pStatistic->CustomStat.ullRsr6MCRCOk);
+    }
+    else if(byRxRate==18){
+        pStatistic->CustomStat.ullRsr9M++;
+        if(BITbIsBitOn(byRSR, RSR_CRCOK)) {
+            pStatistic->CustomStat.ullRsr9MCRCOk++;
+        }
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" 9M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr9M, (INT)pStatistic->CustomStat.ullRsr9MCRCOk);
+    }
+    else if(byRxRate==24){
+        pStatistic->CustomStat.ullRsr12M++;
+        if(BITbIsBitOn(byRSR, RSR_CRCOK)) {
+            pStatistic->CustomStat.ullRsr12MCRCOk++;
+        }
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"12M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr12M, (INT)pStatistic->CustomStat.ullRsr12MCRCOk);
+    }
+    else if(byRxRate==36){
+        pStatistic->CustomStat.ullRsr18M++;
+        if(BITbIsBitOn(byRSR, RSR_CRCOK)) {
+            pStatistic->CustomStat.ullRsr18MCRCOk++;
+        }
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"18M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr18M, (INT)pStatistic->CustomStat.ullRsr18MCRCOk);
+    }
+    else if(byRxRate==48){
+        pStatistic->CustomStat.ullRsr24M++;
+        if(BITbIsBitOn(byRSR, RSR_CRCOK)) {
+            pStatistic->CustomStat.ullRsr24MCRCOk++;
+        }
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"24M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr24M, (INT)pStatistic->CustomStat.ullRsr24MCRCOk);
+    }
+    else if(byRxRate==72){
+        pStatistic->CustomStat.ullRsr36M++;
+        if(BITbIsBitOn(byRSR, RSR_CRCOK)) {
+            pStatistic->CustomStat.ullRsr36MCRCOk++;
+        }
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"36M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr36M, (INT)pStatistic->CustomStat.ullRsr36MCRCOk);
+    }
+    else if(byRxRate==96){
+        pStatistic->CustomStat.ullRsr48M++;
+        if(BITbIsBitOn(byRSR, RSR_CRCOK)) {
+            pStatistic->CustomStat.ullRsr48MCRCOk++;
+        }
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"48M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr48M, (INT)pStatistic->CustomStat.ullRsr48MCRCOk);
+    }
+    else if(byRxRate==108){
+        pStatistic->CustomStat.ullRsr54M++;
+        if(BITbIsBitOn(byRSR, RSR_CRCOK)) {
+            pStatistic->CustomStat.ullRsr54MCRCOk++;
+        }
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"54M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr54M, (INT)pStatistic->CustomStat.ullRsr54MCRCOk);
+    }
+    else {
+    	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Unknown: Total[%d], CRCOK[%d]\n", (INT)pStatistic->dwRsrRxPacket+1, (INT)pStatistic->dwRsrCRCOk);
+    }
+
+    if (BITbIsBitOn(byRSR, RSR_BSSIDOK))
+        pStatistic->dwRsrBSSIDOk++;
+
+    if (BITbIsBitOn(byRSR, RSR_BCNSSIDOK))
+        pStatistic->dwRsrBCNSSIDOk++;
+    if (BITbIsBitOn(byRSR, RSR_IVLDLEN))  //invalid len (> 2312 byte)
+        pStatistic->dwRsrLENErr++;
+    if (BITbIsBitOn(byRSR, RSR_IVLDTYP))  //invalid packet type
+        pStatistic->dwRsrTYPErr++;
+    if (BITbIsBitOn(byRSR, (RSR_IVLDTYP | RSR_IVLDLEN)) || BITbIsBitOff(byRSR, RSR_CRCOK))
+        pStatistic->dwRsrErr++;
+
+    if (BITbIsBitOn(byNewRSR, NEWRSR_DECRYPTOK))
+        pStatistic->dwNewRsrDECRYPTOK++;
+    if (BITbIsBitOn(byNewRSR, NEWRSR_CFPIND))
+        pStatistic->dwNewRsrCFP++;
+    if (BITbIsBitOn(byNewRSR, NEWRSR_HWUTSF))
+        pStatistic->dwNewRsrUTSF++;
+    if (BITbIsBitOn(byNewRSR, NEWRSR_BCNHITAID))
+        pStatistic->dwNewRsrHITAID++;
+    if (BITbIsBitOn(byNewRSR, NEWRSR_BCNHITAID0))
+        pStatistic->dwNewRsrHITAID0++;
+
+    // increase rx packet count
+    pStatistic->dwRsrRxPacket++;
+    pStatistic->dwRsrRxOctet += cbFrameLength;
+
+
+    if (IS_TYPE_DATA(pbyBuffer)) {
+        pStatistic->dwRsrRxData++;
+    } else if (IS_TYPE_MGMT(pbyBuffer)){
+        pStatistic->dwRsrRxManage++;
+    } else if (IS_TYPE_CONTROL(pbyBuffer)){
+        pStatistic->dwRsrRxControl++;
+    }
+
+    if (BITbIsBitOn(byRSR, RSR_ADDRBROAD))
+        pStatistic->dwRsrBroadcast++;
+    else if (BITbIsBitOn(byRSR, RSR_ADDRMULTI))
+        pStatistic->dwRsrMulticast++;
+    else
+        pStatistic->dwRsrDirected++;
+
+    if (WLAN_GET_FC_MOREFRAG(pHeader->wFrameCtl))
+        pStatistic->dwRsrRxFragment++;
+
+    if (cbFrameLength < MIN_PACKET_LEN + 4) {
+        pStatistic->dwRsrRunt++;
+    }
+    else if (cbFrameLength == MIN_PACKET_LEN + 4) {
+        pStatistic->dwRsrRxFrmLen64++;
+    }
+    else if ((65 <= cbFrameLength) && (cbFrameLength <= 127)) {
+        pStatistic->dwRsrRxFrmLen65_127++;
+    }
+    else if ((128 <= cbFrameLength) && (cbFrameLength <= 255)) {
+        pStatistic->dwRsrRxFrmLen128_255++;
+    }
+    else if ((256 <= cbFrameLength) && (cbFrameLength <= 511)) {
+        pStatistic->dwRsrRxFrmLen256_511++;
+    }
+    else if ((512 <= cbFrameLength) && (cbFrameLength <= 1023)) {
+        pStatistic->dwRsrRxFrmLen512_1023++;
+    }
+    else if ((1024 <= cbFrameLength) && (cbFrameLength <= MAX_PACKET_LEN + 4)) {
+        pStatistic->dwRsrRxFrmLen1024_1518++;
+    } else if (cbFrameLength > MAX_PACKET_LEN + 4) {
+        pStatistic->dwRsrLong++;
+    }
+
+}
+
+
+
+/*
+ * Description: Update Rx Statistic Counter and copy Rx buffer
+ *
+ * Parameters:
+ *  In:
+ *      pStatistic      - Pointer to Statistic Counter Data Structure
+ *      byRSR           - Rx Status
+ *      byNewRSR        - Rx Status
+ *      pbyBuffer       - Rx Buffer
+ *      cbFrameLength   - Rx Length
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+
+void
+STAvUpdateRDStatCounterEx (
+    PSStatCounter   pStatistic,
+    BYTE            byRSR,
+    BYTE            byNewRSR,
+    BYTE            byRxSts,
+    BYTE            byRxRate,
+    PBYTE           pbyBuffer,
+    UINT            cbFrameLength
+    )
+{
+    STAvUpdateRDStatCounter(
+                    pStatistic,
+                    byRSR,
+                    byNewRSR,
+                    byRxSts,
+                    byRxRate,
+                    pbyBuffer,
+                    cbFrameLength
+                    );
+
+    // rx length
+    pStatistic->dwCntRxFrmLength = cbFrameLength;
+    // rx pattern, we just see 10 bytes for sample
+    MEMvCopy(pStatistic->abyCntRxPattern, (PBYTE)pbyBuffer, 10);
+}
+
+
+/*
+ * Description: Update Tx Statistic Counter
+ *
+ * Parameters:
+ *  In:
+ *      pStatistic      - Pointer to Statistic Counter Data Structure
+ *      byTSR0          - Tx Status
+ *      byTSR1          - Tx Status
+ *      pbyBuffer       - Tx Buffer
+ *      cbFrameLength   - Tx Length
+ *      uIdx            - Index of Tx DMA
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void
+STAvUpdateTDStatCounter (
+    PSStatCounter   pStatistic,
+    BYTE            byPktNum,
+    BYTE            byRate,
+    BYTE            byTSR
+    )
+{
+    BYTE    byRetyCnt;
+    // increase tx packet count
+    pStatistic->dwTsrTxPacket++;
+
+    byRetyCnt = (byTSR & 0xF0) >> 4;
+    if (byRetyCnt != 0) {
+        pStatistic->dwTsrRetry++;
+        pStatistic->dwTsrTotalRetry += byRetyCnt;
+        pStatistic->dwTxFail[byRate]+= byRetyCnt;
+        pStatistic->dwTxFail[MAX_RATE] += byRetyCnt;
+
+        if ( byRetyCnt == 0x1)
+            pStatistic->dwTsrOnceRetry++;
+        else
+            pStatistic->dwTsrMoreThanOnceRetry++;
+
+        if (byRetyCnt <= 8)
+            pStatistic->dwTxRetryCount[byRetyCnt-1]++;
+
+    }
+    if (BITbIsAllBitsOff(byTSR, (TSR_TMO | TSR_RETRYTMO))) {
+
+#ifdef Calcu_LinkQual
+   if (byRetyCnt < 2)
+        pStatistic->TxNoRetryOkCount ++;
+   else
+        pStatistic->TxRetryOkCount ++;
+#endif
+
+        pStatistic->ullTsrOK++;
+        pStatistic->CustomStat.ullTsrAllOK++;
+        // update counters in case that successful transmit
+        pStatistic->dwTxOk[byRate]++;
+        pStatistic->dwTxOk[MAX_RATE]++;
+
+        if ( pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni == TX_PKT_BROAD )  {
+            pStatistic->ullTxBroadcastFrames++;
+            pStatistic->ullTxBroadcastBytes += pStatistic->abyTxPktInfo[byPktNum].wLength;
+        } else if ( pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni == TX_PKT_MULTI ) {
+            pStatistic->ullTxMulticastFrames++;
+            pStatistic->ullTxMulticastBytes += pStatistic->abyTxPktInfo[byPktNum].wLength;
+        } else if ( pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni == TX_PKT_UNI ) {
+            pStatistic->ullTxDirectedFrames++;
+            pStatistic->ullTxDirectedBytes += pStatistic->abyTxPktInfo[byPktNum].wLength;
+        }
+    }
+    else {
+
+#ifdef Calcu_LinkQual
+        pStatistic->TxFailCount ++;
+#endif
+
+        pStatistic->dwTsrErr++;
+        if (BITbIsBitOn(byTSR, TSR_RETRYTMO))
+            pStatistic->dwTsrRetryTimeout++;
+        if (BITbIsBitOn(byTSR, TSR_TMO))
+            pStatistic->dwTsrTransmitTimeout++;
+    }
+
+    if ( pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni == TX_PKT_BROAD )  {
+        pStatistic->dwTsrBroadcast++;
+    } else if ( pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni == TX_PKT_MULTI ) {
+        pStatistic->dwTsrMulticast++;
+    } else if ( pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni == TX_PKT_UNI ) {
+        pStatistic->dwTsrDirected++;
+    }
+}
+
+
+
+/*
+ * Description: Update 802.11 mib counter
+ *
+ * Parameters:
+ *  In:
+ *      p802_11Counter  - Pointer to 802.11 mib counter
+ *      pStatistic      - Pointer to Statistic Counter Data Structure
+ *      dwCounter       - hardware counter for 802.11 mib
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void
+STAvUpdate802_11Counter(
+    PSDot11Counters         p802_11Counter,
+    PSStatCounter           pStatistic,
+    BYTE                    byRTSSuccess,
+    BYTE                    byRTSFail,
+    BYTE                    byACKFail,
+    BYTE                    byFCSErr
+    )
+{
+    //p802_11Counter->TransmittedFragmentCount
+    p802_11Counter->MulticastTransmittedFrameCount = (ULONGLONG) (pStatistic->dwTsrBroadcast +
+                                                                  pStatistic->dwTsrMulticast);
+    p802_11Counter->FailedCount = (ULONGLONG) (pStatistic->dwTsrErr);
+    p802_11Counter->RetryCount = (ULONGLONG) (pStatistic->dwTsrRetry);
+    p802_11Counter->MultipleRetryCount = (ULONGLONG) (pStatistic->dwTsrMoreThanOnceRetry);
+    //p802_11Counter->FrameDuplicateCount
+    p802_11Counter->RTSSuccessCount += (ULONGLONG) byRTSSuccess;
+    p802_11Counter->RTSFailureCount += (ULONGLONG) byRTSFail;
+    p802_11Counter->ACKFailureCount += (ULONGLONG) byACKFail;
+    p802_11Counter->FCSErrorCount +=   (ULONGLONG) byFCSErr;
+    //p802_11Counter->ReceivedFragmentCount
+    p802_11Counter->MulticastReceivedFrameCount = (ULONGLONG) (pStatistic->dwRsrBroadcast +
+                                                               pStatistic->dwRsrMulticast);
+}
+
+/*
+ * Description: Clear 802.11 mib counter
+ *
+ * Parameters:
+ *  In:
+ *      p802_11Counter  - Pointer to 802.11 mib counter
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void
+STAvClear802_11Counter(PSDot11Counters p802_11Counter)
+{
+    // set memory to zero
+    ZERO_MEMORY(p802_11Counter, sizeof(SDot11Counters));
+}
+
+/*
+ * Description: Clear 802.11 mib counter
+ *
+ * Parameters:
+ *  In:
+ *      pUsbCounter  - Pointer to USB mib counter
+ *      ntStatus - URB status
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+
+void
+STAvUpdateUSBCounter(PSUSBCounter pUsbCounter,
+                     NTSTATUS ntStatus
+                     )
+{
+
+//    if ( ntStatus == USBD_STATUS_CRC ) {
+        pUsbCounter->dwCrc++;
+//    }
+
+}
+
+
diff --git a/drivers/staging/vt6656/mib.h b/drivers/staging/vt6656/mib.h
new file mode 100644
index 0000000..6a11012
--- /dev/null
+++ b/drivers/staging/vt6656/mib.h
@@ -0,0 +1,445 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: mib.h
+ *
+ * Purpose: Implement MIB Data Structure
+ *
+ * Author: Tevin Chen
+ *
+ * Date: May 21, 1996
+ *
+ */
+
+#ifndef __MIB_H__
+#define __MIB_H__
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+#if !defined(__TETHER_H__)
+#include "tether.h"
+#endif
+#if !defined(__DESC_H__)
+#include "desc.h"
+#endif
+
+
+
+//#define ULONGLONG   ULONG
+
+/*---------------------  Export Definitions -------------------------*/
+
+
+//
+// USB counter
+//
+typedef struct tagSUSBCounter {
+    DWORD dwCrc;
+
+} SUSBCounter, DEF* PSUSBCounter;
+
+
+
+//
+// 802.11 counter
+//
+
+
+typedef struct tagSDot11Counters {
+//    ULONG       Length;             // Length of structure
+    ULONGLONG   TransmittedFragmentCount;
+    ULONGLONG   MulticastTransmittedFrameCount;
+    ULONGLONG   FailedCount;
+    ULONGLONG   RetryCount;
+    ULONGLONG   MultipleRetryCount;
+    ULONGLONG   RTSSuccessCount;
+    ULONGLONG   RTSFailureCount;
+    ULONGLONG   ACKFailureCount;
+    ULONGLONG   FrameDuplicateCount;
+    ULONGLONG   ReceivedFragmentCount;
+    ULONGLONG   MulticastReceivedFrameCount;
+    ULONGLONG   FCSErrorCount;
+    ULONGLONG   TKIPLocalMICFailures;
+    ULONGLONG   TKIPRemoteMICFailures;
+    ULONGLONG   TKIPICVErrors;
+    ULONGLONG   TKIPCounterMeasuresInvoked;
+    ULONGLONG   TKIPReplays;
+    ULONGLONG   CCMPFormatErrors;
+    ULONGLONG   CCMPReplays;
+    ULONGLONG   CCMPDecryptErrors;
+    ULONGLONG   FourWayHandshakeFailures;
+//    ULONGLONG   WEPUndecryptableCount;
+//    ULONGLONG   WEPICVErrorCount;
+//    ULONGLONG   DecryptSuccessCount;
+//    ULONGLONG   DecryptFailureCount;
+} SDot11Counters, DEF* PSDot11Counters;
+
+
+//
+// MIB2 counter
+//
+typedef struct tagSMib2Counter {
+    LONG    ifIndex;
+    TCHAR   ifDescr[256];               // max size 255 plus zero ending
+                                        // e.g. "interface 1"
+    LONG    ifType;
+    LONG    ifMtu;
+    DWORD   ifSpeed;
+    BYTE    ifPhysAddress[U_ETHER_ADDR_LEN];
+    LONG    ifAdminStatus;
+    LONG    ifOperStatus;
+    DWORD   ifLastChange;
+    DWORD   ifInOctets;
+    DWORD   ifInUcastPkts;
+    DWORD   ifInNUcastPkts;
+    DWORD   ifInDiscards;
+    DWORD   ifInErrors;
+    DWORD   ifInUnknownProtos;
+    DWORD   ifOutOctets;
+    DWORD   ifOutUcastPkts;
+    DWORD   ifOutNUcastPkts;
+    DWORD   ifOutDiscards;
+    DWORD   ifOutErrors;
+    DWORD   ifOutQLen;
+    DWORD   ifSpecific;
+} SMib2Counter, DEF* PSMib2Counter;
+
+// Value in the ifType entry
+//#define ETHERNETCSMACD      6           //
+#define WIRELESSLANIEEE80211b      6           //
+
+// Value in the ifAdminStatus/ifOperStatus entry
+#define UP                  1           //
+#define DOWN                2           //
+#define TESTING             3           //
+
+
+//
+// RMON counter
+//
+typedef struct tagSRmonCounter {
+    LONG    etherStatsIndex;
+    DWORD   etherStatsDataSource;
+    DWORD   etherStatsDropEvents;
+    DWORD   etherStatsOctets;
+    DWORD   etherStatsPkts;
+    DWORD   etherStatsBroadcastPkts;
+    DWORD   etherStatsMulticastPkts;
+    DWORD   etherStatsCRCAlignErrors;
+    DWORD   etherStatsUndersizePkts;
+    DWORD   etherStatsOversizePkts;
+    DWORD   etherStatsFragments;
+    DWORD   etherStatsJabbers;
+    DWORD   etherStatsCollisions;
+    DWORD   etherStatsPkt64Octets;
+    DWORD   etherStatsPkt65to127Octets;
+    DWORD   etherStatsPkt128to255Octets;
+    DWORD   etherStatsPkt256to511Octets;
+    DWORD   etherStatsPkt512to1023Octets;
+    DWORD   etherStatsPkt1024to1518Octets;
+    DWORD   etherStatsOwners;
+    DWORD   etherStatsStatus;
+} SRmonCounter, DEF* PSRmonCounter;
+
+//
+// Custom counter
+//
+typedef struct tagSCustomCounters {
+    ULONG       Length;
+
+    ULONGLONG   ullTsrAllOK;
+
+    ULONGLONG   ullRsr11M;
+    ULONGLONG   ullRsr5M;
+    ULONGLONG   ullRsr2M;
+    ULONGLONG   ullRsr1M;
+
+    ULONGLONG   ullRsr11MCRCOk;
+    ULONGLONG   ullRsr5MCRCOk;
+    ULONGLONG   ullRsr2MCRCOk;
+    ULONGLONG   ullRsr1MCRCOk;
+
+    ULONGLONG   ullRsr54M;
+    ULONGLONG   ullRsr48M;
+    ULONGLONG   ullRsr36M;
+    ULONGLONG   ullRsr24M;
+    ULONGLONG   ullRsr18M;
+    ULONGLONG   ullRsr12M;
+    ULONGLONG   ullRsr9M;
+    ULONGLONG   ullRsr6M;
+
+    ULONGLONG   ullRsr54MCRCOk;
+    ULONGLONG   ullRsr48MCRCOk;
+    ULONGLONG   ullRsr36MCRCOk;
+    ULONGLONG   ullRsr24MCRCOk;
+    ULONGLONG   ullRsr18MCRCOk;
+    ULONGLONG   ullRsr12MCRCOk;
+    ULONGLONG   ullRsr9MCRCOk;
+    ULONGLONG   ullRsr6MCRCOk;
+
+} SCustomCounters, DEF* PSCustomCounters;
+
+
+//
+// Custom counter
+//
+typedef struct tagSISRCounters {
+    ULONG   Length;
+
+    DWORD   dwIsrTx0OK;
+    DWORD   dwIsrAC0TxOK;
+    DWORD   dwIsrBeaconTxOK;
+    DWORD   dwIsrRx0OK;
+    DWORD   dwIsrTBTTInt;
+    DWORD   dwIsrSTIMERInt;
+    DWORD   dwIsrWatchDog;
+    DWORD   dwIsrUnrecoverableError;
+    DWORD   dwIsrSoftInterrupt;
+    DWORD   dwIsrMIBNearfull;
+    DWORD   dwIsrRxNoBuf;
+
+    DWORD   dwIsrUnknown;               // unknown interrupt count
+
+    DWORD   dwIsrRx1OK;
+    DWORD   dwIsrATIMTxOK;
+    DWORD   dwIsrSYNCTxOK;
+    DWORD   dwIsrCFPEnd;
+    DWORD   dwIsrATIMEnd;
+    DWORD   dwIsrSYNCFlushOK;
+    DWORD   dwIsrSTIMER1Int;
+    /////////////////////////////////////
+} SISRCounters, DEF* PSISRCounters;
+
+
+// Value in the etherStatsStatus entry
+#define VALID               1           //
+#define CREATE_REQUEST      2           //
+#define UNDER_CREATION      3           //
+#define INVALID             4           //
+
+
+//
+// Tx packet information
+//
+typedef struct tagSTxPktInfo {
+    BYTE    byBroadMultiUni;
+    WORD    wLength;
+    WORD    wFIFOCtl;
+    BYTE    abyDestAddr[U_ETHER_ADDR_LEN];
+} STxPktInfo, DEF* PSTxPktInfo;
+
+
+#define MAX_RATE            12
+//
+// statistic counter
+//
+typedef struct tagSStatCounter {
+    //
+    // ISR status count
+    //
+
+    SISRCounters ISRStat;
+
+    // RSR status count
+    //
+    DWORD   dwRsrFrmAlgnErr;
+    DWORD   dwRsrErr;
+    DWORD   dwRsrCRCErr;
+    DWORD   dwRsrCRCOk;
+    DWORD   dwRsrBSSIDOk;
+    DWORD   dwRsrADDROk;
+    DWORD   dwRsrBCNSSIDOk;
+    DWORD   dwRsrLENErr;
+    DWORD   dwRsrTYPErr;
+
+    DWORD   dwNewRsrDECRYPTOK;
+    DWORD   dwNewRsrCFP;
+    DWORD   dwNewRsrUTSF;
+    DWORD   dwNewRsrHITAID;
+    DWORD   dwNewRsrHITAID0;
+
+    DWORD   dwRsrLong;
+    DWORD   dwRsrRunt;
+
+    DWORD   dwRsrRxControl;
+    DWORD   dwRsrRxData;
+    DWORD   dwRsrRxManage;
+
+    DWORD   dwRsrRxPacket;
+    DWORD   dwRsrRxOctet;
+    DWORD   dwRsrBroadcast;
+    DWORD   dwRsrMulticast;
+    DWORD   dwRsrDirected;
+    // 64-bit OID
+    ULONGLONG   ullRsrOK;
+
+    // for some optional OIDs (64 bits) and DMI support
+    ULONGLONG   ullRxBroadcastBytes;
+    ULONGLONG   ullRxMulticastBytes;
+    ULONGLONG   ullRxDirectedBytes;
+    ULONGLONG   ullRxBroadcastFrames;
+    ULONGLONG   ullRxMulticastFrames;
+    ULONGLONG   ullRxDirectedFrames;
+
+    DWORD   dwRsrRxFragment;
+    DWORD   dwRsrRxFrmLen64;
+    DWORD   dwRsrRxFrmLen65_127;
+    DWORD   dwRsrRxFrmLen128_255;
+    DWORD   dwRsrRxFrmLen256_511;
+    DWORD   dwRsrRxFrmLen512_1023;
+    DWORD   dwRsrRxFrmLen1024_1518;
+
+    // TSR status count
+    //
+    DWORD   dwTsrTotalRetry;        // total collision retry count
+    DWORD   dwTsrOnceRetry;         // this packet only occur one collision
+    DWORD   dwTsrMoreThanOnceRetry; // this packet occur more than one collision
+    DWORD   dwTsrRetry;             // this packet has ever occur collision,
+                                         // that is (dwTsrOnceCollision0 + dwTsrMoreThanOnceCollision0)
+    DWORD   dwTsrACKData;
+    DWORD   dwTsrErr;
+    DWORD   dwAllTsrOK;
+    DWORD   dwTsrRetryTimeout;
+    DWORD   dwTsrTransmitTimeout;
+
+    DWORD   dwTsrTxPacket;
+    DWORD   dwTsrTxOctet;
+    DWORD   dwTsrBroadcast;
+    DWORD   dwTsrMulticast;
+    DWORD   dwTsrDirected;
+
+    // RD/TD count
+    DWORD   dwCntRxFrmLength;
+    DWORD   dwCntTxBufLength;
+
+    BYTE    abyCntRxPattern[16];
+    BYTE    abyCntTxPattern[16];
+
+
+
+    // Software check....
+    DWORD   dwCntRxDataErr;             // rx buffer data software compare CRC err count
+    DWORD   dwCntDecryptErr;            // rx buffer data software compare CRC err count
+    DWORD   dwCntRxICVErr;              // rx buffer data software compare CRC err count
+
+
+    // 64-bit OID
+    ULONGLONG   ullTsrOK;
+
+    // for some optional OIDs (64 bits) and DMI support
+    ULONGLONG   ullTxBroadcastFrames;
+    ULONGLONG   ullTxMulticastFrames;
+    ULONGLONG   ullTxDirectedFrames;
+    ULONGLONG   ullTxBroadcastBytes;
+    ULONGLONG   ullTxMulticastBytes;
+    ULONGLONG   ullTxDirectedBytes;
+
+    // for autorate
+    DWORD   dwTxOk[MAX_RATE+1];
+    DWORD   dwTxFail[MAX_RATE+1];
+    DWORD   dwTxRetryCount[8];
+
+    STxPktInfo  abyTxPktInfo[16];
+
+    SUSBCounter USB_EP0Stat;
+    SUSBCounter USB_BulkInStat;
+    SUSBCounter USB_BulkOutStat;
+    SUSBCounter USB_InterruptStat;
+
+    SCustomCounters CustomStat;
+
+   #ifdef Calcu_LinkQual
+       //Tx count:
+    ULONG TxNoRetryOkCount;         //success tx no retry !
+    ULONG TxRetryOkCount;              //sucess tx but retry !
+    ULONG TxFailCount;                      //fail tx ?
+      //Rx count:
+    ULONG RxOkCnt;                          //sucess rx !
+    ULONG RxFcsErrCnt;                    //fail rx ?
+      //statistic
+    ULONG SignalStren;
+    ULONG LinkQuality;
+   #endif
+
+} SStatCounter, DEF* PSStatCounter;
+
+#define NTSTATUS        int
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+#ifdef __cplusplus
+extern "C" {                            /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+
+
+void STAvClearAllCounter(PSStatCounter pStatistic);
+
+void STAvUpdateIsrStatCounter (PSStatCounter pStatistic, BYTE byIsr0, BYTE byIsr1);
+
+void STAvUpdateRDStatCounter(PSStatCounter pStatistic,
+                              BYTE byRSR, BYTE byNewRSR, BYTE byRxSts, BYTE byRxRate,
+                              PBYTE pbyBuffer, UINT cbFrameLength);
+
+void STAvUpdateRDStatCounterEx(PSStatCounter pStatistic,
+                              BYTE byRSR, BYTE byNewRSR, BYTE byRxSts, BYTE byRxRate,
+                              PBYTE pbyBuffer, UINT cbFrameLength);
+
+
+void
+STAvUpdateTDStatCounter (
+    PSStatCounter   pStatistic,
+    BYTE            byPktNum,
+    BYTE            byRate,
+    BYTE            byTSR
+    );
+
+
+void
+STAvUpdate802_11Counter(
+    PSDot11Counters         p802_11Counter,
+    PSStatCounter           pStatistic,
+    BYTE                    byRTSSuccess,
+    BYTE                    byRTSFail,
+    BYTE                    byACKFail,
+    BYTE                    byFCSErr
+    );
+
+void STAvClear802_11Counter(PSDot11Counters p802_11Counter);
+
+void
+STAvUpdateUSBCounter(
+    PSUSBCounter    pUsbCounter,
+    NTSTATUS        ntStatus
+    );
+
+#ifdef __cplusplus
+}                                       /* End of extern "C" { */
+#endif /* __cplusplus */
+
+
+
+
+#endif // __MIB_H__
+
+
+
diff --git a/drivers/staging/vt6656/michael.c b/drivers/staging/vt6656/michael.c
new file mode 100644
index 0000000..7bda4c1
--- /dev/null
+++ b/drivers/staging/vt6656/michael.c
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: michael.cpp
+ *
+ * Purpose: The implementation of LIST data structure.
+ *
+ * Author: Kyle Hsu
+ *
+ * Date: Sep 4, 2002
+ *
+ * Functions:
+ *      s_dwGetUINT32 - Convert from BYTE[] to DWORD in a portable way
+ *      s_vPutUINT32 - Convert from DWORD to BYTE[] in a portable way
+ *      s_vClear - Reset the state to the empty message.
+ *      s_vSetKey - Set the key.
+ *      MIC_vInit - Set the key.
+ *      s_vAppendByte - Append the byte to our word-sized buffer.
+ *      MIC_vAppend - call s_vAppendByte.
+ *      MIC_vGetMIC - Append the minimum padding and call s_vAppendByte.
+ *
+ * Revision History:
+ *
+ */
+
+#if !defined(__TMACRO_H__)
+#include "tmacro.h"
+#endif
+#if !defined(__TBIT_H__)
+#include "tbit.h"
+#endif
+#if !defined(__MICHAEL_H__)
+#include "michael.h"
+#endif
+
+/*---------------------  Static Definitions -------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+
+/*---------------------  Static Functions  --------------------------*/
+/*
+static DWORD s_dwGetUINT32(BYTE * p);         // Get DWORD from 4 bytes LSByte first
+static VOID s_vPutUINT32(BYTE* p, DWORD val); // Put DWORD into 4 bytes LSByte first
+*/
+static VOID s_vClear(void);                       // Clear the internal message,
+                                              // resets the object to the state just after construction.
+static VOID s_vSetKey(DWORD dwK0, DWORD dwK1);
+static VOID s_vAppendByte(BYTE b);            // Add a single byte to the internal message
+
+/*---------------------  Export Variables  --------------------------*/
+static DWORD  L, R;           // Current state
+
+static DWORD  K0, K1;         // Key
+static DWORD  M;              // Message accumulator (single word)
+static UINT   nBytesInM;      // # bytes in M
+
+/*---------------------  Export Functions  --------------------------*/
+
+/*
+static DWORD s_dwGetUINT32 (BYTE * p)
+// Convert from BYTE[] to DWORD in a portable way
+{
+    DWORD res = 0;
+    UINT i;
+    for(i=0; i<4; i++ )
+    {
+        res |= (*p++) << (8*i);
+    }
+    return res;
+}
+
+static VOID s_vPutUINT32 (BYTE* p, DWORD val)
+// Convert from DWORD to BYTE[] in a portable way
+{
+    UINT i;
+    for(i=0; i<4; i++ )
+    {
+        *p++ = (BYTE) (val & 0xff);
+        val >>= 8;
+    }
+}
+*/
+
+static VOID s_vClear (void)
+{
+    // Reset the state to the empty message.
+    L = K0;
+    R = K1;
+    nBytesInM = 0;
+    M = 0;
+}
+
+static VOID s_vSetKey (DWORD dwK0, DWORD dwK1)
+{
+    // Set the key
+    K0 = dwK0;
+    K1 = dwK1;
+    // and reset the message
+    s_vClear();
+}
+
+static VOID s_vAppendByte (BYTE b)
+{
+    // Append the byte to our word-sized buffer
+    M |= b << (8*nBytesInM);
+    nBytesInM++;
+    // Process the word if it is full.
+    if( nBytesInM >= 4 )
+    {
+        L ^= M;
+        R ^= ROL32( L, 17 );
+        L += R;
+        R ^= ((L & 0xff00ff00) >> 8) | ((L & 0x00ff00ff) << 8);
+        L += R;
+        R ^= ROL32( L, 3 );
+        L += R;
+        R ^= ROR32( L, 2 );
+        L += R;
+        // Clear the buffer
+        M = 0;
+        nBytesInM = 0;
+    }
+}
+
+VOID MIC_vInit (DWORD dwK0, DWORD dwK1)
+{
+    // Set the key
+    s_vSetKey(dwK0, dwK1);
+}
+
+
+VOID MIC_vUnInit (void)
+{
+    // Wipe the key material
+    K0 = 0;
+    K1 = 0;
+
+    // And the other fields as well.
+    //Note that this sets (L,R) to (K0,K1) which is just fine.
+    s_vClear();
+}
+
+VOID MIC_vAppend (PBYTE src, UINT nBytes)
+{
+    // This is simple
+    while (nBytes > 0)
+    {
+        s_vAppendByte(*src++);
+        nBytes--;
+    }
+}
+
+VOID MIC_vGetMIC (PDWORD pdwL, PDWORD pdwR)
+{
+    // Append the minimum padding
+    s_vAppendByte(0x5a);
+    s_vAppendByte(0);
+    s_vAppendByte(0);
+    s_vAppendByte(0);
+    s_vAppendByte(0);
+    // and then zeroes until the length is a multiple of 4
+    while( nBytesInM != 0 )
+    {
+        s_vAppendByte(0);
+    }
+    // The s_vAppendByte function has already computed the result.
+    *pdwL = L;
+    *pdwR = R;
+    // Reset to the empty message.
+    s_vClear();
+}
+
diff --git a/drivers/staging/vt6656/michael.h b/drivers/staging/vt6656/michael.h
new file mode 100644
index 0000000..62a24a6
--- /dev/null
+++ b/drivers/staging/vt6656/michael.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: Michael.h
+ *
+ * Purpose: Reference implementation for Michael
+ *          written by Niels Ferguson
+ *
+ * Author: Kyle Hsu
+ *
+ * Date: Jan 2, 2003
+ *
+ */
+
+
+#ifndef __MICHAEL_H__
+#define __MICHAEL_H__
+
+#if !defined(__UMEM_H__)
+#include "umem.h"
+#endif
+/*---------------------  Export Definitions -------------------------*/
+
+/*---------------------  Export Types  ------------------------------*/
+
+VOID MIC_vInit(DWORD dwK0, DWORD dwK1);
+
+VOID MIC_vUnInit(void);
+
+// Append bytes to the message to be MICed
+VOID MIC_vAppend(PBYTE src, UINT nBytes);
+
+// Get the MIC result. Destination should accept 8 bytes of result.
+// This also resets the message to empty.
+VOID MIC_vGetMIC(PDWORD pdwL, PDWORD pdwR);
+
+/*---------------------  Export Macros ------------------------------*/
+
+// Rotation functions on 32 bit values
+#define ROL32( A, n ) \
+ ( ((A) << (n)) | ( ((A)>>(32-(n)))  & ( (1UL << (n)) - 1 ) ) )
+#define ROR32( A, n ) ROL32( (A), 32-(n) )
+
+#endif //__MICHAEL_H__
+
+
diff --git a/drivers/staging/vt6656/power.c b/drivers/staging/vt6656/power.c
new file mode 100644
index 0000000..b522b21
--- /dev/null
+++ b/drivers/staging/vt6656/power.c
@@ -0,0 +1,458 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: power.c
+ *
+ * Purpose: Handles 802.11 power managment  functions
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: July 17, 2002
+ *
+ * Functions:
+ *      PSvEnablePowerSaving - Enable Power Saving Mode
+ *      PSvDiasblePowerSaving - Disable Power Saving Mode
+ *      PSbConsiderPowerDown - Decide if we can Power Down
+ *      PSvSendPSPOLL - Send PS-POLL packet
+ *      PSbSendNullPacket - Send Null packet
+ *      PSbIsNextTBTTWakeUp - Decide if we need to wake up at next Beacon
+ *
+ * Revision History:
+ *
+ */
+
+
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+#if !defined(__TBIT_H__)
+#include "tbit.h"
+#endif
+#if !defined(__MAC_H__)
+#include "mac.h"
+#endif
+#if !defined(__DEVICE_H__)
+#include "device.h"
+#endif
+#if !defined(__WMGR_H__)
+#include "wmgr.h"
+#endif
+#if !defined(__POWER_H__)
+#include "power.h"
+#endif
+#if !defined(__WCMD_H__)
+#include "wcmd.h"
+#endif
+#if !defined(__TBIT_H__)
+#include "tbit.h"
+#endif
+#if !defined(__UMEM_H__)
+#include "umem.h"
+#endif
+#if !defined(__RXTX_H__)
+#include "rxtx.h"
+#endif
+#if !defined(__CARD_H__)
+#include "card.h"
+#endif
+#if !defined(__CONTROL_H__)
+#include "control.h"
+#endif
+#if !defined(__RNDIS_H__)
+#include "rndis.h"
+#endif
+
+
+
+
+/*---------------------  Static Definitions -------------------------*/
+
+
+
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+static int          msglevel                =MSG_LEVEL_INFO;
+/*---------------------  Static Functions  --------------------------*/
+
+
+/*---------------------  Export Variables  --------------------------*/
+
+
+/*---------------------  Export Functions  --------------------------*/
+
+/*+
+ *
+ * Routine Description:
+ * Enable hw power saving functions
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+
+VOID
+PSvEnablePowerSaving(
+    IN HANDLE hDeviceContext,
+    IN WORD wListenInterval
+    )
+{
+    PSDevice        pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    WORD            wAID = pMgmt->wCurrAID | BIT14 | BIT15;
+
+    // set period of power up before TBTT
+    MACvWriteWord(pDevice, MAC_REG_PWBT, C_PWBT);
+
+    if (pDevice->eOPMode != OP_MODE_ADHOC) {
+        // set AID
+        MACvWriteWord(pDevice, MAC_REG_AIDATIM, wAID);
+    } else {
+    	// set ATIM Window
+        //MACvWriteATIMW(pDevice->PortOffset, pMgmt->wCurrATIMWindow);
+    }
+
+    //Warren:06-18-2004,the sequence must follow PSEN->AUTOSLEEP->GO2DOZE
+    // enable power saving hw function
+    MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_PSEN);
+    // Set AutoSleep
+    MACvRegBitsOn(pDevice, MAC_REG_PSCFG, PSCFG_AUTOSLEEP);
+
+    //Warren:MUST turn on this once before turn on AUTOSLEEP ,or the AUTOSLEEP doesn't work
+    MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_GO2DOZE);
+
+
+    if (wListenInterval >= 2) {
+
+        // clear always listen beacon
+        MACvRegBitsOff(pDevice, MAC_REG_PSCTL, PSCTL_ALBCN);
+        // first time set listen next beacon
+        MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_LNBCN);
+
+        pMgmt->wCountToWakeUp = wListenInterval;
+
+    }
+    else {
+
+        // always listen beacon
+        MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_ALBCN);
+        pMgmt->wCountToWakeUp = 0;
+
+    }
+
+    pDevice->bEnablePSMode = TRUE;
+
+    if (pDevice->eOPMode == OP_MODE_ADHOC) {
+//        bMgrPrepareBeaconToSend((HANDLE)pDevice, pMgmt);
+    }
+    // We don't send null pkt in ad hoc mode since beacon will handle this.
+    else if (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) {
+        PSbSendNullPacket(pDevice);
+    }
+    pDevice->bPWBitOn = TRUE;
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "PS:Power Saving Mode Enable... \n");
+    return;
+}
+
+
+
+
+
+
+/*+
+ *
+ * Routine Description:
+ * Disable hw power saving functions
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+VOID
+PSvDisablePowerSaving(
+    IN HANDLE hDeviceContext
+    )
+{
+    PSDevice        pDevice = (PSDevice)hDeviceContext;
+//    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+
+
+    // disable power saving hw function
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_DISABLE_PS,
+                        0,
+                        0,
+                        0,
+                        NULL
+                        );
+
+    //clear AutoSleep
+    MACvRegBitsOff(pDevice, MAC_REG_PSCFG, PSCFG_AUTOSLEEP);
+
+    // set always listen beacon
+    MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_ALBCN);
+
+    pDevice->bEnablePSMode = FALSE;
+
+    if (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) {
+        PSbSendNullPacket(pDevice);
+    }
+    pDevice->bPWBitOn = FALSE;
+    return;
+}
+
+
+/*+
+ *
+ * Routine Description:
+ * Consider to power down when no more packets to tx or rx.
+ *
+ * Return Value:
+ *    TRUE, if power down success
+ *    FALSE, if fail
+-*/
+
+
+BOOL
+PSbConsiderPowerDown(
+    IN HANDLE hDeviceContext,
+    IN BOOL bCheckRxDMA,
+    IN BOOL bCheckCountToWakeUp
+    )
+{
+    PSDevice        pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    BYTE            byData;
+
+
+    // check if already in Doze mode
+    ControlvReadByte(pDevice, MESSAGE_REQUEST_MACREG, MAC_REG_PSCTL, &byData);
+    if ( (byData & PSCTL_PS) != 0 )
+        return TRUE;;
+
+    if (pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) {
+        // check if in TIM wake period
+        if (pMgmt->bInTIMWake)
+            return FALSE;
+    }
+
+    // check scan state
+    if (pDevice->bCmdRunning)
+        return FALSE;
+
+    //Tx Burst
+    if ( pDevice->bPSModeTxBurst )
+        return FALSE;
+
+    // Froce PSEN on
+    MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_PSEN);
+
+    if (pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) {
+        if (bCheckCountToWakeUp &&
+            (pMgmt->wCountToWakeUp == 0 || pMgmt->wCountToWakeUp == 1)) {
+             return FALSE;
+        }
+    }
+
+    pDevice->bPSRxBeacon = TRUE;
+    // no Tx, no Rx isr, now go to Doze
+    MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_GO2DOZE);
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Go to Doze ZZZZZZZZZZZZZZZ\n");
+    return TRUE;
+}
+
+
+
+/*+
+ *
+ * Routine Description:
+ * Send PS-POLL packet
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+
+
+VOID
+PSvSendPSPOLL(
+    IN HANDLE hDeviceContext
+    )
+{
+    PSDevice            pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+    PSTxMgmtPacket      pTxPacket = NULL;
+
+
+    memset(pMgmt->pbyPSPacketPool, 0, sizeof(STxMgmtPacket) + WLAN_HDR_ADDR2_LEN);
+    pTxPacket = (PSTxMgmtPacket)pMgmt->pbyPSPacketPool;
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+    pTxPacket->p80211Header->sA2.wFrameCtl = cpu_to_le16(
+         (
+         WLAN_SET_FC_FTYPE(WLAN_TYPE_CTL) |
+         WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_PSPOLL) |
+         WLAN_SET_FC_PWRMGT(0)
+         ));
+    pTxPacket->p80211Header->sA2.wDurationID = pMgmt->wCurrAID | BIT14 | BIT15;
+    memcpy(pTxPacket->p80211Header->sA2.abyAddr1, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN);
+    memcpy(pTxPacket->p80211Header->sA2.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
+    pTxPacket->cbMPDULen = WLAN_HDR_ADDR2_LEN;
+    pTxPacket->cbPayloadLen = 0;
+    // send the frame
+    if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send PS-Poll packet failed..\n");
+    }
+    else {
+//        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send PS-Poll packet success..\n");
+    };
+
+    return;
+}
+
+
+
+/*+
+ *
+ * Routine Description:
+ * Send NULL packet to AP for notification power state of STA
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+BOOL
+PSbSendNullPacket(
+    IN HANDLE hDeviceContext
+    )
+{
+    PSDevice            pDevice = (PSDevice)hDeviceContext;
+    PSTxMgmtPacket      pTxPacket = NULL;
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+
+
+
+    if (pDevice->bLinkPass == FALSE) {
+        return FALSE;
+    }
+
+//2007-0115-03<Add>by MikeLiu
+#ifdef TxInSleep
+     if ((pDevice->bEnablePSMode == FALSE) &&
+	  (pDevice->fTxDataInSleep == FALSE)){
+        return FALSE;
+    }
+#else
+    if (pDevice->bEnablePSMode == FALSE) {
+        return FALSE;
+    }
+#endif
+    memset(pMgmt->pbyPSPacketPool, 0, sizeof(STxMgmtPacket) + WLAN_NULLDATA_FR_MAXLEN);
+    pTxPacket = (PSTxMgmtPacket)pMgmt->pbyPSPacketPool;
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+
+    if (pDevice->bEnablePSMode) {
+
+        pTxPacket->p80211Header->sA3.wFrameCtl = cpu_to_le16(
+             (
+            WLAN_SET_FC_FTYPE(WLAN_TYPE_DATA) |
+            WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_NULL) |
+            WLAN_SET_FC_PWRMGT(1)
+            ));
+    }
+    else {
+        pTxPacket->p80211Header->sA3.wFrameCtl = cpu_to_le16(
+             (
+            WLAN_SET_FC_FTYPE(WLAN_TYPE_DATA) |
+            WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_NULL) |
+            WLAN_SET_FC_PWRMGT(0)
+            ));
+    }
+
+    if(pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) {
+        pTxPacket->p80211Header->sA3.wFrameCtl |= cpu_to_le16((WORD)WLAN_SET_FC_TODS(1));
+    }
+
+    memcpy(pTxPacket->p80211Header->sA3.abyAddr1, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN);
+    memcpy(pTxPacket->p80211Header->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
+    memcpy(pTxPacket->p80211Header->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
+    pTxPacket->cbMPDULen = WLAN_HDR_ADDR3_LEN;
+    pTxPacket->cbPayloadLen = 0;
+    // send the frame
+    if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send Null Packet failed !\n");
+        return FALSE;
+    }
+    else {
+//            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send Null Packet success....\n");
+    }
+
+
+    return TRUE ;
+}
+
+/*+
+ *
+ * Routine Description:
+ * Check if Next TBTT must wake up
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+BOOL
+PSbIsNextTBTTWakeUp(
+    IN HANDLE hDeviceContext
+    )
+{
+
+    PSDevice         pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+    BOOL                bWakeUp = FALSE;
+
+    if (pMgmt->wListenInterval >= 2) {
+        if (pMgmt->wCountToWakeUp == 0) {
+            pMgmt->wCountToWakeUp = pMgmt->wListenInterval;
+        }
+
+        pMgmt->wCountToWakeUp --;
+
+        if (pMgmt->wCountToWakeUp == 1) {
+
+            // Turn on wake up to listen next beacon
+            MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_LNBCN);
+            pDevice->bPSRxBeacon = FALSE;
+            bWakeUp = TRUE;
+
+        } else if ( !pDevice->bPSRxBeacon ) {
+            //Listen until RxBeacon
+            MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_LNBCN);
+        }
+
+    }
+
+    return bWakeUp;
+}
+
diff --git a/drivers/staging/vt6656/power.h b/drivers/staging/vt6656/power.h
new file mode 100644
index 0000000..c33c93a
--- /dev/null
+++ b/drivers/staging/vt6656/power.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: power.h
+ *
+ * Purpose: Handles 802.11 power managment  functions
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: July 17, 2002
+ *
+ */
+
+#ifndef __POWER_H__
+#define __POWER_H__
+
+
+/*---------------------  Export Definitions -------------------------*/
+#define     C_PWBT                   1000      // micro sec. power up before TBTT
+#define     PS_FAST_INTERVAL         1         // Fast power saving listen interval
+#define     PS_MAX_INTERVAL          4         // MAX power saving listen interval
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+
+/*---------------------  Export Types  ------------------------------*/
+
+
+/*---------------------  Export Functions  --------------------------*/
+
+// IN PSDevice pDevice
+// IN PSDevice hDeviceContext
+
+BOOL
+PSbConsiderPowerDown(
+    IN HANDLE hDeviceContext,
+    IN BOOL bCheckRxDMA,
+    IN BOOL bCheckCountToWakeUp
+    );
+
+VOID
+PSvDisablePowerSaving(
+    IN HANDLE hDeviceContext
+    );
+
+VOID
+PSvEnablePowerSaving(
+    IN HANDLE hDeviceContext,
+    IN WORD wListenInterval
+    );
+
+VOID
+PSvSendPSPOLL(
+    IN HANDLE hDeviceContext
+    );
+
+BOOL
+PSbSendNullPacket(
+    IN HANDLE hDeviceContext
+    );
+
+BOOL
+PSbIsNextTBTTWakeUp(
+    IN HANDLE hDeviceContext
+    );
+
+#endif //__POWER_H__
diff --git a/drivers/staging/vt6656/rc4.c b/drivers/staging/vt6656/rc4.c
new file mode 100644
index 0000000..5ad12a3
--- /dev/null
+++ b/drivers/staging/vt6656/rc4.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: rc4.c
+ *
+ * Purpose:
+ *
+ * Functions:
+ *
+ * Revision History:
+ *
+ * Author: Kyle Hsu
+ *
+ * Date: Sep 4, 2002
+ *
+ */
+
+#if !defined(__RC4_H__)
+#include "rc4.h"
+#endif
+
+VOID rc4_init(PRC4Ext pRC4, PBYTE pbyKey, UINT cbKey_len)
+{
+    UINT  ust1, ust2;
+    UINT  keyindex;
+    UINT  stateindex;
+    PBYTE pbyst;
+    UINT  idx;
+
+    pbyst = pRC4->abystate;
+    pRC4->ux = 0;
+    pRC4->uy = 0;
+    for (idx = 0; idx < 256; idx++)
+        pbyst[idx] = (BYTE)idx;
+    keyindex = 0;
+    stateindex = 0;
+    for (idx = 0; idx < 256; idx++) {
+        ust1 = pbyst[idx];
+        stateindex = (stateindex + pbyKey[keyindex] + ust1) & 0xff;
+        ust2 = pbyst[stateindex];
+        pbyst[stateindex] = (BYTE)ust1;
+        pbyst[idx] = (BYTE)ust2;
+        if (++keyindex >= cbKey_len)
+            keyindex = 0;
+    }
+}
+
+UINT rc4_byte(PRC4Ext pRC4)
+{
+    UINT ux;
+    UINT uy;
+    UINT ustx, usty;
+    PBYTE pbyst;
+
+    pbyst = pRC4->abystate;
+    ux = (pRC4->ux + 1) & 0xff;
+    ustx = pbyst[ux];
+    uy = (ustx + pRC4->uy) & 0xff;
+    usty = pbyst[uy];
+    pRC4->ux = ux;
+    pRC4->uy = uy;
+    pbyst[uy] = (BYTE)ustx;
+    pbyst[ux] = (BYTE)usty;
+
+    return pbyst[(ustx + usty) & 0xff];
+}
+
+VOID rc4_encrypt(PRC4Ext pRC4, PBYTE pbyDest,
+                     PBYTE pbySrc, UINT cbData_len)
+{
+    UINT ii;
+    for (ii = 0; ii < cbData_len; ii++)
+        pbyDest[ii] = (BYTE)(pbySrc[ii] ^ rc4_byte(pRC4));
+}
diff --git a/drivers/staging/vt6656/rc4.h b/drivers/staging/vt6656/rc4.h
new file mode 100644
index 0000000..4e3ccc5
--- /dev/null
+++ b/drivers/staging/vt6656/rc4.h
@@ -0,0 +1,51 @@
+/*
+ * File: rc4.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Purpose:
+ *
+ * Functions:
+ *
+ * Revision History:
+ *
+ * Author: Kyle Hsu
+ *
+ * Date: Sep 4, 2002
+ *
+ */
+
+#ifndef __RC4_H__
+#define __RC4_H__
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+
+
+
+/*---------------------  Export Definitions -------------------------*/
+/*---------------------  Export Types  ------------------------------*/
+typedef struct {
+    UINT ux;
+    UINT uy;
+    BYTE abystate[256];
+} RC4Ext, DEF* PRC4Ext;
+
+VOID rc4_init(PRC4Ext pRC4, PBYTE pbyKey, UINT cbKey_len);
+UINT rc4_byte(PRC4Ext pRC4);
+void rc4_encrypt(PRC4Ext pRC4, PBYTE pbyDest, PBYTE pbySrc, UINT cbData_len);
+
+#endif //__RC4_H__
diff --git a/drivers/staging/vt6656/rf.c b/drivers/staging/vt6656/rf.c
new file mode 100644
index 0000000..53b8546
--- /dev/null
+++ b/drivers/staging/vt6656/rf.c
@@ -0,0 +1,1163 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: rf.c
+ *
+ * Purpose: rf function code
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Feb. 19, 2004
+ *
+ * Functions:
+ *      IFRFbWriteEmbeded      - Embeded write RF register via MAC
+ *
+ * Revision History:
+ *
+ */
+
+#if !defined(__MAC_H__)
+#include "mac.h"
+#endif
+#if !defined(__RF_H__)
+#include "rf.h"
+#endif
+#if !defined(__BASEBAND_H__)
+#include "baseband.h"
+#endif
+#if !defined(__CONTROL_H__)
+#include "control.h"
+#endif
+#if !defined(__RNDIS_H__)
+#include "rndis.h"
+#endif
+#if !defined(__DATARATE_H__)
+#include "datarate.h"
+#endif
+
+static int          msglevel                =MSG_LEVEL_INFO;
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+/*---------------------  Static Definitions -------------------------*/
+#define BY_AL2230_REG_LEN     23 //24bit
+#define CB_AL2230_INIT_SEQ    15
+#define AL2230_PWR_IDX_LEN    64
+
+#define BY_AL7230_REG_LEN     23 //24bit
+#define CB_AL7230_INIT_SEQ    16
+#define AL7230_PWR_IDX_LEN    64
+
+//{{RobertYu:20051111
+#define BY_VT3226_REG_LEN     23
+#define CB_VT3226_INIT_SEQ    11
+#define VT3226_PWR_IDX_LEN    64
+//}}
+
+//{{RobertYu:20060609
+#define BY_VT3342_REG_LEN     23
+#define CB_VT3342_INIT_SEQ    13
+#define VT3342_PWR_IDX_LEN    64
+//}}
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+
+
+
+
+BYTE abyAL2230InitTable[CB_AL2230_INIT_SEQ][3] = {
+    {0x03, 0xF7, 0x90},
+    {0x03, 0x33, 0x31},
+    {0x01, 0xB8, 0x02},
+    {0x00, 0xFF, 0xF3},
+    {0x00, 0x05, 0xA4},
+    {0x0F, 0x4D, 0xC5},   //RobertYu:20060814
+    {0x08, 0x05, 0xB6},
+    {0x01, 0x47, 0xC7},
+    {0x00, 0x06, 0x88},
+    {0x04, 0x03, 0xB9},
+    {0x00, 0xDB, 0xBA},
+    {0x00, 0x09, 0x9B},
+    {0x0B, 0xDF, 0xFC},
+    {0x00, 0x00, 0x0D},
+    {0x00, 0x58, 0x0F}
+    };
+
+BYTE abyAL2230ChannelTable0[CB_MAX_CHANNEL_24G][3] = {
+    {0x03, 0xF7, 0x90}, // channel = 1, Tf = 2412MHz
+    {0x03, 0xF7, 0x90}, // channel = 2, Tf = 2417MHz
+    {0x03, 0xE7, 0x90}, // channel = 3, Tf = 2422MHz
+    {0x03, 0xE7, 0x90}, // channel = 4, Tf = 2427MHz
+    {0x03, 0xF7, 0xA0}, // channel = 5, Tf = 2432MHz
+    {0x03, 0xF7, 0xA0}, // channel = 6, Tf = 2437MHz
+    {0x03, 0xE7, 0xA0}, // channel = 7, Tf = 2442MHz
+    {0x03, 0xE7, 0xA0}, // channel = 8, Tf = 2447MHz
+    {0x03, 0xF7, 0xB0}, // channel = 9, Tf = 2452MHz
+    {0x03, 0xF7, 0xB0}, // channel = 10, Tf = 2457MHz
+    {0x03, 0xE7, 0xB0}, // channel = 11, Tf = 2462MHz
+    {0x03, 0xE7, 0xB0}, // channel = 12, Tf = 2467MHz
+    {0x03, 0xF7, 0xC0}, // channel = 13, Tf = 2472MHz
+    {0x03, 0xE7, 0xC0}  // channel = 14, Tf = 2412M
+    };
+
+BYTE abyAL2230ChannelTable1[CB_MAX_CHANNEL_24G][3] = {
+    {0x03, 0x33, 0x31}, // channel = 1, Tf = 2412MHz
+    {0x0B, 0x33, 0x31}, // channel = 2, Tf = 2417MHz
+    {0x03, 0x33, 0x31}, // channel = 3, Tf = 2422MHz
+    {0x0B, 0x33, 0x31}, // channel = 4, Tf = 2427MHz
+    {0x03, 0x33, 0x31}, // channel = 5, Tf = 2432MHz
+    {0x0B, 0x33, 0x31}, // channel = 6, Tf = 2437MHz
+    {0x03, 0x33, 0x31}, // channel = 7, Tf = 2442MHz
+    {0x0B, 0x33, 0x31}, // channel = 8, Tf = 2447MHz
+    {0x03, 0x33, 0x31}, // channel = 9, Tf = 2452MHz
+    {0x0B, 0x33, 0x31}, // channel = 10, Tf = 2457MHz
+    {0x03, 0x33, 0x31}, // channel = 11, Tf = 2462MHz
+    {0x0B, 0x33, 0x31}, // channel = 12, Tf = 2467MHz
+    {0x03, 0x33, 0x31}, // channel = 13, Tf = 2472MHz
+    {0x06, 0x66, 0x61}  // channel = 14, Tf = 2412M
+    };
+
+// 40MHz reference frequency
+// Need to Pull PLLON(PE3) low when writing channel registers through 3-wire.
+BYTE abyAL7230InitTable[CB_AL7230_INIT_SEQ][3] = {
+    {0x20, 0x37, 0x90}, // Channel1 // Need modify for 11a
+    {0x13, 0x33, 0x31}, // Channel1 // Need modify for 11a
+    {0x84, 0x1F, 0xF2}, // Need modify for 11a: 451FE2
+    {0x3F, 0xDF, 0xA3}, // Need modify for 11a: 5FDFA3
+    {0x7F, 0xD7, 0x84}, // 11b/g    // Need modify for 11a
+    //0x802B4500+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11a: 8D1B45
+    // RoberYu:20050113, Rev0.47 Regsiter Setting Guide
+    {0x80, 0x2B, 0x55}, // Need modify for 11a: 8D1B55
+    {0x56, 0xAF, 0x36},
+    {0xCE, 0x02, 0x07}, // Need modify for 11a: 860207
+    {0x6E, 0xBC, 0x98},
+    {0x22, 0x1B, 0xB9},
+    {0xE0, 0x00, 0x0A}, // Need modify for 11a: E0600A
+    {0x08, 0x03, 0x1B}, // init 0x080B1B00 => 0x080F1B00 for 3 wire control TxGain(D10)
+    //0x00093C00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11a: 00143C
+    // RoberYu:20050113, Rev0.47 Regsiter Setting Guide
+    {0x00, 0x0A, 0x3C}, // Need modify for 11a: 00143C
+    {0xFF, 0xFF, 0xFD},
+    {0x00, 0x00, 0x0E},
+    {0x1A, 0xBA, 0x8F} // Need modify for 11a: 12BACF
+    };
+
+BYTE abyAL7230InitTableAMode[CB_AL7230_INIT_SEQ][3] = {
+    {0x2F, 0xF5, 0x20}, // Channel184 // Need modify for 11b/g
+    {0x00, 0x00, 0x01}, // Channel184 // Need modify for 11b/g
+    {0x45, 0x1F, 0xE2}, // Need modify for 11b/g
+    {0x5F, 0xDF, 0xA3}, // Need modify for 11b/g
+    {0x6F, 0xD7, 0x84}, // 11a    // Need modify for 11b/g
+    {0x85, 0x3F, 0x55}, // Need modify for 11b/g, RoberYu:20050113
+    {0x56, 0xAF, 0x36},
+    {0xCE, 0x02, 0x07}, // Need modify for 11b/g
+    {0x6E, 0xBC, 0x98},
+    {0x22, 0x1B, 0xB9},
+    {0xE0, 0x60, 0x0A}, // Need modify for 11b/g
+    {0x08, 0x03, 0x1B}, // init 0x080B1B00 => 0x080F1B00 for 3 wire control TxGain(D10)
+    {0x00, 0x14, 0x7C}, // Need modify for 11b/g
+    {0xFF, 0xFF, 0xFD},
+    {0x00, 0x00, 0x0E},
+    {0x12, 0xBA, 0xCF} // Need modify for 11b/g
+    };
+
+BYTE abyAL7230ChannelTable0[CB_MAX_CHANNEL][3] = {
+    {0x20, 0x37, 0x90}, // channel =  1, Tf = 2412MHz
+    {0x20, 0x37, 0x90}, // channel =  2, Tf = 2417MHz
+    {0x20, 0x37, 0x90}, // channel =  3, Tf = 2422MHz
+    {0x20, 0x37, 0x90}, // channel =  4, Tf = 2427MHz
+    {0x20, 0x37, 0xA0}, // channel =  5, Tf = 2432MHz
+    {0x20, 0x37, 0xA0}, // channel =  6, Tf = 2437MHz
+    {0x20, 0x37, 0xA0}, // channel =  7, Tf = 2442MHz
+    {0x20, 0x37, 0xA0}, // channel =  8, Tf = 2447MHz //RobertYu: 20050218, update for APNode 0.49
+    {0x20, 0x37, 0xB0}, // channel =  9, Tf = 2452MHz //RobertYu: 20050218, update for APNode 0.49
+    {0x20, 0x37, 0xB0}, // channel = 10, Tf = 2457MHz //RobertYu: 20050218, update for APNode 0.49
+    {0x20, 0x37, 0xB0}, // channel = 11, Tf = 2462MHz //RobertYu: 20050218, update for APNode 0.49
+    {0x20, 0x37, 0xB0}, // channel = 12, Tf = 2467MHz //RobertYu: 20050218, update for APNode 0.49
+    {0x20, 0x37, 0xC0}, // channel = 13, Tf = 2472MHz //RobertYu: 20050218, update for APNode 0.49
+    {0x20, 0x37, 0xC0}, // channel = 14, Tf = 2484MHz
+
+    // 4.9G => Ch 183, 184, 185, 187, 188, 189, 192, 196  (Value:15 ~ 22)
+    {0x0F, 0xF5, 0x20}, // channel = 183, Tf = 4915MHz (15)
+    {0x2F, 0xF5, 0x20}, // channel = 184, Tf = 4920MHz (16)
+    {0x0F, 0xF5, 0x20}, // channel = 185, Tf = 4925MHz (17)
+    {0x0F, 0xF5, 0x20}, // channel = 187, Tf = 4935MHz (18)
+    {0x2F, 0xF5, 0x20}, // channel = 188, Tf = 4940MHz (19)
+    {0x0F, 0xF5, 0x20}, // channel = 189, Tf = 4945MHz (20)
+    {0x2F, 0xF5, 0x30}, // channel = 192, Tf = 4960MHz (21)
+    {0x2F, 0xF5, 0x30}, // channel = 196, Tf = 4980MHz (22)
+
+    // 5G => Ch 7, 8, 9, 11, 12, 16, 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64,
+    // 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165  (Value 23 ~ 56)
+
+    {0x0F, 0xF5, 0x40}, // channel =   7, Tf = 5035MHz (23)
+    {0x2F, 0xF5, 0x40}, // channel =   8, Tf = 5040MHz (24)
+    {0x0F, 0xF5, 0x40}, // channel =   9, Tf = 5045MHz (25)
+    {0x0F, 0xF5, 0x40}, // channel =  11, Tf = 5055MHz (26)
+    {0x2F, 0xF5, 0x40}, // channel =  12, Tf = 5060MHz (27)
+    {0x2F, 0xF5, 0x50}, // channel =  16, Tf = 5080MHz (28)
+    {0x2F, 0xF5, 0x60}, // channel =  34, Tf = 5170MHz (29)
+    {0x2F, 0xF5, 0x60}, // channel =  36, Tf = 5180MHz (30)
+    {0x2F, 0xF5, 0x70}, // channel =  38, Tf = 5190MHz (31) //RobertYu: 20050218, update for APNode 0.49
+    {0x2F, 0xF5, 0x70}, // channel =  40, Tf = 5200MHz (32)
+    {0x2F, 0xF5, 0x70}, // channel =  42, Tf = 5210MHz (33)
+    {0x2F, 0xF5, 0x70}, // channel =  44, Tf = 5220MHz (34)
+    {0x2F, 0xF5, 0x70}, // channel =  46, Tf = 5230MHz (35)
+    {0x2F, 0xF5, 0x70}, // channel =  48, Tf = 5240MHz (36)
+    {0x2F, 0xF5, 0x80}, // channel =  52, Tf = 5260MHz (37)
+    {0x2F, 0xF5, 0x80}, // channel =  56, Tf = 5280MHz (38)
+    {0x2F, 0xF5, 0x80}, // channel =  60, Tf = 5300MHz (39)
+    {0x2F, 0xF5, 0x90}, // channel =  64, Tf = 5320MHz (40)
+
+    {0x2F, 0xF5, 0xC0}, // channel = 100, Tf = 5500MHz (41)
+    {0x2F, 0xF5, 0xC0}, // channel = 104, Tf = 5520MHz (42)
+    {0x2F, 0xF5, 0xC0}, // channel = 108, Tf = 5540MHz (43)
+    {0x2F, 0xF5, 0xD0}, // channel = 112, Tf = 5560MHz (44)
+    {0x2F, 0xF5, 0xD0}, // channel = 116, Tf = 5580MHz (45)
+    {0x2F, 0xF5, 0xD0}, // channel = 120, Tf = 5600MHz (46)
+    {0x2F, 0xF5, 0xE0}, // channel = 124, Tf = 5620MHz (47)
+    {0x2F, 0xF5, 0xE0}, // channel = 128, Tf = 5640MHz (48)
+    {0x2F, 0xF5, 0xE0}, // channel = 132, Tf = 5660MHz (49)
+    {0x2F, 0xF5, 0xF0}, // channel = 136, Tf = 5680MHz (50)
+    {0x2F, 0xF5, 0xF0}, // channel = 140, Tf = 5700MHz (51)
+    {0x2F, 0xF6, 0x00}, // channel = 149, Tf = 5745MHz (52)
+    {0x2F, 0xF6, 0x00}, // channel = 153, Tf = 5765MHz (53)
+    {0x2F, 0xF6, 0x00}, // channel = 157, Tf = 5785MHz (54)
+    {0x2F, 0xF6, 0x10}, // channel = 161, Tf = 5805MHz (55)
+    {0x2F, 0xF6, 0x10} // channel = 165, Tf = 5825MHz (56)
+    };
+
+BYTE abyAL7230ChannelTable1[CB_MAX_CHANNEL][3] = {
+    {0x13, 0x33, 0x31}, // channel =  1, Tf = 2412MHz
+    {0x1B, 0x33, 0x31}, // channel =  2, Tf = 2417MHz
+    {0x03, 0x33, 0x31}, // channel =  3, Tf = 2422MHz
+    {0x0B, 0x33, 0x31}, // channel =  4, Tf = 2427MHz
+    {0x13, 0x33, 0x31}, // channel =  5, Tf = 2432MHz
+    {0x1B, 0x33, 0x31}, // channel =  6, Tf = 2437MHz
+    {0x03, 0x33, 0x31}, // channel =  7, Tf = 2442MHz
+    {0x0B, 0x33, 0x31}, // channel =  8, Tf = 2447MHz
+    {0x13, 0x33, 0x31}, // channel =  9, Tf = 2452MHz
+    {0x1B, 0x33, 0x31}, // channel = 10, Tf = 2457MHz
+    {0x03, 0x33, 0x31}, // channel = 11, Tf = 2462MHz
+    {0x0B, 0x33, 0x31}, // channel = 12, Tf = 2467MHz
+    {0x13, 0x33, 0x31}, // channel = 13, Tf = 2472MHz
+    {0x06, 0x66, 0x61}, // channel = 14, Tf = 2484MHz
+
+    // 4.9G => Ch 183, 184, 185, 187, 188, 189, 192, 196  (Value:15 ~ 22)
+    {0x1D, 0x55, 0x51}, // channel = 183, Tf = 4915MHz (15)
+    {0x00, 0x00, 0x01}, // channel = 184, Tf = 4920MHz (16)
+    {0x02, 0xAA, 0xA1}, // channel = 185, Tf = 4925MHz (17)
+    {0x08, 0x00, 0x01}, // channel = 187, Tf = 4935MHz (18)
+    {0x0A, 0xAA, 0xA1}, // channel = 188, Tf = 4940MHz (19)
+    {0x0D, 0x55, 0x51}, // channel = 189, Tf = 4945MHz (20)
+    {0x15, 0x55, 0x51}, // channel = 192, Tf = 4960MHz (21)
+    {0x00, 0x00, 0x01}, // channel = 196, Tf = 4980MHz (22)
+
+    // 5G => Ch 7, 8, 9, 11, 12, 16, 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64,
+    // 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165  (Value 23 ~ 56)
+    {0x1D, 0x55, 0x51}, // channel =   7, Tf = 5035MHz (23)
+    {0x00, 0x00, 0x01}, // channel =   8, Tf = 5040MHz (24)
+    {0x02, 0xAA, 0xA1}, // channel =   9, Tf = 5045MHz (25)
+    {0x08, 0x00, 0x01}, // channel =  11, Tf = 5055MHz (26)
+    {0x0A, 0xAA, 0xA1}, // channel =  12, Tf = 5060MHz (27)
+    {0x15, 0x55, 0x51}, // channel =  16, Tf = 5080MHz (28)
+    {0x05, 0x55, 0x51}, // channel =  34, Tf = 5170MHz (29)
+    {0x0A, 0xAA, 0xA1}, // channel =  36, Tf = 5180MHz (30)
+    {0x10, 0x00, 0x01}, // channel =  38, Tf = 5190MHz (31)
+    {0x15, 0x55, 0x51}, // channel =  40, Tf = 5200MHz (32)
+    {0x1A, 0xAA, 0xA1}, // channel =  42, Tf = 5210MHz (33)
+    {0x00, 0x00, 0x01}, // channel =  44, Tf = 5220MHz (34)
+    {0x05, 0x55, 0x51}, // channel =  46, Tf = 5230MHz (35)
+    {0x0A, 0xAA, 0xA1}, // channel =  48, Tf = 5240MHz (36)
+    {0x15, 0x55, 0x51}, // channel =  52, Tf = 5260MHz (37)
+    {0x00, 0x00, 0x01}, // channel =  56, Tf = 5280MHz (38)
+    {0x0A, 0xAA, 0xA1}, // channel =  60, Tf = 5300MHz (39)
+    {0x15, 0x55, 0x51}, // channel =  64, Tf = 5320MHz (40)
+    {0x15, 0x55, 0x51}, // channel = 100, Tf = 5500MHz (41)
+    {0x00, 0x00, 0x01}, // channel = 104, Tf = 5520MHz (42)
+    {0x0A, 0xAA, 0xA1}, // channel = 108, Tf = 5540MHz (43)
+    {0x15, 0x55, 0x51}, // channel = 112, Tf = 5560MHz (44)
+    {0x00, 0x00, 0x01}, // channel = 116, Tf = 5580MHz (45)
+    {0x0A, 0xAA, 0xA1}, // channel = 120, Tf = 5600MHz (46)
+    {0x15, 0x55, 0x51}, // channel = 124, Tf = 5620MHz (47)
+    {0x00, 0x00, 0x01}, // channel = 128, Tf = 5640MHz (48)
+    {0x0A, 0xAA, 0xA1}, // channel = 132, Tf = 5660MHz (49)
+    {0x15, 0x55, 0x51}, // channel = 136, Tf = 5680MHz (50)
+    {0x00, 0x00, 0x01}, // channel = 140, Tf = 5700MHz (51)
+    {0x18, 0x00, 0x01}, // channel = 149, Tf = 5745MHz (52)
+    {0x02, 0xAA, 0xA1}, // channel = 153, Tf = 5765MHz (53)
+    {0x0D, 0x55, 0x51}, // channel = 157, Tf = 5785MHz (54)
+    {0x18, 0x00, 0x01}, // channel = 161, Tf = 5805MHz (55)
+    {0x02, 0xAA, 0xB1}  // channel = 165, Tf = 5825MHz (56)
+    };
+
+BYTE abyAL7230ChannelTable2[CB_MAX_CHANNEL][3] = {
+    {0x7F, 0xD7, 0x84}, // channel =  1, Tf = 2412MHz
+    {0x7F, 0xD7, 0x84}, // channel =  2, Tf = 2417MHz
+    {0x7F, 0xD7, 0x84}, // channel =  3, Tf = 2422MHz
+    {0x7F, 0xD7, 0x84}, // channel =  4, Tf = 2427MHz
+    {0x7F, 0xD7, 0x84}, // channel =  5, Tf = 2432MHz
+    {0x7F, 0xD7, 0x84}, // channel =  6, Tf = 2437MHz
+    {0x7F, 0xD7, 0x84}, // channel =  7, Tf = 2442MHz
+    {0x7F, 0xD7, 0x84}, // channel =  8, Tf = 2447MHz
+    {0x7F, 0xD7, 0x84}, // channel =  9, Tf = 2452MHz
+    {0x7F, 0xD7, 0x84}, // channel = 10, Tf = 2457MHz
+    {0x7F, 0xD7, 0x84}, // channel = 11, Tf = 2462MHz
+    {0x7F, 0xD7, 0x84}, // channel = 12, Tf = 2467MHz
+    {0x7F, 0xD7, 0x84}, // channel = 13, Tf = 2472MHz
+    {0x7F, 0xD7, 0x84}, // channel = 14, Tf = 2484MHz
+
+    // 4.9G => Ch 183, 184, 185, 187, 188, 189, 192, 196  (Value:15 ~ 22)
+    {0x7F, 0xD7, 0x84}, // channel = 183, Tf = 4915MHz (15)
+    {0x6F, 0xD7, 0x84}, // channel = 184, Tf = 4920MHz (16)
+    {0x7F, 0xD7, 0x84}, // channel = 185, Tf = 4925MHz (17)
+    {0x7F, 0xD7, 0x84}, // channel = 187, Tf = 4935MHz (18)
+    {0x7F, 0xD7, 0x84}, // channel = 188, Tf = 4940MHz (19)
+    {0x7F, 0xD7, 0x84}, // channel = 189, Tf = 4945MHz (20)
+    {0x7F, 0xD7, 0x84}, // channel = 192, Tf = 4960MHz (21)
+    {0x6F, 0xD7, 0x84}, // channel = 196, Tf = 4980MHz (22)
+
+    // 5G => Ch 7, 8, 9, 11, 12, 16, 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64,
+    // 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165  (Value 23 ~ 56)
+    {0x7F, 0xD7, 0x84}, // channel =   7, Tf = 5035MHz (23)
+    {0x6F, 0xD7, 0x84}, // channel =   8, Tf = 5040MHz (24)
+    {0x7F, 0xD7, 0x84}, // channel =   9, Tf = 5045MHz (25)
+    {0x7F, 0xD7, 0x84}, // channel =  11, Tf = 5055MHz (26)
+    {0x7F, 0xD7, 0x84}, // channel =  12, Tf = 5060MHz (27)
+    {0x7F, 0xD7, 0x84}, // channel =  16, Tf = 5080MHz (28)
+    {0x7F, 0xD7, 0x84}, // channel =  34, Tf = 5170MHz (29)
+    {0x7F, 0xD7, 0x84}, // channel =  36, Tf = 5180MHz (30)
+    {0x7F, 0xD7, 0x84}, // channel =  38, Tf = 5190MHz (31)
+    {0x7F, 0xD7, 0x84}, // channel =  40, Tf = 5200MHz (32)
+    {0x7F, 0xD7, 0x84}, // channel =  42, Tf = 5210MHz (33)
+    {0x6F, 0xD7, 0x84}, // channel =  44, Tf = 5220MHz (34)
+    {0x7F, 0xD7, 0x84}, // channel =  46, Tf = 5230MHz (35)
+    {0x7F, 0xD7, 0x84}, // channel =  48, Tf = 5240MHz (36)
+    {0x7F, 0xD7, 0x84}, // channel =  52, Tf = 5260MHz (37)
+    {0x6F, 0xD7, 0x84}, // channel =  56, Tf = 5280MHz (38)
+    {0x7F, 0xD7, 0x84}, // channel =  60, Tf = 5300MHz (39)
+    {0x7F, 0xD7, 0x84}, // channel =  64, Tf = 5320MHz (40)
+    {0x7F, 0xD7, 0x84}, // channel = 100, Tf = 5500MHz (41)
+    {0x6F, 0xD7, 0x84}, // channel = 104, Tf = 5520MHz (42)
+    {0x7F, 0xD7, 0x84}, // channel = 108, Tf = 5540MHz (43)
+    {0x7F, 0xD7, 0x84}, // channel = 112, Tf = 5560MHz (44)
+    {0x6F, 0xD7, 0x84}, // channel = 116, Tf = 5580MHz (45)
+    {0x7F, 0xD7, 0x84}, // channel = 120, Tf = 5600MHz (46)
+    {0x7F, 0xD7, 0x84}, // channel = 124, Tf = 5620MHz (47)
+    {0x6F, 0xD7, 0x84}, // channel = 128, Tf = 5640MHz (48)
+    {0x7F, 0xD7, 0x84}, // channel = 132, Tf = 5660MHz (49)
+    {0x7F, 0xD7, 0x84}, // channel = 136, Tf = 5680MHz (50)
+    {0x6F, 0xD7, 0x84}, // channel = 140, Tf = 5700MHz (51)
+    {0x7F, 0xD7, 0x84}, // channel = 149, Tf = 5745MHz (52)
+    {0x7F, 0xD7, 0x84}, // channel = 153, Tf = 5765MHz (53)
+    {0x7F, 0xD7, 0x84}, // channel = 157, Tf = 5785MHz (54)
+    {0x7F, 0xD7, 0x84}, // channel = 161, Tf = 5805MHz (55)
+    {0x7F, 0xD7, 0x84}  // channel = 165, Tf = 5825MHz (56)
+    };
+
+///{{RobertYu:20051111
+BYTE abyVT3226_InitTable[CB_VT3226_INIT_SEQ][3] = {
+    {0x03, 0xFF, 0x80},
+    {0x02, 0x82, 0xA1},
+    {0x03, 0xC6, 0xA2},
+    {0x01, 0x97, 0x93},
+    {0x03, 0x66, 0x64},
+    {0x00, 0x61, 0xA5},
+    {0x01, 0x7B, 0xD6},
+    {0x00, 0x80, 0x17},
+    {0x03, 0xF8, 0x08},
+    {0x00, 0x02, 0x39},   //RobertYu:20051116
+    {0x02, 0x00, 0x2A}
+    };
+
+BYTE abyVT3226D0_InitTable[CB_VT3226_INIT_SEQ][3] = {
+    {0x03, 0xFF, 0x80},
+    {0x03, 0x02, 0x21}, //RobertYu:20060327
+    {0x03, 0xC6, 0xA2},
+    {0x01, 0x97, 0x93},
+    {0x03, 0x66, 0x64},
+    {0x00, 0x71, 0xA5}, //RobertYu:20060103
+    {0x01, 0x15, 0xC6}, //RobertYu:20060420
+    {0x01, 0x2E, 0x07}, //RobertYu:20060420
+    {0x00, 0x58, 0x08}, //RobertYu:20060111
+    {0x00, 0x02, 0x79}, //RobertYu:20060420
+    {0x02, 0x01, 0xAA}  //RobertYu:20060523
+    };
+
+
+BYTE abyVT3226_ChannelTable0[CB_MAX_CHANNEL_24G][3] = {
+    {0x01, 0x97, 0x83}, // channel = 1, Tf = 2412MHz
+    {0x01, 0x97, 0x83}, // channel = 2, Tf = 2417MHz
+    {0x01, 0x97, 0x93}, // channel = 3, Tf = 2422MHz
+    {0x01, 0x97, 0x93}, // channel = 4, Tf = 2427MHz
+    {0x01, 0x97, 0x93}, // channel = 5, Tf = 2432MHz
+    {0x01, 0x97, 0x93}, // channel = 6, Tf = 2437MHz
+    {0x01, 0x97, 0xA3}, // channel = 7, Tf = 2442MHz
+    {0x01, 0x97, 0xA3}, // channel = 8, Tf = 2447MHz
+    {0x01, 0x97, 0xA3}, // channel = 9, Tf = 2452MHz
+    {0x01, 0x97, 0xA3}, // channel = 10, Tf = 2457MHz
+    {0x01, 0x97, 0xB3}, // channel = 11, Tf = 2462MHz
+    {0x01, 0x97, 0xB3}, // channel = 12, Tf = 2467MHz
+    {0x01, 0x97, 0xB3}, // channel = 13, Tf = 2472MHz
+    {0x03, 0x37, 0xC3}  // channel = 14, Tf = 2484MHz
+    };
+
+BYTE abyVT3226_ChannelTable1[CB_MAX_CHANNEL_24G][3] = {
+    {0x02, 0x66, 0x64}, // channel = 1, Tf = 2412MHz
+    {0x03, 0x66, 0x64}, // channel = 2, Tf = 2417MHz
+    {0x00, 0x66, 0x64}, // channel = 3, Tf = 2422MHz
+    {0x01, 0x66, 0x64}, // channel = 4, Tf = 2427MHz
+    {0x02, 0x66, 0x64}, // channel = 5, Tf = 2432MHz
+    {0x03, 0x66, 0x64}, // channel = 6, Tf = 2437MHz
+    {0x00, 0x66, 0x64}, // channel = 7, Tf = 2442MHz
+    {0x01, 0x66, 0x64}, // channel = 8, Tf = 2447MHz
+    {0x02, 0x66, 0x64}, // channel = 9, Tf = 2452MHz
+    {0x03, 0x66, 0x64}, // channel = 10, Tf = 2457MHz
+    {0x00, 0x66, 0x64}, // channel = 11, Tf = 2462MHz
+    {0x01, 0x66, 0x64}, // channel = 12, Tf = 2467MHz
+    {0x02, 0x66, 0x64}, // channel = 13, Tf = 2472MHz
+    {0x00, 0xCC, 0xC4}  // channel = 14, Tf = 2484MHz
+    };
+///}}RobertYu
+
+
+//{{RobertYu:20060502, TWIF 1.14, LO Current for 11b mode
+DWORD dwVT3226D0LoCurrentTable[CB_MAX_CHANNEL_24G] = {
+    0x0135C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 1, Tf = 2412MHz
+    0x0135C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 2, Tf = 2417MHz
+    0x0235C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 3, Tf = 2422MHz
+    0x0235C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 4, Tf = 2427MHz
+    0x0235C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 5, Tf = 2432MHz
+    0x0335C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 6, Tf = 2437MHz
+    0x0335C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 7, Tf = 2442MHz
+    0x0335C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 8, Tf = 2447MHz
+    0x0335C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 9, Tf = 2452MHz
+    0x0335C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 10, Tf = 2457MHz
+    0x0335C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 11, Tf = 2462MHz
+    0x0335C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 12, Tf = 2467MHz
+    0x0335C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 13, Tf = 2472MHz
+    0x0135C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW  // channel = 14, Tf = 2484MHz
+};
+//}}
+
+
+//{{RobertYu:20060609
+BYTE abyVT3342A0_InitTable[CB_VT3342_INIT_SEQ][3] = { // 11b/g mode
+    {0x03, 0xFF, 0x80}, //update for mode//
+    {0x02, 0x08, 0x81},
+    {0x00, 0xC6, 0x02},
+    {0x03, 0xC5, 0x13}, // channel6
+    {0x00, 0xEE, 0xE4}, // channel6
+    {0x00, 0x71, 0xA5},
+    {0x01, 0x75, 0x46},
+    {0x01, 0x40, 0x27},
+    {0x01, 0x54, 0x08},
+    {0x00, 0x01, 0x69},
+    {0x02, 0x00, 0xAA},
+    {0x00, 0x08, 0xCB},
+    {0x01, 0x70, 0x0C}
+    };
+
+ //11b/g mode: 0x03, 0xFF, 0x80,
+ //11a mode:   0x03, 0xFF, 0xC0,
+
+ // channel44, 5220MHz  0x00C402
+ // channel56, 5280MHz  0x00C402 for disable Frac
+ // other channels 0x00C602
+
+BYTE abyVT3342_ChannelTable0[CB_MAX_CHANNEL][3] = {
+    {0x02, 0x05, 0x03}, // channel = 1, Tf = 2412MHz
+    {0x01, 0x15, 0x03}, // channel = 2, Tf = 2417MHz
+    {0x03, 0xC5, 0x03}, // channel = 3, Tf = 2422MHz
+    {0x02, 0x65, 0x03}, // channel = 4, Tf = 2427MHz
+    {0x01, 0x15, 0x13}, // channel = 5, Tf = 2432MHz
+    {0x03, 0xC5, 0x13}, // channel = 6, Tf = 2437MHz
+    {0x02, 0x05, 0x13}, // channel = 7, Tf = 2442MHz
+    {0x01, 0x15, 0x13}, // channel = 8, Tf = 2447MHz
+    {0x03, 0xC5, 0x13}, // channel = 9, Tf = 2452MHz
+    {0x02, 0x65, 0x13}, // channel = 10, Tf = 2457MHz
+    {0x01, 0x15, 0x23}, // channel = 11, Tf = 2462MHz
+    {0x03, 0xC5, 0x23}, // channel = 12, Tf = 2467MHz
+    {0x02, 0x05, 0x23}, // channel = 13, Tf = 2472MHz
+    {0x00, 0xD5, 0x23}, // channel = 14, Tf = 2484MHz
+
+    // 4.9G => Ch 183, 184, 185, 187, 188, 189, 192, 196  (Value:15 ~ 22)
+    {0x01, 0x15, 0x13}, // channel = 183, Tf = 4915MHz (15), TBD
+    {0x01, 0x15, 0x13}, // channel = 184, Tf = 4920MHz (16), TBD
+    {0x01, 0x15, 0x13}, // channel = 185, Tf = 4925MHz (17), TBD
+    {0x01, 0x15, 0x13}, // channel = 187, Tf = 4935MHz (18), TBD
+    {0x01, 0x15, 0x13}, // channel = 188, Tf = 4940MHz (19), TBD
+    {0x01, 0x15, 0x13}, // channel = 189, Tf = 4945MHz (20), TBD
+    {0x01, 0x15, 0x13}, // channel = 192, Tf = 4960MHz (21), TBD
+    {0x01, 0x15, 0x13}, // channel = 196, Tf = 4980MHz (22), TBD
+
+    // 5G => Ch 7, 8, 9, 11, 12, 16, 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64,
+    // 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165  (Value 23 ~ 56)
+    {0x01, 0x15, 0x13}, // channel =   7, Tf = 5035MHz (23), TBD
+    {0x01, 0x15, 0x13}, // channel =   8, Tf = 5040MHz (24), TBD
+    {0x01, 0x15, 0x13}, // channel =   9, Tf = 5045MHz (25), TBD
+    {0x01, 0x15, 0x13}, // channel =  11, Tf = 5055MHz (26), TBD
+    {0x01, 0x15, 0x13}, // channel =  12, Tf = 5060MHz (27), TBD
+    {0x01, 0x15, 0x13}, // channel =  16, Tf = 5080MHz (28), TBD
+    {0x01, 0x15, 0x13}, // channel =  34, Tf = 5170MHz (29), TBD
+    {0x01, 0x55, 0x63}, // channel =  36, Tf = 5180MHz (30)
+    {0x01, 0x55, 0x63}, // channel =  38, Tf = 5190MHz (31), TBD
+    {0x02, 0xA5, 0x63}, // channel =  40, Tf = 5200MHz (32)
+    {0x02, 0xA5, 0x63}, // channel =  42, Tf = 5210MHz (33), TBD
+    {0x00, 0x05, 0x73}, // channel =  44, Tf = 5220MHz (34)
+    {0x00, 0x05, 0x73}, // channel =  46, Tf = 5230MHz (35), TBD
+    {0x01, 0x55, 0x73}, // channel =  48, Tf = 5240MHz (36)
+    {0x02, 0xA5, 0x73}, // channel =  52, Tf = 5260MHz (37)
+    {0x00, 0x05, 0x83}, // channel =  56, Tf = 5280MHz (38)
+    {0x01, 0x55, 0x83}, // channel =  60, Tf = 5300MHz (39)
+    {0x02, 0xA5, 0x83}, // channel =  64, Tf = 5320MHz (40)
+
+    {0x02, 0xA5, 0x83}, // channel = 100, Tf = 5500MHz (41), TBD
+    {0x02, 0xA5, 0x83}, // channel = 104, Tf = 5520MHz (42), TBD
+    {0x02, 0xA5, 0x83}, // channel = 108, Tf = 5540MHz (43), TBD
+    {0x02, 0xA5, 0x83}, // channel = 112, Tf = 5560MHz (44), TBD
+    {0x02, 0xA5, 0x83}, // channel = 116, Tf = 5580MHz (45), TBD
+    {0x02, 0xA5, 0x83}, // channel = 120, Tf = 5600MHz (46), TBD
+    {0x02, 0xA5, 0x83}, // channel = 124, Tf = 5620MHz (47), TBD
+    {0x02, 0xA5, 0x83}, // channel = 128, Tf = 5640MHz (48), TBD
+    {0x02, 0xA5, 0x83}, // channel = 132, Tf = 5660MHz (49), TBD
+    {0x02, 0xA5, 0x83}, // channel = 136, Tf = 5680MHz (50), TBD
+    {0x02, 0xA5, 0x83}, // channel = 140, Tf = 5700MHz (51), TBD
+
+    {0x00, 0x05, 0xF3}, // channel = 149, Tf = 5745MHz (52)
+    {0x01, 0x56, 0x03}, // channel = 153, Tf = 5765MHz (53)
+    {0x02, 0xA6, 0x03}, // channel = 157, Tf = 5785MHz (54)
+    {0x00, 0x06, 0x03}, // channel = 161, Tf = 5805MHz (55)
+    {0x00, 0x06, 0x03}  // channel = 165, Tf = 5825MHz (56), TBD
+    };
+
+BYTE abyVT3342_ChannelTable1[CB_MAX_CHANNEL][3] = {
+    {0x01, 0x99, 0x94}, // channel = 1, Tf = 2412MHz
+    {0x02, 0x44, 0x44}, // channel = 2, Tf = 2417MHz
+    {0x02, 0xEE, 0xE4}, // channel = 3, Tf = 2422MHz
+    {0x03, 0x99, 0x94}, // channel = 4, Tf = 2427MHz
+    {0x00, 0x44, 0x44}, // channel = 5, Tf = 2432MHz
+    {0x00, 0xEE, 0xE4}, // channel = 6, Tf = 2437MHz
+    {0x01, 0x99, 0x94}, // channel = 7, Tf = 2442MHz
+    {0x02, 0x44, 0x44}, // channel = 8, Tf = 2447MHz
+    {0x02, 0xEE, 0xE4}, // channel = 9, Tf = 2452MHz
+    {0x03, 0x99, 0x94}, // channel = 10, Tf = 2457MHz
+    {0x00, 0x44, 0x44}, // channel = 11, Tf = 2462MHz
+    {0x00, 0xEE, 0xE4}, // channel = 12, Tf = 2467MHz
+    {0x01, 0x99, 0x94}, // channel = 13, Tf = 2472MHz
+    {0x03, 0x33, 0x34}, // channel = 14, Tf = 2484MHz
+
+    // 4.9G => Ch 183, 184, 185, 187, 188, 189, 192, 196  (Value:15 ~ 22)
+    {0x00, 0x44, 0x44}, // channel = 183, Tf = 4915MHz (15), TBD
+    {0x00, 0x44, 0x44}, // channel = 184, Tf = 4920MHz (16), TBD
+    {0x00, 0x44, 0x44}, // channel = 185, Tf = 4925MHz (17), TBD
+    {0x00, 0x44, 0x44}, // channel = 187, Tf = 4935MHz (18), TBD
+    {0x00, 0x44, 0x44}, // channel = 188, Tf = 4940MHz (19), TBD
+    {0x00, 0x44, 0x44}, // channel = 189, Tf = 4945MHz (20), TBD
+    {0x00, 0x44, 0x44}, // channel = 192, Tf = 4960MHz (21), TBD
+    {0x00, 0x44, 0x44}, // channel = 196, Tf = 4980MHz (22), TBD
+
+    // 5G => Ch 7, 8, 9, 11, 12, 16, 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64,
+    // 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165  (Value 23 ~ 56)
+    {0x00, 0x44, 0x44}, // channel =   7, Tf = 5035MHz (23), TBD
+    {0x00, 0x44, 0x44}, // channel =   8, Tf = 5040MHz (24), TBD
+    {0x00, 0x44, 0x44}, // channel =   9, Tf = 5045MHz (25), TBD
+    {0x00, 0x44, 0x44}, // channel =  11, Tf = 5055MHz (26), TBD
+    {0x00, 0x44, 0x44}, // channel =  12, Tf = 5060MHz (27), TBD
+    {0x00, 0x44, 0x44}, // channel =  16, Tf = 5080MHz (28), TBD
+    {0x00, 0x44, 0x44}, // channel =  34, Tf = 5170MHz (29), TBD
+    {0x01, 0x55, 0x54}, // channel =  36, Tf = 5180MHz (30)
+    {0x01, 0x55, 0x54}, // channel =  38, Tf = 5190MHz (31), TBD
+    {0x02, 0xAA, 0xA4}, // channel =  40, Tf = 5200MHz (32)
+    {0x02, 0xAA, 0xA4}, // channel =  42, Tf = 5210MHz (33), TBD
+    {0x00, 0x00, 0x04}, // channel =  44, Tf = 5220MHz (34)
+    {0x00, 0x00, 0x04}, // channel =  46, Tf = 5230MHz (35), TBD
+    {0x01, 0x55, 0x54}, // channel =  48, Tf = 5240MHz (36)
+    {0x02, 0xAA, 0xA4}, // channel =  52, Tf = 5260MHz (37)
+    {0x00, 0x00, 0x04}, // channel =  56, Tf = 5280MHz (38)
+    {0x01, 0x55, 0x54}, // channel =  60, Tf = 5300MHz (39)
+    {0x02, 0xAA, 0xA4}, // channel =  64, Tf = 5320MHz (40)
+    {0x02, 0xAA, 0xA4}, // channel = 100, Tf = 5500MHz (41), TBD
+    {0x02, 0xAA, 0xA4}, // channel = 104, Tf = 5520MHz (42), TBD
+    {0x02, 0xAA, 0xA4}, // channel = 108, Tf = 5540MHz (43), TBD
+    {0x02, 0xAA, 0xA4}, // channel = 112, Tf = 5560MHz (44), TBD
+    {0x02, 0xAA, 0xA4}, // channel = 116, Tf = 5580MHz (45), TBD
+    {0x02, 0xAA, 0xA4}, // channel = 120, Tf = 5600MHz (46), TBD
+    {0x02, 0xAA, 0xA4}, // channel = 124, Tf = 5620MHz (47), TBD
+    {0x02, 0xAA, 0xA4}, // channel = 128, Tf = 5640MHz (48), TBD
+    {0x02, 0xAA, 0xA4}, // channel = 132, Tf = 5660MHz (49), TBD
+    {0x02, 0xAA, 0xA4}, // channel = 136, Tf = 5680MHz (50), TBD
+    {0x02, 0xAA, 0xA4}, // channel = 140, Tf = 5700MHz (51), TBD
+    {0x03, 0x00, 0x04}, // channel = 149, Tf = 5745MHz (52)
+    {0x00, 0x55, 0x54}, // channel = 153, Tf = 5765MHz (53)
+    {0x01, 0xAA, 0xA4}, // channel = 157, Tf = 5785MHz (54)
+    {0x03, 0x00, 0x04}, // channel = 161, Tf = 5805MHz (55)
+    {0x03, 0x00, 0x04}  // channel = 165, Tf = 5825MHz (56), TBD
+    };
+
+
+/*+
+ *
+ * Power Table
+ *
+-*/
+
+const DWORD dwAL2230PowerTable[AL2230_PWR_IDX_LEN] = {
+    0x04040900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04041900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04042900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04043900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04044900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04045900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04046900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04047900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04048900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04049900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0404A900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0404B900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0404C900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0404D900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0404E900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0404F900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04050900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04051900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04052900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04053900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04054900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04055900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04056900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04057900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04058900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04059900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0405A900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0405B900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0405C900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0405D900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0405E900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0405F900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04060900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04061900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04062900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04063900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04064900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04065900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04066900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04067900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04068900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04069900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0406A900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0406B900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0406C900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0406D900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0406E900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0406F900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04070900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04071900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04072900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04073900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04074900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04075900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04076900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04077900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04078900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04079900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0407A900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0407B900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0407C900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0407D900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0407E900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0407F900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW
+    };
+
+/*---------------------  Static Functions  --------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+//{{ RobertYu:20050103, Channel 11a Number To Index
+// 4.9G => Ch 183, 184, 185, 187, 188, 189, 192, 196  (Value:15 ~ 22)
+// 5G => Ch 7, 8, 9, 11, 12, 16, 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64,
+// 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165  (Value 23 ~ 56)
+
+const BYTE RFaby11aChannelIndex[200] = {
+  // 1   2   3   4   5   6   7   8   9  10
+    00, 00, 00, 00, 00, 00, 23, 24, 25, 00,  // 10
+    26, 27, 00, 00, 00, 28, 00, 00, 00, 00,  // 20
+    00, 00, 00, 00, 00, 00, 00, 00, 00, 00,  // 30
+    00, 00, 00, 29, 00, 30, 00, 31, 00, 32,  // 40
+    00, 33, 00, 34, 00, 35, 00, 36, 00, 00,  // 50
+    00, 37, 00, 00, 00, 38, 00, 00, 00, 39,  // 60
+    00, 00, 00, 40, 00, 00, 00, 00, 00, 00,  // 70
+    00, 00, 00, 00, 00, 00, 00, 00, 00, 00,  // 80
+    00, 00, 00, 00, 00, 00, 00, 00, 00, 00,  // 90
+    00, 00, 00, 00, 00, 00, 00, 00, 00, 41,  //100
+
+    00, 00, 00, 42, 00, 00, 00, 43, 00, 00,  //110
+    00, 44, 00, 00, 00, 45, 00, 00, 00, 46,  //120
+    00, 00, 00, 47, 00, 00, 00, 48, 00, 00,  //130
+    00, 49, 00, 00, 00, 50, 00, 00, 00, 51,  //140
+    00, 00, 00, 00, 00, 00, 00, 00, 52, 00,  //150
+    00, 00, 53, 00, 00, 00, 54, 00, 00, 00,  //160
+    55, 00, 00, 00, 56, 00, 00, 00, 00, 00,  //170
+    00, 00, 00, 00, 00, 00, 00, 00, 00, 00,  //180
+    00, 00, 15, 16, 17, 00, 18, 19, 20, 00,  //190
+    00, 21, 00, 00, 00, 22, 00, 00, 00, 00   //200
+};
+//}} RobertYu
+
+/*---------------------  Export Functions  --------------------------*/
+
+/*
+ * Description: Write to IF/RF, by embeded programming
+ *
+ * Parameters:
+ *  In:
+ *      dwData      - data to write
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if succeeded; FALSE if failed.
+ *
+ */
+BOOL IFRFbWriteEmbeded (PSDevice pDevice, DWORD dwData)
+{
+    BYTE        pbyData[4];
+
+    pbyData[0] = (BYTE)dwData;
+    pbyData[1] = (BYTE)(dwData>>8);
+    pbyData[2] = (BYTE)(dwData>>16);
+    pbyData[3] = (BYTE)(dwData>>24);
+    CONTROLnsRequestOut(pDevice,
+                    MESSAGE_TYPE_WRITE_IFRF,
+                    0,
+                    0,
+                    4,
+                    pbyData
+                        );
+
+
+    return TRUE;
+}
+
+
+/*
+ * Description: Set Tx power
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase       - I/O base address
+ *      dwRFPowerTable - RF Tx Power Setting
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if succeeded; FALSE if failed.
+ *
+ */
+BOOL RFbSetPower (
+    IN  PSDevice  pDevice,
+    IN  UINT      uRATE,
+    IN  UINT      uCH
+    )
+{
+BOOL    bResult = TRUE;
+BYTE    byPwr = pDevice->byCCKPwr;
+
+    if (pDevice->dwDiagRefCount != 0) {
+        return TRUE;
+    }
+
+    switch (uRATE) {
+    case RATE_1M:
+    case RATE_2M:
+    case RATE_5M:
+    case RATE_11M:
+        byPwr = pDevice->abyCCKPwrTbl[uCH-1];
+        break;
+    case RATE_6M:
+    case RATE_9M:
+    case RATE_18M:
+    case RATE_24M:
+    case RATE_36M:
+    case RATE_48M:
+    case RATE_54M:
+        if (uCH > CB_MAX_CHANNEL_24G) {
+            byPwr = pDevice->abyOFDMAPwrTbl[uCH-15];
+        } else {
+            byPwr = pDevice->abyOFDMPwrTbl[uCH-1];
+        }
+        break;
+    }
+
+    bResult = RFbRawSetPower(pDevice, byPwr, uRATE);
+
+    return bResult;
+}
+
+
+/*
+ * Description: Set Tx power
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase       - I/O base address
+ *      dwRFPowerTable - RF Tx Power Setting
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if succeeded; FALSE if failed.
+ *
+ */
+BOOL RFbRawSetPower (
+    IN  PSDevice  pDevice,
+    IN  BYTE      byPwr,
+    IN  UINT      uRATE
+    )
+{
+BOOL        bResult = TRUE;
+
+    if (pDevice->byCurPwr == byPwr)
+        return TRUE;
+
+    pDevice->byCurPwr = byPwr;
+
+    switch (pDevice->byRFType) {
+
+        case RF_AL2230 :
+            if (pDevice->byCurPwr >= AL2230_PWR_IDX_LEN)
+                return FALSE;
+            bResult &= IFRFbWriteEmbeded(pDevice, dwAL2230PowerTable[pDevice->byCurPwr]);
+            if (uRATE <= RATE_11M)
+                bResult &= IFRFbWriteEmbeded(pDevice, 0x0001B400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW);
+            else
+                bResult &= IFRFbWriteEmbeded(pDevice, 0x0005A400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW);
+            break;
+
+        case RF_AL2230S :
+            if (pDevice->byCurPwr >= AL2230_PWR_IDX_LEN)
+                return FALSE;
+            bResult &= IFRFbWriteEmbeded(pDevice, dwAL2230PowerTable[pDevice->byCurPwr]);
+            if (uRATE <= RATE_11M) {
+                bResult &= IFRFbWriteEmbeded(pDevice, 0x040C1400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW);
+                bResult &= IFRFbWriteEmbeded(pDevice, 0x00299B00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW);
+            }else {
+                bResult &= IFRFbWriteEmbeded(pDevice, 0x0005A400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW);
+                bResult &= IFRFbWriteEmbeded(pDevice, 0x00099B00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW);
+            }
+            break;
+
+
+        case RF_AIROHA7230:
+            {
+                DWORD       dwMax7230Pwr;
+
+                if (uRATE <= RATE_11M) { //RobertYu:20060426, for better 11b mask
+                    bResult &= IFRFbWriteEmbeded(pDevice, 0x111BB900+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW);
+                }
+                else {
+                    bResult &= IFRFbWriteEmbeded(pDevice, 0x221BB900+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW);
+                }
+
+                if (pDevice->byCurPwr > AL7230_PWR_IDX_LEN) return FALSE;
+
+                //  0x080F1B00 for 3 wire control TxGain(D10) and 0x31 as TX Gain value
+                dwMax7230Pwr = 0x080C0B00 | ( (pDevice->byCurPwr) << 12 ) |
+                                 (BY_AL7230_REG_LEN << 3 )  | IFREGCTL_REGW;
+
+                bResult &= IFRFbWriteEmbeded(pDevice, dwMax7230Pwr);
+                break;
+            }
+            break;
+
+        case RF_VT3226: //RobertYu:20051111, VT3226C0 and before
+        {
+            DWORD       dwVT3226Pwr;
+
+            if (pDevice->byCurPwr >= VT3226_PWR_IDX_LEN)
+                return FALSE;
+            dwVT3226Pwr = ((0x3F-pDevice->byCurPwr) << 20 ) | ( 0x17 << 8 ) /* Reg7 */ |
+                           (BY_VT3226_REG_LEN << 3 )  | IFREGCTL_REGW;
+            bResult &= IFRFbWriteEmbeded(pDevice, dwVT3226Pwr);
+            break;
+        }
+
+        case RF_VT3226D0: //RobertYu:20051228
+        {
+            DWORD       dwVT3226Pwr;
+
+            if (pDevice->byCurPwr >= VT3226_PWR_IDX_LEN)
+                return FALSE;
+
+            if (uRATE <= RATE_11M) {
+
+                dwVT3226Pwr = ((0x3F-pDevice->byCurPwr) << 20 ) | ( 0xE07 << 8 ) /* Reg7 */ |   //RobertYu:20060420, TWIF 1.10
+                               (BY_VT3226_REG_LEN << 3 )  | IFREGCTL_REGW;
+                bResult &= IFRFbWriteEmbeded(pDevice, dwVT3226Pwr);
+
+                bResult &= IFRFbWriteEmbeded(pDevice, 0x03C6A200+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW);
+                if (pDevice->sMgmtObj.eScanState != WMAC_NO_SCANNING) {
+                    // scanning, the channel number is pDevice->uScanChannel
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"@@@@ RFbRawSetPower> 11B mode uCurrChannel[%d]\n", pDevice->sMgmtObj.uScanChannel);
+                    bResult &= IFRFbWriteEmbeded(pDevice, dwVT3226D0LoCurrentTable[pDevice->sMgmtObj.uScanChannel-1]); //RobertYu:20060420, sometimes didn't change channel just set power with different rate
+                } else {
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"@@@@ RFbRawSetPower> 11B mode uCurrChannel[%d]\n", pDevice->sMgmtObj.uCurrChannel);
+                    bResult &= IFRFbWriteEmbeded(pDevice, dwVT3226D0LoCurrentTable[pDevice->sMgmtObj.uCurrChannel-1]); //RobertYu:20060420, sometimes didn't change channel just set power with different rate
+                }
+
+                bResult &= IFRFbWriteEmbeded(pDevice, 0x015C0800+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW); //RobertYu:20060420, ok now, new switching power (mini-pci can have bigger power consumption)
+            } else {
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"@@@@ RFbRawSetPower> 11G mode\n");
+                dwVT3226Pwr = ((0x3F-pDevice->byCurPwr) << 20 ) | ( 0x7 << 8 ) /* Reg7 */ |   //RobertYu:20060420, TWIF 1.10
+                               (BY_VT3226_REG_LEN << 3 )  | IFREGCTL_REGW;
+                bResult &= IFRFbWriteEmbeded(pDevice, dwVT3226Pwr);
+                bResult &= IFRFbWriteEmbeded(pDevice, 0x00C6A200+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW); //RobertYu:20060327
+                bResult &= IFRFbWriteEmbeded(pDevice, 0x016BC600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW); //RobertYu:20060111
+                bResult &= IFRFbWriteEmbeded(pDevice, 0x00900800+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW); //RobertYu:20060111
+            }
+            break;
+        }
+
+        //{{RobertYu:20060609
+        case RF_VT3342A0:
+        {
+            DWORD       dwVT3342Pwr;
+
+            if (pDevice->byCurPwr >= VT3342_PWR_IDX_LEN)
+                return FALSE;
+
+            dwVT3342Pwr =  ((0x3F-pDevice->byCurPwr) << 20 ) | ( 0x27 << 8 ) /* Reg7 */ |
+                            (BY_VT3342_REG_LEN << 3 )  | IFREGCTL_REGW;
+            bResult &= IFRFbWriteEmbeded(pDevice, dwVT3342Pwr);
+            break;
+        }
+
+        default :
+            break;
+    }
+    return bResult;
+}
+
+/*+
+ *
+ * Routine Description:
+ *     Translate RSSI to dBm
+ *
+ * Parameters:
+ *  In:
+ *      pDevice         - The adapter to be translated
+ *      byCurrRSSI      - RSSI to be translated
+ *  Out:
+ *      pdwdbm          - Translated dbm number
+ *
+ * Return Value: none
+ *
+-*/
+VOID
+RFvRSSITodBm (
+    IN  PSDevice pDevice,
+    IN  BYTE     byCurrRSSI,
+    OUT PLONG    pldBm
+    )
+{
+    BYTE byIdx = (((byCurrRSSI & 0xC0) >> 6) & 0x03);
+    LONG b = (byCurrRSSI & 0x3F);
+    LONG a = 0;
+    BYTE abyAIROHARF[4] = {0, 18, 0, 40};
+
+    switch (pDevice->byRFType) {
+        case RF_AL2230:
+        case RF_AL2230S:
+        case RF_AIROHA7230:
+        case RF_VT3226: //RobertYu:20051111
+        case RF_VT3226D0:
+        case RF_VT3342A0:   //RobertYu:20060609
+            a = abyAIROHARF[byIdx];
+            break;
+        default:
+            break;
+    }
+
+    *pldBm = -1 * (a + b * 2);
+}
+
+
+
+VOID
+RFbRFTableDownload (
+    IN  PSDevice pDevice
+    )
+{
+WORD    wLength1 = 0,wLength2 = 0 ,wLength3 = 0;
+PBYTE   pbyAddr1 = NULL,pbyAddr2 = NULL,pbyAddr3 = NULL;
+WORD    wLength,wValue;
+BYTE    abyArray[256];
+
+    switch ( pDevice->byRFType ) {
+        case RF_AL2230:
+        case RF_AL2230S:
+            wLength1 = CB_AL2230_INIT_SEQ * 3;
+            wLength2 = CB_MAX_CHANNEL_24G * 3;
+            wLength3 = CB_MAX_CHANNEL_24G * 3;
+            pbyAddr1 = &(abyAL2230InitTable[0][0]);
+            pbyAddr2 = &(abyAL2230ChannelTable0[0][0]);
+            pbyAddr3 = &(abyAL2230ChannelTable1[0][0]);
+            break;
+        case RF_AIROHA7230:
+            wLength1 = CB_AL7230_INIT_SEQ * 3;
+            wLength2 = CB_MAX_CHANNEL * 3;
+            wLength3 = CB_MAX_CHANNEL * 3;
+            pbyAddr1 = &(abyAL7230InitTable[0][0]);
+            pbyAddr2 = &(abyAL7230ChannelTable0[0][0]);
+            pbyAddr3 = &(abyAL7230ChannelTable1[0][0]);
+            break;
+        case RF_VT3226: //RobertYu:20051111
+            wLength1 = CB_VT3226_INIT_SEQ * 3;
+            wLength2 = CB_MAX_CHANNEL_24G * 3;
+            wLength3 = CB_MAX_CHANNEL_24G * 3;
+            pbyAddr1 = &(abyVT3226_InitTable[0][0]);
+            pbyAddr2 = &(abyVT3226_ChannelTable0[0][0]);
+            pbyAddr3 = &(abyVT3226_ChannelTable1[0][0]);
+            break;
+        case RF_VT3226D0: //RobertYu:20051114
+            wLength1 = CB_VT3226_INIT_SEQ * 3;
+            wLength2 = CB_MAX_CHANNEL_24G * 3;
+            wLength3 = CB_MAX_CHANNEL_24G * 3;
+            pbyAddr1 = &(abyVT3226D0_InitTable[0][0]);
+            pbyAddr2 = &(abyVT3226_ChannelTable0[0][0]);
+            pbyAddr3 = &(abyVT3226_ChannelTable1[0][0]);
+            break;
+        case RF_VT3342A0: //RobertYu:20060609
+            wLength1 = CB_VT3342_INIT_SEQ * 3;
+            wLength2 = CB_MAX_CHANNEL * 3;
+            wLength3 = CB_MAX_CHANNEL * 3;
+            pbyAddr1 = &(abyVT3342A0_InitTable[0][0]);
+            pbyAddr2 = &(abyVT3342_ChannelTable0[0][0]);
+            pbyAddr3 = &(abyVT3342_ChannelTable1[0][0]);
+            break;
+
+    }
+    //Init Table
+
+    memcpy(abyArray, pbyAddr1, wLength1);
+    CONTROLnsRequestOut(pDevice,
+                    MESSAGE_TYPE_WRITE,
+                    0,
+                    MESSAGE_REQUEST_RF_INIT,
+                    wLength1,
+                    abyArray
+                    );
+    //Channle Table 0
+    wValue = 0;
+    while ( wLength2 > 0 ) {
+
+        if ( wLength2 >= 64 ) {
+            wLength = 64;
+        } else {
+            wLength = wLength2;
+        }
+        memcpy(abyArray, pbyAddr2, wLength);
+        CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_WRITE,
+                        wValue,
+                        MESSAGE_REQUEST_RF_CH0,
+                        wLength,
+                        abyArray);
+
+        wLength2 -= wLength;
+        wValue += wLength;
+        pbyAddr2 += wLength;
+    }
+    //Channel table 1
+    wValue = 0;
+    while ( wLength3 > 0 ) {
+
+        if ( wLength3 >= 64 ) {
+            wLength = 64;
+        } else {
+            wLength = wLength3;
+        }
+        memcpy(abyArray, pbyAddr3, wLength);
+        CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_WRITE,
+                        wValue,
+                        MESSAGE_REQUEST_RF_CH1,
+                        wLength,
+                        abyArray);
+
+        wLength3 -= wLength;
+        wValue += wLength;
+        pbyAddr3 += wLength;
+    }
+
+    //7230 needs 2 InitTable and 3 Channel Table
+    if ( pDevice->byRFType == RF_AIROHA7230 ) {
+        wLength1 = CB_AL7230_INIT_SEQ * 3;
+        wLength2 = CB_MAX_CHANNEL * 3;
+        pbyAddr1 = &(abyAL7230InitTableAMode[0][0]);
+        pbyAddr2 = &(abyAL7230ChannelTable2[0][0]);
+        memcpy(abyArray, pbyAddr1, wLength1);
+        //Init Table 2
+        CONTROLnsRequestOut(pDevice,
+                    MESSAGE_TYPE_WRITE,
+                    0,
+                    MESSAGE_REQUEST_RF_INIT2,
+                    wLength1,
+                    abyArray);
+
+        //Channle Table 0
+        wValue = 0;
+        while ( wLength2 > 0 ) {
+
+            if ( wLength2 >= 64 ) {
+                wLength = 64;
+            } else {
+                wLength = wLength2;
+            }
+            memcpy(abyArray, pbyAddr2, wLength);
+            CONTROLnsRequestOut(pDevice,
+                            MESSAGE_TYPE_WRITE,
+                            wValue,
+                            MESSAGE_REQUEST_RF_CH2,
+                            wLength,
+                            abyArray);
+
+            wLength2 -= wLength;
+            wValue += wLength;
+            pbyAddr2 += wLength;
+        }
+    }
+
+}
+
+// RobertYu:20060412, TWIF1.11 adjust LO Current for 11b mode
+BOOL s_bVT3226D0_11bLoCurrentAdjust(
+    IN  PSDevice    pDevice,
+    IN  BYTE        byChannel,
+    IN  BOOL        b11bMode )
+{
+    BOOL    bResult;
+
+    bResult = TRUE;
+    if( b11bMode )
+        bResult &= IFRFbWriteEmbeded(pDevice, dwVT3226D0LoCurrentTable[byChannel-1]);
+    else
+        bResult &= IFRFbWriteEmbeded(pDevice, 0x016BC600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW); //RobertYu:20060412
+
+    return bResult;
+}
+
+
diff --git a/drivers/staging/vt6656/rf.h b/drivers/staging/vt6656/rf.h
new file mode 100644
index 0000000..c9ebd00
--- /dev/null
+++ b/drivers/staging/vt6656/rf.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: rf.h
+ *
+ * Purpose:
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Feb. 19, 2004
+ *
+ */
+
+
+#ifndef __RF_H__
+#define __RF_H__
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+#if !defined(__DEVICE_H__)
+#include "device.h"
+#endif
+/*---------------------  Export Definitions -------------------------*/
+//
+// Baseband RF pair definition in eeprom (Bits 6..0)
+//
+#define RF_RFMD2959         0x01
+#define RF_MAXIMAG          0x02
+#define RF_AL2230           0x03
+#define RF_GCT5103          0x04
+#define RF_UW2451           0x05
+#define RF_MAXIMG           0x06
+#define RF_MAXIM2829        0x07
+#define RF_UW2452           0x08
+#define RF_VT3226           0x09
+#define RF_AIROHA7230       0x0a
+#define RF_UW2453           0x0b
+#define RF_VT3226D0         0x0c //RobertYu:20051114
+#define RF_VT3342A0         0x0d //RobertYu:20060609
+#define RF_AL2230S          0x0e
+
+#define RF_EMU              0x80
+#define RF_MASK             0x7F
+
+
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+extern const BYTE RFaby11aChannelIndex[200];
+/*---------------------  Export Functions  --------------------------*/
+#ifdef __cplusplus
+extern "C" {                            /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+BOOL IFRFbWriteEmbeded(PSDevice pDevice, DWORD dwData);
+BOOL RFbSetPower (
+    IN  PSDevice  pDevice,
+    IN  UINT      uRATE,
+    IN  UINT      uCH
+    );
+
+BOOL RFbRawSetPower(
+    IN  PSDevice  pDevice,
+    IN  BYTE      byPwr,
+    IN  UINT      uRATE
+    );
+
+VOID
+RFvRSSITodBm (
+    IN  PSDevice pDevice,
+    IN  BYTE     byCurrRSSI,
+    OUT PLONG    pldBm
+    );
+
+VOID
+RFbRFTableDownload (
+    IN  PSDevice pDevice
+    );
+
+BOOL s_bVT3226D0_11bLoCurrentAdjust(
+    IN  PSDevice    pDevice,
+    IN  BYTE        byChannel,
+    IN  BOOL        b11bMode
+    );
+
+#ifdef __cplusplus
+}                                       /* End of extern "C" { */
+#endif /* __cplusplus */
+
+
+#endif // __RF_H__
+
+
+
diff --git a/drivers/staging/vt6656/rndis.h b/drivers/staging/vt6656/rndis.h
new file mode 100644
index 0000000..1d32d81
--- /dev/null
+++ b/drivers/staging/vt6656/rndis.h
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: rndis.h
+ *
+ * Purpose: Interface between firmware and driver
+ *
+ * Author: Warren Hsu
+ *
+ * Date: Nov 24, 2004
+ *
+ */
+
+
+#ifndef __RNDIS_H__
+#define __RNDIS_H__
+
+/*---------------------  Export Definitions -------------------------*/
+#define MESSAGE_TYPE_READ               0x01
+#define MESSAGE_TYPE_WRITE              0x00
+#define MESSAGE_TYPE_LOCK_OR            0x02
+#define MESSAGE_TYPE_LOCK_AND           0x03
+#define MESSAGE_TYPE_WRITE_MASK         0x04
+#define MESSAGE_TYPE_CARDINIT           0x05
+#define MESSAGE_TYPE_INIT_RSP           0x06
+#define MESSAGE_TYPE_MACSHUTDOWN        0x07
+#define MESSAGE_TYPE_SETKEY             0x08
+#define MESSAGE_TYPE_CLRKEYENTRY        0x09
+#define MESSAGE_TYPE_WRITE_MISCFF       0x0A
+#define MESSAGE_TYPE_SET_ANTMD          0x0B
+#define MESSAGE_TYPE_SELECT_CHANNLE     0x0C
+#define MESSAGE_TYPE_SET_TSFTBTT        0x0D
+#define MESSAGE_TYPE_SET_SSTIFS         0x0E
+#define MESSAGE_TYPE_CHANGE_BBTYPE      0x0F
+#define MESSAGE_TYPE_DISABLE_PS         0x10
+#define MESSAGE_TYPE_WRITE_IFRF         0x11
+
+//used for read/write(index)
+#define MESSAGE_REQUEST_MEM             0x01
+#define MESSAGE_REQUEST_BBREG           0x02
+#define MESSAGE_REQUEST_MACREG          0x03
+#define MESSAGE_REQUEST_EEPROM          0x04
+#define MESSAGE_REQUEST_TSF             0x05
+#define MESSAGE_REQUEST_TBTT            0x06
+#define MESSAGE_REQUEST_BBAGC           0x07
+#define MESSAGE_REQUEST_VERSION         0x08
+#define MESSAGE_REQUEST_RF_INIT         0x09
+#define MESSAGE_REQUEST_RF_INIT2        0x0A
+#define MESSAGE_REQUEST_RF_CH0          0x0B
+#define MESSAGE_REQUEST_RF_CH1          0x0C
+#define MESSAGE_REQUEST_RF_CH2          0x0D
+
+
+#define VIAUSB20_PACKET_HEADER          0x04
+
+
+/*---------------------  Export Classes  ----------------------------*/
+
+typedef struct _CMD_MESSAGE
+{
+    BYTE        byData[256];
+} CMD_MESSAGE, *PCMD_MESSAGE;
+
+typedef struct _CMD_WRITE_MASK
+{
+    BYTE        byData;
+    BYTE        byMask;
+} CMD_WRITE_MASK, *PCMD_WRITE_MASK;
+
+typedef struct _CMD_CARD_INIT
+{
+    BYTE        byInitClass;
+    BYTE        bExistSWNetAddr;
+    BYTE        bySWNetAddr[6];
+    BYTE        byShortRetryLimit;
+    BYTE        byLongRetryLimit;
+} CMD_CARD_INIT, *PCMD_CARD_INIT;
+
+typedef struct _RSP_CARD_INIT
+{
+    BYTE        byStatus;
+    BYTE        byNetAddr[6];
+    BYTE        byRFType;
+    BYTE        byMinChannel;
+    BYTE        byMaxChannel;
+} RSP_CARD_INIT, *PRSP_CARD_INIT;
+
+typedef struct _CMD_SET_KEY
+{
+    WORD        wKCTL;
+    BYTE        abyMacAddr[6];
+    BYTE        abyKey[16];
+} CMD_SET_KEY, *PCMD_SET_KEY;
+
+typedef struct _CMD_CLRKEY_ENTRY
+{
+    BYTE        abyKeyEntry[11];
+} CMD_CLRKEY_ENTRY, *PCMD_CLRKEY_ENTRY;
+
+typedef struct _CMD_WRITE_MISCFF
+{
+    DWORD       adwMiscFFData[22][4];  //a key entry has only 22 dwords
+} CMD_WRITE_MISCFF, *PCMD_WRITE_MISCFF;
+
+typedef struct _CMD_SET_TSFTBTT
+{
+    BYTE        abyTSF_TBTT[8];
+} CMD_SET_TSFTBTT, *PCMD_SET_TSFTBTT;
+
+typedef struct _CMD_SET_SSTIFS
+{
+    BYTE        bySIFS;
+    BYTE        byDIFS;
+    BYTE        byEIFS;
+    BYTE        bySlotTime;
+    BYTE        byCwMax_Min;
+    BYTE        byBBCR10;
+} CMD_SET_SSTIFS, *PCMD_SET_SSTIFS;
+
+typedef struct _CMD_CHANGE_BBTYPE
+{
+    BYTE        bySIFS;
+    BYTE        byDIFS;
+    BYTE        byEIFS;
+    BYTE        bySlotTime;
+    BYTE        byCwMax_Min;
+    BYTE        byBBCR10;
+    BYTE        byBB_BBType;    //CR88
+    BYTE        byMAC_BBType;
+    DWORD       dwRSPINF_b_1;
+    DWORD       dwRSPINF_b_2;
+    DWORD       dwRSPINF_b_55;
+    DWORD       dwRSPINF_b_11;
+    WORD        wRSPINF_a[9];
+} CMD_CHANGE_BBTYPE, *PCMD_CHANGE_BBTYPE;
+
+/*---------------------  Export Macros -------------------------*/
+
+#define EXCH_WORD(w)        ( (WORD)((WORD)(w)<<8) | (WORD)((WORD)(w)>>8) )
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+#endif // _RNDIS_H_
diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c
new file mode 100644
index 0000000..c5ce6f5
--- /dev/null
+++ b/drivers/staging/vt6656/rxtx.c
@@ -0,0 +1,3280 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: rxtx.c
+ *
+ * Purpose: handle WMAC/802.3/802.11 rx & tx functions
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: May 20, 2003
+ *
+ * Functions:
+ *      s_vGenerateTxParameter - Generate tx dma requried parameter.
+ *      s_vGenerateMACHeader - Translate 802.3 to 802.11 header
+ *      csBeacon_xmit - beacon tx function
+ *      csMgmt_xmit - management tx function
+ *      s_uGetDataDuration - get tx data required duration
+ *      s_uFillDataHead- fulfill tx data duration header
+ *      s_uGetRTSCTSDuration- get rtx/cts requried duration
+ *      s_uGetRTSCTSRsvTime- get rts/cts reserved time
+ *      s_uGetTxRsvTime- get frame reserved time
+ *      s_vFillCTSHead- fulfill CTS ctl header
+ *      s_vFillFragParameter- Set fragement ctl parameter.
+ *      s_vFillRTSHead- fulfill RTS ctl header
+ *      s_vFillTxKey- fulfill tx encrypt key
+ *      s_vSWencryption- Software encrypt header
+ *      vDMA0_tx_80211- tx 802.11 frame via dma0
+ *      vGenerateFIFOHeader- Generate tx FIFO ctl header
+ *
+ * Revision History:
+ *
+ */
+
+
+#if !defined(__DEVICE_H__)
+#include "device.h"
+#endif
+#if !defined(__RXTX_H__)
+#include "rxtx.h"
+#endif
+#if !defined(__TETHER_H__)
+#include "tether.h"
+#endif
+#if !defined(__CARD_H__)
+#include "card.h"
+#endif
+#if !defined(__BSSDB_H__)
+#include "bssdb.h"
+#endif
+#if !defined(__MAC_H__)
+#include "mac.h"
+#endif
+#if !defined(__BASEBAND_H__)
+#include "baseband.h"
+#endif
+#if !defined(__UMEM_H__)
+#include "umem.h"
+#endif
+#if !defined(__MICHAEL_H__)
+#include "michael.h"
+#endif
+#if !defined(__TKIP_H__)
+#include "tkip.h"
+#endif
+#if !defined(__TCRC_H__)
+#include "tcrc.h"
+#endif
+#if !defined(__WCTL_H__)
+#include "wctl.h"
+#endif
+#if !defined(__TBIT_H__)
+#include "tbit.h"
+#endif
+#if !defined(__HOSTAP_H__)
+#include "hostap.h"
+#endif
+#if !defined(__RF_H__)
+#include "rf.h"
+#endif
+#if !defined(__DATARATE_H__)
+#include "datarate.h"
+#endif
+#if !defined(__USBPIPE_H__)
+#include "usbpipe.h"
+#endif
+
+#ifdef WPA_SM_Transtatus
+#if !defined(__IOCMD_H__)
+#include "iocmd.h"
+#endif
+#endif
+/*---------------------  Static Definitions -------------------------*/
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+static int          msglevel                =MSG_LEVEL_INFO;
+
+/*---------------------  Static Functions  --------------------------*/
+
+/*---------------------  Static Definitions -------------------------*/
+#define CRITICAL_PACKET_LEN      256    // if packet size < 256 -> in-direct send
+                                        //    packet size >= 256 -> direct send
+
+const WORD wTimeStampOff[2][MAX_RATE] = {
+        {384, 288, 226, 209, 54, 43, 37, 31, 28, 25, 24, 23}, // Long Preamble
+        {384, 192, 130, 113, 54, 43, 37, 31, 28, 25, 24, 23}, // Short Preamble
+    };
+
+const WORD wFB_Opt0[2][5] = {
+        {RATE_12M, RATE_18M, RATE_24M, RATE_36M, RATE_48M}, // fallback_rate0
+        {RATE_12M, RATE_12M, RATE_18M, RATE_24M, RATE_36M}, // fallback_rate1
+    };
+const WORD wFB_Opt1[2][5] = {
+        {RATE_12M, RATE_18M, RATE_24M, RATE_24M, RATE_36M}, // fallback_rate0
+        {RATE_6M , RATE_6M,  RATE_12M, RATE_12M, RATE_18M}, // fallback_rate1
+    };
+
+
+#define RTSDUR_BB       0
+#define RTSDUR_BA       1
+#define RTSDUR_AA       2
+#define CTSDUR_BA       3
+#define RTSDUR_BA_F0    4
+#define RTSDUR_AA_F0    5
+#define RTSDUR_BA_F1    6
+#define RTSDUR_AA_F1    7
+#define CTSDUR_BA_F0    8
+#define CTSDUR_BA_F1    9
+#define DATADUR_B       10
+#define DATADUR_A       11
+#define DATADUR_A_F0    12
+#define DATADUR_A_F1    13
+
+/*---------------------  Static Functions  --------------------------*/
+
+static
+VOID
+s_vSaveTxPktInfo(
+    IN PSDevice pDevice,
+    IN BYTE byPktNum,
+    IN PBYTE pbyDestAddr,
+    IN WORD wPktLength,
+    IN WORD wFIFOCtl
+);
+
+static
+PVOID
+s_vGetFreeContext(
+    PSDevice pDevice
+    );
+
+
+static
+VOID
+s_vGenerateTxParameter(
+    IN PSDevice         pDevice,
+    IN BYTE             byPktType,
+    IN WORD             wCurrentRate,
+    IN PVOID            pTxBufHead,
+    IN PVOID            pvRrvTime,
+    IN PVOID            pvRTS,
+    IN PVOID            pvCTS,
+    IN UINT             cbFrameSize,
+    IN BOOL             bNeedACK,
+    IN UINT             uDMAIdx,
+    IN PSEthernetHeader psEthHeader
+    );
+
+
+static
+UINT
+s_uFillDataHead (
+    IN PSDevice pDevice,
+    IN BYTE     byPktType,
+    IN WORD     wCurrentRate,
+    IN PVOID    pTxDataHead,
+    IN UINT     cbFrameLength,
+    IN UINT     uDMAIdx,
+    IN BOOL     bNeedAck,
+    IN UINT     uFragIdx,
+    IN UINT     cbLastFragmentSize,
+    IN UINT     uMACfragNum,
+    IN BYTE     byFBOption
+    );
+
+
+
+
+static
+VOID
+s_vGenerateMACHeader (
+    IN PSDevice         pDevice,
+    IN PBYTE            pbyBufferAddr,
+    IN WORD             wDuration,
+    IN PSEthernetHeader psEthHeader,
+    IN BOOL             bNeedEncrypt,
+    IN WORD             wFragType,
+    IN UINT             uDMAIdx,
+    IN UINT             uFragIdx
+    );
+
+static
+VOID
+s_vFillTxKey(
+    IN  PSDevice   pDevice,
+    IN  PBYTE      pbyBuf,
+    IN  PBYTE      pbyIVHead,
+    IN  PSKeyItem  pTransmitKey,
+    IN  PBYTE      pbyHdrBuf,
+    IN  WORD       wPayloadLen,
+    OUT PBYTE      pMICHDR
+    );
+
+static
+VOID
+s_vSWencryption (
+    IN  PSDevice         pDevice,
+    IN  PSKeyItem        pTransmitKey,
+    IN  PBYTE            pbyPayloadHead,
+    IN  WORD             wPayloadSize
+    );
+
+static
+UINT
+s_uGetTxRsvTime (
+    IN PSDevice pDevice,
+    IN BYTE     byPktType,
+    IN UINT     cbFrameLength,
+    IN WORD     wRate,
+    IN BOOL     bNeedAck
+    );
+
+
+static
+UINT
+s_uGetRTSCTSRsvTime (
+    IN PSDevice pDevice,
+    IN BYTE byRTSRsvType,
+    IN BYTE byPktType,
+    IN UINT cbFrameLength,
+    IN WORD wCurrentRate
+    );
+
+static
+VOID
+s_vFillCTSHead (
+    IN PSDevice pDevice,
+    IN UINT     uDMAIdx,
+    IN BYTE     byPktType,
+    IN PVOID    pvCTS,
+    IN UINT     cbFrameLength,
+    IN BOOL     bNeedAck,
+    IN BOOL     bDisCRC,
+    IN WORD     wCurrentRate,
+    IN BYTE     byFBOption
+    );
+
+static
+VOID
+s_vFillRTSHead(
+    IN PSDevice         pDevice,
+    IN BYTE             byPktType,
+    IN PVOID            pvRTS,
+    IN UINT             cbFrameLength,
+    IN BOOL             bNeedAck,
+    IN BOOL             bDisCRC,
+    IN PSEthernetHeader psEthHeader,
+    IN WORD             wCurrentRate,
+    IN BYTE             byFBOption
+    );
+
+static
+UINT
+s_uGetDataDuration (
+    IN PSDevice pDevice,
+    IN BYTE     byDurType,
+    IN UINT     cbFrameLength,
+    IN BYTE     byPktType,
+    IN WORD     wRate,
+    IN BOOL     bNeedAck,
+    IN UINT     uFragIdx,
+    IN UINT     cbLastFragmentSize,
+    IN UINT     uMACfragNum,
+    IN BYTE     byFBOption
+    );
+
+
+static
+UINT
+s_uGetRTSCTSDuration (
+    IN PSDevice pDevice,
+    IN BYTE byDurType,
+    IN UINT cbFrameLength,
+    IN BYTE byPktType,
+    IN WORD wRate,
+    IN BOOL bNeedAck,
+    IN BYTE byFBOption
+    );
+
+
+/*---------------------  Export Variables  --------------------------*/
+
+static
+PVOID
+s_vGetFreeContext(
+    PSDevice pDevice
+    )
+{
+    PUSB_SEND_CONTEXT   pContext = NULL;
+    PUSB_SEND_CONTEXT   pReturnContext = NULL;
+    UINT                ii;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"GetFreeContext()\n");
+
+    for (ii = 0; ii < pDevice->cbTD; ii++) {
+        pContext = pDevice->apTD[ii];
+        if (pContext->bBoolInUse == FALSE) {
+            pContext->bBoolInUse = TRUE;
+            pReturnContext = pContext;
+            break;
+        }
+    }
+    if ( ii == pDevice->cbTD ) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No Free Tx Context\n");
+    }
+    return ((PVOID) pReturnContext);
+}
+
+
+static
+VOID
+s_vSaveTxPktInfo(PSDevice pDevice, BYTE byPktNum, PBYTE pbyDestAddr, WORD wPktLength, WORD wFIFOCtl)
+{
+    PSStatCounter           pStatistic=&(pDevice->scStatistic);
+
+
+    if (IS_BROADCAST_ADDRESS(pbyDestAddr))
+        pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni = TX_PKT_BROAD;
+    else if (IS_MULTICAST_ADDRESS(pbyDestAddr))
+        pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni = TX_PKT_MULTI;
+    else
+        pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni = TX_PKT_UNI;
+
+    pStatistic->abyTxPktInfo[byPktNum].wLength = wPktLength;
+    pStatistic->abyTxPktInfo[byPktNum].wFIFOCtl = wFIFOCtl;
+    MEMvCopy(pStatistic->abyTxPktInfo[byPktNum].abyDestAddr, pbyDestAddr, U_ETHER_ADDR_LEN);
+}
+
+
+
+
+static
+VOID
+s_vFillTxKey (
+    IN  PSDevice   pDevice,
+    IN  PBYTE      pbyBuf,
+    IN  PBYTE      pbyIVHead,
+    IN  PSKeyItem  pTransmitKey,
+    IN  PBYTE      pbyHdrBuf,
+    IN  WORD       wPayloadLen,
+    OUT PBYTE      pMICHDR
+    )
+{
+    PDWORD          pdwIV = (PDWORD) pbyIVHead;
+    PDWORD          pdwExtIV = (PDWORD) ((PBYTE)pbyIVHead+4);
+    WORD            wValue;
+    PS802_11Header  pMACHeader = (PS802_11Header)pbyHdrBuf;
+    DWORD           dwRevIVCounter;
+
+
+
+    //Fill TXKEY
+    if (pTransmitKey == NULL)
+        return;
+
+    dwRevIVCounter = cpu_to_le32(pDevice->dwIVCounter);
+    *pdwIV = pDevice->dwIVCounter;
+    pDevice->byKeyIndex = pTransmitKey->dwKeyIndex & 0xf;
+
+    if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) {
+        if (pTransmitKey->uKeyLength == WLAN_WEP232_KEYLEN ){
+            MEMvCopy(pDevice->abyPRNG, (PBYTE)&(dwRevIVCounter), 3);
+            MEMvCopy(pDevice->abyPRNG+3, pTransmitKey->abyKey, pTransmitKey->uKeyLength);
+        } else {
+            MEMvCopy(pbyBuf, (PBYTE)&(dwRevIVCounter), 3);
+            MEMvCopy(pbyBuf+3, pTransmitKey->abyKey, pTransmitKey->uKeyLength);
+            if(pTransmitKey->uKeyLength == WLAN_WEP40_KEYLEN) {
+                MEMvCopy(pbyBuf+8, (PBYTE)&(dwRevIVCounter), 3);
+                MEMvCopy(pbyBuf+11, pTransmitKey->abyKey, pTransmitKey->uKeyLength);
+            }
+            MEMvCopy(pDevice->abyPRNG, pbyBuf, 16);
+        }
+        // Append IV after Mac Header
+        *pdwIV &= WEP_IV_MASK;//00000000 11111111 11111111 11111111
+        *pdwIV |= (pDevice->byKeyIndex << 30);
+        *pdwIV = cpu_to_le32(*pdwIV);
+        pDevice->dwIVCounter++;
+        if (pDevice->dwIVCounter > WEP_IV_MASK) {
+            pDevice->dwIVCounter = 0;
+        }
+    } else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
+        pTransmitKey->wTSC15_0++;
+        if (pTransmitKey->wTSC15_0 == 0) {
+            pTransmitKey->dwTSC47_16++;
+        }
+        TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr,
+                    pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, pDevice->abyPRNG);
+        MEMvCopy(pbyBuf, pDevice->abyPRNG, 16);
+        // Make IV
+        MEMvCopy(pdwIV, pDevice->abyPRNG, 3);
+
+        *(pbyIVHead+3) = (BYTE)(((pDevice->byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV
+        // Append IV&ExtIV after Mac Header
+        *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vFillTxKey()---- pdwExtIV: %lx\n", *pdwExtIV);
+
+    } else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) {
+        pTransmitKey->wTSC15_0++;
+        if (pTransmitKey->wTSC15_0 == 0) {
+            pTransmitKey->dwTSC47_16++;
+        }
+        MEMvCopy(pbyBuf, pTransmitKey->abyKey, 16);
+
+        // Make IV
+        *pdwIV = 0;
+        *(pbyIVHead+3) = (BYTE)(((pDevice->byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV
+        *pdwIV |= cpu_to_le16((WORD)(pTransmitKey->wTSC15_0));
+        //Append IV&ExtIV after Mac Header
+        *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16);
+
+        //Fill MICHDR0
+        *pMICHDR = 0x59;
+        *((PBYTE)(pMICHDR+1)) = 0; // TxPriority
+        MEMvCopy(pMICHDR+2, &(pMACHeader->abyAddr2[0]), 6);
+        *((PBYTE)(pMICHDR+8)) = HIBYTE(HIWORD(pTransmitKey->dwTSC47_16));
+        *((PBYTE)(pMICHDR+9)) = LOBYTE(HIWORD(pTransmitKey->dwTSC47_16));
+        *((PBYTE)(pMICHDR+10)) = HIBYTE(LOWORD(pTransmitKey->dwTSC47_16));
+        *((PBYTE)(pMICHDR+11)) = LOBYTE(LOWORD(pTransmitKey->dwTSC47_16));
+        *((PBYTE)(pMICHDR+12)) = HIBYTE(pTransmitKey->wTSC15_0);
+        *((PBYTE)(pMICHDR+13)) = LOBYTE(pTransmitKey->wTSC15_0);
+        *((PBYTE)(pMICHDR+14)) = HIBYTE(wPayloadLen);
+        *((PBYTE)(pMICHDR+15)) = LOBYTE(wPayloadLen);
+
+        //Fill MICHDR1
+        *((PBYTE)(pMICHDR+16)) = 0; // HLEN[15:8]
+        if (pDevice->bLongHeader) {
+            *((PBYTE)(pMICHDR+17)) = 28; // HLEN[7:0]
+        } else {
+            *((PBYTE)(pMICHDR+17)) = 22; // HLEN[7:0]
+        }
+        wValue = cpu_to_le16(pMACHeader->wFrameCtl & 0xC78F);
+        MEMvCopy(pMICHDR+18, (PBYTE)&wValue, 2); // MSKFRACTL
+        MEMvCopy(pMICHDR+20, &(pMACHeader->abyAddr1[0]), 6);
+        MEMvCopy(pMICHDR+26, &(pMACHeader->abyAddr2[0]), 6);
+
+        //Fill MICHDR2
+        MEMvCopy(pMICHDR+32, &(pMACHeader->abyAddr3[0]), 6);
+        wValue = pMACHeader->wSeqCtl;
+        wValue &= 0x000F;
+        wValue = cpu_to_le16(wValue);
+        MEMvCopy(pMICHDR+38, (PBYTE)&wValue, 2); // MSKSEQCTL
+        if (pDevice->bLongHeader) {
+            MEMvCopy(pMICHDR+40, &(pMACHeader->abyAddr4[0]), 6);
+        }
+    }
+}
+
+
+static
+VOID
+s_vSWencryption (
+    IN  PSDevice            pDevice,
+    IN  PSKeyItem           pTransmitKey,
+    IN  PBYTE               pbyPayloadHead,
+    IN  WORD                wPayloadSize
+    )
+{
+    UINT   cbICVlen = 4;
+    DWORD  dwICV = 0xFFFFFFFFL;
+    PDWORD pdwICV;
+
+    if (pTransmitKey == NULL)
+        return;
+
+    if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) {
+        //=======================================================================
+        // Append ICV after payload
+        dwICV = CRCdwGetCrc32Ex(pbyPayloadHead, wPayloadSize, dwICV);//ICV(Payload)
+        pdwICV = (PDWORD)(pbyPayloadHead + wPayloadSize);
+        // finally, we must invert dwCRC to get the correct answer
+        *pdwICV = cpu_to_le32(~dwICV);
+        // RC4 encryption
+        rc4_init(&pDevice->SBox, pDevice->abyPRNG, pTransmitKey->uKeyLength + 3);
+        rc4_encrypt(&pDevice->SBox, pbyPayloadHead, pbyPayloadHead, wPayloadSize+cbICVlen);
+        //=======================================================================
+    } else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
+        //=======================================================================
+        //Append ICV after payload
+        dwICV = CRCdwGetCrc32Ex(pbyPayloadHead, wPayloadSize, dwICV);//ICV(Payload)
+        pdwICV = (PDWORD)(pbyPayloadHead + wPayloadSize);
+        // finally, we must invert dwCRC to get the correct answer
+        *pdwICV = cpu_to_le32(~dwICV);
+        // RC4 encryption
+        rc4_init(&pDevice->SBox, pDevice->abyPRNG, TKIP_KEY_LEN);
+        rc4_encrypt(&pDevice->SBox, pbyPayloadHead, pbyPayloadHead, wPayloadSize+cbICVlen);
+        //=======================================================================
+    }
+}
+
+
+
+
+/*byPktType : PK_TYPE_11A     0
+             PK_TYPE_11B     1
+             PK_TYPE_11GB    2
+             PK_TYPE_11GA    3
+*/
+static
+UINT
+s_uGetTxRsvTime (
+    IN PSDevice pDevice,
+    IN BYTE     byPktType,
+    IN UINT     cbFrameLength,
+    IN WORD     wRate,
+    IN BOOL     bNeedAck
+    )
+{
+    UINT uDataTime, uAckTime;
+
+    uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wRate);
+    if (byPktType == PK_TYPE_11B) {//llb,CCK mode
+        uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (WORD)pDevice->byTopCCKBasicRate);
+    } else {//11g 2.4G OFDM mode & 11a 5G OFDM mode
+        uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (WORD)pDevice->byTopOFDMBasicRate);
+    }
+
+    if (bNeedAck) {
+        return (uDataTime + pDevice->uSIFS + uAckTime);
+    }
+    else {
+        return uDataTime;
+    }
+}
+
+//byFreqType: 0=>5GHZ 1=>2.4GHZ
+static
+UINT
+s_uGetRTSCTSRsvTime (
+    IN PSDevice pDevice,
+    IN BYTE byRTSRsvType,
+    IN BYTE byPktType,
+    IN UINT cbFrameLength,
+    IN WORD wCurrentRate
+    )
+{
+    UINT uRrvTime  , uRTSTime, uCTSTime, uAckTime, uDataTime;
+
+    uRrvTime = uRTSTime = uCTSTime = uAckTime = uDataTime = 0;
+
+
+    uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wCurrentRate);
+    if (byRTSRsvType == 0) { //RTSTxRrvTime_bb
+        uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
+        uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
+    }
+    else if (byRTSRsvType == 1){ //RTSTxRrvTime_ba, only in 2.4GHZ
+        uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
+        uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
+        uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
+    }
+    else if (byRTSRsvType == 2) { //RTSTxRrvTime_aa
+        uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopOFDMBasicRate);
+        uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
+    }
+    else if (byRTSRsvType == 3) { //CTSTxRrvTime_ba, only in 2.4GHZ
+        uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
+        uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
+        uRrvTime = uCTSTime + uAckTime + uDataTime + 2*pDevice->uSIFS;
+        return uRrvTime;
+    }
+
+    //RTSRrvTime
+    uRrvTime = uRTSTime + uCTSTime + uAckTime + uDataTime + 3*pDevice->uSIFS;
+    return uRrvTime;
+}
+
+//byFreqType 0: 5GHz, 1:2.4Ghz
+static
+UINT
+s_uGetDataDuration (
+    IN PSDevice pDevice,
+    IN BYTE     byDurType,
+    IN UINT     cbFrameLength,
+    IN BYTE     byPktType,
+    IN WORD     wRate,
+    IN BOOL     bNeedAck,
+    IN UINT     uFragIdx,
+    IN UINT     cbLastFragmentSize,
+    IN UINT     uMACfragNum,
+    IN BYTE     byFBOption
+    )
+{
+    BOOL bLastFrag = 0;
+    UINT uAckTime =0, uNextPktTime = 0;
+
+
+    if (uFragIdx == (uMACfragNum-1)) {
+        bLastFrag = 1;
+    }
+
+    switch (byDurType) {
+
+    case DATADUR_B:    //DATADUR_B
+        if (((uMACfragNum == 1)) || (bLastFrag == 1)) {//Non Frag or Last Frag
+            if (bNeedAck) {
+            	uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
+                return (pDevice->uSIFS + uAckTime);
+            } else {
+                return 0;
+            }
+        }
+        else {//First Frag or Mid Frag
+            if (uFragIdx == (uMACfragNum-2)) {
+            	uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck);
+            } else {
+                uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
+            }
+            if (bNeedAck) {
+            	uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
+                return (pDevice->uSIFS + uAckTime + uNextPktTime);
+            } else {
+                return (pDevice->uSIFS + uNextPktTime);
+            }
+        }
+        break;
+
+
+    case DATADUR_A:    //DATADUR_A
+        if (((uMACfragNum==1)) || (bLastFrag==1)) {//Non Frag or Last Frag
+            if(bNeedAck){
+            	uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
+                return (pDevice->uSIFS + uAckTime);
+            } else {
+                return 0;
+            }
+        }
+        else {//First Frag or Mid Frag
+            if(uFragIdx == (uMACfragNum-2)){
+            	uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck);
+            } else {
+                uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
+            }
+            if(bNeedAck){
+            	uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
+                return (pDevice->uSIFS + uAckTime + uNextPktTime);
+            } else {
+                return (pDevice->uSIFS + uNextPktTime);
+            }
+        }
+        break;
+
+    case DATADUR_A_F0:    //DATADUR_A_F0
+	    if (((uMACfragNum==1)) || (bLastFrag==1)) {//Non Frag or Last Frag
+            if(bNeedAck){
+            	uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
+                return (pDevice->uSIFS + uAckTime);
+            } else {
+                return 0;
+            }
+        }
+	    else { //First Frag or Mid Frag
+	        if (byFBOption == AUTO_FB_0) {
+                if (wRate < RATE_18M)
+                    wRate = RATE_18M;
+                else if (wRate > RATE_54M)
+                    wRate = RATE_54M;
+
+	            if(uFragIdx == (uMACfragNum-2)){
+            	    uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
+                } else {
+                    uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
+                }
+	        } else { // (byFBOption == AUTO_FB_1)
+                if (wRate < RATE_18M)
+                    wRate = RATE_18M;
+                else if (wRate > RATE_54M)
+                    wRate = RATE_54M;
+
+	            if(uFragIdx == (uMACfragNum-2)){
+            	    uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
+                } else {
+                    uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
+                }
+	        }
+
+	        if(bNeedAck){
+            	uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
+                return (pDevice->uSIFS + uAckTime + uNextPktTime);
+            } else {
+                return (pDevice->uSIFS + uNextPktTime);
+            }
+	    }
+        break;
+
+    case DATADUR_A_F1:    //DATADUR_A_F1
+        if (((uMACfragNum==1)) || (bLastFrag==1)) {//Non Frag or Last Frag
+            if(bNeedAck){
+            	uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
+                return (pDevice->uSIFS + uAckTime);
+            } else {
+                return 0;
+            }
+        }
+	    else { //First Frag or Mid Frag
+	        if (byFBOption == AUTO_FB_0) {
+                if (wRate < RATE_18M)
+                    wRate = RATE_18M;
+                else if (wRate > RATE_54M)
+                    wRate = RATE_54M;
+
+	            if(uFragIdx == (uMACfragNum-2)){
+            	    uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
+                } else {
+                    uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
+                }
+
+	        } else { // (byFBOption == AUTO_FB_1)
+                if (wRate < RATE_18M)
+                    wRate = RATE_18M;
+                else if (wRate > RATE_54M)
+                    wRate = RATE_54M;
+
+	            if(uFragIdx == (uMACfragNum-2)){
+            	    uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
+                } else {
+                    uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
+                }
+	        }
+	        if(bNeedAck){
+            	uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
+                return (pDevice->uSIFS + uAckTime + uNextPktTime);
+            } else {
+                return (pDevice->uSIFS + uNextPktTime);
+            }
+	    }
+        break;
+
+    default:
+        break;
+    }
+
+	ASSERT(FALSE);
+	return 0;
+}
+
+
+//byFreqType: 0=>5GHZ 1=>2.4GHZ
+static
+UINT
+s_uGetRTSCTSDuration (
+    IN PSDevice pDevice,
+    IN BYTE byDurType,
+    IN UINT cbFrameLength,
+    IN BYTE byPktType,
+    IN WORD wRate,
+    IN BOOL bNeedAck,
+    IN BYTE byFBOption
+    )
+{
+    UINT uCTSTime = 0, uDurTime = 0;
+
+
+    switch (byDurType) {
+
+    case RTSDUR_BB:    //RTSDuration_bb
+        uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
+        uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
+        break;
+
+    case RTSDUR_BA:    //RTSDuration_ba
+        uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
+        uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
+        break;
+
+    case RTSDUR_AA:    //RTSDuration_aa
+        uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
+        uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
+        break;
+
+    case CTSDUR_BA:    //CTSDuration_ba
+        uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
+        break;
+
+    case RTSDUR_BA_F0: //RTSDuration_ba_f0
+        uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
+        if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
+            uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
+        } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
+            uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
+        }
+        break;
+
+    case RTSDUR_AA_F0: //RTSDuration_aa_f0
+        uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
+        if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
+            uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
+        } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
+            uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
+        }
+        break;
+
+    case RTSDUR_BA_F1: //RTSDuration_ba_f1
+        uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
+        if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
+            uDurT