Staging: Add pristine upstream vt6655 driver sources
authorForest Bond <forest@alittletooquiet.net>
Sat, 25 Apr 2009 14:30:44 +0000 (10:30 -0400)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 19 Jun 2009 18:00:51 +0000 (11:00 -0700)
Add pristine upstream vt6655 driver sources to drivers/staging/vt6655.  These
files were literally copied from the driver directory in the upstream source
archive, available here:

  http://www.viaarena.com/Driver/vt6655_linux_src_v1.19.12_x86.zip

Signed-off-by: Forest Bond <forest@alittletooquiet.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
78 files changed:
drivers/staging/vt6655/80211hdr.h [new file with mode: 0644]
drivers/staging/vt6655/80211mgr.c [new file with mode: 0644]
drivers/staging/vt6655/80211mgr.h [new file with mode: 0644]
drivers/staging/vt6655/IEEE11h.c [new file with mode: 0644]
drivers/staging/vt6655/IEEE11h.h [new file with mode: 0644]
drivers/staging/vt6655/Makefile [new file with mode: 0644]
drivers/staging/vt6655/Makefile.arm [new file with mode: 0644]
drivers/staging/vt6655/Makefile.x86 [new file with mode: 0644]
drivers/staging/vt6655/aes_ccmp.c [new file with mode: 0644]
drivers/staging/vt6655/aes_ccmp.h [new file with mode: 0644]
drivers/staging/vt6655/baseband.c [new file with mode: 0644]
drivers/staging/vt6655/baseband.h [new file with mode: 0644]
drivers/staging/vt6655/bssdb.c [new file with mode: 0644]
drivers/staging/vt6655/bssdb.h [new file with mode: 0644]
drivers/staging/vt6655/card.c [new file with mode: 0644]
drivers/staging/vt6655/card.h [new file with mode: 0644]
drivers/staging/vt6655/country.h [new file with mode: 0644]
drivers/staging/vt6655/datarate.c [new file with mode: 0644]
drivers/staging/vt6655/datarate.h [new file with mode: 0644]
drivers/staging/vt6655/desc.h [new file with mode: 0644]
drivers/staging/vt6655/device.h [new file with mode: 0644]
drivers/staging/vt6655/device_main.c [new file with mode: 0644]
drivers/staging/vt6655/dpc.c [new file with mode: 0644]
drivers/staging/vt6655/dpc.h [new file with mode: 0644]
drivers/staging/vt6655/hostap.c [new file with mode: 0644]
drivers/staging/vt6655/hostap.h [new file with mode: 0644]
drivers/staging/vt6655/ioctl.c [new file with mode: 0644]
drivers/staging/vt6655/ioctl.h [new file with mode: 0644]
drivers/staging/vt6655/iwctl.c [new file with mode: 0644]
drivers/staging/vt6655/iwctl.h [new file with mode: 0644]
drivers/staging/vt6655/kcompat.h [new file with mode: 0644]
drivers/staging/vt6655/key.c [new file with mode: 0644]
drivers/staging/vt6655/key.h [new file with mode: 0644]
drivers/staging/vt6655/mac.c [new file with mode: 0644]
drivers/staging/vt6655/mac.h [new file with mode: 0644]
drivers/staging/vt6655/mib.c [new file with mode: 0644]
drivers/staging/vt6655/mib.h [new file with mode: 0644]
drivers/staging/vt6655/michael.c [new file with mode: 0644]
drivers/staging/vt6655/michael.h [new file with mode: 0644]
drivers/staging/vt6655/power.c [new file with mode: 0644]
drivers/staging/vt6655/power.h [new file with mode: 0644]
drivers/staging/vt6655/rc4.c [new file with mode: 0644]
drivers/staging/vt6655/rc4.h [new file with mode: 0644]
drivers/staging/vt6655/rf.c [new file with mode: 0644]
drivers/staging/vt6655/rf.h [new file with mode: 0644]
drivers/staging/vt6655/rxtx.c [new file with mode: 0644]
drivers/staging/vt6655/rxtx.h [new file with mode: 0644]
drivers/staging/vt6655/srom.c [new file with mode: 0644]
drivers/staging/vt6655/srom.h [new file with mode: 0644]
drivers/staging/vt6655/tbit.h [new file with mode: 0644]
drivers/staging/vt6655/tcrc.c [new file with mode: 0644]
drivers/staging/vt6655/tcrc.h [new file with mode: 0644]
drivers/staging/vt6655/test [new file with mode: 0644]
drivers/staging/vt6655/tether.c [new file with mode: 0644]
drivers/staging/vt6655/tether.h [new file with mode: 0644]
drivers/staging/vt6655/tkip.c [new file with mode: 0644]
drivers/staging/vt6655/tkip.h [new file with mode: 0644]
drivers/staging/vt6655/tmacro.h [new file with mode: 0644]
drivers/staging/vt6655/tpci.h [new file with mode: 0644]
drivers/staging/vt6655/umem.h [new file with mode: 0644]
drivers/staging/vt6655/upc.h [new file with mode: 0644]
drivers/staging/vt6655/vntconfiguration.dat [new file with mode: 0644]
drivers/staging/vt6655/vntwifi.c [new file with mode: 0644]
drivers/staging/vt6655/vntwifi.h [new file with mode: 0644]
drivers/staging/vt6655/wcmd.c [new file with mode: 0644]
drivers/staging/vt6655/wcmd.h [new file with mode: 0644]
drivers/staging/vt6655/wctl.c [new file with mode: 0644]
drivers/staging/vt6655/wctl.h [new file with mode: 0644]
drivers/staging/vt6655/wmgr.c [new file with mode: 0644]
drivers/staging/vt6655/wmgr.h [new file with mode: 0644]
drivers/staging/vt6655/wpa.c [new file with mode: 0644]
drivers/staging/vt6655/wpa.h [new file with mode: 0644]
drivers/staging/vt6655/wpa2.c [new file with mode: 0644]
drivers/staging/vt6655/wpa2.h [new file with mode: 0644]
drivers/staging/vt6655/wpactl.c [new file with mode: 0644]
drivers/staging/vt6655/wpactl.h [new file with mode: 0644]
drivers/staging/vt6655/wroute.c [new file with mode: 0644]
drivers/staging/vt6655/wroute.h [new file with mode: 0644]

diff --git a/drivers/staging/vt6655/80211hdr.h b/drivers/staging/vt6655/80211hdr.h
new file mode 100644 (file)
index 0000000..b4bbb8d
--- /dev/null
@@ -0,0 +1,357 @@
+/*
+ * 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: Defines the macros, types, and functions for dealing
+ *          with 802.11 MAC headers.
+ *
+ * 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/vt6655/80211mgr.c b/drivers/staging/vt6655/80211mgr.c
new file mode 100644 (file)
index 0000000..84745fb
--- /dev/null
@@ -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 802.11 managment support 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:
+                DEVICE_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:
+                DEVICE_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;
+        DEVICE_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:
+                DEVICE_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:
+                DEVICE_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) ) {
+               /*
+        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:
+                DEVICE_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/vt6655/80211mgr.h b/drivers/staging/vt6655/80211mgr.h
new file mode 100644 (file)
index 0000000..dc54a65
--- /dev/null
@@ -0,0 +1,832 @@
+/*
+ * 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: Defines the macros, types, and functions for dealing
+ *          with 802.11 managment frames.
+ *
+ * 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
+
+
+#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;
+
+
+// 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_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_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/vt6655/IEEE11h.c b/drivers/staging/vt6655/IEEE11h.c
new file mode 100644 (file)
index 0000000..5f25b8e
--- /dev/null
@@ -0,0 +1,324 @@
+/*
+ * Copyright (c) 1996, 2005 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: IEEE11h.c
+ *
+ * Purpose:
+ *
+ * Functions:
+ *
+ * Revision History:
+ *
+ * Author: Yiching Chen
+ *
+ * Date: Mar. 31, 2005
+ *
+ */
+
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+#if !defined(__UMEM_H__)
+#include "umem.h"
+#endif
+#if !defined(__TMACRO_H__)
+#include "tmacro.h"
+#endif
+#if !defined(__TETHER_H__)
+#include "tether.h"
+#endif
+#if !defined(__IEEE11h_H__)
+#include "IEEE11h.h"
+#endif
+
+#if !defined(__DEVICE_H__)
+#include "device.h"
+#endif
+#if !defined(__WMGR_H__)
+#include "wmgr.h"
+#endif
+#if !defined(__RXTX_H__)
+#include "rxtx.h"
+#endif
+
+
+
+/*---------------------  Static Definitions -------------------------*/
+static int          msglevel                =MSG_LEVEL_INFO;
+
+#pragma pack(1)
+
+typedef struct _WLAN_FRAME_ACTION {
+    WLAN_80211HDR_A3    Header;
+    BYTE                byCategory;
+    BYTE                byAction;
+    BYTE                abyVars[1];
+} WLAN_FRAME_ACTION, *PWLAN_FRAME_ACTION;
+
+typedef struct _WLAN_FRAME_MSRREQ {
+    WLAN_80211HDR_A3    Header;
+    BYTE                byCategory;
+    BYTE                byAction;
+    BYTE                byDialogToken;
+    WLAN_IE_MEASURE_REQ sMSRReqEIDs[1];
+} WLAN_FRAME_MSRREQ, *PWLAN_FRAME_MSRREQ;
+
+typedef struct _WLAN_FRAME_MSRREP {
+    WLAN_80211HDR_A3    Header;
+    BYTE                byCategory;
+    BYTE                byAction;
+    BYTE                byDialogToken;
+    WLAN_IE_MEASURE_REP sMSRRepEIDs[1];
+} WLAN_FRAME_MSRREP, *PWLAN_FRAME_MSRREP;
+
+typedef struct _WLAN_FRAME_TPCREQ {
+    WLAN_80211HDR_A3    Header;
+    BYTE                byCategory;
+    BYTE                byAction;
+    BYTE                byDialogToken;
+    WLAN_IE_TPC_REQ     sTPCReqEIDs;
+} WLAN_FRAME_TPCREQ, *PWLAN_FRAME_TPCREQ;
+
+typedef struct _WLAN_FRAME_TPCREP {
+    WLAN_80211HDR_A3    Header;
+    BYTE                byCategory;
+    BYTE                byAction;
+    BYTE                byDialogToken;
+    WLAN_IE_TPC_REP     sTPCRepEIDs;
+} WLAN_FRAME_TPCREP, *PWLAN_FRAME_TPCREP;
+
+#pragma pack()
+
+// action field reference ieee 802.11h Table 20e
+#define ACTION_MSRREQ       0
+#define ACTION_MSRREP       1
+#define ACTION_TPCREQ       2
+#define ACTION_TPCREP       3
+#define ACTION_CHSW         4
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+
+/*---------------------  Static Functions  --------------------------*/
+static BOOL s_bRxMSRReq(PSMgmtObject pMgmt, PWLAN_FRAME_MSRREQ pMSRReq, UINT uLength)
+{
+    UINT    uNumOfEIDs = 0;
+    BOOL    bResult = TRUE;
+
+    if (uLength <= WLAN_A3FR_MAXLEN) {
+        MEMvCopy(pMgmt->abyCurrentMSRReq, pMSRReq, uLength);
+    }
+    uNumOfEIDs = ((uLength - OFFSET(WLAN_FRAME_MSRREQ, sMSRReqEIDs))/ (sizeof(WLAN_IE_MEASURE_REQ)));
+    pMgmt->pCurrMeasureEIDRep = &(((PWLAN_FRAME_MSRREP) (pMgmt->abyCurrentMSRRep))->sMSRRepEIDs[0]);
+    pMgmt->uLengthOfRepEIDs = 0;
+    bResult = CARDbStartMeasure(pMgmt->pAdapter,
+                                ((PWLAN_FRAME_MSRREQ) (pMgmt->abyCurrentMSRReq))->sMSRReqEIDs,
+                                uNumOfEIDs
+                                );
+    return (bResult);
+}
+
+
+static BOOL s_bRxTPCReq(PSMgmtObject pMgmt, PWLAN_FRAME_TPCREQ pTPCReq, BYTE byRate, BYTE byRSSI)
+{
+    PWLAN_FRAME_TPCREP  pFrame;
+    PSTxMgmtPacket      pTxPacket = NULL;
+
+
+    pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
+    memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN);
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+
+    pFrame = (PWLAN_FRAME_TPCREP)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+
+    pFrame->Header.wFrameCtl = (   WLAN_SET_FC_FTYPE(WLAN_FTYPE_MGMT) |
+                                    WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ACTION)
+                                );
+
+    MEMvCopy( pFrame->Header.abyAddr1, pTPCReq->Header.abyAddr2, WLAN_ADDR_LEN);
+    MEMvCopy( pFrame->Header.abyAddr2, CARDpGetCurrentAddress(pMgmt->pAdapter), WLAN_ADDR_LEN);
+    MEMvCopy( pFrame->Header.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
+
+    pFrame->byCategory = 0;
+    pFrame->byAction = 3;
+    pFrame->byDialogToken = ((PWLAN_FRAME_MSRREQ) (pMgmt->abyCurrentMSRReq))->byDialogToken;
+
+    pFrame->sTPCRepEIDs.byElementID = WLAN_EID_TPC_REP;
+    pFrame->sTPCRepEIDs.len = 2;
+    pFrame->sTPCRepEIDs.byTxPower = CARDbyGetTransmitPower(pMgmt->pAdapter);
+    switch (byRate) {
+        case RATE_54M:
+            pFrame->sTPCRepEIDs.byLinkMargin = 65 - byRSSI;
+            break;
+        case RATE_48M:
+            pFrame->sTPCRepEIDs.byLinkMargin = 66 - byRSSI;
+            break;
+        case RATE_36M:
+            pFrame->sTPCRepEIDs.byLinkMargin = 70 - byRSSI;
+            break;
+        case RATE_24M:
+            pFrame->sTPCRepEIDs.byLinkMargin = 74 - byRSSI;
+            break;
+        case RATE_18M:
+            pFrame->sTPCRepEIDs.byLinkMargin = 77 - byRSSI;
+            break;
+        case RATE_12M:
+            pFrame->sTPCRepEIDs.byLinkMargin = 79 - byRSSI;
+            break;
+        case RATE_9M:
+            pFrame->sTPCRepEIDs.byLinkMargin = 81 - byRSSI;
+            break;
+        case RATE_6M:
+        default:
+            pFrame->sTPCRepEIDs.byLinkMargin = 82 - byRSSI;
+            break;
+    }
+
+    pTxPacket->cbMPDULen = sizeof(WLAN_FRAME_TPCREP);
+    pTxPacket->cbPayloadLen = sizeof(WLAN_FRAME_TPCREP) - WLAN_HDR_ADDR3_LEN;
+    if (csMgmt_xmit(pMgmt->pAdapter, pTxPacket) != CMD_STATUS_PENDING)
+        return (FALSE);
+    return (TRUE);
+//    return (CARDbSendPacket(pMgmt->pAdapter, pFrame, PKT_TYPE_802_11_MNG, sizeof(WLAN_FRAME_TPCREP)));
+
+}
+
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+/*+
+ *
+ * Description:
+ *      Handles action management frames.
+ *
+ * Parameters:
+ *  In:
+ *      pMgmt           - Management Object structure
+ *      pRxPacket       - Received packet
+ *  Out:
+ *      none
+ *
+ * Return Value: None.
+ *
+-*/
+BOOL
+IEEE11hbMgrRxAction (
+    IN PVOID pMgmtHandle,
+    IN PVOID pRxPacket
+    )
+{
+    PSMgmtObject            pMgmt = (PSMgmtObject) pMgmtHandle;
+    PWLAN_FRAME_ACTION      pAction = NULL;
+    UINT                    uLength = 0;
+    PWLAN_IE_CH_SW          pChannelSwitch = NULL;
+
+
+    // decode the frame
+    uLength = ((PSRxMgmtPacket)pRxPacket)->cbMPDULen;
+    if (uLength > WLAN_A3FR_MAXLEN) {
+        return (FALSE);
+    }
+
+
+    pAction = (PWLAN_FRAME_ACTION) (((PSRxMgmtPacket)pRxPacket)->p80211Header);
+
+    if (pAction->byCategory == 0) {
+        switch (pAction->byAction) {
+            case ACTION_MSRREQ:
+                return (s_bRxMSRReq(pMgmt, (PWLAN_FRAME_MSRREQ) pAction, uLength));
+                break;
+            case ACTION_MSRREP:
+                break;
+            case ACTION_TPCREQ:
+                return (s_bRxTPCReq(pMgmt,
+                                    (PWLAN_FRAME_TPCREQ) pAction,
+                                    ((PSRxMgmtPacket)pRxPacket)->byRxRate,
+                                    (BYTE) ((PSRxMgmtPacket)pRxPacket)->uRSSI));
+                break;
+            case ACTION_TPCREP:
+                break;
+            case ACTION_CHSW:
+                pChannelSwitch = (PWLAN_IE_CH_SW) (pAction->abyVars);
+                if ((pChannelSwitch->byElementID == WLAN_EID_CH_SWITCH) &&
+                    (pChannelSwitch->len == 3)) {
+                    // valid element id
+                    CARDbChannelSwitch( pMgmt->pAdapter,
+                                        pChannelSwitch->byMode,
+                                        CARDbyGetChannelMapping(pMgmt->pAdapter, pChannelSwitch->byChannel, pMgmt->eCurrentPHYMode),
+                                        pChannelSwitch->byCount
+                                        );
+                }
+                break;
+            default:
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Unknown Action = %d\n", pAction->byAction);
+                break;
+        }
+    } else {
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Unknown Category = %d\n", pAction->byCategory);
+        pAction->byCategory |= 0x80;
+
+       //return (CARDbSendPacket(pMgmt->pAdapter, pAction, PKT_TYPE_802_11_MNG, uLength));
+        return (TRUE);
+    }
+    return (TRUE);
+}
+
+
+BOOL IEEE11hbMSRRepTx (
+    IN PVOID pMgmtHandle
+    )
+{
+    PSMgmtObject            pMgmt = (PSMgmtObject) pMgmtHandle;
+    PWLAN_FRAME_MSRREP      pMSRRep = (PWLAN_FRAME_MSRREP) (pMgmt->abyCurrentMSRRep + sizeof(STxMgmtPacket));
+    UINT                    uLength = 0;
+    PSTxMgmtPacket          pTxPacket = NULL;
+
+    pTxPacket = (PSTxMgmtPacket)pMgmt->abyCurrentMSRRep;
+    memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN);
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+
+
+    pMSRRep->Header.wFrameCtl = (   WLAN_SET_FC_FTYPE(WLAN_FTYPE_MGMT) |
+                                    WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ACTION)
+                                );
+
+    MEMvCopy( pMSRRep->Header.abyAddr1, ((PWLAN_FRAME_MSRREQ) (pMgmt->abyCurrentMSRReq))->Header.abyAddr2, WLAN_ADDR_LEN);
+    MEMvCopy( pMSRRep->Header.abyAddr2, CARDpGetCurrentAddress(pMgmt->pAdapter), WLAN_ADDR_LEN);
+    MEMvCopy( pMSRRep->Header.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
+
+    pMSRRep->byCategory = 0;
+    pMSRRep->byAction = 1;
+    pMSRRep->byDialogToken = ((PWLAN_FRAME_MSRREQ) (pMgmt->abyCurrentMSRReq))->byDialogToken;
+
+    uLength = pMgmt->uLengthOfRepEIDs + OFFSET(WLAN_FRAME_MSRREP, sMSRRepEIDs);
+
+    pTxPacket->cbMPDULen = uLength;
+    pTxPacket->cbPayloadLen = uLength - WLAN_HDR_ADDR3_LEN;
+    if (csMgmt_xmit(pMgmt->pAdapter, pTxPacket) != CMD_STATUS_PENDING)
+        return (FALSE);
+    return (TRUE);
+//    return (CARDbSendPacket(pMgmt->pAdapter, pMSRRep, PKT_TYPE_802_11_MNG, uLength));
+
+}
+
diff --git a/drivers/staging/vt6655/IEEE11h.h b/drivers/staging/vt6655/IEEE11h.h
new file mode 100644 (file)
index 0000000..22bcaf1
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 1996, 2005 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: IEEE11h.h
+ *
+ * Purpose: Defines the macros, types, and functions for dealing
+ *          with IEEE 802.11h.
+ *
+ * Author: Yiching Chen
+ *
+ * Date: Mar. 31, 2005
+ *
+ */
+
+#ifndef __IEEE11h_H__
+#define __IEEE11h_H__
+
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+#if !defined(__80211HDR_H__)
+#include "80211hdr.h"
+#endif
+#if !defined(__80211MGR_H__)
+#include "80211mgr.h"
+#endif
+
+
+/*---------------------  Export Definitions -------------------------*/
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Types  ------------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+#ifdef __cplusplus
+extern "C" {                            /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+BOOL IEEE11hbMSRRepTx (
+    IN PVOID pMgmtHandle
+    );
+
+#ifdef __cplusplus
+}                                       /* End of extern "C" { */
+#endif /* __cplusplus */
+
+
+#endif // __IEEE11h_H__
diff --git a/drivers/staging/vt6655/Makefile b/drivers/staging/vt6655/Makefile
new file mode 100644 (file)
index 0000000..be44423
--- /dev/null
@@ -0,0 +1,218 @@
+#
+# Build options:
+#   PRIV_OBJ := 1 for object version
+#
+
+IO_MAP := 0
+HOSTAP := 1
+PRIV_OBJ := 0
+
+
+
+#KSP : = 0
+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   /home/plice
+
+#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 = viawget.ko
+
+else
+TARGET = viawget.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 = device_main.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 \
+      srom.c mib.c rc4.c tether.c tcrc.c ioctl.c hostap.c wpa.c key.c \
+      tkip.c michael.c wroute.c rf.c iwctl.c wpactl.c aes_ccmp.c \
+      vntwifi.c IEEE11h.c
+
+ifeq ($(IO_MAP), 1)
+  EXTRA_CFLAGS += -DIO_MAP
+endif
+
+ifeq ($(HOSTAP), 1)
+  EXTRA_CFLAGS += -DHOSTAP
+endif
+
+ifeq ($(PRIV_OBJ), 1)
+  EXTRA_CFLAGS += -DPRIVATE_OBJ
+endif
+
+EXTRA_CFLAGS += -I$(PWD) -I$(PWD)/../include -I$(PWD)/../solomon
+
+EXTRA_CFLAGS +=  -I$(PWD)/include -I$(PWD)/solomon
+
+# build rule
+ifeq ($(KVER), 2.6)
+# 2.6 kernel
+
+ifndef KERNEL_CONF
+KERNEL_CONF=   $(KSRC)/.config
+endif
+
+include ${KERNEL_CONF}
+
+obj-m += viawget.o
+
+viawget-objs :=        device_main.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 srom.o \
+       mib.o rc4.o tether.o tcrc.o ioctl.o hostap.o wpa.o key.o tkip.o \
+       michael.o wroute.o rf.o iwctl.o wpactl.o wpa2.o aes_ccmp.o \
+       vntwifi.o IEEE11h.o
+
+.c.o:
+       $(CC) $(CFLAGS) -o $@ $<
+
+default:
+       make -C $(KSRC) SUBDIRS=$(shell pwd) modules
+
+else
+
+# 2.2/2.4 kernel
+OBJS :=        device_main.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 srom.o \
+       mib.o rc4.o tether.o tcrc.o ioctl.o hostap.o wpa.o key.o tkip.o \
+       michael.o wroute.o rf.o iwctl.o wpactl.o wpa2.o aes_ccmp.o \
+       vntwifi.o IEEE11h.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))
+
+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 }')
+
+ifneq ($(SMP),1)
+  SMP := 0
+endif
+
+
+ifeq ($(SMP), 1)
+  EXTRA_CFLAGS += -D__SMP__
+endif
+
+
+ifeq ($(PRIV_OBJ), 1)
+  EXTRA_CFLAGS += -DPRIVATE_OBJ
+  TARGET = x86g_up.o
+
+ifeq ($(SMP), 1)
+  TARGET = x86g_smp.o
+endif
+
+endif
+
+
+# check x86_64
+SUBARCH := $(shell uname -m)
+ifeq ($(SUBARCH),x86_64)
+    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/vt6655/Makefile.arm b/drivers/staging/vt6655/Makefile.arm
new file mode 100644 (file)
index 0000000..2d2ccad
--- /dev/null
@@ -0,0 +1,181 @@
+#
+#
+# Build options:
+#   PRIV_OBJ   := 1 for object version
+#   BIG_ENDIAN := 1 for big-endian mode
+#
+#   arm-linux-tools chain are located at:
+#     /usr/local/bin/arm-linux-gcc
+#     /usr/local/bin/arm-linux-ld
+#
+
+IO_MAP := 0
+HOSTAP := 1
+PRIV_OBJ := 1
+BIG_ENDIAN := 1
+
+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 = viawget.ko
+
+else
+TARGET = viawget.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 = device_main.c card.c mac.c baseband.c wctl.c 80211mgr.c \
+      wcmd.c wmgr.c bssdb.c rxtx.c dpc.c power.c datarate.c srom.c \
+      mib.c rc4.c tether.c tcrc.c ioctl.c hostap.c wpa.c key.c tkip.c \
+      michael.c wroute.c rf.c iwctl.c wpactl.c wpa2.c aes_ccmp.c
+
+ifeq ($(IO_MAP), 1)
+  CFLAGS += -DIO_MAP
+endif
+
+ifeq ($(HOSTAP), 1)
+  CFLAGS += -DHOSTAP
+endif
+
+ifeq ($(PRIV_OBJ), 1)
+  CFLAGS += -DPRIVATE_OBJ
+endif
+
+ifeq ($(BIG_ENDIAN), 1)
+  CFLAGS += -D__BIG_ENDIAN
+  CFLAGS += -mbig-endian
+  LDOPTS += -EB
+else
+  CFLAGS += -mlittle-endian
+  LDOPTS += -EL
+endif
+
+CFLAGS += -I$(PWD) -I$(PWD)/../include -I$(PWD)/../solomon
+
+
+# build rule
+ifeq ($(KVER), 2.6)
+# 2.6 kernel
+
+ifndef KERNEL_CONF
+KERNEL_CONF=   $(KSRC)/.config
+endif
+
+include ${KERNEL_CONF}
+
+obj-m += viawget.o
+
+viawget-objs :=        device_main.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 srom.o \
+       mib.o rc4.o tether.o tcrc.o ioctl.o hostap.o wpa.o key.o tkip.o \
+       michael.o wroute.o rf.o iwctl.o wpactl.o wpa2.o aes_ccmp.o
+
+.c.o:
+       $(CC) $(CFLAGS) -o $@ $<
+
+default:
+       make -C $(KSRC) SUBDIRS=$(shell pwd) modules
+
+else
+
+# 2.2/2.4 kernel
+OBJS :=        device_main.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 srom.o \
+       mib.o rc4.o tether.o tcrc.o ioctl.o hostap.o wpa.o key.o tkip.o \
+       michael.o wroute.o rf.o iwctl.o wpactl.o wpa2.o
+
+
+CC := /usr/local/bin/arm-linux-gcc
+LD := /usr/local/bin/arm-linux-ld
+
+CFLAGS += -Wall -DLINUX -D__KERNEL__ -DMODULE  -DEXPORT_SYMTAB -D__NO_VERSION__ -O2 -pipe
+#CFLAGS += -Wstrict-prototypes -fomit-frame-pointer
+COPTS+= -march=armv4 -fno-strict-aliasing -fno-common
+#COPTS+= -mapcs-32 -mtune=xscale  -mshort-load-bytes -msoft-float -mfp=2
+#COPTS+= -mthumb  -mcpu=arm9 -ffunction-sections -fdata-sections
+
+
+.SILENT: $(TARGET) clean
+
+
+
+ifeq ($(PRIV_OBJ), 1)
+
+ifeq ($(BIG_ENDIAN), 1)
+  TARGET = arm_be_g.o
+else
+  TARGET = arm_le_g.o
+endif
+
+endif
+
+
+
+$(TARGET): $(filter-out $(TARGET), $(SRC:.c=.o))
+       $(LD) $(LDOPTS) -r $^ -o $@
+       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) *~
+       rm -f .*.o.d .*.o.cmd .*.ko.cmd *.mod.c *.mod.o
+
+-include .depend.mak
diff --git a/drivers/staging/vt6655/Makefile.x86 b/drivers/staging/vt6655/Makefile.x86
new file mode 100644 (file)
index 0000000..69082f0
--- /dev/null
@@ -0,0 +1,209 @@
+#
+# Build options:
+#   PRIV_OBJ := 1 for object version
+#
+
+IO_MAP := 0
+HOSTAP := 1
+PRIV_OBJ := 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 = viawget.ko
+
+else
+TARGET = viawget.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 = device_main.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 \
+      srom.c mib.c rc4.c tether.c tcrc.c ioctl.c hostap.c wpa.c key.c \
+      tkip.c michael.c wroute.c rf.c iwctl.c wpactl.c aes_ccmp.c
+
+ifeq ($(IO_MAP), 1)
+  CFLAGS += -DIO_MAP
+endif
+
+ifeq ($(HOSTAP), 1)
+  CFLAGS += -DHOSTAP
+endif
+
+ifeq ($(PRIV_OBJ), 1)
+  CFLAGS += -DPRIVATE_OBJ
+endif
+
+CFLAGS += -I$(PWD) -I$(PWD)/../include -I$(PWD)/../solomon
+
+
+# build rule
+ifeq ($(KVER), 2.6)
+# 2.6 kernel
+
+ifndef KERNEL_CONF
+KERNEL_CONF=   $(KSRC)/.config
+endif
+
+include ${KERNEL_CONF}
+
+obj-m += viawget.o
+
+viawget-objs :=        device_main.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 srom.o \
+       mib.o rc4.o tether.o tcrc.o ioctl.o hostap.o wpa.o key.o tkip.o \
+       michael.o wroute.o rf.o iwctl.o wpactl.o wpa2.o aes_ccmp.o
+
+.c.o:
+       $(CC) $(CFLAGS) -o $@ $<
+
+default:
+       make -C $(KSRC) SUBDIRS=$(shell pwd) modules
+
+else
+
+# 2.2/2.4 kernel
+OBJS :=        device_main.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 srom.o \
+       mib.o rc4.o tether.o tcrc.o ioctl.o hostap.o wpa.o key.o tkip.o \
+       michael.o wroute.o rf.o iwctl.o wpactl.o wpa2.o aes_ccmp.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
+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 }')
+
+ifneq ($(SMP),1)
+  SMP := 0
+endif
+
+
+ifeq ($(SMP), 1)
+  CFLAGS += -D__SMP__
+endif
+
+
+ifeq ($(PRIV_OBJ), 1)
+  CFLAGS += -DPRIVATE_OBJ
+  TARGET = x86g_up.o
+
+ifeq ($(SMP), 1)
+  TARGET = x86g_smp.o
+endif
+
+endif
+
+
+# check x86_64
+SUBARCH := $(shell uname -m)
+ifeq ($(SUBARCH),x86_64)
+    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) *~
+       rm -f .*.o.d .*.o.cmd .*.ko.cmd *.mod.c *.mod.o
+
+-include .depend.mak
diff --git a/drivers/staging/vt6655/aes_ccmp.c b/drivers/staging/vt6655/aes_ccmp.c
new file mode 100644 (file)
index 0000000..59cc018
--- /dev/null
@@ -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/vt6655/aes_ccmp.h b/drivers/staging/vt6655/aes_ccmp.h
new file mode 100644 (file)
index 0000000..2b1920f
--- /dev/null
@@ -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/vt6655/baseband.c b/drivers/staging/vt6655/baseband.c
new file mode 100644 (file)
index 0000000..bc6db86
--- /dev/null
@@ -0,0 +1,2990 @@
+/*
+ * 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: Kyle Hsu
+ *
+ * Date: Aug.22, 2002
+ *
+ * Functions:
+ *      BBuGetFrameTime        - Calculate data frame transmitting time
+ *      BBvCaculateParameter   - Caculate PhyLength, PhyService and Phy Signal parameter for baseband Tx
+ *      BBbReadEmbeded         - Embeded read baseband register via MAC
+ *      BBbWriteEmbeded        - Embeded write baseband register via MAC
+ *      BBbIsRegBitsOn         - Test if baseband register bits on
+ *      BBbIsRegBitsOff        - Test if baseband register bits off
+ *      BBbVT3253Init          - VIA VT3253 baseband chip init code
+ *      BBvReadAllRegs         - Read All Baseband Registers
+ *      BBvLoopbackOn          - Turn on BaseBand Loopback mode
+ *      BBvLoopbackOff         - Turn off BaseBand Loopback mode
+ *
+ * Revision History:
+ *      06-10-2003 Bryan YC Fan:  Re-write codes to support VT3253 spec.
+ *      08-07-2003 Bryan YC Fan:  Add MAXIM2827/2825 and RFMD2959 support.
+ *      08-26-2003 Kyle Hsu    :  Modify BBuGetFrameTime() and BBvCaculateParameter().
+ *                                cancel the setting of MAC_REG_SOFTPWRCTL on BBbVT3253Init().
+ *                                Add the comments.
+ *      09-01-2003 Bryan YC Fan:  RF & BB tables updated.
+ *                                Modified BBvLoopbackOn & BBvLoopbackOff().
+ */
+
+#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(__SROM_H__)
+#include "srom.h"
+#endif
+#if !defined(__UMEM_H__)
+#include "umem.h"
+#endif
+#if !defined(__RF_H__)
+#include "rf.h"
+#endif
+
+/*---------------------  Static Definitions -------------------------*/
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+static int          msglevel                =MSG_LEVEL_INFO;
+
+//#define      PLICE_DEBUG
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+/*---------------------  Static Functions  --------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Static Definitions -------------------------*/
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+
+
+
+#define CB_VT3253_INIT_FOR_RFMD 446
+BYTE byVT3253InitTab_RFMD[CB_VT3253_INIT_FOR_RFMD][2] = {
+    {0x00, 0x30},
+    {0x01, 0x00},
+    {0x02, 0x00},
+    {0x03, 0x00},
+    {0x04, 0x00},
+    {0x05, 0x00},
+    {0x06, 0x00},
+    {0x07, 0x00},
+    {0x08, 0x70},
+    {0x09, 0x45},
+    {0x0a, 0x2a},
+    {0x0b, 0x76},
+    {0x0c, 0x00},
+    {0x0d, 0x01},
+    {0x0e, 0x80},
+    {0x0f, 0x00},
+    {0x10, 0x00},
+    {0x11, 0x00},
+    {0x12, 0x00},
+    {0x13, 0x00},
+    {0x14, 0x00},
+    {0x15, 0x00},
+    {0x16, 0x00},
+    {0x17, 0x00},
+    {0x18, 0x00},
+    {0x19, 0x00},
+    {0x1a, 0x00},
+    {0x1b, 0x9d},
+    {0x1c, 0x05},
+    {0x1d, 0x00},
+    {0x1e, 0x00},
+    {0x1f, 0x00},
+    {0x20, 0x00},
+    {0x21, 0x00},
+    {0x22, 0x00},
+    {0x23, 0x00},
+    {0x24, 0x00},
+    {0x25, 0x4a},
+    {0x26, 0x00},
+    {0x27, 0x00},
+    {0x28, 0x00},
+    {0x29, 0x00},
+    {0x2a, 0x00},
+    {0x2b, 0x00},
+    {0x2c, 0x00},
+    {0x2d, 0xa8},
+    {0x2e, 0x1a},
+    {0x2f, 0x0c},
+    {0x30, 0x26},
+    {0x31, 0x5b},
+    {0x32, 0x00},
+    {0x33, 0x00},
+    {0x34, 0x00},
+    {0x35, 0x00},
+    {0x36, 0xaa},
+    {0x37, 0xaa},
+    {0x38, 0xff},
+    {0x39, 0xff},
+    {0x3a, 0x00},
+    {0x3b, 0x00},
+    {0x3c, 0x00},
+    {0x3d, 0x0d},
+    {0x3e, 0x51},
+    {0x3f, 0x04},
+    {0x40, 0x00},
+    {0x41, 0x08},
+    {0x42, 0x00},
+    {0x43, 0x08},
+    {0x44, 0x06},
+    {0x45, 0x14},
+    {0x46, 0x05},
+    {0x47, 0x08},
+    {0x48, 0x00},
+    {0x49, 0x00},
+    {0x4a, 0x00},
+    {0x4b, 0x00},
+    {0x4c, 0x09},
+    {0x4d, 0x80},
+    {0x4e, 0x00},
+    {0x4f, 0xc5},
+    {0x50, 0x14},
+    {0x51, 0x19},
+    {0x52, 0x00},
+    {0x53, 0x00},
+    {0x54, 0x00},
+    {0x55, 0x00},
+    {0x56, 0x00},
+    {0x57, 0x00},
+    {0x58, 0x00},
+    {0x59, 0xb0},
+    {0x5a, 0x00},
+    {0x5b, 0x00},
+    {0x5c, 0x00},
+    {0x5d, 0x00},
+    {0x5e, 0x00},
+    {0x5f, 0x00},
+    {0x60, 0x44},
+    {0x61, 0x04},
+    {0x62, 0x00},
+    {0x63, 0x00},
+    {0x64, 0x00},
+    {0x65, 0x00},
+    {0x66, 0x04},
+    {0x67, 0xb7},
+    {0x68, 0x00},
+    {0x69, 0x00},
+    {0x6a, 0x00},
+    {0x6b, 0x00},
+    {0x6c, 0x00},
+    {0x6d, 0x03},
+    {0x6e, 0x01},
+    {0x6f, 0x00},
+    {0x70, 0x00},
+    {0x71, 0x00},
+    {0x72, 0x00},
+    {0x73, 0x00},
+    {0x74, 0x00},
+    {0x75, 0x00},
+    {0x76, 0x00},
+    {0x77, 0x00},
+    {0x78, 0x00},
+    {0x79, 0x00},
+    {0x7a, 0x00},
+    {0x7b, 0x00},
+    {0x7c, 0x00},
+    {0x7d, 0x00},
+    {0x7e, 0x00},
+    {0x7f, 0x00},
+    {0x80, 0x0b},
+    {0x81, 0x00},
+    {0x82, 0x3c},
+    {0x83, 0x00},
+    {0x84, 0x00},
+    {0x85, 0x00},
+    {0x86, 0x00},
+    {0x87, 0x00},
+    {0x88, 0x08},
+    {0x89, 0x00},
+    {0x8a, 0x08},
+    {0x8b, 0xa6},
+    {0x8c, 0x84},
+    {0x8d, 0x47},
+    {0x8e, 0xbb},
+    {0x8f, 0x02},
+    {0x90, 0x21},
+    {0x91, 0x0c},
+    {0x92, 0x04},
+    {0x93, 0x22},
+    {0x94, 0x00},
+    {0x95, 0x00},
+    {0x96, 0x00},
+    {0x97, 0xeb},
+    {0x98, 0x00},
+    {0x99, 0x00},
+    {0x9a, 0x00},
+    {0x9b, 0x00},
+    {0x9c, 0x00},
+    {0x9d, 0x00},
+    {0x9e, 0x00},
+    {0x9f, 0x00},
+    {0xa0, 0x00},
+    {0xa1, 0x00},
+    {0xa2, 0x00},
+    {0xa3, 0x00},
+    {0xa4, 0x00},
+    {0xa5, 0x00},
+    {0xa6, 0x10},
+    {0xa7, 0x04},
+    {0xa8, 0x10},
+    {0xa9, 0x00},
+    {0xaa, 0x8f},
+    {0xab, 0x00},
+    {0xac, 0x00},
+    {0xad, 0x00},
+    {0xae, 0x00},
+    {0xaf, 0x80},
+    {0xb0, 0x38},
+    {0xb1, 0x00},
+    {0xb2, 0x00},
+    {0xb3, 0x00},
+    {0xb4, 0xee},
+    {0xb5, 0xff},
+    {0xb6, 0x10},
+    {0xb7, 0x00},
+    {0xb8, 0x00},
+    {0xb9, 0x00},
+    {0xba, 0x00},
+    {0xbb, 0x03},
+    {0xbc, 0x00},
+    {0xbd, 0x00},
+    {0xbe, 0x00},
+    {0xbf, 0x00},
+    {0xc0, 0x10},
+    {0xc1, 0x10},
+    {0xc2, 0x18},
+    {0xc3, 0x20},
+    {0xc4, 0x10},
+    {0xc5, 0x00},
+    {0xc6, 0x22},
+    {0xc7, 0x14},
+    {0xc8, 0x0f},
+    {0xc9, 0x08},
+    {0xca, 0xa4},
+    {0xcb, 0xa7},
+    {0xcc, 0x3c},
+    {0xcd, 0x10},
+    {0xce, 0x20},
+    {0xcf, 0x00},
+    {0xd0, 0x00},
+    {0xd1, 0x10},
+    {0xd2, 0x00},
+    {0xd3, 0x00},
+    {0xd4, 0x10},
+    {0xd5, 0x33},
+    {0xd6, 0x70},
+    {0xd7, 0x01},
+    {0xd8, 0x00},
+    {0xd9, 0x00},
+    {0xda, 0x00},
+    {0xdb, 0x00},
+    {0xdc, 0x00},
+    {0xdd, 0x00},
+    {0xde, 0x00},
+    {0xdf, 0x00},
+    {0xe0, 0x00},
+    {0xe1, 0x00},
+    {0xe2, 0xcc},
+    {0xe3, 0x04},
+    {0xe4, 0x08},
+    {0xe5, 0x10},
+    {0xe6, 0x00},
+    {0xe7, 0x0e},
+    {0xe8, 0x88},
+    {0xe9, 0xd4},
+    {0xea, 0x05},
+    {0xeb, 0xf0},
+    {0xec, 0x79},
+    {0xed, 0x0f},
+    {0xee, 0x04},
+    {0xef, 0x04},
+    {0xf0, 0x00},
+    {0xf1, 0x00},
+    {0xf2, 0x00},
+    {0xf3, 0x00},
+    {0xf4, 0x00},
+    {0xf5, 0x00},
+    {0xf6, 0x00},
+    {0xf7, 0x00},
+    {0xf8, 0x00},
+    {0xf9, 0x00},
+    {0xF0, 0x00},
+    {0xF1, 0xF8},
+    {0xF0, 0x80},
+    {0xF0, 0x00},
+    {0xF1, 0xF4},
+    {0xF0, 0x81},
+    {0xF0, 0x01},
+    {0xF1, 0xF0},
+    {0xF0, 0x82},
+    {0xF0, 0x02},
+    {0xF1, 0xEC},
+    {0xF0, 0x83},
+    {0xF0, 0x03},
+    {0xF1, 0xE8},
+    {0xF0, 0x84},
+    {0xF0, 0x04},
+    {0xF1, 0xE4},
+    {0xF0, 0x85},
+    {0xF0, 0x05},
+    {0xF1, 0xE0},
+    {0xF0, 0x86},
+    {0xF0, 0x06},
+    {0xF1, 0xDC},
+    {0xF0, 0x87},
+    {0xF0, 0x07},
+    {0xF1, 0xD8},
+    {0xF0, 0x88},
+    {0xF0, 0x08},
+    {0xF1, 0xD4},
+    {0xF0, 0x89},
+    {0xF0, 0x09},
+    {0xF1, 0xD0},
+    {0xF0, 0x8A},
+    {0xF0, 0x0A},
+    {0xF1, 0xCC},
+    {0xF0, 0x8B},
+    {0xF0, 0x0B},
+    {0xF1, 0xC8},
+    {0xF0, 0x8C},
+    {0xF0, 0x0C},
+    {0xF1, 0xC4},
+    {0xF0, 0x8D},
+    {0xF0, 0x0D},
+    {0xF1, 0xC0},
+    {0xF0, 0x8E},
+    {0xF0, 0x0E},
+    {0xF1, 0xBC},
+    {0xF0, 0x8F},
+    {0xF0, 0x0F},
+    {0xF1, 0xB8},
+    {0xF0, 0x90},
+    {0xF0, 0x10},
+    {0xF1, 0xB4},
+    {0xF0, 0x91},
+    {0xF0, 0x11},
+    {0xF1, 0xB0},
+    {0xF0, 0x92},
+    {0xF0, 0x12},
+    {0xF1, 0xAC},
+    {0xF0, 0x93},
+    {0xF0, 0x13},
+    {0xF1, 0xA8},
+    {0xF0, 0x94},
+    {0xF0, 0x14},
+    {0xF1, 0xA4},
+    {0xF0, 0x95},
+    {0xF0, 0x15},
+    {0xF1, 0xA0},
+    {0xF0, 0x96},
+    {0xF0, 0x16},
+    {0xF1, 0x9C},
+    {0xF0, 0x97},
+    {0xF0, 0x17},
+    {0xF1, 0x98},
+    {0xF0, 0x98},
+    {0xF0, 0x18},
+    {0xF1, 0x94},
+    {0xF0, 0x99},
+    {0xF0, 0x19},
+    {0xF1, 0x90},
+    {0xF0, 0x9A},
+    {0xF0, 0x1A},
+    {0xF1, 0x8C},
+    {0xF0, 0x9B},
+    {0xF0, 0x1B},
+    {0xF1, 0x88},
+    {0xF0, 0x9C},
+    {0xF0, 0x1C},
+    {0xF1, 0x84},
+    {0xF0, 0x9D},
+    {0xF0, 0x1D},
+    {0xF1, 0x80},
+    {0xF0, 0x9E},
+    {0xF0, 0x1E},
+    {0xF1, 0x7C},
+    {0xF0, 0x9F},
+    {0xF0, 0x1F},
+    {0xF1, 0x78},
+    {0xF0, 0xA0},
+    {0xF0, 0x20},
+    {0xF1, 0x74},
+    {0xF0, 0xA1},
+    {0xF0, 0x21},
+    {0xF1, 0x70},
+    {0xF0, 0xA2},
+    {0xF0, 0x22},
+    {0xF1, 0x6C},
+    {0xF0, 0xA3},
+    {0xF0, 0x23},
+    {0xF1, 0x68},
+    {0xF0, 0xA4},
+    {0xF0, 0x24},
+    {0xF1, 0x64},
+    {0xF0, 0xA5},
+    {0xF0, 0x25},
+    {0xF1, 0x60},
+    {0xF0, 0xA6},
+    {0xF0, 0x26},
+    {0xF1, 0x5C},
+    {0xF0, 0xA7},
+    {0xF0, 0x27},
+    {0xF1, 0x58},
+    {0xF0, 0xA8},
+    {0xF0, 0x28},
+    {0xF1, 0x54},
+    {0xF0, 0xA9},
+    {0xF0, 0x29},
+    {0xF1, 0x50},
+    {0xF0, 0xAA},
+    {0xF0, 0x2A},
+    {0xF1, 0x4C},
+    {0xF0, 0xAB},
+    {0xF0, 0x2B},
+    {0xF1, 0x48},
+    {0xF0, 0xAC},
+    {0xF0, 0x2C},
+    {0xF1, 0x44},
+    {0xF0, 0xAD},
+    {0xF0, 0x2D},
+    {0xF1, 0x40},
+    {0xF0, 0xAE},
+    {0xF0, 0x2E},
+    {0xF1, 0x3C},
+    {0xF0, 0xAF},
+    {0xF0, 0x2F},
+    {0xF1, 0x38},
+    {0xF0, 0xB0},
+    {0xF0, 0x30},
+    {0xF1, 0x34},
+    {0xF0, 0xB1},
+    {0xF0, 0x31},
+    {0xF1, 0x30},
+    {0xF0, 0xB2},
+    {0xF0, 0x32},
+    {0xF1, 0x2C},
+    {0xF0, 0xB3},
+    {0xF0, 0x33},
+    {0xF1, 0x28},
+    {0xF0, 0xB4},
+    {0xF0, 0x34},
+    {0xF1, 0x24},
+    {0xF0, 0xB5},
+    {0xF0, 0x35},
+    {0xF1, 0x20},
+    {0xF0, 0xB6},
+    {0xF0, 0x36},
+    {0xF1, 0x1C},
+    {0xF0, 0xB7},
+    {0xF0, 0x37},
+    {0xF1, 0x18},
+    {0xF0, 0xB8},
+    {0xF0, 0x38},
+    {0xF1, 0x14},
+    {0xF0, 0xB9},
+    {0xF0, 0x39},
+    {0xF1, 0x10},
+    {0xF0, 0xBA},
+    {0xF0, 0x3A},
+    {0xF1, 0x0C},
+    {0xF0, 0xBB},
+    {0xF0, 0x3B},
+    {0xF1, 0x08},
+    {0xF0, 0x00},
+    {0xF0, 0x3C},
+    {0xF1, 0x04},
+    {0xF0, 0xBD},
+    {0xF0, 0x3D},
+    {0xF1, 0x00},
+    {0xF0, 0xBE},
+    {0xF0, 0x3E},
+    {0xF1, 0x00},
+    {0xF0, 0xBF},
+    {0xF0, 0x3F},
+    {0xF1, 0x00},
+    {0xF0, 0xC0},
+    {0xF0, 0x00},
+};
+
+#define CB_VT3253B0_INIT_FOR_RFMD 256
+BYTE byVT3253B0_RFMD[CB_VT3253B0_INIT_FOR_RFMD][2] = {
+    {0x00, 0x31},
+    {0x01, 0x00},
+    {0x02, 0x00},
+    {0x03, 0x00},
+    {0x04, 0x00},
+    {0x05, 0x81},
+    {0x06, 0x00},
+    {0x07, 0x00},
+    {0x08, 0x38},
+    {0x09, 0x45},
+    {0x0a, 0x2a},
+    {0x0b, 0x76},
+    {0x0c, 0x00},
+    {0x0d, 0x00},
+    {0x0e, 0x80},
+    {0x0f, 0x00},
+    {0x10, 0x00},
+    {0x11, 0x00},
+    {0x12, 0x00},
+    {0x13, 0x00},
+    {0x14, 0x00},
+    {0x15, 0x00},
+    {0x16, 0x00},
+    {0x17, 0x00},
+    {0x18, 0x00},
+    {0x19, 0x00},
+    {0x1a, 0x00},
+    {0x1b, 0x8e},
+    {0x1c, 0x06},
+    {0x1d, 0x00},
+    {0x1e, 0x00},
+    {0x1f, 0x00},
+    {0x20, 0x00},
+    {0x21, 0x00},
+    {0x22, 0x00},
+    {0x23, 0x00},
+    {0x24, 0x00},
+    {0x25, 0x4a},
+    {0x26, 0x00},
+    {0x27, 0x00},
+    {0x28, 0x00},
+    {0x29, 0x00},
+    {0x2a, 0x00},
+    {0x2b, 0x00},
+    {0x2c, 0x00},
+    {0x2d, 0x34},
+    {0x2e, 0x18},
+    {0x2f, 0x0c},
+    {0x30, 0x26},
+    {0x31, 0x5b},
+    {0x32, 0x00},
+    {0x33, 0x00},
+    {0x34, 0x00},
+    {0x35, 0x00},
+    {0x36, 0xaa},
+    {0x37, 0xaa},
+    {0x38, 0xff},
+    {0x39, 0xff},
+    {0x3a, 0xf8},
+    {0x3b, 0x00},
+    {0x3c, 0x00},
+    {0x3d, 0x09},
+    {0x3e, 0x0d},
+    {0x3f, 0x04},
+    {0x40, 0x00},
+    {0x41, 0x08},
+    {0x42, 0x00},
+    {0x43, 0x08},
+    {0x44, 0x08},
+    {0x45, 0x14},
+    {0x46, 0x05},
+    {0x47, 0x08},
+    {0x48, 0x00},
+    {0x49, 0x00},
+    {0x4a, 0x00},
+    {0x4b, 0x00},
+    {0x4c, 0x09},
+    {0x4d, 0x80},
+    {0x4e, 0x00},
+    {0x4f, 0xc5},
+    {0x50, 0x14},
+    {0x51, 0x19},
+    {0x52, 0x00},
+    {0x53, 0x00},
+    {0x54, 0x00},
+    {0x55, 0x00},
+    {0x56, 0x00},
+    {0x57, 0x00},
+    {0x58, 0x00},
+    {0x59, 0xb0},
+    {0x5a, 0x00},
+    {0x5b, 0x00},
+    {0x5c, 0x00},
+    {0x5d, 0x00},
+    {0x5e, 0x00},
+    {0x5f, 0x00},
+    {0x60, 0x39},
+    {0x61, 0x83},
+    {0x62, 0x00},
+    {0x63, 0x00},
+    {0x64, 0x00},
+    {0x65, 0x00},
+    {0x66, 0xc0},
+    {0x67, 0x49},
+    {0x68, 0x00},
+    {0x69, 0x00},
+    {0x6a, 0x00},
+    {0x6b, 0x00},
+    {0x6c, 0x00},
+    {0x6d, 0x03},
+    {0x6e, 0x01},
+    {0x6f, 0x00},
+    {0x70, 0x00},
+    {0x71, 0x00},
+    {0x72, 0x00},
+    {0x73, 0x00},
+    {0x74, 0x00},
+    {0x75, 0x00},
+    {0x76, 0x00},
+    {0x77, 0x00},
+    {0x78, 0x00},
+    {0x79, 0x00},
+    {0x7a, 0x00},
+    {0x7b, 0x00},
+    {0x7c, 0x00},
+    {0x7d, 0x00},
+    {0x7e, 0x00},
+    {0x7f, 0x00},
+    {0x80, 0x89},
+    {0x81, 0x00},
+    {0x82, 0x0e},
+    {0x83, 0x00},
+    {0x84, 0x00},
+    {0x85, 0x00},
+    {0x86, 0x00},
+    {0x87, 0x00},
+    {0x88, 0x08},
+    {0x89, 0x00},
+    {0x8a, 0x0e},
+    {0x8b, 0xa7},
+    {0x8c, 0x88},
+    {0x8d, 0x47},
+    {0x8e, 0xaa},
+    {0x8f, 0x02},
+    {0x90, 0x23},
+    {0x91, 0x0c},
+    {0x92, 0x06},
+    {0x93, 0x08},
+    {0x94, 0x00},
+    {0x95, 0x00},
+    {0x96, 0x00},
+    {0x97, 0xeb},
+    {0x98, 0x00},
+    {0x99, 0x00},
+    {0x9a, 0x00},
+    {0x9b, 0x00},
+    {0x9c, 0x00},
+    {0x9d, 0x00},
+    {0x9e, 0x00},
+    {0x9f, 0x00},
+    {0xa0, 0x00},
+    {0xa1, 0x00},
+    {0xa2, 0x00},
+    {0xa3, 0xcd},
+    {0xa4, 0x07},
+    {0xa5, 0x33},
+    {0xa6, 0x18},
+    {0xa7, 0x00},
+    {0xa8, 0x18},
+    {0xa9, 0x00},
+    {0xaa, 0x28},
+    {0xab, 0x00},
+    {0xac, 0x00},
+    {0xad, 0x00},
+    {0xae, 0x00},
+    {0xaf, 0x18},
+    {0xb0, 0x38},
+    {0xb1, 0x30},
+    {0xb2, 0x00},
+    {0xb3, 0x00},
+    {0xb4, 0x00},
+    {0xb5, 0x00},
+    {0xb6, 0x84},
+    {0xb7, 0xfd},
+    {0xb8, 0x00},
+    {0xb9, 0x00},
+    {0xba, 0x00},
+    {0xbb, 0x03},
+    {0xbc, 0x00},
+    {0xbd, 0x00},
+    {0xbe, 0x00},
+    {0xbf, 0x00},
+    {0xc0, 0x10},
+    {0xc1, 0x20},
+    {0xc2, 0x18},
+    {0xc3, 0x20},
+    {0xc4, 0x10},
+    {0xc5, 0x2c},
+    {0xc6, 0x1e},
+    {0xc7, 0x10},
+    {0xc8, 0x12},
+    {0xc9, 0x01},
+    {0xca, 0x6f},
+    {0xcb, 0xa7},
+    {0xcc, 0x3c},
+    {0xcd, 0x10},
+    {0xce, 0x00},
+    {0xcf, 0x22},
+    {0xd0, 0x00},
+    {0xd1, 0x10},
+    {0xd2, 0x00},
+    {0xd3, 0x00},
+    {0xd4, 0x10},
+    {0xd5, 0x33},
+    {0xd6, 0x80},
+    {0xd7, 0x21},
+    {0xd8, 0x00},
+    {0xd9, 0x00},
+    {0xda, 0x00},
+    {0xdb, 0x00},
+    {0xdc, 0x00},
+    {0xdd, 0x00},
+    {0xde, 0x00},
+    {0xdf, 0x00},
+    {0xe0, 0x00},
+    {0xe1, 0xB3},
+    {0xe2, 0x00},
+    {0xe3, 0x00},
+    {0xe4, 0x00},
+    {0xe5, 0x10},
+    {0xe6, 0x00},
+    {0xe7, 0x18},
+    {0xe8, 0x08},
+    {0xe9, 0xd4},
+    {0xea, 0x00},
+    {0xeb, 0xff},
+    {0xec, 0x79},
+    {0xed, 0x10},
+    {0xee, 0x30},
+    {0xef, 0x02},
+    {0xf0, 0x00},
+    {0xf1, 0x09},
+    {0xf2, 0x00},
+    {0xf3, 0x00},
+    {0xf4, 0x00},
+    {0xf5, 0x00},
+    {0xf6, 0x00},
+    {0xf7, 0x00},
+    {0xf8, 0x00},
+    {0xf9, 0x00},
+    {0xfa, 0x00},
+    {0xfb, 0x00},
+    {0xfc, 0x00},
+    {0xfd, 0x00},
+    {0xfe, 0x00},
+    {0xff, 0x00},
+};
+
+#define CB_VT3253B0_AGC_FOR_RFMD2959 195
+// For RFMD2959
+BYTE byVT3253B0_AGC4_RFMD2959[CB_VT3253B0_AGC_FOR_RFMD2959][2] = {
+    {0xF0, 0x00},
+    {0xF1, 0x3E},
+    {0xF0, 0x80},
+    {0xF0, 0x00},
+    {0xF1, 0x3E},
+    {0xF0, 0x81},
+    {0xF0, 0x01},
+    {0xF1, 0x3E},
+    {0xF0, 0x82},
+    {0xF0, 0x02},
+    {0xF1, 0x3E},
+    {0xF0, 0x83},
+    {0xF0, 0x03},
+    {0xF1, 0x3B},
+    {0xF0, 0x84},
+    {0xF0, 0x04},
+    {0xF1, 0x39},
+    {0xF0, 0x85},
+    {0xF0, 0x05},
+    {0xF1, 0x38},
+    {0xF0, 0x86},
+    {0xF0, 0x06},
+    {0xF1, 0x37},
+    {0xF0, 0x87},
+    {0xF0, 0x07},
+    {0xF1, 0x36},
+    {0xF0, 0x88},
+    {0xF0, 0x08},
+    {0xF1, 0x35},
+    {0xF0, 0x89},
+    {0xF0, 0x09},
+    {0xF1, 0x35},
+    {0xF0, 0x8A},
+    {0xF0, 0x0A},
+    {0xF1, 0x34},
+    {0xF0, 0x8B},
+    {0xF0, 0x0B},
+    {0xF1, 0x34},
+    {0xF0, 0x8C},
+    {0xF0, 0x0C},
+    {0xF1, 0x33},
+    {0xF0, 0x8D},
+    {0xF0, 0x0D},
+    {0xF1, 0x32},
+    {0xF0, 0x8E},
+    {0xF0, 0x0E},
+    {0xF1, 0x31},
+    {0xF0, 0x8F},
+    {0xF0, 0x0F},
+    {0xF1, 0x30},
+    {0xF0, 0x90},
+    {0xF0, 0x10},
+    {0xF1, 0x2F},
+    {0xF0, 0x91},
+    {0xF0, 0x11},
+    {0xF1, 0x2F},
+    {0xF0, 0x92},
+    {0xF0, 0x12},
+    {0xF1, 0x2E},
+    {0xF0, 0x93},
+    {0xF0, 0x13},
+    {0xF1, 0x2D},
+    {0xF0, 0x94},
+    {0xF0, 0x14},
+    {0xF1, 0x2C},
+    {0xF0, 0x95},
+    {0xF0, 0x15},
+    {0xF1, 0x2B},
+    {0xF0, 0x96},
+    {0xF0, 0x16},
+    {0xF1, 0x2B},
+    {0xF0, 0x97},
+    {0xF0, 0x17},
+    {0xF1, 0x2A},
+    {0xF0, 0x98},
+    {0xF0, 0x18},
+    {0xF1, 0x29},
+    {0xF0, 0x99},
+    {0xF0, 0x19},
+    {0xF1, 0x28},
+    {0xF0, 0x9A},
+    {0xF0, 0x1A},
+    {0xF1, 0x27},
+    {0xF0, 0x9B},
+    {0xF0, 0x1B},
+    {0xF1, 0x26},
+    {0xF0, 0x9C},
+    {0xF0, 0x1C},
+    {0xF1, 0x25},
+    {0xF0, 0x9D},
+    {0xF0, 0x1D},
+    {0xF1, 0x24},
+    {0xF0, 0x9E},
+    {0xF0, 0x1E},
+    {0xF1, 0x24},
+    {0xF0, 0x9F},
+    {0xF0, 0x1F},
+    {0xF1, 0x23},
+    {0xF0, 0xA0},
+    {0xF0, 0x20},
+    {0xF1, 0x22},
+    {0xF0, 0xA1},
+    {0xF0, 0x21},
+    {0xF1, 0x21},
+    {0xF0, 0xA2},
+    {0xF0, 0x22},
+    {0xF1, 0x20},
+    {0xF0, 0xA3},
+    {0xF0, 0x23},
+    {0xF1, 0x20},
+    {0xF0, 0xA4},
+    {0xF0, 0x24},
+    {0xF1, 0x1F},
+    {0xF0, 0xA5},
+    {0xF0, 0x25},
+    {0xF1, 0x1E},
+    {0xF0, 0xA6},
+    {0xF0, 0x26},
+    {0xF1, 0x1D},
+    {0xF0, 0xA7},
+    {0xF0, 0x27},
+    {0xF1, 0x1C},
+    {0xF0, 0xA8},
+    {0xF0, 0x28},
+    {0xF1, 0x1B},
+    {0xF0, 0xA9},
+    {0xF0, 0x29},
+    {0xF1, 0x1B},
+    {0xF0, 0xAA},
+    {0xF0, 0x2A},
+    {0xF1, 0x1A},
+    {0xF0, 0xAB},
+    {0xF0, 0x2B},
+    {0xF1, 0x1A},
+    {0xF0, 0xAC},
+    {0xF0, 0x2C},
+    {0xF1, 0x19},
+    {0xF0, 0xAD},
+    {0xF0, 0x2D},
+    {0xF1, 0x18},
+    {0xF0, 0xAE},
+    {0xF0, 0x2E},
+    {0xF1, 0x17},
+    {0xF0, 0xAF},
+    {0xF0, 0x2F},
+    {0xF1, 0x16},
+    {0xF0, 0xB0},
+    {0xF0, 0x30},
+    {0xF1, 0x15},
+    {0xF0, 0xB1},
+    {0xF0, 0x31},
+    {0xF1, 0x15},
+    {0xF0, 0xB2},
+    {0xF0, 0x32},
+    {0xF1, 0x15},
+    {0xF0, 0xB3},
+    {0xF0, 0x33},
+    {0xF1, 0x14},
+    {0xF0, 0xB4},
+    {0xF0, 0x34},
+    {0xF1, 0x13},
+    {0xF0, 0xB5},
+    {0xF0, 0x35},
+    {0xF1, 0x12},
+    {0xF0, 0xB6},
+    {0xF0, 0x36},
+    {0xF1, 0x11},
+    {0xF0, 0xB7},
+    {0xF0, 0x37},
+    {0xF1, 0x10},
+    {0xF0, 0xB8},
+    {0xF0, 0x38},
+    {0xF1, 0x0F},
+    {0xF0, 0xB9},
+    {0xF0, 0x39},
+    {0xF1, 0x0E},
+    {0xF0, 0xBA},
+    {0xF0, 0x3A},
+    {0xF1, 0x0D},
+    {0xF0, 0xBB},
+    {0xF0, 0x3B},
+    {0xF1, 0x0C},
+    {0xF0, 0xBC},
+    {0xF0, 0x3C},
+    {0xF1, 0x0B},
+    {0xF0, 0xBD},
+    {0xF0, 0x3D},
+    {0xF1, 0x0B},
+    {0xF0, 0xBE},
+    {0xF0, 0x3E},
+    {0xF1, 0x0A},
+    {0xF0, 0xBF},
+    {0xF0, 0x3F},
+    {0xF1, 0x09},
+    {0xF0, 0x00},
+};
+
+#define CB_VT3253B0_INIT_FOR_AIROHA2230 256
+// For AIROHA
+BYTE byVT3253B0_AIROHA2230[CB_VT3253B0_INIT_FOR_AIROHA2230][2] = {
+    {0x00, 0x31},
+    {0x01, 0x00},
+    {0x02, 0x00},
+    {0x03, 0x00},
+    {0x04, 0x00},
+    {0x05, 0x80},
+    {0x06, 0x00},
+    {0x07, 0x00},
+    {0x08, 0x70},
+    {0x09, 0x41},
+    {0x0a, 0x2A},
+    {0x0b, 0x76},
+    {0x0c, 0x00},
+    {0x0d, 0x00},
+    {0x0e, 0x80},
+    {0x0f, 0x00},
+    {0x10, 0x00},
+    {0x11, 0x00},
+    {0x12, 0x00},
+    {0x13, 0x00},
+    {0x14, 0x00},
+    {0x15, 0x00},
+    {0x16, 0x00},
+    {0x17, 0x00},
+    {0x18, 0x00},
+    {0x19, 0x00},
+    {0x1a, 0x00},
+    {0x1b, 0x8f},
+    {0x1c, 0x09},
+    {0x1d, 0x00},
+    {0x1e, 0x00},
+    {0x1f, 0x00},
+    {0x20, 0x00},
+    {0x21, 0x00},
+    {0x22, 0x00},
+    {0x23, 0x00},
+    {0x24, 0x00},
+    {0x25, 0x4a},
+    {0x26, 0x00},
+    {0x27, 0x00},
+    {0x28, 0x00},
+    {0x29, 0x00},
+    {0x2a, 0x00},
+    {0x2b, 0x00},
+    {0x2c, 0x00},
+    {0x2d, 0x4a},
+    {0x2e, 0x00},
+    {0x2f, 0x0a},
+    {0x30, 0x26},
+    {0x31, 0x5b},
+    {0x32, 0x00},
+    {0x33, 0x00},
+    {0x34, 0x00},
+    {0x35, 0x00},
+    {0x36, 0xaa},
+    {0x37, 0xaa},
+    {0x38, 0xff},
+    {0x39, 0xff},
+    {0x3a, 0x79},
+    {0x3b, 0x00},
+    {0x3c, 0x00},
+    {0x3d, 0x0b},
+    {0x3e, 0x48},
+    {0x3f, 0x04},
+    {0x40, 0x00},
+    {0x41, 0x08},
+    {0x42, 0x00},
+    {0x43, 0x08},
+    {0x44, 0x08},
+    {0x45, 0x14},
+    {0x46, 0x05},
+    {0x47, 0x09},
+    {0x48, 0x00},
+    {0x49, 0x00},
+    {0x4a, 0x00},
+    {0x4b, 0x00},
+    {0x4c, 0x09},
+    {0x4d, 0x73},
+    {0x4e, 0x00},
+    {0x4f, 0xc5},
+    {0x50, 0x15},
+    {0x51, 0x19},
+    {0x52, 0x00},
+    {0x53, 0x00},
+    {0x54, 0x00},
+    {0x55, 0x00},
+    {0x56, 0x00},
+    {0x57, 0x00},
+    {0x58, 0x00},
+    {0x59, 0xb0},
+    {0x5a, 0x00},
+    {0x5b, 0x00},
+    {0x5c, 0x00},
+    {0x5d, 0x00},
+    {0x5e, 0x00},
+    {0x5f, 0x00},
+    {0x60, 0xe4},
+    {0x61, 0x80},
+    {0x62, 0x00},
+    {0x63, 0x00},
+    {0x64, 0x00},
+    {0x65, 0x00},
+    {0x66, 0x98},
+    {0x67, 0x0a},
+    {0x68, 0x00},
+    {0x69, 0x00},
+    {0x6a, 0x00},
+    {0x6b, 0x00},
+    //{0x6c, 0x80},
+    {0x6c, 0x00}, //RobertYu:20050125, request by JJSue
+    {0x6d, 0x03},
+    {0x6e, 0x01},
+    {0x6f, 0x00},
+    {0x70, 0x00},
+    {0x71, 0x00},
+    {0x72, 0x00},
+    {0x73, 0x00},
+    {0x74, 0x00},
+    {0x75, 0x00},
+    {0x76, 0x00},
+    {0x77, 0x00},
+    {0x78, 0x00},
+    {0x79, 0x00},
+    {0x7a, 0x00},
+    {0x7b, 0x00},
+    {0x7c, 0x00},
+    {0x7d, 0x00},
+    {0x7e, 0x00},
+    {0x7f, 0x00},
+    {0x80, 0x8c},
+    {0x81, 0x01},
+    {0x82, 0x09},
+    {0x83, 0x00},
+    {0x84, 0x00},
+    {0x85, 0x00},
+    {0x86, 0x00},
+    {0x87, 0x00},
+    {0x88, 0x08},
+    {0x89, 0x00},
+    {0x8a, 0x0f},
+    {0x8b, 0xb7},
+    {0x8c, 0x88},
+    {0x8d, 0x47},
+    {0x8e, 0xaa},
+    {0x8f, 0x02},
+    {0x90, 0x22},
+    {0x91, 0x00},
+    {0x92, 0x00},
+    {0x93, 0x00},
+    {0x94, 0x00},
+    {0x95, 0x00},
+    {0x96, 0x00},
+    {0x97, 0xeb},
+    {0x98, 0x00},
+    {0x99, 0x00},
+    {0x9a, 0x00},
+    {0x9b, 0x00},
+    {0x9c, 0x00},
+    {0x9d, 0x00},
+    {0x9e, 0x00},
+    {0x9f, 0x01},
+    {0xa0, 0x00},
+    {0xa1, 0x00},
+    {0xa2, 0x00},
+    {0xa3, 0x00},
+    {0xa4, 0x00},
+    {0xa5, 0x00},
+    {0xa6, 0x10},
+    {0xa7, 0x00},
+    {0xa8, 0x18},
+    {0xa9, 0x00},
+    {0xaa, 0x00},
+    {0xab, 0x00},
+    {0xac, 0x00},
+    {0xad, 0x00},
+    {0xae, 0x00},
+    {0xaf, 0x18},
+    {0xb0, 0x38},
+    {0xb1, 0x30},
+    {0xb2, 0x00},
+    {0xb3, 0x00},
+    {0xb4, 0xff},
+    {0xb5, 0x0f},
+    {0xb6, 0xe4},
+    {0xb7, 0xe2},
+    {0xb8, 0x00},
+    {0xb9, 0x00},
+    {0xba, 0x00},
+    {0xbb, 0x03},
+    {0xbc, 0x01},
+    {0xbd, 0x00},
+    {0xbe, 0x00},
+    {0xbf, 0x00},
+    {0xc0, 0x18},
+    {0xc1, 0x20},
+    {0xc2, 0x07},
+    {0xc3, 0x18},
+    {0xc4, 0xff},
+    {0xc5, 0x2c},
+    {0xc6, 0x0c},
+    {0xc7, 0x0a},
+    {0xc8, 0x0e},
+    {0xc9, 0x01},
+    {0xca, 0x68},
+    {0xcb, 0xa7},
+    {0xcc, 0x3c},
+    {0xcd, 0x10},
+    {0xce, 0x00},
+    {0xcf, 0x25},
+    {0xd0, 0x40},
+    {0xd1, 0x12},
+    {0xd2, 0x00},
+    {0xd3, 0x00},
+    {0xd4, 0x10},
+    {0xd5, 0x28},
+    {0xd6, 0x80},
+    {0xd7, 0x2A},
+    {0xd8, 0x00},
+    {0xd9, 0x00},
+    {0xda, 0x00},
+    {0xdb, 0x00},
+    {0xdc, 0x00},
+    {0xdd, 0x00},
+    {0xde, 0x00},
+    {0xdf, 0x00},
+    {0xe0, 0x00},
+    {0xe1, 0xB3},
+    {0xe2, 0x00},
+    {0xe3, 0x00},
+    {0xe4, 0x00},
+    {0xe5, 0x10},
+    {0xe6, 0x00},
+    {0xe7, 0x1C},
+    {0xe8, 0x00},
+    {0xe9, 0xf4},
+    {0xea, 0x00},
+    {0xeb, 0xff},
+    {0xec, 0x79},
+    {0xed, 0x20},
+    {0xee, 0x30},
+    {0xef, 0x01},
+    {0xf0, 0x00},
+    {0xf1, 0x3e},
+    {0xf2, 0x00},
+    {0xf3, 0x00},
+    {0xf4, 0x00},
+    {0xf5, 0x00},
+    {0xf6, 0x00},
+    {0xf7, 0x00},
+    {0xf8, 0x00},
+    {0xf9, 0x00},
+    {0xfa, 0x00},
+    {0xfb, 0x00},
+    {0xfc, 0x00},
+    {0xfd, 0x00},
+    {0xfe, 0x00},
+    {0xff, 0x00},
+};
+
+
+
+#define CB_VT3253B0_INIT_FOR_UW2451 256
+//For UW2451
+BYTE byVT3253B0_UW2451[CB_VT3253B0_INIT_FOR_UW2451][2] = {
+    {0x00, 0x31},
+    {0x01, 0x00},
+    {0x02, 0x00},
+    {0x03, 0x00},
+    {0x04, 0x00},
+    {0x05, 0x81},
+    {0x06, 0x00},
+    {0x07, 0x00},
+    {0x08, 0x38},
+    {0x09, 0x45},
+    {0x0a, 0x28},
+    {0x0b, 0x76},
+    {0x0c, 0x00},
+    {0x0d, 0x00},
+    {0x0e, 0x80},
+    {0x0f, 0x00},
+    {0x10, 0x00},
+    {0x11, 0x00},
+    {0x12, 0x00},
+    {0x13, 0x00},
+    {0x14, 0x00},
+    {0x15, 0x00},
+    {0x16, 0x00},
+    {0x17, 0x00},
+    {0x18, 0x00},
+    {0x19, 0x00},
+    {0x1a, 0x00},
+    {0x1b, 0x8f},
+    {0x1c, 0x0f},
+    {0x1d, 0x00},
+    {0x1e, 0x00},
+    {0x1f, 0x00},
+    {0x20, 0x00},
+    {0x21, 0x00},
+    {0x22, 0x00},
+    {0x23, 0x00},
+    {0x24, 0x00},
+    {0x25, 0x4a},
+    {0x26, 0x00},
+    {0x27, 0x00},
+    {0x28, 0x00},
+    {0x29, 0x00},
+    {0x2a, 0x00},
+    {0x2b, 0x00},
+    {0x2c, 0x00},
+    {0x2d, 0x18},
+    {0x2e, 0x00},
+    {0x2f, 0x0a},
+    {0x30, 0x26},
+    {0x31, 0x5b},
+    {0x32, 0x00},
+    {0x33, 0x00},
+    {0x34, 0x00},
+    {0x35, 0x00},
+    {0x36, 0xaa},
+    {0x37, 0xaa},
+    {0x38, 0xff},
+    {0x39, 0xff},
+    {0x3a, 0x00},
+    {0x3b, 0x00},
+    {0x3c, 0x00},
+    {0x3d, 0x03},
+    {0x3e, 0x1d},
+    {0x3f, 0x04},
+    {0x40, 0x00},
+    {0x41, 0x08},
+    {0x42, 0x00},
+    {0x43, 0x08},
+    {0x44, 0x08},
+    {0x45, 0x14},
+    {0x46, 0x05},
+    {0x47, 0x09},
+    {0x48, 0x00},
+    {0x49, 0x00},
+    {0x4a, 0x00},
+    {0x4b, 0x00},
+    {0x4c, 0x09},
+    {0x4d, 0x90},
+    {0x4e, 0x00},
+    {0x4f, 0xc5},
+    {0x50, 0x15},
+    {0x51, 0x19},
+    {0x52, 0x00},
+    {0x53, 0x00},
+    {0x54, 0x00},
+    {0x55, 0x00},
+    {0x56, 0x00},
+    {0x57, 0x00},
+    {0x58, 0x00},
+    {0x59, 0xb0},
+    {0x5a, 0x00},
+    {0x5b, 0x00},
+    {0x5c, 0x00},
+    {0x5d, 0x00},
+    {0x5e, 0x00},
+    {0x5f, 0x00},
+    {0x60, 0xb3},
+    {0x61, 0x81},
+    {0x62, 0x00},
+    {0x63, 0x00},
+    {0x64, 0x00},
+    {0x65, 0x00},
+    {0x66, 0x57},
+    {0x67, 0x6c},
+    {0x68, 0x00},
+    {0x69, 0x00},
+    {0x6a, 0x00},
+    {0x6b, 0x00},
+    //{0x6c, 0x80},
+    {0x6c, 0x00}, //RobertYu:20050125, request by JJSue
+    {0x6d, 0x03},
+    {0x6e, 0x01},
+    {0x6f, 0x00},
+    {0x70, 0x00},
+    {0x71, 0x00},
+    {0x72, 0x00},
+    {0x73, 0x00},
+    {0x74, 0x00},
+    {0x75, 0x00},
+    {0x76, 0x00},
+    {0x77, 0x00},
+    {0x78, 0x00},
+    {0x79, 0x00},
+    {0x7a, 0x00},
+    {0x7b, 0x00},
+    {0x7c, 0x00},
+    {0x7d, 0x00},
+    {0x7e, 0x00},
+    {0x7f, 0x00},
+    {0x80, 0x8c},
+    {0x81, 0x00},
+    {0x82, 0x0e},
+    {0x83, 0x00},
+    {0x84, 0x00},
+    {0x85, 0x00},
+    {0x86, 0x00},
+    {0x87, 0x00},
+    {0x88, 0x08},
+    {0x89, 0x00},
+    {0x8a, 0x0e},
+    {0x8b, 0xa7},
+    {0x8c, 0x88},
+    {0x8d, 0x47},
+    {0x8e, 0xaa},
+    {0x8f, 0x02},
+    {0x90, 0x00},
+    {0x91, 0x00},
+    {0x92, 0x00},
+    {0x93, 0x00},
+    {0x94, 0x00},
+    {0x95, 0x00},
+    {0x96, 0x00},
+    {0x97, 0xe3},
+    {0x98, 0x00},
+    {0x99, 0x00},
+    {0x9a, 0x00},
+    {0x9b, 0x00},
+    {0x9c, 0x00},
+    {0x9d, 0x00},
+    {0x9e, 0x00},
+    {0x9f, 0x00},
+    {0xa0, 0x00},
+    {0xa1, 0x00},
+    {0xa2, 0x00},
+    {0xa3, 0x00},
+    {0xa4, 0x00},
+    {0xa5, 0x00},
+    {0xa6, 0x10},
+    {0xa7, 0x00},
+    {0xa8, 0x18},
+    {0xa9, 0x00},
+    {0xaa, 0x00},
+    {0xab, 0x00},
+    {0xac, 0x00},
+    {0xad, 0x00},
+    {0xae, 0x00},
+    {0xaf, 0x18},
+    {0xb0, 0x18},
+    {0xb1, 0x30},
+    {0xb2, 0x00},
+    {0xb3, 0x00},
+    {0xb4, 0x00},
+    {0xb5, 0x00},
+    {0xb6, 0x00},
+    {0xb7, 0x00},
+    {0xb8, 0x00},
+    {0xb9, 0x00},
+    {0xba, 0x00},
+    {0xbb, 0x03},
+    {0xbc, 0x01},
+    {0xbd, 0x00},
+    {0xbe, 0x00},
+    {0xbf, 0x00},
+    {0xc0, 0x10},
+    {0xc1, 0x20},
+    {0xc2, 0x00},
+    {0xc3, 0x20},
+    {0xc4, 0x00},
+    {0xc5, 0x2c},
+    {0xc6, 0x1c},
+    {0xc7, 0x10},
+    {0xc8, 0x10},
+    {0xc9, 0x01},
+    {0xca, 0x68},
+    {0xcb, 0xa7},
+    {0xcc, 0x3c},
+    {0xcd, 0x09},
+    {0xce, 0x00},
+    {0xcf, 0x20},
+    {0xd0, 0x40},
+    {0xd1, 0x10},
+    {0xd2, 0x00},
+    {0xd3, 0x00},
+    {0xd4, 0x20},
+    {0xd5, 0x28},
+    {0xd6, 0xa0},
+    {0xd7, 0x2a},
+    {0xd8, 0x00},
+    {0xd9, 0x00},
+    {0xda, 0x00},
+    {0xdb, 0x00},
+    {0xdc, 0x00},
+    {0xdd, 0x00},
+    {0xde, 0x00},
+    {0xdf, 0x00},
+    {0xe0, 0x00},
+    {0xe1, 0xd3},
+    {0xe2, 0xc0},
+    {0xe3, 0x00},
+    {0xe4, 0x00},
+    {0xe5, 0x10},
+    {0xe6, 0x00},
+    {0xe7, 0x12},
+    {0xe8, 0x12},
+    {0xe9, 0x34},
+    {0xea, 0x00},
+    {0xeb, 0xff},
+    {0xec, 0x79},
+    {0xed, 0x20},
+    {0xee, 0x30},
+    {0xef, 0x01},
+    {0xf0, 0x00},
+    {0xf1, 0x3e},
+    {0xf2, 0x00},
+    {0xf3, 0x00},
+    {0xf4, 0x00},
+    {0xf5, 0x00},
+    {0xf6, 0x00},
+    {0xf7, 0x00},
+    {0xf8, 0x00},
+    {0xf9, 0x00},
+    {0xfa, 0x00},
+    {0xfb, 0x00},
+    {0xfc, 0x00},
+    {0xfd, 0x00},
+    {0xfe, 0x00},
+    {0xff, 0x00},
+};
+
+#define CB_VT3253B0_AGC 193
+// For AIROHA
+BYTE byVT3253B0_AGC[CB_VT3253B0_AGC][2] = {
+    {0xF0, 0x00},
+    {0xF1, 0x00},
+    {0xF0, 0x80},
+    {0xF0, 0x01},
+    {0xF1, 0x00},
+    {0xF0, 0x81},
+    {0xF0, 0x02},
+    {0xF1, 0x02},
+    {0xF0, 0x82},
+    {0xF0, 0x03},
+    {0xF1, 0x04},
+    {0xF0, 0x83},
+    {0xF0, 0x03},
+    {0xF1, 0x04},
+    {0xF0, 0x84},
+    {0xF0, 0x04},
+    {0xF1, 0x06},
+    {0xF0, 0x85},
+    {0xF0, 0x05},
+    {0xF1, 0x06},
+    {0xF0, 0x86},
+    {0xF0, 0x06},
+    {0xF1, 0x06},
+    {0xF0, 0x87},
+    {0xF0, 0x07},
+    {0xF1, 0x08},
+    {0xF0, 0x88},
+    {0xF0, 0x08},
+    {0xF1, 0x08},
+    {0xF0, 0x89},
+    {0xF0, 0x09},
+    {0xF1, 0x0A},
+    {0xF0, 0x8A},
+    {0xF0, 0x0A},
+    {0xF1, 0x0A},
+    {0xF0, 0x8B},
+    {0xF0, 0x0B},
+    {0xF1, 0x0C},
+    {0xF0, 0x8C},
+    {0xF0, 0x0C},
+    {0xF1, 0x0C},
+    {0xF0, 0x8D},
+    {0xF0, 0x0D},
+    {0xF1, 0x0E},
+    {0xF0, 0x8E},
+    {0xF0, 0x0E},
+    {0xF1, 0x0E},
+    {0xF0, 0x8F},
+    {0xF0, 0x0F},
+    {0xF1, 0x10},
+    {0xF0, 0x90},
+    {0xF0, 0x10},
+    {0xF1, 0x10},
+    {0xF0, 0x91},
+    {0xF0, 0x11},
+    {0xF1, 0x12},
+    {0xF0, 0x92},
+    {0xF0, 0x12},
+    {0xF1, 0x12},
+    {0xF0, 0x93},
+    {0xF0, 0x13},
+    {0xF1, 0x14},
+    {0xF0, 0x94},
+    {0xF0, 0x14},
+    {0xF1, 0x14},
+    {0xF0, 0x95},
+    {0xF0, 0x15},
+    {0xF1, 0x16},
+    {0xF0, 0x96},
+    {0xF0, 0x16},
+    {0xF1, 0x16},
+    {0xF0, 0x97},
+    {0xF0, 0x17},
+    {0xF1, 0x18},
+    {0xF0, 0x98},
+    {0xF0, 0x18},
+    {0xF1, 0x18},
+    {0xF0, 0x99},
+    {0xF0, 0x19},
+    {0xF1, 0x1A},
+    {0xF0, 0x9A},
+    {0xF0, 0x1A},
+    {0xF1, 0x1A},
+    {0xF0, 0x9B},
+    {0xF0, 0x1B},
+    {0xF1, 0x1C},
+    {0xF0, 0x9C},
+    {0xF0, 0x1C},
+    {0xF1, 0x1C},
+    {0xF0, 0x9D},
+    {0xF0, 0x1D},
+    {0xF1, 0x1E},
+    {0xF0, 0x9E},
+    {0xF0, 0x1E},
+    {0xF1, 0x1E},
+    {0xF0, 0x9F},
+    {0xF0, 0x1F},
+    {0xF1, 0x20},
+    {0xF0, 0xA0},
+    {0xF0, 0x20},
+    {0xF1, 0x20},
+    {0xF0, 0xA1},
+    {0xF0, 0x21},
+    {0xF1, 0x22},
+    {0xF0, 0xA2},
+    {0xF0, 0x22},
+    {0xF1, 0x22},
+    {0xF0, 0xA3},
+    {0xF0, 0x23},
+    {0xF1, 0x24},
+    {0xF0, 0xA4},
+    {0xF0, 0x24},
+    {0xF1, 0x24},
+    {0xF0, 0xA5},
+    {0xF0, 0x25},
+    {0xF1, 0x26},
+    {0xF0, 0xA6},
+    {0xF0, 0x26},
+    {0xF1, 0x26},
+    {0xF0, 0xA7},
+    {0xF0, 0x27},
+    {0xF1, 0x28},
+    {0xF0, 0xA8},
+    {0xF0, 0x28},
+    {0xF1, 0x28},
+    {0xF0, 0xA9},
+    {0xF0, 0x29},
+    {0xF1, 0x2A},
+    {0xF0, 0xAA},
+    {0xF0, 0x2A},
+    {0xF1, 0x2A},
+    {0xF0, 0xAB},
+    {0xF0, 0x2B},
+    {0xF1, 0x2C},
+    {0xF0, 0xAC},
+    {0xF0, 0x2C},
+    {0xF1, 0x2C},
+    {0xF0, 0xAD},
+    {0xF0, 0x2D},
+    {0xF1, 0x2E},
+    {0xF0, 0xAE},
+    {0xF0, 0x2E},
+    {0xF1, 0x2E},
+    {0xF0, 0xAF},
+    {0xF0, 0x2F},
+    {0xF1, 0x30},
+    {0xF0, 0xB0},
+    {0xF0, 0x30},
+    {0xF1, 0x30},
+    {0xF0, 0xB1},
+    {0xF0, 0x31},
+    {0xF1, 0x32},
+    {0xF0, 0xB2},
+    {0xF0, 0x32},
+    {0xF1, 0x32},
+    {0xF0, 0xB3},
+    {0xF0, 0x33},
+    {0xF1, 0x34},
+    {0xF0, 0xB4},
+    {0xF0, 0x34},
+    {0xF1, 0x34},
+    {0xF0, 0xB5},
+    {0xF0, 0x35},
+    {0xF1, 0x36},
+    {0xF0, 0xB6},
+    {0xF0, 0x36},
+    {0xF1, 0x36},
+    {0xF0, 0xB7},
+    {0xF0, 0x37},
+    {0xF1, 0x38},
+    {0xF0, 0xB8},
+    {0xF0, 0x38},
+    {0xF1, 0x38},
+    {0xF0, 0xB9},
+    {0xF0, 0x39},
+    {0xF1, 0x3A},
+    {0xF0, 0xBA},
+    {0xF0, 0x3A},
+    {0xF1, 0x3A},
+    {0xF0, 0xBB},
+    {0xF0, 0x3B},
+    {0xF1, 0x3C},
+    {0xF0, 0xBC},
+    {0xF0, 0x3C},
+    {0xF1, 0x3C},
+    {0xF0, 0xBD},
+    {0xF0, 0x3D},
+    {0xF1, 0x3E},
+    {0xF0, 0xBE},
+    {0xF0, 0x3E},
+    {0xF1, 0x3E},
+    {0xF0, 0xBF},
+    {0xF0, 0x00},
+};
+
+const WORD awcFrameTime[MAX_RATE] =
+{10, 20, 55, 110, 24, 36, 48, 72, 96, 144, 192, 216};
+
+
+/*---------------------  Static Functions  --------------------------*/
+
+static
+ULONG
+s_ulGetRatio(PSDevice pDevice);
+
+static
+VOID
+s_vChangeAntenna(
+    IN PSDevice pDevice
+    );
+
+static
+VOID
+s_vChangeAntenna (
+    IN PSDevice pDevice
+    )
+{
+
+#ifdef PLICE_DEBUG
+       //printk("Enter s_vChangeAntenna:original RxMode is %d,TxMode is %d\n",pDevice->byRxAntennaMode,pDevice->byTxAntennaMode);
+#endif
+    if ( pDevice->dwRxAntennaSel == 0) {
+        pDevice->dwRxAntennaSel=1;
+        if (pDevice->bTxRxAntInv == TRUE)
+            BBvSetRxAntennaMode(pDevice->PortOffset, ANT_A);
+        else
+            BBvSetRxAntennaMode(pDevice->PortOffset, ANT_B);
+    } else {
+        pDevice->dwRxAntennaSel=0;
+        if (pDevice->bTxRxAntInv == TRUE)
+            BBvSetRxAntennaMode(pDevice->PortOffset, ANT_B);
+        else
+            BBvSetRxAntennaMode(pDevice->PortOffset, ANT_A);
+    }
+    if ( pDevice->dwTxAntennaSel == 0) {
+        pDevice->dwTxAntennaSel=1;
+        BBvSetTxAntennaMode(pDevice->PortOffset, ANT_B);
+    } else {
+        pDevice->dwTxAntennaSel=0;
+        BBvSetTxAntennaMode(pDevice->PortOffset, ANT_A);
+    }
+}
+
+
+/*---------------------  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) {
+        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: Read a byte from BASEBAND, by embeded programming
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - I/O base address
+ *      byBBAddr    - address of register in Baseband
+ *  Out:
+ *      pbyData     - data read
+ *
+ * Return Value: TRUE if succeeded; FALSE if failed.
+ *
+ */
+BOOL BBbReadEmbeded (DWORD_PTR dwIoBase, BYTE byBBAddr, PBYTE pbyData)
+{
+    WORD    ww;
+    BYTE    byValue;
+
+    // BB reg offset
+    VNSvOutPortB(dwIoBase + MAC_REG_BBREGADR, byBBAddr);
+
+    // turn on REGR
+    MACvRegBitsOn(dwIoBase, MAC_REG_BBREGCTL, BBREGCTL_REGR);
+    // W_MAX_TIMEOUT is the timeout period
+    for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+        VNSvInPortB(dwIoBase + MAC_REG_BBREGCTL, &byValue);
+        if (BITbIsBitOn(byValue, BBREGCTL_DONE))
+            break;
+    }
+
+    // get BB data
+    VNSvInPortB(dwIoBase + MAC_REG_BBREGDATA, pbyData);
+
+    if (ww == W_MAX_TIMEOUT) {
+        DBG_PORT80(0x30);
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x30)\n");
+        return FALSE;
+    }
+    return TRUE;
+}
+
+
+/*
+ * Description: Write a Byte to BASEBAND, by embeded programming
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - I/O base address
+ *      byBBAddr    - address of register in Baseband
+ *      byData      - data to write
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if succeeded; FALSE if failed.
+ *
+ */
+BOOL BBbWriteEmbeded (DWORD_PTR dwIoBase, BYTE byBBAddr, BYTE byData)
+{
+    WORD    ww;
+    BYTE    byValue;
+
+    // BB reg offset
+    VNSvOutPortB(dwIoBase + MAC_REG_BBREGADR, byBBAddr);
+    // set BB data
+    VNSvOutPortB(dwIoBase + MAC_REG_BBREGDATA, byData);
+
+    // turn on BBREGCTL_REGW
+    MACvRegBitsOn(dwIoBase, MAC_REG_BBREGCTL, BBREGCTL_REGW);
+    // W_MAX_TIMEOUT is the timeout period
+    for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+        VNSvInPortB(dwIoBase + MAC_REG_BBREGCTL, &byValue);
+        if (BITbIsBitOn(byValue, BBREGCTL_DONE))
+            break;
+    }
+
+    if (ww == W_MAX_TIMEOUT) {
+        DBG_PORT80(0x31);
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x31)\n");
+        return FALSE;
+    }
+    return TRUE;
+}
+
+
+/*
+ * Description: Test if all bits are set for the Baseband register
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - I/O base address
+ *      byBBAddr    - address of register in Baseband
+ *      byTestBits  - TestBits
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if all TestBits are set; FALSE otherwise.
+ *
+ */
+BOOL BBbIsRegBitsOn (DWORD_PTR dwIoBase, BYTE byBBAddr, BYTE byTestBits)
+{
+    BYTE byOrgData;
+
+    BBbReadEmbeded(dwIoBase, byBBAddr, &byOrgData);
+    return BITbIsAllBitsOn(byOrgData, byTestBits);
+}
+
+
+/*
+ * Description: Test if all bits are clear for the Baseband register
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - I/O base address
+ *      byBBAddr    - address of register in Baseband
+ *      byTestBits  - TestBits
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if all TestBits are clear; FALSE otherwise.
+ *
+ */
+BOOL BBbIsRegBitsOff (DWORD_PTR dwIoBase, BYTE byBBAddr, BYTE byTestBits)
+{
+    BYTE byOrgData;
+
+    BBbReadEmbeded(dwIoBase, byBBAddr, &byOrgData);
+    return BITbIsAllBitsOff(byOrgData, byTestBits);
+}
+
+/*
+ * Description: VIA VT3253 Baseband chip init function
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - I/O base address
+ *      byRevId     - Revision ID
+ *      byRFType    - RF type
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if succeeded; FALSE if failed.
+ *
+ */
+
+BOOL BBbVT3253Init (PSDevice pDevice)
+{
+    BOOL       bResult = TRUE;
+    int        ii;
+    DWORD_PTR  dwIoBase = pDevice->PortOffset;
+    BYTE       byRFType = pDevice->byRFType;
+    BYTE       byLocalID = pDevice->byLocalID;
+
+    if (byRFType == RF_RFMD2959) {
+        if (byLocalID <= REV_ID_VT3253_A1) {
+            for (ii = 0; ii < CB_VT3253_INIT_FOR_RFMD; ii++) {
+                bResult &= BBbWriteEmbeded(dwIoBase,byVT3253InitTab_RFMD[ii][0],byVT3253InitTab_RFMD[ii][1]);
+            }
+        } else {
+            for (ii = 0; ii < CB_VT3253B0_INIT_FOR_RFMD; ii++) {
+                bResult &= BBbWriteEmbeded(dwIoBase,byVT3253B0_RFMD[ii][0],byVT3253B0_RFMD[ii][1]);
+            }
+            for (ii = 0; ii < CB_VT3253B0_AGC_FOR_RFMD2959; ii++) {
+                   bResult &= BBbWriteEmbeded(dwIoBase,byVT3253B0_AGC4_RFMD2959[ii][0],byVT3253B0_AGC4_RFMD2959[ii][1]);
+            }
+            VNSvOutPortD(dwIoBase + MAC_REG_ITRTMSET, 0x23);
+            MACvRegBitsOn(dwIoBase, MAC_REG_PAPEDELAY, BIT0);
+        }
+        pDevice->abyBBVGA[0] = 0x18;
+        pDevice->abyBBVGA[1] = 0x0A;
+        pDevice->abyBBVGA[2] = 0x0;
+        pDevice->abyBBVGA[3] = 0x0;
+        pDevice->ldBmThreshold[0] = -70;
+        pDevice->ldBmThreshold[1] = -50;
+        pDevice->ldBmThreshold[2] = 0;
+        pDevice->ldBmThreshold[3] = 0;
+    } else if ((byRFType == RF_AIROHA) || (byRFType == RF_AL2230S) ) {
+        for (ii = 0; ii < CB_VT3253B0_INIT_FOR_AIROHA2230; ii++) {
+           bResult &= BBbWriteEmbeded(dwIoBase,byVT3253B0_AIROHA2230[ii][0],byVT3253B0_AIROHA2230[ii][1]);
+       }
+        for (ii = 0; ii < CB_VT3253B0_AGC; ii++) {
+           bResult &= BBbWriteEmbeded(dwIoBase,byVT3253B0_AGC[ii][0],byVT3253B0_AGC[ii][1]);
+       }
+        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 (byRFType == RF_UW2451) {
+        for (ii = 0; ii < CB_VT3253B0_INIT_FOR_UW2451; ii++) {
+               bResult &= BBbWriteEmbeded(dwIoBase,byVT3253B0_UW2451[ii][0],byVT3253B0_UW2451[ii][1]);
+       }
+        for (ii = 0; ii < CB_VT3253B0_AGC; ii++) {
+           bResult &= BBbWriteEmbeded(dwIoBase,byVT3253B0_AGC[ii][0],byVT3253B0_AGC[ii][1]);
+       }
+        VNSvOutPortB(dwIoBase + MAC_REG_ITRTMSET, 0x23);
+        MACvRegBitsOn(dwIoBase, MAC_REG_PAPEDELAY, BIT0);
+
+        pDevice->abyBBVGA[0] = 0x14;
+        pDevice->abyBBVGA[1] = 0x0A;
+        pDevice->abyBBVGA[2] = 0x0;
+        pDevice->abyBBVGA[3] = 0x0;
+        pDevice->ldBmThreshold[0] = -60;
+        pDevice->ldBmThreshold[1] = -50;
+        pDevice->ldBmThreshold[2] = 0;
+        pDevice->ldBmThreshold[3] = 0;
+    } else if (byRFType == RF_UW2452) {
+        for (ii = 0; ii < CB_VT3253B0_INIT_FOR_UW2451; ii++) {
+            bResult &= BBbWriteEmbeded(dwIoBase,byVT3253B0_UW2451[ii][0],byVT3253B0_UW2451[ii][1]);
+       }
+        // Init ANT B select,TX Config CR09 = 0x61->0x45, 0x45->0x41(VC1/VC2 define, make the ANT_A, ANT_B inverted)
+        //bResult &= BBbWriteEmbeded(dwIoBase,0x09,0x41);
+        // Init ANT B select,RX Config CR10 = 0x28->0x2A, 0x2A->0x28(VC1/VC2 define, make the ANT_A, ANT_B inverted)
+        //bResult &= BBbWriteEmbeded(dwIoBase,0x0a,0x28);
+        // Select VC1/VC2, CR215 = 0x02->0x06
+        bResult &= BBbWriteEmbeded(dwIoBase,0xd7,0x06);
+
+        //{{RobertYu:20050125, request by Jack
+        bResult &= BBbWriteEmbeded(dwIoBase,0x90,0x20);
+        bResult &= BBbWriteEmbeded(dwIoBase,0x97,0xeb);
+        //}}
+
+        //{{RobertYu:20050221, request by Jack
+        bResult &= BBbWriteEmbeded(dwIoBase,0xa6,0x00);
+        bResult &= BBbWriteEmbeded(dwIoBase,0xa8,0x30);
+        //}}
+        bResult &= BBbWriteEmbeded(dwIoBase,0xb0,0x58);
+
+        for (ii = 0; ii < CB_VT3253B0_AGC; ii++) {
+           bResult &= BBbWriteEmbeded(dwIoBase,byVT3253B0_AGC[ii][0],byVT3253B0_AGC[ii][1]);
+       }
+        //VNSvOutPortB(dwIoBase + MAC_REG_ITRTMSET, 0x23); // RobertYu: 20050104, 20050131 disable PA_Delay
+        //MACvRegBitsOn(dwIoBase, MAC_REG_PAPEDELAY, BIT0); // RobertYu: 20050104, 20050131 disable PA_Delay
+
+        pDevice->abyBBVGA[0] = 0x14;
+        pDevice->abyBBVGA[1] = 0x0A;
+        pDevice->abyBBVGA[2] = 0x0;
+        pDevice->abyBBVGA[3] = 0x0;
+        pDevice->ldBmThreshold[0] = -60;
+        pDevice->ldBmThreshold[1] = -50;
+        pDevice->ldBmThreshold[2] = 0;
+        pDevice->ldBmThreshold[3] = 0;
+    //}} RobertYu
+
+    } else if (byRFType == RF_VT3226) {
+        for (ii = 0; ii < CB_VT3253B0_INIT_FOR_AIROHA2230; ii++) {
+           bResult &= BBbWriteEmbeded(dwIoBase,byVT3253B0_AIROHA2230[ii][0],byVT3253B0_AIROHA2230[ii][1]);
+       }
+        for (ii = 0; ii < CB_VT3253B0_AGC; ii++) {
+           bResult &= BBbWriteEmbeded(dwIoBase,byVT3253B0_AGC[ii][0],byVT3253B0_AGC[ii][1]);
+       }
+        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;
+        // Fix VT3226 DFC system timing issue
+        MACvSetRFLE_LatchBase(dwIoBase);
+         //{{ RobertYu: 20050104
+    } else if (byRFType == RF_AIROHA7230) {
+        for (ii = 0; ii < CB_VT3253B0_INIT_FOR_AIROHA2230; ii++) {
+           bResult &= BBbWriteEmbeded(dwIoBase,byVT3253B0_AIROHA2230[ii][0],byVT3253B0_AIROHA2230[ii][1]);
+       }
+
+        //{{ RobertYu:20050223, request by JerryChung
+        // Init ANT B select,TX Config CR09 = 0x61->0x45, 0x45->0x41(VC1/VC2 define, make the ANT_A, ANT_B inverted)
+        //bResult &= BBbWriteEmbeded(dwIoBase,0x09,0x41);
+        // Init ANT B select,RX Config CR10 = 0x28->0x2A, 0x2A->0x28(VC1/VC2 define, make the ANT_A, ANT_B inverted)
+        //bResult &= BBbWriteEmbeded(dwIoBase,0x0a,0x28);
+        // Select VC1/VC2, CR215 = 0x02->0x06
+        bResult &= BBbWriteEmbeded(dwIoBase,0xd7,0x06);
+        //}}
+
+        for (ii = 0; ii < CB_VT3253B0_AGC; ii++) {
+           bResult &= BBbWriteEmbeded(dwIoBase,byVT3253B0_AGC[ii][0],byVT3253B0_AGC[ii][1]);
+       }
+        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;
+    //}} RobertYu
+    } else {
+       // No VGA Table now
+       pDevice->bUpdateBBVGA = FALSE;
+        pDevice->abyBBVGA[0] = 0x1C;
+    }
+
+    if (byLocalID > REV_ID_VT3253_A1) {
+        BBbWriteEmbeded(dwIoBase, 0x04, 0x7F);
+        BBbWriteEmbeded(dwIoBase, 0x0D, 0x01);
+    }
+
+    return bResult;
+}
+
+
+
+/*
+ * Description: Read All Baseband Registers
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - I/O base address
+ *      pbyBBRegs   - Point to struct that stores Baseband Registers
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+VOID BBvReadAllRegs (DWORD_PTR dwIoBase, PBYTE pbyBBRegs)
+{
+    int  ii;
+    BYTE byBase = 1;
+    for (ii = 0; ii < BB_MAX_CONTEXT_SIZE; ii++) {
+        BBbReadEmbeded(dwIoBase, (BYTE)(ii*byBase), pbyBBRegs);
+        pbyBBRegs += byBase;
+    }
+}
+
+/*
+ * Description: Turn on BaseBand Loopback mode
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - I/O base address
+ *      bCCK        - If CCK is set
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+
+
+void BBvLoopbackOn (PSDevice pDevice)
+{
+    BYTE      byData;
+    DWORD_PTR dwIoBase = pDevice->PortOffset;
+
+    //CR C9 = 0x00
+    BBbReadEmbeded(dwIoBase, 0xC9, &pDevice->byBBCRc9);//CR201
+    BBbWriteEmbeded(dwIoBase, 0xC9, 0);
+    BBbReadEmbeded(dwIoBase, 0x4D, &pDevice->byBBCR4d);//CR77
+    BBbWriteEmbeded(dwIoBase, 0x4D, 0x90);
+
+    //CR 88 = 0x02(CCK), 0x03(OFDM)
+    BBbReadEmbeded(dwIoBase, 0x88, &pDevice->byBBCR88);//CR136
+
+    if (pDevice->uConnectionRate <= RATE_11M) { //CCK
+        // Enable internal digital loopback: CR33 |= 0000 0001
+        BBbReadEmbeded(dwIoBase, 0x21, &byData);//CR33
+        BBbWriteEmbeded(dwIoBase, 0x21, (BYTE)(byData | 0x01));//CR33
+        // CR154 = 0x00
+        BBbWriteEmbeded(dwIoBase, 0x9A, 0);   //CR154
+
+        BBbWriteEmbeded(dwIoBase, 0x88, 0x02);//CR239
+    }
+    else { //OFDM
+        // Enable internal digital loopback:CR154 |= 0000 0001
+        BBbReadEmbeded(dwIoBase, 0x9A, &byData);//CR154
+        BBbWriteEmbeded(dwIoBase, 0x9A, (BYTE)(byData | 0x01));//CR154
+        // CR33 = 0x00
+        BBbWriteEmbeded(dwIoBase, 0x21, 0);   //CR33
+
+        BBbWriteEmbeded(dwIoBase, 0x88, 0x03);//CR239
+    }
+
+    //CR14 = 0x00
+    BBbWriteEmbeded(dwIoBase, 0x0E, 0);//CR14
+
+    // Disable TX_IQUN
+    BBbReadEmbeded(pDevice->PortOffset, 0x09, &pDevice->byBBCR09);
+    BBbWriteEmbeded(pDevice->PortOffset, 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;
+    DWORD_PTR dwIoBase = pDevice->PortOffset;
+
+    BBbWriteEmbeded(dwIoBase, 0xC9, pDevice->byBBCRc9);//CR201
+    BBbWriteEmbeded(dwIoBase, 0x88, pDevice->byBBCR88);//CR136
+    BBbWriteEmbeded(dwIoBase, 0x09, pDevice->byBBCR09);//CR136
+    BBbWriteEmbeded(dwIoBase, 0x4D, pDevice->byBBCR4d);//CR77
+
+    if (pDevice->uConnectionRate <= RATE_11M) { // CCK
+        // Set the CR33 Bit2 to disable internal Loopback.
+        BBbReadEmbeded(dwIoBase, 0x21, &byData);//CR33
+        BBbWriteEmbeded(dwIoBase, 0x21, (BYTE)(byData & 0xFE));//CR33
+    }
+    else { // OFDM
+        BBbReadEmbeded(dwIoBase, 0x9A, &byData);//CR154
+        BBbWriteEmbeded(dwIoBase, 0x9A, (BYTE)(byData & 0xFE));//CR154
+    }
+    BBbReadEmbeded(dwIoBase, 0x0E, &byData);//CR14
+    BBbWriteEmbeded(dwIoBase, 0x0E, (BYTE)(byData | 0x80));//CR14
+
+}
+
+
+
+/*
+ * Description: Set ShortSlotTime mode
+ *
+ * Parameters:
+ *  In:
+ *      pDevice     - Device Structure
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+VOID
+BBvSetShortSlotTime (PSDevice pDevice)
+{
+    BYTE byBBRxConf=0;
+    BYTE byBBVGA=0;
+
+    BBbReadEmbeded(pDevice->PortOffset, 0x0A, &byBBRxConf);//CR10
+
+    if (pDevice->bShortSlotTime) {
+        byBBRxConf &= 0xDF;//1101 1111
+    } else {
+        byBBRxConf |= 0x20;//0010 0000
+    }
+
+    // patch for 3253B0 Baseband with Cardbus module
+    BBbReadEmbeded(pDevice->PortOffset, 0xE7, &byBBVGA);
+    if (byBBVGA == pDevice->abyBBVGA[0]) {
+        byBBRxConf |= 0x20;//0010 0000
+    }
+
+    BBbWriteEmbeded(pDevice->PortOffset, 0x0A, byBBRxConf);//CR10
+
+}
+
+VOID BBvSetVGAGainOffset(PSDevice pDevice, BYTE byData)
+{
+    BYTE byBBRxConf=0;
+
+    BBbWriteEmbeded(pDevice->PortOffset, 0xE7, byData);
+
+    BBbReadEmbeded(pDevice->PortOffset, 0x0A, &byBBRxConf);//CR10
+    // patch for 3253B0 Baseband with Cardbus module
+    if (byData == pDevice->abyBBVGA[0]) {
+        byBBRxConf |= 0x20;//0010 0000
+    } else if (pDevice->bShortSlotTime) {
+        byBBRxConf &= 0xDF;//1101 1111
+    } else {
+        byBBRxConf |= 0x20;//0010 0000
+    }
+    pDevice->byBBVGACurrent = byData;
+    BBbWriteEmbeded(pDevice->PortOffset, 0x0A, byBBRxConf);//CR10
+}
+
+
+/*
+ * Description: Baseband SoftwareReset
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - I/O base address
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+VOID
+BBvSoftwareReset (DWORD_PTR dwIoBase)
+{
+    BBbWriteEmbeded(dwIoBase, 0x50, 0x40);
+    BBbWriteEmbeded(dwIoBase, 0x50, 0);
+    BBbWriteEmbeded(dwIoBase, 0x9C, 0x01);
+    BBbWriteEmbeded(dwIoBase, 0x9C, 0);
+}
+
+/*
+ * Description: Baseband Power Save Mode ON
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - I/O base address
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+VOID
+BBvPowerSaveModeON (DWORD_PTR dwIoBase)
+{
+    BYTE byOrgData;
+
+    BBbReadEmbeded(dwIoBase, 0x0D, &byOrgData);
+    byOrgData |= BIT0;
+    BBbWriteEmbeded(dwIoBase, 0x0D, byOrgData);
+}
+
+/*
+ * Description: Baseband Power Save Mode OFF
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - I/O base address
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+VOID
+BBvPowerSaveModeOFF (DWORD_PTR dwIoBase)
+{
+    BYTE byOrgData;
+
+    BBbReadEmbeded(dwIoBase, 0x0D, &byOrgData);
+    byOrgData &= ~(BIT0);
+    BBbWriteEmbeded(dwIoBase, 0x0D, byOrgData);
+}
+
+/*
+ * Description: Set Tx Antenna mode
+ *
+ * Parameters:
+ *  In:
+ *      pDevice          - Device Structure
+ *      byAntennaMode    - Antenna Mode
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+
+VOID
+BBvSetTxAntennaMode (DWORD_PTR dwIoBase, BYTE byAntennaMode)
+{
+    BYTE byBBTxConf;
+
+#ifdef PLICE_DEBUG
+       //printk("Enter BBvSetTxAntennaMode\n");
+#endif
+    BBbReadEmbeded(dwIoBase, 0x09, &byBBTxConf);//CR09
+    if (byAntennaMode == ANT_DIVERSITY) {
+        // bit 1 is diversity
+        byBBTxConf |= 0x02;
+    } else if (byAntennaMode == ANT_A) {
+        // bit 2 is ANTSEL
+        byBBTxConf &= 0xF9; // 1111 1001
+    } else if (byAntennaMode == ANT_B) {
+#ifdef PLICE_DEBUG
+       //printk("BBvSetTxAntennaMode:ANT_B\n");
+#endif
+        byBBTxConf &= 0xFD; // 1111 1101
+        byBBTxConf |= 0x04;
+    }
+    BBbWriteEmbeded(dwIoBase, 0x09, byBBTxConf);//CR09
+}
+
+
+
+
+/*
+ * Description: Set Rx Antenna mode
+ *
+ * Parameters:
+ *  In:
+ *      pDevice          - Device Structure
+ *      byAntennaMode    - Antenna Mode
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+
+VOID
+BBvSetRxAntennaMode (DWORD_PTR dwIoBase, BYTE byAntennaMode)
+{
+    BYTE byBBRxConf;
+
+    BBbReadEmbeded(dwIoBase, 0x0A, &byBBRxConf);//CR10
+    if (byAntennaMode == ANT_DIVERSITY) {
+        byBBRxConf |= 0x01;
+
+    } else if (byAntennaMode == ANT_A) {
+        byBBRxConf &= 0xFC; // 1111 1100
+    } else if (byAntennaMode == ANT_B) {
+        byBBRxConf &= 0xFE; // 1111 1110
+        byBBRxConf |= 0x02;
+    }
+    BBbWriteEmbeded(dwIoBase, 0x0A, byBBRxConf);//CR10
+}
+
+
+/*
+ * Description: BBvSetDeepSleep
+ *
+ * Parameters:
+ *  In:
+ *      pDevice          - Device Structure
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+VOID
+BBvSetDeepSleep (DWORD_PTR dwIoBase, BYTE byLocalID)
+{
+    BBbWriteEmbeded(dwIoBase, 0x0C, 0x17);//CR12
+    BBbWriteEmbeded(dwIoBase, 0x0D, 0xB9);//CR13
+}
+
+VOID
+BBvExitDeepSleep (DWORD_PTR dwIoBase, BYTE byLocalID)
+{
+    BBbWriteEmbeded(dwIoBase, 0x0C, 0x00);//CR12
+    BBbWriteEmbeded(dwIoBase, 0x0D, 0x01);//CR13
+}
+
+
+
+static
+ULONG
+s_ulGetRatio (PSDevice pDevice)
+{
+ULONG   ulRatio = 0;
+ULONG   ulMaxPacket;
+ULONG   ulPacketNum;
+
+    //This is a thousand-ratio
+    ulMaxPacket = pDevice->uNumSQ3[RATE_54M];
+    if ( pDevice->uNumSQ3[RATE_54M] != 0 ) {
+        ulPacketNum = pDevice->uNumSQ3[RATE_54M];
+        ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt);
+        //ulRatio = (pDevice->uNumSQ3[RATE_54M] * 1000 / pDevice->uDiversityCnt);
+        ulRatio += TOP_RATE_54M;
+    }
+    if ( pDevice->uNumSQ3[RATE_48M] > ulMaxPacket ) {
+        ulPacketNum = pDevice->uNumSQ3[RATE_54M] + pDevice->uNumSQ3[RATE_48M];
+        ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt);
+        //ulRatio = (pDevice->uNumSQ3[RATE_48M] * 1000 / pDevice->uDiversityCnt);
+        ulRatio += TOP_RATE_48M;
+        ulMaxPacket = pDevice->uNumSQ3[RATE_48M];
+    }
+    if ( pDevice->uNumSQ3[RATE_36M] > ulMaxPacket ) {
+        ulPacketNum = pDevice->uNumSQ3[RATE_54M] + pDevice->uNumSQ3[RATE_48M] +
+                      pDevice->uNumSQ3[RATE_36M];
+        ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt);
+        //ulRatio = (pDevice->uNumSQ3[RATE_36M] * 1000 / pDevice->uDiversityCnt);
+        ulRatio += TOP_RATE_36M;
+        ulMaxPacket = pDevice->uNumSQ3[RATE_36M];
+    }
+    if ( pDevice->uNumSQ3[RATE_24M] > ulMaxPacket ) {
+        ulPacketNum = pDevice->uNumSQ3[RATE_54M] + pDevice->uNumSQ3[RATE_48M] +
+                      pDevice->uNumSQ3[RATE_36M] + pDevice->uNumSQ3[RATE_24M];
+        ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt);
+        //ulRatio = (pDevice->uNumSQ3[RATE_24M] * 1000 / pDevice->uDiversityCnt);
+        ulRatio += TOP_RATE_24M;
+        ulMaxPacket = pDevice->uNumSQ3[RATE_24M];
+    }
+    if ( pDevice->uNumSQ3[RATE_18M] > ulMaxPacket ) {
+        ulPacketNum = pDevice->uNumSQ3[RATE_54M] + pDevice->uNumSQ3[RATE_48M] +
+                      pDevice->uNumSQ3[RATE_36M] + pDevice->uNumSQ3[RATE_24M] +
+                      pDevice->uNumSQ3[RATE_18M];
+        ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt);
+        //ulRatio = (pDevice->uNumSQ3[RATE_18M] * 1000 / pDevice->uDiversityCnt);
+        ulRatio += TOP_RATE_18M;
+        ulMaxPacket = pDevice->uNumSQ3[RATE_18M];
+    }
+    if ( pDevice->uNumSQ3[RATE_12M] > ulMaxPacket ) {
+        ulPacketNum = pDevice->uNumSQ3[RATE_54M] + pDevice->uNumSQ3[RATE_48M] +
+                      pDevice->uNumSQ3[RATE_36M] + pDevice->uNumSQ3[RATE_24M] +
+                      pDevice->uNumSQ3[RATE_18M] + pDevice->uNumSQ3[RATE_12M];
+        ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt);
+        //ulRatio = (pDevice->uNumSQ3[RATE_12M] * 1000 / pDevice->uDiversityCnt);
+        ulRatio += TOP_RATE_12M;
+        ulMaxPacket = pDevice->uNumSQ3[RATE_12M];
+    }
+    if ( pDevice->uNumSQ3[RATE_11M] > ulMaxPacket ) {
+        ulPacketNum = pDevice->uDiversityCnt - pDevice->uNumSQ3[RATE_1M] -
+                      pDevice->uNumSQ3[RATE_2M] - pDevice->uNumSQ3[RATE_5M] -
+                      pDevice->uNumSQ3[RATE_6M] - pDevice->uNumSQ3[RATE_9M];
+        ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt);
+        //ulRatio = (pDevice->uNumSQ3[RATE_11M] * 1000 / pDevice->uDiversityCnt);
+        ulRatio += TOP_RATE_11M;
+        ulMaxPacket = pDevice->uNumSQ3[RATE_11M];
+    }
+    if ( pDevice->uNumSQ3[RATE_9M] > ulMaxPacket ) {
+        ulPacketNum = pDevice->uDiversityCnt - pDevice->uNumSQ3[RATE_1M] -
+                      pDevice->uNumSQ3[RATE_2M] - pDevice->uNumSQ3[RATE_5M] -
+                      pDevice->uNumSQ3[RATE_6M];
+        ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt);
+        //ulRatio = (pDevice->uNumSQ3[RATE_9M] * 1000 / pDevice->uDiversityCnt);
+        ulRatio += TOP_RATE_9M;
+        ulMaxPacket = pDevice->uNumSQ3[RATE_9M];
+    }
+    if ( pDevice->uNumSQ3[RATE_6M] > ulMaxPacket ) {
+        ulPacketNum = pDevice->uDiversityCnt - pDevice->uNumSQ3[RATE_1M] -
+                      pDevice->uNumSQ3[RATE_2M] - pDevice->uNumSQ3[RATE_5M];
+        ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt);
+        //ulRatio = (pDevice->uNumSQ3[RATE_6M] * 1000 / pDevice->uDiversityCnt);
+        ulRatio += TOP_RATE_6M;
+        ulMaxPacket = pDevice->uNumSQ3[RATE_6M];
+    }
+    if ( pDevice->uNumSQ3[RATE_5M] > ulMaxPacket ) {
+        ulPacketNum = pDevice->uDiversityCnt - pDevice->uNumSQ3[RATE_1M] -
+                      pDevice->uNumSQ3[RATE_2M];
+        ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt);
+        //ulRatio = (pDevice->uNumSQ3[RATE_5M] * 1000 / pDevice->uDiversityCnt);
+        ulRatio += TOP_RATE_55M;
+        ulMaxPacket = pDevice->uNumSQ3[RATE_5M];
+    }
+    if ( pDevice->uNumSQ3[RATE_2M] > ulMaxPacket ) {
+        ulPacketNum = pDevice->uDiversityCnt - pDevice->uNumSQ3[RATE_1M];
+        ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt);
+        //ulRatio = (pDevice->uNumSQ3[RATE_2M]  * 1000 / pDevice->uDiversityCnt);
+        ulRatio += TOP_RATE_2M;
+        ulMaxPacket = pDevice->uNumSQ3[RATE_2M];
+    }
+    if ( pDevice->uNumSQ3[RATE_1M] > ulMaxPacket ) {
+        ulPacketNum = pDevice->uDiversityCnt;
+        ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt);
+        //ulRatio = (pDevice->uNumSQ3[RATE_1M]  * 1000 / pDevice->uDiversityCnt);
+        ulRatio += TOP_RATE_1M;
+    }
+
+    return ulRatio;
+}
+
+
+VOID
+BBvClearAntDivSQ3Value (PSDevice pDevice)
+{
+    UINT    ii;
+
+    pDevice->uDiversityCnt = 0;
+    for (ii = 0; ii < MAX_RATE; ii++) {
+        pDevice->uNumSQ3[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)
+{
+
+    if ((byRxRate >= MAX_RATE) || (pDevice->wAntDiversityMaxRate >= MAX_RATE)) {
+        return;
+    }
+    pDevice->uDiversityCnt++;
+   // DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->uDiversityCnt = %d\n", (int)pDevice->uDiversityCnt);
+
+    pDevice->uNumSQ3[byRxRate]++;
+
+    if (pDevice->byAntennaState == 0) {
+
+        if (pDevice->uDiversityCnt > pDevice->ulDiversityNValue) {
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ulDiversityNValue=[%d],54M-[%d]\n",
+                          (int)pDevice->ulDiversityNValue, (int)pDevice->uNumSQ3[(int)pDevice->wAntDiversityMaxRate]);
+
+            if (pDevice->uNumSQ3[pDevice->wAntDiversityMaxRate] < pDevice->uDiversityCnt/2) {
+
+                pDevice->ulRatio_State0 = s_ulGetRatio(pDevice);
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"SQ3_State0, rate = [%08x]\n", (int)pDevice->ulRatio_State0);
+
+                if ( pDevice->byTMax == 0 )
+                    return;
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"1.[%08x], uNumSQ3[%d]=%d, %d\n",
+                              (int)pDevice->ulRatio_State0, (int)pDevice->wAntDiversityMaxRate,
+                              (int)pDevice->uNumSQ3[(int)pDevice->wAntDiversityMaxRate], (int)pDevice->uDiversityCnt);
+#ifdef PLICE_DEBUG
+               //printk("BBvAntennaDiversity1:call s_vChangeAntenna\n");
+#endif
+               s_vChangeAntenna(pDevice);
+                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);
+            }
+            BBvClearAntDivSQ3Value(pDevice);
+
+        }
+    } else { //byAntennaState == 1
+
+        if (pDevice->uDiversityCnt > pDevice->ulDiversityMValue) {
+
+            del_timer(&pDevice->TimerSQ3Tmax1);
+
+            pDevice->ulRatio_State1 = s_ulGetRatio(pDevice);
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"RX:SQ3_State1, rate0 = %08x,rate1 = %08x\n",
+                          (int)pDevice->ulRatio_State0,(int)pDevice->ulRatio_State1);
+
+            if (pDevice->ulRatio_State1 < pDevice->ulRatio_State0) {
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"2.[%08x][%08x], uNumSQ3[%d]=%d, %d\n",
+                              (int)pDevice->ulRatio_State0, (int)pDevice->ulRatio_State1,
+                              (int)pDevice->wAntDiversityMaxRate,
+                              (int)pDevice->uNumSQ3[(int)pDevice->wAntDiversityMaxRate], (int)pDevice->uDiversityCnt);
+#ifdef PLICE_DEBUG
+               //printk("BBvAntennaDiversity2:call s_vChangeAntenna\n");
+#endif
+                               s_vChangeAntenna(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);
+            }
+            pDevice->byAntennaState = 0;
+            BBvClearAntDivSQ3Value(pDevice);
+        }
+    } //byAntennaState
+}
+
+/*+
+ *
+ * Description:
+ *  Timer for SQ3 antenna diversity
+ *
+ * Parameters:
+ *  In:
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+-*/
+
+VOID
+TimerSQ3CallBack (
+    IN  HANDLE      hDeviceContext
+    )
+{
+    PSDevice        pDevice = (PSDevice)hDeviceContext;
+
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"TimerSQ3CallBack...");
+
+
+    spin_lock_irq(&pDevice->lock);
+
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"3.[%08x][%08x], %d\n",(int)pDevice->ulRatio_State0, (int)pDevice->ulRatio_State1, (int)pDevice->uDiversityCnt);
+#ifdef PLICE_DEBUG
+               //printk("TimerSQ3CallBack1:call s_vChangeAntenna\n");
+#endif
+
+    s_vChangeAntenna(pDevice);
+    pDevice->byAntennaState = 0;
+    BBvClearAntDivSQ3Value(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
+TimerState1CallBack (
+    IN  HANDLE      hDeviceContext
+    )
+{
+    PSDevice        pDevice = (PSDevice)hDeviceContext;
+
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"TimerState1CallBack...");
+
+    spin_lock_irq(&pDevice->lock);
+    if (pDevice->uDiversityCnt < pDevice->ulDiversityMValue/100) {
+#ifdef PLICE_DEBUG
+               //printk("TimerSQ3CallBack2:call s_vChangeAntenna\n");
+#endif
+
+               s_vChangeAntenna(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);
+    } else {
+        pDevice->ulRatio_State1 = s_ulGetRatio(pDevice);
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"SQ3_State1, rate0 = %08x,rate1 = %08x\n",
+                      (int)pDevice->ulRatio_State0,(int)pDevice->ulRatio_State1);
+
+        if ( pDevice->ulRatio_State1 < pDevice->ulRatio_State0 ) {
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"2.[%08x][%08x], uNumSQ3[%d]=%d, %d\n",
+                          (int)pDevice->ulRatio_State0, (int)pDevice->ulRatio_State1,
+                          (int)pDevice->wAntDiversityMaxRate,
+                          (int)pDevice->uNumSQ3[(int)pDevice->wAntDiversityMaxRate], (int)pDevice->uDiversityCnt);
+#ifdef PLICE_DEBUG
+               //printk("TimerSQ3CallBack3:call s_vChangeAntenna\n");
+#endif
+
+                       s_vChangeAntenna(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);
+        }
+    }
+    pDevice->byAntennaState = 0;
+    BBvClearAntDivSQ3Value(pDevice);
+    spin_unlock_irq(&pDevice->lock);
+
+    return;
+}
+
diff --git a/drivers/staging/vt6655/baseband.h b/drivers/staging/vt6655/baseband.h
new file mode 100644 (file)
index 0000000..09cf4f9
--- /dev/null
@@ -0,0 +1,198 @@
+/*
+ * 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
+ *
+ */
+
+
+#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 -------------------------*/
+
+//
+// Registers in the BASEBAND
+//
+#define BB_MAX_CONTEXT_SIZE 256
+
+
+//
+// Baseband RF pair definition in eeprom (Bits 6..0)
+//
+
+/*
+#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
+
+
+//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 PREAMBLE_LONG   0
+#define PREAMBLE_SHORT  1
+
+
+#define F5G             0
+#define F2_4G           1
+
+#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 ------------------------------*/
+
+
+
+#define BBvClearFOE(dwIoBase)                               \
+{                                                           \
+    BBbWriteEmbeded(dwIoBase, 0xB1, 0);                     \
+}
+
+#define BBvSetFOE(dwIoBase)                                 \
+{                                                           \
+    BBbWriteEmbeded(dwIoBase, 0xB1, 0x0C);                  \
+}
+
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+#ifdef __cplusplus
+extern "C" {                            /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+UINT
+BBuGetFrameTime(
+    IN BYTE byPreambleType,
+    IN BYTE byPktType,
+    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
+    );
+
+BOOL BBbReadEmbeded(DWORD_PTR dwIoBase, BYTE byBBAddr, PBYTE pbyData);
+BOOL BBbWriteEmbeded(DWORD_PTR dwIoBase, BYTE byBBAddr, BYTE byData);
+
+VOID BBvReadAllRegs(DWORD_PTR dwIoBase, PBYTE pbyBBRegs);
+void BBvLoopbackOn(PSDevice pDevice);
+void BBvLoopbackOff(PSDevice pDevice);
+void BBvSetShortSlotTime(PSDevice pDevice);
+BOOL BBbIsRegBitsOn(DWORD_PTR dwIoBase, BYTE byBBAddr, BYTE byTestBits);
+BOOL BBbIsRegBitsOff(DWORD_PTR dwIoBase, BYTE byBBAddr, BYTE byTestBits);
+VOID BBvSetVGAGainOffset(PSDevice pDevice, BYTE byData);
+
+// VT3253 Baseband
+BOOL BBbVT3253Init(PSDevice pDevice);
+VOID BBvSoftwareReset(DWORD_PTR dwIoBase);
+VOID BBvPowerSaveModeON(DWORD_PTR dwIoBase);
+VOID BBvPowerSaveModeOFF(DWORD_PTR dwIoBase);
+VOID BBvSetTxAntennaMode(DWORD_PTR dwIoBase, BYTE byAntennaMode);
+VOID BBvSetRxAntennaMode(DWORD_PTR dwIoBase, BYTE byAntennaMode);
+VOID BBvSetDeepSleep(DWORD_PTR dwIoBase, BYTE byLocalID);
+VOID BBvExitDeepSleep(DWORD_PTR dwIoBase, BYTE byLocalID);
+
+// timer for antenna diversity
+VOID
+TimerSQ3CallBack(
+    IN  HANDLE hDeviceContext
+    );
+VOID
+TimerState1CallBack(
+    IN  HANDLE hDeviceContext
+    );
+
+void BBvAntennaDiversity(PSDevice pDevice, BYTE byRxRate, BYTE bySQ3);
+VOID
+BBvClearAntDivSQ3Value (PSDevice pDevice);
+
+
+#ifdef __cplusplus
+}                /* End of extern "C" { */
+#endif /* __cplusplus */
+
+
+#endif // __BASEBAND_H__
+
+
+
diff --git a/drivers/staging/vt6655/bssdb.c b/drivers/staging/vt6655/bssdb.c
new file mode 100644 (file)
index 0000000..4bac7b6
--- /dev/null
@@ -0,0 +1,1791 @@
+/*
+ * 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
+ *      BSSDBbIsSTAInNodeDB - 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(__TBIT_H__)
+#include "tbit.h"
+#endif//chester
+#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
+//DavidWang
+#if !defined(__IOWPA_H__)
+#include "iowpa.h"
+#endif
+
+//#define      PLICE_DEBUG
+/*---------------------  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
+    );
+
+#ifdef Calcu_LinkQual
+VOID s_uCalculateLinkQual(
+    IN HANDLE hDeviceContext
+    );
+#endif
+
+
+VOID s_vCheckPreEDThreshold(
+    IN HANDLE hDeviceContext
+    );
+/*---------------------  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->pMgmt;
+    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) {
+        DEVICE_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) {
+        // match BSSID first
+        for (ii = 0; ii <MAX_BSS_NUM; ii++) {
+            pCurrBSS = &(pMgmt->sBSSList[ii]);
+if(pDevice->bLinkPass==FALSE) 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<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
+                    DEVICE_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
+                        DEVICE_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;
+                    }
+                }
+*/
+                if (pSelect == NULL) {
+                    pSelect = pCurrBSS;
+                } else {
+                    // compare RSSI, select signal strong one
+                    if (pCurrBSS->uRSSI < pSelect->uRSSI) {
+                        pSelect = pCurrBSS;
+                    }
+                }
+            }
+        }
+        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->pMgmt;
+    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)) {
+               // 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->pMgmt;
+    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 == NULL)
+//                    return pBSSList;
+                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->pMgmt;
+    PSRxMgmtPacket  pRxPacket = (PSRxMgmtPacket)pRxPacketContext;
+    PKnownBSS       pBSSList = NULL;
+    UINT            ii;
+    BOOL            bParsingQuiet = FALSE;
+    PWLAN_IE_QUIET  pQuiet = NULL;
+
+
+
+    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){
+        DEVICE_PRT(MSG_LEVEL_NOTICE, 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);
+        DEVICE_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;
+        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;
+    PSDevice        pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject    pMgmt = pDevice->pMgmt;
+    PSRxMgmtPacket  pRxPacket = (PSRxMgmtPacket)pRxPacketContext;
+    LONG            ldBm;
+    BOOL            bParsingQuiet = FALSE;
+    PWLAN_IE_QUIET  pQuiet = NULL;
+
+
+
+    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;
+//    DEVICE_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;
+        for(ii=0;ii<RSSI_STAT_COUNT;ii++) {
+            if (pBSSList->ldBmAverage[ii] != 0) {
+                pBSSList->ldBmMAX = max(pBSSList->ldBmAverage[ii], ldBm);
+            }
+        }
+    }
+
+    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;
+    memcpy(pBSSList->abyIEs, pbyIEs, pBSSList->uIELength);
+
+    return TRUE;
+}
+
+
+
+
+
+/*+
+ *
+ * Routine Description:
+ *    Search Node DB table to find the index of matched DstAddr
+ *
+ * Return Value:
+ *    None
+ *
+-*/
+
+BOOL
+BSSDBbIsSTAInNodeDB(
+    IN PVOID pMgmtObject,
+    IN PBYTE abyDstAddr,
+    OUT PUINT puNodeIndex
+    )
+{
+    PSMgmtObject    pMgmt = (PSMgmtObject) pMgmtObject;
+    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->pMgmt;
+    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;
+        DEVICE_PRT(MSG_LEVEL_NOTICE, 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;
+    DEVICE_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->pMgmt;
+    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->pMgmt;
+    UINT            uRateLen = WLAN_RATES_MAXLEN;
+
+    memset(&pMgmt->sNodeDBTable[0], 0, sizeof(KnownNodeDB));
+
+    pMgmt->sNodeDBTable[0].bActive = TRUE;
+    if (pDevice->eCurrentPHYType == PHY_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;
+#ifdef PLICE_DEBUG
+       printk("BSSvUpdateAPNode:MaxSuppRate is %d\n",pMgmt->sNodeDBTable[0].wMaxSuppRate);
+#endif
+    // Auto rate fallback function initiation.
+    // RATEbInit(pDevice);
+    DEVICE_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->pMgmt;
+
+    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;
+#ifdef PLICE_DEBUG
+       printk("BSSvAddMultiCastNode:pMgmt->sNodeDBTable[0].wTxDataRate is %d\n",pMgmt->sNodeDBTable[0].wTxDataRate);
+#endif
+    pMgmt->sNodeDBTable[0].uRatePollTimeout = FALLBACK_POLL_SECOND;
+
+};
+
+
+
+
+
+/*+
+ *
+ * Routine Description:
+ *
+ *
+ *  Second call back function to update Node DB info & AP link status
+ *
+ *
+ * Return Value:
+ *    none.
+ *
+-*/
+ //2008-4-14 <add> by chester for led issue
+ #ifdef FOR_LED_ON_NOTEBOOK
+BOOL cc=FALSE;
+UINT status;
+#endif
+VOID
+BSSvSecondCallBack(
+    IN  HANDLE hDeviceContext
+    )
+{
+    PSDevice        pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject    pMgmt = pDevice->pMgmt;
+    UINT            ii;
+    PWLAN_IE_SSID   pItemSSID, pCurrSSID;
+    UINT            uSleepySTACnt = 0;
+    UINT            uNonShortSlotSTACnt = 0;
+    UINT            uLongPreambleSTACnt = 0;
+viawget_wpa_header* wpahdr;
+
+    spin_lock_irq(&pDevice->lock);
+
+    pDevice->uAssocCount = 0;
+
+    pDevice->byERPFlag &=
+        ~(WLAN_SET_ERP_BARKER_MODE(1) | WLAN_SET_ERP_NONERP_PRESENT(1));
+ //2008-4-14 <add> by chester for led issue
+#ifdef FOR_LED_ON_NOTEBOOK
+MACvGPIOIn(pDevice->PortOffset, &pDevice->byGPIO);
+if (((BITbIsBitOff(pDevice->byGPIO,GPIO0_DATA)&&(pDevice->bHWRadioOff == FALSE))||(BITbIsBitOn(pDevice->byGPIO,GPIO0_DATA)&&(pDevice->bHWRadioOff == TRUE)))&&(cc==FALSE)){
+cc=TRUE;
+}
+else if(cc==TRUE){
+
+if(pDevice->bHWRadioOff == TRUE){
+            if (BITbIsBitOff(pDevice->byGPIO,GPIO0_DATA))
+//||(BITbIsBitOff(pDevice->byGPIO,GPIO0_DATA) && BITbIsBitOn(pDevice->byRadioCtl, EEP_RADIOCTL_INV)))
+{if(status==1) goto start;
+status=1;
+CARDbRadioPowerOff(pDevice);
+                pMgmt->sNodeDBTable[0].bActive = FALSE;
+                pMgmt->eCurrMode = WMAC_MODE_STANDBY;
+                pMgmt->eCurrState = WMAC_STATE_IDLE;
+                //netif_stop_queue(pDevice->dev);
+                pDevice->bLinkPass = FALSE;
+
+}
+  if (BITbIsBitOn(pDevice->byGPIO,GPIO0_DATA))
+//||(BITbIsBitOff(pDevice->byGPIO,GPIO0_DATA) && BITbIsBitOn(pDevice->byRadioCtl, EEP_RADIOCTL_INV)))
+{if(status==2) goto start;
+status=2;
+CARDbRadioPowerOn(pDevice);
+} }
+else{
+            if (BITbIsBitOn(pDevice->byGPIO,GPIO0_DATA))
+//||(BITbIsBitOff(pDevice->byGPIO,GPIO0_DATA) && BITbIsBitOn(pDevice->byRadioCtl, EEP_RADIOCTL_INV)))
+{if(status==3) goto start;
+status=3;
+CARDbRadioPowerOff(pDevice);
+                pMgmt->sNodeDBTable[0].bActive = FALSE;
+                pMgmt->eCurrMode = WMAC_MODE_STANDBY;
+                pMgmt->eCurrState = WMAC_STATE_IDLE;
+                //netif_stop_queue(pDevice->dev);
+                pDevice->bLinkPass = FALSE;
+
+}
+  if (BITbIsBitOff(pDevice->byGPIO,GPIO0_DATA))
+//||(BITbIsBitOff(pDevice->byGPIO,GPIO0_DATA) && BITbIsBitOn(pDevice->byRadioCtl, EEP_RADIOCTL_INV)))
+{if(status==4) goto start;
+status=4;
+CARDbRadioPowerOn(pDevice);
+} }
+}
+start:
+#endif
+
+
+    if (pDevice->wUseProtectCntDown > 0) {
+        pDevice->wUseProtectCntDown --;
+    }
+    else {
+        // disable protect mode
+        pDevice->byERPFlag &= ~(WLAN_SET_ERP_USE_PROTECTION(1));
+    }
+
+{
+       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;
+                       printk("wireless_send_event--->SIOCGIWAP(disassociated)\n");
+                       wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
+                       }
+                    #endif
+     }
+   else if(pDevice->bLinkPass == TRUE)
+       pDevice->byReAssocCount = 0;
+}
+
+#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);
+                    DEVICE_PRT(MSG_LEVEL_NOTICE, 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)
+#ifdef PLICE_DEBUG
+               printk("SecondCallback:Before:TxDataRate is %d\n",pMgmt->sNodeDBTable[0].wTxDataRate);
+#endif
+                        RATEvTxRateFallBack((PVOID)pDevice, &(pMgmt->sNodeDBTable[ii]));
+#ifdef PLICE_DEBUG
+               printk("SecondCallback:After:TxDataRate is %d\n",pMgmt->sNodeDBTable[0].wTxDataRate);
+#endif
+
+               }
+
+            }
+
+            // check if pending PS queue
+            if (pMgmt->sNodeDBTable[ii].wEnQueueCnt != 0) {
+                DEVICE_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);
+                    DEVICE_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->eCurrentPHYType == PHY_TYPE_11G)) {
+
+        // on/off protect mode
+        if (WLAN_GET_ERP_USE_PROTECTION(pDevice->byERPFlag)) {
+            if (!pDevice->bProtectMode) {
+                MACvEnableProtectMD(pDevice->PortOffset);
+                pDevice->bProtectMode = TRUE;
+            }
+        }
+        else {
+            if (pDevice->bProtectMode) {
+                MACvDisableProtectMD(pDevice->PortOffset);
+                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->PortOffset);
+                pDevice->bBarkerPreambleMd = TRUE;
+            }
+        }
+        else {
+            if (pDevice->bBarkerPreambleMd) {
+                MACvDisableBarkerPreambleMd(pDevice->PortOffset);
+                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;
+//printk("pCurrSSID=%s\n",pCurrSSID->abySSID);
+    if ((pMgmt->eCurrMode == WMAC_MODE_STANDBY) ||
+        (pMgmt->eCurrMode == WMAC_MODE_ESS_STA)) {
+
+        if (pMgmt->sNodeDBTable[0].bActive) { // Assoc with BSS
+           // DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO "Callback inactive Count = [%d]\n", pMgmt->sNodeDBTable[0].uInActiveCount);
+            //if (pDevice->bUpdateBBVGA) {
+            //  s_vCheckSensitivity((HANDLE) pDevice);
+            //}
+            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;
+                pDevice->bRoaming = TRUE;
+                DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Lost AP beacon [%d] sec, disconnected !\n", pMgmt->sNodeDBTable[0].uInActiveCount);
+        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;
+       printk("wireless_send_event--->SIOCGIWAP(disassociated)\n");
+       wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
+     }
+  #endif
+                       }
+        }
+        else if (pItemSSID->len != 0) {
+            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;
+                DEVICE_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 {
+                DEVICE_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) {
+                   DEVICE_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;
+            }
+        }
+    }
+
+    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 BYTE        byTsr0,
+    IN BYTE        byTsr1,
+    IN PBYTE       pbyBuffer,
+    IN UINT        uFIFOHeaderSize
+    )
+{
+    PSDevice        pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject    pMgmt = pDevice->pMgmt;
+    UINT            uNodeIndex = 0;
+    BYTE            byTxRetry = (byTsr0 & TSR0_NCR);
+    PSTxBufHead     pTxBufHead;
+    PS802_11Header  pMACHeader;
+    WORD            wRate;
+    WORD            wFallBackRate = RATE_1M;
+    BYTE            byFallBack;
+    UINT            ii;
+//     UINT            txRetryTemp;
+//PLICE_DEBUG->
+       //txRetryTemp = byTxRetry;
+       //if (txRetryTemp== 8)
+       //txRetryTemp -=3;
+//PLICE_DEBUG <-
+    pTxBufHead = (PSTxBufHead) pbyBuffer;
+    if (pTxBufHead->wFIFOCtl & FIFOCTL_AUTO_FB_0) {
+        byFallBack = AUTO_FB_0;
+    } else if (pTxBufHead->wFIFOCtl & FIFOCTL_AUTO_FB_1) {
+        byFallBack = AUTO_FB_1;
+    } else {
+        byFallBack = AUTO_FB_NONE;
+    }
+    wRate = pTxBufHead->wReserved; //?wRate
+    //printk("BSSvUpdateNodeTxCounter:byTxRetry is %d\n",byTxRetry);
+
+//printk("BSSvUpdateNodeTx:wRate is %d,byFallback is %d\n",wRate,byFallBack);
+//#ifdef       PLICE_DEBUG
+       //printk("BSSvUpdateNodeTx: wRate is %d\n",wRate);
+////#endif
+    // Only Unicast using support rates
+    if (pTxBufHead->wFIFOCtl & FIFOCTL_NEEDACK) {
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wRate %04X, byTsr0 %02X, byTsr1 %02X\n", wRate, byTsr0, byTsr1);
+        if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) {
+            pMgmt->sNodeDBTable[0].uTxAttempts += 1;
+            if ((byTsr1 & TSR1_TERR) == 0) {
+                // 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) {
+//PLICE_DEBUG
+                                 if (byTxRetry < 5)
+                               //if (txRetryTemp < 5)
+                                       wFallBackRate = awHWRetry0[wRate-RATE_18M][byTxRetry];
+                       //wFallBackRate = awHWRetry0[wRate-RATE_12M][byTxRetry];
+                       //wFallBackRate = awHWRetry0[wRate-RATE_18M][txRetryTemp] +1;
+               else
+                        wFallBackRate = awHWRetry0[wRate-RATE_18M][4];
+                       //wFallBackRate = awHWRetry0[wRate-RATE_12M][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) {
+//PLICE_DEBUG
+                                  for(ii=0;ii<byTxRetry;ii++)
+               //for (ii=0;ii<txRetryTemp;ii++)
+               {
+                        if (ii < 5)
+                               {
+
+//PLICE_DEBUG
+                                               wFallBackRate = awHWRetry0[wRate-RATE_18M][ii];
+                                       //printk(" II is %d:BSSvUpdateNodeTx:wFallBackRate is %d\n",ii,wFallBackRate);
+                               //wFallBackRate = awHWRetry0[wRate-RATE_12M][ii];
+                               }
+                       else
+                               {
+                       wFallBackRate = awHWRetry0[wRate-RATE_18M][4];
+                       //printk("ii is %d BSSvUpdateNodeTx:wFallBackRate is %d\n",ii,wFallBackRate);
+                               //wFallBackRate = awHWRetry0[wRate-RATE_12M][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)) {
+
+            pMACHeader = (PS802_11Header)(pbyBuffer + uFIFOHeaderSize);
+
+            if (BSSDBbIsSTAInNodeDB((HANDLE)pMgmt, &(pMACHeader->abyAddr1[0]), &uNodeIndex)){
+                pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts += 1;
+                if ((byTsr1 & TSR1_TERR) == 0) {
+                    // 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->pMgmt;
+    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){
+                        DEVICE_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->pMgmt;
+    int             ii;
+
+    if ((pDevice->byLocalID <= REV_ID_VT3253_A1) && (pDevice->byRFType == RF_RFMD2959) &&
+        (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) {
+        return;
+    }
+
+    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++) {
+                    DEVICE_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;
+                }
+            }
+        }
+    }
+}
+
+
+VOID
+BSSvClearAnyBSSJoinRecord (
+    IN HANDLE hDeviceContext
+    )
+{
+    PSDevice        pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject    pMgmt = pDevice->pMgmt;
+    UINT            ii;
+
+    for (ii = 0; ii < MAX_BSS_NUM; ii++) {
+        pMgmt->sBSSList[ii].bSelected = FALSE;
+    }
+    return;
+}
+
+#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 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/vt6655/bssdb.h b/drivers/staging/vt6655/bssdb.h
new file mode 100644 (file)
index 0000000..d35616d
--- /dev/null
@@ -0,0 +1,380 @@
+/*
+ * 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__
+
+//#if !defined(__DEVICE_H__)
+//#include "device.h"
+//#endif
+#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
+
+
+
+/*---------------------  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 enum _NDIS_802_11_NETWORK_TYPE
+{
+    Ndis802_11FH,
+    Ndis802_11DS,
+    Ndis802_11OFDM5,
+    Ndis802_11OFDM24,
+    Ndis802_11NetworkTypeMax    // not a real type, defined as an upper bound
+} NDIS_802_11_NETWORK_TYPE, *PNDIS_802_11_NETWORK_TYPE;
+
+
+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
+
+//    NDIS_802_11_NETWORK_TYPE    NetworkTypeInUse;
+    CARD_PHY_TYPE   eNetworkTypeInUse;
+
+    ERPObject       sERP;
+    SRSNCapObject   sRSNCapObj;
+    BYTE            abyIEs[1024];   // don't move this field !!
+
+}__attribute__ ((__packed__))
+KnownBSS , DEF* PKnownBSS;
+
+//2006-1116-01,<Add> by NomadZhao
+#pragma pack()
+
+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
+BSSDBbIsSTAInNodeDB(
+    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 BYTE        byTsr0,
+    IN BYTE        byTsr1,
+    IN PBYTE       pbyBuffer,
+    IN UINT        uFIFOHeaderSize
+    );
+
+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/vt6655/card.c b/drivers/staging/vt6655/card.c
new file mode 100644 (file)
index 0000000..723f44e
--- /dev/null
@@ -0,0 +1,3126 @@
+/*
+ * 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(__VNTWIFI_H__)
+#include "vntwifi.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
+
+
+
+/*---------------------  Static Definitions -------------------------*/
+
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+static int          msglevel                =MSG_LEVEL_INFO;
+
+#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
+
+#define CARD_MAX_CHANNEL_TBL    56
+
+#define WAIT_BEACON_TX_DOWN_TMO         3    // Times
+
+typedef struct tagSChannelTblElement {
+    BYTE    byChannelNumber;
+    UINT    uFrequency;
+    BOOL    bValid;
+    BYTE    byMAP;
+}SChannelTblElement, DEF* PSChannelTblElement;
+
+                                                              //1M,   2M,   5M,  11M,  18M,  24M,  36M,  54M
+static BYTE abyDefaultSuppRatesG[] = {WLAN_EID_SUPP_RATES, 8, 0x02, 0x04, 0x0B, 0x16, 0x24, 0x30, 0x48, 0x6C};
+                                                                    //6M,   9M,  12M,  48M
+static BYTE abyDefaultExtSuppRatesG[] = {WLAN_EID_EXTSUPP_RATES, 4, 0x0C, 0x12, 0x18, 0x60};
+                                                              //6M,   9M,  12M,  18M,  24M,  36M,  48M,  54M
+static BYTE abyDefaultSuppRatesA[] = {WLAN_EID_SUPP_RATES, 8, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C};
+                                                              //1M,   2M,   5M,  11M,
+static BYTE abyDefaultSuppRatesB[] = {WLAN_EID_SUPP_RATES, 4, 0x02, 0x04, 0x0B, 0x16};
+
+
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+
+
+const WORD cwRXBCNTSFOff[MAX_RATE] =
+{17, 17, 17, 17, 34, 23, 17, 11, 8, 5, 4, 3};
+
+static SChannelTblElement sChannelTbl[CARD_MAX_CHANNEL_TBL+1] =
+{
+  {0,   0,    FALSE,    0},
+  {1,   2412, TRUE,     0},
+  {2,   2417, TRUE,     0},
+  {3,   2422, TRUE,     0},
+  {4,   2427, TRUE,     0},
+  {5,   2432, TRUE,     0},
+  {6,   2437, TRUE,     0},
+  {7,   2442, TRUE,     0},
+  {8,   2447, TRUE,     0},
+  {9,   2452, TRUE,     0},
+  {10,  2457, TRUE,     0},
+  {11,  2462, TRUE,     0},
+  {12,  2467, TRUE,     0},
+  {13,  2472, TRUE,     0},
+  {14,  2484, TRUE,     0},
+  {183, 4915, TRUE,     0},
+  {184, 4920, TRUE,     0},
+  {185, 4925, TRUE,     0},
+  {187, 4935, TRUE,     0},
+  {188, 4940, TRUE,     0},
+  {189, 4945, TRUE,     0},
+  {192, 4960, TRUE,     0},
+  {196, 4980, TRUE,     0},
+  {7,   5035, TRUE,     0},
+  {8,   5040, TRUE,     0},
+  {9,   5045, TRUE,     0},
+  {11,  5055, TRUE,     0},
+  {12,  5060, TRUE,     0},
+  {16,  5080, TRUE,     0},
+  {34,  5170, TRUE,     0},
+  {36,  5180, TRUE,     0},
+  {38,  5190, TRUE,     0},
+  {40,  5200, TRUE,     0},
+  {42,  5210, TRUE,     0},
+  {44,  5220, TRUE,     0},
+  {46,  5230, TRUE,     0},
+  {48,  5240, TRUE,     0},
+  {52,  5260, TRUE,     0},
+  {56,  5280, TRUE,     0},
+  {60,  5300, TRUE,     0},
+  {64,  5320, TRUE,     0},
+  {100, 5500, TRUE,     0},
+  {104, 5520, TRUE,     0},
+  {108, 5540, TRUE,     0},
+  {112, 5560, TRUE,     0},
+  {116, 5580, TRUE,     0},
+  {120, 5600, TRUE,     0},
+  {124, 5620, TRUE,     0},
+  {128, 5640, TRUE,     0},
+  {132, 5660, TRUE,     0},
+  {136, 5680, TRUE,     0},
+  {140, 5700, TRUE,     0},
+  {149, 5745, TRUE,     0},
+  {153, 5765, TRUE,     0},
+  {157, 5785, TRUE,     0},
+  {161, 5805, TRUE,     0},
+  {165, 5825, TRUE,     0}
+};
+
+
+/************************************************************************
+ * The Radar regulation rules for each country
+ ************************************************************************/
+SCountryTable ChannelRuleTab[CCODE_MAX+1] =
+{
+/************************************************************************
+ * 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  */
+};
+
+
+/*---------------------  Static Functions  --------------------------*/
+
+static
+VOID
+s_vCaculateOFDMRParameter(
+    IN  BYTE byRate,
+    IN  CARD_PHY_TYPE ePHYType,
+    OUT PBYTE pbyTxRate,
+    OUT PBYTE pbyRsvTime
+    );
+
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+/*---------------------  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)
+ ************************************************************************/
+//2008-8-4 <add> by chester
+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 */
+
+
+/*
+ * 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
+ *
+ */
+static
+VOID
+s_vCaculateOFDMRParameter (
+    IN  BYTE byRate,
+    IN  CARD_PHY_TYPE ePHYType,
+    OUT PBYTE pbyTxRate,
+    OUT PBYTE pbyRsvTime
+    )
+{
+    switch (byRate) {
+    case RATE_6M :
+        if (ePHYType == PHY_TYPE_11A) {//5GHZ
+            *pbyTxRate = 0x9B;
+            *pbyRsvTime = 44;
+        }
+        else {
+            *pbyTxRate = 0x8B;
+            *pbyRsvTime = 50;
+        }
+        break;
+
+    case RATE_9M :
+        if (ePHYType == PHY_TYPE_11A) {//5GHZ
+            *pbyTxRate = 0x9F;
+            *pbyRsvTime = 36;
+        }
+        else {
+            *pbyTxRate = 0x8F;
+            *pbyRsvTime = 42;
+        }
+        break;
+
+   case RATE_12M :
+        if (ePHYType == PHY_TYPE_11A) {//5GHZ
+            *pbyTxRate = 0x9A;
+            *pbyRsvTime = 32;
+        }
+        else {
+            *pbyTxRate = 0x8A;
+            *pbyRsvTime = 38;
+        }
+        break;
+
+   case RATE_18M :
+        if (ePHYType == PHY_TYPE_11A) {//5GHZ
+            *pbyTxRate = 0x9E;
+            *pbyRsvTime = 28;
+        }
+        else {
+            *pbyTxRate = 0x8E;
+            *pbyRsvTime = 34;
+        }
+        break;
+
+    case RATE_36M :
+        if (ePHYType == PHY_TYPE_11A) {//5GHZ
+            *pbyTxRate = 0x9D;
+            *pbyRsvTime = 24;
+        }
+        else {
+            *pbyTxRate = 0x8D;
+            *pbyRsvTime = 30;
+        }
+        break;
+
+    case RATE_48M :
+        if (ePHYType == PHY_TYPE_11A) {//5GHZ
+            *pbyTxRate = 0x98;
+            *pbyRsvTime = 24;
+        }
+        else {
+            *pbyTxRate = 0x88;
+            *pbyRsvTime = 30;
+        }
+        break;
+
+    case RATE_54M :
+        if (ePHYType == PHY_TYPE_11A) {//5GHZ
+            *pbyTxRate = 0x9C;
+            *pbyRsvTime = 24;
+        }
+        else {
+            *pbyTxRate = 0x8C;
+            *pbyRsvTime = 30;
+        }
+        break;
+
+    case RATE_24M :
+    default :
+        if (ePHYType == PHY_TYPE_11A) {//5GHZ
+            *pbyTxRate = 0x99;
+            *pbyRsvTime = 28;
+        }
+        else {
+            *pbyTxRate = 0x89;
+            *pbyRsvTime = 34;
+        }
+        break;
+    }
+}
+
+
+
+/*
+ * Description: Set RSPINF
+ *
+ * Parameters:
+ *  In:
+ *      pDevice             - The adapter to be set
+ *  Out:
+ *      none
+ *
+ * Return Value: None.
+ *
+ */
+static
+VOID
+s_vSetRSPINF (PSDevice pDevice, CARD_PHY_TYPE ePHYType, PVOID pvSupportRateIEs, PVOID pvExtSupportRateIEs)
+{
+    BYTE  byServ = 0, bySignal = 0; // For CCK
+    WORD  wLen = 0;
+    BYTE  byTxRate = 0, byRsvTime = 0;    // For OFDM
+
+    //Set to Page1
+    MACvSelectPage1(pDevice->PortOffset);
+
+    //RSPINF_b_1
+    BBvCaculateParameter(pDevice,
+                         14,
+                         VNTWIFIbyGetACKTxRate(RATE_1M, pvSupportRateIEs, pvExtSupportRateIEs),
+                         PK_TYPE_11B,
+                         &wLen,
+                         &byServ,
+                         &bySignal
+    );
+
+    VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_1, MAKEDWORD(wLen,MAKEWORD(bySignal,byServ)));
+    ///RSPINF_b_2
+    BBvCaculateParameter(pDevice,
+                         14,
+                         VNTWIFIbyGetACKTxRate(RATE_2M, pvSupportRateIEs, pvExtSupportRateIEs),
+                         PK_TYPE_11B,
+                         &wLen,
+                         &byServ,
+                         &bySignal
+    );
+
+    VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_2, MAKEDWORD(wLen,MAKEWORD(bySignal,byServ)));
+    //RSPINF_b_5
+    BBvCaculateParameter(pDevice,
+                         14,
+                         VNTWIFIbyGetACKTxRate(RATE_5M, pvSupportRateIEs, pvExtSupportRateIEs),
+                         PK_TYPE_11B,
+                         &wLen,
+                         &byServ,
+                         &bySignal
+    );
+
+    VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_5, MAKEDWORD(wLen,MAKEWORD(bySignal,byServ)));
+    //RSPINF_b_11
+    BBvCaculateParameter(pDevice,
+                         14,
+                         VNTWIFIbyGetACKTxRate(RATE_11M, pvSupportRateIEs, pvExtSupportRateIEs),
+                         PK_TYPE_11B,
+                         &wLen,
+                         &byServ,
+                         &bySignal
+    );
+
+    VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_11, MAKEDWORD(wLen,MAKEWORD(bySignal,byServ)));
+    //RSPINF_a_6
+    s_vCaculateOFDMRParameter(RATE_6M,
+                              ePHYType,
+                              &byTxRate,
+                              &byRsvTime);
+    VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_6, MAKEWORD(byTxRate,byRsvTime));
+    //RSPINF_a_9
+    s_vCaculateOFDMRParameter(RATE_9M,
+                              ePHYType,
+                              &byTxRate,
+                              &byRsvTime);
+    VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_9, MAKEWORD(byTxRate,byRsvTime));
+    //RSPINF_a_12
+    s_vCaculateOFDMRParameter(RATE_12M,
+                              ePHYType,
+                              &byTxRate,
+                              &byRsvTime);
+    VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_12, MAKEWORD(byTxRate,byRsvTime));
+    //RSPINF_a_18
+    s_vCaculateOFDMRParameter(RATE_18M,
+                              ePHYType,
+                              &byTxRate,
+                              &byRsvTime);
+    VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_18, MAKEWORD(byTxRate,byRsvTime));
+    //RSPINF_a_24
+    s_vCaculateOFDMRParameter(RATE_24M,
+                              ePHYType,
+                              &byTxRate,
+                              &byRsvTime);
+    VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_24, MAKEWORD(byTxRate,byRsvTime));
+    //RSPINF_a_36
+    s_vCaculateOFDMRParameter(
+                              VNTWIFIbyGetACKTxRate(RATE_36M, pvSupportRateIEs, pvExtSupportRateIEs),
+                              ePHYType,
+                              &byTxRate,
+                              &byRsvTime);
+    VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_36, MAKEWORD(byTxRate,byRsvTime));
+    //RSPINF_a_48
+    s_vCaculateOFDMRParameter(
+                              VNTWIFIbyGetACKTxRate(RATE_48M, pvSupportRateIEs, pvExtSupportRateIEs),
+                              ePHYType,
+                              &byTxRate,
+                              &byRsvTime);
+    VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_48, MAKEWORD(byTxRate,byRsvTime));
+    //RSPINF_a_54
+    s_vCaculateOFDMRParameter(
+                              VNTWIFIbyGetACKTxRate(RATE_54M, pvSupportRateIEs, pvExtSupportRateIEs),
+                              ePHYType,
+                              &byTxRate,
+                              &byRsvTime);
+    VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_54, MAKEWORD(byTxRate,byRsvTime));
+    //RSPINF_a_72
+    VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_72, MAKEWORD(byTxRate,byRsvTime));
+    //Set to Page0
+    MACvSelectPage0(pDevice->PortOffset);
+}
+
+
+
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+BYTE CARDbyGetChannelMapping (PVOID pDeviceHandler, BYTE byChannelNumber, CARD_PHY_TYPE ePhyType)
+{
+    UINT        ii;
+
+    if ((ePhyType == PHY_TYPE_11B) || (ePhyType == PHY_TYPE_11G)) {
+        return (byChannelNumber);
+    }
+
+    for(ii = (CB_MAX_CHANNEL_24G + 1); ii <= CB_MAX_CHANNEL; ) {
+        if (sChannelTbl[ii].byChannelNumber == byChannelNumber) {
+            return ((BYTE) ii);
+        }
+        ii++;
+    }
+    return (0);
+}
+
+
+BYTE CARDbyGetChannelNumber (PVOID pDeviceHandler, BYTE byChannelIndex)
+{
+//    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+    return(sChannelTbl[byChannelIndex].byChannelNumber);
+}
+
+/*
+ * Description: Set NIC media channel
+ *
+ * Parameters:
+ *  In:
+ *      pDeviceHandler      - The adapter to be set
+ *      uConnectionChannel  - Channel to be set
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if succeeded; FALSE if failed.
+ *
+ */
+BOOL CARDbSetChannel (PVOID pDeviceHandler, UINT uConnectionChannel)
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+    BOOL        bResult = TRUE;
+
+
+    if (pDevice->byCurrentCh == uConnectionChannel) {
+        return bResult;
+    }
+
+    if (sChannelTbl[uConnectionChannel].bValid == FALSE) {
+        return (FALSE);
+    }
+
+    if ((uConnectionChannel > CB_MAX_CHANNEL_24G) &&
+        (pDevice->eCurrentPHYType != PHY_TYPE_11A)) {
+        CARDbSetPhyParameter(pDevice, PHY_TYPE_11A, 0, 0, NULL, NULL);
+    } else if ((uConnectionChannel <= CB_MAX_CHANNEL_24G) &&
+        (pDevice->eCurrentPHYType == PHY_TYPE_11A)) {
+        CARDbSetPhyParameter(pDevice, PHY_TYPE_11G, 0, 0, NULL, NULL);
+    }
+    // clear NAV
+    MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MACCR, MACCR_CLRNAV);
+
+    //{{ RobertYu: 20041202
+    //// TX_PE will reserve 3 us for MAX2829 A mode only, it is for better TX throughput
+
+    if ( pDevice->byRFType == RF_AIROHA7230 )
+    {
+        RFbAL7230SelectChannelPostProcess(pDevice->PortOffset, pDevice->byCurrentCh, (BYTE)uConnectionChannel);
+    }
+    //}} RobertYu
+
+
+    pDevice->byCurrentCh = (BYTE)uConnectionChannel;
+    bResult &= RFbSelectChannel(pDevice->PortOffset, pDevice->byRFType, (BYTE)uConnectionChannel);
+
+    // Init Synthesizer Table
+    if (pDevice->bEnablePSMode == TRUE)
+        RFvWriteWakeProgSyn(pDevice->PortOffset, pDevice->byRFType, uConnectionChannel);
+
+
+    //DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"CARDbSetMediaChannel: %d\n", (BYTE)uConnectionChannel);
+    BBvSoftwareReset(pDevice->PortOffset);
+
+    if (pDevice->byLocalID > REV_ID_VT3253_B1) {
+        // set HW default power register
+        MACvSelectPage1(pDevice->PortOffset);
+        RFbSetPower(pDevice, RATE_1M, pDevice->byCurrentCh);
+        VNSvOutPortB(pDevice->PortOffset + MAC_REG_PWRCCK, pDevice->byCurPwr);
+        RFbSetPower(pDevice, RATE_6M, pDevice->byCurrentCh);
+        VNSvOutPortB(pDevice->PortOffset + MAC_REG_PWROFDM, pDevice->byCurPwr);
+        MACvSelectPage0(pDevice->PortOffset);
+    }
+
+    if (pDevice->eCurrentPHYType == PHY_TYPE_11B) {
+#ifdef PLICE_DEBUG
+       //printk("Func:CARDbSetChannel:call RFbSetPower:11B\n");
+#endif
+        RFbSetPower(pDevice, RATE_1M, pDevice->byCurrentCh);
+    } else {
+#ifdef PLICE_DEBUG
+       //printk("Func:CARDbSetChannel:call RFbSetPower\n");
+#endif
+               RFbSetPower(pDevice, RATE_6M, pDevice->byCurrentCh);
+    }
+
+    return(bResult);
+}
+
+
+
+/*
+ * Description: Card Send packet function
+ *
+ * Parameters:
+ *  In:
+ *      pDeviceHandler      - The adapter to be set
+ *      pPacket             - Packet buffer pointer
+ *      ePktType            - Packet type
+ *      uLength             - Packet length
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if succeeded; FALSE if failed.
+ *
+ */
+/*
+BOOL CARDbSendPacket (PVOID pDeviceHandler, PVOID pPacket, CARD_PKT_TYPE ePktType, UINT uLength)
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+    if (ePktType == PKT_TYPE_802_11_MNG) {
+        return TXbTD0Send(pDevice, pPacket, uLength);
+    } else if (ePktType == PKT_TYPE_802_11_BCN) {
+        return TXbBeaconSend(pDevice, pPacket, uLength);
+    } if (ePktType == PKT_TYPE_802_11_DATA) {
+        return TXbTD1Send(pDevice, pPacket, uLength);
+    }
+
+    return (TRUE);
+}
+*/
+
+
+/*
+ * Description: Get Card short preamble option value
+ *
+ * Parameters:
+ *  In:
+ *      pDevice             - The adapter to be set
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if short preamble; otherwise FALSE
+ *
+ */
+BOOL CARDbIsShortPreamble (PVOID pDeviceHandler)
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+    if (pDevice->byPreambleType == 0) {
+        return(FALSE);
+    }
+    return(TRUE);
+}
+
+/*
+ * Description: Get Card short slot time option value
+ *
+ * Parameters:
+ *  In:
+ *      pDevice             - The adapter to be set
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if short slot time; otherwise FALSE
+ *
+ */
+BOOL CARDbIsShorSlotTime (PVOID pDeviceHandler)
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+    return(pDevice->bShortSlotTime);
+}
+
+
+/*
+ * Description: Update IFS
+ *
+ * Parameters:
+ *  In:
+ *      pDevice             - The adapter to be set
+ *  Out:
+ *      none
+ *
+ * Return Value: None.
+ *
+ */
+BOOL CARDbSetPhyParameter (PVOID pDeviceHandler, CARD_PHY_TYPE ePHYType, WORD wCapInfo, BYTE byERPField, PVOID pvSupportRateIEs, PVOID pvExtSupportRateIEs)
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+    BYTE        byCWMaxMin = 0;
+    BYTE        bySlot = 0;
+    BYTE        bySIFS = 0;
+    BYTE        byDIFS = 0;
+    BYTE        byData;
+//    PWLAN_IE_SUPP_RATES pRates = NULL;
+    PWLAN_IE_SUPP_RATES pSupportRates = (PWLAN_IE_SUPP_RATES) pvSupportRateIEs;
+    PWLAN_IE_SUPP_RATES pExtSupportRates = (PWLAN_IE_SUPP_RATES) pvExtSupportRateIEs;
+
+
+    //Set SIFS, DIFS, EIFS, SlotTime, CwMin
+    if (ePHYType == PHY_TYPE_11A) {
+        if (pSupportRates == NULL) {
+            pSupportRates = (PWLAN_IE_SUPP_RATES) abyDefaultSuppRatesA;
+        }
+        if (pDevice->byRFType == RF_AIROHA7230) {
+            // AL7230 use single PAPE and connect to PAPE_2.4G
+            MACvSetBBType(pDevice->PortOffset, BB_TYPE_11G);
+            pDevice->abyBBVGA[0] = 0x20;
+            pDevice->abyBBVGA[2] = 0x10;
+            pDevice->abyBBVGA[3] = 0x10;
+            BBbReadEmbeded(pDevice->PortOffset, 0xE7, &byData);
+            if (byData == 0x1C) {
+                BBbWriteEmbeded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]);
+            }
+        } else if (pDevice->byRFType == RF_UW2452) {
+            MACvSetBBType(pDevice->PortOffset, BB_TYPE_11A);
+            pDevice->abyBBVGA[0] = 0x18;
+            BBbReadEmbeded(pDevice->PortOffset, 0xE7, &byData);
+            if (byData == 0x14) {
+                BBbWriteEmbeded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]);
+                BBbWriteEmbeded(pDevice->PortOffset, 0xE1, 0x57);
+            }
+        } else {
+            MACvSetBBType(pDevice->PortOffset, BB_TYPE_11A);
+        }
+        BBbWriteEmbeded(pDevice->PortOffset, 0x88, 0x03);
+        bySlot = C_SLOT_SHORT;
+        bySIFS = C_SIFS_A;
+        byDIFS = C_SIFS_A + 2*C_SLOT_SHORT;
+        byCWMaxMin = 0xA4;
+    } else if (ePHYType == PHY_TYPE_11B) {
+        if (pSupportRates == NULL) {
+            pSupportRates = (PWLAN_IE_SUPP_RATES) abyDefaultSuppRatesB;
+        }
+        MACvSetBBType(pDevice->PortOffset, BB_TYPE_11B);
+        if (pDevice->byRFType == RF_AIROHA7230) {
+            pDevice->abyBBVGA[0] = 0x1C;
+            pDevice->abyBBVGA[2] = 0x00;
+            pDevice->abyBBVGA[3] = 0x00;
+            BBbReadEmbeded(pDevice->PortOffset, 0xE7, &byData);
+            if (byData == 0x20) {
+                BBbWriteEmbeded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]);
+            }
+        } else if (pDevice->byRFType == RF_UW2452) {
+            pDevice->abyBBVGA[0] = 0x14;
+            BBbReadEmbeded(pDevice->PortOffset, 0xE7, &byData);
+            if (byData == 0x18) {
+                BBbWriteEmbeded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]);
+                BBbWriteEmbeded(pDevice->PortOffset, 0xE1, 0xD3);
+            }
+        }
+        BBbWriteEmbeded(pDevice->PortOffset, 0x88, 0x02);
+        bySlot = C_SLOT_LONG;
+        bySIFS = C_SIFS_BG;
+        byDIFS = C_SIFS_BG + 2*C_SLOT_LONG;
+        byCWMaxMin = 0xA5;
+    } else {// PK_TYPE_11GA & PK_TYPE_11GB
+        if (pSupportRates == NULL) {
+            pSupportRates = (PWLAN_IE_SUPP_RATES) abyDefaultSuppRatesG;
+            pExtSupportRates = (PWLAN_IE_SUPP_RATES) abyDefaultExtSuppRatesG;
+        }
+        MACvSetBBType(pDevice->PortOffset, BB_TYPE_11G);
+        if (pDevice->byRFType == RF_AIROHA7230) {
+            pDevice->abyBBVGA[0] = 0x1C;
+            pDevice->abyBBVGA[2] = 0x00;
+            pDevice->abyBBVGA[3] = 0x00;
+            BBbReadEmbeded(pDevice->PortOffset, 0xE7, &byData);
+            if (byData == 0x20) {
+                BBbWriteEmbeded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]);
+            }
+        } else if (pDevice->byRFType == RF_UW2452) {
+            pDevice->abyBBVGA[0] = 0x14;
+            BBbReadEmbeded(pDevice->PortOffset, 0xE7, &byData);
+            if (byData == 0x18) {
+                BBbWriteEmbeded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]);
+                BBbWriteEmbeded(pDevice->PortOffset, 0xE1, 0xD3);
+            }
+        }
+        BBbWriteEmbeded(pDevice->PortOffset, 0x88, 0x08);
+        bySIFS = C_SIFS_BG;
+        if(VNTWIFIbIsShortSlotTime(wCapInfo)) {
+            bySlot = C_SLOT_SHORT;
+            byDIFS = C_SIFS_BG + 2*C_SLOT_SHORT;
+        } else {
+            bySlot = C_SLOT_LONG;
+            byDIFS = C_SIFS_BG + 2*C_SLOT_LONG;
+           }
+        if (VNTWIFIbyGetMaxSupportRate(pSupportRates, pExtSupportRates) > RATE_11M) {
+            byCWMaxMin = 0xA4;
+        } else {
+            byCWMaxMin = 0xA5;
+        }
+        if (pDevice->bProtectMode != VNTWIFIbIsProtectMode(byERPField)) {
+            pDevice->bProtectMode = VNTWIFIbIsProtectMode(byERPField);
+            if (pDevice->bProtectMode) {
+                MACvEnableProtectMD(pDevice->PortOffset);
+            } else {
+                MACvDisableProtectMD(pDevice->PortOffset);
+            }
+        }
+        if (pDevice->bBarkerPreambleMd != VNTWIFIbIsBarkerMode(byERPField)) {
+            pDevice->bBarkerPreambleMd = VNTWIFIbIsBarkerMode(byERPField);
+            if (pDevice->bBarkerPreambleMd) {
+                MACvEnableBarkerPreambleMd(pDevice->PortOffset);
+            } else {
+                MACvDisableBarkerPreambleMd(pDevice->PortOffset);
+            }
+        }
+    }
+
+    if (pDevice->byRFType == RF_RFMD2959) {
+        // bcs TX_PE will reserve 3 us
+        // hardware's processing time here is 2 us.
+        bySIFS -= 3;
+        byDIFS -= 3;
+    //{{ RobertYu: 20041202
+    //// TX_PE will reserve 3 us for MAX2829 A mode only, it is for better TX throughput
+    //// MAC will need 2 us to process, so the SIFS, DIFS can be shorter by 2 us.
+    }
+
+    if (pDevice->bySIFS != bySIFS) {
+        pDevice->bySIFS = bySIFS;
+        VNSvOutPortB(pDevice->PortOffset + MAC_REG_SIFS, pDevice->bySIFS);
+    }
+    if (pDevice->byDIFS != byDIFS) {
+        pDevice->byDIFS = byDIFS;
+        VNSvOutPortB(pDevice->PortOffset + MAC_REG_DIFS, pDevice->byDIFS);
+    }
+    if (pDevice->byEIFS != C_EIFS) {
+        pDevice->byEIFS = C_EIFS;
+        VNSvOutPortB(pDevice->PortOffset + MAC_REG_EIFS, pDevice->byEIFS);
+    }
+    if (pDevice->bySlot != bySlot) {
+        pDevice->bySlot = bySlot;
+        VNSvOutPortB(pDevice->PortOffset + MAC_REG_SLOT, pDevice->bySlot);
+        if (pDevice->bySlot == C_SLOT_SHORT) {
+            pDevice->bShortSlotTime = TRUE;
+        } else {
+            pDevice->bShortSlotTime = FALSE;
+        }
+        BBvSetShortSlotTime(pDevice);
+    }
+    if (pDevice->byCWMaxMin != byCWMaxMin) {
+        pDevice->byCWMaxMin = byCWMaxMin;
+        VNSvOutPortB(pDevice->PortOffset + MAC_REG_CWMAXMIN0, pDevice->byCWMaxMin);
+    }
+    if (VNTWIFIbIsShortPreamble(wCapInfo)) {
+        pDevice->byPreambleType = pDevice->byShortPreamble;
+    } else {
+        pDevice->byPreambleType = 0;
+    }
+    s_vSetRSPINF(pDevice, ePHYType, pSupportRates, pExtSupportRates);
+    pDevice->eCurrentPHYType = ePHYType;
+    // set for NDIS OID_802_11SUPPORTED_RATES
+    return (TRUE);
+}
+
+/*
+ * Description: Sync. TSF counter to BSS
+ *              Get TSF offset and write to HW
+ *
+ * Parameters:
+ *  In:
+ *      pDevice         - The adapter to be sync.
+ *      byRxRate        - data rate of receive beacon
+ *      qwBSSTimestamp  - Rx BCN's TSF
+ *      qwLocalTSF      - Local TSF
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+BOOL CARDbUpdateTSF (PVOID pDeviceHandler, BYTE byRxRate, QWORD qwBSSTimestamp, QWORD qwLocalTSF)
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+    QWORD       qwTSFOffset;
+
+    HIDWORD(qwTSFOffset) = 0;
+    LODWORD(qwTSFOffset) = 0;
+
+    if ((HIDWORD(qwBSSTimestamp) != HIDWORD(qwLocalTSF)) ||
+        (LODWORD(qwBSSTimestamp) != LODWORD(qwLocalTSF))) {
+        qwTSFOffset = CARDqGetTSFOffset(byRxRate, qwBSSTimestamp, qwLocalTSF);
+        // adjust TSF
+        // HW's TSF add TSF Offset reg
+        VNSvOutPortD(pDevice->PortOffset + MAC_REG_TSFOFST, LODWORD(qwTSFOffset));
+        VNSvOutPortD(pDevice->PortOffset + MAC_REG_TSFOFST + 4, HIDWORD(qwTSFOffset));
+        MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TFTCTL, TFTCTL_TSFSYNCEN);
+    }
+    return(TRUE);
+}
+
+
+/*
+ * Description: Set NIC TSF counter for first Beacon time
+ *              Get NEXTTBTT from adjusted TSF and Beacon Interval
+ *
+ * Parameters:
+ *  In:
+ *      pDevice         - The adapter to be set.
+ *      wBeaconInterval - Beacon Interval
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if succeed; otherwise FALSE
+ *
+ */
+BOOL CARDbSetBeaconPeriod (PVOID pDeviceHandler, WORD wBeaconInterval)
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+    UINT        uBeaconInterval = 0;
+    UINT        uLowNextTBTT = 0;
+    UINT        uHighRemain = 0;
+    UINT        uLowRemain = 0;
+    QWORD       qwNextTBTT;
+
+    HIDWORD(qwNextTBTT) = 0;
+    LODWORD(qwNextTBTT) = 0;
+    CARDbGetCurrentTSF(pDevice->PortOffset, &qwNextTBTT); //Get Local TSF counter
+    uBeaconInterval = wBeaconInterval * 1024;
+    // Next TBTT = ((local_current_TSF / beacon_interval) + 1 ) * beacon_interval
+    uLowNextTBTT = (LODWORD(qwNextTBTT) >> 10) << 10;
+    uLowRemain = (uLowNextTBTT) % uBeaconInterval;
+    // high dword (mod) bcn
+    uHighRemain = (((0xffffffff % uBeaconInterval) + 1) * HIDWORD(qwNextTBTT))
+                  % uBeaconInterval;
+    uLowRemain = (uHighRemain + uLowRemain) % uBeaconInterval;
+    uLowRemain = uBeaconInterval - uLowRemain;
+
+    // check if carry when add one beacon interval
+    if ((~uLowNextTBTT) < uLowRemain) {
+        HIDWORD(qwNextTBTT) ++ ;
+    }
+    LODWORD(qwNextTBTT) = uLowNextTBTT + uLowRemain;
+
+    // set HW beacon interval
+    VNSvOutPortW(pDevice->PortOffset + MAC_REG_BI, wBeaconInterval);
+    pDevice->wBeaconInterval = wBeaconInterval;
+    // Set NextTBTT
+    VNSvOutPortD(pDevice->PortOffset + MAC_REG_NEXTTBTT, LODWORD(qwNextTBTT));
+    VNSvOutPortD(pDevice->PortOffset + MAC_REG_NEXTTBTT + 4, HIDWORD(qwNextTBTT));
+    MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN);
+
+    return(TRUE);
+}
+
+
+
+/*
+ * Description: Card Stop Hardware Tx
+ *
+ * Parameters:
+ *  In:
+ *      pDeviceHandler      - The adapter to be set
+ *      ePktType            - Packet type to stop
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if all data packet complete; otherwise FALSE.
+ *
+ */
+BOOL CARDbStopTxPacket (PVOID pDeviceHandler, CARD_PKT_TYPE ePktType)
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+
+
+    if (ePktType == PKT_TYPE_802_11_ALL) {
+        pDevice->bStopBeacon = TRUE;
+        pDevice->bStopTx0Pkt = TRUE;
+        pDevice->bStopDataPkt = TRUE;
+    } else if (ePktType == PKT_TYPE_802_11_BCN) {
+        pDevice->bStopBeacon = TRUE;
+    } else if (ePktType == PKT_TYPE_802_11_MNG) {
+        pDevice->bStopTx0Pkt = TRUE;
+    } else if (ePktType == PKT_TYPE_802_11_DATA) {
+        pDevice->bStopDataPkt = TRUE;
+    }
+
+    if (pDevice->bStopBeacon == TRUE) {
+        if (pDevice->bIsBeaconBufReadySet == TRUE) {
+            if (pDevice->cbBeaconBufReadySetCnt < WAIT_BEACON_TX_DOWN_TMO) {
+                pDevice->cbBeaconBufReadySetCnt ++;
+                return(FALSE);
+            }
+        }
+        pDevice->bIsBeaconBufReadySet = FALSE;
+        pDevice->cbBeaconBufReadySetCnt = 0;
+        MACvRegBitsOff(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX);
+    }
+    // wait all TD0 complete
+    if (pDevice->bStopTx0Pkt == TRUE) {
+         if (pDevice->iTDUsed[TYPE_TXDMA0] != 0){
+            return(FALSE);
+        }
+    }
+    // wait all Data TD complete
+    if (pDevice->bStopDataPkt == TRUE) {
+        if (pDevice->iTDUsed[TYPE_AC0DMA] != 0){
+            return(FALSE);
+        }
+    }
+
+    return(TRUE);
+}
+
+
+/*
+ * Description: Card Start Hardware Tx
+ *
+ * Parameters:
+ *  In:
+ *      pDeviceHandler      - The adapter to be set
+ *      ePktType            - Packet type to start
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if success; FALSE if failed.
+ *
+ */
+BOOL CARDbStartTxPacket (PVOID pDeviceHandler, CARD_PKT_TYPE ePktType)
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+
+
+    if (ePktType == PKT_TYPE_802_11_ALL) {
+        pDevice->bStopBeacon = FALSE;
+        pDevice->bStopTx0Pkt = FALSE;
+        pDevice->bStopDataPkt = FALSE;
+    } else if (ePktType == PKT_TYPE_802_11_BCN) {
+        pDevice->bStopBeacon = FALSE;
+    } else if (ePktType == PKT_TYPE_802_11_MNG) {
+        pDevice->bStopTx0Pkt = FALSE;
+    } else if (ePktType == PKT_TYPE_802_11_DATA) {
+        pDevice->bStopDataPkt = FALSE;
+    }
+
+    if ((pDevice->bStopBeacon == FALSE) &&
+        (pDevice->bBeaconBufReady == TRUE) &&
+        (pDevice->eOPMode == OP_MODE_ADHOC)) {
+        MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX);
+    }
+
+    return(TRUE);
+}
+
+
+
+/*
+ * Description: Card Set BSSID value
+ *
+ * Parameters:
+ *  In:
+ *      pDeviceHandler      - The adapter to be set
+ *      pbyBSSID            - pointer to BSSID field
+ *      bAdhoc              - flag to indicate IBSS
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if success; FALSE if failed.
+ *
+ */
+BOOL CARDbSetBSSID(PVOID pDeviceHandler, PBYTE pbyBSSID, CARD_OP_MODE eOPMode)
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+
+    MACvWriteBSSIDAddress(pDevice->PortOffset, pbyBSSID);
+    MEMvCopy(pDevice->abyBSSID, pbyBSSID, WLAN_BSSID_LEN);
+    if (eOPMode == OP_MODE_ADHOC) {
+        MACvRegBitsOn(pDevice->PortOffset, MAC_REG_HOSTCR, HOSTCR_ADHOC);
+    } else {
+        MACvRegBitsOff(pDevice->PortOffset, MAC_REG_HOSTCR, HOSTCR_ADHOC);
+    }
+    if (eOPMode == OP_MODE_AP) {
+        MACvRegBitsOn(pDevice->PortOffset, MAC_REG_HOSTCR, HOSTCR_AP);
+    } else {
+        MACvRegBitsOff(pDevice->PortOffset, MAC_REG_HOSTCR, HOSTCR_AP);
+    }
+    if (eOPMode == OP_MODE_UNKNOWN) {
+        MACvRegBitsOff(pDevice->PortOffset, MAC_REG_RCR, RCR_BSSID);
+        pDevice->bBSSIDFilter = FALSE;
+        pDevice->byRxMode &= ~RCR_BSSID;
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wcmd: rx_mode = %x\n", pDevice->byRxMode );
+    } else {
+        if (IS_NULL_ADDRESS(pDevice->abyBSSID) == FALSE) {
+            MACvRegBitsOn(pDevice->PortOffset, MAC_REG_RCR, RCR_BSSID);
+            pDevice->bBSSIDFilter = TRUE;
+            pDevice->byRxMode |= RCR_BSSID;
+           }
+           DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: rx_mode = %x\n", pDevice->byRxMode );
+    }
+    // Adopt BSS state in Adapter Device Object
+    pDevice->eOPMode = eOPMode;
+    return(TRUE);
+}
+
+
+/*
+ * Description: Card indicate status
+ *
+ * Parameters:
+ *  In:
+ *      pDeviceHandler      - The adapter to be set
+ *      eStatus             - Status
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if success; FALSE if failed.
+ *
+ */
+
+
+
+
+/*
+ * Description: Save Assoc info. contain in assoc. response frame
+ *
+ * Parameters:
+ *  In:
+ *      pDevice             - The adapter to be set
+ *      wCapabilityInfo     - Capability information
+ *      wStatus             - Status code
+ *      wAID                - Assoc. ID
+ *      uLen                - Length of IEs
+ *      pbyIEs              - pointer to IEs
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if succeed; otherwise FALSE
+ *
+ */
+BOOL CARDbSetTxDataRate(
+    PVOID   pDeviceHandler,
+    WORD    wDataRate
+    )
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+
+    pDevice->wCurrentRate = wDataRate;
+    return(TRUE);
+}
+
+/*+
+ *
+ * Routine Description:
+ *      Consider to power down when no more packets to tx or rx.
+ *
+ * Parameters:
+ *  In:
+ *      pDevice             - The adapter to be set
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if power down success; otherwise FALSE
+ *
+-*/
+BOOL
+CARDbPowerDown(
+    PVOID   pDeviceHandler
+    )
+{
+    PSDevice        pDevice = (PSDevice)pDeviceHandler;
+    UINT            uIdx;
+
+    // check if already in Doze mode
+    if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS))
+        return TRUE;
+
+    // Froce PSEN on
+    MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PSEN);
+
+    // check if all TD are empty,
+
+    for (uIdx = 0; uIdx < TYPE_MAXTD; uIdx ++) {
+        if (pDevice->iTDUsed[uIdx] != 0)
+            return FALSE;
+    }
+
+    MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_GO2DOZE);
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Go to Doze ZZZZZZZZZZZZZZZ\n");
+    return TRUE;
+}
+
+/*
+ * 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;
+
+
+    switch (pDevice->byRFType) {
+
+        case RF_RFMD2959:
+            MACvWordRegBitsOff(pDevice->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_TXPEINV);
+            MACvWordRegBitsOn(pDevice->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE1);
+            break;
+
+        case RF_AIROHA:
+        case RF_AL2230S:
+        case RF_AIROHA7230: //RobertYu:20050104
+            MACvWordRegBitsOff(pDevice->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE2);
+            MACvWordRegBitsOff(pDevice->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3);
+            break;
+
+    }
+
+    MACvRegBitsOff(pDevice->PortOffset, MAC_REG_HOSTCR, HOSTCR_RXON);
+
+    BBvSetDeepSleep(pDevice->PortOffset, pDevice->byLocalID);
+
+    pDevice->bRadioOff = TRUE;
+     //2007-0409-03,<Add> by chester
+printk("chester power off\n");
+MACvRegBitsOn(pDevice->PortOffset, MAC_REG_GPIOCTL0, LED_ACTSET);  //LED issue
+    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;
+printk("chester power on\n");
+    if (pDevice->bRadioControlOff == TRUE){
+if (pDevice->bHWRadioOff == TRUE) printk("chester bHWRadioOff\n");
+if (pDevice->bRadioControlOff == TRUE) printk("chester bRadioControlOff\n");
+        return FALSE;}
+
+    if (pDevice->bRadioOff == FALSE)
+       {
+printk("chester pbRadioOff\n");
+return TRUE;}
+
+    BBvExitDeepSleep(pDevice->PortOffset, pDevice->byLocalID);
+
+    MACvRegBitsOn(pDevice->PortOffset, MAC_REG_HOSTCR, HOSTCR_RXON);
+
+    switch (pDevice->byRFType) {
+
+        case RF_RFMD2959:
+            MACvWordRegBitsOn(pDevice->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_TXPEINV);
+            MACvWordRegBitsOff(pDevice->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE1);
+            break;
+
+        case RF_AIROHA:
+        case RF_AL2230S:
+        case RF_AIROHA7230: //RobertYu:20050104
+            MACvWordRegBitsOn(pDevice->PortOffset, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPE2 |
+                                                                        SOFTPWRCTL_SWPE3));
+            break;
+
+    }
+
+    pDevice->bRadioOff = FALSE;
+//  2007-0409-03,<Add> by chester
+printk("chester power on\n");
+MACvRegBitsOff(pDevice->PortOffset, MAC_REG_GPIOCTL0, LED_ACTSET); //LED issue
+    return bResult;
+}
+
+
+
+BOOL CARDbRemoveKey (PVOID pDeviceHandler, PBYTE pbyBSSID)
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+
+    KeybRemoveAllKey(&(pDevice->sKey), pbyBSSID, pDevice->PortOffset);
+    return (TRUE);
+}
+
+
+/*
+ *
+ * Description:
+ *    Add BSSID in PMKID Candidate list.
+ *
+ * Parameters:
+ *  In:
+ *      hDeviceContext - device structure point
+ *      pbyBSSID - BSSID address for adding
+ *      wRSNCap - BSS's RSN capability
+ *  Out:
+ *      none
+ *
+ * Return Value: none.
+ *
+-*/
+BOOL
+CARDbAdd_PMKID_Candidate (
+    IN PVOID            pDeviceHandler,
+    IN PBYTE            pbyBSSID,
+    IN BOOL             bRSNCapExist,
+    IN WORD             wRSNCap
+    )
+{
+    PSDevice            pDevice = (PSDevice) pDeviceHandler;
+    PPMKID_CANDIDATE    pCandidateList;
+    UINT                ii = 0;
+
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"bAdd_PMKID_Candidate START: (%d)\n", (int)pDevice->gsPMKIDCandidate.NumCandidates);
+
+    if (pDevice->gsPMKIDCandidate.NumCandidates >= MAX_PMKIDLIST) {
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vFlush_PMKID_Candidate: 3\n");
+        ZERO_MEMORY(&pDevice->gsPMKIDCandidate, sizeof(SPMKIDCandidateEvent));
+    }
+
+    for (ii = 0; ii < 6; ii++) {
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02X ", *(pbyBSSID + ii));
+    }
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+
+
+    // Update Old Candidate
+    for (ii = 0; ii < pDevice->gsPMKIDCandidate.NumCandidates; ii++) {
+        pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[ii];
+        if (MEMEqualMemory(pCandidateList->BSSID, pbyBSSID, U_ETHER_ADDR_LEN)) {
+            if ((bRSNCapExist == TRUE) && (wRSNCap & BIT0)) {
+                pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED;
+            } else {
+                pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED);
+            }
+            return TRUE;
+        }
+    }
+
+    // New Candidate
+    pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[pDevice->gsPMKIDCandidate.NumCandidates];
+    if ((bRSNCapExist == TRUE) && (wRSNCap & BIT0)) {
+        pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED;
+    } else {
+        pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED);
+    }
+    MEMvCopy(pCandidateList->BSSID, pbyBSSID, U_ETHER_ADDR_LEN);
+    pDevice->gsPMKIDCandidate.NumCandidates++;
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"NumCandidates:%d\n", (int)pDevice->gsPMKIDCandidate.NumCandidates);
+    return TRUE;
+}
+
+PVOID
+CARDpGetCurrentAddress (
+    IN PVOID            pDeviceHandler
+    )
+{
+    PSDevice            pDevice = (PSDevice) pDeviceHandler;
+
+    return (pDevice->abyCurrentNetAddr);
+}
+
+
+
+VOID CARDvInitChannelTable (PVOID pDeviceHandler)
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+    BOOL        bMultiBand = FALSE;
+    UINT        ii;
+
+    for(ii=1;ii<=CARD_MAX_CHANNEL_TBL;ii++) {
+        sChannelTbl[ii].bValid = FALSE;
+    }
+
+    switch (pDevice->byRFType) {
+        case RF_RFMD2959 :
+        case RF_AIROHA :
+        case RF_AL2230S:
+        case RF_UW2451 :
+        case RF_VT3226 :
+       //              printk("chester-false\n");
+            bMultiBand = FALSE;
+            break;
+        case RF_AIROHA7230 :
+        case RF_UW2452 :
+        case RF_NOTHING :
+        default :
+            bMultiBand = TRUE;
+            break;
+    }
+
+    if ((pDevice->dwDiagRefCount != 0) ||
+        (pDevice->b11hEnable == TRUE)) {
+        if (bMultiBand == TRUE) {
+            for(ii=0;ii<CARD_MAX_CHANNEL_TBL;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<CHANNEL_MAX_24G;ii++) {
+                pDevice->abyRegPwr[ii+1] = pDevice->abyCCKDefaultPwr[ii+1];
+                pDevice->abyLocalPwr[ii+1] = pDevice->abyCCKDefaultPwr[ii+1];
+            }
+        } else {
+            for(ii=0;ii<CHANNEL_MAX_24G;ii++) {
+//2008-8-4 <add> by chester
+ if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] != 0) {
+                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<CARD_MAX_CHANNEL_TBL;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<CHANNEL_MAX_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];
+                }
+            }
+        }
+    }
+ DEVICE_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<CARD_MAX_CHANNEL_TBL;ii++) {
+        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];
+        }
+    }
+}
+
+
+
+/*
+ *
+ * Description:
+ *    Start Spectrum Measure defined in 802.11h
+ *
+ * Parameters:
+ *  In:
+ *      hDeviceContext - device structure point
+ *  Out:
+ *      none
+ *
+ * Return Value: none.
+ *
+-*/
+BOOL
+CARDbStartMeasure (
+    IN PVOID            pDeviceHandler,
+    IN PVOID            pvMeasureEIDs,
+    IN UINT             uNumOfMeasureEIDs
+    )
+{
+    PSDevice                pDevice = (PSDevice) pDeviceHandler;
+    PWLAN_IE_MEASURE_REQ    pEID = (PWLAN_IE_MEASURE_REQ) pvMeasureEIDs;
+    QWORD                   qwCurrTSF;
+    QWORD                   qwStartTSF;
+    BOOL                    bExpired = TRUE;
+    WORD                    wDuration = 0;
+
+    if ((pEID == NULL) ||
+        (uNumOfMeasureEIDs == 0)) {
+        return (TRUE);
+    }
+    CARDbGetCurrentTSF(pDevice->PortOffset, &qwCurrTSF);
+    if (pDevice->bMeasureInProgress == TRUE) {
+        pDevice->bMeasureInProgress = FALSE;
+        VNSvOutPortB(pDevice->PortOffset + MAC_REG_RCR, pDevice->byOrgRCR);
+        MACvSelectPage1(pDevice->PortOffset);
+        VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0, pDevice->dwOrgMAR0);
+        VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR4, pDevice->dwOrgMAR4);
+        // clear measure control
+        MACvRegBitsOff(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_EN);
+        MACvSelectPage0(pDevice->PortOffset);
+        CARDbSetChannel(pDevice, pDevice->byOrgChannel);
+        MACvSelectPage1(pDevice->PortOffset);
+        MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE);
+        MACvSelectPage0(pDevice->PortOffset);
+    }
+    pDevice->uNumOfMeasureEIDs = uNumOfMeasureEIDs;
+
+    do {
+        pDevice->pCurrMeasureEID = pEID;
+        pEID++;
+        pDevice->uNumOfMeasureEIDs--;
+
+        if (pDevice->byLocalID > REV_ID_VT3253_B1) {
+            HIDWORD(qwStartTSF) = HIDWORD(*((PQWORD) (pDevice->pCurrMeasureEID->sReq.abyStartTime)));
+            LODWORD(qwStartTSF) = LODWORD(*((PQWORD) (pDevice->pCurrMeasureEID->sReq.abyStartTime)));
+            wDuration = *((PWORD) (pDevice->pCurrMeasureEID->sReq.abyDuration));
+            wDuration += 1; // 1 TU for channel switching
+
+            if ((LODWORD(qwStartTSF) == 0) && (HIDWORD(qwStartTSF) == 0)) {
+                // start imediately by setting start TSF == current TSF + 2 TU
+                LODWORD(qwStartTSF) = LODWORD(qwCurrTSF) + 2048;
+                HIDWORD(qwStartTSF) = HIDWORD(qwCurrTSF);
+                if (LODWORD(qwCurrTSF) > LODWORD(qwStartTSF)) {
+                    HIDWORD(qwStartTSF)++;
+                }
+                bExpired = FALSE;
+                break;
+            } else {
+                // start at setting start TSF - 1TU(for channel switching)
+                if (LODWORD(qwStartTSF) < 1024) {
+                    HIDWORD(qwStartTSF)--;
+                }
+                LODWORD(qwStartTSF) -= 1024;
+            }
+
+            if ((HIDWORD(qwCurrTSF) < HIDWORD(qwStartTSF)) ||
+                ((HIDWORD(qwCurrTSF) == HIDWORD(qwStartTSF)) &&
+                (LODWORD(qwCurrTSF) < LODWORD(qwStartTSF)))
+                ) {
+                bExpired = FALSE;
+                break;
+            }
+            VNTWIFIbMeasureReport(  pDevice->pMgmt,
+                                    FALSE,
+                                    pDevice->pCurrMeasureEID,
+                                    MEASURE_MODE_LATE,
+                                    pDevice->byBasicMap,
+                                    pDevice->byCCAFraction,
+                                    pDevice->abyRPIs
+                                    );
+        } else {
+            // hardware do not support measure
+            VNTWIFIbMeasureReport(  pDevice->pMgmt,
+                                    FALSE,
+                                    pDevice->pCurrMeasureEID,
+                                    MEASURE_MODE_INCAPABLE,
+                                    pDevice->byBasicMap,
+                                    pDevice->byCCAFraction,
+                                    pDevice->abyRPIs
+                                    );
+        }
+    } while (pDevice->uNumOfMeasureEIDs != 0);
+
+    if (bExpired == FALSE) {
+        MACvSelectPage1(pDevice->PortOffset);
+        VNSvOutPortD(pDevice->PortOffset + MAC_REG_MSRSTART, LODWORD(qwStartTSF));
+        VNSvOutPortD(pDevice->PortOffset + MAC_REG_MSRSTART + 4, HIDWORD(qwStartTSF));
+        VNSvOutPortW(pDevice->PortOffset + MAC_REG_MSRDURATION, wDuration);
+        MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_EN);
+        MACvSelectPage0(pDevice->PortOffset);
+    } else {
+        // all measure start time expired we should complete action
+        VNTWIFIbMeasureReport(  pDevice->pMgmt,
+                                TRUE,
+                                NULL,
+                                0,
+                                pDevice->byBasicMap,
+                                pDevice->byCCAFraction,
+                                pDevice->abyRPIs
+                                );
+    }
+    return (TRUE);
+}
+
+
+/*
+ *
+ * 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) {
+        bResult = CARDbSetChannel(pDevice, byNewChannel);
+        VNTWIFIbChannelSwitch(pDevice->pMgmt, byNewChannel);
+        MACvSelectPage1(pDevice->PortOffset);
+        MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE);
+        MACvSelectPage0(pDevice->PortOffset);
+        return(bResult);
+    }
+    pDevice->byChannelSwitchCount = byCount;
+    pDevice->byNewChannel = byNewChannel;
+    pDevice->bChannelSwitch = TRUE;
+    if (byMode == 1) {
+        bResult=CARDbStopTxPacket(pDevice, PKT_TYPE_802_11_ALL);
+    }
+    return (bResult);
+}
+
+
+/*
+ *
+ * Description:
+ *    Handle Quiet EID defined in 802.11h
+ *
+ * Parameters:
+ *  In:
+ *      hDeviceContext - device structure point
+ *  Out:
+ *      none
+ *
+ * Return Value: none.
+ *
+-*/
+BOOL
+CARDbSetQuiet (
+    IN PVOID            pDeviceHandler,
+    IN BOOL             bResetQuiet,
+    IN BYTE             byQuietCount,
+    IN BYTE             byQuietPeriod,
+    IN WORD             wQuietDuration,
+    IN WORD             wQuietOffset
+    )
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+    UINT        ii = 0;
+
+    if (bResetQuiet == TRUE) {
+        MACvRegBitsOff(pDevice->PortOffset, MAC_REG_MSRCTL, (MSRCTL_QUIETTXCHK | MSRCTL_QUIETEN));
+        for(ii=0;ii<MAX_QUIET_COUNT;ii++) {
+            pDevice->sQuiet[ii].bEnable = FALSE;
+        }
+        pDevice->uQuietEnqueue = 0;
+        pDevice->bEnableFirstQuiet = FALSE;
+        pDevice->bQuietEnable = FALSE;
+        pDevice->byQuietStartCount = byQuietCount;
+    }
+    if (pDevice->sQuiet[pDevice->uQuietEnqueue].bEnable == FALSE) {
+        pDevice->sQuiet[pDevice->uQuietEnqueue].bEnable = TRUE;
+        pDevice->sQuiet[pDevice->uQuietEnqueue].byPeriod = byQuietPeriod;
+        pDevice->sQuiet[pDevice->uQuietEnqueue].wDuration = wQuietDuration;
+        pDevice->sQuiet[pDevice->uQuietEnqueue].dwStartTime = (DWORD) byQuietCount;
+        pDevice->sQuiet[pDevice->uQuietEnqueue].dwStartTime *= pDevice->wBeaconInterval;
+        pDevice->sQuiet[pDevice->uQuietEnqueue].dwStartTime += wQuietOffset;
+        pDevice->uQuietEnqueue++;
+        pDevice->uQuietEnqueue %= MAX_QUIET_COUNT;
+        if (pDevice->byQuietStartCount < byQuietCount) {
+            pDevice->byQuietStartCount = byQuietCount;
+        }
+    } else {
+        // we can not handle Quiet EID more
+    }
+    return (TRUE);
+}
+
+
+/*
+ *
+ * Description:
+ *    Do Quiet, It will called by either ISR (after start) or VNTWIFI (before start) so do not need SPINLOCK
+ *
+ * Parameters:
+ *  In:
+ *      hDeviceContext - device structure point
+ *  Out:
+ *      none
+ *
+ * Return Value: none.
+ *
+-*/
+BOOL
+CARDbStartQuiet (
+    IN PVOID            pDeviceHandler
+    )
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+    UINT        ii = 0;
+    DWORD       dwStartTime = 0xFFFFFFFF;
+    UINT        uCurrentQuietIndex = 0;
+    DWORD       dwNextTime = 0;
+    DWORD       dwGap = 0;
+    DWORD       dwDuration = 0;
+
+    for(ii=0;ii<MAX_QUIET_COUNT;ii++) {
+        if ((pDevice->sQuiet[ii].bEnable == TRUE) &&
+            (dwStartTime > pDevice->sQuiet[ii].dwStartTime)) {
+            dwStartTime = pDevice->sQuiet[ii].dwStartTime;
+            uCurrentQuietIndex = ii;
+        }
+    }
+    if (dwStartTime == 0xFFFFFFFF) {
+        // no more quiet
+        pDevice->bQuietEnable = FALSE;
+        MACvRegBitsOff(pDevice->PortOffset, MAC_REG_MSRCTL, (MSRCTL_QUIETTXCHK | MSRCTL_QUIETEN));
+    } else {
+        if (pDevice->bQuietEnable == FALSE) {
+            // first quiet
+            pDevice->byQuietStartCount--;
+            dwNextTime = pDevice->sQuiet[uCurrentQuietIndex].dwStartTime;
+            dwNextTime %= pDevice->wBeaconInterval;
+            MACvSelectPage1(pDevice->PortOffset);
+            VNSvOutPortW(pDevice->PortOffset + MAC_REG_QUIETINIT, (WORD) dwNextTime);
+            VNSvOutPortW(pDevice->PortOffset + MAC_REG_QUIETDUR, (WORD) pDevice->sQuiet[uCurrentQuietIndex].wDuration);
+            if (pDevice->byQuietStartCount == 0) {
+                pDevice->bEnableFirstQuiet = FALSE;
+                MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL, (MSRCTL_QUIETTXCHK | MSRCTL_QUIETEN));
+            } else {
+                pDevice->bEnableFirstQuiet = TRUE;
+            }
+            MACvSelectPage0(pDevice->PortOffset);
+        } else {
+            if (pDevice->dwCurrentQuietEndTime > pDevice->sQuiet[uCurrentQuietIndex].dwStartTime) {
+                // overlap with previous Quiet
+                dwGap =  pDevice->dwCurrentQuietEndTime - pDevice->sQuiet[uCurrentQuietIndex].dwStartTime;
+                if (dwGap >= pDevice->sQuiet[uCurrentQuietIndex].wDuration) {
+                    // return FALSE to indicate next quiet expired, should call this function again
+                    return (FALSE);
+                }
+                dwDuration = pDevice->sQuiet[uCurrentQuietIndex].wDuration - dwGap;
+                dwGap = 0;
+            } else {
+                dwGap = pDevice->sQuiet[uCurrentQuietIndex].dwStartTime - pDevice->dwCurrentQuietEndTime;
+                dwDuration = pDevice->sQuiet[uCurrentQuietIndex].wDuration;
+            }
+            // set GAP and Next duration
+            MACvSelectPage1(pDevice->PortOffset);
+            VNSvOutPortW(pDevice->PortOffset + MAC_REG_QUIETGAP, (WORD) dwGap);
+            VNSvOutPortW(pDevice->PortOffset + MAC_REG_QUIETDUR, (WORD) dwDuration);
+            MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_QUIETRPT);
+            MACvSelectPage0(pDevice->PortOffset);
+        }
+        pDevice->bQuietEnable = TRUE;
+        pDevice->dwCurrentQuietEndTime = pDevice->sQuiet[uCurrentQuietIndex].dwStartTime;
+        pDevice->dwCurrentQuietEndTime += pDevice->sQuiet[uCurrentQuietIndex].wDuration;
+        if (pDevice->sQuiet[uCurrentQuietIndex].byPeriod == 0) {
+            // not period disable current quiet element
+            pDevice->sQuiet[uCurrentQuietIndex].bEnable = FALSE;
+        } else {
+            // set next period start time
+            dwNextTime = (DWORD) pDevice->sQuiet[uCurrentQuietIndex].byPeriod;
+            dwNextTime *= pDevice->wBeaconInterval;
+            pDevice->sQuiet[uCurrentQuietIndex].dwStartTime = dwNextTime;
+        }
+        if (pDevice->dwCurrentQuietEndTime > 0x80010000) {
+            // decreament all time to avoid wrap around
+            for(ii=0;ii<MAX_QUIET_COUNT;ii++) {
+                if (pDevice->sQuiet[ii].bEnable == TRUE) {
+                    pDevice->sQuiet[ii].dwStartTime -= 0x80000000;
+                }
+            }
+            pDevice->dwCurrentQuietEndTime -= 0x80000000;
+        }
+    }
+    return (TRUE);
+}
+
+
+/*
+ *
+ * Description:
+ *    Set Channel Info of Country
+ *
+ * Parameters:
+ *  In:
+ *      hDeviceContext - device structure point
+ *  Out:
+ *      none
+ *
+ * Return Value: none.
+ *
+-*/
+VOID
+CARDvSetCountryInfo (
+    IN PVOID            pDeviceHandler,
+    IN CARD_PHY_TYPE    ePHYType,
+    IN PVOID            pIE
+    )
+{
+    PSDevice            pDevice = (PSDevice) pDeviceHandler;
+    UINT                ii = 0;
+    UINT                uu = 0;
+    UINT                step = 0;
+    UINT                uNumOfCountryInfo = 0;
+    BYTE                byCh = 0;
+    PWLAN_IE_COUNTRY    pIE_Country = (PWLAN_IE_COUNTRY) pIE;
+
+
+    uNumOfCountryInfo = (pIE_Country->len - 3);
+    uNumOfCountryInfo /= 3;
+
+    if (ePHYType == PHY_TYPE_11A) {
+        pDevice->bCountryInfo5G = TRUE;
+        for(ii=CB_MAX_CHANNEL_24G+1;ii<=CARD_MAX_CHANNEL_TBL;ii++) {
+            sChannelTbl[ii].bValid = FALSE;
+        }
+        step = 4;
+    } else {
+        pDevice->bCountryInfo24G = TRUE;
+        for(ii=1;ii<=CB_MAX_CHANNEL_24G;ii++) {
+            sChannelTbl[ii].bValid = FALSE;
+        }
+        step = 1;
+    }
+    pDevice->abyCountryCode[0] = pIE_Country->abyCountryString[0];
+    pDevice->abyCountryCode[1] = pIE_Country->abyCountryString[1];
+    pDevice->abyCountryCode[2] = pIE_Country->abyCountryString[2];
+
+    for(ii=0;ii<uNumOfCountryInfo;ii++) {
+        for(uu=0;uu<pIE_Country->abyCountryInfo[ii*3+1];uu++) {
+            byCh = CARDbyGetChannelMapping(pDevice, (BYTE)(pIE_Country->abyCountryInfo[ii*3]+step*uu), ePHYType);
+            sChannelTbl[byCh].bValid = TRUE;
+            pDevice->abyRegPwr[byCh] = pIE_Country->abyCountryInfo[ii*3+2];
+        }
+    }
+}
+
+/*
+ *
+ * Description:
+ *    Set Local Power Constraint
+ *
+ * Parameters:
+ *  In:
+ *      hDeviceContext - device structure point
+ *  Out:
+ *      none
+ *
+ * Return Value: none.
+ *
+-*/
+VOID
+CARDvSetPowerConstraint (
+    IN PVOID            pDeviceHandler,
+    IN BYTE             byChannel,
+    IN I8               byPower
+    )
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+
+    if (byChannel > CB_MAX_CHANNEL_24G) {
+        if (pDevice->bCountryInfo5G == TRUE) {
+            pDevice->abyLocalPwr[byChannel] = pDevice->abyRegPwr[byChannel] - byPower;
+        }
+    } else {
+        if (pDevice->bCountryInfo24G == TRUE) {
+            pDevice->abyLocalPwr[byChannel] = pDevice->abyRegPwr[byChannel] - byPower;
+        }
+    }
+}
+
+
+/*
+ *
+ * Description:
+ *    Set Local Power Constraint
+ *
+ * Parameters:
+ *  In:
+ *      hDeviceContext - device structure point
+ *  Out:
+ *      none
+ *
+ * Return Value: none.
+ *
+-*/
+VOID
+CARDvGetPowerCapability (
+    IN PVOID            pDeviceHandler,
+    OUT PBYTE           pbyMinPower,
+    OUT PBYTE           pbyMaxPower
+    )
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+    BYTE        byDec = 0;
+
+    *pbyMaxPower = pDevice->abyOFDMDefaultPwr[pDevice->byCurrentCh];
+    byDec = pDevice->abyOFDMPwrTbl[pDevice->byCurrentCh];
+    if (pDevice->byRFType == RF_UW2452) {
+        byDec *= 3;
+        byDec >>= 1;
+    } else {
+        byDec <<= 1;
+    }
+    *pbyMinPower = pDevice->abyOFDMDefaultPwr[pDevice->byCurrentCh] - byDec;
+}
+
+
+/*
+ *
+ * Description:
+ *    Set Support Channels IE defined in 802.11h
+ *
+ * Parameters:
+ *  In:
+ *      hDeviceContext - device structure point
+ *  Out:
+ *      none
+ *
+ * Return Value: none.
+ *
+-*/
+BYTE
+CARDbySetSupportChannels (
+    IN PVOID            pDeviceHandler,
+    IN OUT PBYTE        pbyIEs
+    )
+{
+    PSDevice            pDevice = (PSDevice) pDeviceHandler;
+    UINT                ii;
+    BYTE                byCount;
+    PWLAN_IE_SUPP_CH    pIE = (PWLAN_IE_SUPP_CH) pbyIEs;
+    PBYTE               pbyChTupple;
+    BYTE                byLen = 0;
+
+
+    pIE->byElementID = WLAN_EID_SUPP_CH;
+    pIE->len = 0;
+    pbyChTupple = pIE->abyChannelTuple;
+    byLen = 2;
+    // lower band
+    byCount = 0;
+    if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[28] == TRUE) {
+        for (ii=28;ii<36;ii+=2) {
+            if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] == TRUE) {
+                byCount++;
+            }
+        }
+        *pbyChTupple++ = 34;
+        *pbyChTupple++ = byCount;
+        byLen += 2;
+    } else if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[29] == TRUE) {
+        for (ii=29;ii<36;ii+=2) {
+            if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] == TRUE) {
+                byCount++;
+            }
+        }
+        *pbyChTupple++ = 36;
+        *pbyChTupple++ = byCount;
+        byLen += 2;
+    }
+    // middle band
+    byCount = 0;
+    if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[36] == TRUE) {
+        for (ii=36;ii<40;ii++) {
+            if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] == TRUE) {
+                byCount++;
+            }
+        }
+        *pbyChTupple++ = 52;
+        *pbyChTupple++ = byCount;
+        byLen += 2;
+    }
+    // higher band
+    byCount = 0;
+    if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[40] == TRUE) {
+        for (ii=40;ii<51;ii++) {
+            if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] == TRUE) {
+                byCount++;
+            }
+        }
+        *pbyChTupple++ = 100;
+        *pbyChTupple++ = byCount;
+        byLen += 2;
+    } else if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[51] == TRUE) {
+        for (ii=51;ii<56;ii++) {
+            if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] == TRUE) {
+                byCount++;
+            }
+        }
+        *pbyChTupple++ = 149;
+        *pbyChTupple++ = byCount;
+        byLen += 2;
+    }
+    pIE->len += (byLen - 2);
+    return (byLen);
+}
+
+
+/*
+ *
+ * Description:
+ *    Get Current Tx Power
+ *
+ * Parameters:
+ *  In:
+ *      hDeviceContext - device structure point
+ *  Out:
+ *      none
+ *
+ * Return Value: none.
+ *
+-*/
+I8
+CARDbyGetTransmitPower (
+    IN PVOID            pDeviceHandler
+    )
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+
+    return (pDevice->byCurPwrdBm);
+}
+
+
+BOOL
+CARDbChannelGetList (
+    IN  UINT       uCountryCodeIdx,
+    OUT PBYTE      pbyChannelTable
+    )
+{
+    if (uCountryCodeIdx >= CCODE_MAX) {
+        return (FALSE);
+    }
+    MEMvCopy(pbyChannelTable, ChannelRuleTab[uCountryCodeIdx].bChannelIdxList, CB_MAX_CHANNEL);
+    return (TRUE);
+}
+
+
+VOID
+CARDvSetCountryIE(
+    IN PVOID        pDeviceHandler,
+    IN PVOID        pIE
+    )
+{
+    PSDevice            pDevice = (PSDevice) pDeviceHandler;
+    UINT                ii;
+    PWLAN_IE_COUNTRY    pIECountry = (PWLAN_IE_COUNTRY) pIE;
+
+    pIECountry->byElementID = WLAN_EID_COUNTRY;
+    pIECountry->len = 0;
+    pIECountry->abyCountryString[0] = ChannelRuleTab[pDevice->byZoneType].chCountryCode[0];
+    pIECountry->abyCountryString[1] = ChannelRuleTab[pDevice->byZoneType].chCountryCode[1];
+    pIECountry->abyCountryString[2] = ' ';
+    for (ii = CB_MAX_CHANNEL_24G; ii < CB_MAX_CHANNEL; ii++ ) {
+        if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] != 0) {
+            pIECountry->abyCountryInfo[pIECountry->len++] = sChannelTbl[ii+1].byChannelNumber;
+            pIECountry->abyCountryInfo[pIECountry->len++] = 1;
+            pIECountry->abyCountryInfo[pIECountry->len++] = ChannelRuleTab[pDevice->byZoneType].byPower[ii];
+        }
+    }
+    pIECountry->len += 3;
+}
+
+
+BOOL
+CARDbGetChannelMapInfo(
+    IN PVOID        pDeviceHandler,
+    IN UINT         uChannelIndex,
+    OUT PBYTE       pbyChannelNumber,
+    OUT PBYTE       pbyMap
+    )
+{
+//    PSDevice            pDevice = (PSDevice) pDeviceHandler;
+
+    if (uChannelIndex > CB_MAX_CHANNEL) {
+        return FALSE;
+    }
+    *pbyChannelNumber = sChannelTbl[uChannelIndex].byChannelNumber;
+    *pbyMap = sChannelTbl[uChannelIndex].byMAP;
+    return sChannelTbl[uChannelIndex].bValid;
+}
+
+
+VOID
+CARDvSetChannelMapInfo(
+    IN PVOID        pDeviceHandler,
+    IN UINT         uChannelIndex,
+    IN BYTE         byMap
+    )
+{
+//    PSDevice            pDevice = (PSDevice) pDeviceHandler;
+
+    if (uChannelIndex > CB_MAX_CHANNEL) {
+        return;
+    }
+    sChannelTbl[uChannelIndex].byMAP |= byMap;
+}
+
+
+VOID
+CARDvClearChannelMapInfo(
+    IN PVOID        pDeviceHandler
+    )
+{
+//    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+    UINT        ii = 0;
+
+    for (ii = 1; ii <=  CB_MAX_CHANNEL; ii++) {
+        sChannelTbl[ii].byMAP = 0;
+    }
+}
+
+
+BYTE
+CARDbyAutoChannelSelect(
+    IN PVOID        pDeviceHandler,
+    CARD_PHY_TYPE   ePHYType
+    )
+{
+//    PSDevice        pDevice = (PSDevice) pDeviceHandler;
+    UINT            ii = 0;
+    BYTE            byOptionChannel = 0;
+    INT             aiWeight[CB_MAX_CHANNEL_24G+1] = {-1000,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+
+    if (ePHYType == PHY_TYPE_11A) {
+        for(ii=CB_MAX_CHANNEL_24G+1;ii<=CB_MAX_CHANNEL;ii++) {
+            if (sChannelTbl[ii].bValid == TRUE) {
+                if (byOptionChannel == 0) {
+                    byOptionChannel = (BYTE) ii;
+                }
+                if (sChannelTbl[ii].byMAP == 0) {
+                    return ((BYTE) ii);
+                } else if (BITbIsBitOff(sChannelTbl[ii].byMAP, 0x08)) {
+                    byOptionChannel = (BYTE) ii;
+                }
+            }
+        }
+    } else {
+        byOptionChannel = 0;
+        for(ii=1;ii<=CB_MAX_CHANNEL_24G;ii++) {
+            if (sChannelTbl[ii].bValid == TRUE) {
+                if (sChannelTbl[ii].byMAP == 0) {
+                    aiWeight[ii] += 100;
+                } else if (BITbIsBitOn(sChannelTbl[ii].byMAP, 0x01)) {
+                    if (ii > 3) {
+                        aiWeight[ii-3] -= 10;
+                    }
+                    if (ii > 2) {
+                        aiWeight[ii-2] -= 20;
+                    }
+                    if (ii > 1) {
+                        aiWeight[ii-1] -= 40;
+                    }
+                    aiWeight[ii] -= 80;
+                    if (ii < CB_MAX_CHANNEL_24G) {
+                        aiWeight[ii+1] -= 40;
+                    }
+                    if (ii < (CB_MAX_CHANNEL_24G - 1)) {
+                        aiWeight[ii+2] -= 20;
+                    }
+                    if (ii < (CB_MAX_CHANNEL_24G - 2)) {
+                        aiWeight[ii+3] -= 10;
+                    }
+                }
+            }
+        }
+        for(ii=1;ii<=CB_MAX_CHANNEL_24G;ii++) {
+            if ((sChannelTbl[ii].bValid == TRUE) &&
+                (aiWeight[ii] > aiWeight[byOptionChannel])) {
+                byOptionChannel = (BYTE) ii;
+            }
+        }
+    }
+    return (byOptionChannel);
+}
+
+
+
+//xxx
+VOID
+CARDvSafeResetTx (
+    IN PVOID    pDeviceHandler
+    )
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+    UINT        uu;
+    PSTxDesc    pCurrTD;
+
+    // initialize TD index
+    pDevice->apTailTD[0] = pDevice->apCurrTD[0] = &(pDevice->apTD0Rings[0]);
+    pDevice->apTailTD[1] = pDevice->apCurrTD[1] = &(pDevice->apTD1Rings[0]);
+
+    for (uu = 0; uu < TYPE_MAXTD; uu ++)
+        pDevice->iTDUsed[uu] = 0;
+
+    for (uu = 0; uu < pDevice->sOpts.nTxDescs[0]; uu++) {
+        pCurrTD = &(pDevice->apTD0Rings[uu]);
+        pCurrTD->m_td0TD0.f1Owner = OWNED_BY_HOST;
+        // init all Tx Packet pointer to NULL
+    }
+    for (uu = 0; uu < pDevice->sOpts.nTxDescs[1]; uu++) {
+        pCurrTD = &(pDevice->apTD1Rings[uu]);
+        pCurrTD->m_td0TD0.f1Owner = OWNED_BY_HOST;
+        // init all Tx Packet pointer to NULL
+    }
+
+    // set MAC TD pointer
+    MACvSetCurrTXDescAddr(TYPE_TXDMA0, pDevice->PortOffset,
+                        (pDevice->td0_pool_dma));
+
+    MACvSetCurrTXDescAddr(TYPE_AC0DMA, pDevice->PortOffset,
+                        (pDevice->td1_pool_dma));
+
+    // set MAC Beacon TX pointer
+    MACvSetCurrBCNTxDescAddr(pDevice->PortOffset,
+                        (pDevice->tx_beacon_dma));
+
+}
+
+
+
+/*+
+ *
+ * Description:
+ *      Reset Rx
+ *
+ * Parameters:
+ *  In:
+ *      pDevice     - Pointer to the adapter
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+-*/
+VOID
+CARDvSafeResetRx (
+    IN PVOID    pDeviceHandler
+    )
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+    UINT        uu;
+    PSRxDesc    pDesc;
+
+
+
+    // initialize RD index
+    pDevice->pCurrRD[0]=&(pDevice->aRD0Ring[0]);
+    pDevice->pCurrRD[1]=&(pDevice->aRD1Ring[0]);
+
+    // init state, all RD is chip's
+    for (uu = 0; uu < pDevice->sOpts.nRxDescs0; uu++) {
+        pDesc =&(pDevice->aRD0Ring[uu]);
+        pDesc->m_rd0RD0.wResCount = (WORD)(pDevice->rx_buf_sz);
+        pDesc->m_rd0RD0.f1Owner=OWNED_BY_NIC;
+        pDesc->m_rd1RD1.wReqCount = (WORD)(pDevice->rx_buf_sz);
+    }
+
+    // init state, all RD is chip's
+    for (uu = 0; uu < pDevice->sOpts.nRxDescs1; uu++) {
+        pDesc =&(pDevice->aRD1Ring[uu]);
+        pDesc->m_rd0RD0.wResCount = (WORD)(pDevice->rx_buf_sz);
+        pDesc->m_rd0RD0.f1Owner=OWNED_BY_NIC;
+        pDesc->m_rd1RD1.wReqCount = (WORD)(pDevice->rx_buf_sz);
+    }
+
+    pDevice->cbDFCB = CB_MAX_RX_FRAG;
+    pDevice->cbFreeDFCB = pDevice->cbDFCB;
+
+    // set perPkt mode
+    MACvRx0PerPktMode(pDevice->PortOffset);
+    MACvRx1PerPktMode(pDevice->PortOffset);
+    // set MAC RD pointer
+    MACvSetCurrRx0DescAddr(pDevice->PortOffset,
+                            pDevice->rd0_pool_dma);
+
+    MACvSetCurrRx1DescAddr(pDevice->PortOffset,
+                            pDevice->rd1_pool_dma);
+}
+
+
+
+
+/*
+ * Description: Get response Control frame rate in CCK mode
+ *
+ * Parameters:
+ *  In:
+ *      pDevice             - The adapter to be set
+ *      wRateIdx            - Receiving data rate
+ *  Out:
+ *      none
+ *
+ * Return Value: response Control frame rate
+ *
+ */
+WORD CARDwGetCCKControlRate(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 response Control frame rate in OFDM mode
+ *
+ * Parameters:
+ *  In:
+ *      pDevice             - The adapter to be set
+ *      wRateIdx            - Receiving data rate
+ *  Out:
+ *      none
+ *
+ * Return Value: response Control frame rate
+ *
+ */
+WORD CARDwGetOFDMControlRate (PVOID pDeviceHandler, WORD wRateIdx)
+{
+    PSDevice pDevice = (PSDevice) pDeviceHandler;
+    UINT ui = (UINT)wRateIdx;
+
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BASIC RATE: %X\n", pDevice->wBasicRate);
+
+    if (!CARDbIsOFDMinBasicRate((PVOID)pDevice)) {
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"CARDwGetOFDMControlRate:(NO OFDM) %d\n", wRateIdx);
+        if (wRateIdx > RATE_24M)
+            wRateIdx = RATE_24M;
+        return wRateIdx;
+    }
+    while (ui > RATE_11M) {
+        if (pDevice->wBasicRate & ((WORD)1 << ui)) {
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"CARDwGetOFDMControlRate : %d\n", ui);
+            return (WORD)ui;
+        }
+        ui --;
+    }
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"CARDwGetOFDMControlRate: 6M\n");
+    return (WORD)RATE_24M;
+}
+
+
+/*
+ * Description: Set RSPINF
+ *
+ * Parameters:
+ *  In:
+ *      pDevice             - The adapter to be set
+ *  Out:
+ *      none
+ *
+ * Return Value: None.
+ *
+ */
+void CARDvSetRSPINF (PVOID pDeviceHandler, CARD_PHY_TYPE ePHYType)
+{
+    PSDevice pDevice = (PSDevice) pDeviceHandler;
+    BYTE  byServ = 0x00, bySignal = 0x00; //For CCK
+    WORD  wLen = 0x0000;
+    BYTE  byTxRate, byRsvTime;             //For OFDM
+
+    //Set to Page1
+    MACvSelectPage1(pDevice->PortOffset);
+
+    //RSPINF_b_1
+    BBvCaculateParameter(pDevice,
+                         14,
+                         CARDwGetCCKControlRate((PVOID)pDevice, RATE_1M),
+                         PK_TYPE_11B,
+                         &wLen,
+                         &byServ,
+                         &bySignal
+    );
+
+    VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_1, MAKEDWORD(wLen,MAKEWORD(bySignal,byServ)));
+    ///RSPINF_b_2
+    BBvCaculateParameter(pDevice,
+                         14,
+                         CARDwGetCCKControlRate((PVOID)pDevice, RATE_2M),
+                         PK_TYPE_11B,
+                         &wLen,
+                         &byServ,
+                         &bySignal
+    );
+
+    VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_2, MAKEDWORD(wLen,MAKEWORD(bySignal,byServ)));
+    //RSPINF_b_5
+    BBvCaculateParameter(pDevice,
+                         14,
+                         CARDwGetCCKControlRate((PVOID)pDevice, RATE_5M),
+                         PK_TYPE_11B,
+                         &wLen,
+                         &byServ,
+                         &bySignal
+    );
+
+    VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_5, MAKEDWORD(wLen,MAKEWORD(bySignal,byServ)));
+    //RSPINF_b_11
+    BBvCaculateParameter(pDevice,
+                         14,
+                         CARDwGetCCKControlRate((PVOID)pDevice, RATE_11M),
+                         PK_TYPE_11B,
+                         &wLen,
+                         &byServ,
+                         &bySignal
+    );
+
+    VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_11, MAKEDWORD(wLen,MAKEWORD(bySignal,byServ)));
+    //RSPINF_a_6
+    s_vCaculateOFDMRParameter(RATE_6M,
+                              ePHYType,
+                              &byTxRate,
+                              &byRsvTime);
+    VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_6, MAKEWORD(byTxRate,byRsvTime));
+    //RSPINF_a_9
+    s_vCaculateOFDMRParameter(RATE_9M,
+                              ePHYType,
+                              &byTxRate,
+                              &byRsvTime);
+    VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_9, MAKEWORD(byTxRate,byRsvTime));
+    //RSPINF_a_12
+    s_vCaculateOFDMRParameter(RATE_12M,
+                              ePHYType,
+                              &byTxRate,
+                              &byRsvTime);
+    VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_12, MAKEWORD(byTxRate,byRsvTime));
+    //RSPINF_a_18
+    s_vCaculateOFDMRParameter(RATE_18M,
+                              ePHYType,
+                              &byTxRate,
+                              &byRsvTime);
+   VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_18, MAKEWORD(byTxRate,byRsvTime));
+    //RSPINF_a_24
+    s_vCaculateOFDMRParameter(RATE_24M,
+                              ePHYType,
+                              &byTxRate,
+                              &byRsvTime);
+    VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_24, MAKEWORD(byTxRate,byRsvTime));
+    //RSPINF_a_36
+    s_vCaculateOFDMRParameter(CARDwGetOFDMControlRate((PVOID)pDevice, RATE_36M),
+                              ePHYType,
+                              &byTxRate,
+                              &byRsvTime);
+    VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_36, MAKEWORD(byTxRate,byRsvTime));
+    //RSPINF_a_48
+    s_vCaculateOFDMRParameter(CARDwGetOFDMControlRate((PVOID)pDevice, RATE_48M),
+                              ePHYType,
+                              &byTxRate,
+                              &byRsvTime);
+    VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_48, MAKEWORD(byTxRate,byRsvTime));
+    //RSPINF_a_54
+    s_vCaculateOFDMRParameter(CARDwGetOFDMControlRate((PVOID)pDevice, RATE_54M),
+                              ePHYType,
+                              &byTxRate,
+                              &byRsvTime);
+    VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_54, MAKEWORD(byTxRate,byRsvTime));
+
+    //RSPINF_a_72
+    s_vCaculateOFDMRParameter(CARDwGetOFDMControlRate((PVOID)pDevice, RATE_54M),
+                              ePHYType,
+                              &byTxRate,
+                              &byRsvTime);
+    VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_72, MAKEWORD(byTxRate,byRsvTime));
+    //Set to Page0
+    MACvSelectPage0(pDevice->PortOffset);
+}
+
+/*
+ * Description: Update IFS
+ *
+ * Parameters:
+ *  In:
+ *      pDevice             - The adapter to be set
+ *  Out:
+ *      none
+ *
+ * Return Value: None.
+ *
+ */
+void vUpdateIFS (PVOID pDeviceHandler)
+{
+    //Set SIFS, DIFS, EIFS, SlotTime, CwMin
+    PSDevice pDevice = (PSDevice) pDeviceHandler;
+
+    BYTE byMaxMin = 0;
+    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
+        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;
+        if (pDevice->wBasicRate & 0x0150) { //0000 0001 0101 0000,24M,12M,6M
+            pDevice->uCwMin = C_CWMIN_A;
+            byMaxMin = 4;
+        }
+        else {
+            pDevice->uCwMin = C_CWMIN_B;
+            byMaxMin = 5;
+        }
+    }
+
+    pDevice->uCwMax = C_CWMAX;
+    pDevice->uEIFS = C_EIFS;
+    if (pDevice->byRFType == RF_RFMD2959) {
+        // bcs TX_PE will reserve 3 us
+        VNSvOutPortB(pDevice->PortOffset + MAC_REG_SIFS, (BYTE)(pDevice->uSIFS - 3));
+        VNSvOutPortB(pDevice->PortOffset + MAC_REG_DIFS, (BYTE)(pDevice->uDIFS - 3));
+    } else {
+        VNSvOutPortB(pDevice->PortOffset + MAC_REG_SIFS, (BYTE)pDevice->uSIFS);
+        VNSvOutPortB(pDevice->PortOffset + MAC_REG_DIFS, (BYTE)pDevice->uDIFS);
+    }
+    VNSvOutPortB(pDevice->PortOffset + MAC_REG_EIFS, (BYTE)pDevice->uEIFS);
+    VNSvOutPortB(pDevice->PortOffset + MAC_REG_SLOT, (BYTE)pDevice->uSlot);
+    byMaxMin |= 0xA0;//1010 1111,C_CWMAX = 1023
+    VNSvOutPortB(pDevice->PortOffset + MAC_REG_CWMAXMIN0, (BYTE)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((PVOID)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((PVOID)pDevice)) {
+        return PK_TYPE_11GA;
+    }
+    else {
+       return PK_TYPE_11GB;
+    }
+}
+
+/*
+ * Description: Set NIC Loopback mode
+ *
+ * Parameters:
+ *  In:
+ *      pDevice         - The adapter to be set
+ *      wLoopbackMode   - Loopback mode to be set
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void CARDvSetLoopbackMode (DWORD_PTR dwIoBase, WORD wLoopbackMode)
+{
+    switch(wLoopbackMode) {
+    case CARD_LB_NONE:
+    case CARD_LB_MAC:
+    case CARD_LB_PHY:
+        break;
+    default:
+        ASSERT(FALSE);
+        break;
+    }
+    // set MAC loopback
+    MACvSetLoopbackMode(dwIoBase, LOBYTE(wLoopbackMode));
+    // set Baseband loopback
+}
+
+
+/*
+ * Description: Software Reset NIC
+ *
+ * Parameters:
+ *  In:
+ *      pDevice         - The adapter to be reset
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+BOOL CARDbSoftwareReset (PVOID pDeviceHandler)
+{
+    PSDevice pDevice = (PSDevice) pDeviceHandler;
+
+    // reset MAC
+    if (!MACbSafeSoftwareReset(pDevice->PortOffset))
+        return FALSE;
+
+    return TRUE;
+}
+
+
+/*
+ * 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: 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 (DWORD_PTR dwIoBase, PQWORD pqwCurrTSF)
+{
+    WORD    ww;
+    BYTE    byData;
+
+    MACvRegBitsOn(dwIoBase, MAC_REG_TFTCTL, TFTCTL_TSFCNTRRD);
+    for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+        VNSvInPortB(dwIoBase + MAC_REG_TFTCTL, &byData);
+        if (BITbIsBitOff(byData, TFTCTL_TSFCNTRRD))
+            break;
+    }
+    if (ww == W_MAX_TIMEOUT)
+        return(FALSE);
+    VNSvInPortD(dwIoBase + MAC_REG_TSFCNTR, &LODWORD(*pqwCurrTSF));
+    VNSvInPortD(dwIoBase + MAC_REG_TSFCNTR + 4, &HIDWORD(*pqwCurrTSF));
+
+    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;
+    // low dword (mod) bcn
+    uLowRemain = (uLowNextTBTT) % uBeaconInterval;
+//    uHighRemain = ((0x80000000 % uBeaconInterval)* 2 * HIDWORD(qwTSF))
+//                  % uBeaconInterval;
+    // high dword (mod) bcn
+    uHighRemain = (((0xffffffff % uBeaconInterval) + 1) * 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 (DWORD_PTR dwIoBase, WORD wBeaconInterval)
+{
+
+    QWORD   qwNextTBTT;
+
+    HIDWORD(qwNextTBTT) = 0;
+    LODWORD(qwNextTBTT) = 0;
+    CARDbGetCurrentTSF(dwIoBase, &qwNextTBTT); //Get Local TSF counter
+    qwNextTBTT = CARDqGetNextTBTT(qwNextTBTT, wBeaconInterval);
+    // Set NextTBTT
+    VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT, LODWORD(qwNextTBTT));
+    VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT + 4, HIDWORD(qwNextTBTT));
+    MACvRegBitsOn(dwIoBase, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN);
+    //DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Card:First Next TBTT[%8xh:%8xh] \n", HIDWORD(qwNextTBTT), LODWORD(qwNextTBTT));
+    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 (DWORD_PTR dwIoBase, QWORD qwTSF, WORD wBeaconInterval)
+{
+
+    qwTSF = CARDqGetNextTBTT(qwTSF, wBeaconInterval);
+    // Set NextTBTT
+    VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT, LODWORD(qwTSF));
+    VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT + 4, HIDWORD(qwTSF));
+    MACvRegBitsOn(dwIoBase, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN);
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Card:Update Next TBTT[%8xh:%8xh] \n",(UINT)HIDWORD(qwTSF), (UINT)LODWORD(qwTSF));
+
+    return;
+}
+
+
+
+
+
+
+
diff --git a/drivers/staging/vt6655/card.h b/drivers/staging/vt6655/card.h
new file mode 100644 (file)
index 0000000..bb292e1
--- /dev/null
@@ -0,0 +1,273 @@
+/*
+ * 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(__DEVICE_H__)
+//#include "device.h"
+//#endif
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+
+
+
+
+/*---------------------  Export Definitions -------------------------*/
+//
+// Loopback mode
+//
+// LOBYTE is MAC LB mode, HIBYTE is MII LB mode
+#define CARD_LB_NONE            MAKEWORD(MAC_LB_NONE, 0)
+#define CARD_LB_MAC             MAKEWORD(MAC_LB_INTERNAL, 0)   // PHY must ISO, avoid MAC loopback packet go out
+#define CARD_LB_PHY             MAKEWORD(MAC_LB_EXT, 0)
+
+
+#define DEFAULT_MSDU_LIFETIME           512  // ms
+#define DEFAULT_MSDU_LIFETIME_RES_64us  8000 // 64us
+
+#define DEFAULT_MGN_LIFETIME            8    // ms
+#define DEFAULT_MGN_LIFETIME_RES_64us   125  // 64us
+
+#define CB_MAX_CHANNEL_24G      14
+#define CB_MAX_CHANNEL_5G       42 //[20050104] add channel9(5045MHz), 41==>42
+#define CB_MAX_CHANNEL          (CB_MAX_CHANNEL_24G+CB_MAX_CHANNEL_5G)
+
+typedef enum _CARD_PHY_TYPE {
+    PHY_TYPE_AUTO,
+    PHY_TYPE_11B,
+    PHY_TYPE_11G,
+    PHY_TYPE_11A
+} CARD_PHY_TYPE, *PCARD_PHY_TYPE;
+
+typedef enum _CARD_PKT_TYPE {
+    PKT_TYPE_802_11_BCN,
+    PKT_TYPE_802_11_MNG,
+    PKT_TYPE_802_11_DATA,
+    PKT_TYPE_802_11_ALL
+} CARD_PKT_TYPE, *PCARD_PKT_TYPE;
+
+typedef enum _CARD_STATUS_TYPE {
+    CARD_STATUS_MEDIA_CONNECT,
+    CARD_STATUS_MEDIA_DISCONNECT,
+    CARD_STATUS_PMKID
+} CARD_STATUS_TYPE, *PCARD_STATUS_TYPE;
+
+typedef enum _CARD_OP_MODE {
+    OP_MODE_INFRASTRUCTURE,
+    OP_MODE_ADHOC,
+    OP_MODE_AP,
+    OP_MODE_UNKNOWN
+} CARD_OP_MODE, *PCARD_OP_MODE;
+
+
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+#ifdef __cplusplus
+extern "C" {                            /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+BOOL ChannelValid(UINT CountryCode, UINT ChannelIndex);
+void CARDvSetRSPINF(PVOID pDeviceHandler, CARD_PHY_TYPE ePHYType);
+void vUpdateIFS(PVOID pDeviceHandler);
+void CARDvUpdateBasicTopRate(PVOID pDeviceHandler);
+BOOL CARDbAddBasicRate(PVOID pDeviceHandler, WORD wRateIdx);
+BOOL CARDbIsOFDMinBasicRate(PVOID pDeviceHandler);
+void CARDvSetLoopbackMode(DWORD_PTR dwIoBase, WORD wLoopbackMode);
+BOOL CARDbSoftwareReset(PVOID pDeviceHandler);
+void CARDvSetFirstNextTBTT(DWORD_PTR dwIoBase, WORD wBeaconInterval);
+void CARDvUpdateNextTBTT(DWORD_PTR dwIoBase, QWORD qwTSF, WORD wBeaconInterval);
+BOOL CARDbGetCurrentTSF(DWORD_PTR dwIoBase, PQWORD pqwCurrTSF);
+QWORD CARDqGetNextTBTT(QWORD qwTSF, WORD wBeaconInterval);
+QWORD CARDqGetTSFOffset(BYTE byRxRate, QWORD qwTSF1, QWORD qwTSF2);
+BOOL CARDbSetTxPower(PVOID pDeviceHandler, ULONG ulTxPower);
+BYTE CARDbyGetPktType(PVOID pDeviceHandler);
+VOID CARDvSafeResetTx(PVOID pDeviceHandler);
+VOID CARDvSafeResetRx(PVOID pDeviceHandler);
+
+//xxx
+BOOL CARDbRadioPowerOff(PVOID pDeviceHandler);
+BOOL CARDbRadioPowerOn(PVOID pDeviceHandler);
+BOOL CARDbSetChannel(PVOID pDeviceHandler, UINT uConnectionChannel);
+//BOOL CARDbSendPacket(PVOID pDeviceHandler, PVOID pPacket, CARD_PKT_TYPE ePktType, UINT uLength);
+BOOL CARDbIsShortPreamble(PVOID pDeviceHandler);
+BOOL CARDbIsShorSlotTime(PVOID pDeviceHandler);
+BOOL CARDbSetPhyParameter(PVOID pDeviceHandler, CARD_PHY_TYPE ePHYType, WORD wCapInfo, BYTE byERPField, PVOID pvSupportRateIEs, PVOID pvExtSupportRateIEs);
+BOOL CARDbUpdateTSF(PVOID pDeviceHandler, BYTE byRxRate, QWORD qwBSSTimestamp, QWORD qwLocalTSF);
+BOOL CARDbStopTxPacket(PVOID pDeviceHandler, CARD_PKT_TYPE ePktType);
+BOOL CARDbStartTxPacket(PVOID pDeviceHandler, CARD_PKT_TYPE ePktType);
+BOOL CARDbSetBeaconPeriod(PVOID pDeviceHandler, WORD wBeaconInterval);
+BOOL CARDbSetBSSID(PVOID pDeviceHandler, PBYTE pbyBSSID, CARD_OP_MODE eOPMode);
+
+BOOL
+CARDbPowerDown(
+    PVOID   pDeviceHandler
+    );
+
+BOOL CARDbSetTxDataRate(
+    PVOID   pDeviceHandler,
+    WORD    wDataRate
+    );
+
+
+BOOL CARDbRemoveKey (PVOID pDeviceHandler, PBYTE pbyBSSID);
+
+BOOL
+CARDbAdd_PMKID_Candidate (
+    IN PVOID            pDeviceHandler,
+    IN PBYTE            pbyBSSID,
+    IN BOOL             bRSNCapExist,
+    IN WORD             wRSNCap
+    );
+
+PVOID
+CARDpGetCurrentAddress (
+    IN PVOID            pDeviceHandler
+    );
+
+
+VOID CARDvInitChannelTable(PVOID pDeviceHandler);
+BYTE CARDbyGetChannelMapping(PVOID pDeviceHandler, BYTE byChannelNumber, CARD_PHY_TYPE ePhyType);
+
+BOOL
+CARDbStartMeasure (
+    IN PVOID            pDeviceHandler,
+    IN PVOID            pvMeasureEIDs,
+    IN UINT             uNumOfMeasureEIDs
+    );
+
+BOOL
+CARDbChannelSwitch (
+    IN PVOID            pDeviceHandler,
+    IN BYTE             byMode,
+    IN BYTE             byNewChannel,
+    IN BYTE             byCount
+    );
+
+BOOL
+CARDbSetQuiet (
+    IN PVOID            pDeviceHandler,
+    IN BOOL             bResetQuiet,
+    IN BYTE             byQuietCount,
+    IN BYTE             byQuietPeriod,
+    IN WORD             wQuietDuration,
+    IN WORD             wQuietOffset
+    );
+
+BOOL
+CARDbStartQuiet (
+    IN PVOID            pDeviceHandler
+    );
+
+VOID
+CARDvSetCountryInfo (
+    IN PVOID            pDeviceHandler,
+    IN CARD_PHY_TYPE    ePHYType,
+    IN PVOID            pIE
+    );
+
+VOID
+CARDvSetPowerConstraint (
+    IN PVOID            pDeviceHandler,
+    IN BYTE             byChannel,
+    IN I8               byPower
+    );
+
+VOID
+CARDvGetPowerCapability (
+    IN PVOID            pDeviceHandler,
+    OUT PBYTE           pbyMinPower,
+    OUT PBYTE           pbyMaxPower
+    );
+
+BYTE
+CARDbySetSupportChannels (
+    IN PVOID            pDeviceHandler,
+    IN OUT PBYTE        pbyIEs
+    );
+
+I8
+CARDbyGetTransmitPower (
+    IN PVOID            pDeviceHandler
+    );
+
+BOOL
+CARDbChannelGetList (
+    IN  UINT       uCountryCodeIdx,
+    OUT PBYTE      pbyChannelTable
+    );
+
+VOID
+CARDvSetCountryIE(
+    IN PVOID        pDeviceHandler,
+    IN PVOID        pIE
+    );
+
+BOOL
+CARDbGetChannelMapInfo(
+    IN PVOID        pDeviceHandler,
+    IN UINT         uChannelIndex,
+    OUT PBYTE       pbyChannelNumber,
+    OUT PBYTE       pbyMap
+    );
+
+VOID
+CARDvSetChannelMapInfo(
+    IN PVOID        pDeviceHandler,
+    IN UINT         uChannelIndex,
+    IN BYTE         byMap
+    );
+
+VOID
+CARDvClearChannelMapInfo(
+    IN PVOID        pDeviceHandler
+    );
+
+BYTE
+CARDbyAutoChannelSelect(
+    IN PVOID        pDeviceHandler,
+    CARD_PHY_TYPE   ePHYType
+    );
+
+BYTE CARDbyGetChannelNumber(PVOID pDeviceHandler, BYTE byChannelIndex);
+
+#ifdef __cplusplus
+}                                       /* End of extern "C" { */
+#endif /* __cplusplus */
+
+
+#endif // __CARD_H__
+
+
+
diff --git a/drivers/staging/vt6655/country.h b/drivers/staging/vt6655/country.h
new file mode 100644 (file)
index 0000000..65d1e52
--- /dev/null
@@ -0,0 +1,192 @@
+/*
+ * 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__
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+
+
+/*---------------------  Export Definitions -------------------------*/
+/************************************************************************
+ * 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;
+
+typedef struct tagSCountryTable
+{
+    BYTE    byChannelCountryCode;             /* The country code         */
+    CHAR    chCountryCode[2];
+    BYTE    bChannelIdxList[CB_MAX_CHANNEL];  /* Available channels Index */
+    BYTE    byPower[CB_MAX_CHANNEL];
+}   SCountryTable, DEF* PSCountryTable;
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+extern SCountryTable ChannelRuleTab[CCODE_MAX+1];
+
+/*---------------------  Export Functions  --------------------------*/
+#ifdef __cplusplus
+extern "C" {                            /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+
+#ifdef __cplusplus
+}                                       /* End of extern "C" { */
+#endif /* __cplusplus */
+
+
+/************************************************************************
+ * Function prototype
+ ************************************************************************/
+#endif  /* __COUNTRY_H__ */
diff --git a/drivers/staging/vt6655/datarate.c b/drivers/staging/vt6655/datarate.c
new file mode 100644 (file)
index 0000000..f58f963
--- /dev/null
@@ -0,0 +1,455 @@
+/*
+ * 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
+
+/*---------------------  Static Definitions -------------------------*/
+
+
+
+
+/*---------------------  Static Classes  ----------------------------*/
+
+
+ extern WORD TxRate_iwconfig; //2008-5-8 <add> by chester
+/*---------------------  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
+wGetRateIdx(
+    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;
+
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ParseMaxRate Len: %d\n", uRateLen);
+    if (pDevice->eCurrentPHYType != PHY_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, wGetRateIdx(byRate));
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ParseMaxRate AddBasicRate: %d\n", wGetRateIdx(byRate));
+        }
+        byRate = (BYTE)(pItemRates->abyRates[ii]&0x7F);
+        if (byHighSuppRate == 0)
+            byHighSuppRate = byRate;
+        if (byRate > byHighSuppRate)
+            byHighSuppRate = byRate;
+        *pwSuppRate |= (1<<wGetRateIdx(byRate));
+    }
+    if ((pItemExtRates != NULL) && (pItemExtRates->byElementID == WLAN_EID_EXTSUPP_RATES) &&
+        (pDevice->eCurrentPHYType != PHY_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, wGetRateIdx(byRate));
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ParseMaxRate AddBasicRate: %d\n", wGetRateIdx(byRate));
+            }
+            byRate = (BYTE)(pItemExtRates->abyRates[ii]&0x7F);
+            if (byHighSuppRate == 0)
+                byHighSuppRate = byRate;
+            if (byRate > byHighSuppRate)
+                byHighSuppRate = byRate;
+            *pwSuppRate |= (1<<wGetRateIdx(byRate));
+            //DBG_PRN_GRP09(("ParseMaxRate : HighSuppRate: %d, %X\n", wGetRateIdx(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 = wGetRateIdx(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->eCurrentPHYType);
+
+     DEVICE_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;
+WORD            wIdxDownRate = 0;
+UINT            ii;
+//DWORD           dwRateTable[MAX_RATE]  = {1,   2,   5,   11,  6,    9,    12,   18,  24,  36,  48,  54};
+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 (pDevice->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, psNodeDBTable->uTxOk[ii], psNodeDBTable->uTxFail[ii], 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 =0 & uTxFail = 0
+        if (psNodeDBTable->uTxFail[MAX_RATE] == 0)
+            psNodeDBTable->wTxDataRate = wIdxUpRate;
+    }
+//2008-5-8 <add> by chester
+TxRate_iwconfig=psNodeDBTable->wTxDataRate;
+    s_vResetCounter(psNodeDBTable);
+//    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Rate: %d, U:%d, D:%d\n", psNodeDBTable->wTxDataRate, wIdxUpRate, wIdxDownRate);
+
+    return;
+
+}
+
+/*+
+ *
+ * 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/vt6655/datarate.h b/drivers/staging/vt6655/datarate.h
new file mode 100644 (file)
index 0000000..5096f3d
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * 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
+
+
+/*---------------------  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
+wGetRateIdx(
+    IN BYTE byRate
+    );
+
+
+BYTE
+DATARATEbyGetRateIdx(
+    IN BYTE byRate
+    );
+
+
+#endif //__DATARATE_H__
diff --git a/drivers/staging/vt6655/desc.h b/drivers/staging/vt6655/desc.h
new file mode 100644 (file)
index 0000000..c0fc1d3
--- /dev/null
@@ -0,0 +1,697 @@
+/*
+ * 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
+// #ifdef PRIVATE_OBJ
+//#if !defined(__DEVICE_MODULE_H)
+//#include "device_module.h"
+//#endif
+
+
+
+
+/*---------------------  Export Definitions -------------------------*/
+
+#define B_OWNED_BY_CHIP     1           //
+#define B_OWNED_BY_HOST     0           //
+
+//
+// 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 TSR0 register
+//
+#define TSR0_PWRSTS1_2      0xC0        // 1100 0000
+#define TSR0_PWRSTS7        0x20        // 0010 0000
+#define TSR0_NCR            0x1F        // 0001 1111
+
+//
+// Bits in the TSR1 register
+//
+#define TSR1_TERR           0x80        // 1000 0000
+#define TSR1_PWRSTS4_6      0x70        // 0111 0000
+#define TSR1_RETRYTMO       0x08        // 0000 1000
+#define TSR1_TMO            0x04        // 0000 0100
+#define TSR1_PWRSTS3        0x02        // 0000 0010
+#define ACK_DATA            0x01        // 0000 0000
+
+//
+// Bits in the TCR register
+//
+#define EDMSDU              0x04        // 0000 0100 end of sdu
+#define TCR_EDP             0x02        // 0000 0010 end of packet
+#define TCR_STP             0x01        // 0000 0001 start of packet
+
+// 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 CB_MAX_RX_DESC      128         // max # of descriptor
+#define CB_MIN_RX_DESC      16          // min # of rx descriptor
+#define CB_MAX_TX_DESC      64          // max # of descriptor
+#define CB_MIN_TX_DESC      16          // min # of tx descriptor
+
+#define CB_MAX_RECEIVED_PACKETS     16  // max # of received packets at one time
+                                        // limit our receive routine to indicating
+                                        // this many at a time for 2 reasons:
+                                        // 1. driver flow control to protocol layer
+                                        // 2. limit the time used in ISR routine
+
+#define CB_EXTRA_RD_NUM     32          // default # of Extra RD
+#define CB_RD_NUM           32          // default # of RD
+#define CB_TD_NUM           32          // default # of TD
+
+
+// max number of physical segments
+// in a single NDIS packet. Above this threshold, the packet
+// is copied into a single physically contiguous buffer
+#define CB_MAX_SEGMENT      4
+
+#define CB_MIN_MAP_REG_NUM  4
+#define CB_MAX_MAP_REG_NUM  CB_MAX_TX_DESC
+
+#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
+
+#ifdef __BIG_ENDIAN
+
+// WMAC definition FIFO Control
+#define FIFOCTL_AUTO_FB_1   0x0010 // 0001 0000 0000 0000
+#define FIFOCTL_AUTO_FB_0   0x0008 // 0000 1000 0000 0000
+#define FIFOCTL_GRPACK      0x0004 // 0000 0100 0000 0000
+#define FIFOCTL_11GA        0x0003 // 0000 0011 0000 0000
+#define FIFOCTL_11GB        0x0002 // 0000 0010 0000 0000
+#define FIFOCTL_11B         0x0001 // 0000 0001 0000 0000
+#define FIFOCTL_11A         0x0000 // 0000 0000 0000 0000
+#define FIFOCTL_RTS         0x8000 // 0000 0000 1000 0000
+#define FIFOCTL_ISDMA0      0x4000 // 0000 0000 0100 0000
+#define FIFOCTL_GENINT      0x2000 // 0000 0000 0010 0000
+#define FIFOCTL_TMOEN       0x1000 // 0000 0000 0001 0000
+#define FIFOCTL_LRETRY      0x0800 // 0000 0000 0000 1000
+#define FIFOCTL_CRCDIS      0x0400 // 0000 0000 0000 0100
+#define FIFOCTL_NEEDACK     0x0200 // 0000 0000 0000 0010
+#define FIFOCTL_LHEAD       0x0100 // 0000 0000 0000 0001
+
+//WMAC definition Frag Control
+#define FRAGCTL_AES         0x0003 // 0000 0011 0000 0000
+#define FRAGCTL_TKIP        0x0002 // 0000 0010 0000 0000
+#define FRAGCTL_LEGACY      0x0001 // 0000 0001 0000 0000
+#define FRAGCTL_NONENCRYPT  0x0000 // 0000 0000 0000 0000
+//#define FRAGCTL_AC3         0x0C00 // 0000 0000 0000 1100
+//#define FRAGCTL_AC2         0x0800 // 0000 0000 0000 1000
+//#define FRAGCTL_AC1         0x0400 // 0000 0000 0000 0100
+//#define FRAGCTL_AC0         0x0000 // 0000 0000 0000 0000
+#define FRAGCTL_ENDFRAG     0x0300 // 0000 0000 0000 0011
+#define FRAGCTL_MIDFRAG     0x0200 // 0000 0000 0000 0010
+#define FRAGCTL_STAFRAG     0x0100 // 0000 0000 0000 0001
+#define FRAGCTL_NONFRAG     0x0000 // 0000 0000 0000 0000
+
+#else
+
+#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
+
+#endif // #ifdef __BIG_ENDIAN
+
+//#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  ------------------------------*/
+
+// ref_sk_buff is used for mapping the skb structure between pre-built driver-obj & running kernel.
+// Since different kernel version (2.4x) may change skb structure, i.e. pre-built driver-obj
+// may link to older skb that leads error.
+
+typedef struct tagDEVICE_RD_INFO {
+    struct sk_buff* skb;
+#ifdef PRIVATE_OBJ
+    ref_sk_buff ref_skb;
+#endif
+    dma_addr_t  skb_dma;
+    dma_addr_t  curr_desc;
+} DEVICE_RD_INFO,   *PDEVICE_RD_INFO;
+
+/*
+static inline PDEVICE_RD_INFO alloc_rd_info(void) {
+    PDEVICE_RD_INFO  ptr;
+    if ((ptr = kmalloc(sizeof(DEVICE_RD_INFO), GFP_ATOMIC)) == NULL)
+        return NULL;
+    else {
+        memset(ptr,0,sizeof(DEVICE_RD_INFO));
+        return ptr;
+    }
+}
+*/
+
+/*
+typedef struct tagRDES0 {
+    WORD    wResCount;
+    WORD    wf1Owner ;
+//    WORD    f15Reserved : 15;
+//    WORD    f1Owner : 1;
+} __attribute__ ((__packed__))
+SRDES0;
+*/
+
+#ifdef __BIG_ENDIAN
+
+typedef struct tagRDES0 {
+   volatile WORD    wResCount;
+       union {
+               volatile U16    f15Reserved;
+               struct {
+            volatile U8 f8Reserved1;
+                       volatile U8 f1Owner:1;
+                       volatile U8 f7Reserved:7;
+               } __attribute__ ((__packed__));
+       } __attribute__ ((__packed__));
+} __attribute__ ((__packed__))
+SRDES0, *PSRDES0;
+
+#else
+
+typedef struct tagRDES0 {
+    WORD    wResCount;
+    WORD    f15Reserved : 15;
+    WORD    f1Owner : 1;
+} __attribute__ ((__packed__))
+SRDES0;
+
+
+#endif
+
+typedef struct tagRDES1 {
+    WORD   wReqCount;
+    WORD   wReserved;
+} __attribute__ ((__packed__))
+SRDES1;
+
+//
+// Rx descriptor
+//
+typedef struct tagSRxDesc {
+    volatile SRDES0 m_rd0RD0;
+    volatile SRDES1 m_rd1RD1;
+    volatile U32    buff_addr;
+    volatile U32    next_desc;
+    struct tagSRxDesc   *next;//4 bytes
+    volatile PDEVICE_RD_INFO    pRDInfo;//4 bytes
+    volatile U32    Reserved[2];//8 bytes
+} __attribute__ ((__packed__))
+SRxDesc, DEF* PSRxDesc;
+typedef const SRxDesc DEF*      PCSRxDesc;
+
+#ifdef __BIG_ENDIAN
+
+/*
+typedef struct tagTDES0 {
+    volatile    BYTE    byTSR0;
+    volatile    BYTE    byTSR1;
+    volatile    WORD    wOwner_Txtime;
+//    volatile    WORD    f15Txtime : 15;
+//    volatile    WORD    f1Owner:1;
+} __attribute__ ((__packed__))
+STDES0;
+*/
+
+typedef struct tagTDES0 {
+    volatile    BYTE    byTSR0;
+    volatile    BYTE    byTSR1;
+       union {
+               volatile U16    f15Txtime;
+               struct {
+            volatile U8 f8Reserved1;
+                       volatile U8 f1Owner:1;
+                       volatile U8 f7Reserved:7;
+               } __attribute__ ((__packed__));
+       } __attribute__ ((__packed__));
+} __attribute__ ((__packed__))
+STDES0, PSTDES0;
+
+#else
+
+typedef struct tagTDES0 {
+    volatile    BYTE    byTSR0;
+    volatile    BYTE    byTSR1;
+    volatile    WORD    f15Txtime : 15;
+    volatile    WORD    f1Owner:1;
+} __attribute__ ((__packed__))
+STDES0;
+
+#endif
+
+
+typedef struct tagTDES1 {
+    volatile    WORD    wReqCount;
+    volatile    BYTE    byTCR;
+    volatile    BYTE    byReserved;
+} __attribute__ ((__packed__))
+STDES1;
+
+
+typedef struct tagDEVICE_TD_INFO{
+    struct sk_buff*     skb;
+    PBYTE               buf;
+    dma_addr_t          skb_dma;
+    dma_addr_t          buf_dma;
+    dma_addr_t          curr_desc;
+    DWORD               dwReqCount;
+    DWORD               dwHeaderLength;
+    BYTE                byFlags;
+} DEVICE_TD_INFO,    *PDEVICE_TD_INFO;
+
+/*
+static inline PDEVICE_TD_INFO alloc_td_info(void) {
+    PDEVICE_TD_INFO  ptr;
+    if ((ptr = kmalloc(sizeof(DEVICE_TD_INFO),GFP_ATOMIC))==NULL)
+        return NULL;
+    else {
+        memset(ptr,0,sizeof(DEVICE_TD_INFO));
+        return ptr;
+    }
+}
+*/
+
+//
+// transmit descriptor
+//
+typedef struct tagSTxDesc {
+    volatile    STDES0  m_td0TD0;
+    volatile    STDES1  m_td1TD1;
+    volatile    U32    buff_addr;
+    volatile    U32    next_desc;
+    struct tagSTxDesc*  next; //4 bytes
+    volatile    PDEVICE_TD_INFO pTDInfo;//4 bytes
+    volatile    U32    Reserved[2];//8 bytes
+} __attribute__ ((__packed__))
+STxDesc, DEF* PSTxDesc;
+typedef const STxDesc DEF*      PCSTxDesc;
+
+
+typedef struct tagSTxSyncDesc {
+    volatile    STDES0  m_td0TD0;
+    volatile    STDES1  m_td1TD1;
+    volatile    DWORD   buff_addr; // pointer to logical buffer
+    volatile    DWORD   next_desc; // pointer to next logical descriptor
+    volatile    WORD    m_wFIFOCtl;
+    volatile    WORD    m_wTimeStamp;
+    struct tagSTxSyncDesc*  next; //4 bytes
+    volatile    PDEVICE_TD_INFO pTDInfo;//4 bytes
+    volatile    DWORD   m_dwReserved2;
+} __attribute__ ((__packed__))
+STxSyncDesc, DEF* PSTxSyncDesc;
+typedef const STxSyncDesc DEF*      PCSTxSyncDesc;
+
+
+//
+// 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;
+    BYTE    byTxPower;
+    BYTE    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/vt6655/device.h b/drivers/staging/vt6655/device.h
new file mode 100644 (file)
index 0000000..264d1bb
--- /dev/null
@@ -0,0 +1,1063 @@
+/*
+ * 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 <asm/io.h>
+#include <linux/if.h>
+//#include <linux/config.h>
+#include <asm/uaccess.h>
+#include <linux/proc_fs.h>
+#include <linux/inetdevice.h>
+#include <linux/reboot.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
+//2008-4-14<add> by chester for led issue
+//#define FOR_LED_ON_NOTEBOOK
+//
+
+
+
+//  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(__MAC_H__)
+#include "mac.h"
+#endif
+
+//PLICE_DEBUG->
+//#define              THREAD
+
+//#define      TASK_LET
+//PLICE_DEBUG<-
+
+// #ifdef PRIVATE_OBJ
+//#if !defined(__DEVICE_MODULE_H)
+//#include "device_module.h"
+//#endif
+
+
+/*---------------------  Export Definitions -------------------------*/
+
+#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 MAXCHECKHANGCNT         4
+
+#define BB_VGA_LEVEL            4
+#define BB_VGA_CHANGE_THRESHOLD 16
+
+
+#ifndef RUN_AT
+#define RUN_AT(x)                       (jiffies+(x))
+#endif
+
+// DMA related
+#define RESERV_AC0DMA                   4
+
+
+// BUILD OBJ mode
+#ifdef PRIVATE_OBJ
+
+#undef dev_kfree_skb
+#undef dev_kfree_skb_irq
+#undef dev_alloc_skb
+#undef kfree
+#undef del_timer
+#undef init_timer
+#undef add_timer
+#undef kmalloc
+#undef netif_stop_queue
+#undef netif_start_queue
+#undef netif_wake_queue
+#undef netif_queue_stopped
+#undef netif_rx
+#undef netif_running
+#undef udelay
+#undef mdelay
+#undef eth_type_trans
+#undef skb_put
+#undef HZ
+#undef RUN_AT
+#undef pci_alloc_consistent
+#undef pci_free_consistent
+#undef register_netdevice
+#undef register_netdev
+#undef unregister_netdevice
+#undef unregister_netdev
+#undef skb_queue_head_init
+#undef skb_queue_tail
+#undef skb_queue_empty
+#undef free_irq
+#undef copy_from_user
+#undef copy_to_user
+#undef spin_lock_init
+#undef pci_map_single
+#undef pci_unmap_single
+
+// redefine kernel dependent fucntion
+#define dev_kfree_skb       ref_dev_kfree_skb
+#define dev_kfree_skb_irq   ref_dev_kfree_skb_irq
+#define dev_alloc_skb       ref_dev_alloc_skb
+#define kfree               ref_kfree
+#define del_timer           ref_del_timer
+#define init_timer          ref_init_timer
+#define add_timer           ref_add_timer
+#define kmalloc             ref_kmalloc
+#define netif_stop_queue    ref_netif_stop_queue
+#define netif_start_queue   ref_netif_start_queue
+#define netif_wake_queue    ref_netif_wake_queue
+#define netif_queue_stopped ref_netif_queue_stopped
+#define netif_rx            ref_netif_rx
+#define netif_running       ref_netif_running
+#define udelay              ref_udelay
+#define mdelay              ref_mdelay
+#define get_jiffies()       ref_get_jiffies()
+#define RUN_AT(x)           (get_jiffies()+(x))
+#define HZ                  ref_HZ_tick()
+#define eth_type_trans      ref_eth_type_trans
+#define skb_put             ref_skb_put
+#define skb_queue_head_init ref_skb_queue_head_init
+#define skb_queue_tail      ref_skb_queue_tail
+#define skb_queue_empty     ref_skb_queue_empty
+
+#define pci_alloc_consistent    ref_pci_alloc_consistent
+#define pci_free_consistent     ref_pci_free_consistent
+#define register_netdevice      ref_register_netdevice
+#define register_netdev         ref_register_netdev
+#define unregister_netdevice    ref_unregister_netdevice
+#define unregister_netdev       ref_unregister_netdev
+
+#define free_irq                ref_free_irq
+#define copy_from_user          ref_copy_from_user
+#define copy_to_user            ref_copy_to_user
+#define spin_lock_init          ref_spin_lock_init
+#define pci_map_single          ref_pci_map_single
+#define pci_unmap_single        ref_pci_unmap_single
+#endif
+
+
+#ifdef PRIVATE_OBJ
+#undef  printk
+#define DEVICE_PRT(l, p, args...) {if (l<=msglevel) do {} while (0);}
+//#define DEVICE_PRT(l, p, args...) {if (l<=msglevel) printk( p ,##args);}
+#else
+#define DEVICE_PRT(l, p, args...) {if (l<=msglevel) printk( p ,##args);}
+#endif
+
+
+#define        AVAIL_TD(p,q)   ((p)->sOpts.nTxDescs[(q)]-((p)->iTDUsed[(q)]))
+
+//PLICE_DEBUG ->
+#define        NUM                             64
+//PLICE_DEUBG <-
+
+
+
+/*---------------------  Export Types  ------------------------------*/
+
+
+//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;
+
+
+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;
+
+
+//++ NDIS related
+
+#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;
+
+//--
+typedef struct __chip_info_tbl{
+    CHIP_TYPE   chip_id;
+    char*       name;
+    int         io_size;
+    int         nTxQueue;
+    U32         flags;
+} CHIP_INFO, *PCHIP_INFO;
+
+
+typedef enum {
+    OWNED_BY_HOST=0,
+    OWNED_BY_NIC=1
+} DEVICE_OWNER_TYPE, *PDEVICE_OWNER_TYPE;
+
+
+// The receive duplicate detection cache entry
+typedef struct tagSCacheEntry{
+    WORD        wFmSequence;
+    BYTE        abyAddr2[U_ETHER_ADDR_LEN];
+} 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;
+#ifdef PRIVATE_OBJ
+    ref_sk_buff     ref_skb;
+#endif
+    PBYTE           pbyRxBuffer;
+    UINT            cbFrameLength;
+    BOOL            bInUse;
+} SDeFragControlBlock, DEF* PSDeFragControlBlock;
+
+
+
+
+//flags for options
+#define     DEVICE_FLAGS_IP_ALIGN        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
+#define                DEVICE_FLAGS_DiversityANT        0x00000020UL
+
+//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
+
+
+//PLICE_DEBUG->
+
+
+typedef        struct _RxManagementQueue
+{
+       int     packet_num;
+       int     head,tail;
+       PSRxMgmtPacket  Q[NUM];
+} RxManagementQueue,*PSRxManagementQueue;
+
+
+
+//PLICE_DEBUG<-
+
+
+typedef struct __device_opt {
+    int         nRxDescs0;      //Number of RX descriptors0
+    int         nRxDescs1;      //Number of RX descriptors1
+    int         nTxDescs[2];    //Number of TX descriptors 0, 1
+    int         int_works;      //interrupt limits
+    int         rts_thresh;     //rts threshold
+    int         frag_thresh;
+    int         data_rate;
+    int         channel_num;
+    int         short_retry;
+    int         long_retry;
+    int         bbp_type;
+    U32         flags;
+} OPTIONS, *POPTIONS;
+
+
+typedef struct __device_info {
+    struct __device_info*        next;
+    struct __device_info*        prev;
+
+    struct pci_dev*             pcid;
+
+#if CONFIG_PM
+    u32                         pci_state[16];
+#endif
+
+// netdev
+    struct net_device*          dev;
+    struct net_device*          next_module;
+    struct net_device_stats     stats;
+
+//dma addr, rx/tx pool
+    dma_addr_t                  pool_dma;
+    dma_addr_t                  rd0_pool_dma;
+    dma_addr_t                  rd1_pool_dma;
+
+    dma_addr_t                  td0_pool_dma;
+    dma_addr_t                  td1_pool_dma;
+
+    dma_addr_t                  tx_bufs_dma0;
+    dma_addr_t                  tx_bufs_dma1;
+    dma_addr_t                  tx_beacon_dma;
+
+    PBYTE                       tx0_bufs;
+    PBYTE                       tx1_bufs;
+    PBYTE                       tx_beacon_bufs;
+
+    CHIP_TYPE                   chip_id;
+
+    U32                         PortOffset;
+    DWORD                       dwIsr;
+    U32                         memaddr;
+    U32                         ioaddr;
+    U32                         io_size;
+
+    BYTE                        byRevId;
+    WORD                        SubSystemID;
+    WORD                        SubVendorID;
+
+    int                         nTxQueues;
+    volatile int                iTDUsed[TYPE_MAXTD];
+
+    volatile PSTxDesc           apCurrTD[TYPE_MAXTD];
+    volatile PSTxDesc           apTailTD[TYPE_MAXTD];
+
+    volatile PSTxDesc           apTD0Rings;
+    volatile PSTxDesc           apTD1Rings;
+
+    volatile PSRxDesc           aRD0Ring;
+    volatile PSRxDesc           aRD1Ring;
+    volatile PSRxDesc           pCurrRD[TYPE_MAXRD];
+    SCache                      sDupRxCache;
+
+    SDeFragControlBlock         sRxDFCB[CB_MAX_RX_FRAG];
+    UINT                        cbDFCB;
+    UINT                        cbFreeDFCB;
+    UINT                        uCurrentDFCBIdx;
+
+    OPTIONS                     sOpts;
+
+    U32                         flags;
+
+    U32                         rx_buf_sz;
+    int                         multicast_limit;
+    BYTE                        byRxMode;
+
+    spinlock_t                  lock;
+//PLICE_DEBUG->
+       struct  tasklet_struct          RxMngWorkItem;
+       RxManagementQueue       rxManeQueue;
+//PLICE_DEBUG<-
+//PLICE_DEBUG ->
+       pid_t                           MLMEThr_pid;
+       struct  completion      notify;
+       struct  semaphore       mlme_semaphore;
+//PLICE_DEBUG <-
+
+
+    U32                         rx_bytes;
+
+    // Version control
+    BYTE                        byLocalID;
+    BYTE                        byRFType;
+
+    BYTE                        byMaxPwrLevel;
+    BYTE                        byZoneType;
+    BOOL                        bZoneRegExist;
+   BYTE                        byOriginalZonetype;
+    BYTE                        abyMacContext[MAC_MAX_CONTEXT_REG];
+    BOOL                        bLinkPass;          // link status: OK or fail
+    BYTE                        abyCurrentNetAddr[U_ETHER_ADDR_LEN];
+
+    // Adapter statistics
+    SStatCounter                scStatistic;
+    // 802.11 counter
+    SDot11Counters              s802_11Counter;
+
+
+    // 802.11 management
+    PSMgmtObject                pMgmt;
+    SMgmtObject                 sMgmtObj;
+
+    // 802.11 MAC specific
+    UINT                        uCurrRSSI;
+    BYTE                        byCurrSQ;
+
+    DWORD                       dwTxAntennaSel;
+    DWORD                       dwRxAntennaSel;
+    BYTE                        byAntennaCount;
+    BYTE                        byRxAntennaMode;
+    BYTE                        byTxAntennaMode;
+    BOOL                        bTxRxAntInv;
+
+    PBYTE                       pbyTmpBuff;
+    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;
+    CARD_PHY_TYPE               eCurrentPHYType;
+
+
+    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;
+
+    BYTE                        byMinChannel;
+    BYTE                        byMaxChannel;
+    UINT                        uConnectionRate;
+
+    BYTE                        byPreambleType;
+    BYTE                        byShortPreamble;
+
+    WORD                        wCurrentRate;
+    WORD                        wRTSThreshold;
+    WORD                        wFragmentationThreshold;
+    BYTE                        byShortRetryLimit;
+    BYTE                        byLongRetryLimit;
+    CARD_OP_MODE                eOPMode;
+    BYTE                        byOpMode;
+    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                        bShortSlotTime;
+    BOOL                        bProtectMode;
+    BOOL                        bNonERPPresent;
+    BOOL                        bBarkerPreambleMd;
+
+    BYTE                        byERPFlag;
+    WORD                        wUseProtectCntDown;
+
+    BOOL                    bRadioControlOff;
+    BOOL                    bRadioOff;
+    BOOL                    bEnablePSMode;
+    WORD                    wListenInterval;
+    BOOL                    bPWBitOn;
+    WMAC_POWER_MODE         ePSMode;
+
+
+    // GPIO Radio Control
+    BYTE                    byRadioCtl;
+    BYTE                    byGPIO;
+    BOOL                    bHWRadioOff;
+    BOOL                    bPrvActive4RadioOFF;
+    BOOL                    bGPIOBlockRead;
+
+    // Beacon releated
+    WORD                    wSeqCounter;
+    WORD                    wBCNBufLen;
+    BOOL                    bBeaconBufReady;
+    BOOL                    bBeaconSent;
+    BOOL                    bIsBeaconBufReadySet;
+    UINT                    cbBeaconBufReadySetCnt;
+    BOOL                    bFixRate;
+    BYTE                    byCurrentCh;
+    UINT                    uScanTime;
+
+    CMD_STATE               eCommandState;
+
+    CMD_CODE                eCommand;
+    BOOL                    bBeaconTx;
+
+    BOOL                    bStopBeacon;
+    BOOL                    bStopDataPkt;
+    BOOL                    bStopTx0Pkt;
+    UINT                    uAutoReConnectTime;
+
+    // 802.11 counter
+
+    CMD_ITEM                eCmdQueue[CMD_Q_SIZE];
+    UINT                    uCmdDequeueIdx;
+    UINT                    uCmdEnqueueIdx;
+    UINT                    cbFreeCmdQueue;
+    BOOL                    bCmdRunning;
+    BOOL                    bCmdClear;
+
+
+
+    BOOL                    bRoaming;
+    //WOW
+    BYTE                    abyIPAddr[4];
+
+    ULONG                   ulTxPower;
+    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;
+
+    QWORD                   qwPacketNumber; //For CCMP and TKIP as TSC(6 bytes)
+    UINT                    uCurrentWEPMode;
+
+    RC4Ext                  SBox;
+    BYTE                    abyPRNG[WLAN_WEPMAX_KEYLEN+3];
+
+    BYTE                    byKeyIndex;
+    UINT                    uKeyLength;
+    BYTE                    abyKey[WLAN_WEP232_KEYLEN];
+
+    BOOL                    bAES;
+    BYTE                    byCntMeasure;
+
+    // for AP mode
+    UINT                    uAssocCount;
+    BOOL                    bMoreData;
+
+    // QoS
+    BOOL                    bGrpAckPolicy;
+
+    // for OID_802_11_ASSOCIATION_INFORMATION
+    BOOL                    bAssocInfoSet;
+
+
+    BYTE                    byAutoFBCtrl;
+
+    BOOL                    bTxMICFail;
+    BOOL                    bRxMICFail;
+
+
+    UINT                    uRATEIdx;
+
+
+    // 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;
+    SHORT                   sPSetPointCCK;
+    SHORT                   sPSetPointOFDMG;
+    SHORT                   sPSetPointOFDMA;
+    LONG                    lPFormulaOffset;
+    SHORT                   sPThreshold;
+    CHAR                    cAdjustStep;
+    CHAR                    cMinTxAGC;
+
+    // For RF Power table
+    BYTE                    byCCKPwr;
+    BYTE                    byOFDMPwrG;
+    BYTE                    byCurPwr;
+    I8                      byCurPwrdBm;
+    BYTE                    abyCCKPwrTbl[CB_MAX_CHANNEL_24G+1];
+    BYTE                    abyOFDMPwrTbl[CB_MAX_CHANNEL+1];
+    I8                      abyCCKDefaultPwr[CB_MAX_CHANNEL_24G+1];
+    I8                      abyOFDMDefaultPwr[CB_MAX_CHANNEL+1];
+    I8                      abyRegPwr[CB_MAX_CHANNEL+1];
+    I8                      abyLocalPwr[CB_MAX_CHANNEL+1];
+
+
+    // BaseBand Loopback Use
+    BYTE                    byBBCR4d;
+    BYTE                    byBBCRc9;
+    BYTE                    byBBCR88;
+    BYTE                    byBBCR09;
+
+    // command timer
+    struct timer_list       sTimerCommand;
+#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;
+
+
+    BYTE                    abyNodeName[17];
+
+    BOOL                    bDiversityRegCtlON;
+    BOOL                    bDiversityEnable;
+    ULONG                   ulDiversityNValue;
+    ULONG                   ulDiversityMValue;
+    BYTE                    byTMax;
+    BYTE                    byTMax2;
+    BYTE                    byTMax3;
+    ULONG                   ulSQ3TH;
+
+// ANT diversity
+    ULONG                   uDiversityCnt;
+    BYTE                    byAntennaState;
+    ULONG                   ulRatio_State0;
+    ULONG                   ulRatio_State1;
+
+    //SQ3 functions for antenna diversity
+    struct timer_list           TimerSQ3Tmax1;
+    struct timer_list           TimerSQ3Tmax2;
+    struct timer_list           TimerSQ3Tmax3;
+
+
+    ULONG                   uNumSQ3[MAX_RATE];
+    WORD                    wAntDiversityMaxRate;
+
+
+    SEthernetHeader         sTxEthHeader;
+    SEthernetHeader         sRxEthHeader;
+    BYTE                    abyBroadcastAddr[U_ETHER_ADDR_LEN];
+    BYTE                    abySNAP_RFC1042[U_ETHER_ADDR_LEN];
+    BYTE                    abySNAP_Bridgetunnel[U_ETHER_ADDR_LEN];
+     BYTE                        abyEEPROM[EEP_MAX_CONTEXT_SIZE];  //DWORD alignment
+    // Pre-Authentication & PMK cache
+    SPMKID                  gsPMKID;
+    SPMKIDCandidateEvent    gsPMKIDCandidate;
+
+
+    // for 802.11h
+    BOOL                    b11hEnable;
+    BYTE                    abyCountryCode[3];
+    // for 802.11h DFS
+    UINT                    uNumOfMeasureEIDs;
+    PWLAN_IE_MEASURE_REQ    pCurrMeasureEID;
+    BOOL                    bMeasureInProgress;
+    BYTE                    byOrgChannel;
+    BYTE                    byOrgRCR;
+    DWORD                   dwOrgMAR0;
+    DWORD                   dwOrgMAR4;
+    BYTE                    byBasicMap;
+    BYTE                    byCCAFraction;
+    BYTE                    abyRPIs[8];
+    DWORD                   dwRPIs[8];
+    BOOL                    bChannelSwitch;
+    BYTE                    byNewChannel;
+    BYTE                    byChannelSwitchCount;
+    BOOL                    bQuietEnable;
+    BOOL                    bEnableFirstQuiet;
+    BYTE                    byQuietStartCount;
+    UINT                    uQuietEnqueue;
+    DWORD                   dwCurrentQuietEndTime;
+    SQuietControl           sQuiet[MAX_QUIET_COUNT];
+    // for 802.11h TPC
+    BOOL                    bCountryInfo5G;
+    BOOL                    bCountryInfo24G;
+
+    WORD                    wBeaconInterval;
+
+    //WPA supplicant deamon
+       struct net_device       *wpadev;
+       BOOL                    bWPADEVUp;
+    struct sk_buff          *skb;
+#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+/*
+        BOOL                 bwextstep0;
+        BOOL                 bwextstep1;
+        BOOL                 bwextstep2;
+        BOOL                 bwextstep3;
+        */
+        UINT                   bwextcount;
+        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;
+    BOOL                    bMACSuspend;
+
+#ifdef WIRELESS_EXT
+       struct iw_statistics    wstats;         // wireless stats
+#endif /* WIRELESS_EXT */
+    BOOL                    bCommit;
+
+} DEVICE_INFO, *PSDevice;
+
+
+//PLICE_DEBUG->
+
+
+ inline  static        VOID   EnQueue (PSDevice pDevice,PSRxMgmtPacket  pRxMgmtPacket)
+{
+       //printk("Enter EnQueue:tail is %d\n",pDevice->rxManeQueue.tail);
+       if ((pDevice->rxManeQueue.tail+1) % NUM == pDevice->rxManeQueue.head)
+       {
+               //printk("Queue is Full,tail is %d\n",pDevice->rxManeQueue.tail);
+               return ;
+       }
+       else
+       {
+               pDevice->rxManeQueue.tail = (pDevice->rxManeQueue.tail+1)% NUM;
+               pDevice->rxManeQueue.Q[pDevice->rxManeQueue.tail] = pRxMgmtPacket;
+               pDevice->rxManeQueue.packet_num++;
+               //printk("packet num is %d\n",pDevice->rxManeQueue.packet_num);
+       }
+}
+
+
+
+
+       inline  static  PSRxMgmtPacket DeQueue (PSDevice pDevice)
+{
+       PSRxMgmtPacket  pRxMgmtPacket;
+       if (pDevice->rxManeQueue.tail == pDevice->rxManeQueue.head)
+       {
+               printk("Queue is Empty\n");
+               return NULL;
+       }
+       else
+       {
+               int     x;
+               //x=pDevice->rxManeQueue.head = (pDevice->rxManeQueue.head+1)%NUM;
+               pDevice->rxManeQueue.head = (pDevice->rxManeQueue.head+1)%NUM;
+               x = pDevice->rxManeQueue.head;
+               //printk("Enter DeQueue:head is %d\n",x);
+               pRxMgmtPacket = pDevice->rxManeQueue.Q[x];
+               pDevice->rxManeQueue.packet_num--;
+               return pRxMgmtPacket;
+       }
+}
+
+VOID   InitRxManagementQueue(PSDevice   pDevice);
+
+
+
+//PLICE_DEBUG<-
+
+
+
+
+
+
+inline static BOOL device_get_ip(PSDevice pInfo) {
+    struct in_device* in_dev=(struct in_device*) pInfo->dev->ip_ptr;
+    struct in_ifaddr* ifa;
+
+    if (in_dev!=NULL) {
+        ifa=(struct in_ifaddr*) in_dev->ifa_list;
+        if (ifa!=NULL) {
+            memcpy(pInfo->abyIPAddr,&ifa->ifa_address,4);
+            return TRUE;
+        }
+    }
+    return FALSE;
+}
+
+
+
+static inline PDEVICE_RD_INFO alloc_rd_info(void) {
+    PDEVICE_RD_INFO  ptr;
+    if ((ptr = (PDEVICE_RD_INFO)kmalloc((int)sizeof(DEVICE_RD_INFO), (int)GFP_ATOMIC)) == NULL)
+        return NULL;
+    else {
+        memset(ptr,0,sizeof(DEVICE_RD_INFO));
+        return ptr;
+    }
+}
+
+static inline PDEVICE_TD_INFO alloc_td_info(void) {
+    PDEVICE_TD_INFO  ptr;
+    if ((ptr = (PDEVICE_TD_INFO)kmalloc((int)sizeof(DEVICE_TD_INFO), (int)GFP_ATOMIC))==NULL)
+        return NULL;
+    else {
+        memset(ptr,0,sizeof(DEVICE_TD_INFO));
+        return ptr;
+    }
+}
+
+/*---------------------  Export Functions  --------------------------*/
+
+BOOL device_dma0_xmit(PSDevice pDevice, struct sk_buff *skb, UINT uNodeIndex);
+BOOL device_alloc_frag_buf(PSDevice pDevice, PSDeFragControlBlock pDeF);
+int Config_FileOperation(PSDevice pDevice,BOOL fwrite,unsigned char *Parameter);
+#endif
+
+
diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c
new file mode 100644 (file)
index 0000000..bade552
--- /dev/null
@@ -0,0 +1,4153 @@
+/*
+ * 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_main.c
+ *
+ * Purpose: driver entry for initial, open, close, tx and rx.
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: Jan 8, 2003
+ *
+ * Functions:
+ *
+ *   device_found1 - module initial (insmod) driver entry
+ *   device_remove1 - module remove entry
+ *   device_init_info - device structure resource allocation function
+ *   device_free_info - device structure resource free function
+ *   device_get_pci_info - get allocated pci io/mem resource
+ *   device_print_info - print out resource
+ *   device_open - allocate dma/descripter resource & initial mac/bbp function
+ *   device_xmit - asynchrous data tx function
+ *   device_intr - interrupt handle function
+ *   device_set_multi - set mac filter
+ *   device_ioctl - ioctl entry
+ *   device_close - shutdown mac/bbp & free dma/descripter resource
+ *   device_rx_srv - rx service function
+ *   device_receive_frame - rx data function
+ *   device_alloc_rx_buf - rx buffer pre-allocated function
+ *   device_alloc_frag_buf - rx fragement pre-allocated function
+ *   device_free_tx_buf - free tx buffer function
+ *   device_free_frag_buf- free de-fragement buffer
+ *   device_dma0_tx_80211- tx 802.11 frame via dma0
+ *   device_dma0_xmit- tx PS bufferred frame via dma0
+ *   device_init_rd0_ring- initial rd dma0 ring
+ *   device_init_rd1_ring- initial rd dma1 ring
+ *   device_init_td0_ring- initial tx dma0 ring buffer
+ *   device_init_td1_ring- initial tx dma1 ring buffer
+ *   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_free_rings- free all allocated ring 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(__WROUTE_H__)
+#include "wroute.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(__DATARATE_H__)
+#include "datarate.h"
+#endif
+#if !defined(__RF_H__)
+#include "rf.h"
+#endif
+#if !defined(__IOWPA_H__)
+#include "iowpa.h"
+#endif
+
+#include <linux/delay.h>
+#include <linux/kthread.h>
+// #ifdef PRIVATE_OBJ
+//#if !defined(__DEVICE_EXP_H)
+//#include "device_exp.h"
+//#endif
+//#if !defined(__DEVICE_MODULE_H)
+//#include "device_module.h"
+//#endif
+
+
+// #endif
+//#define      DEBUG
+/*---------------------  Static Definitions -------------------------*/
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+static int          msglevel                =   MSG_LEVEL_INFO;
+
+//#define      PLICE_DEBUG
+//
+// Define module options
+//
+#ifndef PRIVATE_OBJ
+MODULE_AUTHOR("VIA Networking Technologies, Inc., <lyndonchen@vntek.com.tw>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("VIA Networking Solomon-A/B/G Wireless LAN Adapter Driver");
+#endif
+
+//PLICE_DEBUG ->
+       static int mlme_kill;
+       //static  struct task_struct * mlme_task;
+//PLICE_DEBUG <-
+
+#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);
+*/
+
+#define RX_DESC_MIN0     16
+#define RX_DESC_MAX0     128
+#define RX_DESC_DEF0     32
+DEVICE_PARAM(RxDescriptors0,"Number of receive descriptors0");
+
+#define RX_DESC_MIN1     16
+#define RX_DESC_MAX1     128
+#define RX_DESC_DEF1     32
+DEVICE_PARAM(RxDescriptors1,"Number of receive descriptors1");
+
+#define TX_DESC_MIN0     16
+#define TX_DESC_MAX0     128
+#define TX_DESC_DEF0     32
+DEVICE_PARAM(TxDescriptors0,"Number of transmit descriptors0");
+
+#define TX_DESC_MIN1     16
+#define TX_DESC_MAX1     128
+#define TX_DESC_DEF1     64
+DEVICE_PARAM(TxDescriptors1,"Number of transmit descriptors1");
+
+
+#define IP_ALIG_DEF     0
+/* IP_byte_align[] is used for IP header DWORD byte aligned
+   0: indicate the IP header won't be DWORD byte aligned.(Default) .
+   1: indicate the IP header will be DWORD byte aligned.
+      In some enviroment, the IP header should be DWORD byte aligned,
+      or the packet will be droped when we receive it. (eg: IPVS)
+*/
+DEVICE_PARAM(IP_byte_align,"Enable IP header dword aligned");
+
+
+#define INT_WORKS_DEF   20
+#define INT_WORKS_MIN   10
+#define INT_WORKS_MAX   64
+
+DEVICE_PARAM(int_works,"Number of packets per interrupt services");
+
+#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_DEF     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");
+
+/* 80211hEnable[]
+   0: indicate disable 802.11h
+   1: indicate enable 802.11h
+*/
+
+#define DIVERSITY_ANT_DEF     0
+
+DEVICE_PARAM(bDiversityANTEnable, "ANT diversity mode");
+
+
+//
+// Static vars definitions
+//
+
+
+#ifndef PRIVATE_OBJ
+static int          device_nics             =0;
+static PSDevice     pDevice_Infos           =NULL;
+static struct net_device *root_device_dev = NULL;
+
+static CHIP_INFO chip_info_table[]= {
+    { VT3253,       "VIA Networking Solomon-A/B/G Wireless LAN Adapter ",
+        256, 1,     DEVICE_FLAGS_IP_ALIGN|DEVICE_FLAGS_TX_ALIGN },
+    {0,NULL}
+};
+
+static struct pci_device_id device_id_table[] __devinitdata = {
+{ 0x1106, 0x3253, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (int)&chip_info_table[0]},
+{ 0, }
+};
+#endif
+
+/*---------------------  Static Functions  --------------------------*/
+
+#ifndef PRIVATE_OBJ
+
+static int  device_found1(struct pci_dev *pcid, const struct pci_device_id *ent);
+static BOOL device_init_info(struct pci_dev* pcid, PSDevice* ppDevice, PCHIP_INFO);
+static void device_free_info(PSDevice pDevice);
+static BOOL device_get_pci_info(PSDevice, struct pci_dev* pcid);
+static void device_print_info(PSDevice pDevice);
+static struct net_device_stats *device_get_stats(struct net_device *dev);
+static void device_init_diversity_timer(PSDevice pDevice);
+static int  device_open(struct net_device *dev);
+static int  device_xmit(struct sk_buff *skb, struct net_device *dev);
+static  irqreturn_t  device_intr(int irq,  void*dev_instance);
+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);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,9)
+#ifdef CONFIG_PM
+static int device_notify_reboot(struct notifier_block *, unsigned long event, void *ptr);
+static int viawget_suspend(struct pci_dev *pcid, u32 state);
+static int viawget_resume(struct pci_dev *pcid);
+struct notifier_block device_notifier = {
+        notifier_call:  device_notify_reboot,
+        next:           NULL,
+        priority:       0
+};
+#endif
+#endif
+
+#endif // #ifndef PRIVATE_OBJ
+
+static void device_init_rd0_ring(PSDevice pDevice);
+static void device_init_rd1_ring(PSDevice pDevice);
+static void device_init_defrag_cb(PSDevice pDevice);
+static void device_init_td0_ring(PSDevice pDevice);
+static void device_init_td1_ring(PSDevice pDevice);
+
+#ifndef PRIVATE_OBJ
+static int  device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev);
+#endif
+//2008-0714<Add>by Mike Liu
+static BOOL device_release_WPADEV(PSDevice pDevice);
+
+static int  ethtool_ioctl(struct net_device *dev, void *useraddr);
+static int  device_rx_srv(PSDevice pDevice, UINT uIdx);
+static int  device_tx_srv(PSDevice pDevice, UINT uIdx);
+static BOOL device_alloc_rx_buf(PSDevice pDevice, PSRxDesc pDesc);
+static void device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType);
+static void device_free_tx_buf(PSDevice pDevice, PSTxDesc pDesc);
+static void device_free_td0_ring(PSDevice pDevice);
+static void device_free_td1_ring(PSDevice pDevice);
+static void device_free_rd0_ring(PSDevice pDevice);
+static void device_free_rd1_ring(PSDevice pDevice);
+static void device_free_rings(PSDevice pDevice);
+static void device_free_frag_buf(PSDevice pDevice);
+static int Config_FileGetParameter(UCHAR *string, UCHAR *dest,UCHAR *source);
+
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+#ifndef PRIVATE_OBJ
+
+static char* get_chip_name(int chip_id) {
+    int i;
+    for (i=0;chip_info_table[i].name!=NULL;i++)
+        if (chip_info_table[i].chip_id==chip_id)
+            break;
+    return chip_info_table[i].name;
+}
+
+static void __devexit device_remove1(struct pci_dev *pcid)
+{
+    PSDevice pDevice=pci_get_drvdata(pcid);
+
+    if (pDevice==NULL)
+        return;
+    device_free_info(pDevice);
+
+}
+
+#endif
+/*
+static void
+device_set_int_opt(int *opt, int val, int min, int max, int def,char* name,char* devname) {
+    if (val==-1)
+        *opt=def;
+    else if (val<min || val>max) {
+        DEVICE_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: the value of parameter %s is invalid, the valid range is (%d-%d)\n" ,
+            devname,name, min,max);
+        *opt=def;
+    } else {
+        DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: set value of parameter %s to %d\n",
+            devname, name, val);
+        *opt=val;
+    }
+}
+
+static void
+device_set_bool_opt(PU32 opt, int val,BOOL def,U32 flag, char* name,char* devname) {
+    (*opt)&=(~flag);
+    if (val==-1)
+        *opt|=(def ? flag : 0);
+    else if (val<0 || val>1) {
+        DEVICE_PRT(MSG_LEVEL_INFO, KERN_NOTICE
+            "%s: the value of parameter %s is invalid, the valid range is (0-1)\n",devname,name);
+        *opt|=(def ? flag : 0);
+    } else {
+        DEVICE_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: set parameter %s to %s\n",
+            devname,name , val ? "TRUE" : "FALSE");
+        *opt|=(val ? flag : 0);
+    }
+}
+*/
+static void
+device_get_options(PSDevice pDevice, int index, char* devname) {
+
+    POPTIONS pOpts = &(pDevice->sOpts);
+  pOpts->nRxDescs0=RX_DESC_DEF0;
+  pOpts->nRxDescs1=RX_DESC_DEF1;
+  pOpts->nTxDescs[0]=TX_DESC_DEF0;
+  pOpts->nTxDescs[1]=TX_DESC_DEF1;
+pOpts->flags|=DEVICE_FLAGS_IP_ALIGN;
+  pOpts->int_works=INT_WORKS_DEF;
+  pOpts->rts_thresh=RTS_THRESH_DEF;
+  pOpts->frag_thresh=FRAG_THRESH_DEF;
+  pOpts->data_rate=DATA_RATE_DEF;
+  pOpts->channel_num=CHANNEL_DEF;
+
+pOpts->flags|=DEVICE_FLAGS_PREAMBLE_TYPE;
+pOpts->flags|=DEVICE_FLAGS_OP_MODE;
+//pOpts->flags|=DEVICE_FLAGS_PS_MODE;
+  pOpts->short_retry=SHORT_RETRY_DEF;
+  pOpts->long_retry=LONG_RETRY_DEF;
+  pOpts->bbp_type=BBP_TYPE_DEF;
+pOpts->flags|=DEVICE_FLAGS_80211h_MODE;
+pOpts->flags|=DEVICE_FLAGS_DiversityANT;
+
+
+}
+
+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->uChannel = pDevice->sOpts.channel_num;
+    pDevice->wRTSThreshold = pDevice->sOpts.rts_thresh;
+    pDevice->wFragmentationThreshold = pDevice->sOpts.frag_thresh;
+    pDevice->byShortRetryLimit = pDevice->sOpts.short_retry;
+    pDevice->byLongRetryLimit = pDevice->sOpts.long_retry;
+    pDevice->wMaxTransmitMSDULifetime = DEFAULT_MSDU_LIFETIME;
+    pDevice->byShortPreamble = (pDevice->sOpts.flags & DEVICE_FLAGS_PREAMBLE_TYPE) ? 1 : 0;
+    pDevice->byOpMode = (pDevice->sOpts.flags & DEVICE_FLAGS_OP_MODE) ? 1 : 0;
+    pDevice->ePSMode = (pDevice->sOpts.flags & DEVICE_FLAGS_PS_MODE) ? 1 : 0;
+    pDevice->b11hEnable = (pDevice->sOpts.flags & DEVICE_FLAGS_80211h_MODE) ? 1 : 0;
+    pDevice->bDiversityRegCtlON = (pDevice->sOpts.flags & DEVICE_FLAGS_DiversityANT) ? 1 : 0;
+    pDevice->uConnectionRate = pDevice->sOpts.data_rate;
+    if (pDevice->uConnectionRate < RATE_AUTO) pDevice->bFixRate = TRUE;
+    pDevice->byBBType = pDevice->sOpts.bbp_type;
+    pDevice->byPacketType = pDevice->byBBType;
+
+//PLICE_DEBUG->
+       pDevice->byAutoFBCtrl = AUTO_FB_0;
+       //pDevice->byAutoFBCtrl = AUTO_FB_1;
+//PLICE_DEBUG<-
+pDevice->bUpdateBBVGA = TRUE;
+    pDevice->byFOETuning = 0;
+    pDevice->wCTSDuration = 0;
+    pDevice->byPreambleType = 0;
+
+
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" uChannel= %d\n",(INT)pDevice->uChannel);
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" byOpMode= %d\n",(INT)pDevice->byOpMode);
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" ePSMode= %d\n",(INT)pDevice->ePSMode);
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" wRTSThreshold= %d\n",(INT)pDevice->wRTSThreshold);
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" byShortRetryLimit= %d\n",(INT)pDevice->byShortRetryLimit);
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" byLongRetryLimit= %d\n",(INT)pDevice->byLongRetryLimit);
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" byPreambleType= %d\n",(INT)pDevice->byPreambleType);
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" byShortPreamble= %d\n",(INT)pDevice->byShortPreamble);
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" uConnectionRate= %d\n",(INT)pDevice->uConnectionRate);
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" byBBType= %d\n",(INT)pDevice->byBBType);
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->b11hEnable= %d\n",(INT)pDevice->b11hEnable);
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->bDiversityRegCtlON= %d\n",(INT)pDevice->bDiversityRegCtlON);
+}
+
+static VOID s_vCompleteCurrentMeasure (IN PSDevice pDevice, IN BYTE byResult)
+{
+    UINT    ii;
+    DWORD   dwDuration = 0;
+    BYTE    byRPI0 = 0;
+
+    for(ii=1;ii<8;ii++) {
+        pDevice->dwRPIs[ii] *= 255;
+        dwDuration |= *((PWORD) (pDevice->pCurrMeasureEID->sReq.abyDuration));
+        dwDuration <<= 10;
+        pDevice->dwRPIs[ii] /= dwDuration;
+        pDevice->abyRPIs[ii] = (BYTE) pDevice->dwRPIs[ii];
+        byRPI0 += pDevice->abyRPIs[ii];
+    }
+    pDevice->abyRPIs[0] = (0xFF - byRPI0);
+
+     if (pDevice->uNumOfMeasureEIDs == 0) {
+        VNTWIFIbMeasureReport(  pDevice->pMgmt,
+                                TRUE,
+                                pDevice->pCurrMeasureEID,
+                                byResult,
+                                pDevice->byBasicMap,
+                                pDevice->byCCAFraction,
+                                pDevice->abyRPIs
+                                );
+    } else {
+        VNTWIFIbMeasureReport(  pDevice->pMgmt,
+                                FALSE,
+                                pDevice->pCurrMeasureEID,
+                                byResult,
+                                pDevice->byBasicMap,
+                                pDevice->byCCAFraction,
+                                pDevice->abyRPIs
+                                );
+        CARDbStartMeasure (pDevice, pDevice->pCurrMeasureEID++, pDevice->uNumOfMeasureEIDs);
+    }
+
+}
+
+
+
+//
+// Initialiation of MAC & BBP registers
+//
+
+static void device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType)
+{
+    UINT    ii;
+    BYTE    byValue;
+       BYTE    byValue1;
+    BYTE    byCCKPwrdBm = 0;
+    BYTE    byOFDMPwrdBm = 0;
+    INT zonetype=0;
+     PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    MACbShutdown(pDevice->PortOffset);
+    BBvSoftwareReset(pDevice->PortOffset);
+
+    if ((InitType == DEVICE_INIT_COLD) ||
+        (InitType == DEVICE_INIT_DXPL)) {
+        // Do MACbSoftwareReset in MACvInitialize
+        MACbSoftwareReset(pDevice->PortOffset);
+        // force CCK
+        pDevice->bCCK = TRUE;
+        pDevice->bAES = FALSE;
+        pDevice->bProtectMode = FALSE;      //Only used in 11g type, sync with ERP IE
+        pDevice->bNonERPPresent = FALSE;
+        pDevice->bBarkerPreambleMd = FALSE;
+        pDevice->wCurrentRate = RATE_1M;
+        pDevice->byTopOFDMBasicRate = RATE_24M;
+        pDevice->byTopCCKBasicRate = RATE_1M;
+
+        pDevice->byRevId = 0;                   //Target to IF pin while programming to RF chip.
+
+        // init MAC
+        MACvInitialize(pDevice->PortOffset);
+
+        // Get Local ID
+        VNSvInPortB(pDevice->PortOffset + MAC_REG_LOCALID, &(pDevice->byLocalID));
+
+           spin_lock_irq(&pDevice->lock);
+        SROMvReadAllContents(pDevice->PortOffset,pDevice->abyEEPROM);
+
+           spin_unlock_irq(&pDevice->lock);
+
+        // Get Channel range
+
+        pDevice->byMinChannel = 1;
+        pDevice->byMaxChannel = CB_MAX_CHANNEL;
+
+        // Get Antena
+        byValue = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_ANTENNA);
+        if (byValue & EEP_ANTINV)
+            pDevice->bTxRxAntInv = TRUE;
+        else
+            pDevice->bTxRxAntInv = FALSE;
+#ifdef PLICE_DEBUG
+       //printk("init_register:TxRxAntInv is %d,byValue is %d\n",pDevice->bTxRxAntInv,byValue);
+#endif
+
+        byValue &= (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN);
+        if (byValue == 0) // if not set default is All
+            byValue = (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN);
+#ifdef PLICE_DEBUG
+       //printk("init_register:byValue is %d\n",byValue);
+#endif
+        pDevice->ulDiversityNValue = 100*260;//100*SROMbyReadEmbedded(pDevice->PortOffset, 0x51);
+        pDevice->ulDiversityMValue = 100*16;//SROMbyReadEmbedded(pDevice->PortOffset, 0x52);
+        pDevice->byTMax = 1;//SROMbyReadEmbedded(pDevice->PortOffset, 0x53);
+        pDevice->byTMax2 = 4;//SROMbyReadEmbedded(pDevice->PortOffset, 0x54);
+        pDevice->ulSQ3TH = 0;//(ULONG) SROMbyReadEmbedded(pDevice->PortOffset, 0x55);
+        pDevice->byTMax3 = 64;//SROMbyReadEmbedded(pDevice->PortOffset, 0x56);
+
+        if (byValue == (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;
+                // chester for antenna
+byValue1 = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_ANTENNA);
+          //  if (pDevice->bDiversityRegCtlON)
+          if((byValue1&0x08)==0)
+                pDevice->bDiversityEnable = FALSE;//SROMbyReadEmbedded(pDevice->PortOffset, 0x50);
+            else
+                pDevice->bDiversityEnable = TRUE;
+#ifdef PLICE_DEBUG
+               //printk("aux |main antenna: RxAntennaMode is %d\n",pDevice->byRxAntennaMode);
+#endif
+       } else  {
+            pDevice->bDiversityEnable = FALSE;
+            pDevice->byAntennaCount = 1;
+            pDevice->dwTxAntennaSel = 0;
+            pDevice->dwRxAntennaSel = 0;
+            if (byValue & 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;
+            }
+        }
+#ifdef PLICE_DEBUG
+       //printk("init registers: TxAntennaMode is %d\n",pDevice->byTxAntennaMode);
+#endif
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "bDiversityEnable=[%d],NValue=[%d],MValue=[%d],TMax=[%d],TMax2=[%d]\n",
+            pDevice->bDiversityEnable,(int)pDevice->ulDiversityNValue,(int)pDevice->ulDiversityMValue,pDevice->byTMax,pDevice->byTMax2);
+
+//#ifdef ZoneType_DefaultSetting
+//2008-8-4 <add> by chester
+//zonetype initial
+ pDevice->byOriginalZonetype = pDevice->abyEEPROM[EEP_OFS_ZONETYPE];
+ if((zonetype=Config_FileOperation(pDevice,FALSE,NULL)) >= 0) {         //read zonetype file ok!
+  if ((zonetype == 0)&&
+        (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] !=0x00)){          //for USA
+    pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0;
+    pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0B;
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Init Zone Type :USA\n");
+  }
+ else if((zonetype == 1)&&
+            (pDevice->abyEEPROM[EEP_OFS_ZONETYPE]!=0x01)){   //for Japan
+    pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0x01;
+    pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0D;
+  }
+ else if((zonetype == 2)&&
+            (pDevice->abyEEPROM[EEP_OFS_ZONETYPE]!=0x02)){   //for Europe
+    pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0x02;
+    pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0D;
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Init Zone Type :Europe\n");
+  }
+
+else
+{
+   if(zonetype!=pDevice->abyEEPROM[EEP_OFS_ZONETYPE])
+      printk("zonetype in file[%02x] mismatch with in EEPROM[%02x]\n",zonetype,pDevice->abyEEPROM[EEP_OFS_ZONETYPE]);
+   else
+      printk("Read Zonetype file sucess,use default zonetype setting[%02x]\n",zonetype);
+ }
+       }
+  else
+    printk("Read Zonetype file fail,use default zonetype setting[%02x]\n",SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_ZONETYPE));
+
+        // Get RFType
+        pDevice->byRFType = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_RFTYPE);
+
+        if ((pDevice->byRFType & RF_EMU) != 0) {
+            // force change RevID for VT3253 emu
+            pDevice->byRevId = 0x80;
+        }
+
+        pDevice->byRFType &= RF_MASK;
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRFType = %x\n", pDevice->byRFType);
+
+        if (pDevice->bZoneRegExist == FALSE) {
+            pDevice->byZoneType = pDevice->abyEEPROM[EEP_OFS_ZONETYPE];
+        }
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byZoneType = %x\n", pDevice->byZoneType);
+
+        //Init RF module
+        RFbInit(pDevice);
+
+        //Get Desire Power Value
+        pDevice->byCurPwr = 0xFF;
+        pDevice->byCCKPwr = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_PWR_CCK);
+        pDevice->byOFDMPwrG = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_PWR_OFDMG);
+        //byCCKPwrdBm = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_CCK_PWR_dBm);
+
+       //byOFDMPwrdBm = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_OFDM_PWR_dBm);
+//printk("CCKPwrdBm is 0x%x,byOFDMPwrdBm is 0x%x\n",byCCKPwrdBm,byOFDMPwrdBm);
+               // Load power Table
+
+
+        for (ii=0;ii<CB_MAX_CHANNEL_24G;ii++) {
+            pDevice->abyCCKPwrTbl[ii+1] = SROMbyReadEmbedded(pDevice->PortOffset, (BYTE)(ii + EEP_OFS_CCK_PWR_TBL));
+            if (pDevice->abyCCKPwrTbl[ii+1] == 0) {
+                pDevice->abyCCKPwrTbl[ii+1] = pDevice->byCCKPwr;
+            }
+            pDevice->abyOFDMPwrTbl[ii+1] = SROMbyReadEmbedded(pDevice->PortOffset, (BYTE)(ii + EEP_OFS_OFDM_PWR_TBL));
+            if (pDevice->abyOFDMPwrTbl[ii+1] == 0) {
+                pDevice->abyOFDMPwrTbl[ii+1] = pDevice->byOFDMPwrG;
+            }
+            pDevice->abyCCKDefaultPwr[ii+1] = byCCKPwrdBm;
+            pDevice->abyOFDMDefaultPwr[ii+1] = byOFDMPwrdBm;
+        }
+               //2008-8-4 <add> by chester
+         //recover 12,13 ,14channel for EUROPE by 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];
+
+           }
+         }
+
+
+        // Load OFDM A Power Table
+        for (ii=0;ii<CB_MAX_CHANNEL_5G;ii++) { //RobertYu:20041224, bug using CB_MAX_CHANNEL
+            pDevice->abyOFDMPwrTbl[ii+CB_MAX_CHANNEL_24G+1] = SROMbyReadEmbedded(pDevice->PortOffset, (BYTE)(ii + EEP_OFS_OFDMA_PWR_TBL));
+            pDevice->abyOFDMDefaultPwr[ii+CB_MAX_CHANNEL_24G+1] = SROMbyReadEmbedded(pDevice->PortOffset, (BYTE)(ii + EEP_OFS_OFDMA_PWR_dBm));
+        }
+        CARDvInitChannelTable((PVOID)pDevice);
+
+
+        if (pDevice->byLocalID > REV_ID_VT3253_B1) {
+            MACvSelectPage1(pDevice->PortOffset);
+            VNSvOutPortB(pDevice->PortOffset + MAC_REG_MSRCTL + 1, (MSRCTL1_TXPWR | MSRCTL1_CSAPAREN));
+            MACvSelectPage0(pDevice->PortOffset);
+        }
+
+
+         // use relative tx timeout and 802.11i D4
+        MACvWordRegBitsOn(pDevice->PortOffset, MAC_REG_CFG, (CFG_TKIPOPT | CFG_NOTXTIMEOUT));
+
+        // set performance parameter by registry
+        MACvSetShortRetryLimit(pDevice->PortOffset, pDevice->byShortRetryLimit);
+        MACvSetLongRetryLimit(pDevice->PortOffset, pDevice->byLongRetryLimit);
+
+        // reset TSF counter
+        VNSvOutPortB(pDevice->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);
+        // enable TSF counter
+        VNSvOutPortB(pDevice->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
+
+        // initialize BBP registers
+        BBbVT3253Init(pDevice);
+
+        if (pDevice->bUpdateBBVGA) {
+            pDevice->byBBVGACurrent = pDevice->abyBBVGA[0];
+            pDevice->byBBVGANew = pDevice->byBBVGACurrent;
+            BBvSetVGAGainOffset(pDevice, pDevice->abyBBVGA[0]);
+        }
+#ifdef PLICE_DEBUG
+       //printk("init registers:RxAntennaMode is %x,TxAntennaMode is %x\n",pDevice->byRxAntennaMode,pDevice->byTxAntennaMode);
+#endif
+        BBvSetRxAntennaMode(pDevice->PortOffset, pDevice->byRxAntennaMode);
+        BBvSetTxAntennaMode(pDevice->PortOffset, pDevice->byTxAntennaMode);
+
+        pDevice->byCurrentCh = 0;
+
+        //pDevice->NetworkType = Ndis802_11Automode;
+        // Set BB and packet type at the same time.
+        // Set Short Slot Time, xIFS, and RSPINF.
+        if (pDevice->uConnectionRate == RATE_AUTO) {
+            pDevice->wCurrentRate = RATE_54M;
+        } else {
+            pDevice->wCurrentRate = (WORD)pDevice->uConnectionRate;
+        }
+
+        // default G Mode
+        VNTWIFIbConfigPhyMode(pDevice->pMgmt, PHY_TYPE_11G);
+        VNTWIFIbConfigPhyMode(pDevice->pMgmt, PHY_TYPE_AUTO);
+
+        pDevice->bRadioOff = FALSE;
+
+        pDevice->byRadioCtl = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_RADIOCTL);
+        pDevice->bHWRadioOff = FALSE;
+
+        if (pDevice->byRadioCtl & EEP_RADIOCTL_ENABLE) {
+            // Get GPIO
+            MACvGPIOIn(pDevice->PortOffset, &pDevice->byGPIO);
+//2008-4-14 <add> by chester for led issue
+ #ifdef FOR_LED_ON_NOTEBOOK
+if (BITbIsBitOn(pDevice->byGPIO,GPIO0_DATA)){pDevice->bHWRadioOff = TRUE;}
+if (BITbIsBitOff(pDevice->byGPIO,GPIO0_DATA)){pDevice->bHWRadioOff = FALSE;}
+
+            }
+        if ( (pDevice->bRadioControlOff == TRUE)) {
+            CARDbRadioPowerOff(pDevice);
+        }
+else  CARDbRadioPowerOn(pDevice);
+#else
+            if ((BITbIsBitOn(pDevice->byGPIO,GPIO0_DATA) && BITbIsBitOff(pDevice->byRadioCtl, EEP_RADIOCTL_INV)) ||
+                (BITbIsBitOff(pDevice->byGPIO,GPIO0_DATA) && BITbIsBitOn(pDevice->byRadioCtl, EEP_RADIOCTL_INV))) {
+                pDevice->bHWRadioOff = TRUE;
+            }
+        }
+        if ((pDevice->bHWRadioOff == TRUE) || (pDevice->bRadioControlOff == TRUE)) {
+            CARDbRadioPowerOff(pDevice);
+        }
+
+#endif
+    }
+            pMgmt->eScanType = WMAC_SCAN_PASSIVE;
+    // get Permanent network address
+    SROMvReadEtherAddress(pDevice->PortOffset, pDevice->abyCurrentNetAddr);
+    DEVICE_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]);
+
+
+    // reset Tx pointer
+    CARDvSafeResetRx(pDevice);
+    // reset Rx pointer
+    CARDvSafeResetTx(pDevice);
+
+    if (pDevice->byLocalID <= REV_ID_VT3253_A1) {
+        MACvRegBitsOn(pDevice->PortOffset, MAC_REG_RCR, RCR_WPAERR);
+    }
+
+    pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
+
+    // Turn On Rx DMA
+    MACvReceive0(pDevice->PortOffset);
+    MACvReceive1(pDevice->PortOffset);
+
+    // start the adapter
+    MACvStart(pDevice->PortOffset);
+
+    netif_stop_queue(pDevice->dev);
+
+
+}
+
+
+
+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)TimerState1CallBack;
+    pDevice->TimerSQ3Tmax3.expires = RUN_AT(HZ);
+
+    return;
+}
+
+
+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;
+}
+
+
+#ifndef PRIVATE_OBJ
+
+static int
+device_found1(struct pci_dev *pcid, const struct pci_device_id *ent)
+{
+    static BOOL bFirst = TRUE;
+    struct net_device*  dev = NULL;
+    PCHIP_INFO  pChip_info = (PCHIP_INFO)ent->driver_data;
+    PSDevice    pDevice;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+    int         rc;
+#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 (device_nics ++>= MAX_UINTS) {
+        printk(KERN_NOTICE DEVICE_NAME ": already found %d NICs\n", device_nics);
+        return -ENODEV;
+    }
+
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+    dev = alloc_etherdev(0);
+#else
+    dev = init_etherdev(dev, 0);
+#endif
+
+    if (dev == NULL) {
+        printk(KERN_ERR DEVICE_NAME ": allocate net device failed \n");
+        return -ENODEV;
+    }
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+    // Chain it all together
+   // SET_MODULE_OWNER(dev);
+    SET_NETDEV_DEV(dev, &pcid->dev);
+#endif
+
+    if (bFirst) {
+        printk(KERN_NOTICE "%s Ver. %s\n",DEVICE_FULL_DRV_NAM, DEVICE_VERSION);
+        printk(KERN_NOTICE "Copyright (c) 2003 VIA Networking Technologies, Inc.\n");
+        bFirst=FALSE;
+    }
+
+    if (!device_init_info(pcid, &pDevice, pChip_info)) {
+        return -ENOMEM;
+    }
+    pDevice->dev = dev;
+    pDevice->next_module = root_device_dev;
+    root_device_dev = dev;
+    dev->priv = pDevice;
+    dev->irq = pcid->irq;
+
+    if (pci_enable_device(pcid)) {
+        device_free_info(pDevice);
+        return -ENODEV;
+    }
+#ifdef DEBUG
+       printk("Before get pci_info memaddr is %x\n",pDevice->memaddr);
+#endif
+    if (device_get_pci_info(pDevice,pcid) == FALSE) {
+        printk(KERN_ERR DEVICE_NAME ": Failed to find PCI device.\n");
+        device_free_info(pDevice);
+        return -ENODEV;
+    }
+
+#if 1
+
+#ifdef DEBUG
+
+       //pci_read_config_byte(pcid, PCI_BASE_ADDRESS_0, &pDevice->byRevId);
+       printk("after get pci_info memaddr is %x, io addr is %x,io_size is %d\n",pDevice->memaddr,pDevice->ioaddr,pDevice->io_size);
+       {
+               int i;
+               U32                     bar,len;
+               u32 address[] = {
+               PCI_BASE_ADDRESS_0,
+               PCI_BASE_ADDRESS_1,
+               PCI_BASE_ADDRESS_2,
+               PCI_BASE_ADDRESS_3,
+               PCI_BASE_ADDRESS_4,
+               PCI_BASE_ADDRESS_5,
+               0};
+               for (i=0;address[i];i++)
+               {
+                       //pci_write_config_dword(pcid,address[i], 0xFFFFFFFF);
+                       pci_read_config_dword(pcid, address[i], &bar);
+                       printk("bar %d is %x\n",i,bar);
+                       if (!bar)
+                       {
+                               printk("bar %d not implemented\n",i);
+                               continue;
+                       }
+                       if (bar & PCI_BASE_ADDRESS_SPACE_IO) {
+                       /* This is IO */
+
+                       len = bar & (PCI_BASE_ADDRESS_IO_MASK & 0xFFFF);
+                       len = len & ~(len - 1);
+
+                       printk("IO space:  len in IO %x, BAR %d\n", len, i);
+                       }
+                       else
+                       {
+                               len = bar & 0xFFFFFFF0;
+                               len = ~len + 1;
+
+                               printk("len in MEM %x, BAR %d\n", len, i);
+                       }
+               }
+       }
+#endif
+
+
+#endif
+
+#ifdef DEBUG
+       //return  0  ;
+#endif
+    pDevice->PortOffset = (DWORD)ioremap(pDevice->memaddr & PCI_BASE_ADDRESS_MEM_MASK, pDevice->io_size);
+       //pDevice->PortOffset = (DWORD)ioremap(pDevice->ioaddr & PCI_BASE_ADDRESS_IO_MASK, pDevice->io_size);
+
+       if(pDevice->PortOffset == 0) {
+       printk(KERN_ERR DEVICE_NAME ": Failed to IO remapping ..\n");
+       device_free_info(pDevice);
+        return -ENODEV;
+    }
+
+
+
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+    rc = pci_request_regions(pcid, DEVICE_NAME);
+    if (rc) {
+        printk(KERN_ERR DEVICE_NAME ": Failed to find PCI device\n");
+        device_free_info(pDevice);
+        return -ENODEV;
+    }
+#else
+    if (check_region(pDevice->ioaddr, pDevice->io_size)) {
+        printk(KERN_ERR DEVICE_NAME ": Failed to find PCI device\n");
+        device_free_info(pDevice);
+        return -ENODEV;
+    }
+    request_region(pDevice->ioaddr, pDevice->io_size, DEVICE_NAME);
+#endif
+
+    dev->base_addr = pDevice->ioaddr;
+#ifdef PLICE_DEBUG
+       BYTE    value;
+
+       VNSvInPortB(pDevice->PortOffset+0x4F, &value);
+       printk("Before write: value is %x\n",value);
+       //VNSvInPortB(pDevice->PortOffset+0x3F, 0x00);
+       VNSvOutPortB(pDevice->PortOffset,value);
+       VNSvInPortB(pDevice->PortOffset+0x4F, &value);
+       printk("After write: value is %x\n",value);
+#endif
+
+
+
+#ifdef IO_MAP
+    pDevice->PortOffset = pDevice->ioaddr;
+#endif
+    // do reset
+    if (!MACbSoftwareReset(pDevice->PortOffset)) {
+        printk(KERN_ERR DEVICE_NAME ": Failed to access MAC hardware..\n");
+        device_free_info(pDevice);
+        return -ENODEV;
+    }
+    // initial to reload eeprom
+    MACvInitialize(pDevice->PortOffset);
+    MACvReadEtherAddress(pDevice->PortOffset, dev->dev_addr);
+
+    device_get_options(pDevice, device_nics-1, dev->name);
+    device_set_options(pDevice);
+    //Mask out the options cannot be set to the chip
+    pDevice->sOpts.flags &= pChip_info->flags;
+
+    //Enable the chip specified capbilities
+    pDevice->flags = pDevice->sOpts.flags | (pChip_info->flags & 0xFF000000UL);
+    pDevice->tx_80211 = device_dma0_tx_80211;
+    pDevice->sMgmtObj.pAdapter = (PVOID)pDevice;
+    pDevice->pMgmt = &(pDevice->sMgmtObj);
+
+    dev->irq                = pcid->irq;
+    dev->open               = device_open;
+    dev->hard_start_xmit    = device_xmit;
+    dev->stop               = device_close;
+    dev->get_stats          = device_get_stats;
+    dev->set_multicast_list = device_set_multi;
+    dev->do_ioctl           = device_ioctl;
+
+#ifdef WIRELESS_EXT
+//Einsn Modify for ubuntu-7.04
+//     dev->wireless_handlers->get_wireless_stats = iwctl_get_wireless_stats;
+#if WIRELESS_EXT > 12
+       dev->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,23)
+  //  memcpy(pDevice->dev->dev_addr, fake_mac, U_ETHER_ADDR_LEN); //use fake mac address
+ //  #endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+    rc = register_netdev(dev);
+    if (rc)
+    {
+        printk(KERN_ERR DEVICE_NAME " Failed to register netdev\n");
+        device_free_info(pDevice);
+        return -ENODEV;
+    }
+#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(dev);
+        kfree(pDevice);
+   }
+    device_print_info(pDevice);
+    pci_set_drvdata(pcid, pDevice);
+    return 0;
+
+}
+
+static void device_print_info(PSDevice pDevice)
+{
+    struct net_device* dev=pDevice->dev;
+
+    DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: %s\n",dev->name, get_chip_name(pDevice->chip_id));
+    DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
+        dev->name,
+        dev->dev_addr[0],dev->dev_addr[1],dev->dev_addr[2],
+        dev->dev_addr[3],dev->dev_addr[4],dev->dev_addr[5]);
+#ifdef IO_MAP
+    DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO" IO=0x%lx  ",(ULONG) pDevice->ioaddr);
+    DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO" IRQ=%d \n", pDevice->dev->irq);
+#else
+    DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO" IO=0x%lx Mem=0x%lx ",(ULONG) pDevice->ioaddr,(ULONG) pDevice->PortOffset);
+    DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO" IRQ=%d \n", pDevice->dev->irq);
+#endif
+
+}
+
+static BOOL device_init_info(struct pci_dev* pcid, PSDevice* ppDevice,
+    PCHIP_INFO pChip_info) {
+
+    PSDevice p;
+
+    *ppDevice = kmalloc(sizeof(DEVICE_INFO),GFP_ATOMIC);
+
+    if (*ppDevice == NULL)
+        return FALSE;
+
+    memset(*ppDevice,0,sizeof(DEVICE_INFO));
+
+    if (pDevice_Infos == NULL) {
+        pDevice_Infos =*ppDevice;
+    }
+    else {
+        for (p=pDevice_Infos;p->next!=NULL;p=p->next)
+            do {} while (0);
+        p->next = *ppDevice;
+        (*ppDevice)->prev = p;
+    }
+
+    (*ppDevice)->pcid = pcid;
+    (*ppDevice)->chip_id = pChip_info->chip_id;
+    (*ppDevice)->io_size = pChip_info->io_size;
+    (*ppDevice)->nTxQueues = pChip_info->nTxQueue;
+    (*ppDevice)->multicast_limit =32;
+
+    spin_lock_init(&((*ppDevice)->lock));
+
+    return TRUE;
+}
+
+static BOOL device_get_pci_info(PSDevice pDevice, struct pci_dev* pcid) {
+
+    U16 pci_cmd;
+    U8  b;
+    UINT cis_addr;
+#ifdef PLICE_DEBUG
+       BYTE       pci_config[256];
+       BYTE    value =0x00;
+       int             ii,j;
+       U16     max_lat=0x0000;
+       memset(pci_config,0x00,256);
+#endif
+
+    pci_read_config_byte(pcid, PCI_REVISION_ID, &pDevice->byRevId);
+    pci_read_config_word(pcid, PCI_SUBSYSTEM_ID,&pDevice->SubSystemID);
+    pci_read_config_word(pcid, PCI_SUBSYSTEM_VENDOR_ID, &pDevice->SubVendorID);
+    pci_read_config_word(pcid, PCI_COMMAND, (u16 *) & (pci_cmd));
+
+    pci_set_master(pcid);
+
+    pDevice->memaddr = pci_resource_start(pcid,0);
+    pDevice->ioaddr = pci_resource_start(pcid,1);
+
+#ifdef DEBUG
+//     pDevice->ioaddr = pci_resource_start(pcid, 0);
+//     pDevice->memaddr = pci_resource_start(pcid,1);
+#endif
+
+    cis_addr = pci_resource_start(pcid,2);
+
+    pDevice->pcid = pcid;
+
+    pci_read_config_byte(pcid, PCI_REG_COMMAND, &b);
+    pci_write_config_byte(pcid, PCI_REG_COMMAND, (b|COMMAND_BUSM));
+
+#ifdef PLICE_DEBUG
+       //pci_read_config_word(pcid,PCI_REG_MAX_LAT,&max_lat);
+       //printk("max lat is %x,SubSystemID is %x\n",max_lat,pDevice->SubSystemID);
+       //for (ii=0;ii<0xFF;ii++)
+       //pci_read_config_word(pcid,PCI_REG_MAX_LAT,&max_lat);
+       //max_lat  = 0x20;
+       //pci_write_config_word(pcid,PCI_REG_MAX_LAT,max_lat);
+       //pci_read_config_word(pcid,PCI_REG_MAX_LAT,&max_lat);
+       //printk("max lat is %x\n",max_lat);
+
+       for (ii=0;ii<0xFF;ii++)
+       {
+               pci_read_config_byte(pcid,ii,&value);
+               pci_config[ii] = value;
+       }
+       for (ii=0,j=1;ii<0x100;ii++,j++)
+       {
+               if (j %16 == 0)
+               {
+                       printk("%x:",pci_config[ii]);
+                       printk("\n");
+               }
+               else
+               {
+                       printk("%x:",pci_config[ii]);
+               }
+       }
+#endif
+    return TRUE;
+}
+
+static void device_free_info(PSDevice pDevice) {
+    PSDevice         ptr;
+    struct net_device*  dev=pDevice->dev;
+
+    ASSERT(pDevice);
+//2008-0714-01<Add>by chester
+device_release_WPADEV(pDevice);
+
+//2008-07-21-01<Add>by MikeLiu
+//unregister wpadev
+   if(wpa_set_wpadev(pDevice, 0)!=0)
+     printk("unregister wpadev fail?\n");
+
+    if (pDevice_Infos==NULL)
+        return;
+
+    for (ptr=pDevice_Infos;ptr && (ptr!=pDevice);ptr=ptr->next)
+            do {} while (0);
+
+    if (ptr==pDevice) {
+        if (ptr==pDevice_Infos)
+            pDevice_Infos=ptr->next;
+        else
+            ptr->prev->next=ptr->next;
+    }
+    else {
+        DEVICE_PRT(MSG_LEVEL_ERR, KERN_ERR "info struct not found\n");
+        return;
+    }
+#ifdef HOSTAP
+    if (dev)
+        hostap_set_hostapd(pDevice, 0, 0);
+#endif
+    if (dev)
+        unregister_netdev(dev);
+
+    if (pDevice->PortOffset)
+        iounmap((PVOID)pDevice->PortOffset);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+    if (pDevice->pcid)
+        pci_release_regions(pDevice->pcid);
+    if (dev)
+        free_netdev(dev);
+#else
+    if (pDevice->ioaddr)
+        release_region(pDevice->ioaddr,pDevice->io_size);
+    if (dev)
+        kfree(dev);
+#endif
+
+    if (pDevice->pcid) {
+        pci_set_drvdata(pDevice->pcid,NULL);
+    }
+    kfree(pDevice);
+
+}
+#endif// ifndef PRIVATE_OBJ
+
+static BOOL device_init_rings(PSDevice pDevice) {
+    void*   vir_pool;
+
+
+    /*allocate all RD/TD rings a single pool*/
+    vir_pool = pci_alloc_consistent(pDevice->pcid,
+                    pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc) +
+                    pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc) +
+                    pDevice->sOpts.nTxDescs[0] * sizeof(STxDesc) +
+                    pDevice->sOpts.nTxDescs[1] * sizeof(STxDesc),
+                    &pDevice->pool_dma);
+
+    if (vir_pool == NULL) {
+        DEVICE_PRT(MSG_LEVEL_ERR,KERN_ERR "%s : allocate desc dma memory failed\n", pDevice->dev->name);
+        return FALSE;
+    }
+
+    memset(vir_pool, 0,
+            pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc) +
+            pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc) +
+            pDevice->sOpts.nTxDescs[0] * sizeof(STxDesc) +
+            pDevice->sOpts.nTxDescs[1] * sizeof(STxDesc)
+          );
+
+    pDevice->aRD0Ring = vir_pool;
+    pDevice->aRD1Ring = vir_pool +
+                        pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc);
+
+
+    pDevice->rd0_pool_dma = pDevice->pool_dma;
+    pDevice->rd1_pool_dma = pDevice->rd0_pool_dma +
+                            pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc);
+
+    pDevice->tx0_bufs = pci_alloc_consistent(pDevice->pcid,
+                    pDevice->sOpts.nTxDescs[0] * PKT_BUF_SZ +
+                    pDevice->sOpts.nTxDescs[1] * PKT_BUF_SZ +
+                    CB_BEACON_BUF_SIZE +
+                    CB_MAX_BUF_SIZE,
+                    &pDevice->tx_bufs_dma0);
+
+    if (pDevice->tx0_bufs == NULL) {
+        DEVICE_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: allocate buf dma memory failed\n", pDevice->dev->name);
+        pci_free_consistent(pDevice->pcid,
+            pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc) +
+            pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc) +
+            pDevice->sOpts.nTxDescs[0] * sizeof(STxDesc) +
+            pDevice->sOpts.nTxDescs[1] * sizeof(STxDesc),
+            vir_pool, pDevice->pool_dma
+            );
+        return FALSE;
+    }
+
+    memset(pDevice->tx0_bufs, 0,
+           pDevice->sOpts.nTxDescs[0] * PKT_BUF_SZ +
+           pDevice->sOpts.nTxDescs[1] * PKT_BUF_SZ +
+           CB_BEACON_BUF_SIZE +
+           CB_MAX_BUF_SIZE
+          );
+
+    pDevice->td0_pool_dma = pDevice->rd1_pool_dma +
+            pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc);
+
+    pDevice->td1_pool_dma = pDevice->td0_pool_dma +
+            pDevice->sOpts.nTxDescs[0] * sizeof(STxDesc);
+
+
+    // vir_pool: pvoid type
+    pDevice->apTD0Rings = vir_pool
+                          + pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc)
+                          + pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc);
+
+    pDevice->apTD1Rings = vir_pool
+            + pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc)
+            + pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc)
+            + pDevice->sOpts.nTxDescs[0] * sizeof(STxDesc);
+
+
+    pDevice->tx1_bufs = pDevice->tx0_bufs +
+            pDevice->sOpts.nTxDescs[0] * PKT_BUF_SZ;
+
+
+    pDevice->tx_beacon_bufs = pDevice->tx1_bufs +
+            pDevice->sOpts.nTxDescs[1] * PKT_BUF_SZ;
+
+    pDevice->pbyTmpBuff = pDevice->tx_beacon_bufs +
+            CB_BEACON_BUF_SIZE;
+
+    pDevice->tx_bufs_dma1 = pDevice->tx_bufs_dma0 +
+            pDevice->sOpts.nTxDescs[0] * PKT_BUF_SZ;
+
+
+    pDevice->tx_beacon_dma = pDevice->tx_bufs_dma1 +
+            pDevice->sOpts.nTxDescs[1] * PKT_BUF_SZ;
+
+
+    return TRUE;
+}
+
+static void device_free_rings(PSDevice pDevice) {
+
+    pci_free_consistent(pDevice->pcid,
+            pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc) +
+            pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc) +
+            pDevice->sOpts.nTxDescs[0] * sizeof(STxDesc) +
+            pDevice->sOpts.nTxDescs[1] * sizeof(STxDesc)
+            ,
+            pDevice->aRD0Ring, pDevice->pool_dma
+        );
+
+    if (pDevice->tx0_bufs)
+        pci_free_consistent(pDevice->pcid,
+           pDevice->sOpts.nTxDescs[0] * PKT_BUF_SZ +
+           pDevice->sOpts.nTxDescs[1] * PKT_BUF_SZ +
+           CB_BEACON_BUF_SIZE +
+           CB_MAX_BUF_SIZE,
+           pDevice->tx0_bufs, pDevice->tx_bufs_dma0
+        );
+}
+
+static void device_init_rd0_ring(PSDevice pDevice) {
+    int i;
+    dma_addr_t      curr = pDevice->rd0_pool_dma;
+    PSRxDesc        pDesc;
+
+    /* Init the RD0 ring entries */
+    for (i = 0; i < pDevice->sOpts.nRxDescs0; i ++, curr += sizeof(SRxDesc)) {
+        pDesc = &(pDevice->aRD0Ring[i]);
+        pDesc->pRDInfo = alloc_rd_info();
+        ASSERT(pDesc->pRDInfo);
+        if (!device_alloc_rx_buf(pDevice, pDesc)) {
+            DEVICE_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc rx bufs\n",
+            pDevice->dev->name);
+        }
+        pDesc->next = &(pDevice->aRD0Ring[(i+1) % pDevice->sOpts.nRxDescs0]);
+        pDesc->pRDInfo->curr_desc = cpu_to_le32(curr);
+        pDesc->next_desc = cpu_to_le32(curr + sizeof(SRxDesc));
+    }
+
+    pDevice->aRD0Ring[i-1].next_desc = cpu_to_le32(pDevice->rd0_pool_dma);
+    pDevice->pCurrRD[0] = &(pDevice->aRD0Ring[0]);
+}
+
+
+static void device_init_rd1_ring(PSDevice pDevice) {
+    int i;
+    dma_addr_t      curr = pDevice->rd1_pool_dma;
+    PSRxDesc        pDesc;
+
+    /* Init the RD1 ring entries */
+    for (i = 0; i < pDevice->sOpts.nRxDescs1; i ++, curr += sizeof(SRxDesc)) {
+        pDesc = &(pDevice->aRD1Ring[i]);
+        pDesc->pRDInfo = alloc_rd_info();
+        ASSERT(pDesc->pRDInfo);
+        if (!device_alloc_rx_buf(pDevice, pDesc)) {
+            DEVICE_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc rx bufs\n",
+            pDevice->dev->name);
+        }
+        pDesc->next = &(pDevice->aRD1Ring[(i+1) % pDevice->sOpts.nRxDescs1]);
+        pDesc->pRDInfo->curr_desc = cpu_to_le32(curr);
+        pDesc->next_desc = cpu_to_le32(curr + sizeof(SRxDesc));
+    }
+
+    pDevice->aRD1Ring[i-1].next_desc = cpu_to_le32(pDevice->rd1_pool_dma);
+    pDevice->pCurrRD[1] = &(pDevice->aRD1Ring[0]);
+}
+
+
+static void 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)) {
+            DEVICE_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc frag bufs\n",
+                pDevice->dev->name);
+        };
+    }
+    pDevice->cbDFCB = CB_MAX_RX_FRAG;
+    pDevice->cbFreeDFCB = pDevice->cbDFCB;
+}
+
+
+
+
+static void device_free_rd0_ring(PSDevice pDevice) {
+    int i;
+
+    for (i = 0; i < pDevice->sOpts.nRxDescs0; i++) {
+        PSRxDesc        pDesc =&(pDevice->aRD0Ring[i]);
+        PDEVICE_RD_INFO  pRDInfo =pDesc->pRDInfo;
+
+        pci_unmap_single(pDevice->pcid,pRDInfo->skb_dma,
+           pDevice->rx_buf_sz, PCI_DMA_FROMDEVICE);
+
+        dev_kfree_skb(pRDInfo->skb);
+
+        kfree((PVOID)pDesc->pRDInfo);
+    }
+
+}
+
+static void device_free_rd1_ring(PSDevice pDevice) {
+    int i;
+
+
+    for (i = 0; i < pDevice->sOpts.nRxDescs1; i++) {
+        PSRxDesc        pDesc=&(pDevice->aRD1Ring[i]);
+        PDEVICE_RD_INFO  pRDInfo=pDesc->pRDInfo;
+
+        pci_unmap_single(pDevice->pcid,pRDInfo->skb_dma,
+           pDevice->rx_buf_sz, PCI_DMA_FROMDEVICE);
+
+        dev_kfree_skb(pRDInfo->skb);
+
+        kfree((PVOID)pDesc->pRDInfo);
+    }
+
+}
+
+static void device_free_frag_buf(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);
+
+    }
+
+}
+
+static void device_init_td0_ring(PSDevice pDevice) {
+    int i;
+    dma_addr_t  curr;
+    PSTxDesc        pDesc;
+
+    curr = pDevice->td0_pool_dma;
+    for (i = 0; i < pDevice->sOpts.nTxDescs[0]; i++, curr += sizeof(STxDesc)) {
+        pDesc = &(pDevice->apTD0Rings[i]);
+        pDesc->pTDInfo = alloc_td_info();
+        ASSERT(pDesc->pTDInfo);
+        if (pDevice->flags & DEVICE_FLAGS_TX_ALIGN) {
+            pDesc->pTDInfo->buf = pDevice->tx0_bufs + (i)*PKT_BUF_SZ;
+            pDesc->pTDInfo->buf_dma = pDevice->tx_bufs_dma0 + (i)*PKT_BUF_SZ;
+        }
+        pDesc->next =&(pDevice->apTD0Rings[(i+1) % pDevice->sOpts.nTxDescs[0]]);
+        pDesc->pTDInfo->curr_desc = cpu_to_le32(curr);
+        pDesc->next_desc = cpu_to_le32(curr+sizeof(STxDesc));
+    }
+
+    pDevice->apTD0Rings[i-1].next_desc = cpu_to_le32(pDevice->td0_pool_dma);
+    pDevice->apTailTD[0] = pDevice->apCurrTD[0] =&(pDevice->apTD0Rings[0]);
+
+}
+
+static void device_init_td1_ring(PSDevice pDevice) {
+    int i;
+    dma_addr_t  curr;
+    PSTxDesc    pDesc;
+
+    /* Init the TD ring entries */
+    curr=pDevice->td1_pool_dma;
+    for (i = 0; i < pDevice->sOpts.nTxDescs[1]; i++, curr+=sizeof(STxDesc)) {
+        pDesc=&(pDevice->apTD1Rings[i]);
+        pDesc->pTDInfo = alloc_td_info();
+        ASSERT(pDesc->pTDInfo);
+        if (pDevice->flags & DEVICE_FLAGS_TX_ALIGN) {
+            pDesc->pTDInfo->buf=pDevice->tx1_bufs+(i)*PKT_BUF_SZ;
+            pDesc->pTDInfo->buf_dma=pDevice->tx_bufs_dma1+(i)*PKT_BUF_SZ;
+        }
+        pDesc->next=&(pDevice->apTD1Rings[(i+1) % pDevice->sOpts.nTxDescs[1]]);
+        pDesc->pTDInfo->curr_desc = cpu_to_le32(curr);
+        pDesc->next_desc = cpu_to_le32(curr+sizeof(STxDesc));
+    }
+
+    pDevice->apTD1Rings[i-1].next_desc = cpu_to_le32(pDevice->td1_pool_dma);
+    pDevice->apTailTD[1] = pDevice->apCurrTD[1] = &(pDevice->apTD1Rings[0]);
+}
+
+
+
+static void device_free_td0_ring(PSDevice pDevice) {
+    int i;
+    for (i = 0; i < pDevice->sOpts.nTxDescs[0]; i++) {
+        PSTxDesc        pDesc=&(pDevice->apTD0Rings[i]);
+        PDEVICE_TD_INFO  pTDInfo=pDesc->pTDInfo;
+
+        if (pTDInfo->skb_dma && (pTDInfo->skb_dma != pTDInfo->buf_dma))
+            pci_unmap_single(pDevice->pcid,pTDInfo->skb_dma,
+               pTDInfo->skb->len, PCI_DMA_TODEVICE);
+
+        if (pTDInfo->skb)
+            dev_kfree_skb(pTDInfo->skb);
+
+        kfree((PVOID)pDesc->pTDInfo);
+    }
+}
+
+static void device_free_td1_ring(PSDevice pDevice) {
+    int i;
+
+    for (i = 0; i < pDevice->sOpts.nTxDescs[1]; i++) {
+        PSTxDesc        pDesc=&(pDevice->apTD1Rings[i]);
+        PDEVICE_TD_INFO  pTDInfo=pDesc->pTDInfo;
+
+        if (pTDInfo->skb_dma && (pTDInfo->skb_dma != pTDInfo->buf_dma))
+            pci_unmap_single(pDevice->pcid, pTDInfo->skb_dma,
+               pTDInfo->skb->len, PCI_DMA_TODEVICE);
+
+        if (pTDInfo->skb)
+            dev_kfree_skb(pTDInfo->skb);
+
+        kfree((PVOID)pDesc->pTDInfo);
+    }
+
+}
+
+
+
+/*-----------------------------------------------------------------*/
+
+static int device_rx_srv(PSDevice pDevice, UINT uIdx) {
+    PSRxDesc    pRD;
+    int works = 0;
+
+
+    for (pRD = pDevice->pCurrRD[uIdx];
+         pRD->m_rd0RD0.f1Owner == OWNED_BY_HOST;
+         pRD = pRD->next) {
+//        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->pCurrRD = %x, works = %d\n", pRD, works);
+        if (works++>15)
+            break;
+        if (device_receive_frame(pDevice, pRD)) {
+            if (!device_alloc_rx_buf(pDevice,pRD)) {
+                    DEVICE_PRT(MSG_LEVEL_ERR, KERN_ERR
+                    "%s: can not allocate rx buf\n", pDevice->dev->name);
+                    break;
+            }
+        }
+        pRD->m_rd0RD0.f1Owner = OWNED_BY_NIC;
+#ifdef PRIVATE_OBJ
+        ref_set_rx_jiffies(pDevice->dev);
+#else
+        pDevice->dev->last_rx = jiffies;
+#endif
+    }
+
+    pDevice->pCurrRD[uIdx]=pRD;
+
+    return works;
+}
+
+
+static BOOL device_alloc_rx_buf(PSDevice pDevice, PSRxDesc pRD) {
+
+    PDEVICE_RD_INFO pRDInfo=pRD->pRDInfo;
+
+#ifdef PRIVATE_OBJ
+
+    pRDInfo->skb=dev_alloc_skb(pDevice->rx_buf_sz);
+    if (pRDInfo->skb==NULL)
+        return FALSE;
+    ref_skb_remap(pDevice->dev, &(pRDInfo->ref_skb), pRDInfo->skb);
+    pRDInfo->skb_dma = pci_map_single(pDevice->pcid, pRDInfo->ref_skb.tail, pDevice->rx_buf_sz,
+                        PCI_DMA_FROMDEVICE);
+#else
+
+    pRDInfo->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
+#ifdef PLICE_DEBUG
+       //printk("device_alloc_rx_buf:skb is %x\n",pRDInfo->skb);
+#endif
+    if (pRDInfo->skb==NULL)
+        return FALSE;
+    ASSERT(pRDInfo->skb);
+    pRDInfo->skb->dev = pDevice->dev;
+    pRDInfo->skb_dma = pci_map_single(pDevice->pcid, pRDInfo->skb->tail, pDevice->rx_buf_sz,
+                        PCI_DMA_FROMDEVICE);
+#endif
+    *((PU32) &(pRD->m_rd0RD0)) = 0;
+
+    pRD->m_rd0RD0.wResCount = cpu_to_le16(pDevice->rx_buf_sz);
+    pRD->m_rd0RD0.f1Owner = OWNED_BY_NIC;
+    pRD->m_rd1RD1.wReqCount = cpu_to_le16(pDevice->rx_buf_sz);
+    pRD->buff_addr = cpu_to_le32(pRDInfo->skb_dma);
+
+    return TRUE;
+}
+
+
+
+BOOL device_alloc_frag_buf(PSDevice pDevice, PSDeFragControlBlock pDeF) {
+
+#ifdef PRIVATE_OBJ
+
+    pDeF->skb=dev_alloc_skb(pDevice->rx_buf_sz);
+    if (pDeF->skb==NULL)
+        return FALSE;
+    ref_skb_remap(pDevice->dev, &(pDeF->ref_skb), pDeF->skb);
+
+#else
+    pDeF->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
+    if (pDeF->skb == NULL)
+        return FALSE;
+    ASSERT(pDeF->skb);
+    pDeF->skb->dev = pDevice->dev;
+#endif
+
+    return TRUE;
+}
+
+
+
+static int device_tx_srv(PSDevice pDevice, UINT uIdx) {
+    PSTxDesc                 pTD;
+    BOOL                     bFull=FALSE;
+    int                      works = 0;
+    BYTE                     byTsr0;
+    BYTE                     byTsr1;
+    UINT                     uFrameSize, uFIFOHeaderSize;
+    PSTxBufHead              pTxBufHead;
+    struct net_device_stats* pStats = &pDevice->stats;
+    struct sk_buff*          skb;
+    UINT                     uNodeIndex;
+    PSMgmtObject             pMgmt = pDevice->pMgmt;
+#ifdef PRIVATE_OBJ
+    ref_sk_buff              ref_skb;
+#endif
+
+
+    for (pTD = pDevice->apTailTD[uIdx]; pDevice->iTDUsed[uIdx] >0; pTD = pTD->next) {
+
+        if (pTD->m_td0TD0.f1Owner == OWNED_BY_NIC)
+            break;
+        if (works++>15)
+            break;
+
+        byTsr0 = pTD->m_td0TD0.byTSR0;
+        byTsr1 = pTD->m_td0TD0.byTSR1;
+
+        //Only the status of first TD in the chain is correct
+        if (pTD->m_td1TD1.byTCR & TCR_STP) {
+
+            if ((pTD->pTDInfo->byFlags & TD_FLAGS_NETIF_SKB) != 0) {
+                uFIFOHeaderSize = pTD->pTDInfo->dwHeaderLength;
+                uFrameSize = pTD->pTDInfo->dwReqCount - uFIFOHeaderSize;
+                pTxBufHead = (PSTxBufHead) (pTD->pTDInfo->buf);
+#ifdef PRIVATE_OBJ
+                ref_skb_remap(pDevice->dev, &ref_skb, pTD->pTDInfo->skb);
+#endif
+                // Update the statistics based on the Transmit status
+                // now, we DO'NT check TSR0_CDH
+
+                STAvUpdateTDStatCounter(&pDevice->scStatistic,
+                        byTsr0, byTsr1,
+                        (PBYTE)(pTD->pTDInfo->buf + uFIFOHeaderSize),
+                        uFrameSize, uIdx);
+
+
+                BSSvUpdateNodeTxCounter(pDevice,
+                         byTsr0, byTsr1,
+                         (PBYTE)(pTD->pTDInfo->buf),
+                         uFIFOHeaderSize
+                         );
+
+                if (BITbIsBitOff(byTsr1, TSR1_TERR)) {
+                    if (byTsr0 != 0) {
+                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Tx[%d] OK but has error. tsr1[%02X] tsr0[%02X].\n",
+                           (INT)uIdx, byTsr1, byTsr0);
+                    }
+                    if ((pTxBufHead->wFragCtl & FRAGCTL_ENDFRAG) != FRAGCTL_NONFRAG) {
+                        pDevice->s802_11Counter.TransmittedFragmentCount ++;
+                    }
+                    pStats->tx_packets++;
+#ifdef PRIVATE_OBJ
+                    pStats->tx_bytes += *(ref_skb.len);
+#else
+                    pStats->tx_bytes += pTD->pTDInfo->skb->len;
+#endif
+                }
+                else {
+                     DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Tx[%d] dropped & tsr1[%02X] tsr0[%02X].\n",
+                           (INT)uIdx, byTsr1, byTsr0);
+                    pStats->tx_errors++;
+                    pStats->tx_dropped++;
+                }
+            }
+
+            if ((pTD->pTDInfo->byFlags & TD_FLAGS_PRIV_SKB) != 0) {
+                if (pDevice->bEnableHostapd) {
+                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "tx call back netif.. \n");
+#ifdef PRIVATE_OBJ
+                    ref_skb_remap(pDevice->apdev, &(ref_skb), pTD->pTDInfo->skb);
+                       ref_skb.mac.raw = ref_skb.data;
+                       *(ref_skb.pkt_type) = PACKET_OTHERHOST;
+                   //*(ref_skb.protocol) = htons(ETH_P_802_2);
+                       memset(ref_skb.cb, 0, sizeof(ref_skb.cb));
+                       netif_rx(ref_skb.skb);
+#else
+                    skb = pTD->pTDInfo->skb;
+                       skb->dev = pDevice->apdev;
+#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);
+#endif
+                   }
+            }
+
+            if (BITbIsBitOn(byTsr1, TSR1_TERR)) {
+            if ((pTD->pTDInfo->byFlags & TD_FLAGS_PRIV_SKB) != 0) {
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Tx[%d] fail has error. tsr1[%02X] tsr0[%02X].\n",
+                          (INT)uIdx, byTsr1, byTsr0);
+            }
+
+//                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Tx[%d] fail has error. tsr1[%02X] tsr0[%02X].\n",
+//                          (INT)uIdx, byTsr1, byTsr0);
+
+                if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) &&
+                    (pTD->pTDInfo->byFlags & TD_FLAGS_NETIF_SKB)) {
+                    WORD    wAID;
+                    BYTE    byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
+
+                    skb = pTD->pTDInfo->skb;
+                    if (BSSDBbIsSTAInNodeDB(pMgmt, (PBYTE)(skb->data), &uNodeIndex)) {
+                        if (pMgmt->sNodeDBTable[uNodeIndex].bPSEnable) {
+                            skb_queue_tail(&pMgmt->sNodeDBTable[uNodeIndex].sTxPSQueue, skb);
+                            pMgmt->sNodeDBTable[uNodeIndex].wEnQueueCnt++;
+                            // set tx map
+                            wAID = pMgmt->sNodeDBTable[uNodeIndex].wAID;
+                            pMgmt->abyPSTxMap[wAID >> 3] |=  byMask[wAID & 7];
+                            pTD->pTDInfo->byFlags &= ~(TD_FLAGS_NETIF_SKB);
+                            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "tx_srv:tx fail re-queue sta index= %d, QueCnt= %d\n"
+                                    ,(INT)uNodeIndex, pMgmt->sNodeDBTable[uNodeIndex].wEnQueueCnt);
+                            pStats->tx_errors--;
+                            pStats->tx_dropped--;
+                        }
+                    }
+                }
+            }
+            device_free_tx_buf(pDevice,pTD);
+            pDevice->iTDUsed[uIdx]--;
+        }
+    }
+
+
+    if (uIdx == TYPE_AC0DMA) {
+        // RESERV_AC0DMA reserved for relay
+
+        if (AVAIL_TD(pDevice, uIdx) < RESERV_AC0DMA) {
+            bFull = TRUE;
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " AC0DMA is Full = %d\n", pDevice->iTDUsed[uIdx]);
+        }
+        if (netif_queue_stopped(pDevice->dev) && (bFull==FALSE)){
+            netif_wake_queue(pDevice->dev);
+        }
+    }
+
+
+    pDevice->apTailTD[uIdx] = pTD;
+
+    return works;
+}
+
+
+static void device_error(PSDevice pDevice, WORD status) {
+
+    if (status & ISR_FETALERR) {
+        DEVICE_PRT(MSG_LEVEL_ERR, KERN_ERR
+            "%s: Hardware fatal error.\n",
+            pDevice->dev->name);
+        netif_stop_queue(pDevice->dev);
+        del_timer(&pDevice->sTimerCommand);
+        del_timer(&(pDevice->pMgmt->sTimerSecondCallback));
+        pDevice->bCmdRunning = FALSE;
+        MACbShutdown(pDevice->PortOffset);
+        return;
+    }
+
+}
+
+static void device_free_tx_buf(PSDevice pDevice, PSTxDesc pDesc) {
+    PDEVICE_TD_INFO  pTDInfo=pDesc->pTDInfo;
+    struct sk_buff* skb=pTDInfo->skb;
+
+    // pre-allocated buf_dma can't be unmapped.
+    if (pTDInfo->skb_dma && (pTDInfo->skb_dma != pTDInfo->buf_dma)) {
+        pci_unmap_single(pDevice->pcid,pTDInfo->skb_dma,skb->len,
+              PCI_DMA_TODEVICE);
+    }
+
+    if ((pTDInfo->byFlags & TD_FLAGS_NETIF_SKB) != 0)
+        dev_kfree_skb_irq(skb);
+
+    pTDInfo->skb_dma = 0;
+    pTDInfo->skb = 0;
+    pTDInfo->byFlags = 0;
+}
+
+
+
+//PLICE_DEBUG ->
+VOID   InitRxManagementQueue(PSDevice  pDevice)
+{
+       pDevice->rxManeQueue.packet_num = 0;
+       pDevice->rxManeQueue.head = pDevice->rxManeQueue.tail = 0;
+}
+//PLICE_DEBUG<-
+
+
+
+
+
+//PLICE_DEBUG ->
+INT MlmeThread(
+     void * Context)
+{
+       PSDevice        pDevice =  (PSDevice) Context;
+       PSRxMgmtPacket                  pRxMgmtPacket;
+       // int i ;
+       //complete(&pDevice->notify);
+//printk("Enter MngWorkItem,Queue packet num is %d\n",pDevice->rxManeQueue.packet_num);
+
+       //printk("Enter MlmeThread,packet _num is %d\n",pDevice->rxManeQueue.packet_num);
+       //i = 0;
+#if 1
+       while (1)
+       {
+
+       //printk("DDDD\n");
+       //down(&pDevice->mlme_semaphore);
+        // pRxMgmtPacket =  DeQueue(pDevice);
+#if 1
+               spin_lock_irq(&pDevice->lock);
+                while(pDevice->rxManeQueue.packet_num != 0)
+               {
+                        pRxMgmtPacket =  DeQueue(pDevice);
+                               //pDevice;
+                               //DequeueManageObject(pDevice->FirstRecvMngList, pDevice->LastRecvMngList);
+                       vMgrRxManagePacket(pDevice, pDevice->pMgmt, pRxMgmtPacket);
+                       //printk("packet_num is %d\n",pDevice->rxManeQueue.packet_num);
+
+                }
+               spin_unlock_irq(&pDevice->lock);
+               if (mlme_kill == 0)
+               break;
+               //udelay(200);
+#endif
+       //printk("Before schedule thread jiffies is %x\n",jiffies);
+       schedule();
+       //printk("after schedule thread jiffies is %x\n",jiffies);
+       if (mlme_kill == 0)
+               break;
+       //printk("i is %d\n",i);
+       }
+
+#endif
+       return 0;
+
+}
+
+
+#ifdef PRIVATE_OBJ
+
+int __device_open(HANDLE pExDevice) {
+    PSDevice_info pDevice_info = (PSDevice_info)pExDevice;
+    PSDevice    pDevice = (PSDevice)(pDevice_info->pWDevice);
+
+#else
+
+static int  device_open(struct net_device *dev) {
+    PSDevice    pDevice=(PSDevice) dev->priv;
+    int i;
+#endif
+    pDevice->rx_buf_sz = PKT_BUF_SZ;
+    if (!device_init_rings(pDevice)) {
+        return -ENOMEM;
+    }
+//2008-5-13 <add> by chester
+#ifndef PRIVATE_OBJ
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+    i=request_irq(pDevice->pcid->irq, &device_intr, IRQF_SHARED, dev->name, dev);
+#else
+    i=request_irq(pDevice->pcid->irq, &device_intr, (unsigned long)SA_SHIRQ, dev->name, dev);
+#endif
+    if (i)
+        return i;
+#endif
+       //printk("DEBUG1\n");
+#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
+DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "call device init rd0 ring\n");
+device_init_rd0_ring(pDevice);
+    device_init_rd1_ring(pDevice);
+    device_init_defrag_cb(pDevice);
+    device_init_td0_ring(pDevice);
+    device_init_td1_ring(pDevice);
+//    VNTWIFIvSet11h(pDevice->pMgmt, pDevice->b11hEnable);
+
+
+    if (pDevice->bDiversityRegCtlON) {
+        device_init_diversity_timer(pDevice);
+    }
+    vMgrObjectInit(pDevice);
+    vMgrTimerInit(pDevice);
+
+//PLICE_DEBUG->
+#ifdef TASK_LET
+       tasklet_init (&pDevice->RxMngWorkItem,(void *)MngWorkItem,(unsigned long )pDevice);
+#endif
+#ifdef THREAD
+       InitRxManagementQueue(pDevice);
+       mlme_kill = 0;
+       mlme_task = kthread_run(MlmeThread,(void *) pDevice, "MLME");
+       if (IS_ERR(mlme_task)) {
+               printk("thread create fail\n");
+               return -1;
+       }
+
+       mlme_kill = 1;
+#endif
+
+
+
+#if 0
+       pDevice->MLMEThr_pid = kernel_thread(MlmeThread, pDevice, CLONE_VM);
+       if (pDevice->MLMEThr_pid <0 )
+       {
+               printk("unable start thread MlmeThread\n");
+               return -1;
+       }
+#endif
+
+       //printk("thread id is %d\n",pDevice->MLMEThr_pid);
+       //printk("Create thread time is %x\n",jiffies);
+       //wait_for_completion(&pDevice->notify);
+
+
+
+
+  // if (( SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_RADIOCTL)&0x06)==0x04)
+    //    return -ENOMEM;
+DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "call device_init_registers\n");
+       device_init_registers(pDevice, DEVICE_INIT_COLD);
+    MACvReadEtherAddress(pDevice->PortOffset, pDevice->abyCurrentNetAddr);
+    memcpy(pDevice->pMgmt->abyMACAddr, pDevice->abyCurrentNetAddr, U_ETHER_ADDR_LEN);
+#ifdef PRIVATE_OBJ
+    __device_set_multi(pExDevice);
+#else
+    device_set_multi(pDevice->dev);
+#endif
+
+    // Init for Key Management
+    KeyvInitTable(&pDevice->sKey, pDevice->PortOffset);
+    add_timer(&(pDevice->pMgmt->sTimerSecondCallback));
+
+       #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+       /*
+     pDevice->bwextstep0 = FALSE;
+     pDevice->bwextstep1 = FALSE;
+     pDevice->bwextstep2 = FALSE;
+     pDevice->bwextstep3 = FALSE;
+     */
+       pDevice->bwextcount=0;
+     pDevice->bWPASuppWextEnabled = FALSE;
+#endif
+    pDevice->byReAssocCount = 0;
+   pDevice->bWPADEVUp = FALSE;
+    // Patch: if WEP key already set by iwconfig but device not yet open
+    if ((pDevice->bEncryptionEnable == TRUE) && (pDevice->bTransmitKey == TRUE)) {
+        KeybSetDefaultKey(&(pDevice->sKey),
+                            (DWORD)(pDevice->byKeyIndex | (1 << 31)),
+                            pDevice->uKeyLength,
+                            NULL,
+                            pDevice->abyKey,
+                            KEY_CTL_WEP,
+                            pDevice->PortOffset,
+                            pDevice->byLocalID
+                          );
+         pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
+    }
+
+//printk("DEBUG2\n");
+
+
+DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "call MACvIntEnable\n");
+       MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE);
+
+    if (pDevice->pMgmt->eConfigMode == WMAC_CONFIG_AP) {
+        bScheduleCommand((HANDLE)pDevice, WLAN_CMD_RUN_AP, NULL);
+       }
+       else {
+        bScheduleCommand((HANDLE)pDevice, WLAN_CMD_BSSID_SCAN, NULL);
+        bScheduleCommand((HANDLE)pDevice, WLAN_CMD_SSID, NULL);
+    }
+    pDevice->flags |=DEVICE_FLAGS_OPENED;
+
+#ifndef PRIVATE_OBJ
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
+    MOD_INC_USE_COUNT;
+#endif
+#endif
+
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_open success.. \n");
+    return 0;
+}
+
+
+#ifdef PRIVATE_OBJ
+
+int  __device_close(HANDLE pExDevice) {
+    PSDevice_info pDevice_info = (PSDevice_info)pExDevice;
+    struct net_device *dev = pDevice_info->dev;
+    PSDevice    pDevice = (PSDevice)(pDevice_info->pWDevice);
+
+#else
+static int  device_close(struct net_device *dev) {
+    PSDevice  pDevice=(PSDevice) dev->priv;
+#endif
+    PSMgmtObject     pMgmt = pDevice->pMgmt;
+ //PLICE_DEBUG->
+#ifdef THREAD
+       mlme_kill = 0;
+#endif
+//PLICE_DEBUG<-
+//2007-1121-02<Add>by EinsnLiu
+    if (pDevice->bLinkPass) {
+       bScheduleCommand((HANDLE)pDevice, WLAN_CMD_DISASSOCIATE, NULL);
+        mdelay(30);
+    }
+#ifdef TxInSleep
+    del_timer(&pDevice->sTimerTxData);
+#endif
+    del_timer(&pDevice->sTimerCommand);
+    del_timer(&pMgmt->sTimerSecondCallback);
+    if (pDevice->bDiversityRegCtlON) {
+        del_timer(&pDevice->TimerSQ3Tmax1);
+        del_timer(&pDevice->TimerSQ3Tmax2);
+        del_timer(&pDevice->TimerSQ3Tmax3);
+    }
+
+#ifdef TASK_LET
+       tasklet_kill(&pDevice->RxMngWorkItem);
+#endif
+     netif_stop_queue(dev);
+    pDevice->bCmdRunning = FALSE;
+    MACbShutdown(pDevice->PortOffset);
+    MACbSoftwareReset(pDevice->PortOffset);
+    CARDbRadioPowerOff(pDevice);
+
+    pDevice->bLinkPass = FALSE;
+    memset(pMgmt->abyCurrBSSID, 0, 6);
+    pMgmt->eCurrState = WMAC_STATE_IDLE;
+    device_free_td0_ring(pDevice);
+    device_free_td1_ring(pDevice);
+    device_free_rd0_ring(pDevice);
+    device_free_rd1_ring(pDevice);
+    device_free_frag_buf(pDevice);
+    device_free_rings(pDevice);
+    BSSvClearNodeDBTable(pDevice, 0);
+    free_irq(dev->irq, dev);
+    pDevice->flags &=(~DEVICE_FLAGS_OPENED);
+       //2008-0714-01<Add>by chester
+device_release_WPADEV(pDevice);
+//PLICE_DEBUG->
+       //tasklet_kill(&pDevice->RxMngWorkItem);
+//PLICE_DEBUG<-
+#ifndef PRIVATE_OBJ
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
+    MOD_DEC_USE_COUNT;
+#endif
+#endif
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_close.. \n");
+    return 0;
+}
+
+#ifdef PRIVATE_OBJ
+
+int  __device_dma0_tx_80211(HANDLE pExDevice, struct sk_buff *skb) {
+    PSDevice_info pDevice_info = (PSDevice_info)pExDevice;
+    PSDevice    pDevice = (PSDevice)(pDevice_info->pWDevice);
+    ref_sk_buff     ref_skb;
+
+#else
+
+
+static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev) {
+    PSDevice        pDevice=dev->priv;
+#endif
+    PBYTE           pbMPDU;
+    UINT            cbMPDULen = 0;
+
+
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_tx_80211\n");
+    spin_lock_irq(&pDevice->lock);
+
+    if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 0) {
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_tx_80211, td0 <=0\n");
+        dev_kfree_skb_irq(skb);
+        spin_unlock_irq(&pDevice->lock);
+        return 0;
+    }
+
+    if (pDevice->bStopTx0Pkt == TRUE) {
+        dev_kfree_skb_irq(skb);
+        spin_unlock_irq(&pDevice->lock);
+        return 0;
+    };
+
+#ifdef PRIVATE_OBJ
+    ref_skb_remap(pDevice->dev, &ref_skb, skb);
+    cbMPDULen = *(ref_skb.len);
+    pbMPDU = ref_skb.data;
+#else
+    cbMPDULen = skb->len;
+    pbMPDU = skb->data;
+#endif
+
+    vDMA0_tx_80211(pDevice, skb, pbMPDU, cbMPDULen);
+
+    spin_unlock_irq(&pDevice->lock);
+
+    return 0;
+
+}
+
+
+
+BOOL device_dma0_xmit(PSDevice pDevice, struct sk_buff *skb, UINT uNodeIndex) {
+    PSMgmtObject    pMgmt = pDevice->pMgmt;
+    PSTxDesc        pHeadTD, pLastTD;
+    UINT            cbFrameBodySize;
+    UINT            uMACfragNum;
+    BYTE            byPktTyp;
+    BOOL            bNeedEncryption = FALSE;
+    PSKeyItem       pTransmitKey = NULL;
+    UINT            cbHeaderSize;
+    UINT            ii;
+    SKeyItem        STempKey;
+//    BYTE            byKeyIndex = 0;
+#ifdef PRIVATE_OBJ
+    ref_sk_buff     ref_skb;
+#endif
+
+
+    if (pDevice->bStopTx0Pkt == TRUE) {
+        dev_kfree_skb_irq(skb);
+        return FALSE;
+    };
+
+    if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 0) {
+        dev_kfree_skb_irq(skb);
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_xmit, td0 <=0\n");
+        return FALSE;
+    }
+
+    if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
+        if (pDevice->uAssocCount == 0) {
+            dev_kfree_skb_irq(skb);
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_xmit, assocCount = 0\n");
+            return FALSE;
+        }
+    }
+
+#ifdef PRIVATE_OBJ
+    ref_skb_remap(pDevice->dev, &(ref_skb), skb);
+#endif
+    pHeadTD = pDevice->apCurrTD[TYPE_TXDMA0];
+
+    pHeadTD->m_td1TD1.byTCR = (TCR_EDP|TCR_STP);
+
+#ifdef PRIVATE_OBJ
+    memcpy(pDevice->sTxEthHeader.abyDstAddr, (PBYTE)(ref_skb.data), U_HEADER_LEN);
+    cbFrameBodySize = *(ref_skb.len) - U_HEADER_LEN;
+
+#else
+    memcpy(pDevice->sTxEthHeader.abyDstAddr, (PBYTE)(skb->data), U_HEADER_LEN);
+    cbFrameBodySize = skb->len - U_HEADER_LEN;
+#endif
+
+    // 802.1H
+    if (ntohs(pDevice->sTxEthHeader.wType) > MAX_DATA_LEN) {
+        cbFrameBodySize += 8;
+    }
+    uMACfragNum = cbGetFragCount(pDevice, pTransmitKey, cbFrameBodySize, &pDevice->sTxEthHeader);
+
+    if ( uMACfragNum > AVAIL_TD(pDevice, TYPE_TXDMA0)) {
+        dev_kfree_skb_irq(skb);
+        return FALSE;
+    }
+    byPktTyp = (BYTE)pDevice->byPacketType;
+
+
+    if (pDevice->bFixRate) {
+        if (pDevice->eCurrentPHYType == PHY_TYPE_11B) {
+            if (pDevice->uConnectionRate >= RATE_11M) {
+                pDevice->wCurrentRate = RATE_11M;
+            } else {
+                pDevice->wCurrentRate = (WORD)pDevice->uConnectionRate;
+            }
+        } else {
+            if (pDevice->uConnectionRate >= RATE_54M)
+                pDevice->wCurrentRate = RATE_54M;
+            else
+                pDevice->wCurrentRate = (WORD)pDevice->uConnectionRate;
+        }
+    }
+    else {
+        pDevice->wCurrentRate = pDevice->pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate;
+    }
+
+    //preamble type
+    if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble) {
+        pDevice->byPreambleType = pDevice->byShortPreamble;
+    }
+    else {
+        pDevice->byPreambleType = PREAMBLE_LONG;
+    }
+
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dma0: pDevice->wCurrentRate = %d \n", pDevice->wCurrentRate);
+
+
+    if (pDevice->wCurrentRate <= RATE_11M) {
+        byPktTyp = PK_TYPE_11B;
+    } else if (pDevice->eCurrentPHYType == PHY_TYPE_11A) {
+        byPktTyp = PK_TYPE_11A;
+    } else {
+        if (pDevice->bProtectMode == TRUE) {
+            byPktTyp = PK_TYPE_11GB;
+        } else {
+            byPktTyp = PK_TYPE_11GA;
+        }
+    }
+
+    if (pDevice->bEncryptionEnable == TRUE)
+        bNeedEncryption = TRUE;
+
+    if (pDevice->bEnableHostWEP) {
+        pTransmitKey = &STempKey;
+        pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite;
+        pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex;
+        pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength;
+        pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16;
+        pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0;
+        memcpy(pTransmitKey->abyKey,
+            &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0],
+            pTransmitKey->uKeyLength
+            );
+    }
+    vGenerateFIFOHeader(pDevice, byPktTyp, pDevice->pbyTmpBuff, bNeedEncryption,
+                        cbFrameBodySize, TYPE_TXDMA0, pHeadTD,
+                        &pDevice->sTxEthHeader, (PBYTE)skb->data, pTransmitKey, uNodeIndex,
+                        &uMACfragNum,
+                        &cbHeaderSize
+                        );
+
+    if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) {
+        // Disable PS
+        MACbPSWakeup(pDevice->PortOffset);
+    }
+
+    pDevice->bPWBitOn = FALSE;
+
+    pLastTD = pHeadTD;
+    for (ii = 0; ii < uMACfragNum; ii++) {
+        // Poll Transmit the adapter
+        wmb();
+        pHeadTD->m_td0TD0.f1Owner=OWNED_BY_NIC;
+        wmb();
+        if (ii == (uMACfragNum - 1))
+            pLastTD = pHeadTD;
+        pHeadTD = pHeadTD->next;
+    }
+
+    // Save the information needed by the tx interrupt handler
+    // to complete the Send request
+    pLastTD->pTDInfo->skb = skb;
+    pLastTD->pTDInfo->byFlags = 0;
+    pLastTD->pTDInfo->byFlags |= TD_FLAGS_NETIF_SKB;
+
+    pDevice->apCurrTD[TYPE_TXDMA0] = pHeadTD;
+
+    MACvTransmit0(pDevice->PortOffset);
+
+
+    return TRUE;
+}
+
+//TYPE_AC0DMA data tx
+#ifdef PRIVATE_OBJ
+
+int  __device_xmit(HANDLE pExDevice, struct sk_buff *skb) {
+    PSDevice_info pDevice_info = (PSDevice_info)pExDevice;
+    PSDevice    pDevice = (PSDevice)(pDevice_info->pWDevice);
+    struct net_device *dev = pDevice_info->dev;
+    ref_sk_buff     ref_skb;
+
+#else
+static int  device_xmit(struct sk_buff *skb, struct net_device *dev) {
+    PSDevice pDevice=dev->priv;
+
+#endif
+    PSMgmtObject    pMgmt = pDevice->pMgmt;
+    PSTxDesc        pHeadTD, pLastTD;
+    UINT            uNodeIndex = 0;
+    BYTE            byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
+    WORD            wAID;
+    UINT            uMACfragNum = 1;
+    UINT            cbFrameBodySize;
+    BYTE            byPktTyp;
+    UINT            cbHeaderSize;
+    BOOL            bNeedEncryption = FALSE;
+    PSKeyItem       pTransmitKey = NULL;
+    SKeyItem        STempKey;
+    UINT            ii;
+    BOOL            bTKIP_UseGTK = FALSE;
+    BOOL            bNeedDeAuth = FALSE;
+    PBYTE           pbyBSSID;
+    BOOL            bNodeExist = FALSE;
+
+
+
+    spin_lock_irq(&pDevice->lock);
+    if (pDevice->bLinkPass == FALSE) {
+        dev_kfree_skb_irq(skb);
+        spin_unlock_irq(&pDevice->lock);
+        return 0;
+    }
+
+    if (pDevice->bStopDataPkt) {
+        dev_kfree_skb_irq(skb);
+        spin_unlock_irq(&pDevice->lock);
+        return 0;
+    }
+
+#ifdef PRIVATE_OBJ
+    ref_skb_remap(pDevice->dev, &ref_skb, skb);
+#endif
+
+    if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
+        if (pDevice->uAssocCount == 0) {
+            dev_kfree_skb_irq(skb);
+            spin_unlock_irq(&pDevice->lock);
+            return 0;
+        }
+#ifdef PRIVATE_OBJ
+        if (IS_MULTICAST_ADDRESS((PBYTE)(ref_skb.data))) {
+#else
+        if (IS_MULTICAST_ADDRESS((PBYTE)(skb->data))) {
+#endif
+            uNodeIndex = 0;
+            bNodeExist = TRUE;
+            if (pMgmt->sNodeDBTable[0].bPSEnable) {
+#ifdef PRIVATE_OBJ
+                skb_queue_tail(&(pMgmt->sNodeDBTable[0].sTxPSQueue), ref_skb.skb);
+#else
+                skb_queue_tail(&(pMgmt->sNodeDBTable[0].sTxPSQueue), skb);
+#endif
+                pMgmt->sNodeDBTable[0].wEnQueueCnt++;
+                // set tx map
+                pMgmt->abyPSTxMap[0] |= byMask[0];
+                spin_unlock_irq(&pDevice->lock);
+                return 0;
+            }
+}else {
+#ifdef PRIVATE_OBJ
+            if (BSSDBbIsSTAInNodeDB(pMgmt, (PBYTE)(ref_skb.data), &uNodeIndex)) {
+#else
+            if (BSSDBbIsSTAInNodeDB(pMgmt, (PBYTE)(skb->data), &uNodeIndex)) {
+#endif
+                if (pMgmt->sNodeDBTable[uNodeIndex].bPSEnable) {
+#ifdef PRIVATE_OBJ
+                    skb_queue_tail(&pMgmt->sNodeDBTable[uNodeIndex].sTxPSQueue, ref_skb.skb);
+#else
+                    skb_queue_tail(&pMgmt->sNodeDBTable[uNodeIndex].sTxPSQueue, skb);
+#endif
+                    pMgmt->sNodeDBTable[uNodeIndex].wEnQueueCnt++;
+                    // set tx map
+                    wAID = pMgmt->sNodeDBTable[uNodeIndex].wAID;
+                    pMgmt->abyPSTxMap[wAID >> 3] |=  byMask[wAID & 7];
+                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set:pMgmt->abyPSTxMap[%d]= %d\n",
+                             (wAID >> 3), pMgmt->abyPSTxMap[wAID >> 3]);
+                    spin_unlock_irq(&pDevice->lock);
+                    return 0;
+                }
+
+                if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble) {
+                    pDevice->byPreambleType = pDevice->byShortPreamble;
+
+                }else {
+                    pDevice->byPreambleType = PREAMBLE_LONG;
+                }
+                bNodeExist = TRUE;
+
+            }
+        }
+
+        if (bNodeExist == FALSE) {
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Unknown STA not found in node DB \n");
+            dev_kfree_skb_irq(skb);
+            spin_unlock_irq(&pDevice->lock);
+            return 0;
+        }
+    }
+
+    pHeadTD = pDevice->apCurrTD[TYPE_AC0DMA];
+
+    pHeadTD->m_td1TD1.byTCR = (TCR_EDP|TCR_STP);
+
+
+#ifdef PRIVATE_OBJ
+    memcpy(pDevice->sTxEthHeader.abyDstAddr, (PBYTE)(ref_skb.data), U_HEADER_LEN);
+    cbFrameBodySize = *(ref_skb.len) - U_HEADER_LEN;
+#else
+    memcpy(pDevice->sTxEthHeader.abyDstAddr, (PBYTE)(skb->data), U_HEADER_LEN);
+    cbFrameBodySize = skb->len - U_HEADER_LEN;
+#endif
+    // 802.1H
+    if (ntohs(pDevice->sTxEthHeader.wType) > MAX_DATA_LEN) {
+        cbFrameBodySize += 8;
+    }
+
+
+    if (pDevice->bEncryptionEnable == TRUE) {
+        bNeedEncryption = TRUE;
+        // get Transmit key
+        do {
+            if ((pDevice->pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
+                (pDevice->pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
+                pbyBSSID = pDevice->abyBSSID;
+                // get pairwise key
+                if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == FALSE) {
+                    // get group key
+                    if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == TRUE) {
+                        bTKIP_UseGTK = TRUE;
+                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n");
+                        break;
+                    }
+                } else {
+                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get PTK.\n");
+                    break;
+                }
+            }else if (pDevice->pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
+
+                pbyBSSID = pDevice->sTxEthHeader.abyDstAddr;  //TO_DS = 0 and FROM_DS = 0 --> 802.11 MAC Address1
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"IBSS Serach Key: \n");
+                for (ii = 0; ii< 6; ii++)
+                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"%x \n", *(pbyBSSID+ii));
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"\n");
+
+                // get pairwise key
+                if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == TRUE)
+                    break;
+            }
+            // get group key
+            pbyBSSID = pDevice->abyBroadcastAddr;
+            if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == FALSE) {
+                pTransmitKey = NULL;
+                if (pDevice->pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
+                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"IBSS and KEY is NULL. [%d]\n", pDevice->pMgmt->eCurrMode);
+                }
+                else
+                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"NOT IBSS and KEY is NULL. [%d]\n", pDevice->pMgmt->eCurrMode);
+            } else {
+                bTKIP_UseGTK = TRUE;
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n");
+            }
+        } while(FALSE);
+    }
+
+    if (pDevice->bEnableHostWEP) {
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"acdma0: STA index %d\n", uNodeIndex);
+        if (pDevice->bEncryptionEnable == TRUE) {
+            pTransmitKey = &STempKey;
+            pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite;
+            pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex;
+            pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength;
+            pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16;
+            pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0;
+            memcpy(pTransmitKey->abyKey,
+                &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0],
+                pTransmitKey->uKeyLength
+                );
+         }
+    }
+
+    uMACfragNum = cbGetFragCount(pDevice, pTransmitKey, cbFrameBodySize, &pDevice->sTxEthHeader);
+
+    if (uMACfragNum > AVAIL_TD(pDevice, TYPE_AC0DMA)) {
+        DEVICE_PRT(MSG_LEVEL_ERR, KERN_DEBUG "uMACfragNum > AVAIL_TD(TYPE_AC0DMA) = %d\n", uMACfragNum);
+        dev_kfree_skb_irq(skb);
+        spin_unlock_irq(&pDevice->lock);
+        return 0;
+    }
+
+    if (pTransmitKey != NULL) {
+        if ((pTransmitKey->byCipherSuite == KEY_CTL_WEP) &&
+            (pTransmitKey->uKeyLength == WLAN_WEP232_KEYLEN)) {
+            uMACfragNum = 1; //WEP256 doesn't support fragment
+        }
+    }
+
+    byPktTyp = (BYTE)pDevice->byPacketType;
+
+    if (pDevice->bFixRate) {
+#ifdef PLICE_DEBUG
+       printk("Fix Rate: PhyType is %d,ConnectionRate is %d\n",pDevice->eCurrentPHYType,pDevice->uConnectionRate);
+#endif
+
+        if (pDevice->eCurrentPHYType == PHY_TYPE_11B) {
+            if (pDevice->uConnectionRate >= RATE_11M) {
+                pDevice->wCurrentRate = RATE_11M;
+            } else {
+                pDevice->wCurrentRate = (WORD)pDevice->uConnectionRate;
+            }
+        } else {
+            if ((pDevice->eCurrentPHYType == PHY_TYPE_11A) &&
+                (pDevice->uConnectionRate <= RATE_6M)) {
+                pDevice->wCurrentRate = RATE_6M;
+            } else {
+                if (pDevice->uConnectionRate >= RATE_54M)
+                    pDevice->wCurrentRate = RATE_54M;
+                else
+                    pDevice->wCurrentRate = (WORD)pDevice->uConnectionRate;
+
+            }
+        }
+        pDevice->byACKRate = (BYTE) pDevice->wCurrentRate;
+        pDevice->byTopCCKBasicRate = RATE_1M;
+        pDevice->byTopOFDMBasicRate = RATE_6M;
+    }
+    else {
+        //auto rate
+    if (pDevice->sTxEthHeader.wType == TYPE_PKT_802_1x) {
+            if (pDevice->eCurrentPHYType != PHY_TYPE_11A) {
+                pDevice->wCurrentRate = RATE_1M;
+                pDevice->byACKRate = RATE_1M;
+                pDevice->byTopCCKBasicRate = RATE_1M;
+                pDevice->byTopOFDMBasicRate = RATE_6M;
+            } else {
+                pDevice->wCurrentRate = RATE_6M;
+                pDevice->byACKRate = RATE_6M;
+                pDevice->byTopCCKBasicRate = RATE_1M;
+                pDevice->byTopOFDMBasicRate = RATE_6M;
+            }
+        }
+        else {
+               VNTWIFIvGetTxRate(  pDevice->pMgmt,
+                                pDevice->sTxEthHeader.abyDstAddr,
+                                &(pDevice->wCurrentRate),
+                                &(pDevice->byACKRate),
+                                &(pDevice->byTopCCKBasicRate),
+                                &(pDevice->byTopOFDMBasicRate));
+
+#if 0
+printk("auto rate:Rate : %d,AckRate:%d,TopCCKRate:%d,TopOFDMRate:%d\n",
+pDevice->wCurrentRate,pDevice->byACKRate,
+pDevice->byTopCCKBasicRate,pDevice->byTopOFDMBasicRate);
+
+#endif
+
+#if 0
+
+       pDevice->wCurrentRate = 11;
+       pDevice->byACKRate = 8;
+       pDevice->byTopCCKBasicRate = 3;
+       pDevice->byTopOFDMBasicRate = 8;
+#endif
+
+
+               }
+    }
+
+//    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "acdma0: pDevice->wCurrentRate = %d \n", pDevice->wCurrentRate);
+
+    if (pDevice->wCurrentRate <= RATE_11M) {
+        byPktTyp = PK_TYPE_11B;
+    } else if (pDevice->eCurrentPHYType == PHY_TYPE_11A) {
+        byPktTyp = PK_TYPE_11A;
+    } else {
+        if (pDevice->bProtectMode == TRUE) {
+            byPktTyp = PK_TYPE_11GB;
+        } else {
+            byPktTyp = PK_TYPE_11GA;
+        }
+    }
+
+//#ifdef       PLICE_DEBUG
+//     printk("FIX RATE:CurrentRate is %d");
+//#endif
+
+    if (bNeedEncryption == TRUE) {
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ntohs Pkt Type=%04x\n", ntohs(pDevice->sTxEthHeader.wType));
+        if ((pDevice->sTxEthHeader.wType) == TYPE_PKT_802_1x) {
+            bNeedEncryption = FALSE;
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Pkt Type=%04x\n", (pDevice->sTxEthHeader.wType));
+            if ((pDevice->pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pDevice->pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
+                if (pTransmitKey == NULL) {
+                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Don't Find TX KEY\n");
+                }
+                else {
+                    if (bTKIP_UseGTK == TRUE) {
+                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"error: KEY is GTK!!~~\n");
+                    }
+                    else {
+                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Find PTK [%lX]\n", pTransmitKey->dwKeyIndex);
+                        bNeedEncryption = TRUE;
+                    }
+                }
+            }
+
+            if (pDevice->byCntMeasure == 2) {
+                bNeedDeAuth = TRUE;
+                pDevice->s802_11Counter.TKIPCounterMeasuresInvoked++;
+            }
+
+            if (pDevice->bEnableHostWEP) {
+                if ((uNodeIndex != 0) &&
+                    (pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex & PAIRWISE_KEY)) {
+                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Find PTK [%lX]\n", pTransmitKey->dwKeyIndex);
+                    bNeedEncryption = TRUE;
+                 }
+             }
+        }
+        else {
+            if (pTransmitKey == NULL) {
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"return no tx key\n");
+                dev_kfree_skb_irq(skb);
+                spin_unlock_irq(&pDevice->lock);
+                return 0;
+            }
+        }
+    }
+
+
+#ifdef PRIVATE_OBJ
+    vGenerateFIFOHeader(pDevice, byPktTyp, pDevice->pbyTmpBuff, bNeedEncryption,
+                        cbFrameBodySize, TYPE_AC0DMA, pHeadTD,
+                        &pDevice->sTxEthHeader, (PBYTE)ref_skb.data, pTransmitKey, uNodeIndex,
+                        &uMACfragNum,
+                        &cbHeaderSize
+                        );
+#else
+#ifdef PLICE_DEBUG
+       //if (skb->len == 98)
+       //{
+       //      printk("ping:len is %d\n");
+       //}
+#endif
+    vGenerateFIFOHeader(pDevice, byPktTyp, pDevice->pbyTmpBuff, bNeedEncryption,
+                        cbFrameBodySize, TYPE_AC0DMA, pHeadTD,
+                        &pDevice->sTxEthHeader, (PBYTE)skb->data, pTransmitKey, uNodeIndex,
+                        &uMACfragNum,
+                        &cbHeaderSize
+                        );
+#endif
+
+    if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) {
+        // Disable PS
+        MACbPSWakeup(pDevice->PortOffset);
+    }
+    pDevice->bPWBitOn = FALSE;
+
+    pLastTD = pHeadTD;
+    for (ii = 0; ii < uMACfragNum; ii++) {
+        // Poll Transmit the adapter
+        wmb();
+        pHeadTD->m_td0TD0.f1Owner=OWNED_BY_NIC;
+        wmb();
+        if (ii == uMACfragNum - 1)
+            pLastTD = pHeadTD;
+        pHeadTD = pHeadTD->next;
+    }
+
+    // Save the information needed by the tx interrupt handler
+    // to complete the Send request
+#ifdef PRIVATE_OBJ
+    pLastTD->pTDInfo->skb = ref_skb.skb;
+#else
+    pLastTD->pTDInfo->skb = skb;
+#endif
+    pLastTD->pTDInfo->byFlags = 0;
+    pLastTD->pTDInfo->byFlags |= TD_FLAGS_NETIF_SKB;
+#ifdef TxInSleep
+  pDevice->nTxDataTimeCout=0; //2008-8-21 chester <add> for send null packet
+  #endif
+    if (AVAIL_TD(pDevice, TYPE_AC0DMA) <= 1) {
+        netif_stop_queue(dev);
+    }
+
+    pDevice->apCurrTD[TYPE_AC0DMA] = pHeadTD;
+//#ifdef       PLICE_DEBUG
+       if (pDevice->bFixRate)
+       {
+               printk("FixRate:Rate is %d,TxPower is %d\n",pDevice->wCurrentRate,pDevice->byCurPwr);
+       }
+       else
+       {
+               //printk("Auto Rate:Rate is %d,TxPower is %d\n",pDevice->wCurrentRate,pDevice->byCurPwr);
+       }
+//#endif
+
+{
+    BYTE  Protocol_Version;    //802.1x Authentication
+    BYTE  Packet_Type;           //802.1x Authentication
+    BYTE  Descriptor_type;
+    WORD Key_info;
+BOOL            bTxeapol_key = FALSE;
+    Protocol_Version = skb->data[U_HEADER_LEN];
+    Packet_Type = skb->data[U_HEADER_LEN+1];
+    Descriptor_type = skb->data[U_HEADER_LEN+1+1+2];
+    Key_info = (skb->data[U_HEADER_LEN+1+1+2+1] << 8)|(skb->data[U_HEADER_LEN+1+1+2+2]);
+   if (pDevice->sTxEthHeader.wType == TYPE_PKT_802_1x) {
+           if(((Protocol_Version==1) ||(Protocol_Version==2)) &&
+               (Packet_Type==3)) {  //802.1x OR eapol-key challenge frame transfer
+                        bTxeapol_key = TRUE;
+               if((Descriptor_type==254)||(Descriptor_type==2)) {       //WPA or RSN
+                       if(!(Key_info & BIT3) &&   //group-key challenge
+                          (Key_info & BIT8) && (Key_info & BIT9)) {    //send 2/2 key
+                         pDevice->fWPA_Authened = TRUE;
+                         if(Descriptor_type==254)
+                             printk("WPA ");
+                         else
+                             printk("WPA2 ");
+                         printk("Authentication completed!!\n");
+                        }
+                }
+             }
+   }
+}
+
+    MACvTransmitAC0(pDevice->PortOffset);
+//    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "acdma0:pDevice->apCurrTD= %p\n", pHeadTD);
+
+#ifdef PRIVATE_OBJ
+    ref_set_tx_jiffies(pDevice->dev);
+#else
+    dev->trans_start = jiffies;
+#endif
+
+    spin_unlock_irq(&pDevice->lock);
+    return 0;
+
+}
+
+#ifdef PRIVATE_OBJ
+
+int __device_intr(int irq, HANDLE pExDevice, struct pt_regs *regs) {
+    PSDevice_info pDevice_info = (PSDevice_info)pExDevice;
+    PSDevice    pDevice = (PSDevice)(pDevice_info->pWDevice);
+
+
+#else
+static  irqreturn_t  device_intr(int irq,  void *dev_instance) {
+    struct net_device* dev=dev_instance;
+    PSDevice     pDevice=(PSDevice) dev->priv;
+#endif
+
+    int             max_count=0;
+    DWORD           dwMIBCounter=0;
+    PSMgmtObject    pMgmt = pDevice->pMgmt;
+    BYTE            byOrgPageSel=0;
+    int             handled = 0;
+    BYTE            byData = 0;
+    int             ii= 0;
+//    BYTE            byRSSI;
+
+
+    MACvReadISR(pDevice->PortOffset, &pDevice->dwIsr);
+
+    if (pDevice->dwIsr == 0)
+        return IRQ_RETVAL(handled);
+
+    if (pDevice->dwIsr == 0xffffffff) {
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dwIsr = 0xffff\n");
+        return IRQ_RETVAL(handled);
+    }
+    /*
+      // 2008-05-21 <mark> by Richardtai, we can't read RSSI here, because no packet bound with RSSI
+
+       if ((BITbIsBitOn(pDevice->dwIsr, ISR_RXDMA0)) &&
+        (pDevice->byLocalID != REV_ID_VT3253_B0) &&
+        (pDevice->bBSSIDFilter == TRUE)) {
+        // update RSSI
+        //BBbReadEmbeded(pDevice->PortOffset, 0x3E, &byRSSI);
+        //pDevice->uCurrRSSI = byRSSI;
+    }
+    */
+
+    handled = 1;
+    MACvIntDisable(pDevice->PortOffset);
+    spin_lock_irq(&pDevice->lock);
+
+    //Make sure current page is 0
+    VNSvInPortB(pDevice->PortOffset + MAC_REG_PAGE1SEL, &byOrgPageSel);
+    if (byOrgPageSel == 1) {
+        MACvSelectPage0(pDevice->PortOffset);
+    }
+    else
+        byOrgPageSel = 0;
+
+    MACvReadMIBCounter(pDevice->PortOffset, &dwMIBCounter);
+    // TBD....
+    // Must do this after doing rx/tx, cause ISR bit is slow
+    // than RD/TD write back
+    // update ISR counter
+    STAvUpdate802_11Counter(&pDevice->s802_11Counter, &pDevice->scStatistic , dwMIBCounter);
+    while (pDevice->dwIsr != 0) {
+
+        STAvUpdateIsrStatCounter(&pDevice->scStatistic, pDevice->dwIsr);
+        MACvWriteISR(pDevice->PortOffset, pDevice->dwIsr);
+
+        if (pDevice->dwIsr & ISR_FETALERR){
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " ISR_FETALERR \n");
+            VNSvOutPortB(pDevice->PortOffset + MAC_REG_SOFTPWRCTL, 0);
+            VNSvOutPortW(pDevice->PortOffset + MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPECTI);
+            device_error(pDevice, pDevice->dwIsr);
+        }
+
+        if (pDevice->byLocalID > REV_ID_VT3253_B1) {
+
+            if (BITbIsBitOn(pDevice->dwIsr, ISR_MEASURESTART)) {
+                // 802.11h measure start
+                pDevice->byOrgChannel = pDevice->byCurrentCh;
+                VNSvInPortB(pDevice->PortOffset + MAC_REG_RCR, &(pDevice->byOrgRCR));
+                VNSvOutPortB(pDevice->PortOffset + MAC_REG_RCR, (RCR_RXALLTYPE | RCR_UNICAST | RCR_BROADCAST | RCR_MULTICAST | RCR_WPAERR));
+                MACvSelectPage1(pDevice->PortOffset);
+                VNSvInPortD(pDevice->PortOffset + MAC_REG_MAR0, &(pDevice->dwOrgMAR0));
+                VNSvInPortD(pDevice->PortOffset + MAC_REG_MAR4, &(pDevice->dwOrgMAR4));
+                MACvSelectPage0(pDevice->PortOffset);
+               //xxxx
+               // WCMDbFlushCommandQueue(pDevice->pMgmt, TRUE);
+                if (CARDbSetChannel(pDevice, pDevice->pCurrMeasureEID->sReq.byChannel) == TRUE) {
+                    pDevice->bMeasureInProgress = TRUE;
+                    MACvSelectPage1(pDevice->PortOffset);
+                    MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_READY);
+                    MACvSelectPage0(pDevice->PortOffset);
+                    pDevice->byBasicMap = 0;
+                    pDevice->byCCAFraction = 0;
+                    for(ii=0;ii<8;ii++) {
+                        pDevice->dwRPIs[ii] = 0;
+                    }
+                } else {
+                    // can not measure because set channel fail
+                   // WCMDbResetCommandQueue(pDevice->pMgmt);
+                    // clear measure control
+                    MACvRegBitsOff(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_EN);
+                    s_vCompleteCurrentMeasure(pDevice, MEASURE_MODE_INCAPABLE);
+                    MACvSelectPage1(pDevice->PortOffset);
+                    MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE);
+                    MACvSelectPage0(pDevice->PortOffset);
+                }
+            }
+            if (BITbIsBitOn(pDevice->dwIsr, ISR_MEASUREEND)) {
+                // 802.11h measure end
+                pDevice->bMeasureInProgress = FALSE;
+                VNSvOutPortB(pDevice->PortOffset + MAC_REG_RCR, pDevice->byOrgRCR);
+                MACvSelectPage1(pDevice->PortOffset);
+                VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0, pDevice->dwOrgMAR0);
+                VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR4, pDevice->dwOrgMAR4);
+                VNSvInPortB(pDevice->PortOffset + MAC_REG_MSRBBSTS, &byData);
+                pDevice->byBasicMap |= (byData >> 4);
+                VNSvInPortB(pDevice->PortOffset + MAC_REG_CCAFRACTION, &pDevice->byCCAFraction);
+                VNSvInPortB(pDevice->PortOffset + MAC_REG_MSRCTL, &byData);
+                // clear measure control
+                MACvRegBitsOff(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_EN);
+                MACvSelectPage0(pDevice->PortOffset);
+                CARDbSetChannel(pDevice, pDevice->byOrgChannel);
+                // WCMDbResetCommandQueue(pDevice->pMgmt);
+                MACvSelectPage1(pDevice->PortOffset);
+                MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE);
+                MACvSelectPage0(pDevice->PortOffset);
+                if (BITbIsBitOn(byData, MSRCTL_FINISH)) {
+                    // measure success
+                    s_vCompleteCurrentMeasure(pDevice, 0);
+                } else {
+                    // can not measure because not ready before end of measure time
+                    s_vCompleteCurrentMeasure(pDevice, MEASURE_MODE_LATE);
+                }
+            }
+            if (BITbIsBitOn(pDevice->dwIsr, ISR_QUIETSTART)) {
+                do {
+                    ;
+                } while (CARDbStartQuiet(pDevice) == FALSE);
+            }
+        }
+
+        if (pDevice->dwIsr & ISR_TBTT) {
+            if (pDevice->bEnableFirstQuiet == TRUE) {
+                pDevice->byQuietStartCount--;
+                if (pDevice->byQuietStartCount == 0) {
+                    pDevice->bEnableFirstQuiet = FALSE;
+                    MACvSelectPage1(pDevice->PortOffset);
+                    MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL, (MSRCTL_QUIETTXCHK | MSRCTL_QUIETEN));
+                    MACvSelectPage0(pDevice->PortOffset);
+                }
+            }
+            if ((pDevice->bChannelSwitch == TRUE) &&
+                (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE)) {
+                pDevice->byChannelSwitchCount--;
+                if (pDevice->byChannelSwitchCount == 0) {
+                    pDevice->bChannelSwitch = FALSE;
+                    CARDbSetChannel(pDevice, pDevice->byNewChannel);
+                    VNTWIFIbChannelSwitch(pDevice->pMgmt, pDevice->byNewChannel);
+                    MACvSelectPage1(pDevice->PortOffset);
+                    MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE);
+                    MACvSelectPage0(pDevice->PortOffset);
+                    CARDbStartTxPacket(pDevice, PKT_TYPE_802_11_ALL);
+
+                }
+            }
+            if (pDevice->eOPMode == OP_MODE_ADHOC) {
+                //pDevice->bBeaconSent = FALSE;
+            } else {
+                if ((pDevice->bUpdateBBVGA) && (pDevice->bLinkPass == TRUE) && (pDevice->uCurrRSSI != 0)) {
+                    LONG            ldBm;
+
+                    RFvRSSITodBm(pDevice, (BYTE) pDevice->uCurrRSSI, &ldBm);
+                    for (ii=0;ii<BB_VGA_LEVEL;ii++) {
+                        if (ldBm < pDevice->ldBmThreshold[ii]) {
+                            pDevice->byBBVGANew = pDevice->abyBBVGA[ii];
+                            break;
+                        }
+                    }
+                    if (pDevice->byBBVGANew != pDevice->byBBVGACurrent) {
+                        pDevice->uBBVGADiffCount++;
+                        if (pDevice->uBBVGADiffCount == 1) {
+                            // first VGA diff gain
+                            BBvSetVGAGainOffset(pDevice, pDevice->byBBVGANew);
+                            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"First RSSI[%d] NewGain[%d] OldGain[%d] Count[%d]\n",
+                                            (int)ldBm, pDevice->byBBVGANew, pDevice->byBBVGACurrent, (int)pDevice->uBBVGADiffCount);
+                        }
+                        if (pDevice->uBBVGADiffCount >= BB_VGA_CHANGE_THRESHOLD) {
+                            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"RSSI[%d] NewGain[%d] OldGain[%d] Count[%d]\n",
+                                            (int)ldBm, pDevice->byBBVGANew, pDevice->byBBVGACurrent, (int)pDevice->uBBVGADiffCount);
+                            BBvSetVGAGainOffset(pDevice, pDevice->byBBVGANew);
+                        }
+                    } else {
+                        pDevice->uBBVGADiffCount = 1;
+                    }
+                }
+            }
+
+            pDevice->bBeaconSent = FALSE;
+            if (pDevice->bEnablePSMode) {
+                PSbIsNextTBTTWakeUp((HANDLE)pDevice);
+            };
+
+            if ((pDevice->eOPMode == OP_MODE_AP) ||
+                (pDevice->eOPMode == OP_MODE_ADHOC)) {
+
+                MACvOneShotTimer1MicroSec(pDevice->PortOffset,
+                        (pMgmt->wIBSSBeaconPeriod - MAKE_BEACON_RESERVED) << 10);
+            }
+
+            if (pDevice->eOPMode == OP_MODE_ADHOC && pDevice->pMgmt->wCurrATIMWindow > 0) {
+                // todo adhoc PS mode
+            };
+
+        }
+
+        if (pDevice->dwIsr & ISR_BNTX) {
+
+            if (pDevice->eOPMode == OP_MODE_ADHOC) {
+                pDevice->bIsBeaconBufReadySet = FALSE;
+                pDevice->cbBeaconBufReadySetCnt = 0;
+            };
+
+            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;
+                        bScheduleCommand((HANDLE)pDevice, WLAN_CMD_RX_PSPOLL, NULL);
+                    }
+                }
+            }
+            pDevice->bBeaconSent = TRUE;
+
+            if (pDevice->bChannelSwitch == TRUE) {
+                pDevice->byChannelSwitchCount--;
+                if (pDevice->byChannelSwitchCount == 0) {
+                    pDevice->bChannelSwitch = FALSE;
+                    CARDbSetChannel(pDevice, pDevice->byNewChannel);
+                    VNTWIFIbChannelSwitch(pDevice->pMgmt, pDevice->byNewChannel);
+                    MACvSelectPage1(pDevice->PortOffset);
+                    MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE);
+                    MACvSelectPage0(pDevice->PortOffset);
+                    //VNTWIFIbSendBeacon(pDevice->pMgmt);
+                    CARDbStartTxPacket(pDevice, PKT_TYPE_802_11_ALL);
+                }
+            }
+
+        }
+
+        if (pDevice->dwIsr & ISR_RXDMA0) {
+            max_count += device_rx_srv(pDevice, TYPE_RXDMA0);
+        }
+        if (pDevice->dwIsr & ISR_RXDMA1) {
+            max_count += device_rx_srv(pDevice, TYPE_RXDMA1);
+        }
+        if (pDevice->dwIsr & ISR_TXDMA0){
+            max_count += device_tx_srv(pDevice, TYPE_TXDMA0);
+        }
+        if (pDevice->dwIsr & ISR_AC0DMA){
+            max_count += device_tx_srv(pDevice, TYPE_AC0DMA);
+        }
+        if (pDevice->dwIsr & ISR_SOFTTIMER) {
+
+        }
+        if (pDevice->dwIsr & ISR_SOFTTIMER1) {
+            if (pDevice->eOPMode == OP_MODE_AP) {
+               if (pDevice->bShortSlotTime)
+                   pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTSLOTTIME(1);
+               else
+                   pMgmt->wCurrCapInfo &= ~(WLAN_SET_CAP_INFO_SHORTSLOTTIME(1));
+            }
+            bMgrPrepareBeaconToSend(pDevice, pMgmt);
+            pDevice->byCntMeasure = 0;
+        }
+
+        MACvReadISR(pDevice->PortOffset, &pDevice->dwIsr);
+
+        MACvReceive0(pDevice->PortOffset);
+        MACvReceive1(pDevice->PortOffset);
+
+        if (max_count>pDevice->sOpts.int_works)
+            break;
+    }
+
+    if (byOrgPageSel == 1) {
+        MACvSelectPage1(pDevice->PortOffset);
+    }
+
+    spin_unlock_irq(&pDevice->lock);
+    MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE);
+
+    return IRQ_RETVAL(handled);
+}
+
+
+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;
+}
+
+//2008-8-4 <add> by chester
+static int Config_FileGetParameter(UCHAR *string, UCHAR *dest,UCHAR *source)
+{
+  UCHAR buf1[100];
+  int source_len = strlen(source);
+
+    memset(buf1,0,100);
+    strcat(buf1, string);
+    strcat(buf1, "=");
+    source+=strlen(buf1);
+
+   memcpy(dest,source,source_len-strlen(buf1));
+ return TRUE;
+}
+
+int Config_FileOperation(PSDevice pDevice,BOOL fwrite,unsigned char *Parameter) {
+    UCHAR    *config_path=CONFIG_PATH;
+    UCHAR    *buffer=NULL;
+    UCHAR      tmpbuffer[20];
+    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:open file fail?\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;
+ goto error1;
+}
+
+if(Config_FileGetParameter("ZONETYPE",tmpbuffer,buffer)!=TRUE) {
+  printk("get parameter error?\n");
+  result = -1;
+  goto error1;
+}
+
+if(memcmp(tmpbuffer,"USA",3)==0) {
+  result=ZoneType_USA;
+}
+else if(memcmp(tmpbuffer,"JAPAN",5)==0) {
+  result=ZoneType_Japan;
+}
+else if(memcmp(tmpbuffer,"EUROPE",5)==0) {
+ result=ZoneType_Europe;
+}
+else {
+  result = -1;
+  printk("Unknown Zonetype[%s]?\n",tmpbuffer);
+}
+
+error1:
+  if(buffer)
+        kfree(buffer);
+
+  if(filp_close(filp,NULL))
+       printk("Config_FileOperation:close file fail\n");
+
+error2:
+  set_fs (old_fs);
+  current->fsuid=oldfsuid;
+  current->fsgid=oldfsgid;
+
+  return result;
+}
+
+
+#ifdef PRIVATE_OBJ
+
+void __device_set_multi(HANDLE pExDevice) {
+    PSDevice_info pDevice_info = (PSDevice_info)pExDevice;
+    ref_net_device  *dev = &(pDevice_info->ref_dev);
+    PSDevice    pDevice = (PSDevice)(pDevice_info->pWDevice);
+
+#else
+
+static void device_set_multi(struct net_device *dev) {
+    PSDevice         pDevice = (PSDevice) dev->priv;
+#endif
+
+    PSMgmtObject     pMgmt = pDevice->pMgmt;
+    u32              mc_filter[2];
+    int              i;
+    struct dev_mc_list  *mclist;
+
+
+    VNSvInPortB(pDevice->PortOffset + MAC_REG_RCR, &(pDevice->byRxMode));
+
+#ifdef PRIVATE_OBJ
+    if (*(dev->flags) & IFF_PROMISC) {         /* Set promiscuous. */
+        DEVICE_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: Promiscuous mode enabled.\n", pDevice->dev->name);
+
+#else
+    if (dev->flags & IFF_PROMISC) {         /* Set promiscuous. */
+        DEVICE_PRT(MSG_LEVEL_ERR,KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name);
+#endif
+        /* Unconditionally log net taps. */
+        pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST|RCR_UNICAST);
+    }
+#ifdef PRIVATE_OBJ
+    else if ((*(dev->mc_count) > pDevice->multicast_limit)
+        ||  (*(dev->flags) & IFF_ALLMULTI)) {
+#else
+    else if ((dev->mc_count > pDevice->multicast_limit)
+        ||  (dev->flags & IFF_ALLMULTI)) {
+#endif
+        MACvSelectPage1(pDevice->PortOffset);
+        VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0, 0xffffffff);
+        VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0 + 4, 0xffffffff);
+        MACvSelectPage0(pDevice->PortOffset);
+        pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
+    }
+    else {
+        memset(mc_filter, 0, sizeof(mc_filter));
+#ifdef PRIVATE_OBJ
+        for (i = 0, mclist = dev->mc_list; mclist && i < *(dev->mc_count);
+             i++, mclist = mclist->next) {
+#else
+        for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
+             i++, mclist = mclist->next) {
+#endif
+            int bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
+            mc_filter[bit_nr >> 5] |= cpu_to_le32(1 << (bit_nr & 31));
+        }
+        MACvSelectPage1(pDevice->PortOffset);
+        VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0, mc_filter[0]);
+        VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0 + 4, mc_filter[1]);
+        MACvSelectPage0(pDevice->PortOffset);
+        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);
+    }
+
+    VNSvOutPortB(pDevice->PortOffset + MAC_REG_RCR, pDevice->byRxMode);
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRxMode = %x\n", pDevice->byRxMode );
+}
+
+
+#ifdef PRIVATE_OBJ
+
+struct net_device_stats *__device_get_stats(HANDLE pExDevice) {
+    PSDevice_info pDevice_info = (PSDevice_info)pExDevice;
+    PSDevice    pDevice = (PSDevice)(pDevice_info->pWDevice);
+
+#else
+static struct net_device_stats *device_get_stats(struct net_device *dev) {
+    PSDevice pDevice=(PSDevice) dev->priv;
+#endif
+
+    return &pDevice->stats;
+}
+
+
+#ifdef PRIVATE_OBJ
+
+int __device_ioctl(HANDLE pExDevice, struct ifreq *rq, int cmd) {
+    PSDevice_info pDevice_info = (PSDevice_info)pExDevice;
+    struct net_device *dev = pDevice_info->dev;
+    PSDevice    pDevice = (PSDevice)(pDevice_info->pWDevice);
+
+#else
+
+static int  device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
+       PSDevice                pDevice = (PSDevice)dev->priv;
+#endif
+
+#ifdef WIRELESS_EXT
+       struct iwreq *wrq = (struct iwreq *) rq;
+       int                 rc =0;
+#endif
+    PSMgmtObject        pMgmt = pDevice->pMgmt;
+    PSCmdRequest        pReq;
+
+
+    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 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:
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWNICKN \n");
+        rc = -EOPNOTSUPP;
+               break;
+
+               // Get current station name
+       case SIOCGIWNICKN:
+        DEVICE_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:
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWTXPOW \n");
+        rc = -EOPNOTSUPP;
+               break;
+
+       case SIOCSIWTXPOW:
+        DEVICE_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:
+        DEVICE_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:
+
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSPY \n");
+               rc = -EOPNOTSUPP;
+               break;
+
+               // Get the spy list
+       case SIOCGIWSPY:
+
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSPY \n");
+               rc = -EOPNOTSUPP;
+               break;
+
+#endif // WIRELESS_SPY
+
+       case SIOCGIWPRIV:
+        DEVICE_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:
+               DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH \n");
+               rc = iwctl_siwauth(dev, NULL, &(wrq->u.param), NULL);
+               break;
+
+       case SIOCGIWAUTH:
+               DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAUTH \n");
+               rc = iwctl_giwauth(dev, NULL, &(wrq->u.param), NULL);
+               break;
+
+       case SIOCSIWGENIE:
+               DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWGENIE \n");
+               rc = iwctl_siwgenie(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
+               break;
+
+       case SIOCGIWGENIE:
+               DEVICE_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];
+                       DEVICE_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:
+               DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODEEXT \n");
+               rc = iwctl_giwencodeext(dev, NULL, &(wrq->u.encoding), NULL);
+               break;
+
+       case SIOCSIWMLME:
+               DEVICE_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;
+        pReq->wResult = MAGIC_CODE;
+        break;
+
+    case IOCTL_CMD_SET:
+
+               #ifdef SndEvt_ToAPI
+                  if((((PSCmdRequest)rq)->wCmdCode !=WLAN_CMD_SET_EVT) &&
+                      !(pDevice->flags & DEVICE_FLAGS_OPENED))
+             #else
+               if (!(pDevice->flags & DEVICE_FLAGS_OPENED) &&
+                      (((PSCmdRequest)rq)->wCmdCode !=WLAN_CMD_SET_WPA))
+             #endif
+               {
+                   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 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 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;
+        DEVICE_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 {
+           DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Commit the settings\n");
+           spin_lock_irq(&pDevice->lock);
+           pDevice->bLinkPass = FALSE;
+           memset(pMgmt->abyCurrBSSID, 0, 6);
+           pMgmt->eCurrState = WMAC_STATE_IDLE;
+           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;
+}
+
+/*------------------------------------------------------------------*/
+#ifndef PRIVATE_OBJ
+
+MODULE_DEVICE_TABLE(pci, device_id_table);
+
+static struct pci_driver device_driver = {
+        name:       DEVICE_NAME,
+        id_table:   device_id_table,
+        probe:      device_found1,
+        remove:     device_remove1,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,9)
+#ifdef CONFIG_PM
+        suspend:    viawget_suspend,
+        resume:     viawget_resume,
+#endif
+#endif
+};
+
+static int __init device_init_module(void)
+{
+    int ret;
+
+
+//    ret=pci_module_init(&device_driver);
+       //ret = pcie_port_service_register(&device_driver);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
+       ret = pci_register_driver(&device_driver);
+#else
+       ret = pci_module_init(&device_driver);
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,9)
+#ifdef CONFIG_PM
+    if(ret >= 0)
+        register_reboot_notifier(&device_notifier);
+#endif
+#endif
+
+    return ret;
+}
+
+static void __exit device_cleanup_module(void)
+{
+
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,9)
+#ifdef CONFIG_PM
+    unregister_reboot_notifier(&device_notifier);
+#endif
+#endif
+    pci_unregister_driver(&device_driver);
+
+}
+
+module_init(device_init_module);
+module_exit(device_cleanup_module);
+
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,9)
+#ifdef CONFIG_PM
+static int
+device_notify_reboot(struct notifier_block *nb, unsigned long event, void *p)
+{
+    struct pci_dev *pdev = NULL;
+    switch(event) {
+    case SYS_DOWN:
+    case SYS_HALT:
+    case SYS_POWER_OFF:
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+        while ((pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
+#else
+        pci_for_each_dev(pdev) {
+#endif
+            if(pci_dev_driver(pdev) == &device_driver) {
+                if (pci_get_drvdata(pdev))
+                    viawget_suspend(pdev, 3);
+            }
+        }
+    }
+    return NOTIFY_DONE;
+}
+
+static int
+viawget_suspend(struct pci_dev *pcid, u32 state)
+{
+    int power_status;   // to silence the compiler
+
+    PSDevice pDevice=pci_get_drvdata(pcid);
+    PSMgmtObject  pMgmt = pDevice->pMgmt;
+
+    netif_stop_queue(pDevice->dev);
+    spin_lock_irq(&pDevice->lock);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
+    pci_save_state(pcid);
+#else
+    pci_save_state(pcid, pDevice->pci_state);
+#endif
+    del_timer(&pDevice->sTimerCommand);
+    del_timer(&pMgmt->sTimerSecondCallback);
+    pDevice->cbFreeCmdQueue = CMD_Q_SIZE;
+    pDevice->uCmdDequeueIdx = 0;
+    pDevice->uCmdEnqueueIdx = 0;
+    pDevice->bCmdRunning = FALSE;
+    MACbShutdown(pDevice->PortOffset);
+    MACvSaveContext(pDevice->PortOffset, pDevice->abyMacContext);
+    pDevice->bLinkPass = FALSE;
+    memset(pMgmt->abyCurrBSSID, 0, 6);
+    pMgmt->eCurrState = WMAC_STATE_IDLE;
+    pci_disable_device(pcid);
+    power_status = pci_set_power_state(pcid, state);
+    spin_unlock_irq(&pDevice->lock);
+    return 0;
+}
+
+static int
+viawget_resume(struct pci_dev *pcid)
+{
+    PSDevice  pDevice=pci_get_drvdata(pcid);
+    PSMgmtObject  pMgmt = pDevice->pMgmt;
+    int power_status;   // to silence the compiler
+
+
+    power_status = pci_set_power_state(pcid, 0);
+    power_status = pci_enable_wake(pcid, 0, 0);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
+    pci_restore_state(pcid);
+#else
+    pci_restore_state(pcid, pDevice->pci_state);
+#endif
+    if (netif_running(pDevice->dev)) {
+        spin_lock_irq(&pDevice->lock);
+        MACvRestoreContext(pDevice->PortOffset, pDevice->abyMacContext);
+        device_init_registers(pDevice, DEVICE_INIT_DXPL);
+        if (pMgmt->sNodeDBTable[0].bActive == TRUE) { // Assoc with BSS
+            pMgmt->sNodeDBTable[0].bActive = FALSE;
+            pDevice->bLinkPass = FALSE;
+            if(pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
+                // In Adhoc, BSS state set back to started.
+                pMgmt->eCurrState = WMAC_STATE_STARTED;
+           }
+            else {
+                pMgmt->eCurrMode = WMAC_MODE_STANDBY;
+                pMgmt->eCurrState = WMAC_STATE_IDLE;
+            }
+        }
+        init_timer(&pMgmt->sTimerSecondCallback);
+        init_timer(&pDevice->sTimerCommand);
+        MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE);
+        BSSvClearBSSList((HANDLE)pDevice, pDevice->bLinkPass);
+        bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, NULL);
+        bScheduleCommand((HANDLE) pDevice, WLAN_CMD_SSID, NULL);
+        spin_unlock_irq(&pDevice->lock);
+    }
+    return 0;
+}
+
+#endif
+#endif
+
+#endif //#ifndef PRIVATE_OBJ
+
+#ifdef PRIVATE_OBJ
+
+
+int __device_hw_reset(HANDLE pExDevice){
+     PSDevice_info pDevice_info = (PSDevice_info)pExDevice;
+
+     return MACbSoftwareReset(pDevice_info->port_offset);
+}
+
+
+int __device_hw_init(HANDLE pExDevice){
+    PSDevice_info pDevice_info = (PSDevice_info)pExDevice;
+    PSDevice    pDevice;
+
+
+    pDevice = (PSDevice)kmalloc(sizeof(DEVICE_INFO), (int)GFP_ATOMIC);
+    if (pDevice == NULL)
+        return FALSE;
+
+    memset(pDevice, 0, sizeof(DEVICE_INFO));
+    pDevice_info->pWDevice = pDevice;
+    pDevice->PortOffset = pDevice_info->port_offset;
+    pDevice->dev = pDevice_info->dev;
+    pDevice->pcid = pDevice_info->pcid;
+    pDevice->chip_id = pDevice_info->chip_id;
+    pDevice->memaddr = pDevice_info->mem_addr;
+    pDevice->ioaddr = pDevice_info->io_addr;
+    pDevice->io_size = pDevice_info->io_size;
+    pDevice->nTxQueues = pDevice_info->nTxQueues;
+    pDevice->multicast_limit = pDevice_info->multicast_limit;
+    pDevice->sMgmtObj.pAdapter = (PVOID)pDevice;
+    pDevice->pMgmt = &(pDevice->sMgmtObj);
+    MACvInitialize(pDevice->PortOffset);
+    device_get_options(pDevice, 0 , pDevice_info->dev->name);
+    device_set_options(pDevice);
+    pDevice->sOpts.flags &= pDevice_info->flags;
+    pDevice->flags = pDevice->sOpts.flags | (pDevice_info->flags & 0xFF000000UL);
+    spin_lock_init(&(pDevice->lock));
+
+    return TRUE;
+}
+
+
+void __device_read_mac(HANDLE pExDevice, PBYTE dev_addr){
+    PSDevice_info pDevice_info = (PSDevice_info)pExDevice;
+    PSDevice    pDevice = (PSDevice)(pDevice_info->pWDevice);
+
+    MACvReadEtherAddress(pDevice->PortOffset, dev_addr);
+    return;
+}
+
+
+#endif
+
+
diff --git a/drivers/staging/vt6655/dpc.c b/drivers/staging/vt6655/dpc.c
new file mode 100644 (file)
index 0000000..05366b9
--- /dev/null
@@ -0,0 +1,1688 @@
+/*
+ * 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(__WROUTE_H__)
+#include "wroute.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
+
+//#define      PLICE_DEBUG
+
+
+/*---------------------  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
+    );
+
+#ifdef PRIVATE_OBJ
+
+static BOOL s_bAPModeRxData (
+    IN PSDevice pDevice,
+    IN ref_sk_buff* skb,
+    IN UINT     FrameSize,
+    IN UINT     cbHeaderOffset,
+    IN INT      iSANodeIndex,
+    IN INT      iDANodeIndex
+    );
+#else
+
+static BOOL s_bAPModeRxData (
+    IN PSDevice pDevice,
+    IN struct sk_buff* skb,
+    IN UINT     FrameSize,
+    IN UINT     cbHeaderOffset,
+    IN INT      iSANodeIndex,
+    IN INT      iDANodeIndex
+    );
+#endif
+
+
+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;
+}
+
+
+
+
+//PLICE_DEBUG ->
+
+VOID   MngWorkItem(PVOID Context)
+{
+       PSRxMgmtPacket                  pRxMgmtPacket;
+       PSDevice        pDevice =  (PSDevice) Context;
+       //printk("Enter MngWorkItem,Queue packet num is %d\n",pDevice->rxManeQueue.packet_num);
+       spin_lock_irq(&pDevice->lock);
+        while(pDevice->rxManeQueue.packet_num != 0)
+        {
+                pRxMgmtPacket =  DeQueue(pDevice);
+                       vMgrRxManagePacket(pDevice, pDevice->pMgmt, pRxMgmtPacket);
+       }
+       spin_unlock_irq(&pDevice->lock);
+}
+
+
+//PLICE_DEBUG<-
+
+
+
+BOOL
+device_receive_frame (
+    IN  PSDevice pDevice,
+    IN  PSRxDesc pCurrRD
+    )
+{
+
+    PDEVICE_RD_INFO  pRDInfo = pCurrRD->pRDInfo;
+#ifdef PLICE_DEBUG
+       //printk("device_receive_frame:pCurrRD is %x,pRDInfo is %x\n",pCurrRD,pCurrRD->pRDInfo);
+#endif
+    struct net_device_stats* pStats=&pDevice->stats;
+#ifdef PRIVATE_OBJ
+    ref_sk_buff*    skb;
+#else
+    struct sk_buff* skb;
+#endif
+    PSMgmtObject    pMgmt = pDevice->pMgmt;
+    PSRxMgmtPacket  pRxPacket = &(pDevice->pMgmt->sRxPacket);
+    PS802_11Header  p802_11Header;
+    PBYTE           pbyRsr;
+    PBYTE           pbyNewRsr;
+    PBYTE           pbyRSSI;
+    PQWORD          pqwTSFTime;
+    PWORD           pwFrameSize;
+    PBYTE           pbyFrame;
+    BOOL            bDeFragRx = FALSE;
+    BOOL            bIsWEP = FALSE;
+    UINT            cbHeaderOffset;
+    UINT            FrameSize;
+    WORD            wEtherType = 0;
+    INT             iSANodeIndex = -1;
+    INT             iDANodeIndex = -1;
+    UINT            ii;
+    UINT            cbIVOffset;
+    BOOL            bExtIV = FALSE;
+    PBYTE           pbyRxSts;
+    PBYTE           pbyRxRate;
+    PBYTE           pbySQ;
+    UINT            cbHeaderSize;
+    PSKeyItem       pKey = NULL;
+    WORD            wRxTSC15_0 = 0;
+    DWORD           dwRxTSC47_16 = 0;
+    SKeyItem        STempKey;
+    // 802.11h RPI
+    DWORD           dwDuration = 0;
+    LONG            ldBm = 0;
+    LONG            ldBmThreshold = 0;
+    PS802_11Header pMACHeader;
+ BOOL            bRxeapol_key = FALSE;
+
+//    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---------- device_receive_frame---\n");
+#ifdef PRIVATE_OBJ
+    skb = &(pRDInfo->ref_skb);
+#else
+
+    skb = pRDInfo->skb;
+#endif
+
+
+//PLICE_DEBUG->
+#if 1
+       pci_unmap_single(pDevice->pcid, pRDInfo->skb_dma,
+                     pDevice->rx_buf_sz, PCI_DMA_FROMDEVICE);
+#endif
+//PLICE_DEBUG<-
+    pwFrameSize = (PWORD)(skb->data + 2);
+    FrameSize = cpu_to_le16(pCurrRD->m_rd1RD1.wReqCount) - cpu_to_le16(pCurrRD->m_rd0RD0.wResCount);
+
+    // Max: 2312Payload + 30HD +4CRC + 2Padding + 4Len + 8TSF + 4RSR
+    // Min (ACK): 10HD +4CRC + 2Padding + 4Len + 8TSF + 4RSR
+    if ((FrameSize > 2364)||(FrameSize <= 32)) {
+        // Frame Size error drop this packet.
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---------- WRONG Length 1 \n");
+        return FALSE;
+    }
+
+    pbyRxSts = (PBYTE) (skb->data);
+    pbyRxRate = (PBYTE) (skb->data + 1);
+    pbyRsr = (PBYTE) (skb->data + FrameSize - 1);
+    pbyRSSI = (PBYTE) (skb->data + FrameSize - 2);
+    pbyNewRsr = (PBYTE) (skb->data + FrameSize - 3);
+    pbySQ = (PBYTE) (skb->data + FrameSize - 4);
+    pqwTSFTime = (PQWORD) (skb->data + FrameSize - 12);
+    pbyFrame = (PBYTE)(skb->data + 4);
+
+    // get packet size
+    FrameSize = cpu_to_le16(*pwFrameSize);
+
+    if ((FrameSize > 2346)|(FrameSize < 14)) { // Max: 2312Payload + 30HD +4CRC
+                                               // Min: 14 bytes ACK
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---------- WRONG Length 2 \n");
+        return FALSE;
+    }
+//PLICE_DEBUG->
+#if 1
+       // update receive statistic counter
+    STAvUpdateRDStatCounter(&pDevice->scStatistic,
+                            *pbyRsr,
+                            *pbyNewRsr,
+                            *pbyRxRate,
+                            pbyFrame,
+                            FrameSize);
+
+#endif
+
+  pMACHeader=(PS802_11Header)((PBYTE) (skb->data)+8);
+//PLICE_DEBUG<-
+       if (pDevice->bMeasureInProgress == TRUE) {
+        if ((*pbyRsr & RSR_CRCOK) != 0) {
+            pDevice->byBasicMap |= 0x01;
+        }
+        dwDuration = (FrameSize << 4);
+        dwDuration /= acbyRxRate[*pbyRxRate%MAX_RATE];
+        if (*pbyRxRate <= RATE_11M) {
+            if (BITbIsBitOn(*pbyRxSts, 0x01)) {
+                // long preamble
+                dwDuration += 192;
+            } else {
+                // short preamble
+                dwDuration += 96;
+            }
+        } else {
+            dwDuration += 16;
+        }
+        RFvRSSITodBm(pDevice, *pbyRSSI, &ldBm);
+        ldBmThreshold = -57;
+        for (ii = 7; ii > 0;) {
+            if (ldBm > ldBmThreshold) {
+                break;
+            }
+            ldBmThreshold -= 5;
+            ii--;
+        }
+        pDevice->dwRPIs[ii] += dwDuration;
+        return FALSE;
+    }
+
+    if (!IS_MULTICAST_ADDRESS(pbyFrame) && !IS_BROADCAST_ADDRESS(pbyFrame)) {
+        if (WCTLbIsDuplicate(&(pDevice->sDupRxCache), (PS802_11Header) (skb->data + 4))) {
+            pDevice->s802_11Counter.FrameDuplicateCount++;
+            return FALSE;
+        }
+    }
+
+
+    // Use for TKIP MIC
+    s_vGetDASA(skb->data+4, &cbHeaderSize, &pDevice->sRxEthHeader);
+
+    // filter packet send from myself
+    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 (BSSDBbIsSTAInNodeDB(pMgmt, (PBYTE)(p802_11Header->abyAddr2), &iSANodeIndex)) {
+#ifdef PRIVATE_OBJ
+                pMgmt->sNodeDBTable[iSANodeIndex].ulLastRxJiffer = get_jiffies();
+#else
+                pMgmt->sNodeDBTable[iSANodeIndex].ulLastRxJiffer = jiffies;
+#endif
+                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;
+
+        DEVICE_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) {
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV Fail\n");
+                if ( (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPA) ||
+                    (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) ||
+                    (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) ||
+                    (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPA2) ||
+                    (pDevice->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 {
+            DEVICE_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((skb->data+4)))
+        ) {
+        // defragment
+        bDeFragRx = WCTLbHandleFragment(pDevice, (PS802_11Header) (skb->data+4), FrameSize, bIsWEP, bExtIV);
+        pDevice->s802_11Counter.ReceivedFragmentCount++;
+        if (bDeFragRx) {
+            // defrag complete
+#ifdef PRIVATE_OBJ
+            skb = &(pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].ref_skb);
+#else
+            skb = pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].skb;
+#endif
+            FrameSize = pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength;
+
+        }
+        else {
+            return FALSE;
+        }
+    }
+
+
+// Management & Control frame Handle
+    if ((IS_TYPE_DATA((skb->data+4))) == FALSE) {
+        // Handle Control & Manage Frame
+
+        if (IS_TYPE_MGMT((skb->data+4))) {
+            PBYTE pbyData1;
+            PBYTE pbyData2;
+
+            pRxPacket->p80211Header = (PUWLAN_80211HDR)(skb->data+4);
+            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(skb->data+4);
+                pbyData2 = WLAN_HDR_A3_DATA_PTR(skb->data+4) + 4;
+                for (ii = 0; ii < (FrameSize - 4); ii++) {
+                    *pbyData1 = *pbyData2;
+                     pbyData1++;
+                     pbyData2++;
+                }
+            }
+            pRxPacket->byRxRate = s_byGetRateIdx(*pbyRxRate);
+            pRxPacket->byRxChannel = (*pbyRxSts) >> 2;
+//PLICE_DEBUG->
+//EnQueue(pDevice,pRxPacket);
+
+#ifdef THREAD
+               EnQueue(pDevice,pRxPacket);
+
+               //printk("enque time is %x\n",jiffies);
+               //up(&pDevice->mlme_semaphore);
+                       //Enque (pDevice->FirstRecvMngList,pDevice->LastRecvMngList,pMgmt);
+#else
+
+#ifdef TASK_LET
+               EnQueue(pDevice,pRxPacket);
+               tasklet_schedule(&pDevice->RxMngWorkItem);
+#else
+//printk("RxMan\n");
+       vMgrRxManagePacket((HANDLE)pDevice, pDevice->pMgmt, pRxPacket);
+           //tasklet_schedule(&pDevice->RxMngWorkItem);
+#endif
+
+#endif
+//PLICE_DEBUG<-
+                       //vMgrRxManagePacket((HANDLE)pDevice, pDevice->pMgmt, pRxPacket);
+            // hostap Deamon handle 802.11 management
+            if (pDevice->bEnableHostapd) {
+                   skb->dev = pDevice->apdev;
+#ifdef PRIVATE_OBJ
+                ref_skb_add_offset(skb->skb, 4);
+                ref_skb_set_dev(pDevice->apdev, skb->skb);
+                skb_put(skb->skb, FrameSize);
+#if    LINUX_VERSION_CODE      > KERNEL_VERSION(2,6,21)
+                   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->skb);
+#else
+                   skb->data += 4;
+                   skb->tail += 4;
+                     skb_put(skb, FrameSize);
+#if    LINUX_VERSION_CODE > KERNEL_VERSION (2,6,21)
+                   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);
+#endif
+                return TRUE;
+               }
+        }
+        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])) {
+                        DEVICE_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])) {
+                        DEVICE_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
+              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;
+                  }
+             }
+         }
+    //mike add:station mode check eapol-key challenge<---
+        }
+    }
+
+// Data frame Handle
+
+    if (pDevice->bEnablePSMode) {
+        if (IS_FC_MOREDATA((skb->data+4))) {
+            if (BITbIsBitOn(*pbyRsr, RSR_ADDROK)) {
+                //PSbSendPSPOLL((PSDevice)pDevice);
+            }
+        }
+        else {
+            if (pDevice->pMgmt->bInTIMWake == TRUE) {
+                pDevice->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)) {
+       //printk("device_receive_frame: RxRate is %d\n",*pbyRxRate);
+               BBvAntennaDiversity(pDevice, s_byGetRateIdx(*pbyRxRate), 0);
+    }
+
+
+    if (pDevice->byLocalID != REV_ID_VT3253_B1) {
+        pDevice->uCurrRSSI = *pbyRSSI;
+    }
+    pDevice->byCurrSQ = *pbySQ;
+
+    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 + 4 + 24 + 6] << 8) |
+                    skb->data[cbIVOffset + 4 + 24 + 6 + 1];
+
+           DEVICE_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 + 4), 24);
+                memcpy((skb->data + 4 + cbIVOffset), &abyMacHdr[0], 24);
+            }
+#ifdef PRIVATE_OBJ
+            ref_skb_add_offset(skb->skb, (cbIVOffset + 4));
+            ref_skb_set_dev(pDevice->apdev, skb->skb);
+            skb_put(skb->skb, FrameSize);
+#if    LINUX_VERSION_CODE      > KERNEL_VERSION(2,6,21)
+                       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->skb);
+#else
+            skb->data +=  (cbIVOffset + 4);
+            skb->tail +=  (cbIVOffset + 4);
+            skb_put(skb, FrameSize);
+#if    LINUX_VERSION_CODE      > KERNEL_VERSION(2,6,21)
+           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);
+#endif
+            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 (pDevice->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 + 4 + WLAN_HDR_ADDR3_LEN + 8),
+                        FrameSize - WLAN_HDR_ADDR3_LEN - 8);
+            MIC_vGetMIC(&dwLocalMIC_L, &dwLocalMIC_R);
+            MIC_vUnInit();
+
+            pdwMIC_L = (PDWORD)(skb->data + 4 + FrameSize);
+            pdwMIC_R = (PDWORD)(skb->data + 4 + FrameSize + 4);
+            //DBG_PRN_GRP12(("RxL: %lx, RxR: %lx\n", *pdwMIC_L, *pdwMIC_R));
+            //DBG_PRN_GRP12(("LocalL: %lx, LocalR: %lx\n", dwLocalMIC_L, dwLocalMIC_R));
+            //DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"dwMICKey0= %lx,dwMICKey1= %lx \n", dwMICKey0, dwMICKey1);
+
+
+            if ((cpu_to_le32(*pdwMIC_L) != dwLocalMIC_L) || (cpu_to_le32(*pdwMIC_R) != dwLocalMIC_R) ||
+                (pDevice->bRxMICFail == TRUE)) {
+                DEVICE_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])) {
+                        DEVICE_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->bWPADevEnable == 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);
+                                       wireless_send_event(pDevice->dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&ev);
+
+                               }
+         #endif
+                if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) {
+                     wpahdr = (viawget_wpa_header *)pDevice->skb->data;
+                     if ((pDevice->pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
+                         (pDevice->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;
+#if    LINUX_VERSION_CODE      > KERNEL_VERSION(2,6,21)
+               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))) {
+                    DEVICE_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])) {
+                            DEVICE_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
+                                pDevice->dev->name);
+                        }
+                    }
+                    return FALSE;
+                }
+            }
+        }
+    } // ----- End of Reply Counter Check --------------------------
+
+
+
+    if ((pKey != NULL) && (bIsWEP)) {
+//      pDevice->s802_11Counter.DecryptSuccessCount.QuadPart++;
+    }
+
+
+    s_vProcessRxMACHeader(pDevice, (PBYTE)(skb->data+4), FrameSize, bIsWEP, bExtIV, &cbHeaderOffset);
+    FrameSize -= cbHeaderOffset;
+    cbHeaderOffset += 4;        // 4 is Rcv buffer header
+
+    // Null data, framesize = 14
+    if (FrameSize < 15)
+        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])) {
+                    DEVICE_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
+                    pDevice->dev->name);
+                }
+            }
+            return FALSE;
+        }
+
+//        if(pDevice->bRxMICFail == FALSE) {
+//           for (ii =0; ii < 100; ii++)
+//                printk(" %02x", *(skb->data + ii));
+//           printk("\n");
+//         }
+
+    }
+
+#ifdef PRIVATE_OBJ
+    ref_skb_add_offset(skb->skb, cbHeaderOffset);
+    skb_put(skb->skb, FrameSize);
+    *(skb->protocol)=eth_type_trans(skb->skb, skb->dev);
+
+#else
+       skb->data += cbHeaderOffset;
+       skb->tail += cbHeaderOffset;
+    skb_put(skb, FrameSize);
+    skb->protocol=eth_type_trans(skb, skb->dev);
+#endif
+
+
+       //drop frame not met IEEE 802.3
+/*
+       if (pDevice->flags & DEVICE_FLAGS_VAL_PKT_LEN) {
+#ifdef PRIVATE_OBJ
+               if ((*(skb->protocol)==htons(ETH_P_802_3)) &&
+                       (*(skb->len)!=htons(skb->mac.ethernet->h_proto))) {
+#else
+               if ((skb->protocol==htons(ETH_P_802_3)) &&
+                       (skb->len!=htons(skb->mac.ethernet->h_proto))) {
+#endif
+                       pStats->rx_length_errors++;
+                       pStats->rx_dropped++;
+            if (bDeFragRx) {
+                if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
+                    DEVICE_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
+                    pDevice->dev->name);
+                }
+            }
+                       return FALSE;
+               }
+       }
+*/
+
+#ifdef PRIVATE_OBJ
+    *(skb->ip_summed)=CHECKSUM_NONE;
+    pStats->rx_bytes +=*(skb->len);
+    pStats->rx_packets++;
+    netif_rx(skb->skb);
+#else
+    skb->ip_summed=CHECKSUM_NONE;
+    pStats->rx_bytes +=skb->len;
+    pStats->rx_packets++;
+    netif_rx(skb);
+#endif
+
+    if (bDeFragRx) {
+        if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
+            DEVICE_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->pMgmt;
+
+
+    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
+                                         );
+                    DEVICE_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
+                                         );
+                    DEVICE_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);
+                        DEVICE_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);
+                            DEVICE_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);
+                         DEVICE_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
+                                       );
+                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: send vMgrDeAuthenBeginSta 3\n");
+                    DEVICE_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]
+                               );
+                    DEVICE_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]
+                               );
+                    DEVICE_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]
+                               );
+                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: wFrameCtl= %x\n", p802_11Header->wFrameCtl );
+                    VNSvInPortB(pDevice->PortOffset + MAC_REG_RCR, &(pDevice->byRxMode));
+                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc:pDevice->byRxMode = %x\n", pDevice->byRxMode );
+                    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->pMgmt;
+
+
+    *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;
+    DEVICE_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) &&
+            (pDevice->pMgmt->byCSSPK != KEY_CTL_NONE)) {
+            // unicast pkt use pairwise key
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"unicast pkt\n");
+            if (KeybGetKey(&(pDevice->sKey), pDevice->abyBSSID, 0xFFFFFFFF, &pKey) == TRUE) {
+                if (pDevice->pMgmt->byCSSPK == KEY_CTL_TKIP)
+                    byDecMode = KEY_CTL_TKIP;
+                else if (pDevice->pMgmt->byCSSPK == KEY_CTL_CCMP)
+                    byDecMode = KEY_CTL_CCMP;
+            }
+            DEVICE_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 (pDevice->pMgmt->byCSSGK == KEY_CTL_TKIP)
+                byDecMode = KEY_CTL_TKIP;
+            else if (pDevice->pMgmt->byCSSGK == KEY_CTL_CCMP)
+                byDecMode = KEY_CTL_CCMP;
+            DEVICE_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 (pDevice->pMgmt->byCSSGK == KEY_CTL_TKIP)
+            byDecMode = KEY_CTL_TKIP;
+        else if (pDevice->pMgmt->byCSSGK == KEY_CTL_CCMP)
+            byDecMode = KEY_CTL_CCMP;
+    }
+    *pKeyOut = pKey;
+
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"AES:%d %d %d\n", pDevice->pMgmt->byCSSPK, pDevice->pMgmt->byCSSGK, byDecMode);
+
+    if (pKey == NULL) {
+        DEVICE_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));
+        DEVICE_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);
+        }
+        DEVICE_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;
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV OK!\n");
+            } else {
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV FAIL!!!\n");
+                DEVICE_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
+    )
+{
+    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;
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\nKeyIdx: %d\n", byKeyIdx);
+
+
+    if (pDevice->pMgmt->byCSSGK == KEY_CTL_TKIP)
+        byDecMode = KEY_CTL_TKIP;
+    else if (pDevice->pMgmt->byCSSGK == KEY_CTL_CCMP)
+        byDecMode = KEY_CTL_CCMP;
+
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"AES:%d %d %d\n", pDevice->pMgmt->byCSSPK, pDevice->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
+        DEVICE_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));
+        DEVICE_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);
+        }
+        DEVICE_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
+                DEVICE_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;
+                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV OK!\n");
+                } else {
+                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV FAIL!!!\n");
+                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"PayloadLen = %d\n", PayloadLen);
+                }
+            }
+        }
+
+        if (byDecMode == KEY_CTL_CCMP) {
+            if (bOnFly == FALSE) {
+                // Software CCMP
+                // NotOnFly
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"soft KEY_CTL_CCMP\n");
+                if (AESbGenCCMP(pKey->abyKey, pbyFrame, FrameSize)) {
+                    *pbyNewRsr |= NEWRSR_DECRYPTOK;
+                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"CCMP MIC compare OK!\n");
+                } else {
+                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"CCMP MIC fail!\n");
+                }
+            }
+        }
+
+    }// end of TKIP/AES
+
+    if ((*(pbyIV+3) & 0x20) != 0)
+        *pbExtIV = TRUE;
+    return TRUE;
+}
+
+
+
+
+#ifdef PRIVATE_OBJ
+
+static BOOL s_bAPModeRxData (
+    IN PSDevice pDevice,
+    IN ref_sk_buff* skb,
+    IN UINT     FrameSize,
+    IN UINT     cbHeaderOffset,
+    IN INT      iSANodeIndex,
+    IN INT      iDANodeIndex
+    )
+
+#else
+
+static BOOL s_bAPModeRxData (
+    IN PSDevice pDevice,
+    IN struct sk_buff* skb,
+    IN UINT     FrameSize,
+    IN UINT     cbHeaderOffset,
+    IN INT      iSANodeIndex,
+    IN INT      iDANodeIndex
+    )
+#endif
+{
+    PSMgmtObject        pMgmt = pDevice->pMgmt;
+    BOOL                bRelayAndForward = FALSE;
+    BOOL                bRelayOnly = FALSE;
+    BYTE                byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
+    WORD                wAID;
+#ifdef PRIVATE_OBJ
+    struct sk_buff* tmp_skb;
+    ref_sk_buff     s_ref_skb;
+    ref_sk_buff*    skbcpy = &s_ref_skb;
+#else
+    struct sk_buff* skbcpy = NULL;
+#endif
+
+
+
+    if (FrameSize > CB_MAX_BUF_SIZE)
+        return FALSE;
+    // check DA
+    if(IS_MULTICAST_ADDRESS((PBYTE)(skb->data+cbHeaderOffset))) {
+       if (pMgmt->sNodeDBTable[0].bPSEnable) {
+
+#ifdef PRIVATE_OBJ
+           tmp_skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
+           skbcpy = &s_ref_skb;
+           ref_skb_remap(pDevice->dev, skbcpy, tmp_skb);
+#else
+           skbcpy = dev_alloc_skb((int)pDevice->rx_buf_sz);
+#endif
+        // if any node in PS mode, buffer packet until DTIM.
+           if (skbcpy == NULL) {
+               DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "relay multicast no skb available \n");
+           }
+           else {
+               skbcpy->dev = pDevice->dev;
+#ifdef PRIVATE_OBJ
+               *(skbcpy->len) = FrameSize;
+               memcpy(skbcpy->data, skb->data+cbHeaderOffset, FrameSize);
+               skb_queue_tail(&(pMgmt->sNodeDBTable[0].sTxPSQueue), skbcpy->skb);
+#else
+               skbcpy->len = FrameSize;
+               memcpy(skbcpy->data, skb->data+cbHeaderOffset, FrameSize);
+               skb_queue_tail(&(pMgmt->sNodeDBTable[0].sTxPSQueue), skbcpy);
+#endif
+               pMgmt->sNodeDBTable[0].wEnQueueCnt++;
+               // set tx map
+               pMgmt->abyPSTxMap[0] |= byMask[0];
+           }
+       }
+       else {
+           bRelayAndForward = TRUE;
+       }
+    }
+    else {
+        // check if relay
+        if (BSSDBbIsSTAInNodeDB(pMgmt, (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.
+
+#ifdef PRIVATE_OBJ
+                    ref_skb_add_offset(skb->skb, cbHeaderOffset);
+                    skb_put(skb->skb, FrameSize);
+                    skb_queue_tail(&pMgmt->sNodeDBTable[iDANodeIndex].sTxPSQueue, skb->skb);
+#else
+                       skb->data += cbHeaderOffset;
+                       skb->tail += cbHeaderOffset;
+                    skb_put(skb, FrameSize);
+                    skb_queue_tail(&pMgmt->sNodeDBTable[iDANodeIndex].sTxPSQueue, skb);
+#endif
+                    pMgmt->sNodeDBTable[iDANodeIndex].wEnQueueCnt++;
+                    wAID = pMgmt->sNodeDBTable[iDANodeIndex].wAID;
+                    pMgmt->abyPSTxMap[wAID >> 3] |=  byMask[wAID & 7];
+                    DEVICE_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)) {
+            ROUTEbRelay(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;
+}
+
diff --git a/drivers/staging/vt6655/dpc.h b/drivers/staging/vt6655/dpc.h
new file mode 100644 (file)
index 0000000..68447c4
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * 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: whdr.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 */
+
+
+BOOL
+device_receive_frame (
+    IN  PSDevice pDevice,
+    IN  PSRxDesc pCurrRD
+    );
+
+
+#ifdef __cplusplus
+}                                       /* End of extern "C" { */
+#endif /* __cplusplus */
+
+
+
+VOID   MngWorkItem(PVOID Context);
+#endif // __RXTX_H__
+
+
+
diff --git a/drivers/staging/vt6655/hostap.c b/drivers/staging/vt6655/hostap.c
new file mode 100644 (file)
index 0000000..134de86
--- /dev/null
@@ -0,0 +1,907 @@
+/*
+ * 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
+
+
+#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;
+
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Enabling hostapd mode\n", dev->name);
+
+#ifdef PRIVATE_OBJ
+    pDevice->apdev = ref_init_apdev(dev);
+
+    if (pDevice->apdev == NULL)
+               return -ENOMEM;
+
+       if (rtnl_locked)
+               ret = register_netdevice(pDevice->apdev);
+       else
+               ret = register_netdev(pDevice->apdev);
+       if (ret) {
+               DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: register_netdevice(AP) failed!\n",
+                      dev->name);
+               return -1;
+       }
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Registered netdevice %s for AP management\n",
+              dev->name, pDevice->apdev->name);
+
+#else
+       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) {
+               DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: register_netdevice(AP) failed!\n",
+                      dev->name);
+               return -1;
+       }
+
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Registered netdevice %s for AP management\n",
+              dev->name, pDevice->apdev->name);
+
+    KeyvInitTable(&pDevice->sKey, pDevice->PortOffset);
+#endif
+
+       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)
+{
+
+    DEVICE_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);
+            DEVICE_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;
+
+//4.2007-0118-03,<Add> by EinsnLiu
+//execute some clear work
+pDevice->pMgmt->byCSSPK=KEY_CTL_NONE;
+pDevice->pMgmt->byCSSGK=KEY_CTL_NONE;
+KeyvInitTable(&pDevice->sKey,pDevice->PortOffset);
+
+       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 (BSSDBbIsSTAInNodeDB(pDevice->pMgmt, 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->pMgmt;
+       UINT uNodeIndex;
+
+
+    if (!BSSDBbIsSTAInNodeDB(pMgmt, 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;
+#ifdef PRIVATE_OBJ
+    pMgmt->sNodeDBTable[uNodeIndex].ulLastRxJiffer = get_jiffies();
+#else
+    pMgmt->sNodeDBTable[uNodeIndex].ulLastRxJiffer = jiffies;
+#endif
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Add STA AID= %d \n", pMgmt->sNodeDBTable[uNodeIndex].wAID);
+    DEVICE_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]
+              ) ;
+    DEVICE_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->pMgmt;
+       UINT uNodeIndex;
+
+    if (BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &uNodeIndex)) {
+#ifdef PRIVATE_OBJ
+           param->u.get_info_sta.inactive_sec =
+               (get_jiffies() - pMgmt->sNodeDBTable[uNodeIndex].ulLastRxJiffer) / HZ;
+#else
+           param->u.get_info_sta.inactive_sec =
+               (jiffies - pMgmt->sNodeDBTable[uNodeIndex].ulLastRxJiffer) / HZ;
+#endif
+           //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->pMgmt;
+       UINT uNodeIndex;
+
+    if (BSSDBbIsSTAInNodeDB(pMgmt, 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->pMgmt;
+       UINT uNodeIndex;
+
+    if (BSSDBbIsSTAInNodeDB(pMgmt, 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;
+               DEVICE_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->pMgmt;
+
+
+
+    memcpy( pMgmt->abyWPAIE,
+            param->u.generic_elem.data,
+            param->u.generic_elem.len
+           );
+
+    pMgmt->wWPAIELen =         param->u.generic_elem.len;
+
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pMgmt->wWPAIELen = %d\n",  pMgmt->wWPAIELen);
+
+    // disable wpa
+    if (pMgmt->wWPAIELen == 0) {
+        pMgmt->eAuthenMode = WMAC_AUTH_OPEN;
+               DEVICE_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;
+               DEVICE_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->pMgmt;
+    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;
+               DEVICE_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 (BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &iNodeIndex) == FALSE) {
+               param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR;
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " HOSTAP_CRYPT_ERR_UNKNOWN_ADDR\n");
+               return -EINVAL;
+           }
+       }
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " hostap_set_encryption: sta_index %d \n", iNodeIndex);
+    DEVICE_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->sKey),
+                                param->sta_addr,
+                                pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex,
+                                pDevice->PortOffset) == FALSE) {
+                DEVICE_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->sKey),
+                                dwKeyIndex & ~(BIT30 | USE_KEYRSC),
+                                param->u.crypt.key_len,
+                                NULL,
+                                abyKey,
+                                KEY_CTL_WEP,
+                                pDevice->PortOffset,
+                                pDevice->byLocalID);
+
+        } else {
+            // 8021x enable, individual key
+            dwKeyIndex |= (1 << 30); // set pairwise key
+            if (KeybSetKey(&(pDevice->sKey),
+                           &param->sta_addr[0],
+                           dwKeyIndex & ~(USE_KEYRSC),
+                           param->u.crypt.key_len,
+                           (PQWORD) &(KeyRSC),
+                           (PBYTE)abyKey,
+                            KEY_CTL_WEP,
+                            pDevice->PortOffset,
+                            pDevice->byLocalID) == 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->sKey),
+                           dwKeyIndex,
+                           param->u.crypt.key_len,
+                           (PQWORD) &(KeyRSC),
+                           abyKey,
+                           byKeyDecMode,
+                           pDevice->PortOffset,
+                           pDevice->byLocalID);
+       pMgmt->sNodeDBTable[iNodeIndex].bOnFly = TRUE;
+
+    } else {
+        dwKeyIndex |= (1 << 30); // set pairwise key
+        if (KeybSetKey(&(pDevice->sKey),
+                       &param->sta_addr[0],
+                       dwKeyIndex,
+                       param->u.crypt.key_len,
+                       (PQWORD) &(KeyRSC),
+                       (PBYTE)abyKey,
+                        byKeyDecMode,
+                        pDevice->PortOffset,
+                        pDevice->byLocalID) == TRUE) {
+
+            pMgmt->sNodeDBTable[iNodeIndex].bOnFly = TRUE;
+
+        } else {
+            // Key Table Full
+            pMgmt->sNodeDBTable[iNodeIndex].bOnFly = FALSE;
+            bKeyTableFull = TRUE;
+            DEVICE_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
+        MACvSetDefaultKeyCtl(pDevice->PortOffset, wKeyCtl, MAX_KEY_TABLE-1, pDevice->byLocalID);
+    }
+
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Set key sta_index= %d \n", iNodeIndex);
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " tx_index=%d len=%d \n", param->u.crypt.idx,
+               param->u.crypt.key_len );
+    DEVICE_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->pMgmt;
+       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 (BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &iNodeIndex) == FALSE) {
+               param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR;
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "hostap_get_encryption: HOSTAP_CRYPT_ERR_UNKNOWN_ADDR\n");
+               return -EINVAL;
+           }
+       }
+       DEVICE_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:
+           DEVICE_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:
+           DEVICE_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:
+           DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_ASSOC_AP_ADDR \n");
+               return -EOPNOTSUPP;
+               break;
+       case VIAWGET_HOSTAPD_FLUSH:
+           DEVICE_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:
+           DEVICE_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:
+           DEVICE_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:
+           DEVICE_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:
+           DEVICE_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:
+           DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_FLAGS_STA \n");
+                ret = hostap_set_flags_sta(pDevice, param);
+               break;
+
+       case VIAWGET_HOSTAPD_MLME:
+           DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_MLME \n");
+           return -EOPNOTSUPP;
+
+       case VIAWGET_HOSTAPD_SET_GENERIC_ELEMENT:
+           DEVICE_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:
+           DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SCAN_REQ \n");
+           return -EOPNOTSUPP;
+
+       case VIAWGET_HOSTAPD_STA_CLEAR_STATS:
+           DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_STA_CLEAR_STATS \n");
+           return -EOPNOTSUPP;
+
+       default:
+           DEVICE_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/vt6655/hostap.h b/drivers/staging/vt6655/hostap.h
new file mode 100644 (file)
index 0000000..1fcb2f0
--- /dev/null
@@ -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/vt6655/ioctl.c b/drivers/staging/vt6655/ioctl.c
new file mode 100644 (file)
index 0000000..4869107
--- /dev/null
@@ -0,0 +1,775 @@
+/*
+ * 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(__RF_H__)
+#include "rf.h"
+#endif
+
+
+/*---------------------  Static Definitions -------------------------*/
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+static int          msglevel                =MSG_LEVEL_INFO;
+
+/*---------------------  Static Functions  --------------------------*/
+
+#ifdef WPA_SM_Transtatus
+    SWPAResult wpa_Result;
+#endif
+
+
+/*---------------------  Export Variables  --------------------------*/
+
+int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
+
+       PSCmdRequest        pReq = (PSCmdRequest)rq;
+    PSMgmtObject        pMgmt = pDevice->pMgmt;
+       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:
+
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_BSS_SCAN..begin \n");
+        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);
+        }
+
+        if (pDevice->bMACSuspend == TRUE) {
+            if (pDevice->bRadioOff == TRUE)
+                CARDbRadioPowerOn(pDevice);
+            vMgrTimerInit(pDevice);
+            MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE);
+            add_timer(&pMgmt->sTimerSecondCallback);
+            pDevice->bMACSuspend = FALSE;
+        }
+        spin_lock_irq(&pDevice->lock);
+        if (memcmp(pMgmt->abyCurrBSSID, &abyNullAddr[0], 6) == 0)
+            BSSvClearBSSList((HANDLE)pDevice, FALSE);
+        else
+            BSSvClearBSSList((HANDLE)pDevice, pDevice->bLinkPass);
+
+        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 (pDevice->bMACSuspend == TRUE) {
+            if (pDevice->bRadioOff == TRUE)
+                CARDbRadioPowerOn(pDevice);
+            vMgrTimerInit(pDevice);
+            MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE);
+            add_timer(&pMgmt->sTimerSecondCallback);
+            pDevice->bMACSuspend = FALSE;
+        }
+
+        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;
+               DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ioct set to adhoc mode\n");
+           }
+           else {
+               pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA;
+               DEVICE_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;
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Power Saving On\n");
+        }
+        else {
+            pDevice->ePSMode = WMAC_POWER_CAM;
+            pMgmt->wListenInterval = 1;
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Power Saving Off \n");
+        }
+
+        if (sJoinCmd.bShareKeyAuth == TRUE){
+            pMgmt->bShareKeyAlgorithm = TRUE;
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Share Key \n");
+        }
+        else {
+            pMgmt->bShareKeyAlgorithm = FALSE;
+            DEVICE_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:
+
+        DEVICE_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) {
+            pDevice->bEncryptionEnable = FALSE;
+            pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
+            MACvDisableDefaultKey(pDevice->PortOffset);
+            DEVICE_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-1123-02,<Modify> by EinsnLiu
+       //Evaluate the "dwKeyIndex" error
+       //  dwKeyIndex |= (1 << 31);
+         dwKeyIndex =ii|(1 << 31);
+                else
+                    dwKeyIndex = ii;
+
+                KeybSetDefaultKey(&(pDevice->sKey),
+                                    dwKeyIndex,
+                                    sWEPCmd.auWepKeyLength[ii],
+                                    NULL,
+                                    (PBYTE)&sWEPCmd.abyWepKey[ii][0],
+                                    KEY_CTL_WEP,
+                                    pDevice->PortOffset,
+                                    pDevice->byLocalID);
+            }
+        }
+        pDevice->byKeyIndex = sWEPCmd.byKeyIndex;
+        pDevice->bTransmitKey = TRUE;
+        pDevice->bEncryptionEnable = TRUE;
+        pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
+
+        break;
+
+    case WLAN_CMD_GET_LINK:
+        DEVICE_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;
+            DEVICE_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;
+//                 pList->sBSSIDList[ii].uRSSI = pBSS->uRSSI;
+                   RFvRSSITodBm(pDevice, (BYTE)(pBSS->uRSSI), &ldBm);
+                   pList->sBSSIDList[ii].uRSSI = (UINT)ldBm;
+                   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:
+
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_STOP_MAC\n");
+        netif_stop_queue(pDevice->dev);
+
+        spin_lock_irq(&pDevice->lock);
+        if (pDevice->bRadioOff == FALSE) {
+            CARDbRadioPowerOff(pDevice);
+        }
+        pDevice->bLinkPass = FALSE;
+        memset(pMgmt->abyCurrBSSID, 0, 6);
+        pMgmt->eCurrState = WMAC_STATE_IDLE;
+        del_timer(&pDevice->sTimerCommand);
+        del_timer(&pMgmt->sTimerSecondCallback);
+        pDevice->bCmdRunning = FALSE;
+        pDevice->bMACSuspend = TRUE;
+        MACvIntDisable(pDevice->PortOffset);
+        spin_unlock_irq(&pDevice->lock);
+
+        break;
+
+    case WLAN_CMD_START_MAC:
+
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_START_MAC\n");
+
+        if (pDevice->bMACSuspend == TRUE) {
+            if (pDevice->bRadioOff == TRUE)
+                CARDbRadioPowerOn(pDevice);
+            vMgrTimerInit(pDevice);
+            MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE);
+            add_timer(&pMgmt->sTimerSecondCallback);
+            pDevice->bMACSuspend = FALSE;
+        }
+        break;
+
+    case WLAN_CMD_SET_HOSTAPD:
+
+        DEVICE_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){
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable HOSTAP\n");
+            }
+            else {
+                           result = -EFAULT;
+                           break;
+                       }
+        }
+        else {
+            hostap_set_hostapd(pDevice, 0, 1);
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable HOSTAP\n");
+        }
+
+        break;
+
+    case WLAN_CMD_SET_HOSTAPD_STA:
+
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_HOSTAPD_STA\n");
+
+        break;
+    case WLAN_CMD_SET_802_1X:
+
+        DEVICE_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;
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable 802.1x\n");
+        }
+        else {
+            pDevice->bEnable8021x = FALSE;
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable 802.1x\n");
+        }
+
+        break;
+
+
+    case WLAN_CMD_SET_HOST_WEP:
+
+        DEVICE_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;
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable HostWEP\n");
+        }
+        else {
+            pDevice->bEnableHostWEP = FALSE;
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable HostWEP\n");
+        }
+
+        break;
+
+    case WLAN_CMD_SET_WPA:
+         DEVICE_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) {
+                     DEVICE_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 {
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "close wpadev\n");
+          pDevice->bWPADEVUp = FALSE;
+        }
+
+        break;
+
+    case WLAN_CMD_AP_START:
+
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_AP_START\n");
+        if (pDevice->bRadioOff == TRUE) {
+            CARDbRadioPowerOn(pDevice);
+            vMgrTimerInit(pDevice);
+            MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE);
+            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;
+               DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ioct set to AP mode\n");
+           }
+           else {
+               DEVICE_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;
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Share Key \n");
+        }
+        else {
+            pMgmt->bShareKeyAlgorithm = FALSE;
+            DEVICE_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;
+        }
+
+        DEVICE_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);
+                DEVICE_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;
+               }
+
+       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:
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Private command not support..\n");
+    }
+
+    return result;
+}
+
+/*
+VOID
+vConfigWEPKey (
+    IN PSDevice pDevice,
+    IN DWORD    dwKeyIndex,
+    IN PBYTE    pbyKey,
+    IN ULONG    uKeyLength
+    )
+{
+    int ii;
+
+
+    ZERO_MEMORY(&pDevice->abyWepKey[dwKeyIndex][0], WLAN_WEPMAX_KEYLEN);
+    MEMvCopy(&pDevice->abyWepKey[dwKeyIndex][0], pbyKey, uKeyLength);
+
+    pDevice->bWepKeyAvailable[dwKeyIndex] = TRUE;
+    pDevice->auWepKeyLength[dwKeyIndex] = uKeyLength;
+
+    MACvSetDefaultKeyEntry(pDevice->PortOffset, uKeyLength, dwKeyIndex,
+                           (PDWORD) &(pDevice->abyWepKey[dwKeyIndex][0]), pDevice->byLocalID);
+
+    if (pDevice->eEncryptionStatus < Ndis802_11EncryptionNotSupported) {
+        for(ii=0; ii<MAX_GROUP_KEY; ii++) {
+            if ((pDevice->bWepKeyAvailable[ii] == TRUE) &&
+                (pDevice->auWepKeyLength[ii] == WLAN_WEP232_KEYLEN)) {
+                pDevice->uCurrentWEPMode = TX_WEP_SW232;
+                MACvDisableDefaultKey(pDevice->PortOffset);
+                break;
+            }
+        }
+        if ((ii == MAX_GROUP_KEY) &&
+            (pDevice->eEncryptionStatus < Ndis802_11EncryptionNotSupported)) {
+            MACvEnableDefaultKey(pDevice->PortOffset, pDevice->byLocalID);
+        }
+    }
+}
+*/
diff --git a/drivers/staging/vt6655/ioctl.h b/drivers/staging/vt6655/ioctl.h
new file mode 100644 (file)
index 0000000..9c6816e
--- /dev/null
@@ -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/vt6655/iwctl.c b/drivers/staging/vt6655/iwctl.c
new file mode 100644 (file)
index 0000000..160baf0
--- /dev/null
@@ -0,0 +1,2453 @@
+/*
+ * 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
+extern WORD TxRate_iwconfig;//2008-5-8 <add> by chester
+
+/*---------------------  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 = (U32)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)
+{
+    DEVICE_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;
+               struct iw_scan_req  *req = (struct iw_scan_req *)extra;
+                PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+       BYTE                abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
+       PWLAN_IE_SSID       pItemSSID=NULL;
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSCAN \n");
+
+
+if(pDevice->byReAssocCount > 0) {   //reject scan when re-associating!
+//send scan event to wpa_Supplicant
+  union iwreq_data wrqu;
+ printk("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);
+          BSSvClearBSSList((HANDLE)pDevice, pDevice->bLinkPass);
+
+//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;
+         printk("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;
+       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 */
+
+
+    DEVICE_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) {
+                   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;
+
+             //  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
+
+            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;
+
+    DEVICE_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)) {
+                       DEVICE_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 !!!
+              DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Set to channel = %d\n", channel);
+                         pDevice->uChannel = channel;
+                        //2007-0207-04,<Add> by EinsnLiu
+                        //Make change effect at once
+                         pDevice->bCommit = TRUE;
+               }
+       }
+
+       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);
+
+    DEVICE_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;
+
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMODE \n");
+
+    if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP && pDevice->bEnableHostapd) {
+        DEVICE_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;
+                   }
+               }
+        DEVICE_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;
+                   }
+               }
+        DEVICE_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;
+                   }
+               }
+        DEVICE_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);
+
+
+    DEVICE_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};
+
+
+    DEVICE_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};
+
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAP \n");
+if (pMgmt->eScanState ==  WMAC_IS_SCANNING) {
+        // In scanning..
+     printk("SIOCSIWAP(??)-->In scanning...\n");
+   //  return -EAGAIN;
+  }
+       if (wrq->sa_family != ARPHRD_ETHER)
+               rc = -EINVAL;
+       else {
+               memset(pMgmt->abyDesireBSSID, 0xFF, 6);
+               memcpy(pMgmt->abyDesireBSSID, wrq->sa_data, 6);
+                               //2008-0409-05, <Add> by Einsn Liu
+               if((pDevice->bLinkPass == TRUE) &&
+                     (memcmp(pMgmt->abyDesireBSSID, pMgmt->abyCurrBSSID, 6)== 0)){
+                       return rc;
+                       }
+       //mike :add
+        if ((IS_BROADCAST_ADDRESS(pMgmt->abyDesireBSSID)) ||
+            (memcmp(pMgmt->abyDesireBSSID, ZeroBSSID, 6) == 0)){
+             printk("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!!!
+                 printk("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);
+
+
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAP \n");
+
+    memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6);
+   //2008-0410,<Modify> by Einsn Liu
+    if ((pDevice->bLinkPass == FALSE) && (pMgmt->eCurrMode != WMAC_MODE_ESS_AP))
+        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);
+
+
+    DEVICE_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-0409-05, <Add> by Einsn Liu
+    BYTE  len;
+
+
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWESSID \n");
+ pDevice->fWPA_Authened = FALSE;
+if (pMgmt->eScanState ==  WMAC_IS_SCANNING) {
+        // In scanning..
+     printk("SIOCSIWESSID(??)-->In scanning...\n");
+   //  return -EAGAIN;
+  }
+       // Check if we asked for `any'
+       if(wrq->flags == 0) {
+               // Just send an empty SSID list
+               // Just send an empty SSID list
+               memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+                  memset(pMgmt->abyDesireBSSID, 0xFF,6);
+           printk("set essid to 'any' \n");
+           #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+             //Unknown desired AP,so here need not associate??
+            //if(pDevice->bWPASuppWextEnabled == TRUE)  {
+                  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;
+       printk("set essid to %s \n",pItemSSID->abySSID);
+               //2008-0409-05, <Add> by Einsn Liu
+       len=(pItemSSID->len > ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len)?pItemSSID->len:((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len;
+   if((pDevice->bLinkPass == TRUE) &&
+       (memcmp(pItemSSID->abySSID,((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID,len)==0))
+         return 0;
+
+        //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,
+                                      pMgmt->eConfigPHYMode
+                                      );
+
+            if (pCurr == NULL){
+               printk("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!!!
+                 printk("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
+
+           DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set essid = %s \n", pItemSSID->abySSID);
+/*
+                    #if WIRELESS_EXT < 21
+ DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO " SIOCSIWESSID1 \n");
+               pItemSSID->len = wrq->length - 1;
+            #else
+ DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO " SIOCSIWESSID2 \n");
+               pItemSSID->len = wrq->length;
+            #endif
+            */
+       }
+
+    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;
+
+    DEVICE_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';
+       wrq->length = pItemSSID->len + 1;
+               //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};
+
+
+    DEVICE_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
+       printk("Rate Fix\n");
+               pDevice->bFixRate = TRUE;
+        if ((pDevice->byBBType == BB_TYPE_11B)&& (brate > 3)) {
+
+                       pDevice->uConnectionRate = 3;
+        }
+        else {
+            pDevice->uConnectionRate = brate;
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Fixed to Rate %d \n", pDevice->uConnectionRate);
+        }
+
+       }
+       else {
+        pDevice->bFixRate = FALSE;
+        pDevice->uConnectionRate = 13;
+       printk("auto rate:connection_rate is 13\n");
+}
+
+       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;
+//2007-0118-05,<Mark> by EinsnLiu
+//Mark the unnecessary sentences.
+//    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+
+    DEVICE_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;
+//2008-5-8 <modify> by chester
+if(pDevice->bLinkPass){
+if(pDevice->bFixRate == TRUE){
+               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;
+           }
+}
+else
+{
+
+ brate = abySupportedRates[TxRate_iwconfig];
+}
+}
+else brate =0;
+//2007-0118-05,<Mark> by EinsnLiu
+//Mark the unnecessary sentences.
+/*
+           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;
+
+    DEVICE_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;
+
+    DEVICE_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;
+
+
+    DEVICE_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;
+
+    DEVICE_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;
+
+
+    DEVICE_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;
+    DEVICE_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);
+
+//2007-0207-07,<Modify> by EinsnLiu
+//There are some problems when using iwconfig encode/key command to set the WEP key.
+//I almost rewrite this function.
+//now it support:(assume the wireless interface's name is eth0)
+//iwconfig eth0 key [1] 1122334455 open  /*set key stirng to index 1,and driver using key index is set to 1*/
+//iwconfig eth0 key [3]    /*set driver using  key index to 3,the key string no change */
+//iwconfig eth0 key 1122334455  /*set key string to driver using index*/
+//iwconfig eth0 key restricted  /*enable share key*/
+
+       PSKeyTable pkeytab;
+
+       DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODE \n");
+
+if((wrq->flags & IW_ENCODE_DISABLED)==0){
+       //Not disable encryption
+
+       if (dwKeyIndex > WLAN_WEP_NKEYS) {
+               rc = -EINVAL;
+        return rc;
+       }
+
+       if(dwKeyIndex<1&&((wrq->flags&IW_ENCODE_NOKEY)==0)){//set default key
+               if(pDevice->byKeyIndex<WLAN_WEP_NKEYS){
+                       dwKeyIndex=pDevice->byKeyIndex;
+                       }
+               else dwKeyIndex=0;
+               }else dwKeyIndex--;
+
+
+       // Check the size of the key
+       if (wrq->length > WLAN_WEP232_KEYLEN) {
+               rc = -EINVAL;
+        return rc;
+       }
+
+       if(wrq->length>0){//have key
+
+        if (wrq->length ==  WLAN_WEP232_KEYLEN) {
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 232 bit wep key\n");
+        }
+        else if (wrq->length ==  WLAN_WEP104_KEYLEN) {
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 104 bit wep key\n");
+        }
+        else if (wrq->length == WLAN_WEP40_KEYLEN) {
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 40 bit wep key, index= %d\n", (int)dwKeyIndex);
+        }else {//no support length
+               rc = -EINVAL;
+        return rc;
+               }
+        memset(pDevice->abyKey, 0, WLAN_WEP232_KEYLEN);
+        memcpy(pDevice->abyKey, extra, wrq->length);
+
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"abyKey: ");
+        for (ii = 0; ii < wrq->length; ii++) {
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pDevice->abyKey[ii]);
+        }
+
+        if (pDevice->flags & DEVICE_FLAGS_OPENED) {
+            spin_lock_irq(&pDevice->lock);
+            KeybSetDefaultKey(&(pDevice->sKey),
+                            (DWORD)(dwKeyIndex | (1 << 31)),
+                               wrq->length,
+                            NULL,
+                            pDevice->abyKey,
+                            KEY_CTL_WEP,
+                            pDevice->PortOffset,
+                            pDevice->byLocalID
+                          );
+            spin_unlock_irq(&pDevice->lock);
+        }
+        pDevice->byKeyIndex = (BYTE)dwKeyIndex;
+        pDevice->uKeyLength = wrq->length;
+        pDevice->bTransmitKey = TRUE;
+        pDevice->bEncryptionEnable = TRUE;
+        pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
+
+               }else if(index>0){
+       //when the length is 0 the request only changes the default transmit key index
+       //check the new key has a non zero lenget
+       if(pDevice->bEncryptionEnable==FALSE)
+       {
+               rc = -EINVAL;
+               return rc;
+       }
+       DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Just set Default key Index:\n");
+       pkeytab=&(pDevice->sKey.KeyTable[MAX_KEY_TABLE-1]);
+       if(pkeytab->GroupKey[(BYTE)dwKeyIndex].uKeyLength==0){
+               DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Default key len is 0\n");
+               rc = -EINVAL;
+               return rc;
+               }
+        pDevice->byKeyIndex =(BYTE)dwKeyIndex;
+        pkeytab->dwGTKeyIndex =dwKeyIndex | (1 << 31);
+        pkeytab->GroupKey[(BYTE)dwKeyIndex].dwKeyIndex=dwKeyIndex | (1 << 31);
+       }
+
+}else {//disable the key
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable WEP function\n");
+       if(pDevice->bEncryptionEnable==FALSE)
+               return 0;
+       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->PortOffset, uu);
+            spin_unlock_irq(&pDevice->lock);
+        }
+}
+//End Modify,Einsn
+
+/*
+       DEVICE_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) {
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 232 bit wep key\n");
+        }
+        else if (wrq->length ==  WLAN_WEP104_KEYLEN) {
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 104 bit wep key\n");
+        }
+        else if (wrq->length == WLAN_WEP40_KEYLEN) {
+            DEVICE_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);
+
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"abyKey: ");
+        for (ii = 0; ii < wrq->length; ii++) {
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pDevice->abyKey[ii]);
+        }
+
+        if (pDevice->flags & DEVICE_FLAGS_OPENED) {
+            spin_lock_irq(&pDevice->lock);
+            KeybSetDefaultKey(&(pDevice->sKey),
+                            (DWORD)(pDevice->byKeyIndex | (1 << 31)),
+                            pDevice->uKeyLength,
+                            NULL,
+                            pDevice->abyKey,
+                            KEY_CTL_WEP,
+                            pDevice->PortOffset,
+                            pDevice->byLocalID
+                          );
+            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){
+
+        DEVICE_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->PortOffset, uu);
+            spin_unlock_irq(&pDevice->lock);
+        }
+       }
+*/
+
+       if(wrq->flags & IW_ENCODE_RESTRICTED) {
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable WEP & ShareKey System\n");
+               pMgmt->bShareKeyAlgorithm = TRUE;
+       }
+       if(wrq->flags & IW_ENCODE_OPEN) {
+           DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable WEP & Open System\n");
+               pMgmt->bShareKeyAlgorithm = FALSE;
+       }
+       return rc;
+}
+
+/*
+ * Wireless Handler : get encode mode
+ */
+ /*
+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;
+
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODE\n");
+//2007-0207-06,<Add> by EinsnLiu
+//the key index in iwconfig is 1-4 when our driver is 0-3
+//so it can't be used directly.
+//if the index is 0,we should used the index set by driver.
+       if (index > WLAN_WEP_NKEYS) {
+               rc = -EINVAL;
+        return rc;
+       }
+       if(index<1){//set default key
+               if(pDevice->byKeyIndex<WLAN_WEP_NKEYS){
+                       index=pDevice->byKeyIndex;
+                       }
+               else index=0;
+               }else index--;
+//End Add,Einsn
+
+       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);
+//2007-0207-06,<Modify> by EinsnLiu
+//only get key success need to  copy data
+//index should +1.
+//there is not necessary to return -EINVAL when get key failed
+//if return -EINVAL,the encryption item can't be display by the command "iwconfig".
+       wrq->flags |= index+1;
+       memcpy(extra,  abyKey, WLAN_WEP232_KEYLEN);
+    }
+
+    //else {
+    //    rc = -EINVAL;
+   //     return rc;
+  //  }
+
+
+//End Modify,Einsn
+
+       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;
+
+       DEVICE_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;
+
+    DEVICE_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:
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_UNICAST_R \n");
+               rc = -EINVAL;
+               break;
+       case IW_POWER_ALL_R:
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ALL_R \n");
+               rc = -EINVAL;
+       case IW_POWER_ON:
+        DEVICE_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;
+
+
+    DEVICE_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;
+
+    DEVICE_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;
+
+    DEVICE_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) {
+                      printk("iwctl_siwauth:set WPADEV to disable at 1??????\n");
+                       //pDevice->bWPADevEnable = FALSE;
+               }
+               else if(wrq->value == IW_AUTH_WPA_VERSION_WPA) {
+                          printk("iwctl_siwauth:set WPADEV to WPA1******\n");
+               }
+               else {
+                          printk("iwctl_siwauth:set WPADEV to WPA2******\n");
+               }
+               //pDevice->bWPASuppWextEnabled =TRUE;
+               break;
+       case IW_AUTH_CIPHER_PAIRWISE:
+               pairwise = wrq->value;
+
+               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:
+               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:
+
+               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:
+               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->bWPADevEnable = !! wrq->value;
+               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 = FALSE;
+                       //pDevice->bWPADevEnable = FALSE;
+               }
+
+               break;
+       default:
+               ret = -EOPNOTSUPP;
+               break;
+       }
+/*
+       DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_version = %d\n",wpa_version);
+       DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pairwise = %d\n",pairwise);
+       DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->eEncryptionStatus = %d\n",pDevice->eEncryptionStatus);
+       DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pMgmt->eAuthenMode  = %d\n",pMgmt->eAuthenMode);
+       DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pMgmt->bShareKeyAlgorithm = %s\n",pMgmt->bShareKeyAlgorithm?"TRUE":"FALSE");
+       DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->bEncryptionEnable = %s\n",pDevice->bEncryptionEnable?"TRUE":"FALSE");
+       DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->bWPADevEnable = %s\n",pDevice->bWPADevEnable?"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;
+       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;
+    u8  seq[IW_ENCODE_SEQ_MAX_SIZE];
+    u8 key[64];
+    size_t seq_len,key_len=0;
+//
+   // int ii;
+    u8 *buf;
+    size_t blen;
+    u8 key_array[64];
+    int ret=0;
+
+printk("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:
+               printk("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
+int ii;
+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->bwextcount++;
+    }
+   if((pDevice->bwextcount == 1)&&(param->u.wpa_key.key_index ==1)) {
+ pDevice->bwextcount++;
+    }
+   if((pDevice->bwextcount ==2)&&(param->u.wpa_key.key_index ==2)) {
+ pDevice->bwextcount++;
+       }
+   if((pDevice->bwextcount ==3)&&(param->u.wpa_key.key_index ==3)) {
+ pDevice->bwextcount++;
+        }
+                }
+if( pDevice->bwextcount == 4) {
+    printk("SIOCSIWENCODEEXT:Enable WPA WEXT SUPPORT!!!!!\n");
+ pDevice->bwextcount=0;
+   pDevice->bWPASuppWextEnabled = TRUE;
+                }
+//******
+
+               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
+               //bScheduleCommand((HANDLE) pDevice, WLAN_CMD_DEAUTH, (PBYTE)&reason);
+               break;
+       case IW_MLME_DISASSOC:
+               if(pDevice->bLinkPass == TRUE){
+                                         printk("iwctl_siwmlme--->send DISASSOCIATE\n");
+                 //clear related flags
+                  memset(pMgmt->abyDesireBSSID, 0xFF,6);
+               KeyvInitTable(&pDevice->sKey, pDevice->PortOffset);
+                       bScheduleCommand((HANDLE)pDevice, WLAN_CMD_DISASSOCIATE, NULL);
+               }
+               break;
+       default:
+               ret = -EOPNOTSUPP;
+       }
+
+       return ret;
+
+}
+
+#endif
+
+
+/*------------------------------------------------------------------*/
+/*
+ * 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/vt6655/iwctl.h b/drivers/staging/vt6655/iwctl.h
new file mode 100644 (file)
index 0000000..07554e1
--- /dev/null
@@ -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
+
+#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/vt6655/kcompat.h b/drivers/staging/vt6655/kcompat.h
new file mode 100644 (file)
index 0000000..693939d
--- /dev/null
@@ -0,0 +1,302 @@
+/*
+ * 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: 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;
+
+#ifdef PRIVATE_OBJ
+#define IRQ_RETVAL(x)   (int)x
+#else
+#define IRQ_RETVAL(x)
+#endif
+
+#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)
+{
+       1112
+       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/vt6655/key.c b/drivers/staging/vt6655/key.c
new file mode 100644 (file)
index 0000000..168ebd3
--- /dev/null
@@ -0,0 +1,836 @@
+/*
+ * 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
+
+
+/*---------------------  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 (PSKeyManagement pTable, DWORD_PTR dwIoBase)
+{
+    int i;
+
+    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;
+            MACvDisableKeyEntry(dwIoBase, i);
+        }
+    }
+}
+
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+/*
+ * Description: Init Key management table
+ *
+ * Parameters:
+ *  In:
+ *      pTable          - Pointer to Key table
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+VOID KeyvInitTable (PSKeyManagement pTable, DWORD_PTR dwIoBase)
+{
+    int i;
+    int jj;
+
+    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;
+        MACvDisableKeyEntry(dwIoBase, i);
+    }
+}
+
+
+/*
+ * 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;
+
+    DEVICE_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 (
+    PSKeyManagement pTable,
+    PBYTE           pbyBSSID,
+    DWORD           dwKeyIndex,
+    ULONG           uKeyLength,
+    PQWORD          pKeyRSC,
+    PBYTE           pbyKey,
+    BYTE            byKeyDecMode,
+    DWORD_PTR       dwIoBase,
+    BYTE            byLocalID
+    )
+{
+    int         i,j;
+    UINT        ii;
+    PSKeyItem   pKey;
+    UINT        uKeyIdx;
+
+    DEVICE_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;
+                    DEVICE_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(dwIoBase, pTable->KeyTable[i].wKeyCtl, i, uKeyIdx, pbyBSSID, (PDWORD)pKey->abyKey, byLocalID);
+
+            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;
+
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybSetKey(R): \n");
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->bKeyValid: %d\n ", pKey->bKeyValid);
+            //DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->uKeyLength: %d\n ", pKey->uKeyLength);
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->abyKey: ");
+            for (ii = 0; ii < pKey->uKeyLength; ii++) {
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pKey->abyKey[ii]);
+            }
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %lx\n ", pKey->dwTSC47_16);
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n ", pKey->wTSC15_0);
+            DEVICE_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;
+                DEVICE_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(dwIoBase, pTable->KeyTable[j].wKeyCtl, j, uKeyIdx, pbyBSSID, (PDWORD)pKey->abyKey, byLocalID);
+
+        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;
+
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybSetKey(N): \n");
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->bKeyValid: %d\n ", pKey->bKeyValid);
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->uKeyLength: %d\n ", (int)pKey->uKeyLength);
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->abyKey: ");
+        for (ii = 0; ii < pKey->uKeyLength; ii++) {
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pKey->abyKey[ii]);
+        }
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %lx\n ", pKey->dwTSC47_16);
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n ", pKey->wTSC15_0);
+        DEVICE_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 (
+    PSKeyManagement pTable,
+    PBYTE           pbyBSSID,
+    DWORD           dwKeyIndex,
+    DWORD_PTR       dwIoBase
+    )
+{
+    int  i;
+
+    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;
+            }
+            s_vCheckKeyTableValid(pTable, dwIoBase);
+            return 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;
+                }
+            }
+            s_vCheckKeyTableValid(pTable, dwIoBase);
+            return TRUE;
+        }
+        else {
+            return FALSE;
+        }
+    }
+
+    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;
+                s_vCheckKeyTableValid(pTable, dwIoBase);
+                return (TRUE);
+            }
+            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;
+                }
+                s_vCheckKeyTableValid(pTable, dwIoBase);
+                return (TRUE);
+            }
+            else {
+                return (FALSE);
+            }
+        }
+    }
+    return (FALSE);
+}
+
+
+/*
+ * 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 (
+    PSKeyManagement pTable,
+    PBYTE           pbyBSSID,
+    DWORD_PTR       dwIoBase
+    )
+{
+    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(pTable, dwIoBase);
+            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 (
+    PSKeyManagement pTable,
+    DWORD           dwKeyIndex,
+    DWORD_PTR       dwIoBase
+    )
+{
+
+   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(pTable, dwIoBase);
+    }
+    return;
+}
+
+VOID KeyvRemoveAllWEPKey (
+    PSKeyManagement pTable,
+    DWORD_PTR       dwIoBase
+    )
+{
+    int i;
+
+    for(i=0;i<MAX_GROUP_KEY;i++) {
+        KeyvRemoveWEPKey(pTable, i, dwIoBase);
+    }
+}
+
+/*
+ * 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);
+
+                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybGetTransmitKey:");
+                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"PAIRWISE_KEY: KeyTable.abyBSSID: ");
+                    for (ii = 0; ii < 6; ii++) {
+                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%x ", pTable->KeyTable[i].abyBSSID[ii]);
+                    }
+                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+
+
+                    return (TRUE);
+                }
+                else {
+                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"PairwiseKey.bKeyValid == FALSE\n");
+                    return (FALSE);
+                }
+            } // End of Type == PAIRWISE
+            else {
+                if (pTable->KeyTable[i].dwGTKeyIndex == 0) {
+                    DEVICE_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)]);
+
+                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybGetTransmitKey:");
+                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"GROUP_KEY: KeyTable.abyBSSID\n");
+                        for (ii = 0; ii < 6; ii++) {
+                            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%x ", pTable->KeyTable[i].abyBSSID[ii]);
+                        }
+                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"dwGTKeyIndex: %lX\n", pTable->KeyTable[i].dwGTKeyIndex);
+
+                    return (TRUE);
+                }
+                else {
+                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"GroupKey.bKeyValid == FALSE\n");
+                    return (FALSE);
+                }
+            } // End of Type = GROUP
+        } // BSSID match
+    }
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ERROR: NO Match BSSID !!! ");
+    for (ii = 0; ii < 6; ii++) {
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *(pbyBSSID+ii));
+    }
+    DEVICE_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 (
+    PSKeyManagement pTable,
+    DWORD           dwKeyIndex,
+    ULONG           uKeyLength,
+    PQWORD          pKeyRSC,
+    PBYTE           pbyKey,
+    BYTE            byKeyDecMode,
+    DWORD_PTR       dwIoBase,
+    BYTE            byLocalID
+    )
+{
+    UINT        ii;
+    PSKeyItem   pKey;
+    UINT        uKeyIdx;
+
+    DEVICE_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;
+        DEVICE_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(dwIoBase, pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl, MAX_KEY_TABLE-1, uKeyIdx, pTable->KeyTable[MAX_KEY_TABLE-1].abyBSSID, (PDWORD)pKey->abyKey, byLocalID);
+
+    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;
+
+
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybSetKey(R): \n");
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->bKeyValid: %d\n", pKey->bKeyValid);
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->uKeyLength: %d\n", (int)pKey->uKeyLength);
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->abyKey: \n");
+    for (ii = 0; ii < pKey->uKeyLength; ii++) {
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%x", pKey->abyKey[ii]);
+    }
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %lx\n", pKey->dwTSC47_16);
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n", pKey->wTSC15_0);
+    DEVICE_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 (
+    PSKeyManagement pTable,
+    DWORD           dwKeyIndex,
+    ULONG           uKeyLength,
+    PQWORD          pKeyRSC,
+    PBYTE           pbyKey,
+    BYTE            byKeyDecMode,
+    DWORD_PTR       dwIoBase,
+    BYTE            byLocalID
+    )
+{
+    int         i;
+    UINT        ii;
+    PSKeyItem   pKey;
+    UINT        uKeyIdx;
+
+    DEVICE_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;
+                DEVICE_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(dwIoBase, pTable->KeyTable[i].wKeyCtl, i, uKeyIdx, pTable->KeyTable[i].abyBSSID, (PDWORD)pKey->abyKey, byLocalID);
+
+            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;
+
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybSetKey(R): \n");
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->bKeyValid: %d\n ", pKey->bKeyValid);
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->uKeyLength: %d\n ", (int)pKey->uKeyLength);
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->abyKey: ");
+            for (ii = 0; ii < pKey->uKeyLength; ii++) {
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", pKey->abyKey[ii]);
+            }
+            DEVICE_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/vt6655/key.h b/drivers/staging/vt6655/key.h
new file mode 100644 (file)
index 0000000..9c7d335
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+ * 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;
+    //2006-1116-01,<Modify> by NomadZhao
+    //WORD      wKeyCtl;
+    //BOOL      bSoftWEP;
+    BOOL        bSoftWEP;
+    WORD        wKeyCtl;      // for address of wKeyCtl at align 4
+
+    BYTE        byReserved1[6];
+} SKeyTable, DEF* PSKeyTable; //348
+
+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(PSKeyManagement pTable, DWORD_PTR dwIoBase);
+
+BOOL KeybGetKey(
+    IN  PSKeyManagement pTable,
+    IN  PBYTE           pbyBSSID,
+    IN  DWORD           dwKeyIndex,
+    OUT PSKeyItem       *pKey
+    );
+
+BOOL KeybSetKey(
+    PSKeyManagement pTable,
+    PBYTE           pbyBSSID,
+    DWORD           dwKeyIndex,
+    ULONG           uKeyLength,
+    PQWORD          pKeyRSC,
+    PBYTE           pbyKey,
+    BYTE            byKeyDecMode,
+    DWORD_PTR       dwIoBase,
+    BYTE            byLocalID
+    );
+
+BOOL KeybSetDefaultKey(
+    PSKeyManagement pTable,
+    DWORD           dwKeyIndex,
+    ULONG           uKeyLength,
+    PQWORD          pKeyRSC,
+    PBYTE           pbyKey,
+    BYTE            byKeyDecMode,
+    DWORD_PTR       dwIoBase,
+    BYTE            byLocalID
+    );
+
+BOOL KeybRemoveKey(
+    PSKeyManagement pTable,
+    PBYTE           pbyBSSID,
+    DWORD           dwKeyIndex,
+    DWORD_PTR       dwIoBase
+    );
+
+BOOL KeybGetTransmitKey(
+    IN  PSKeyManagement pTable,
+    IN  PBYTE           pbyBSSID,
+    IN  DWORD           dwKeyType,
+    OUT PSKeyItem       *pKey
+    );
+
+BOOL KeybCheckPairewiseKey(
+    IN  PSKeyManagement pTable,
+    OUT PSKeyItem       *pKey
+    );
+
+BOOL KeybRemoveAllKey(
+    PSKeyManagement pTable,
+    PBYTE           pbyBSSID,
+    DWORD_PTR       dwIoBase
+    );
+
+VOID KeyvRemoveWEPKey(
+    PSKeyManagement pTable,
+    DWORD           dwKeyIndex,
+    DWORD_PTR       dwIoBase
+    );
+
+VOID KeyvRemoveAllWEPKey(
+    PSKeyManagement pTable,
+    DWORD_PTR       dwIoBase
+    );
+
+BOOL KeybSetAllGroupKey (
+    PSKeyManagement pTable,
+    DWORD           dwKeyIndex,
+    ULONG           uKeyLength,
+    PQWORD          pKeyRSC,
+    PBYTE           pbyKey,
+    BYTE            byKeyDecMode,
+    DWORD_PTR       dwIoBase,
+    BYTE            byLocalID
+    );
+
+#ifdef __cplusplus
+}                                       /* End of extern "C" { */
+
+#endif /* __cplusplus */
+
+
+#endif // __KEY_H__
+
diff --git a/drivers/staging/vt6655/mac.c b/drivers/staging/vt6655/mac.c
new file mode 100644 (file)
index 0000000..0283ed3
--- /dev/null
@@ -0,0 +1,1752 @@
+/*
+ * 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:
+ *      MACvReadAllRegs - Read All MAC Registers to buffer
+ *      MACbIsRegBitsOn - Test if All test Bits On
+ *      MACbIsRegBitsOff - Test if All test Bits Off
+ *      MACbIsIntDisable - Test if MAC interrupt disable
+ *      MACbyReadMultiAddr - Read Multicast Address Mask Pattern
+ *      MACvWriteMultiAddr - Write Multicast Address Mask Pattern
+ *      MACvSetMultiAddrByHash - Set Multicast Address Mask by Hash value
+ *      MACvResetMultiAddrByHash - Clear Multicast Address Mask by Hash value
+ *      MACvSetRxThreshold - Set Rx Threshold value
+ *      MACvGetRxThreshold - Get Rx Threshold value
+ *      MACvSetTxThreshold - Set Tx Threshold value
+ *      MACvGetTxThreshold - Get Tx Threshold value
+ *      MACvSetDmaLength - Set Dma Length value
+ *      MACvGetDmaLength - Get Dma Length value
+ *      MACvSetShortRetryLimit - Set 802.11 Short Retry limit
+ *      MACvGetShortRetryLimit - Get 802.11 Short Retry limit
+ *      MACvSetLongRetryLimit - Set 802.11 Long Retry limit
+ *      MACvGetLongRetryLimit - Get 802.11 Long Retry limit
+ *      MACvSetLoopbackMode - Set MAC Loopback Mode
+ *      MACbIsInLoopbackMode - Test if MAC in Loopback mode
+ *      MACvSetPacketFilter - Set MAC Address Filter
+ *      MACvSaveContext - Save Context of MAC Registers
+ *      MACvRestoreContext - Restore Context of MAC Registers
+ *      MACbCompareContext - Compare if values of MAC Registers same as Context
+ *      MACbSoftwareReset - Software Reset MAC
+ *      MACbSafeRxOff - Turn Off MAC Rx
+ *      MACbSafeTxOff - Turn Off MAC Tx
+ *      MACbSafeStop - Stop MAC function
+ *      MACbShutdown - Shut down MAC
+ *      MACvInitialize - Initialize MAC
+ *      MACvSetCurrRxDescAddr - Set Rx Descriptos Address
+ *      MACvSetCurrTx0DescAddr - Set Tx0 Descriptos Address
+ *      MACvSetCurrTx1DescAddr - Set Tx1 Descriptos Address
+ *      MACvTimer0MicroSDelay - Micro Second Delay Loop by MAC
+ *
+ * Revision History:
+ *      08-22-2003 Kyle Hsu     :  Porting MAC functions from sim53
+ *      09-03-2003 Bryan YC Fan :  Add MACvClearBusSusInd()& MACvEnableBusSusEn()
+ *      09-18-2003 Jerry Chen   :  Add MACvSetKeyEntry & MACvDisableKeyEntry
+ *
+ */
+
+#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
+
+
+WORD TxRate_iwconfig;//2008-5-8 <add> by chester
+/*---------------------  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:
+ *      Read All MAC Registers to buffer
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - Base Address for MAC
+ *  Out:
+ *      pbyMacRegs  - buffer to read
+ *
+ * Return Value: none
+ *
+ */
+VOID MACvReadAllRegs (DWORD_PTR dwIoBase, PBYTE pbyMacRegs)
+{
+    int ii;
+
+    // read page0 register
+    for (ii = 0; ii < MAC_MAX_CONTEXT_SIZE_PAGE0; ii++) {
+        VNSvInPortB(dwIoBase + ii, pbyMacRegs);
+        pbyMacRegs++;
+    }
+
+    MACvSelectPage1(dwIoBase);
+
+    // read page1 register
+    for (ii = 0; ii < MAC_MAX_CONTEXT_SIZE_PAGE1; ii++) {
+        VNSvInPortB(dwIoBase + ii, pbyMacRegs);
+        pbyMacRegs++;
+    }
+
+    MACvSelectPage0(dwIoBase);
+
+}
+
+/*
+ * Description:
+ *      Test if all test bits on
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - Base Address for MAC
+ *      byRegOfs    - Offset of MAC Register
+ *      byTestBits  - Test bits
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if all test bits On; otherwise FALSE
+ *
+ */
+BOOL MACbIsRegBitsOn (DWORD_PTR dwIoBase, BYTE byRegOfs, BYTE byTestBits)
+{
+    BYTE byData;
+
+    VNSvInPortB(dwIoBase + byRegOfs, &byData);
+    return BITbIsAllBitsOn(byData, byTestBits);
+}
+
+/*
+ * Description:
+ *      Test if all test bits off
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - Base Address for MAC
+ *      byRegOfs    - Offset of MAC Register
+ *      byTestBits  - Test bits
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if all test bits Off; otherwise FALSE
+ *
+ */
+BOOL MACbIsRegBitsOff (DWORD_PTR dwIoBase, BYTE byRegOfs, BYTE byTestBits)
+{
+    BYTE byData;
+
+    VNSvInPortB(dwIoBase + byRegOfs, &byData);
+    return BITbIsAllBitsOff(byData, byTestBits);
+}
+
+/*
+ * Description:
+ *      Test if MAC interrupt disable
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - Base Address for MAC
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if interrupt is disable; otherwise FALSE
+ *
+ */
+BOOL MACbIsIntDisable (DWORD_PTR dwIoBase)
+{
+    DWORD dwData;
+
+    VNSvInPortD(dwIoBase + MAC_REG_IMR, &dwData);
+    if (dwData != 0)
+        return FALSE;
+
+    return TRUE;
+}
+
+/*
+ * Description:
+ *      Read MAC Multicast Address Mask
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - Base Address for MAC
+ *      uByteidx    - Index of Mask
+ *  Out:
+ *      none
+ *
+ * Return Value: Mask Value read
+ *
+ */
+BYTE MACbyReadMultiAddr (DWORD_PTR dwIoBase, UINT uByteIdx)
+{
+    BYTE byData;
+
+    MACvSelectPage1(dwIoBase);
+    VNSvInPortB(dwIoBase + MAC_REG_MAR0 + uByteIdx, &byData);
+    MACvSelectPage0(dwIoBase);
+    return byData;
+}
+
+/*
+ * Description:
+ *      Write MAC Multicast Address Mask
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - Base Address for MAC
+ *      uByteidx    - Index of Mask
+ *      byData      - Mask Value to write
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+VOID MACvWriteMultiAddr (DWORD_PTR dwIoBase, UINT uByteIdx, BYTE byData)
+{
+    MACvSelectPage1(dwIoBase);
+    VNSvOutPortB(dwIoBase + MAC_REG_MAR0 + uByteIdx, byData);
+    MACvSelectPage0(dwIoBase);
+}
+
+/*
+ * Description:
+ *      Set this hash index into multicast address register bit
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - Base Address for MAC
+ *      byHashIdx   - Hash index to set
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void MACvSetMultiAddrByHash (DWORD_PTR dwIoBase, BYTE byHashIdx)
+{
+    UINT uByteIdx;
+    BYTE byBitMask;
+    BYTE byOrgValue;
+
+    // calculate byte position
+    uByteIdx = byHashIdx / 8;
+    ASSERT(uByteIdx < 8);
+    // calculate bit position
+    byBitMask = 1;
+    byBitMask <<= (byHashIdx % 8);
+    // turn on the bit
+    byOrgValue = MACbyReadMultiAddr(dwIoBase, uByteIdx);
+    MACvWriteMultiAddr(dwIoBase, uByteIdx, (BYTE)(byOrgValue | byBitMask));
+}
+
+/*
+ * Description:
+ *      Reset this hash index into multicast address register bit
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - Base Address for MAC
+ *      byHashIdx   - Hash index to clear
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void MACvResetMultiAddrByHash (DWORD_PTR dwIoBase, BYTE byHashIdx)
+{
+    UINT uByteIdx;
+    BYTE byBitMask;
+    BYTE byOrgValue;
+
+    // calculate byte position
+    uByteIdx = byHashIdx / 8;
+    ASSERT(uByteIdx < 8);
+    // calculate bit position
+    byBitMask = 1;
+    byBitMask <<= (byHashIdx % 8);
+    // turn off the bit
+    byOrgValue = MACbyReadMultiAddr(dwIoBase, uByteIdx);
+    MACvWriteMultiAddr(dwIoBase, uByteIdx, (BYTE)(byOrgValue & (~byBitMask)));
+}
+
+/*
+ * Description:
+ *      Set Rx Threshold
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - Base Address for MAC
+ *      byThreshold - Threshold Value
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void MACvSetRxThreshold (DWORD_PTR dwIoBase, BYTE byThreshold)
+{
+    BYTE byOrgValue;
+
+    ASSERT(byThreshold < 4);
+
+    // set FCR0
+    VNSvInPortB(dwIoBase + MAC_REG_FCR0, &byOrgValue);
+    byOrgValue = (byOrgValue & 0xCF) | (byThreshold << 4);
+    VNSvOutPortB(dwIoBase + MAC_REG_FCR0, byOrgValue);
+}
+
+/*
+ * Description:
+ *      Get Rx Threshold
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - Base Address for MAC
+ *  Out:
+ *      pbyThreshold- Threshold Value Get
+ *
+ * Return Value: none
+ *
+ */
+void MACvGetRxThreshold (DWORD_PTR dwIoBase, PBYTE pbyThreshold)
+{
+    // get FCR0
+    VNSvInPortB(dwIoBase + MAC_REG_FCR0, pbyThreshold);
+    *pbyThreshold = (*pbyThreshold >> 4) & 0x03;
+}
+
+/*
+ * Description:
+ *      Set Tx Threshold
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - Base Address for MAC
+ *      byThreshold - Threshold Value
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void MACvSetTxThreshold (DWORD_PTR dwIoBase, BYTE byThreshold)
+{
+    BYTE byOrgValue;
+
+    ASSERT(byThreshold < 4);
+
+    // set FCR0
+    VNSvInPortB(dwIoBase + MAC_REG_FCR0, &byOrgValue);
+    byOrgValue = (byOrgValue & 0xF3) | (byThreshold << 2);
+    VNSvOutPortB(dwIoBase + MAC_REG_FCR0, byOrgValue);
+}
+
+/*
+ * Description:
+ *      Get Tx Threshold
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - Base Address for MAC
+ *  Out:
+ *      pbyThreshold- Threshold Value Get
+ *
+ * Return Value: none
+ *
+ */
+void MACvGetTxThreshold (DWORD_PTR dwIoBase, PBYTE pbyThreshold)
+{
+    // get FCR0
+    VNSvInPortB(dwIoBase + MAC_REG_FCR0, pbyThreshold);
+    *pbyThreshold = (*pbyThreshold >> 2) & 0x03;
+}
+
+/*
+ * Description:
+ *      Set Dma Length
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - Base Address for MAC
+ *      byDmaLength - Dma Length Value
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void MACvSetDmaLength (DWORD_PTR dwIoBase, BYTE byDmaLength)
+{
+    BYTE byOrgValue;
+
+    ASSERT(byDmaLength < 4);
+
+    // set FCR0
+    VNSvInPortB(dwIoBase + MAC_REG_FCR0, &byOrgValue);
+    byOrgValue = (byOrgValue & 0xFC) | byDmaLength;
+    VNSvOutPortB(dwIoBase + MAC_REG_FCR0, byOrgValue);
+}
+
+/*
+ * Description:
+ *      Get Dma Length
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - Base Address for MAC
+ *  Out:
+ *      pbyDmaLength- Dma Length Value Get
+ *
+ * Return Value: none
+ *
+ */
+void MACvGetDmaLength (DWORD_PTR dwIoBase, PBYTE pbyDmaLength)
+{
+    // get FCR0
+    VNSvInPortB(dwIoBase + MAC_REG_FCR0, pbyDmaLength);
+    *pbyDmaLength &= 0x03;
+}
+
+/*
+ * Description:
+ *      Set 802.11 Short Retry Limit
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - Base Address for MAC
+ *      byRetryLimit- Retry Limit
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void MACvSetShortRetryLimit (DWORD_PTR dwIoBase, BYTE byRetryLimit)
+{
+    // set SRT
+    VNSvOutPortB(dwIoBase + MAC_REG_SRT, byRetryLimit);
+}
+
+/*
+ * Description:
+ *      Get 802.11 Short Retry Limit
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase        - Base Address for MAC
+ *  Out:
+ *      pbyRetryLimit   - Retry Limit Get
+ *
+ * Return Value: none
+ *
+ */
+void MACvGetShortRetryLimit (DWORD_PTR dwIoBase, PBYTE pbyRetryLimit)
+{
+    // get SRT
+    VNSvInPortB(dwIoBase + MAC_REG_SRT, pbyRetryLimit);
+}
+
+/*
+ * Description:
+ *      Set 802.11 Long Retry Limit
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - Base Address for MAC
+ *      byRetryLimit- Retry Limit
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void MACvSetLongRetryLimit (DWORD_PTR dwIoBase, BYTE byRetryLimit)
+{
+    // set LRT
+    VNSvOutPortB(dwIoBase + MAC_REG_LRT, byRetryLimit);
+}
+
+/*
+ * Description:
+ *      Get 802.11 Long Retry Limit
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase        - Base Address for MAC
+ *  Out:
+ *      pbyRetryLimit   - Retry Limit Get
+ *
+ * Return Value: none
+ *
+ */
+void MACvGetLongRetryLimit (DWORD_PTR dwIoBase, PBYTE pbyRetryLimit)
+{
+    // get LRT
+    VNSvInPortB(dwIoBase + MAC_REG_LRT, pbyRetryLimit);
+}
+
+/*
+ * Description:
+ *      Set MAC Loopback mode
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase        - Base Address for MAC
+ *      byLoopbackMode  - Loopback Mode
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void MACvSetLoopbackMode (DWORD_PTR dwIoBase, BYTE byLoopbackMode)
+{
+    BYTE byOrgValue;
+
+    ASSERT(byLoopbackMode < 3);
+    byLoopbackMode <<= 6;
+    // set TCR
+    VNSvInPortB(dwIoBase + MAC_REG_TEST, &byOrgValue);
+    byOrgValue = byOrgValue & 0x3F;
+    byOrgValue = byOrgValue | byLoopbackMode;
+    VNSvOutPortB(dwIoBase + MAC_REG_TEST, byOrgValue);
+}
+
+/*
+ * Description:
+ *      Test if MAC in Loopback mode
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase        - Base Address for MAC
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if in Loopback mode; otherwise FALSE
+ *
+ */
+BOOL MACbIsInLoopbackMode (DWORD_PTR dwIoBase)
+{
+    BYTE byOrgValue;
+
+    VNSvInPortB(dwIoBase + MAC_REG_TEST, &byOrgValue);
+    if (BITbIsAnyBitsOn(byOrgValue, (TEST_LBINT | TEST_LBEXT)))
+        return TRUE;
+    return FALSE;
+}
+
+/*
+ * Description:
+ *      Set MAC Address filter
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase        - Base Address for MAC
+ *      wFilterType     - Filter Type
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void MACvSetPacketFilter (DWORD_PTR dwIoBase, WORD wFilterType)
+{
+    BYTE    byOldRCR;
+    BYTE    byNewRCR = 0;
+
+    // if only in DIRECTED mode, multicast-address will set to zero,
+    // but if other mode exist (e.g. PROMISCUOUS), multicast-address
+    // will be open
+    if (BITbIsBitOn(wFilterType, PKT_TYPE_DIRECTED)) {
+        // set multicast address to accept none
+        MACvSelectPage1(dwIoBase);
+        VNSvOutPortD(dwIoBase + MAC_REG_MAR0, 0L);
+        VNSvOutPortD(dwIoBase + MAC_REG_MAR0 + sizeof(DWORD), 0L);
+        MACvSelectPage0(dwIoBase);
+    }
+
+    if (BITbIsAnyBitsOn(wFilterType, PKT_TYPE_PROMISCUOUS | PKT_TYPE_ALL_MULTICAST)) {
+        // set multicast address to accept all
+        MACvSelectPage1(dwIoBase);
+        VNSvOutPortD(dwIoBase + MAC_REG_MAR0, 0xFFFFFFFFL);
+        VNSvOutPortD(dwIoBase + MAC_REG_MAR0 + sizeof(DWORD), 0xFFFFFFFFL);
+        MACvSelectPage0(dwIoBase);
+    }
+
+    if (BITbIsBitOn(wFilterType, PKT_TYPE_PROMISCUOUS)) {
+
+        byNewRCR |= (RCR_RXALLTYPE | RCR_UNICAST | RCR_MULTICAST | RCR_BROADCAST);
+
+        byNewRCR &= ~RCR_BSSID;
+    }
+
+    if (BITbIsAnyBitsOn(wFilterType, (PKT_TYPE_ALL_MULTICAST | PKT_TYPE_MULTICAST)))
+        byNewRCR |= RCR_MULTICAST;
+
+    if (BITbIsBitOn(wFilterType, PKT_TYPE_BROADCAST))
+        byNewRCR |= RCR_BROADCAST;
+
+    if (BITbIsBitOn(wFilterType, PKT_TYPE_ERROR_CRC))
+        byNewRCR |= RCR_ERRCRC;
+
+    VNSvInPortB(dwIoBase + MAC_REG_RCR,  &byOldRCR);
+    if (byNewRCR != byOldRCR) {
+        // Modify the Receive Command Register
+        VNSvOutPortB(dwIoBase + MAC_REG_RCR, byNewRCR);
+    }
+}
+
+/*
+ * Description:
+ *      Save MAC registers to context buffer
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - Base Address for MAC
+ *  Out:
+ *      pbyCxtBuf   - Context buffer
+ *
+ * Return Value: none
+ *
+ */
+void MACvSaveContext (DWORD_PTR dwIoBase, PBYTE pbyCxtBuf)
+{
+    int         ii;
+
+    // read page0 register
+    for (ii = 0; ii < MAC_MAX_CONTEXT_SIZE_PAGE0; ii++) {
+        VNSvInPortB((dwIoBase + ii), (pbyCxtBuf + ii));
+    }
+
+    MACvSelectPage1(dwIoBase);
+
+    // read page1 register
+    for (ii = 0; ii < MAC_MAX_CONTEXT_SIZE_PAGE1; ii++) {
+        VNSvInPortB((dwIoBase + ii), (pbyCxtBuf + MAC_MAX_CONTEXT_SIZE_PAGE0 + ii));
+    }
+
+    MACvSelectPage0(dwIoBase);
+}
+
+/*
+ * Description:
+ *      Restore MAC registers from context buffer
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - Base Address for MAC
+ *      pbyCxtBuf   - Context buffer
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+VOID MACvRestoreContext (DWORD_PTR dwIoBase, PBYTE pbyCxtBuf)
+{
+    int         ii;
+
+    MACvSelectPage1(dwIoBase);
+    // restore page1
+    for (ii = 0; ii < MAC_MAX_CONTEXT_SIZE_PAGE1; ii++) {
+        VNSvOutPortB((dwIoBase + ii), *(pbyCxtBuf + MAC_MAX_CONTEXT_SIZE_PAGE0 + ii));
+    }
+    MACvSelectPage0(dwIoBase);
+
+    // restore RCR,TCR,IMR...
+    for (ii = MAC_REG_RCR; ii < MAC_REG_ISR; ii++) {
+        VNSvOutPortB(dwIoBase + ii, *(pbyCxtBuf + ii));
+    }
+    // restore MAC Config.
+    for (ii = MAC_REG_LRT; ii < MAC_REG_PAGE1SEL; ii++) {
+        VNSvOutPortB(dwIoBase + ii, *(pbyCxtBuf + ii));
+    }
+    VNSvOutPortB(dwIoBase + MAC_REG_CFG, *(pbyCxtBuf + MAC_REG_CFG));
+
+    // restore PS Config.
+    for (ii = MAC_REG_PSCFG; ii < MAC_REG_BBREGCTL; ii++) {
+        VNSvOutPortB(dwIoBase + ii, *(pbyCxtBuf + ii));
+    }
+
+    // restore CURR_RX_DESC_ADDR, CURR_TX_DESC_ADDR
+    VNSvOutPortD(dwIoBase + MAC_REG_TXDMAPTR0, *(PDWORD)(pbyCxtBuf + MAC_REG_TXDMAPTR0));
+    VNSvOutPortD(dwIoBase + MAC_REG_AC0DMAPTR, *(PDWORD)(pbyCxtBuf + MAC_REG_AC0DMAPTR));
+    VNSvOutPortD(dwIoBase + MAC_REG_BCNDMAPTR, *(PDWORD)(pbyCxtBuf + MAC_REG_BCNDMAPTR));
+
+
+    VNSvOutPortD(dwIoBase + MAC_REG_RXDMAPTR0, *(PDWORD)(pbyCxtBuf + MAC_REG_RXDMAPTR0));
+
+    VNSvOutPortD(dwIoBase + MAC_REG_RXDMAPTR1, *(PDWORD)(pbyCxtBuf + MAC_REG_RXDMAPTR1));
+
+}
+
+/*
+ * Description:
+ *      Compare if MAC registers same as context buffer
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - Base Address for MAC
+ *      pbyCxtBuf   - Context buffer
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if all values are the same; otherwise FALSE
+ *
+ */
+BOOL MACbCompareContext (DWORD_PTR dwIoBase, PBYTE pbyCxtBuf)
+{
+    DWORD       dwData;
+
+    // compare MAC context to determine if this is a power lost init,
+    // return TRUE for power remaining init, return FALSE for power lost init
+
+    // compare CURR_RX_DESC_ADDR, CURR_TX_DESC_ADDR
+    VNSvInPortD(dwIoBase + MAC_REG_TXDMAPTR0, &dwData);
+    if (dwData != *(PDWORD)(pbyCxtBuf + MAC_REG_TXDMAPTR0)) {
+        return FALSE;
+    }
+
+    VNSvInPortD(dwIoBase + MAC_REG_AC0DMAPTR, &dwData);
+    if (dwData != *(PDWORD)(pbyCxtBuf + MAC_REG_AC0DMAPTR)) {
+        return FALSE;
+    }
+
+    VNSvInPortD(dwIoBase + MAC_REG_RXDMAPTR0, &dwData);
+    if (dwData != *(PDWORD)(pbyCxtBuf + MAC_REG_RXDMAPTR0)) {
+        return FALSE;
+    }
+
+    VNSvInPortD(dwIoBase + MAC_REG_RXDMAPTR1, &dwData);
+    if (dwData != *(PDWORD)(pbyCxtBuf + MAC_REG_RXDMAPTR1)) {
+        return FALSE;
+    }
+
+
+    return TRUE;
+}
+
+/*
+ * Description:
+ *      Software Reset MAC
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - Base Address for MAC
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if Reset Success; otherwise FALSE
+ *
+ */
+BOOL MACbSoftwareReset (DWORD_PTR dwIoBase)
+{
+    BYTE    byData;
+    WORD    ww;
+
+    // turn on HOSTCR_SOFTRST, just write 0x01 to reset
+    //MACvRegBitsOn(dwIoBase, MAC_REG_HOSTCR, HOSTCR_SOFTRST);
+    VNSvOutPortB(dwIoBase+ MAC_REG_HOSTCR, 0x01);
+
+    for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+        VNSvInPortB(dwIoBase + MAC_REG_HOSTCR, &byData);
+        if (BITbIsBitOff(byData, HOSTCR_SOFTRST))
+            break;
+    }
+    if (ww == W_MAX_TIMEOUT)
+        return FALSE;
+    return TRUE;
+
+}
+
+/*
+ * Description:
+ *      save some important register's value, then do reset, then restore register's value
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - Base Address for MAC
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if success; otherwise FALSE
+ *
+ */
+BOOL MACbSafeSoftwareReset (DWORD_PTR dwIoBase)
+{
+    BYTE    abyTmpRegData[MAC_MAX_CONTEXT_SIZE_PAGE0+MAC_MAX_CONTEXT_SIZE_PAGE1];
+    BOOL    bRetVal;
+
+    // PATCH....
+    // save some important register's value, then do
+    // reset, then restore register's value
+
+    // save MAC context
+    MACvSaveContext(dwIoBase, abyTmpRegData);
+    // do reset
+    bRetVal = MACbSoftwareReset(dwIoBase);
+    //BBvSoftwareReset(pDevice->PortOffset);
+    // restore MAC context, except CR0
+    MACvRestoreContext(dwIoBase, abyTmpRegData);
+
+    return bRetVal;
+}
+
+/*
+ * Description:
+ *      Trun Off MAC Rx
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - Base Address for MAC
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if success; otherwise FALSE
+ *
+ */
+BOOL MACbSafeRxOff (DWORD_PTR dwIoBase)
+{
+    WORD    ww;
+    DWORD   dwData;
+    BYTE    byData;
+
+    // turn off wow temp for turn off Rx safely
+
+    // Clear RX DMA0,1
+    VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL0, DMACTL_CLRRUN);
+    VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL1, DMACTL_CLRRUN);
+    for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+        VNSvInPortD(dwIoBase + MAC_REG_RXDMACTL0, &dwData);
+        if (BITbIsAllBitsOff(dwData, DMACTL_RUN))
+            break;
+    }
+    if (ww == W_MAX_TIMEOUT) {
+        DBG_PORT80(0x10);
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x10)\n");
+        return(FALSE);
+    }
+    for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+        VNSvInPortD(dwIoBase + MAC_REG_RXDMACTL1, &dwData);
+        if (BITbIsAllBitsOff(dwData, DMACTL_RUN))
+            break;
+    }
+    if (ww == W_MAX_TIMEOUT) {
+        DBG_PORT80(0x11);
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x11)\n");
+        return(FALSE);
+    }
+
+    // try to safe shutdown RX
+    MACvRegBitsOff(dwIoBase, MAC_REG_HOSTCR, HOSTCR_RXON);
+    // W_MAX_TIMEOUT is the timeout period
+    for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+        VNSvInPortB(dwIoBase + MAC_REG_HOSTCR, &byData);
+        if (BITbIsAllBitsOff(byData, HOSTCR_RXONST))
+            break;
+    }
+    if (ww == W_MAX_TIMEOUT) {
+        DBG_PORT80(0x12);
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x12)\n");
+        return(FALSE);
+    }
+    return TRUE;
+}
+
+/*
+ * Description:
+ *      Trun Off MAC Tx
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - Base Address for MAC
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if success; otherwise FALSE
+ *
+ */
+BOOL MACbSafeTxOff (DWORD_PTR dwIoBase)
+{
+    WORD    ww;
+    DWORD   dwData;
+    BYTE    byData;
+
+    // Clear TX DMA
+    //Tx0
+    VNSvOutPortD(dwIoBase + MAC_REG_TXDMACTL0, DMACTL_CLRRUN);
+    //AC0
+    VNSvOutPortD(dwIoBase + MAC_REG_AC0DMACTL, DMACTL_CLRRUN);
+
+
+    for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+        VNSvInPortD(dwIoBase + MAC_REG_TXDMACTL0, &dwData);
+        if (BITbIsAllBitsOff(dwData, DMACTL_RUN))
+            break;
+    }
+    if (ww == W_MAX_TIMEOUT) {
+        DBG_PORT80(0x20);
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x20)\n");
+        return(FALSE);
+    }
+    for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+        VNSvInPortD(dwIoBase + MAC_REG_AC0DMACTL, &dwData);
+        if (BITbIsAllBitsOff(dwData, DMACTL_RUN))
+            break;
+    }
+    if (ww == W_MAX_TIMEOUT) {
+        DBG_PORT80(0x21);
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x21)\n");
+        return(FALSE);
+    }
+
+    // try to safe shutdown TX
+    MACvRegBitsOff(dwIoBase, MAC_REG_HOSTCR, HOSTCR_TXON);
+
+    // W_MAX_TIMEOUT is the timeout period
+    for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+        VNSvInPortB(dwIoBase + MAC_REG_HOSTCR, &byData);
+        if (BITbIsAllBitsOff(byData, HOSTCR_TXONST))
+            break;
+    }
+    if (ww == W_MAX_TIMEOUT) {
+        DBG_PORT80(0x24);
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x24)\n");
+        return(FALSE);
+    }
+    return TRUE;
+}
+
+/*
+ * Description:
+ *      Stop MAC function
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - Base Address for MAC
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if success; otherwise FALSE
+ *
+ */
+BOOL MACbSafeStop (DWORD_PTR dwIoBase)
+{
+    MACvRegBitsOff(dwIoBase, MAC_REG_TCR, TCR_AUTOBCNTX);
+
+    if (MACbSafeRxOff(dwIoBase) == FALSE) {
+        DBG_PORT80(0xA1);
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" MACbSafeRxOff == FALSE)\n");
+        MACbSafeSoftwareReset(dwIoBase);
+        return FALSE;
+    }
+    if (MACbSafeTxOff(dwIoBase) == FALSE) {
+        DBG_PORT80(0xA2);
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" MACbSafeTxOff == FALSE)\n");
+        MACbSafeSoftwareReset(dwIoBase);
+        return FALSE;
+    }
+
+    MACvRegBitsOff(dwIoBase, MAC_REG_HOSTCR, HOSTCR_MACEN);
+
+    return TRUE;
+}
+
+/*
+ * Description:
+ *      Shut Down MAC
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - Base Address for MAC
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if success; otherwise FALSE
+ *
+ */
+BOOL MACbShutdown (DWORD_PTR dwIoBase)
+{
+    // disable MAC IMR
+    MACvIntDisable(dwIoBase);
+    MACvSetLoopbackMode(dwIoBase, MAC_LB_INTERNAL);
+    // stop the adapter
+    if (!MACbSafeStop(dwIoBase)) {
+        MACvSetLoopbackMode(dwIoBase, MAC_LB_NONE);
+        return FALSE;
+    }
+    MACvSetLoopbackMode(dwIoBase, MAC_LB_NONE);
+    return TRUE;
+}
+
+/*
+ * Description:
+ *      Initialize MAC
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - Base Address for MAC
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void MACvInitialize (DWORD_PTR dwIoBase)
+{
+    // clear sticky bits
+    MACvClearStckDS(dwIoBase);
+    // disable force PME-enable
+    VNSvOutPortB(dwIoBase + MAC_REG_PMC1, PME_OVR);
+    // only 3253 A
+    /*
+    MACvPwrEvntDisable(dwIoBase);
+    // clear power status
+    VNSvOutPortW(dwIoBase + MAC_REG_WAKEUPSR0, 0x0F0F);
+    */
+
+    // do reset
+    MACbSoftwareReset(dwIoBase);
+
+    // issue AUTOLD in EECSR to reload eeprom
+    //MACvRegBitsOn(dwIoBase, MAC_REG_I2MCSR, I2MCSR_AUTOLD);
+    // wait until EEPROM loading complete
+    //while (TRUE) {
+    //    U8 u8Data;
+    //    VNSvInPortB(dwIoBase + MAC_REG_I2MCSR, &u8Data);
+    //    if (BITbIsBitOff(u8Data, I2MCSR_AUTOLD))
+    //        break;
+    //}
+
+    // reset TSF counter
+    VNSvOutPortB(dwIoBase + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);
+    // enable TSF counter
+    VNSvOutPortB(dwIoBase + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
+
+
+    // set packet filter
+    // receive directed and broadcast address
+
+    MACvSetPacketFilter(dwIoBase, PKT_TYPE_DIRECTED | PKT_TYPE_BROADCAST);
+
+}
+
+/*
+ * Description:
+ *      Set the chip with current rx descriptor address
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase        - Base Address for MAC
+ *      dwCurrDescAddr  - Descriptor Address
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void MACvSetCurrRx0DescAddr (DWORD_PTR dwIoBase, DWORD dwCurrDescAddr)
+{
+WORD    ww;
+BYTE    byData;
+BYTE    byOrgDMACtl;
+
+    VNSvInPortB(dwIoBase + MAC_REG_RXDMACTL0, &byOrgDMACtl);
+    if (BITbIsAllBitsOn(byOrgDMACtl, DMACTL_RUN)) {
+        VNSvOutPortB(dwIoBase + MAC_REG_RXDMACTL0+2, DMACTL_RUN);
+    }
+    for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+        VNSvInPortB(dwIoBase + MAC_REG_RXDMACTL0, &byData);
+        if (BITbIsAllBitsOff(byData, DMACTL_RUN))
+            break;
+    }
+    if (ww == W_MAX_TIMEOUT) {
+        DBG_PORT80(0x13);
+    }
+    VNSvOutPortD(dwIoBase + MAC_REG_RXDMAPTR0, dwCurrDescAddr);
+    if (BITbIsAllBitsOn(byOrgDMACtl, DMACTL_RUN)) {
+        VNSvOutPortB(dwIoBase + MAC_REG_RXDMACTL0, DMACTL_RUN);
+    }
+}
+
+/*
+ * Description:
+ *      Set the chip with current rx descriptor address
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase        - Base Address for MAC
+ *      dwCurrDescAddr  - Descriptor Address
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void MACvSetCurrRx1DescAddr (DWORD_PTR dwIoBase, DWORD dwCurrDescAddr)
+{
+WORD    ww;
+BYTE    byData;
+BYTE    byOrgDMACtl;
+
+    VNSvInPortB(dwIoBase + MAC_REG_RXDMACTL1, &byOrgDMACtl);
+    if (BITbIsAllBitsOn(byOrgDMACtl, DMACTL_RUN)) {
+        VNSvOutPortB(dwIoBase + MAC_REG_RXDMACTL1+2, DMACTL_RUN);
+    }
+    for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+        VNSvInPortB(dwIoBase + MAC_REG_RXDMACTL1, &byData);
+        if (BITbIsAllBitsOff(byData, DMACTL_RUN))
+            break;
+    }
+    if (ww == W_MAX_TIMEOUT) {
+        DBG_PORT80(0x14);
+    }
+    VNSvOutPortD(dwIoBase + MAC_REG_RXDMAPTR1, dwCurrDescAddr);
+    if (BITbIsAllBitsOn(byOrgDMACtl, DMACTL_RUN)) {
+        VNSvOutPortB(dwIoBase + MAC_REG_RXDMACTL1, DMACTL_RUN);
+    }
+}
+
+/*
+ * Description:
+ *      Set the chip with current tx0 descriptor address
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase        - Base Address for MAC
+ *      dwCurrDescAddr  - Descriptor Address
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void MACvSetCurrTx0DescAddrEx (DWORD_PTR dwIoBase, DWORD dwCurrDescAddr)
+{
+WORD    ww;
+BYTE    byData;
+BYTE    byOrgDMACtl;
+
+    VNSvInPortB(dwIoBase + MAC_REG_TXDMACTL0, &byOrgDMACtl);
+    if (BITbIsAllBitsOn(byOrgDMACtl, DMACTL_RUN)) {
+        VNSvOutPortB(dwIoBase + MAC_REG_TXDMACTL0+2, DMACTL_RUN);
+    }
+    for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+        VNSvInPortB(dwIoBase + MAC_REG_TXDMACTL0, &byData);
+        if (BITbIsAllBitsOff(byData, DMACTL_RUN))
+            break;
+    }
+    if (ww == W_MAX_TIMEOUT) {
+        DBG_PORT80(0x25);
+    }
+    VNSvOutPortD(dwIoBase + MAC_REG_TXDMAPTR0, dwCurrDescAddr);
+    if (BITbIsAllBitsOn(byOrgDMACtl, DMACTL_RUN)) {
+        VNSvOutPortB(dwIoBase + MAC_REG_TXDMACTL0, DMACTL_RUN);
+    }
+}
+
+/*
+ * Description:
+ *      Set the chip with current AC0 descriptor address
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase        - Base Address for MAC
+ *      dwCurrDescAddr  - Descriptor Address
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+ //TxDMA1 = AC0DMA
+void MACvSetCurrAC0DescAddrEx (DWORD_PTR dwIoBase, DWORD dwCurrDescAddr)
+{
+WORD    ww;
+BYTE    byData;
+BYTE    byOrgDMACtl;
+
+    VNSvInPortB(dwIoBase + MAC_REG_AC0DMACTL, &byOrgDMACtl);
+    if (BITbIsAllBitsOn(byOrgDMACtl, DMACTL_RUN)) {
+        VNSvOutPortB(dwIoBase + MAC_REG_AC0DMACTL+2, DMACTL_RUN);
+    }
+    for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+        VNSvInPortB(dwIoBase + MAC_REG_AC0DMACTL, &byData);
+        if (BITbIsAllBitsOff(byData, DMACTL_RUN))
+            break;
+    }
+    if (ww == W_MAX_TIMEOUT) {
+        DBG_PORT80(0x26);
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x26)\n");
+    }
+    VNSvOutPortD(dwIoBase + MAC_REG_AC0DMAPTR, dwCurrDescAddr);
+    if (BITbIsAllBitsOn(byOrgDMACtl, DMACTL_RUN)) {
+        VNSvOutPortB(dwIoBase + MAC_REG_AC0DMACTL, DMACTL_RUN);
+    }
+}
+
+
+
+void MACvSetCurrTXDescAddr (int iTxType, DWORD_PTR dwIoBase, DWORD dwCurrDescAddr)
+{
+    if(iTxType == TYPE_AC0DMA){
+        MACvSetCurrAC0DescAddrEx(dwIoBase, dwCurrDescAddr);
+    }else if(iTxType == TYPE_TXDMA0){
+        MACvSetCurrTx0DescAddrEx(dwIoBase, dwCurrDescAddr);
+    }
+}
+
+/*
+ * Description:
+ *      Micro Second Delay via MAC
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - Base Address for MAC
+ *      uDelay      - Delay time (timer resolution is 4 us)
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+VOID MACvTimer0MicroSDelay (DWORD_PTR dwIoBase, UINT uDelay)
+{
+BYTE byValue;
+UINT uu,ii;
+
+    VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, 0);
+    VNSvOutPortD(dwIoBase + MAC_REG_TMDATA0, uDelay);
+    VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, (TMCTL_TMD | TMCTL_TE));
+    for(ii=0;ii<66;ii++) {  // assume max PCI clock is 66Mhz
+        for (uu = 0; uu < uDelay; uu++) {
+            VNSvInPortB(dwIoBase + MAC_REG_TMCTL0, &byValue);
+            if ((byValue == 0) ||
+                (BITbIsAllBitsOn(byValue, TMCTL_TSUSP))) {
+                VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, 0);
+                return;
+            }
+        }
+    }
+    VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, 0);
+
+}
+
+/*
+ * Description:
+ *      Micro Second One shot timer via MAC
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - Base Address for MAC
+ *      uDelay      - Delay time
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void MACvOneShotTimer0MicroSec (DWORD_PTR dwIoBase, UINT uDelayTime)
+{
+    VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, 0);
+    VNSvOutPortD(dwIoBase + MAC_REG_TMDATA0, uDelayTime);
+    VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, (TMCTL_TMD | TMCTL_TE));
+}
+
+/*
+ * Description:
+ *      Micro Second One shot timer via MAC
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - Base Address for MAC
+ *      uDelay      - Delay time
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void MACvOneShotTimer1MicroSec (DWORD_PTR dwIoBase, UINT uDelayTime)
+{
+    VNSvOutPortB(dwIoBase + MAC_REG_TMCTL1, 0);
+    VNSvOutPortD(dwIoBase + MAC_REG_TMDATA1, uDelayTime);
+    VNSvOutPortB(dwIoBase + MAC_REG_TMCTL1, (TMCTL_TMD | TMCTL_TE));
+}
+
+
+void MACvSetMISCFifo (DWORD_PTR dwIoBase, WORD wOffset, DWORD dwData)
+{
+    if (wOffset > 273)
+        return;
+    VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
+    VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
+    VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
+}
+
+
+BOOL MACbTxDMAOff (DWORD_PTR dwIoBase, UINT idx)
+{
+BYTE byData;
+UINT ww = 0;
+
+    if (idx == TYPE_TXDMA0) {
+        VNSvOutPortB(dwIoBase + MAC_REG_TXDMACTL0+2, DMACTL_RUN);
+        for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+            VNSvInPortB(dwIoBase + MAC_REG_TXDMACTL0, &byData);
+            if (BITbIsAllBitsOff(byData, DMACTL_RUN))
+                break;
+        }
+    } else if (idx == TYPE_AC0DMA) {
+        VNSvOutPortB(dwIoBase + MAC_REG_AC0DMACTL+2, DMACTL_RUN);
+        for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+            VNSvInPortB(dwIoBase + MAC_REG_AC0DMACTL, &byData);
+            if (BITbIsAllBitsOff(byData, DMACTL_RUN))
+                break;
+        }
+    }
+    if (ww == W_MAX_TIMEOUT) {
+        DBG_PORT80(0x29);
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x29)\n");
+        return FALSE;
+    }
+    return TRUE;
+}
+
+void MACvClearBusSusInd (DWORD_PTR dwIoBase)
+{
+    DWORD dwOrgValue;
+    UINT ww;
+    // check if BcnSusInd enabled
+    VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue);
+    if(BITbIsBitOff(dwOrgValue, EnCFG_BcnSusInd))
+        return;
+    //Set BcnSusClr
+    dwOrgValue = dwOrgValue | EnCFG_BcnSusClr;
+    VNSvOutPortD(dwIoBase + MAC_REG_ENCFG, dwOrgValue);
+    for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+        VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue);
+        if(BITbIsBitOff(dwOrgValue, EnCFG_BcnSusInd))
+            break;
+    }
+    if (ww == W_MAX_TIMEOUT) {
+        DBG_PORT80(0x33);
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x33)\n");
+    }
+}
+
+void MACvEnableBusSusEn (DWORD_PTR dwIoBase)
+{
+    BYTE  byOrgValue;
+    DWORD dwOrgValue;
+    UINT ww;
+    // check if BcnSusInd enabled
+    VNSvInPortB(dwIoBase + MAC_REG_CFG , &byOrgValue);
+
+    //Set BcnSusEn
+    byOrgValue = byOrgValue | CFG_BCNSUSEN;
+    VNSvOutPortB(dwIoBase + MAC_REG_ENCFG, byOrgValue);
+    for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+        VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue);
+        if(BITbIsBitOn(dwOrgValue, EnCFG_BcnSusInd))
+            break;
+    }
+    if (ww == W_MAX_TIMEOUT) {
+        DBG_PORT80(0x34);
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x34)\n");
+    }
+}
+
+BOOL MACbFlushSYNCFifo (DWORD_PTR dwIoBase)
+{
+    BYTE  byOrgValue;
+    UINT ww;
+    // Read MACCR
+    VNSvInPortB(dwIoBase + MAC_REG_MACCR , &byOrgValue);
+
+    // Set SYNCFLUSH
+    byOrgValue = byOrgValue | MACCR_SYNCFLUSH;
+    VNSvOutPortB(dwIoBase + MAC_REG_MACCR, byOrgValue);
+
+    // Check if SyncFlushOK
+    for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+        VNSvInPortB(dwIoBase + MAC_REG_MACCR , &byOrgValue);
+        if(BITbIsBitOn(byOrgValue, MACCR_SYNCFLUSHOK))
+            break;
+    }
+    if (ww == W_MAX_TIMEOUT) {
+        DBG_PORT80(0x35);
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x33)\n");
+    }
+    return TRUE;
+}
+
+BOOL MACbPSWakeup (DWORD_PTR dwIoBase)
+{
+    BYTE  byOrgValue;
+    UINT ww;
+    // Read PSCTL
+    if (MACbIsRegBitsOff(dwIoBase, MAC_REG_PSCTL, PSCTL_PS)) {
+        return TRUE;
+    }
+    // Disable PS
+    MACvRegBitsOff(dwIoBase, MAC_REG_PSCTL, PSCTL_PSEN);
+
+    // Check if SyncFlushOK
+    for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+        VNSvInPortB(dwIoBase + MAC_REG_PSCTL , &byOrgValue);
+        if(BITbIsBitOn(byOrgValue, PSCTL_WAKEDONE))
+            break;
+    }
+    if (ww == W_MAX_TIMEOUT) {
+        DBG_PORT80(0x36);
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x33)\n");
+        return FALSE;
+    }
+    return TRUE;
+}
+
+/*
+ * Description:
+ *      Set the Key by MISCFIFO
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase        - Base Address for MAC
+ *
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+
+void MACvSetKeyEntry (DWORD_PTR dwIoBase, WORD wKeyCtl, UINT uEntryIdx, UINT uKeyIdx, PBYTE pbyAddr, PDWORD pdwKey, BYTE byLocalID)
+{
+WORD    wOffset;
+DWORD   dwData;
+int     ii;
+
+    if (byLocalID <= 1)
+        return;
+
+
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MACvSetKeyEntry\n");
+    wOffset = MISCFIFO_KEYETRY0;
+    wOffset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE);
+
+    dwData = 0;
+    dwData |= wKeyCtl;
+    dwData <<= 16;
+    dwData |= MAKEWORD(*(pbyAddr+4), *(pbyAddr+5));
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"1. wOffset: %d, Data: %lX, KeyCtl:%X\n", wOffset, dwData, wKeyCtl);
+
+    VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
+    VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
+    VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
+    wOffset++;
+
+    dwData = 0;
+    dwData |= *(pbyAddr+3);
+    dwData <<= 8;
+    dwData |= *(pbyAddr+2);
+    dwData <<= 8;
+    dwData |= *(pbyAddr+1);
+    dwData <<= 8;
+    dwData |= *(pbyAddr+0);
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"2. wOffset: %d, Data: %lX\n", wOffset, dwData);
+
+    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
+        DEVICE_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);
+    }
+}
+
+
+
+/*
+ * Description:
+ *      Disable the Key Entry by MISCFIFO
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase        - Base Address for MAC
+ *
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void MACvDisableKeyEntry (DWORD_PTR dwIoBase, UINT uEntryIdx)
+{
+WORD    wOffset;
+
+    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);
+}
+
+
+/*
+ * Description:
+ *      Set the default Key (KeyEntry[10]) by MISCFIFO
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase        - Base Address for MAC
+ *
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+
+void MACvSetDefaultKeyEntry (DWORD_PTR dwIoBase, UINT uKeyLen, UINT uKeyIdx, PDWORD pdwKey, BYTE byLocalID)
+{
+WORD    wOffset;
+DWORD   dwData;
+int     ii;
+
+    if (byLocalID <= 1)
+        return;
+
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MACvSetDefaultKeyEntry\n");
+    wOffset = MISCFIFO_KEYETRY0;
+    wOffset += (10 * MISCFIFO_KEYENTRYSIZE);
+
+    wOffset++;
+    wOffset++;
+    wOffset += (uKeyIdx * 4);
+    // alway push 128 bits
+    for (ii=0; ii<3; ii++) {
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"(%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);
+    }
+    dwData = *pdwKey;
+    if (uKeyLen == WLAN_WEP104_KEYLEN) {
+        dwData |= 0x80000000;
+    }
+    VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset+3);
+    VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
+    VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"End. wOffset: %d, Data: %lX\n", wOffset+3, dwData);
+
+}
+
+
+/*
+ * Description:
+ *      Enable default Key (KeyEntry[10]) by MISCFIFO
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase        - Base Address for MAC
+ *
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+/*
+void MACvEnableDefaultKey (DWORD_PTR dwIoBase, BYTE byLocalID)
+{
+WORD    wOffset;
+DWORD   dwData;
+
+
+    if (byLocalID <= 1)
+        return;
+
+    wOffset = MISCFIFO_KEYETRY0;
+    wOffset += (10 * MISCFIFO_KEYENTRYSIZE);
+
+    dwData = 0xC0440000;
+    VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
+    VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
+    VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MACvEnableDefaultKey: wOffset: %d, Data: %lX\n", wOffset, dwData);
+
+}
+*/
+
+/*
+ * Description:
+ *      Disable default Key (KeyEntry[10]) by MISCFIFO
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase        - Base Address for MAC
+ *
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void MACvDisableDefaultKey (DWORD_PTR dwIoBase)
+{
+WORD    wOffset;
+DWORD   dwData;
+
+
+    wOffset = MISCFIFO_KEYETRY0;
+    wOffset += (10 * MISCFIFO_KEYENTRYSIZE);
+
+    dwData = 0x0;
+    VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
+    VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
+    VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MACvDisableDefaultKey: wOffset: %d, Data: %lX\n", wOffset, dwData);
+}
+
+/*
+ * Description:
+ *      Set the default TKIP Group Key (KeyEntry[10]) by MISCFIFO
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase        - Base Address for MAC
+ *
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void MACvSetDefaultTKIPKeyEntry (DWORD_PTR dwIoBase, UINT uKeyLen, UINT uKeyIdx, PDWORD pdwKey, BYTE byLocalID)
+{
+WORD    wOffset;
+DWORD   dwData;
+int     ii;
+
+    if (byLocalID <= 1)
+        return;
+
+
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MACvSetDefaultTKIPKeyEntry\n");
+    wOffset = MISCFIFO_KEYETRY0;
+    // Kyle test : change offset from 10 -> 0
+    wOffset += (10 * MISCFIFO_KEYENTRYSIZE);
+
+    dwData = 0xC0660000;
+    VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
+    VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
+    VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
+    wOffset++;
+
+    dwData = 0;
+    VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
+    VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
+    VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
+    wOffset++;
+
+    wOffset += (uKeyIdx * 4);
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"1. wOffset: %d, Data: %lX, idx:%d\n", wOffset, *pdwKey, uKeyIdx);
+    // alway push 128 bits
+    for (ii=0; ii<4; ii++) {
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"2.(%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);
+    }
+
+}
+
+
+
+/*
+ * Description:
+ *      Set the Key Control by MISCFIFO
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase        - Base Address for MAC
+ *
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+
+void MACvSetDefaultKeyCtl (DWORD_PTR dwIoBase, WORD wKeyCtl, UINT uEntryIdx, BYTE byLocalID)
+{
+WORD    wOffset;
+DWORD   dwData;
+
+    if (byLocalID <= 1)
+        return;
+
+
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MACvSetKeyEntry\n");
+    wOffset = MISCFIFO_KEYETRY0;
+    wOffset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE);
+
+    dwData = 0;
+    dwData |= wKeyCtl;
+    dwData <<= 16;
+    dwData |= 0xffff;
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"1. wOffset: %d, Data: %lX, KeyCtl:%X\n", wOffset, dwData, wKeyCtl);
+
+    VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
+    VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
+    VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
+
+}
+
diff --git a/drivers/staging/vt6655/mac.h b/drivers/staging/vt6655/mac.h
new file mode 100644 (file)
index 0000000..edb7096
--- /dev/null
@@ -0,0 +1,1166 @@
+/*
+ * 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(__TMACRO_H__)
+#include "tmacro.h"
+#endif
+#if !defined(__UPC_H__)
+#include "upc.h"
+#endif
+
+/*---------------------  Export Definitions -------------------------*/
+//
+// Registers in the MAC
+//
+#define MAC_MAX_CONTEXT_SIZE_PAGE0  256
+#define MAC_MAX_CONTEXT_SIZE_PAGE1  128
+#define MAC_MAX_CONTEXT_SIZE        MAC_MAX_CONTEXT_SIZE_PAGE0 + MAC_MAX_CONTEXT_SIZE_PAGE1
+
+// Registers not related to 802.11b
+#define MAC_REG_BCFG0       0x00
+#define MAC_REG_BCFG1       0x01
+#define MAC_REG_FCR0        0x02
+#define MAC_REG_FCR1        0x03
+#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_PMC0        0x10
+#define MAC_REG_PMC1        0x11
+#define MAC_REG_STICKHW     0x12
+#define MAC_REG_LOCALID     0x14
+#define MAC_REG_TESTCFG     0x15
+#define MAC_REG_JUMPER0     0x16
+#define MAC_REG_JUMPER1     0x17
+#define MAC_REG_TMCTL0      0x18
+#define MAC_REG_TMCTL1      0x19
+#define MAC_REG_TMDATA0     0x1C
+// 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_MIBCNTR     0x2C
+#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_ENCFG       0x4C        //
+#define MAC_REG_PAGE1SEL    0x4F        //
+#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
+// 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_GPIOCTL0    0x7A        //
+#define MAC_REG_GPIOCTL1    0x7B        //
+
+// MAC DMA Related Group
+#define MAC_REG_TXDMACTL0   0x7C        //
+#define MAC_REG_TXDMAPTR0   0x80        //
+#define MAC_REG_AC0DMACTL   0x84        //
+#define MAC_REG_AC0DMAPTR   0x88        //
+#define MAC_REG_BCNDMACTL   0x8C        //
+#define MAC_REG_BCNDMAPTR   0x90        //
+#define MAC_REG_RXDMACTL0   0x94        //
+#define MAC_REG_RXDMAPTR0   0x98        //
+#define MAC_REG_RXDMACTL1   0x9C        //
+#define MAC_REG_RXDMAPTR1   0xA0        //
+#define MAC_REG_SYNCDMACTL  0xA4        //
+#define MAC_REG_SYNCDMAPTR  0xA8
+#define MAC_REG_ATIMDMACTL  0xAC
+#define MAC_REG_ATIMDMAPTR  0xB0
+// MiscFF PIO related
+#define MAC_REG_MISCFFNDEX  0xB4
+#define MAC_REG_MISCFFCTL   0xB6
+#define MAC_REG_MISCFFDATA  0xB8
+// Extend SW Timer
+#define MAC_REG_TMDATA1     0xBC
+// WOW Related Group
+#define MAC_REG_WAKEUPEN0   0xC0
+#define MAC_REG_WAKEUPEN1   0xC1
+#define MAC_REG_WAKEUPSR0   0xC2
+#define MAC_REG_WAKEUPSR1   0xC3
+#define MAC_REG_WAKE128_0   0xC4
+#define MAC_REG_WAKE128_1   0xD4
+#define MAC_REG_WAKE128_2   0xE4
+#define MAC_REG_WAKE128_3   0xF4
+
+/////////////// Page 1 ///////////////////
+#define MAC_REG_CRC_128_0   0x04
+#define MAC_REG_CRC_128_1   0x06
+#define MAC_REG_CRC_128_2   0x08
+#define MAC_REG_CRC_128_3   0x0A
+// MAC Configuration Group
+#define MAC_REG_PAR0        0x0C
+#define MAC_REG_PAR4        0x10
+#define MAC_REG_BSSID0      0x14
+#define MAC_REG_BSSID4      0x18
+#define MAC_REG_MAR0        0x1C
+#define MAC_REG_MAR4        0x20
+// MAC RSPPKT INFO Group
+#define MAC_REG_RSPINF_B_1  0x24
+#define MAC_REG_RSPINF_B_2  0x28
+#define MAC_REG_RSPINF_B_5  0x2C
+#define MAC_REG_RSPINF_B_11 0x30
+#define MAC_REG_RSPINF_A_6  0x34
+#define MAC_REG_RSPINF_A_9  0x36
+#define MAC_REG_RSPINF_A_12 0x38
+#define MAC_REG_RSPINF_A_18 0x3A
+#define MAC_REG_RSPINF_A_24 0x3C
+#define MAC_REG_RSPINF_A_36 0x3E
+#define MAC_REG_RSPINF_A_48 0x40
+#define MAC_REG_RSPINF_A_54 0x42
+#define MAC_REG_RSPINF_A_72 0x44
+
+// 802.11h relative
+#define MAC_REG_QUIETINIT   0x60
+#define MAC_REG_QUIETGAP    0x62
+#define MAC_REG_QUIETDUR    0x64
+#define MAC_REG_MSRCTL      0x66
+#define MAC_REG_MSRBBSTS    0x67
+#define MAC_REG_MSRSTART    0x68
+#define MAC_REG_MSRDURATION 0x70
+#define MAC_REG_CCAFRACTION 0x72
+#define MAC_REG_PWRCCK      0x73
+#define MAC_REG_PWROFDM     0x7C
+
+
+//
+// Bits in the BCFG0 register
+//
+#define BCFG0_PERROFF       0x40
+#define BCFG0_MRDMDIS       0x20
+#define BCFG0_MRDLDIS       0x10
+#define BCFG0_MWMEN         0x08
+#define BCFG0_VSERREN       0x02
+#define BCFG0_LATMEN        0x01
+
+//
+// Bits in the BCFG1 register
+//
+#define BCFG1_CFUNOPT       0x80
+#define BCFG1_CREQOPT       0x40
+#define BCFG1_DMA8          0x10
+#define BCFG1_ARBITOPT      0x08
+#define BCFG1_PCIMEN        0x04
+#define BCFG1_MIOEN         0x02
+#define BCFG1_CISDLYEN      0x01
+
+// Bits in RAMBIST registers
+#define BISTCMD_TSTPAT5     0x00        //
+#define BISTCMD_TSTPATA     0x80        //
+#define BISTCMD_TSTERR      0x20        //
+#define BISTCMD_TSTPATF     0x18        //
+#define BISTCMD_TSTPAT0     0x10        //
+#define BISTCMD_TSTMODE     0x04        //
+#define BISTCMD_TSTITTX     0x03        //
+#define BISTCMD_TSTATRX     0x02        //
+#define BISTCMD_TSTATTX     0x01        //
+#define BISTCMD_TSTRX       0x00        //
+#define BISTSR0_BISTGO      0x01        //
+#define BISTSR1_TSTSR       0x01        //
+#define BISTSR2_CMDPRTEN    0x02        //
+#define BISTSR2_RAMTSTEN    0x01        //
+
+//
+// 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 PMC1 register
+//
+#define SPS_RST             0x80
+#define PCISTIKY            0x40
+#define PME_OVR             0x02
+
+//
+// Bits in the STICKYHW register
+//
+#define STICKHW_DS1_SHADOW  0x02
+#define STICKHW_DS0_SHADOW  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 register
+//
+#define EnCFG_BarkerPream   0x00020000
+#define EnCFG_NXTBTTCFPSTR  0x00010000
+//#define EnCFG_TXLMT3UPDATE  0x00008000
+//#define EnCFG_TXLMT2UPDATE  0x00004000
+//#define EnCFG_TXLMT1UPDATE  0x00002000
+//#define EnCFG_TXLMT3EN      0x00001000
+//#define EnCFG_TXLMT2EN      0x00000800
+//#define EnCFG_TXLMT1EN      0x00000400
+#define EnCFG_BcnSusClr     0x00000200
+#define EnCFG_BcnSusInd     0x00000100
+//#define EnCFG_CWOFF1        0x00000080
+#define EnCFG_CFP_ProtectEn 0x00000040
+#define EnCFG_ProtectMd     0x00000020
+#define EnCFG_HwParCFP      0x00000010
+//#define EnCFG_QOS           0x00000008
+#define EnCFG_CFNULRSP      0x00000004
+#define EnCFG_BBType_MASK   0x00000003
+#define EnCFG_BBType_g      0x00000002
+#define EnCFG_BBType_b      0x00000001
+#define EnCFG_BBType_a      0x00000000
+
+//
+// Bits in the Page1Sel register
+//
+#define PAGE1_SEL           0x01
+
+//
+// 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 MAC_REG_GPIOCTL0 register
+//
+#define LED_ACTSET           0x01        //
+#define LED_RFOFF            0x02        //
+#define LED_NOCONNECT        0x04        //
+//
+// 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
+
+//
+// Bits in the IMR register
+//
+#define IMR_MEASURESTART    0x80000000      //
+#define IMR_QUIETSTART      0x20000000      //
+#define IMR_RADARDETECT     0x10000000      //
+#define IMR_MEASUREEND      0x08000000      //
+#define IMR_SOFTTIMER1      0x00200000      //
+//#define IMR_SYNCFLUSHOK     0x00100000      //
+//#define IMR_ATIMEND         0x00080000      //0000 1000 0000 0000 0000 0000
+//#define IMR_CFPEND          0x00040000      //0000 0100 0000 0000 0000 0000
+//#define IMR_AC3DMA          0x00020000      //0000 0010 0000 0000 0000 0000
+//#define IMR_AC2DMA          0x00010000      //0000 0001 0000 0000 0000 0000
+//#define IMR_AC1DMA          0x00008000      //0000 0000 1000 0000 0000 0000
+//#define IMR_SYNCTX          0x00004000      //0000 0000 0100 0000 0000 0000
+//#define IMR_ATIMTX          0x00002000      //0000 0000 0010 0000 0000 0000
+#define IMR_RXDMA1          0x00001000      //0000 0000 0001 0000 0000 0000
+#define IMR_RXNOBUF         0x00000800      //
+#define IMR_MIBNEARFULL     0x00000400      //
+#define IMR_SOFTINT         0x00000200      //
+#define IMR_FETALERR        0x00000100      //
+#define IMR_WATCHDOG        0x00000080      //
+#define IMR_SOFTTIMER       0x00000040      //
+#define IMR_GPIO            0x00000020      //
+#define IMR_TBTT            0x00000010      //
+#define IMR_RXDMA0          0x00000008      //
+#define IMR_BNTX            0x00000004      //
+#define IMR_AC0DMA          0x00000002      //
+#define IMR_TXDMA0          0x00000001      //
+
+
+//
+// Bits in the ISR register
+//
+
+#define ISR_MEASURESTART    0x80000000      //
+#define ISR_QUIETSTART      0x20000000      //
+#define ISR_RADARDETECT     0x10000000      //
+#define ISR_MEASUREEND      0x08000000      //
+#define ISR_SOFTTIMER1      0x00200000      //
+//#define ISR_SYNCFLUSHOK     0x00100000      //0001 0000 0000 0000 0000 0000
+//#define ISR_ATIMEND         0x00080000      //0000 1000 0000 0000 0000 0000
+//#define ISR_CFPEND          0x00040000      //0000 0100 0000 0000 0000 0000
+//#define ISR_AC3DMA          0x00020000      //0000 0010 0000 0000 0000 0000
+//#define ISR_AC2DMA          0x00010000      //0000 0001 0000 0000 0000 0000
+//#define ISR_AC1DMA          0x00008000      //0000 0000 1000 0000 0000 0000
+//#define ISR_SYNCTX          0x00004000      //0000 0000 0100 0000 0000 0000
+//#define ISR_ATIMTX          0x00002000      //0000 0000 0010 0000 0000 0000
+#define ISR_RXDMA1          0x00001000      //0000 0000 0001 0000 0000 0000
+#define ISR_RXNOBUF         0x00000800      //0000 0000 0000 1000 0000 0000
+#define ISR_MIBNEARFULL     0x00000400      //0000 0000 0000 0100 0000 0000
+#define ISR_SOFTINT         0x00000200      //
+#define ISR_FETALERR        0x00000100      //
+#define ISR_WATCHDOG        0x00000080      //
+#define ISR_SOFTTIMER       0x00000040      //
+#define ISR_GPIO            0x00000020      //
+#define ISR_TBTT            0x00000010      //
+#define ISR_RXDMA0          0x00000008      //
+#define ISR_BNTX            0x00000004      //
+#define ISR_AC0DMA          0x00000002      //
+#define ISR_TXDMA0          0x00000001      //
+
+
+//
+// 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      0x0800  //
+#define SOFTPWRCTL_TXPEINV      0x0200  //
+#define SOFTPWRCTL_SWPECTI      0x0100  //
+#define SOFTPWRCTL_SWPAPE       0x0020  //
+#define SOFTPWRCTL_SWCALEN      0x0010  //
+#define SOFTPWRCTL_SWRADIO_PE   0x0008  //
+#define SOFTPWRCTL_SWPE2        0x0004  //
+#define SOFTPWRCTL_SWPE1        0x0002  //
+#define SOFTPWRCTL_SWPE3        0x0001  //
+
+//
+// Bits in the GPIOCTL1 register
+//
+#define GPIO1_DATA1             0x20    //
+#define GPIO1_MD1               0x10    //
+#define GPIO1_DATA0             0x02    //
+#define GPIO1_MD0               0x01    //
+
+//
+// Bits in the DMACTL register
+//
+#define DMACTL_CLRRUN       0x00080000  //
+#define DMACTL_RUN          0x00000008  //
+#define DMACTL_WAKE         0x00000004  //
+#define DMACTL_DEAD         0x00000002  //
+#define DMACTL_ACTIVE       0x00000001  //
+//
+// Bits in the RXDMACTL0 register
+//
+#define RX_PERPKT           0x00000100  //
+#define RX_PERPKTCLR        0x01000000  //
+//
+// Bits in the BCNDMACTL register
+//
+#define BEACON_READY        0x01        //
+//
+// Bits in the MISCFFCTL register
+//
+#define MISCFFCTL_WRITE     0x0001      //
+
+
+//
+// Bits in WAKEUPEN0
+//
+#define WAKEUPEN0_DIRPKT    0x10
+#define WAKEUPEN0_LINKOFF   0x08
+#define WAKEUPEN0_ATIMEN    0x04
+#define WAKEUPEN0_TIMEN     0x02
+#define WAKEUPEN0_MAGICEN   0x01
+
+//
+// Bits in WAKEUPEN1
+//
+#define WAKEUPEN1_128_3     0x08
+#define WAKEUPEN1_128_2     0x04
+#define WAKEUPEN1_128_1     0x02
+#define WAKEUPEN1_128_0     0x01
+
+//
+// Bits in WAKEUPSR0
+//
+#define WAKEUPSR0_DIRPKT    0x10
+#define WAKEUPSR0_LINKOFF   0x08
+#define WAKEUPSR0_ATIMEN    0x04
+#define WAKEUPSR0_TIMEN     0x02
+#define WAKEUPSR0_MAGICEN   0x01
+
+//
+// Bits in WAKEUPSR1
+//
+#define WAKEUPSR1_128_3     0x08
+#define WAKEUPSR1_128_2     0x04
+#define WAKEUPSR1_128_1     0x02
+#define WAKEUPSR1_128_0     0x01
+
+//
+// Bits in the MAC_REG_GPIOCTL register
+//
+#define GPIO0_MD            0x01        //
+#define GPIO0_DATA          0x02        //
+#define GPIO0_INTMD         0x04        //
+#define GPIO1_MD            0x10        //
+#define GPIO1_DATA          0x20        //
+
+
+//
+// Bits in the MSRCTL register
+//
+#define MSRCTL_FINISH       0x80
+#define MSRCTL_READY        0x40
+#define MSRCTL_RADARDETECT  0x20
+#define MSRCTL_EN           0x10
+#define MSRCTL_QUIETTXCHK   0x08
+#define MSRCTL_QUIETRPT     0x04
+#define MSRCTL_QUIETINT     0x02
+#define MSRCTL_QUIETEN      0x01
+//
+// Bits in the MSRCTL1 register
+//
+#define MSRCTL1_TXPWR       0x08
+#define MSRCTL1_CSAPAREN    0x04
+#define MSRCTL1_TXPAUSE     0x01
+
+
+// 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
+#define MISCFIFO_SYNINFO_IDX    10
+#define MISCFIFO_SYNDATA_IDX    11
+#define MISCFIFO_SYNDATASIZE    21
+
+// enabled mask value of irq
+#define IMR_MASK_VALUE     (IMR_SOFTTIMER1 | \
+                            IMR_RXDMA1 | \
+                            IMR_RXNOBUF | \
+                            IMR_MIBNEARFULL | \
+                            IMR_SOFTINT | \
+                            IMR_FETALERR | \
+                            IMR_WATCHDOG | \
+                            IMR_SOFTTIMER | \
+                            IMR_GPIO | \
+                            IMR_TBTT | \
+                            IMR_RXDMA0 | \
+                            IMR_BNTX | \
+                            IMR_AC0DMA | \
+                            IMR_TXDMA0)
+
+// max time out delay time
+#define W_MAX_TIMEOUT       0xFFF0U     //
+
+// wait time within loop
+#define CB_DELAY_LOOP_WAIT  10          // 10ms
+
+//
+// revision id
+//
+#define REV_ID_VT3253_A0    0x00
+#define REV_ID_VT3253_A1    0x01
+#define REV_ID_VT3253_B0    0x08
+#define REV_ID_VT3253_B1    0x09
+
+/*---------------------  Export Types  ------------------------------*/
+
+/*---------------------  Export Macros ------------------------------*/
+
+#define MACvRegBitsOn(dwIoBase, byRegOfs, byBits)           \
+{                                                           \
+    BYTE byData;                                            \
+    VNSvInPortB(dwIoBase + byRegOfs, &byData);              \
+    VNSvOutPortB(dwIoBase + byRegOfs, byData | (byBits));   \
+}
+
+#define MACvWordRegBitsOn(dwIoBase, byRegOfs, wBits)        \
+{                                                           \
+    WORD wData;                                             \
+    VNSvInPortW(dwIoBase + byRegOfs, &wData);               \
+    VNSvOutPortW(dwIoBase + byRegOfs, wData | (wBits));     \
+}
+
+#define MACvDWordRegBitsOn(dwIoBase, byRegOfs, dwBits)      \
+{                                                           \
+    DWORD dwData;                                           \
+    VNSvInPortD(dwIoBase + byRegOfs, &dwData);              \
+    VNSvOutPortD(dwIoBase + byRegOfs, dwData | (dwBits));   \
+}
+
+#define MACvRegBitsOnEx(dwIoBase, byRegOfs, byMask, byBits) \
+{                                                           \
+    BYTE byData;                                            \
+    VNSvInPortB(dwIoBase + byRegOfs, &byData);              \
+    byData &= byMask;                                       \
+    VNSvOutPortB(dwIoBase + byRegOfs, byData | (byBits));   \
+}
+
+#define MACvRegBitsOff(dwIoBase, byRegOfs, byBits)          \
+{                                                           \
+    BYTE byData;                                            \
+    VNSvInPortB(dwIoBase + byRegOfs, &byData);              \
+    VNSvOutPortB(dwIoBase + byRegOfs, byData & ~(byBits));  \
+}
+
+#define MACvWordRegBitsOff(dwIoBase, byRegOfs, wBits)       \
+{                                                           \
+    WORD wData;                                             \
+    VNSvInPortW(dwIoBase + byRegOfs, &wData);               \
+    VNSvOutPortW(dwIoBase + byRegOfs, wData & ~(wBits));    \
+}
+
+#define MACvDWordRegBitsOff(dwIoBase, byRegOfs, dwBits)     \
+{                                                           \
+    DWORD dwData;                                           \
+    VNSvInPortD(dwIoBase + byRegOfs, &dwData);              \
+    VNSvOutPortD(dwIoBase + byRegOfs, dwData & ~(dwBits));  \
+}
+
+#define MACvGetCurrRx0DescAddr(dwIoBase, pdwCurrDescAddr)    \
+{                                                           \
+    VNSvInPortD(dwIoBase + MAC_REG_RXDMAPTR0,               \
+                (PDWORD)pdwCurrDescAddr);                   \
+}
+
+#define MACvGetCurrRx1DescAddr(dwIoBase, pdwCurrDescAddr)   \
+{                                                           \
+    VNSvInPortD(dwIoBase + MAC_REG_RXDMAPTR1,               \
+                (PDWORD)pdwCurrDescAddr);                   \
+}
+
+#define MACvGetCurrTx0DescAddr(dwIoBase, pdwCurrDescAddr)   \
+{                                                           \
+    VNSvInPortD(dwIoBase + MAC_REG_TXDMAPTR0,               \
+                (PDWORD)pdwCurrDescAddr);                   \
+}
+
+#define MACvGetCurrAC0DescAddr(dwIoBase, pdwCurrDescAddr)   \
+{                                                           \
+    VNSvInPortD(dwIoBase + MAC_REG_AC0DMAPTR,               \
+                (PDWORD)pdwCurrDescAddr);                   \
+}
+
+#define MACvGetCurrSyncDescAddr(dwIoBase, pdwCurrDescAddr)  \
+{                                                           \
+    VNSvInPortD(dwIoBase + MAC_REG_SYNCDMAPTR,              \
+                (PDWORD)pdwCurrDescAddr);                   \
+}
+
+#define MACvGetCurrATIMDescAddr(dwIoBase, pdwCurrDescAddr)  \
+{                                                           \
+    VNSvInPortD(dwIoBase + MAC_REG_ATIMDMAPTR,              \
+                (PDWORD)pdwCurrDescAddr);                   \
+}                                                           \
+
+// set the chip with current BCN tx descriptor address
+#define MACvSetCurrBCNTxDescAddr(dwIoBase, dwCurrDescAddr)  \
+{                                                           \
+    VNSvOutPortD(dwIoBase + MAC_REG_BCNDMAPTR,              \
+                 dwCurrDescAddr);                           \
+}
+
+// set the chip with current BCN length
+#define MACvSetCurrBCNLength(dwIoBase, wCurrBCNLength)     \
+{                                                          \
+    VNSvOutPortW(dwIoBase + MAC_REG_BCNDMACTL+2,           \
+                 wCurrBCNLength);                          \
+}
+
+#define MACvReadBSSIDAddress(dwIoBase, pbyEtherAddr)        \
+{                                                           \
+    VNSvOutPortB(dwIoBase + MAC_REG_PAGE1SEL, 1);           \
+    VNSvInPortB(dwIoBase + MAC_REG_BSSID0,                  \
+                (PBYTE)pbyEtherAddr);                       \
+    VNSvInPortB(dwIoBase + MAC_REG_BSSID0 + 1,              \
+                pbyEtherAddr + 1);                          \
+    VNSvInPortB(dwIoBase + MAC_REG_BSSID0 + 2,              \
+                pbyEtherAddr + 2);                          \
+    VNSvInPortB(dwIoBase + MAC_REG_BSSID0 + 3,              \
+                pbyEtherAddr + 3);                          \
+    VNSvInPortB(dwIoBase + MAC_REG_BSSID0 + 4,              \
+                pbyEtherAddr + 4);                          \
+    VNSvInPortB(dwIoBase + MAC_REG_BSSID0 + 5,              \
+                pbyEtherAddr + 5);                          \
+    VNSvOutPortB(dwIoBase + MAC_REG_PAGE1SEL, 0);           \
+}
+
+#define MACvWriteBSSIDAddress(dwIoBase, pbyEtherAddr)       \
+{                                                           \
+    VNSvOutPortB(dwIoBase + MAC_REG_PAGE1SEL, 1);           \
+    VNSvOutPortB(dwIoBase + MAC_REG_BSSID0,                 \
+                *(pbyEtherAddr));                           \
+    VNSvOutPortB(dwIoBase + MAC_REG_BSSID0 + 1,             \
+                *(pbyEtherAddr + 1));                       \
+    VNSvOutPortB(dwIoBase + MAC_REG_BSSID0 + 2,             \
+                *(pbyEtherAddr + 2));                       \
+    VNSvOutPortB(dwIoBase + MAC_REG_BSSID0 + 3,             \
+                *(pbyEtherAddr + 3));                       \
+    VNSvOutPortB(dwIoBase + MAC_REG_BSSID0 + 4,             \
+                *(pbyEtherAddr + 4));                       \
+    VNSvOutPortB(dwIoBase + MAC_REG_BSSID0 + 5,             \
+                *(pbyEtherAddr + 5));                       \
+    VNSvOutPortB(dwIoBase + MAC_REG_PAGE1SEL, 0);           \
+}
+
+#define MACvReadEtherAddress(dwIoBase, pbyEtherAddr)        \
+{                                                           \
+    VNSvOutPortB(dwIoBase + MAC_REG_PAGE1SEL, 1);           \
+    VNSvInPortB(dwIoBase + MAC_REG_PAR0,                    \
+                (PBYTE)pbyEtherAddr);                       \
+    VNSvInPortB(dwIoBase + MAC_REG_PAR0 + 1,                \
+                pbyEtherAddr + 1);                          \
+    VNSvInPortB(dwIoBase + MAC_REG_PAR0 + 2,                \
+                pbyEtherAddr + 2);                          \
+    VNSvInPortB(dwIoBase + MAC_REG_PAR0 + 3,                \
+                pbyEtherAddr + 3);                          \
+    VNSvInPortB(dwIoBase + MAC_REG_PAR0 + 4,                \
+                pbyEtherAddr + 4);                          \
+    VNSvInPortB(dwIoBase + MAC_REG_PAR0 + 5,                \
+                pbyEtherAddr + 5);                          \
+    VNSvOutPortB(dwIoBase + MAC_REG_PAGE1SEL, 0);           \
+}
+
+
+#define MACvWriteEtherAddress(dwIoBase, pbyEtherAddr)       \
+{                                                           \
+    VNSvOutPortB(dwIoBase + MAC_REG_PAGE1SEL, 1);           \
+    VNSvOutPortB(dwIoBase + MAC_REG_PAR0,                   \
+                *pbyEtherAddr);                             \
+    VNSvOutPortB(dwIoBase + MAC_REG_PAR0 + 1,               \
+                *(pbyEtherAddr + 1));                       \
+    VNSvOutPortB(dwIoBase + MAC_REG_PAR0 + 2,               \
+                *(pbyEtherAddr + 2));                       \
+    VNSvOutPortB(dwIoBase + MAC_REG_PAR0 + 3,               \
+                *(pbyEtherAddr + 3));                       \
+    VNSvOutPortB(dwIoBase + MAC_REG_PAR0 + 4,               \
+                *(pbyEtherAddr + 4));                       \
+    VNSvOutPortB(dwIoBase + MAC_REG_PAR0 + 5,               \
+                *(pbyEtherAddr + 5));                       \
+    VNSvOutPortB(dwIoBase + MAC_REG_PAGE1SEL, 0);           \
+}
+
+
+#define MACvClearISR(dwIoBase)                              \
+{                                                           \
+    VNSvOutPortD(dwIoBase + MAC_REG_ISR, IMR_MASK_VALUE);   \
+}
+
+#define MACvStart(dwIoBase)                                      \
+{                                                                \
+    VNSvOutPortB(dwIoBase + MAC_REG_HOSTCR,                      \
+                    (HOSTCR_MACEN | HOSTCR_RXON | HOSTCR_TXON)); \
+}
+
+#define MACvRx0PerPktMode(dwIoBase)                         \
+{                                                           \
+    VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL0, RX_PERPKT);  \
+}
+
+#define MACvRx0BufferFillMode(dwIoBase)                         \
+{                                                               \
+    VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL0, RX_PERPKTCLR);   \
+}
+
+#define MACvRx1PerPktMode(dwIoBase)                         \
+{                                                           \
+    VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL1, RX_PERPKT);  \
+}
+
+#define MACvRx1BufferFillMode(dwIoBase)                         \
+{                                                               \
+    VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL1, RX_PERPKTCLR);   \
+}
+
+#define MACvRxOn(dwIoBase)                                      \
+{                                                               \
+    MACvRegBitsOn(dwIoBase, MAC_REG_HOSTCR, HOSTCR_RXON);       \
+}
+
+#define MACvReceive0(dwIoBase)                                  \
+{                                                               \
+    DWORD dwData;                                               \
+    VNSvInPortD(dwIoBase + MAC_REG_RXDMACTL0, &dwData);         \
+    if (dwData & DMACTL_RUN) {                                  \
+        VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL0, DMACTL_WAKE);\
+    }                                                           \
+    else {                                                      \
+        VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL0, DMACTL_RUN); \
+    }                                                           \
+}
+
+#define MACvReceive1(dwIoBase)                                  \
+{                                                               \
+    DWORD dwData;                                                \
+    VNSvInPortD(dwIoBase + MAC_REG_RXDMACTL1, &dwData);         \
+    if (dwData & DMACTL_RUN) {                                  \
+        VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL1, DMACTL_WAKE);\
+    }                                                           \
+    else {                                                      \
+        VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL1, DMACTL_RUN); \
+    }                                                           \
+}
+
+#define MACvTxOn(dwIoBase)                                      \
+{                                                               \
+    MACvRegBitsOn(dwIoBase, MAC_REG_HOSTCR, HOSTCR_TXON);       \
+}
+
+#define MACvTransmit0(dwIoBase)                                 \
+{                                                               \
+    DWORD dwData;                                                \
+    VNSvInPortD(dwIoBase + MAC_REG_TXDMACTL0, &dwData);         \
+    if (dwData & DMACTL_RUN) {                                  \
+        VNSvOutPortD(dwIoBase + MAC_REG_TXDMACTL0, DMACTL_WAKE);\
+    }                                                           \
+    else {                                                      \
+        VNSvOutPortD(dwIoBase + MAC_REG_TXDMACTL0, DMACTL_RUN); \
+    }                                                           \
+}
+
+#define MACvTransmitAC0(dwIoBase)                               \
+{                                                               \
+    DWORD dwData;                                                \
+    VNSvInPortD(dwIoBase + MAC_REG_AC0DMACTL, &dwData);         \
+    if (dwData & DMACTL_RUN) {                                  \
+        VNSvOutPortD(dwIoBase + MAC_REG_AC0DMACTL, DMACTL_WAKE);\
+    }                                                           \
+    else {                                                      \
+        VNSvOutPortD(dwIoBase + MAC_REG_AC0DMACTL, DMACTL_RUN); \
+    }                                                           \
+}
+
+#define MACvTransmitSYNC(dwIoBase)                               \
+{                                                                \
+    DWORD dwData;                                                 \
+    VNSvInPortD(dwIoBase + MAC_REG_SYNCDMACTL, &dwData);         \
+    if (dwData & DMACTL_RUN) {                                   \
+        VNSvOutPortD(dwIoBase + MAC_REG_SYNCDMACTL, DMACTL_WAKE);\
+    }                                                            \
+    else {                                                       \
+        VNSvOutPortD(dwIoBase + MAC_REG_SYNCDMACTL, DMACTL_RUN); \
+    }                                                            \
+}
+
+#define MACvTransmitATIM(dwIoBase)                               \
+{                                                                \
+    DWORD dwData;                                                 \
+    VNSvInPortD(dwIoBase + MAC_REG_ATIMDMACTL, &dwData);         \
+    if (dwData & DMACTL_RUN) {                                   \
+        VNSvOutPortD(dwIoBase + MAC_REG_ATIMDMACTL, DMACTL_WAKE);\
+    }                                                            \
+    else {                                                       \
+        VNSvOutPortD(dwIoBase + MAC_REG_ATIMDMACTL, DMACTL_RUN); \
+    }                                                            \
+}
+
+#define MACvTransmitBCN(dwIoBase)                               \
+{                                                               \
+    VNSvOutPortB(dwIoBase + MAC_REG_BCNDMACTL, BEACON_READY);   \
+}
+
+#define MACvClearStckDS(dwIoBase)                           \
+{                                                           \
+    BYTE byOrgValue;                                        \
+    VNSvInPortB(dwIoBase + MAC_REG_STICKHW, &byOrgValue);   \
+    byOrgValue = byOrgValue & 0xFC;                         \
+    VNSvOutPortB(dwIoBase + MAC_REG_STICKHW, byOrgValue);   \
+}
+
+#define MACvReadISR(dwIoBase, pdwValue)             \
+{                                                   \
+    VNSvInPortD(dwIoBase + MAC_REG_ISR, pdwValue);  \
+}
+
+#define MACvWriteISR(dwIoBase, dwValue)             \
+{                                                   \
+    VNSvOutPortD(dwIoBase + MAC_REG_ISR, dwValue);  \
+}
+
+#define MACvIntEnable(dwIoBase, dwMask)             \
+{                                                   \
+    VNSvOutPortD(dwIoBase + MAC_REG_IMR, dwMask);   \
+}
+
+#define MACvIntDisable(dwIoBase)                    \
+{                                                   \
+    VNSvOutPortD(dwIoBase + MAC_REG_IMR, 0);        \
+}
+
+#define MACvSelectPage0(dwIoBase)                   \
+{                                                   \
+    VNSvOutPortB(dwIoBase + MAC_REG_PAGE1SEL, 0);   \
+}
+#define MACvSelectPage1(dwIoBase)                   \
+{                                                   \
+    VNSvOutPortB(dwIoBase + MAC_REG_PAGE1SEL, 1);   \
+}
+
+#define MACvReadMIBCounter(dwIoBase, pdwCounter)            \
+{                                                           \
+    VNSvInPortD(dwIoBase + MAC_REG_MIBCNTR , pdwCounter);   \
+}
+
+#define MACvPwrEvntDisable(dwIoBase)                    \
+{                                                       \
+    VNSvOutPortW(dwIoBase + MAC_REG_WAKEUPEN0, 0x0000); \
+}
+
+#define MACvEnableProtectMD(dwIoBase)                    \
+{                                                        \
+    DWORD dwOrgValue;                                    \
+    VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue); \
+    dwOrgValue = dwOrgValue | EnCFG_ProtectMd;           \
+    VNSvOutPortD(dwIoBase + MAC_REG_ENCFG, dwOrgValue);  \
+}
+
+#define MACvDisableProtectMD(dwIoBase)                   \
+{                                                        \
+    DWORD dwOrgValue;                                     \
+    VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue); \
+    dwOrgValue = dwOrgValue & ~EnCFG_ProtectMd;          \
+    VNSvOutPortD(dwIoBase + MAC_REG_ENCFG, dwOrgValue);  \
+}
+
+#define MACvEnableBarkerPreambleMd(dwIoBase)             \
+{                                                        \
+    DWORD dwOrgValue;                                    \
+    VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue); \
+    dwOrgValue = dwOrgValue | EnCFG_BarkerPream;         \
+    VNSvOutPortD(dwIoBase + MAC_REG_ENCFG, dwOrgValue);  \
+}
+
+#define MACvDisableBarkerPreambleMd(dwIoBase)            \
+{                                                        \
+    DWORD dwOrgValue;                                    \
+    VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue); \
+    dwOrgValue = dwOrgValue & ~EnCFG_BarkerPream;        \
+    VNSvOutPortD(dwIoBase + MAC_REG_ENCFG, dwOrgValue);  \
+}
+
+#define MACvSetBBType(dwIoBase, byTyp)                   \
+{                                                        \
+    DWORD dwOrgValue;                                    \
+    VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue); \
+    dwOrgValue = dwOrgValue & ~EnCFG_BBType_MASK;        \
+    dwOrgValue = dwOrgValue | (DWORD) byTyp;             \
+    VNSvOutPortD(dwIoBase + MAC_REG_ENCFG, dwOrgValue);  \
+}
+
+#define MACvReadATIMW(dwIoBase, pwCounter)                 \
+{                                                          \
+    VNSvInPortW(dwIoBase + MAC_REG_AIDATIM , pwCounter);   \
+}
+
+#define MACvWriteATIMW(dwIoBase, wCounter)                 \
+{                                                          \
+    VNSvOutPortW(dwIoBase + MAC_REG_AIDATIM , wCounter);   \
+}
+
+#define MACvWriteCRC16_128(dwIoBase, byRegOfs, wCRC)       \
+{                                                          \
+    VNSvOutPortB(dwIoBase + MAC_REG_PAGE1SEL, 1);          \
+    VNSvOutPortW(dwIoBase + byRegOfs, wCRC);               \
+    VNSvOutPortB(dwIoBase + MAC_REG_PAGE1SEL, 0);          \
+}
+
+#define MACvGPIOIn(dwIoBase, pbyValue)                      \
+{                                                           \
+    VNSvInPortB(dwIoBase + MAC_REG_GPIOCTL1, pbyValue);     \
+}
+
+#define MACvSetRFLE_LatchBase(dwIoBase)                                 \
+{                                                                        \
+    MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_RFLEOPT); \
+}
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+#ifdef __cplusplus
+extern "C" {                            /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+extern WORD TxRate_iwconfig;//2008-5-8 <add> by chester
+VOID MACvReadAllRegs(DWORD_PTR dwIoBase, PBYTE pbyMacRegs);
+
+BOOL MACbIsRegBitsOn(DWORD_PTR dwIoBase, BYTE byRegOfs, BYTE byTestBits);
+BOOL MACbIsRegBitsOff(DWORD_PTR dwIoBase, BYTE byRegOfs, BYTE byTestBits);
+
+BOOL MACbIsIntDisable(DWORD_PTR dwIoBase);
+
+BYTE MACbyReadMultiAddr(DWORD_PTR dwIoBase, UINT uByteIdx);
+VOID MACvWriteMultiAddr(DWORD_PTR dwIoBase, UINT uByteIdx, BYTE byData);
+VOID MACvSetMultiAddrByHash(DWORD_PTR dwIoBase, BYTE byHashIdx);
+VOID MACvResetMultiAddrByHash(DWORD_PTR dwIoBase, BYTE byHashIdx);
+
+VOID MACvSetRxThreshold(DWORD_PTR dwIoBase, BYTE byThreshold);
+VOID MACvGetRxThreshold(DWORD_PTR dwIoBase, PBYTE pbyThreshold);
+
+VOID MACvSetTxThreshold(DWORD_PTR dwIoBase, BYTE byThreshold);
+VOID MACvGetTxThreshold(DWORD_PTR dwIoBase, PBYTE pbyThreshold);
+
+VOID MACvSetDmaLength(DWORD_PTR dwIoBase, BYTE byDmaLength);
+VOID MACvGetDmaLength(DWORD_PTR dwIoBase, PBYTE pbyDmaLength);
+
+VOID MACvSetShortRetryLimit(DWORD_PTR dwIoBase, BYTE byRetryLimit);
+VOID MACvGetShortRetryLimit(DWORD_PTR dwIoBase, PBYTE pbyRetryLimit);
+
+VOID MACvSetLongRetryLimit(DWORD_PTR dwIoBase, BYTE byRetryLimit);
+VOID MACvGetLongRetryLimit(DWORD_PTR dwIoBase, PBYTE pbyRetryLimit);
+
+VOID MACvSetLoopbackMode(DWORD_PTR dwIoBase, BYTE byLoopbackMode);
+BOOL MACbIsInLoopbackMode(DWORD_PTR dwIoBase);
+
+VOID MACvSetPacketFilter(DWORD_PTR dwIoBase, WORD wFilterType);
+
+VOID MACvSaveContext(DWORD_PTR dwIoBase, PBYTE pbyCxtBuf);
+VOID MACvRestoreContext(DWORD_PTR dwIoBase, PBYTE pbyCxtBuf);
+BOOL MACbCompareContext(DWORD_PTR dwIoBase, PBYTE pbyCxtBuf);
+
+BOOL MACbSoftwareReset(DWORD_PTR dwIoBase);
+BOOL MACbSafeSoftwareReset(DWORD_PTR dwIoBase);
+BOOL MACbSafeRxOff(DWORD_PTR dwIoBase);
+BOOL MACbSafeTxOff(DWORD_PTR dwIoBase);
+BOOL MACbSafeStop(DWORD_PTR dwIoBase);
+BOOL MACbShutdown(DWORD_PTR dwIoBase);
+VOID MACvInitialize(DWORD_PTR dwIoBase);
+VOID MACvSetCurrRx0DescAddr(DWORD_PTR dwIoBase, DWORD dwCurrDescAddr);
+VOID MACvSetCurrRx1DescAddr(DWORD_PTR dwIoBase, DWORD dwCurrDescAddr);
+VOID MACvSetCurrTXDescAddr(int iTxType, DWORD_PTR dwIoBase, DWORD dwCurrDescAddr);
+VOID MACvSetCurrTx0DescAddrEx(DWORD_PTR dwIoBase, DWORD dwCurrDescAddr);
+VOID MACvSetCurrAC0DescAddrEx(DWORD_PTR dwIoBase, DWORD dwCurrDescAddr);
+VOID MACvSetCurrSyncDescAddrEx(DWORD_PTR dwIoBase, DWORD dwCurrDescAddr);
+VOID MACvSetCurrATIMDescAddrEx(DWORD_PTR dwIoBase, DWORD dwCurrDescAddr);
+void MACvTimer0MicroSDelay(DWORD_PTR dwIoBase, UINT uDelay);
+void MACvOneShotTimer0MicroSec(DWORD_PTR dwIoBase, UINT uDelayTime);
+void MACvOneShotTimer1MicroSec(DWORD_PTR dwIoBase, UINT uDelayTime);
+
+void MACvSetMISCFifo(DWORD_PTR dwIoBase, WORD wOffset, DWORD dwData);
+
+BOOL MACbTxDMAOff (DWORD_PTR dwIoBase, UINT idx);
+
+void MACvClearBusSusInd(DWORD_PTR dwIoBase);
+void MACvEnableBusSusEn(DWORD_PTR dwIoBase);
+
+BOOL MACbFlushSYNCFifo(DWORD_PTR dwIoBase);
+BOOL MACbPSWakeup(DWORD_PTR dwIoBase);
+
+void MACvSetKeyEntry(DWORD_PTR dwIoBase, WORD wKeyCtl, UINT uEntryIdx, UINT uKeyIdx, PBYTE pbyAddr, PDWORD pdwKey, BYTE byLocalID);
+void MACvDisableKeyEntry(DWORD_PTR dwIoBase, UINT uEntryIdx);
+void MACvSetDefaultKeyEntry(DWORD_PTR dwIoBase, UINT uKeyLen, UINT uKeyIdx, PDWORD pdwKey, BYTE byLocalID);
+//void MACvEnableDefaultKey(DWORD_PTR dwIoBase, BYTE byLocalID);
+void MACvDisableDefaultKey(DWORD_PTR dwIoBase);
+void MACvSetDefaultTKIPKeyEntry(DWORD_PTR dwIoBase, UINT uKeyLen, UINT uKeyIdx, PDWORD pdwKey, BYTE byLocalID);
+void MACvSetDefaultKeyCtl(DWORD_PTR dwIoBase, WORD wKeyCtl, UINT uEntryIdx, BYTE byLocalID);
+
+#ifdef __cplusplus
+}                                       /* End of extern "C" { */
+#endif /* __cplusplus */
+
+#endif // __MAC_H__
+
diff --git a/drivers/staging/vt6655/mib.c b/drivers/staging/vt6655/mib.c
new file mode 100644 (file)
index 0000000..3f06de1
--- /dev/null
@@ -0,0 +1,616 @@
+/*
+ * 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, DWORD dwIsr)
+{
+    /**********************/
+    /* ABNORMAL interrupt */
+    /**********************/
+    // not any IMR bit invoke irq
+
+    if (dwIsr == 0) {
+        pStatistic->ISRStat.dwIsrUnknown++;
+        return;
+    }
+
+//Added by Kyle
+    if (BITbIsBitOn(dwIsr, ISR_TXDMA0))               // ISR, bit0
+        pStatistic->ISRStat.dwIsrTx0OK++;             // TXDMA0 successful
+
+    if (BITbIsBitOn(dwIsr, ISR_AC0DMA))               // ISR, bit1
+        pStatistic->ISRStat.dwIsrAC0TxOK++;           // AC0DMA successful
+
+    if (BITbIsBitOn(dwIsr, ISR_BNTX))                 // ISR, bit2
+        pStatistic->ISRStat.dwIsrBeaconTxOK++;        // BeaconTx successful
+
+    if (BITbIsBitOn(dwIsr, ISR_RXDMA0))               // ISR, bit3
+        pStatistic->ISRStat.dwIsrRx0OK++;             // Rx0 successful
+
+    if (BITbIsBitOn(dwIsr, ISR_TBTT))                 // ISR, bit4
+        pStatistic->ISRStat.dwIsrTBTTInt++;           // TBTT successful
+
+    if (BITbIsBitOn(dwIsr, ISR_SOFTTIMER))            // ISR, bit6
+        pStatistic->ISRStat.dwIsrSTIMERInt++;
+
+    if (BITbIsBitOn(dwIsr, ISR_WATCHDOG))             // ISR, bit7
+        pStatistic->ISRStat.dwIsrWatchDog++;
+
+    if (BITbIsBitOn(dwIsr, ISR_FETALERR))             // ISR, bit8
+        pStatistic->ISRStat.dwIsrUnrecoverableError++;
+
+    if (BITbIsBitOn(dwIsr, ISR_SOFTINT))              // ISR, bit9
+        pStatistic->ISRStat.dwIsrSoftInterrupt++;     // software interrupt
+
+    if (BITbIsBitOn(dwIsr, ISR_MIBNEARFULL))          // ISR, bit10
+        pStatistic->ISRStat.dwIsrMIBNearfull++;
+
+    if (BITbIsBitOn(dwIsr, ISR_RXNOBUF))              // ISR, bit11
+        pStatistic->ISRStat.dwIsrRxNoBuf++;           // Rx No Buff
+
+    if (BITbIsBitOn(dwIsr, ISR_RXDMA1))               // ISR, bit12
+        pStatistic->ISRStat.dwIsrRx1OK++;             // Rx1 successful
+
+//    if (BITbIsBitOn(dwIsr, ISR_ATIMTX))               // ISR, bit13
+//        pStatistic->ISRStat.dwIsrATIMTxOK++;          // ATIMTX successful
+
+//    if (BITbIsBitOn(dwIsr, ISR_SYNCTX))               // ISR, bit14
+//        pStatistic->ISRStat.dwIsrSYNCTxOK++;          // SYNCTX successful
+
+//    if (BITbIsBitOn(dwIsr, ISR_CFPEND))               // ISR, bit18
+//        pStatistic->ISRStat.dwIsrCFPEnd++;
+
+//    if (BITbIsBitOn(dwIsr, ISR_ATIMEND))              // ISR, bit19
+//        pStatistic->ISRStat.dwIsrATIMEnd++;
+
+//    if (BITbIsBitOn(dwIsr, ISR_SYNCFLUSHOK))          // ISR, bit20
+//        pStatistic->ISRStat.dwIsrSYNCFlushOK++;
+
+    if (BITbIsBitOn(dwIsr, ISR_SOFTTIMER1))           // ISR, bit21
+        pStatistic->ISRStat.dwIsrSTIMER1Int++;
+
+}
+
+
+/*
+ * 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 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++;
+        }
+        DEVICE_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++;
+        }
+        DEVICE_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++;
+        }
+        DEVICE_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++;
+        }
+        DEVICE_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++;
+        }
+        DEVICE_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++;
+        }
+        DEVICE_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++;
+        }
+        DEVICE_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++;
+        }
+        DEVICE_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++;
+        }
+        DEVICE_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++;
+        }
+        DEVICE_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++;
+        }
+        DEVICE_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++;
+        }
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"54M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr54M, (INT)pStatistic->CustomStat.ullRsr54MCRCOk);
+    }
+    else {
+       DEVICE_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)))
+        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            byRxRate,
+    PBYTE           pbyBuffer,
+    UINT            cbFrameLength
+    )
+{
+    STAvUpdateRDStatCounter(
+                    pStatistic,
+                    byRSR,
+                    byNewRSR,
+                    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            byTSR0,
+    BYTE            byTSR1,
+    PBYTE           pbyBuffer,
+    UINT            cbFrameLength,
+    UINT            uIdx
+    )
+{
+    PWLAN_80211HDR_A4   pHeader;
+    PBYTE               pbyDestAddr;
+    BYTE                byTSR0_NCR = byTSR0 & TSR0_NCR;
+
+
+
+    pHeader = (PWLAN_80211HDR_A4) pbyBuffer;
+    if (WLAN_GET_FC_TODS(pHeader->wFrameCtl) == 0) {
+        pbyDestAddr = &(pHeader->abyAddr1[0]);
+    }
+    else {
+        pbyDestAddr = &(pHeader->abyAddr3[0]);
+    }
+    // increase tx packet count
+    pStatistic->dwTsrTxPacket[uIdx]++;
+    pStatistic->dwTsrTxOctet[uIdx] += cbFrameLength;
+
+    if (byTSR0_NCR != 0) {
+        pStatistic->dwTsrRetry[uIdx]++;
+        pStatistic->dwTsrTotalRetry[uIdx] += byTSR0_NCR;
+
+        if (byTSR0_NCR == 1)
+            pStatistic->dwTsrOnceRetry[uIdx]++;
+        else
+            pStatistic->dwTsrMoreThanOnceRetry[uIdx]++;
+    }
+
+    if ((byTSR1&(TSR1_TERR|TSR1_RETRYTMO|TSR1_TMO|ACK_DATA)) == 0) {
+        pStatistic->ullTsrOK[uIdx]++;
+        pStatistic->CustomStat.ullTsrAllOK =
+            (pStatistic->ullTsrOK[TYPE_AC0DMA] + pStatistic->ullTsrOK[TYPE_TXDMA0]);
+        // update counters in case that successful transmit
+        if (IS_BROADCAST_ADDRESS(pbyDestAddr)) {
+            pStatistic->ullTxBroadcastFrames[uIdx]++;
+            pStatistic->ullTxBroadcastBytes[uIdx] += (ULONGLONG)cbFrameLength;
+        }
+        else if (IS_MULTICAST_ADDRESS(pbyDestAddr)) {
+            pStatistic->ullTxMulticastFrames[uIdx]++;
+            pStatistic->ullTxMulticastBytes[uIdx] += (ULONGLONG)cbFrameLength;
+        }
+        else {
+            pStatistic->ullTxDirectedFrames[uIdx]++;
+            pStatistic->ullTxDirectedBytes[uIdx] += (ULONGLONG)cbFrameLength;
+        }
+    }
+    else {
+        if (BITbIsBitOn(byTSR1, TSR1_TERR))
+            pStatistic->dwTsrErr[uIdx]++;
+        if (BITbIsBitOn(byTSR1, TSR1_RETRYTMO))
+            pStatistic->dwTsrRetryTimeout[uIdx]++;
+        if (BITbIsBitOn(byTSR1, TSR1_TMO))
+            pStatistic->dwTsrTransmitTimeout[uIdx]++;
+        if (BITbIsBitOn(byTSR1, ACK_DATA))
+            pStatistic->dwTsrACKData[uIdx]++;
+    }
+
+    if (IS_BROADCAST_ADDRESS(pbyDestAddr))
+        pStatistic->dwTsrBroadcast[uIdx]++;
+    else if (IS_MULTICAST_ADDRESS(pbyDestAddr))
+        pStatistic->dwTsrMulticast[uIdx]++;
+    else
+        pStatistic->dwTsrDirected[uIdx]++;
+
+}
+
+
+/*
+ * Description: Update Tx Statistic Counter and copy Tx buffer
+ *
+ * Parameters:
+ *  In:
+ *      pStatistic      - Pointer to Statistic Counter Data Structure
+ *      pbyBuffer       - Tx Buffer
+ *      cbFrameLength   - Tx Length
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void
+STAvUpdateTDStatCounterEx (
+    PSStatCounter   pStatistic,
+    PBYTE           pbyBuffer,
+    DWORD           cbFrameLength
+    )
+{
+    UINT    uPktLength;
+
+    uPktLength = (UINT)cbFrameLength;
+
+    // tx length
+    pStatistic->dwCntTxBufLength = uPktLength;
+    // tx pattern, we just see 16 bytes for sample
+    MEMvCopy(pStatistic->abyCntTxPattern, pbyBuffer, 16);
+}
+
+
+/*
+ * 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,
+    DWORD                   dwCounter
+    )
+{
+    //p802_11Counter->TransmittedFragmentCount
+    p802_11Counter->MulticastTransmittedFrameCount = (ULONGLONG) (pStatistic->dwTsrBroadcast[TYPE_AC0DMA] +
+                                                                  pStatistic->dwTsrBroadcast[TYPE_TXDMA0] +
+                                                                  pStatistic->dwTsrMulticast[TYPE_AC0DMA] +
+                                                                  pStatistic->dwTsrMulticast[TYPE_TXDMA0]);
+    p802_11Counter->FailedCount = (ULONGLONG) (pStatistic->dwTsrErr[TYPE_AC0DMA] + pStatistic->dwTsrErr[TYPE_TXDMA0]);
+    p802_11Counter->RetryCount = (ULONGLONG) (pStatistic->dwTsrRetry[TYPE_AC0DMA] + pStatistic->dwTsrRetry[TYPE_TXDMA0]);
+    p802_11Counter->MultipleRetryCount = (ULONGLONG) (pStatistic->dwTsrMoreThanOnceRetry[TYPE_AC0DMA] +
+                                                          pStatistic->dwTsrMoreThanOnceRetry[TYPE_TXDMA0]);
+    //p802_11Counter->FrameDuplicateCount
+    p802_11Counter->RTSSuccessCount += (ULONGLONG)  (dwCounter & 0x000000ff);
+    p802_11Counter->RTSFailureCount += (ULONGLONG) ((dwCounter & 0x0000ff00) >> 8);
+    p802_11Counter->ACKFailureCount += (ULONGLONG) ((dwCounter & 0x00ff0000) >> 16);
+    p802_11Counter->FCSErrorCount +=   (ULONGLONG) ((dwCounter & 0xff000000) >> 24);
+    //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));
+}
diff --git a/drivers/staging/vt6655/mib.h b/drivers/staging/vt6655/mib.h
new file mode 100644 (file)
index 0000000..b4e1c4a
--- /dev/null
@@ -0,0 +1,399 @@
+/*
+ * 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 -------------------------*/
+//
+// 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           //
+
+//#define MAX_RATE            12
+//
+// statistic counter
+//
+typedef struct tagSStatCounter {
+    //
+    // ISR status count
+    //
+
+
+    // 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[TYPE_MAXTD];        // total collision retry count
+    DWORD   dwTsrOnceRetry[TYPE_MAXTD];         // this packet only occur one collision
+    DWORD   dwTsrMoreThanOnceRetry[TYPE_MAXTD]; // this packet occur more than one collision
+    DWORD   dwTsrRetry[TYPE_MAXTD];             // this packet has ever occur collision,
+                                         // that is (dwTsrOnceCollision0 + dwTsrMoreThanOnceCollision0)
+    DWORD   dwTsrACKData[TYPE_MAXTD];
+    DWORD   dwTsrErr[TYPE_MAXTD];
+    DWORD   dwAllTsrOK[TYPE_MAXTD];
+    DWORD   dwTsrRetryTimeout[TYPE_MAXTD];
+    DWORD   dwTsrTransmitTimeout[TYPE_MAXTD];
+
+    DWORD   dwTsrTxPacket[TYPE_MAXTD];
+    DWORD   dwTsrTxOctet[TYPE_MAXTD];
+    DWORD   dwTsrBroadcast[TYPE_MAXTD];
+    DWORD   dwTsrMulticast[TYPE_MAXTD];
+    DWORD   dwTsrDirected[TYPE_MAXTD];
+
+    // 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
+    UINT    idxRxErrorDesc[TYPE_MAXRD]; // index for rx data error RD
+
+    // 64-bit OID
+    ULONGLONG   ullTsrOK[TYPE_MAXTD];
+
+    // for some optional OIDs (64 bits) and DMI support
+    ULONGLONG   ullTxBroadcastFrames[TYPE_MAXTD];
+    ULONGLONG   ullTxMulticastFrames[TYPE_MAXTD];
+    ULONGLONG   ullTxDirectedFrames[TYPE_MAXTD];
+    ULONGLONG   ullTxBroadcastBytes[TYPE_MAXTD];
+    ULONGLONG   ullTxMulticastBytes[TYPE_MAXTD];
+    ULONGLONG   ullTxDirectedBytes[TYPE_MAXTD];
+
+//    DWORD   dwTxRetryCount[8];
+    //
+    // ISR status count
+    //
+    SISRCounters ISRStat;
+
+    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;
+
+/*---------------------  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, DWORD dwIsr);
+
+void STAvUpdateRDStatCounter(PSStatCounter pStatistic,
+                              BYTE byRSR, BYTE byNewRSR, BYTE byRxRate,
+                              PBYTE pbyBuffer, UINT cbFrameLength);
+
+void STAvUpdateRDStatCounterEx(PSStatCounter pStatistic,
+                              BYTE byRSR, BYTE byNewRsr, BYTE byRxRate,
+                              PBYTE pbyBuffer, UINT cbFrameLength);
+
+void STAvUpdateTDStatCounter(PSStatCounter pStatistic,
+                             BYTE byTSR0, BYTE byTSR1,
+                             PBYTE pbyBuffer, UINT cbFrameLength, UINT uIdx );
+
+void STAvUpdateTDStatCounterEx(
+    PSStatCounter   pStatistic,
+    PBYTE           pbyBuffer,
+    DWORD           cbFrameLength
+    );
+
+void STAvUpdate802_11Counter(
+    PSDot11Counters p802_11Counter,
+    PSStatCounter   pStatistic,
+    DWORD           dwCounter
+    );
+
+void STAvClear802_11Counter(PSDot11Counters p802_11Counter);
+
+#ifdef __cplusplus
+}                                       /* End of extern "C" { */
+#endif /* __cplusplus */
+
+
+
+
+#endif // __MIB_H__
+
+
+
diff --git a/drivers/staging/vt6655/michael.c b/drivers/staging/vt6655/michael.c
new file mode 100644 (file)
index 0000000..7bda4c1
--- /dev/null
@@ -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/vt6655/michael.h b/drivers/staging/vt6655/michael.h
new file mode 100644 (file)
index 0000000..62a24a6
--- /dev/null
@@ -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/vt6655/power.c b/drivers/staging/vt6655/power.c
new file mode 100644 (file)
index 0000000..edd8336
--- /dev/null
@@ -0,0 +1,441 @@
+/*
+ * 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
+
+
+
+
+/*---------------------  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->pMgmt;
+    WORD            wAID = pMgmt->wCurrAID | BIT14 | BIT15;
+
+    // set period of power up before TBTT
+    VNSvOutPortW(pDevice->PortOffset + MAC_REG_PWBT, C_PWBT);
+    if (pDevice->eOPMode != OP_MODE_ADHOC) {
+        // set AID
+        VNSvOutPortW(pDevice->PortOffset + MAC_REG_AIDATIM, wAID);
+    } else {
+       // set ATIM Window
+        MACvWriteATIMW(pDevice->PortOffset, pMgmt->wCurrATIMWindow);
+    }
+    // Set AutoSleep
+    MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCFG, PSCFG_AUTOSLEEP);
+    // Set HWUTSF
+    MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TFTCTL, TFTCTL_HWUTSF);
+
+    if (wListenInterval >= 2) {
+        // clear always listen beacon
+        MACvRegBitsOff(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_ALBCN);
+        //pDevice->wCFG &= ~CFG_ALB;
+        // first time set listen next beacon
+        MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_LNBCN);
+        pMgmt->wCountToWakeUp = wListenInterval;
+    }
+    else {
+        // always listen beacon
+        MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_ALBCN);
+        //pDevice->wCFG |= CFG_ALB;
+        pMgmt->wCountToWakeUp = 0;
+    }
+
+    // enable power saving hw function
+    MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PSEN);
+    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;
+    DEVICE_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->pMgmt;
+
+    // disable power saving hw function
+    MACbPSWakeup(pDevice->PortOffset);
+    //clear AutoSleep
+    MACvRegBitsOff(pDevice->PortOffset, MAC_REG_PSCFG, PSCFG_AUTOSLEEP);
+    //clear HWUTSF
+    MACvRegBitsOff(pDevice->PortOffset, MAC_REG_TFTCTL, TFTCTL_HWUTSF);
+    // set always listen beacon
+    MACvRegBitsOn(pDevice->PortOffset, 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->pMgmt;
+    UINT            uIdx;
+
+    // check if already in Doze mode
+    if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS))
+        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;
+
+    // Froce PSEN on
+    MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PSEN);
+
+    // check if all TD are empty,
+    for (uIdx = 0; uIdx < TYPE_MAXTD; uIdx ++) {
+        if (pDevice->iTDUsed[uIdx] != 0)
+            return FALSE;
+    }
+
+    // check if rx isr is clear
+    if (bCheckRxDMA &&
+        ((pDevice->dwIsr& ISR_RXDMA0) != 0) &&
+        ((pDevice->dwIsr & ISR_RXDMA1) != 0)){
+        return FALSE;
+    };
+
+    if (pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) {
+        if (bCheckCountToWakeUp &&
+           (pMgmt->wCountToWakeUp == 0 || pMgmt->wCountToWakeUp == 1)) {
+             return FALSE;
+        }
+    }
+
+    // no Tx, no Rx isr, now go to Doze
+    MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_GO2DOZE);
+    DEVICE_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->pMgmt;
+    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) {
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send PS-Poll packet failed..\n");
+    }
+    else {
+//        DEVICE_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->pMgmt;
+    UINT                uIdx;
+
+
+    if (pDevice->bLinkPass == FALSE) {
+        return FALSE;
+    }
+    #ifdef TxInSleep
+     if ((pDevice->bEnablePSMode == FALSE) &&
+         (pDevice->fTxDataInSleep == FALSE)){
+        return FALSE;
+    }
+#else
+    if (pDevice->bEnablePSMode == FALSE) {
+        return FALSE;
+    }
+#endif
+    if (pDevice->bEnablePSMode) {
+        for (uIdx = 0; uIdx < TYPE_MAXTD; uIdx ++) {
+            if (pDevice->iTDUsed[uIdx] != 0)
+                return FALSE;
+        }
+    }
+
+    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) {
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send Null Packet failed !\n");
+        return FALSE;
+    }
+    else {
+
+//            DEVICE_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->pMgmt;
+    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->PortOffset, MAC_REG_PSCTL, PSCTL_LNBCN);
+            bWakeUp = TRUE;
+        }
+
+    }
+
+    return bWakeUp;
+}
+
diff --git a/drivers/staging/vt6655/power.h b/drivers/staging/vt6655/power.h
new file mode 100644 (file)
index 0000000..a01e7e9
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * 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/vt6655/rc4.c b/drivers/staging/vt6655/rc4.c
new file mode 100644 (file)
index 0000000..0345e32
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * File: rc4.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * 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/vt6655/rc4.h b/drivers/staging/vt6655/rc4.h
new file mode 100644 (file)
index 0000000..4e3ccc5
--- /dev/null
@@ -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/vt6655/rf.c b/drivers/staging/vt6655/rf.c
new file mode 100644 (file)
index 0000000..9d4e3eb
--- /dev/null
@@ -0,0 +1,1283 @@
+/*
+ * 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(__SROM_H__)
+#include "srom.h"
+#endif
+#if !defined(__TBIT_H__)
+#include "tbit.h"
+#endif
+#if !defined(__RF_H__)
+#include "rf.h"
+#endif
+#if !defined(__BASEBAND_H__)
+#include "baseband.h"
+#endif
+
+/*---------------------  Static Definitions -------------------------*/
+
+//static int          msglevel                =MSG_LEVEL_INFO;
+
+#define BY_RF2959_REG_LEN     23 //24bits
+#define CB_RF2959_INIT_SEQ    15
+#define SWITCH_CHANNEL_DELAY_RF2959 200 //us
+#define RF2959_PWR_IDX_LEN    32
+
+#define BY_MA2825_REG_LEN     23 //24bit
+#define CB_MA2825_INIT_SEQ    13
+#define SWITCH_CHANNEL_DELAY_MA2825 200 //us
+#define MA2825_PWR_IDX_LEN    31
+
+#define BY_AL2230_REG_LEN     23 //24bit
+#define CB_AL2230_INIT_SEQ    15
+#define SWITCH_CHANNEL_DELAY_AL2230 200 //us
+#define AL2230_PWR_IDX_LEN    64
+
+
+#define BY_UW2451_REG_LEN     23
+#define CB_UW2451_INIT_SEQ    6
+#define SWITCH_CHANNEL_DELAY_UW2451 200 //us
+#define UW2451_PWR_IDX_LEN    25
+
+//{{ RobertYu: 20041118
+#define BY_MA2829_REG_LEN     23 //24bit
+#define CB_MA2829_INIT_SEQ    13
+#define SWITCH_CHANNEL_DELAY_MA2829 200 //us
+#define MA2829_PWR_IDX_LEN    64
+//}} RobertYu
+
+//{{ RobertYu:20050103
+#define BY_AL7230_REG_LEN     23 //24bit
+#define CB_AL7230_INIT_SEQ    16
+#define SWITCH_CHANNEL_DELAY_AL7230 200 //us
+#define AL7230_PWR_IDX_LEN    64
+//}} RobertYu
+
+//{{ RobertYu: 20041210
+#define BY_UW2452_REG_LEN     23
+#define CB_UW2452_INIT_SEQ    5 //RoberYu:20050113, Rev0.2 Programming Guide(remove R3, so 6-->5)
+#define SWITCH_CHANNEL_DELAY_UW2452 100 //us
+#define UW2452_PWR_IDX_LEN    64
+//}} RobertYu
+
+#define BY_VT3226_REG_LEN     23
+#define CB_VT3226_INIT_SEQ    12
+#define SWITCH_CHANNEL_DELAY_VT3226 200 //us
+#define VT3226_PWR_IDX_LEN    16
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+
+
+
+const DWORD dwAL2230InitTable[CB_AL2230_INIT_SEQ] = {
+    0x03F79000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, //
+    0x03333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, //
+    0x01A00200+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, //
+    0x00FFF300+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, //
+    0x0005A400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, //
+    0x0F4DC500+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, //
+    0x0805B600+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, //
+    0x0146C700+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, //
+    0x00068800+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, //
+    0x0403B900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, //
+    0x00DBBA00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, //
+    0x00099B00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, //
+    0x0BDFFC00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x00000D00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x00580F00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW
+    };
+
+const DWORD dwAL2230ChannelTable0[CB_MAX_CHANNEL] = {
+    0x03F79000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 1, Tf = 2412MHz
+    0x03F79000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 2, Tf = 2417MHz
+    0x03E79000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 3, Tf = 2422MHz
+    0x03E79000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 4, Tf = 2427MHz
+    0x03F7A000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 5, Tf = 2432MHz
+    0x03F7A000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 6, Tf = 2437MHz
+    0x03E7A000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 7, Tf = 2442MHz
+    0x03E7A000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 8, Tf = 2447MHz
+    0x03F7B000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 9, Tf = 2452MHz
+    0x03F7B000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 10, Tf = 2457MHz
+    0x03E7B000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 11, Tf = 2462MHz
+    0x03E7B000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 12, Tf = 2467MHz
+    0x03F7C000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 13, Tf = 2472MHz
+    0x03E7C000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW  // channel = 14, Tf = 2412M
+    };
+
+const DWORD dwAL2230ChannelTable1[CB_MAX_CHANNEL] = {
+    0x03333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 1, Tf = 2412MHz
+    0x0B333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 2, Tf = 2417MHz
+    0x03333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 3, Tf = 2422MHz
+    0x0B333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 4, Tf = 2427MHz
+    0x03333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 5, Tf = 2432MHz
+    0x0B333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 6, Tf = 2437MHz
+    0x03333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 7, Tf = 2442MHz
+    0x0B333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 8, Tf = 2447MHz
+    0x03333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 9, Tf = 2452MHz
+    0x0B333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 10, Tf = 2457MHz
+    0x03333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 11, Tf = 2462MHz
+    0x0B333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 12, Tf = 2467MHz
+    0x03333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 13, Tf = 2472MHz
+    0x06666100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW  // channel = 14, Tf = 2412M
+    };
+
+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
+    };
+
+//{{ RobertYu:20050104
+// 40MHz reference frequency
+// Need to Pull PLLON(PE3) low when writing channel registers through 3-wire.
+const DWORD dwAL7230InitTable[CB_AL7230_INIT_SEQ] = {
+    0x00379000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Channel1 // Need modify for 11a
+    0x13333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Channel1 // Need modify for 11a
+    0x841FF200+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11a: 451FE2
+    0x3FDFA300+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11a: 5FDFA3
+    0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // 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
+    0x802B5500+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11a: 8D1B55
+    0x56AF3600+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW,
+    0xCE020700+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11a: 860207
+    0x6EBC0800+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x221BB900+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW,
+    0xE0000A00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11a: E0600A
+    0x08031B00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // 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
+    0x000A3C00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11a: 00143C
+    0xFFFFFD00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x00000E00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x1ABA8F00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW  // Need modify for 11a: 12BACF
+    };
+
+const DWORD dwAL7230InitTableAMode[CB_AL7230_INIT_SEQ] = {
+    0x0FF52000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Channel184 // Need modify for 11b/g
+    0x00000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Channel184 // Need modify for 11b/g
+    0x451FE200+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11b/g
+    0x5FDFA300+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11b/g
+    0x67F78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // 11a    // Need modify for 11b/g
+    0x853F5500+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11b/g, RoberYu:20050113
+    0x56AF3600+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW,
+    0xCE020700+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11b/g
+    0x6EBC0800+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x221BB900+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW,
+    0xE0600A00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11b/g
+    0x08031B00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // init 0x080B1B00 => 0x080F1B00 for 3 wire control TxGain(D10)
+    0x00147C00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11b/g
+    0xFFFFFD00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x00000E00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x12BACF00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW  // Need modify for 11b/g
+    };
+
+
+const DWORD dwAL7230ChannelTable0[CB_MAX_CHANNEL] = {
+    0x00379000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  1, Tf = 2412MHz
+    0x00379000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  2, Tf = 2417MHz
+    0x00379000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  3, Tf = 2422MHz
+    0x00379000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  4, Tf = 2427MHz
+    0x0037A000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  5, Tf = 2432MHz
+    0x0037A000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  6, Tf = 2437MHz
+    0x0037A000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  7, Tf = 2442MHz
+    0x0037A000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  8, Tf = 2447MHz //RobertYu: 20050218, update for APNode 0.49
+    0x0037B000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  9, Tf = 2452MHz //RobertYu: 20050218, update for APNode 0.49
+    0x0037B000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 10, Tf = 2457MHz //RobertYu: 20050218, update for APNode 0.49
+    0x0037B000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 11, Tf = 2462MHz //RobertYu: 20050218, update for APNode 0.49
+    0x0037B000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 12, Tf = 2467MHz //RobertYu: 20050218, update for APNode 0.49
+    0x0037C000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 13, Tf = 2472MHz //RobertYu: 20050218, update for APNode 0.49
+    0x0037C000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 14, Tf = 2484MHz
+
+    // 4.9G => Ch 183, 184, 185, 187, 188, 189, 192, 196  (Value:15 ~ 22)
+    0x0FF52000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 183, Tf = 4915MHz (15)
+    0x0FF52000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 184, Tf = 4920MHz (16)
+    0x0FF52000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 185, Tf = 4925MHz (17)
+    0x0FF52000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 187, Tf = 4935MHz (18)
+    0x0FF52000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 188, Tf = 4940MHz (19)
+    0x0FF52000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 189, Tf = 4945MHz (20)
+    0x0FF53000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 192, Tf = 4960MHz (21)
+    0x0FF53000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // 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)
+
+    0x0FF54000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =   7, Tf = 5035MHz (23)
+    0x0FF54000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =   8, Tf = 5040MHz (24)
+    0x0FF54000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =   9, Tf = 5045MHz (25)
+    0x0FF54000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  11, Tf = 5055MHz (26)
+    0x0FF54000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  12, Tf = 5060MHz (27)
+    0x0FF55000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  16, Tf = 5080MHz (28)
+    0x0FF56000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  34, Tf = 5170MHz (29)
+    0x0FF56000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  36, Tf = 5180MHz (30)
+    0x0FF57000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  38, Tf = 5190MHz (31) //RobertYu: 20050218, update for APNode 0.49
+    0x0FF57000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  40, Tf = 5200MHz (32)
+    0x0FF57000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  42, Tf = 5210MHz (33)
+    0x0FF57000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  44, Tf = 5220MHz (34)
+    0x0FF57000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  46, Tf = 5230MHz (35)
+    0x0FF57000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  48, Tf = 5240MHz (36)
+    0x0FF58000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  52, Tf = 5260MHz (37)
+    0x0FF58000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  56, Tf = 5280MHz (38)
+    0x0FF58000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  60, Tf = 5300MHz (39)
+    0x0FF59000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  64, Tf = 5320MHz (40)
+
+    0x0FF5C000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 100, Tf = 5500MHz (41)
+    0x0FF5C000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 104, Tf = 5520MHz (42)
+    0x0FF5C000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 108, Tf = 5540MHz (43)
+    0x0FF5D000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 112, Tf = 5560MHz (44)
+    0x0FF5D000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 116, Tf = 5580MHz (45)
+    0x0FF5D000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 120, Tf = 5600MHz (46)
+    0x0FF5E000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 124, Tf = 5620MHz (47)
+    0x0FF5E000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 128, Tf = 5640MHz (48)
+    0x0FF5E000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 132, Tf = 5660MHz (49)
+    0x0FF5F000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 136, Tf = 5680MHz (50)
+    0x0FF5F000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 140, Tf = 5700MHz (51)
+    0x0FF60000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 149, Tf = 5745MHz (52)
+    0x0FF60000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 153, Tf = 5765MHz (53)
+    0x0FF60000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 157, Tf = 5785MHz (54)
+    0x0FF61000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 161, Tf = 5805MHz (55)
+    0x0FF61000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW  // channel = 165, Tf = 5825MHz (56)
+    };
+
+const DWORD dwAL7230ChannelTable1[CB_MAX_CHANNEL] = {
+    0x13333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  1, Tf = 2412MHz
+    0x1B333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  2, Tf = 2417MHz
+    0x03333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  3, Tf = 2422MHz
+    0x0B333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  4, Tf = 2427MHz
+    0x13333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  5, Tf = 2432MHz
+    0x1B333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  6, Tf = 2437MHz
+    0x03333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  7, Tf = 2442MHz
+    0x0B333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  8, Tf = 2447MHz
+    0x13333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  9, Tf = 2452MHz
+    0x1B333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 10, Tf = 2457MHz
+    0x03333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 11, Tf = 2462MHz
+    0x0B333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 12, Tf = 2467MHz
+    0x13333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 13, Tf = 2472MHz
+    0x06666100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 14, Tf = 2484MHz
+
+    // 4.9G => Ch 183, 184, 185, 187, 188, 189, 192, 196  (Value:15 ~ 22)
+    0x1D555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 183, Tf = 4915MHz (15)
+    0x00000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 184, Tf = 4920MHz (16)
+    0x02AAA100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 185, Tf = 4925MHz (17)
+    0x08000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 187, Tf = 4935MHz (18)
+    0x0AAAA100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 188, Tf = 4940MHz (19)
+    0x0D555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 189, Tf = 4945MHz (20)
+    0x15555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 192, Tf = 4960MHz (21)
+    0x00000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // 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)
+    0x1D555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =   7, Tf = 5035MHz (23)
+    0x00000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =   8, Tf = 5040MHz (24)
+    0x02AAA100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =   9, Tf = 5045MHz (25)
+    0x08000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  11, Tf = 5055MHz (26)
+    0x0AAAA100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  12, Tf = 5060MHz (27)
+    0x15555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  16, Tf = 5080MHz (28)
+    0x05555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  34, Tf = 5170MHz (29)
+    0x0AAAA100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  36, Tf = 5180MHz (30)
+    0x10000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  38, Tf = 5190MHz (31)
+    0x15555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  40, Tf = 5200MHz (32)
+    0x1AAAA100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  42, Tf = 5210MHz (33)
+    0x00000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  44, Tf = 5220MHz (34)
+    0x05555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  46, Tf = 5230MHz (35)
+    0x0AAAA100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  48, Tf = 5240MHz (36)
+    0x15555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  52, Tf = 5260MHz (37)
+    0x00000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  56, Tf = 5280MHz (38)
+    0x0AAAA100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  60, Tf = 5300MHz (39)
+    0x15555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  64, Tf = 5320MHz (40)
+    0x15555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 100, Tf = 5500MHz (41)
+    0x00000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 104, Tf = 5520MHz (42)
+    0x0AAAA100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 108, Tf = 5540MHz (43)
+    0x15555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 112, Tf = 5560MHz (44)
+    0x00000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 116, Tf = 5580MHz (45)
+    0x0AAAA100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 120, Tf = 5600MHz (46)
+    0x15555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 124, Tf = 5620MHz (47)
+    0x00000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 128, Tf = 5640MHz (48)
+    0x0AAAA100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 132, Tf = 5660MHz (49)
+    0x15555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 136, Tf = 5680MHz (50)
+    0x00000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 140, Tf = 5700MHz (51)
+    0x18000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 149, Tf = 5745MHz (52)
+    0x02AAA100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 153, Tf = 5765MHz (53)
+    0x0D555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 157, Tf = 5785MHz (54)
+    0x18000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 161, Tf = 5805MHz (55)
+    0x02AAA100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW  // channel = 165, Tf = 5825MHz (56)
+    };
+
+const DWORD dwAL7230ChannelTable2[CB_MAX_CHANNEL] = {
+    0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  1, Tf = 2412MHz
+    0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  2, Tf = 2417MHz
+    0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  3, Tf = 2422MHz
+    0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  4, Tf = 2427MHz
+    0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  5, Tf = 2432MHz
+    0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  6, Tf = 2437MHz
+    0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  7, Tf = 2442MHz
+    0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  8, Tf = 2447MHz
+    0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  9, Tf = 2452MHz
+    0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 10, Tf = 2457MHz
+    0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 11, Tf = 2462MHz
+    0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 12, Tf = 2467MHz
+    0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 13, Tf = 2472MHz
+    0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 14, Tf = 2484MHz
+
+    // 4.9G => Ch 183, 184, 185, 187, 188, 189, 192, 196  (Value:15 ~ 22)
+    0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 183, Tf = 4915MHz (15)
+    0x67D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 184, Tf = 4920MHz (16)
+    0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 185, Tf = 4925MHz (17)
+    0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 187, Tf = 4935MHz (18)
+    0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 188, Tf = 4940MHz (19)
+    0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 189, Tf = 4945MHz (20)
+    0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 192, Tf = 4960MHz (21)
+    0x67D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // 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)
+    0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =   7, Tf = 5035MHz (23)
+    0x67D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =   8, Tf = 5040MHz (24)
+    0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =   9, Tf = 5045MHz (25)
+    0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  11, Tf = 5055MHz (26)
+    0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  12, Tf = 5060MHz (27)
+    0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  16, Tf = 5080MHz (28)
+    0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  34, Tf = 5170MHz (29)
+    0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  36, Tf = 5180MHz (30)
+    0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  38, Tf = 5190MHz (31)
+    0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  40, Tf = 5200MHz (32)
+    0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  42, Tf = 5210MHz (33)
+    0x67D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  44, Tf = 5220MHz (34)
+    0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  46, Tf = 5230MHz (35)
+    0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  48, Tf = 5240MHz (36)
+    0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  52, Tf = 5260MHz (37)
+    0x67D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  56, Tf = 5280MHz (38)
+    0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  60, Tf = 5300MHz (39)
+    0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  64, Tf = 5320MHz (40)
+    0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 100, Tf = 5500MHz (41)
+    0x67D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 104, Tf = 5520MHz (42)
+    0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 108, Tf = 5540MHz (43)
+    0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 112, Tf = 5560MHz (44)
+    0x67D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 116, Tf = 5580MHz (45)
+    0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 120, Tf = 5600MHz (46)
+    0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 124, Tf = 5620MHz (47)
+    0x67D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 128, Tf = 5640MHz (48)
+    0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 132, Tf = 5660MHz (49)
+    0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 136, Tf = 5680MHz (50)
+    0x67D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 140, Tf = 5700MHz (51)
+    0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 149, Tf = 5745MHz (52)
+    0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 153, Tf = 5765MHz (53)
+    0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 157, Tf = 5785MHz (54)
+    0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 161, Tf = 5805MHz (55)
+    0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW  // channel = 165, Tf = 5825MHz (56)
+    };
+//}} RobertYu
+
+
+
+
+/*---------------------  Static Functions  --------------------------*/
+
+
+
+
+/*
+ * Description: AIROHA IFRF chip init function
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - I/O base address
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if succeeded; FALSE if failed.
+ *
+ */
+BOOL s_bAL7230Init (DWORD_PTR dwIoBase)
+{
+    int     ii;
+    BOOL    bResult;
+
+    bResult = TRUE;
+
+    //3-wire control for normal mode
+    VNSvOutPortB(dwIoBase + MAC_REG_SOFTPWRCTL, 0);
+
+    MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPECTI  |
+                                                     SOFTPWRCTL_TXPEINV));
+    BBvPowerSaveModeOFF(dwIoBase); //RobertYu:20050106, have DC value for Calibration
+
+    for (ii = 0; ii < CB_AL7230_INIT_SEQ; ii++)
+        bResult &= IFRFbWriteEmbeded(dwIoBase, dwAL7230InitTable[ii]);
+
+    // PLL On
+    MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3);
+
+    //Calibration
+    MACvTimer0MicroSDelay(dwIoBase, 150);//150us
+    bResult &= IFRFbWriteEmbeded(dwIoBase, (0x9ABA8F00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW)); //TXDCOC:active, RCK:diable
+    MACvTimer0MicroSDelay(dwIoBase, 30);//30us
+    bResult &= IFRFbWriteEmbeded(dwIoBase, (0x3ABA8F00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW)); //TXDCOC:diable, RCK:active
+    MACvTimer0MicroSDelay(dwIoBase, 30);//30us
+    bResult &= IFRFbWriteEmbeded(dwIoBase, dwAL7230InitTable[CB_AL7230_INIT_SEQ-1]); //TXDCOC:diable, RCK:diable
+
+    MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPE3    |
+                                                     SOFTPWRCTL_SWPE2    |
+                                                     SOFTPWRCTL_SWPECTI  |
+                                                     SOFTPWRCTL_TXPEINV));
+
+    BBvPowerSaveModeON(dwIoBase); // RobertYu:20050106
+
+    // PE1: TX_ON, PE2: RX_ON, PE3: PLLON
+    //3-wire control for power saving mode
+    VNSvOutPortB(dwIoBase + MAC_REG_PSPWRSIG, (PSSIG_WPE3 | PSSIG_WPE2)); //1100 0000
+
+    return bResult;
+}
+
+// Need to Pull PLLON low when writing channel registers through 3-wire interface
+BOOL s_bAL7230SelectChannel (DWORD_PTR dwIoBase, BYTE byChannel)
+{
+    BOOL    bResult;
+
+    bResult = TRUE;
+
+    // PLLON Off
+    MACvWordRegBitsOff(dwIoBase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3);
+
+    bResult &= IFRFbWriteEmbeded (dwIoBase, dwAL7230ChannelTable0[byChannel-1]); //Reg0
+    bResult &= IFRFbWriteEmbeded (dwIoBase, dwAL7230ChannelTable1[byChannel-1]); //Reg1
+    bResult &= IFRFbWriteEmbeded (dwIoBase, dwAL7230ChannelTable2[byChannel-1]); //Reg4
+
+    // PLLOn On
+    MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3);
+
+    // Set Channel[7] = 0 to tell H/W channel is changing now.
+    VNSvOutPortB(dwIoBase + MAC_REG_CHANNEL, (byChannel & 0x7F));
+    MACvTimer0MicroSDelay(dwIoBase, SWITCH_CHANNEL_DELAY_AL7230);
+    // Set Channel[7] = 1 to tell H/W channel change is done.
+    VNSvOutPortB(dwIoBase + MAC_REG_CHANNEL, (byChannel | 0x80));
+
+    return bResult;
+}
+
+/*
+ * Description: Select channel with UW2452 chip
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - I/O base address
+ *      uChannel    - Channel number
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if succeeded; FALSE if failed.
+ *
+ */
+
+
+//{{ RobertYu: 20041210
+/*
+ * Description: UW2452 IFRF chip init function
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - I/O base address
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if succeeded; FALSE if failed.
+ *
+ */
+
+
+
+//}} RobertYu
+////////////////////////////////////////////////////////////////////////////////
+
+/*
+ * Description: VT3226 IFRF chip init function
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - I/O base address
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if succeeded; FALSE if failed.
+ *
+ */
+
+/*
+ * Description: Select channel with VT3226 chip
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - I/O base address
+ *      uChannel    - Channel number
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if succeeded; FALSE if failed.
+ *
+ */
+
+
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+/*
+ * Description: Write to IF/RF, by embeded programming
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - I/O base address
+ *      dwData      - data to write
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if succeeded; FALSE if failed.
+ *
+ */
+BOOL IFRFbWriteEmbeded (DWORD_PTR dwIoBase, DWORD dwData)
+{
+    WORD    ww;
+    DWORD   dwValue;
+
+    VNSvOutPortD(dwIoBase + MAC_REG_IFREGCTL, dwData);
+
+    // W_MAX_TIMEOUT is the timeout period
+    for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+        VNSvInPortD(dwIoBase + MAC_REG_IFREGCTL, &dwValue);
+        if (BITbIsBitOn(dwValue, IFREGCTL_DONE))
+            break;
+    }
+
+    if (ww == W_MAX_TIMEOUT) {
+//        DBG_PORT80_ALWAYS(0x32);
+        return FALSE;
+    }
+    return TRUE;
+}
+
+
+
+/*
+ * Description: RFMD RF2959 IFRF chip init function
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - I/O base address
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if succeeded; FALSE if failed.
+ *
+ */
+
+/*
+ * Description: Select channel with RFMD 2959 chip
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - I/O base address
+ *      uChannel    - Channel number
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if succeeded; FALSE if failed.
+ *
+ */
+
+/*
+ * Description: AIROHA IFRF chip init function
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - I/O base address
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if succeeded; FALSE if failed.
+ *
+ */
+BOOL RFbAL2230Init (DWORD_PTR dwIoBase)
+{
+    int     ii;
+    BOOL    bResult;
+
+    bResult = TRUE;
+
+    //3-wire control for normal mode
+    VNSvOutPortB(dwIoBase + MAC_REG_SOFTPWRCTL, 0);
+
+    MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPECTI  |
+                                                     SOFTPWRCTL_TXPEINV));
+//2008-8-21 chester <add>
+    // PLL  Off
+
+    MACvWordRegBitsOff(dwIoBase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3);
+
+
+
+    //patch abnormal AL2230 frequency output
+//2008-8-21 chester <add>
+    IFRFbWriteEmbeded(dwIoBase, (0x07168700+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW));
+
+
+    for (ii = 0; ii < CB_AL2230_INIT_SEQ; ii++)
+        bResult &= IFRFbWriteEmbeded(dwIoBase, dwAL2230InitTable[ii]);
+//2008-8-21 chester <add>
+MACvTimer0MicroSDelay(dwIoBase, 30); //delay 30 us
+
+    // PLL On
+    MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3);
+
+    MACvTimer0MicroSDelay(dwIoBase, 150);//150us
+    bResult &= IFRFbWriteEmbeded(dwIoBase, (0x00d80f00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW));
+    MACvTimer0MicroSDelay(dwIoBase, 30);//30us
+    bResult &= IFRFbWriteEmbeded(dwIoBase, (0x00780f00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW));
+    MACvTimer0MicroSDelay(dwIoBase, 30);//30us
+    bResult &= IFRFbWriteEmbeded(dwIoBase, dwAL2230InitTable[CB_AL2230_INIT_SEQ-1]);
+
+    MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPE3    |
+                                                     SOFTPWRCTL_SWPE2    |
+                                                     SOFTPWRCTL_SWPECTI  |
+                                                     SOFTPWRCTL_TXPEINV));
+
+    //3-wire control for power saving mode
+    VNSvOutPortB(dwIoBase + MAC_REG_PSPWRSIG, (PSSIG_WPE3 | PSSIG_WPE2)); //1100 0000
+
+    return bResult;
+}
+
+BOOL RFbAL2230SelectChannel (DWORD_PTR dwIoBase, BYTE byChannel)
+{
+    BOOL    bResult;
+
+    bResult = TRUE;
+
+    bResult &= IFRFbWriteEmbeded (dwIoBase, dwAL2230ChannelTable0[byChannel-1]);
+    bResult &= IFRFbWriteEmbeded (dwIoBase, dwAL2230ChannelTable1[byChannel-1]);
+
+    // Set Channel[7] = 0 to tell H/W channel is changing now.
+    VNSvOutPortB(dwIoBase + MAC_REG_CHANNEL, (byChannel & 0x7F));
+    MACvTimer0MicroSDelay(dwIoBase, SWITCH_CHANNEL_DELAY_AL2230);
+    // Set Channel[7] = 1 to tell H/W channel change is done.
+    VNSvOutPortB(dwIoBase + MAC_REG_CHANNEL, (byChannel | 0x80));
+
+    return bResult;
+}
+
+/*
+ * Description: UW2451 IFRF chip init function
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - I/O base address
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if succeeded; FALSE if failed.
+ *
+ */
+
+
+/*
+ * Description: Select channel with UW2451 chip
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - I/O base address
+ *      uChannel    - Channel number
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if succeeded; FALSE if failed.
+ *
+ */
+
+/*
+ * Description: Set sleep mode to UW2451 chip
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - I/O base address
+ *      uChannel    - Channel number
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if succeeded; FALSE if failed.
+ *
+ */
+
+/*
+ * Description: RF init function
+ *
+ * Parameters:
+ *  In:
+ *      byBBType
+ *      byRFType
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if succeeded; FALSE if failed.
+ *
+ */
+BOOL RFbInit (
+    IN  PSDevice  pDevice
+    )
+{
+BOOL    bResult = TRUE;
+    switch (pDevice->byRFType) {
+        case RF_AIROHA :
+        case RF_AL2230S:
+            pDevice->byMaxPwrLevel = AL2230_PWR_IDX_LEN;
+            bResult = RFbAL2230Init(pDevice->PortOffset);
+            break;
+        case RF_AIROHA7230 :
+            pDevice->byMaxPwrLevel = AL7230_PWR_IDX_LEN;
+            bResult = s_bAL7230Init(pDevice->PortOffset);
+            break;
+        case RF_NOTHING :
+            bResult = TRUE;
+            break;
+        default :
+            bResult = FALSE;
+            break;
+    }
+    return bResult;
+}
+
+/*
+ * Description: RF ShutDown function
+ *
+ * Parameters:
+ *  In:
+ *      byBBType
+ *      byRFType
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if succeeded; FALSE if failed.
+ *
+ */
+BOOL RFbShutDown (
+    IN  PSDevice  pDevice
+    )
+{
+BOOL    bResult = TRUE;
+
+    switch (pDevice->byRFType) {
+        case RF_AIROHA7230 :
+            bResult = IFRFbWriteEmbeded (pDevice->PortOffset, 0x1ABAEF00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW);
+            break;
+        default :
+            bResult = TRUE;
+            break;
+    }
+    return bResult;
+}
+
+/*
+ * Description: Select channel
+ *
+ * Parameters:
+ *  In:
+ *      byRFType
+ *      byChannel    - Channel number
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if succeeded; FALSE if failed.
+ *
+ */
+BOOL RFbSelectChannel (DWORD_PTR dwIoBase, BYTE byRFType, BYTE byChannel)
+{
+BOOL    bResult = TRUE;
+    switch (byRFType) {
+
+        case RF_AIROHA :
+        case RF_AL2230S:
+            bResult = RFbAL2230SelectChannel(dwIoBase, byChannel);
+            break;
+        //{{ RobertYu: 20050104
+        case RF_AIROHA7230 :
+            bResult = s_bAL7230SelectChannel(dwIoBase, byChannel);
+            break;
+        //}} RobertYu
+        case RF_NOTHING :
+            bResult = TRUE;
+            break;
+        default:
+            bResult = FALSE;
+            break;
+    }
+    return bResult;
+}
+
+/*
+ * Description: Write WakeProgSyn
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - I/O base address
+ *      uChannel    - channel number
+ *      bySleepCnt  - SleepProgSyn count
+ *
+ * Return Value: None.
+ *
+ */
+BOOL RFvWriteWakeProgSyn (DWORD_PTR dwIoBase, BYTE byRFType, UINT uChannel)
+{
+    int   ii;
+    BYTE  byInitCount = 0;
+    BYTE  bySleepCount = 0;
+
+    VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, 0);
+    switch (byRFType) {
+        case RF_AIROHA:
+        case RF_AL2230S:
+
+            if (uChannel > CB_MAX_CHANNEL_24G)
+                return FALSE;
+
+            byInitCount = CB_AL2230_INIT_SEQ + 2; // Init Reg + Channel Reg (2)
+            bySleepCount = 0;
+            if (byInitCount > (MISCFIFO_SYNDATASIZE - bySleepCount)) {
+                return FALSE;
+            }
+
+            for (ii = 0; ii < CB_AL2230_INIT_SEQ; ii++ ) {
+                MACvSetMISCFifo(dwIoBase, (WORD)(MISCFIFO_SYNDATA_IDX + ii), dwAL2230InitTable[ii]);
+            }
+            MACvSetMISCFifo(dwIoBase, (WORD)(MISCFIFO_SYNDATA_IDX + ii), dwAL2230ChannelTable0[uChannel-1]);
+            ii ++;
+            MACvSetMISCFifo(dwIoBase, (WORD)(MISCFIFO_SYNDATA_IDX + ii), dwAL2230ChannelTable1[uChannel-1]);
+            break;
+
+        //{{ RobertYu: 20050104
+        // Need to check, PLLON need to be low for channel setting
+        case RF_AIROHA7230:
+            byInitCount = CB_AL7230_INIT_SEQ + 3; // Init Reg + Channel Reg (3)
+            bySleepCount = 0;
+            if (byInitCount > (MISCFIFO_SYNDATASIZE - bySleepCount)) {
+                return FALSE;
+            }
+
+            if (uChannel <= CB_MAX_CHANNEL_24G)
+            {
+                for (ii = 0; ii < CB_AL7230_INIT_SEQ; ii++ ) {
+                    MACvSetMISCFifo(dwIoBase, (WORD)(MISCFIFO_SYNDATA_IDX + ii), dwAL7230InitTable[ii]);
+                }
+            }
+            else
+            {
+                for (ii = 0; ii < CB_AL7230_INIT_SEQ; ii++ ) {
+                    MACvSetMISCFifo(dwIoBase, (WORD)(MISCFIFO_SYNDATA_IDX + ii), dwAL7230InitTableAMode[ii]);
+                }
+            }
+
+            MACvSetMISCFifo(dwIoBase, (WORD)(MISCFIFO_SYNDATA_IDX + ii), dwAL7230ChannelTable0[uChannel-1]);
+            ii ++;
+            MACvSetMISCFifo(dwIoBase, (WORD)(MISCFIFO_SYNDATA_IDX + ii), dwAL7230ChannelTable1[uChannel-1]);
+            ii ++;
+            MACvSetMISCFifo(dwIoBase, (WORD)(MISCFIFO_SYNDATA_IDX + ii), dwAL7230ChannelTable2[uChannel-1]);
+            break;
+        //}} RobertYu
+
+        case RF_NOTHING :
+            return TRUE;
+            break;
+
+        default:
+            return FALSE;
+            break;
+    }
+
+    MACvSetMISCFifo(dwIoBase, MISCFIFO_SYNINFO_IDX, (DWORD)MAKEWORD(bySleepCount, byInitCount));
+
+    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 = 0;
+BYTE    byDec = 0;
+BYTE    byPwrdBm = 0;
+
+    if (pDevice->dwDiagRefCount != 0) {
+        return TRUE;
+    }
+    if ((uCH < 1) || (uCH > CB_MAX_CHANNEL)) {
+        return FALSE;
+    }
+
+    switch (uRATE) {
+    case RATE_1M:
+    case RATE_2M:
+    case RATE_5M:
+    case RATE_11M:
+        byPwr = pDevice->abyCCKPwrTbl[uCH];
+        byPwrdBm = pDevice->abyCCKDefaultPwr[uCH];
+//PLICE_DEBUG->
+       //byPwr+=5;
+//PLICE_DEBUG <-
+
+//printk("Rate <11:byPwr is %d\n",byPwr);
+               break;
+    case RATE_6M:
+    case RATE_9M:
+    case RATE_18M:
+        byPwr = pDevice->abyOFDMPwrTbl[uCH];
+        if (pDevice->byRFType == RF_UW2452) {
+            byDec = byPwr + 14;
+        } else {
+            byDec = byPwr + 10;
+        }
+        if (byDec >= pDevice->byMaxPwrLevel) {
+            byDec = pDevice->byMaxPwrLevel-1;
+        }
+        if (pDevice->byRFType == RF_UW2452) {
+            byPwrdBm = byDec - byPwr;
+            byPwrdBm /= 3;
+        } else {
+            byPwrdBm = byDec - byPwr;
+            byPwrdBm >>= 1;
+        }
+        byPwrdBm += pDevice->abyOFDMDefaultPwr[uCH];
+        byPwr = byDec;
+//PLICE_DEBUG->
+       //byPwr+=5;
+//PLICE_DEBUG<-
+
+//printk("Rate <24:byPwr is %d\n",byPwr);
+               break;
+    case RATE_24M:
+    case RATE_36M:
+    case RATE_48M:
+    case RATE_54M:
+        byPwr = pDevice->abyOFDMPwrTbl[uCH];
+        byPwrdBm = pDevice->abyOFDMDefaultPwr[uCH];
+//PLICE_DEBUG->
+       //byPwr+=5;
+//PLICE_DEBUG<-
+//printk("Rate < 54:byPwr is %d\n",byPwr);
+               break;
+    }
+
+#if 0
+
+    // 802.11h TPC
+    if (pDevice->bLinkPass == TRUE) {
+        // do not over local constraint
+        if (byPwrdBm > pDevice->abyLocalPwr[uCH]) {
+            pDevice->byCurPwrdBm = pDevice->abyLocalPwr[uCH];
+            byDec = byPwrdBm - pDevice->abyLocalPwr[uCH];
+            if (pDevice->byRFType == RF_UW2452) {
+                byDec *= 3;
+            } else {
+                byDec <<= 1;
+            }
+            if (byPwr > byDec) {
+                byPwr -= byDec;
+            } else {
+                byPwr = 0;
+            }
+        } else {
+            pDevice->byCurPwrdBm = byPwrdBm;
+        }
+    } else {
+        // do not over regulatory constraint
+        if (byPwrdBm > pDevice->abyRegPwr[uCH]) {
+            pDevice->byCurPwrdBm = pDevice->abyRegPwr[uCH];
+            byDec = byPwrdBm - pDevice->abyRegPwr[uCH];
+            if (pDevice->byRFType == RF_UW2452) {
+                byDec *= 3;
+            } else {
+                byDec <<= 1;
+            }
+            if (byPwr > byDec) {
+                byPwr -= byDec;
+            } else {
+                byPwr = 0;
+            }
+        } else {
+            pDevice->byCurPwrdBm = byPwrdBm;
+        }
+    }
+#endif
+
+//    if (pDevice->byLocalID <= REV_ID_VT3253_B1) {
+    if (pDevice->byCurPwr == byPwr) {
+        return TRUE;
+    }
+    bResult = RFbRawSetPower(pDevice, byPwr, uRATE);
+//    }
+    if (bResult == TRUE) {
+       pDevice->byCurPwr = byPwr;
+    }
+    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;
+DWORD   dwMax7230Pwr = 0;
+
+    if (byPwr >=  pDevice->byMaxPwrLevel) {
+        return (FALSE);
+    }
+    switch (pDevice->byRFType) {
+
+        case RF_AIROHA :
+            bResult &= IFRFbWriteEmbeded(pDevice->PortOffset, dwAL2230PowerTable[byPwr]);
+            if (uRATE <= RATE_11M) {
+                bResult &= IFRFbWriteEmbeded(pDevice->PortOffset, 0x0001B400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW);
+            } else {
+                bResult &= IFRFbWriteEmbeded(pDevice->PortOffset, 0x0005A400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW);
+            }
+            break;
+
+
+        case RF_AL2230S :
+            bResult &= IFRFbWriteEmbeded(pDevice->PortOffset, dwAL2230PowerTable[byPwr]);
+            if (uRATE <= RATE_11M) {
+                bResult &= IFRFbWriteEmbeded(pDevice->PortOffset, 0x040C1400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW);
+                bResult &= IFRFbWriteEmbeded(pDevice->PortOffset, 0x00299B00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW);
+            }else {
+                bResult &= IFRFbWriteEmbeded(pDevice->PortOffset, 0x0005A400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW);
+                bResult &= IFRFbWriteEmbeded(pDevice->PortOffset, 0x00099B00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW);
+            }
+
+            break;
+
+        case RF_AIROHA7230:
+            //  0x080F1B00 for 3 wire control TxGain(D10) and 0x31 as TX Gain value
+            dwMax7230Pwr = 0x080C0B00 | ( (byPwr) << 12 ) |
+                           (BY_AL7230_REG_LEN << 3 )  | IFREGCTL_REGW;
+
+            bResult &= IFRFbWriteEmbeded(pDevice->PortOffset, dwMax7230Pwr);
+            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_AIROHA:
+        case RF_AL2230S:
+        case RF_AIROHA7230: //RobertYu: 20040104
+            a = abyAIROHARF[byIdx];
+            break;
+        default:
+            break;
+    }
+
+    *pldBm = -1 * (a + b * 2);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//{{ RobertYu: 20050104
+
+
+// Post processing for the 11b/g and 11a.
+// for save time on changing Reg2,3,5,7,10,12,15
+BOOL RFbAL7230SelectChannelPostProcess (DWORD_PTR dwIoBase, BYTE byOldChannel, BYTE byNewChannel)
+{
+    BOOL    bResult;
+
+    bResult = TRUE;
+
+    // if change between 11 b/g and 11a need to update the following register
+    // Channel Index 1~14
+
+    if( (byOldChannel <= CB_MAX_CHANNEL_24G) && (byNewChannel > CB_MAX_CHANNEL_24G) )
+    {
+        // Change from 2.4G to 5G
+        bResult &= IFRFbWriteEmbeded(dwIoBase, dwAL7230InitTableAMode[2]); //Reg2
+        bResult &= IFRFbWriteEmbeded(dwIoBase, dwAL7230InitTableAMode[3]); //Reg3
+        bResult &= IFRFbWriteEmbeded(dwIoBase, dwAL7230InitTableAMode[5]); //Reg5
+        bResult &= IFRFbWriteEmbeded(dwIoBase, dwAL7230InitTableAMode[7]); //Reg7
+        bResult &= IFRFbWriteEmbeded(dwIoBase, dwAL7230InitTableAMode[10]);//Reg10
+        bResult &= IFRFbWriteEmbeded(dwIoBase, dwAL7230InitTableAMode[12]);//Reg12
+        bResult &= IFRFbWriteEmbeded(dwIoBase, dwAL7230InitTableAMode[15]);//Reg15
+    }
+    else if( (byOldChannel > CB_MAX_CHANNEL_24G) && (byNewChannel <= CB_MAX_CHANNEL_24G) )
+    {
+        // change from 5G to 2.4G
+        bResult &= IFRFbWriteEmbeded(dwIoBase, dwAL7230InitTable[2]); //Reg2
+        bResult &= IFRFbWriteEmbeded(dwIoBase, dwAL7230InitTable[3]); //Reg3
+        bResult &= IFRFbWriteEmbeded(dwIoBase, dwAL7230InitTable[5]); //Reg5
+        bResult &= IFRFbWriteEmbeded(dwIoBase, dwAL7230InitTable[7]); //Reg7
+        bResult &= IFRFbWriteEmbeded(dwIoBase, dwAL7230InitTable[10]);//Reg10
+        bResult &= IFRFbWriteEmbeded(dwIoBase, dwAL7230InitTable[12]);//Reg12
+        bResult &= IFRFbWriteEmbeded(dwIoBase, dwAL7230InitTable[15]);//Reg15
+    }
+
+    return bResult;
+}
+
+
+//}} RobertYu
+////////////////////////////////////////////////////////////////////////////////
+
diff --git a/drivers/staging/vt6655/rf.h b/drivers/staging/vt6655/rf.h
new file mode 100644 (file)
index 0000000..05fe17b
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * 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_AIROHA               0x03
+
+//#define RF_GCT5103              0x04
+#define RF_UW2451               0x05
+#define RF_MAXIMG               0x06
+#define RF_MAXIM2829            0x07 // RobertYu: 20041118
+#define RF_UW2452               0x08 // RobertYu: 20041210
+#define RF_AIROHA7230           0x0a // RobertYu: 20050104
+#define RF_UW2453               0x0b
+
+#define RF_VT3226               0x09
+#define RF_AL2230S              0x0e
+
+#define RF_NOTHING              0x7E
+#define RF_EMU                  0x80
+#define RF_MASK                 0x7F
+
+#define ZONE_FCC                0
+#define ZONE_MKK1               1
+#define ZONE_ETSI               2
+#define ZONE_IC                 3
+#define ZONE_SPAIN              4
+#define ZONE_FRANCE             5
+#define ZONE_MKK                6
+#define ZONE_ISRAEL             7
+
+//[20050104] CB_MAXIM2829_CHANNEL_5G_HIGH, CB_UW2452_CHANNEL_5G_HIGH: 40==>41
+#define CB_MAXIM2829_CHANNEL_5G_HIGH    41 //Index41: channel = 100, Tf = 5500MHz, set the (A3:A0=0101) D6=1
+#define CB_UW2452_CHANNEL_5G_HIGH       41 //[20041210] Index41: channel = 100, Tf = 5500MHz, change VCO2->VCO3
+
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+#ifdef __cplusplus
+extern "C" {                            /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+BOOL IFRFbWriteEmbeded(DWORD_PTR dwIoBase, DWORD dwData);
+BOOL RFbSelectChannel(DWORD_PTR dwIoBase, BYTE byRFType, BYTE byChannel);
+BOOL RFbInit (
+    IN  PSDevice  pDevice
+    );
+BOOL RFvWriteWakeProgSyn(DWORD_PTR dwIoBase, BYTE byRFType, UINT uChannel);
+BOOL RFbSetPower(PSDevice pDevice, UINT uRATE, UINT uCH);
+BOOL RFbRawSetPower(
+    IN  PSDevice  pDevice,
+    IN  BYTE      byPwr,
+    IN  UINT      uRATE
+    );
+
+VOID
+RFvRSSITodBm(
+    IN  PSDevice pDevice,
+    IN  BYTE     byCurrRSSI,
+    OUT PLONG    pldBm
+    );
+
+//{{ RobertYu: 20050104
+BOOL RFbAL7230SelectChannelPostProcess(DWORD_PTR dwIoBase, BYTE byOldChannel, BYTE byNewChannel);
+//}} RobertYu
+
+#ifdef __cplusplus
+}                                       /* End of extern "C" { */
+#endif /* __cplusplus */
+
+
+#endif // __RF_H__
+
+
+
diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c
new file mode 100644 (file)
index 0000000..c8a4a55
--- /dev/null
@@ -0,0 +1,3269 @@
+/*
+ * 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.
+ *      vGenerateMACHeader - Translate 802.3 to 802.11 header
+ *      cbGetFragCount - Caculate fragement number count
+ *      csBeacon_xmit - beacon tx function
+ *      csMgmt_xmit - management tx function
+ *      s_cbFillTxBufHead - fulfill tx dma buffer header
+ *      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(__WROUTE_H__)
+#include "wroute.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
+
+/*---------------------  Static Definitions -------------------------*/
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+static int          msglevel                =MSG_LEVEL_INFO;
+
+#define        PLICE_DEBUG
+
+
+/*---------------------  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_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_vFillRTSHead(
+    IN PSDevice         pDevice,
+    IN BYTE             byPktTyp,
+    IN PVOID            pvRTS,
+    IN UINT             cbFrameLength,
+    IN BOOL             bNeedAck,
+    IN BOOL             bDisCRC,
+    IN PSEthernetHeader psEthHeader,
+    IN WORD             wCurrentRate,
+    IN BYTE             byFBOption
+    );
+
+static
+VOID
+s_vGenerateTxParameter(
+    IN PSDevice         pDevice,
+    IN  BYTE            byPktTyp,
+    IN PVOID            pTxBufHead,
+    IN PVOID            pvRrvTime,
+    IN PVOID            pvRTS,
+    IN PVOID            pvCTS,
+    IN UINT             cbFrameSize,
+    IN BOOL             bNeedACK,
+    IN UINT             uDMAIdx,
+    IN PSEthernetHeader psEthHeader,
+    IN WORD             wCurrentRate
+    );
+
+
+
+static void s_vFillFragParameter(
+    IN PSDevice pDevice,
+    IN PBYTE    pbyBuffer,
+    IN UINT     uTxType,
+    IN PVOID    pvtdCurr,
+    IN WORD     wFragType,
+    IN UINT     cbReqCount
+    );
+
+
+static
+UINT
+s_cbFillTxBufHead (
+    IN  PSDevice         pDevice,
+    IN  BYTE             byPktTyp,
+    IN  PBYTE            pbyTxBufferAddr,
+    IN  UINT             cbFrameBodySize,
+    IN  UINT             uDMAIdx,
+    IN  PSTxDesc         pHeadTD,
+    IN  PSEthernetHeader psEthHeader,
+    IN  PBYTE            pPacket,
+    IN  BOOL             bNeedEncrypt,
+    IN  PSKeyItem        pTransmitKey,
+    IN  UINT             uNodeIndex,
+    OUT PUINT            puMACfragNum
+    );
+
+
+static
+UINT
+s_uFillDataHead (
+    IN PSDevice pDevice,
+    IN BYTE     byPktTyp,
+    IN PVOID    pTxDataHead,
+    IN UINT     cbFrameLength,
+    IN UINT     uDMAIdx,
+    IN BOOL     bNeedAck,
+    IN UINT     uFragIdx,
+    IN UINT     cbLastFragmentSize,
+    IN UINT     uMACfragNum,
+    IN BYTE     byFBOption,
+    IN WORD     wCurrentRate
+    );
+
+
+/*---------------------  Export Variables  --------------------------*/
+
+
+
+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;
+    BYTE            byKeyIndex = 0;
+
+
+
+    //Fill TXKEY
+    if (pTransmitKey == NULL)
+        return;
+
+    dwRevIVCounter = cpu_to_le32(pDevice->dwIVCounter);
+    *pdwIV = pDevice->dwIVCounter;
+    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 |= (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)(((byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV
+        // Append IV&ExtIV after Mac Header
+        *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16);
+        DEVICE_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)(((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);
+        //=======================================================================
+    }
+}
+
+
+
+
+/*byPktTyp : 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     byPktTyp,
+    IN UINT     cbFrameLength,
+    IN WORD     wRate,
+    IN BOOL     bNeedAck
+    )
+{
+    UINT uDataTime, uAckTime;
+
+    uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktTyp, cbFrameLength, wRate);
+#ifdef PLICE_DEBUG
+       //printk("s_uGetTxRsvTime is %d\n",uDataTime);
+#endif
+    if (byPktTyp == PK_TYPE_11B) {//llb,CCK mode
+        uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktTyp, 14, (WORD)pDevice->byTopCCKBasicRate);
+    } else {//11g 2.4G OFDM mode & 11a 5G OFDM mode
+        uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktTyp, 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 byPktTyp,
+    IN UINT cbFrameLength,
+    IN WORD wCurrentRate
+    )
+{
+    UINT uRrvTime  , uRTSTime, uCTSTime, uAckTime, uDataTime;
+
+    uRrvTime = uRTSTime = uCTSTime = uAckTime = uDataTime = 0;
+
+
+    uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktTyp, cbFrameLength, wCurrentRate);
+    if (byRTSRsvType == 0) { //RTSTxRrvTime_bb
+        uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktTyp, 20, pDevice->byTopCCKBasicRate);
+        uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktTyp, 14, pDevice->byTopCCKBasicRate);
+    }
+    else if (byRTSRsvType == 1){ //RTSTxRrvTime_ba, only in 2.4GHZ
+        uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktTyp, 20, pDevice->byTopCCKBasicRate);
+        uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktTyp, 14, pDevice->byTopCCKBasicRate);
+        uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktTyp, 14, pDevice->byTopOFDMBasicRate);
+    }
+    else if (byRTSRsvType == 2) { //RTSTxRrvTime_aa
+        uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktTyp, 20, pDevice->byTopOFDMBasicRate);
+        uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktTyp, 14, pDevice->byTopOFDMBasicRate);
+    }
+    else if (byRTSRsvType == 3) { //CTSTxRrvTime_ba, only in 2.4GHZ
+        uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktTyp, 14, pDevice->byTopCCKBasicRate);
+        uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktTyp, 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)) {
+            uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][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_RATE1][wRate-RATE_18M], bNeedAck);
+        }
+        break;
+
+    case RTSDUR_AA_F1: //RTSDuration_aa_f1
+        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_RATE1][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_RATE1][wRate-RATE_18M], bNeedAck);
+        }
+        break;
+
+    case CTSDUR_BA_F0: //CTSDuration_ba_f0
+        if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
+            uDurTime = 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 = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
+        }
+        break;
+
+    case CTSDUR_BA_F1: //CTSDuration_ba_f1
+        if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
+            uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
+        } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
+            uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
+        }
+        break;
+
+    default:
+        break;
+    }
+
+    return uDurTime;
+
+}
+
+
+
+static
+UINT
+s_uFillDataHead (
+    IN PSDevice pDevice,
+    IN BYTE     byPktTyp,
+    IN PVOID    pTxDataHead,
+    IN UINT     cbFrameLength,
+    IN UINT     uDMAIdx,
+    IN BOOL     bNeedAck,
+    IN UINT     uFragIdx,
+    IN UINT     cbLastFragmentSize,
+    IN UINT     uMACfragNum,
+    IN BYTE     byFBOption,
+    IN WORD     wCurrentRate
+    )
+{
+    WORD  wLen = 0x0000;
+
+    if (pTxDataHead == NULL) {
+        return 0;
+    }
+
+    if (byPktTyp == PK_TYPE_11GB || byPktTyp == PK_TYPE_11GA) {
+        if (byFBOption == AUTO_FB_NONE) {
+            PSTxDataHead_g pBuf = (PSTxDataHead_g)pTxDataHead;
+            //Get SignalField,ServiceField,Length
+            BBvCaculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktTyp,
+                (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_a), (PBYTE)&(pBuf->bySignalField_a)
+            );
+            pBuf->wTransmitLength_a = cpu_to_le16(wLen);
+            BBvCaculateParameter(pDevice, cbFrameLength, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
+                (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_b), (PBYTE)&(pBuf->bySignalField_b)
+            );
+            pBuf->wTransmitLength_b = cpu_to_le16(wLen);
+            //Get Duration and TimeStamp
+            pBuf->wDuration_a = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength,
+                                                         byPktTyp, wCurrentRate, bNeedAck, uFragIdx,
+                                                         cbLastFragmentSize, uMACfragNum,
+                                                         byFBOption)); //1: 2.4GHz
+            pBuf->wDuration_b = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength,
+                                                         PK_TYPE_11B, pDevice->byTopCCKBasicRate,
+                                                         bNeedAck, uFragIdx, cbLastFragmentSize,
+                                                         uMACfragNum, byFBOption)); //1: 2.4
+
+            pBuf->wTimeStampOff_a = cpu_to_le16(wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE]);
+            pBuf->wTimeStampOff_b = cpu_to_le16(wTimeStampOff[pDevice->byPreambleType%2][pDevice->byTopCCKBasicRate%MAX_RATE]);
+
+            return (pBuf->wDuration_a);
+         } else {
+            // Auto Fallback
+            PSTxDataHead_g_FB pBuf = (PSTxDataHead_g_FB)pTxDataHead;
+            //Get SignalField,ServiceField,Length
+            BBvCaculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktTyp,
+                (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_a), (PBYTE)&(pBuf->bySignalField_a)
+            );
+            pBuf->wTransmitLength_a = cpu_to_le16(wLen);
+            BBvCaculateParameter(pDevice, cbFrameLength, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
+                (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_b), (PBYTE)&(pBuf->bySignalField_b)
+            );
+            pBuf->wTransmitLength_b = cpu_to_le16(wLen);
+            //Get Duration and TimeStamp
+            pBuf->wDuration_a = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktTyp,
+                                         wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //1: 2.4GHz
+            pBuf->wDuration_b = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, PK_TYPE_11B,
+                                         pDevice->byTopCCKBasicRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //1: 2.4GHz
+            pBuf->wDuration_a_f0 = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktTyp,
+                                         wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //1: 2.4GHz
+            pBuf->wDuration_a_f1 = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktTyp,
+                                         wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //1: 2.4GHz
+
+            pBuf->wTimeStampOff_a = cpu_to_le16(wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE]);
+            pBuf->wTimeStampOff_b = cpu_to_le16(wTimeStampOff[pDevice->byPreambleType%2][pDevice->byTopCCKBasicRate%MAX_RATE]);
+
+            return (pBuf->wDuration_a);
+        } //if (byFBOption == AUTO_FB_NONE)
+    }
+    else if (byPktTyp == PK_TYPE_11A) {
+        if ((byFBOption != AUTO_FB_NONE)) {
+            // Auto Fallback
+            PSTxDataHead_a_FB pBuf = (PSTxDataHead_a_FB)pTxDataHead;
+            //Get SignalField,ServiceField,Length
+            BBvCaculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktTyp,
+                (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField)
+            );
+            pBuf->wTransmitLength = cpu_to_le16(wLen);
+            //Get Duration and TimeStampOff
+
+            pBuf->wDuration = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktTyp,
+                                        wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //0: 5GHz
+            pBuf->wDuration_f0 = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktTyp,
+                                        wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //0: 5GHz
+            pBuf->wDuration_f1 = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktTyp,
+                                        wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //0: 5GHz
+            pBuf->wTimeStampOff = cpu_to_le16(wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE]);
+            return (pBuf->wDuration);
+        } else {
+            PSTxDataHead_ab pBuf = (PSTxDataHead_ab)pTxDataHead;
+            //Get SignalField,ServiceField,Length
+            BBvCaculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktTyp,
+                (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField)
+            );
+            pBuf->wTransmitLength = cpu_to_le16(wLen);
+            //Get Duration and TimeStampOff
+
+            pBuf->wDuration = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktTyp,
+                                                       wCurrentRate, bNeedAck, uFragIdx,
+                                                       cbLastFragmentSize, uMACfragNum,
+                                                       byFBOption));
+
+            pBuf->wTimeStampOff = cpu_to_le16(wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE]);
+            return (pBuf->wDuration);
+        }
+    }
+    else {
+            PSTxDataHead_ab pBuf = (PSTxDataHead_ab)pTxDataHead;
+            //Get SignalField,ServiceField,Length
+            BBvCaculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktTyp,
+                (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField)
+            );
+            pBuf->wTransmitLength = cpu_to_le16(wLen);
+            //Get Duration and TimeStampOff
+            pBuf->wDuration = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktTyp,
+                                                       wCurrentRate, bNeedAck, uFragIdx,
+                                                       cbLastFragmentSize, uMACfragNum,
+                                                       byFBOption));
+            pBuf->wTimeStampOff = cpu_to_le16(wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE]);
+            return (pBuf->wDuration);
+    }
+    return 0;
+}
+
+
+static
+VOID
+s_vFillRTSHead (
+    IN PSDevice         pDevice,
+    IN BYTE             byPktTyp,
+    IN PVOID            pvRTS,
+    IN UINT             cbFrameLength,
+    IN BOOL             bNeedAck,
+    IN BOOL             bDisCRC,
+    IN PSEthernetHeader psEthHeader,
+    IN WORD             wCurrentRate,
+    IN BYTE             byFBOption
+    )
+{
+    UINT uRTSFrameLen = 20;
+    WORD  wLen = 0x0000;
+
+    // dummy code, only to avoid compiler warning message
+    UNREFERENCED_PARAMETER(bNeedAck);
+
+    if (pvRTS == NULL)
+       return;
+
+    if (bDisCRC) {
+        // When CRCDIS bit is on, H/W forgot to generate FCS for RTS frame,
+        // in this case we need to decrease its length by 4.
+        uRTSFrameLen -= 4;
+    }
+
+    // Note: So far RTSHead dosen't appear in ATIM & Beacom DMA, so we don't need to take them into account.
+    //       Otherwise, we need to modified codes for them.
+    if (byPktTyp == PK_TYPE_11GB || byPktTyp == PK_TYPE_11GA) {
+        if (byFBOption == AUTO_FB_NONE) {
+            PSRTS_g pBuf = (PSRTS_g)pvRTS;
+            //Get SignalField,ServiceField,Length
+            BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
+                (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_b), (PBYTE)&(pBuf->bySignalField_b)
+            );
+            pBuf->wTransmitLength_b = cpu_to_le16(wLen);
+            BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktTyp,
+                (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_a), (PBYTE)&(pBuf->bySignalField_a)
+            );
+            pBuf->wTransmitLength_a = cpu_to_le16(wLen);
+            //Get Duration
+            pBuf->wDuration_bb = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, PK_TYPE_11B, pDevice->byTopCCKBasicRate, bNeedAck, byFBOption));    //0:RTSDuration_bb, 1:2.4G, 1:CCKData
+            pBuf->wDuration_aa = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktTyp, wCurrentRate, bNeedAck, byFBOption)); //2:RTSDuration_aa, 1:2.4G, 2,3: 2.4G OFDMData
+            pBuf->wDuration_ba = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA, cbFrameLength, byPktTyp, wCurrentRate, bNeedAck, byFBOption)); //1:RTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data
+
+            pBuf->Data.wDurationID = pBuf->wDuration_aa;
+            //Get RTS Frame body
+            pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4
+            if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
+                (pDevice->eOPMode == OP_MODE_AP)) {
+                MEMvCopy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN);
+            }
+            else {
+                MEMvCopy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
+            }
+            if (pDevice->eOPMode == OP_MODE_AP) {
+                MEMvCopy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
+            }
+            else {
+                MEMvCopy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN);
+            }
+        }
+        else {
+           PSRTS_g_FB pBuf = (PSRTS_g_FB)pvRTS;
+            //Get SignalField,ServiceField,Length
+            BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
+                (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_b), (PBYTE)&(pBuf->bySignalField_b)
+            );
+            pBuf->wTransmitLength_b = cpu_to_le16(wLen);
+            BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktTyp,
+                (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_a), (PBYTE)&(pBuf->bySignalField_a)
+            );
+            pBuf->wTransmitLength_a = cpu_to_le16(wLen);
+
+            //Get Duration
+            pBuf->wDuration_bb = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, PK_TYPE_11B, pDevice->byTopCCKBasicRate, bNeedAck, byFBOption));    //0:RTSDuration_bb, 1:2.4G, 1:CCKData
+            pBuf->wDuration_aa = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktTyp, wCurrentRate, bNeedAck, byFBOption)); //2:RTSDuration_aa, 1:2.4G, 2,3:2.4G OFDMData
+            pBuf->wDuration_ba = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA, cbFrameLength, byPktTyp, wCurrentRate, bNeedAck, byFBOption)); //1:RTSDuration_ba, 1:2.4G, 2,3:2.4G OFDMData
+            pBuf->wRTSDuration_ba_f0 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F0, cbFrameLength, byPktTyp, wCurrentRate, bNeedAck, byFBOption));    //4:wRTSDuration_ba_f0, 1:2.4G, 1:CCKData
+            pBuf->wRTSDuration_aa_f0 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0, cbFrameLength, byPktTyp, wCurrentRate, bNeedAck, byFBOption));    //5:wRTSDuration_aa_f0, 1:2.4G, 1:CCKData
+            pBuf->wRTSDuration_ba_f1 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F1, cbFrameLength, byPktTyp, wCurrentRate, bNeedAck, byFBOption));    //6:wRTSDuration_ba_f1, 1:2.4G, 1:CCKData
+            pBuf->wRTSDuration_aa_f1 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1, cbFrameLength, byPktTyp, wCurrentRate, bNeedAck, byFBOption));    //7:wRTSDuration_aa_f1, 1:2.4G, 1:CCKData
+            pBuf->Data.wDurationID = pBuf->wDuration_aa;
+            //Get RTS Frame body
+            pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4
+
+            if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
+                (pDevice->eOPMode == OP_MODE_AP)) {
+                MEMvCopy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN);
+            }
+            else {
+                MEMvCopy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
+            }
+
+            if (pDevice->eOPMode == OP_MODE_AP) {
+                MEMvCopy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
+            }
+            else {
+                MEMvCopy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN);
+            }
+
+        } // if (byFBOption == AUTO_FB_NONE)
+    }
+    else if (byPktTyp == PK_TYPE_11A) {
+        if (byFBOption == AUTO_FB_NONE) {
+            PSRTS_ab pBuf = (PSRTS_ab)pvRTS;
+            //Get SignalField,ServiceField,Length
+            BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktTyp,
+                (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField)
+            );
+            pBuf->wTransmitLength = cpu_to_le16(wLen);
+            //Get Duration
+            pBuf->wDuration = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktTyp, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_aa, 0:5G, 0: 5G OFDMData
+           pBuf->Data.wDurationID = pBuf->wDuration;
+            //Get RTS Frame body
+            pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4
+
+            if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
+                (pDevice->eOPMode == OP_MODE_AP)) {
+                MEMvCopy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN);
+            }
+            else {
+                MEMvCopy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
+            }
+
+            if (pDevice->eOPMode == OP_MODE_AP) {
+                MEMvCopy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
+            }
+            else {
+                MEMvCopy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN);
+            }
+
+        }
+        else {
+            PSRTS_a_FB pBuf = (PSRTS_a_FB)pvRTS;
+            //Get SignalField,ServiceField,Length
+            BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktTyp,
+                (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField)
+            );
+            pBuf->wTransmitLength = cpu_to_le16(wLen);
+            //Get Duration
+            pBuf->wDuration = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktTyp, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_aa, 0:5G, 0: 5G OFDMData
+           pBuf->wRTSDuration_f0 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0, cbFrameLength, byPktTyp, wCurrentRate, bNeedAck, byFBOption)); //5:RTSDuration_aa_f0, 0:5G, 0: 5G OFDMData
+           pBuf->wRTSDuration_f1 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1, cbFrameLength, byPktTyp, wCurrentRate, bNeedAck, byFBOption)); //7:RTSDuration_aa_f1, 0:5G, 0:
+           pBuf->Data.wDurationID = pBuf->wDuration;
+           //Get RTS Frame body
+            pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4
+
+            if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
+                (pDevice->eOPMode == OP_MODE_AP)) {
+                MEMvCopy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN);
+            }
+            else {
+                MEMvCopy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
+            }
+            if (pDevice->eOPMode == OP_MODE_AP) {
+                MEMvCopy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
+            }
+            else {
+                MEMvCopy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN);
+            }
+        }
+    }
+    else if (byPktTyp == PK_TYPE_11B) {
+        PSRTS_ab pBuf = (PSRTS_ab)pvRTS;
+        //Get SignalField,ServiceField,Length
+        BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
+            (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField)
+        );
+        pBuf->wTransmitLength = cpu_to_le16(wLen);
+        //Get Duration
+        pBuf->wDuration = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, byPktTyp, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_bb, 1:2.4G, 1:CCKData
+        pBuf->Data.wDurationID = pBuf->wDuration;
+        //Get RTS Frame body
+        pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4
+
+
+        if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
+            (pDevice->eOPMode == OP_MODE_AP)) {
+            MEMvCopy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN);
+        }
+        else {
+            MEMvCopy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
+        }
+
+        if (pDevice->eOPMode == OP_MODE_AP) {
+            MEMvCopy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
+        }
+        else {
+            MEMvCopy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN);
+        }
+    }
+}
+
+static
+VOID
+s_vFillCTSHead (
+    IN PSDevice pDevice,
+    IN UINT     uDMAIdx,
+    IN BYTE     byPktTyp,
+    IN PVOID    pvCTS,
+    IN UINT     cbFrameLength,
+    IN BOOL     bNeedAck,
+    IN BOOL     bDisCRC,
+    IN WORD     wCurrentRate,
+    IN BYTE     byFBOption
+    )
+{
+    UINT uCTSFrameLen = 14;
+    WORD  wLen = 0x0000;
+
+    if (pvCTS == NULL) {
+        return;
+    }
+
+    if (bDisCRC) {
+        // When CRCDIS bit is on, H/W forgot to generate FCS for CTS frame,
+        // in this case we need to decrease its length by 4.
+        uCTSFrameLen -= 4;
+    }
+
+    if (byPktTyp == PK_TYPE_11GB || byPktTyp == PK_TYPE_11GA) {
+        if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) {
+            // Auto Fall back
+            PSCTS_FB pBuf = (PSCTS_FB)pvCTS;
+            //Get SignalField,ServiceField,Length
+            BBvCaculateParameter(pDevice, uCTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
+                (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_b), (PBYTE)&(pBuf->bySignalField_b)
+            );
+
+
+            pBuf->wTransmitLength_b = cpu_to_le16(wLen);
+
+            pBuf->wDuration_ba = (WORD)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA, cbFrameLength, byPktTyp, wCurrentRate, bNeedAck, byFBOption); //3:CTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data
+            pBuf->wDuration_ba += pDevice->wCTSDuration;
+            pBuf->wDuration_ba = cpu_to_le16(pBuf->wDuration_ba);
+            //Get CTSDuration_ba_f0
+            pBuf->wCTSDuration_ba_f0 = (WORD)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F0, cbFrameLength, byPktTyp, wCurrentRate, bNeedAck, byFBOption); //8:CTSDuration_ba_f0, 1:2.4G, 2,3:2.4G OFDM Data
+            pBuf->wCTSDuration_ba_f0 += pDevice->wCTSDuration;
+            pBuf->wCTSDuration_ba_f0 = cpu_to_le16(pBuf->wCTSDuration_ba_f0);
+            //Get CTSDuration_ba_f1
+            pBuf->wCTSDuration_ba_f1 = (WORD)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F1, cbFrameLength, byPktTyp, wCurrentRate, bNeedAck, byFBOption); //9:CTSDuration_ba_f1, 1:2.4G, 2,3:2.4G OFDM Data
+            pBuf->wCTSDuration_ba_f1 += pDevice->wCTSDuration;
+            pBuf->wCTSDuration_ba_f1 = cpu_to_le16(pBuf->wCTSDuration_ba_f1);
+            //Get CTS Frame body
+            pBuf->Data.wDurationID = pBuf->wDuration_ba;
+            pBuf->Data.wFrameControl = TYPE_CTL_CTS;//0x00C4
+            pBuf->Data.wReserved = 0x0000;
+            MEMvCopy(&(pBuf->Data.abyRA[0]), &(pDevice->abyCurrentNetAddr[0]), U_ETHER_ADDR_LEN);
+
+        } else { //if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA)
+            PSCTS pBuf = (PSCTS)pvCTS;
+            //Get SignalField,ServiceField,Length
+            BBvCaculateParameter(pDevice, uCTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
+                (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_b), (PBYTE)&(pBuf->bySignalField_b)
+            );
+            pBuf->wTransmitLength_b = cpu_to_le16(wLen);
+            //Get CTSDuration_ba
+            pBuf->wDuration_ba = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA, cbFrameLength, byPktTyp, wCurrentRate, bNeedAck, byFBOption)); //3:CTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data
+            pBuf->wDuration_ba += pDevice->wCTSDuration;
+            pBuf->wDuration_ba = cpu_to_le16(pBuf->wDuration_ba);
+
+            //Get CTS Frame body
+            pBuf->Data.wDurationID = pBuf->wDuration_ba;
+            pBuf->Data.wFrameControl = TYPE_CTL_CTS;//0x00C4
+            pBuf->Data.wReserved = 0x0000;
+            MEMvCopy(&(pBuf->Data.abyRA[0]), &(pDevice->abyCurrentNetAddr[0]), U_ETHER_ADDR_LEN);
+        }
+    }
+}
+
+
+
+
+
+
+/*+
+ *
+ * Description:
+ *      Generate FIFO control for MAC & Baseband controller
+ *
+ * Parameters:
+ *  In:
+ *      pDevice         - Pointer to adpater
+ *      pTxDataHead     - Transmit Data Buffer
+ *      pTxBufHead      - pTxBufHead
+ *      pvRrvTime        - pvRrvTime
+ *      pvRTS            - RTS Buffer
+ *      pCTS            - CTS Buffer
+ *      cbFrameSize     - Transmit Data Length (Hdr+Payload+FCS)
+ *      bNeedACK        - If need ACK
+ *      uDescIdx        - Desc Index
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+-*/
+// UINT            cbFrameSize,//Hdr+Payload+FCS
+static
+VOID
+s_vGenerateTxParameter (
+    IN PSDevice         pDevice,
+    IN BYTE             byPktTyp,
+    IN PVOID            pTxBufHead,
+    IN PVOID            pvRrvTime,
+    IN PVOID            pvRTS,
+    IN PVOID            pvCTS,
+    IN UINT             cbFrameSize,
+    IN BOOL             bNeedACK,
+    IN UINT             uDMAIdx,
+    IN PSEthernetHeader psEthHeader,
+    IN WORD             wCurrentRate
+    )
+{
+    UINT cbMACHdLen = WLAN_HDR_ADDR3_LEN; //24
+    WORD wFifoCtl;
+    BOOL bDisCRC = FALSE;
+    BYTE byFBOption = AUTO_FB_NONE;
+//    WORD wCurrentRate = pDevice->wCurrentRate;
+
+    //DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vGenerateTxParameter...\n");
+    PSTxBufHead pFifoHead = (PSTxBufHead)pTxBufHead;
+    pFifoHead->wReserved = wCurrentRate;
+    wFifoCtl = pFifoHead->wFIFOCtl;
+
+    if (wFifoCtl & FIFOCTL_CRCDIS) {
+        bDisCRC = TRUE;
+    }
+
+    if (wFifoCtl & FIFOCTL_AUTO_FB_0) {
+        byFBOption = AUTO_FB_0;
+    }
+    else if (wFifoCtl & FIFOCTL_AUTO_FB_1) {
+        byFBOption = AUTO_FB_1;
+    }
+
+    if (pDevice->bLongHeader)
+        cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6;
+
+    if (byPktTyp == PK_TYPE_11GB || byPktTyp == PK_TYPE_11GA) {
+
+        if (pvRTS != NULL) { //RTS_need
+            //Fill RsvTime
+            if (pvRrvTime) {
+                PSRrvTime_gRTS pBuf = (PSRrvTime_gRTS)pvRrvTime;
+                pBuf->wRTSTxRrvTime_aa = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 2, byPktTyp, cbFrameSize, wCurrentRate));//2:RTSTxRrvTime_aa, 1:2.4GHz
+                pBuf->wRTSTxRrvTime_ba = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 1, byPktTyp, cbFrameSize, wCurrentRate));//1:RTSTxRrvTime_ba, 1:2.4GHz
+                pBuf->wRTSTxRrvTime_bb = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 0, byPktTyp, cbFrameSize, wCurrentRate));//0:RTSTxRrvTime_bb, 1:2.4GHz
+                pBuf->wTxRrvTime_a = cpu_to_le16((WORD) s_uGetTxRsvTime(pDevice, byPktTyp, cbFrameSize, wCurrentRate, bNeedACK));//2.4G OFDM
+                pBuf->wTxRrvTime_b = cpu_to_le16((WORD) s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK));//1:CCK
+            }
+            //Fill RTS
+            s_vFillRTSHead(pDevice, byPktTyp, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
+        }
+        else {//RTS_needless, PCF mode
+
+            //Fill RsvTime
+            if (pvRrvTime) {
+                PSRrvTime_gCTS pBuf = (PSRrvTime_gCTS)pvRrvTime;
+                pBuf->wTxRrvTime_a = cpu_to_le16((WORD)s_uGetTxRsvTime(pDevice, byPktTyp, cbFrameSize, wCurrentRate, bNeedACK));//2.4G OFDM
+                pBuf->wTxRrvTime_b = cpu_to_le16((WORD)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK));//1:CCK
+                pBuf->wCTSTxRrvTime_ba = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 3, byPktTyp, cbFrameSize, wCurrentRate));//3:CTSTxRrvTime_Ba, 1:2.4GHz
+            }
+
+
+            //Fill CTS
+            s_vFillCTSHead(pDevice, uDMAIdx, byPktTyp, pvCTS, cbFrameSize, bNeedACK, bDisCRC, wCurrentRate, byFBOption);
+        }
+    }
+    else if (byPktTyp == PK_TYPE_11A) {
+
+        if (pvRTS != NULL) {//RTS_need, non PCF mode
+            //Fill RsvTime
+            if (pvRrvTime) {
+                PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime;
+                pBuf->wRTSTxRrvTime = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 2, byPktTyp, cbFrameSize, wCurrentRate));//2:RTSTxRrvTime_aa, 0:5GHz
+                pBuf->wTxRrvTime = cpu_to_le16((WORD)s_uGetTxRsvTime(pDevice, byPktTyp, cbFrameSize, wCurrentRate, bNeedACK));//0:OFDM
+            }
+            //Fill RTS
+            s_vFillRTSHead(pDevice, byPktTyp, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
+        }
+        else if (pvRTS == NULL) {//RTS_needless, non PCF mode
+            //Fill RsvTime
+            if (pvRrvTime) {
+                PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime;
+                pBuf->wTxRrvTime = cpu_to_le16((WORD)s_uGetTxRsvTime(pDevice, PK_TYPE_11A, cbFrameSize, wCurrentRate, bNeedACK)); //0:OFDM
+            }
+        }
+    }
+    else if (byPktTyp == PK_TYPE_11B) {
+
+        if ((pvRTS != NULL)) {//RTS_need, non PCF mode
+            //Fill RsvTime
+            if (pvRrvTime) {
+                PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime;
+                pBuf->wRTSTxRrvTime = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 0, byPktTyp, cbFrameSize, wCurrentRate));//0:RTSTxRrvTime_bb, 1:2.4GHz
+                pBuf->wTxRrvTime = cpu_to_le16((WORD)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK));//1:CCK
+            }
+            //Fill RTS
+            s_vFillRTSHead(pDevice, byPktTyp, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
+        }
+        else { //RTS_needless, non PCF mode
+            //Fill RsvTime
+            if (pvRrvTime) {
+                PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime;
+                pBuf->wTxRrvTime = cpu_to_le16((WORD)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK)); //1:CCK
+            }
+        }
+    }
+    //DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vGenerateTxParameter END.\n");
+}
+/*
+    PBYTE pbyBuffer,//point to pTxBufHead
+    WORD  wFragType,//00:Non-Frag, 01:Start, 02:Mid, 03:Last
+    UINT  cbFragmentSize,//Hdr+payoad+FCS
+*/
+static
+VOID
+s_vFillFragParameter(
+    IN PSDevice pDevice,
+    IN PBYTE    pbyBuffer,
+    IN UINT     uTxType,
+    IN PVOID    pvtdCurr,
+    IN WORD     wFragType,
+    IN UINT     cbReqCount
+    )
+{
+    PSTxBufHead pTxBufHead = (PSTxBufHead) pbyBuffer;
+    //DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vFillFragParameter...\n");
+
+    if (uTxType == TYPE_SYNCDMA) {
+        //PSTxSyncDesc ptdCurr = (PSTxSyncDesc)s_pvGetTxDescHead(pDevice, uTxType, uCurIdx);
+        PSTxSyncDesc ptdCurr = (PSTxSyncDesc)pvtdCurr;
+
+         //Set FIFOCtl & TimeStamp in TxSyncDesc
+        ptdCurr->m_wFIFOCtl = pTxBufHead->wFIFOCtl;
+        ptdCurr->m_wTimeStamp = pTxBufHead->wTimeStamp;
+        //Set TSR1 & ReqCount in TxDescHead
+        ptdCurr->m_td1TD1.wReqCount = cpu_to_le16((WORD)(cbReqCount));
+        if (wFragType == FRAGCTL_ENDFRAG) { //Last Fragmentation
+            ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP | EDMSDU);
+        }
+        else {
+            ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP);
+        }
+    }
+    else {
+        //PSTxDesc ptdCurr = (PSTxDesc)s_pvGetTxDescHead(pDevice, uTxType, uCurIdx);
+        PSTxDesc ptdCurr = (PSTxDesc)pvtdCurr;
+        //Set TSR1 & ReqCount in TxDescHead
+        ptdCurr->m_td1TD1.wReqCount = cpu_to_le16((WORD)(cbReqCount));
+        if (wFragType == FRAGCTL_ENDFRAG) { //Last Fragmentation
+            ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP | EDMSDU);
+        }
+        else {
+            ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP);
+        }
+    }
+
+    pTxBufHead->wFragCtl |= (WORD)wFragType;//0x0001; //0000 0000 0000 0001
+
+    //DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vFillFragParameter END\n");
+}
+
+static
+UINT
+s_cbFillTxBufHead (
+    IN  PSDevice         pDevice,
+    IN  BYTE             byPktTyp,
+    IN  PBYTE            pbyTxBufferAddr,
+    IN  UINT             cbFrameBodySize,
+    IN  UINT             uDMAIdx,
+    IN  PSTxDesc         pHeadTD,
+    IN  PSEthernetHeader psEthHeader,
+    IN  PBYTE            pPacket,
+    IN  BOOL             bNeedEncrypt,
+    IN  PSKeyItem        pTransmitKey,
+    IN  UINT             uNodeIndex,
+    OUT PUINT            puMACfragNum
+    )
+{
+    UINT           cbMACHdLen;
+    UINT           cbFrameSize;
+    UINT           cbFragmentSize; //Hdr+(IV)+payoad+(MIC)+(ICV)+FCS
+    UINT           cbFragPayloadSize;
+    UINT           cbLastFragmentSize; //Hdr+(IV)+payoad+(MIC)+(ICV)+FCS
+    UINT           cbLastFragPayloadSize;
+    UINT           uFragIdx;
+    PBYTE          pbyPayloadHead;
+    PBYTE          pbyIVHead;
+    PBYTE          pbyMacHdr;
+    WORD           wFragType; //00:Non-Frag, 01:Start, 10:Mid, 11:Last
+    UINT           uDuration;
+    PBYTE          pbyBuffer;
+//    UINT           uKeyEntryIdx = NUM_KEY_ENTRY+1;
+//    BYTE           byKeySel = 0xFF;
+    UINT           cbIVlen = 0;
+    UINT           cbICVlen = 0;
+    UINT           cbMIClen = 0;
+    UINT           cbFCSlen = 4;
+    UINT           cb802_1_H_len = 0;
+    UINT           uLength = 0;
+    UINT           uTmpLen = 0;
+//    BYTE           abyTmp[8];
+//    DWORD          dwCRC;
+    UINT           cbMICHDR = 0;
+    DWORD          dwMICKey0, dwMICKey1;
+    DWORD          dwMIC_Priority;
+    PDWORD         pdwMIC_L;
+    PDWORD         pdwMIC_R;
+    DWORD          dwSafeMIC_L, dwSafeMIC_R; //Fix "Last Frag Size" < "MIC length".
+    BOOL           bMIC2Frag = FALSE;
+    UINT           uMICFragLen = 0;
+    UINT           uMACfragNum = 1;
+    UINT           uPadding = 0;
+    UINT           cbReqCount = 0;
+
+    BOOL           bNeedACK;
+    BOOL           bRTS;
+    BOOL           bIsAdhoc;
+    PBYTE          pbyType;
+    PSTxDesc       ptdCurr;
+    PSTxBufHead    psTxBufHd = (PSTxBufHead) pbyTxBufferAddr;
+//    UINT           tmpDescIdx;
+    UINT           cbHeaderLength = 0;
+    PVOID          pvRrvTime;
+    PSMICHDRHead   pMICHDR;
+    PVOID          pvRTS;
+    PVOID          pvCTS;
+    PVOID          pvTxDataHd;
+    WORD           wTxBufSize;   // FFinfo size
+    UINT           uTotalCopyLength = 0;
+    BYTE           byFBOption = AUTO_FB_NONE;
+    BOOL           bIsWEP256 = FALSE;
+    PSMgmtObject    pMgmt = pDevice->pMgmt;
+
+
+    pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL;
+
+    //DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_cbFillTxBufHead...\n");
+    if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
+        (pDevice->eOPMode == OP_MODE_AP)) {
+
+        if (IS_MULTICAST_ADDRESS(&(psEthHeader->abyDstAddr[0])) ||
+            IS_BROADCAST_ADDRESS(&(psEthHeader->abyDstAddr[0]))) {
+            bNeedACK = FALSE;
+        }
+        else {
+            bNeedACK = TRUE;
+        }
+        bIsAdhoc = TRUE;
+    }
+    else {
+        // MSDUs in Infra mode always need ACK
+        bNeedACK = TRUE;
+        bIsAdhoc = FALSE;
+    }
+
+    if (pDevice->bLongHeader)
+        cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6;
+    else
+        cbMACHdLen = WLAN_HDR_ADDR3_LEN;
+
+
+    if ((bNeedEncrypt == TRUE) && (pTransmitKey != NULL)) {
+        if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) {
+            cbIVlen = 4;
+            cbICVlen = 4;
+            if (pTransmitKey->uKeyLength == WLAN_WEP232_KEYLEN) {
+                bIsWEP256 = TRUE;
+            }
+        }
+        if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
+            cbIVlen = 8;//IV+ExtIV
+            cbMIClen = 8;
+            cbICVlen = 4;
+        }
+        if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) {
+            cbIVlen = 8;//RSN Header
+            cbICVlen = 8;//MIC
+            cbMICHDR = sizeof(SMICHDRHead);
+        }
+        if (pDevice->byLocalID > REV_ID_VT3253_A1) {
+            //MAC Header should be padding 0 to DW alignment.
+            uPadding = 4 - (cbMACHdLen%4);
+            uPadding %= 4;
+        }
+    }
+
+
+    cbFrameSize = cbMACHdLen + cbIVlen + (cbFrameBodySize + cbMIClen) + cbICVlen + cbFCSlen;
+
+    if ((bNeedACK == FALSE) ||
+        (cbFrameSize < pDevice->wRTSThreshold) ||
+        ((cbFrameSize >= pDevice->wFragmentationThreshold) && (pDevice->wFragmentationThreshold <= pDevice->wRTSThreshold))
+        ) {
+        bRTS = FALSE;
+    }
+    else {
+        bRTS = TRUE;
+        psTxBufHd->wFIFOCtl |= (FIFOCTL_RTS | FIFOCTL_LRETRY);
+    }
+    //
+    // Use for AUTO FALL BACK
+    //
+    if (psTxBufHd->wFIFOCtl & FIFOCTL_AUTO_FB_0) {
+        byFBOption = AUTO_FB_0;
+    }
+    else if (psTxBufHd->wFIFOCtl & FIFOCTL_AUTO_FB_1) {
+        byFBOption = AUTO_FB_1;
+    }
+
+    //////////////////////////////////////////////////////
+    //Set RrvTime/RTS/CTS Buffer
+    wTxBufSize = sizeof(STxBufHead);
+    if (byPktTyp == PK_TYPE_11GB || byPktTyp == PK_TYPE_11GA) {//802.11g packet
+
+        if (byFBOption == AUTO_FB_NONE) {
+            if (bRTS == TRUE) {//RTS_need
+                pvRrvTime = (PSRrvTime_gRTS) (pbyTxBufferAddr + wTxBufSize);
+                pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS));
+                pvRTS = (PSRTS_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR);
+                pvCTS = NULL;
+                pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR + sizeof(SRTS_g));
+                cbHeaderLength = wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR + sizeof(SRTS_g) + sizeof(STxDataHead_g);
+            }
+            else { //RTS_needless
+                pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize);
+                pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS));
+                pvRTS = NULL;
+                pvCTS = (PSCTS) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR);
+                pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS));
+                cbHeaderLength = wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS) + sizeof(STxDataHead_g);
+            }
+        } else {
+            // Auto Fall Back
+            if (bRTS == TRUE) {//RTS_need
+                pvRrvTime = (PSRrvTime_gRTS) (pbyTxBufferAddr + wTxBufSize);
+                pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS));
+                pvRTS = (PSRTS_g_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR);
+                pvCTS = NULL;
+                pvTxDataHd = (PSTxDataHead_g_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR + sizeof(SRTS_g_FB));
+                cbHeaderLength = wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR + sizeof(SRTS_g_FB) + sizeof(STxDataHead_g_FB);
+            }
+            else { //RTS_needless
+                pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize);
+                pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS));
+                pvRTS = NULL;
+                pvCTS = (PSCTS_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR);
+                pvTxDataHd = (PSTxDataHead_g_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS_FB));
+                cbHeaderLength = wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS_FB) + sizeof(STxDataHead_g_FB);
+            }
+        } // Auto Fall Back
+    }
+    else {//802.11a/b packet
+
+        if (byFBOption == AUTO_FB_NONE) {
+            if (bRTS == TRUE) {
+                pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize);
+                pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab));
+                pvRTS = (PSRTS_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR);
+                pvCTS = NULL;
+                pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(PSRrvTime_ab) + cbMICHDR + sizeof(SRTS_ab));
+                cbHeaderLength = wTxBufSize + sizeof(PSRrvTime_ab) + cbMICHDR + sizeof(SRTS_ab) + sizeof(STxDataHead_ab);
+            }
+            else { //RTS_needless, need MICHDR
+                pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize);
+                pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab));
+                pvRTS = NULL;
+                pvCTS = NULL;
+                pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR);
+                cbHeaderLength = wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR + sizeof(STxDataHead_ab);
+            }
+        } else {
+            // Auto Fall Back
+            if (bRTS == TRUE) {//RTS_need
+                pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize);
+                pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab));
+                pvRTS = (PSRTS_a_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR);
+                pvCTS = NULL;
+                pvTxDataHd = (PSTxDataHead_a_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(PSRrvTime_ab) + cbMICHDR + sizeof(SRTS_a_FB));
+                cbHeaderLength = wTxBufSize + sizeof(PSRrvTime_ab) + cbMICHDR + sizeof(SRTS_a_FB) + sizeof(STxDataHead_a_FB);
+            }
+            else { //RTS_needless
+                pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize);
+                pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab));
+                pvRTS = NULL;
+                pvCTS = NULL;
+                pvTxDataHd = (PSTxDataHead_a_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR);
+                cbHeaderLength = wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR + sizeof(STxDataHead_a_FB);
+            }
+        } // Auto Fall Back
+    }
+    ZERO_MEMORY((PVOID)(pbyTxBufferAddr + wTxBufSize), (cbHeaderLength - wTxBufSize));
+
+//////////////////////////////////////////////////////////////////
+    if ((bNeedEncrypt == TRUE) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
+        if (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
+            dwMICKey0 = *(PDWORD)(&pTransmitKey->abyKey[16]);
+            dwMICKey1 = *(PDWORD)(&pTransmitKey->abyKey[20]);
+        }
+        else if ((pTransmitKey->dwKeyIndex & AUTHENTICATOR_KEY) != 0) {
+            dwMICKey0 = *(PDWORD)(&pTransmitKey->abyKey[16]);
+            dwMICKey1 = *(PDWORD)(&pTransmitKey->abyKey[20]);
+        }
+        else {
+            dwMICKey0 = *(PDWORD)(&pTransmitKey->abyKey[24]);
+            dwMICKey1 = *(PDWORD)(&pTransmitKey->abyKey[28]);
+        }
+        // DO Software Michael
+        MIC_vInit(dwMICKey0, dwMICKey1);
+        MIC_vAppend((PBYTE)&(psEthHeader->abyDstAddr[0]), 12);
+        dwMIC_Priority = 0;
+        MIC_vAppend((PBYTE)&dwMIC_Priority, 4);
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC KEY: %lX, %lX\n", dwMICKey0, dwMICKey1);
+    }
+
+///////////////////////////////////////////////////////////////////
+
+    pbyMacHdr = (PBYTE)(pbyTxBufferAddr + cbHeaderLength);
+    pbyPayloadHead = (PBYTE)(pbyMacHdr + cbMACHdLen + uPadding + cbIVlen);
+    pbyIVHead = (PBYTE)(pbyMacHdr + cbMACHdLen + uPadding);
+
+    if ((cbFrameSize > pDevice->wFragmentationThreshold) && (bNeedACK == TRUE) && (bIsWEP256 == FALSE)) {
+        // Fragmentation
+        // FragThreshold = Fragment size(Hdr+(IV)+fragment payload+(MIC)+(ICV)+FCS)
+        cbFragmentSize = pDevice->wFragmentationThreshold;
+        cbFragPayloadSize = cbFragmentSize - cbMACHdLen - cbIVlen - cbICVlen - cbFCSlen;
+        //FragNum = (FrameSize-(Hdr+FCS))/(Fragment Size -(Hrd+FCS)))
+        uMACfragNum = (WORD) ((cbFrameBodySize + cbMIClen) / cbFragPayloadSize);
+        cbLastFragPayloadSize = (cbFrameBodySize + cbMIClen) % cbFragPayloadSize;
+        if (cbLastFragPayloadSize == 0) {
+            cbLastFragPayloadSize = cbFragPayloadSize;
+        } else {
+            uMACfragNum++;
+        }
+        //[Hdr+(IV)+last fragment payload+(MIC)+(ICV)+FCS]
+        cbLastFragmentSize = cbMACHdLen + cbLastFragPayloadSize + cbIVlen + cbICVlen + cbFCSlen;
+
+        for (uFragIdx = 0; uFragIdx < uMACfragNum; uFragIdx ++) {
+            if (uFragIdx == 0) {
+                //=========================
+                //    Start Fragmentation
+                //=========================
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Start Fragmentation...\n");
+                wFragType = FRAGCTL_STAFRAG;
+
+
+                //Fill FIFO,RrvTime,RTS,and CTS
+                s_vGenerateTxParameter(pDevice, byPktTyp, (PVOID)psTxBufHd, pvRrvTime, pvRTS, pvCTS,
+                                       cbFragmentSize, bNeedACK, uDMAIdx, psEthHeader, pDevice->wCurrentRate);
+                //Fill DataHead
+                uDuration = s_uFillDataHead(pDevice, byPktTyp, pvTxDataHd, cbFragmentSize, uDMAIdx, bNeedACK,
+                                            uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption, pDevice->wCurrentRate);
+                // Generate TX MAC Header
+                vGenerateMACHeader(pDevice, pbyMacHdr, (WORD)uDuration, psEthHeader, bNeedEncrypt,
+                                   wFragType, uDMAIdx, uFragIdx);
+
+                if (bNeedEncrypt == TRUE) {
+                    //Fill TXKEY
+                    s_vFillTxKey(pDevice, (PBYTE)(psTxBufHd->adwTxKey), pbyIVHead, pTransmitKey,
+                                 pbyMacHdr, (WORD)cbFragPayloadSize, (PBYTE)pMICHDR);
+                    //Fill IV(ExtIV,RSNHDR)
+                    if (pDevice->bEnableHostWEP) {
+                        pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16;
+                        pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0;
+                    }
+                }
+
+
+                // 802.1H
+                if (ntohs(psEthHeader->wType) > MAX_DATA_LEN) {
+                    if ((psEthHeader->wType == TYPE_PKT_IPX) ||
+                        (psEthHeader->wType == cpu_to_le16(0xF380))) {
+                        MEMvCopy((PBYTE) (pbyPayloadHead), &pDevice->abySNAP_Bridgetunnel[0], 6);
+                    }
+                    else {
+                        MEMvCopy((PBYTE) (pbyPayloadHead), &pDevice->abySNAP_RFC1042[0], 6);
+                    }
+                    pbyType = (PBYTE) (pbyPayloadHead + 6);
+                    MEMvCopy(pbyType, &(psEthHeader->wType), sizeof(WORD));
+                    cb802_1_H_len = 8;
+                }
+
+                cbReqCount = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cbFragPayloadSize;
+                //---------------------------
+                // S/W or H/W Encryption
+                //---------------------------
+                //Fill MICHDR
+                //if (pDevice->bAES) {
+                //    s_vFillMICHDR(pDevice, (PBYTE)pMICHDR, pbyMacHdr, (WORD)cbFragPayloadSize);
+                //}
+                //cbReqCount += s_uDoEncryption(pDevice, psEthHeader, (PVOID)psTxBufHd, byKeySel,
+                //                                pbyPayloadHead, (WORD)cbFragPayloadSize, uDMAIdx);
+
+
+
+                //pbyBuffer = (PBYTE)pDevice->aamTxBuf[uDMAIdx][uDescIdx].pbyVAddr;
+                pbyBuffer = (PBYTE)pHeadTD->pTDInfo->buf;
+
+                uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cb802_1_H_len;
+                //copy TxBufferHeader + MacHeader to desc
+                MEMvCopy(pbyBuffer, (PVOID)psTxBufHd, uLength);
+
+                // Copy the Packet into a tx Buffer
+                MEMvCopy((pbyBuffer + uLength), (pPacket + 14), (cbFragPayloadSize - cb802_1_H_len));
+
+
+                uTotalCopyLength += cbFragPayloadSize - cb802_1_H_len;
+
+                if ((bNeedEncrypt == TRUE) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
+                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Start MIC: %d\n", cbFragPayloadSize);
+                    MIC_vAppend((pbyBuffer + uLength - cb802_1_H_len), cbFragPayloadSize);
+
+                }
+
+                //---------------------------
+                // S/W Encryption
+                //---------------------------
+                if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) {
+                    if (bNeedEncrypt) {
+                        s_vSWencryption(pDevice, pTransmitKey, (pbyBuffer + uLength - cb802_1_H_len), (WORD)cbFragPayloadSize);
+                        cbReqCount += cbICVlen;
+                    }
+                }
+
+                ptdCurr = (PSTxDesc)pHeadTD;
+                //--------------------
+                //1.Set TSR1 & ReqCount in TxDescHead
+                //2.Set FragCtl in TxBufferHead
+                //3.Set Frame Control
+                //4.Set Sequence Control
+                //5.Get S/W generate FCS
+                //--------------------
+                s_vFillFragParameter(pDevice, pbyBuffer, uDMAIdx, (PVOID)ptdCurr, wFragType, cbReqCount);
+
+                ptdCurr->pTDInfo->dwReqCount = cbReqCount - uPadding;
+                ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength;
+                ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma;
+                ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma);
+                pDevice->iTDUsed[uDMAIdx]++;
+                pHeadTD = ptdCurr->next;
+            }
+            else if (uFragIdx == (uMACfragNum-1)) {
+                //=========================
+                //    Last Fragmentation
+                //=========================
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Last Fragmentation...\n");
+                //tmpDescIdx = (uDescIdx + uFragIdx) % pDevice->cbTD[uDMAIdx];
+
+                wFragType = FRAGCTL_ENDFRAG;
+
+                //Fill FIFO,RrvTime,RTS,and CTS
+                s_vGenerateTxParameter(pDevice, byPktTyp, (PVOID)psTxBufHd, pvRrvTime, pvRTS, pvCTS,
+                                       cbLastFragmentSize, bNeedACK, uDMAIdx, psEthHeader, pDevice->wCurrentRate);
+                //Fill DataHead
+                uDuration = s_uFillDataHead(pDevice, byPktTyp, pvTxDataHd, cbLastFragmentSize, uDMAIdx, bNeedACK,
+                                            uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption, pDevice->wCurrentRate);
+
+                // Generate TX MAC Header
+                vGenerateMACHeader(pDevice, pbyMacHdr, (WORD)uDuration, psEthHeader, bNeedEncrypt,
+                                   wFragType, uDMAIdx, uFragIdx);
+
+                if (bNeedEncrypt == TRUE) {
+                    //Fill TXKEY
+                    s_vFillTxKey(pDevice, (PBYTE)(psTxBufHd->adwTxKey), pbyIVHead, pTransmitKey,
+                                 pbyMacHdr, (WORD)cbLastFragPayloadSize, (PBYTE)pMICHDR);
+
+                    if (pDevice->bEnableHostWEP) {
+                        pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16;
+                        pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0;
+                    }
+
+                }
+
+
+                cbReqCount = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cbLastFragPayloadSize;
+                //---------------------------
+                // S/W or H/W Encryption
+                //---------------------------
+
+
+
+                pbyBuffer = (PBYTE)pHeadTD->pTDInfo->buf;
+                //pbyBuffer = (PBYTE)pDevice->aamTxBuf[uDMAIdx][tmpDescIdx].pbyVAddr;
+
+                uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen;
+
+                //copy TxBufferHeader + MacHeader to desc
+                MEMvCopy(pbyBuffer, (PVOID)psTxBufHd, uLength);
+
+                // Copy the Packet into a tx Buffer
+                if (bMIC2Frag == FALSE) {
+
+                    MEMvCopy((pbyBuffer + uLength),
+                             (pPacket + 14 + uTotalCopyLength),
+                             (cbLastFragPayloadSize - cbMIClen)
+                             );
+                    //TODO check uTmpLen !
+                    uTmpLen = cbLastFragPayloadSize - cbMIClen;
+
+                }
+                if ((bNeedEncrypt == TRUE) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
+                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"LAST: uMICFragLen:%d, cbLastFragPayloadSize:%d, uTmpLen:%d\n",
+                                   uMICFragLen, cbLastFragPayloadSize, uTmpLen);
+
+                    if (bMIC2Frag == FALSE) {
+                        if (uTmpLen != 0)
+                            MIC_vAppend((pbyBuffer + uLength), uTmpLen);
+                        pdwMIC_L = (PDWORD)(pbyBuffer + uLength + uTmpLen);
+                        pdwMIC_R = (PDWORD)(pbyBuffer + uLength + uTmpLen + 4);
+                        MIC_vGetMIC(pdwMIC_L, pdwMIC_R);
+                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Last MIC:%lX, %lX\n", *pdwMIC_L, *pdwMIC_R);
+                    } else {
+                        if (uMICFragLen >= 4) {
+                            MEMvCopy((pbyBuffer + uLength), ((PBYTE)&dwSafeMIC_R + (uMICFragLen - 4)),
+                                     (cbMIClen - uMICFragLen));
+                            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"LAST: uMICFragLen >= 4: %X, %d\n",
+                                           *(PBYTE)((PBYTE)&dwSafeMIC_R + (uMICFragLen - 4)),
+                                           (cbMIClen - uMICFragLen));
+
+                        } else {
+                            MEMvCopy((pbyBuffer + uLength), ((PBYTE)&dwSafeMIC_L + uMICFragLen),
+                                     (4 - uMICFragLen));
+                            MEMvCopy((pbyBuffer + uLength + (4 - uMICFragLen)), &dwSafeMIC_R, 4);
+                            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"LAST: uMICFragLen < 4: %X, %d\n",
+                                           *(PBYTE)((PBYTE)&dwSafeMIC_R + uMICFragLen - 4),
+                                           (cbMIClen - uMICFragLen));
+                        }
+                        /*
+                        for (ii = 0; ii < cbLastFragPayloadSize + 8 + 24; ii++) {
+                            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *((PBYTE)((pbyBuffer + uLength) + ii - 8 - 24)));
+                        }
+                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n\n");
+                        */
+                    }
+                    MIC_vUnInit();
+                } else {
+                    ASSERT(uTmpLen == (cbLastFragPayloadSize - cbMIClen));
+                }
+
+
+                //---------------------------
+                // S/W Encryption
+                //---------------------------
+                if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) {
+                    if (bNeedEncrypt) {
+                        s_vSWencryption(pDevice, pTransmitKey, (pbyBuffer + uLength), (WORD)cbLastFragPayloadSize);
+                        cbReqCount += cbICVlen;
+                    }
+                }
+
+                ptdCurr = (PSTxDesc)pHeadTD;
+
+                //--------------------
+                //1.Set TSR1 & ReqCount in TxDescHead
+                //2.Set FragCtl in TxBufferHead
+                //3.Set Frame Control
+                //4.Set Sequence Control
+                //5.Get S/W generate FCS
+                //--------------------
+
+
+                s_vFillFragParameter(pDevice, pbyBuffer, uDMAIdx, (PVOID)ptdCurr, wFragType, cbReqCount);
+
+                ptdCurr->pTDInfo->dwReqCount = cbReqCount - uPadding;
+                ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength;
+                ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma;
+                ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma);
+                pDevice->iTDUsed[uDMAIdx]++;
+                pHeadTD = ptdCurr->next;
+
+            }
+            else {
+                //=========================
+                //    Middle Fragmentation
+                //=========================
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Middle Fragmentation...\n");
+                //tmpDescIdx = (uDescIdx + uFragIdx) % pDevice->cbTD[uDMAIdx];
+
+                wFragType = FRAGCTL_MIDFRAG;
+
+                //Fill FIFO,RrvTime,RTS,and CTS
+                s_vGenerateTxParameter(pDevice, byPktTyp, (PVOID)psTxBufHd, pvRrvTime, pvRTS, pvCTS,
+                                       cbFragmentSize, bNeedACK, uDMAIdx, psEthHeader, pDevice->wCurrentRate);
+                //Fill DataHead
+                uDuration = s_uFillDataHead(pDevice, byPktTyp, pvTxDataHd, cbFragmentSize, uDMAIdx, bNeedACK,
+                                            uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption, pDevice->wCurrentRate);
+
+                // Generate TX MAC Header
+                vGenerateMACHeader(pDevice, pbyMacHdr, (WORD)uDuration, psEthHeader, bNeedEncrypt,
+                                   wFragType, uDMAIdx, uFragIdx);
+
+
+                if (bNeedEncrypt == TRUE) {
+                    //Fill TXKEY
+                    s_vFillTxKey(pDevice, (PBYTE)(psTxBufHd->adwTxKey), pbyIVHead, pTransmitKey,
+                                 pbyMacHdr, (WORD)cbFragPayloadSize, (PBYTE)pMICHDR);
+
+                    if (pDevice->bEnableHostWEP) {
+                        pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16;
+                        pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0;
+                    }
+                }
+
+                cbReqCount = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cbFragPayloadSize;
+                //---------------------------
+                // S/W or H/W Encryption
+                //---------------------------
+                //Fill MICHDR
+                //if (pDevice->bAES) {
+                //    s_vFillMICHDR(pDevice, (PBYTE)pMICHDR, pbyMacHdr, (WORD)cbFragPayloadSize);
+                //}
+                //cbReqCount += s_uDoEncryption(pDevice, psEthHeader, (PVOID)psTxBufHd, byKeySel,
+                //                              pbyPayloadHead, (WORD)cbFragPayloadSize, uDMAIdx);
+
+
+                pbyBuffer = (PBYTE)pHeadTD->pTDInfo->buf;
+                //pbyBuffer = (PBYTE)pDevice->aamTxBuf[uDMAIdx][tmpDescIdx].pbyVAddr;
+
+
+                uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen;
+
+                //copy TxBufferHeader + MacHeader to desc
+                MEMvCopy(pbyBuffer, (PVOID)psTxBufHd, uLength);
+
+                // Copy the Packet into a tx Buffer
+                MEMvCopy((pbyBuffer + uLength),
+                         (pPacket + 14 + uTotalCopyLength),
+                         cbFragPayloadSize
+                        );
+                uTmpLen = cbFragPayloadSize;
+
+                uTotalCopyLength += uTmpLen;
+
+                if ((bNeedEncrypt == TRUE) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
+
+                    MIC_vAppend((pbyBuffer + uLength), uTmpLen);
+
+                    if (uTmpLen < cbFragPayloadSize) {
+                        bMIC2Frag = TRUE;
+                        uMICFragLen = cbFragPayloadSize - uTmpLen;
+                        ASSERT(uMICFragLen < cbMIClen);
+
+                        pdwMIC_L = (PDWORD)(pbyBuffer + uLength + uTmpLen);
+                        pdwMIC_R = (PDWORD)(pbyBuffer + uLength + uTmpLen + 4);
+                        MIC_vGetMIC(pdwMIC_L, pdwMIC_R);
+                        dwSafeMIC_L = *pdwMIC_L;
+                        dwSafeMIC_R = *pdwMIC_R;
+
+                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIDDLE: uMICFragLen:%d, cbFragPayloadSize:%d, uTmpLen:%d\n",
+                                       uMICFragLen, cbFragPayloadSize, uTmpLen);
+                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Fill MIC in Middle frag [%d]\n", uMICFragLen);
+                        /*
+                        for (ii = 0; ii < uMICFragLen; ii++) {
+                            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *((PBYTE)((pbyBuffer + uLength + uTmpLen) + ii)));
+                        }
+                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+                        */
+                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get MIC:%lX, %lX\n", *pdwMIC_L, *pdwMIC_R);
+                    }
+                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Middle frag len: %d\n", uTmpLen);
+                    /*
+                    for (ii = 0; ii < uTmpLen; ii++) {
+                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *((PBYTE)((pbyBuffer + uLength) + ii)));
+                    }
+                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n\n");
+                    */
+
+                } else {
+                    ASSERT(uTmpLen == (cbFragPayloadSize));
+                }
+
+                if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) {
+                    if (bNeedEncrypt) {
+                        s_vSWencryption(pDevice, pTransmitKey, (pbyBuffer + uLength), (WORD)cbFragPayloadSize);
+                        cbReqCount += cbICVlen;
+                    }
+                }
+
+                ptdCurr = (PSTxDesc)pHeadTD;
+
+                //--------------------
+                //1.Set TSR1 & ReqCount in TxDescHead
+                //2.Set FragCtl in TxBufferHead
+                //3.Set Frame Control
+                //4.Set Sequence Control
+                //5.Get S/W generate FCS
+                //--------------------
+
+                s_vFillFragParameter(pDevice, pbyBuffer, uDMAIdx, (PVOID)ptdCurr, wFragType, cbReqCount);
+
+                ptdCurr->pTDInfo->dwReqCount = cbReqCount - uPadding;
+                ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength;
+                ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma;
+                ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma);
+                pDevice->iTDUsed[uDMAIdx]++;
+                pHeadTD = ptdCurr->next;
+            }
+        }  // for (uMACfragNum)
+    }
+    else {
+        //=========================
+        //    No Fragmentation
+        //=========================
+        //DEVICE_PRTGRP03(("No Fragmentation...\n"));
+        //DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No Fragmentation...\n");
+        wFragType = FRAGCTL_NONFRAG;
+
+        //Set FragCtl in TxBufferHead
+        psTxBufHd->wFragCtl |= (WORD)wFragType;
+
+        //Fill FIFO,RrvTime,RTS,and CTS
+        s_vGenerateTxParameter(pDevice, byPktTyp, (PVOID)psTxBufHd, pvRrvTime, pvRTS, pvCTS,
+                               cbFrameSize, bNeedACK, uDMAIdx, psEthHeader, pDevice->wCurrentRate);
+        //Fill DataHead
+        uDuration = s_uFillDataHead(pDevice, byPktTyp, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK,
+                                    0, 0, uMACfragNum, byFBOption, pDevice->wCurrentRate);
+
+        // Generate TX MAC Header
+        vGenerateMACHeader(pDevice, pbyMacHdr, (WORD)uDuration, psEthHeader, bNeedEncrypt,
+                           wFragType, uDMAIdx, 0);
+
+        if (bNeedEncrypt == TRUE) {
+            //Fill TXKEY
+            s_vFillTxKey(pDevice, (PBYTE)(psTxBufHd->adwTxKey), pbyIVHead, pTransmitKey,
+                         pbyMacHdr, (WORD)cbFrameBodySize, (PBYTE)pMICHDR);
+
+            if (pDevice->bEnableHostWEP) {
+                pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16;
+                pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0;
+            }
+        }
+
+        // 802.1H
+        if (ntohs(psEthHeader->wType) > MAX_DATA_LEN) {
+            if ((psEthHeader->wType == TYPE_PKT_IPX) ||
+                (psEthHeader->wType == cpu_to_le16(0xF380))) {
+                MEMvCopy((PBYTE) (pbyPayloadHead), &pDevice->abySNAP_Bridgetunnel[0], 6);
+            }
+            else {
+                MEMvCopy((PBYTE) (pbyPayloadHead), &pDevice->abySNAP_RFC1042[0], 6);
+            }
+            pbyType = (PBYTE) (pbyPayloadHead + 6);
+            MEMvCopy(pbyType, &(psEthHeader->wType), sizeof(WORD));
+            cb802_1_H_len = 8;
+        }
+
+        cbReqCount = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + (cbFrameBodySize + cbMIClen);
+        //---------------------------
+        // S/W or H/W Encryption
+        //---------------------------
+        //Fill MICHDR
+        //if (pDevice->bAES) {
+        //    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Fill MICHDR...\n");
+        //    s_vFillMICHDR(pDevice, (PBYTE)pMICHDR, pbyMacHdr, (WORD)cbFrameBodySize);
+        //}
+
+        pbyBuffer = (PBYTE)pHeadTD->pTDInfo->buf;
+        //pbyBuffer = (PBYTE)pDevice->aamTxBuf[uDMAIdx][uDescIdx].pbyVAddr;
+
+        uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cb802_1_H_len;
+
+        //copy TxBufferHeader + MacHeader to desc
+        MEMvCopy(pbyBuffer, (PVOID)psTxBufHd, uLength);
+
+        // Copy the Packet into a tx Buffer
+        MEMvCopy((pbyBuffer + uLength),
+                 (pPacket + 14),
+                 cbFrameBodySize - cb802_1_H_len
+                 );
+
+        if ((bNeedEncrypt == TRUE) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)){
+
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Length:%d, %d\n", cbFrameBodySize - cb802_1_H_len, uLength);
+            /*
+            for (ii = 0; ii < (cbFrameBodySize - cb802_1_H_len); ii++) {
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *((PBYTE)((pbyBuffer + uLength) + ii)));
+            }
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+            */
+
+            MIC_vAppend((pbyBuffer + uLength - cb802_1_H_len), cbFrameBodySize);
+
+            pdwMIC_L = (PDWORD)(pbyBuffer + uLength - cb802_1_H_len + cbFrameBodySize);
+            pdwMIC_R = (PDWORD)(pbyBuffer + uLength - cb802_1_H_len + cbFrameBodySize + 4);
+
+            MIC_vGetMIC(pdwMIC_L, pdwMIC_R);
+            MIC_vUnInit();
+
+
+            if (pDevice->bTxMICFail == TRUE) {
+                *pdwMIC_L = 0;
+                *pdwMIC_R = 0;
+                pDevice->bTxMICFail = FALSE;
+            }
+
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"uLength: %d, %d\n", uLength, cbFrameBodySize);
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"cbReqCount:%d, %d, %d, %d\n", cbReqCount, cbHeaderLength, uPadding, cbIVlen);
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC:%lx, %lx\n", *pdwMIC_L, *pdwMIC_R);
+/*
+            for (ii = 0; ii < 8; ii++) {
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *(((PBYTE)(pdwMIC_L) + ii)));
+            }
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+*/
+
+        }
+
+
+        if ((pDevice->byLocalID <= REV_ID_VT3253_A1)){
+            if (bNeedEncrypt) {
+                s_vSWencryption(pDevice, pTransmitKey, (pbyBuffer + uLength - cb802_1_H_len),
+                                (WORD)(cbFrameBodySize + cbMIClen));
+                cbReqCount += cbICVlen;
+            }
+        }
+
+
+        ptdCurr = (PSTxDesc)pHeadTD;
+
+        ptdCurr->pTDInfo->dwReqCount = cbReqCount - uPadding;
+        ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength;
+        ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma;
+        ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma);
+           //Set TSR1 & ReqCount in TxDescHead
+        ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP | EDMSDU);
+        ptdCurr->m_td1TD1.wReqCount = cpu_to_le16((WORD)(cbReqCount));
+
+        pDevice->iTDUsed[uDMAIdx]++;
+
+
+//   DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" ptdCurr->m_dwReserved0[%d] ptdCurr->m_dwReserved1[%d].\n", ptdCurr->pTDInfo->dwReqCount, ptdCurr->pTDInfo->dwHeaderLength);
+//   DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" cbHeaderLength[%d]\n", cbHeaderLength);
+
+    }
+    *puMACfragNum = uMACfragNum;
+    //DEVICE_PRTGRP03(("s_cbFillTxBufHead END\n"));
+    return cbHeaderLength;
+}
+
+
+VOID
+vGenerateFIFOHeader (
+    IN  PSDevice         pDevice,
+    IN  BYTE             byPktTyp,
+    IN  PBYTE            pbyTxBufferAddr,
+    IN  BOOL             bNeedEncrypt,
+    IN  UINT             cbPayloadSize,
+    IN  UINT             uDMAIdx,
+    IN  PSTxDesc         pHeadTD,
+    IN  PSEthernetHeader psEthHeader,
+    IN  PBYTE            pPacket,
+    IN  PSKeyItem        pTransmitKey,
+    IN  UINT             uNodeIndex,
+    OUT PUINT            puMACfragNum,
+    OUT PUINT            pcbHeaderSize
+    )
+{
+    UINT            wTxBufSize;       // FFinfo size
+    BOOL            bNeedACK;
+    BOOL            bIsAdhoc;
+    WORD            cbMacHdLen;
+    PSTxBufHead     pTxBufHead = (PSTxBufHead) pbyTxBufferAddr;
+
+    wTxBufSize = sizeof(STxBufHead);
+
+    ZERO_MEMORY(pTxBufHead, wTxBufSize);
+    //Set FIFOCTL_NEEDACK
+
+    if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
+        (pDevice->eOPMode == OP_MODE_AP)) {
+        if (IS_MULTICAST_ADDRESS(&(psEthHeader->abyDstAddr[0])) ||
+            IS_BROADCAST_ADDRESS(&(psEthHeader->abyDstAddr[0]))) {
+            bNeedACK = FALSE;
+            pTxBufHead->wFIFOCtl = pTxBufHead->wFIFOCtl & (~FIFOCTL_NEEDACK);
+        }
+        else {
+            bNeedACK = TRUE;
+            pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
+        }
+        bIsAdhoc = TRUE;
+    }
+    else {
+        // MSDUs in Infra mode always need ACK
+        bNeedACK = TRUE;
+        pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
+        bIsAdhoc = FALSE;
+    }
+
+
+    pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN;
+    pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us);
+
+    //Set FIFOCTL_LHEAD
+    if (pDevice->bLongHeader)
+        pTxBufHead->wFIFOCtl |= FIFOCTL_LHEAD;
+
+    //Set FIFOCTL_GENINT
+
+    pTxBufHead->wFIFOCtl |= FIFOCTL_GENINT;
+
+
+    //Set FIFOCTL_ISDMA0
+    if (TYPE_TXDMA0 == uDMAIdx) {
+        pTxBufHead->wFIFOCtl |= FIFOCTL_ISDMA0;
+    }
+
+    //Set FRAGCTL_MACHDCNT
+    if (pDevice->bLongHeader) {
+        cbMacHdLen = WLAN_HDR_ADDR3_LEN + 6;
+    } else {
+        cbMacHdLen = WLAN_HDR_ADDR3_LEN;
+    }
+    pTxBufHead->wFragCtl |= cpu_to_le16((WORD)(cbMacHdLen << 10));
+
+    //Set packet type
+    if (byPktTyp == PK_TYPE_11A) {//0000 0000 0000 0000
+        ;
+    }
+    else if (byPktTyp == PK_TYPE_11B) {//0000 0001 0000 0000
+        pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
+    }
+    else if (byPktTyp == PK_TYPE_11GB) {//0000 0010 0000 0000
+        pTxBufHead->wFIFOCtl |= FIFOCTL_11GB;
+    }
+    else if (byPktTyp == PK_TYPE_11GA) {//0000 0011 0000 0000
+        pTxBufHead->wFIFOCtl |= FIFOCTL_11GA;
+    }
+    //Set FIFOCTL_GrpAckPolicy
+    if (pDevice->bGrpAckPolicy == TRUE) {//0000 0100 0000 0000
+        pTxBufHead->wFIFOCtl |=        FIFOCTL_GRPACK;
+    }
+
+    //Set Auto Fallback Ctl
+    if (pDevice->wCurrentRate >= RATE_18M) {
+        if (pDevice->byAutoFBCtrl == AUTO_FB_0) {
+            pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_0;
+        } else if (pDevice->byAutoFBCtrl == AUTO_FB_1) {
+            pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_1;
+        }
+    }
+
+    //Set FRAGCTL_WEPTYP
+    pDevice->bAES = FALSE;
+
+    //Set FRAGCTL_WEPTYP
+    if (pDevice->byLocalID > REV_ID_VT3253_A1) {
+        if ((bNeedEncrypt) && (pTransmitKey != NULL))  { //WEP enabled
+            if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
+                pTxBufHead->wFragCtl |= FRAGCTL_TKIP;
+            }
+            else if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) { //WEP40 or WEP104
+                if (pTransmitKey->uKeyLength != WLAN_WEP232_KEYLEN)
+                    pTxBufHead->wFragCtl |= FRAGCTL_LEGACY;
+            }
+            else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) { //CCMP
+                pTxBufHead->wFragCtl |= FRAGCTL_AES;
+            }
+        }
+    }
+
+#ifdef PLICE_DEBUG
+       //printk("Func:vGenerateFIFOHeader:TxDataRate is %d,TxPower is %d\n",pDevice->wCurrentRate,pDevice->byCurPwr);
+
+       //if (pDevice->wCurrentRate <= 3)
+       //{
+       //      RFbRawSetPower(pDevice,36,pDevice->wCurrentRate);
+       //}
+       //else
+
+       RFbSetPower(pDevice, pDevice->wCurrentRate, pDevice->byCurrentCh);
+#endif
+               //if (pDevice->wCurrentRate == 3)
+               //pDevice->byCurPwr = 46;
+               pTxBufHead->byTxPower = pDevice->byCurPwr;
+
+
+
+
+/*
+    if(pDevice->bEnableHostWEP)
+        pTxBufHead->wFragCtl &=  ~(FRAGCTL_TKIP | FRAGCTL_LEGACY |FRAGCTL_AES);
+*/
+    *pcbHeaderSize = s_cbFillTxBufHead(pDevice, byPktTyp, pbyTxBufferAddr, cbPayloadSize,
+                                   uDMAIdx, pHeadTD, psEthHeader, pPacket, bNeedEncrypt,
+                                   pTransmitKey, uNodeIndex, puMACfragNum);
+
+    return;
+}
+
+
+
+
+/*+
+ *
+ * Description:
+ *      Translate 802.3 to 802.11 header
+ *
+ * Parameters:
+ *  In:
+ *      pDevice         - Pointer to adpater
+ *      dwTxBufferAddr  - Transmit Buffer
+ *      pPacket         - Packet from upper layer
+ *      cbPacketSize    - Transmit Data Length
+ *  Out:
+ *      pcbHeadSize         - Header size of MAC&Baseband control and 802.11 Header
+ *      pcbAppendPayload    - size of append payload for 802.1H translation
+ *
+ * Return Value: none
+ *
+-*/
+
+VOID
+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
+    )
+{
+    PS802_11Header  pMACHeader = (PS802_11Header)pbyBufferAddr;
+
+    ZERO_MEMORY(pMACHeader, (sizeof(S802_11Header)));  //- sizeof(pMACHeader->dwIV)));
+
+    if (uDMAIdx == TYPE_ATIMDMA) {
+       pMACHeader->wFrameCtl = TYPE_802_11_ATIM;
+    } else {
+        pMACHeader->wFrameCtl = TYPE_802_11_DATA;
+    }
+
+    if (pDevice->eOPMode == OP_MODE_AP) {
+        MEMvCopy(&(pMACHeader->abyAddr1[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN);
+        MEMvCopy(&(pMACHeader->abyAddr2[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
+        MEMvCopy(&(pMACHeader->abyAddr3[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN);
+        pMACHeader->wFrameCtl |= FC_FROMDS;
+    }
+    else {
+        if (pDevice->eOPMode == OP_MODE_ADHOC) {
+            MEMvCopy(&(pMACHeader->abyAddr1[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN);
+            MEMvCopy(&(pMACHeader->abyAddr2[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN);
+            MEMvCopy(&(pMACHeader->abyAddr3[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
+        }
+        else {
+            MEMvCopy(&(pMACHeader->abyAddr3[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN);
+            MEMvCopy(&(pMACHeader->abyAddr2[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN);
+            MEMvCopy(&(pMACHeader->abyAddr1[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
+            pMACHeader->wFrameCtl |= FC_TODS;
+        }
+    }
+
+    if (bNeedEncrypt)
+        pMACHeader->wFrameCtl |= cpu_to_le16((WORD)WLAN_SET_FC_ISWEP(1));
+
+    pMACHeader->wDurationID = cpu_to_le16(wDuration);
+
+    if (pDevice->bLongHeader) {
+        PWLAN_80211HDR_A4 pMACA4Header  = (PWLAN_80211HDR_A4) pbyBufferAddr;
+        pMACHeader->wFrameCtl |= (FC_TODS | FC_FROMDS);
+        MEMvCopy(pMACA4Header->abyAddr4, pDevice->abyBSSID, WLAN_ADDR_LEN);
+    }
+    pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4);
+
+    //Set FragNumber in Sequence Control
+    pMACHeader->wSeqCtl |= cpu_to_le16((WORD)uFragIdx);
+
+    if ((wFragType == FRAGCTL_ENDFRAG) || (wFragType == FRAGCTL_NONFRAG)) {
+        pDevice->wSeqCounter++;
+        if (pDevice->wSeqCounter > 0x0fff)
+            pDevice->wSeqCounter = 0;
+    }
+
+    if ((wFragType == FRAGCTL_STAFRAG) || (wFragType == FRAGCTL_MIDFRAG)) { //StartFrag or MidFrag
+        pMACHeader->wFrameCtl |= FC_MOREFRAG;
+    }
+}
+
+
+
+
+
+
+CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) {
+
+    PSTxDesc        pFrstTD;
+    BYTE            byPktTyp;
+    PBYTE           pbyTxBufferAddr;
+    PVOID           pvRTS;
+    PSCTS           pCTS;
+    PVOID           pvTxDataHd;
+    UINT            uDuration;
+    UINT            cbReqCount;
+    PS802_11Header  pMACHeader;
+    UINT            cbHeaderSize;
+    UINT            cbFrameBodySize;
+    BOOL            bNeedACK;
+    BOOL            bIsPSPOLL = FALSE;
+    PSTxBufHead     pTxBufHead;
+    UINT            cbFrameSize;
+    UINT            cbIVlen = 0;
+    UINT            cbICVlen = 0;
+    UINT            cbMIClen = 0;
+    UINT            cbFCSlen = 4;
+    UINT            uPadding = 0;
+    WORD            wTxBufSize;
+    UINT            cbMacHdLen;
+    SEthernetHeader sEthHeader;
+    PVOID           pvRrvTime;
+    PVOID           pMICHDR;
+    PSMgmtObject    pMgmt = pDevice->pMgmt;
+    WORD            wCurrentRate = RATE_1M;
+
+
+    if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 0) {
+        return CMD_STATUS_RESOURCES;
+    }
+
+    pFrstTD = pDevice->apCurrTD[TYPE_TXDMA0];
+    pbyTxBufferAddr = (PBYTE)pFrstTD->pTDInfo->buf;
+    cbFrameBodySize = pPacket->cbPayloadLen;
+    pTxBufHead = (PSTxBufHead) pbyTxBufferAddr;
+    wTxBufSize = sizeof(STxBufHead);
+    memset(pTxBufHead, 0, wTxBufSize);
+
+    if (pDevice->eCurrentPHYType == PHY_TYPE_11A) {
+        wCurrentRate = RATE_6M;
+        byPktTyp = PK_TYPE_11A;
+    } else {
+        wCurrentRate = RATE_1M;
+        byPktTyp = PK_TYPE_11B;
+    }
+
+    // SetPower will cause error power TX state for OFDM Date packet in TX buffer.
+    // 2004.11.11 Kyle -- Using OFDM power to tx MngPkt will decrease the connection capability.
+    //                    And cmd timer will wait data pkt TX finish before scanning so it's OK
+    //                    to set power here.
+    if (pDevice->pMgmt->eScanState != WMAC_NO_SCANNING) {
+
+               RFbSetPower(pDevice, wCurrentRate, pDevice->byCurrentCh);
+    } else {
+        RFbSetPower(pDevice, wCurrentRate, pMgmt->uCurrChannel);
+    }
+    pTxBufHead->byTxPower = pDevice->byCurPwr;
+    //+++++++++++++++++++++ Patch VT3253 A1 performance +++++++++++++++++++++++++++
+    if (pDevice->byFOETuning) {
+        if ((pPacket->p80211Header->sA3.wFrameCtl & TYPE_DATE_NULL) == TYPE_DATE_NULL) {
+            wCurrentRate = RATE_24M;
+            byPktTyp = PK_TYPE_11GA;
+        }
+    }
+
+    //Set packet type
+    if (byPktTyp == PK_TYPE_11A) {//0000 0000 0000 0000
+        pTxBufHead->wFIFOCtl = 0;
+    }
+    else if (byPktTyp == PK_TYPE_11B) {//0000 0001 0000 0000
+        pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
+    }
+    else if (byPktTyp == PK_TYPE_11GB) {//0000 0010 0000 0000
+        pTxBufHead->wFIFOCtl |= FIFOCTL_11GB;
+    }
+    else if (byPktTyp == PK_TYPE_11GA) {//0000 0011 0000 0000
+        pTxBufHead->wFIFOCtl |= FIFOCTL_11GA;
+    }
+
+    pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN;
+    pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
+
+
+    if (IS_MULTICAST_ADDRESS(&(pPacket->p80211Header->sA3.abyAddr1[0])) ||
+        IS_BROADCAST_ADDRESS(&(pPacket->p80211Header->sA3.abyAddr1[0]))) {
+        bNeedACK = FALSE;
+    }
+    else {
+        bNeedACK = TRUE;
+        pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
+    };
+
+    if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) ||
+        (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) ) {
+
+        pTxBufHead->wFIFOCtl |= FIFOCTL_LRETRY;
+        //Set Preamble type always long
+        //pDevice->byPreambleType = PREAMBLE_LONG;
+        // probe-response don't retry
+        //if ((pPacket->p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_MGMT_PROBE_RSP) {
+        //     bNeedACK = FALSE;
+        //     pTxBufHead->wFIFOCtl  &= (~FIFOCTL_NEEDACK);
+        //}
+    }
+
+    pTxBufHead->wFIFOCtl |= (FIFOCTL_GENINT | FIFOCTL_ISDMA0);
+
+    if ((pPacket->p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL) {
+        bIsPSPOLL = TRUE;
+        cbMacHdLen = WLAN_HDR_ADDR2_LEN;
+    } else {
+        cbMacHdLen = WLAN_HDR_ADDR3_LEN;
+    }
+
+    //Set FRAGCTL_MACHDCNT
+    pTxBufHead->wFragCtl |= cpu_to_le16((WORD)(cbMacHdLen << 10));
+
+    // Notes:
+    // Although spec says MMPDU can be fragmented; In most case,
+    // no one will send a MMPDU under fragmentation. With RTS may occur.
+    pDevice->bAES = FALSE;  //Set FRAGCTL_WEPTYP
+
+    if (WLAN_GET_FC_ISWEP(pPacket->p80211Header->sA4.wFrameCtl) != 0) {
+        if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) {
+            cbIVlen = 4;
+            cbICVlen = 4;
+           pTxBufHead->wFragCtl |= FRAGCTL_LEGACY;
+        }
+        else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
+            cbIVlen = 8;//IV+ExtIV
+            cbMIClen = 8;
+            cbICVlen = 4;
+           pTxBufHead->wFragCtl |= FRAGCTL_TKIP;
+           //We need to get seed here for filling TxKey entry.
+            //TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr,
+            //            pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, pDevice->abyPRNG);
+        }
+        else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
+            cbIVlen = 8;//RSN Header
+            cbICVlen = 8;//MIC
+            pTxBufHead->wFragCtl |= FRAGCTL_AES;
+            pDevice->bAES = TRUE;
+        }
+        //MAC Header should be padding 0 to DW alignment.
+        uPadding = 4 - (cbMacHdLen%4);
+        uPadding %= 4;
+    }
+
+    cbFrameSize = cbMacHdLen + cbFrameBodySize + cbIVlen + cbMIClen + cbICVlen + cbFCSlen;
+
+    //Set FIFOCTL_GrpAckPolicy
+    if (pDevice->bGrpAckPolicy == TRUE) {//0000 0100 0000 0000
+        pTxBufHead->wFIFOCtl |=        FIFOCTL_GRPACK;
+    }
+    //the rest of pTxBufHead->wFragCtl:FragTyp will be set later in s_vFillFragParameter()
+
+    //Set RrvTime/RTS/CTS Buffer
+    if (byPktTyp == PK_TYPE_11GB || byPktTyp == PK_TYPE_11GA) {//802.11g packet
+
+        pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize);
+        pMICHDR = NULL;
+        pvRTS = NULL;
+        pCTS = (PSCTS) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS));
+        pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + sizeof(SCTS));
+        cbHeaderSize = wTxBufSize + sizeof(SRrvTime_gCTS) + sizeof(SCTS) + sizeof(STxDataHead_g);
+    }
+    else { // 802.11a/b packet
+        pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize);
+        pMICHDR = NULL;
+        pvRTS = NULL;
+        pCTS = NULL;
+        pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab));
+        cbHeaderSize = wTxBufSize + sizeof(SRrvTime_ab) + sizeof(STxDataHead_ab);
+    }
+
+    ZERO_MEMORY((PVOID)(pbyTxBufferAddr + wTxBufSize), (cbHeaderSize - wTxBufSize));
+
+    MEMvCopy(&(sEthHeader.abyDstAddr[0]), &(pPacket->p80211Header->sA3.abyAddr1[0]), U_ETHER_ADDR_LEN);
+    MEMvCopy(&(sEthHeader.abySrcAddr[0]), &(pPacket->p80211Header->sA3.abyAddr2[0]), U_ETHER_ADDR_LEN);
+    //=========================
+    //    No Fragmentation
+    //=========================
+    pTxBufHead->wFragCtl |= (WORD)FRAGCTL_NONFRAG;
+
+
+    //Fill FIFO,RrvTime,RTS,and CTS
+    s_vGenerateTxParameter(pDevice, byPktTyp, pbyTxBufferAddr, pvRrvTime, pvRTS, pCTS,
+                           cbFrameSize, bNeedACK, TYPE_TXDMA0, &sEthHeader, wCurrentRate);
+
+    //Fill DataHead
+    uDuration = s_uFillDataHead(pDevice, byPktTyp, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK,
+                                0, 0, 1, AUTO_FB_NONE, wCurrentRate);
+
+    pMACHeader = (PS802_11Header) (pbyTxBufferAddr + cbHeaderSize);
+
+    cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + cbFrameBodySize;
+
+    if (WLAN_GET_FC_ISWEP(pPacket->p80211Header->sA4.wFrameCtl) != 0) {
+        PBYTE           pbyIVHead;
+        PBYTE           pbyPayloadHead;
+        PBYTE           pbyBSSID;
+        PSKeyItem       pTransmitKey = NULL;
+
+        pbyIVHead = (PBYTE)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding);
+        pbyPayloadHead = (PBYTE)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding + cbIVlen);
+
+        //Fill TXKEY
+        //Kyle: Need fix: TKIP and AES did't encryt Mnt Packet.
+        //s_vFillTxKey(pDevice, (PBYTE)pTxBufHead->adwTxKey, NULL);
+
+        //Fill IV(ExtIV,RSNHDR)
+        //s_vFillPrePayload(pDevice, pbyIVHead, NULL);
+        //---------------------------
+        // S/W or H/W Encryption
+        //---------------------------
+        //Fill MICHDR
+        //if (pDevice->bAES) {
+        //    s_vFillMICHDR(pDevice, (PBYTE)pMICHDR, (PBYTE)pMACHeader, (WORD)cbFrameBodySize);
+        //}
+        do {
+            if ((pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) &&
+                (pDevice->bLinkPass == TRUE)) {
+                pbyBSSID = pDevice->abyBSSID;
+                // get pairwise key
+                if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == FALSE) {
+                    // get group key
+                    if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == TRUE) {
+                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get GTK.\n");
+                        break;
+                    }
+                } else {
+                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get PTK.\n");
+                    break;
+                }
+            }
+            // get group key
+            pbyBSSID = pDevice->abyBroadcastAddr;
+            if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == FALSE) {
+                pTransmitKey = NULL;
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KEY is NULL. OP Mode[%d]\n", pDevice->eOPMode);
+            } else {
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get GTK.\n");
+            }
+        } while(FALSE);
+        //Fill TXKEY
+        s_vFillTxKey(pDevice, (PBYTE)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey,
+                     (PBYTE)pMACHeader, (WORD)cbFrameBodySize, NULL);
+
+        MEMvCopy(pMACHeader, pPacket->p80211Header, cbMacHdLen);
+        MEMvCopy(pbyPayloadHead, ((PBYTE)(pPacket->p80211Header) + cbMacHdLen),
+                 cbFrameBodySize);
+    }
+    else {
+        // Copy the Packet into a tx Buffer
+        MEMvCopy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen);
+    }
+
+    pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4);
+    pDevice->wSeqCounter++ ;
+    if (pDevice->wSeqCounter > 0x0fff)
+        pDevice->wSeqCounter = 0;
+
+    if (bIsPSPOLL) {
+        // The MAC will automatically replace the Duration-field of MAC header by Duration-field
+        // of  FIFO control header.
+        // This will cause AID-field of PS-POLL packet be incorrect (Because PS-POLL's AID field is
+        // in the same place of other packet's Duration-field).
+        // And it will cause Cisco-AP to issue Disassociation-packet
+        if (byPktTyp == PK_TYPE_11GB || byPktTyp == PK_TYPE_11GA) {
+            ((PSTxDataHead_g)pvTxDataHd)->wDuration_a = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
+            ((PSTxDataHead_g)pvTxDataHd)->wDuration_b = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
+        } else {
+            ((PSTxDataHead_ab)pvTxDataHd)->wDuration = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
+        }
+    }
+
+
+    // first TD is the only TD
+    //Set TSR1 & ReqCount in TxDescHead
+    pFrstTD->m_td1TD1.byTCR = (TCR_STP | TCR_EDP | EDMSDU);
+    pFrstTD->pTDInfo->skb_dma = pFrstTD->pTDInfo->buf_dma;
+    pFrstTD->m_td1TD1.wReqCount = cpu_to_le16((WORD)(cbReqCount));
+    pFrstTD->buff_addr = cpu_to_le32(pFrstTD->pTDInfo->skb_dma);
+    pFrstTD->pTDInfo->byFlags = 0;
+
+    if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) {
+        // Disable PS
+        MACbPSWakeup(pDevice->PortOffset);
+    }
+    pDevice->bPWBitOn = FALSE;
+
+    wmb();
+    pFrstTD->m_td0TD0.f1Owner = OWNED_BY_NIC;
+    wmb();
+
+    pDevice->iTDUsed[TYPE_TXDMA0]++;
+
+    if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 1) {
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " available td0 <= 1\n");
+    }
+
+    pDevice->apCurrTD[TYPE_TXDMA0] = pFrstTD->next;
+#ifdef PLICE_DEBUG
+               //printk("SCAN:CurrentRate is  %d,TxPower is %d\n",wCurrentRate,pTxBufHead->byTxPower);
+#endif
+
+#ifdef TxInSleep
+  pDevice->nTxDataTimeCout=0; //2008-8-21 chester <add> for send null packet
+  #endif
+
+    // Poll Transmit the adapter
+    MACvTransmit0(pDevice->PortOffset);
+
+    return CMD_STATUS_PENDING;
+
+}
+
+
+CMD_STATUS csBeacon_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) {
+
+    BYTE             byPktTyp;
+    PBYTE            pbyBuffer = (PBYTE)pDevice->tx_beacon_bufs;
+    UINT             cbFrameSize = pPacket->cbMPDULen + WLAN_FCS_LEN;
+    UINT             cbHeaderSize = 0;
+    WORD             wTxBufSize = sizeof(STxShortBufHead);
+    PSTxShortBufHead pTxBufHead = (PSTxShortBufHead) pbyBuffer;
+    PSTxDataHead_ab  pTxDataHead = (PSTxDataHead_ab) (pbyBuffer + wTxBufSize);
+    PS802_11Header   pMACHeader;
+    WORD             wCurrentRate;
+    WORD             wLen = 0x0000;
+
+
+    memset(pTxBufHead, 0, wTxBufSize);
+
+    if (pDevice->eCurrentPHYType == PHY_TYPE_11A) {
+        wCurrentRate = RATE_6M;
+        byPktTyp = PK_TYPE_11A;
+    } else {
+        wCurrentRate = RATE_2M;
+        byPktTyp = PK_TYPE_11B;
+    }
+
+    //Set Preamble type always long
+    pDevice->byPreambleType = PREAMBLE_LONG;
+
+    //Set FIFOCTL_GENINT
+
+    pTxBufHead->wFIFOCtl |= FIFOCTL_GENINT;
+
+
+    //Set packet type & Get Duration
+    if (byPktTyp == PK_TYPE_11A) {//0000 0000 0000 0000
+        pTxDataHead->wDuration = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameSize, byPktTyp,
+                                                          wCurrentRate, FALSE, 0, 0, 1, AUTO_FB_NONE));
+    }
+    else if (byPktTyp == PK_TYPE_11B) {//0000 0001 0000 0000
+        pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
+        pTxDataHead->wDuration = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameSize, byPktTyp,
+                                                          wCurrentRate, FALSE, 0, 0, 1, AUTO_FB_NONE));
+    }
+
+    BBvCaculateParameter(pDevice, cbFrameSize, wCurrentRate, byPktTyp,
+        (PWORD)&(wLen), (PBYTE)&(pTxDataHead->byServiceField), (PBYTE)&(pTxDataHead->bySignalField)
+    );
+    pTxDataHead->wTransmitLength = cpu_to_le16(wLen);
+    //Get TimeStampOff
+    pTxDataHead->wTimeStampOff = cpu_to_le16(wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE]);
+    cbHeaderSize = wTxBufSize + sizeof(STxDataHead_ab);
+
+   //Generate Beacon Header
+    pMACHeader = (PS802_11Header)(pbyBuffer + cbHeaderSize);
+    MEMvCopy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen);
+
+    pMACHeader->wDurationID = 0;
+    pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4);
+    pDevice->wSeqCounter++ ;
+    if (pDevice->wSeqCounter > 0x0fff)
+        pDevice->wSeqCounter = 0;
+
+    // Set Beacon buffer length
+    pDevice->wBCNBufLen = pPacket->cbMPDULen + cbHeaderSize;
+
+    MACvSetCurrBCNTxDescAddr(pDevice->PortOffset, (pDevice->tx_beacon_dma));
+
+    MACvSetCurrBCNLength(pDevice->PortOffset, pDevice->wBCNBufLen);
+    // Set auto Transmit on
+    MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX);
+    // Poll Transmit the adapter
+    MACvTransmitBCN(pDevice->PortOffset);
+
+    return CMD_STATUS_PENDING;
+}
+
+
+
+UINT
+cbGetFragCount (
+    IN  PSDevice         pDevice,
+    IN  PSKeyItem        pTransmitKey,
+    IN  UINT             cbFrameBodySize,
+    IN  PSEthernetHeader psEthHeader
+    )
+{
+    UINT           cbMACHdLen;
+    UINT           cbFrameSize;
+    UINT           cbFragmentSize; //Hdr+(IV)+payoad+(MIC)+(ICV)+FCS
+    UINT           cbFragPayloadSize;
+    UINT           cbLastFragPayloadSize;
+    UINT           cbIVlen = 0;
+    UINT           cbICVlen = 0;
+    UINT           cbMIClen = 0;
+    UINT           cbFCSlen = 4;
+    UINT           uMACfragNum = 1;
+    BOOL           bNeedACK;
+
+
+
+    if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
+        (pDevice->eOPMode == OP_MODE_AP)) {
+        if (IS_MULTICAST_ADDRESS(&(psEthHeader->abyDstAddr[0])) ||
+            IS_BROADCAST_ADDRESS(&(psEthHeader->abyDstAddr[0]))) {
+            bNeedACK = FALSE;
+        }
+        else {
+            bNeedACK = TRUE;
+        }
+    }
+    else {
+        // MSDUs in Infra mode always need ACK
+        bNeedACK = TRUE;
+    }
+
+    if (pDevice->bLongHeader)
+        cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6;
+    else
+        cbMACHdLen = WLAN_HDR_ADDR3_LEN;
+
+
+    if (pDevice->bEncryptionEnable == TRUE) {
+
+        if (pTransmitKey == NULL) {
+            if ((pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) ||
+                (pDevice->pMgmt->eAuthenMode < WMAC_AUTH_WPA)) {
+                cbIVlen = 4;
+                cbICVlen = 4;
+            } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
+                cbIVlen = 8;//IV+ExtIV
+                cbMIClen = 8;
+                cbICVlen = 4;
+            } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
+                cbIVlen = 8;//RSN Header
+                cbICVlen = 8;//MIC
+            }
+        } else if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) {
+            cbIVlen = 4;
+            cbICVlen = 4;
+        } else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
+            cbIVlen = 8;//IV+ExtIV
+            cbMIClen = 8;
+            cbICVlen = 4;
+        } else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) {
+            cbIVlen = 8;//RSN Header
+            cbICVlen = 8;//MIC
+        }
+    }
+
+    cbFrameSize = cbMACHdLen + cbIVlen + (cbFrameBodySize + cbMIClen) + cbICVlen + cbFCSlen;
+
+    if ((cbFrameSize > pDevice->wFragmentationThreshold) && (bNeedACK == TRUE)) {
+        // Fragmentation
+        cbFragmentSize = pDevice->wFragmentationThreshold;
+        cbFragPayloadSize = cbFragmentSize - cbMACHdLen - cbIVlen - cbICVlen - cbFCSlen;
+        uMACfragNum = (WORD) ((cbFrameBodySize + cbMIClen) / cbFragPayloadSize);
+        cbLastFragPayloadSize = (cbFrameBodySize + cbMIClen) % cbFragPayloadSize;
+        if (cbLastFragPayloadSize == 0) {
+            cbLastFragPayloadSize = cbFragPayloadSize;
+        } else {
+            uMACfragNum++;
+        }
+    }
+    return uMACfragNum;
+}
+
+
+VOID
+vDMA0_tx_80211(PSDevice  pDevice, struct sk_buff *skb, PBYTE pbMPDU, UINT cbMPDULen) {
+
+    PSTxDesc        pFrstTD;
+    BYTE            byPktTyp;
+    PBYTE           pbyTxBufferAddr;
+    PVOID           pvRTS;
+    PVOID           pvCTS;
+    PVOID           pvTxDataHd;
+    UINT            uDuration;
+    UINT            cbReqCount;
+    PS802_11Header  pMACHeader;
+    UINT            cbHeaderSize;
+    UINT            cbFrameBodySize;
+    BOOL            bNeedACK;
+    BOOL            bIsPSPOLL = FALSE;
+    PSTxBufHead     pTxBufHead;
+    UINT            cbFrameSize;
+    UINT            cbIVlen = 0;
+    UINT            cbICVlen = 0;
+    UINT            cbMIClen = 0;
+    UINT            cbFCSlen = 4;
+    UINT            uPadding = 0;
+    UINT            cbMICHDR = 0;
+    UINT            uLength = 0;
+    DWORD           dwMICKey0, dwMICKey1;
+    DWORD           dwMIC_Priority;
+    PDWORD          pdwMIC_L;
+    PDWORD          pdwMIC_R;
+    WORD            wTxBufSize;
+    UINT            cbMacHdLen;
+    SEthernetHeader sEthHeader;
+    PVOID           pvRrvTime;
+    PVOID           pMICHDR;
+    PSMgmtObject    pMgmt = pDevice->pMgmt;
+    WORD            wCurrentRate = RATE_1M;
+    PUWLAN_80211HDR  p80211Header;
+    UINT             uNodeIndex = 0;
+    BOOL            bNodeExist = FALSE;
+    SKeyItem        STempKey;
+    PSKeyItem       pTransmitKey = NULL;
+    PBYTE           pbyIVHead;
+    PBYTE           pbyPayloadHead;
+    PBYTE           pbyMacHdr;
+
+    UINT            cbExtSuppRate = 0;
+//    PWLAN_IE        pItem;
+
+
+    pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL;
+
+    if(cbMPDULen <= WLAN_HDR_ADDR3_LEN) {
+       cbFrameBodySize = 0;
+    }
+    else {
+       cbFrameBodySize = cbMPDULen - WLAN_HDR_ADDR3_LEN;
+    }
+    p80211Header = (PUWLAN_80211HDR)pbMPDU;
+
+
+    pFrstTD = pDevice->apCurrTD[TYPE_TXDMA0];
+    pbyTxBufferAddr = (PBYTE)pFrstTD->pTDInfo->buf;
+    pTxBufHead = (PSTxBufHead) pbyTxBufferAddr;
+    wTxBufSize = sizeof(STxBufHead);
+    memset(pTxBufHead, 0, wTxBufSize);
+
+    if (pDevice->eCurrentPHYType == PHY_TYPE_11A) {
+        wCurrentRate = RATE_6M;
+        byPktTyp = PK_TYPE_11A;
+    } else {
+        wCurrentRate = RATE_1M;
+        byPktTyp = PK_TYPE_11B;
+    }
+
+    // SetPower will cause error power TX state for OFDM Date packet in TX buffer.
+    // 2004.11.11 Kyle -- Using OFDM power to tx MngPkt will decrease the connection capability.
+    //                    And cmd timer will wait data pkt TX finish before scanning so it's OK
+    //                    to set power here.
+    if (pDevice->pMgmt->eScanState != WMAC_NO_SCANNING) {
+        RFbSetPower(pDevice, wCurrentRate, pDevice->byCurrentCh);
+    } else {
+        RFbSetPower(pDevice, wCurrentRate, pMgmt->uCurrChannel);
+    }
+    pTxBufHead->byTxPower = pDevice->byCurPwr;
+
+    //+++++++++++++++++++++ Patch VT3253 A1 performance +++++++++++++++++++++++++++
+    if (pDevice->byFOETuning) {
+        if ((p80211Header->sA3.wFrameCtl & TYPE_DATE_NULL) == TYPE_DATE_NULL) {
+            wCurrentRate = RATE_24M;
+            byPktTyp = PK_TYPE_11GA;
+        }
+    }
+
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vDMA0_tx_80211: p80211Header->sA3.wFrameCtl = %x \n", p80211Header->sA3.wFrameCtl);
+
+    //Set packet type
+    if (byPktTyp == PK_TYPE_11A) {//0000 0000 0000 0000
+        pTxBufHead->wFIFOCtl = 0;
+    }
+    else if (byPktTyp == PK_TYPE_11B) {//0000 0001 0000 0000
+        pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
+    }
+    else if (byPktTyp == PK_TYPE_11GB) {//0000 0010 0000 0000
+        pTxBufHead->wFIFOCtl |= FIFOCTL_11GB;
+    }
+    else if (byPktTyp == PK_TYPE_11GA) {//0000 0011 0000 0000
+        pTxBufHead->wFIFOCtl |= FIFOCTL_11GA;
+    }
+
+    pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN;
+    pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
+
+
+    if (IS_MULTICAST_ADDRESS(&(p80211Header->sA3.abyAddr1[0])) ||
+        IS_BROADCAST_ADDRESS(&(p80211Header->sA3.abyAddr1[0]))) {
+        bNeedACK = FALSE;
+        if (pDevice->bEnableHostWEP) {
+            uNodeIndex = 0;
+            bNodeExist = TRUE;
+        };
+    }
+    else {
+        if (pDevice->bEnableHostWEP) {
+            if (BSSDBbIsSTAInNodeDB(pDevice->pMgmt, (PBYTE)(p80211Header->sA3.abyAddr1), &uNodeIndex))
+                bNodeExist = TRUE;
+        };
+        bNeedACK = TRUE;
+        pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
+    };
+
+    if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) ||
+        (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) ) {
+
+        pTxBufHead->wFIFOCtl |= FIFOCTL_LRETRY;
+        //Set Preamble type always long
+        //pDevice->byPreambleType = PREAMBLE_LONG;
+
+        // probe-response don't retry
+        //if ((p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_MGMT_PROBE_RSP) {
+        //     bNeedACK = FALSE;
+        //     pTxBufHead->wFIFOCtl  &= (~FIFOCTL_NEEDACK);
+        //}
+    }
+
+    pTxBufHead->wFIFOCtl |= (FIFOCTL_GENINT | FIFOCTL_ISDMA0);
+
+    if ((p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL) {
+        bIsPSPOLL = TRUE;
+        cbMacHdLen = WLAN_HDR_ADDR2_LEN;
+    } else {
+        cbMacHdLen = WLAN_HDR_ADDR3_LEN;
+    }
+
+    // hostapd deamon ext support rate patch
+    if (WLAN_GET_FC_FSTYPE(p80211Header->sA4.wFrameCtl) == WLAN_FSTYPE_ASSOCRESP) {
+
+        if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len != 0) {
+            cbExtSuppRate += ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN;
+         }
+
+        if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len != 0) {
+            cbExtSuppRate += ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len + WLAN_IEHDR_LEN;
+         }
+
+         if (cbExtSuppRate >0) {
+            cbFrameBodySize = WLAN_ASSOCRESP_OFF_SUPP_RATES;
+         }
+    }
+
+
+    //Set FRAGCTL_MACHDCNT
+    pTxBufHead->wFragCtl |= cpu_to_le16((WORD)cbMacHdLen << 10);
+
+    // Notes:
+    // Although spec says MMPDU can be fragmented; In most case,
+    // no one will send a MMPDU under fragmentation. With RTS may occur.
+    pDevice->bAES = FALSE;  //Set FRAGCTL_WEPTYP
+
+
+    if (WLAN_GET_FC_ISWEP(p80211Header->sA4.wFrameCtl) != 0) {
+        if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) {
+            cbIVlen = 4;
+            cbICVlen = 4;
+           pTxBufHead->wFragCtl |= FRAGCTL_LEGACY;
+        }
+        else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
+            cbIVlen = 8;//IV+ExtIV
+            cbMIClen = 8;
+            cbICVlen = 4;
+           pTxBufHead->wFragCtl |= FRAGCTL_TKIP;
+           //We need to get seed here for filling TxKey entry.
+            //TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr,
+            //            pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, pDevice->abyPRNG);
+        }
+        else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
+            cbIVlen = 8;//RSN Header
+            cbICVlen = 8;//MIC
+            cbMICHDR = sizeof(SMICHDRHead);
+            pTxBufHead->wFragCtl |= FRAGCTL_AES;
+            pDevice->bAES = TRUE;
+        }
+        //MAC Header should be padding 0 to DW alignment.
+        uPadding = 4 - (cbMacHdLen%4);
+        uPadding %= 4;
+    }
+
+    cbFrameSize = cbMacHdLen + cbFrameBodySize + cbIVlen + cbMIClen + cbICVlen + cbFCSlen + cbExtSuppRate;
+
+    //Set FIFOCTL_GrpAckPolicy
+    if (pDevice->bGrpAckPolicy == TRUE) {//0000 0100 0000 0000
+        pTxBufHead->wFIFOCtl |=        FIFOCTL_GRPACK;
+    }
+    //the rest of pTxBufHead->wFragCtl:FragTyp will be set later in s_vFillFragParameter()
+
+
+    if (byPktTyp == PK_TYPE_11GB || byPktTyp == PK_TYPE_11GA) {//802.11g packet
+
+        pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize);
+        pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS));
+        pvRTS = NULL;
+        pvCTS = (PSCTS) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR);
+        pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS));
+        cbHeaderSize = wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS) + sizeof(STxDataHead_g);
+
+    }
+    else {//802.11a/b packet
+
+        pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize);
+        pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab));
+        pvRTS = NULL;
+        pvCTS = NULL;
+        pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR);
+        cbHeaderSize = wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR + sizeof(STxDataHead_ab);
+
+    }
+
+    ZERO_MEMORY((PVOID)(pbyTxBufferAddr + wTxBufSize), (cbHeaderSize - wTxBufSize));
+    MEMvCopy(&(sEthHeader.abyDstAddr[0]), &(p80211Header->sA3.abyAddr1[0]), U_ETHER_ADDR_LEN);
+    MEMvCopy(&(sEthHeader.abySrcAddr[0]), &(p80211Header->sA3.abyAddr2[0]), U_ETHER_ADDR_LEN);
+    //=========================
+    //    No Fragmentation
+    //=========================
+    pTxBufHead->wFragCtl |= (WORD)FRAGCTL_NONFRAG;
+
+
+    //Fill FIFO,RrvTime,RTS,and CTS
+    s_vGenerateTxParameter(pDevice, byPktTyp, pbyTxBufferAddr, pvRrvTime, pvRTS, pvCTS,
+                           cbFrameSize, bNeedACK, TYPE_TXDMA0, &sEthHeader, wCurrentRate);
+
+    //Fill DataHead
+    uDuration = s_uFillDataHead(pDevice, byPktTyp, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK,
+                                0, 0, 1, AUTO_FB_NONE, wCurrentRate);
+
+    pMACHeader = (PS802_11Header) (pbyTxBufferAddr + cbHeaderSize);
+
+    cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + (cbFrameBodySize + cbMIClen) + cbExtSuppRate;
+
+    pbyMacHdr = (PBYTE)(pbyTxBufferAddr + cbHeaderSize);
+    pbyPayloadHead = (PBYTE)(pbyMacHdr + cbMacHdLen + uPadding + cbIVlen);
+    pbyIVHead = (PBYTE)(pbyMacHdr + cbMacHdLen + uPadding);
+
+    // Copy the Packet into a tx Buffer
+    memcpy(pbyMacHdr, pbMPDU, cbMacHdLen);
+
+    // version set to 0, patch for hostapd deamon
+    pMACHeader->wFrameCtl &= cpu_to_le16(0xfffc);
+    memcpy(pbyPayloadHead, (pbMPDU + cbMacHdLen), cbFrameBodySize);
+
+    // replace support rate, patch for hostapd deamon( only support 11M)
+    if (WLAN_GET_FC_FSTYPE(p80211Header->sA4.wFrameCtl) == WLAN_FSTYPE_ASSOCRESP) {
+        if (cbExtSuppRate != 0) {
+            if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len != 0)
+                memcpy((pbyPayloadHead + cbFrameBodySize),
+                        pMgmt->abyCurrSuppRates,
+                        ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN
+                       );
+             if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len != 0)
+                memcpy((pbyPayloadHead + cbFrameBodySize) + ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN,
+                        pMgmt->abyCurrExtSuppRates,
+                        ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len + WLAN_IEHDR_LEN
+                       );
+         }
+    }
+
+    // Set wep
+    if (WLAN_GET_FC_ISWEP(p80211Header->sA4.wFrameCtl) != 0) {
+
+        if (pDevice->bEnableHostWEP) {
+            pTransmitKey = &STempKey;
+            pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite;
+            pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex;
+            pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength;
+            pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16;
+            pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0;
+            memcpy(pTransmitKey->abyKey,
+                &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0],
+                pTransmitKey->uKeyLength
+                );
+        }
+
+        if ((pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
+
+            dwMICKey0 = *(PDWORD)(&pTransmitKey->abyKey[16]);
+            dwMICKey1 = *(PDWORD)(&pTransmitKey->abyKey[20]);
+
+            // DO Software Michael
+            MIC_vInit(dwMICKey0, dwMICKey1);
+            MIC_vAppend((PBYTE)&(sEthHeader.abyDstAddr[0]), 12);
+            dwMIC_Priority = 0;
+            MIC_vAppend((PBYTE)&dwMIC_Priority, 4);
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"DMA0_tx_8021:MIC KEY: %lX, %lX\n", dwMICKey0, dwMICKey1);
+
+            uLength = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen;
+
+            MIC_vAppend((pbyTxBufferAddr + uLength), cbFrameBodySize);
+
+            pdwMIC_L = (PDWORD)(pbyTxBufferAddr + uLength + cbFrameBodySize);
+            pdwMIC_R = (PDWORD)(pbyTxBufferAddr + uLength + cbFrameBodySize + 4);
+
+            MIC_vGetMIC(pdwMIC_L, pdwMIC_R);
+            MIC_vUnInit();
+
+            if (pDevice->bTxMICFail == TRUE) {
+                *pdwMIC_L = 0;
+                *pdwMIC_R = 0;
+                pDevice->bTxMICFail = FALSE;
+            }
+
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"uLength: %d, %d\n", uLength, cbFrameBodySize);
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"cbReqCount:%d, %d, %d, %d\n", cbReqCount, cbHeaderSize, uPadding, cbIVlen);
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC:%lx, %lx\n", *pdwMIC_L, *pdwMIC_R);
+
+        }
+
+
+        s_vFillTxKey(pDevice, (PBYTE)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey,
+                     pbyMacHdr, (WORD)cbFrameBodySize, (PBYTE)pMICHDR);
+
+        if (pDevice->bEnableHostWEP) {
+            pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16;
+            pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0;
+        }
+
+        if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) {
+            s_vSWencryption(pDevice, pTransmitKey, pbyPayloadHead, (WORD)(cbFrameBodySize + cbMIClen));
+        }
+    }
+
+    pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4);
+    pDevice->wSeqCounter++ ;
+    if (pDevice->wSeqCounter > 0x0fff)
+        pDevice->wSeqCounter = 0;
+
+
+    if (bIsPSPOLL) {
+        // The MAC will automatically replace the Duration-field of MAC header by Duration-field
+        // of  FIFO control header.
+        // This will cause AID-field of PS-POLL packet be incorrect (Because PS-POLL's AID field is
+        // in the same place of other packet's Duration-field).
+        // And it will cause Cisco-AP to issue Disassociation-packet
+        if (byPktTyp == PK_TYPE_11GB || byPktTyp == PK_TYPE_11GA) {
+            ((PSTxDataHead_g)pvTxDataHd)->wDuration_a = cpu_to_le16(p80211Header->sA2.wDurationID);
+            ((PSTxDataHead_g)pvTxDataHd)->wDuration_b = cpu_to_le16(p80211Header->sA2.wDurationID);
+        } else {
+            ((PSTxDataHead_ab)pvTxDataHd)->wDuration = cpu_to_le16(p80211Header->sA2.wDurationID);
+        }
+    }
+
+
+    // first TD is the only TD
+    //Set TSR1 & ReqCount in TxDescHead
+    pFrstTD->pTDInfo->skb = skb;
+    pFrstTD->m_td1TD1.byTCR = (TCR_STP | TCR_EDP | EDMSDU);
+    pFrstTD->pTDInfo->skb_dma = pFrstTD->pTDInfo->buf_dma;
+    pFrstTD->m_td1TD1.wReqCount = cpu_to_le16(cbReqCount);
+    pFrstTD->buff_addr = cpu_to_le32(pFrstTD->pTDInfo->skb_dma);
+    pFrstTD->pTDInfo->byFlags = 0;
+    pFrstTD->pTDInfo->byFlags |= TD_FLAGS_PRIV_SKB;
+
+    if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) {
+        // Disable PS
+        MACbPSWakeup(pDevice->PortOffset);
+    }
+    pDevice->bPWBitOn = FALSE;
+
+    wmb();
+    pFrstTD->m_td0TD0.f1Owner = OWNED_BY_NIC;
+    wmb();
+
+    pDevice->iTDUsed[TYPE_TXDMA0]++;
+
+    if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 1) {
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " available td0 <= 1\n");
+    }
+
+    pDevice->apCurrTD[TYPE_TXDMA0] = pFrstTD->next;
+
+    // Poll Transmit the adapter
+    MACvTransmit0(pDevice->PortOffset);
+
+    return;
+}
+
+
diff --git a/drivers/staging/vt6655/rxtx.h b/drivers/staging/vt6655/rxtx.h
new file mode 100644 (file)
index 0000000..3e85264
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * 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: whdr.h
+ *
+ * Purpose:
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Jun. 27, 2002
+ *
+ */
+
+
+#ifndef __RXTX_H__
+#define __RXTX_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 vGenerateMACHeader(
+    IN PSDevice pDevice,
+    IN DWORD dwTxBufferAddr,
+    IN PBYTE pbySkbData,
+    IN UINT cbPacketSize,
+    IN BOOL bDMA0Used,
+    OUT PUINT pcbHeadSize,
+    OUT PUINT pcbAppendPayload
+     );
+
+VOID vProcessRxMACHeader (
+    IN  PSDevice pDevice,
+    IN  DWORD dwRxBufferAddr,
+    IN  UINT cbPacketSize,
+    IN  BOOL bIsWEP,
+    OUT PUINT pcbHeadSize
+    );
+*/
+
+
+VOID
+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
+    );
+
+
+UINT
+cbGetFragCount(
+    IN  PSDevice         pDevice,
+    IN  PSKeyItem        pTransmitKey,
+    IN  UINT             cbFrameBodySize,
+    IN  PSEthernetHeader psEthHeader
+    );
+
+
+VOID
+vGenerateFIFOHeader (
+    IN  PSDevice         pDevice,
+    IN  BYTE             byPktTyp,
+    IN  PBYTE            pbyTxBufferAddr,
+    IN  BOOL             bNeedEncrypt,
+    IN  UINT             cbPayloadSize,
+    IN  UINT             uDMAIdx,
+    IN  PSTxDesc         pHeadTD,
+    IN  PSEthernetHeader psEthHeader,
+    IN  PBYTE            pPacket,
+    IN  PSKeyItem        pTransmitKey,
+    IN  UINT             uNodeIndex,
+    OUT PUINT            puMACfragNum,
+    OUT PUINT            pcbHeaderSize
+    );
+
+
+VOID vDMA0_tx_80211(PSDevice  pDevice, struct sk_buff *skb, PBYTE pbMPDU, UINT cbMPDULen);
+CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket);
+CMD_STATUS csBeacon_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket);
+
+#ifdef __cplusplus
+}                                       /* End of extern "C" { */
+#endif /* __cplusplus */
+
+
+
+
+#endif // __RXTX_H__
+
+
+
diff --git a/drivers/staging/vt6655/srom.c b/drivers/staging/vt6655/srom.c
new file mode 100644 (file)
index 0000000..655d685
--- /dev/null
@@ -0,0 +1,437 @@
+/*
+ * 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: srom.c
+ *
+ * Purpose:Implement functions to access eeprom
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Jan 29, 2003
+ *
+ * Functions:
+ *      SROMbyReadEmbedded - Embedded read eeprom via MAC
+ *      SROMbWriteEmbedded - Embedded write eeprom via MAC
+ *      SROMvRegBitsOn - Set Bits On in eeprom
+ *      SROMvRegBitsOff - Clear Bits Off in eeprom
+ *      SROMbIsRegBitsOn - Test if Bits On in eeprom
+ *      SROMbIsRegBitsOff - Test if Bits Off in eeprom
+ *      SROMvReadAllContents - Read all contents in eeprom
+ *      SROMvWriteAllContents - Write all contents in eeprom
+ *      SROMvReadEtherAddress - Read Ethernet Address in eeprom
+ *      SROMvWriteEtherAddress - Write Ethernet Address in eeprom
+ *      SROMvReadSubSysVenId - Read Sub_VID and Sub_SysId in eeprom
+ *      SROMbAutoLoad - Auto Load eeprom to MAC register
+ *
+ * Revision History:
+ *
+ */
+
+
+#if !defined(__UPC_H__)
+#include "upc.h"
+#endif
+#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(__SROM_H__)
+#include "srom.h"
+#endif
+
+
+
+
+/*---------------------  Static Definitions -------------------------*/
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+
+/*---------------------  Static Functions  --------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+
+
+/*
+ * Description: Read a byte from EEPROM, by MAC I2C
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase        - I/O base address
+ *      byContntOffset  - address of EEPROM
+ *  Out:
+ *      none
+ *
+ * Return Value: data read
+ *
+ */
+BYTE SROMbyReadEmbedded(DWORD_PTR dwIoBase, BYTE byContntOffset)
+{
+    WORD    wDelay, wNoACK;
+    BYTE    byWait;
+    BYTE    byData;
+    BYTE    byOrg;
+
+    byData = 0xFF;
+    VNSvInPortB(dwIoBase + MAC_REG_I2MCFG, &byOrg);
+    // turn off hardware retry for getting NACK
+    VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, (byOrg & (~I2MCFG_NORETRY)));
+    for (wNoACK = 0; wNoACK < W_MAX_I2CRETRY; wNoACK++) {
+        VNSvOutPortB(dwIoBase + MAC_REG_I2MTGID, EEP_I2C_DEV_ID);
+        VNSvOutPortB(dwIoBase + MAC_REG_I2MTGAD, byContntOffset);
+
+        // issue read command
+        VNSvOutPortB(dwIoBase + MAC_REG_I2MCSR, I2MCSR_EEMR);
+        // wait DONE be set
+        for (wDelay = 0; wDelay < W_MAX_TIMEOUT; wDelay++) {
+            VNSvInPortB(dwIoBase + MAC_REG_I2MCSR, &byWait);
+            if (BITbIsAnyBitsOn(byWait, (I2MCSR_DONE | I2MCSR_NACK)))
+                break;
+            PCAvDelayByIO(CB_DELAY_LOOP_WAIT);
+        }
+        if ((wDelay < W_MAX_TIMEOUT) &&
+             (BITbIsBitOff(byWait, I2MCSR_NACK))) {
+            break;
+        }
+    }
+    VNSvInPortB(dwIoBase + MAC_REG_I2MDIPT, &byData);
+    VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, byOrg);
+    return byData;
+}
+
+
+/*
+ * Description: Write a byte to EEPROM, by MAC I2C
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase        - I/O base address
+ *      byContntOffset  - address of EEPROM
+ *      wData           - data to write
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if succeeded; FALSE if failed.
+ *
+ */
+BOOL SROMbWriteEmbedded (DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byData)
+{
+    WORD    wDelay, wNoACK;
+    BYTE    byWait;
+
+    BYTE    byOrg;
+
+    VNSvInPortB(dwIoBase + MAC_REG_I2MCFG, &byOrg);
+    // turn off hardware retry for getting NACK
+    VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, (byOrg & (~I2MCFG_NORETRY)));
+    for (wNoACK = 0; wNoACK < W_MAX_I2CRETRY; wNoACK++) {
+        VNSvOutPortB(dwIoBase + MAC_REG_I2MTGID, EEP_I2C_DEV_ID);
+        VNSvOutPortB(dwIoBase + MAC_REG_I2MTGAD, byContntOffset);
+        VNSvOutPortB(dwIoBase + MAC_REG_I2MDOPT, byData);
+
+        // issue write command
+        VNSvOutPortB(dwIoBase + MAC_REG_I2MCSR, I2MCSR_EEMW);
+        // wait DONE be set
+        for (wDelay = 0; wDelay < W_MAX_TIMEOUT; wDelay++) {
+            VNSvInPortB(dwIoBase + MAC_REG_I2MCSR, &byWait);
+            if (BITbIsAnyBitsOn(byWait, (I2MCSR_DONE | I2MCSR_NACK)))
+                break;
+            PCAvDelayByIO(CB_DELAY_LOOP_WAIT);
+        }
+
+        if ((wDelay < W_MAX_TIMEOUT) &&
+             (BITbIsBitOff(byWait, I2MCSR_NACK))) {
+            break;
+        }
+    }
+    if (wNoACK == W_MAX_I2CRETRY) {
+        VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, byOrg);
+        return FALSE;
+    }
+    VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, byOrg);
+    return TRUE;
+}
+
+
+/*
+ * Description: Turn bits on in eeprom
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase        - I/O base address
+ *      byContntOffset  - address of EEPROM
+ *      byBits          - bits to turn on
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void SROMvRegBitsOn (DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byBits)
+{
+    BYTE    byOrgData;
+
+    byOrgData = SROMbyReadEmbedded(dwIoBase, byContntOffset);
+    SROMbWriteEmbedded(dwIoBase, byContntOffset,(BYTE)(byOrgData | byBits));
+}
+
+
+/*
+ * Description: Turn bits off in eeprom
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase        - I/O base address
+ *      byContntOffset  - address of EEPROM
+ *      byBits          - bits to turn off
+ *  Out:
+ *      none
+ *
+ */
+void SROMvRegBitsOff (DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byBits)
+{
+    BYTE    byOrgData;
+
+    byOrgData = SROMbyReadEmbedded(dwIoBase, byContntOffset);
+    SROMbWriteEmbedded(dwIoBase, byContntOffset,(BYTE)(byOrgData & (~byBits)));
+}
+
+
+/*
+ * Description: Test if bits on in eeprom
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase        - I/O base address
+ *      byContntOffset  - address of EEPROM
+ *      byTestBits      - bits to test
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if all test bits on; otherwise FALSE
+ *
+ */
+BOOL SROMbIsRegBitsOn (DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byTestBits)
+{
+    BYTE    byOrgData;
+
+    byOrgData = SROMbyReadEmbedded(dwIoBase, byContntOffset);
+    return BITbIsAllBitsOn(byOrgData, byTestBits);
+}
+
+
+/*
+ * Description: Test if bits off in eeprom
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase        - I/O base address
+ *      byContntOffset  - address of EEPROM
+ *      byTestBits      - bits to test
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if all test bits off; otherwise FALSE
+ *
+ */
+BOOL SROMbIsRegBitsOff (DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byTestBits)
+{
+    BYTE    byOrgData;
+
+    byOrgData = SROMbyReadEmbedded(dwIoBase, byContntOffset);
+    return BITbIsAllBitsOff(byOrgData, byTestBits);
+}
+
+
+/*
+ * Description: Read all contents of eeprom to buffer
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase        - I/O base address
+ *  Out:
+ *      pbyEepromRegs   - EEPROM content Buffer
+ *
+ * Return Value: none
+ *
+ */
+void SROMvReadAllContents (DWORD_PTR dwIoBase, PBYTE pbyEepromRegs)
+{
+    int     ii;
+
+    // ii = Rom Address
+    for (ii = 0; ii < EEP_MAX_CONTEXT_SIZE; ii++) {
+        *pbyEepromRegs = SROMbyReadEmbedded(dwIoBase,(BYTE) ii);
+        pbyEepromRegs++;
+    }
+}
+
+
+/*
+ * Description: Write all contents of buffer to eeprom
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase        - I/O base address
+ *      pbyEepromRegs   - EEPROM content Buffer
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void SROMvWriteAllContents (DWORD_PTR dwIoBase, PBYTE pbyEepromRegs)
+{
+    int     ii;
+
+    // ii = Rom Address
+    for (ii = 0; ii < EEP_MAX_CONTEXT_SIZE; ii++) {
+        SROMbWriteEmbedded(dwIoBase,(BYTE) ii, *pbyEepromRegs);
+        pbyEepromRegs++;
+    }
+}
+
+
+/*
+ * Description: Read Ethernet Address from eeprom to buffer
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase        - I/O base address
+ *  Out:
+ *      pbyEtherAddress - Ethernet Address buffer
+ *
+ * Return Value: none
+ *
+ */
+void SROMvReadEtherAddress (DWORD_PTR dwIoBase, PBYTE pbyEtherAddress)
+{
+    BYTE     ii;
+
+    // ii = Rom Address
+    for (ii = 0; ii < U_ETHER_ADDR_LEN; ii++) {
+        *pbyEtherAddress = SROMbyReadEmbedded(dwIoBase, ii);
+        pbyEtherAddress++;
+    }
+}
+
+
+/*
+ * Description: Write Ethernet Address from buffer to eeprom
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase        - I/O base address
+ *      pbyEtherAddress - Ethernet Address buffer
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void SROMvWriteEtherAddress (DWORD_PTR dwIoBase, PBYTE pbyEtherAddress)
+{
+    BYTE     ii;
+
+    // ii = Rom Address
+    for (ii = 0; ii < U_ETHER_ADDR_LEN; ii++) {
+        SROMbWriteEmbedded(dwIoBase, ii, *pbyEtherAddress);
+        pbyEtherAddress++;
+    }
+}
+
+
+/*
+ * Description: Read Sub_VID and Sub_SysId from eeprom to buffer
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase        - I/O base address
+ *  Out:
+ *      pdwSubSysVenId  - Sub_VID and Sub_SysId read
+ *
+ * Return Value: none
+ *
+ */
+void SROMvReadSubSysVenId (DWORD_PTR dwIoBase, PDWORD pdwSubSysVenId)
+{
+    PBYTE   pbyData;
+
+    pbyData = (PBYTE)pdwSubSysVenId;
+    // sub vendor
+    *pbyData = SROMbyReadEmbedded(dwIoBase, 6);
+    *(pbyData+1) = SROMbyReadEmbedded(dwIoBase, 7);
+    // sub system
+    *(pbyData+2) = SROMbyReadEmbedded(dwIoBase, 8);
+    *(pbyData+3) = SROMbyReadEmbedded(dwIoBase, 9);
+}
+
+/*
+ * Description: Auto Load EEPROM to MAC register
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase        - I/O base address
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if success; otherwise FALSE
+ *
+ */
+BOOL SROMbAutoLoad (DWORD_PTR dwIoBase)
+{
+    BYTE    byWait;
+    int     ii;
+
+    BYTE    byOrg;
+
+    VNSvInPortB(dwIoBase + MAC_REG_I2MCFG, &byOrg);
+    // turn on hardware retry
+    VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, (byOrg | I2MCFG_NORETRY));
+
+    MACvRegBitsOn(dwIoBase, MAC_REG_I2MCSR, I2MCSR_AUTOLD);
+
+    // ii = Rom Address
+    for (ii = 0; ii < EEP_MAX_CONTEXT_SIZE; ii++) {
+        MACvTimer0MicroSDelay(dwIoBase, CB_EEPROM_READBYTE_WAIT);
+        VNSvInPortB(dwIoBase + MAC_REG_I2MCSR, &byWait);
+        if (BITbIsBitOff(byWait, I2MCSR_AUTOLD))
+            break;
+    }
+
+    VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, byOrg);
+
+    if (ii == EEP_MAX_CONTEXT_SIZE)
+        return FALSE;
+    return TRUE;
+}
+
+
diff --git a/drivers/staging/vt6655/srom.h b/drivers/staging/vt6655/srom.h
new file mode 100644 (file)
index 0000000..a4ca5f0
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * 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: srom.h
+ *
+ * Purpose: Implement functions to access eeprom
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Jan 29, 2003
+ *
+ */
+
+
+#ifndef __SROM_H__
+#define __SROM_H__
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+
+
+/*---------------------  Export Definitions -------------------------*/
+
+
+#define EEP_MAX_CONTEXT_SIZE    256
+
+#define CB_EEPROM_READBYTE_WAIT 900     //us
+
+#define W_MAX_I2CRETRY          0x0fff
+
+//
+// Contents in the EEPROM
+//
+
+#define EEP_OFS_PAR         0x00        // physical address
+#define EEP_OFS_ANTENNA     0x16
+#define EEP_OFS_RADIOCTL    0x17
+#define EEP_OFS_RFTYPE      0x1B        // for select RF
+#define EEP_OFS_MINCHANNEL  0x1C        // Min Channel #
+#define EEP_OFS_MAXCHANNEL  0x1D        // Max Channel #
+#define EEP_OFS_SIGNATURE   0x1E        //
+#define EEP_OFS_ZONETYPE    0x1F        //
+#define EEP_OFS_RFTABLE     0x20        // RF POWER TABLE
+#define EEP_OFS_PWR_CCK     0x20
+#define EEP_OFS_SETPT_CCK   0x21
+#define EEP_OFS_PWR_OFDMG   0x23
+#define EEP_OFS_SETPT_OFDMG 0x24
+#define EEP_OFS_PWR_FORMULA_OST  0x26   //
+#define EEP_OFS_MAJOR_VER 0x2E
+#define EEP_OFS_MINOR_VER 0x2F
+#define EEP_OFS_CCK_PWR_TBL     0x30
+#define EEP_OFS_CCK_PWR_dBm     0x3F
+#define EEP_OFS_OFDM_PWR_TBL    0x40
+#define EEP_OFS_OFDM_PWR_dBm    0x4F
+//{{ RobertYu: 20041124
+#define EEP_OFS_SETPT_OFDMA         0x4E
+#define EEP_OFS_OFDMA_PWR_TBL       0x50
+//}}
+#define EEP_OFS_OFDMA_PWR_dBm       0xD2
+
+
+//----------need to remove --------------------
+#define EEP_OFS_BBTAB_LEN   0x70        // BB Table Length
+#define EEP_OFS_BBTAB_ADR   0x71        // BB Table Offset
+#define EEP_OFS_CHECKSUM    0xFF        // reserved area for baseband 28h ~ 78h
+
+#define EEP_I2C_DEV_ID      0x50        // EEPROM device address on the I2C bus
+
+
+//
+// Bits in EEP_OFS_ANTENNA
+//
+#define EEP_ANTENNA_MAIN    0x01
+#define EEP_ANTENNA_AUX     0x02
+#define EEP_ANTINV          0x04
+
+//
+// Bits in EEP_OFS_RADIOCTL
+//
+#define EEP_RADIOCTL_ENABLE 0x80
+#define EEP_RADIOCTL_INV    0x01
+
+
+
+/*---------------------  Export Types  ------------------------------*/
+
+// AT24C02 eeprom contents
+//      2048 bits = 256 bytes = 128 words
+//
+typedef struct tagSSromReg {
+    BYTE    abyPAR[6];                  // 0x00 (WORD)
+
+    WORD    wSUB_VID;                   // 0x03 (WORD)
+    WORD    wSUB_SID;
+
+    BYTE    byBCFG0;                    // 0x05 (WORD)
+    BYTE    byBCFG1;
+
+    BYTE    byFCR0;                     // 0x06 (WORD)
+    BYTE    byFCR1;
+    BYTE    byPMC0;                     // 0x07 (WORD)
+    BYTE    byPMC1;
+    BYTE    byMAXLAT;                   // 0x08 (WORD)
+    BYTE    byMINGNT;
+    BYTE    byCFG0;                     // 0x09 (WORD)
+    BYTE    byCFG1;
+    WORD    wCISPTR;                    // 0x0A (WORD)
+    WORD    wRsv0;                      // 0x0B (WORD)
+    WORD    wRsv1;                      // 0x0C (WORD)
+    BYTE    byBBPAIR;                   // 0x0D (WORD)
+    BYTE    byRFTYPE;
+    BYTE    byMinChannel;               // 0x0E (WORD)
+    BYTE    byMaxChannel;
+    BYTE    bySignature;                // 0x0F (WORD)
+    BYTE    byCheckSum;
+
+    BYTE    abyReserved0[96];           // 0x10 (WORD)
+    BYTE    abyCIS[128];                // 0x80 (WORD)
+} SSromReg, DEF* PSSromReg;
+
+/*---------------------  Export Macros ------------------------------*/
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+#ifdef __cplusplus
+extern "C" {                            /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+
+BYTE SROMbyReadEmbedded(DWORD_PTR dwIoBase, BYTE byContntOffset);
+BOOL SROMbWriteEmbedded(DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byData);
+
+void SROMvRegBitsOn(DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byBits);
+void SROMvRegBitsOff(DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byBits);
+
+BOOL SROMbIsRegBitsOn(DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byTestBits);
+BOOL SROMbIsRegBitsOff(DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byTestBits);
+
+void SROMvReadAllContents(DWORD_PTR dwIoBase, PBYTE pbyEepromRegs);
+void SROMvWriteAllContents(DWORD_PTR dwIoBase, PBYTE pbyEepromRegs);
+
+void SROMvReadEtherAddress(DWORD_PTR dwIoBase, PBYTE pbyEtherAddress);
+void SROMvWriteEtherAddress(DWORD_PTR dwIoBase, PBYTE pbyEtherAddress);
+
+VOID SROMvReadSubSysVenId(DWORD_PTR dwIoBase, PDWORD pdwSubSysVenId);
+
+BOOL SROMbAutoLoad (DWORD_PTR dwIoBase);
+
+
+#ifdef __cplusplus
+}                                       /* End of extern "C" { */
+#endif /* __cplusplus */
+
+
+
+
+#endif // __EEPROM_H__
+
+
diff --git a/drivers/staging/vt6655/tbit.h b/drivers/staging/vt6655/tbit.h
new file mode 100644 (file)
index 0000000..7c3a82e
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * 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: tbit.h
+ *
+ * Purpose: Bit routines
+ *
+ * Author: Tevin Chen
+ *
+ * Date: May 21, 1996
+ *
+ */
+
+
+#ifndef __TBIT_H__
+#define __TBIT_H__
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+
+
+
+/*---------------------  Export Definitions -------------------------*/
+
+/*---------------------  Export Types  ------------------------------*/
+
+/*---------------------  Export Macros ------------------------------*/
+
+// test single bit on
+#define BITbIsBitOn(tData, tTestBit)                \
+    (((tData) & (tTestBit)) != 0)
+
+// test single bit off
+#define BITbIsBitOff(tData, tTestBit)               \
+    (((tData) & (tTestBit)) == 0)
+
+
+#define BITbIsAllBitsOn(tData, tTestBit)            \
+    (((tData) & (tTestBit)) == (tTestBit))
+
+#define BITbIsAllBitsOff(tData, tTestBit)           \
+    (((tData) & (tTestBit)) == 0)
+
+#define BITbIsAnyBitsOn(tData, tTestBit)            \
+    (((tData) & (tTestBit)) != 0)
+
+#define BITbIsAnyBitsOff(tData, tTestBit)           \
+    (((tData) & (tTestBit)) != (tTestBit))
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+
+#endif // __TBIT_H__
+
+
+
diff --git a/drivers/staging/vt6655/tcrc.c b/drivers/staging/vt6655/tcrc.c
new file mode 100644 (file)
index 0000000..b70080c
--- /dev/null
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 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: tcrc.c
+ *
+ * Purpose: Implement functions to caculate CRC
+ *
+ * Author: Tevin Chen
+ *
+ * Date: May 21, 1996
+ *
+ * Functions:
+ *      CRCdwCrc32 -
+ *      CRCdwGetCrc32 -
+ *      CRCdwGetCrc32Ex -
+ *
+ * Revision History:
+ *
+ */
+
+
+#if !defined(__TBIT_H__)
+#include "tbit.h"
+#endif
+#if !defined(__TCRC_H__)
+#include "tcrc.h"
+#endif
+
+
+
+
+/*---------------------  Static Definitions -------------------------*/
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+
+// 32-bit CRC table
+static const DWORD s_adwCrc32Table[256] = {
+    0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL,
+    0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L,
+    0x0EDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L,
+    0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L, 0x90BF1D91L,
+    0x1DB71064L, 0x6AB020F2L, 0xF3B97148L, 0x84BE41DEL,
+    0x1ADAD47DL, 0x6DDDE4EBL, 0xF4D4B551L, 0x83D385C7L,
+    0x136C9856L, 0x646BA8C0L, 0xFD62F97AL, 0x8A65C9ECL,
+    0x14015C4FL, 0x63066CD9L, 0xFA0F3D63L, 0x8D080DF5L,
+    0x3B6E20C8L, 0x4C69105EL, 0xD56041E4L, 0xA2677172L,
+    0x3C03E4D1L, 0x4B04D447L, 0xD20D85FDL, 0xA50AB56BL,
+    0x35B5A8FAL, 0x42B2986CL, 0xDBBBC9D6L, 0xACBCF940L,
+    0x32D86CE3L, 0x45DF5C75L, 0xDCD60DCFL, 0xABD13D59L,
+    0x26D930ACL, 0x51DE003AL, 0xC8D75180L, 0xBFD06116L,
+    0x21B4F4B5L, 0x56B3C423L, 0xCFBA9599L, 0xB8BDA50FL,
+    0x2802B89EL, 0x5F058808L, 0xC60CD9B2L, 0xB10BE924L,
+    0x2F6F7C87L, 0x58684C11L, 0xC1611DABL, 0xB6662D3DL,
+    0x76DC4190L, 0x01DB7106L, 0x98D220BCL, 0xEFD5102AL,
+    0x71B18589L, 0x06B6B51FL, 0x9FBFE4A5L, 0xE8B8D433L,
+    0x7807C9A2L, 0x0F00F934L, 0x9609A88EL, 0xE10E9818L,
+    0x7F6A0DBBL, 0x086D3D2DL, 0x91646C97L, 0xE6635C01L,
+    0x6B6B51F4L, 0x1C6C6162L, 0x856530D8L, 0xF262004EL,
+    0x6C0695EDL, 0x1B01A57BL, 0x8208F4C1L, 0xF50FC457L,
+    0x65B0D9C6L, 0x12B7E950L, 0x8BBEB8EAL, 0xFCB9887CL,
+    0x62DD1DDFL, 0x15DA2D49L, 0x8CD37CF3L, 0xFBD44C65L,
+    0x4DB26158L, 0x3AB551CEL, 0xA3BC0074L, 0xD4BB30E2L,
+    0x4ADFA541L, 0x3DD895D7L, 0xA4D1C46DL, 0xD3D6F4FBL,
+    0x4369E96AL, 0x346ED9FCL, 0xAD678846L, 0xDA60B8D0L,
+    0x44042D73L, 0x33031DE5L, 0xAA0A4C5FL, 0xDD0D7CC9L,
+    0x5005713CL, 0x270241AAL, 0xBE0B1010L, 0xC90C2086L,
+    0x5768B525L, 0x206F85B3L, 0xB966D409L, 0xCE61E49FL,
+    0x5EDEF90EL, 0x29D9C998L, 0xB0D09822L, 0xC7D7A8B4L,
+    0x59B33D17L, 0x2EB40D81L, 0xB7BD5C3BL, 0xC0BA6CADL,
+    0xEDB88320L, 0x9ABFB3B6L, 0x03B6E20CL, 0x74B1D29AL,
+    0xEAD54739L, 0x9DD277AFL, 0x04DB2615L, 0x73DC1683L,
+    0xE3630B12L, 0x94643B84L, 0x0D6D6A3EL, 0x7A6A5AA8L,
+    0xE40ECF0BL, 0x9309FF9DL, 0x0A00AE27L, 0x7D079EB1L,
+    0xF00F9344L, 0x8708A3D2L, 0x1E01F268L, 0x6906C2FEL,
+    0xF762575DL, 0x806567CBL, 0x196C3671L, 0x6E6B06E7L,
+    0xFED41B76L, 0x89D32BE0L, 0x10DA7A5AL, 0x67DD4ACCL,
+    0xF9B9DF6FL, 0x8EBEEFF9L, 0x17B7BE43L, 0x60B08ED5L,
+    0xD6D6A3E8L, 0xA1D1937EL, 0x38D8C2C4L, 0x4FDFF252L,
+    0xD1BB67F1L, 0xA6BC5767L, 0x3FB506DDL, 0x48B2364BL,
+    0xD80D2BDAL, 0xAF0A1B4CL, 0x36034AF6L, 0x41047A60L,
+    0xDF60EFC3L, 0xA867DF55L, 0x316E8EEFL, 0x4669BE79L,
+    0xCB61B38CL, 0xBC66831AL, 0x256FD2A0L, 0x5268E236L,
+    0xCC0C7795L, 0xBB0B4703L, 0x220216B9L, 0x5505262FL,
+    0xC5BA3BBEL, 0xB2BD0B28L, 0x2BB45A92L, 0x5CB36A04L,
+    0xC2D7FFA7L, 0xB5D0CF31L, 0x2CD99E8BL, 0x5BDEAE1DL,
+    0x9B64C2B0L, 0xEC63F226L, 0x756AA39CL, 0x026D930AL,
+    0x9C0906A9L, 0xEB0E363FL, 0x72076785L, 0x05005713L,
+    0x95BF4A82L, 0xE2B87A14L, 0x7BB12BAEL, 0x0CB61B38L,
+    0x92D28E9BL, 0xE5D5BE0DL, 0x7CDCEFB7L, 0x0BDBDF21L,
+    0x86D3D2D4L, 0xF1D4E242L, 0x68DDB3F8L, 0x1FDA836EL,
+    0x81BE16CDL, 0xF6B9265BL, 0x6FB077E1L, 0x18B74777L,
+    0x88085AE6L, 0xFF0F6A70L, 0x66063BCAL, 0x11010B5CL,
+    0x8F659EFFL, 0xF862AE69L, 0x616BFFD3L, 0x166CCF45L,
+    0xA00AE278L, 0xD70DD2EEL, 0x4E048354L, 0x3903B3C2L,
+    0xA7672661L, 0xD06016F7L, 0x4969474DL, 0x3E6E77DBL,
+    0xAED16A4AL, 0xD9D65ADCL, 0x40DF0B66L, 0x37D83BF0L,
+    0xA9BCAE53L, 0xDEBB9EC5L, 0x47B2CF7FL, 0x30B5FFE9L,
+    0xBDBDF21CL, 0xCABAC28AL, 0x53B39330L, 0x24B4A3A6L,
+    0xBAD03605L, 0xCDD70693L, 0x54DE5729L, 0x23D967BFL,
+    0xB3667A2EL, 0xC4614AB8L, 0x5D681B02L, 0x2A6F2B94L,
+    0xB40BBE37L, 0xC30C8EA1L, 0x5A05DF1BL, 0x2D02EF8DL
+};
+
+/*---------------------  Static Functions  --------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+
+
+
+/*+
+ *
+ * Description:
+ *    Generate a CRC-32 from the data stream
+ *
+ * Parameters:
+ *  In:
+ *      pbyData     - the data stream
+ *      cbByte      - the length of the stream
+ *      dwCrcSeed   - Seed for CRC32
+ *  Out:
+ *      none
+ *
+ * Return Value: CRC-32
+ *
+-*/
+DWORD CRCdwCrc32 (PBYTE pbyData, UINT cbByte, DWORD dwCrcSeed)
+{
+    DWORD dwCrc;
+
+    dwCrc = dwCrcSeed;
+    while (cbByte--) {
+        dwCrc = s_adwCrc32Table[(BYTE)((dwCrc ^ (*pbyData)) & 0xFF)] ^ (dwCrc >> 8);
+        pbyData++;
+    }
+
+    return dwCrc;
+}
+
+
+/*+
+ *
+ * Description:
+ * To test CRC generator, input 8 bytes packet
+ *      -- 0xff 0xff 0xff 0xff 0x00 0x00 0x00 0x00
+ * the generated CRC should be
+ *      -- 0xff 0xff 0xff 0xff
+ *
+ * Parameters:
+ *  In:
+ *      pbyData     - the data stream
+ *      cbByte      - the length of the stream
+ *  Out:
+ *      none
+ *
+ * Return Value: CRC-32
+ *
+-*/
+DWORD CRCdwGetCrc32 (PBYTE pbyData, UINT cbByte)
+{
+    return ~CRCdwCrc32(pbyData, cbByte, 0xFFFFFFFFL);
+}
+
+
+/*+
+ *
+ * Description:
+ *
+ * NOTE.... Because CRCdwGetCrc32Ex() is an iteration function,
+ *          this means we will use the output of CRCdwGetCrc32Ex()
+ *          to be a new argument to do next CRCdwGetCrc32Ex() calculation.
+ *          Thus, the final result must be inverted to be the
+ *          correct answer.
+ *
+ * Parameters:
+ *  In:
+ *      pbyData     - the data stream
+ *      cbByte      - the length of the stream
+ *  Out:
+ *      none
+ *
+ * Return Value: CRC-32
+ *
+-*/
+DWORD CRCdwGetCrc32Ex(PBYTE pbyData, UINT cbByte, DWORD dwPreCRC)
+{
+    return CRCdwCrc32(pbyData, cbByte, dwPreCRC);
+}
+
+
diff --git a/drivers/staging/vt6655/tcrc.h b/drivers/staging/vt6655/tcrc.h
new file mode 100644 (file)
index 0000000..ebea22e
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 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: tcrc.h
+ *
+ * Purpose: Implement functions to caculate CRC
+ *
+ * Author: Tevin Chen
+ *
+ * Date: Jan. 28, 1997
+ *
+ */
+
+
+#ifndef __TCRC_H__
+#define __TCRC_H__
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+
+
+
+
+/*---------------------  Export Definitions -------------------------*/
+
+/*---------------------  Export Types  ------------------------------*/
+
+/*---------------------  Export Macros ------------------------------*/
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+#ifdef __cplusplus
+extern "C" {                            /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+
+DWORD CRCdwCrc32(PBYTE pbyData, UINT cbByte, DWORD dwCrcSeed);
+DWORD CRCdwGetCrc32(PBYTE pbyData, UINT cbByte);
+DWORD CRCdwGetCrc32Ex(PBYTE pbyData, UINT cbByte, DWORD dwPreCRC);
+
+
+#ifdef __cplusplus
+}                                       /* End of extern "C" { */
+#endif /* __cplusplus */
+
+
+
+
+#endif // __TCRC_H__
+
+
+
diff --git a/drivers/staging/vt6655/test b/drivers/staging/vt6655/test
new file mode 100644 (file)
index 0000000..039f7d7
--- /dev/null
@@ -0,0 +1,9 @@
+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   /home/plice
+test_dir = $(shell [ -e $(dir)/include/linux ] && echo $(dir))
+KSP := $(foreach dir, $(KSP), $(test_dir))
\ No newline at end of file
diff --git a/drivers/staging/vt6655/tether.c b/drivers/staging/vt6655/tether.c
new file mode 100644 (file)
index 0000000..fd69423
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 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: tether.c
+ *
+ * Purpose:
+ *
+ * Author: Tevin Chen
+ *
+ * Date: May 21, 1996
+ *
+ * Functions:
+ *      ETHbyGetHashIndexByCrc32 - Caculate multicast hash value by CRC32
+ *      ETHbIsBufferCrc32Ok - Check CRC value of the buffer if Ok or not
+ *
+ * Revision History:
+ *
+ */
+
+#if !defined(__DEVICE_H__)
+#include "device.h"
+#endif
+#if !defined(__TMACRO_H__)
+#include "tmacro.h"
+#endif
+#if !defined(__TBIT_H__)
+#include "tbit.h"
+#endif
+#if !defined(__TCRC_H__)
+#include "tcrc.h"
+#endif
+#if !defined(__TETHER_H__)
+#include "tether.h"
+#endif
+
+
+
+
+/*---------------------  Static Definitions -------------------------*/
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+
+/*---------------------  Static Functions  --------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+
+
+/*
+ * Description: Caculate multicast hash value by CRC32
+ *
+ * Parameters:
+ *  In:
+ *             pbyMultiAddr    - Multicast Address
+ *  Out:
+ *      none
+ *
+ * Return Value: Hash value
+ *
+ */
+BYTE ETHbyGetHashIndexByCrc32 (PBYTE pbyMultiAddr)
+{
+    int     ii;
+    BYTE    byTmpHash;
+    BYTE    byHash = 0;
+
+    // get the least 6-bits from CRC generator
+    byTmpHash = (BYTE)(CRCdwCrc32(pbyMultiAddr, U_ETHER_ADDR_LEN,
+            0xFFFFFFFFL) & 0x3F);
+    // reverse most bit to least bit
+    for (ii = 0; ii < (sizeof(byTmpHash) * 8); ii++) {
+        byHash <<= 1;
+        if (BITbIsBitOn(byTmpHash, 0x01))
+            byHash |= 1;
+        byTmpHash >>= 1;
+    }
+
+    // adjust 6-bits to the right most
+    return (byHash >> 2);
+}
+
+
+/*
+ * Description: Check CRC value of the buffer if Ok or not
+ *
+ * Parameters:
+ *  In:
+ *             pbyBuffer           - pointer of buffer (normally is rx buffer)
+ *             cbFrameLength   - length of buffer, including CRC portion
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if ok; FALSE if error.
+ *
+ */
+BOOL ETHbIsBufferCrc32Ok (PBYTE pbyBuffer, UINT cbFrameLength)
+{
+    DWORD dwCRC;
+
+    dwCRC = CRCdwGetCrc32(pbyBuffer, cbFrameLength - 4);
+    if (cpu_to_le32(*((PDWORD)(pbyBuffer + cbFrameLength - 4))) != dwCRC) {
+        return FALSE;
+    }
+    return TRUE;
+}
+
diff --git a/drivers/staging/vt6655/tether.h b/drivers/staging/vt6655/tether.h
new file mode 100644 (file)
index 0000000..920a8bb
--- /dev/null
@@ -0,0 +1,256 @@
+/*
+ * 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: tether.h
+ *
+ * Purpose:
+ *
+ * Author: Tevin Chen
+ *
+ * Date: Jan. 28, 1997
+ *
+ */
+
+
+
+#ifndef __TETHER_H__
+#define __TETHER_H__
+
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+
+
+
+
+/*---------------------  Export Definitions -------------------------*/
+//
+// constants
+//
+#define U_ETHER_ADDR_LEN    6           // Ethernet address length
+#define U_TYPE_LEN          2           //
+#define U_CRC_LEN           4           //
+#define U_HEADER_LEN        (U_ETHER_ADDR_LEN * 2 + U_TYPE_LEN)
+#define U_ETHER_ADDR_STR_LEN (U_ETHER_ADDR_LEN * 2 + 1)
+                                        // Ethernet address string length
+
+#define MIN_DATA_LEN        46          // min data length
+#define MAX_DATA_LEN        1500        // max data length
+
+#define MIN_PACKET_LEN      (MIN_DATA_LEN + U_HEADER_LEN)
+                                        // 60
+                                        // min total packet length (tx)
+#define MAX_PACKET_LEN      (MAX_DATA_LEN + U_HEADER_LEN)
+                                        // 1514
+                                        // max total packet length (tx)
+
+#define MAX_LOOKAHEAD_SIZE  MAX_PACKET_LEN
+
+#define U_MULTI_ADDR_LEN    8           // multicast address length
+
+
+#ifdef __BIG_ENDIAN
+
+#define TYPE_PKT_IP         0x0800      //
+#define TYPE_PKT_ARP        0x0806      //
+#define TYPE_PKT_RARP       0x8035      //
+#define TYPE_PKT_IPX       0x8137          //
+#define TYPE_PKT_802_1x     0x888e
+#define TYPE_PKT_PreAuth    0x88C7
+
+#define TYPE_PKT_PING_M_REQ 0x8011      // master reguest
+#define TYPE_PKT_PING_S_GNT 0x8022      // slave grant
+#define TYPE_PKT_PING_M     0x8077      // pingpong master packet
+#define TYPE_PKT_PING_S     0x8088      // pingpong slave packet
+#define TYPE_PKT_WOL_M_REQ  0x8033      // WOL waker request
+#define TYPE_PKT_WOL_S_GNT  0x8044      // WOL sleeper grant
+#define TYPE_MGMT_PROBE_RSP 0x5000
+#define TYPE_PKT_VNT_DIAG   0x8011      // Diag Pkt
+#define TYPE_PKT_VNT_PER    0x8888      // Diag PER Pkt
+//
+// wFrameCtl field in the S802_11Header
+//
+// NOTE....
+//   in network byte order, high byte is going first
+#define FC_TODS             0x0001
+#define FC_FROMDS           0x0002
+#define FC_MOREFRAG         0x0004
+#define FC_RETRY            0x0008
+#define FC_POWERMGT         0x0010
+#define FC_MOREDATA         0x0020
+#define FC_WEP              0x0040
+#define TYPE_802_11_ATIM    0x9000
+
+#define TYPE_802_11_DATA    0x0800
+#define TYPE_802_11_CTL     0x0400
+#define TYPE_802_11_MGMT    0x0000
+#define TYPE_802_11_MASK    0x0C00
+#define TYPE_SUBTYPE_MASK   0xFC00
+#define TYPE_802_11_NODATA  0x4000
+#define TYPE_DATE_NULL      0x4800
+
+#define TYPE_CTL_PSPOLL     0xa400
+#define TYPE_CTL_RTS        0xb400
+#define TYPE_CTL_CTS        0xc400
+#define TYPE_CTL_ACK        0xd400
+
+
+//#define WEP_IV_MASK         0xFFFFFF00
+
+#else //if LITTLE_ENDIAN
+//
+// wType field in the SEthernetHeader
+//
+// NOTE....
+//   in network byte order, high byte is going first
+#define TYPE_PKT_IP         0x0008      //
+#define TYPE_PKT_ARP        0x0608      //
+#define TYPE_PKT_RARP       0x3580      //
+#define TYPE_PKT_IPX       0x3781          //
+
+#define TYPE_PKT_802_1x     0x8e88
+#define TYPE_PKT_PreAuth    0xC788
+
+#define TYPE_PKT_PING_M_REQ 0x1180      // master reguest
+#define TYPE_PKT_PING_S_GNT 0x2280      // slave grant
+#define TYPE_PKT_PING_M     0x7780      // pingpong master packet
+#define TYPE_PKT_PING_S     0x8880      // pingpong slave packet
+#define TYPE_PKT_WOL_M_REQ  0x3380      // WOL waker request
+#define TYPE_PKT_WOL_S_GNT  0x4480      // WOL sleeper grant
+#define TYPE_MGMT_PROBE_RSP 0x0050
+#define TYPE_PKT_VNT_DIAG   0x1180      // Diag Pkt
+#define TYPE_PKT_VNT_PER    0x8888      // Diag PER Pkt
+//
+// wFrameCtl field in the S802_11Header
+//
+// NOTE....
+//   in network byte order, high byte is going first
+#define FC_TODS             0x0100
+#define FC_FROMDS           0x0200
+#define FC_MOREFRAG         0x0400
+#define FC_RETRY            0x0800
+#define FC_POWERMGT         0x1000
+#define FC_MOREDATA         0x2000
+#define FC_WEP              0x4000
+#define TYPE_802_11_ATIM    0x0090
+
+#define TYPE_802_11_DATA    0x0008
+#define TYPE_802_11_CTL     0x0004
+#define TYPE_802_11_MGMT    0x0000
+#define TYPE_802_11_MASK    0x000C
+#define TYPE_SUBTYPE_MASK   0x00FC
+#define TYPE_802_11_NODATA  0x0040
+#define TYPE_DATE_NULL      0x0048
+
+#define TYPE_CTL_PSPOLL     0x00a4
+#define TYPE_CTL_RTS        0x00b4
+#define TYPE_CTL_CTS        0x00c4
+#define TYPE_CTL_ACK        0x00d4
+
+
+//#define WEP_IV_MASK         0x00FFFFFF
+
+#endif //#ifdef __BIG_ENDIAN
+
+#define WEP_IV_MASK         0x00FFFFFF
+
+/*---------------------  Export Types  ------------------------------*/
+//
+// Ethernet packet
+//
+typedef struct tagSEthernetHeader {
+    BYTE    abyDstAddr[U_ETHER_ADDR_LEN];
+    BYTE    abySrcAddr[U_ETHER_ADDR_LEN];
+    WORD    wType;
+}__attribute__ ((__packed__))
+SEthernetHeader, DEF* PSEthernetHeader;
+
+
+//
+// 802_3 packet
+//
+typedef struct tagS802_3Header {
+    BYTE    abyDstAddr[U_ETHER_ADDR_LEN];
+    BYTE    abySrcAddr[U_ETHER_ADDR_LEN];
+    WORD    wLen;
+}__attribute__ ((__packed__))
+S802_3Header, DEF* PS802_3Header;
+
+//
+// 802_11 packet
+//
+typedef struct tagS802_11Header {
+    WORD    wFrameCtl;
+    WORD    wDurationID;
+    BYTE    abyAddr1[U_ETHER_ADDR_LEN];
+    BYTE    abyAddr2[U_ETHER_ADDR_LEN];
+    BYTE    abyAddr3[U_ETHER_ADDR_LEN];
+    WORD    wSeqCtl;
+    BYTE    abyAddr4[U_ETHER_ADDR_LEN];
+}__attribute__ ((__packed__))
+S802_11Header, DEF* PS802_11Header;
+
+/*---------------------  Export Macros ------------------------------*/
+// Frame type macro
+
+#define IS_MULTICAST_ADDRESS(pbyEtherAddr)          \
+    ((*(PBYTE)(pbyEtherAddr) & 0x01) == 1)
+
+#define IS_BROADCAST_ADDRESS(pbyEtherAddr) (        \
+    (*(PDWORD)(pbyEtherAddr) == 0xFFFFFFFFL) &&     \
+    (*(PWORD)((PBYTE)(pbyEtherAddr) + 4) == 0xFFFF) \
+)
+
+#define IS_NULL_ADDRESS(pbyEtherAddr) (             \
+    (*(PDWORD)(pbyEtherAddr) == 0L) &&              \
+    (*(PWORD)((PBYTE)(pbyEtherAddr) + 4) == 0)      \
+)
+
+#define IS_ETH_ADDRESS_EQUAL(pbyAddr1, pbyAddr2) (  \
+    (*(PDWORD)(pbyAddr1) == *(PDWORD)(pbyAddr2)) && \
+    (*(PWORD)((PBYTE)(pbyAddr1) + 4) ==             \
+    *(PWORD)((PBYTE)(pbyAddr2) + 4))                \
+)
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+#ifdef __cplusplus
+extern "C" {                            /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+
+BYTE ETHbyGetHashIndexByCrc32(PBYTE pbyMultiAddr);
+//BYTE ETHbyGetHashIndexByCrc(PBYTE pbyMultiAddr);
+BOOL ETHbIsBufferCrc32Ok(PBYTE pbyBuffer, UINT cbFrameLength);
+
+
+#ifdef __cplusplus
+}                                       /* End of extern "C" { */
+#endif /* __cplusplus */
+
+
+
+
+#endif // __TETHER_H__
+
+
+
diff --git a/drivers/staging/vt6655/tkip.c b/drivers/staging/vt6655/tkip.c
new file mode 100644 (file)
index 0000000..2ded842
--- /dev/null
@@ -0,0 +1,284 @@
+/*
+ * 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: tkip.c
+ *
+ * Purpose: Implement functions for 802.11i TKIP
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Mar. 11, 2003
+ *
+ * Functions:
+ *      TKIPvMixKey - Get TKIP RC4 Key from TK,TA, and TSC
+ *
+ * Revision History:
+ *
+ */
+
+
+#if !defined(__TMACRO_H__)
+#include "tmacro.h"
+#endif
+#if !defined(__TBIT_H__)
+#include "tbit.h"
+#endif
+#if !defined(__TKIP_H__)
+#include "tkip.h"
+#endif
+#if !defined(__UMEM_H__)
+#include "umem.h"
+#endif
+
+
+/*---------------------  Static Definitions -------------------------*/
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+
+/*---------------------  Static Functions  --------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Static Definitions -------------------------*/
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+
+/* The Sbox is reduced to 2 16-bit wide tables, each with 256 entries. */
+/* The 2nd table is the same as the 1st but with the upper and lower   */
+/* bytes swapped. To allow an endian tolerant implementation, the byte */
+/* halves have been expressed independently here.                      */
+const BYTE TKIP_Sbox_Lower[256] = {
+    0xA5,0x84,0x99,0x8D,0x0D,0xBD,0xB1,0x54,
+    0x50,0x03,0xA9,0x7D,0x19,0x62,0xE6,0x9A,
+    0x45,0x9D,0x40,0x87,0x15,0xEB,0xC9,0x0B,
+    0xEC,0x67,0xFD,0xEA,0xBF,0xF7,0x96,0x5B,
+    0xC2,0x1C,0xAE,0x6A,0x5A,0x41,0x02,0x4F,
+    0x5C,0xF4,0x34,0x08,0x93,0x73,0x53,0x3F,
+    0x0C,0x52,0x65,0x5E,0x28,0xA1,0x0F,0xB5,
+    0x09,0x36,0x9B,0x3D,0x26,0x69,0xCD,0x9F,
+    0x1B,0x9E,0x74,0x2E,0x2D,0xB2,0xEE,0xFB,
+    0xF6,0x4D,0x61,0xCE,0x7B,0x3E,0x71,0x97,
+    0xF5,0x68,0x00,0x2C,0x60,0x1F,0xC8,0xED,
+    0xBE,0x46,0xD9,0x4B,0xDE,0xD4,0xE8,0x4A,
+    0x6B,0x2A,0xE5,0x16,0xC5,0xD7,0x55,0x94,
+    0xCF,0x10,0x06,0x81,0xF0,0x44,0xBA,0xE3,
+    0xF3,0xFE,0xC0,0x8A,0xAD,0xBC,0x48,0x04,
+    0xDF,0xC1,0x75,0x63,0x30,0x1A,0x0E,0x6D,
+    0x4C,0x14,0x35,0x2F,0xE1,0xA2,0xCC,0x39,
+    0x57,0xF2,0x82,0x47,0xAC,0xE7,0x2B,0x95,
+    0xA0,0x98,0xD1,0x7F,0x66,0x7E,0xAB,0x83,
+    0xCA,0x29,0xD3,0x3C,0x79,0xE2,0x1D,0x76,
+    0x3B,0x56,0x4E,0x1E,0xDB,0x0A,0x6C,0xE4,
+    0x5D,0x6E,0xEF,0xA6,0xA8,0xA4,0x37,0x8B,
+    0x32,0x43,0x59,0xB7,0x8C,0x64,0xD2,0xE0,
+    0xB4,0xFA,0x07,0x25,0xAF,0x8E,0xE9,0x18,
+    0xD5,0x88,0x6F,0x72,0x24,0xF1,0xC7,0x51,
+    0x23,0x7C,0x9C,0x21,0xDD,0xDC,0x86,0x85,
+    0x90,0x42,0xC4,0xAA,0xD8,0x05,0x01,0x12,
+    0xA3,0x5F,0xF9,0xD0,0x91,0x58,0x27,0xB9,
+    0x38,0x13,0xB3,0x33,0xBB,0x70,0x89,0xA7,
+    0xB6,0x22,0x92,0x20,0x49,0xFF,0x78,0x7A,
+    0x8F,0xF8,0x80,0x17,0xDA,0x31,0xC6,0xB8,
+    0xC3,0xB0,0x77,0x11,0xCB,0xFC,0xD6,0x3A
+};
+
+const BYTE TKIP_Sbox_Upper[256] = {
+    0xC6,0xF8,0xEE,0xF6,0xFF,0xD6,0xDE,0x91,
+    0x60,0x02,0xCE,0x56,0xE7,0xB5,0x4D,0xEC,
+    0x8F,0x1F,0x89,0xFA,0xEF,0xB2,0x8E,0xFB,
+    0x41,0xB3,0x5F,0x45,0x23,0x53,0xE4,0x9B,
+    0x75,0xE1,0x3D,0x4C,0x6C,0x7E,0xF5,0x83,
+    0x68,0x51,0xD1,0xF9,0xE2,0xAB,0x62,0x2A,
+    0x08,0x95,0x46,0x9D,0x30,0x37,0x0A,0x2F,
+    0x0E,0x24,0x1B,0xDF,0xCD,0x4E,0x7F,0xEA,
+    0x12,0x1D,0x58,0x34,0x36,0xDC,0xB4,0x5B,
+    0xA4,0x76,0xB7,0x7D,0x52,0xDD,0x5E,0x13,
+    0xA6,0xB9,0x00,0xC1,0x40,0xE3,0x79,0xB6,
+    0xD4,0x8D,0x67,0x72,0x94,0x98,0xB0,0x85,
+    0xBB,0xC5,0x4F,0xED,0x86,0x9A,0x66,0x11,
+    0x8A,0xE9,0x04,0xFE,0xA0,0x78,0x25,0x4B,
+    0xA2,0x5D,0x80,0x05,0x3F,0x21,0x70,0xF1,
+    0x63,0x77,0xAF,0x42,0x20,0xE5,0xFD,0xBF,
+    0x81,0x18,0x26,0xC3,0xBE,0x35,0x88,0x2E,
+    0x93,0x55,0xFC,0x7A,0xC8,0xBA,0x32,0xE6,
+    0xC0,0x19,0x9E,0xA3,0x44,0x54,0x3B,0x0B,
+    0x8C,0xC7,0x6B,0x28,0xA7,0xBC,0x16,0xAD,
+    0xDB,0x64,0x74,0x14,0x92,0x0C,0x48,0xB8,
+    0x9F,0xBD,0x43,0xC4,0x39,0x31,0xD3,0xF2,
+    0xD5,0x8B,0x6E,0xDA,0x01,0xB1,0x9C,0x49,
+    0xD8,0xAC,0xF3,0xCF,0xCA,0xF4,0x47,0x10,
+    0x6F,0xF0,0x4A,0x5C,0x38,0x57,0x73,0x97,
+    0xCB,0xA1,0xE8,0x3E,0x96,0x61,0x0D,0x0F,
+    0xE0,0x7C,0x71,0xCC,0x90,0x06,0xF7,0x1C,
+    0xC2,0x6A,0xAE,0x69,0x17,0x99,0x3A,0x27,
+    0xD9,0xEB,0x2B,0x22,0xD2,0xA9,0x07,0x33,
+    0x2D,0x3C,0x15,0xC9,0x87,0xAA,0x50,0xA5,
+    0x03,0x59,0x09,0x1A,0x65,0xD7,0x84,0xD0,
+    0x82,0x29,0x5A,0x1E,0x7B,0xA8,0x6D,0x2C
+};
+
+
+//STKIPKeyManagement  sTKIPKeyTable[MAX_TKIP_KEY];
+
+/*---------------------  Static Functions  --------------------------*/
+unsigned int tkip_sbox(unsigned int index);
+unsigned int rotr1(unsigned int a);
+
+/*---------------------  Export Variables  --------------------------*/
+
+/************************************************************/
+/* tkip_sbox()                                              */
+/* Returns a 16 bit value from a 64K entry table. The Table */
+/* is synthesized from two 256 entry byte wide tables.      */
+/************************************************************/
+unsigned int tkip_sbox(unsigned int index)
+{
+    unsigned int index_low;
+    unsigned int index_high;
+    unsigned int left, right;
+
+    index_low = (index % 256);
+    index_high = ((index >> 8) % 256);
+
+    left = TKIP_Sbox_Lower[index_low] + (TKIP_Sbox_Upper[index_low] * 256);
+    right = TKIP_Sbox_Upper[index_high] + (TKIP_Sbox_Lower[index_high] * 256);
+
+    return (left ^ right);
+};
+
+
+unsigned int rotr1(unsigned int a)
+{
+    unsigned int b;
+
+    if ((a & 0x01) == 0x01) {
+        b = (a >> 1) | 0x8000;
+    } else {
+        b = (a >> 1) & 0x7fff;
+    }
+    b = b % 65536;
+    return b;
+}
+
+
+/*
+ * Description: Caculate RC4Key fom TK, TA, and TSC
+ *
+ * Parameters:
+ *  In:
+ *      pbyTKey         - TKey
+ *      pbyTA           - TA
+ *      dwTSC           - TSC
+ *  Out:
+ *      pbyRC4Key       - RC4Key
+ *
+ * Return Value: none
+ *
+ */
+VOID TKIPvMixKey(
+    PBYTE   pbyTKey,
+    PBYTE   pbyTA,
+    WORD    wTSC15_0,
+    DWORD   dwTSC47_16,
+    PBYTE   pbyRC4Key
+    )
+{
+    unsigned int p1k[5];
+//    unsigned int ttak0, ttak1, ttak2, ttak3, ttak4;
+    unsigned int tsc0, tsc1, tsc2;
+    unsigned int ppk0, ppk1, ppk2, ppk3, ppk4, ppk5;
+    unsigned long int pnl,pnh;
+
+    int i, j;
+
+    pnl = wTSC15_0;
+    pnh = dwTSC47_16;
+
+    tsc0 = (unsigned int)((pnh >> 16) % 65536); /* msb */
+    tsc1 = (unsigned int)(pnh % 65536);
+    tsc2 = (unsigned int)(pnl % 65536); /* lsb */
+
+    /* Phase 1, step 1 */
+    p1k[0] = tsc1;
+    p1k[1] = tsc0;
+    p1k[2] = (unsigned int)(pbyTA[0] + (pbyTA[1]*256));
+    p1k[3] = (unsigned int)(pbyTA[2] + (pbyTA[3]*256));
+    p1k[4] = (unsigned int)(pbyTA[4] + (pbyTA[5]*256));
+
+    /* Phase 1, step 2 */
+    for (i=0; i<8; i++) {
+        j = 2*(i & 1);
+        p1k[0] = (p1k[0] + tkip_sbox( (p1k[4] ^ ((256*pbyTKey[1+j]) + pbyTKey[j])) % 65536 )) % 65536;
+        p1k[1] = (p1k[1] + tkip_sbox( (p1k[0] ^ ((256*pbyTKey[5+j]) + pbyTKey[4+j])) % 65536 )) % 65536;
+        p1k[2] = (p1k[2] + tkip_sbox( (p1k[1] ^ ((256*pbyTKey[9+j]) + pbyTKey[8+j])) % 65536 )) % 65536;
+        p1k[3] = (p1k[3] + tkip_sbox( (p1k[2] ^ ((256*pbyTKey[13+j]) + pbyTKey[12+j])) % 65536 )) % 65536;
+        p1k[4] = (p1k[4] + tkip_sbox( (p1k[3] ^ (((256*pbyTKey[1+j]) + pbyTKey[j]))) % 65536 )) % 65536;
+        p1k[4] = (p1k[4] + i) % 65536;
+    }
+    /* Phase 2, Step 1 */
+    ppk0 = p1k[0];
+    ppk1 = p1k[1];
+    ppk2 = p1k[2];
+    ppk3 = p1k[3];
+    ppk4 = p1k[4];
+    ppk5 = (p1k[4] + tsc2) % 65536;
+
+    /* Phase2, Step 2 */
+    ppk0 = ppk0 + tkip_sbox( (ppk5 ^ ((256*pbyTKey[1]) + pbyTKey[0])) % 65536);
+    ppk1 = ppk1 + tkip_sbox( (ppk0 ^ ((256*pbyTKey[3]) + pbyTKey[2])) % 65536);
+    ppk2 = ppk2 + tkip_sbox( (ppk1 ^ ((256*pbyTKey[5]) + pbyTKey[4])) % 65536);
+    ppk3 = ppk3 + tkip_sbox( (ppk2 ^ ((256*pbyTKey[7]) + pbyTKey[6])) % 65536);
+    ppk4 = ppk4 + tkip_sbox( (ppk3 ^ ((256*pbyTKey[9]) + pbyTKey[8])) % 65536);
+    ppk5 = ppk5 + tkip_sbox( (ppk4 ^ ((256*pbyTKey[11]) + pbyTKey[10])) % 65536);
+
+    ppk0 = ppk0 + rotr1(ppk5 ^ ((256*pbyTKey[13]) + pbyTKey[12]));
+    ppk1 = ppk1 + rotr1(ppk0 ^ ((256*pbyTKey[15]) + pbyTKey[14]));
+    ppk2 = ppk2 + rotr1(ppk1);
+    ppk3 = ppk3 + rotr1(ppk2);
+    ppk4 = ppk4 + rotr1(ppk3);
+    ppk5 = ppk5 + rotr1(ppk4);
+
+    /* Phase 2, Step 3 */
+    pbyRC4Key[0] = (tsc2 >> 8) % 256;
+    pbyRC4Key[1] = (((tsc2 >> 8) % 256) | 0x20) & 0x7f;
+    pbyRC4Key[2] = tsc2 % 256;
+    pbyRC4Key[3] = ((ppk5 ^ ((256*pbyTKey[1]) + pbyTKey[0])) >> 1) % 256;
+
+    pbyRC4Key[4] = ppk0 % 256;
+    pbyRC4Key[5] = (ppk0 >> 8) % 256;
+
+    pbyRC4Key[6] = ppk1 % 256;
+    pbyRC4Key[7] = (ppk1 >> 8) % 256;
+
+    pbyRC4Key[8] = ppk2 % 256;
+    pbyRC4Key[9] = (ppk2 >> 8) % 256;
+
+    pbyRC4Key[10] = ppk3 % 256;
+    pbyRC4Key[11] = (ppk3 >> 8) % 256;
+
+    pbyRC4Key[12] = ppk4 % 256;
+    pbyRC4Key[13] = (ppk4 >> 8) % 256;
+
+    pbyRC4Key[14] = ppk5 % 256;
+    pbyRC4Key[15] = (ppk5 >> 8) % 256;
+}
diff --git a/drivers/staging/vt6655/tkip.h b/drivers/staging/vt6655/tkip.h
new file mode 100644 (file)
index 0000000..dc8382b
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * 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: tkip.h
+ *
+ * Purpose: Implement functions for 802.11i TKIP
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Mar. 11, 2003
+ *
+ */
+
+
+#ifndef __TKIP_H__
+#define __TKIP_H__
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+
+#if !defined(__TETHER_H__)
+#include "tether.h"
+#endif
+
+
+
+/*---------------------  Export Definitions -------------------------*/
+#define TKIP_KEY_LEN        16
+
+/*---------------------  Export Types  ------------------------------*/
+
+/*---------------------  Export Macros ------------------------------*/
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+#ifdef __cplusplus
+extern "C" {                            /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+VOID TKIPvMixKey(
+    PBYTE   pbyTKey,
+    PBYTE   pbyTA,
+    WORD    wTSC15_0,
+    DWORD   dwTSC47_16,
+    PBYTE   pbyRC4Key
+    );
+
+#ifdef __cplusplus
+}                                       /* End of extern "C" { */
+#endif /* __cplusplus */
+
+
+#endif // __TKIP_H__
+
+
+
diff --git a/drivers/staging/vt6655/tmacro.h b/drivers/staging/vt6655/tmacro.h
new file mode 100644 (file)
index 0000000..3d932a2
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * 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: tmacro.h
+ *
+ * Purpose: define basic common types and macros
+ *
+ * Author: Tevin Chen
+ *
+ * Date: May 21, 1996
+ *
+ */
+
+
+#ifndef __TMACRO_H__
+#define __TMACRO_H__
+
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+
+
+
+
+/****** Common helper macros ***********************************************/
+
+#if !defined(LONIBBLE)
+#define LONIBBLE(b)         ((BYTE)(b) & 0x0F)
+#endif
+#if !defined(HINIBBLE)
+#define HINIBBLE(b)         ((BYTE)(((WORD)(b) >> 4) & 0x0F))
+#endif
+
+#if !defined(LOBYTE)
+#define LOBYTE(w)           ((BYTE)(w))
+#endif
+#if !defined(HIBYTE)
+#define HIBYTE(w)           ((BYTE)(((WORD)(w) >> 8) & 0xFF))
+#endif
+
+#if !defined(LOWORD)
+#define LOWORD(d)           ((WORD)(d))
+#endif
+#if !defined(HIWORD)
+#define HIWORD(d)           ((WORD)((((DWORD)(d)) >> 16) & 0xFFFF))
+#endif
+
+#define LODWORD(q)          ((q).u.dwLowDword)
+#define HIDWORD(q)          ((q).u.dwHighDword)
+
+
+
+#if !defined(MAKEBYTE)
+#define MAKEBYTE(ln, hn)    ((BYTE)(((BYTE)(ln) & 0x0F) | ((BYTE)(hn) << 4)))
+#endif
+#if !defined(MAKEWORD)
+#define MAKEWORD(lb, hb)    ((WORD)(((BYTE)(lb)) | (((WORD)((BYTE)(hb))) << 8)))
+#endif
+#if !defined(MAKEDWORD)
+#define MAKEDWORD(lw, hw)   ((DWORD)(((WORD)(lw)) | (((DWORD)((WORD)(hw))) << 16)))
+#endif
+#if !defined(MAKEQWORD)
+#define MAKEQWORD(ld, hd, pq) {pq->u.dwLowDword = ld; pq->u.dwHighDword = hd;}
+#endif
+
+#if !defined(MAKELONG)
+#define MAKELONG(low, high) ((LONG)(((WORD)(low)) | (((DWORD)((WORD)(high))) << 16)))
+#endif
+
+
+
+// Bytes Reverse: big endian to little endian convert
+#if !defined(REVWORD)
+#define REVWORD(w) ((WORD)( ((WORD)(w) >> 8) | ((WORD)(w) << 8) ))
+#endif
+#if !defined(REVDWORD)
+#define REVDWORD(d) (MAKEDWORD(MAKEWORD(HIBYTE(HIWORD(d)),LOBYTE(HIWORD(d))),MAKEWORD(HIBYTE(LOWORD(d)),LOBYTE(LOWORD(d)))))
+#endif
+
+/* map to known network names */
+/*
+#define ntohs(x)        REVWORD(x)
+#define ntohl(x)        REVDWORD(x)
+#define htons(x)        REVWORD(x)
+#define htonl(x)        REVDWORD(x)
+*/
+
+
+/*
+#ifndef NOMINMAX
+#ifndef max
+#define max(a,b)            (((a) > (b)) ? (a) : (b))
+#endif
+#ifndef min
+#define min(a,b)            (((a) < (b)) ? (a) : (b))
+#endif
+#endif // NOMINMAX
+*/
+
+
+
+/****** Misc macros ********************************************************/
+
+// get the field offset in the type(struct, class, ...)
+#define OFFSET(type, field) ((int)(&((type NEAR*)1)->field)-1)
+
+
+/* string equality shorthand */
+#define STR_EQ(x, y)        (strcmp(x, y) == 0)
+#define STR_NE(x, y)        (strcmp(x, y) != 0)
+
+
+// calculate element # of array
+#define ELEMENT_NUM(array)  (sizeof(array) / sizeof(array[0]))
+//#define ARRAY_SIZE(a)       (sizeof(a) / sizeof(a[0]))
+
+
+// null statement
+#define NULL_FUNC()
+
+
+/* Since not all compilers support structure assignment, the ASSIGN()
+ * macro is used. This controls how it's actually implemented.
+ */
+#ifdef NOSTRUCTASSIGN  /* Version for old compilers that don't support it */
+#define        ASSIGN(a,b)     memcpy((char *)&(a),(char *)&(b),sizeof(b);
+#else                  /* Version for compilers that do */
+#define        ASSIGN(a,b)     ((a) = (b))
+#endif
+
+
+
+
+#endif // __TMACRO_H__
+
+
diff --git a/drivers/staging/vt6655/tpci.h b/drivers/staging/vt6655/tpci.h
new file mode 100644 (file)
index 0000000..4a1c8ed
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * 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: tpci.h
+ *
+ * Purpose: PCI routines
+ *
+ * Author: Tevin Chen
+ *
+ * Date: May 21, 1996
+ *
+ */
+
+
+#ifndef __TPCI_H__
+#define __TPCI_H__
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+
+
+
+
+/*---------------------  Export Definitions -------------------------*/
+#define MAX_PCI_BUS             4       // max. # of PCI bus that we support
+#define MAX_PCI_DEVICE          32      // max. # of PCI devices
+
+
+//
+// Registers in the PCI configuration space
+//
+#define PCI_REG_VENDOR_ID       0x00    //
+#define PCI_REG_DEVICE_ID       0x02    //
+#define PCI_REG_COMMAND         0x04    //
+#define PCI_REG_STATUS          0x06    //
+#define PCI_REG_REV_ID          0x08    //
+#define PCI_REG_CLASS_CODE      0x09    //
+#define PCI_REG_CACHELINE_SIZE  0x0C    //
+#define PCI_REG_LAT_TIMER       0x0D    //
+#define PCI_REG_HDR_TYPE        0x0E    //
+#define PCI_REG_BIST            0x0F    //
+
+#define PCI_REG_BAR0            0x10    //
+#define PCI_REG_BAR1            0x14    //
+#define PCI_REG_BAR2            0x18    //
+#define PCI_REG_CARDBUS_CIS_PTR 0x28    //
+
+#define PCI_REG_SUB_VEN_ID      0x2C    //
+#define PCI_REG_SUB_SYS_ID      0x2E    //
+#define PCI_REG_EXP_ROM_BAR     0x30    //
+#define PCI_REG_CAP             0x34    //
+
+#define PCI_REG_INT_LINE        0x3C    //
+#define PCI_REG_INT_PIN         0x3D    //
+#define PCI_REG_MIN_GNT         0x3E    //
+#define PCI_REG_MAX_LAT         0x3F    //
+
+#define PCI_REG_MAX_SIZE        0x100   // maximun total PCI registers
+
+
+//
+// Bits in the COMMAND register
+//
+#define COMMAND_BUSM        0x04        //
+#define COMMAND_WAIT        0x80        //
+
+/*---------------------  Export Types  ------------------------------*/
+
+/*---------------------  Export Macros ------------------------------*/
+
+// macro MAKE Bus Dev Fun ID into WORD
+#define MAKE_BDF_TO_WORD(byBusId, byDevId, byFunId) \
+    MAKEWORD(                                       \
+        ((((BYTE)(byDevId)) & 0x1F) << 3) +         \
+            (((BYTE)(byFunId)) & 0x07),             \
+        (byBusId)                                   \
+        )
+
+#define GET_BUSID(wBusDevFunId) \
+    HIBYTE(wBusDevFunId)
+
+#define GET_DEVID(wBusDevFunId) \
+    (LOBYTE(wBusDevFunId) >> 3)
+
+#define GET_FUNID(wBusDevFunId) \
+    (LOBYTE(wBusDevFunId) & 0x07)
+
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+
+
+#endif // __TPCI_H__
+
+
diff --git a/drivers/staging/vt6655/umem.h b/drivers/staging/vt6655/umem.h
new file mode 100644 (file)
index 0000000..2c3eafa
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * 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: umem.h
+ *
+ * Purpose: Define Memory macros
+ *
+ * Author: Tevin Chen
+ *
+ * Date: Mar 17, 1997
+ *
+ */
+
+
+#ifndef __UMEM_H__
+#define __UMEM_H__
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+
+
+
+/*---------------------  Export Definitions -------------------------*/
+// 4-byte memory tag
+#define MEM_TAG 'mTEW'
+
+// Macros used for memory allocation and deallocation.
+
+
+
+#define ZERO_MEMORY(Destination,Length) {       \
+            memset((PVOID)(Destination),        \
+            0,                                  \
+            (ULONG)(Length)                     \
+            );                                  \
+}
+
+#define MEMvCopy(pvDest, pvSource, uCount) {    \
+            memcpy((PVOID)(pvDest),             \
+            (PVOID)(pvSource),                  \
+            (ULONG)(uCount)                     \
+            );                                  \
+}
+
+
+#define MEMEqualMemory(Destination,Source,Length)   (!memcmp((Destination),(Source),(Length)))
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+
+
+#endif // __UMEM_H__
+
+
diff --git a/drivers/staging/vt6655/upc.h b/drivers/staging/vt6655/upc.h
new file mode 100644 (file)
index 0000000..113fc2c
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * 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: upc.h
+ *
+ * Purpose: Macros to access device
+ *
+ * Author: Tevin Chen
+ *
+ * Date: Mar 17, 1997
+ *
+ */
+
+
+#ifndef __UPC_H__
+#define __UPC_H__
+
+#if !defined(DEVICE_H)
+#include "device.h"
+#endif
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+
+/*---------------------  Export Definitions -------------------------*/
+
+
+//
+//  For IO mapped
+//
+
+#ifdef IO_MAP
+
+#define VNSvInPortB(dwIOAddress, pbyData) {                     \
+       *(pbyData) = inb(dwIOAddress);                              \
+}
+
+
+#define VNSvInPortW(dwIOAddress, pwData) {                      \
+           *(pwData) = inw(dwIOAddress);                           \
+}
+
+#define VNSvInPortD(dwIOAddress, pdwData) {                     \
+           *(pdwData) = inl(dwIOAddress);                          \
+}
+
+
+#define VNSvOutPortB(dwIOAddress, byData) {                     \
+        outb(byData, dwIOAddress);                              \
+}
+
+
+#define VNSvOutPortW(dwIOAddress, wData) {                      \
+        outw(wData, dwIOAddress);                               \
+}
+
+#define VNSvOutPortD(dwIOAddress, dwData) {                     \
+        outl(dwData, dwIOAddress);                              \
+}
+
+#else
+
+//
+//  For memory mapped IO
+//
+
+
+#define VNSvInPortB(dwIOAddress, pbyData) {                     \
+       volatile BYTE* pbyAddr = ((PBYTE)(dwIOAddress));            \
+       *(pbyData) = readb(pbyAddr);                           \
+}
+
+
+#define VNSvInPortW(dwIOAddress, pwData) {                      \
+       volatile WORD* pwAddr = ((PWORD)(dwIOAddress));             \
+       *(pwData) = readw(pwAddr);                             \
+}
+
+#define VNSvInPortD(dwIOAddress, pdwData) {                     \
+       volatile DWORD* pdwAddr = ((PDWORD)(dwIOAddress));          \
+       *(pdwData) = readl(pdwAddr);                           \
+}
+
+
+#define VNSvOutPortB(dwIOAddress, byData) {                     \
+    volatile BYTE* pbyAddr = ((PBYTE)(dwIOAddress));            \
+    writeb((BYTE)byData, pbyAddr);                                                     \
+}
+
+
+#define VNSvOutPortW(dwIOAddress, wData) {                      \
+    volatile WORD* pwAddr = ((PWORD)(dwIOAddress));             \
+    writew((WORD)wData, pwAddr);                                                       \
+}
+
+#define VNSvOutPortD(dwIOAddress, dwData) {                     \
+    volatile DWORD* pdwAddr = ((PDWORD)(dwIOAddress));          \
+    writel((DWORD)dwData, pdwAddr);                                        \
+}
+
+#endif
+
+
+//
+// ALWAYS IO-Mapped IO when in 16-bit/32-bit environment
+//
+#define PCBvInPortB(dwIOAddress, pbyData) {     \
+           *(pbyData) = inb(dwIOAddress);          \
+}
+
+#define PCBvInPortW(dwIOAddress, pwData) {      \
+           *(pwData) = inw(dwIOAddress);           \
+}
+
+#define PCBvInPortD(dwIOAddress, pdwData) {     \
+           *(pdwData) = inl(dwIOAddress);          \
+}
+
+#define PCBvOutPortB(dwIOAddress, byData) {     \
+        outb(byData, dwIOAddress);              \
+}
+
+#define PCBvOutPortW(dwIOAddress, wData) {      \
+        outw(wData, dwIOAddress);               \
+}
+
+#define PCBvOutPortD(dwIOAddress, dwData) {     \
+        outl(dwData, dwIOAddress);              \
+}
+
+
+#define PCAvDelayByIO(uDelayUnit) {             \
+    BYTE    byData;                             \
+    ULONG   ii;                                 \
+                                                \
+    if (uDelayUnit <= 50) {                     \
+        udelay(uDelayUnit);                     \
+    }                                           \
+    else {                                      \
+        for (ii = 0; ii < (uDelayUnit); ii++)   \
+                    byData = inb(0x61);                                \
+    }                                           \
+}
+
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+
+
+#endif // __UPC_H__
+
diff --git a/drivers/staging/vt6655/vntconfiguration.dat b/drivers/staging/vt6655/vntconfiguration.dat
new file mode 100644 (file)
index 0000000..0064ddc
--- /dev/null
@@ -0,0 +1 @@
+ZONETYPE=EUROPE
\ No newline at end of file
diff --git a/drivers/staging/vt6655/vntwifi.c b/drivers/staging/vt6655/vntwifi.c
new file mode 100644 (file)
index 0000000..58a1ba0
--- /dev/null
@@ -0,0 +1,832 @@
+/*
+ * 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: vntwifi.c
+ *
+ * Purpose: export functions for vntwifi lib
+ *
+ * Functions:
+ *
+ * Revision History:
+ *
+ * Author: Yiching Chen
+ *
+ * Date: feb. 2, 2005
+ *
+ */
+
+#if !defined(__VNTWIFI_H__)
+#include "vntwifi.h"
+#endif
+#if !defined(__UMEM_H__)
+#include "umem.h"
+#endif
+
+
+#if !defined(__TBIT_H__)
+#include "tbit.h"
+#endif
+#if !defined(__IEEE11h_H__)
+#include "IEEE11h.h"
+#endif
+#if !defined(__COUNTRY_H__)
+#include "country.h"
+#endif
+#if !defined(__DEVICE_H__)
+#include "device.h"
+#endif
+#if !defined(__WMGR_H__)
+#include "wmgr.h"
+#endif
+#if !defined(__DATARATE_H__)
+#include "datarate.h"
+#endif
+//#define      PLICE_DEBUG
+
+/*---------------------  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 Operation Mode
+ *
+ * Parameters:
+ *  In:
+ *      pMgmtHandle - pointer to management object
+ *      eOPMode     - Opreation Mode
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+-*/
+VOID
+VNTWIFIvSetOPMode (
+    IN PVOID pMgmtHandle,
+    IN WMAC_CONFIG_MODE eOPMode
+    )
+{
+    PSMgmtObject        pMgmt = (PSMgmtObject)pMgmtHandle;
+
+    pMgmt->eConfigMode = eOPMode;
+}
+
+
+/*+
+ *
+ * Description:
+ *    Set Operation Mode
+ *
+ * Parameters:
+ *  In:
+ *      pMgmtHandle - pointer to management object
+ *      wBeaconPeriod - Beacon Period
+ *      wATIMWindow - ATIM window
+ *      uChannel - channel number
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+-*/
+VOID
+VNTWIFIvSetIBSSParameter (
+    IN PVOID pMgmtHandle,
+    IN WORD  wBeaconPeriod,
+    IN WORD  wATIMWindow,
+    IN UINT  uChannel
+    )
+{
+    PSMgmtObject        pMgmt = (PSMgmtObject)pMgmtHandle;
+
+    pMgmt->wIBSSBeaconPeriod = wBeaconPeriod;
+    pMgmt->wIBSSATIMWindow = wATIMWindow;
+    pMgmt->uIBSSChannel = uChannel;
+}
+
+/*+
+ *
+ * Description:
+ *    Get current SSID
+ *
+ * Parameters:
+ *  In:
+ *      pMgmtHandle - pointer to management object
+ *  Out:
+ *      none
+ *
+ * Return Value: current SSID pointer.
+ *
+-*/
+PWLAN_IE_SSID
+VNTWIFIpGetCurrentSSID (
+    IN PVOID pMgmtHandle
+    )
+{
+    PSMgmtObject        pMgmt = (PSMgmtObject)pMgmtHandle;
+    return((PWLAN_IE_SSID) pMgmt->abyCurrSSID);
+}
+
+/*+
+ *
+ * Description:
+ *    Get current link channel
+ *
+ * Parameters:
+ *  In:
+ *      pMgmtHandle - pointer to management object
+ *  Out:
+ *      none
+ *
+ * Return Value: current Channel.
+ *
+-*/
+UINT
+VNTWIFIpGetCurrentChannel (
+    IN PVOID pMgmtHandle
+    )
+{
+    PSMgmtObject        pMgmt = (PSMgmtObject)pMgmtHandle;
+    if (pMgmtHandle != NULL) {
+        return (pMgmt->uCurrChannel);
+    }
+    return 0;
+}
+
+/*+
+ *
+ * Description:
+ *    Get current Assoc ID
+ *
+ * Parameters:
+ *  In:
+ *      pMgmtHandle - pointer to management object
+ *  Out:
+ *      none
+ *
+ * Return Value: current Assoc ID
+ *
+-*/
+WORD
+VNTWIFIwGetAssocID (
+    IN PVOID pMgmtHandle
+    )
+{
+    PSMgmtObject        pMgmt = (PSMgmtObject)pMgmtHandle;
+    return(pMgmt->wCurrAID);
+}
+
+
+
+/*+
+ *
+ * Description:
+ *    This routine return max support rate of IES
+ *
+ * Parameters:
+ *  In:
+ *      pSupportRateIEs
+ *      pExtSupportRateIEs
+ *
+ *  Out:
+ *
+ * Return Value: max support rate
+ *
+-*/
+BYTE
+VNTWIFIbyGetMaxSupportRate (
+    IN PWLAN_IE_SUPP_RATES pSupportRateIEs,
+    IN PWLAN_IE_SUPP_RATES pExtSupportRateIEs
+    )
+{
+    BYTE    byMaxSupportRate = RATE_1M;
+    BYTE    bySupportRate = RATE_1M;
+    UINT    ii = 0;
+
+    if (pSupportRateIEs) {
+        for (ii = 0; ii < pSupportRateIEs->len; ii++) {
+            bySupportRate = DATARATEbyGetRateIdx(pSupportRateIEs->abyRates[ii]);
+            if (bySupportRate > byMaxSupportRate) {
+                byMaxSupportRate = bySupportRate;
+            }
+        }
+    }
+    if (pExtSupportRateIEs) {
+        for (ii = 0; ii < pExtSupportRateIEs->len; ii++) {
+            bySupportRate = DATARATEbyGetRateIdx(pExtSupportRateIEs->abyRates[ii]);
+            if (bySupportRate > byMaxSupportRate) {
+                byMaxSupportRate = bySupportRate;
+            }
+        }
+    }
+
+    return byMaxSupportRate;
+}
+
+/*+
+ *
+ * Description:
+ *    This routine return data rate of ACK packtet
+ *
+ * Parameters:
+ *  In:
+ *      byRxDataRate
+ *      pSupportRateIEs
+ *      pExtSupportRateIEs
+ *
+ *  Out:
+ *
+ * Return Value: max support rate
+ *
+-*/
+BYTE
+VNTWIFIbyGetACKTxRate (
+    IN BYTE byRxDataRate,
+    IN PWLAN_IE_SUPP_RATES pSupportRateIEs,
+    IN PWLAN_IE_SUPP_RATES pExtSupportRateIEs
+    )
+{
+    BYTE    byMaxAckRate;
+    BYTE    byBasicRate;
+    UINT    ii;
+
+    if (byRxDataRate <= RATE_11M) {
+        byMaxAckRate = RATE_1M;
+    } else  {
+        // 24M is mandatory for 802.11a and 802.11g
+        byMaxAckRate = RATE_24M;
+    }
+    if (pSupportRateIEs) {
+        for (ii = 0; ii < pSupportRateIEs->len; ii++) {
+            if (pSupportRateIEs->abyRates[ii] & 0x80) {
+                byBasicRate = DATARATEbyGetRateIdx(pSupportRateIEs->abyRates[ii]);
+                if ((byBasicRate <= byRxDataRate) &&
+                    (byBasicRate > byMaxAckRate))  {
+                    byMaxAckRate = byBasicRate;
+                }
+            }
+        }
+    }
+    if (pExtSupportRateIEs) {
+        for (ii = 0; ii < pExtSupportRateIEs->len; ii++) {
+            if (pExtSupportRateIEs->abyRates[ii] & 0x80) {
+                byBasicRate = DATARATEbyGetRateIdx(pExtSupportRateIEs->abyRates[ii]);
+                if ((byBasicRate <= byRxDataRate) &&
+                    (byBasicRate > byMaxAckRate))  {
+                    byMaxAckRate = byBasicRate;
+                }
+            }
+        }
+    }
+
+    return byMaxAckRate;
+}
+
+/*+
+ *
+ * Description:
+ *    Set Authentication Mode
+ *
+ * Parameters:
+ *  In:
+ *      pMgmtHandle - pointer to management object
+ *      eAuthMode   - Authentication mode
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+-*/
+VOID
+VNTWIFIvSetAuthenticationMode (
+    IN PVOID pMgmtHandle,
+    IN WMAC_AUTHENTICATION_MODE eAuthMode
+    )
+{
+    PSMgmtObject        pMgmt = (PSMgmtObject)pMgmtHandle;
+
+    pMgmt->eAuthenMode = eAuthMode;
+    if ((eAuthMode == WMAC_AUTH_SHAREKEY) ||
+        (eAuthMode == WMAC_AUTH_AUTO)) {
+        pMgmt->bShareKeyAlgorithm = TRUE;
+    } else {
+        pMgmt->bShareKeyAlgorithm = FALSE;
+    }
+}
+
+/*+
+ *
+ * Description:
+ *    Set Encryption Mode
+ *
+ * Parameters:
+ *  In:
+ *      pMgmtHandle - pointer to management object
+ *      eAuthMode   - Authentication mode
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+-*/
+VOID
+VNTWIFIvSetEncryptionMode (
+    IN PVOID pMgmtHandle,
+    IN WMAC_ENCRYPTION_MODE eEncryptionMode
+    )
+{
+    PSMgmtObject        pMgmt = (PSMgmtObject)pMgmtHandle;
+
+    pMgmt->eEncryptionMode = eEncryptionMode;
+    if ((eEncryptionMode == WMAC_ENCRYPTION_WEPEnabled) ||
+        (eEncryptionMode == WMAC_ENCRYPTION_TKIPEnabled) ||
+        (eEncryptionMode == WMAC_ENCRYPTION_AESEnabled) ) {
+        pMgmt->bPrivacyInvoked = TRUE;
+    } else {
+        pMgmt->bPrivacyInvoked = FALSE;
+    }
+}
+
+
+
+BOOL
+VNTWIFIbConfigPhyMode (
+    IN PVOID pMgmtHandle,
+    IN CARD_PHY_TYPE ePhyType
+    )
+{
+    PSMgmtObject        pMgmt = (PSMgmtObject)pMgmtHandle;
+
+    if ((ePhyType != PHY_TYPE_AUTO) &&
+        (ePhyType != pMgmt->eCurrentPHYMode)) {
+        if (CARDbSetPhyParameter(pMgmt->pAdapter, ePhyType, 0, 0, NULL, NULL)==TRUE) {
+            pMgmt->eCurrentPHYMode = ePhyType;
+        } else {
+            return(FALSE);
+        }
+    }
+    pMgmt->eConfigPHYMode = ePhyType;
+    return(TRUE);
+}
+
+
+VOID
+VNTWIFIbGetConfigPhyMode (
+    IN  PVOID pMgmtHandle,
+    OUT PVOID pePhyType
+    )
+{
+    PSMgmtObject        pMgmt = (PSMgmtObject)pMgmtHandle;
+
+    if ((pMgmt != NULL) && (pePhyType != NULL)) {
+        *(PCARD_PHY_TYPE)pePhyType = pMgmt->eConfigPHYMode;
+    }
+}
+
+/*+
+ *
+ * Description:
+ *      Clear BSS List Database except current assoc BSS
+ *
+ * Parameters:
+ *  In:
+ *      pMgmtHandle     - Management Object structure
+ *      bLinkPass       - Current Link status
+ *  Out:
+ *
+ * Return Value: None.
+ *
+-*/
+
+
+/*+
+ *
+ * Description:
+ *      Query BSS List in management database
+ *
+ * Parameters:
+ *  In:
+ *      pMgmtHandle     - Management Object structure
+ *  Out:
+ *      puBSSCount      - BSS count
+ *      pvFirstBSS      - pointer to first BSS
+ *
+ * Return Value: None.
+ *
+-*/
+
+VOID
+VNTWIFIvQueryBSSList (
+    IN PVOID    pMgmtHandle,
+    OUT PUINT   puBSSCount,
+    OUT PVOID   *pvFirstBSS
+    )
+{
+    UINT            ii = 0;
+    PSMgmtObject    pMgmt = (PSMgmtObject)pMgmtHandle;
+    PKnownBSS       pBSS = NULL;
+    UINT            uCount = 0;
+
+    *pvFirstBSS = NULL;
+
+    for (ii = 0; ii < MAX_BSS_NUM; ii++) {
+        pBSS = &(pMgmt->sBSSList[ii]);
+        if (!pBSS->bActive) {
+            continue;
+        }
+        if (*pvFirstBSS == NULL) {
+            *pvFirstBSS = &(pMgmt->sBSSList[ii]);
+        }
+        uCount++;
+    }
+    *puBSSCount = uCount;
+}
+
+
+
+
+VOID
+VNTWIFIvGetNextBSS (
+    IN PVOID            pMgmtHandle,
+    IN PVOID            pvCurrentBSS,
+    OUT PVOID           *pvNextBSS
+    )
+{
+    PKnownBSS       pBSS = (PKnownBSS) pvCurrentBSS;
+    PSMgmtObject    pMgmt = (PSMgmtObject)pMgmtHandle;
+
+    *pvNextBSS = NULL;
+
+    while (*pvNextBSS == NULL) {
+        pBSS++;
+        if (pBSS > &(pMgmt->sBSSList[MAX_BSS_NUM])) {
+            return;
+        }
+        if (pBSS->bActive == TRUE) {
+            *pvNextBSS = pBSS;
+            return;
+        }
+    }
+}
+
+
+
+
+
+/*+
+ *
+ * Description:
+ *      Update Tx attemps, Tx failure counter in Node DB
+ *
+ *  In:
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+-*/
+VOID
+VNTWIFIvUpdateNodeTxCounter(
+    IN PVOID    pMgmtHandle,
+    IN PBYTE    pbyDestAddress,
+    IN BOOL     bTxOk,
+    IN WORD     wRate,
+    IN PBYTE    pbyTxFailCount
+    )
+{
+    PSMgmtObject    pMgmt = (PSMgmtObject)pMgmtHandle;
+    UINT            uNodeIndex = 0;
+    UINT            ii;
+
+    if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) ||
+        (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)) {
+        if (BSSDBbIsSTAInNodeDB(pMgmt, pbyDestAddress, &uNodeIndex) == FALSE) {
+            return;
+        }
+    }
+    pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts++;
+    if (bTxOk == TRUE) {
+        // transmit success, TxAttempts at least plus one
+        pMgmt->sNodeDBTable[uNodeIndex].uTxOk[MAX_RATE]++;
+        pMgmt->sNodeDBTable[uNodeIndex].uTxOk[wRate]++;
+    } else {
+        pMgmt->sNodeDBTable[uNodeIndex].uTxFailures++;
+    }
+    pMgmt->sNodeDBTable[uNodeIndex].uTxRetry += pbyTxFailCount[MAX_RATE];
+    for(ii=0;ii<MAX_RATE;ii++) {
+        pMgmt->sNodeDBTable[uNodeIndex].uTxFail[ii] += pbyTxFailCount[ii];
+    }
+    return;
+}
+
+
+VOID
+VNTWIFIvGetTxRate(
+    IN PVOID    pMgmtHandle,
+    IN PBYTE    pbyDestAddress,
+    OUT PWORD   pwTxDataRate,
+    OUT PBYTE   pbyACKRate,
+    OUT PBYTE   pbyCCKBasicRate,
+    OUT PBYTE   pbyOFDMBasicRate
+    )
+{
+    PSMgmtObject        pMgmt = (PSMgmtObject)pMgmtHandle;
+    UINT                uNodeIndex = 0;
+    WORD                wTxDataRate = RATE_1M;
+    BYTE                byACKRate = RATE_1M;
+    BYTE                byCCKBasicRate = RATE_1M;
+    BYTE                byOFDMBasicRate = RATE_24M;
+    PWLAN_IE_SUPP_RATES pSupportRateIEs = NULL;
+    PWLAN_IE_SUPP_RATES pExtSupportRateIEs = NULL;
+
+
+    if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) ||
+        (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)) {
+        // Adhoc Tx rate decided from node DB
+        if(BSSDBbIsSTAInNodeDB(pMgmt, pbyDestAddress, &uNodeIndex)) {
+            wTxDataRate = (pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate);
+            pSupportRateIEs = (PWLAN_IE_SUPP_RATES) (pMgmt->sNodeDBTable[uNodeIndex].abyCurrSuppRates);
+            pExtSupportRateIEs = (PWLAN_IE_SUPP_RATES) (pMgmt->sNodeDBTable[uNodeIndex].abyCurrExtSuppRates);
+        } else {
+            if (pMgmt->eCurrentPHYMode != PHY_TYPE_11A) {
+                wTxDataRate = RATE_2M;
+            } else {
+                wTxDataRate = RATE_24M;
+            }
+            pSupportRateIEs = (PWLAN_IE_SUPP_RATES) pMgmt->abyCurrSuppRates;
+            pExtSupportRateIEs = (PWLAN_IE_SUPP_RATES) pMgmt->abyCurrExtSuppRates;
+        }
+    } else { // Infrastructure: rate decided from AP Node, index = 0
+
+               wTxDataRate = (pMgmt->sNodeDBTable[0].wTxDataRate);
+#ifdef PLICE_DEBUG
+               printk("GetTxRate:AP MAC is %02x:%02x:%02x:%02x:%02x:%02x,TxRate is %d\n",
+                               pMgmt->sNodeDBTable[0].abyMACAddr[0],pMgmt->sNodeDBTable[0].abyMACAddr[1],
+                               pMgmt->sNodeDBTable[0].abyMACAddr[2],pMgmt->sNodeDBTable[0].abyMACAddr[3],
+                               pMgmt->sNodeDBTable[0].abyMACAddr[4],pMgmt->sNodeDBTable[0].abyMACAddr[5],wTxDataRate);
+#endif
+
+
+        pSupportRateIEs = (PWLAN_IE_SUPP_RATES) pMgmt->abyCurrSuppRates;
+        pExtSupportRateIEs = (PWLAN_IE_SUPP_RATES) pMgmt->abyCurrExtSuppRates;
+    }
+    byACKRate = VNTWIFIbyGetACKTxRate(  (BYTE) wTxDataRate,
+                                        pSupportRateIEs,
+                                        pExtSupportRateIEs
+                                        );
+    if (byACKRate > (BYTE) wTxDataRate) {
+        byACKRate = (BYTE) wTxDataRate;
+    }
+    byCCKBasicRate = VNTWIFIbyGetACKTxRate( RATE_11M,
+                                            pSupportRateIEs,
+                                            pExtSupportRateIEs
+                                            );
+    byOFDMBasicRate = VNTWIFIbyGetACKTxRate(RATE_54M,
+                                            pSupportRateIEs,
+                                            pExtSupportRateIEs
+                                            );
+    *pwTxDataRate = wTxDataRate;
+    *pbyACKRate = byACKRate;
+    *pbyCCKBasicRate = byCCKBasicRate;
+    *pbyOFDMBasicRate = byOFDMBasicRate;
+    return;
+}
+
+BYTE
+VNTWIFIbyGetKeyCypher(
+    IN PVOID    pMgmtHandle,
+    IN BOOL     bGroupKey
+    )
+{
+    PSMgmtObject    pMgmt = (PSMgmtObject)pMgmtHandle;
+
+    if (bGroupKey == TRUE) {
+        return (pMgmt->byCSSGK);
+    } else {
+        return (pMgmt->byCSSPK);
+    }
+}
+
+
+/*
+BOOL
+VNTWIFIbInit(
+    IN PVOID    pAdapterHandler,
+    OUT PVOID   *pMgmtHandler
+    )
+{
+
+    PSMgmtObject        pMgmt = NULL;
+    UINT                ii;
+
+
+    pMgmt = (PSMgmtObject)kmalloc(sizeof(SMgmtObject), (int)GFP_ATOMIC);
+    if (pMgmt == NULL) {
+        *pMgmtHandler = NULL;
+        return FALSE;
+    }
+
+    memset(pMgmt, 0, sizeof(SMgmtObject));
+    pMgmt->pAdapter = (PVOID) pAdapterHandler;
+
+    // should initial MAC address abyMACAddr
+    for(ii=0;ii<WLAN_BSSID_LEN;ii++) {
+        pMgmt->abyDesireBSSID[ii] = 0xFF;
+    }
+    pMgmt->pbyPSPacketPool = &pMgmt->byPSPacketPool[0];
+    pMgmt->pbyMgmtPacketPool = &pMgmt->byMgmtPacketPool[0];
+    pMgmt->byCSSPK = KEY_CTL_NONE;
+    pMgmt->byCSSGK = KEY_CTL_NONE;
+    pMgmt->wIBSSBeaconPeriod = DEFAULT_IBSS_BI;
+
+    pMgmt->cbFreeCmdQueue = CMD_Q_SIZE;
+    pMgmt->uCmdDequeueIdx = 0;
+    pMgmt->uCmdEnqueueIdx = 0;
+    pMgmt->eCommandState = WLAN_CMD_STATE_IDLE;
+    pMgmt->bCmdStop = FALSE;
+    pMgmt->bCmdRunning = FALSE;
+
+    *pMgmtHandler = pMgmt;
+    return TRUE;
+}
+*/
+
+
+
+BOOL
+VNTWIFIbSetPMKIDCache (
+    IN PVOID pMgmtObject,
+    IN ULONG ulCount,
+    IN PVOID pPMKIDInfo
+    )
+{
+    PSMgmtObject    pMgmt = (PSMgmtObject) pMgmtObject;
+
+    if (ulCount > MAX_PMKID_CACHE) {
+        return (FALSE);
+    }
+    pMgmt->gsPMKIDCache.BSSIDInfoCount = ulCount;
+    MEMvCopy(pMgmt->gsPMKIDCache.BSSIDInfo, pPMKIDInfo, (ulCount*sizeof(PMKIDInfo)));
+    return (TRUE);
+}
+
+
+
+WORD
+VNTWIFIwGetMaxSupportRate(
+    IN PVOID pMgmtObject
+    )
+{
+    WORD wRate = RATE_54M;
+    PSMgmtObject    pMgmt = (PSMgmtObject) pMgmtObject;
+
+    for(wRate = RATE_54M; wRate > RATE_1M; wRate--) {
+        if (BITbIsBitOn(pMgmt->sNodeDBTable[0].wSuppRate, (1<<wRate))) {
+            return (wRate);
+        }
+    }
+    if (pMgmt->eCurrentPHYMode == PHY_TYPE_11A) {
+        return (RATE_6M);
+    } else {
+        return (RATE_1M);
+    }
+}
+
+
+VOID
+VNTWIFIvSet11h (
+    IN PVOID pMgmtObject,
+    IN BOOL  b11hEnable
+    )
+{
+    PSMgmtObject    pMgmt = (PSMgmtObject) pMgmtObject;
+
+    pMgmt->b11hEnable = b11hEnable;
+}
+
+BOOL
+VNTWIFIbMeasureReport(
+    IN PVOID pMgmtObject,
+    IN BOOL  bEndOfReport,
+    IN PVOID pvMeasureEID,
+    IN BYTE  byReportMode,
+    IN BYTE  byBasicMap,
+    IN BYTE  byCCAFraction,
+    IN PBYTE pbyRPIs
+    )
+{
+    PSMgmtObject    pMgmt = (PSMgmtObject) pMgmtObject;
+    PBYTE           pbyCurrentEID = (PBYTE) (pMgmt->pCurrMeasureEIDRep);
+
+    //spin_lock_irq(&pDevice->lock);
+    if ((pvMeasureEID != NULL) &&
+        (pMgmt->uLengthOfRepEIDs < (WLAN_A3FR_MAXLEN - sizeof(MEASEURE_REP) - sizeof(WLAN_80211HDR_A3) - 3))
+        ) {
+        pMgmt->pCurrMeasureEIDRep->byElementID = WLAN_EID_MEASURE_REP;
+        pMgmt->pCurrMeasureEIDRep->len = 3;
+        pMgmt->pCurrMeasureEIDRep->byToken = ((PWLAN_IE_MEASURE_REQ) pvMeasureEID)->byToken;
+        pMgmt->pCurrMeasureEIDRep->byMode = byReportMode;
+        pMgmt->pCurrMeasureEIDRep->byType = ((PWLAN_IE_MEASURE_REQ) pvMeasureEID)->byType;
+        switch (pMgmt->pCurrMeasureEIDRep->byType) {
+            case MEASURE_TYPE_BASIC :
+                pMgmt->pCurrMeasureEIDRep->len += sizeof(MEASEURE_REP_BASIC);
+                MEMvCopy(   &(pMgmt->pCurrMeasureEIDRep->sRep.sBasic),
+                            &(((PWLAN_IE_MEASURE_REQ) pvMeasureEID)->sReq),
+                            sizeof(MEASEURE_REQ));
+                pMgmt->pCurrMeasureEIDRep->sRep.sBasic.byMap = byBasicMap;
+                break;
+            case MEASURE_TYPE_CCA :
+                pMgmt->pCurrMeasureEIDRep->len += sizeof(MEASEURE_REP_CCA);
+                MEMvCopy(   &(pMgmt->pCurrMeasureEIDRep->sRep.sCCA),
+                            &(((PWLAN_IE_MEASURE_REQ) pvMeasureEID)->sReq),
+                            sizeof(MEASEURE_REQ));
+                pMgmt->pCurrMeasureEIDRep->sRep.sCCA.byCCABusyFraction = byCCAFraction;
+                break;
+            case MEASURE_TYPE_RPI :
+                pMgmt->pCurrMeasureEIDRep->len += sizeof(MEASEURE_REP_RPI);
+                MEMvCopy(   &(pMgmt->pCurrMeasureEIDRep->sRep.sRPI),
+                            &(((PWLAN_IE_MEASURE_REQ) pvMeasureEID)->sReq),
+                            sizeof(MEASEURE_REQ));
+                MEMvCopy(pMgmt->pCurrMeasureEIDRep->sRep.sRPI.abyRPIdensity, pbyRPIs, 8);
+                break;
+            default :
+                break;
+        }
+        pbyCurrentEID += (2 + pMgmt->pCurrMeasureEIDRep->len);
+        pMgmt->uLengthOfRepEIDs += (2 + pMgmt->pCurrMeasureEIDRep->len);
+        pMgmt->pCurrMeasureEIDRep = (PWLAN_IE_MEASURE_REP) pbyCurrentEID;
+    }
+    if (bEndOfReport == TRUE) {
+        IEEE11hbMSRRepTx(pMgmt);
+    }
+    //spin_unlock_irq(&pDevice->lock);
+    return (TRUE);
+}
+
+
+BOOL
+VNTWIFIbChannelSwitch(
+    IN PVOID pMgmtObject,
+    IN BYTE  byNewChannel
+    )
+{
+    PSMgmtObject    pMgmt = (PSMgmtObject) pMgmtObject;
+
+    //spin_lock_irq(&pDevice->lock);
+    pMgmt->uCurrChannel = byNewChannel;
+    pMgmt->bSwitchChannel = FALSE;
+    //spin_unlock_irq(&pDevice->lock);
+    return TRUE;
+}
+
+/*
+BOOL
+VNTWIFIbRadarPresent(
+    IN PVOID pMgmtObject,
+    IN BYTE  byChannel
+    )
+{
+    PSMgmtObject    pMgmt = (PSMgmtObject) pMgmtObject;
+    if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) &&
+        (byChannel == (BYTE) pMgmt->uCurrChannel) &&
+        (pMgmt->bSwitchChannel != TRUE) &&
+        (pMgmt->b11hEnable == TRUE)) {
+        if (IS_ETH_ADDRESS_EQUAL(pMgmt->abyIBSSDFSOwner, CARDpGetCurrentAddress(pMgmt->pAdapter))) {
+            pMgmt->byNewChannel = CARDbyAutoChannelSelect(pMgmt->pAdapter,(BYTE) pMgmt->uCurrChannel);
+            pMgmt->bSwitchChannel = TRUE;
+        }
+        BEACONbSendBeacon(pMgmt);
+        CARDbChannelSwitch(pMgmt->pAdapter, 0, pMgmt->byNewChannel, 10);
+    }
+    return TRUE;
+}
+*/
+
diff --git a/drivers/staging/vt6655/vntwifi.h b/drivers/staging/vt6655/vntwifi.h
new file mode 100644 (file)
index 0000000..3e620a7
--- /dev/null
@@ -0,0 +1,330 @@
+/*
+ * 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: vntwifi.h
+ *
+ * Purpose: export VNT Host WiFi library function
+ *
+ * Author: Yiching Chen
+ *
+ * Date: Jan 7, 2004
+ *
+ */
+
+#ifndef __VNTWIFI_H__
+#define __VNTWIFI_H__
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+#if !defined(__80211MGR_H__)
+#include "80211mgr.h"
+#endif
+#if !defined(__CARD_H__)
+#include "card.h"
+#endif
+
+/*---------------------  Export Definitions -------------------------*/
+#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
+
+// key CipherSuite
+#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
+
+#define CHANNEL_MAX_24G         14
+
+#define MAX_BSS_NUM             42
+
+#define MAX_PMKID_CACHE         16
+
+// Pre-configured Authenticaiton Mode (from XP)
+typedef enum tagWMAC_AUTHENTICATION_MODE {
+
+    WMAC_AUTH_OPEN,
+    WMAC_AUTH_SHAREKEY,
+    WMAC_AUTH_AUTO,
+    WMAC_AUTH_WPA,
+    WMAC_AUTH_WPAPSK,
+    WMAC_AUTH_WPANONE,
+    WMAC_AUTH_WPA2,
+    WMAC_AUTH_WPA2PSK,
+    WMAC_AUTH_MAX       // Not a real mode, defined as upper bound
+
+} WMAC_AUTHENTICATION_MODE, *PWMAC_AUTHENTICATION_MODE;
+
+typedef enum tagWMAC_ENCRYPTION_MODE {
+
+    WMAC_ENCRYPTION_WEPEnabled,
+    WMAC_ENCRYPTION_WEPDisabled,
+    WMAC_ENCRYPTION_WEPKeyAbsent,
+    WMAC_ENCRYPTION_WEPNotSupported,
+    WMAC_ENCRYPTION_TKIPEnabled,
+    WMAC_ENCRYPTION_TKIPKeyAbsent,
+    WMAC_ENCRYPTION_AESEnabled,
+    WMAC_ENCRYPTION_AESKeyAbsent
+
+} WMAC_ENCRYPTION_MODE, *PWMAC_ENCRYPTION_MODE;
+
+// Pre-configured Mode (from XP)
+
+typedef enum tagWMAC_CONFIG_MODE {
+
+    WMAC_CONFIG_ESS_STA = 0,
+    WMAC_CONFIG_IBSS_STA,
+    WMAC_CONFIG_AUTO,
+    WMAC_CONFIG_AP
+
+} WMAC_CONFIG_MODE, *PWMAC_CONFIG_MODE;
+
+
+
+typedef enum tagWMAC_POWER_MODE {
+
+    WMAC_POWER_CAM,
+    WMAC_POWER_FAST,
+    WMAC_POWER_MAX
+
+} WMAC_POWER_MODE, *PWMAC_POWER_MODE;
+
+#define VNTWIFIbIsShortSlotTime(wCapInfo)               \
+        WLAN_GET_CAP_INFO_SHORTSLOTTIME(wCapInfo)       \
+
+#define VNTWIFIbIsProtectMode(byERP)                    \
+        ((byERP & WLAN_EID_ERP_USE_PROTECTION) != 0)    \
+
+#define VNTWIFIbIsBarkerMode(byERP)                     \
+        ((byERP & WLAN_EID_ERP_BARKER_MODE) != 0)       \
+
+#define VNTWIFIbIsShortPreamble(wCapInfo)               \
+        WLAN_GET_CAP_INFO_SHORTPREAMBLE(wCapInfo)       \
+
+#define VNTWIFIbIsEncryption(wCapInfo)                  \
+        WLAN_GET_CAP_INFO_PRIVACY(wCapInfo)             \
+
+#define VNTWIFIbIsESS(wCapInfo)                         \
+        WLAN_GET_CAP_INFO_ESS(wCapInfo)                 \
+
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+
+/*---------------------  Export Types  ------------------------------*/
+
+
+/*---------------------  Export Functions  --------------------------*/
+
+#ifdef __cplusplus
+extern "C" {                            /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+
+VOID
+VNTWIFIvSetIBSSParameter (
+    IN PVOID pMgmtHandle,
+    IN WORD  wBeaconPeriod,
+    IN WORD  wATIMWindow,
+    IN UINT  uChannel
+    );
+
+VOID
+VNTWIFIvSetOPMode (
+    IN PVOID pMgmtHandle,
+    IN WMAC_CONFIG_MODE eOPMode
+    );
+
+PWLAN_IE_SSID
+VNTWIFIpGetCurrentSSID(
+    IN PVOID pMgmtHandle
+    );
+
+UINT
+VNTWIFIpGetCurrentChannel(
+    IN PVOID pMgmtHandle
+    );
+
+WORD
+VNTWIFIwGetAssocID (
+    IN PVOID pMgmtHandle
+    );
+
+BYTE
+VNTWIFIbyGetMaxSupportRate (
+    IN PWLAN_IE_SUPP_RATES pSupportRateIEs,
+    IN PWLAN_IE_SUPP_RATES pExtSupportRateIEs
+    );
+
+BYTE
+VNTWIFIbyGetACKTxRate (
+    IN BYTE byRxDataRate,
+    IN PWLAN_IE_SUPP_RATES pSupportRateIEs,
+    IN PWLAN_IE_SUPP_RATES pExtSupportRateIEs
+    );
+
+VOID
+VNTWIFIvSetAuthenticationMode (
+    IN PVOID pMgmtHandle,
+    IN WMAC_AUTHENTICATION_MODE eAuthMode
+    );
+
+VOID
+VNTWIFIvSetEncryptionMode (
+    IN PVOID pMgmtHandle,
+    IN WMAC_ENCRYPTION_MODE eEncryptionMode
+    );
+
+
+BOOL
+VNTWIFIbConfigPhyMode(
+    IN PVOID pMgmtHandle,
+    IN CARD_PHY_TYPE ePhyType
+    );
+
+VOID
+VNTWIFIbGetConfigPhyMode(
+    IN  PVOID pMgmtHandle,
+    OUT PVOID pePhyType
+    );
+
+VOID
+VNTWIFIvQueryBSSList(
+    IN PVOID    pMgmtHandle,
+    OUT PUINT   puBSSCount,
+    OUT PVOID   *pvFirstBSS
+    );
+
+
+
+
+VOID
+VNTWIFIvGetNextBSS (
+    IN PVOID            pMgmtHandle,
+    IN PVOID            pvCurrentBSS,
+    OUT PVOID           *pvNextBSS
+    );
+
+
+
+VOID
+VNTWIFIvUpdateNodeTxCounter(
+    IN PVOID    pMgmtHandle,
+    IN PBYTE    pbyDestAddress,
+    IN BOOL     bTxOk,
+    IN WORD     wRate,
+    IN PBYTE    pbyTxFailCount
+    );
+
+
+VOID
+VNTWIFIvGetTxRate(
+    IN PVOID    pMgmtHandle,
+    IN PBYTE    pbyDestAddress,
+    OUT PWORD   pwTxDataRate,
+    OUT PBYTE   pbyACKRate,
+    OUT PBYTE   pbyCCKBasicRate,
+    OUT PBYTE   pbyOFDMBasicRate
+    );
+/*
+BOOL
+VNTWIFIbInit(
+    IN PVOID    pAdapterHandler,
+    OUT PVOID   *pMgmtHandler
+    );
+*/
+
+BYTE
+VNTWIFIbyGetKeyCypher(
+    IN PVOID    pMgmtHandle,
+    IN BOOL     bGroupKey
+    );
+
+
+
+
+BOOL
+VNTWIFIbSetPMKIDCache (
+    IN PVOID pMgmtObject,
+    IN ULONG ulCount,
+    IN PVOID pPMKIDInfo
+    );
+
+BOOL
+VNTWIFIbCommandRunning (
+    IN PVOID pMgmtObject
+    );
+
+WORD
+VNTWIFIwGetMaxSupportRate(
+    IN PVOID pMgmtObject
+    );
+
+// for 802.11h
+VOID
+VNTWIFIvSet11h (
+    IN PVOID pMgmtObject,
+    IN BOOL  b11hEnable
+    );
+
+BOOL
+VNTWIFIbMeasureReport(
+    IN PVOID pMgmtObject,
+    IN BOOL  bEndOfReport,
+    IN PVOID pvMeasureEID,
+    IN BYTE  byReportMode,
+    IN BYTE  byBasicMap,
+    IN BYTE  byCCAFraction,
+    IN PBYTE pbyRPIs
+    );
+
+BOOL
+VNTWIFIbChannelSwitch(
+    IN PVOID pMgmtObject,
+    IN BYTE  byNewChannel
+    );
+/*
+BOOL
+VNTWIFIbRadarPresent(
+    IN PVOID pMgmtObject,
+    IN BYTE  byChannel
+    );
+*/
+
+#ifdef __cplusplus
+}                                       /* End of extern "C" { */
+#endif /* __cplusplus */
+
+
+#endif //__VNTWIFI_H__
diff --git a/drivers/staging/vt6655/wcmd.c b/drivers/staging/vt6655/wcmd.c
new file mode 100644 (file)
index 0000000..92563bd
--- /dev/null
@@ -0,0 +1,1178 @@
+ /*
+ * 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: wcmd.c
+ *
+ * Purpose: Handles the management command interface functions
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: May 8, 2003
+ *
+ * Functions:
+ *      s_vProbeChannel - Active scan channel
+ *      s_MgrMakeProbeRequest - Make ProbeRequest packet
+ *      CommandTimer - Timer function to handle command
+ *      s_bCommandComplete - Command Complete function
+ *      bScheduleCommand - Push Command and wait Command Scheduler to do
+ *      vCommandTimer- Command call back functions
+ *      vCommandTimerWait- Call back timer
+ *      bClearBSSID_SCAN- Clear BSSID_SCAN cmd in CMD Queue
+ *
+ * Revision History:
+ *
+ */
+
+
+
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+#if !defined(__TMACRO_H__)
+#include "tmacro.h"
+#endif
+#if !defined(__DEVICE_H__)
+#include "device.h"
+#endif
+#if !defined(__MAC_H__)
+#include "mac.h"
+#endif
+#if !defined(__CARD_H__)
+#include "card.h"
+#endif
+#if !defined(__80211HDR_H__)
+#include "80211hdr.h"
+#endif
+#if !defined(__WCMD_H__)
+#include "wcmd.h"
+#endif
+#if !defined(__WMGR_H__)
+#include "wmgr.h"
+#endif
+#if !defined(__POWER_H__)
+#include "power.h"
+#endif
+#if !defined(__WCTL_H__)
+#include "wctl.h"
+#endif
+#if !defined(__CARD_H__)
+#include "card.h"
+#endif
+#if !defined(__BASEBAND_H__)
+#include "baseband.h"
+#endif
+#if !defined(__UMEM_H__)
+#include "umem.h"
+#endif
+#if !defined(__RXTX_H__)
+#include "rxtx.h"
+#endif
+#if !defined(__RF_H__)
+#include "rf.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;
+/*---------------------  Static Functions  --------------------------*/
+
+static
+VOID
+s_vProbeChannel(
+    IN PSDevice pDevice
+    );
+
+
+static
+PSTxMgmtPacket
+s_MgrMakeProbeRequest(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PBYTE pScanBSSID,
+    IN PWLAN_IE_SSID pSSID,
+    IN PWLAN_IE_SUPP_RATES pCurrRates,
+    IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates
+    );
+
+static
+BOOL
+s_bCommandComplete (
+    PSDevice pDevice
+    );
+
+/*---------------------  Export Variables  --------------------------*/
+
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+/*
+ * Description:
+ *      Stop AdHoc beacon during scan process
+ *
+ * Parameters:
+ *  In:
+ *      pDevice     - Pointer to the adapter
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+static
+void
+vAdHocBeaconStop(PSDevice  pDevice)
+{
+
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    BOOL            bStop;
+
+    /*
+     * temporarily stop Beacon packet for AdHoc Server
+     * if all of the following coditions are met:
+     *  (1) STA is in AdHoc mode
+     *  (2) VT3253 is programmed as automatic Beacon Transmitting
+     *  (3) One of the following conditions is met
+     *      (3.1) AdHoc channel is in B/G band and the
+     *      current scan channel is in A band
+     *      or
+     *      (3.2) AdHoc channel is in A mode
+     */
+    bStop = FALSE;
+    if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) &&
+    (pMgmt->eCurrState >= WMAC_STATE_STARTED))
+    {
+        if ((pMgmt->uIBSSChannel <=  CB_MAX_CHANNEL_24G) &&
+             (pMgmt->uScanChannel > CB_MAX_CHANNEL_24G))
+        {
+            bStop = TRUE;
+        }
+        if (pMgmt->uIBSSChannel >  CB_MAX_CHANNEL_24G)
+        {
+            bStop = TRUE;
+        }
+    }
+
+    if (bStop)
+    {
+        MACvRegBitsOff(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX);
+    }
+
+}
+
+/*
+ * Description:
+ *      Restart AdHoc beacon after scan process complete
+ *
+ * Parameters:
+ *  In:
+ *      pDevice     - Pointer to the adapter
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+static
+void
+vAdHocBeaconRestart(PSDevice pDevice)
+{
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+
+    /*
+     * Restart Beacon packet for AdHoc Server
+     * if all of the following coditions are met:
+     *  (1) STA is in AdHoc mode
+     *  (2) VT3253 is programmed as automatic Beacon Transmitting
+     */
+    if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) &&
+    (pMgmt->eCurrState >= WMAC_STATE_STARTED))
+    {
+         MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX);
+    }
+
+}
+
+
+
+
+/*+
+ *
+ * Routine Description:
+ *   Prepare and send probe request management frames.
+ *
+ *
+ * Return Value:
+ *    none.
+ *
+-*/
+
+static
+VOID
+s_vProbeChannel(
+    IN PSDevice pDevice
+    )
+{
+                                                     //1M,   2M,   5M,   11M,  18M,  24M,  36M,  54M
+    BYTE abyCurrSuppRatesG[] = {WLAN_EID_SUPP_RATES, 8, 0x02, 0x04, 0x0B, 0x16, 0x24, 0x30, 0x48, 0x6C};
+    BYTE abyCurrExtSuppRatesG[] = {WLAN_EID_EXTSUPP_RATES, 4, 0x0C, 0x12, 0x18, 0x60};
+                                                           //6M,   9M,   12M,  48M
+    BYTE abyCurrSuppRatesA[] = {WLAN_EID_SUPP_RATES, 8, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C};
+    BYTE abyCurrSuppRatesB[] = {WLAN_EID_SUPP_RATES, 4, 0x02, 0x04, 0x0B, 0x16};
+    PBYTE           pbyRate;
+    PSTxMgmtPacket  pTxPacket;
+    PSMgmtObject    pMgmt = pDevice->pMgmt;
+    UINT            ii;
+
+
+    if (pDevice->eCurrentPHYType == PHY_TYPE_11A) {
+        pbyRate = &abyCurrSuppRatesA[0];
+    } else if (pDevice->eCurrentPHYType == PHY_TYPE_11B) {
+        pbyRate = &abyCurrSuppRatesB[0];
+    } else {
+        pbyRate = &abyCurrSuppRatesG[0];
+    }
+    // build an assocreq frame and send it
+    pTxPacket = s_MgrMakeProbeRequest
+                (
+                  pDevice,
+                  pMgmt,
+                  pMgmt->abyScanBSSID,
+                  (PWLAN_IE_SSID)pMgmt->abyScanSSID,
+                  (PWLAN_IE_SUPP_RATES)pbyRate,
+                  (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRatesG
+                );
+
+    if (pTxPacket != NULL ){
+        for (ii = 0; ii < 2 ; ii++) {
+            if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) {
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request sending fail.. \n");
+            }
+            else {
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request is sending.. \n");
+            }
+        }
+    }
+
+}
+
+
+
+
+/*+
+ *
+ * Routine Description:
+ *  Constructs an probe request frame
+ *
+ *
+ * Return Value:
+ *    A ptr to Tx frame or NULL on allocation failue
+ *
+-*/
+
+
+PSTxMgmtPacket
+s_MgrMakeProbeRequest(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PBYTE pScanBSSID,
+    IN PWLAN_IE_SSID pSSID,
+    IN PWLAN_IE_SUPP_RATES pCurrRates,
+    IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates
+
+    )
+{
+    PSTxMgmtPacket      pTxPacket = NULL;
+    WLAN_FR_PROBEREQ    sFrame;
+
+
+    pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
+    memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_PROBEREQ_FR_MAXLEN);
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+    sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
+    sFrame.len = WLAN_PROBEREQ_FR_MAXLEN;
+    vMgrEncodeProbeRequest(&sFrame);
+    sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
+        (
+        WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
+        WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_PROBEREQ)
+        ));
+    memcpy( sFrame.pHdr->sA3.abyAddr1, pScanBSSID, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr3, pScanBSSID, WLAN_BSSID_LEN);
+    // Copy the SSID, pSSID->len=0 indicate broadcast SSID
+    sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len);
+    sFrame.len += pSSID->len + WLAN_IEHDR_LEN;
+    memcpy(sFrame.pSSID, pSSID, pSSID->len + WLAN_IEHDR_LEN);
+    sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
+    sFrame.len += pCurrRates->len + WLAN_IEHDR_LEN;
+    memcpy(sFrame.pSuppRates, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN);
+    // Copy the extension rate set
+    if (pDevice->eCurrentPHYType == PHY_TYPE_11G) {
+        sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
+        sFrame.len += pCurrExtSuppRates->len + WLAN_IEHDR_LEN;
+        memcpy(sFrame.pExtSuppRates, pCurrExtSuppRates, pCurrExtSuppRates->len + WLAN_IEHDR_LEN);
+    }
+    pTxPacket->cbMPDULen = sFrame.len;
+    pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
+
+    return pTxPacket;
+}
+
+
+
+
+VOID
+vCommandTimerWait(
+    IN HANDLE    hDeviceContext,
+    IN UINT MSecond
+    )
+{
+    PSDevice        pDevice = (PSDevice)hDeviceContext;
+
+    init_timer(&pDevice->sTimerCommand);
+    pDevice->sTimerCommand.data = (ULONG)pDevice;
+    pDevice->sTimerCommand.function = (TimerFunction)vCommandTimer;
+    // RUN_AT :1 msec ~= (HZ/1024)
+    pDevice->sTimerCommand.expires = (UINT)RUN_AT((MSecond * HZ) >> 10);
+    add_timer(&pDevice->sTimerCommand);
+    return;
+}
+
+
+
+VOID
+vCommandTimer (
+    IN  HANDLE      hDeviceContext
+    )
+{
+    PSDevice        pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject    pMgmt = pDevice->pMgmt;
+    PWLAN_IE_SSID   pItemSSID;
+    PWLAN_IE_SSID   pItemSSIDCurr;
+    CMD_STATUS      Status;
+    UINT            ii;
+    BYTE            byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
+    struct sk_buff  *skb;
+
+
+    if (pDevice->dwDiagRefCount != 0)
+        return;
+    if (pDevice->bCmdRunning != TRUE)
+        return;
+
+    spin_lock_irq(&pDevice->lock);
+
+    switch ( pDevice->eCommandState ) {
+
+        case WLAN_CMD_SCAN_START:
+
+       pDevice->byReAssocCount = 0;
+            if (pDevice->bRadioOff == TRUE) {
+                s_bCommandComplete(pDevice);
+                spin_unlock_irq(&pDevice->lock);
+                return;
+            }
+
+            if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
+                s_bCommandComplete(pDevice);
+                CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_AP);
+                spin_unlock_irq(&pDevice->lock);
+                return;
+            }
+
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState= WLAN_CMD_SCAN_START\n");
+            pItemSSID = (PWLAN_IE_SSID)pMgmt->abyScanSSID;
+            // wait all Data TD complete
+            if (pDevice->iTDUsed[TYPE_AC0DMA] != 0){
+                spin_unlock_irq(&pDevice->lock);
+                vCommandTimerWait((HANDLE)pDevice, 10);
+                return;
+            };
+
+            if (pMgmt->uScanChannel == 0 ) {
+                pMgmt->uScanChannel = pDevice->byMinChannel;
+                // Set Baseband to be more sensitive.
+
+            }
+            if (pMgmt->uScanChannel > pDevice->byMaxChannel) {
+                pMgmt->eScanState = WMAC_NO_SCANNING;
+
+                // Set Baseband's sensitivity back.
+                // Set channel back
+                CARDbSetChannel(pMgmt->pAdapter, pMgmt->uCurrChannel);
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Scanning, set back to channel: [%d]\n", pMgmt->uCurrChannel);
+                if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
+                    CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_ADHOC);
+                } else {
+                    CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_INFRASTRUCTURE);
+                }
+                vAdHocBeaconRestart(pDevice);
+                s_bCommandComplete(pDevice);
+
+            } else {
+//2008-8-4 <add> by chester
+                 if (!ChannelValid(pDevice->byZoneType, pMgmt->uScanChannel)) {
+                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Invalid channel pMgmt->uScanChannel = %d \n",pMgmt->uScanChannel);
+                    s_bCommandComplete(pDevice);
+                    return;
+                }
+//printk("chester-pMgmt->uScanChannel=%d,pDevice->byMaxChannel=%d\n",pMgmt->uScanChannel,pDevice->byMaxChannel);
+                if (pMgmt->uScanChannel == pDevice->byMinChannel) {
+                    //pMgmt->eScanType = WMAC_SCAN_ACTIVE;
+                    pMgmt->abyScanBSSID[0] = 0xFF;
+                    pMgmt->abyScanBSSID[1] = 0xFF;
+                    pMgmt->abyScanBSSID[2] = 0xFF;
+                    pMgmt->abyScanBSSID[3] = 0xFF;
+                    pMgmt->abyScanBSSID[4] = 0xFF;
+                    pMgmt->abyScanBSSID[5] = 0xFF;
+                    pItemSSID->byElementID = WLAN_EID_SSID;
+                    // clear bssid list
+                    // BSSvClearBSSList((HANDLE)pDevice, pDevice->bLinkPass);
+                    pMgmt->eScanState = WMAC_IS_SCANNING;
+
+                }
+
+                vAdHocBeaconStop(pDevice);
+
+                if (CARDbSetChannel(pMgmt->pAdapter, pMgmt->uScanChannel) == TRUE) {
+                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"SCAN Channel: %d\n", pMgmt->uScanChannel);
+                } else {
+                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"SET SCAN Channel Fail: %d\n", pMgmt->uScanChannel);
+                }
+                CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_UNKNOWN);
+//     printk("chester-mxch=%d\n",pDevice->byMaxChannel);
+      //          printk("chester-ch=%d\n",pMgmt->uScanChannel);
+       pMgmt->uScanChannel++;
+//2008-8-4 <modify> by chester
+        if (!ChannelValid(pDevice->byZoneType, pMgmt->uScanChannel) &&
+                        pMgmt->uScanChannel <= pDevice->byMaxChannel ){
+                    pMgmt->uScanChannel=pDevice->byMaxChannel+1;
+                pMgmt->eCommandState = WLAN_CMD_SCAN_END;
+
+                }
+
+
+                if ((pMgmt->b11hEnable == FALSE) ||
+                    (pMgmt->uScanChannel < CB_MAX_CHANNEL_24G)) {
+                    s_vProbeChannel(pDevice);
+                    spin_unlock_irq(&pDevice->lock);
+                    vCommandTimerWait((HANDLE)pDevice, WCMD_ACTIVE_SCAN_TIME);
+                    return;
+                } else {
+                    spin_unlock_irq(&pDevice->lock);
+                    vCommandTimerWait((HANDLE)pDevice, WCMD_PASSIVE_SCAN_TIME);
+                    return;
+                }
+
+            }
+
+            break;
+
+        case WLAN_CMD_SCAN_END:
+
+            // Set Baseband's sensitivity back.
+            // Set channel back
+            CARDbSetChannel(pMgmt->pAdapter, pMgmt->uCurrChannel);
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Scanning, set back to channel: [%d]\n", pMgmt->uCurrChannel);
+            if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
+                CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_ADHOC);
+            } else {
+                CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_INFRASTRUCTURE);
+            }
+
+            pMgmt->eScanState = WMAC_NO_SCANNING;
+            vAdHocBeaconRestart(pDevice);
+//2008-0409-07, <Add> by Einsn Liu
+#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+       if(pMgmt->eScanType == WMAC_SCAN_PASSIVE)
+                       {//send scan event to wpa_Supplicant
+                               union iwreq_data wrqu;
+                               memset(&wrqu, 0, sizeof(wrqu));
+                               wireless_send_event(pDevice->dev, SIOCGIWSCAN, &wrqu, NULL);
+                       }
+#endif
+            s_bCommandComplete(pDevice);
+            break;
+
+        case WLAN_CMD_DISASSOCIATE_START :
+       pDevice->byReAssocCount = 0;
+            if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
+                (pMgmt->eCurrState != WMAC_STATE_ASSOC)) {
+                s_bCommandComplete(pDevice);
+                spin_unlock_irq(&pDevice->lock);
+                return;
+            } else {
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Send Disassociation Packet..\n");
+                // reason = 8 : disassoc because sta has left
+                vMgrDisassocBeginSta((HANDLE)pDevice, pMgmt, pMgmt->abyCurrBSSID, (8), &Status);
+                pDevice->bLinkPass = FALSE;
+                // unlock command busy
+                pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
+                pItemSSID->len = 0;
+                memset(pItemSSID->abySSID, 0, WLAN_SSID_MAXLEN);
+                pMgmt->eCurrState = WMAC_STATE_IDLE;
+                pMgmt->sNodeDBTable[0].bActive = FALSE;
+//                pDevice->bBeaconBufReady = FALSE;
+            }
+            netif_stop_queue(pDevice->dev);
+            pDevice->eCommandState = WLAN_DISASSOCIATE_WAIT;
+            // wait all Control TD complete
+            if (pDevice->iTDUsed[TYPE_TXDMA0] != 0){
+                vCommandTimerWait((HANDLE)pDevice, 10);
+                spin_unlock_irq(&pDevice->lock);
+                return;
+            };
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" CARDbRadioPowerOff\n");
+       //2008-09-02  <mark>    by chester
+           // CARDbRadioPowerOff(pDevice);
+            s_bCommandComplete(pDevice);
+            break;
+
+        case WLAN_DISASSOCIATE_WAIT :
+            // wait all Control TD complete
+            if (pDevice->iTDUsed[TYPE_TXDMA0] != 0){
+                vCommandTimerWait((HANDLE)pDevice, 10);
+                spin_unlock_irq(&pDevice->lock);
+                return;
+            };
+//2008-09-02  <mark> by chester
+           // CARDbRadioPowerOff(pDevice);
+            s_bCommandComplete(pDevice);
+            break;
+
+        case WLAN_CMD_SSID_START:
+               pDevice->byReAssocCount = 0;
+            if (pDevice->bRadioOff == TRUE) {
+                s_bCommandComplete(pDevice);
+                spin_unlock_irq(&pDevice->lock);
+                return;
+            }
+//printk("chester-currmode=%d\n",pMgmt->eCurrMode);
+printk("chester-abyDesireSSID=%s\n",((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySSID);
+                     //memcpy(pMgmt->abyAdHocSSID,pMgmt->abyDesireSSID,
+                              //((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->len + WLAN_IEHDR_LEN);
+            pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
+            pItemSSIDCurr = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" cmd: desire ssid = %s\n", pItemSSID->abySSID);
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" cmd: curr ssid = %s\n", pItemSSIDCurr->abySSID);
+
+            if (pMgmt->eCurrState == WMAC_STATE_ASSOC) {
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Cmd pMgmt->eCurrState == WMAC_STATE_ASSOC\n");
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pItemSSID->len =%d\n",pItemSSID->len);
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pItemSSIDCurr->len = %d\n",pItemSSIDCurr->len);
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" desire ssid = %s\n", pItemSSID->abySSID);
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" curr ssid = %s\n", pItemSSIDCurr->abySSID);
+            }
+
+            if ((pMgmt->eCurrState == WMAC_STATE_ASSOC) ||
+                ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)&& (pMgmt->eCurrState == WMAC_STATE_JOINTED))) {
+
+                if (pItemSSID->len == pItemSSIDCurr->len) {
+                    if (memcmp(pItemSSID->abySSID, pItemSSIDCurr->abySSID, pItemSSID->len) == 0) {
+                        s_bCommandComplete(pDevice);
+                        spin_unlock_irq(&pDevice->lock);
+                        return;
+                    }
+                }
+
+                netif_stop_queue(pDevice->dev);
+                pDevice->bLinkPass = FALSE;
+            }
+            // set initial state
+            pMgmt->eCurrState = WMAC_STATE_IDLE;
+            pMgmt->eCurrMode = WMAC_MODE_STANDBY;
+            PSvDisablePowerSaving((HANDLE)pDevice);
+            BSSvClearNodeDBTable(pDevice, 0);
+
+            vMgrJoinBSSBegin((HANDLE)pDevice, &Status);
+            // if Infra mode
+            if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED)) {
+
+               // Call mgr to begin the deauthentication
+                // reason = (3) beacuse sta has left ESS
+                if (pMgmt->eCurrState>= WMAC_STATE_AUTH) {
+                    vMgrDeAuthenBeginSta((HANDLE)pDevice, pMgmt, pMgmt->abyCurrBSSID, (3), &Status);
+                }
+                // Call mgr to begin the authentication
+                vMgrAuthenBeginSta((HANDLE)pDevice, pMgmt, &Status);
+                if (Status == CMD_STATUS_SUCCESS) {
+               pDevice->byLinkWaitCount = 0;
+                    pDevice->eCommandState = WLAN_AUTHENTICATE_WAIT;
+                    vCommandTimerWait((HANDLE)pDevice, AUTHENTICATE_TIMEOUT);
+                    spin_unlock_irq(&pDevice->lock);
+                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Set eCommandState = WLAN_AUTHENTICATE_WAIT\n");
+                    return;
+                }
+            }
+            // if Adhoc mode
+            else if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
+                if (pMgmt->eCurrState == WMAC_STATE_JOINTED) {
+                    if (netif_queue_stopped(pDevice->dev)){
+                        netif_wake_queue(pDevice->dev);
+                    }
+                    pDevice->bLinkPass = TRUE;
+
+                    pMgmt->sNodeDBTable[0].bActive = TRUE;
+                    pMgmt->sNodeDBTable[0].uInActiveCount = 0;
+                    bClearBSSID_SCAN(pDevice);
+                }
+                else {
+                    // start own IBSS
+                    vMgrCreateOwnIBSS((HANDLE)pDevice, &Status);
+                    if (Status != CMD_STATUS_SUCCESS){
+                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " WLAN_CMD_IBSS_CREATE fail ! \n");
+                    };
+                    BSSvAddMulticastNode(pDevice);
+                }
+            }
+            // if SSID not found
+            else if (pMgmt->eCurrMode == WMAC_MODE_STANDBY) {
+                if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA ||
+                    pMgmt->eConfigMode == WMAC_CONFIG_AUTO) {
+                    // start own IBSS
+                    vMgrCreateOwnIBSS((HANDLE)pDevice, &Status);
+                    if (Status != CMD_STATUS_SUCCESS){
+                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" WLAN_CMD_IBSS_CREATE fail ! \n");
+                    };
+                    BSSvAddMulticastNode(pDevice);
+                    if (netif_queue_stopped(pDevice->dev)){
+                        netif_wake_queue(pDevice->dev);
+                    }
+                    pDevice->bLinkPass = TRUE;
+                }
+                else {
+                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disconnect SSID none\n");
+                 #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;
+                       printk("wireless_send_event--->SIOCGIWAP(disassociated:vMgrJoinBSSBegin Fail !!)\n");
+                       wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
+                       }
+                    #endif
+
+                }
+            }
+            s_bCommandComplete(pDevice);
+            break;
+
+        case WLAN_AUTHENTICATE_WAIT :
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState == WLAN_AUTHENTICATE_WAIT\n");
+            if (pMgmt->eCurrState == WMAC_STATE_AUTH) {
+                // Call mgr to begin the association
+                       pDevice->byLinkWaitCount = 0;
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCurrState == WMAC_STATE_AUTH\n");
+                vMgrAssocBeginSta((HANDLE)pDevice, pMgmt, &Status);
+                if (Status == CMD_STATUS_SUCCESS) {
+               pDevice->byLinkWaitCount = 0;
+                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState = WLAN_ASSOCIATE_WAIT\n");
+                    pDevice->eCommandState = WLAN_ASSOCIATE_WAIT;
+                    vCommandTimerWait((HANDLE)pDevice, ASSOCIATE_TIMEOUT);
+                    spin_unlock_irq(&pDevice->lock);
+                    return;
+                }
+            }
+
+       else if(pMgmt->eCurrState < WMAC_STATE_AUTHPENDING) {
+               printk("WLAN_AUTHENTICATE_WAIT:Authen Fail???\n");
+          }
+          else  if(pDevice->byLinkWaitCount <= 4){    //mike add:wait another 2 sec if authenticated_frame delay!
+                pDevice->byLinkWaitCount ++;
+              printk("WLAN_AUTHENTICATE_WAIT:wait %d times!!\n",pDevice->byLinkWaitCount);
+              spin_unlock_irq(&pDevice->lock);
+              vCommandTimerWait((HANDLE)pDevice, AUTHENTICATE_TIMEOUT/2);
+              return;
+          }
+                 pDevice->byLinkWaitCount = 0;
+                #if 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;
+                       printk("wireless_send_event--->SIOCGIWAP(disassociated:AUTHENTICATE_WAIT_timeout)\n");
+                       wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
+                       }
+                    #endif
+                #endif
+            s_bCommandComplete(pDevice);
+            break;
+
+        case WLAN_ASSOCIATE_WAIT :
+            if (pMgmt->eCurrState == WMAC_STATE_ASSOC) {
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCurrState == WMAC_STATE_ASSOC\n");
+                if (pDevice->ePSMode != WMAC_POWER_CAM) {
+                    PSvEnablePowerSaving((HANDLE)pDevice, pMgmt->wListenInterval);
+                }
+                if (pMgmt->eAuthenMode >= WMAC_AUTH_WPA) {
+                    KeybRemoveAllKey(&(pDevice->sKey), pDevice->abyBSSID, pDevice->PortOffset);
+                }
+                pDevice->bLinkPass = TRUE;
+                pDevice->byLinkWaitCount = 0;
+                pDevice->byReAssocCount = 0;
+                bClearBSSID_SCAN(pDevice);
+                if (pDevice->byFOETuning) {
+                    BBvSetFOE(pDevice->PortOffset);
+                    PSbSendNullPacket(pDevice);
+                }
+                if (netif_queue_stopped(pDevice->dev)){
+                    netif_wake_queue(pDevice->dev);
+                }
+            #ifdef TxInSleep
+                if(pDevice->IsTxDataTrigger != FALSE)   {    //TxDataTimer is not triggered at the first time
+                     // printk("Re-initial TxDataTimer****\n");
+                   del_timer(&pDevice->sTimerTxData);
+                      init_timer(&pDevice->sTimerTxData);
+                      pDevice->sTimerTxData.data = (ULONG)pDevice;
+                      pDevice->sTimerTxData.function = (TimerFunction)BSSvSecondTxData;
+                      pDevice->sTimerTxData.expires = RUN_AT(10*HZ);      //10s callback
+                      pDevice->fTxDataInSleep = FALSE;
+                      pDevice->nTxDataTimeCout = 0;
+                }
+                else {
+                  // printk("mike:-->First time triger TimerTxData InSleep\n");
+                }
+               pDevice->IsTxDataTrigger = TRUE;
+                add_timer(&pDevice->sTimerTxData);
+             #endif
+            }
+                  else if(pMgmt->eCurrState < WMAC_STATE_ASSOCPENDING) {
+               printk("WLAN_ASSOCIATE_WAIT:Association Fail???\n");
+          }
+          else  if(pDevice->byLinkWaitCount <= 4){    //mike add:wait another 2 sec if associated_frame delay!
+                pDevice->byLinkWaitCount ++;
+              printk("WLAN_ASSOCIATE_WAIT:wait %d times!!\n",pDevice->byLinkWaitCount);
+              spin_unlock_irq(&pDevice->lock);
+              vCommandTimerWait((HANDLE)pDevice, ASSOCIATE_TIMEOUT/2);
+              return;
+          }
+                 pDevice->byLinkWaitCount = 0;
+               #if 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;
+                       printk("wireless_send_event--->SIOCGIWAP(disassociated:ASSOCIATE_WAIT_timeout)\n");
+                       wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
+                       }
+                    #endif
+               #endif
+
+            s_bCommandComplete(pDevice);
+            break;
+
+        case WLAN_CMD_AP_MODE_START :
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState == WLAN_CMD_AP_MODE_START\n");
+
+            if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
+                del_timer(&pMgmt->sTimerSecondCallback);
+                pMgmt->eCurrState = WMAC_STATE_IDLE;
+                pMgmt->eCurrMode = WMAC_MODE_STANDBY;
+                pDevice->bLinkPass = FALSE;
+                if (pDevice->bEnableHostWEP == TRUE)
+                    BSSvClearNodeDBTable(pDevice, 1);
+                else
+                    BSSvClearNodeDBTable(pDevice, 0);
+                pDevice->uAssocCount = 0;
+                pMgmt->eCurrState = WMAC_STATE_IDLE;
+                pDevice->bFixRate = FALSE;
+
+                vMgrCreateOwnIBSS((HANDLE)pDevice, &Status);
+                if (Status != CMD_STATUS_SUCCESS){
+                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " vMgrCreateOwnIBSS fail ! \n");
+                };
+                // alway turn off unicast bit
+                MACvRegBitsOff(pDevice->PortOffset, MAC_REG_RCR, RCR_UNICAST);
+                pDevice->byRxMode &= ~RCR_UNICAST;
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wcmd: rx_mode = %x\n", pDevice->byRxMode );
+                BSSvAddMulticastNode(pDevice);
+                if (netif_queue_stopped(pDevice->dev)){
+                    netif_wake_queue(pDevice->dev);
+                }
+                pDevice->bLinkPass = TRUE;
+                add_timer(&pMgmt->sTimerSecondCallback);
+            }
+            s_bCommandComplete(pDevice);
+            break;
+
+        case WLAN_CMD_TX_PSPACKET_START :
+            // DTIM Multicast tx
+            if (pMgmt->sNodeDBTable[0].bRxPSPoll) {
+                while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[0].sTxPSQueue)) != NULL) {
+                    if (skb_queue_empty(&pMgmt->sNodeDBTable[0].sTxPSQueue)) {
+                        pMgmt->abyPSTxMap[0] &= ~byMask[0];
+                        pDevice->bMoreData = FALSE;
+                    }
+                    else {
+                        pDevice->bMoreData = TRUE;
+                    }
+                    if (!device_dma0_xmit(pDevice, skb, 0)) {
+                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Multicast ps tx fail \n");
+                    }
+                    pMgmt->sNodeDBTable[0].wEnQueueCnt--;
+                }
+            };
+
+            // PS nodes tx
+            for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) {
+                if (pMgmt->sNodeDBTable[ii].bActive &&
+                    pMgmt->sNodeDBTable[ii].bRxPSPoll) {
+                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index=%d Enqueu Cnt= %d\n",
+                               ii, pMgmt->sNodeDBTable[ii].wEnQueueCnt);
+                    while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) != NULL) {
+                        if (skb_queue_empty(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) {
+                            // clear tx map
+                            pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[ii].wAID >> 3] &=
+                                    ~byMask[pMgmt->sNodeDBTable[ii].wAID & 7];
+                            pDevice->bMoreData = FALSE;
+                        }
+                        else {
+                            pDevice->bMoreData = TRUE;
+                        }
+                        if (!device_dma0_xmit(pDevice, skb, ii)) {
+                            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "sta ps tx fail \n");
+                        }
+                        pMgmt->sNodeDBTable[ii].wEnQueueCnt--;
+                        // check if sta ps enable, wait next pspoll
+                        // if sta ps disable, send all pending buffers.
+                        if (pMgmt->sNodeDBTable[ii].bPSEnable)
+                            break;
+                    }
+                    if (skb_queue_empty(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) {
+                        // clear tx map
+                        pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[ii].wAID >> 3] &=
+                                    ~byMask[pMgmt->sNodeDBTable[ii].wAID & 7];
+                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index=%d PS queue clear \n", ii);
+                    }
+                    pMgmt->sNodeDBTable[ii].bRxPSPoll = FALSE;
+                }
+            }
+
+            s_bCommandComplete(pDevice);
+            break;
+
+
+        case WLAN_CMD_RADIO_START :
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState == WLAN_CMD_RADIO_START\n");
+            if (pDevice->bRadioCmd == TRUE)
+                CARDbRadioPowerOn(pDevice);
+            else
+                CARDbRadioPowerOff(pDevice);
+
+            s_bCommandComplete(pDevice);
+            break;
+
+
+        case WLAN_CMD_CHECK_BBSENSITIVITY_CHANGE :
+            //DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState == WLAN_CMD_CHECK_BBSENSITIVITY_START\n");
+            // wait all TD complete
+            if (pDevice->iTDUsed[TYPE_AC0DMA] != 0){
+                vCommandTimerWait((HANDLE)pDevice, 10);
+                spin_unlock_irq(&pDevice->lock);
+                return;
+            }
+            if (pDevice->iTDUsed[TYPE_TXDMA0] != 0){
+                vCommandTimerWait((HANDLE)pDevice, 10);
+                spin_unlock_irq(&pDevice->lock);
+                return;
+            }
+            pDevice->byBBVGACurrent = pDevice->byBBVGANew;
+            BBvSetVGAGainOffset(pDevice, pDevice->byBBVGACurrent);
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"SetVGAGainOffset %02X\n", pDevice->byBBVGACurrent);
+            s_bCommandComplete(pDevice);
+            break;
+
+        default :
+            s_bCommandComplete(pDevice);
+            break;
+
+    } //switch
+    spin_unlock_irq(&pDevice->lock);
+    return;
+
+}
+
+
+static
+BOOL
+s_bCommandComplete (
+    PSDevice pDevice
+    )
+{
+    PWLAN_IE_SSID pSSID;
+    BOOL          bRadioCmd = FALSE;
+    //WORD          wDeAuthenReason = 0;
+    BOOL          bForceSCAN = TRUE;
+    PSMgmtObject  pMgmt = pDevice->pMgmt;
+
+
+    pDevice->eCommandState = WLAN_CMD_IDLE;
+    if (pDevice->cbFreeCmdQueue == CMD_Q_SIZE) {
+        //Command Queue Empty
+        pDevice->bCmdRunning = FALSE;
+        return TRUE;
+    }
+    else {
+        pDevice->eCommand = pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].eCmd;
+        pSSID = (PWLAN_IE_SSID)pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].abyCmdDesireSSID;
+        bRadioCmd = pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].bRadioCmd;
+        bForceSCAN = pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].bForceSCAN;
+        ADD_ONE_WITH_WRAP_AROUND(pDevice->uCmdDequeueIdx, CMD_Q_SIZE);
+        pDevice->cbFreeCmdQueue++;
+        pDevice->bCmdRunning = TRUE;
+        switch ( pDevice->eCommand ) {
+            case WLAN_CMD_BSSID_SCAN:
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState= WLAN_CMD_BSSID_SCAN\n");
+                pDevice->eCommandState = WLAN_CMD_SCAN_START;
+                pMgmt->uScanChannel = 0;
+                if (pSSID->len != 0) {
+                    MEMvCopy(pMgmt->abyScanSSID, pSSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+                } else {
+                    memset(pMgmt->abyScanSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+                }
+/*
+                if ((bForceSCAN == FALSE) && (pDevice->bLinkPass == TRUE)) {
+                    if ((pSSID->len == ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) &&
+                        (MEMEqualMemory(pSSID->abySSID, ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID, pSSID->len))) {
+                        pDevice->eCommandState = WLAN_CMD_IDLE;
+                    }
+                }
+*/
+                break;
+            case WLAN_CMD_SSID:
+                pDevice->eCommandState = WLAN_CMD_SSID_START;
+                if (pSSID->len > WLAN_SSID_MAXLEN)
+                    pSSID->len = WLAN_SSID_MAXLEN;
+                if (pSSID->len != 0)
+                    MEMvCopy(pDevice->pMgmt->abyDesireSSID, pSSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState= WLAN_CMD_SSID_START\n");
+                break;
+            case WLAN_CMD_DISASSOCIATE:
+                pDevice->eCommandState = WLAN_CMD_DISASSOCIATE_START;
+                break;
+            case WLAN_CMD_RX_PSPOLL:
+                pDevice->eCommandState = WLAN_CMD_TX_PSPACKET_START;
+                break;
+            case WLAN_CMD_RUN_AP:
+                pDevice->eCommandState = WLAN_CMD_AP_MODE_START;
+                break;
+            case WLAN_CMD_RADIO:
+                pDevice->eCommandState = WLAN_CMD_RADIO_START;
+                pDevice->bRadioCmd = bRadioCmd;
+                break;
+            case WLAN_CMD_CHANGE_BBSENSITIVITY:
+                pDevice->eCommandState = WLAN_CMD_CHECK_BBSENSITIVITY_CHANGE;
+                break;
+
+            default:
+                break;
+
+        }
+
+        vCommandTimerWait((HANDLE)pDevice, 0);
+    }
+
+    return TRUE;
+}
+
+
+
+BOOL bScheduleCommand (
+    IN HANDLE hDeviceContext,
+    IN CMD_CODE    eCommand,
+    IN PBYTE       pbyItem0
+    )
+{
+    PSDevice        pDevice = (PSDevice)hDeviceContext;
+
+
+    if (pDevice->cbFreeCmdQueue == 0) {
+        return (FALSE);
+    }
+    pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].eCmd = eCommand;
+    pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bForceSCAN = TRUE;
+    memset(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID, 0 , WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+
+    if (pbyItem0 != NULL) {
+        switch (eCommand) {
+
+            case WLAN_CMD_BSSID_SCAN:
+                MEMvCopy(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID,
+                         pbyItem0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+                pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bForceSCAN = FALSE;
+                break;
+
+            case WLAN_CMD_SSID:
+                MEMvCopy(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID,
+                         pbyItem0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+                break;
+
+            case WLAN_CMD_DISASSOCIATE:
+                pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bNeedRadioOFF = *((PBOOL)pbyItem0);
+                break;
+/*
+            case WLAN_CMD_DEAUTH:
+                pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].wDeAuthenReason = *((PWORD)pbyItem0);
+                break;
+*/
+
+            case WLAN_CMD_RX_PSPOLL:
+                break;
+
+            case WLAN_CMD_RADIO:
+                pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bRadioCmd = *((PBOOL)pbyItem0);
+                break;
+
+            case WLAN_CMD_CHANGE_BBSENSITIVITY:
+                pDevice->eCommandState = WLAN_CMD_CHECK_BBSENSITIVITY_CHANGE;
+                break;
+
+            default:
+                break;
+        }
+    }
+
+    ADD_ONE_WITH_WRAP_AROUND(pDevice->uCmdEnqueueIdx, CMD_Q_SIZE);
+    pDevice->cbFreeCmdQueue--;
+
+    if (pDevice->bCmdRunning == FALSE) {
+        s_bCommandComplete(pDevice);
+    }
+    else {
+    }
+    return (TRUE);
+
+}
+
+/*
+ * Description:
+ *      Clear BSSID_SCAN cmd in CMD Queue
+ *
+ * Parameters:
+ *  In:
+ *      hDeviceContext  - Pointer to the adapter
+ *      eCommand        - Command
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if success; otherwise FALSE
+ *
+ */
+BOOL bClearBSSID_SCAN (
+    IN HANDLE hDeviceContext
+    )
+{
+    PSDevice        pDevice = (PSDevice)hDeviceContext;
+    UINT            uCmdDequeueIdx = pDevice->uCmdDequeueIdx;
+    UINT            ii;
+
+    if ((pDevice->cbFreeCmdQueue < CMD_Q_SIZE) && (uCmdDequeueIdx != pDevice->uCmdEnqueueIdx)) {
+        for (ii = 0; ii < (CMD_Q_SIZE - pDevice->cbFreeCmdQueue); ii ++) {
+            if (pDevice->eCmdQueue[uCmdDequeueIdx].eCmd == WLAN_CMD_BSSID_SCAN)
+                pDevice->eCmdQueue[uCmdDequeueIdx].eCmd = WLAN_CMD_IDLE;
+            ADD_ONE_WITH_WRAP_AROUND(uCmdDequeueIdx, CMD_Q_SIZE);
+            if (uCmdDequeueIdx == pDevice->uCmdEnqueueIdx)
+                break;
+        }
+    }
+    return TRUE;
+}
+
+//mike add:reset command timer
+VOID
+vResetCommandTimer(
+    IN HANDLE      hDeviceContext
+    )
+{
+  PSDevice        pDevice = (PSDevice)hDeviceContext;
+
+  //delete timer
+      del_timer(&pDevice->sTimerCommand);
+  //init timer
+      init_timer(&pDevice->sTimerCommand);
+    pDevice->sTimerCommand.data = (ULONG)pDevice;
+    pDevice->sTimerCommand.function = (TimerFunction)vCommandTimer;
+    pDevice->sTimerCommand.expires = RUN_AT(HZ);
+    pDevice->cbFreeCmdQueue = CMD_Q_SIZE;
+    pDevice->uCmdDequeueIdx = 0;
+    pDevice->uCmdEnqueueIdx = 0;
+    pDevice->eCommandState = WLAN_CMD_IDLE;
+    pDevice->bCmdRunning = FALSE;
+    pDevice->bCmdClear = FALSE;
+}
+
+
+#ifdef TxInSleep
+VOID
+BSSvSecondTxData(
+    IN  HANDLE      hDeviceContext
+    )
+{
+  PSDevice        pDevice = (PSDevice)hDeviceContext;
+  PSMgmtObject  pMgmt = &(pDevice->sMgmtObj);
+  pDevice->nTxDataTimeCout++;
+
+  if(pDevice->nTxDataTimeCout<4)     //don't tx data if timer less than 40s
+    {
+     // printk("mike:%s-->no data Tx not exceed the desired Time as %d\n",__FUNCTION__,
+       //      (int)pDevice->nTxDataTimeCout);
+     pDevice->sTimerTxData.expires = RUN_AT(10*HZ);      //10s callback
+     add_timer(&pDevice->sTimerTxData);
+      return;
+    }
+
+  spin_lock_irq(&pDevice->lock);
+  #if 1
+  if(((pDevice->bLinkPass ==TRUE)&&(pMgmt->eAuthenMode < WMAC_AUTH_WPA)) ||  //open && sharekey linking
+      (pDevice->fWPA_Authened == TRUE)) {   //wpa linking
+ #else
+  if(pDevice->bLinkPass ==TRUE) {
+ #endif
+
+        //   printk("mike:%s-->InSleep Tx Data Procedure\n",__FUNCTION__);
+         pDevice->fTxDataInSleep = TRUE;
+         PSbSendNullPacket(pDevice);      //send null packet
+         pDevice->fTxDataInSleep = FALSE;
+       }
+  spin_unlock_irq(&pDevice->lock);
+
+  pDevice->sTimerTxData.expires = RUN_AT(10*HZ);      //10s callback
+  add_timer(&pDevice->sTimerTxData);
+  return;
+}
+#endif
+
diff --git a/drivers/staging/vt6655/wcmd.h b/drivers/staging/vt6655/wcmd.h
new file mode 100644 (file)
index 0000000..8c6bbc4
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * 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: wcmd.h
+ *
+ * Purpose: Handles the management command interface functions
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: May 8, 2002
+ *
+ */
+
+#ifndef __WCMD_H__
+#define __WCMD_H__
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+#if !defined(__80211HDR_H__)
+#include "80211hdr.h"
+#endif
+#if !defined(__80211MGR_H__)
+#include "80211mgr.h"
+#endif
+
+/*---------------------  Export Definitions -------------------------*/
+
+
+
+#define AUTHENTICATE_TIMEOUT   1000 //ms
+#define ASSOCIATE_TIMEOUT      1000 //ms
+
+// Command code
+typedef enum tagCMD_CODE {
+    WLAN_CMD_BSSID_SCAN,
+    WLAN_CMD_SSID,
+    WLAN_CMD_DISASSOCIATE,
+    WLAN_CMD_DEAUTH,
+    WLAN_CMD_RX_PSPOLL,
+    WLAN_CMD_RADIO,
+    WLAN_CMD_CHANGE_BBSENSITIVITY,
+    WLAN_CMD_SETPOWER,
+    WLAN_CMD_TBTT_WAKEUP,
+    WLAN_CMD_BECON_SEND,
+    WLAN_CMD_CHANGE_ANTENNA,
+    WLAN_CMD_REMOVE_ALLKEY,
+    WLAN_CMD_MAC_DISPOWERSAVING,
+    WLAN_CMD_11H_CHSW,
+    WLAN_CMD_RUN_AP
+} CMD_CODE, DEF* PCMD_CODE;
+
+#define CMD_Q_SIZE              32
+
+
+// Command code
+typedef enum tagCMD_STATUS {
+
+    CMD_STATUS_SUCCESS,
+    CMD_STATUS_FAILURE,
+    CMD_STATUS_RESOURCES,
+    CMD_STATUS_TIMEOUT,
+    CMD_STATUS_PENDING
+
+} CMD_STATUS, DEF* PCMD_STATUS;
+
+
+typedef struct tagCMD_ITEM {
+    CMD_CODE eCmd;
+    BYTE     abyCmdDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
+    BOOL     bNeedRadioOFF;
+    WORD     wDeAuthenReason;
+    BOOL     bRadioCmd;
+    BOOL     bForceSCAN;
+} CMD_ITEM, DEF* PCMD_ITEM;
+
+// Command state
+typedef enum tagCMD_STATE {
+    WLAN_CMD_SCAN_START,
+    WLAN_CMD_SCAN_END,
+    WLAN_CMD_DISASSOCIATE_START,
+    WLAN_CMD_SSID_START,
+    WLAN_AUTHENTICATE_WAIT,
+    WLAN_ASSOCIATE_WAIT,
+    WLAN_DISASSOCIATE_WAIT,
+    WLAN_CMD_TX_PSPACKET_START,
+    WLAN_CMD_AP_MODE_START,
+    WLAN_CMD_RADIO_START,
+    WLAN_CMD_CHECK_BBSENSITIVITY_CHANGE,
+    WLAN_CMD_IDLE
+} CMD_STATE, DEF* PCMD_STATE;
+
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+
+/*---------------------  Export Types  ------------------------------*/
+
+
+/*---------------------  Export Functions  --------------------------*/
+
+VOID
+vResetCommandTimer(
+    IN HANDLE      hDeviceContext
+    );
+
+VOID
+vCommandTimer (
+    IN  HANDLE hDeviceContext
+    );
+
+BOOL bClearBSSID_SCAN(
+    IN HANDLE hDeviceContext
+    );
+
+BOOL
+bScheduleCommand(
+    IN HANDLE      hDeviceContext,
+    IN CMD_CODE    eCommand,
+    IN PBYTE       pbyItem0
+    );
+
+VOID
+vCommandTimerWait(
+    IN HANDLE      hDeviceContext,
+    IN UINT MSecond
+    );
+#ifdef TxInSleep
+VOID
+BSSvSecondTxData(
+    IN  HANDLE      hDeviceContext
+    );
+#endif
+#endif //__WCMD_H__
diff --git a/drivers/staging/vt6655/wctl.c b/drivers/staging/vt6655/wctl.c
new file mode 100644 (file)
index 0000000..b4fecc2
--- /dev/null
@@ -0,0 +1,261 @@
+/*
+ * 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: wctl.c
+ *
+ * Purpose: handle WMAC duplicate filter & defragment
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Jun. 27, 2002
+ *
+ * Functions:
+ *      WCTLbIsDuplicate - Test if duplicate packet
+ *      WCTLuSearchDFCB - Search DeFragment Control Database
+ *      WCTLuInsertDFCB - Insert DeFragment Control Database
+ *      WCTLbHandleFragment - Handle received fragment packet
+ *
+ * Revision History:
+ *
+ */
+
+
+#if !defined(__WCTL_H__)
+#include "wctl.h"
+#endif
+#if !defined(__DEVICE_H__)
+#include "device.h"
+#endif
+#if !defined(__CARD_H__)
+#include "card.h"
+#endif
+
+/*---------------------  Static Definitions -------------------------*/
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+// static int          msglevel                =MSG_LEVEL_INFO;
+/*---------------------  Static Functions  --------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+
+
+/*
+ * Description:
+ *      Scan Rx cache.  Return TRUE if packet is duplicate, else
+ *      inserts in receive cache and returns FALSE.
+ *
+ * Parameters:
+ *  In:
+ *      pCache      - Receive packets history
+ *      pMACHeader  - 802.11 MAC Header of received packet
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if packet duplicate; otherwise FALSE
+ *
+ */
+
+BOOL WCTLbIsDuplicate (PSCache pCache, PS802_11Header pMACHeader)
+{
+    UINT            uIndex;
+    UINT            ii;
+    PSCacheEntry    pCacheEntry;
+
+    if (IS_FC_RETRY(pMACHeader)) {
+
+        uIndex = pCache->uInPtr;
+        for (ii = 0; ii < DUPLICATE_RX_CACHE_LENGTH; ii++) {
+            pCacheEntry = &(pCache->asCacheEntry[uIndex]);
+            if ((pCacheEntry->wFmSequence == pMACHeader->wSeqCtl) &&
+                (IS_ETH_ADDRESS_EQUAL (&(pCacheEntry->abyAddr2[0]), &(pMACHeader->abyAddr2[0])))
+                ) {
+                /* Duplicate match */
+                return TRUE;
+            }
+            ADD_ONE_WITH_WRAP_AROUND(uIndex, DUPLICATE_RX_CACHE_LENGTH);
+        }
+    }
+    /* Not fount in cache - insert */
+    pCacheEntry = &pCache->asCacheEntry[pCache->uInPtr];
+    pCacheEntry->wFmSequence = pMACHeader->wSeqCtl;
+    memcpy(&(pCacheEntry->abyAddr2[0]), &(pMACHeader->abyAddr2[0]), U_ETHER_ADDR_LEN);
+    ADD_ONE_WITH_WRAP_AROUND(pCache->uInPtr, DUPLICATE_RX_CACHE_LENGTH);
+    return FALSE;
+}
+
+/*
+ * Description:
+ *      Found if sequence number of received fragment packet in Defragment Database
+ *
+ * Parameters:
+ *  In:
+ *      pDevice     - Pointer to adapter
+ *      pMACHeader  - 802.11 MAC Header of received packet
+ *  Out:
+ *      none
+ *
+ * Return Value: index number in Defragment Database
+ *
+ */
+UINT WCTLuSearchDFCB (PSDevice pDevice, PS802_11Header pMACHeader)
+{
+UINT ii;
+
+    for(ii=0;ii<pDevice->cbDFCB;ii++) {
+        if ((pDevice->sRxDFCB[ii].bInUse == TRUE) &&
+            (IS_ETH_ADDRESS_EQUAL (&(pDevice->sRxDFCB[ii].abyAddr2[0]), &(pMACHeader->abyAddr2[0])))
+            ) {
+            //
+            return(ii);
+        }
+    }
+    return(pDevice->cbDFCB);
+}
+
+
+/*
+ * Description:
+ *      Insert received fragment packet in Defragment Database
+ *
+ * Parameters:
+ *  In:
+ *      pDevice     - Pointer to adapter
+ *      pMACHeader  - 802.11 MAC Header of received packet
+ *  Out:
+ *      none
+ *
+ * Return Value: index number in Defragment Database
+ *
+ */
+UINT WCTLuInsertDFCB (PSDevice pDevice, PS802_11Header pMACHeader)
+{
+UINT ii;
+
+    if (pDevice->cbFreeDFCB == 0)
+        return(pDevice->cbDFCB);
+    for(ii=0;ii<pDevice->cbDFCB;ii++) {
+        if (pDevice->sRxDFCB[ii].bInUse == FALSE) {
+            pDevice->cbFreeDFCB--;
+            pDevice->sRxDFCB[ii].uLifetime = pDevice->dwMaxReceiveLifetime;
+            pDevice->sRxDFCB[ii].bInUse = TRUE;
+            pDevice->sRxDFCB[ii].wSequence = (pMACHeader->wSeqCtl >> 4);
+            pDevice->sRxDFCB[ii].wFragNum = (pMACHeader->wSeqCtl & 0x000F);
+            memcpy(&(pDevice->sRxDFCB[ii].abyAddr2[0]), &(pMACHeader->abyAddr2[0]), U_ETHER_ADDR_LEN);
+            return(ii);
+        }
+    }
+    return(pDevice->cbDFCB);
+}
+
+
+/*
+ * Description:
+ *      Handle received fragment packet
+ *
+ * Parameters:
+ *  In:
+ *      pDevice         - Pointer to adapter
+ *      pMACHeader      - 802.11 MAC Header of received packet
+ *      cbFrameLength   - Frame length
+ *      bWEP            - is WEP packet
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if it is valid fragment packet and we have resource to defragment; otherwise FALSE
+ *
+ */
+BOOL WCTLbHandleFragment (PSDevice pDevice, PS802_11Header pMACHeader, UINT cbFrameLength, BOOL bWEP, BOOL bExtIV)
+{
+UINT            uHeaderSize;
+
+
+    if (bWEP == TRUE) {
+        uHeaderSize = 28;
+        if (bExtIV)
+        // ExtIV
+            uHeaderSize +=4;
+    }
+    else {
+        uHeaderSize = 24;
+    }
+
+    if (IS_FIRST_FRAGMENT_PKT(pMACHeader)) {
+        pDevice->uCurrentDFCBIdx = WCTLuSearchDFCB(pDevice, pMACHeader);
+        if (pDevice->uCurrentDFCBIdx < pDevice->cbDFCB) {
+            // duplicate, we must flush previous DCB
+            pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].uLifetime = pDevice->dwMaxReceiveLifetime;
+            pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wSequence = (pMACHeader->wSeqCtl >> 4);
+            pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wFragNum = (pMACHeader->wSeqCtl & 0x000F);
+        }
+        else {
+            pDevice->uCurrentDFCBIdx = WCTLuInsertDFCB(pDevice, pMACHeader);
+            if (pDevice->uCurrentDFCBIdx == pDevice->cbDFCB) {
+                return(FALSE);
+            }
+        }
+        // reserve 4 byte to match MAC RX Buffer
+#ifdef PRIVATE_OBJ
+        pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer = (PBYTE) (pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].ref_skb.data + 4);
+#else
+        pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer = (PBYTE) (pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].skb->data + 4);
+#endif
+        memcpy(pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer, pMACHeader, cbFrameLength);
+        pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength = cbFrameLength;
+        pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer += cbFrameLength;
+        pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wFragNum++;
+        //DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "First pDevice->uCurrentDFCBIdx= %d\n", pDevice->uCurrentDFCBIdx);
+        return(FALSE);
+    }
+    else {
+        pDevice->uCurrentDFCBIdx = WCTLuSearchDFCB(pDevice, pMACHeader);
+        if (pDevice->uCurrentDFCBIdx != pDevice->cbDFCB) {
+            if ((pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wSequence == (pMACHeader->wSeqCtl >> 4)) &&
+                (pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wFragNum == (pMACHeader->wSeqCtl & 0x000F)) &&
+                ((pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength + cbFrameLength - uHeaderSize) < 2346)) {
+
+                memcpy(pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer, ((PBYTE) (pMACHeader) + uHeaderSize), (cbFrameLength - uHeaderSize));
+                pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength += (cbFrameLength - uHeaderSize);
+                pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer += (cbFrameLength - uHeaderSize);
+                pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wFragNum++;
+                //DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Second pDevice->uCurrentDFCBIdx= %d\n", pDevice->uCurrentDFCBIdx);
+            }
+            else {
+                // seq error or frag # error flush DFCB
+                pDevice->cbFreeDFCB++;
+                pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].bInUse = FALSE;
+                return(FALSE);
+            }
+        }
+        else {
+            return(FALSE);
+        }
+        if (IS_LAST_FRAGMENT_PKT(pMACHeader)) {
+            //enq defragcontrolblock
+            pDevice->cbFreeDFCB++;
+            pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].bInUse = FALSE;
+            //DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Last pDevice->uCurrentDFCBIdx= %d\n", pDevice->uCurrentDFCBIdx);
+            return(TRUE);
+        }
+        return(FALSE);
+    }
+}
+
+
diff --git a/drivers/staging/vt6655/wctl.h b/drivers/staging/vt6655/wctl.h
new file mode 100644 (file)
index 0000000..f75ca59
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * 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: wctl.h
+ *
+ * Purpose:
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Jun. 27, 2002
+ *
+ */
+
+
+#ifndef __WCTL_H__
+#define __WCTL_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 IS_TYPE_DATA(pMACHeader)                                                        \
+    ((((PS802_11Header) pMACHeader)->wFrameCtl & TYPE_802_11_MASK) == TYPE_802_11_DATA)
+
+#define IS_TYPE_MGMT(pMACHeader)                                                        \
+    ((((PS802_11Header) pMACHeader)->wFrameCtl & TYPE_802_11_MASK) == TYPE_802_11_MGMT)
+
+#define IS_TYPE_CONTROL(pMACHeader)                                                     \
+    ((((PS802_11Header) pMACHeader)->wFrameCtl & TYPE_802_11_MASK) == TYPE_802_11_CTL)
+
+#define IS_FC_MOREDATA(pMACHeader)                                                      \
+    ((((PS802_11Header) pMACHeader)->wFrameCtl & FC_MOREDATA) == FC_MOREDATA)
+
+#define IS_FC_POWERMGT(pMACHeader)                                                      \
+    ((((PS802_11Header) pMACHeader)->wFrameCtl & FC_POWERMGT) == FC_POWERMGT)
+
+#define IS_FC_RETRY(pMACHeader)                                                         \
+    ((((PS802_11Header) pMACHeader)->wFrameCtl & FC_RETRY) == FC_RETRY)
+
+#define IS_FC_WEP(pMACHeader)                                                           \
+    ((((PS802_11Header) pMACHeader)->wFrameCtl & FC_WEP) == FC_WEP)
+
+#ifdef __BIG_ENDIAN
+
+#define IS_FRAGMENT_PKT(pMACHeader)                                                     \
+    (((((PS802_11Header) pMACHeader)->wFrameCtl & FC_MOREFRAG) != 0) |                  \
+     ((((PS802_11Header) pMACHeader)->wSeqCtl & 0x0F00) != 0))
+
+#define IS_FIRST_FRAGMENT_PKT(pMACHeader)                                               \
+    ((((PS802_11Header) pMACHeader)->wSeqCtl & 0x0F00) == 0)
+
+#else
+
+#define IS_FRAGMENT_PKT(pMACHeader)                                                     \
+    (((((PS802_11Header) pMACHeader)->wFrameCtl & FC_MOREFRAG) != 0) |                  \
+     ((((PS802_11Header) pMACHeader)->wSeqCtl & 0x000F) != 0))
+
+#define IS_FIRST_FRAGMENT_PKT(pMACHeader)                                               \
+    ((((PS802_11Header) pMACHeader)->wSeqCtl & 0x000F) == 0)
+
+#endif//#ifdef __BIG_ENDIAN
+
+#define IS_LAST_FRAGMENT_PKT(pMACHeader)                                                \
+    ((((PS802_11Header) pMACHeader)->wFrameCtl & FC_MOREFRAG) == 0)
+
+#define IS_CTL_PSPOLL(pMACHeader)                                                       \
+    ((((PS802_11Header) pMACHeader)->wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL)
+
+
+#define ADD_ONE_WITH_WRAP_AROUND(uVar, uModulo) {   \
+    if ((uVar) >= ((uModulo) - 1))                  \
+        (uVar) = 0;                                 \
+    else                                            \
+        (uVar)++;                                   \
+}
+
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+#ifdef __cplusplus
+extern "C" {                            /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+BOOL WCTLbIsDuplicate(PSCache pCache, PS802_11Header pMACHeader);
+BOOL WCTLbHandleFragment(PSDevice pDevice, PS802_11Header pMACHeader, UINT cbFrameLength, BOOL bWEP, BOOL bExtIV);
+UINT WCTLuSearchDFCB(PSDevice pDevice, PS802_11Header pMACHeader);
+UINT WCTLuInsertDFCB(PSDevice pDevice, PS802_11Header pMACHeader);
+
+#ifdef __cplusplus
+}                                       /* End of extern "C" { */
+#endif /* __cplusplus */
+
+
+
+
+#endif // __WCTL_H__
+
+
+
diff --git a/drivers/staging/vt6655/wmgr.c b/drivers/staging/vt6655/wmgr.c
new file mode 100644 (file)
index 0000000..c5f52e9
--- /dev/null
@@ -0,0 +1,5100 @@
+/*
+ * 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: wmgr.c
+ *
+ * Purpose: Handles the 802.11 management functions
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: May 8, 2002
+ *
+ * Functions:
+ *      nsMgrObjectInitial - Initialize Management Objet data structure
+ *      vMgrObjectReset - Reset Management Objet data structure
+ *      vMgrAssocBeginSta - Start associate function
+ *      vMgrReAssocBeginSta - Start reassociate function
+ *      vMgrDisassocBeginSta - Start disassociate function
+ *      s_vMgrRxAssocRequest - Handle Rcv associate_request
+ *      s_vMgrRxAssocResponse - Handle Rcv associate_response
+ *      vMrgAuthenBeginSta - Start authentication function
+ *      vMgrDeAuthenDeginSta - Start deauthentication function
+ *      s_vMgrRxAuthentication - Handle Rcv authentication
+ *      s_vMgrRxAuthenSequence_1 - Handle Rcv authentication sequence 1
+ *      s_vMgrRxAuthenSequence_2 - Handle Rcv authentication sequence 2
+ *      s_vMgrRxAuthenSequence_3 - Handle Rcv authentication sequence 3
+ *      s_vMgrRxAuthenSequence_4 - Handle Rcv authentication sequence 4
+ *      s_vMgrRxDisassociation - Handle Rcv disassociation
+ *      s_vMgrRxBeacon - Handle Rcv Beacon
+ *      vMgrCreateOwnIBSS - Create ad_hoc IBSS or AP BSS
+ *      vMgrJoinBSSBegin - Join BSS function
+ *      s_vMgrSynchBSS - Synch & adopt BSS parameters
+ *      s_MgrMakeBeacon - Create Baecon frame
+ *      s_MgrMakeProbeResponse - Create Probe Response frame
+ *      s_MgrMakeAssocRequest - Create Associate Request frame
+ *      s_MgrMakeReAssocRequest - Create ReAssociate Request frame
+ *      s_vMgrRxProbeResponse - Handle Rcv probe_response
+ *      s_vMrgRxProbeRequest - Handle Rcv probe_request
+ *      bMgrPrepareBeaconToSend - Prepare Beacon frame
+ *      s_vMgrLogStatus - Log 802.11 Status
+ *      vMgrRxManagePacket - Rcv management frame dispatch function
+ *      s_vMgrFormatTIM- Assember TIM field of beacon
+ *      vMgrTimerInit- Initial 1-sec and command call back funtions
+ *
+ * Revision History:
+ *
+ */
+
+
+#if !defined(__TMACRO_H__)
+#include "tmacro.h"
+#endif
+#if !defined(__TBIT_H__)
+#include "tbit.h"
+#endif
+#if !defined(__DESC_H__)
+#include "desc.h"
+#endif
+#if !defined(__DEVICE_H__)
+#include "device.h"
+#endif
+#if !defined(__CARD_H__)
+#include "card.h"
+#endif
+#if !defined(__80211HDR_H__)
+#include "80211hdr.h"
+#endif
+#if !defined(__80211MGR_H__)
+#include "80211mgr.h"
+#endif
+#if !defined(__WMGR_H__)
+#include "wmgr.h"
+#endif
+#if !defined(__WCMD_H__)
+#include "wcmd.h"
+#endif
+#if !defined(__MAC_H__)
+#include "mac.h"
+#endif
+#if !defined(__BSSDB_H__)
+#include "bssdb.h"
+#endif
+#if !defined(__POWER_H__)
+#include "power.h"
+#endif
+#if !defined(__DATARATE_H__)
+#include "datarate.h"
+#endif
+#if !defined(__BASEBAND_H__)
+#include "baseband.h"
+#endif
+#if !defined(__RXTX_H__)
+#include "rxtx.h"
+#endif
+#if !defined(__WPA_H__)
+#include "wpa.h"
+#endif
+#if !defined(__RF_H__)
+#include "rf.h"
+#endif
+#if !defined(__UMEM_H__)
+#include "umem.h"
+#endif
+#if !defined(__IOWPA_H__)
+#include "iowpa.h"
+#endif
+
+#define        PLICE_DEBUG
+
+/*---------------------  Static Definitions -------------------------*/
+
+
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+static int          msglevel                =MSG_LEVEL_INFO;
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+
+/*---------------------  Static Functions  --------------------------*/
+//2008-8-4 <add> by chester
+static BOOL ChannelExceedZoneType(
+    IN PSDevice pDevice,
+    IN BYTE byCurrChannel
+    );
+// Association/diassociation functions
+static
+PSTxMgmtPacket
+s_MgrMakeAssocRequest(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PBYTE pDAddr,
+    IN WORD wCurrCapInfo,
+    IN WORD wListenInterval,
+    IN PWLAN_IE_SSID pCurrSSID,
+    IN PWLAN_IE_SUPP_RATES pCurrRates,
+    IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates
+    );
+
+static
+VOID
+s_vMgrRxAssocRequest(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PSRxMgmtPacket pRxPacket,
+    IN UINT  uNodeIndex
+    );
+
+static
+PSTxMgmtPacket
+s_MgrMakeReAssocRequest(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PBYTE pDAddr,
+    IN WORD wCurrCapInfo,
+    IN WORD wListenInterval,
+    IN PWLAN_IE_SSID pCurrSSID,
+    IN PWLAN_IE_SUPP_RATES pCurrRates,
+    IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates
+    );
+
+static
+VOID
+s_vMgrRxAssocResponse(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PSRxMgmtPacket pRxPacket,
+    IN BOOL bReAssocType
+    );
+
+static
+VOID
+s_vMgrRxDisassociation(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PSRxMgmtPacket pRxPacket
+    );
+
+// Authentication/deauthen functions
+static
+VOID
+s_vMgrRxAuthenSequence_1(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PWLAN_FR_AUTHEN pFrame
+    );
+
+static
+VOID
+s_vMgrRxAuthenSequence_2(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PWLAN_FR_AUTHEN pFrame
+    );
+
+static
+VOID
+s_vMgrRxAuthenSequence_3(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PWLAN_FR_AUTHEN pFrame
+    );
+
+static
+VOID
+s_vMgrRxAuthenSequence_4(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PWLAN_FR_AUTHEN pFrame
+    );
+
+static
+VOID
+s_vMgrRxAuthentication(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PSRxMgmtPacket pRxPacket
+    );
+
+static
+VOID
+s_vMgrRxDeauthentication(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PSRxMgmtPacket pRxPacket
+    );
+
+// Scan functions
+// probe request/response functions
+static
+VOID
+s_vMgrRxProbeRequest(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PSRxMgmtPacket pRxPacket
+    );
+
+static
+VOID
+s_vMgrRxProbeResponse(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PSRxMgmtPacket pRxPacket
+    );
+
+// beacon functions
+static
+VOID
+s_vMgrRxBeacon(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PSRxMgmtPacket pRxPacket,
+    IN BOOL bInScan
+    );
+
+static
+VOID
+s_vMgrFormatTIM(
+    IN PSMgmtObject pMgmt,
+    IN PWLAN_IE_TIM pTIM
+    );
+
+static
+PSTxMgmtPacket
+s_MgrMakeBeacon(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN WORD wCurrCapInfo,
+    IN WORD wCurrBeaconPeriod,
+    IN UINT uCurrChannel,
+    IN WORD wCurrATIMWinodw,
+    IN PWLAN_IE_SSID pCurrSSID,
+    IN PBYTE pCurrBSSID,
+    IN PWLAN_IE_SUPP_RATES pCurrSuppRates,
+    IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates
+    );
+
+
+// Association response
+static
+PSTxMgmtPacket
+s_MgrMakeAssocResponse(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN WORD wCurrCapInfo,
+    IN WORD wAssocStatus,
+    IN WORD wAssocAID,
+    IN PBYTE pDstAddr,
+    IN PWLAN_IE_SUPP_RATES pCurrSuppRates,
+    IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates
+    );
+
+// ReAssociation response
+static
+PSTxMgmtPacket
+s_MgrMakeReAssocResponse(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN WORD wCurrCapInfo,
+    IN WORD wAssocStatus,
+    IN WORD wAssocAID,
+    IN PBYTE pDstAddr,
+    IN PWLAN_IE_SUPP_RATES pCurrSuppRates,
+    IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates
+    );
+
+// Probe response
+static
+PSTxMgmtPacket
+s_MgrMakeProbeResponse(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN WORD wCurrCapInfo,
+    IN WORD wCurrBeaconPeriod,
+    IN UINT uCurrChannel,
+    IN WORD wCurrATIMWinodw,
+    IN PBYTE pDstAddr,
+    IN PWLAN_IE_SSID pCurrSSID,
+    IN PBYTE pCurrBSSID,
+    IN PWLAN_IE_SUPP_RATES pCurrSuppRates,
+    IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates,
+    IN BYTE byPHYType
+    );
+
+// received status
+static
+VOID
+s_vMgrLogStatus(
+    IN PSMgmtObject pMgmt,
+    IN WORD wStatus
+    );
+
+
+static
+VOID
+s_vMgrSynchBSS (
+    IN PSDevice      pDevice,
+    IN UINT          uBSSMode,
+    IN PKnownBSS     pCurr,
+    OUT PCMD_STATUS  pStatus
+    );
+
+
+static BOOL
+s_bCipherMatch (
+    IN PKnownBSS                        pBSSNode,
+    IN NDIS_802_11_ENCRYPTION_STATUS    EncStatus,
+    OUT PBYTE                           pbyCCSPK,
+    OUT PBYTE                           pbyCCSGK
+    );
+
+
+ static VOID  Encyption_Rebuild(
+    IN PSDevice pDevice,
+    IN PKnownBSS pCurr
+ );
+/*
+static
+VOID
+s_vProbeChannel(
+    IN PSDevice pDevice
+    );
+
+static
+VOID
+s_vListenChannel(
+    IN PSDevice pDevice
+    );
+
+static
+PSTxMgmtPacket
+s_MgrMakeProbeRequest(
+    IN PSMgmtObject pMgmt,
+    IN PBYTE pScanBSSID,
+    IN PWLAN_IE_SSID pSSID,
+    IN PWLAN_IE_SUPP_RATES pCurrRates
+    );
+*/
+
+
+
+/*---------------------  Export Variables  --------------------------*/
+
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+/*+
+ *
+ * Routine Description:
+ *    Allocates and initializes the Management object.
+ *
+ * Return Value:
+ *    Ndis_staus.
+ *
+-*/
+
+VOID
+vMgrObjectInit(
+    IN  HANDLE hDeviceContext
+    )
+{
+    PSDevice     pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject    pMgmt = pDevice->pMgmt;
+    int ii;
+
+
+    pMgmt->pbyPSPacketPool = &pMgmt->byPSPacketPool[0];
+    pMgmt->pbyMgmtPacketPool = &pMgmt->byMgmtPacketPool[0];
+    pMgmt->uCurrChannel = pDevice->uChannel;
+    for(ii=0;ii<WLAN_BSSID_LEN;ii++) {
+        pMgmt->abyDesireBSSID[ii] = 0xFF;
+    }
+    pMgmt->sAssocInfo.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
+    //memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN +1);
+    pMgmt->byCSSPK = KEY_CTL_NONE;
+    pMgmt->byCSSGK = KEY_CTL_NONE;
+    pMgmt->wIBSSBeaconPeriod = DEFAULT_IBSS_BI;
+    BSSvClearBSSList((HANDLE)pDevice, FALSE);
+
+    return;
+}
+
+/*+
+ *
+ * Routine Description:
+ *    Initializes timer object
+ *
+ * Return Value:
+ *    Ndis_staus.
+ *
+-*/
+
+void
+vMgrTimerInit(
+    IN  HANDLE hDeviceContext
+    )
+{
+    PSDevice     pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject    pMgmt = pDevice->pMgmt;
+
+
+    init_timer(&pMgmt->sTimerSecondCallback);
+    pMgmt->sTimerSecondCallback.data = (ULONG)pDevice;
+    pMgmt->sTimerSecondCallback.function = (TimerFunction)BSSvSecondCallBack;
+    pMgmt->sTimerSecondCallback.expires = RUN_AT(HZ);
+
+    init_timer(&pDevice->sTimerCommand);
+    pDevice->sTimerCommand.data = (ULONG)pDevice;
+    pDevice->sTimerCommand.function = (TimerFunction)vCommandTimer;
+    pDevice->sTimerCommand.expires = RUN_AT(HZ);
+
+   #ifdef TxInSleep
+    init_timer(&pDevice->sTimerTxData);
+    pDevice->sTimerTxData.data = (ULONG)pDevice;
+    pDevice->sTimerTxData.function = (TimerFunction)BSSvSecondTxData;
+    pDevice->sTimerTxData.expires = RUN_AT(10*HZ);      //10s callback
+    pDevice->fTxDataInSleep = FALSE;
+    pDevice->IsTxDataTrigger = FALSE;
+    pDevice->nTxDataTimeCout = 0;
+   #endif
+
+    pDevice->cbFreeCmdQueue = CMD_Q_SIZE;
+    pDevice->uCmdDequeueIdx = 0;
+    pDevice->uCmdEnqueueIdx = 0;
+
+    return;
+}
+
+
+
+/*+
+ *
+ * Routine Description:
+ *    Reset the management object  structure.
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+VOID
+vMgrObjectReset(
+    IN  HANDLE hDeviceContext
+    )
+{
+    PSDevice         pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject        pMgmt = pDevice->pMgmt;
+
+    pMgmt->eCurrMode = WMAC_MODE_STANDBY;
+    pMgmt->eCurrState = WMAC_STATE_IDLE;
+    pDevice->bEnablePSMode = FALSE;
+    // TODO: timer
+
+    return;
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *    Start the station association procedure.  Namely, send an
+ *    association request frame to the AP.
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+
+VOID
+vMgrAssocBeginSta(
+    IN  HANDLE hDeviceContext,
+    IN  PSMgmtObject pMgmt,
+    OUT PCMD_STATUS pStatus
+    )
+{
+    PSDevice             pDevice = (PSDevice)hDeviceContext;
+    PSTxMgmtPacket          pTxPacket;
+
+
+    pMgmt->wCurrCapInfo = 0;
+    pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_ESS(1);
+    if (pDevice->bEncryptionEnable) {
+        pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1);
+    }
+    // always allow receive short preamble
+    //if (pDevice->byPreambleType == 1) {
+    //    pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
+    //}
+    pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
+    if (pMgmt->wListenInterval == 0)
+        pMgmt->wListenInterval = 1;    // at least one.
+
+    // ERP Phy (802.11g) should support short preamble.
+    if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) {
+        pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
+        if (CARDbIsShorSlotTime(pMgmt->pAdapter) == TRUE) {
+            pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTSLOTTIME(1);
+        }
+    } else if (pMgmt->eCurrentPHYMode == PHY_TYPE_11B) {
+        if (CARDbIsShortPreamble(pMgmt->pAdapter) == TRUE) {
+            pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
+        }
+    }
+    if (pMgmt->b11hEnable == TRUE)
+        pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SPECTRUMMNG(1);
+
+    /* build an assocreq frame and send it */
+    pTxPacket = s_MgrMakeAssocRequest
+                (
+                  pDevice,
+                  pMgmt,
+                  pMgmt->abyCurrBSSID,
+                  pMgmt->wCurrCapInfo,
+                  pMgmt->wListenInterval,
+                  (PWLAN_IE_SSID)pMgmt->abyCurrSSID,
+                  (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
+                  (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates
+                );
+
+    if (pTxPacket != NULL ){
+        /* send the frame */
+        *pStatus = csMgmt_xmit(pDevice, pTxPacket);
+        if (*pStatus == CMD_STATUS_PENDING) {
+            pMgmt->eCurrState = WMAC_STATE_ASSOCPENDING;
+            *pStatus = CMD_STATUS_SUCCESS;
+        }
+    }
+    else
+        *pStatus = CMD_STATUS_RESOURCES;
+
+    return ;
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *    Start the station re-association procedure.
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+VOID
+vMgrReAssocBeginSta(
+    IN  HANDLE hDeviceContext,
+    IN  PSMgmtObject pMgmt,
+    OUT PCMD_STATUS pStatus
+    )
+{
+    PSDevice             pDevice = (PSDevice)hDeviceContext;
+    PSTxMgmtPacket          pTxPacket;
+
+
+
+    pMgmt->wCurrCapInfo = 0;
+    pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_ESS(1);
+    if (pDevice->bEncryptionEnable) {
+        pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1);
+    }
+
+    //if (pDevice->byPreambleType == 1) {
+    //    pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
+    //}
+    pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
+
+    if (pMgmt->wListenInterval == 0)
+        pMgmt->wListenInterval = 1;    // at least one.
+
+
+    // ERP Phy (802.11g) should support short preamble.
+    if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) {
+        pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
+        if (CARDbIsShorSlotTime(pMgmt->pAdapter) == TRUE) {
+            pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTSLOTTIME(1);
+        }
+    } else if (pMgmt->eCurrentPHYMode == PHY_TYPE_11B) {
+        if (CARDbIsShortPreamble(pMgmt->pAdapter) == TRUE) {
+            pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
+        }
+    }
+    if (pMgmt->b11hEnable == TRUE)
+        pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SPECTRUMMNG(1);
+
+
+    pTxPacket = s_MgrMakeReAssocRequest
+                (
+                  pDevice,
+                  pMgmt,
+                  pMgmt->abyCurrBSSID,
+                  pMgmt->wCurrCapInfo,
+                  pMgmt->wListenInterval,
+                  (PWLAN_IE_SSID)pMgmt->abyCurrSSID,
+                  (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
+                  (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates
+                );
+
+    if (pTxPacket != NULL ){
+        /* send the frame */
+        *pStatus = csMgmt_xmit(pDevice, pTxPacket);
+        if (*pStatus != CMD_STATUS_PENDING) {
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Reassociation tx failed.\n");
+        }
+        else {
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Reassociation tx sending.\n");
+        }
+    }
+
+
+    return ;
+}
+
+/*+
+ *
+ * Routine Description:
+ *    Send an dis-association request frame to the AP.
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+VOID
+vMgrDisassocBeginSta(
+    IN  HANDLE hDeviceContext,
+    IN  PSMgmtObject pMgmt,
+    IN  PBYTE  abyDestAddress,
+    IN  WORD    wReason,
+    OUT PCMD_STATUS pStatus
+    )
+{
+    PSDevice            pDevice = (PSDevice)hDeviceContext;
+    PSTxMgmtPacket      pTxPacket = NULL;
+    WLAN_FR_DISASSOC    sFrame;
+
+    pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
+    memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_DISASSOC_FR_MAXLEN);
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+
+    // Setup the sFrame structure
+    sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
+    sFrame.len = WLAN_DISASSOC_FR_MAXLEN;
+
+    // format fixed field frame structure
+    vMgrEncodeDisassociation(&sFrame);
+
+    // Setup the header
+    sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
+        (
+        WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
+        WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_DISASSOC)
+        ));
+
+    memcpy( sFrame.pHdr->sA3.abyAddr1, abyDestAddress, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
+
+    // Set reason code
+    *(sFrame.pwReason) = cpu_to_le16(wReason);
+    pTxPacket->cbMPDULen = sFrame.len;
+    pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
+
+    // send the frame
+    *pStatus = csMgmt_xmit(pDevice, pTxPacket);
+    if (*pStatus == CMD_STATUS_PENDING) {
+        pMgmt->eCurrState = WMAC_STATE_IDLE;
+        *pStatus = CMD_STATUS_SUCCESS;
+    };
+
+    return;
+}
+
+
+
+/*+
+ *
+ * Routine Description:(AP function)
+ *    Handle incoming station association request frames.
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+static
+VOID
+s_vMgrRxAssocRequest(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PSRxMgmtPacket pRxPacket,
+    IN UINT uNodeIndex
+    )
+{
+    WLAN_FR_ASSOCREQ    sFrame;
+    CMD_STATUS          Status;
+    PSTxMgmtPacket      pTxPacket;
+    WORD                wAssocStatus = 0;
+    WORD                wAssocAID = 0;
+    UINT                uRateLen = WLAN_RATES_MAXLEN;
+    BYTE                abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
+    BYTE                abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
+
+
+    if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP)
+        return;
+    //  node index not found
+    if (!uNodeIndex)
+        return;
+
+    //check if node is authenticated
+    //decode the frame
+    memset(&sFrame, 0, sizeof(WLAN_FR_ASSOCREQ));
+    memset(abyCurrSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1);
+    memset(abyCurrExtSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1);
+    sFrame.len = pRxPacket->cbMPDULen;
+    sFrame.pBuf = (PBYTE)pRxPacket->p80211Header;
+
+    vMgrDecodeAssocRequest(&sFrame);
+
+    if (pMgmt->sNodeDBTable[uNodeIndex].eNodeState >= NODE_AUTH) {
+        pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_ASSOC;
+        pMgmt->sNodeDBTable[uNodeIndex].wCapInfo = cpu_to_le16(*sFrame.pwCapInfo);
+        pMgmt->sNodeDBTable[uNodeIndex].wListenInterval = cpu_to_le16(*sFrame.pwListenInterval);
+        pMgmt->sNodeDBTable[uNodeIndex].bPSEnable =
+                WLAN_GET_FC_PWRMGT(sFrame.pHdr->sA3.wFrameCtl) ? TRUE : FALSE;
+        // Todo: check sta basic rate, if ap can't support, set status code
+        if (pDevice->eCurrentPHYType == PHY_TYPE_11B) {
+            uRateLen = WLAN_RATES_MAXLEN_11B;
+        }
+        abyCurrSuppRates[0] = WLAN_EID_SUPP_RATES;
+        abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates,
+                                         (PWLAN_IE_SUPP_RATES)abyCurrSuppRates,
+                                         uRateLen);
+        abyCurrExtSuppRates[0] = WLAN_EID_EXTSUPP_RATES;
+        if (pDevice->eCurrentPHYType == PHY_TYPE_11G) {
+            abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pExtSuppRates,
+                                                (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates,
+                                                uRateLen);
+        } else {
+            abyCurrExtSuppRates[1] = 0;
+        }
+
+
+        RATEvParseMaxRate((PVOID)pDevice,
+                           (PWLAN_IE_SUPP_RATES)abyCurrSuppRates,
+                           (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates,
+                           FALSE, // do not change our basic rate
+                           &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate),
+                           &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate),
+                           &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate),
+                           &(pMgmt->sNodeDBTable[uNodeIndex].byTopCCKBasicRate),
+                           &(pMgmt->sNodeDBTable[uNodeIndex].byTopOFDMBasicRate)
+                          );
+
+        // set max tx rate
+        pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate =
+                pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate;
+#ifdef PLICE_DEBUG
+       printk("RxAssocRequest:wTxDataRate is %d\n",pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate);
+#endif
+               // Todo: check sta preamble, if ap can't support, set status code
+        pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble =
+                WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo);
+        pMgmt->sNodeDBTable[uNodeIndex].bShortSlotTime =
+                WLAN_GET_CAP_INFO_SHORTSLOTTIME(*sFrame.pwCapInfo);
+        pMgmt->sNodeDBTable[uNodeIndex].wAID = (WORD)uNodeIndex;
+        wAssocStatus = WLAN_MGMT_STATUS_SUCCESS;
+        wAssocAID = (WORD)uNodeIndex;
+        // check if ERP support
+        if(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate > RATE_11M)
+           pMgmt->sNodeDBTable[uNodeIndex].bERPExist = TRUE;
+
+        if (pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate <= RATE_11M) {
+            // B only STA join
+            pDevice->bProtectMode = TRUE;
+            pDevice->bNonERPPresent = TRUE;
+        }
+        if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble == FALSE) {
+            pDevice->bBarkerPreambleMd = TRUE;
+        }
+
+        DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO "Associate AID= %d \n", wAssocAID);
+        DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO "MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X \n",
+                   sFrame.pHdr->sA3.abyAddr2[0],
+                   sFrame.pHdr->sA3.abyAddr2[1],
+                   sFrame.pHdr->sA3.abyAddr2[2],
+                   sFrame.pHdr->sA3.abyAddr2[3],
+                   sFrame.pHdr->sA3.abyAddr2[4],
+                   sFrame.pHdr->sA3.abyAddr2[5]
+                  ) ;
+        DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO "Max Support rate = %d \n",
+                   pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate);
+    }//else { TODO: received STA under state1 handle }
+    else {
+        return;
+    }
+
+
+    // assoc response reply..
+    pTxPacket = s_MgrMakeAssocResponse
+                (
+                  pDevice,
+                  pMgmt,
+                  pMgmt->wCurrCapInfo,
+                  wAssocStatus,
+                  wAssocAID,
+                  sFrame.pHdr->sA3.abyAddr2,
+                  (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
+                  (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates
+                );
+    if (pTxPacket != NULL ){
+
+        if (pDevice->bEnableHostapd) {
+            return;
+        }
+        /* send the frame */
+        Status = csMgmt_xmit(pDevice, pTxPacket);
+        if (Status != CMD_STATUS_PENDING) {
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Assoc response tx failed\n");
+        }
+        else {
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Assoc response tx sending..\n");
+        }
+
+    }
+
+    return;
+}
+
+
+/*+
+ *
+ * Description:(AP function)
+ *      Handle incoming station re-association request frames.
+ *
+ * Parameters:
+ *  In:
+ *      pMgmt           - Management Object structure
+ *      pRxPacket       - Received Packet
+ *  Out:
+ *      none
+ *
+ * Return Value: None.
+ *
+-*/
+
+static
+VOID
+s_vMgrRxReAssocRequest(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PSRxMgmtPacket pRxPacket,
+    IN UINT uNodeIndex
+    )
+{
+    WLAN_FR_REASSOCREQ    sFrame;
+    CMD_STATUS          Status;
+    PSTxMgmtPacket      pTxPacket;
+    WORD                wAssocStatus = 0;
+    WORD                wAssocAID = 0;
+    UINT                uRateLen = WLAN_RATES_MAXLEN;
+    BYTE                abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
+    BYTE                abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
+
+    if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP)
+        return;
+    //  node index not found
+    if (!uNodeIndex)
+        return;
+    //check if node is authenticated
+    //decode the frame
+    memset(&sFrame, 0, sizeof(WLAN_FR_REASSOCREQ));
+    sFrame.len = pRxPacket->cbMPDULen;
+    sFrame.pBuf = (PBYTE)pRxPacket->p80211Header;
+    vMgrDecodeReassocRequest(&sFrame);
+
+    if (pMgmt->sNodeDBTable[uNodeIndex].eNodeState >= NODE_AUTH) {
+        pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_ASSOC;
+        pMgmt->sNodeDBTable[uNodeIndex].wCapInfo = cpu_to_le16(*sFrame.pwCapInfo);
+        pMgmt->sNodeDBTable[uNodeIndex].wListenInterval = cpu_to_le16(*sFrame.pwListenInterval);
+        pMgmt->sNodeDBTable[uNodeIndex].bPSEnable =
+                WLAN_GET_FC_PWRMGT(sFrame.pHdr->sA3.wFrameCtl) ? TRUE : FALSE;
+        // Todo: check sta basic rate, if ap can't support, set status code
+
+        if (pDevice->eCurrentPHYType == PHY_TYPE_11B) {
+            uRateLen = WLAN_RATES_MAXLEN_11B;
+        }
+
+        abyCurrSuppRates[0] = WLAN_EID_SUPP_RATES;
+        abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates,
+                                         (PWLAN_IE_SUPP_RATES)abyCurrSuppRates,
+                                         uRateLen);
+        abyCurrExtSuppRates[0] = WLAN_EID_EXTSUPP_RATES;
+        if (pDevice->eCurrentPHYType == PHY_TYPE_11G) {
+            abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pExtSuppRates,
+                                                (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates,
+                                                uRateLen);
+        } else {
+            abyCurrExtSuppRates[1] = 0;
+        }
+
+
+        RATEvParseMaxRate((PVOID)pDevice,
+                          (PWLAN_IE_SUPP_RATES)abyCurrSuppRates,
+                          (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates,
+                           FALSE, // do not change our basic rate
+                           &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate),
+                           &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate),
+                           &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate),
+                           &(pMgmt->sNodeDBTable[uNodeIndex].byTopCCKBasicRate),
+                           &(pMgmt->sNodeDBTable[uNodeIndex].byTopOFDMBasicRate)
+                          );
+
+        // set max tx rate
+        pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate =
+                pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate;
+#ifdef PLICE_DEBUG
+       printk("RxReAssocRequest:TxDataRate is %d\n",pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate);
+#endif
+               // Todo: check sta preamble, if ap can't support, set status code
+        pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble =
+                WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo);
+        pMgmt->sNodeDBTable[uNodeIndex].bShortSlotTime =
+                WLAN_GET_CAP_INFO_SHORTSLOTTIME(*sFrame.pwCapInfo);
+        pMgmt->sNodeDBTable[uNodeIndex].wAID = (WORD)uNodeIndex;
+        wAssocStatus = WLAN_MGMT_STATUS_SUCCESS;
+        wAssocAID = (WORD)uNodeIndex;
+
+        // if suppurt ERP
+        if(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate > RATE_11M)
+           pMgmt->sNodeDBTable[uNodeIndex].bERPExist = TRUE;
+
+        if (pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate <= RATE_11M) {
+            // B only STA join
+            pDevice->bProtectMode = TRUE;
+            pDevice->bNonERPPresent = TRUE;
+        }
+        if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble == FALSE) {
+            pDevice->bBarkerPreambleMd = TRUE;
+        }
+
+        DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO "Rx ReAssociate AID= %d \n", wAssocAID);
+        DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO "MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X \n",
+                   sFrame.pHdr->sA3.abyAddr2[0],
+                   sFrame.pHdr->sA3.abyAddr2[1],
+                   sFrame.pHdr->sA3.abyAddr2[2],
+                   sFrame.pHdr->sA3.abyAddr2[3],
+                   sFrame.pHdr->sA3.abyAddr2[4],
+                   sFrame.pHdr->sA3.abyAddr2[5]
+                  ) ;
+        DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO "Max Support rate = %d \n",
+                   pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate);
+
+    }
+
+
+    // assoc response reply..
+    pTxPacket = s_MgrMakeReAssocResponse
+                (
+                  pDevice,
+                  pMgmt,
+                  pMgmt->wCurrCapInfo,
+                  wAssocStatus,
+                  wAssocAID,
+                  sFrame.pHdr->sA3.abyAddr2,
+                  (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
+                  (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates
+                );
+
+    if (pTxPacket != NULL ){
+        /* send the frame */
+        if (pDevice->bEnableHostapd) {
+            return;
+        }
+        Status = csMgmt_xmit(pDevice, pTxPacket);
+        if (Status != CMD_STATUS_PENDING) {
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:ReAssoc response tx failed\n");
+        }
+        else {
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:ReAssoc response tx sending..\n");
+        }
+    }
+    return;
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *    Handle incoming association response frames.
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+static
+VOID
+s_vMgrRxAssocResponse(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PSRxMgmtPacket pRxPacket,
+    IN BOOL bReAssocType
+    )
+{
+    WLAN_FR_ASSOCRESP   sFrame;
+    PWLAN_IE_SSID   pItemSSID;
+    PBYTE   pbyIEs;
+    viawget_wpa_header *wpahdr;
+
+
+
+    if (pMgmt->eCurrState == WMAC_STATE_ASSOCPENDING ||
+         pMgmt->eCurrState == WMAC_STATE_ASSOC) {
+
+        sFrame.len = pRxPacket->cbMPDULen;
+        sFrame.pBuf = (PBYTE)pRxPacket->p80211Header;
+        // decode the frame
+        vMgrDecodeAssocResponse(&sFrame);
+        if ((sFrame.pwCapInfo == 0) ||
+            (sFrame.pwStatus == 0) ||
+            (sFrame.pwAid == 0) ||
+            (sFrame.pSuppRates == 0)){
+            DBG_PORT80(0xCC);
+            return;
+        };
+
+        pMgmt->sAssocInfo.AssocInfo.ResponseFixedIEs.Capabilities = *(sFrame.pwCapInfo);
+        pMgmt->sAssocInfo.AssocInfo.ResponseFixedIEs.StatusCode = *(sFrame.pwStatus);
+        pMgmt->sAssocInfo.AssocInfo.ResponseFixedIEs.AssociationId = *(sFrame.pwAid);
+        pMgmt->sAssocInfo.AssocInfo.AvailableResponseFixedIEs |= 0x07;
+
+        pMgmt->sAssocInfo.AssocInfo.ResponseIELength = sFrame.len - 24 - 6;
+        pMgmt->sAssocInfo.AssocInfo.OffsetResponseIEs = pMgmt->sAssocInfo.AssocInfo.OffsetRequestIEs + pMgmt->sAssocInfo.AssocInfo.RequestIELength;
+        pbyIEs = pMgmt->sAssocInfo.abyIEs;
+        pbyIEs += pMgmt->sAssocInfo.AssocInfo.RequestIELength;
+        memcpy(pbyIEs, (sFrame.pBuf + 24 +6), pMgmt->sAssocInfo.AssocInfo.ResponseIELength);
+
+        // save values and set current BSS state
+        if (cpu_to_le16((*(sFrame.pwStatus))) == WLAN_MGMT_STATUS_SUCCESS ){
+            // set AID
+            pMgmt->wCurrAID = cpu_to_le16((*(sFrame.pwAid)));
+            if ( (pMgmt->wCurrAID >> 14) != (BIT0 | BIT1) )
+            {
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "AID from AP, has two msb clear.\n");
+            };
+            DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO "Association Successful, AID=%d.\n", pMgmt->wCurrAID & ~(BIT14|BIT15));
+            pMgmt->eCurrState = WMAC_STATE_ASSOC;
+            BSSvUpdateAPNode((HANDLE)pDevice, sFrame.pwCapInfo, sFrame.pSuppRates, sFrame.pExtSuppRates);
+            pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
+            DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO "Link with AP(SSID): %s\n", pItemSSID->abySSID);
+            pDevice->bLinkPass = TRUE;
+            pDevice->uBBVGADiffCount = 0;
+            if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) {
+         if(skb_tailroom(pDevice->skb) <(sizeof(viawget_wpa_header)+pMgmt->sAssocInfo.AssocInfo.ResponseIELength+
+                                                                        pMgmt->sAssocInfo.AssocInfo.RequestIELength)) {    //data room not enough
+                     dev_kfree_skb(pDevice->skb);
+                  pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
+               }
+                wpahdr = (viawget_wpa_header *)pDevice->skb->data;
+                wpahdr->type = VIAWGET_ASSOC_MSG;
+                wpahdr->resp_ie_len = pMgmt->sAssocInfo.AssocInfo.ResponseIELength;
+                wpahdr->req_ie_len = pMgmt->sAssocInfo.AssocInfo.RequestIELength;
+                memcpy(pDevice->skb->data + sizeof(viawget_wpa_header), pMgmt->sAssocInfo.abyIEs, wpahdr->req_ie_len);
+                memcpy(pDevice->skb->data + sizeof(viawget_wpa_header) + wpahdr->req_ie_len,
+                       pbyIEs,
+                       wpahdr->resp_ie_len
+                       );
+                skb_put(pDevice->skb, sizeof(viawget_wpa_header) + wpahdr->resp_ie_len + wpahdr->req_ie_len);
+                pDevice->skb->dev = pDevice->wpadev;
+#if    LINUX_VERSION_CODE      > KERNEL_VERSION(2,6,21)
+               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);
+            }
+
+//2008-0409-07, <Add> by Einsn Liu
+#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+       //if(pDevice->bWPADevEnable == TRUE)
+               {
+               BYTE buf[512];
+               size_t len;
+               union iwreq_data  wrqu;
+               int we_event;
+
+               memset(buf, 0, 512);
+
+               len = pMgmt->sAssocInfo.AssocInfo.RequestIELength;
+               if(len) {
+                       memcpy(buf, pMgmt->sAssocInfo.abyIEs, len);
+                       memset(&wrqu, 0, sizeof (wrqu));
+                       wrqu.data.length = len;
+                       we_event = IWEVASSOCREQIE;
+                       wireless_send_event(pDevice->dev, we_event, &wrqu, buf);
+               }
+
+               memset(buf, 0, 512);
+               len = pMgmt->sAssocInfo.AssocInfo.ResponseIELength;
+
+               if(len) {
+                       memcpy(buf, pbyIEs, len);
+                       memset(&wrqu, 0, sizeof (wrqu));
+                       wrqu.data.length = len;
+                       we_event = IWEVASSOCRESPIE;
+                       wireless_send_event(pDevice->dev, we_event, &wrqu, buf);
+               }
+
+
+  memset(&wrqu, 0, sizeof (wrqu));
+       memcpy(wrqu.ap_addr.sa_data, &pMgmt->abyCurrBSSID[0], ETH_ALEN);
+        wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+       wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
+       }
+#endif //#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+//End Add -- //2008-0409-07, <Add> by Einsn Liu
+               }
+        else {
+            if (bReAssocType) {
+                pMgmt->eCurrState = WMAC_STATE_IDLE;
+            }
+            else {
+                // jump back to the auth state and indicate the error
+                pMgmt->eCurrState = WMAC_STATE_AUTH;
+            }
+            s_vMgrLogStatus(pMgmt,cpu_to_le16((*(sFrame.pwStatus))));
+        }
+
+    }
+
+#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+//need clear flags related to Networkmanager
+
+              pDevice->bwextcount = 0;
+              pDevice->bWPASuppWextEnabled = FALSE;
+#endif
+
+
+if(pMgmt->eCurrState == WMAC_STATE_ASSOC)
+      timer_expire(pDevice->sTimerCommand, 0);
+    return;
+}
+
+
+
+/*+
+ *
+ * Routine Description:
+ *    Start the station authentication procedure.  Namely, send an
+ *    authentication frame to the AP.
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+VOID
+vMgrAuthenBeginSta(
+    IN  HANDLE hDeviceContext,
+    IN  PSMgmtObject  pMgmt,
+    OUT PCMD_STATUS pStatus
+    )
+{
+    PSDevice     pDevice = (PSDevice)hDeviceContext;
+    WLAN_FR_AUTHEN  sFrame;
+    PSTxMgmtPacket  pTxPacket = NULL;
+
+    pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
+    memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_AUTHEN_FR_MAXLEN);
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+    sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
+    sFrame.len = WLAN_AUTHEN_FR_MAXLEN;
+    vMgrEncodeAuthen(&sFrame);
+    /* insert values */
+    sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
+        (
+        WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
+        WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_AUTHEN)
+        ));
+    memcpy( sFrame.pHdr->sA3.abyAddr1, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
+    if (pMgmt->bShareKeyAlgorithm)
+        *(sFrame.pwAuthAlgorithm) = cpu_to_le16(WLAN_AUTH_ALG_SHAREDKEY);
+    else
+        *(sFrame.pwAuthAlgorithm) = cpu_to_le16(WLAN_AUTH_ALG_OPENSYSTEM);
+
+    *(sFrame.pwAuthSequence) = cpu_to_le16(1);
+    /* Adjust the length fields */
+    pTxPacket->cbMPDULen = sFrame.len;
+    pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
+
+    *pStatus = csMgmt_xmit(pDevice, pTxPacket);
+    if (*pStatus == CMD_STATUS_PENDING){
+        pMgmt->eCurrState = WMAC_STATE_AUTHPENDING;
+        *pStatus = CMD_STATUS_SUCCESS;
+    }
+
+    return ;
+}
+
+
+
+/*+
+ *
+ * Routine Description:
+ *    Start the station(AP) deauthentication procedure.  Namely, send an
+ *    deauthentication frame to the AP or Sta.
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+VOID
+vMgrDeAuthenBeginSta(
+    IN  HANDLE hDeviceContext,
+    IN  PSMgmtObject  pMgmt,
+    IN  PBYTE  abyDestAddress,
+    IN  WORD    wReason,
+    OUT PCMD_STATUS pStatus
+    )
+{
+    PSDevice            pDevice = (PSDevice)hDeviceContext;
+    WLAN_FR_DEAUTHEN    sFrame;
+    PSTxMgmtPacket      pTxPacket = NULL;
+
+
+    pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
+    memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_DEAUTHEN_FR_MAXLEN);
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+    sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
+    sFrame.len = WLAN_DEAUTHEN_FR_MAXLEN;
+    vMgrEncodeDeauthen(&sFrame);
+    /* insert values */
+    sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
+        (
+        WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
+        WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_DEAUTHEN)
+        ));
+
+    memcpy( sFrame.pHdr->sA3.abyAddr1, abyDestAddress, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
+
+    *(sFrame.pwReason) = cpu_to_le16(wReason);       // deauthen. bcs left BSS
+    /* Adjust the length fields */
+    pTxPacket->cbMPDULen = sFrame.len;
+    pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
+
+    *pStatus = csMgmt_xmit(pDevice, pTxPacket);
+    if (*pStatus == CMD_STATUS_PENDING){
+        *pStatus = CMD_STATUS_SUCCESS;
+    }
+
+
+    return ;
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *    Handle incoming authentication frames.
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+static
+VOID
+s_vMgrRxAuthentication(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PSRxMgmtPacket pRxPacket
+    )
+{
+    WLAN_FR_AUTHEN  sFrame;
+
+    // we better be an AP or a STA in AUTHPENDING otherwise ignore
+    if (!(pMgmt->eCurrMode == WMAC_MODE_ESS_AP ||
+          pMgmt->eCurrState == WMAC_STATE_AUTHPENDING)) {
+        return;
+    }
+
+    // decode the frame
+    sFrame.len = pRxPacket->cbMPDULen;
+    sFrame.pBuf = (PBYTE)pRxPacket->p80211Header;
+    vMgrDecodeAuthen(&sFrame);
+    switch (cpu_to_le16((*(sFrame.pwAuthSequence )))){
+        case 1:
+            //AP funciton
+            s_vMgrRxAuthenSequence_1(pDevice,pMgmt, &sFrame);
+            break;
+        case 2:
+            s_vMgrRxAuthenSequence_2(pDevice, pMgmt, &sFrame);
+            break;
+        case 3:
+            //AP funciton
+            s_vMgrRxAuthenSequence_3(pDevice, pMgmt, &sFrame);
+            break;
+        case 4:
+            s_vMgrRxAuthenSequence_4(pDevice, pMgmt, &sFrame);
+            break;
+        default:
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Auth Sequence error, seq = %d\n",
+                        cpu_to_le16((*(sFrame.pwAuthSequence))));
+            break;
+    }
+    return;
+}
+
+
+
+/*+
+ *
+ * Routine Description:
+ *   Handles incoming authen frames with sequence 1.  Currently
+ *   assumes we're an AP.  So far, no one appears to use authentication
+ *   in Ad-Hoc mode.
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+
+static
+VOID
+s_vMgrRxAuthenSequence_1(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PWLAN_FR_AUTHEN pFrame
+     )
+{
+    PSTxMgmtPacket      pTxPacket = NULL;
+    UINT                uNodeIndex;
+    WLAN_FR_AUTHEN      sFrame;
+    PSKeyItem           pTransmitKey;
+
+    // Insert a Node entry
+    if (!BSSDBbIsSTAInNodeDB(pMgmt, pFrame->pHdr->sA3.abyAddr2, &uNodeIndex)) {
+        BSSvCreateOneNode((PSDevice)pDevice, &uNodeIndex);
+        memcpy(pMgmt->sNodeDBTable[uNodeIndex].abyMACAddr, pFrame->pHdr->sA3.abyAddr2,
+               WLAN_ADDR_LEN);
+    }
+
+    if (pMgmt->bShareKeyAlgorithm) {
+        pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_KNOWN;
+        pMgmt->sNodeDBTable[uNodeIndex].byAuthSequence = 1;
+    }
+    else {
+        pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_AUTH;
+    }
+
+    // send auth reply
+    pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
+    memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_AUTHEN_FR_MAXLEN);
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+    sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
+    sFrame.len = WLAN_AUTHEN_FR_MAXLEN;
+    // format buffer structure
+    vMgrEncodeAuthen(&sFrame);
+    // insert values
+    sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
+         (
+         WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
+         WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_AUTHEN)|
+         WLAN_SET_FC_ISWEP(0)
+         ));
+    memcpy( sFrame.pHdr->sA3.abyAddr1, pFrame->pHdr->sA3.abyAddr2, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
+    *(sFrame.pwAuthAlgorithm) = *(pFrame->pwAuthAlgorithm);
+    *(sFrame.pwAuthSequence) = cpu_to_le16(2);
+
+    if (cpu_to_le16(*(pFrame->pwAuthAlgorithm)) == WLAN_AUTH_ALG_SHAREDKEY) {
+        if (pMgmt->bShareKeyAlgorithm)
+            *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_SUCCESS);
+        else
+            *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG);
+    }
+    else {
+        if (pMgmt->bShareKeyAlgorithm)
+            *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG);
+        else
+            *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_SUCCESS);
+    }
+
+    if (pMgmt->bShareKeyAlgorithm &&
+        (cpu_to_le16(*(sFrame.pwStatus)) == WLAN_MGMT_STATUS_SUCCESS)) {
+
+        sFrame.pChallenge = (PWLAN_IE_CHALLENGE)(sFrame.pBuf + sFrame.len);
+        sFrame.len += WLAN_CHALLENGE_IE_LEN;
+        sFrame.pChallenge->byElementID = WLAN_EID_CHALLENGE;
+        sFrame.pChallenge->len = WLAN_CHALLENGE_LEN;
+        memset(pMgmt->abyChallenge, 0, WLAN_CHALLENGE_LEN);
+        // get group key
+        if(KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, GROUP_KEY, &pTransmitKey) == TRUE) {
+            rc4_init(&pDevice->SBox, pDevice->abyPRNG, pTransmitKey->uKeyLength+3);
+            rc4_encrypt(&pDevice->SBox, pMgmt->abyChallenge, pMgmt->abyChallenge, WLAN_CHALLENGE_LEN);
+        }
+        memcpy(sFrame.pChallenge->abyChallenge, pMgmt->abyChallenge , WLAN_CHALLENGE_LEN);
+    }
+
+    /* Adjust the length fields */
+    pTxPacket->cbMPDULen = sFrame.len;
+    pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
+    // send the frame
+    if (pDevice->bEnableHostapd) {
+        return;
+    }
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Authreq_reply sequence_1 tx.. \n");
+    if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) {
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Authreq_reply sequence_1 tx failed.\n");
+    }
+    return;
+}
+
+
+
+/*+
+ *
+ * Routine Description:
+ *   Handles incoming auth frames with sequence number 2.  Currently
+ *   assumes we're a station.
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+static
+VOID
+s_vMgrRxAuthenSequence_2(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PWLAN_FR_AUTHEN pFrame
+    )
+{
+    WLAN_FR_AUTHEN      sFrame;
+    PSTxMgmtPacket      pTxPacket = NULL;
+
+
+    switch (cpu_to_le16((*(pFrame->pwAuthAlgorithm))))
+    {
+        case WLAN_AUTH_ALG_OPENSYSTEM:
+            if ( cpu_to_le16((*(pFrame->pwStatus))) == WLAN_MGMT_STATUS_SUCCESS ){
+                DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (OPEN) Successful.\n");
+                pMgmt->eCurrState = WMAC_STATE_AUTH;
+        timer_expire(pDevice->sTimerCommand, 0);
+            }
+            else {
+                DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (OPEN) Failed.\n");
+                s_vMgrLogStatus(pMgmt, cpu_to_le16((*(pFrame->pwStatus))));
+                pMgmt->eCurrState = WMAC_STATE_IDLE;
+            }
+            if (pDevice->eCommandState == WLAN_AUTHENTICATE_WAIT ) {
+//                spin_unlock_irq(&pDevice->lock);
+//                vCommandTimerWait((HANDLE)pDevice, 0);
+//                spin_lock_irq(&pDevice->lock);
+            }
+
+            break;
+
+        case WLAN_AUTH_ALG_SHAREDKEY:
+
+            if (cpu_to_le16((*(pFrame->pwStatus))) == WLAN_MGMT_STATUS_SUCCESS) {
+                pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
+                memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_AUTHEN_FR_MAXLEN);
+                pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+                sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
+                sFrame.len = WLAN_AUTHEN_FR_MAXLEN;
+                // format buffer structure
+                vMgrEncodeAuthen(&sFrame);
+                // insert values
+                sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
+                     (
+                     WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
+                     WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_AUTHEN)|
+                     WLAN_SET_FC_ISWEP(1)
+                     ));
+                memcpy( sFrame.pHdr->sA3.abyAddr1, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
+                memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
+                memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
+                *(sFrame.pwAuthAlgorithm) = *(pFrame->pwAuthAlgorithm);
+                *(sFrame.pwAuthSequence) = cpu_to_le16(3);
+                *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_SUCCESS);
+                sFrame.pChallenge = (PWLAN_IE_CHALLENGE)(sFrame.pBuf + sFrame.len);
+                sFrame.len += WLAN_CHALLENGE_IE_LEN;
+                sFrame.pChallenge->byElementID = WLAN_EID_CHALLENGE;
+                sFrame.pChallenge->len = WLAN_CHALLENGE_LEN;
+                memcpy( sFrame.pChallenge->abyChallenge, pFrame->pChallenge->abyChallenge, WLAN_CHALLENGE_LEN);
+                // Adjust the length fields
+                pTxPacket->cbMPDULen = sFrame.len;
+                pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
+                // send the frame
+                if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) {
+                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Auth_reply sequence_2 tx failed.\n");
+                }
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Auth_reply sequence_2 tx ...\n");
+            }
+            else {
+               DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:rx Auth_reply sequence_2 status error ...\n");
+                if ( pDevice->eCommandState == WLAN_AUTHENTICATE_WAIT ) {
+//                    spin_unlock_irq(&pDevice->lock);
+//                    vCommandTimerWait((HANDLE)pDevice, 0);
+//                    spin_lock_irq(&pDevice->lock);
+                }
+                s_vMgrLogStatus(pMgmt, cpu_to_le16((*(pFrame->pwStatus))));
+            }
+            break;
+        default:
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt: rx auth.seq = 2 unknown AuthAlgorithm=%d\n", cpu_to_le16((*(pFrame->pwAuthAlgorithm))));
+            break;
+    }
+    return;
+}
+
+
+
+/*+
+ *
+ * Routine Description:
+ *   Handles incoming authen frames with sequence 3.  Currently
+ *   assumes we're an AP.  This function assumes the frame has
+ *   already been successfully decrypted.
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+static
+VOID
+s_vMgrRxAuthenSequence_3(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PWLAN_FR_AUTHEN pFrame
+    )
+{
+    PSTxMgmtPacket      pTxPacket = NULL;
+    UINT                uStatusCode = 0 ;
+    UINT                uNodeIndex = 0;
+    WLAN_FR_AUTHEN      sFrame;
+
+    if (!WLAN_GET_FC_ISWEP(pFrame->pHdr->sA3.wFrameCtl)) {
+        uStatusCode = WLAN_MGMT_STATUS_CHALLENGE_FAIL;
+        goto reply;
+    }
+    if (BSSDBbIsSTAInNodeDB(pMgmt, pFrame->pHdr->sA3.abyAddr2, &uNodeIndex)) {
+         if (pMgmt->sNodeDBTable[uNodeIndex].byAuthSequence != 1) {
+            uStatusCode = WLAN_MGMT_STATUS_RX_AUTH_NOSEQ;
+            goto reply;
+         }
+         if (memcmp(pMgmt->abyChallenge, pFrame->pChallenge->abyChallenge, WLAN_CHALLENGE_LEN) != 0) {
+            uStatusCode = WLAN_MGMT_STATUS_CHALLENGE_FAIL;
+            goto reply;
+         }
+    }
+    else {
+        uStatusCode = WLAN_MGMT_STATUS_UNSPEC_FAILURE;
+        goto reply;
+    }
+
+    if (uNodeIndex) {
+        pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_AUTH;
+        pMgmt->sNodeDBTable[uNodeIndex].byAuthSequence = 0;
+    }
+    uStatusCode = WLAN_MGMT_STATUS_SUCCESS;
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Challenge text check ok..\n");
+
+reply:
+    // send auth reply
+    pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
+    memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_AUTHEN_FR_MAXLEN);
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+    sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
+    sFrame.len = WLAN_AUTHEN_FR_MAXLEN;
+    // format buffer structure
+    vMgrEncodeAuthen(&sFrame);
+    /* insert values */
+    sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
+         (
+         WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
+         WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_AUTHEN)|
+         WLAN_SET_FC_ISWEP(0)
+         ));
+    memcpy( sFrame.pHdr->sA3.abyAddr1, pFrame->pHdr->sA3.abyAddr2, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
+    *(sFrame.pwAuthAlgorithm) = *(pFrame->pwAuthAlgorithm);
+    *(sFrame.pwAuthSequence) = cpu_to_le16(4);
+    *(sFrame.pwStatus) = cpu_to_le16(uStatusCode);
+
+    /* Adjust the length fields */
+    pTxPacket->cbMPDULen = sFrame.len;
+    pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
+    // send the frame
+    if (pDevice->bEnableHostapd) {
+        return;
+    }
+    if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) {
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Authreq_reply sequence_4 tx failed.\n");
+    }
+    return;
+
+}
+
+
+
+/*+
+ *
+ * Routine Description:
+ *   Handles incoming authen frames with sequence 4
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+static
+VOID
+s_vMgrRxAuthenSequence_4(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PWLAN_FR_AUTHEN pFrame
+    )
+{
+
+    if ( cpu_to_le16((*(pFrame->pwStatus))) == WLAN_MGMT_STATUS_SUCCESS ){
+        DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (SHAREDKEY) Successful.\n");
+        pMgmt->eCurrState = WMAC_STATE_AUTH;
+         timer_expire(pDevice->sTimerCommand, 0);
+    }
+    else{
+        DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (SHAREDKEY) Failed.\n");
+        s_vMgrLogStatus(pMgmt, cpu_to_le16((*(pFrame->pwStatus))) );
+        pMgmt->eCurrState = WMAC_STATE_IDLE;
+    }
+
+    if ( pDevice->eCommandState == WLAN_AUTHENTICATE_WAIT ) {
+//        spin_unlock_irq(&pDevice->lock);
+//        vCommandTimerWait((HANDLE)pDevice, 0);
+//        spin_lock_irq(&pDevice->lock);
+    }
+
+}
+
+/*+
+ *
+ * Routine Description:
+ *   Handles incoming disassociation frames
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+static
+VOID
+s_vMgrRxDisassociation(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PSRxMgmtPacket pRxPacket
+    )
+{
+    WLAN_FR_DISASSOC    sFrame;
+    UINT        uNodeIndex = 0;
+//    CMD_STATUS          CmdStatus;
+    viawget_wpa_header *wpahdr;
+
+    if ( pMgmt->eCurrMode == WMAC_MODE_ESS_AP ){
+        // if is acting an AP..
+        // a STA is leaving this BSS..
+        sFrame.len = pRxPacket->cbMPDULen;
+        sFrame.pBuf = (PBYTE)pRxPacket->p80211Header;
+        if (BSSDBbIsSTAInNodeDB(pMgmt, pRxPacket->p80211Header->sA3.abyAddr2, &uNodeIndex)) {
+            BSSvRemoveOneNode(pDevice, uNodeIndex);
+        }
+        else {
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx disassoc, sta not found\n");
+        }
+    }
+    else if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA ){
+        sFrame.len = pRxPacket->cbMPDULen;
+        sFrame.pBuf = (PBYTE)pRxPacket->p80211Header;
+        vMgrDecodeDisassociation(&sFrame);
+        DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "AP disassociated me, reason=%d.\n", cpu_to_le16(*(sFrame.pwReason)));
+        //TODO: do something let upper layer know or
+        //try to send associate packet again because of inactivity timeout
+      //  if (pMgmt->eCurrState == WMAC_STATE_ASSOC) {
+       //     vMgrReAssocBeginSta((PSDevice)pDevice, pMgmt, &CmdStatus);
+      //  };
+        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;
+#if    LINUX_VERSION_CODE      > KERNEL_VERSION(2,6,21)
+                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;
+       printk("wireless_send_event--->SIOCGIWAP(disassociated)\n");
+       wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
+     }
+  #endif
+
+    }
+    /* else, ignore it */
+
+    return;
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *   Handles incoming deauthentication frames
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+static
+VOID
+s_vMgrRxDeauthentication(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PSRxMgmtPacket pRxPacket
+    )
+{
+    WLAN_FR_DEAUTHEN    sFrame;
+    UINT        uNodeIndex = 0;
+    viawget_wpa_header *wpahdr;
+
+
+    if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP ){
+        //Todo:
+        // if is acting an AP..
+        // a STA is leaving this BSS..
+        sFrame.len = pRxPacket->cbMPDULen;
+        sFrame.pBuf = (PBYTE)pRxPacket->p80211Header;
+        if (BSSDBbIsSTAInNodeDB(pMgmt, pRxPacket->p80211Header->sA3.abyAddr2, &uNodeIndex)) {
+            BSSvRemoveOneNode(pDevice, uNodeIndex);
+        }
+        else {
+            DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Rx deauth, sta not found\n");
+        }
+    }
+    else {
+        if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA ) {
+            sFrame.len = pRxPacket->cbMPDULen;
+            sFrame.pBuf = (PBYTE)pRxPacket->p80211Header;
+            vMgrDecodeDeauthen(&sFrame);
+            DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO  "AP deauthed me, reason=%d.\n", cpu_to_le16((*(sFrame.pwReason))));
+            // TODO: update BSS list for specific BSSID if pre-authentication case
+            if (IS_ETH_ADDRESS_EQUAL(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID)) {
+                if (pMgmt->eCurrState >= WMAC_STATE_AUTHPENDING) {
+                    pMgmt->sNodeDBTable[0].bActive = FALSE;
+                    pMgmt->eCurrMode = WMAC_MODE_STANDBY;
+                    pMgmt->eCurrState = WMAC_STATE_IDLE;
+                    netif_stop_queue(pDevice->dev);
+                    pDevice->bLinkPass = FALSE;
+                }
+            };
+
+            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;
+#if    LINUX_VERSION_CODE      > KERNEL_VERSION(2,6,21)
+               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;
+       printk("wireless_send_event--->SIOCGIWAP(disauthen)\n");
+       wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
+     }
+  #endif
+
+        }
+        /* else, ignore it.  TODO: IBSS authentication service
+            would be implemented here */
+    };
+    return;
+}
+
+
+//2008-8-4 <add> by chester
+/*+
+ *
+ * Routine Description:
+ * check if current channel is match ZoneType.
+ *for USA:1~11;
+ *      Japan:1~13;
+ *      Europe:1~13
+ * Return Value:
+ *               True:exceed;
+ *                False:normal case
+-*/
+static BOOL
+ChannelExceedZoneType(
+    IN PSDevice pDevice,
+    IN BYTE byCurrChannel
+    )
+{
+  BOOL exceed=FALSE;
+
+  switch(pDevice->byZoneType) {
+       case 0x00:                  //USA:1~11
+                     if((byCurrChannel<1) ||(byCurrChannel>11))
+                       exceed = TRUE;
+                break;
+       case 0x01:                  //Japan:1~13
+       case 0x02:                  //Europe:1~13
+                     if((byCurrChannel<1) ||(byCurrChannel>13))
+                       exceed = TRUE;
+                break;
+       default:                    //reserve for other zonetype
+               break;
+  }
+
+  return exceed;
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *   Handles and analysis incoming beacon frames.
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+static
+VOID
+s_vMgrRxBeacon(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PSRxMgmtPacket pRxPacket,
+    IN BOOL bInScan
+    )
+{
+
+    PKnownBSS           pBSSList;
+    WLAN_FR_BEACON      sFrame;
+    QWORD               qwTSFOffset;
+    BOOL                bIsBSSIDEqual = FALSE;
+    BOOL                bIsSSIDEqual = FALSE;
+    BOOL                bTSFLargeDiff = FALSE;
+    BOOL                bTSFOffsetPostive = FALSE;
+    BOOL                bUpdateTSF = FALSE;
+    BOOL                bIsAPBeacon = FALSE;
+    BOOL                bIsChannelEqual = FALSE;
+    UINT                uLocateByteIndex;
+    BYTE                byTIMBitOn = 0;
+    WORD                wAIDNumber = 0;
+    UINT                uNodeIndex;
+    QWORD               qwTimestamp, qwLocalTSF;
+    QWORD               qwCurrTSF;
+    WORD                wStartIndex = 0;
+    WORD                wAIDIndex = 0;
+    BYTE                byCurrChannel = pRxPacket->byRxChannel;
+    ERPObject           sERP;
+    UINT                uRateLen = WLAN_RATES_MAXLEN;
+    BOOL                bChannelHit = FALSE;
+    BOOL                bUpdatePhyParameter = FALSE;
+    BYTE                byIEChannel = 0;
+
+
+    memset(&sFrame, 0, sizeof(WLAN_FR_BEACON));
+    sFrame.len = pRxPacket->cbMPDULen;
+    sFrame.pBuf = (PBYTE)pRxPacket->p80211Header;
+
+    // decode the beacon frame
+    vMgrDecodeBeacon(&sFrame);
+
+    if ((sFrame.pwBeaconInterval == 0) ||
+        (sFrame.pwCapInfo == 0) ||
+        (sFrame.pSSID == 0) ||
+        (sFrame.pSuppRates == 0) ) {
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx beacon frame error\n");
+        return;
+    };
+
+
+    if (sFrame.pDSParms != NULL) {
+        if (byCurrChannel > CB_MAX_CHANNEL_24G) {
+            // channel remapping to
+            byIEChannel = CARDbyGetChannelMapping(pDevice, sFrame.pDSParms->byCurrChannel, PHY_TYPE_11A);
+        } else {
+            byIEChannel = sFrame.pDSParms->byCurrChannel;
+        }
+        if (byCurrChannel != byIEChannel) {
+            // adjust channel info. bcs we rcv adjcent channel pakckets
+            bChannelHit = FALSE;
+            byCurrChannel = byIEChannel;
+        }
+    } else {
+        // no DS channel info
+        bChannelHit = TRUE;
+    }
+//2008-0730-01<Add>by MikeLiu
+if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE)
+      return;
+
+    if (sFrame.pERP != NULL) {
+        sERP.byERP = sFrame.pERP->byContext;
+        sERP.bERPExist = TRUE;
+
+    } else {
+        sERP.bERPExist = FALSE;
+        sERP.byERP = 0;
+    }
+
+    pBSSList = BSSpAddrIsInBSSList((HANDLE)pDevice, sFrame.pHdr->sA3.abyAddr3, sFrame.pSSID);
+    if (pBSSList == NULL) {
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Beacon/insert: RxChannel = : %d\n", byCurrChannel);
+        BSSbInsertToBSSList((HANDLE)pDevice,
+                            sFrame.pHdr->sA3.abyAddr3,
+                            *sFrame.pqwTimestamp,
+                            *sFrame.pwBeaconInterval,
+                            *sFrame.pwCapInfo,
+                            byCurrChannel,
+                            sFrame.pSSID,
+                            sFrame.pSuppRates,
+                            sFrame.pExtSuppRates,
+                            &sERP,
+                            sFrame.pRSN,
+                            sFrame.pRSNWPA,
+                            sFrame.pIE_Country,
+                            sFrame.pIE_Quiet,
+                            sFrame.len - WLAN_HDR_ADDR3_LEN,
+                            sFrame.pHdr->sA4.abyAddr4,   // payload of beacon
+                            (HANDLE)pRxPacket
+                           );
+    }
+    else {
+//        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"update bcn: RxChannel = : %d\n", byCurrChannel);
+        BSSbUpdateToBSSList((HANDLE)pDevice,
+                            *sFrame.pqwTimestamp,
+                            *sFrame.pwBeaconInterval,
+                            *sFrame.pwCapInfo,
+                            byCurrChannel,
+                            bChannelHit,
+                            sFrame.pSSID,
+                            sFrame.pSuppRates,
+                            sFrame.pExtSuppRates,
+                            &sERP,
+                            sFrame.pRSN,
+                            sFrame.pRSNWPA,
+                            sFrame.pIE_Country,
+                            sFrame.pIE_Quiet,
+                            pBSSList,
+                            sFrame.len - WLAN_HDR_ADDR3_LEN,
+                            sFrame.pHdr->sA4.abyAddr4,   // payload of probresponse
+                            (HANDLE)pRxPacket
+                           );
+
+    }
+
+    if (bInScan) {
+        return;
+    }
+
+    if(byCurrChannel == (BYTE)pMgmt->uCurrChannel)
+       bIsChannelEqual = TRUE;
+
+    if (bIsChannelEqual && (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)) {
+
+        // if rx beacon without ERP field
+        if (sERP.bERPExist) {
+            if (WLAN_GET_ERP_USE_PROTECTION(sERP.byERP)){
+                pDevice->byERPFlag |= WLAN_SET_ERP_USE_PROTECTION(1);
+                pDevice->wUseProtectCntDown = USE_PROTECT_PERIOD;
+            }
+        }
+        else {
+            pDevice->byERPFlag |= WLAN_SET_ERP_USE_PROTECTION(1);
+            pDevice->wUseProtectCntDown = USE_PROTECT_PERIOD;
+        }
+
+        if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
+            if(!WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo))
+                pDevice->byERPFlag |= WLAN_SET_ERP_BARKER_MODE(1);
+            if(!sERP.bERPExist)
+                pDevice->byERPFlag |= WLAN_SET_ERP_NONERP_PRESENT(1);
+        }
+
+        // set to MAC&BBP
+        if (WLAN_GET_ERP_USE_PROTECTION(pDevice->byERPFlag)){
+            if (!pDevice->bProtectMode) {
+                 MACvEnableProtectMD(pDevice->PortOffset);
+                 pDevice->bProtectMode = TRUE;
+            }
+        }
+    }
+
+
+    if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)
+        return;
+
+    // check if BSSID the same
+    if (memcmp(sFrame.pHdr->sA3.abyAddr3,
+               pMgmt->abyCurrBSSID,
+               WLAN_BSSID_LEN) == 0) {
+
+        bIsBSSIDEqual = TRUE;
+
+// 2008-05-21 <add> by Richardtai
+        pDevice->uCurrRSSI = pRxPacket->uRSSI;
+        pDevice->byCurrSQ = pRxPacket->bySQ;
+
+        if (pMgmt->sNodeDBTable[0].uInActiveCount != 0) {
+            pMgmt->sNodeDBTable[0].uInActiveCount = 0;
+            //DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BCN:Wake Count= [%d]\n", pMgmt->wCountToWakeUp);
+        }
+    }
+    // check if SSID the same
+    if (sFrame.pSSID->len == ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) {
+        if (memcmp(sFrame.pSSID->abySSID,
+                   ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID,
+                   sFrame.pSSID->len
+                   ) == 0) {
+            bIsSSIDEqual = TRUE;
+        };
+    }
+
+    if ((WLAN_GET_CAP_INFO_ESS(*sFrame.pwCapInfo)== TRUE) &&
+        (bIsBSSIDEqual == TRUE) &&
+        (bIsSSIDEqual == TRUE) &&
+        (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
+        (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
+        // add state check to prevent reconnect fail since we'll receive Beacon
+
+        bIsAPBeacon = TRUE;
+
+        if (pBSSList != NULL) {
+
+            // Compare PHY paramater setting
+            if (pMgmt->wCurrCapInfo != pBSSList->wCapInfo) {
+                bUpdatePhyParameter = TRUE;
+                pMgmt->wCurrCapInfo = pBSSList->wCapInfo;
+            }
+            if (sFrame.pERP != NULL) {
+                if ((sFrame.pERP->byElementID == WLAN_EID_ERP) &&
+                    (pMgmt->byERPContext != sFrame.pERP->byContext)) {
+                    bUpdatePhyParameter = TRUE;
+                    pMgmt->byERPContext = sFrame.pERP->byContext;
+                }
+            }
+            //
+            // Basic Rate Set may change dynamiclly
+            //
+            if (pBSSList->eNetworkTypeInUse == PHY_TYPE_11B) {
+                uRateLen = WLAN_RATES_MAXLEN_11B;
+            }
+            pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pBSSList->abySuppRates,
+                                                    (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
+                                                    uRateLen);
+            pMgmt->abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pBSSList->abyExtSuppRates,
+                                                    (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)
+                              );
+#ifdef PLICE_DEBUG
+               //printk("RxBeacon:MaxSuppRate is %d\n",pMgmt->sNodeDBTable[0].wMaxSuppRate);
+#endif
+                       if (bUpdatePhyParameter == TRUE) {
+                CARDbSetPhyParameter( pMgmt->pAdapter,
+                                      pMgmt->eCurrentPHYMode,
+                                      pMgmt->wCurrCapInfo,
+                                      pMgmt->byERPContext,
+                                      pMgmt->abyCurrSuppRates,
+                                      pMgmt->abyCurrExtSuppRates
+                                      );
+            }
+            if (sFrame.pIE_PowerConstraint != NULL) {
+                CARDvSetPowerConstraint(pMgmt->pAdapter,
+                                        (BYTE) pBSSList->uChannel,
+                                        sFrame.pIE_PowerConstraint->byPower
+                                        );
+            }
+            if (sFrame.pIE_CHSW != NULL) {
+                CARDbChannelSwitch( pMgmt->pAdapter,
+                                    sFrame.pIE_CHSW->byMode,
+                                    CARDbyGetChannelMapping(pMgmt->pAdapter, sFrame.pIE_CHSW->byMode, pMgmt->eCurrentPHYMode),
+                                    sFrame.pIE_CHSW->byCount
+                                    );
+
+            } else if (bIsChannelEqual == FALSE) {
+                CARDbSetChannel(pMgmt->pAdapter, pBSSList->uChannel);
+            }
+        }
+    }
+
+//    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Beacon 2 \n");
+    // check if CF field exisit
+    if (WLAN_GET_CAP_INFO_ESS(*sFrame.pwCapInfo)) {
+        if (sFrame.pCFParms->wCFPDurRemaining > 0) {
+            // TODO: deal with CFP period to set NAV
+        };
+    };
+
+    HIDWORD(qwTimestamp) = cpu_to_le32(HIDWORD(*sFrame.pqwTimestamp));
+    LODWORD(qwTimestamp) = cpu_to_le32(LODWORD(*sFrame.pqwTimestamp));
+    HIDWORD(qwLocalTSF) = HIDWORD(pRxPacket->qwLocalTSF);
+    LODWORD(qwLocalTSF) = LODWORD(pRxPacket->qwLocalTSF);
+
+    // check if beacon TSF larger or small than our local TSF
+    if (HIDWORD(qwTimestamp) == HIDWORD(qwLocalTSF)) {
+        if (LODWORD(qwTimestamp) >= LODWORD(qwLocalTSF)) {
+            bTSFOffsetPostive = TRUE;
+        }
+        else {
+            bTSFOffsetPostive = FALSE;
+        }
+    }
+    else if (HIDWORD(qwTimestamp) > HIDWORD(qwLocalTSF)) {
+        bTSFOffsetPostive = TRUE;
+    }
+    else if (HIDWORD(qwTimestamp) < HIDWORD(qwLocalTSF)) {
+        bTSFOffsetPostive = FALSE;
+    };
+
+    if (bTSFOffsetPostive) {
+        qwTSFOffset = CARDqGetTSFOffset(pRxPacket->byRxRate, (qwTimestamp), (qwLocalTSF));
+    }
+    else {
+        qwTSFOffset = CARDqGetTSFOffset(pRxPacket->byRxRate, (qwLocalTSF), (qwTimestamp));
+    }
+
+    if (HIDWORD(qwTSFOffset) != 0 ||
+        (LODWORD(qwTSFOffset) > TRIVIAL_SYNC_DIFFERENCE )) {
+         bTSFLargeDiff = TRUE;
+    }
+
+
+    // if infra mode
+    if (bIsAPBeacon == TRUE) {
+
+        // Infra mode: Local TSF always follow AP's TSF if Difference huge.
+        if (bTSFLargeDiff)
+            bUpdateTSF = TRUE;
+
+        if ((pDevice->bEnablePSMode == TRUE) &&(sFrame.pTIM != 0)) {
+
+            // deal with DTIM, analysis TIM
+            pMgmt->bMulticastTIM = WLAN_MGMT_IS_MULTICAST_TIM(sFrame.pTIM->byBitMapCtl) ? TRUE : FALSE ;
+            pMgmt->byDTIMCount = sFrame.pTIM->byDTIMCount;
+            pMgmt->byDTIMPeriod = sFrame.pTIM->byDTIMPeriod;
+            wAIDNumber = pMgmt->wCurrAID & ~(BIT14|BIT15);
+
+            // check if AID in TIM field bit on
+            // wStartIndex = N1
+            wStartIndex = WLAN_MGMT_GET_TIM_OFFSET(sFrame.pTIM->byBitMapCtl) << 1;
+            // AIDIndex = N2
+            wAIDIndex = (wAIDNumber >> 3);
+            if ((wAIDNumber > 0) && (wAIDIndex >= wStartIndex)) {
+                uLocateByteIndex = wAIDIndex - wStartIndex;
+                // len = byDTIMCount + byDTIMPeriod + byDTIMPeriod + byVirtBitMap[0~250]
+                if (sFrame.pTIM->len >= (uLocateByteIndex + 4)) {
+                    byTIMBitOn  = (0x01) << ((wAIDNumber) % 8);
+                    pMgmt->bInTIM = sFrame.pTIM->byVirtBitMap[uLocateByteIndex] & byTIMBitOn ? TRUE : FALSE;
+                }
+                else {
+                    pMgmt->bInTIM = FALSE;
+                };
+            }
+            else {
+                pMgmt->bInTIM = FALSE;
+            };
+
+            if (pMgmt->bInTIM ||
+                (pMgmt->bMulticastTIM && (pMgmt->byDTIMCount == 0))) {
+                pMgmt->bInTIMWake = TRUE;
+                // send out ps-poll packet
+//                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN:In TIM\n");
+                if (pMgmt->bInTIM) {
+                    PSvSendPSPOLL((PSDevice)pDevice);
+//                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN:PS-POLL sent..\n");
+                };
+
+            }
+            else {
+                pMgmt->bInTIMWake = FALSE;
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Not In TIM..\n");
+                if (pDevice->bPWBitOn == FALSE) {
+                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Send Null Packet\n");
+                    if (PSbSendNullPacket(pDevice))
+                        pDevice->bPWBitOn = TRUE;
+                }
+                if(PSbConsiderPowerDown(pDevice, FALSE, FALSE)) {
+                   DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Power down now...\n");
+                };
+            }
+
+        }
+
+    }
+    // if adhoc mode
+    if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && !bIsAPBeacon && bIsChannelEqual) {
+        if (bIsBSSIDEqual) {
+            // Use sNodeDBTable[0].uInActiveCount as IBSS beacons received count.
+                   if (pMgmt->sNodeDBTable[0].uInActiveCount != 0)
+                           pMgmt->sNodeDBTable[0].uInActiveCount = 0;
+
+            // adhoc mode:TSF updated only when beacon larger then local TSF
+            if (bTSFLargeDiff && bTSFOffsetPostive &&
+                (pMgmt->eCurrState == WMAC_STATE_JOINTED))
+                bUpdateTSF = TRUE;
+
+            // During dpc, already in spinlocked.
+            if (BSSDBbIsSTAInNodeDB(pMgmt, sFrame.pHdr->sA3.abyAddr2, &uNodeIndex)) {
+
+                // Update the STA, (Techically the Beacons of all the IBSS nodes
+                       // should be identical, but that's not happening in practice.
+                pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates,
+                                                        (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
+                                                        WLAN_RATES_MAXLEN_11B);
+                RATEvParseMaxRate( (PVOID)pDevice,
+                                   (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
+                                   NULL,
+                                   TRUE,
+                                   &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate),
+                                   &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate),
+                                   &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate),
+                                   &(pMgmt->sNodeDBTable[uNodeIndex].byTopCCKBasicRate),
+                                   &(pMgmt->sNodeDBTable[uNodeIndex].byTopOFDMBasicRate)
+                                  );
+                pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble = WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo);
+                pMgmt->sNodeDBTable[uNodeIndex].bShortSlotTime = WLAN_GET_CAP_INFO_SHORTSLOTTIME(*sFrame.pwCapInfo);
+                pMgmt->sNodeDBTable[uNodeIndex].uInActiveCount = 0;
+            }
+            else {
+                // Todo, initial Node content
+                BSSvCreateOneNode((PSDevice)pDevice, &uNodeIndex);
+
+                pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates,
+                                                        (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
+                                                        WLAN_RATES_MAXLEN_11B);
+                RATEvParseMaxRate( (PVOID)pDevice,
+                                   (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
+                                   NULL,
+                                   TRUE,
+                                   &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate),
+                                   &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate),
+                                   &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate),
+                                   &(pMgmt->sNodeDBTable[uNodeIndex].byTopCCKBasicRate),
+                                   &(pMgmt->sNodeDBTable[uNodeIndex].byTopOFDMBasicRate)
+                                 );
+
+                memcpy(pMgmt->sNodeDBTable[uNodeIndex].abyMACAddr, sFrame.pHdr->sA3.abyAddr2, WLAN_ADDR_LEN);
+                pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble = WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo);
+                pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate = pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate;
+#ifdef PLICE_DEBUG
+               //if (uNodeIndex == 0)
+               {
+                       printk("s_vMgrRxBeacon:TxDataRate is %d,Index is %d\n",pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate,uNodeIndex);
+               }
+#endif
+/*
+                pMgmt->sNodeDBTable[uNodeIndex].bShortSlotTime = WLAN_GET_CAP_INFO_SHORTSLOTTIME(*sFrame.pwCapInfo);
+                if(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate > RATE_11M)
+                       pMgmt->sNodeDBTable[uNodeIndex].bERPExist = TRUE;
+*/
+            }
+
+            // if other stations jointed, indicate connect to upper layer..
+            if (pMgmt->eCurrState == WMAC_STATE_STARTED) {
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Current IBSS State: [Started]........to: [Jointed] \n");
+                pMgmt->eCurrState = WMAC_STATE_JOINTED;
+                pDevice->bLinkPass = TRUE;
+                if (netif_queue_stopped(pDevice->dev)){
+                    netif_wake_queue(pDevice->dev);
+                }
+                pMgmt->sNodeDBTable[0].bActive = TRUE;
+                pMgmt->sNodeDBTable[0].uInActiveCount = 0;
+
+            };
+        }
+        else if (bIsSSIDEqual) {
+
+            // See other adhoc sta with the same SSID but BSSID is different.
+            // adpot this vars only when TSF larger then us.
+            if (bTSFLargeDiff && bTSFOffsetPostive) {
+                 // we don't support ATIM under adhoc mode
+               // if ( sFrame.pIBSSParms->wATIMWindow == 0) {
+                     // adpot this vars
+                     // TODO: check sFrame cap if privacy on, and support rate syn
+                     memcpy(pMgmt->abyCurrBSSID, sFrame.pHdr->sA3.abyAddr3, WLAN_BSSID_LEN);
+                     memcpy(pDevice->abyBSSID, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
+                     pMgmt->wCurrATIMWindow = cpu_to_le16(sFrame.pIBSSParms->wATIMWindow);
+                     pMgmt->wCurrBeaconPeriod = cpu_to_le16(*sFrame.pwBeaconInterval);
+                     pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates,
+                                                      (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
+                                                      WLAN_RATES_MAXLEN_11B);
+                     // set HW beacon interval and re-synchronizing....
+                     DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rejoining to Other Adhoc group with same SSID........\n");
+                     VNSvOutPortW(pDevice->PortOffset + MAC_REG_BI, pMgmt->wCurrBeaconPeriod);
+                     CARDbUpdateTSF(pDevice, pRxPacket->byRxRate, qwTimestamp, qwLocalTSF);
+                     CARDvUpdateNextTBTT(pDevice->PortOffset, qwTimestamp, pMgmt->wCurrBeaconPeriod);
+                     // Turn off bssid filter to avoid filter others adhoc station which bssid is different.
+                     MACvWriteBSSIDAddress(pDevice->PortOffset, pMgmt->abyCurrBSSID);
+
+                     CARDbSetPhyParameter (  pMgmt->pAdapter,
+                                            pMgmt->eCurrentPHYMode,
+                                            pMgmt->wCurrCapInfo,
+                                            pMgmt->byERPContext,
+                                            pMgmt->abyCurrSuppRates,
+                                            pMgmt->abyCurrExtSuppRates);
+
+
+                     // MACvRegBitsOff(pDevice->PortOffset, MAC_REG_RCR, RCR_BSSID);
+                     // set highest basic rate
+                     // s_vSetHighestBasicRate(pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates);
+                     // Prepare beacon frame
+                     bMgrPrepareBeaconToSend((HANDLE)pDevice, pMgmt);
+              //  }
+            };
+        }
+    };
+    // endian issue ???
+    // Update TSF
+    if (bUpdateTSF) {
+        CARDbGetCurrentTSF(pDevice->PortOffset, &qwCurrTSF);
+        CARDbUpdateTSF(pDevice, pRxPacket->byRxRate, qwTimestamp, pRxPacket->qwLocalTSF);
+        CARDbGetCurrentTSF(pDevice->PortOffset, &qwCurrTSF);
+        CARDvUpdateNextTBTT(pDevice->PortOffset, qwTimestamp, pMgmt->wCurrBeaconPeriod);
+    }
+
+    return;
+}
+
+
+
+/*+
+ *
+ * Routine Description:
+ *   Instructs the hw to create a bss using the supplied
+ *   attributes. Note that this implementation only supports Ad-Hoc
+ *   BSS creation.
+ *
+ *
+ * Return Value:
+ *    CMD_STATUS
+ *
+-*/
+VOID
+vMgrCreateOwnIBSS(
+    IN  HANDLE hDeviceContext,
+    OUT PCMD_STATUS pStatus
+    )
+{
+    PSDevice            pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject        pMgmt = pDevice->pMgmt;
+    WORD                wMaxBasicRate;
+    WORD                wMaxSuppRate;
+    BYTE                byTopCCKBasicRate;
+    BYTE                byTopOFDMBasicRate;
+    QWORD               qwCurrTSF;
+    UINT                ii;
+    BYTE    abyRATE[] = {0x82, 0x84, 0x8B, 0x96, 0x24, 0x30, 0x48, 0x6C, 0x0C, 0x12, 0x18, 0x60};
+    BYTE    abyCCK_RATE[] = {0x82, 0x84, 0x8B, 0x96};
+    BYTE    abyOFDM_RATE[] = {0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C};
+    WORD                wSuppRate;
+
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Create Basic Service Set .......\n");
+
+    if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) {
+        if ((pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) &&
+            (pDevice->eEncryptionStatus != Ndis802_11Encryption2Enabled) &&
+            (pDevice->eEncryptionStatus != Ndis802_11Encryption3Enabled)) {
+            // encryption mode error
+            *pStatus = CMD_STATUS_FAILURE;
+            return;
+        }
+    }
+
+    pMgmt->abyCurrSuppRates[0] = WLAN_EID_SUPP_RATES;
+    pMgmt->abyCurrExtSuppRates[0] = WLAN_EID_EXTSUPP_RATES;
+
+    if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
+        pMgmt->eCurrentPHYMode = pMgmt->byAPBBType;
+    } else {
+        if (pDevice->byBBType == BB_TYPE_11G)
+            pMgmt->eCurrentPHYMode = PHY_TYPE_11G;
+        if (pDevice->byBBType == BB_TYPE_11B)
+            pMgmt->eCurrentPHYMode = PHY_TYPE_11B;
+        if (pDevice->byBBType == BB_TYPE_11A)
+            pMgmt->eCurrentPHYMode = PHY_TYPE_11A;
+    }
+
+    if (pMgmt->eCurrentPHYMode != PHY_TYPE_11A) {
+        pMgmt->abyCurrSuppRates[1] = WLAN_RATES_MAXLEN_11B;
+        pMgmt->abyCurrExtSuppRates[1] = 0;
+        for (ii = 0; ii < 4; ii++)
+            pMgmt->abyCurrSuppRates[2+ii] = abyRATE[ii];
+    } else {
+        pMgmt->abyCurrSuppRates[1] = 8;
+        pMgmt->abyCurrExtSuppRates[1] = 0;
+        for (ii = 0; ii < 8; ii++)
+            pMgmt->abyCurrSuppRates[2+ii] = abyRATE[ii];
+    }
+
+
+    if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) {
+        pMgmt->abyCurrSuppRates[1] = 8;
+        pMgmt->abyCurrExtSuppRates[1] = 4;
+        for (ii = 0; ii < 4; ii++)
+            pMgmt->abyCurrSuppRates[2+ii] =  abyCCK_RATE[ii];
+        for (ii = 4; ii < 8; ii++)
+            pMgmt->abyCurrSuppRates[2+ii] =  abyOFDM_RATE[ii-4];
+        for (ii = 0; ii < 4; ii++)
+            pMgmt->abyCurrExtSuppRates[2+ii] =  abyOFDM_RATE[ii+4];
+    }
+
+
+    // Disable Protect Mode
+    pDevice->bProtectMode = 0;
+    MACvDisableProtectMD(pDevice->PortOffset);
+
+    pDevice->bBarkerPreambleMd = 0;
+    MACvDisableBarkerPreambleMd(pDevice->PortOffset);
+
+    // Kyle Test 2003.11.04
+
+    // set HW beacon interval
+    if (pMgmt->wIBSSBeaconPeriod == 0)
+        pMgmt->wIBSSBeaconPeriod = DEFAULT_IBSS_BI;
+
+
+    CARDbGetCurrentTSF(pDevice->PortOffset, &qwCurrTSF);
+    // clear TSF counter
+    VNSvOutPortB(pDevice->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);
+    // enable TSF counter
+    VNSvOutPortB(pDevice->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
+
+    // set Next TBTT
+    CARDvSetFirstNextTBTT(pDevice->PortOffset, pMgmt->wIBSSBeaconPeriod);
+
+    pMgmt->uIBSSChannel = pDevice->uChannel;
+
+    if (pMgmt->uIBSSChannel == 0)
+        pMgmt->uIBSSChannel = DEFAULT_IBSS_CHANNEL;
+
+
+    // set basic rate
+
+    RATEvParseMaxRate((PVOID)pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
+                      (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, TRUE,
+                      &wMaxBasicRate, &wMaxSuppRate, &wSuppRate,
+                      &byTopCCKBasicRate, &byTopOFDMBasicRate);
+
+
+    if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
+        pMgmt->eCurrMode = WMAC_MODE_ESS_AP;
+    }
+
+    if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) {
+        MEMvCopy(pMgmt->abyIBSSDFSOwner, pDevice->abyCurrentNetAddr, 6);
+        pMgmt->byIBSSDFSRecovery = 10;
+        pMgmt->eCurrMode = WMAC_MODE_IBSS_STA;
+    }
+
+    // Adopt pre-configured IBSS vars to current vars
+    pMgmt->eCurrState = WMAC_STATE_STARTED;
+    pMgmt->wCurrBeaconPeriod = pMgmt->wIBSSBeaconPeriod;
+    pMgmt->uCurrChannel = pMgmt->uIBSSChannel;
+    pMgmt->wCurrATIMWindow = pMgmt->wIBSSATIMWindow;
+    MACvWriteATIMW(pDevice->PortOffset, pMgmt->wCurrATIMWindow);
+    pDevice->uCurrRSSI = 0;
+    pDevice->byCurrSQ = 0;
+    //memcpy(pMgmt->abyDesireSSID,pMgmt->abyAdHocSSID,
+                     // ((PWLAN_IE_SSID)pMgmt->abyAdHocSSID)->len + WLAN_IEHDR_LEN);
+    memset(pMgmt->abyCurrSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+    memcpy(pMgmt->abyCurrSSID,
+           pMgmt->abyDesireSSID,
+           ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->len + WLAN_IEHDR_LEN
+          );
+
+    if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
+        // AP mode BSSID = MAC addr
+        memcpy(pMgmt->abyCurrBSSID, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
+        DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO"AP beacon created BSSID:%02x-%02x-%02x-%02x-%02x-%02x \n",
+                      pMgmt->abyCurrBSSID[0],
+                      pMgmt->abyCurrBSSID[1],
+                      pMgmt->abyCurrBSSID[2],
+                      pMgmt->abyCurrBSSID[3],
+                      pMgmt->abyCurrBSSID[4],
+                      pMgmt->abyCurrBSSID[5]
+                    );
+    }
+
+    if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
+
+        // BSSID selected must be randomized as spec 11.1.3
+        pMgmt->abyCurrBSSID[5] = (BYTE) (LODWORD(qwCurrTSF)& 0x000000ff);
+        pMgmt->abyCurrBSSID[4] = (BYTE)((LODWORD(qwCurrTSF)& 0x0000ff00) >> 8);
+        pMgmt->abyCurrBSSID[3] = (BYTE)((LODWORD(qwCurrTSF)& 0x00ff0000) >> 16);
+        pMgmt->abyCurrBSSID[2] = (BYTE)((LODWORD(qwCurrTSF)& 0x00000ff0) >> 4);
+        pMgmt->abyCurrBSSID[1] = (BYTE)((LODWORD(qwCurrTSF)& 0x000ff000) >> 12);
+        pMgmt->abyCurrBSSID[0] = (BYTE)((LODWORD(qwCurrTSF)& 0x0ff00000) >> 20);
+        pMgmt->abyCurrBSSID[5] ^= pMgmt->abyMACAddr[0];
+        pMgmt->abyCurrBSSID[4] ^= pMgmt->abyMACAddr[1];
+        pMgmt->abyCurrBSSID[3] ^= pMgmt->abyMACAddr[2];
+        pMgmt->abyCurrBSSID[2] ^= pMgmt->abyMACAddr[3];
+        pMgmt->abyCurrBSSID[1] ^= pMgmt->abyMACAddr[4];
+        pMgmt->abyCurrBSSID[0] ^= pMgmt->abyMACAddr[5];
+        pMgmt->abyCurrBSSID[0] &= ~IEEE_ADDR_GROUP;
+        pMgmt->abyCurrBSSID[0] |= IEEE_ADDR_UNIVERSAL;
+
+
+        DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO"Adhoc beacon created bssid:%02x-%02x-%02x-%02x-%02x-%02x \n",
+                      pMgmt->abyCurrBSSID[0],
+                      pMgmt->abyCurrBSSID[1],
+                      pMgmt->abyCurrBSSID[2],
+                      pMgmt->abyCurrBSSID[3],
+                      pMgmt->abyCurrBSSID[4],
+                      pMgmt->abyCurrBSSID[5]
+                    );
+    }
+
+    // Set Capability Info
+    pMgmt->wCurrCapInfo = 0;
+
+    if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
+        pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_ESS(1);
+        pMgmt->byDTIMPeriod = DEFAULT_DTIM_PERIOD;
+        pMgmt->byDTIMCount = pMgmt->byDTIMPeriod - 1;
+    }
+
+    if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
+        pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_IBSS(1);
+    }
+
+    if (pDevice->bEncryptionEnable) {
+        pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1);
+        if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
+            if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
+                pMgmt->byCSSPK = KEY_CTL_CCMP;
+                pMgmt->byCSSGK = KEY_CTL_CCMP;
+            } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
+                pMgmt->byCSSPK = KEY_CTL_TKIP;
+                pMgmt->byCSSGK = KEY_CTL_TKIP;
+            } else {
+                pMgmt->byCSSPK = KEY_CTL_NONE;
+                pMgmt->byCSSGK = KEY_CTL_WEP;
+            }
+        } else {
+            pMgmt->byCSSPK = KEY_CTL_WEP;
+            pMgmt->byCSSGK = KEY_CTL_WEP;
+        }
+    };
+
+    pMgmt->byERPContext = 0;
+
+//    memcpy(pDevice->abyBSSID, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
+
+    if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
+        CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_AP);
+    } else {
+        CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_ADHOC);
+    }
+
+    CARDbSetPhyParameter(   pMgmt->pAdapter,
+                            pMgmt->eCurrentPHYMode,
+                            pMgmt->wCurrCapInfo,
+                            pMgmt->byERPContext,
+                            pMgmt->abyCurrSuppRates,
+                            pMgmt->abyCurrExtSuppRates
+                            );
+
+    CARDbSetBeaconPeriod(pMgmt->pAdapter, pMgmt->wIBSSBeaconPeriod);
+    // set channel and clear NAV
+    CARDbSetChannel(pMgmt->pAdapter, pMgmt->uIBSSChannel);
+    pMgmt->uCurrChannel = pMgmt->uIBSSChannel;
+
+    if (CARDbIsShortPreamble(pMgmt->pAdapter)) {
+        pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
+    } else {
+        pMgmt->wCurrCapInfo &= (~WLAN_SET_CAP_INFO_SHORTPREAMBLE(1));
+    }
+
+    if ((pMgmt->b11hEnable == TRUE) &&
+        (pMgmt->eCurrentPHYMode == PHY_TYPE_11A)) {
+        pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SPECTRUMMNG(1);
+    } else {
+        pMgmt->wCurrCapInfo &= (~WLAN_SET_CAP_INFO_SPECTRUMMNG(1));
+    }
+
+    pMgmt->eCurrState = WMAC_STATE_STARTED;
+    // Prepare beacon to send
+    if (bMgrPrepareBeaconToSend((HANDLE)pDevice, pMgmt)) {
+        *pStatus = CMD_STATUS_SUCCESS;
+    }
+
+    return ;
+}
+
+
+
+/*+
+ *
+ * Routine Description:
+ *   Instructs wmac to join a bss using the supplied attributes.
+ *   The arguments may the BSSID or SSID and the rest of the
+ *   attributes are obtained from the scan result of known bss list.
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+VOID
+vMgrJoinBSSBegin(
+    IN  HANDLE hDeviceContext,
+    OUT PCMD_STATUS pStatus
+    )
+{
+
+    PSDevice     pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject    pMgmt = pDevice->pMgmt;
+    PKnownBSS       pCurr = NULL;
+    UINT            ii, uu;
+    PWLAN_IE_SUPP_RATES pItemRates = NULL;
+    PWLAN_IE_SUPP_RATES pItemExtRates = NULL;
+    PWLAN_IE_SSID   pItemSSID;
+    UINT            uRateLen = WLAN_RATES_MAXLEN;
+    WORD            wMaxBasicRate = RATE_1M;
+    WORD            wMaxSuppRate = RATE_1M;
+    WORD            wSuppRate;
+    BYTE            byTopCCKBasicRate = RATE_1M;
+    BYTE            byTopOFDMBasicRate = RATE_1M;
+
+
+    for (ii = 0; ii < MAX_BSS_NUM; ii++) {
+        if (pMgmt->sBSSList[ii].bActive == TRUE)
+            break;
+    }
+
+    if (ii == MAX_BSS_NUM) {
+       *pStatus = CMD_STATUS_RESOURCES;
+        DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "BSS finding:BSS list is empty.\n");
+       return;
+    };
+
+    // memset(pMgmt->abyDesireBSSID, 0,  WLAN_BSSID_LEN);
+    // Search known BSS list for prefer BSSID or SSID
+
+    pCurr = BSSpSearchBSSList(pDevice,
+                              pMgmt->abyDesireBSSID,
+                              pMgmt->abyDesireSSID,
+                              pMgmt->eConfigPHYMode
+                              );
+
+    if (pCurr == NULL){
+       *pStatus = CMD_STATUS_RESOURCES;
+       pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
+       DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Scanning [%s] not found, disconnected !\n", pItemSSID->abySSID);
+       return;
+    };
+
+    DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "AP(BSS) finding:Found a AP(BSS)..\n");
+    if (WLAN_GET_CAP_INFO_ESS(cpu_to_le16(pCurr->wCapInfo))){
+
+        if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA)||(pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK)) {
+
+    // patch for CISCO migration mode
+/*
+            if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
+                if (WPA_SearchRSN(0, WPA_TKIP, pCurr) == FALSE) {
+                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No match RSN info. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
+                    // encryption mode error
+                    pMgmt->eCurrState = WMAC_STATE_IDLE;
+                    return;
+                }
+            } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
+                if (WPA_SearchRSN(0, WPA_AESCCMP, pCurr) == FALSE) {
+                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No match RSN info. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
+                    // encryption mode error
+                    pMgmt->eCurrState = WMAC_STATE_IDLE;
+                    return;
+                }
+            }
+*/
+        }
+
+#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+       //if(pDevice->bWPASuppWextEnabled == TRUE)
+            Encyption_Rebuild(pDevice, pCurr);
+#endif
+        // Infrastructure BSS
+        s_vMgrSynchBSS(pDevice,
+                       WMAC_MODE_ESS_STA,
+                       pCurr,
+                       pStatus
+                       );
+
+        if (*pStatus == CMD_STATUS_SUCCESS){
+
+            // Adopt this BSS state vars in Mgmt Object
+            pMgmt->uCurrChannel = pCurr->uChannel;
+
+            memset(pMgmt->abyCurrSuppRates, 0 , WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1);
+            memset(pMgmt->abyCurrExtSuppRates, 0 , WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1);
+
+            if (pCurr->eNetworkTypeInUse == PHY_TYPE_11B) {
+                uRateLen = WLAN_RATES_MAXLEN_11B;
+            }
+
+            pItemRates = (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates;
+            pItemExtRates = (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates;
+
+            // Parse Support Rate IE
+            pItemRates->byElementID = WLAN_EID_SUPP_RATES;
+            pItemRates->len = RATEuSetIE((PWLAN_IE_SUPP_RATES)pCurr->abySuppRates,
+                                         pItemRates,
+                                         uRateLen);
+
+            // Parse Extension Support Rate IE
+            pItemExtRates->byElementID = WLAN_EID_EXTSUPP_RATES;
+            pItemExtRates->len = RATEuSetIE((PWLAN_IE_SUPP_RATES)pCurr->abyExtSuppRates,
+                                            pItemExtRates,
+                                            uRateLen);
+            // Stuffing Rate IE
+            if ((pItemExtRates->len > 0) && (pItemRates->len < 8)) {
+                for (ii = 0; ii < (UINT)(8 - pItemRates->len); ) {
+                    pItemRates->abyRates[pItemRates->len + ii] = pItemExtRates->abyRates[ii];
+                    ii ++;
+                    if (pItemExtRates->len <= ii)
+                        break;
+                }
+                pItemRates->len += (BYTE)ii;
+                if (pItemExtRates->len - ii > 0) {
+                    pItemExtRates->len -= (BYTE)ii;
+                    for (uu = 0; uu < pItemExtRates->len; uu ++) {
+                        pItemExtRates->abyRates[uu] = pItemExtRates->abyRates[uu + ii];
+                    }
+                } else {
+                    pItemExtRates->len = 0;
+                }
+            }
+
+            RATEvParseMaxRate((PVOID)pDevice, pItemRates, pItemExtRates, TRUE,
+                              &wMaxBasicRate, &wMaxSuppRate, &wSuppRate,
+                              &byTopCCKBasicRate, &byTopOFDMBasicRate);
+
+            // TODO: deal with if wCapInfo the privacy is on, but station WEP is off
+            // TODO: deal with if wCapInfo the PS-Pollable is on.
+            pMgmt->wCurrBeaconPeriod = pCurr->wBeaconInterval;
+            memset(pMgmt->abyCurrSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+            memcpy(pMgmt->abyCurrBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN);
+            memcpy(pMgmt->abyCurrSSID, pCurr->abySSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+
+            pMgmt->eCurrMode = WMAC_MODE_ESS_STA;
+
+            pMgmt->eCurrState = WMAC_STATE_JOINTED;
+            // Adopt BSS state in Adapter Device Object
+            //pDevice->byOpMode = OP_MODE_INFRASTRUCTURE;
+//            memcpy(pDevice->abyBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN);
+
+            // Add current BSS to Candidate list
+            // This should only works for WPA2 BSS, and WPA2 BSS check must be done before.
+            if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) {
+                BOOL bResult = bAdd_PMKID_Candidate((HANDLE)pDevice, pMgmt->abyCurrBSSID, &pCurr->sRSNCapObj);
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"bAdd_PMKID_Candidate: 1(%d)\n", bResult);
+                if (bResult == FALSE) {
+                    vFlush_PMKID_Candidate((HANDLE)pDevice);
+                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vFlush_PMKID_Candidate: 4\n");
+                    bAdd_PMKID_Candidate((HANDLE)pDevice, pMgmt->abyCurrBSSID, &pCurr->sRSNCapObj);
+                }
+            }
+
+            // Preamble type auto-switch: if AP can receive short-preamble cap,
+            // we can turn on too.
+
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Join ESS\n");
+
+
+
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"End of Join AP -- A/B/G Action\n");
+        }
+        else {
+            pMgmt->eCurrState = WMAC_STATE_IDLE;
+        };
+
+
+     }
+     else {
+        // ad-hoc mode BSS
+        if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
+
+            if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
+                if (WPA_SearchRSN(0, WPA_TKIP, pCurr) == FALSE) {
+                    // encryption mode error
+                    pMgmt->eCurrState = WMAC_STATE_IDLE;
+                    return;
+                }
+            } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
+                if (WPA_SearchRSN(0, WPA_AESCCMP, pCurr) == FALSE) {
+                    // encryption mode error
+                    pMgmt->eCurrState = WMAC_STATE_IDLE;
+                    return;
+                }
+            } else {
+                // encryption mode error
+                pMgmt->eCurrState = WMAC_STATE_IDLE;
+                return;
+            }
+        }
+
+        s_vMgrSynchBSS(pDevice,
+                       WMAC_MODE_IBSS_STA,
+                       pCurr,
+                       pStatus
+                       );
+
+        if (*pStatus == CMD_STATUS_SUCCESS){
+            // Adopt this BSS state vars in Mgmt Object
+            // TODO: check if CapInfo privacy on, but we don't..
+            pMgmt->uCurrChannel = pCurr->uChannel;
+
+
+            // Parse Support Rate IE
+            pMgmt->abyCurrSuppRates[0] = WLAN_EID_SUPP_RATES;
+            pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pCurr->abySuppRates,
+                                                    (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
+                                                    WLAN_RATES_MAXLEN_11B);
+            // set basic rate
+            RATEvParseMaxRate((PVOID)pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
+                              NULL, TRUE, &wMaxBasicRate, &wMaxSuppRate, &wSuppRate,
+                              &byTopCCKBasicRate, &byTopOFDMBasicRate);
+
+            pMgmt->wCurrCapInfo = pCurr->wCapInfo;
+            pMgmt->wCurrBeaconPeriod = pCurr->wBeaconInterval;
+            memset(pMgmt->abyCurrSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN);
+            memcpy(pMgmt->abyCurrBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN);
+            memcpy(pMgmt->abyCurrSSID, pCurr->abySSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN);
+//          pMgmt->wCurrATIMWindow = pCurr->wATIMWindow;
+            MACvWriteATIMW(pDevice->PortOffset, pMgmt->wCurrATIMWindow);
+            pMgmt->eCurrMode = WMAC_MODE_IBSS_STA;
+
+            pMgmt->eCurrState = WMAC_STATE_STARTED;
+            // Adopt BSS state in Adapter Device Object
+            //pDevice->byOpMode = OP_MODE_ADHOC;
+//            pDevice->bLinkPass = TRUE;
+//            memcpy(pDevice->abyBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN);
+
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Join IBSS ok:%02x-%02x-%02x-%02x-%02x-%02x \n",
+                  pMgmt->abyCurrBSSID[0],
+                  pMgmt->abyCurrBSSID[1],
+                  pMgmt->abyCurrBSSID[2],
+                  pMgmt->abyCurrBSSID[3],
+                  pMgmt->abyCurrBSSID[4],
+                  pMgmt->abyCurrBSSID[5]
+                );
+            // Preamble type auto-switch: if AP can receive short-preamble cap,
+            // and if registry setting is short preamble we can turn on too.
+
+            // Prepare beacon
+            bMgrPrepareBeaconToSend((HANDLE)pDevice, pMgmt);
+        }
+        else {
+            pMgmt->eCurrState = WMAC_STATE_IDLE;
+        };
+     };
+    return;
+}
+
+
+
+/*+
+ *
+ * Routine Description:
+ * Set HW to synchronize a specific BSS from known BSS list.
+ *
+ *
+ * Return Value:
+ *    PCM_STATUS
+ *
+-*/
+static
+VOID
+s_vMgrSynchBSS (
+    IN PSDevice      pDevice,
+    IN UINT          uBSSMode,
+    IN PKnownBSS     pCurr,
+    OUT PCMD_STATUS  pStatus
+    )
+{
+    CARD_PHY_TYPE   ePhyType = PHY_TYPE_11B;
+    PSMgmtObject  pMgmt = pDevice->pMgmt;
+//    int     ii;
+                                                     //1M,   2M,   5M,   11M,  18M,  24M,  36M,  54M
+    BYTE abyCurrSuppRatesG[] = {WLAN_EID_SUPP_RATES, 8, 0x02, 0x04, 0x0B, 0x16, 0x24, 0x30, 0x48, 0x6C};
+    BYTE abyCurrExtSuppRatesG[] = {WLAN_EID_EXTSUPP_RATES, 4, 0x0C, 0x12, 0x18, 0x60};
+                                                           //6M,   9M,   12M,  48M
+    BYTE abyCurrSuppRatesA[] = {WLAN_EID_SUPP_RATES, 8, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C};
+    BYTE abyCurrSuppRatesB[] = {WLAN_EID_SUPP_RATES, 4, 0x02, 0x04, 0x0B, 0x16};
+
+
+    *pStatus = CMD_STATUS_FAILURE;
+
+    if (s_bCipherMatch(pCurr,
+                       pDevice->eEncryptionStatus,
+                       &(pMgmt->byCSSPK),
+                       &(pMgmt->byCSSGK)) == FALSE) {
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "s_bCipherMatch Fail .......\n");
+        return;
+    }
+
+    pMgmt->pCurrBSS = pCurr;
+
+    // if previous mode is IBSS.
+    if(pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
+        MACvRegBitsOff(pDevice->PortOffset, MAC_REG_BCNDMACTL, BEACON_READY);
+        MACvRegBitsOff(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX);
+    }
+
+    // Init the BSS informations
+    pDevice->bCCK = TRUE;
+    pDevice->bProtectMode = FALSE;
+    MACvDisableProtectMD(pDevice->PortOffset);
+    pDevice->bBarkerPreambleMd = FALSE;
+    MACvDisableBarkerPreambleMd(pDevice->PortOffset);
+    pDevice->bNonERPPresent = FALSE;
+    pDevice->byPreambleType = 0;
+    pDevice->wBasicRate = 0;
+    // Set Basic Rate
+    CARDbAddBasicRate((PVOID)pDevice, RATE_1M);
+    // calculate TSF offset
+    // TSF Offset = Received Timestamp TSF - Marked Local's TSF
+    CARDbUpdateTSF(pDevice, pCurr->byRxRate, pCurr->qwBSSTimestamp, pCurr->qwLocalTSF);
+
+    CARDbSetBeaconPeriod(pDevice, pCurr->wBeaconInterval);
+
+    // set Next TBTT
+    // Next TBTT = ((local_current_TSF / beacon_interval) + 1 ) * beacon_interval
+    CARDvSetFirstNextTBTT(pDevice->PortOffset, pCurr->wBeaconInterval);
+
+    // set BSSID
+    MACvWriteBSSIDAddress(pDevice->PortOffset, pCurr->abyBSSID);
+
+    MACvReadBSSIDAddress(pDevice->PortOffset, pMgmt->abyCurrBSSID);
+
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Sync:set CurrBSSID address = %02x-%02x-%02x=%02x-%02x-%02x\n",
+        pMgmt->abyCurrBSSID[0],
+        pMgmt->abyCurrBSSID[1],
+        pMgmt->abyCurrBSSID[2],
+        pMgmt->abyCurrBSSID[3],
+        pMgmt->abyCurrBSSID[4],
+        pMgmt->abyCurrBSSID[5]);
+
+    if (pCurr->eNetworkTypeInUse == PHY_TYPE_11A) {
+        if ((pMgmt->eConfigPHYMode == PHY_TYPE_11A) ||
+            (pMgmt->eConfigPHYMode == PHY_TYPE_AUTO)) {
+            ePhyType = PHY_TYPE_11A;
+        } else {
+            return;
+        }
+    } else if (pCurr->eNetworkTypeInUse == PHY_TYPE_11B) {
+        if ((pMgmt->eConfigPHYMode == PHY_TYPE_11B) ||
+            (pMgmt->eConfigPHYMode == PHY_TYPE_11G) ||
+            (pMgmt->eConfigPHYMode == PHY_TYPE_AUTO)) {
+            ePhyType = PHY_TYPE_11B;
+        } else {
+            return;
+        }
+    } else {
+        if ((pMgmt->eConfigPHYMode == PHY_TYPE_11G) ||
+            (pMgmt->eConfigPHYMode == PHY_TYPE_AUTO)) {
+            ePhyType = PHY_TYPE_11G;
+        } else if (pMgmt->eConfigPHYMode == PHY_TYPE_11B) {
+            ePhyType = PHY_TYPE_11B;
+        } else {
+            return;
+        }
+    }
+
+    if (ePhyType == PHY_TYPE_11A) {
+        MEMvCopy(pMgmt->abyCurrSuppRates, &abyCurrSuppRatesA[0], sizeof(abyCurrSuppRatesA));
+        pMgmt->abyCurrExtSuppRates[1] = 0;
+    } else if (ePhyType == PHY_TYPE_11B) {
+        MEMvCopy(pMgmt->abyCurrSuppRates, &abyCurrSuppRatesB[0], sizeof(abyCurrSuppRatesB));
+        pMgmt->abyCurrExtSuppRates[1] = 0;
+    } else {
+        MEMvCopy(pMgmt->abyCurrSuppRates, &abyCurrSuppRatesG[0], sizeof(abyCurrSuppRatesG));
+        MEMvCopy(pMgmt->abyCurrExtSuppRates, &abyCurrExtSuppRatesG[0], sizeof(abyCurrExtSuppRatesG));
+    }
+
+
+    if (WLAN_GET_CAP_INFO_ESS(pCurr->wCapInfo)) {
+        CARDbSetBSSID(pMgmt->pAdapter, pCurr->abyBSSID, OP_MODE_INFRASTRUCTURE);
+        // Add current BSS to Candidate list
+        // This should only works for WPA2 BSS, and WPA2 BSS check must be done before.
+        if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) {
+            CARDbAdd_PMKID_Candidate(pMgmt->pAdapter, pMgmt->abyCurrBSSID, pCurr->sRSNCapObj.bRSNCapExist, pCurr->sRSNCapObj.wRSNCap);
+        }
+    } else {
+        CARDbSetBSSID(pMgmt->pAdapter, pCurr->abyBSSID, OP_MODE_ADHOC);
+    }
+
+    if (CARDbSetPhyParameter(   pMgmt->pAdapter,
+                                ePhyType,
+                                pCurr->wCapInfo,
+                                pCurr->sERP.byERP,
+                                pMgmt->abyCurrSuppRates,
+                                pMgmt->abyCurrExtSuppRates
+                            ) != TRUE) {
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "<----s_bSynchBSS Set Phy Mode Fail [%d]\n", ePhyType);
+        return;
+    }
+    // set channel and clear NAV
+    if (CARDbSetChannel(pMgmt->pAdapter, pCurr->uChannel) == FALSE) {
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "<----s_bSynchBSS Set Channel [%d]\n", pCurr->uChannel);
+        return;
+    }
+
+/*
+    for (ii=0;ii<BB_VGA_LEVEL;ii++) {
+        if (pCurr->ldBmMAX< pDevice->ldBmThreshold[ii]) {
+            pDevice->byBBVGANew = pDevice->abyBBVGA[ii];
+            break;
+        }
+    }
+
+    if (pDevice->byBBVGANew != pDevice->byBBVGACurrent) {
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"RSSI[%d] NewGain[%d] OldGain[%d] \n",
+                        (int)pCurr->ldBmMAX, pDevice->byBBVGANew, pDevice->byBBVGACurrent);
+        printk("RSSI[%d] NewGain[%d] OldGain[%d] \n",
+                        (int)pCurr->ldBmMAX, pDevice->byBBVGANew, pDevice->byBBVGACurrent);
+        BBvSetVGAGainOffset(pDevice, pDevice->byBBVGANew);
+    }
+    printk("ldBmMAX[%d] NewGain[%d] OldGain[%d] \n",
+           (int)pCurr->ldBmMAX, pDevice->byBBVGANew, pDevice->byBBVGACurrent);
+*/
+    pMgmt->uCurrChannel = pCurr->uChannel;
+    pMgmt->eCurrentPHYMode = ePhyType;
+    pMgmt->byERPContext = pCurr->sERP.byERP;
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Sync:Set to channel = [%d]\n", (INT)pCurr->uChannel);
+
+
+    *pStatus = CMD_STATUS_SUCCESS;
+
+
+    return;
+};
+
+//mike add: fix NetworkManager 0.7.0 hidden ssid mode in WPA encryption
+//                   ,need reset eAuthenMode and eEncryptionStatus
+ static VOID  Encyption_Rebuild(
+    IN PSDevice pDevice,
+    IN PKnownBSS pCurr
+ )
+ {
+  PSMgmtObject  pMgmt = &(pDevice->sMgmtObj);
+ // 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, pCurr->abyBSSID)) {
+             //       uSameBssidNum++;
+               //   }
+           // }
+  //   if( uSameBssidNum>=2) {  //we only check AP in hidden sssid  mode
+        if ((pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) ||           //networkmanager 0.7.0 does not give the pairwise-key selsection,
+             (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) {         // so we need re-selsect it according to real pairwise-key info.
+               if(pCurr->bWPAValid == TRUE)  {   //WPA-PSK
+                          pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK;
+                   if(pCurr->abyPKType[0] == WPA_TKIP) {
+                       pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;    //TKIP
+                       printk("Encyption_Rebuild--->ssid reset config to [WPAPSK-TKIP]\n");
+                     }
+                  else if(pCurr->abyPKType[0] == WPA_AESCCMP) {
+                       pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;    //AES
+                          printk("Encyption_Rebuild--->ssid reset config to [WPAPSK-AES]\n");
+                    }
+                       }
+               else if(pCurr->bWPA2Valid == TRUE) {  //WPA2-PSK
+                         pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK;
+                      if(pCurr->abyCSSPK[0] == WLAN_11i_CSS_TKIP) {
+                          pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;     //TKIP
+                             printk("Encyption_Rebuild--->ssid reset config to [WPA2PSK-TKIP]\n");
+                       }
+                      else if(pCurr->abyCSSPK[0] == WLAN_11i_CSS_CCMP) {
+                          pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;    //AES
+                            printk("Encyption_Rebuild--->ssid reset config to [WPA2PSK-AES]\n");
+                       }
+                       }
+              }
+        //  }
+      return;
+ }
+
+
+/*+
+ *
+ * Routine Description:
+ *  Format TIM field
+ *
+ *
+ * Return Value:
+ *    VOID
+ *
+-*/
+
+static
+VOID
+s_vMgrFormatTIM(
+    IN PSMgmtObject pMgmt,
+    IN PWLAN_IE_TIM pTIM
+    )
+{
+    BYTE        byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
+    BYTE        byMap;
+    UINT        ii, jj;
+    BOOL        bStartFound = FALSE;
+    BOOL        bMulticast = FALSE;
+    WORD        wStartIndex = 0;
+    WORD        wEndIndex = 0;
+
+
+    // Find size of partial virtual bitmap
+    for (ii = 0; ii < (MAX_NODE_NUM + 1); ii++) {
+        byMap = pMgmt->abyPSTxMap[ii];
+        if (!ii) {
+            // Mask out the broadcast bit which is indicated separately.
+            bMulticast = (byMap & byMask[0]) != 0;
+            if(bMulticast) {
+               pMgmt->sNodeDBTable[0].bRxPSPoll = TRUE;
+            }
+            byMap = 0;
+        }
+        if (byMap) {
+            if (!bStartFound) {
+                bStartFound = TRUE;
+                wStartIndex = ii;
+            }
+            wEndIndex = ii;
+        }
+    };
+
+
+    // Round start index down to nearest even number
+    wStartIndex &=  ~BIT0;
+
+    // Round end index up to nearest even number
+    wEndIndex = ((wEndIndex + 1) & ~BIT0);
+
+    // Size of element payload
+
+    pTIM->len =  3 + (wEndIndex - wStartIndex) + 1;
+
+    // Fill in the Fixed parts of the TIM
+    pTIM->byDTIMCount = pMgmt->byDTIMCount;
+    pTIM->byDTIMPeriod = pMgmt->byDTIMPeriod;
+    pTIM->byBitMapCtl = (bMulticast ? TIM_MULTICAST_MASK : 0) |
+        (((wStartIndex >> 1) << 1) & TIM_BITMAPOFFSET_MASK);
+
+    // Append variable part of TIM
+
+    for (ii = wStartIndex, jj =0 ; ii <= wEndIndex; ii++, jj++) {
+         pTIM->byVirtBitMap[jj] = pMgmt->abyPSTxMap[ii];
+    }
+
+    // Aid = 0 don't used.
+    pTIM->byVirtBitMap[0]  &= ~BIT0;
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *  Constructs an Beacon frame( Ad-hoc mode)
+ *
+ *
+ * Return Value:
+ *    PTR to frame; or NULL on allocation failue
+ *
+-*/
+
+static
+PSTxMgmtPacket
+s_MgrMakeBeacon(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN WORD wCurrCapInfo,
+    IN WORD wCurrBeaconPeriod,
+    IN UINT uCurrChannel,
+    IN WORD wCurrATIMWinodw,
+    IN PWLAN_IE_SSID pCurrSSID,
+    IN PBYTE pCurrBSSID,
+    IN PWLAN_IE_SUPP_RATES pCurrSuppRates,
+    IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates
+    )
+{
+    PSTxMgmtPacket      pTxPacket = NULL;
+    WLAN_FR_BEACON      sFrame;
+    BYTE                abyBroadcastAddr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+    PBYTE               pbyBuffer;
+    UINT                uLength = 0;
+    PWLAN_IE_IBSS_DFS   pIBSSDFS = NULL;
+    UINT                ii;
+
+    // prepare beacon frame
+    pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
+    memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_BEACON_FR_MAXLEN);
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+    // Setup the sFrame structure.
+    sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
+    sFrame.len = WLAN_BEACON_FR_MAXLEN;
+    vMgrEncodeBeacon(&sFrame);
+    // Setup the header
+    sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
+        (
+        WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
+        WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_BEACON)
+        ));
+
+    if (pDevice->bEnablePSMode) {
+        sFrame.pHdr->sA3.wFrameCtl |= cpu_to_le16((WORD)WLAN_SET_FC_PWRMGT(1));
+    }
+
+    memcpy( sFrame.pHdr->sA3.abyAddr1, abyBroadcastAddr, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr3, pCurrBSSID, WLAN_BSSID_LEN);
+    *sFrame.pwBeaconInterval = cpu_to_le16(wCurrBeaconPeriod);
+    *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo);
+    // Copy SSID
+    sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len);
+    sFrame.len += ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len + WLAN_IEHDR_LEN;
+    memcpy(sFrame.pSSID,
+             pCurrSSID,
+             ((PWLAN_IE_SSID)pCurrSSID)->len + WLAN_IEHDR_LEN
+            );
+    // Copy the rate set
+    sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
+    sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN;
+    memcpy(sFrame.pSuppRates,
+           pCurrSuppRates,
+           ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN
+          );
+    // DS parameter
+    if (pDevice->eCurrentPHYType != PHY_TYPE_11A) {
+        sFrame.pDSParms = (PWLAN_IE_DS_PARMS)(sFrame.pBuf + sFrame.len);
+        sFrame.len += (1) + WLAN_IEHDR_LEN;
+        sFrame.pDSParms->byElementID = WLAN_EID_DS_PARMS;
+        sFrame.pDSParms->len = 1;
+        sFrame.pDSParms->byCurrChannel = (BYTE)uCurrChannel;
+    }
+    // TIM field
+    if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
+        sFrame.pTIM = (PWLAN_IE_TIM)(sFrame.pBuf + sFrame.len);
+        sFrame.pTIM->byElementID = WLAN_EID_TIM;
+        s_vMgrFormatTIM(pMgmt, sFrame.pTIM);
+        sFrame.len += (WLAN_IEHDR_LEN + sFrame.pTIM->len);
+    }
+
+    if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
+
+        // IBSS parameter
+        sFrame.pIBSSParms = (PWLAN_IE_IBSS_PARMS)(sFrame.pBuf + sFrame.len);
+        sFrame.len += (2) + WLAN_IEHDR_LEN;
+        sFrame.pIBSSParms->byElementID = WLAN_EID_IBSS_PARMS;
+        sFrame.pIBSSParms->len = 2;
+        sFrame.pIBSSParms->wATIMWindow = wCurrATIMWinodw;
+        if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
+            /* RSN parameter */
+            sFrame.pRSNWPA = (PWLAN_IE_RSN_EXT)(sFrame.pBuf + sFrame.len);
+            sFrame.pRSNWPA->byElementID = WLAN_EID_RSN_WPA;
+            sFrame.pRSNWPA->len = 12;
+            sFrame.pRSNWPA->abyOUI[0] = 0x00;
+            sFrame.pRSNWPA->abyOUI[1] = 0x50;
+            sFrame.pRSNWPA->abyOUI[2] = 0xf2;
+            sFrame.pRSNWPA->abyOUI[3] = 0x01;
+            sFrame.pRSNWPA->wVersion = 1;
+            sFrame.pRSNWPA->abyMulticast[0] = 0x00;
+            sFrame.pRSNWPA->abyMulticast[1] = 0x50;
+            sFrame.pRSNWPA->abyMulticast[2] = 0xf2;
+            if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled)
+                sFrame.pRSNWPA->abyMulticast[3] = 0x04;//AES
+            else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled)
+                sFrame.pRSNWPA->abyMulticast[3] = 0x02;//TKIP
+            else if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled)
+                sFrame.pRSNWPA->abyMulticast[3] = 0x01;//WEP40
+            else
+                sFrame.pRSNWPA->abyMulticast[3] = 0x00;//NONE
+
+            // Pairwise Key Cipher Suite
+            sFrame.pRSNWPA->wPKCount = 0;
+            // Auth Key Management Suite
+            *((PWORD)(sFrame.pBuf + sFrame.len + sFrame.pRSNWPA->len))=0;
+            sFrame.pRSNWPA->len +=2;
+
+            // RSN Capabilites
+            *((PWORD)(sFrame.pBuf + sFrame.len + sFrame.pRSNWPA->len))=0;
+            sFrame.pRSNWPA->len +=2;
+            sFrame.len += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
+        }
+    }
+
+    if ((pMgmt->b11hEnable == TRUE) &&
+        (pMgmt->eCurrentPHYMode == PHY_TYPE_11A)) {
+        // Country IE
+        pbyBuffer = (PBYTE)(sFrame.pBuf + sFrame.len);
+        CARDvSetCountryIE(pMgmt->pAdapter, pbyBuffer);
+        CARDvSetCountryInfo(pMgmt->pAdapter, PHY_TYPE_11A, pbyBuffer);
+        uLength += ((PWLAN_IE_COUNTRY) pbyBuffer)->len + WLAN_IEHDR_LEN;
+        pbyBuffer += (((PWLAN_IE_COUNTRY) pbyBuffer)->len + WLAN_IEHDR_LEN);
+        // Power Constrain IE
+        ((PWLAN_IE_PW_CONST) pbyBuffer)->byElementID = WLAN_EID_PWR_CONSTRAINT;
+        ((PWLAN_IE_PW_CONST) pbyBuffer)->len = 1;
+        ((PWLAN_IE_PW_CONST) pbyBuffer)->byPower = 0;
+        pbyBuffer += (1) + WLAN_IEHDR_LEN;
+        uLength += (1) + WLAN_IEHDR_LEN;
+        if (pMgmt->bSwitchChannel == TRUE) {
+            // Channel Switch IE
+            ((PWLAN_IE_CH_SW) pbyBuffer)->byElementID = WLAN_EID_CH_SWITCH;
+            ((PWLAN_IE_CH_SW) pbyBuffer)->len = 3;
+            ((PWLAN_IE_CH_SW) pbyBuffer)->byMode = 1;
+            ((PWLAN_IE_CH_SW) pbyBuffer)->byChannel = CARDbyGetChannelNumber(pMgmt->pAdapter, pMgmt->byNewChannel);
+            ((PWLAN_IE_CH_SW) pbyBuffer)->byCount = 0;
+            pbyBuffer += (3) + WLAN_IEHDR_LEN;
+            uLength += (3) + WLAN_IEHDR_LEN;
+        }
+        // TPC report
+        ((PWLAN_IE_TPC_REP) pbyBuffer)->byElementID = WLAN_EID_TPC_REP;
+        ((PWLAN_IE_TPC_REP) pbyBuffer)->len = 2;
+        ((PWLAN_IE_TPC_REP) pbyBuffer)->byTxPower = CARDbyGetTransmitPower(pMgmt->pAdapter);
+        ((PWLAN_IE_TPC_REP) pbyBuffer)->byLinkMargin = 0;
+        pbyBuffer += (2) + WLAN_IEHDR_LEN;
+        uLength += (2) + WLAN_IEHDR_LEN;
+        // IBSS DFS
+        if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP) {
+            pIBSSDFS = (PWLAN_IE_IBSS_DFS) pbyBuffer;
+            pIBSSDFS->byElementID = WLAN_EID_IBSS_DFS;
+            pIBSSDFS->len = 7;
+            MEMvCopy(   pIBSSDFS->abyDFSOwner,
+                        pMgmt->abyIBSSDFSOwner,
+                        6);
+            pIBSSDFS->byDFSRecovery = pMgmt->byIBSSDFSRecovery;
+            pbyBuffer += (7) + WLAN_IEHDR_LEN;
+            uLength += (7) + WLAN_IEHDR_LEN;
+            for(ii=CB_MAX_CHANNEL_24G+1; ii<=CB_MAX_CHANNEL; ii++ ) {
+                if (CARDbGetChannelMapInfo(pMgmt->pAdapter, ii, pbyBuffer, pbyBuffer+1) == TRUE) {
+                    pbyBuffer += 2;
+                    uLength += 2;
+                    pIBSSDFS->len += 2;
+                }
+            }
+        }
+        sFrame.len += uLength;
+    }
+
+    if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) {
+        sFrame.pERP = (PWLAN_IE_ERP)(sFrame.pBuf + sFrame.len);
+        sFrame.len += 1 + WLAN_IEHDR_LEN;
+        sFrame.pERP->byElementID = WLAN_EID_ERP;
+        sFrame.pERP->len = 1;
+        sFrame.pERP->byContext = 0;
+        if (pDevice->bProtectMode == TRUE)
+            sFrame.pERP->byContext |= WLAN_EID_ERP_USE_PROTECTION;
+        if (pDevice->bNonERPPresent == TRUE)
+            sFrame.pERP->byContext |= WLAN_EID_ERP_NONERP_PRESENT;
+        if (pDevice->bBarkerPreambleMd == TRUE)
+            sFrame.pERP->byContext |= WLAN_EID_ERP_BARKER_MODE;
+    }
+    if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) {
+        sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
+        sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN;
+        MEMvCopy(sFrame.pExtSuppRates,
+             pCurrExtSuppRates,
+             ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN
+             );
+    }
+    // hostapd wpa/wpa2 IE
+    if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && (pDevice->bEnableHostapd == TRUE)) {
+         if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
+             if (pMgmt->wWPAIELen != 0) {
+                 sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len);
+                 memcpy(sFrame.pRSN, pMgmt->abyWPAIE, pMgmt->wWPAIELen);
+                 sFrame.len += pMgmt->wWPAIELen;
+             }
+         }
+    }
+
+    /* Adjust the length fields */
+    pTxPacket->cbMPDULen = sFrame.len;
+    pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
+
+    return pTxPacket;
+}
+
+
+
+
+
+/*+
+ *
+ * Routine Description:
+ *  Constructs an Prob-response frame
+ *
+ *
+ * Return Value:
+ *    PTR to frame; or NULL on allocation failue
+ *
+-*/
+
+
+
+
+PSTxMgmtPacket
+s_MgrMakeProbeResponse(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN WORD wCurrCapInfo,
+    IN WORD wCurrBeaconPeriod,
+    IN UINT uCurrChannel,
+    IN WORD wCurrATIMWinodw,
+    IN PBYTE pDstAddr,
+    IN PWLAN_IE_SSID pCurrSSID,
+    IN PBYTE pCurrBSSID,
+    IN PWLAN_IE_SUPP_RATES pCurrSuppRates,
+    IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates,
+    IN BYTE byPHYType
+    )
+{
+    PSTxMgmtPacket      pTxPacket = NULL;
+    WLAN_FR_PROBERESP   sFrame;
+    PBYTE               pbyBuffer;
+    UINT                uLength = 0;
+    PWLAN_IE_IBSS_DFS   pIBSSDFS = NULL;
+    UINT                ii;
+
+
+    pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
+    memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_PROBERESP_FR_MAXLEN);
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+    // Setup the sFrame structure.
+    sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
+    sFrame.len = WLAN_PROBERESP_FR_MAXLEN;
+    vMgrEncodeProbeResponse(&sFrame);
+    // Setup the header
+    sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
+        (
+        WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
+        WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_PROBERESP)
+        ));
+    memcpy( sFrame.pHdr->sA3.abyAddr1, pDstAddr, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr3, pCurrBSSID, WLAN_BSSID_LEN);
+    *sFrame.pwBeaconInterval = cpu_to_le16(wCurrBeaconPeriod);
+    *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo);
+
+    if (byPHYType == BB_TYPE_11B) {
+        *sFrame.pwCapInfo &= cpu_to_le16((WORD)~(WLAN_SET_CAP_INFO_SHORTSLOTTIME(1)));
+    }
+
+    // Copy SSID
+    sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len);
+    sFrame.len += ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len + WLAN_IEHDR_LEN;
+    memcpy(sFrame.pSSID,
+           pCurrSSID,
+           ((PWLAN_IE_SSID)pCurrSSID)->len + WLAN_IEHDR_LEN
+           );
+    // Copy the rate set
+    sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
+
+    sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN;
+    memcpy(sFrame.pSuppRates,
+           pCurrSuppRates,
+           ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN
+          );
+
+    // DS parameter
+    if (pDevice->eCurrentPHYType != PHY_TYPE_11A) {
+        sFrame.pDSParms = (PWLAN_IE_DS_PARMS)(sFrame.pBuf + sFrame.len);
+        sFrame.len += (1) + WLAN_IEHDR_LEN;
+        sFrame.pDSParms->byElementID = WLAN_EID_DS_PARMS;
+        sFrame.pDSParms->len = 1;
+        sFrame.pDSParms->byCurrChannel = (BYTE)uCurrChannel;
+    }
+
+    if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP) {
+        // IBSS parameter
+        sFrame.pIBSSParms = (PWLAN_IE_IBSS_PARMS)(sFrame.pBuf + sFrame.len);
+        sFrame.len += (2) + WLAN_IEHDR_LEN;
+        sFrame.pIBSSParms->byElementID = WLAN_EID_IBSS_PARMS;
+        sFrame.pIBSSParms->len = 2;
+        sFrame.pIBSSParms->wATIMWindow = 0;
+    }
+    if (pDevice->eCurrentPHYType == PHY_TYPE_11G) {
+        sFrame.pERP = (PWLAN_IE_ERP)(sFrame.pBuf + sFrame.len);
+        sFrame.len += 1 + WLAN_IEHDR_LEN;
+        sFrame.pERP->byElementID = WLAN_EID_ERP;
+        sFrame.pERP->len = 1;
+        sFrame.pERP->byContext = 0;
+        if (pDevice->bProtectMode == TRUE)
+            sFrame.pERP->byContext |= WLAN_EID_ERP_USE_PROTECTION;
+        if (pDevice->bNonERPPresent == TRUE)
+            sFrame.pERP->byContext |= WLAN_EID_ERP_NONERP_PRESENT;
+        if (pDevice->bBarkerPreambleMd == TRUE)
+            sFrame.pERP->byContext |= WLAN_EID_ERP_BARKER_MODE;
+    }
+
+    if ((pMgmt->b11hEnable == TRUE) &&
+        (pMgmt->eCurrentPHYMode == PHY_TYPE_11A)) {
+        // Country IE
+        pbyBuffer = (PBYTE)(sFrame.pBuf + sFrame.len);
+        CARDvSetCountryIE(pMgmt->pAdapter, pbyBuffer);
+        CARDvSetCountryInfo(pMgmt->pAdapter, PHY_TYPE_11A, pbyBuffer);
+        uLength += ((PWLAN_IE_COUNTRY) pbyBuffer)->len + WLAN_IEHDR_LEN;
+        pbyBuffer += (((PWLAN_IE_COUNTRY) pbyBuffer)->len + WLAN_IEHDR_LEN);
+        // Power Constrain IE
+        ((PWLAN_IE_PW_CONST) pbyBuffer)->byElementID = WLAN_EID_PWR_CONSTRAINT;
+        ((PWLAN_IE_PW_CONST) pbyBuffer)->len = 1;
+        ((PWLAN_IE_PW_CONST) pbyBuffer)->byPower = 0;
+        pbyBuffer += (1) + WLAN_IEHDR_LEN;
+        uLength += (1) + WLAN_IEHDR_LEN;
+        if (pMgmt->bSwitchChannel == TRUE) {
+            // Channel Switch IE
+            ((PWLAN_IE_CH_SW) pbyBuffer)->byElementID = WLAN_EID_CH_SWITCH;
+            ((PWLAN_IE_CH_SW) pbyBuffer)->len = 3;
+            ((PWLAN_IE_CH_SW) pbyBuffer)->byMode = 1;
+            ((PWLAN_IE_CH_SW) pbyBuffer)->byChannel = CARDbyGetChannelNumber(pMgmt->pAdapter, pMgmt->byNewChannel);
+            ((PWLAN_IE_CH_SW) pbyBuffer)->byCount = 0;
+            pbyBuffer += (3) + WLAN_IEHDR_LEN;
+            uLength += (3) + WLAN_IEHDR_LEN;
+        }
+        // TPC report
+        ((PWLAN_IE_TPC_REP) pbyBuffer)->byElementID = WLAN_EID_TPC_REP;
+        ((PWLAN_IE_TPC_REP) pbyBuffer)->len = 2;
+        ((PWLAN_IE_TPC_REP) pbyBuffer)->byTxPower = CARDbyGetTransmitPower(pMgmt->pAdapter);
+        ((PWLAN_IE_TPC_REP) pbyBuffer)->byLinkMargin = 0;
+        pbyBuffer += (2) + WLAN_IEHDR_LEN;
+        uLength += (2) + WLAN_IEHDR_LEN;
+        // IBSS DFS
+        if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP) {
+            pIBSSDFS = (PWLAN_IE_IBSS_DFS) pbyBuffer;
+            pIBSSDFS->byElementID = WLAN_EID_IBSS_DFS;
+            pIBSSDFS->len = 7;
+            MEMvCopy(   pIBSSDFS->abyDFSOwner,
+                        pMgmt->abyIBSSDFSOwner,
+                        6);
+            pIBSSDFS->byDFSRecovery = pMgmt->byIBSSDFSRecovery;
+            pbyBuffer += (7) + WLAN_IEHDR_LEN;
+            uLength += (7) + WLAN_IEHDR_LEN;
+            for(ii=CB_MAX_CHANNEL_24G+1; ii<=CB_MAX_CHANNEL; ii++ ) {
+                if (CARDbGetChannelMapInfo(pMgmt->pAdapter, ii, pbyBuffer, pbyBuffer+1) == TRUE) {
+                    pbyBuffer += 2;
+                    uLength += 2;
+                    pIBSSDFS->len += 2;
+                }
+            }
+        }
+        sFrame.len += uLength;
+    }
+
+
+    if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) {
+        sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
+        sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN;
+        MEMvCopy(sFrame.pExtSuppRates,
+             pCurrExtSuppRates,
+             ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN
+             );
+    }
+
+    // hostapd wpa/wpa2 IE
+    if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && (pDevice->bEnableHostapd == TRUE)) {
+         if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
+             if (pMgmt->wWPAIELen != 0) {
+                 sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len);
+                 memcpy(sFrame.pRSN, pMgmt->abyWPAIE, pMgmt->wWPAIELen);
+                 sFrame.len += pMgmt->wWPAIELen;
+             }
+         }
+    }
+
+    // Adjust the length fields
+    pTxPacket->cbMPDULen = sFrame.len;
+    pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
+
+    return pTxPacket;
+}
+
+
+
+/*+
+ *
+ * Routine Description:
+ *  Constructs an association request frame
+ *
+ *
+ * Return Value:
+ *    A ptr to frame or NULL on allocation failue
+ *
+-*/
+
+
+PSTxMgmtPacket
+s_MgrMakeAssocRequest(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PBYTE pDAddr,
+    IN WORD wCurrCapInfo,
+    IN WORD wListenInterval,
+    IN PWLAN_IE_SSID pCurrSSID,
+    IN PWLAN_IE_SUPP_RATES pCurrRates,
+    IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates
+    )
+{
+    PSTxMgmtPacket      pTxPacket = NULL;
+    WLAN_FR_ASSOCREQ    sFrame;
+    PBYTE               pbyIEs;
+    PBYTE               pbyRSN;
+
+
+    pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
+    memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_ASSOCREQ_FR_MAXLEN);
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+    // Setup the sFrame structure.
+    sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
+    sFrame.len = WLAN_ASSOCREQ_FR_MAXLEN;
+    // format fixed field frame structure
+    vMgrEncodeAssocRequest(&sFrame);
+    // Setup the header
+    sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
+        (
+        WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
+        WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ASSOCREQ)
+        ));
+    memcpy( sFrame.pHdr->sA3.abyAddr1, pDAddr, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
+
+    // Set the capibility and listen interval
+    *(sFrame.pwCapInfo) = cpu_to_le16(wCurrCapInfo);
+    *(sFrame.pwListenInterval) = cpu_to_le16(wListenInterval);
+
+    // sFrame.len point to end of fixed field
+    sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len);
+    sFrame.len += pCurrSSID->len + WLAN_IEHDR_LEN;
+    memcpy(sFrame.pSSID, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN);
+
+    pMgmt->sAssocInfo.AssocInfo.RequestIELength = pCurrSSID->len + WLAN_IEHDR_LEN;
+    pMgmt->sAssocInfo.AssocInfo.OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
+    pbyIEs = pMgmt->sAssocInfo.abyIEs;
+    MEMvCopy(pbyIEs, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN);
+    pbyIEs += pCurrSSID->len + WLAN_IEHDR_LEN;
+
+    // Copy the rate set
+    sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
+    if ((pDevice->eCurrentPHYType == PHY_TYPE_11B) && (pCurrRates->len > 4))
+        sFrame.len += 4 + WLAN_IEHDR_LEN;
+    else
+        sFrame.len += pCurrRates->len + WLAN_IEHDR_LEN;
+    memcpy(sFrame.pSuppRates, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN);
+
+    // Copy the extension rate set
+    if ((pDevice->eCurrentPHYType == PHY_TYPE_11G) && (pCurrExtSuppRates->len > 0)) {
+        sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
+        sFrame.len += pCurrExtSuppRates->len + WLAN_IEHDR_LEN;
+        memcpy(sFrame.pExtSuppRates, pCurrExtSuppRates, pCurrExtSuppRates->len + WLAN_IEHDR_LEN);
+    }
+
+    pMgmt->sAssocInfo.AssocInfo.RequestIELength += pCurrRates->len + WLAN_IEHDR_LEN;
+    MEMvCopy(pbyIEs, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN);
+    pbyIEs += pCurrRates->len + WLAN_IEHDR_LEN;
+
+    // for 802.11h
+    if (pMgmt->b11hEnable == TRUE) {
+        if (sFrame.pCurrPowerCap == NULL) {
+            sFrame.pCurrPowerCap = (PWLAN_IE_PW_CAP)(sFrame.pBuf + sFrame.len);
+            sFrame.len += (2 + WLAN_IEHDR_LEN);
+            sFrame.pCurrPowerCap->byElementID = WLAN_EID_PWR_CAPABILITY;
+            sFrame.pCurrPowerCap->len = 2;
+            CARDvGetPowerCapability(pMgmt->pAdapter,
+                                    &(sFrame.pCurrPowerCap->byMinPower),
+                                    &(sFrame.pCurrPowerCap->byMaxPower)
+                                    );
+        }
+        if (sFrame.pCurrSuppCh == NULL) {
+            sFrame.pCurrSuppCh = (PWLAN_IE_SUPP_CH)(sFrame.pBuf + sFrame.len);
+            sFrame.len += CARDbySetSupportChannels(pMgmt->pAdapter,(PBYTE)sFrame.pCurrSuppCh);
+        }
+    }
+
+    if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA) ||
+         (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) ||
+         (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE)) &&
+        (pMgmt->pCurrBSS != NULL)) {
+        /* WPA IE */
+        sFrame.pRSNWPA = (PWLAN_IE_RSN_EXT)(sFrame.pBuf + sFrame.len);
+        sFrame.pRSNWPA->byElementID = WLAN_EID_RSN_WPA;
+        sFrame.pRSNWPA->len = 16;
+        sFrame.pRSNWPA->abyOUI[0] = 0x00;
+        sFrame.pRSNWPA->abyOUI[1] = 0x50;
+        sFrame.pRSNWPA->abyOUI[2] = 0xf2;
+        sFrame.pRSNWPA->abyOUI[3] = 0x01;
+        sFrame.pRSNWPA->wVersion = 1;
+        //Group Key Cipher Suite
+        sFrame.pRSNWPA->abyMulticast[0] = 0x00;
+        sFrame.pRSNWPA->abyMulticast[1] = 0x50;
+        sFrame.pRSNWPA->abyMulticast[2] = 0xf2;
+        if (pMgmt->byCSSGK == KEY_CTL_WEP) {
+            sFrame.pRSNWPA->abyMulticast[3] = pMgmt->pCurrBSS->byGKType;
+        } else if (pMgmt->byCSSGK == KEY_CTL_TKIP) {
+            sFrame.pRSNWPA->abyMulticast[3] = WPA_TKIP;
+        } else if (pMgmt->byCSSGK == KEY_CTL_CCMP) {
+            sFrame.pRSNWPA->abyMulticast[3] = WPA_AESCCMP;
+        } else {
+            sFrame.pRSNWPA->abyMulticast[3] = WPA_NONE;
+        }
+        // Pairwise Key Cipher Suite
+        sFrame.pRSNWPA->wPKCount = 1;
+        sFrame.pRSNWPA->PKSList[0].abyOUI[0] = 0x00;
+        sFrame.pRSNWPA->PKSList[0].abyOUI[1] = 0x50;
+        sFrame.pRSNWPA->PKSList[0].abyOUI[2] = 0xf2;
+        if (pMgmt->byCSSPK == KEY_CTL_TKIP) {
+            sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_TKIP;
+        } else if (pMgmt->byCSSPK == KEY_CTL_CCMP) {
+            sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_AESCCMP;
+        } else {
+            sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_NONE;
+        }
+        // Auth Key Management Suite
+        pbyRSN = (PBYTE)(sFrame.pBuf + sFrame.len + 2 + sFrame.pRSNWPA->len);
+        *pbyRSN++=0x01;
+        *pbyRSN++=0x00;
+        *pbyRSN++=0x00;
+        *pbyRSN++=0x50;
+        *pbyRSN++=0xf2;
+        if (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) {
+            *pbyRSN++=WPA_AUTH_PSK;
+        }
+        else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA) {
+            *pbyRSN++=WPA_AUTH_IEEE802_1X;
+        }
+        else {
+            *pbyRSN++=WPA_NONE;
+        }
+        sFrame.pRSNWPA->len +=6;
+
+        // RSN Capabilites
+        *pbyRSN++=0x00;
+        *pbyRSN++=0x00;
+        sFrame.pRSNWPA->len +=2;
+        sFrame.len += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
+        // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION
+        pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
+        MEMvCopy(pbyIEs, sFrame.pRSNWPA, sFrame.pRSNWPA->len + WLAN_IEHDR_LEN);
+        pbyIEs += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
+
+    } else if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) ||
+                (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) &&
+               (pMgmt->pCurrBSS != NULL)) {
+        UINT                ii;
+        PWORD               pwPMKID;
+
+        // WPA IE
+        sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len);
+        sFrame.pRSN->byElementID = WLAN_EID_RSN;
+        sFrame.pRSN->len = 6; //Version(2)+GK(4)
+        sFrame.pRSN->wVersion = 1;
+        //Group Key Cipher Suite
+        sFrame.pRSN->abyRSN[0] = 0x00;
+        sFrame.pRSN->abyRSN[1] = 0x0F;
+        sFrame.pRSN->abyRSN[2] = 0xAC;
+        if (pMgmt->byCSSGK == KEY_CTL_WEP) {
+            sFrame.pRSN->abyRSN[3] = pMgmt->pCurrBSS->byCSSGK;
+        } else if (pMgmt->byCSSGK == KEY_CTL_TKIP) {
+            sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_TKIP;
+        } else if (pMgmt->byCSSGK == KEY_CTL_CCMP) {
+            sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_CCMP;
+        } else {
+            sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_UNKNOWN;
+        }
+
+        // Pairwise Key Cipher Suite
+        sFrame.pRSN->abyRSN[4] = 1;
+        sFrame.pRSN->abyRSN[5] = 0;
+        sFrame.pRSN->abyRSN[6] = 0x00;
+        sFrame.pRSN->abyRSN[7] = 0x0F;
+        sFrame.pRSN->abyRSN[8] = 0xAC;
+        if (pMgmt->byCSSPK == KEY_CTL_TKIP) {
+            sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_TKIP;
+        } else if (pMgmt->byCSSPK == KEY_CTL_CCMP) {
+            sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_CCMP;
+        } else if (pMgmt->byCSSPK == KEY_CTL_NONE) {
+            sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_USE_GROUP;
+        } else {
+            sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_UNKNOWN;
+        }
+        sFrame.pRSN->len += 6;
+
+        // Auth Key Management Suite
+        sFrame.pRSN->abyRSN[10] = 1;
+        sFrame.pRSN->abyRSN[11] = 0;
+        sFrame.pRSN->abyRSN[12] = 0x00;
+        sFrame.pRSN->abyRSN[13] = 0x0F;
+        sFrame.pRSN->abyRSN[14] = 0xAC;
+        if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK) {
+            sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_PSK;
+        } else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) {
+            sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_802_1X;
+        } else {
+            sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_UNKNOWN;
+        }
+        sFrame.pRSN->len +=6;
+
+        // RSN Capabilites
+        if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist == TRUE) {
+            MEMvCopy(&sFrame.pRSN->abyRSN[16], &pMgmt->pCurrBSS->sRSNCapObj.wRSNCap, 2);
+        } else {
+            sFrame.pRSN->abyRSN[16] = 0;
+            sFrame.pRSN->abyRSN[17] = 0;
+        }
+        sFrame.pRSN->len +=2;
+
+        if ((pDevice->gsPMKID.BSSIDInfoCount > 0) && (pDevice->bRoaming == TRUE) && (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) {
+            // RSN PMKID
+            pbyRSN = &sFrame.pRSN->abyRSN[18];
+            pwPMKID = (PWORD)pbyRSN; // Point to PMKID count
+            *pwPMKID = 0;            // Initialize PMKID count
+            pbyRSN += 2;             // Point to PMKID list
+            for (ii = 0; ii < pDevice->gsPMKID.BSSIDInfoCount; ii++) {
+                if (MEMEqualMemory(&pDevice->gsPMKID.BSSIDInfo[ii].BSSID[0], pMgmt->abyCurrBSSID, U_ETHER_ADDR_LEN)) {
+                    (*pwPMKID) ++;
+                    MEMvCopy(pbyRSN, pDevice->gsPMKID.BSSIDInfo[ii].PMKID, 16);
+                    pbyRSN += 16;
+                }
+            }
+            if (*pwPMKID != 0) {
+                sFrame.pRSN->len += (2 + (*pwPMKID)*16);
+            }
+        }
+
+        sFrame.len += sFrame.pRSN->len + WLAN_IEHDR_LEN;
+        // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION
+        pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSN->len + WLAN_IEHDR_LEN;
+        MEMvCopy(pbyIEs, sFrame.pRSN, sFrame.pRSN->len + WLAN_IEHDR_LEN);
+        pbyIEs += sFrame.pRSN->len + WLAN_IEHDR_LEN;
+    }
+
+
+    // Adjust the length fields
+    pTxPacket->cbMPDULen = sFrame.len;
+    pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
+    return pTxPacket;
+}
+
+
+
+
+
+
+
+
+/*+
+ *
+ * Routine Description:
+ *  Constructs an re-association request frame
+ *
+ *
+ * Return Value:
+ *    A ptr to frame or NULL on allocation failue
+ *
+-*/
+
+
+PSTxMgmtPacket
+s_MgrMakeReAssocRequest(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PBYTE pDAddr,
+    IN WORD wCurrCapInfo,
+    IN WORD wListenInterval,
+    IN PWLAN_IE_SSID pCurrSSID,
+    IN PWLAN_IE_SUPP_RATES pCurrRates,
+    IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates
+    )
+{
+    PSTxMgmtPacket      pTxPacket = NULL;
+    WLAN_FR_REASSOCREQ  sFrame;
+    PBYTE               pbyIEs;
+    PBYTE               pbyRSN;
+
+
+    pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
+    memset( pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_REASSOCREQ_FR_MAXLEN);
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+    /* Setup the sFrame structure. */
+    sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
+    sFrame.len = WLAN_REASSOCREQ_FR_MAXLEN;
+
+    // format fixed field frame structure
+    vMgrEncodeReassocRequest(&sFrame);
+
+    /* Setup the header */
+    sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
+        (
+        WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
+        WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_REASSOCREQ)
+        ));
+    memcpy( sFrame.pHdr->sA3.abyAddr1, pDAddr, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
+
+    /* Set the capibility and listen interval */
+    *(sFrame.pwCapInfo) = cpu_to_le16(wCurrCapInfo);
+    *(sFrame.pwListenInterval) = cpu_to_le16(wListenInterval);
+
+    memcpy(sFrame.pAddrCurrAP, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
+    /* Copy the SSID */
+    /* sFrame.len point to end of fixed field */
+    sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len);
+    sFrame.len += pCurrSSID->len + WLAN_IEHDR_LEN;
+    memcpy(sFrame.pSSID, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN);
+
+    pMgmt->sAssocInfo.AssocInfo.RequestIELength = pCurrSSID->len + WLAN_IEHDR_LEN;
+    pMgmt->sAssocInfo.AssocInfo.OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
+    pbyIEs = pMgmt->sAssocInfo.abyIEs;
+    MEMvCopy(pbyIEs, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN);
+    pbyIEs += pCurrSSID->len + WLAN_IEHDR_LEN;
+
+    /* Copy the rate set */
+    /* sFrame.len point to end of SSID */
+    sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
+    sFrame.len += pCurrRates->len + WLAN_IEHDR_LEN;
+    memcpy(sFrame.pSuppRates, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN);
+
+    // Copy the extension rate set
+    if ((pMgmt->eCurrentPHYMode == PHY_TYPE_11G) && (pCurrExtSuppRates->len > 0)) {
+        sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
+        sFrame.len += pCurrExtSuppRates->len + WLAN_IEHDR_LEN;
+        memcpy(sFrame.pExtSuppRates, pCurrExtSuppRates, pCurrExtSuppRates->len + WLAN_IEHDR_LEN);
+    }
+
+    pMgmt->sAssocInfo.AssocInfo.RequestIELength += pCurrRates->len + WLAN_IEHDR_LEN;
+    MEMvCopy(pbyIEs, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN);
+    pbyIEs += pCurrRates->len + WLAN_IEHDR_LEN;
+
+    if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA) ||
+         (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) ||
+         (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE)) &&
+        (pMgmt->pCurrBSS != NULL)) {
+        /* WPA IE */
+        sFrame.pRSNWPA = (PWLAN_IE_RSN_EXT)(sFrame.pBuf + sFrame.len);
+        sFrame.pRSNWPA->byElementID = WLAN_EID_RSN_WPA;
+        sFrame.pRSNWPA->len = 16;
+        sFrame.pRSNWPA->abyOUI[0] = 0x00;
+        sFrame.pRSNWPA->abyOUI[1] = 0x50;
+        sFrame.pRSNWPA->abyOUI[2] = 0xf2;
+        sFrame.pRSNWPA->abyOUI[3] = 0x01;
+        sFrame.pRSNWPA->wVersion = 1;
+        //Group Key Cipher Suite
+        sFrame.pRSNWPA->abyMulticast[0] = 0x00;
+        sFrame.pRSNWPA->abyMulticast[1] = 0x50;
+        sFrame.pRSNWPA->abyMulticast[2] = 0xf2;
+        if (pMgmt->byCSSGK == KEY_CTL_WEP) {
+            sFrame.pRSNWPA->abyMulticast[3] = pMgmt->pCurrBSS->byGKType;
+        } else if (pMgmt->byCSSGK == KEY_CTL_TKIP) {
+            sFrame.pRSNWPA->abyMulticast[3] = WPA_TKIP;
+        } else if (pMgmt->byCSSGK == KEY_CTL_CCMP) {
+            sFrame.pRSNWPA->abyMulticast[3] = WPA_AESCCMP;
+        } else {
+            sFrame.pRSNWPA->abyMulticast[3] = WPA_NONE;
+        }
+        // Pairwise Key Cipher Suite
+        sFrame.pRSNWPA->wPKCount = 1;
+        sFrame.pRSNWPA->PKSList[0].abyOUI[0] = 0x00;
+        sFrame.pRSNWPA->PKSList[0].abyOUI[1] = 0x50;
+        sFrame.pRSNWPA->PKSList[0].abyOUI[2] = 0xf2;
+        if (pMgmt->byCSSPK == KEY_CTL_TKIP) {
+            sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_TKIP;
+        } else if (pMgmt->byCSSPK == KEY_CTL_CCMP) {
+            sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_AESCCMP;
+        } else {
+            sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_NONE;
+        }
+        // Auth Key Management Suite
+        pbyRSN = (PBYTE)(sFrame.pBuf + sFrame.len + 2 + sFrame.pRSNWPA->len);
+        *pbyRSN++=0x01;
+        *pbyRSN++=0x00;
+        *pbyRSN++=0x00;
+        *pbyRSN++=0x50;
+        *pbyRSN++=0xf2;
+        if (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) {
+            *pbyRSN++=WPA_AUTH_PSK;
+        } else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA) {
+            *pbyRSN++=WPA_AUTH_IEEE802_1X;
+        } else {
+            *pbyRSN++=WPA_NONE;
+        }
+        sFrame.pRSNWPA->len +=6;
+
+        // RSN Capabilites
+        *pbyRSN++=0x00;
+        *pbyRSN++=0x00;
+        sFrame.pRSNWPA->len +=2;
+        sFrame.len += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
+        // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION
+        pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
+        MEMvCopy(pbyIEs, sFrame.pRSNWPA, sFrame.pRSNWPA->len + WLAN_IEHDR_LEN);
+        pbyIEs += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
+
+    } else if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) ||
+                (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) &&
+               (pMgmt->pCurrBSS != NULL)) {
+        UINT                ii;
+        PWORD               pwPMKID;
+
+        /* WPA IE */
+        sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len);
+        sFrame.pRSN->byElementID = WLAN_EID_RSN;
+        sFrame.pRSN->len = 6; //Version(2)+GK(4)
+        sFrame.pRSN->wVersion = 1;
+        //Group Key Cipher Suite
+        sFrame.pRSN->abyRSN[0] = 0x00;
+        sFrame.pRSN->abyRSN[1] = 0x0F;
+        sFrame.pRSN->abyRSN[2] = 0xAC;
+        if (pMgmt->byCSSGK == KEY_CTL_WEP) {
+            sFrame.pRSN->abyRSN[3] = pMgmt->pCurrBSS->byCSSGK;
+        } else if (pMgmt->byCSSGK == KEY_CTL_TKIP) {
+            sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_TKIP;
+        } else if (pMgmt->byCSSGK == KEY_CTL_CCMP) {
+            sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_CCMP;
+        } else {
+            sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_UNKNOWN;
+        }
+
+        // Pairwise Key Cipher Suite
+        sFrame.pRSN->abyRSN[4] = 1;
+        sFrame.pRSN->abyRSN[5] = 0;
+        sFrame.pRSN->abyRSN[6] = 0x00;
+        sFrame.pRSN->abyRSN[7] = 0x0F;
+        sFrame.pRSN->abyRSN[8] = 0xAC;
+        if (pMgmt->byCSSPK == KEY_CTL_TKIP) {
+            sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_TKIP;
+        } else if (pMgmt->byCSSPK == KEY_CTL_CCMP) {
+            sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_CCMP;
+        } else if (pMgmt->byCSSPK == KEY_CTL_NONE) {
+            sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_USE_GROUP;
+        } else {
+            sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_UNKNOWN;
+        }
+        sFrame.pRSN->len += 6;
+
+        // Auth Key Management Suite
+        sFrame.pRSN->abyRSN[10] = 1;
+        sFrame.pRSN->abyRSN[11] = 0;
+        sFrame.pRSN->abyRSN[12] = 0x00;
+        sFrame.pRSN->abyRSN[13] = 0x0F;
+        sFrame.pRSN->abyRSN[14] = 0xAC;
+        if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK) {
+            sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_PSK;
+        } else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) {
+            sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_802_1X;
+        } else {
+            sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_UNKNOWN;
+        }
+        sFrame.pRSN->len +=6;
+
+        // RSN Capabilites
+        if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist == TRUE) {
+            MEMvCopy(&sFrame.pRSN->abyRSN[16], &pMgmt->pCurrBSS->sRSNCapObj.wRSNCap, 2);
+        } else {
+            sFrame.pRSN->abyRSN[16] = 0;
+            sFrame.pRSN->abyRSN[17] = 0;
+        }
+        sFrame.pRSN->len +=2;
+
+        if ((pDevice->gsPMKID.BSSIDInfoCount > 0) && (pDevice->bRoaming == TRUE) && (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) {
+            // RSN PMKID
+            pbyRSN = &sFrame.pRSN->abyRSN[18];
+            pwPMKID = (PWORD)pbyRSN; // Point to PMKID count
+            *pwPMKID = 0;            // Initialize PMKID count
+            pbyRSN += 2;             // Point to PMKID list
+            for (ii = 0; ii < pDevice->gsPMKID.BSSIDInfoCount; ii++) {
+                if (MEMEqualMemory(&pDevice->gsPMKID.BSSIDInfo[ii].BSSID[0], pMgmt->abyCurrBSSID, U_ETHER_ADDR_LEN)) {
+                    (*pwPMKID) ++;
+                    MEMvCopy(pbyRSN, pDevice->gsPMKID.BSSIDInfo[ii].PMKID, 16);
+                    pbyRSN += 16;
+                }
+            }
+            if (*pwPMKID != 0) {
+                sFrame.pRSN->len += (2 + (*pwPMKID)*16);
+            }
+        }
+
+        sFrame.len += sFrame.pRSN->len + WLAN_IEHDR_LEN;
+        // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION
+        pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSN->len + WLAN_IEHDR_LEN;
+        MEMvCopy(pbyIEs, sFrame.pRSN, sFrame.pRSN->len + WLAN_IEHDR_LEN);
+        pbyIEs += sFrame.pRSN->len + WLAN_IEHDR_LEN;
+    }
+
+
+    /* Adjust the length fields */
+    pTxPacket->cbMPDULen = sFrame.len;
+    pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
+
+    return pTxPacket;
+}
+
+
+
+/*+
+ *
+ * Routine Description:
+ *  Constructs an assoc-response frame
+ *
+ *
+ * Return Value:
+ *    PTR to frame; or NULL on allocation failue
+ *
+-*/
+
+
+PSTxMgmtPacket
+s_MgrMakeAssocResponse(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN WORD wCurrCapInfo,
+    IN WORD wAssocStatus,
+    IN WORD wAssocAID,
+    IN PBYTE pDstAddr,
+    IN PWLAN_IE_SUPP_RATES pCurrSuppRates,
+    IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates
+    )
+{
+    PSTxMgmtPacket      pTxPacket = NULL;
+    WLAN_FR_ASSOCRESP   sFrame;
+
+
+    pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
+    memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_ASSOCREQ_FR_MAXLEN);
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+    // Setup the sFrame structure
+    sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
+    sFrame.len = WLAN_REASSOCRESP_FR_MAXLEN;
+    vMgrEncodeAssocResponse(&sFrame);
+    // Setup the header
+    sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
+        (
+        WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
+        WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ASSOCRESP)
+        ));
+    memcpy( sFrame.pHdr->sA3.abyAddr1, pDstAddr, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
+
+    *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo);
+    *sFrame.pwStatus = cpu_to_le16(wAssocStatus);
+    *sFrame.pwAid = cpu_to_le16((WORD)(wAssocAID | BIT14 | BIT15));
+
+    // Copy the rate set
+    sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
+    sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN;
+    memcpy(sFrame.pSuppRates,
+           pCurrSuppRates,
+           ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN
+          );
+
+    if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) {
+        sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
+        sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN;
+        MEMvCopy(sFrame.pExtSuppRates,
+             pCurrExtSuppRates,
+             ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN
+             );
+    }
+
+    // Adjust the length fields
+    pTxPacket->cbMPDULen = sFrame.len;
+    pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
+
+    return pTxPacket;
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *  Constructs an reassoc-response frame
+ *
+ *
+ * Return Value:
+ *    PTR to frame; or NULL on allocation failue
+ *
+-*/
+
+
+PSTxMgmtPacket
+s_MgrMakeReAssocResponse(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN WORD wCurrCapInfo,
+    IN WORD wAssocStatus,
+    IN WORD wAssocAID,
+    IN PBYTE pDstAddr,
+    IN PWLAN_IE_SUPP_RATES pCurrSuppRates,
+    IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates
+    )
+{
+    PSTxMgmtPacket      pTxPacket = NULL;
+    WLAN_FR_REASSOCRESP   sFrame;
+
+
+    pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
+    memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_ASSOCREQ_FR_MAXLEN);
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+    // Setup the sFrame structure
+    sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
+    sFrame.len = WLAN_REASSOCRESP_FR_MAXLEN;
+    vMgrEncodeReassocResponse(&sFrame);
+    // Setup the header
+    sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
+        (
+        WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
+        WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_REASSOCRESP)
+        ));
+    memcpy( sFrame.pHdr->sA3.abyAddr1, pDstAddr, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
+
+    *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo);
+    *sFrame.pwStatus = cpu_to_le16(wAssocStatus);
+    *sFrame.pwAid = cpu_to_le16((WORD)(wAssocAID | BIT14 | BIT15));
+
+    // Copy the rate set
+    sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
+    sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN;
+    memcpy(sFrame.pSuppRates,
+             pCurrSuppRates,
+             ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN
+             );
+
+    if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) {
+        sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
+        sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN;
+        MEMvCopy(sFrame.pExtSuppRates,
+             pCurrExtSuppRates,
+             ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN
+             );
+    }
+
+    // Adjust the length fields
+    pTxPacket->cbMPDULen = sFrame.len;
+    pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
+
+    return pTxPacket;
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *  Handles probe response management frames.
+ *
+ *
+ * Return Value:
+ *    none.
+ *
+-*/
+
+static
+VOID
+s_vMgrRxProbeResponse(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PSRxMgmtPacket pRxPacket
+    )
+{
+    PKnownBSS           pBSSList = NULL;
+    WLAN_FR_PROBERESP   sFrame;
+    BYTE                byCurrChannel = pRxPacket->byRxChannel;
+    ERPObject           sERP;
+    BYTE                byIEChannel = 0;
+    BOOL                bChannelHit = TRUE;
+
+
+    memset(&sFrame, 0, sizeof(WLAN_FR_PROBERESP));
+    // decode the frame
+    sFrame.len = pRxPacket->cbMPDULen;
+    sFrame.pBuf = (PBYTE)pRxPacket->p80211Header;
+    vMgrDecodeProbeResponse(&sFrame);
+
+    if ((sFrame.pqwTimestamp == 0) ||
+        (sFrame.pwBeaconInterval == 0) ||
+        (sFrame.pwCapInfo == 0) ||
+        (sFrame.pSSID == 0) ||
+        (sFrame.pSuppRates == 0)) {
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe resp:Fail addr:[%p] \n", pRxPacket->p80211Header);
+        DBG_PORT80(0xCC);
+        return;
+    };
+
+    if(sFrame.pSSID->len == 0)
+       DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx Probe resp: SSID len = 0 \n");
+
+    if (sFrame.pDSParms != 0) {
+        if (byCurrChannel > CB_MAX_CHANNEL_24G) {
+            // channel remapping to
+            byIEChannel = CARDbyGetChannelMapping(pMgmt->pAdapter, sFrame.pDSParms->byCurrChannel, PHY_TYPE_11A);
+        } else {
+            byIEChannel = sFrame.pDSParms->byCurrChannel;
+        }
+        if (byCurrChannel != byIEChannel) {
+            // adjust channel info. bcs we rcv adjcent channel pakckets
+            bChannelHit = FALSE;
+            byCurrChannel = byIEChannel;
+        }
+    } else {
+        // no DS channel info
+        bChannelHit = TRUE;
+    }
+
+//2008-0730-01<Add>by MikeLiu
+if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE)
+      return;
+
+    if (sFrame.pERP != NULL) {
+        sERP.byERP = sFrame.pERP->byContext;
+        sERP.bERPExist = TRUE;
+    } else {
+        sERP.bERPExist = FALSE;
+        sERP.byERP = 0;
+    }
+
+
+    // update or insert the bss
+    pBSSList = BSSpAddrIsInBSSList((HANDLE)pDevice, sFrame.pHdr->sA3.abyAddr3, sFrame.pSSID);
+    if (pBSSList) {
+        BSSbUpdateToBSSList((HANDLE)pDevice,
+                            *sFrame.pqwTimestamp,
+                            *sFrame.pwBeaconInterval,
+                            *sFrame.pwCapInfo,
+                            byCurrChannel,
+                            bChannelHit,
+                            sFrame.pSSID,
+                            sFrame.pSuppRates,
+                            sFrame.pExtSuppRates,
+                            &sERP,
+                            sFrame.pRSN,
+                            sFrame.pRSNWPA,
+                            sFrame.pIE_Country,
+                            sFrame.pIE_Quiet,
+                            pBSSList,
+                            sFrame.len - WLAN_HDR_ADDR3_LEN,
+                            sFrame.pHdr->sA4.abyAddr4,   // payload of probresponse
+                            (HANDLE)pRxPacket
+                           );
+    }
+    else {
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Probe resp/insert: RxChannel = : %d\n", byCurrChannel);
+        BSSbInsertToBSSList((HANDLE)pDevice,
+                            sFrame.pHdr->sA3.abyAddr3,
+                            *sFrame.pqwTimestamp,
+                            *sFrame.pwBeaconInterval,
+                            *sFrame.pwCapInfo,
+                            byCurrChannel,
+                            sFrame.pSSID,
+                            sFrame.pSuppRates,
+                            sFrame.pExtSuppRates,
+                            &sERP,
+                            sFrame.pRSN,
+                            sFrame.pRSNWPA,
+                            sFrame.pIE_Country,
+                            sFrame.pIE_Quiet,
+                            sFrame.len - WLAN_HDR_ADDR3_LEN,
+                            sFrame.pHdr->sA4.abyAddr4,   // payload of beacon
+                            (HANDLE)pRxPacket
+                           );
+    }
+    return;
+
+}
+
+/*+
+ *
+ * Routine Description:(AP)or(Ad-hoc STA)
+ *  Handles probe request management frames.
+ *
+ *
+ * Return Value:
+ *    none.
+ *
+-*/
+
+
+static
+VOID
+s_vMgrRxProbeRequest(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PSRxMgmtPacket pRxPacket
+    )
+{
+    WLAN_FR_PROBEREQ    sFrame;
+    CMD_STATUS          Status;
+    PSTxMgmtPacket      pTxPacket;
+    BYTE                byPHYType = BB_TYPE_11B;
+
+    // STA in Ad-hoc mode: when latest TBTT beacon transmit success,
+    // STA have to response this request.
+    if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) ||
+        ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && pDevice->bBeaconSent)) {
+
+        memset(&sFrame, 0, sizeof(WLAN_FR_PROBEREQ));
+        // decode the frame
+        sFrame.len = pRxPacket->cbMPDULen;
+        sFrame.pBuf = (PBYTE)pRxPacket->p80211Header;
+        vMgrDecodeProbeRequest(&sFrame);
+/*
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request rx:MAC addr:%02x-%02x-%02x=%02x-%02x-%02x \n",
+                  sFrame.pHdr->sA3.abyAddr2[0],
+                  sFrame.pHdr->sA3.abyAddr2[1],
+                  sFrame.pHdr->sA3.abyAddr2[2],
+                  sFrame.pHdr->sA3.abyAddr2[3],
+                  sFrame.pHdr->sA3.abyAddr2[4],
+                  sFrame.pHdr->sA3.abyAddr2[5]
+                );
+*/
+        if (sFrame.pSSID->len != 0) {
+            if (sFrame.pSSID->len != ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len)
+                return;
+            if (memcmp(sFrame.pSSID->abySSID,
+                       ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID,
+                       ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) != 0) {
+                       return;
+            }
+        }
+
+        if ((sFrame.pSuppRates->len > 4) || (sFrame.pExtSuppRates != NULL)) {
+            byPHYType = BB_TYPE_11G;
+        }
+
+        // Probe response reply..
+        pTxPacket = s_MgrMakeProbeResponse
+                    (
+                      pDevice,
+                      pMgmt,
+                      pMgmt->wCurrCapInfo,
+                      pMgmt->wCurrBeaconPeriod,
+                      pMgmt->uCurrChannel,
+                      0,
+                      sFrame.pHdr->sA3.abyAddr2,
+                      (PWLAN_IE_SSID)pMgmt->abyCurrSSID,
+                      (PBYTE)pMgmt->abyCurrBSSID,
+                      (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
+                      (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates,
+                       byPHYType
+                    );
+        if (pTxPacket != NULL ){
+            /* send the frame */
+            Status = csMgmt_xmit(pDevice, pTxPacket);
+            if (Status != CMD_STATUS_PENDING) {
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Probe response tx failed\n");
+            }
+            else {
+//                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Probe response tx sending..\n");
+            }
+        }
+    }
+
+    return;
+}
+
+
+
+
+
+/*+
+ *
+ * Routine Description:
+ *
+ *  Entry point for the reception and handling of 802.11 management
+ *  frames. Makes a determination of the frame type and then calls
+ *  the appropriate function.
+ *
+ *
+ * Return Value:
+ *    none.
+ *
+-*/
+
+
+VOID
+vMgrRxManagePacket(
+    IN  HANDLE hDeviceContext,
+    IN PSMgmtObject pMgmt,
+    IN PSRxMgmtPacket pRxPacket
+     )
+{
+    PSDevice    pDevice = (PSDevice)hDeviceContext;
+    BOOL        bInScan = FALSE;
+    UINT        uNodeIndex = 0;
+    NODE_STATE  eNodeState = 0;
+    CMD_STATUS  Status;
+
+
+    if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
+        if (BSSDBbIsSTAInNodeDB(pMgmt, pRxPacket->p80211Header->sA3.abyAddr2, &uNodeIndex))
+            eNodeState = pMgmt->sNodeDBTable[uNodeIndex].eNodeState;
+    }
+
+    switch( WLAN_GET_FC_FSTYPE((pRxPacket->p80211Header->sA3.wFrameCtl)) ){
+
+        case WLAN_FSTYPE_ASSOCREQ:
+            // Frame Clase = 2
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx assocreq\n");
+            if (eNodeState < NODE_AUTH) {
+                // send deauth notification
+                // reason = (6) class 2 received from nonauth sta
+                vMgrDeAuthenBeginSta(pDevice,
+                                     pMgmt,
+                                     pRxPacket->p80211Header->sA3.abyAddr2,
+                                     (6),
+                                     &Status
+                                     );
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: send vMgrDeAuthenBeginSta 1\n");
+            }
+            else {
+                s_vMgrRxAssocRequest(pDevice, pMgmt, pRxPacket, uNodeIndex);
+            }
+            break;
+
+        case WLAN_FSTYPE_ASSOCRESP:
+            // Frame Clase = 2
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx assocresp1\n");
+            s_vMgrRxAssocResponse(pDevice, pMgmt, pRxPacket, FALSE);
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx assocresp2\n");
+            break;
+
+        case WLAN_FSTYPE_REASSOCREQ:
+            // Frame Clase = 2
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx reassocreq\n");
+            // Todo: reassoc
+            if (eNodeState < NODE_AUTH) {
+                // send deauth notification
+                // reason = (6) class 2 received from nonauth sta
+                vMgrDeAuthenBeginSta(pDevice,
+                                     pMgmt,
+                                     pRxPacket->p80211Header->sA3.abyAddr2,
+                                     (6),
+                                     &Status
+                                     );
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: send vMgrDeAuthenBeginSta 2\n");
+
+            }
+            s_vMgrRxReAssocRequest(pDevice, pMgmt, pRxPacket, uNodeIndex);
+            break;
+
+        case WLAN_FSTYPE_REASSOCRESP:
+            // Frame Clase = 2
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx reassocresp\n");
+            s_vMgrRxAssocResponse(pDevice, pMgmt, pRxPacket, TRUE);
+            break;
+
+        case WLAN_FSTYPE_PROBEREQ:
+            // Frame Clase = 0
+            //DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx probereq\n");
+            s_vMgrRxProbeRequest(pDevice, pMgmt, pRxPacket);
+            break;
+
+        case WLAN_FSTYPE_PROBERESP:
+            // Frame Clase = 0
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx proberesp\n");
+
+            s_vMgrRxProbeResponse(pDevice, pMgmt, pRxPacket);
+            break;
+
+        case WLAN_FSTYPE_BEACON:
+            // Frame Clase = 0
+            // DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx beacon\n");
+            if (pMgmt->eScanState != WMAC_NO_SCANNING) {
+                bInScan = TRUE;
+            };
+            s_vMgrRxBeacon(pDevice, pMgmt, pRxPacket, bInScan);
+            break;
+
+        case WLAN_FSTYPE_ATIM:
+            // Frame Clase = 1
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx atim\n");
+            break;
+
+        case WLAN_FSTYPE_DISASSOC:
+            // Frame Clase = 2
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx disassoc\n");
+            if (eNodeState < NODE_AUTH) {
+                // send deauth notification
+                // reason = (6) class 2 received from nonauth sta
+                vMgrDeAuthenBeginSta(pDevice,
+                                     pMgmt,
+                                     pRxPacket->p80211Header->sA3.abyAddr2,
+                                     (6),
+                                     &Status
+                                     );
+                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: send vMgrDeAuthenBeginSta 3\n");
+            }
+            s_vMgrRxDisassociation(pDevice, pMgmt, pRxPacket);
+            break;
+
+        case WLAN_FSTYPE_AUTHEN:
+            // Frame Clase = 1
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO  "rx authen\n");
+            s_vMgrRxAuthentication(pDevice, pMgmt, pRxPacket);
+            break;
+
+        case WLAN_FSTYPE_DEAUTHEN:
+            // Frame Clase = 1
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx deauthen\n");
+            s_vMgrRxDeauthentication(pDevice, pMgmt, pRxPacket);
+            break;
+
+        default:
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx unknown mgmt\n");
+    }
+
+    return;
+}
+
+
+
+
+/*+
+ *
+ * Routine Description:
+ *
+ *
+ *  Prepare beacon to send
+ *
+ * Return Value:
+ *    TRUE if success; FALSE if failed.
+ *
+-*/
+BOOL
+bMgrPrepareBeaconToSend(
+    IN HANDLE hDeviceContext,
+    IN PSMgmtObject pMgmt
+    )
+{
+    PSDevice            pDevice = (PSDevice)hDeviceContext;
+    PSTxMgmtPacket      pTxPacket;
+
+//    pDevice->bBeaconBufReady = FALSE;
+    if (pDevice->bEncryptionEnable || pDevice->bEnable8021x){
+        pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1);
+    }
+    else {
+        pMgmt->wCurrCapInfo &= ~WLAN_SET_CAP_INFO_PRIVACY(1);
+    }
+    pTxPacket = s_MgrMakeBeacon
+                (
+                  pDevice,
+                  pMgmt,
+                  pMgmt->wCurrCapInfo,
+                  pMgmt->wCurrBeaconPeriod,
+                  pMgmt->uCurrChannel,
+                  pMgmt->wCurrATIMWindow, //0,
+                  (PWLAN_IE_SSID)pMgmt->abyCurrSSID,
+                  (PBYTE)pMgmt->abyCurrBSSID,
+                  (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
+                  (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates
+                );
+
+    if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) &&
+        (pMgmt->abyCurrBSSID[0] == 0))
+        return FALSE;
+
+    csBeacon_xmit(pDevice, pTxPacket);
+
+    return TRUE;
+}
+
+
+
+
+/*+
+ *
+ * Routine Description:
+ *
+ *  Log a warning message based on the contents of the Status
+ *  Code field of an 802.11 management frame.  Defines are
+ *  derived from 802.11-1997 SPEC.
+ *
+ * Return Value:
+ *    none.
+ *
+-*/
+static
+VOID
+s_vMgrLogStatus(
+    IN PSMgmtObject pMgmt,
+    IN WORD  wStatus
+    )
+{
+    switch( wStatus ){
+        case WLAN_MGMT_STATUS_UNSPEC_FAILURE:
+            DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Unspecified error.\n");
+            break;
+        case WLAN_MGMT_STATUS_CAPS_UNSUPPORTED:
+            DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Can't support all requested capabilities.\n");
+            break;
+        case WLAN_MGMT_STATUS_REASSOC_NO_ASSOC:
+            DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Reassoc denied, can't confirm original Association.\n");
+            break;
+        case WLAN_MGMT_STATUS_ASSOC_DENIED_UNSPEC:
+            DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, undefine in spec\n");
+            break;
+        case WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG:
+            DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Peer doesn't support authen algorithm.\n");
+            break;
+        case WLAN_MGMT_STATUS_RX_AUTH_NOSEQ:
+            DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Authen frame received out of sequence.\n");
+            break;
+        case WLAN_MGMT_STATUS_CHALLENGE_FAIL:
+            DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Authen rejected, challenge  failure.\n");
+            break;
+        case WLAN_MGMT_STATUS_AUTH_TIMEOUT:
+            DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Authen rejected, timeout waiting for next frame.\n");
+            break;
+        case WLAN_MGMT_STATUS_ASSOC_DENIED_BUSY:
+            DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, AP too busy.\n");
+            break;
+        case WLAN_MGMT_STATUS_ASSOC_DENIED_RATES:
+            DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we haven't enough basic rates.\n");
+            break;
+        case WLAN_MGMT_STATUS_ASSOC_DENIED_SHORTPREAMBLE:
+            DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we do not support short preamble.\n");
+            break;
+        case WLAN_MGMT_STATUS_ASSOC_DENIED_PBCC:
+            DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we do not support PBCC.\n");
+            break;
+        case WLAN_MGMT_STATUS_ASSOC_DENIED_AGILITY:
+            DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we do not support channel agility.\n");
+            break;
+        default:
+            DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Unknown status code %d.\n", wStatus);
+            break;
+    }
+}
+
+
+/*
+ *
+ * Description:
+ *    Add BSSID in PMKID Candidate list.
+ *
+ * Parameters:
+ *  In:
+ *      hDeviceContext - device structure point
+ *      pbyBSSID - BSSID address for adding
+ *      wRSNCap - BSS's RSN capability
+ *  Out:
+ *      none
+ *
+ * Return Value: none.
+ *
+-*/
+BOOL
+bAdd_PMKID_Candidate (
+    IN HANDLE    hDeviceContext,
+    IN PBYTE          pbyBSSID,
+    IN PSRSNCapObject psRSNCapObj
+    )
+{
+    PSDevice         pDevice = (PSDevice)hDeviceContext;
+    PPMKID_CANDIDATE pCandidateList;
+    UINT             ii = 0;
+
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"bAdd_PMKID_Candidate START: (%d)\n", (int)pDevice->gsPMKIDCandidate.NumCandidates);
+
+    if ((pDevice == NULL) || (pbyBSSID == NULL) || (psRSNCapObj == NULL))
+        return FALSE;
+
+    if (pDevice->gsPMKIDCandidate.NumCandidates >= MAX_PMKIDLIST)
+        return FALSE;
+
+
+
+    // Update Old Candidate
+    for (ii = 0; ii < pDevice->gsPMKIDCandidate.NumCandidates; ii++) {
+        pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[ii];
+        if (MEMEqualMemory(pCandidateList->BSSID, pbyBSSID, U_ETHER_ADDR_LEN)) {
+            if ((psRSNCapObj->bRSNCapExist == TRUE) && (psRSNCapObj->wRSNCap & BIT0)) {
+                pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED;
+            } else {
+                pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED);
+            }
+            return TRUE;
+        }
+    }
+
+    // New Candidate
+    pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[pDevice->gsPMKIDCandidate.NumCandidates];
+    if ((psRSNCapObj->bRSNCapExist == TRUE) && (psRSNCapObj->wRSNCap & BIT0)) {
+        pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED;
+    } else {
+        pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED);
+    }
+    MEMvCopy(pCandidateList->BSSID, pbyBSSID, U_ETHER_ADDR_LEN);
+    pDevice->gsPMKIDCandidate.NumCandidates++;
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"NumCandidates:%d\n", (int)pDevice->gsPMKIDCandidate.NumCandidates);
+    return TRUE;
+}
+
+/*
+ *
+ * Description:
+ *    Flush PMKID Candidate list.
+ *
+ * Parameters:
+ *  In:
+ *      hDeviceContext - device structure point
+ *  Out:
+ *      none
+ *
+ * Return Value: none.
+ *
+-*/
+VOID
+vFlush_PMKID_Candidate (
+    IN HANDLE hDeviceContext
+    )
+{
+    PSDevice        pDevice = (PSDevice)hDeviceContext;
+
+    if (pDevice == NULL)
+        return;
+
+    ZERO_MEMORY(&pDevice->gsPMKIDCandidate, sizeof(SPMKIDCandidateEvent));
+}
+
+static BOOL
+s_bCipherMatch (
+    IN PKnownBSS                        pBSSNode,
+    IN NDIS_802_11_ENCRYPTION_STATUS    EncStatus,
+    OUT PBYTE                           pbyCCSPK,
+    OUT PBYTE                           pbyCCSGK
+    )
+{
+    BYTE byMulticastCipher = KEY_CTL_INVALID;
+    BYTE byCipherMask = 0x00;
+    int i;
+
+    if (pBSSNode == NULL)
+        return FALSE;
+
+    // check cap. of BSS
+
+    if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) &&
+         (EncStatus == Ndis802_11Encryption1Enabled)) {
+        // default is WEP only
+        byMulticastCipher = KEY_CTL_WEP;
+    }
+
+    if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) &&
+        (pBSSNode->bWPA2Valid == TRUE) &&
+        ((EncStatus == Ndis802_11Encryption3Enabled)||(EncStatus == Ndis802_11Encryption2Enabled))) {
+
+        //WPA2
+        // check Group Key Cipher
+        if ((pBSSNode->byCSSGK == WLAN_11i_CSS_WEP40) ||
+            (pBSSNode->byCSSGK == WLAN_11i_CSS_WEP104)) {
+            byMulticastCipher = KEY_CTL_WEP;
+        } else if (pBSSNode->byCSSGK == WLAN_11i_CSS_TKIP) {
+            byMulticastCipher = KEY_CTL_TKIP;
+        } else if (pBSSNode->byCSSGK == WLAN_11i_CSS_CCMP) {
+            byMulticastCipher = KEY_CTL_CCMP;
+        } else {
+            byMulticastCipher = KEY_CTL_INVALID;
+        }
+
+        // check Pairwise Key Cipher
+        for(i=0;i<pBSSNode->wCSSPKCount;i++) {
+            if ((pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_WEP40) ||
+                (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_WEP104)) {
+                // this should not happen as defined 802.11i
+                byCipherMask |= 0x01;
+            } else if (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_TKIP) {
+                byCipherMask |= 0x02;
+            } else if (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_CCMP) {
+                byCipherMask |= 0x04;
+            } else if (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_USE_GROUP) {
+                // use group key only ignore all others
+                byCipherMask = 0;
+                i = pBSSNode->wCSSPKCount;
+            }
+        }
+    } else if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) &&
+                (pBSSNode->bWPAValid == TRUE) &&
+                ((EncStatus == Ndis802_11Encryption3Enabled)||(EncStatus == Ndis802_11Encryption2Enabled))) {
+
+        //WPA
+        // check Group Key Cipher
+        if ((pBSSNode->byGKType == WPA_WEP40) ||
+            (pBSSNode->byGKType == WPA_WEP104)) {
+            byMulticastCipher = KEY_CTL_WEP;
+        } else if (pBSSNode->byGKType == WPA_TKIP) {
+            byMulticastCipher = KEY_CTL_TKIP;
+        } else if (pBSSNode->byGKType == WPA_AESCCMP) {
+            byMulticastCipher = KEY_CTL_CCMP;
+        } else {
+            byMulticastCipher = KEY_CTL_INVALID;
+        }
+
+        // check Pairwise Key Cipher
+        for(i=0;i<pBSSNode->wPKCount;i++) {
+            if (pBSSNode->abyPKType[i] == WPA_TKIP) {
+                byCipherMask |= 0x02;
+            } else if (pBSSNode->abyPKType[i] == WPA_AESCCMP) {
+                byCipherMask |= 0x04;
+            } else if (pBSSNode->abyPKType[i] == WPA_NONE) {
+                // use group key only ignore all others
+                byCipherMask = 0;
+                i = pBSSNode->wPKCount;
+            }
+        }
+    }
+
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%d, %d, %d, %d, EncStatus:%d\n",
+        byMulticastCipher, byCipherMask, pBSSNode->bWPAValid, pBSSNode->bWPA2Valid, EncStatus);
+
+    // mask our cap. with BSS
+    if (EncStatus == Ndis802_11Encryption1Enabled) {
+        // For supporting Cisco migration mode, don't care pairwise key cipher
+        if ((byMulticastCipher == KEY_CTL_WEP) &&
+            (byCipherMask == 0)) {
+            *pbyCCSGK = KEY_CTL_WEP;
+            *pbyCCSPK = KEY_CTL_NONE;
+            return TRUE;
+        } else {
+            return FALSE;
+        }
+
+    } else if (EncStatus == Ndis802_11Encryption2Enabled) {
+        if ((byMulticastCipher == KEY_CTL_TKIP) &&
+            (byCipherMask == 0)) {
+            *pbyCCSGK = KEY_CTL_TKIP;
+            *pbyCCSPK = KEY_CTL_NONE;
+            return TRUE;
+        } else if ((byMulticastCipher == KEY_CTL_WEP) &&
+                   ((byCipherMask & 0x02) != 0)) {
+            *pbyCCSGK = KEY_CTL_WEP;
+            *pbyCCSPK = KEY_CTL_TKIP;
+            return TRUE;
+        } else if ((byMulticastCipher == KEY_CTL_TKIP) &&
+                   ((byCipherMask & 0x02) != 0)) {
+            *pbyCCSGK = KEY_CTL_TKIP;
+            *pbyCCSPK = KEY_CTL_TKIP;
+            return TRUE;
+        } else {
+            return FALSE;
+        }
+    } else if (EncStatus == Ndis802_11Encryption3Enabled) {
+        if ((byMulticastCipher == KEY_CTL_CCMP) &&
+            (byCipherMask == 0)) {
+            // When CCMP is enable, "Use group cipher suite" shall not be a valid option.
+            return FALSE;
+        } else if ((byMulticastCipher == KEY_CTL_WEP) &&
+                   ((byCipherMask & 0x04) != 0)) {
+            *pbyCCSGK = KEY_CTL_WEP;
+            *pbyCCSPK = KEY_CTL_CCMP;
+            return TRUE;
+        } else if ((byMulticastCipher == KEY_CTL_TKIP) &&
+                   ((byCipherMask & 0x04) != 0)) {
+            *pbyCCSGK = KEY_CTL_TKIP;
+            *pbyCCSPK = KEY_CTL_CCMP;
+            return TRUE;
+        } else if ((byMulticastCipher == KEY_CTL_CCMP) &&
+                   ((byCipherMask & 0x04) != 0)) {
+            *pbyCCSGK = KEY_CTL_CCMP;
+            *pbyCCSPK = KEY_CTL_CCMP;
+            return TRUE;
+        } else {
+            return FALSE;
+        }
+    }
+    return TRUE;
+}
+
+
diff --git a/drivers/staging/vt6655/wmgr.h b/drivers/staging/vt6655/wmgr.h
new file mode 100644 (file)
index 0000000..5b526ab
--- /dev/null
@@ -0,0 +1,521 @@
+/*
+ * 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: wmgr.h
+ *
+ * Purpose:
+ *
+ * Author: lyndon chen
+ *
+ * Date: Jan 2, 2003
+ *
+ * Functions:
+ *
+ * Revision History:
+ *
+ */
+
+
+#ifndef __WMGR_H__
+#define __WMGR_H__
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+#if !defined(__80211MGR_H__)
+#include "80211mgr.h"
+#endif
+#if !defined(__80211HDR_H__)
+#include "80211hdr.h"
+#endif
+#if !defined(__WCMD_H__)
+#include "wcmd.h"
+#endif
+#if !defined(__BSSDB_H__)
+#include "bssdb.h"
+#endif
+#if !defined(__CARD_H__)
+#include "card.h"
+#endif
+#if !defined(__WPA2_H__)
+#include "wpa2.h"
+#endif
+#if !defined(__VNTWIFI_H__)
+#include "vntwifi.h"
+#endif
+
+
+
+/*---------------------  Export Definitions -------------------------*/
+
+
+
+// Scan time
+#define PROBE_DELAY                  100  // (us)
+#define SWITCH_CHANNEL_DELAY         200 // (us)
+#define WLAN_SCAN_MINITIME           25   // (ms)
+#define WLAN_SCAN_MAXTIME            100  // (ms)
+#define TRIVIAL_SYNC_DIFFERENCE      0    // (us)
+#define DEFAULT_IBSS_BI              100  // (ms)
+
+#define WCMD_ACTIVE_SCAN_TIME   50 //(ms)
+#define WCMD_PASSIVE_SCAN_TIME  100 //(ms)
+
+
+#define DEFAULT_MSDU_LIFETIME           512  // ms
+#define DEFAULT_MSDU_LIFETIME_RES_64us  8000 // 64us
+
+#define DEFAULT_MGN_LIFETIME            8    // ms
+#define DEFAULT_MGN_LIFETIME_RES_64us   125  // 64us
+
+#define MAKE_BEACON_RESERVED            10  //(us)
+
+
+#define TIM_MULTICAST_MASK           0x01
+#define TIM_BITMAPOFFSET_MASK        0xFE
+#define DEFAULT_DTIM_PERIOD             1
+
+#define AP_LONG_RETRY_LIMIT             4
+
+#define DEFAULT_IBSS_CHANNEL            6  //2.4G
+
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Types  ------------------------------*/
+#define timer_expire(timer,next_tick)   mod_timer(&timer, RUN_AT(next_tick))
+typedef void (*TimerFunction)(ULONG);
+
+
+//+++ NDIS related
+
+typedef UCHAR   NDIS_802_11_MAC_ADDRESS[6];
+typedef struct _NDIS_802_11_AI_REQFI
+{
+    USHORT Capabilities;
+    USHORT ListenInterval;
+    NDIS_802_11_MAC_ADDRESS  CurrentAPAddress;
+} NDIS_802_11_AI_REQFI, *PNDIS_802_11_AI_REQFI;
+
+typedef struct _NDIS_802_11_AI_RESFI
+{
+    USHORT Capabilities;
+    USHORT StatusCode;
+    USHORT AssociationId;
+} NDIS_802_11_AI_RESFI, *PNDIS_802_11_AI_RESFI;
+
+typedef struct _NDIS_802_11_ASSOCIATION_INFORMATION
+{
+    ULONG                   Length;
+    USHORT                  AvailableRequestFixedIEs;
+    NDIS_802_11_AI_REQFI    RequestFixedIEs;
+    ULONG                   RequestIELength;
+    ULONG                   OffsetRequestIEs;
+    USHORT                  AvailableResponseFixedIEs;
+    NDIS_802_11_AI_RESFI    ResponseFixedIEs;
+    ULONG                   ResponseIELength;
+    ULONG                   OffsetResponseIEs;
+} NDIS_802_11_ASSOCIATION_INFORMATION, *PNDIS_802_11_ASSOCIATION_INFORMATION;
+
+
+
+typedef struct tagSAssocInfo {
+    NDIS_802_11_ASSOCIATION_INFORMATION     AssocInfo;
+    BYTE                                    abyIEs[WLAN_BEACON_FR_MAXLEN+WLAN_BEACON_FR_MAXLEN];
+    // store ReqIEs set by OID_802_11_ASSOCIATION_INFORMATION
+    ULONG                                   RequestIELength;
+    BYTE                                    abyReqIEs[WLAN_BEACON_FR_MAXLEN];
+} SAssocInfo, DEF* PSAssocInfo;
+//---
+
+
+/*
+typedef enum tagWMAC_AUTHENTICATION_MODE {
+
+
+    WMAC_AUTH_OPEN,
+    WMAC_AUTH_SHAREKEY,
+    WMAC_AUTH_AUTO,
+    WMAC_AUTH_WPA,
+    WMAC_AUTH_WPAPSK,
+    WMAC_AUTH_WPANONE,
+    WMAC_AUTH_WPA2,
+    WMAC_AUTH_WPA2PSK,
+    WMAC_AUTH_MAX       // Not a real mode, defined as upper bound
+
+
+} WMAC_AUTHENTICATION_MODE, *PWMAC_AUTHENTICATION_MODE;
+*/
+
+
+// Pre-configured Mode (from XP)
+/*
+typedef enum tagWMAC_CONFIG_MODE {
+    WMAC_CONFIG_ESS_STA,
+    WMAC_CONFIG_IBSS_STA,
+    WMAC_CONFIG_AUTO,
+    WMAC_CONFIG_AP
+
+} WMAC_CONFIG_MODE, *PWMAC_CONFIG_MODE;
+*/
+
+typedef enum tagWMAC_SCAN_TYPE {
+
+    WMAC_SCAN_ACTIVE,
+    WMAC_SCAN_PASSIVE,
+    WMAC_SCAN_HYBRID
+
+} WMAC_SCAN_TYPE, *PWMAC_SCAN_TYPE;
+
+
+typedef enum tagWMAC_SCAN_STATE {
+
+    WMAC_NO_SCANNING,
+    WMAC_IS_SCANNING,
+    WMAC_IS_PROBEPENDING
+
+} WMAC_SCAN_STATE, *PWMAC_SCAN_STATE;
+
+
+
+// Notes:
+// Basic Service Set state explained as following:
+// WMAC_STATE_IDLE          : no BSS is selected (Adhoc or Infra)
+// WMAC_STATE_STARTED       : no BSS is selected, start own IBSS (Adhoc only)
+// WMAC_STATE_JOINTED       : BSS is selected and synchronized (Adhoc or Infra)
+// WMAC_STATE_AUTHPENDING   : Authentication pending (Infra)
+// WMAC_STATE_AUTH          : Authenticated (Infra)
+// WMAC_STATE_ASSOCPENDING  : Association pending (Infra)
+// WMAC_STATE_ASSOC         : Associated (Infra)
+
+typedef enum tagWMAC_BSS_STATE {
+
+    WMAC_STATE_IDLE,
+    WMAC_STATE_STARTED,
+    WMAC_STATE_JOINTED,
+    WMAC_STATE_AUTHPENDING,
+    WMAC_STATE_AUTH,
+    WMAC_STATE_ASSOCPENDING,
+    WMAC_STATE_ASSOC
+
+} WMAC_BSS_STATE, *PWMAC_BSS_STATE;
+
+// WMAC selected running mode
+typedef enum tagWMAC_CURRENT_MODE {
+
+    WMAC_MODE_STANDBY,
+    WMAC_MODE_ESS_STA,
+    WMAC_MODE_IBSS_STA,
+    WMAC_MODE_ESS_AP
+
+} WMAC_CURRENT_MODE, *PWMAC_CURRENT_MODE;
+
+/*
+typedef enum tagWMAC_POWER_MODE {
+
+    WMAC_POWER_CAM,
+    WMAC_POWER_FAST,
+    WMAC_POWER_MAX
+
+} WMAC_POWER_MODE, *PWMAC_POWER_MODE;
+*/
+
+
+// Tx Managment Packet descriptor
+typedef struct tagSTxMgmtPacket {
+
+    PUWLAN_80211HDR     p80211Header;
+    UINT                cbMPDULen;
+    UINT                cbPayloadLen;
+
+} STxMgmtPacket, DEF* PSTxMgmtPacket;
+
+
+// Rx Managment Packet descriptor
+typedef struct tagSRxMgmtPacket {
+
+    PUWLAN_80211HDR     p80211Header;
+    QWORD               qwLocalTSF;
+    UINT                cbMPDULen;
+    UINT                cbPayloadLen;
+    UINT                uRSSI;
+    BYTE                bySQ;
+    BYTE                byRxRate;
+    BYTE                byRxChannel;
+
+} SRxMgmtPacket, DEF* PSRxMgmtPacket;
+
+
+
+typedef struct tagSMgmtObject
+{
+
+    PVOID                   pAdapter;
+    // MAC address
+    BYTE                    abyMACAddr[WLAN_ADDR_LEN];
+
+    // Configuration Mode
+    WMAC_CONFIG_MODE        eConfigMode; // MAC pre-configed mode
+    CARD_PHY_TYPE           eCurrentPHYMode;
+    CARD_PHY_TYPE           eConfigPHYMode;
+
+
+    // Operation state variables
+    WMAC_CURRENT_MODE       eCurrMode;   // MAC current connection mode
+    WMAC_BSS_STATE          eCurrState;  // MAC current BSS state
+
+    PKnownBSS               pCurrBSS;
+    BYTE                    byCSSGK;
+    BYTE                    byCSSPK;
+
+//    BYTE                    abyNewSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN];
+//    BYTE                    abyNewExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN];
+
+    // Current state vars
+    UINT                    uCurrChannel;
+    BYTE                    abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
+    BYTE                    abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
+    BYTE                    abyCurrSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
+    BYTE                    abyCurrBSSID[WLAN_BSSID_LEN];
+    WORD                    wCurrCapInfo;
+    WORD                    wCurrAID;
+    WORD                    wCurrATIMWindow;
+    WORD                    wCurrBeaconPeriod;
+    BOOL                    bIsDS;
+    BYTE                    byERPContext;
+
+    CMD_STATE               eCommandState;
+    UINT                    uScanChannel;
+
+    // Desire joinning BSS vars
+    BYTE                    abyDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
+    BYTE                    abyDesireBSSID[WLAN_BSSID_LEN];
+
+    // Adhoc or AP configuration vars
+  //BYTE                    abyAdHocSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
+    WORD                    wIBSSBeaconPeriod;
+    WORD                    wIBSSATIMWindow;
+    UINT                    uIBSSChannel;
+    BYTE                    abyIBSSSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
+    BYTE                    byAPBBType;
+    BYTE                    abyWPAIE[MAX_WPA_IE_LEN];
+    WORD                    wWPAIELen;
+
+    UINT                    uAssocCount;
+    BOOL                    bMoreData;
+
+    // Scan state vars
+    WMAC_SCAN_STATE         eScanState;
+    WMAC_SCAN_TYPE          eScanType;
+    UINT                    uScanStartCh;
+    UINT                    uScanEndCh;
+    WORD                    wScanSteps;
+    UINT                    uScanBSSType;
+    // Desire scannig vars
+    BYTE                    abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
+    BYTE                    abyScanBSSID[WLAN_BSSID_LEN];
+
+    // Privacy
+    WMAC_AUTHENTICATION_MODE eAuthenMode;
+    WMAC_ENCRYPTION_MODE    eEncryptionMode;
+    BOOL                    bShareKeyAlgorithm;
+    BYTE                    abyChallenge[WLAN_CHALLENGE_LEN];
+    BOOL                    bPrivacyInvoked;
+
+    // Received beacon state vars
+    BOOL                    bInTIM;
+    BOOL                    bMulticastTIM;
+    BYTE                    byDTIMCount;
+    BYTE                    byDTIMPeriod;
+
+    // Power saving state vars
+    WMAC_POWER_MODE         ePSMode;
+    WORD                    wListenInterval;
+    WORD                    wCountToWakeUp;
+    BOOL                    bInTIMWake;
+    PBYTE                   pbyPSPacketPool;
+    BYTE                    byPSPacketPool[sizeof(STxMgmtPacket) + WLAN_NULLDATA_FR_MAXLEN];
+    BOOL                    bRxBeaconInTBTTWake;
+    BYTE                    abyPSTxMap[MAX_NODE_NUM + 1];
+
+    // managment command related
+    UINT                    uCmdBusy;
+    UINT                    uCmdHostAPBusy;
+
+    // managment packet pool
+    PBYTE                   pbyMgmtPacketPool;
+    BYTE                    byMgmtPacketPool[sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN];
+
+
+    // One second callback timer
+    struct timer_list      sTimerSecondCallback;
+
+    // Temporarily Rx Mgmt Packet Descriptor
+    SRxMgmtPacket           sRxPacket;
+
+    // link list of known bss's (scan results)
+    KnownBSS                sBSSList[MAX_BSS_NUM];
+
+
+
+    // table list of known node
+    // sNodeDBList[0] is reserved for AP under Infra mode
+    // sNodeDBList[0] is reserved for Multicast under adhoc/AP mode
+    KnownNodeDB             sNodeDBTable[MAX_NODE_NUM + 1];
+
+
+
+    // WPA2 PMKID Cache
+    SPMKIDCache             gsPMKIDCache;
+    BOOL                    bRoaming;
+
+    // rate fall back vars
+
+
+
+    // associate info
+    SAssocInfo              sAssocInfo;
+
+
+    // for 802.11h
+    BOOL                    b11hEnable;
+    BOOL                    bSwitchChannel;
+    BYTE                    byNewChannel;
+    PWLAN_IE_MEASURE_REP    pCurrMeasureEIDRep;
+    UINT                    uLengthOfRepEIDs;
+    BYTE                    abyCurrentMSRReq[sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN];
+    BYTE                    abyCurrentMSRRep[sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN];
+    BYTE                    abyIECountry[WLAN_A3FR_MAXLEN];
+    BYTE                    abyIBSSDFSOwner[6];
+    BYTE                    byIBSSDFSRecovery;
+
+    struct sk_buff  skb;
+
+} SMgmtObject, DEF *PSMgmtObject;
+
+
+/*---------------------  Export Macros ------------------------------*/
+
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+void
+vMgrObjectInit(
+    IN  HANDLE hDeviceContext
+    );
+
+void
+vMgrTimerInit(
+    IN  HANDLE hDeviceContext
+    );
+
+VOID
+vMgrObjectReset(
+    IN  HANDLE hDeviceContext
+    );
+
+void
+vMgrAssocBeginSta(
+    IN  HANDLE hDeviceContext,
+    IN  PSMgmtObject pMgmt,
+    OUT PCMD_STATUS pStatus
+    );
+
+VOID
+vMgrReAssocBeginSta(
+    IN  HANDLE hDeviceContext,
+    IN  PSMgmtObject pMgmt,
+    OUT PCMD_STATUS pStatus
+    );
+
+VOID
+vMgrDisassocBeginSta(
+    IN  HANDLE hDeviceContext,
+    IN  PSMgmtObject pMgmt,
+    IN  PBYTE  abyDestAddress,
+    IN  WORD    wReason,
+    OUT PCMD_STATUS pStatus
+    );
+
+VOID
+vMgrAuthenBeginSta(
+    IN  HANDLE hDeviceContext,
+    IN  PSMgmtObject pMgmt,
+    OUT PCMD_STATUS pStatus
+    );
+
+VOID
+vMgrCreateOwnIBSS(
+    IN  HANDLE hDeviceContext,
+    OUT PCMD_STATUS pStatus
+    );
+
+VOID
+vMgrJoinBSSBegin(
+    IN  HANDLE hDeviceContext,
+    OUT PCMD_STATUS pStatus
+    );
+
+VOID
+vMgrRxManagePacket(
+    IN  HANDLE hDeviceContext,
+    IN  PSMgmtObject pMgmt,
+    IN  PSRxMgmtPacket pRxPacket
+    );
+
+/*
+VOID
+vMgrScanBegin(
+    IN  HANDLE hDeviceContext,
+    OUT PCMD_STATUS pStatus
+    );
+*/
+
+VOID
+vMgrDeAuthenBeginSta(
+    IN  HANDLE hDeviceContext,
+    IN  PSMgmtObject  pMgmt,
+    IN  PBYTE   abyDestAddress,
+    IN  WORD    wReason,
+    OUT PCMD_STATUS pStatus
+    );
+
+BOOL
+bMgrPrepareBeaconToSend(
+    IN  HANDLE hDeviceContext,
+    IN  PSMgmtObject pMgmt
+    );
+
+
+BOOL
+bAdd_PMKID_Candidate (
+    IN HANDLE    hDeviceContext,
+    IN PBYTE          pbyBSSID,
+    IN PSRSNCapObject psRSNCapObj
+    );
+
+VOID
+vFlush_PMKID_Candidate (
+    IN HANDLE hDeviceContext
+    );
+
+#endif // __WMGR_H__
diff --git a/drivers/staging/vt6655/wpa.c b/drivers/staging/vt6655/wpa.c
new file mode 100644 (file)
index 0000000..8b4e7fc
--- /dev/null
@@ -0,0 +1,339 @@
+/*
+ * 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: wpa.c
+ *
+ * Purpose: Handles the Basic Service Set & Node Database functions
+ *
+ * Functions:
+ *      WPA_ParseRSN - Parse RSN IE.
+ *
+ * Revision History:
+ *
+ * Author: Kyle Hsu
+ *
+ * Date: July 14, 2003
+ *
+ */
+
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+#if !defined(__UMEM_H__)
+#include "umem.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(__WPA_H__)
+#include "wpa.h"
+#endif
+#if !defined(__80211MGR_H__)
+#include "80211mgr.h"
+#endif
+
+
+/*---------------------  Static Variables  --------------------------*/
+static int          msglevel                =MSG_LEVEL_INFO;
+
+const BYTE abyOUI00[4] = { 0x00, 0x50, 0xf2, 0x00 };
+const BYTE abyOUI01[4] = { 0x00, 0x50, 0xf2, 0x01 };
+const BYTE abyOUI02[4] = { 0x00, 0x50, 0xf2, 0x02 };
+const BYTE abyOUI03[4] = { 0x00, 0x50, 0xf2, 0x03 };
+const BYTE abyOUI04[4] = { 0x00, 0x50, 0xf2, 0x04 };
+const BYTE abyOUI05[4] = { 0x00, 0x50, 0xf2, 0x05 };
+
+
+/*+
+ *
+ * Description:
+ *    Clear RSN information in BSSList.
+ *
+ * Parameters:
+ *  In:
+ *      pBSSList - BSS list.
+ *  Out:
+ *      none
+ *
+ * Return Value: none.
+ *
+-*/
+
+VOID
+WPA_ClearRSN (
+    IN PKnownBSS        pBSSList
+    )
+{
+    int ii;
+    pBSSList->byGKType = WPA_TKIP;
+    for (ii=0; ii < 4; ii ++)
+        pBSSList->abyPKType[ii] = WPA_TKIP;
+    pBSSList->wPKCount = 0;
+    for (ii=0; ii < 4; ii ++)
+        pBSSList->abyAuthType[ii] = WPA_AUTH_IEEE802_1X;
+    pBSSList->wAuthCount = 0;
+    pBSSList->byDefaultK_as_PK = 0;
+    pBSSList->byReplayIdx = 0;
+    pBSSList->sRSNCapObj.bRSNCapExist = FALSE;
+    pBSSList->sRSNCapObj.wRSNCap = 0;
+    pBSSList->bWPAValid = FALSE;
+}
+
+
+/*+
+ *
+ * Description:
+ *    Parse RSN IE.
+ *
+ * Parameters:
+ *  In:
+ *      pBSSList - BSS list.
+ *      pRSN - Pointer to the RSN IE.
+ *  Out:
+ *      none
+ *
+ * Return Value: none.
+ *
+-*/
+VOID
+WPA_ParseRSN (
+    IN PKnownBSS        pBSSList,
+    IN PWLAN_IE_RSN_EXT pRSN
+    )
+{
+    PWLAN_IE_RSN_AUTH  pIE_RSN_Auth = NULL;
+    int                i, j, m, n = 0;
+    PBYTE              pbyCaps;
+
+    WPA_ClearRSN(pBSSList);
+
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"WPA_ParseRSN: [%d]\n", pRSN->len);
+
+    // information element header makes sense
+    if ((pRSN->len >= 6) // oui1(4)+ver(2)
+         && (pRSN->byElementID == WLAN_EID_RSN_WPA) && MEMEqualMemory(pRSN->abyOUI, abyOUI01, 4)
+         && (pRSN->wVersion == 1)) {
+
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Legal RSN\n");
+        // update each variable if pRSN is long enough to contain the variable
+        if (pRSN->len >= 10) //oui1(4)+ver(2)+GKSuite(4)
+        {
+            if (MEMEqualMemory(pRSN->abyMulticast, abyOUI01, 4))
+                pBSSList->byGKType = WPA_WEP40;
+            else if (MEMEqualMemory(pRSN->abyMulticast, abyOUI02, 4))
+                pBSSList->byGKType = WPA_TKIP;
+            else if (MEMEqualMemory(pRSN->abyMulticast, abyOUI03, 4))
+                pBSSList->byGKType = WPA_AESWRAP;
+            else if (MEMEqualMemory(pRSN->abyMulticast, abyOUI04, 4))
+                pBSSList->byGKType = WPA_AESCCMP;
+            else if (MEMEqualMemory(pRSN->abyMulticast, abyOUI05, 4))
+                pBSSList->byGKType = WPA_WEP104;
+            else
+                // any vendor checks here
+                pBSSList->byGKType = WPA_NONE;
+
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"byGKType: %x\n", pBSSList->byGKType);
+        }
+
+        if (pRSN->len >= 12) //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)
+        {
+            j = 0;
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wPKCount: %d, sizeof(pBSSList->abyPKType): %d\n", pRSN->wPKCount, sizeof(pBSSList->abyPKType));
+            for(i = 0; (i < pRSN->wPKCount) && (j < sizeof(pBSSList->abyPKType)/sizeof(BYTE)); i++) {
+                if(pRSN->len >= 12+i*4+4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*i)
+                    if (MEMEqualMemory(pRSN->PKSList[i].abyOUI, abyOUI00, 4))
+                        pBSSList->abyPKType[j++] = WPA_NONE;
+                    else if (MEMEqualMemory(pRSN->PKSList[i].abyOUI, abyOUI02, 4))
+                        pBSSList->abyPKType[j++] = WPA_TKIP;
+                    else if (MEMEqualMemory(pRSN->PKSList[i].abyOUI, abyOUI03, 4))
+                        pBSSList->abyPKType[j++] = WPA_AESWRAP;
+                    else if (MEMEqualMemory(pRSN->PKSList[i].abyOUI, abyOUI04, 4))
+                        pBSSList->abyPKType[j++] = WPA_AESCCMP;
+                    else
+                        // any vendor checks here
+                        ;
+                }
+                else
+                    break;
+                //DBG_PRN_GRP14(("abyPKType[%d]: %X\n", j-1, pBSSList->abyPKType[j-1]));
+            } //for
+            pBSSList->wPKCount = (WORD)j;
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wPKCount: %d\n", pBSSList->wPKCount);
+        }
+
+        m = pRSN->wPKCount;
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"m: %d\n", m);
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"14+m*4: %d\n", 14+m*4);
+
+        if (pRSN->len >= 14+m*4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*m)+AKC(2)
+            // overlay IE_RSN_Auth structure into correct place
+            pIE_RSN_Auth = (PWLAN_IE_RSN_AUTH) pRSN->PKSList[m].abyOUI;
+            j = 0;
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wAuthCount: %d, sizeof(pBSSList->abyAuthType): %d\n",
+                          pIE_RSN_Auth->wAuthCount, sizeof(pBSSList->abyAuthType));
+            for(i = 0; (i < pIE_RSN_Auth->wAuthCount) && (j < sizeof(pBSSList->abyAuthType)/sizeof(BYTE)); i++) {
+                if(pRSN->len >= 14+4+(m+i)*4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*m)+AKC(2)+AKS(4*i)
+                    if (MEMEqualMemory(pIE_RSN_Auth->AuthKSList[i].abyOUI, abyOUI01, 4))
+                        pBSSList->abyAuthType[j++] = WPA_AUTH_IEEE802_1X;
+                    else if (MEMEqualMemory(pIE_RSN_Auth->AuthKSList[i].abyOUI, abyOUI02, 4))
+                        pBSSList->abyAuthType[j++] = WPA_AUTH_PSK;
+                    else
+                    // any vendor checks here
+                    ;
+                }
+                else
+                    break;
+                //DBG_PRN_GRP14(("abyAuthType[%d]: %X\n", j-1, pBSSList->abyAuthType[j-1]));
+            }
+            if(j > 0)
+                pBSSList->wAuthCount = (WORD)j;
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wAuthCount: %d\n", pBSSList->wAuthCount);
+        }
+
+        if (pIE_RSN_Auth != NULL) {
+
+            n = pIE_RSN_Auth->wAuthCount;
+
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"n: %d\n", n);
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"14+4+(m+n)*4: %d\n", 14+4+(m+n)*4);
+
+            if(pRSN->len+2 >= 14+4+(m+n)*4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*m)+AKC(2)+AKS(4*n)+Cap(2)
+                pbyCaps = (PBYTE)pIE_RSN_Auth->AuthKSList[n].abyOUI;
+                pBSSList->byDefaultK_as_PK = (*pbyCaps) & WPA_GROUPFLAG;
+                pBSSList->byReplayIdx = 2 << ((*pbyCaps >> WPA_REPLAYBITSSHIFT) & WPA_REPLAYBITS);
+                pBSSList->sRSNCapObj.bRSNCapExist = TRUE;
+                pBSSList->sRSNCapObj.wRSNCap = *(PWORD)pbyCaps;
+                //DBG_PRN_GRP14(("pbyCaps: %X\n", *pbyCaps));
+                //DBG_PRN_GRP14(("byDefaultK_as_PK: %X\n", pBSSList->byDefaultK_as_PK));
+                //DBG_PRN_GRP14(("byReplayIdx: %X\n", pBSSList->byReplayIdx));
+            }
+        }
+        pBSSList->bWPAValid = TRUE;
+    }
+}
+
+/*+
+ *
+ * Description:
+ *    Search RSN information in BSSList.
+ *
+ * Parameters:
+ *  In:
+ *      byCmd    - Search type
+ *      byEncrypt- Encrcypt Type
+ *      pBSSList - BSS list
+ *  Out:
+ *      none
+ *
+ * Return Value: none.
+ *
+-*/
+BOOL
+WPA_SearchRSN (
+    BYTE                byCmd,
+    BYTE                byEncrypt,
+    IN PKnownBSS        pBSSList
+    )
+{
+    int ii;
+    BYTE byPKType = WPA_NONE;
+
+    if (pBSSList->bWPAValid == FALSE)
+        return FALSE;
+
+    switch(byCmd) {
+    case 0:
+
+        if (byEncrypt != pBSSList->byGKType)
+            return FALSE;
+
+        if (pBSSList->wPKCount > 0) {
+            for (ii = 0; ii < pBSSList->wPKCount; ii ++) {
+                if (pBSSList->abyPKType[ii] == WPA_AESCCMP)
+                    byPKType = WPA_AESCCMP;
+                else if ((pBSSList->abyPKType[ii] == WPA_TKIP) && (byPKType != WPA_AESCCMP))
+                     byPKType = WPA_TKIP;
+                else if ((pBSSList->abyPKType[ii] == WPA_WEP40) && (byPKType != WPA_AESCCMP) && (byPKType != WPA_TKIP))
+                     byPKType = WPA_WEP40;
+                else if ((pBSSList->abyPKType[ii] == WPA_WEP104) && (byPKType != WPA_AESCCMP) && (byPKType != WPA_TKIP))
+                     byPKType = WPA_WEP104;
+            }
+            if (byEncrypt != byPKType)
+                return FALSE;
+        }
+        return TRUE;
+//        if (pBSSList->wAuthCount > 0)
+//            for (ii=0; ii < pBSSList->wAuthCount; ii ++)
+//                if (byAuth == pBSSList->abyAuthType[ii])
+//                    break;
+        break;
+
+    default:
+        break;
+    }
+    return FALSE;
+}
+
+/*+
+ *
+ * Description:
+ *    Check if RSN IE makes sense.
+ *
+ * Parameters:
+ *  In:
+ *      pRSN - Pointer to the RSN IE.
+ *  Out:
+ *      none
+ *
+ * Return Value: none.
+ *
+-*/
+BOOL
+WPAb_Is_RSN (
+    IN PWLAN_IE_RSN_EXT pRSN
+    )
+{
+    if (pRSN == NULL)
+        return FALSE;
+
+    if ((pRSN->len >= 6) && // oui1(4)+ver(2)
+        (pRSN->byElementID == WLAN_EID_RSN_WPA) && MEMEqualMemory(pRSN->abyOUI, abyOUI01, 4) &&
+        (pRSN->wVersion == 1)) {
+        return TRUE;
+    }
+    else
+        return FALSE;
+}
+
diff --git a/drivers/staging/vt6655/wpa.h b/drivers/staging/vt6655/wpa.h
new file mode 100644 (file)
index 0000000..8000a37
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * 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: wpa.h
+ *
+ * Purpose: Defines the macros, types, and functions for dealing
+ *          with WPA informations.
+ *
+ * Author: Kyle Hsu
+ *
+ * Date: Jul 14, 2003
+ *
+ */
+
+#ifndef __WPA_H__
+#define __WPA_H__
+
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+#if !defined(__80211HDR_H__)
+#include "80211hdr.h"
+#endif
+
+
+/*---------------------  Export Definitions -------------------------*/
+
+#define WPA_NONE            0
+#define WPA_WEP40           1
+#define WPA_TKIP            2
+#define WPA_AESWRAP         3
+#define WPA_AESCCMP         4
+#define WPA_WEP104          5
+#define WPA_AUTH_IEEE802_1X 1
+#define WPA_AUTH_PSK        2
+
+#define WPA_GROUPFLAG       0x02
+#define WPA_REPLAYBITSSHIFT 2
+#define WPA_REPLAYBITS      0x03
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Types  ------------------------------*/
+
+
+/*---------------------  Export Functions  --------------------------*/
+#ifdef __cplusplus
+extern "C" {                            /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+VOID
+WPA_ClearRSN(
+    IN PKnownBSS        pBSSList
+    );
+
+VOID
+WPA_ParseRSN(
+    IN PKnownBSS        pBSSList,
+    IN PWLAN_IE_RSN_EXT pRSN
+    );
+
+BOOL
+WPA_SearchRSN(
+    BYTE                byCmd,
+    BYTE                byEncrypt,
+    IN PKnownBSS        pBSSList
+    );
+
+BOOL
+WPAb_Is_RSN(
+    IN PWLAN_IE_RSN_EXT pRSN
+    );
+
+#ifdef __cplusplus
+}                                       /* End of extern "C" { */
+#endif /* __cplusplus */
+
+
+#endif // __WPA_H__
diff --git a/drivers/staging/vt6655/wpa2.c b/drivers/staging/vt6655/wpa2.c
new file mode 100644 (file)
index 0000000..e2fdb33
--- /dev/null
@@ -0,0 +1,373 @@
+/*
+ * 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: wpa2.c
+ *
+ * Purpose: Handles the Basic Service Set & Node Database functions
+ *
+ * Functions:
+ *
+ * Revision History:
+ *
+ * Author: Yiching Chen
+ *
+ * Date: Oct. 4, 2004
+ *
+ */
+#if !defined(__WPA2_H__)
+#include "wpa2.h"
+#endif
+#if !defined(__UMEM_H__)
+#include "umem.h"
+#endif
+#if !defined(__DEVICE_H__)
+#include "device.h"
+#endif
+#if !defined(__WMGR_H__)
+#include "wmgr.h"
+#endif
+
+
+/*---------------------  Static Definitions -------------------------*/
+static int          msglevel                =MSG_LEVEL_INFO;
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+
+const BYTE abyOUIGK[4]      = { 0x00, 0x0F, 0xAC, 0x00 };
+const BYTE abyOUIWEP40[4]   = { 0x00, 0x0F, 0xAC, 0x01 };
+const BYTE abyOUIWEP104[4]  = { 0x00, 0x0F, 0xAC, 0x05 };
+const BYTE abyOUITKIP[4]    = { 0x00, 0x0F, 0xAC, 0x02 };
+const BYTE abyOUICCMP[4]    = { 0x00, 0x0F, 0xAC, 0x04 };
+
+const BYTE abyOUI8021X[4]   = { 0x00, 0x0F, 0xAC, 0x01 };
+const BYTE abyOUIPSK[4]     = { 0x00, 0x0F, 0xAC, 0x02 };
+
+
+/*---------------------  Static Functions  --------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+/*+
+ *
+ * Description:
+ *    Clear RSN information in BSSList.
+ *
+ * Parameters:
+ *  In:
+ *      pBSSNode - BSS list.
+ *  Out:
+ *      none
+ *
+ * Return Value: none.
+ *
+-*/
+VOID
+WPA2_ClearRSN (
+    IN PKnownBSS        pBSSNode
+    )
+{
+    int ii;
+
+    pBSSNode->bWPA2Valid = FALSE;
+
+    pBSSNode->byCSSGK = WLAN_11i_CSS_CCMP;
+    for (ii=0; ii < 4; ii ++)
+        pBSSNode->abyCSSPK[ii] = WLAN_11i_CSS_CCMP;
+    pBSSNode->wCSSPKCount = 1;
+    for (ii=0; ii < 4; ii ++)
+        pBSSNode->abyAKMSSAuthType[ii] = WLAN_11i_AKMSS_802_1X;
+    pBSSNode->wAKMSSAuthCount = 1;
+    pBSSNode->sRSNCapObj.bRSNCapExist = FALSE;
+    pBSSNode->sRSNCapObj.wRSNCap = 0;
+}
+
+/*+
+ *
+ * Description:
+ *    Parse RSN IE.
+ *
+ * Parameters:
+ *  In:
+ *      pBSSNode - BSS list.
+ *      pRSN - Pointer to the RSN IE.
+ *  Out:
+ *      none
+ *
+ * Return Value: none.
+ *
+-*/
+VOID
+WPA2vParseRSN (
+    IN PKnownBSS        pBSSNode,
+    IN PWLAN_IE_RSN     pRSN
+    )
+{
+    int                 i, j;
+    WORD                m = 0, n = 0;
+    PBYTE               pbyOUI;
+    BOOL                bUseGK = FALSE;
+
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"WPA2_ParseRSN: [%d]\n", pRSN->len);
+
+    WPA2_ClearRSN(pBSSNode);
+
+    if (pRSN->len == 2) { // ver(2)
+        if ((pRSN->byElementID == WLAN_EID_RSN) && (pRSN->wVersion == 1)) {
+            pBSSNode->bWPA2Valid = TRUE;
+        }
+        return;
+    }
+
+    if (pRSN->len < 6) { // ver(2) + GK(4)
+        // invalid CSS, P802.11i/D10.0, p31
+        return;
+    }
+
+    // information element header makes sense
+    if ((pRSN->byElementID == WLAN_EID_RSN) &&
+        (pRSN->wVersion == 1)) {
+
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Legal 802.11i RSN\n");
+
+        pbyOUI = &(pRSN->abyRSN[0]);
+        if (MEMEqualMemory(pbyOUI, abyOUIWEP40, 4))
+            pBSSNode->byCSSGK = WLAN_11i_CSS_WEP40;
+        else if (MEMEqualMemory(pbyOUI, abyOUITKIP, 4))
+            pBSSNode->byCSSGK = WLAN_11i_CSS_TKIP;
+        else if (MEMEqualMemory(pbyOUI, abyOUICCMP, 4))
+            pBSSNode->byCSSGK = WLAN_11i_CSS_CCMP;
+        else if (MEMEqualMemory(pbyOUI, abyOUIWEP104, 4))
+            pBSSNode->byCSSGK = WLAN_11i_CSS_WEP104;
+        else if (MEMEqualMemory(pbyOUI, abyOUIGK, 4)) {
+            // invalid CSS, P802.11i/D10.0, p32
+            return;
+        } else
+            // any vendor checks here
+            pBSSNode->byCSSGK = WLAN_11i_CSS_UNKNOWN;
+
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"802.11i CSS: %X\n", pBSSNode->byCSSGK);
+
+        if (pRSN->len == 6) {
+            pBSSNode->bWPA2Valid = TRUE;
+            return;
+        }
+
+        if (pRSN->len >= 8) { // ver(2) + GK(4) + PK count(2)
+            pBSSNode->wCSSPKCount = *((PWORD) &(pRSN->abyRSN[4]));
+            j = 0;
+            pbyOUI = &(pRSN->abyRSN[6]);
+
+            for (i = 0; (i < pBSSNode->wCSSPKCount) && (j < sizeof(pBSSNode->abyCSSPK)/sizeof(BYTE)); i++) {
+
+                if (pRSN->len >= 8+i*4+4) { // ver(2)+GK(4)+PKCnt(2)+PKS(4*i)
+                    if (MEMEqualMemory(pbyOUI, abyOUIGK, 4)) {
+                        pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_USE_GROUP;
+                        bUseGK = TRUE;
+                    } else if (MEMEqualMemory(pbyOUI, abyOUIWEP40, 4)) {
+                        // Invialid CSS, continue to parsing
+                    } else if (MEMEqualMemory(pbyOUI, abyOUITKIP, 4)) {
+                        if (pBSSNode->byCSSGK != WLAN_11i_CSS_CCMP)
+                            pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_TKIP;
+                        else
+                            ; // Invialid CSS, continue to parsing
+                    } else if (MEMEqualMemory(pbyOUI, abyOUICCMP, 4)) {
+                        pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_CCMP;
+                    } else if (MEMEqualMemory(pbyOUI, abyOUIWEP104, 4)) {
+                        // Invialid CSS, continue to parsing
+                    } else {
+                        // any vendor checks here
+                        pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_UNKNOWN;
+                    }
+                    pbyOUI += 4;
+                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"abyCSSPK[%d]: %X\n", j-1, pBSSNode->abyCSSPK[j-1]);
+                } else
+                    break;
+            } //for
+
+            if (bUseGK == TRUE) {
+                if (j != 1) {
+                    // invalid CSS, This should be only PK CSS.
+                    return;
+                }
+                if (pBSSNode->byCSSGK == WLAN_11i_CSS_CCMP) {
+                    // invalid CSS, If CCMP is enable , PK can't be CSSGK.
+                    return;
+                }
+            }
+            if ((pBSSNode->wCSSPKCount != 0) && (j == 0)) {
+                // invalid CSS, No valid PK.
+                return;
+            }
+            pBSSNode->wCSSPKCount = (WORD)j;
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wCSSPKCount: %d\n", pBSSNode->wCSSPKCount);
+        }
+
+        m = *((PWORD) &(pRSN->abyRSN[4]));
+
+        if (pRSN->len >= 10+m*4) { // ver(2) + GK(4) + PK count(2) + PKS(4*m) + AKMSS count(2)
+            pBSSNode->wAKMSSAuthCount = *((PWORD) &(pRSN->abyRSN[6+4*m]));;
+            j = 0;
+            pbyOUI = &(pRSN->abyRSN[8+4*m]);
+            for (i = 0; (i < pBSSNode->wAKMSSAuthCount) && (j < sizeof(pBSSNode->abyAKMSSAuthType)/sizeof(BYTE)); i++) {
+                if (pRSN->len >= 10+(m+i)*4+4) { // ver(2)+GK(4)+PKCnt(2)+PKS(4*m)+AKMSS(2)+AKS(4*i)
+                    if (MEMEqualMemory(pbyOUI, abyOUI8021X, 4))
+                        pBSSNode->abyAKMSSAuthType[j++] = WLAN_11i_AKMSS_802_1X;
+                    else if (MEMEqualMemory(pbyOUI, abyOUIPSK, 4))
+                        pBSSNode->abyAKMSSAuthType[j++] = WLAN_11i_AKMSS_PSK;
+                    else
+                        // any vendor checks here
+                        pBSSNode->abyAKMSSAuthType[j++] = WLAN_11i_AKMSS_UNKNOWN;
+                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"abyAKMSSAuthType[%d]: %X\n", j-1, pBSSNode->abyAKMSSAuthType[j-1]);
+                } else
+                    break;
+            }
+            pBSSNode->wAKMSSAuthCount = (WORD)j;
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wAKMSSAuthCount: %d\n", pBSSNode->wAKMSSAuthCount);
+
+            n = *((PWORD) &(pRSN->abyRSN[6+4*m]));;
+            if (pRSN->len >= 12+4*m+4*n) { // ver(2)+GK(4)+PKCnt(2)+PKS(4*m)+AKMSSCnt(2)+AKMSS(4*n)+Cap(2)
+                pBSSNode->sRSNCapObj.bRSNCapExist = TRUE;
+                pBSSNode->sRSNCapObj.wRSNCap = *((PWORD) &(pRSN->abyRSN[8+4*m+4*n]));
+            }
+        }
+        //ignore PMKID lists bcs only (Re)Assocrequest has this field
+        pBSSNode->bWPA2Valid = TRUE;
+    }
+}
+
+
+/*+
+ *
+ * Description:
+ *    Set WPA IEs
+ *
+ * Parameters:
+ *  In:
+ *      pMgmtHandle - Pointer to management object
+ *  Out:
+ *      pRSNIEs     - Pointer to the RSN IE to set.
+ *
+ * Return Value: length of IEs.
+ *
+-*/
+UINT
+WPA2uSetIEs(
+    IN PVOID pMgmtHandle,
+    OUT PWLAN_IE_RSN pRSNIEs
+    )
+{
+    PSMgmtObject    pMgmt = (PSMgmtObject) pMgmtHandle;
+    PBYTE           pbyBuffer = NULL;
+    UINT            ii = 0;
+    PWORD           pwPMKID = NULL;
+
+    if (pRSNIEs == NULL) {
+        return(0);
+    }
+    if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) ||
+         (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) &&
+        (pMgmt->pCurrBSS != NULL)) {
+        /* WPA2 IE */
+        pbyBuffer = (PBYTE) pRSNIEs;
+        pRSNIEs->byElementID = WLAN_EID_RSN;
+        pRSNIEs->len = 6; //Version(2)+GK(4)
+        pRSNIEs->wVersion = 1;
+        //Group Key Cipher Suite
+        pRSNIEs->abyRSN[0] = 0x00;
+        pRSNIEs->abyRSN[1] = 0x0F;
+        pRSNIEs->abyRSN[2] = 0xAC;
+        if (pMgmt->byCSSGK == KEY_CTL_WEP) {
+            pRSNIEs->abyRSN[3] = pMgmt->pCurrBSS->byCSSGK;
+        } else if (pMgmt->byCSSGK == KEY_CTL_TKIP) {
+            pRSNIEs->abyRSN[3] = WLAN_11i_CSS_TKIP;
+        } else if (pMgmt->byCSSGK == KEY_CTL_CCMP) {
+            pRSNIEs->abyRSN[3] = WLAN_11i_CSS_CCMP;
+        } else {
+            pRSNIEs->abyRSN[3] = WLAN_11i_CSS_UNKNOWN;
+        }
+
+        // Pairwise Key Cipher Suite
+        pRSNIEs->abyRSN[4] = 1;
+        pRSNIEs->abyRSN[5] = 0;
+        pRSNIEs->abyRSN[6] = 0x00;
+        pRSNIEs->abyRSN[7] = 0x0F;
+        pRSNIEs->abyRSN[8] = 0xAC;
+        if (pMgmt->byCSSPK == KEY_CTL_TKIP) {
+            pRSNIEs->abyRSN[9] = WLAN_11i_CSS_TKIP;
+        } else if (pMgmt->byCSSPK == KEY_CTL_CCMP) {
+            pRSNIEs->abyRSN[9] = WLAN_11i_CSS_CCMP;
+        } else if (pMgmt->byCSSPK == KEY_CTL_NONE) {
+            pRSNIEs->abyRSN[9] = WLAN_11i_CSS_USE_GROUP;
+        } else {
+            pRSNIEs->abyRSN[9] = WLAN_11i_CSS_UNKNOWN;
+        }
+        pRSNIEs->len += 6;
+
+        // Auth Key Management Suite
+        pRSNIEs->abyRSN[10] = 1;
+        pRSNIEs->abyRSN[11] = 0;
+        pRSNIEs->abyRSN[12] = 0x00;
+        pRSNIEs->abyRSN[13] = 0x0F;
+        pRSNIEs->abyRSN[14] = 0xAC;
+        if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK) {
+            pRSNIEs->abyRSN[15] = WLAN_11i_AKMSS_PSK;
+        } else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) {
+            pRSNIEs->abyRSN[15] = WLAN_11i_AKMSS_802_1X;
+        } else {
+            pRSNIEs->abyRSN[15] = WLAN_11i_AKMSS_UNKNOWN;
+        }
+        pRSNIEs->len +=6;
+
+        // RSN Capabilites
+        if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist == TRUE) {
+            MEMvCopy(&pRSNIEs->abyRSN[16], &pMgmt->pCurrBSS->sRSNCapObj.wRSNCap, 2);
+        } else {
+            pRSNIEs->abyRSN[16] = 0;
+            pRSNIEs->abyRSN[17] = 0;
+        }
+        pRSNIEs->len +=2;
+
+        if ((pMgmt->gsPMKIDCache.BSSIDInfoCount > 0) &&
+            (pMgmt->bRoaming == TRUE) &&
+            (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) {
+            // RSN PMKID
+            pwPMKID = (PWORD)(&pRSNIEs->abyRSN[18]);  // Point to PMKID count
+            *pwPMKID = 0;                               // Initialize PMKID count
+            pbyBuffer = &pRSNIEs->abyRSN[20];           // Point to PMKID list
+            for (ii = 0; ii < pMgmt->gsPMKIDCache.BSSIDInfoCount; ii++) {
+                if (MEMEqualMemory(&pMgmt->gsPMKIDCache.BSSIDInfo[ii].abyBSSID[0], pMgmt->abyCurrBSSID, U_ETHER_ADDR_LEN)) {
+                    (*pwPMKID) ++;
+                    MEMvCopy(pbyBuffer, pMgmt->gsPMKIDCache.BSSIDInfo[ii].abyPMKID, 16);
+                    pbyBuffer += 16;
+                }
+            }
+            if (*pwPMKID != 0) {
+                pRSNIEs->len += (2 + (*pwPMKID)*16);
+            } else {
+                pbyBuffer = &pRSNIEs->abyRSN[18];
+            }
+        }
+        return(pRSNIEs->len + WLAN_IEHDR_LEN);
+    }
+    return(0);
+}
diff --git a/drivers/staging/vt6655/wpa2.h b/drivers/staging/vt6655/wpa2.h
new file mode 100644 (file)
index 0000000..bda045b
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * 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: wpa2.h
+ *
+ * Purpose: Defines the macros, types, and functions for dealing
+ *          with WPA2 informations.
+ *
+ * Author: Yiching Chen
+ *
+ * Date: Oct. 4, 2004
+ *
+ */
+
+#ifndef __WPA2_H__
+#define __WPA2_H__
+
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+#if !defined(__80211MGR_H__)
+#include "80211mgr.h"
+#endif
+#if !defined(__80211HDR_H__)
+#include "80211hdr.h"
+#endif
+#if !defined(__BSSDB_H__)
+#include "bssdb.h"
+#endif
+#if !defined(__VNTWIFI_H__)
+#include "vntwifi.h"
+#endif
+
+
+
+/*---------------------  Export Definitions -------------------------*/
+
+typedef struct tagsPMKIDInfo {
+    BYTE    abyBSSID[6];
+    BYTE    abyPMKID[16];
+} PMKIDInfo, *PPMKIDInfo;
+
+typedef struct tagSPMKIDCache {
+    ULONG       BSSIDInfoCount;
+    PMKIDInfo   BSSIDInfo[MAX_PMKID_CACHE];
+} SPMKIDCache, *PSPMKIDCache;
+
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Types  ------------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+#ifdef __cplusplus
+extern "C" {                            /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+VOID
+WPA2_ClearRSN (
+    IN PKnownBSS        pBSSNode
+    );
+
+VOID
+WPA2vParseRSN (
+    IN PKnownBSS        pBSSNode,
+    IN PWLAN_IE_RSN     pRSN
+    );
+
+UINT
+WPA2uSetIEs(
+    IN PVOID pMgmtHandle,
+    OUT PWLAN_IE_RSN pRSNIEs
+    );
+
+
+#ifdef __cplusplus
+}                                       /* End of extern "C" { */
+#endif /* __cplusplus */
+
+
+#endif // __WPA2_H__
diff --git a/drivers/staging/vt6655/wpactl.c b/drivers/staging/vt6655/wpactl.c
new file mode 100644 (file)
index 0000000..ee7109d
--- /dev/null
@@ -0,0 +1,1014 @@
+/*
+ * 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: wpactl.c
+ *
+ * Purpose: handle wpa supplicant ioctl input/out functions
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: Oct. 20, 2003
+ *
+ * Functions:
+ *
+ * Revision History:
+ *
+ */
+
+
+#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(__DEVICE_H__)
+#include "device.h"
+#endif
+#if !defined(__WMGR_H__)
+#include "wmgr.h"
+#endif
+#if !defined(__IOCMD_H__)
+#include "iocmd.h"
+#endif
+#if !defined(__IOWPA_H__)
+#include "iowpa.h"
+#endif
+//2008-0717-05, <Add> by James
+#if !defined(__RF_H__)
+#include "rf.h"
+#endif
+
+/*---------------------  Static Definitions -------------------------*/
+
+#define VIAWGET_WPA_MAX_BUF_SIZE 1024
+
+
+
+static const int frequency_list[] = {
+       2412, 2417, 2422, 2427, 2432, 2437, 2442,
+       2447, 2452, 2457, 2462, 2467, 2472, 2484
+};
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+static int          msglevel                =MSG_LEVEL_INFO;
+
+/*---------------------  Static Functions  --------------------------*/
+
+
+
+
+/*---------------------  Export Variables  --------------------------*/
+
+
+static void wpadev_setup(struct net_device *dev)
+{
+       dev->type               = ARPHRD_IEEE80211;
+       dev->hard_header_len    = ETH_HLEN;
+       dev->mtu                = 2048;
+       dev->addr_len           = ETH_ALEN;
+       dev->tx_queue_len       = 1000;
+
+       memset(dev->broadcast,0xFF, ETH_ALEN);
+
+       dev->flags              = IFF_BROADCAST|IFF_MULTICAST;
+}
+
+
+
+/*
+ * Description:
+ *      register netdev for wpa supplicant deamon
+ *
+ * Parameters:
+ *  In:
+ *      pDevice             -
+ *      enable              -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+
+static int wpa_init_wpadev(PSDevice pDevice)
+{
+       struct net_device *dev = pDevice->dev;
+         int ret=0;
+
+       pDevice->wpadev = alloc_netdev(0, "vntwpa", wpadev_setup);
+       if (pDevice->wpadev == NULL)
+               return -ENOMEM;
+
+       pDevice->wpadev->priv = pDevice;
+       memcpy(pDevice->wpadev->dev_addr, dev->dev_addr, U_ETHER_ADDR_LEN);
+         pDevice->wpadev->base_addr = dev->base_addr;
+       pDevice->wpadev->irq = dev->irq;
+       pDevice->wpadev->mem_start = dev->mem_start;
+       pDevice->wpadev->mem_end = dev->mem_end;
+       ret = register_netdev(pDevice->wpadev);
+       if (ret) {
+               DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: register_netdev(WPA) failed!\n",
+                      dev->name);
+               free_netdev(pDevice->wpadev);
+               return -1;
+       }
+
+       if (pDevice->skb == NULL) {
+        pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
+        if (pDevice->skb == NULL)
+                   return -ENOMEM;
+    }
+
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Registered netdev %s for WPA management\n",
+              dev->name, pDevice->wpadev->name);
+
+       return 0;
+}
+
+
+/*
+ * Description:
+ *      unregister net_device (wpadev)
+ *
+ * Parameters:
+ *  In:
+ *      pDevice             -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+
+static int wpa_release_wpadev(PSDevice pDevice)
+{
+
+    if (pDevice->skb) {
+        dev_kfree_skb(pDevice->skb);
+        pDevice->skb = NULL;
+    }
+
+    if (pDevice->wpadev) {
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Netdevice %s unregistered\n",
+              pDevice->dev->name, pDevice->wpadev->name);
+       unregister_netdev(pDevice->wpadev);
+       free_netdev(pDevice->wpadev);
+         pDevice->wpadev = NULL;
+    }
+
+       return 0;
+}
+
+
+
+
+
+/*
+ * Description:
+ *      Set enable/disable dev for wpa supplicant deamon
+ *
+ * Parameters:
+ *  In:
+ *      pDevice             -
+ *      val                 -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+
+int wpa_set_wpadev(PSDevice pDevice, int val)
+{
+
+
+       if (val)
+               return wpa_init_wpadev(pDevice);
+       else
+               return wpa_release_wpadev(pDevice);
+}
+
+
+/*
+ * Description:
+ *      Set WPA algorithm & keys
+ *
+ * Parameters:
+ *  In:
+ *      pDevice -
+ *      param -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+
+int wpa_set_keys(PSDevice pDevice, void *ctx, BOOL  fcpfkernel)
+{
+ struct viawget_wpa_param *param=ctx;
+    PSMgmtObject pMgmt = pDevice->pMgmt;
+    DWORD   dwKeyIndex = 0;
+    BYTE    abyKey[MAX_KEY_LEN];
+    BYTE    abySeq[MAX_KEY_LEN];
+    QWORD   KeyRSC;
+//    NDIS_802_11_KEY_RSC KeyRSC;
+    BYTE    byKeyDecMode = KEY_CTL_WEP;
+       int ret = 0;
+       int uu, ii;
+
+
+       if (param->u.wpa_key.alg_name > WPA_ALG_CCMP)
+               return -EINVAL;
+
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "param->u.wpa_key.alg_name = %d \n", param->u.wpa_key.alg_name);
+       if (param->u.wpa_key.alg_name == WPA_ALG_NONE) {
+        pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
+        pDevice->bEncryptionEnable = FALSE;
+        pDevice->byKeyIndex = 0;
+        pDevice->bTransmitKey = FALSE;
+        KeyvRemoveAllWEPKey(&(pDevice->sKey), pDevice->PortOffset);
+        for (uu=0; uu<MAX_KEY_TABLE; uu++) {
+            MACvDisableKeyEntry(pDevice->PortOffset, uu);
+        }
+        return ret;
+    }
+
+    //spin_unlock_irq(&pDevice->lock);
+    if(param->u.wpa_key.key && fcpfkernel) {
+       memcpy(&abyKey[0], param->u.wpa_key.key, param->u.wpa_key.key_len);
+     }
+    else {
+       spin_unlock_irq(&pDevice->lock);
+       if (param->u.wpa_key.key &&
+           copy_from_user(&abyKey[0], param->u.wpa_key.key, param->u.wpa_key.key_len)){
+               spin_lock_irq(&pDevice->lock);
+           return -EINVAL;
+       }
+spin_lock_irq(&pDevice->lock);
+       }
+
+    dwKeyIndex = (DWORD)(param->u.wpa_key.key_index);
+
+       if (param->u.wpa_key.alg_name == WPA_ALG_WEP) {
+        if (dwKeyIndex > 3) {
+            return -EINVAL;
+        }
+        else {
+            if (param->u.wpa_key.set_tx) {
+                pDevice->byKeyIndex = (BYTE)dwKeyIndex;
+                pDevice->bTransmitKey = TRUE;
+                       dwKeyIndex |= (1 << 31);
+            }
+            KeybSetDefaultKey(&(pDevice->sKey),
+                                dwKeyIndex & ~(BIT30 | USE_KEYRSC),
+                                param->u.wpa_key.key_len,
+                                NULL,
+                                abyKey,
+                                KEY_CTL_WEP,
+                                pDevice->PortOffset,
+                                pDevice->byLocalID);
+
+        }
+        pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
+        pDevice->bEncryptionEnable = TRUE;
+        return ret;
+       }
+
+           //spin_unlock_irq(&pDevice->lock);
+        if(param->u.wpa_key.seq && fcpfkernel) {
+           memcpy(&abySeq[0], param->u.wpa_key.seq, param->u.wpa_key.seq_len);
+               }
+       else {
+               spin_unlock_irq(&pDevice->lock);
+       if (param->u.wpa_key.seq &&
+           copy_from_user(&abySeq[0], param->u.wpa_key.seq, param->u.wpa_key.seq_len)){
+
+        spin_lock_irq(&pDevice->lock);
+           return -EINVAL;
+               }
+spin_lock_irq(&pDevice->lock);
+}
+
+       if (param->u.wpa_key.seq_len > 0) {
+               for (ii = 0 ; ii < param->u.wpa_key.seq_len ; ii++) {
+                    if (ii < 4)
+                           LODWORD(KeyRSC) |= (abySeq[ii] << (ii * 8));
+                        else
+                           HIDWORD(KeyRSC) |= (abySeq[ii] << ((ii-4) * 8));
+                //KeyRSC |= (abySeq[ii] << (ii * 8));
+               }
+               dwKeyIndex |= 1 << 29;
+       }
+
+    if (param->u.wpa_key.key_index >= MAX_GROUP_KEY) {
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return  dwKeyIndex > 3\n");
+        return -EINVAL;
+    }
+
+       if (param->u.wpa_key.alg_name == WPA_ALG_TKIP) {
+        pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
+    }
+
+       if (param->u.wpa_key.alg_name == WPA_ALG_CCMP) {
+        pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
+    }
+
+       if (param->u.wpa_key.set_tx)
+               dwKeyIndex |= (1 << 31);
+
+    if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled)
+        byKeyDecMode = KEY_CTL_CCMP;
+    else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled)
+        byKeyDecMode = KEY_CTL_TKIP;
+    else
+        byKeyDecMode = KEY_CTL_WEP;
+
+    // Fix HCT test that set 256 bits KEY and Ndis802_11Encryption3Enabled
+    if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
+        if (param->u.wpa_key.key_len == MAX_KEY_LEN)
+            byKeyDecMode = KEY_CTL_TKIP;
+        else if (param->u.wpa_key.key_len == WLAN_WEP40_KEYLEN)
+            byKeyDecMode = KEY_CTL_WEP;
+        else if (param->u.wpa_key.key_len == WLAN_WEP104_KEYLEN)
+            byKeyDecMode = KEY_CTL_WEP;
+    } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
+        if (param->u.wpa_key.key_len == WLAN_WEP40_KEYLEN)
+            byKeyDecMode = KEY_CTL_WEP;
+        else if (param->u.wpa_key.key_len == WLAN_WEP104_KEYLEN)
+            byKeyDecMode = KEY_CTL_WEP;
+    }
+
+
+    // Check TKIP key length
+    if ((byKeyDecMode == KEY_CTL_TKIP) &&
+        (param->u.wpa_key.key_len != MAX_KEY_LEN)) {
+        // TKIP Key must be 256 bits
+        //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA - TKIP Key must be 256 bits\n"));
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return- TKIP Key must be 256 bits!\n");
+        return -EINVAL;
+    }
+    // Check AES key length
+    if ((byKeyDecMode == KEY_CTL_CCMP) &&
+        (param->u.wpa_key.key_len != AES_KEY_LEN)) {
+        // AES Key must be 128 bits
+        //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA - AES Key must be 128 bits\n"));
+        return -EINVAL;
+    }
+
+   // spin_lock_irq(&pDevice->lock);
+    if (IS_BROADCAST_ADDRESS(&param->addr[0]) || (param->addr == NULL)) {
+        // If IS_BROADCAST_ADDRESS, set the key as every key entry's group key.
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Groupe Key Assign.\n");
+
+        if ((KeybSetAllGroupKey(&(pDevice->sKey),
+                            dwKeyIndex,
+                            param->u.wpa_key.key_len,
+                            (PQWORD) &(KeyRSC),
+                            (PBYTE)abyKey,
+                            byKeyDecMode,
+                            pDevice->PortOffset,
+                            pDevice->byLocalID) == TRUE) &&
+            (KeybSetDefaultKey(&(pDevice->sKey),
+                            dwKeyIndex,
+                            param->u.wpa_key.key_len,
+                            (PQWORD) &(KeyRSC),
+                            (PBYTE)abyKey,
+                            byKeyDecMode,
+                            pDevice->PortOffset,
+                            pDevice->byLocalID) == TRUE) ) {
+             DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "GROUP Key Assign.\n");
+
+        } else {
+            //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA -KeybSetDefaultKey Fail.0\n"));
+           // spin_unlock_irq(&pDevice->lock);
+            return -EINVAL;
+        }
+
+    } else {
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key Assign.\n");
+        // BSSID not 0xffffffffffff
+        // Pairwise Key can't be WEP
+        if (byKeyDecMode == KEY_CTL_WEP) {
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key can't be WEP\n");
+            //spin_unlock_irq(&pDevice->lock);
+            return -EINVAL;
+        }
+
+        dwKeyIndex |= (1 << 30); // set pairwise key
+        if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) {
+            //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA - WMAC_CONFIG_IBSS_STA\n"));
+            //spin_unlock_irq(&pDevice->lock);
+            return -EINVAL;
+        }
+        if (KeybSetKey(&(pDevice->sKey),
+                       &param->addr[0],
+                       dwKeyIndex,
+                       param->u.wpa_key.key_len,
+                       (PQWORD) &(KeyRSC),
+                       (PBYTE)abyKey,
+                        byKeyDecMode,
+                        pDevice->PortOffset,
+                        pDevice->byLocalID) == TRUE) {
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key Set\n");
+
+        } else {
+            // Key Table Full
+            if (IS_ETH_ADDRESS_EQUAL(&param->addr[0], pDevice->abyBSSID)) {
+                //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA -Key Table Full.2\n"));
+                //spin_unlock_irq(&pDevice->lock);
+                return -EINVAL;
+
+            } else {
+                // Save Key and configure just before associate/reassociate to BSSID
+                // we do not implement now
+                //spin_unlock_irq(&pDevice->lock);
+                return -EINVAL;
+            }
+        }
+    } // BSSID not 0xffffffffffff
+    if ((ret == 0) && ((param->u.wpa_key.set_tx) != 0)) {
+        pDevice->byKeyIndex = (BYTE)param->u.wpa_key.key_index;
+        pDevice->bTransmitKey = TRUE;
+    }
+    pDevice->bEncryptionEnable = TRUE;
+    //spin_unlock_irq(&pDevice->lock);
+
+/*
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " key=%x-%x-%x-%x-%x-xxxxx \n",
+               pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][0],
+               pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][1],
+               pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][2],
+               pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][3],
+               pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][4]
+              );
+*/
+
+       return ret;
+
+}
+
+
+/*
+ * Description:
+ *      enable wpa auth & mode
+ *
+ * Parameters:
+ *  In:
+ *      pDevice   -
+ *      param     -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+
+static int wpa_set_wpa(PSDevice pDevice,
+                                    struct viawget_wpa_param *param)
+{
+
+    PSMgmtObject    pMgmt = pDevice->pMgmt;
+       int ret = 0;
+
+    pMgmt->eAuthenMode = WMAC_AUTH_OPEN;
+    pMgmt->bShareKeyAlgorithm = FALSE;
+
+    return ret;
+}
+
+
+
+
+ /*
+ * Description:
+ *      set disassociate
+ *
+ * Parameters:
+ *  In:
+ *      pDevice   -
+ *      param     -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+
+static int wpa_set_disassociate(PSDevice pDevice,
+                                    struct viawget_wpa_param *param)
+{
+    PSMgmtObject    pMgmt = pDevice->pMgmt;
+       int ret = 0;
+
+    spin_lock_irq(&pDevice->lock);
+    if (pDevice->bLinkPass) {
+        if (!memcmp(param->addr, pMgmt->abyCurrBSSID, 6))
+            bScheduleCommand((HANDLE)pDevice, WLAN_CMD_DISASSOCIATE, NULL);
+    }
+    spin_unlock_irq(&pDevice->lock);
+
+    return ret;
+}
+
+
+
+/*
+ * Description:
+ *      enable scan process
+ *
+ * Parameters:
+ *  In:
+ *      pDevice   -
+ *      param     -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+
+static int wpa_set_scan(PSDevice pDevice,
+                                    struct viawget_wpa_param *param)
+{
+       int ret = 0;
+
+    spin_lock_irq(&pDevice->lock);
+    BSSvClearBSSList((HANDLE)pDevice, pDevice->bLinkPass);
+    bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, NULL);
+    spin_unlock_irq(&pDevice->lock);
+
+    return ret;
+}
+
+
+
+/*
+ * Description:
+ *      get bssid
+ *
+ * Parameters:
+ *  In:
+ *      pDevice   -
+ *      param     -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+
+static int wpa_get_bssid(PSDevice pDevice,
+                                    struct viawget_wpa_param *param)
+{
+    PSMgmtObject        pMgmt = pDevice->pMgmt;
+       int ret = 0;
+
+       memcpy(param->u.wpa_associate.bssid, pMgmt->abyCurrBSSID , 6);
+
+    return ret;
+
+}
+
+
+/*
+ * Description:
+ *      get bssid
+ *
+ * Parameters:
+ *  In:
+ *      pDevice   -
+ *      param     -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+
+static int wpa_get_ssid(PSDevice pDevice,
+                                    struct viawget_wpa_param *param)
+{
+    PSMgmtObject        pMgmt = pDevice->pMgmt;
+       PWLAN_IE_SSID       pItemSSID;
+       int ret = 0;
+
+    pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
+
+       memcpy(param->u.wpa_associate.ssid, pItemSSID->abySSID , pItemSSID->len);
+       param->u.wpa_associate.ssid_len = pItemSSID->len;
+
+    return ret;
+}
+
+
+
+/*
+ * Description:
+ *      get scan results
+ *
+ * Parameters:
+ *  In:
+ *      pDevice   -
+ *      param     -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+
+static int wpa_get_scan(PSDevice pDevice,
+                                    struct viawget_wpa_param *param)
+{
+       struct viawget_scan_result *scan_buf;
+    PSMgmtObject    pMgmt = pDevice->pMgmt;
+    PWLAN_IE_SSID   pItemSSID;
+    PKnownBSS pBSS;
+       PBYTE  pBuf;
+       int ret = 0;
+       u16 count = 0;
+       u16 ii, jj;
+#if 1
+
+    PBYTE ptempBSS;
+
+
+
+    ptempBSS = kmalloc(sizeof(KnownBSS), (int)GFP_ATOMIC);
+
+    if (ptempBSS == NULL) {
+
+       printk("bubble sort kmalloc memory fail@@@\n");
+
+        ret = -ENOMEM;
+
+        return ret;
+
+    }
+
+    for (ii = 0; ii < MAX_BSS_NUM; ii++) {
+
+         for(jj=0;jj<MAX_BSS_NUM-ii-1;jj++) {
+
+           if((pMgmt->sBSSList[jj].bActive!=TRUE) ||
+
+                ((pMgmt->sBSSList[jj].uRSSI>pMgmt->sBSSList[jj+1].uRSSI) &&(pMgmt->sBSSList[jj+1].bActive!=FALSE))) {
+
+                 memcpy(ptempBSS,&pMgmt->sBSSList[jj],sizeof(KnownBSS));
+
+                 memcpy(&pMgmt->sBSSList[jj],&pMgmt->sBSSList[jj+1],sizeof(KnownBSS));
+
+                 memcpy(&pMgmt->sBSSList[jj+1],ptempBSS,sizeof(KnownBSS));
+
+              }
+
+         }
+
+    };
+
+  kfree(ptempBSS);
+
+ // printk("bubble sort result:\n");
+
+  //for (ii = 0; ii < MAX_BSS_NUM; ii++)
+
+  //    printk("%d [%s]:RSSI=%d\n",ii,((PWLAN_IE_SSID)(pMgmt->sBSSList[ii].abySSID))->abySSID,
+
+  //                                                                 pMgmt->sBSSList[ii].uRSSI);
+
+ #endif
+
+//******mike:bubble sort by stronger RSSI*****//
+
+
+
+
+       count = 0;
+       pBSS = &(pMgmt->sBSSList[0]);
+    for (ii = 0; ii < MAX_BSS_NUM; ii++) {
+        pBSS = &(pMgmt->sBSSList[ii]);
+        if (!pBSS->bActive)
+            continue;
+        count++;
+    };
+
+    pBuf = kmalloc(sizeof(struct viawget_scan_result) * count, (int)GFP_ATOMIC);
+
+    if (pBuf == NULL) {
+        ret = -ENOMEM;
+        return ret;
+    }
+       memset(pBuf, 0, sizeof(struct viawget_scan_result) * count);
+    scan_buf = (struct viawget_scan_result *)pBuf;
+       pBSS = &(pMgmt->sBSSList[0]);
+    for (ii = 0, jj = 0; ii < MAX_BSS_NUM ; ii++) {
+        pBSS = &(pMgmt->sBSSList[ii]);
+        if (pBSS->bActive) {
+            if (jj >= count)
+                break;
+            memcpy(scan_buf->bssid, pBSS->abyBSSID, WLAN_BSSID_LEN);
+            pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID;
+                   memcpy(scan_buf->ssid, pItemSSID->abySSID, pItemSSID->len);
+                   scan_buf->ssid_len = pItemSSID->len;
+            scan_buf->freq = frequency_list[pBSS->uChannel-1];
+         scan_buf->caps = pBSS->wCapInfo;
+            //scan_buf->caps = pBSS->wCapInfo;
+            //scan_buf->qual =
+            //scan_buf->noise =
+            //scan_buf->level =
+            //scan_buf->maxrate =
+            if (pBSS->wWPALen != 0) {
+                scan_buf->wpa_ie_len = pBSS->wWPALen;
+                memcpy(scan_buf->wpa_ie, pBSS->byWPAIE, pBSS->wWPALen);
+            }
+            if (pBSS->wRSNLen != 0) {
+                scan_buf->rsn_ie_len = pBSS->wRSNLen;
+                memcpy(scan_buf->rsn_ie, pBSS->byRSNIE, pBSS->wRSNLen);
+            }
+            scan_buf = (struct viawget_scan_result *)((PBYTE)scan_buf + sizeof(struct viawget_scan_result));
+            jj ++;
+        }
+    }
+
+    if (jj < count)
+        count = jj;
+
+    if (copy_to_user(param->u.scan_results.buf, pBuf, sizeof(struct viawget_scan_result) * count)) {
+               ret = -EFAULT;
+       };
+       param->u.scan_results.scan_count = count;
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " param->u.scan_results.scan_count = %d\n", count)
+
+    kfree(pBuf);
+    return ret;
+}
+
+
+
+/*
+ * Description:
+ *      set associate with AP
+ *
+ * Parameters:
+ *  In:
+ *      pDevice   -
+ *      param     -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+
+static int wpa_set_associate(PSDevice pDevice,
+                                    struct viawget_wpa_param *param)
+{
+    PSMgmtObject    pMgmt = pDevice->pMgmt;
+    PWLAN_IE_SSID   pItemSSID;
+    BYTE    abyNullAddr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+    BYTE    abyWPAIE[64];
+    int ret = 0;
+    BOOL bWepEnabled=FALSE;
+
+       // set key type & algorithm
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pairwise_suite = %d\n", param->u.wpa_associate.pairwise_suite);
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "group_suite = %d\n", param->u.wpa_associate.group_suite);
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "key_mgmt_suite = %d\n", param->u.wpa_associate.key_mgmt_suite);
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "auth_alg = %d\n", param->u.wpa_associate.auth_alg);
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "mode = %d\n", param->u.wpa_associate.mode);
+    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_ie_len = %d\n", param->u.wpa_associate.wpa_ie_len);
+
+
+       if (param->u.wpa_associate.wpa_ie &&
+           copy_from_user(&abyWPAIE[0], param->u.wpa_associate.wpa_ie, param->u.wpa_associate.wpa_ie_len))
+           return -EINVAL;
+
+       if (param->u.wpa_associate.mode == 1)
+           pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA;
+       else
+           pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA;
+    // set ssid
+       memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+    pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
+    pItemSSID->byElementID = WLAN_EID_SSID;
+       pItemSSID->len = param->u.wpa_associate.ssid_len;
+       memcpy(pItemSSID->abySSID, param->u.wpa_associate.ssid, pItemSSID->len);
+       // set bssid
+    if (memcmp(param->u.wpa_associate.bssid, &abyNullAddr[0], 6) != 0)
+        memcpy(pMgmt->abyDesireBSSID, param->u.wpa_associate.bssid, 6);
+else
+{
+   bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, pItemSSID->abySSID);
+}
+
+    if (param->u.wpa_associate.wpa_ie_len == 0) {
+           if (param->u.wpa_associate.auth_alg & AUTH_ALG_SHARED_KEY)
+            pMgmt->eAuthenMode = WMAC_AUTH_SHAREKEY;
+           else
+            pMgmt->eAuthenMode = WMAC_AUTH_OPEN;
+       } else if (abyWPAIE[0] == RSN_INFO_ELEM) {
+               if (param->u.wpa_associate.key_mgmt_suite == KEY_MGMT_PSK)
+                       pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK;
+               else
+                       pMgmt->eAuthenMode = WMAC_AUTH_WPA2;
+       } else {
+               if (param->u.wpa_associate.key_mgmt_suite == KEY_MGMT_WPA_NONE)
+                       pMgmt->eAuthenMode = WMAC_AUTH_WPANONE;
+               else if (param->u.wpa_associate.key_mgmt_suite == KEY_MGMT_PSK)
+                   pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK;
+               else
+                   pMgmt->eAuthenMode = WMAC_AUTH_WPA;
+       }
+
+       switch (param->u.wpa_associate.pairwise_suite) {
+       case CIPHER_CCMP:
+               pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
+               break;
+       case CIPHER_TKIP:
+               pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
+               break;
+       case CIPHER_WEP40:
+       case CIPHER_WEP104:
+               pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
+               bWepEnabled=TRUE;
+               break;
+       case CIPHER_NONE:
+               if (param->u.wpa_associate.group_suite == CIPHER_CCMP)
+                       pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
+               else
+                       pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
+               break;
+       default:
+               pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
+       };
+
+//DavidWang add for WPA_supplicant support open/share mode
+
+      if (pMgmt->eAuthenMode == WMAC_AUTH_SHAREKEY) {
+            pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
+            //pMgmt->eAuthenMode = WMAC_AUTH_SHAREKEY;
+            pMgmt->bShareKeyAlgorithm = TRUE;
+             }
+     else if (pMgmt->eAuthenMode == WMAC_AUTH_OPEN) {
+          if(!bWepEnabled)  pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
+       else pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
+            //pMgmt->eAuthenMode = WMAC_AUTH_OPEN;
+            //pMgmt->bShareKeyAlgorithm = FALSE; //20080717-06,<Modify> by chester//Fix Open mode, WEP encrytion
+           }
+//mike save old encryption status
+       pDevice->eOldEncryptionStatus = pDevice->eEncryptionStatus;
+
+    if (pDevice->eEncryptionStatus !=  Ndis802_11EncryptionDisabled)
+        pDevice->bEncryptionEnable = TRUE;
+    else
+        pDevice->bEncryptionEnable = FALSE;
+if (!((pMgmt->eAuthenMode == WMAC_AUTH_SHAREKEY) ||
+      ((pMgmt->eAuthenMode == WMAC_AUTH_OPEN) && (bWepEnabled==TRUE))) )  //DavidWang  //20080717-06,<Modify> by chester//Not to initial WEP
+    KeyvInitTable(&pDevice->sKey, pDevice->PortOffset);
+    spin_lock_irq(&pDevice->lock);
+    pDevice->bLinkPass = FALSE;
+    memset(pMgmt->abyCurrBSSID, 0, 6);
+    pMgmt->eCurrState = WMAC_STATE_IDLE;
+    netif_stop_queue(pDevice->dev);
+       //20080701-02,<Add> by Mike Liu
+/*******search if ap_scan=2 ,which is associating request in hidden ssid mode ****/
+{
+   PKnownBSS       pCurr = NULL;
+    pCurr = BSSpSearchBSSList(pDevice,
+                              pMgmt->abyDesireBSSID,
+                              pMgmt->abyDesireSSID,
+                              pMgmt->eConfigPHYMode
+                              );
+
+    if (pCurr == NULL){
+    printk("wpa_set_associate---->hidden mode site survey before associate.......\n");
+    bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID);
+  };
+}
+/****************************************************************/
+    bScheduleCommand((HANDLE) pDevice, WLAN_CMD_SSID, NULL);
+    spin_unlock_irq(&pDevice->lock);
+
+    return ret;
+}
+
+
+/*
+ * Description:
+ *      wpa_ioctl main function supported for wpa supplicant
+ *
+ * Parameters:
+ *  In:
+ *      pDevice   -
+ *      iw_point  -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+
+int wpa_ioctl(PSDevice pDevice, struct iw_point *p)
+{
+       struct viawget_wpa_param *param;
+       int ret = 0;
+       int wpa_ioctl = 0;
+
+       if (p->length < sizeof(struct viawget_wpa_param) ||
+           p->length > VIAWGET_WPA_MAX_BUF_SIZE || !p->pointer)
+               return -EINVAL;
+
+       param = (struct viawget_wpa_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_SET_WPA:
+        ret = wpa_set_wpa(pDevice, param);
+           DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_WPA \n");
+               break;
+
+       case VIAWGET_SET_KEY:
+           DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_KEY \n");
+           spin_lock_irq(&pDevice->lock);
+        ret = wpa_set_keys(pDevice, param, FALSE);
+        spin_unlock_irq(&pDevice->lock);
+               break;
+
+       case VIAWGET_SET_SCAN:
+           DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_SCAN \n");
+        ret = wpa_set_scan(pDevice, param);
+               break;
+
+       case VIAWGET_GET_SCAN:
+           DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_SCAN\n");
+        ret = wpa_get_scan(pDevice, param);
+               wpa_ioctl = 1;
+               break;
+
+       case VIAWGET_GET_SSID:
+           DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_SSID \n");
+        ret = wpa_get_ssid(pDevice, param);
+               wpa_ioctl = 1;
+               break;
+
+       case VIAWGET_GET_BSSID:
+           DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_BSSID \n");
+        ret = wpa_get_bssid(pDevice, param);
+               wpa_ioctl = 1;
+               break;
+
+       case VIAWGET_SET_ASSOCIATE:
+           DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_ASSOCIATE \n");
+        ret = wpa_set_associate(pDevice, param);
+               break;
+
+       case VIAWGET_SET_DISASSOCIATE:
+           DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DISASSOCIATE \n");
+        ret = wpa_set_disassociate(pDevice, param);
+               break;
+
+       case VIAWGET_SET_DROP_UNENCRYPT:
+           DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DROP_UNENCRYPT \n");
+               break;
+
+    case VIAWGET_SET_DEAUTHENTICATE:
+           DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DEAUTHENTICATE \n");
+               break;
+
+       default:
+           DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_ioctl: unknown cmd=%d\n",
+                      param->cmd);
+               return -EOPNOTSUPP;
+               break;
+       }
+
+       if ((ret == 0) && wpa_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/vt6655/wpactl.h b/drivers/staging/vt6655/wpactl.h
new file mode 100644 (file)
index 0000000..9e78897
--- /dev/null
@@ -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: wpactl.h
+ *
+ * Purpose:
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: March 1, 2005
+ *
+ */
+
+
+#ifndef __WPACTL_H__
+#define __WPACTL_H__
+
+#if !defined(__DEVICE_H__)
+#include "device.h"
+#endif
+#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+#if !defined(__IOWPA_H__)
+#include "iowpa.h"
+#endif
+#endif
+
+/*---------------------  Export Definitions -------------------------*/
+
+
+//WPA related
+
+typedef enum { WPA_ALG_NONE, WPA_ALG_WEP, WPA_ALG_TKIP, WPA_ALG_CCMP } wpa_alg;
+typedef enum { CIPHER_NONE, CIPHER_WEP40, CIPHER_TKIP, CIPHER_CCMP,
+              CIPHER_WEP104 } wpa_cipher;
+typedef enum { KEY_MGMT_802_1X, KEY_MGMT_CCKM,KEY_MGMT_PSK, KEY_MGMT_NONE,
+              KEY_MGMT_802_1X_NO_WPA, KEY_MGMT_WPA_NONE } wpa_key_mgmt;
+
+#define AUTH_ALG_OPEN_SYSTEM   0x01
+#define AUTH_ALG_SHARED_KEY    0x02
+#define AUTH_ALG_LEAP          0x04
+
+#define GENERIC_INFO_ELEM 0xdd
+#define RSN_INFO_ELEM 0x30
+
+
+
+typedef ULONGLONG   NDIS_802_11_KEY_RSC;
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+#ifdef __cplusplus
+extern "C" {                            /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+int wpa_set_wpadev(PSDevice pDevice, int val);
+int wpa_ioctl(PSDevice pDevice, struct iw_point *p);
+int wpa_set_keys(PSDevice pDevice, void *ctx, BOOL  fcpfkernel);
+
+#ifdef __cplusplus
+}                                       /* End of extern "C" { */
+#endif /* __cplusplus */
+
+
+
+
+#endif // __WPACL_H__
+
+
+
diff --git a/drivers/staging/vt6655/wroute.c b/drivers/staging/vt6655/wroute.c
new file mode 100644 (file)
index 0000000..219ae21
--- /dev/null
@@ -0,0 +1,211 @@
+/*
+ * 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: wroute.c
+ *
+ * Purpose: handle WMAC frame relay & filterring
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: May 20, 2003
+ *
+ * Functions:
+ *      ROUTEbRelay - Relay packet
+ *
+ * Revision History:
+ *
+ */
+
+
+#if !defined(__MAC_H__)
+#include "mac.h"
+#endif
+#if !defined(__TCRC_H__)
+#include "tcrc.h"
+#endif
+#if !defined(__RXTX_H__)
+#include "rxtx.h"
+#endif
+#if !defined(__WROUTE_H__)
+#include "wroute.h"
+#endif
+#if !defined(__CARD_H__)
+#include "card.h"
+#endif
+#if !defined(__BASEBAND_H__)
+#include "baseband.h"
+#endif
+/*---------------------  Static Definitions -------------------------*/
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+static int          msglevel                =MSG_LEVEL_INFO;
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+/*---------------------  Static Functions  --------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+
+
+/*
+ * Description:
+ *      Relay packet.  Return TRUE if packet is copy to DMA1
+ *
+ * Parameters:
+ *  In:
+ *      pDevice             -
+ *      pbySkbData          - rx packet skb data
+ *  Out:
+ *      TURE, FALSE
+ *
+ * Return Value: TRUE if packet duplicate; otherwise FALSE
+ *
+ */
+BOOL ROUTEbRelay (PSDevice pDevice, PBYTE pbySkbData, UINT uDataLen, UINT uNodeIndex)
+{
+    PSMgmtObject    pMgmt = pDevice->pMgmt;
+    PSTxDesc        pHeadTD, pLastTD;
+    UINT            cbFrameBodySize;
+    UINT            uMACfragNum;
+    BYTE            byPktTyp;
+    BOOL            bNeedEncryption = FALSE;
+    SKeyItem        STempKey;
+    PSKeyItem       pTransmitKey = NULL;
+    UINT            cbHeaderSize;
+    UINT            ii;
+    PBYTE           pbyBSSID;
+
+
+
+
+    if (AVAIL_TD(pDevice, TYPE_AC0DMA)<=0) {
+        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Relay can't allocate TD1..\n");
+        return FALSE;
+    }
+
+    pHeadTD = pDevice->apCurrTD[TYPE_AC0DMA];
+
+    pHeadTD->m_td1TD1.byTCR = (TCR_EDP|TCR_STP);
+
+    memcpy(pDevice->sTxEthHeader.abyDstAddr, (PBYTE)pbySkbData, U_HEADER_LEN);
+
+    cbFrameBodySize = uDataLen - U_HEADER_LEN;
+
+    if (ntohs(pDevice->sTxEthHeader.wType) > MAX_DATA_LEN) {
+        cbFrameBodySize += 8;
+    }
+
+    if (pDevice->bEncryptionEnable == TRUE) {
+        bNeedEncryption = TRUE;
+
+        // get group key
+        pbyBSSID = pDevice->abyBroadcastAddr;
+        if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == FALSE) {
+            pTransmitKey = NULL;
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"KEY is NULL. [%d]\n", pDevice->pMgmt->eCurrMode);
+        } else {
+            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n");
+        }
+    }
+
+    if (pDevice->bEnableHostWEP) {
+        if (uNodeIndex >= 0) {
+            pTransmitKey = &STempKey;
+            pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite;
+            pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex;
+            pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength;
+            pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16;
+            pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0;
+            memcpy(pTransmitKey->abyKey,
+                &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0],
+                pTransmitKey->uKeyLength
+                );
+        }
+    }
+
+    uMACfragNum = cbGetFragCount(pDevice, pTransmitKey, cbFrameBodySize, &pDevice->sTxEthHeader);
+
+    if (uMACfragNum > AVAIL_TD(pDevice,TYPE_AC0DMA)) {
+        return FALSE;
+    }
+    byPktTyp = (BYTE)pDevice->byPacketType;
+
+    if (pDevice->bFixRate) {
+        if (pDevice->eCurrentPHYType == PHY_TYPE_11B) {
+            if (pDevice->uConnectionRate >= RATE_11M) {
+                pDevice->wCurrentRate = RATE_11M;
+            } else {
+                pDevice->wCurrentRate = (WORD)pDevice->uConnectionRate;
+            }
+        } else {
+            if ((pDevice->eCurrentPHYType == PHY_TYPE_11A) &&
+                (pDevice->uConnectionRate <= RATE_6M)) {
+                pDevice->wCurrentRate = RATE_6M;
+            } else {
+                if (pDevice->uConnectionRate >= RATE_54M)
+                    pDevice->wCurrentRate = RATE_54M;
+                else
+                    pDevice->wCurrentRate = (WORD)pDevice->uConnectionRate;
+            }
+        }
+    }
+    else {
+        pDevice->wCurrentRate = pDevice->pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate;
+    }
+
+    if (pDevice->wCurrentRate <= RATE_11M)
+        byPktTyp = PK_TYPE_11B;
+
+    vGenerateFIFOHeader(pDevice, byPktTyp, pDevice->pbyTmpBuff, bNeedEncryption,
+                        cbFrameBodySize, TYPE_AC0DMA, pHeadTD,
+                        &pDevice->sTxEthHeader, pbySkbData, pTransmitKey, uNodeIndex,
+                        &uMACfragNum,
+                        &cbHeaderSize
+                        );
+
+    if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) {
+        // Disable PS
+        MACbPSWakeup(pDevice->PortOffset);
+    }
+
+    pDevice->bPWBitOn = FALSE;
+
+    pLastTD = pHeadTD;
+    for (ii = 0; ii < uMACfragNum; ii++) {
+        // Poll Transmit the adapter
+        wmb();
+        pHeadTD->m_td0TD0.f1Owner=OWNED_BY_NIC;
+        wmb();
+        if (ii == (uMACfragNum - 1))
+            pLastTD = pHeadTD;
+        pHeadTD = pHeadTD->next;
+    }
+
+    pLastTD->pTDInfo->skb = 0;
+    pLastTD->pTDInfo->byFlags = 0;
+
+    pDevice->apCurrTD[TYPE_AC0DMA] = pHeadTD;
+
+    MACvTransmitAC0(pDevice->PortOffset);
+
+    return TRUE;
+}
+
+
+
diff --git a/drivers/staging/vt6655/wroute.h b/drivers/staging/vt6655/wroute.h
new file mode 100644 (file)
index 0000000..ea5f589
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * 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: wroute.h
+ *
+ * Purpose:
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: May 21, 2003
+ *
+ */
+
+
+#ifndef __WROUTE_H__
+#define __WROUTE_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 */
+
+BOOL ROUTEbRelay (PSDevice pDevice, PBYTE pbySkbData, UINT uDataLen, UINT uNodeIndex);
+
+#ifdef __cplusplus
+}                                       /* End of extern "C" { */
+#endif /* __cplusplus */
+
+
+
+
+#endif // __WROUTE_H__
+
+
+