summaryrefslogtreecommitdiff
path: root/drivers/staging/vt6656
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/vt6656')
-rw-r--r--drivers/staging/vt6656/80211hdr.h324
-rw-r--r--drivers/staging/vt6656/80211mgr.c861
-rw-r--r--drivers/staging/vt6656/80211mgr.h808
-rw-r--r--drivers/staging/vt6656/Kconfig9
-rw-r--r--drivers/staging/vt6656/Makefile38
-rw-r--r--drivers/staging/vt6656/TODO19
-rw-r--r--drivers/staging/vt6656/aes_ccmp.c373
-rw-r--r--drivers/staging/vt6656/aes_ccmp.h35
-rw-r--r--drivers/staging/vt6656/baseband.c1901
-rw-r--r--drivers/staging/vt6656/baseband.h111
-rw-r--r--drivers/staging/vt6656/bssdb.c1435
-rw-r--r--drivers/staging/vt6656/bssdb.h278
-rw-r--r--drivers/staging/vt6656/card.c996
-rw-r--r--drivers/staging/vt6656/card.h75
-rw-r--r--drivers/staging/vt6656/channel.c474
-rw-r--r--drivers/staging/vt6656/channel.h44
-rw-r--r--drivers/staging/vt6656/control.c79
-rw-r--r--drivers/staging/vt6656/control.h54
-rw-r--r--drivers/staging/vt6656/country.h162
-rw-r--r--drivers/staging/vt6656/datarate.c371
-rw-r--r--drivers/staging/vt6656/datarate.h77
-rw-r--r--drivers/staging/vt6656/desc.h416
-rw-r--r--drivers/staging/vt6656/device.h820
-rw-r--r--drivers/staging/vt6656/device_cfg.h99
-rw-r--r--drivers/staging/vt6656/dpc.c1430
-rw-r--r--drivers/staging/vt6656/dpc.h44
-rw-r--r--drivers/staging/vt6656/firmware.c148
-rw-r--r--drivers/staging/vt6656/firmware.h39
-rw-r--r--drivers/staging/vt6656/hostap.c778
-rw-r--r--drivers/staging/vt6656/hostap.h58
-rw-r--r--drivers/staging/vt6656/int.c202
-rw-r--r--drivers/staging/vt6656/int.h62
-rw-r--r--drivers/staging/vt6656/iocmd.h425
-rw-r--r--drivers/staging/vt6656/iowpa.h128
-rw-r--r--drivers/staging/vt6656/iwctl.c1837
-rw-r--r--drivers/staging/vt6656/iwctl.h138
-rw-r--r--drivers/staging/vt6656/key.c737
-rw-r--r--drivers/staging/vt6656/key.h112
-rw-r--r--drivers/staging/vt6656/mac.c388
-rw-r--r--drivers/staging/vt6656/mac.h421
-rw-r--r--drivers/staging/vt6656/main_usb.c1490
-rw-r--r--drivers/staging/vt6656/mib.c489
-rw-r--r--drivers/staging/vt6656/mib.h378
-rw-r--r--drivers/staging/vt6656/michael.c167
-rw-r--r--drivers/staging/vt6656/michael.h52
-rw-r--r--drivers/staging/vt6656/power.c330
-rw-r--r--drivers/staging/vt6656/power.h47
-rw-r--r--drivers/staging/vt6656/rc4.c87
-rw-r--r--drivers/staging/vt6656/rc4.h46
-rw-r--r--drivers/staging/vt6656/rf.c1099
-rw-r--r--drivers/staging/vt6656/rf.h64
-rw-r--r--drivers/staging/vt6656/rndis.h151
-rw-r--r--drivers/staging/vt6656/rxtx.c2928
-rw-r--r--drivers/staging/vt6656/rxtx.h638
-rw-r--r--drivers/staging/vt6656/srom.h112
-rw-r--r--drivers/staging/vt6656/tcrc.c183
-rw-r--r--drivers/staging/vt6656/tcrc.h38
-rw-r--r--drivers/staging/vt6656/tether.c61
-rw-r--r--drivers/staging/vt6656/tether.h115
-rw-r--r--drivers/staging/vt6656/tkip.c246
-rw-r--r--drivers/staging/vt6656/tkip.h45
-rw-r--r--drivers/staging/vt6656/tmacro.h58
-rw-r--r--drivers/staging/vt6656/usbpipe.c696
-rw-r--r--drivers/staging/vt6656/usbpipe.h46
-rw-r--r--drivers/staging/vt6656/vntconfiguration.dat6
-rw-r--r--drivers/staging/vt6656/wcmd.c1203
-rw-r--r--drivers/staging/vt6656/wcmd.h119
-rw-r--r--drivers/staging/vt6656/wctl.c245
-rw-r--r--drivers/staging/vt6656/wctl.h94
-rw-r--r--drivers/staging/vt6656/wmgr.c4408
-rw-r--r--drivers/staging/vt6656/wmgr.h400
-rw-r--r--drivers/staging/vt6656/wpa.c314
-rw-r--r--drivers/staging/vt6656/wpa.h72
-rw-r--r--drivers/staging/vt6656/wpa2.c235
-rw-r--r--drivers/staging/vt6656/wpa2.h53
-rw-r--r--drivers/staging/vt6656/wpactl.c248
-rw-r--r--drivers/staging/vt6656/wpactl.h47
77 files changed, 33816 insertions, 0 deletions
diff --git a/drivers/staging/vt6656/80211hdr.h b/drivers/staging/vt6656/80211hdr.h
new file mode 100644
index 00000000..000304ff
--- /dev/null
+++ b/drivers/staging/vt6656/80211hdr.h
@@ -0,0 +1,324 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: 80211hdr.h
+ *
+ * Purpose: 802.11 MAC headers related pre-defines and macros.
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: Apr 8, 2002
+ */
+
+#ifndef __80211HDR_H__
+#define __80211HDR_H__
+
+/* 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 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 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) ((((u16)(n) >> 8) & (BIT0 | BIT1))
+#define WLAN_GET_FC_FTYPE(n) ((((u16)(n) >> 8) & (BIT2 | BIT3)) >> 2)
+#define WLAN_GET_FC_FSTYPE(n) ((((u16)(n) >> 8) \
+ & (BIT4|BIT5|BIT6|BIT7)) >> 4)
+#define WLAN_GET_FC_TODS(n) ((((u16)(n) << 8) & (BIT8)) >> 8)
+#define WLAN_GET_FC_FROMDS(n) ((((u16)(n) << 8) & (BIT9)) >> 9)
+#define WLAN_GET_FC_MOREFRAG(n) ((((u16)(n) << 8) & (BIT10)) >> 10)
+#define WLAN_GET_FC_RETRY(n) ((((u16)(n) << 8) & (BIT11)) >> 11)
+#define WLAN_GET_FC_PWRMGT(n) ((((u16)(n) << 8) & (BIT12)) >> 12)
+#define WLAN_GET_FC_MOREDATA(n) ((((u16)(n) << 8) & (BIT13)) >> 13)
+#define WLAN_GET_FC_ISWEP(n) ((((u16)(n) << 8) & (BIT14)) >> 14)
+#define WLAN_GET_FC_ORDER(n) ((((u16)(n) << 8) & (BIT15)) >> 15)
+
+/* Sequence Field bit */
+#define WLAN_GET_SEQ_FRGNUM(n) (((u16)(n) >> 8) & (BIT0|BIT1|BIT2|BIT3))
+#define WLAN_GET_SEQ_SEQNUM(n) ((((u16)(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) (((u16)(n)) & (BIT0 | BIT1))
+#define WLAN_GET_FC_FTYPE(n) ((((u16)(n)) & (BIT2 | BIT3)) >> 2)
+#define WLAN_GET_FC_FSTYPE(n) ((((u16)(n)) & (BIT4|BIT5|BIT6|BIT7)) >> 4)
+#define WLAN_GET_FC_TODS(n) ((((u16)(n)) & (BIT8)) >> 8)
+#define WLAN_GET_FC_FROMDS(n) ((((u16)(n)) & (BIT9)) >> 9)
+#define WLAN_GET_FC_MOREFRAG(n) ((((u16)(n)) & (BIT10)) >> 10)
+#define WLAN_GET_FC_RETRY(n) ((((u16)(n)) & (BIT11)) >> 11)
+#define WLAN_GET_FC_PWRMGT(n) ((((u16)(n)) & (BIT12)) >> 12)
+#define WLAN_GET_FC_MOREDATA(n) ((((u16)(n)) & (BIT13)) >> 13)
+#define WLAN_GET_FC_ISWEP(n) ((((u16)(n)) & (BIT14)) >> 14)
+#define WLAN_GET_FC_ORDER(n) ((((u16)(n)) & (BIT15)) >> 15)
+
+/* Sequence Field bit */
+#define WLAN_GET_SEQ_FRGNUM(n) (((u16)(n)) & (BIT0|BIT1|BIT2|BIT3))
+#define WLAN_GET_SEQ_SEQNUM(n) ((((u16)(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) ((u16)(n))
+#define WLAN_SET_FC_FTYPE(n) (((u16)(n)) << 2)
+#define WLAN_SET_FC_FSTYPE(n) (((u16)(n)) << 4)
+#define WLAN_SET_FC_TODS(n) (((u16)(n)) << 8)
+#define WLAN_SET_FC_FROMDS(n) (((u16)(n)) << 9)
+#define WLAN_SET_FC_MOREFRAG(n) (((u16)(n)) << 10)
+#define WLAN_SET_FC_RETRY(n) (((u16)(n)) << 11)
+#define WLAN_SET_FC_PWRMGT(n) (((u16)(n)) << 12)
+#define WLAN_SET_FC_MOREDATA(n) (((u16)(n)) << 13)
+#define WLAN_SET_FC_ISWEP(n) (((u16)(n)) << 14)
+#define WLAN_SET_FC_ORDER(n) (((u16)(n)) << 15)
+
+#define WLAN_SET_SEQ_FRGNUM(n) ((u16)(n))
+#define WLAN_SET_SEQ_SEQNUM(n) (((u16)(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) (((u8 *)(p)) + WLAN_HDR_ADDR3_LEN)
+#define WLAN_HDR_A4_DATA_PTR(p) (((u8 *)(p)) + WLAN_HDR_ADDR4_LEN)
+
+/* IEEE ADDR */
+#define IEEE_ADDR_UNIVERSAL 0x02
+#define IEEE_ADDR_GROUP 0x01
+
+typedef struct {
+ u8 abyAddr[6];
+} IEEE_ADDR, *PIEEE_ADDR;
+
+/* 802.11 Header Format */
+
+typedef struct tagWLAN_80211HDR_A2 {
+
+ u16 wFrameCtl;
+ u16 wDurationID;
+ u8 abyAddr1[WLAN_ADDR_LEN];
+ u8 abyAddr2[WLAN_ADDR_LEN];
+
+} __attribute__ ((__packed__))
+WLAN_80211HDR_A2, *PWLAN_80211HDR_A2;
+
+typedef struct tagWLAN_80211HDR_A3 {
+
+ u16 wFrameCtl;
+ u16 wDurationID;
+ u8 abyAddr1[WLAN_ADDR_LEN];
+ u8 abyAddr2[WLAN_ADDR_LEN];
+ u8 abyAddr3[WLAN_ADDR_LEN];
+ u16 wSeqCtl;
+
+} __attribute__ ((__packed__))
+WLAN_80211HDR_A3, *PWLAN_80211HDR_A3;
+
+typedef struct tagWLAN_80211HDR_A4 {
+
+ u16 wFrameCtl;
+ u16 wDurationID;
+ u8 abyAddr1[WLAN_ADDR_LEN];
+ u8 abyAddr2[WLAN_ADDR_LEN];
+ u8 abyAddr3[WLAN_ADDR_LEN];
+ u16 wSeqCtl;
+ u8 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;
+
+#endif /* __80211HDR_H__ */
diff --git a/drivers/staging/vt6656/80211mgr.c b/drivers/staging/vt6656/80211mgr.c
new file mode 100644
index 00000000..61edb51f
--- /dev/null
+++ b/drivers/staging/vt6656/80211mgr.c
@@ -0,0 +1,861 @@
+/*
+ * 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 management support functions
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: May 8, 2002
+ *
+ * Functions:
+ * vMgrEncodeBeacon - Encode the Beacon frame
+ * vMgrDecodeBeacon - Decode the Beacon 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
+ *
+ * Revision History:
+ *
+ */
+
+#include "device.h"
+#include "tmacro.h"
+#include "tether.h"
+#include "80211mgr.h"
+#include "80211hdr.h"
+#include "wpa.h"
+
+static int msglevel = MSG_LEVEL_INFO;
+/*static int msglevel =MSG_LEVEL_DEBUG;*/
+
+/*+
+ *
+ * Routine Description:
+ * Encode Beacon frame body offset
+ *
+ * Return Value:
+ * None.
+ *
+-*/
+
+void
+vMgrEncodeBeacon(
+ PWLAN_FR_BEACON pFrame
+ )
+{
+ pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+ /* Fixed Fields */
+ pFrame->pqwTimestamp =
+ (u64 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) +
+ WLAN_BEACON_OFF_TS);
+ pFrame->pwBeaconInterval = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+ + WLAN_BEACON_OFF_BCN_INT);
+ pFrame->pwCapInfo = (u16 *)(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(
+ PWLAN_FR_BEACON pFrame
+ )
+{
+ PWLAN_IE pItem;
+
+ pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+ /* Fixed Fields */
+ pFrame->pqwTimestamp =
+ (u64 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) +
+ WLAN_BEACON_OFF_TS);
+ pFrame->pwBeaconInterval = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+ + WLAN_BEACON_OFF_BCN_INT);
+ pFrame->pwCapInfo = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+ + WLAN_BEACON_OFF_CAPINFO);
+
+ /* Information elements */
+ pItem = (PWLAN_IE)((u8 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)))
+ + WLAN_BEACON_OFF_SSID);
+ while (((u8 *)pItem) < (pFrame->pBuf + pFrame->len)) {
+
+ switch (pItem->byElementID) {
+ case WLAN_EID_SSID:
+ if (pFrame->pSSID == NULL)
+ pFrame->pSSID = (PWLAN_IE_SSID)pItem;
+ break;
+ case WLAN_EID_SUPP_RATES:
+ if (pFrame->pSuppRates == NULL)
+ pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
+ break;
+ case WLAN_EID_FH_PARMS:
+ /* pFrame->pFHParms = (PWLAN_IE_FH_PARMS)pItem; */
+ break;
+ case WLAN_EID_DS_PARMS:
+ if (pFrame->pDSParms == NULL)
+ pFrame->pDSParms = (PWLAN_IE_DS_PARMS)pItem;
+ break;
+ case WLAN_EID_CF_PARMS:
+ if (pFrame->pCFParms == NULL)
+ pFrame->pCFParms = (PWLAN_IE_CF_PARMS)pItem;
+ break;
+ case WLAN_EID_IBSS_PARMS:
+ if (pFrame->pIBSSParms == NULL)
+ pFrame->pIBSSParms = (PWLAN_IE_IBSS_PARMS)pItem;
+ break;
+ case WLAN_EID_TIM:
+ if (pFrame->pTIM == NULL)
+ pFrame->pTIM = (PWLAN_IE_TIM)pItem;
+ break;
+
+ case WLAN_EID_RSN:
+ if (pFrame->pRSN == NULL)
+ pFrame->pRSN = (PWLAN_IE_RSN)pItem;
+ break;
+ case WLAN_EID_RSN_WPA:
+ if (pFrame->pRSNWPA == NULL) {
+ if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == true)
+ pFrame->pRSNWPA = (PWLAN_IE_RSN_EXT)pItem;
+ }
+ break;
+
+ case WLAN_EID_ERP:
+ if (pFrame->pERP == NULL)
+ pFrame->pERP = (PWLAN_IE_ERP)pItem;
+ break;
+ case WLAN_EID_EXTSUPP_RATES:
+ if (pFrame->pExtSuppRates == NULL)
+ pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
+ break;
+
+ case WLAN_EID_COUNTRY: /* 7 */
+ if (pFrame->pIE_Country == NULL)
+ pFrame->pIE_Country = (PWLAN_IE_COUNTRY)pItem;
+ break;
+
+ case WLAN_EID_PWR_CONSTRAINT: /* 32 */
+ if (pFrame->pIE_PowerConstraint == NULL)
+ pFrame->pIE_PowerConstraint = (PWLAN_IE_PW_CONST)pItem;
+ break;
+
+ case WLAN_EID_CH_SWITCH: /* 37 */
+ if (pFrame->pIE_CHSW == NULL)
+ pFrame->pIE_CHSW = (PWLAN_IE_CH_SW)pItem;
+ break;
+
+ case WLAN_EID_QUIET: /* 40 */
+ if (pFrame->pIE_Quiet == NULL)
+ pFrame->pIE_Quiet = (PWLAN_IE_QUIET)pItem;
+ break;
+
+ case WLAN_EID_IBSS_DFS:
+ if (pFrame->pIE_IBSSDFS == NULL)
+ pFrame->pIE_IBSSDFS = (PWLAN_IE_IBSS_DFS)pItem;
+ break;
+
+ default:
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Unrecognized EID=%dd in beacon decode.\n", pItem->byElementID);
+ break;
+
+ }
+ pItem = (PWLAN_IE)(((u8 *)pItem) + 2 + pItem->len);
+ }
+}
+
+/*+
+ *
+ * Routine Description:
+ * Encode Disassociation
+ *
+ *
+ * Return Value:
+ * None.
+ *
+-*/
+
+void
+vMgrEncodeDisassociation(
+ PWLAN_FR_DISASSOC pFrame
+ )
+{
+ pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+ /* Fixed Fields */
+ pFrame->pwReason = (u16 *)(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));
+}
+
+/*+
+ *
+ * Routine Description:
+ * Decode Disassociation
+ *
+ *
+ * Return Value:
+ * None.
+ *
+-*/
+
+void
+vMgrDecodeDisassociation(
+ PWLAN_FR_DISASSOC pFrame
+ )
+{
+ pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+ /* Fixed Fields */
+ pFrame->pwReason = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+ + WLAN_DISASSOC_OFF_REASON);
+}
+
+/*+
+ *
+ * Routine Description:
+ * Encode Association Request
+ *
+ *
+ * Return Value:
+ * None.
+ *
+-*/
+
+void
+vMgrEncodeAssocRequest(
+ PWLAN_FR_ASSOCREQ pFrame
+ )
+{
+ pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+ /* Fixed Fields */
+ pFrame->pwCapInfo = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+ + WLAN_ASSOCREQ_OFF_CAP_INFO);
+ pFrame->pwListenInterval = (u16 *)(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));
+}
+
+/*+
+ *
+ * Routine Description: (AP)
+ * Decode Association Request
+ *
+ *
+ * Return Value:
+ * None.
+ *
+-*/
+
+void
+vMgrDecodeAssocRequest(
+ PWLAN_FR_ASSOCREQ pFrame
+ )
+{
+ PWLAN_IE pItem;
+
+ pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+ /* Fixed Fields */
+ pFrame->pwCapInfo = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+ + WLAN_ASSOCREQ_OFF_CAP_INFO);
+ pFrame->pwListenInterval = (u16 *)(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 (((u8 *)pItem) < (pFrame->pBuf + pFrame->len)) {
+ switch (pItem->byElementID) {
+ case WLAN_EID_SSID:
+ if (pFrame->pSSID == NULL)
+ pFrame->pSSID = (PWLAN_IE_SSID)pItem;
+ break;
+ case WLAN_EID_SUPP_RATES:
+ if (pFrame->pSuppRates == NULL)
+ pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
+ break;
+
+ case WLAN_EID_RSN:
+ if (pFrame->pRSN == NULL)
+ pFrame->pRSN = (PWLAN_IE_RSN)pItem;
+ break;
+ case WLAN_EID_RSN_WPA:
+ if (pFrame->pRSNWPA == NULL) {
+ if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == true)
+ pFrame->pRSNWPA = (PWLAN_IE_RSN_EXT)pItem;
+ }
+ break;
+ case WLAN_EID_EXTSUPP_RATES:
+ if (pFrame->pExtSuppRates == NULL)
+ pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
+ break;
+
+ default:
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Unrecognized EID=%dd in assocreq decode.\n",
+ pItem->byElementID);
+ break;
+ }
+ pItem = (PWLAN_IE)(((u8 *)pItem) + 2 + pItem->len);
+ }
+}
+
+/*+
+ *
+ * Routine Description: (AP)
+ * Encode Association Response
+ *
+ *
+ * Return Value:
+ * None.
+ *
+-*/
+
+void
+vMgrEncodeAssocResponse(
+ PWLAN_FR_ASSOCRESP pFrame
+ )
+{
+ pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+ /* Fixed Fields */
+ pFrame->pwCapInfo = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+ + WLAN_ASSOCRESP_OFF_CAP_INFO);
+ pFrame->pwStatus = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+ + WLAN_ASSOCRESP_OFF_STATUS);
+ pFrame->pwAid = (u16 *)(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));
+}
+
+/*+
+ *
+ * Routine Description:
+ * Decode Association Response
+ *
+ *
+ * Return Value:
+ * None.
+ *
+-*/
+
+void
+vMgrDecodeAssocResponse(
+ PWLAN_FR_ASSOCRESP pFrame
+ )
+{
+ PWLAN_IE pItem;
+
+ pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+ /* Fixed Fields */
+ pFrame->pwCapInfo = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+ + WLAN_ASSOCRESP_OFF_CAP_INFO);
+ pFrame->pwStatus = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+ + WLAN_ASSOCRESP_OFF_STATUS);
+ pFrame->pwAid = (u16 *)(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)(((u8 *)pItem) + 2 + pItem->len);
+
+ if ((((u8 *)pItem) < (pFrame->pBuf + pFrame->len)) && (pItem->byElementID == WLAN_EID_EXTSUPP_RATES)) {
+ pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pFrame->pExtSuppRates=[%p].\n", pItem);
+ } else
+ pFrame->pExtSuppRates = NULL;
+}
+
+/*+
+ *
+ * Routine Description:
+ * Encode Reassociation Request
+ *
+ *
+ * Return Value:
+ * None.
+ *
+-*/
+
+void
+vMgrEncodeReassocRequest(
+ PWLAN_FR_REASSOCREQ pFrame
+ )
+{
+ pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+ /* Fixed Fields */
+ pFrame->pwCapInfo = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+ + WLAN_REASSOCREQ_OFF_CAP_INFO);
+ pFrame->pwListenInterval = (u16 *)(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));
+}
+
+/*+
+ *
+ * Routine Description: (AP)
+ * Decode Reassociation Request
+ *
+ *
+ * Return Value:
+ * None.
+ *
+-*/
+
+void
+vMgrDecodeReassocRequest(
+ PWLAN_FR_REASSOCREQ pFrame
+ )
+{
+ PWLAN_IE pItem;
+ pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+ /* Fixed Fields */
+ pFrame->pwCapInfo = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+ + WLAN_REASSOCREQ_OFF_CAP_INFO);
+ pFrame->pwListenInterval = (u16 *)(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 (((u8 *)pItem) < (pFrame->pBuf + pFrame->len)) {
+
+ switch (pItem->byElementID) {
+ case WLAN_EID_SSID:
+ if (pFrame->pSSID == NULL)
+ pFrame->pSSID = (PWLAN_IE_SSID)pItem;
+ break;
+ case WLAN_EID_SUPP_RATES:
+ if (pFrame->pSuppRates == NULL)
+ pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
+ break;
+
+ case WLAN_EID_RSN:
+ if (pFrame->pRSN == NULL)
+ pFrame->pRSN = (PWLAN_IE_RSN)pItem;
+ break;
+ case WLAN_EID_RSN_WPA:
+ if (pFrame->pRSNWPA == NULL)
+ if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == true)
+ pFrame->pRSNWPA = (PWLAN_IE_RSN_EXT)pItem;
+ break;
+
+ case WLAN_EID_EXTSUPP_RATES:
+ if (pFrame->pExtSuppRates == NULL)
+ pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
+ break;
+ default:
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Unrecognized EID=%dd in reassocreq decode.\n",
+ pItem->byElementID);
+ break;
+ }
+ pItem = (PWLAN_IE)(((u8 *)pItem) + 2 + pItem->len);
+ }
+}
+
+/*+
+ *
+ * Routine Description:
+ * Encode Probe Request
+ *
+ *
+ * Return Value:
+ * None.
+ *
+-*/
+
+void
+vMgrEncodeProbeRequest(
+ PWLAN_FR_PROBEREQ pFrame
+ )
+{
+ pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+ pFrame->len = WLAN_HDR_ADDR3_LEN;
+}
+
+/*+
+ *
+ * Routine Description:
+ * Decode Probe Request
+ *
+ *
+ * Return Value:
+ * None.
+ *
+-*/
+
+void
+vMgrDecodeProbeRequest(
+ 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 (((u8 *)pItem) < (pFrame->pBuf + pFrame->len)) {
+
+ switch (pItem->byElementID) {
+ case WLAN_EID_SSID:
+ if (pFrame->pSSID == NULL)
+ pFrame->pSSID = (PWLAN_IE_SSID)pItem;
+ break;
+
+ case WLAN_EID_SUPP_RATES:
+ if (pFrame->pSuppRates == NULL)
+ pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
+ break;
+
+ case WLAN_EID_EXTSUPP_RATES:
+ if (pFrame->pExtSuppRates == NULL)
+ pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
+ break;
+
+ default:
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Bad EID=%dd in probereq\n", pItem->byElementID);
+ break;
+ }
+
+ pItem = (PWLAN_IE)(((u8 *)pItem) + 2 + pItem->len);
+ }
+}
+
+/*+
+ *
+ * Routine Description:
+ * Encode Probe Response
+ *
+ *
+ * Return Value:
+ * None.
+ *
+-*/
+
+void
+vMgrEncodeProbeResponse(
+ PWLAN_FR_PROBERESP pFrame
+ )
+{
+ pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+ /* Fixed Fields */
+ pFrame->pqwTimestamp =
+ (u64 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) +
+ WLAN_PROBERESP_OFF_TS);
+ pFrame->pwBeaconInterval = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+ + WLAN_PROBERESP_OFF_BCN_INT);
+ pFrame->pwCapInfo = (u16 *)(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));
+}
+
+/*+
+ *
+ * Routine Description:
+ * Decode Probe Response
+ *
+ *
+ * Return Value:
+ * None.
+ *
+-*/
+
+void
+vMgrDecodeProbeResponse(
+ PWLAN_FR_PROBERESP pFrame
+ )
+{
+ PWLAN_IE pItem;
+
+ pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+ /* Fixed Fields */
+ pFrame->pqwTimestamp =
+ (u64 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) +
+ WLAN_PROBERESP_OFF_TS);
+ pFrame->pwBeaconInterval = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+ + WLAN_PROBERESP_OFF_BCN_INT);
+ pFrame->pwCapInfo = (u16 *)(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 (((u8 *)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:
+ break;
+ case WLAN_EID_DS_PARMS:
+ if (pFrame->pDSParms == NULL)
+ pFrame->pDSParms = (PWLAN_IE_DS_PARMS)pItem;
+ break;
+ case WLAN_EID_CF_PARMS:
+ if (pFrame->pCFParms == NULL)
+ pFrame->pCFParms = (PWLAN_IE_CF_PARMS)pItem;
+ break;
+ case WLAN_EID_IBSS_PARMS:
+ if (pFrame->pIBSSParms == NULL)
+ pFrame->pIBSSParms = (PWLAN_IE_IBSS_PARMS)pItem;
+ break;
+
+ case WLAN_EID_RSN:
+ if (pFrame->pRSN == NULL)
+ pFrame->pRSN = (PWLAN_IE_RSN)pItem;
+ break;
+ case WLAN_EID_RSN_WPA:
+ if (pFrame->pRSNWPA == NULL) {
+ if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == true)
+ pFrame->pRSNWPA = (PWLAN_IE_RSN_EXT)pItem;
+ }
+ break;
+ case WLAN_EID_ERP:
+ if (pFrame->pERP == NULL)
+ pFrame->pERP = (PWLAN_IE_ERP)pItem;
+ break;
+ case WLAN_EID_EXTSUPP_RATES:
+ if (pFrame->pExtSuppRates == NULL)
+ pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
+ break;
+
+ case WLAN_EID_COUNTRY: /* 7 */
+ if (pFrame->pIE_Country == NULL)
+ pFrame->pIE_Country = (PWLAN_IE_COUNTRY)pItem;
+ break;
+
+ case WLAN_EID_PWR_CONSTRAINT: /* 32 */
+ if (pFrame->pIE_PowerConstraint == NULL)
+ pFrame->pIE_PowerConstraint = (PWLAN_IE_PW_CONST)pItem;
+ break;
+
+ case WLAN_EID_CH_SWITCH: /* 37 */
+ if (pFrame->pIE_CHSW == NULL)
+ pFrame->pIE_CHSW = (PWLAN_IE_CH_SW)pItem;
+ break;
+
+ case WLAN_EID_QUIET: /* 40 */
+ if (pFrame->pIE_Quiet == NULL)
+ pFrame->pIE_Quiet = (PWLAN_IE_QUIET)pItem;
+ break;
+
+ case WLAN_EID_IBSS_DFS:
+ if (pFrame->pIE_IBSSDFS == NULL)
+ pFrame->pIE_IBSSDFS = (PWLAN_IE_IBSS_DFS)pItem;
+ break;
+
+ default:
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Bad EID=%dd in proberesp\n", pItem->byElementID);
+ break;
+ }
+
+ pItem = (PWLAN_IE)(((u8 *)pItem) + 2 + pItem->len);
+ }
+}
+
+/*+
+ *
+ * Routine Description:
+ * Encode Authentication frame
+ *
+ *
+ * Return Value:
+ * None.
+ *
+-*/
+
+void
+vMgrEncodeAuthen(
+ PWLAN_FR_AUTHEN pFrame
+ )
+{
+ pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+ /* Fixed Fields */
+ pFrame->pwAuthAlgorithm = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+ + WLAN_AUTHEN_OFF_AUTH_ALG);
+ pFrame->pwAuthSequence = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+ + WLAN_AUTHEN_OFF_AUTH_SEQ);
+ pFrame->pwStatus = (u16 *)(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));
+}
+
+/*+
+ *
+ * Routine Description:
+ * Decode Authentication
+ *
+ *
+ * Return Value:
+ * None.
+ *
+-*/
+
+void
+vMgrDecodeAuthen(
+ PWLAN_FR_AUTHEN pFrame
+ )
+{
+ PWLAN_IE pItem;
+
+ pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+ /* Fixed Fields */
+ pFrame->pwAuthAlgorithm = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+ + WLAN_AUTHEN_OFF_AUTH_ALG);
+ pFrame->pwAuthSequence = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+ + WLAN_AUTHEN_OFF_AUTH_SEQ);
+ pFrame->pwStatus = (u16 *)(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 ((((u8 *)pItem) < (pFrame->pBuf + pFrame->len)) && (pItem->byElementID == WLAN_EID_CHALLENGE))
+ pFrame->pChallenge = (PWLAN_IE_CHALLENGE)pItem;
+}
+
+/*+
+ *
+ * Routine Description:
+ * Encode Authentication
+ *
+ *
+ * Return Value:
+ * None.
+ *
+-*/
+
+void
+vMgrEncodeDeauthen(
+ PWLAN_FR_DEAUTHEN pFrame
+ )
+{
+ pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+ /* Fixed Fields */
+ pFrame->pwReason = (u16 *)(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));
+}
+
+/*+
+ *
+ * Routine Description:
+ * Decode Deauthentication
+ *
+ *
+ * Return Value:
+ * None.
+ *
+-*/
+
+void
+vMgrDecodeDeauthen(
+ PWLAN_FR_DEAUTHEN pFrame
+ )
+{
+ pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+ /* Fixed Fields */
+ pFrame->pwReason = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+ + WLAN_DEAUTHEN_OFF_REASON);
+}
+
+/*+
+ *
+ * Routine Description: (AP)
+ * Encode Reassociation Response
+ *
+ *
+ * Return Value:
+ * None.
+ *
+-*/
+
+void
+vMgrEncodeReassocResponse(
+ PWLAN_FR_REASSOCRESP pFrame
+ )
+{
+ pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+ /* Fixed Fields */
+ pFrame->pwCapInfo = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+ + WLAN_REASSOCRESP_OFF_CAP_INFO);
+ pFrame->pwStatus = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+ + WLAN_REASSOCRESP_OFF_STATUS);
+ pFrame->pwAid = (u16 *)(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));
+}
diff --git a/drivers/staging/vt6656/80211mgr.h b/drivers/staging/vt6656/80211mgr.h
new file mode 100644
index 00000000..39cde1a0
--- /dev/null
+++ b/drivers/staging/vt6656/80211mgr.h
@@ -0,0 +1,808 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: 80211mgr.h
+ *
+ * Purpose: 802.11 management frames pre-defines.
+ *
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: May 8, 2002
+ *
+ */
+
+#ifndef __80211MGR_H__
+#define __80211MGR_H__
+
+#include "80211hdr.h"
+
+#define WLAN_MIN_ARRAY 1
+
+/* Information Element ID value */
+#define WLAN_EID_SSID 0
+#define WLAN_EID_SUPP_RATES 1
+#define WLAN_EID_FH_PARMS 2
+#define WLAN_EID_DS_PARMS 3
+#define WLAN_EID_CF_PARMS 4
+#define WLAN_EID_TIM 5
+#define WLAN_EID_IBSS_PARMS 6
+#define WLAN_EID_COUNTRY 7
+#define WLAN_EID_CHALLENGE 16
+#define WLAN_EID_PWR_CONSTRAINT 32
+#define WLAN_EID_PWR_CAPABILITY 33
+#define WLAN_EID_TPC_REQ 34
+#define WLAN_EID_TPC_REP 35
+#define WLAN_EID_SUPP_CH 36
+#define WLAN_EID_CH_SWITCH 37
+#define WLAN_EID_MEASURE_REQ 38
+#define WLAN_EID_MEASURE_REP 39
+#define WLAN_EID_QUIET 40
+#define WLAN_EID_IBSS_DFS 41
+#define WLAN_EID_ERP 42
+/* reference 802.11i 7.3.2 table 20 */
+#define WLAN_EID_RSN 48
+#define WLAN_EID_EXTSUPP_RATES 50
+/* reference WiFi WPA spec */
+#define WLAN_EID_RSN_WPA 221
+
+#ifdef Cisco_ccx
+#define WLAN_EID_CCX 133
+#define WLAN_EID_CCX_IP 149
+#define WLAN_EID_CCX_Ver 221
+#endif
+
+#define WLAN_EID_ERP_NONERP_PRESENT 0x01
+#define WLAN_EID_ERP_USE_PROTECTION 0x02
+#define WLAN_EID_ERP_BARKER_MODE 0x04
+
+/* reason codes */
+#define WLAN_MGMT_REASON_RSVD 0
+#define WLAN_MGMT_REASON_UNSPEC 1
+#define WLAN_MGMT_REASON_PRIOR_AUTH_INVALID 2
+#define WLAN_MGMT_REASON_DEAUTH_LEAVING 3
+#define WLAN_MGMT_REASON_DISASSOC_INACTIVE 4
+#define WLAN_MGMT_REASON_DISASSOC_AP_BUSY 5
+#define WLAN_MGMT_REASON_CLASS2_NONAUTH 6
+#define WLAN_MGMT_REASON_CLASS3_NONASSOC 7
+#define WLAN_MGMT_REASON_DISASSOC_STA_HASLEFT 8
+#define WLAN_MGMT_REASON_CANT_ASSOC_NONAUTH 9
+#define WLAN_MGMT_REASON_DISASSOC_PWR_CAP_UNACCEPT 10
+#define WLAN_MGMT_REASON_DISASSOC_SUPP_CH_UNACCEPT 11
+#define WLAN_MGMT_REASON_INVALID_IE 13
+#define WLAN_MGMT_REASON_MIC_FAILURE 14
+#define WLAN_MGMT_REASON_4WAY_HANDSHAKE_TIMEOUT 15
+#define WLAN_MGMT_REASON_GRPKEY_UPDATE_TIMEOUT 16
+#define WLAN_MGMT_REASON_4WAY_INFO_DIFFERENT 17
+#define WLAN_MGMT_REASON_MULTCAST_CIPHER_INVALID 18
+#define WLAN_MGMT_REASON_UNCAST_CIPHER_INVALID 19
+#define WLAN_MGMT_REASON_AKMP_INVALID 20
+#define WLAN_MGMT_REASON_RSNE_UNSUPPORTED 21
+#define WLAN_MGMT_REASON_RSNE_CAP_INVALID 22
+#define WLAN_MGMT_REASON_80211X_AUTH_FAILED 23
+
+/* status codes */
+#define WLAN_MGMT_STATUS_SUCCESS 0
+#define WLAN_MGMT_STATUS_UNSPEC_FAILURE 1
+#define WLAN_MGMT_STATUS_CAPS_UNSUPPORTED 10
+#define WLAN_MGMT_STATUS_REASSOC_NO_ASSOC 11
+#define WLAN_MGMT_STATUS_ASSOC_DENIED_UNSPEC 12
+#define WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG 13
+#define WLAN_MGMT_STATUS_RX_AUTH_NOSEQ 14
+#define WLAN_MGMT_STATUS_CHALLENGE_FAIL 15
+#define WLAN_MGMT_STATUS_AUTH_TIMEOUT 16
+#define WLAN_MGMT_STATUS_ASSOC_DENIED_BUSY 17
+#define WLAN_MGMT_STATUS_ASSOC_DENIED_RATES 18
+#define WLAN_MGMT_STATUS_ASSOC_DENIED_SHORTPREAMBLE 19
+#define WLAN_MGMT_STATUS_ASSOC_DENIED_PBCC 20
+#define WLAN_MGMT_STATUS_ASSOC_DENIED_AGILITY 21
+
+/* reference 802.11h 7.3.1.9 */
+#define WLAN_MGMT_STATUS_ASSOC_REJECT_BCS_SPECTRUM_MNG 22
+#define WLAN_MGMT_STATUS_ASSOC_REJECT_BCS_PWR_CAP 23
+#define WLAN_MGMT_STATUS_ASSOC_REJECT_BCS_SUPP_CH 24
+
+/* reference 802.11g 7.3.1.9 */
+#define WLAN_MGMT_STATUS_SHORTSLOTTIME_UNSUPPORTED 25
+#define WLAN_MGMT_STATUS_DSSSOFDM_UNSUPPORTED 26
+
+/* reference 802.11i 7.3.1.9 table 19 */
+#define WLAN_MGMT_STATUS_INVALID_IE 40
+#define WLAN_MGMT_STATUS_GROUP_CIPHER_INVALID 41
+#define WLAN_MGMT_STATUS_PAIRWISE_CIPHER_INVALID 42
+#define WLAN_MGMT_STATUS_AKMP_INVALID 43
+#define WLAN_MGMT_STATUS_UNSUPPORT_RSN_IE_VER 44
+#define WLAN_MGMT_STATUS_INVALID_RSN_IE_CAP 45
+#define WLAN_MGMT_STATUS_CIPHER_REJECT 46
+
+/* auth algorithm */
+#define WLAN_AUTH_ALG_OPENSYSTEM 0
+#define WLAN_AUTH_ALG_SHAREDKEY 1
+
+/* management frame field offsets */
+
+/*
+ * Note: Not all fields are listed because of variable lengths
+ * Note: These offsets are from the start of the frame data
+ */
+
+#define WLAN_BEACON_OFF_TS 0
+#define WLAN_BEACON_OFF_BCN_INT 8
+#define WLAN_BEACON_OFF_CAPINFO 10
+#define WLAN_BEACON_OFF_SSID 12
+
+#define WLAN_DISASSOC_OFF_REASON 0
+
+#define WLAN_ASSOCREQ_OFF_CAP_INFO 0
+#define WLAN_ASSOCREQ_OFF_LISTEN_INT 2
+#define WLAN_ASSOCREQ_OFF_SSID 4
+
+#define WLAN_ASSOCRESP_OFF_CAP_INFO 0
+#define WLAN_ASSOCRESP_OFF_STATUS 2
+#define WLAN_ASSOCRESP_OFF_AID 4
+#define WLAN_ASSOCRESP_OFF_SUPP_RATES 6
+
+#define WLAN_REASSOCREQ_OFF_CAP_INFO 0
+#define WLAN_REASSOCREQ_OFF_LISTEN_INT 2
+#define WLAN_REASSOCREQ_OFF_CURR_AP 4
+#define WLAN_REASSOCREQ_OFF_SSID 10
+
+#define WLAN_REASSOCRESP_OFF_CAP_INFO 0
+#define WLAN_REASSOCRESP_OFF_STATUS 2
+#define WLAN_REASSOCRESP_OFF_AID 4
+#define WLAN_REASSOCRESP_OFF_SUPP_RATES 6
+
+#define WLAN_PROBEREQ_OFF_SSID 0
+
+#define WLAN_PROBERESP_OFF_TS 0
+#define WLAN_PROBERESP_OFF_BCN_INT 8
+#define WLAN_PROBERESP_OFF_CAP_INFO 10
+#define WLAN_PROBERESP_OFF_SSID 12
+
+#define WLAN_AUTHEN_OFF_AUTH_ALG 0
+#define WLAN_AUTHEN_OFF_AUTH_SEQ 2
+#define WLAN_AUTHEN_OFF_STATUS 4
+#define WLAN_AUTHEN_OFF_CHALLENGE 6
+
+#define WLAN_DEAUTHEN_OFF_REASON 0
+
+/* cipher suite selectors defined 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
+
+/* Information Element types */
+
+#pragma pack(1)
+typedef struct tagWLAN_IE {
+ u8 byElementID;
+ u8 len;
+} __attribute__ ((__packed__))
+WLAN_IE, *PWLAN_IE;
+
+/* Service Set IDentity (SSID) */
+#pragma pack(1)
+typedef struct tagWLAN_IE_SSID {
+ u8 byElementID;
+ u8 len;
+ u8 abySSID[1];
+} __attribute__ ((__packed__))
+WLAN_IE_SSID, *PWLAN_IE_SSID;
+
+/* Supported Rates */
+#pragma pack(1)
+typedef struct tagWLAN_IE_SUPP_RATES {
+ u8 byElementID;
+ u8 len;
+ u8 abyRates[1];
+} __attribute__ ((__packed__))
+WLAN_IE_SUPP_RATES, *PWLAN_IE_SUPP_RATES;
+
+/* FH Parameter Set */
+#pragma pack(1)
+typedef struct _WLAN_IE_FH_PARMS {
+ u8 byElementID;
+ u8 len;
+ u16 wDwellTime;
+ u8 byHopSet;
+ u8 byHopPattern;
+ u8 byHopIndex;
+} WLAN_IE_FH_PARMS, *PWLAN_IE_FH_PARMS;
+
+/* DS Parameter Set */
+#pragma pack(1)
+typedef struct tagWLAN_IE_DS_PARMS {
+ u8 byElementID;
+ u8 len;
+ u8 byCurrChannel;
+} __attribute__ ((__packed__))
+WLAN_IE_DS_PARMS, *PWLAN_IE_DS_PARMS;
+
+/* CF Parameter Set */
+#pragma pack(1)
+typedef struct tagWLAN_IE_CF_PARMS {
+ u8 byElementID;
+ u8 len;
+ u8 byCFPCount;
+ u8 byCFPPeriod;
+ u16 wCFPMaxDuration;
+ u16 wCFPDurRemaining;
+} __attribute__ ((__packed__))
+WLAN_IE_CF_PARMS, *PWLAN_IE_CF_PARMS;
+
+/* TIM */
+#pragma pack(1)
+typedef struct tagWLAN_IE_TIM {
+ u8 byElementID;
+ u8 len;
+ u8 byDTIMCount;
+ u8 byDTIMPeriod;
+ u8 byBitMapCtl;
+ u8 byVirtBitMap[1];
+} __attribute__ ((__packed__))
+WLAN_IE_TIM, *PWLAN_IE_TIM;
+
+/* IBSS Parameter Set */
+#pragma pack(1)
+typedef struct tagWLAN_IE_IBSS_PARMS {
+ u8 byElementID;
+ u8 len;
+ u16 wATIMWindow;
+} __attribute__ ((__packed__))
+WLAN_IE_IBSS_PARMS, *PWLAN_IE_IBSS_PARMS;
+
+/* Challenge Text */
+#pragma pack(1)
+typedef struct tagWLAN_IE_CHALLENGE {
+ u8 byElementID;
+ u8 len;
+ u8 abyChallenge[1];
+} __attribute__ ((__packed__))
+WLAN_IE_CHALLENGE, *PWLAN_IE_CHALLENGE;
+
+#pragma pack(1)
+typedef struct tagWLAN_IE_RSN_EXT {
+ u8 byElementID;
+ u8 len;
+ u8 abyOUI[4];
+ u16 wVersion;
+ u8 abyMulticast[4];
+ u16 wPKCount;
+ struct {
+ u8 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 {
+ u16 wAuthCount;
+ struct {
+ u8 abyOUI[4];
+ } AuthKSList[1];
+} WLAN_IE_RSN_AUTH, *PWLAN_IE_RSN_AUTH;
+
+/* RSN Identity */
+#pragma pack(1)
+typedef struct tagWLAN_IE_RSN {
+ u8 byElementID;
+ u8 len;
+ u16 wVersion;
+ u8 abyRSN[WLAN_MIN_ARRAY];
+} WLAN_IE_RSN, *PWLAN_IE_RSN;
+
+/* CCX Identity DavidWang */
+#pragma pack(1)
+typedef struct tagWLAN_IE_CCX {
+u8 byElementID;
+u8 len;
+u8 abyCCX[30];
+} WLAN_IE_CCX, *PWLAN_IE_CCX;
+#pragma pack(1)
+typedef struct tagWLAN_IE_CCX_IP {
+u8 byElementID;
+u8 len;
+u8 abyCCXOUI[4];
+u8 abyCCXIP[4];
+u8 abyCCXREV[2];
+} WLAN_IE_CCX_IP, *PWLAN_IE_CCX_IP;
+#pragma pack(1)
+typedef struct tagWLAN_IE_CCX_Ver {
+u8 byElementID;
+u8 len;
+u8 abyCCXVer[5];
+} WLAN_IE_CCX_Ver, *PWLAN_IE_CCX_Ver;
+
+/* ERP */
+#pragma pack(1)
+typedef struct tagWLAN_IE_ERP {
+ u8 byElementID;
+ u8 len;
+ u8 byContext;
+} __attribute__ ((__packed__))
+WLAN_IE_ERP, *PWLAN_IE_ERP;
+
+#pragma pack(1)
+typedef struct _MEASEURE_REQ {
+ u8 byChannel;
+ u8 abyStartTime[8];
+ u8 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 {
+ u8 byChannel;
+ u8 abyStartTime[8];
+ u8 abyDuration[2];
+ u8 byMap;
+} MEASEURE_REP_BASIC, *PMEASEURE_REP_BASIC;
+
+typedef struct _MEASEURE_REP_CCA {
+ u8 byChannel;
+ u8 abyStartTime[8];
+ u8 abyDuration[2];
+ u8 byCCABusyFraction;
+} MEASEURE_REP_CCA, *PMEASEURE_REP_CCA;
+
+typedef struct _MEASEURE_REP_RPI {
+ u8 byChannel;
+ u8 abyStartTime[8];
+ u8 abyDuration[2];
+ u8 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 {
+ u8 byElementID;
+ u8 len;
+ u8 byToken;
+ u8 byMode;
+ u8 byType;
+ MEASEURE_REQ sReq;
+} WLAN_IE_MEASURE_REQ, *PWLAN_IE_MEASURE_REQ;
+
+typedef struct _WLAN_IE_MEASURE_REP {
+ u8 byElementID;
+ u8 len;
+ u8 byToken;
+ u8 byMode;
+ u8 byType;
+ MEASEURE_REP sRep;
+} WLAN_IE_MEASURE_REP, *PWLAN_IE_MEASURE_REP;
+
+typedef struct _WLAN_IE_CH_SW {
+ u8 byElementID;
+ u8 len;
+ u8 byMode;
+ u8 byChannel;
+ u8 byCount;
+} WLAN_IE_CH_SW, *PWLAN_IE_CH_SW;
+
+typedef struct _WLAN_IE_QUIET {
+ u8 byElementID;
+ u8 len;
+ u8 byQuietCount;
+ u8 byQuietPeriod;
+ u8 abyQuietDuration[2];
+ u8 abyQuietOffset[2];
+} WLAN_IE_QUIET, *PWLAN_IE_QUIET;
+
+typedef struct _WLAN_IE_COUNTRY {
+ u8 byElementID;
+ u8 len;
+ u8 abyCountryString[3];
+ u8 abyCountryInfo[3];
+} WLAN_IE_COUNTRY, *PWLAN_IE_COUNTRY;
+
+typedef struct _WLAN_IE_PW_CONST {
+ u8 byElementID;
+ u8 len;
+ u8 byPower;
+} WLAN_IE_PW_CONST, *PWLAN_IE_PW_CONST;
+
+typedef struct _WLAN_IE_PW_CAP {
+ u8 byElementID;
+ u8 len;
+ u8 byMinPower;
+ u8 byMaxPower;
+} WLAN_IE_PW_CAP, *PWLAN_IE_PW_CAP;
+
+typedef struct _WLAN_IE_SUPP_CH {
+ u8 byElementID;
+ u8 len;
+ u8 abyChannelTuple[2];
+} WLAN_IE_SUPP_CH, *PWLAN_IE_SUPP_CH;
+
+typedef struct _WLAN_IE_TPC_REQ {
+ u8 byElementID;
+ u8 len;
+} WLAN_IE_TPC_REQ, *PWLAN_IE_TPC_REQ;
+
+typedef struct _WLAN_IE_TPC_REP {
+ u8 byElementID;
+ u8 len;
+ u8 byTxPower;
+ u8 byLinkMargin;
+} WLAN_IE_TPC_REP, *PWLAN_IE_TPC_REP;
+
+typedef struct _WLAN_IE_IBSS_DFS {
+ u8 byElementID;
+ u8 len;
+ u8 abyDFSOwner[6];
+ u8 byDFSRecovery;
+ u8 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 {
+
+ unsigned int uType;
+ unsigned int len;
+ u8 * pBuf;
+ PUWLAN_80211HDR pHdr;
+
+} WLAN_FR_MGMT, *PWLAN_FR_MGMT;
+
+/* beacon frame */
+typedef struct tagWLAN_FR_BEACON {
+
+ unsigned int uType;
+ unsigned int len;
+ u8 * pBuf;
+ PUWLAN_80211HDR pHdr;
+ /* fixed fields */
+ u64 *pqwTimestamp;
+ u16 * pwBeaconInterval;
+ u16 * 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 {
+
+ unsigned int uType;
+ unsigned int len;
+ u8 * 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 {
+
+ unsigned int uType;
+ unsigned int len;
+ u8 * pBuf;
+ PUWLAN_80211HDR pHdr;
+ /* fixed fields */
+ u16 * pwReason;
+ /* info elements */
+
+} WLAN_FR_DISASSOC, *PWLAN_FR_DISASSOC;
+
+/* association request */
+typedef struct tagWLAN_FR_ASSOCREQ {
+
+ unsigned int uType;
+ unsigned int len;
+ u8 * pBuf;
+ PUWLAN_80211HDR pHdr;
+ /* fixed fields */
+ u16 * pwCapInfo;
+ u16 * pwListenInterval;
+ /* info elements */
+ PWLAN_IE_SSID pSSID;
+ PWLAN_IE_SUPP_RATES pSuppRates;
+ PWLAN_IE_RSN pRSN;
+ PWLAN_IE_CCX pCCX;
+ PWLAN_IE_CCX_IP pCCXIP;
+ PWLAN_IE_CCX_Ver pCCXVER;
+ PWLAN_IE_RSN_EXT pRSNWPA;
+ PWLAN_IE_SUPP_RATES pExtSuppRates;
+ PWLAN_IE_PW_CAP pCurrPowerCap;
+ PWLAN_IE_SUPP_CH pCurrSuppCh;
+
+} WLAN_FR_ASSOCREQ, *PWLAN_FR_ASSOCREQ;
+
+/* association response */
+typedef struct tagWLAN_FR_ASSOCRESP {
+
+ unsigned int uType;
+ unsigned int len;
+ u8 * pBuf;
+ PUWLAN_80211HDR pHdr;
+ /* fixed fields */
+ u16 * pwCapInfo;
+ u16 * pwStatus;
+ u16 * 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 {
+
+ unsigned int uType;
+ unsigned int len;
+ u8 * pBuf;
+ PUWLAN_80211HDR pHdr;
+
+ /* fixed fields */
+ u16 * pwCapInfo;
+ u16 * pwListenInterval;
+ PIEEE_ADDR pAddrCurrAP;
+
+ /* info elements */
+ PWLAN_IE_SSID pSSID;
+ PWLAN_IE_SUPP_RATES pSuppRates;
+ PWLAN_IE_RSN pRSN;
+ PWLAN_IE_CCX pCCX;
+ PWLAN_IE_CCX_IP pCCXIP;
+ PWLAN_IE_CCX_Ver pCCXVER;
+ PWLAN_IE_RSN_EXT pRSNWPA;
+ PWLAN_IE_SUPP_RATES pExtSuppRates;
+
+} WLAN_FR_REASSOCREQ, *PWLAN_FR_REASSOCREQ;
+
+/* reassociation response */
+typedef struct tagWLAN_FR_REASSOCRESP {
+
+ unsigned int uType;
+ unsigned int len;
+ u8 * pBuf;
+ PUWLAN_80211HDR pHdr;
+ /* fixed fields */
+ u16 * pwCapInfo;
+ u16 * pwStatus;
+ u16 * 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 {
+
+ unsigned int uType;
+ unsigned int len;
+ u8 * 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 {
+
+ unsigned int uType;
+ unsigned int len;
+ u8 * pBuf;
+ PUWLAN_80211HDR pHdr;
+ /* fixed fields */
+ u64 *pqwTimestamp;
+ u16 * pwBeaconInterval;
+ u16 * 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 {
+
+ unsigned int uType;
+ unsigned int len;
+ u8 * pBuf;
+ PUWLAN_80211HDR pHdr;
+ /* fixed fields */
+ u16 * pwAuthAlgorithm;
+ u16 * pwAuthSequence;
+ u16 * pwStatus;
+ /* info elements */
+ PWLAN_IE_CHALLENGE pChallenge;
+
+} WLAN_FR_AUTHEN, *PWLAN_FR_AUTHEN;
+
+/* deauthentication */
+typedef struct tagWLAN_FR_DEAUTHEN {
+
+ unsigned int uType;
+ unsigned int len;
+ u8 * pBuf;
+ PUWLAN_80211HDR pHdr;
+ /* fixed fields */
+ u16 * pwReason;
+
+ /* info elements */
+
+} WLAN_FR_DEAUTHEN, *PWLAN_FR_DEAUTHEN;
+
+void
+vMgrEncodeBeacon(
+ PWLAN_FR_BEACON pFrame
+ );
+
+void
+vMgrDecodeBeacon(
+ PWLAN_FR_BEACON pFrame
+ );
+
+void
+vMgrEncodeDisassociation(
+ PWLAN_FR_DISASSOC pFrame
+ );
+
+void
+vMgrDecodeDisassociation(
+ PWLAN_FR_DISASSOC pFrame
+ );
+
+void
+vMgrEncodeAssocRequest(
+ PWLAN_FR_ASSOCREQ pFrame
+ );
+
+void
+vMgrDecodeAssocRequest(
+ PWLAN_FR_ASSOCREQ pFrame
+ );
+
+void
+vMgrEncodeAssocResponse(
+ PWLAN_FR_ASSOCRESP pFrame
+ );
+
+void
+vMgrDecodeAssocResponse(
+ PWLAN_FR_ASSOCRESP pFrame
+ );
+
+void
+vMgrEncodeReassocRequest(
+ PWLAN_FR_REASSOCREQ pFrame
+ );
+
+void
+vMgrDecodeReassocRequest(
+ PWLAN_FR_REASSOCREQ pFrame
+ );
+
+void
+vMgrEncodeProbeRequest(
+ PWLAN_FR_PROBEREQ pFrame
+ );
+
+void
+vMgrDecodeProbeRequest(
+ PWLAN_FR_PROBEREQ pFrame
+ );
+
+void
+vMgrEncodeProbeResponse(
+ PWLAN_FR_PROBERESP pFrame
+ );
+
+void
+vMgrDecodeProbeResponse(
+ PWLAN_FR_PROBERESP pFrame
+ );
+
+void
+vMgrEncodeAuthen(
+ PWLAN_FR_AUTHEN pFrame
+ );
+
+void
+vMgrDecodeAuthen(
+ PWLAN_FR_AUTHEN pFrame
+ );
+
+void
+vMgrEncodeDeauthen(
+ PWLAN_FR_DEAUTHEN pFrame
+ );
+
+void
+vMgrDecodeDeauthen(
+ PWLAN_FR_DEAUTHEN pFrame
+ );
+
+void
+vMgrEncodeReassocResponse(
+ PWLAN_FR_REASSOCRESP pFrame
+ );
+
+#endif /* __80211MGR_H__ */
diff --git a/drivers/staging/vt6656/Kconfig b/drivers/staging/vt6656/Kconfig
new file mode 100644
index 00000000..f89ab205
--- /dev/null
+++ b/drivers/staging/vt6656/Kconfig
@@ -0,0 +1,9 @@
+config VT6656
+ tristate "VIA Technologies VT6656 support"
+ depends on USB && WLAN && m
+ select WIRELESS_EXT
+ select WEXT_PRIV
+ select FW_LOADER
+ ---help---
+ This is a vendor-written driver for VIA VT6656.
+
diff --git a/drivers/staging/vt6656/Makefile b/drivers/staging/vt6656/Makefile
new file mode 100644
index 00000000..c9985478
--- /dev/null
+++ b/drivers/staging/vt6656/Makefile
@@ -0,0 +1,38 @@
+# TODO: all of these should be removed
+ccflags-y := -DLINUX -D__KERNEL__ -DEXPORT_SYMTAB -D__NO_VERSION__
+ccflags-y += -DHOSTAP
+
+vt6656_stage-y += main_usb.o \
+ card.o \
+ mac.o \
+ baseband.o \
+ wctl.o \
+ 80211mgr.o \
+ wcmd.o\
+ wmgr.o \
+ bssdb.o \
+ wpa2.o \
+ rxtx.o \
+ dpc.o \
+ power.o \
+ datarate.o \
+ mib.o \
+ rc4.o \
+ tether.o \
+ tcrc.o \
+ hostap.o \
+ wpa.o \
+ key.o \
+ tkip.o \
+ michael.o \
+ rf.o \
+ iwctl.o \
+ wpactl.o \
+ aes_ccmp.o \
+ usbpipe.o \
+ channel.o \
+ control.o \
+ firmware.o \
+ int.o
+
+obj-$(CONFIG_VT6656) += vt6656_stage.o
diff --git a/drivers/staging/vt6656/TODO b/drivers/staging/vt6656/TODO
new file mode 100644
index 00000000..e154b2f3
--- /dev/null
+++ b/drivers/staging/vt6656/TODO
@@ -0,0 +1,19 @@
+TODO:
+- remove __cplusplus ifdefs -- done
+- remove kernel version compatibility wrappers
+- remove support for older wireless extensions
+- prepare for merge with vt6655 driver:
+ - remove PRINT_K() macro
+ - split rf.c
+ - abstract VT3184 chipset specific code
+- add common vt665x infrastructure
+- kill ttype.h -- done
+- switch to use LIB80211
+- switch to use MAC80211
+- use kernel coding style
+- checkpatch.pl fixes
+- sparse fixes
+- integrate with drivers/net/wireless
+
+Please send any patches to Greg Kroah-Hartman <greg@kroah.com>
+and Forest Bond <forest@alittletooquiet.net>.
diff --git a/drivers/staging/vt6656/aes_ccmp.c b/drivers/staging/vt6656/aes_ccmp.c
new file mode 100644
index 00000000..28a4c4c3
--- /dev/null
+++ b/drivers/staging/vt6656/aes_ccmp.c
@@ -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: aes_ccmp.c
+ *
+ * Purpose: AES_CCMP decryption
+ *
+ * Author: Warren Hsu
+ *
+ * Date: Feb 15, 2005
+ *
+ * Functions:
+ * AESbGenCCMP - Parsing RX-packet
+ *
+ * Revision History:
+ */
+
+#include "device.h"
+#include "80211hdr.h"
+
+/*
+ * SBOX Table
+ */
+
+u8 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
+};
+
+u8 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
+};
+
+u8 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 void xor_128(u8 *a, u8 *b, u8 *out)
+{
+ u32 * dwPtrA = (u32 *) a;
+ u32 * dwPtrB = (u32 *) b;
+ u32 * dwPtrOut = (u32 *) out;
+
+ (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
+ (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
+ (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
+ (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
+}
+
+static void xor_32(u8 *a, u8 *b, u8 *out)
+{
+ u32 * dwPtrA = (u32 *) a;
+ u32 * dwPtrB = (u32 *) b;
+ u32 * dwPtrOut = (u32 *) out;
+
+ (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
+}
+
+void AddRoundKey(u8 *key, int round)
+{
+ u8 sbox_key[4];
+ u8 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(u8 *in, u8 *out)
+{
+ int i;
+
+ for (i = 0; i < 16; i++)
+ out[i] = sbox_table[in[i]];
+}
+
+void ShiftRows(u8 *in, u8 *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(u8 *in, u8 *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(u8 *key, u8 *data, u8 *ciphertext)
+{
+ int i;
+ int round;
+ u8 TmpdataA[16];
+ u8 TmpdataB[16];
+ u8 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(u8 * pbyRxKey, u8 * pbyFrame, u16 wFrameSize)
+{
+ u8 abyNonce[13];
+ u8 MIC_IV[16];
+ u8 MIC_HDR1[16];
+ u8 MIC_HDR2[16];
+ u8 abyMIC[16];
+ u8 abyCTRPLD[16];
+ u8 abyTmp[16];
+ u8 abyPlainText[16];
+ u8 abyLastCipher[16];
+
+ struct ieee80211_hdr *pMACHeader = (struct ieee80211_hdr *) pbyFrame;
+ u8 * pbyIV;
+ u8 * pbyPayload;
+ u16 wHLen = 22;
+ /* 8 is IV, 8 is MIC, 4 is CRC */
+ u16 wPayloadSize = wFrameSize - 8 - 8 - 4 - WLAN_HDR_ADDR3_LEN;
+ bool bA4 = false;
+ u8 byTmp;
+ u16 wCnt;
+ int ii, jj, kk;
+
+ pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN;
+ if (WLAN_GET_FC_TODS(*(u16 *) pbyFrame) &&
+ WLAN_GET_FC_FROMDS(*(u16 *) 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 */
+ memcpy(&(abyNonce[1]), pMACHeader->addr2, ETH_ALEN);
+ 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;
+ memcpy(&(MIC_IV[1]), &(abyNonce[0]), 13);
+ MIC_IV[14] = (u8)(wPayloadSize >> 8);
+ MIC_IV[15] = (u8)(wPayloadSize & 0xff);
+
+ /* MIC_HDR1 */
+ MIC_HDR1[0] = (u8)(wHLen >> 8);
+ MIC_HDR1[1] = (u8)(wHLen & 0xff);
+ byTmp = (u8)(pMACHeader->frame_control & 0xff);
+ MIC_HDR1[2] = byTmp & 0x8f;
+ byTmp = (u8)(pMACHeader->frame_control >> 8);
+ byTmp &= 0x87;
+ MIC_HDR1[3] = byTmp | 0x40;
+ memcpy(&(MIC_HDR1[4]), pMACHeader->addr1, ETH_ALEN);
+ memcpy(&(MIC_HDR1[10]), pMACHeader->addr2, ETH_ALEN);
+
+ /* MIC_HDR2 */
+ memcpy(&(MIC_HDR2[0]), pMACHeader->addr3, ETH_ALEN);
+ byTmp = (u8)(pMACHeader->seq_ctrl & 0xff);
+ MIC_HDR2[6] = byTmp & 0x0f;
+ MIC_HDR2[7] = 0;
+
+ if (bA4) {
+ memcpy(&(MIC_HDR2[8]), pMACHeader->addr4, ETH_ALEN);
+ } 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;
+ memcpy(&(abyCTRPLD[1]), &(abyNonce[0]), 13);
+
+ for (jj = wPayloadSize; jj > 16; jj = jj-16) {
+
+ abyCTRPLD[14] = (u8) (wCnt >> 8);
+ abyCTRPLD[15] = (u8) (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);
+
+ memcpy(pbyPayload, abyPlainText, 16);
+ wCnt++;
+ pbyPayload += 16;
+ } /* for wPayloadSize */
+
+ /* last payload */
+ memcpy(&(abyLastCipher[0]), pbyPayload, jj);
+ for (ii = jj; ii < 16; ii++)
+ abyLastCipher[ii] = 0x00;
+
+ abyCTRPLD[14] = (u8) (wCnt >> 8);
+ abyCTRPLD[15] = (u8) (wCnt & 0xff);
+
+ AESv128(pbyRxKey, abyCTRPLD, abyTmp);
+ for (kk = 0; kk < 16; kk++)
+ abyPlainText[kk] = abyTmp[kk] ^ abyLastCipher[kk];
+
+ memcpy(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 calculated MIC */
+
+ wCnt = 0;
+ abyCTRPLD[14] = (u8) (wCnt >> 8);
+ abyCTRPLD[15] = (u8) (wCnt & 0xff);
+ AESv128(pbyRxKey, abyCTRPLD, abyTmp);
+
+ for (kk = 0; kk < 8; kk++)
+ abyTmp[kk] = abyTmp[kk] ^ pbyPayload[kk];
+
+ /* => above is the packet dec-MIC */
+
+ if (!memcmp(abyMIC, abyTmp, 8))
+ return true;
+ else
+ return false;
+}
diff --git a/drivers/staging/vt6656/aes_ccmp.h b/drivers/staging/vt6656/aes_ccmp.h
new file mode 100644
index 00000000..ed6a9ae3
--- /dev/null
+++ b/drivers/staging/vt6656/aes_ccmp.h
@@ -0,0 +1,35 @@
+/*
+ * 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__
+
+bool AESbGenCCMP(u8 * pbyRxKey, u8 * pbyFrame, u16 wFrameSize);
+
+#endif /* __AES_CCMP_H__ */
diff --git a/drivers/staging/vt6656/baseband.c b/drivers/staging/vt6656/baseband.c
new file mode 100644
index 00000000..55185336
--- /dev/null
+++ b/drivers/staging/vt6656/baseband.c
@@ -0,0 +1,1901 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: baseband.c
+ *
+ * Purpose: Implement functions to access baseband
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Jun. 5, 2002
+ *
+ * Functions:
+ * BBuGetFrameTime - Calculate data frame transmitting time
+ * BBvCalculateParameter - Calculate PhyLength, PhyService and Phy Signal parameter for baseband Tx
+ * BBbVT3184Init - VIA VT3184 baseband chip init code
+ *
+ * Revision History:
+ *
+ *
+ */
+
+#include "tmacro.h"
+#include "tether.h"
+#include "mac.h"
+#include "baseband.h"
+#include "rf.h"
+#include "srom.h"
+#include "control.h"
+#include "datarate.h"
+#include "rndis.h"
+
+static int msglevel =MSG_LEVEL_INFO;
+//static int msglevel =MSG_LEVEL_DEBUG;
+
+u8 abyVT3184_AGC[] = {
+ 0x00, //0
+ 0x00, //1
+ 0x02, //2
+ 0x02, //3 //RobertYu:20060505, 0x04, //3
+ 0x04, //4
+ 0x04, //5 //RobertYu:20060505, 0x06, //5
+ 0x06, //6
+ 0x06, //7
+ 0x08, //8
+ 0x08, //9
+ 0x0A, //A
+ 0x0A, //B
+ 0x0C, //C
+ 0x0C, //D
+ 0x0E, //E
+ 0x0E, //F
+ 0x10, //10
+ 0x10, //11
+ 0x12, //12
+ 0x12, //13
+ 0x14, //14
+ 0x14, //15
+ 0x16, //16
+ 0x16, //17
+ 0x18, //18
+ 0x18, //19
+ 0x1A, //1A
+ 0x1A, //1B
+ 0x1C, //1C
+ 0x1C, //1D
+ 0x1E, //1E
+ 0x1E, //1F
+ 0x20, //20
+ 0x20, //21
+ 0x22, //22
+ 0x22, //23
+ 0x24, //24
+ 0x24, //25
+ 0x26, //26
+ 0x26, //27
+ 0x28, //28
+ 0x28, //29
+ 0x2A, //2A
+ 0x2A, //2B
+ 0x2C, //2C
+ 0x2C, //2D
+ 0x2E, //2E
+ 0x2E, //2F
+ 0x30, //30
+ 0x30, //31
+ 0x32, //32
+ 0x32, //33
+ 0x34, //34
+ 0x34, //35
+ 0x36, //36
+ 0x36, //37
+ 0x38, //38
+ 0x38, //39
+ 0x3A, //3A
+ 0x3A, //3B
+ 0x3C, //3C
+ 0x3C, //3D
+ 0x3E, //3E
+ 0x3E //3F
+};
+
+u8 abyVT3184_AL2230[] = {
+ 0x31,//00
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x80,
+ 0x00,
+ 0x00,
+ 0x70,
+ 0x45,//tx //0x64 for FPGA
+ 0x2A,
+ 0x76,
+ 0x00,
+ 0x00,
+ 0x80,
+ 0x00,
+ 0x00,//10
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x8e, //RobertYu:20060522, //0x8d,
+ 0x0a, //RobertYu:20060515, //0x09,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,//20
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x4a,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x4a,
+ 0x00,
+ 0x0c, //RobertYu:20060522, //0x10,
+ 0x26,//30
+ 0x5b,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xaa,
+ 0xaa,
+ 0xff,
+ 0xff,
+ 0x79,
+ 0x00,
+ 0x00,
+ 0x0b,
+ 0x48,
+ 0x04,
+ 0x00,//40
+ 0x08,
+ 0x00,
+ 0x08,
+ 0x08,
+ 0x14,
+ 0x05,
+ 0x09,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x09,
+ 0x73,
+ 0x00,
+ 0xc5,
+ 0x00,//50 //RobertYu:20060505, //0x15,//50
+ 0x19,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xd0, //RobertYu:20060505, //0xb0,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xe4,//60
+ 0x80,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x98,
+ 0x0a,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00, //0x80 for FPGA
+ 0x03,
+ 0x01,
+ 0x00,
+ 0x00,//70
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x8c,//80
+ 0x01,
+ 0x09,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x08,
+ 0x00,
+ 0x1f, //RobertYu:20060516, //0x0f,
+ 0xb7,
+ 0x88,
+ 0x47,
+ 0xaa,
+ 0x00, //RobertYu:20060505, //0x02,
+ 0x20,//90 //RobertYu:20060505, //0x22,//90
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xeb,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x01,
+ 0x00,//a0
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x10,
+ 0x00,
+ 0x18,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x15, //RobertYu:20060516, //0x00,
+ 0x00,
+ 0x18,
+ 0x38,//b0
+ 0x30,
+ 0x00,
+ 0x00,
+ 0xff,
+ 0x0f,
+ 0xe4,
+ 0xe2,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x03,
+ 0x01,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x18,//c0
+ 0x20,
+ 0x07,
+ 0x18,
+ 0xff,
+ 0xff, //RobertYu:20060509, //0x2c,
+ 0x0e, //RobertYu:20060530, //0x0c,
+ 0x0a,
+ 0x0e,
+ 0x00, //RobertYu:20060505, //0x01,
+ 0x82, //RobertYu:20060516, //0x8f,
+ 0xa7,
+ 0x3c,
+ 0x10,
+ 0x30, //RobertYu:20060627, //0x0b,
+ 0x05, //RobertYu:20060516, //0x25,
+ 0x40,//d0
+ 0x12,
+ 0x00,
+ 0x00,
+ 0x10,
+ 0x28,
+ 0x80,
+ 0x2A,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,//e0
+ 0xf3, //RobertYu:20060516, //0xd3,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x10,
+ 0x00,
+ 0x12, //RobertYu:20060627, //0x10,
+ 0x00,
+ 0xf4,
+ 0x00,
+ 0xff,
+ 0x79,
+ 0x20,
+ 0x30,
+ 0x05, //RobertYu:20060516, //0x0c,
+ 0x00,//f0
+ 0x3e,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+//{{RobertYu:20060515, new BB setting for VT3226D0
+u8 abyVT3184_VT3226D0[] = {
+ 0x31,//00
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x80,
+ 0x00,
+ 0x00,
+ 0x70,
+ 0x45,//tx //0x64 for FPGA
+ 0x2A,
+ 0x76,
+ 0x00,
+ 0x00,
+ 0x80,
+ 0x00,
+ 0x00,//10
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x8e, //RobertYu:20060525, //0x8d,
+ 0x0a, //RobertYu:20060515, //0x09,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,//20
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x4a,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x4a,
+ 0x00,
+ 0x0c, //RobertYu:20060525, //0x10,
+ 0x26,//30
+ 0x5b,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xaa,
+ 0xaa,
+ 0xff,
+ 0xff,
+ 0x79,
+ 0x00,
+ 0x00,
+ 0x0b,
+ 0x48,
+ 0x04,
+ 0x00,//40
+ 0x08,
+ 0x00,
+ 0x08,
+ 0x08,
+ 0x14,
+ 0x05,
+ 0x09,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x09,
+ 0x73,
+ 0x00,
+ 0xc5,
+ 0x00,//50 //RobertYu:20060505, //0x15,//50
+ 0x19,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xd0, //RobertYu:20060505, //0xb0,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xe4,//60
+ 0x80,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x98,
+ 0x0a,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00, //0x80 for FPGA
+ 0x03,
+ 0x01,
+ 0x00,
+ 0x00,//70
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x8c,//80
+ 0x01,
+ 0x09,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x08,
+ 0x00,
+ 0x1f, //RobertYu:20060515, //0x0f,
+ 0xb7,
+ 0x88,
+ 0x47,
+ 0xaa,
+ 0x00, //RobertYu:20060505, //0x02,
+ 0x20,//90 //RobertYu:20060505, //0x22,//90
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xeb,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x01,
+ 0x00,//a0
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x10,
+ 0x00,
+ 0x18,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x18,
+ 0x38,//b0
+ 0x30,
+ 0x00,
+ 0x00,
+ 0xff,
+ 0x0f,
+ 0xe4,
+ 0xe2,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x03,
+ 0x01,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x18,//c0
+ 0x20,
+ 0x07,
+ 0x18,
+ 0xff,
+ 0xff, //RobertYu:20060509, //0x2c,
+ 0x10, //RobertYu:20060525, //0x0c,
+ 0x0a,
+ 0x0e,
+ 0x00, //RobertYu:20060505, //0x01,
+ 0x84, //RobertYu:20060525, //0x8f,
+ 0xa7,
+ 0x3c,
+ 0x10,
+ 0x24, //RobertYu:20060627, //0x18,
+ 0x05, //RobertYu:20060515, //0x25,
+ 0x40,//d0
+ 0x12,
+ 0x00,
+ 0x00,
+ 0x10,
+ 0x28,
+ 0x80,
+ 0x2A,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,//e0
+ 0xf3, //RobertYu:20060515, //0xd3,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x10,
+ 0x00,
+ 0x10, //RobertYu:20060627, //0x0e,
+ 0x00,
+ 0xf4,
+ 0x00,
+ 0xff,
+ 0x79,
+ 0x20,
+ 0x30,
+ 0x08, //RobertYu:20060515, //0x0c,
+ 0x00,//f0
+ 0x3e,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+};
+
+const u16 awcFrameTime[MAX_RATE] =
+{10, 20, 55, 110, 24, 36, 48, 72, 96, 144, 192, 216};
+
+/*
+static
+unsigned long
+s_ulGetLowSQ3(PSDevice pDevice);
+
+static
+unsigned long
+s_ulGetRatio(PSDevice pDevice);
+
+static
+void
+s_vClearSQ3Value(PSDevice pDevice);
+*/
+
+/*
+ * 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
+ *
+ */
+unsigned int
+BBuGetFrameTime(
+ u8 byPreambleType,
+ u8 byPktType,
+ unsigned int cbFrameLength,
+ u16 wRate
+ )
+{
+ unsigned int uFrameTime;
+ unsigned int uPreamble;
+ unsigned int uTmp;
+ unsigned int uRateIdx = (unsigned int)wRate;
+ unsigned int uRate = 0;
+
+ if (uRateIdx > RATE_54M) {
+ ASSERT(0);
+ return 0;
+ }
+
+ uRate = (unsigned int)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: Calculate 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 BBvCalculateParameter(struct vnt_private *pDevice, u32 cbFrameLength,
+ u16 wRate, u8 byPacketType, u16 *pwPhyLen, u8 *pbyPhySrv,
+ u8 *pbyPhySgn)
+{
+ u32 cbBitCount;
+ u32 cbUsCount = 0;
+ u32 cbTmp;
+ int bExtBit;
+ u8 byPreambleType = pDevice->byPreambleType;
+ int 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 = (u16) cbUsCount;
+ }
+ else {
+ *pbyPhySrv = 0x00;
+ *pwPhyLen = (u16)cbFrameLength;
+ }
+}
+
+/*
+ * Description: Set Antenna mode
+ *
+ * Parameters:
+ * In:
+ * pDevice - Device Structure
+ * byAntennaMode - Antenna Mode
+ * Out:
+ * none
+ *
+ * Return Value: none
+ *
+ */
+void BBvSetAntennaMode(struct vnt_private *pDevice, u8 byAntennaMode)
+{
+ switch (byAntennaMode) {
+ case ANT_TXA:
+ case ANT_TXB:
+ break;
+ case ANT_RXA:
+ pDevice->byBBRxConf &= 0xFC;
+ break;
+ case ANT_RXB:
+ pDevice->byBBRxConf &= 0xFE;
+ pDevice->byBBRxConf |= 0x02;
+ break;
+ }
+
+ CONTROLnsRequestOut(pDevice,
+ MESSAGE_TYPE_SET_ANTMD,
+ (u16) byAntennaMode,
+ 0,
+ 0,
+ NULL);
+}
+
+/*
+ * Description: Set Antenna mode
+ *
+ * Parameters:
+ * In:
+ * pDevice - Device Structure
+ * byAntennaMode - Antenna Mode
+ * Out:
+ * none
+ *
+ * Return Value: none
+ *
+ */
+
+int BBbVT3184Init(struct vnt_private *pDevice)
+{
+ int ntStatus;
+ u16 wLength;
+ u8 * pbyAddr;
+ u8 * pbyAgc;
+ u16 wLengthAgc;
+ u8 abyArray[256];
+ u8 data;
+
+ ntStatus = CONTROLnsRequestIn(pDevice,
+ MESSAGE_TYPE_READ,
+ 0,
+ MESSAGE_REQUEST_EEPROM,
+ EEP_MAX_CONTEXT_SIZE,
+ pDevice->abyEEPROM);
+ if (ntStatus != STATUS_SUCCESS) {
+ return false;
+ }
+
+// if ((pDevice->abyEEPROM[EEP_OFS_RADIOCTL]&0x06)==0x04)
+// return false;
+
+//zonetype initial
+ pDevice->byOriginalZonetype = pDevice->abyEEPROM[EEP_OFS_ZONETYPE];
+ if(pDevice->config_file.ZoneType >= 0) { //read zonetype file ok!
+ if ((pDevice->config_file.ZoneType == 0)&&
+ (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] !=0x00)){ //for USA
+ pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0;
+ pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0B;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Init Zone Type :USA\n");
+ }
+ else if((pDevice->config_file.ZoneType == 1)&&
+ (pDevice->abyEEPROM[EEP_OFS_ZONETYPE]!=0x01)){ //for Japan
+ pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0x01;
+ pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0D;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Init Zone Type :Japan\n");
+ }
+ else if((pDevice->config_file.ZoneType == 2)&&
+ (pDevice->abyEEPROM[EEP_OFS_ZONETYPE]!=0x02)){ //for Europe
+ pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0x02;
+ pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0D;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Init Zone Type :Europe\n");
+ }
+else {
+ if(pDevice->config_file.ZoneType !=pDevice->abyEEPROM[EEP_OFS_ZONETYPE])
+ printk("zonetype in file[%02x] mismatch with in EEPROM[%02x]\n",pDevice->config_file.ZoneType,pDevice->abyEEPROM[EEP_OFS_ZONETYPE]);
+ else
+ printk("Read Zonetype file success,use default zonetype setting[%02x]\n",pDevice->config_file.ZoneType);
+ }
+}
+
+ if ( !pDevice->bZoneRegExist ) {
+ pDevice->byZoneType = pDevice->abyEEPROM[EEP_OFS_ZONETYPE];
+ }
+ pDevice->byRFType = pDevice->abyEEPROM[EEP_OFS_RFTYPE];
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Zone Type %x\n", pDevice->byZoneType);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"RF Type %d\n", pDevice->byRFType);
+
+ if ((pDevice->byRFType == RF_AL2230) || (pDevice->byRFType == RF_AL2230S)) {
+ pDevice->byBBRxConf = abyVT3184_AL2230[10];
+ wLength = sizeof(abyVT3184_AL2230);
+ pbyAddr = abyVT3184_AL2230;
+ pbyAgc = abyVT3184_AGC;
+ wLengthAgc = sizeof(abyVT3184_AGC);
+
+ pDevice->abyBBVGA[0] = 0x1C;
+ pDevice->abyBBVGA[1] = 0x10;
+ pDevice->abyBBVGA[2] = 0x0;
+ pDevice->abyBBVGA[3] = 0x0;
+ pDevice->ldBmThreshold[0] = -70;
+ pDevice->ldBmThreshold[1] = -48;
+ pDevice->ldBmThreshold[2] = 0;
+ pDevice->ldBmThreshold[3] = 0;
+ }
+ else if (pDevice->byRFType == RF_AIROHA7230) {
+ pDevice->byBBRxConf = abyVT3184_AL2230[10];
+ wLength = sizeof(abyVT3184_AL2230);
+ pbyAddr = abyVT3184_AL2230;
+ pbyAgc = abyVT3184_AGC;
+ wLengthAgc = sizeof(abyVT3184_AGC);
+
+ // Init ANT B select,TX Config CR09 = 0x61->0x45, 0x45->0x41(VC1/VC2 define, make the ANT_A, ANT_B inverted)
+ //pbyAddr[0x09] = 0x41;
+ // Init ANT B select,RX Config CR10 = 0x28->0x2A, 0x2A->0x28(VC1/VC2 define, make the ANT_A, ANT_B inverted)
+ //pbyAddr[0x0a] = 0x28;
+ // Select VC1/VC2, CR215 = 0x02->0x06
+ pbyAddr[0xd7] = 0x06;
+
+ pDevice->abyBBVGA[0] = 0x1C;
+ pDevice->abyBBVGA[1] = 0x10;
+ pDevice->abyBBVGA[2] = 0x0;
+ pDevice->abyBBVGA[3] = 0x0;
+ pDevice->ldBmThreshold[0] = -70;
+ pDevice->ldBmThreshold[1] = -48;
+ pDevice->ldBmThreshold[2] = 0;
+ pDevice->ldBmThreshold[3] = 0;
+ }
+ else if ( (pDevice->byRFType == RF_VT3226) || (pDevice->byRFType == RF_VT3226D0) ) {
+ pDevice->byBBRxConf = abyVT3184_VT3226D0[10]; //RobertYu:20060515
+ wLength = sizeof(abyVT3184_VT3226D0); //RobertYu:20060515
+ pbyAddr = abyVT3184_VT3226D0; //RobertYu:20060515
+ pbyAgc = abyVT3184_AGC;
+ wLengthAgc = sizeof(abyVT3184_AGC);
+
+ pDevice->abyBBVGA[0] = 0x20; //RobertYu:20060104, reguest by Jack
+ pDevice->abyBBVGA[1] = 0x10;
+ pDevice->abyBBVGA[2] = 0x0;
+ pDevice->abyBBVGA[3] = 0x0;
+ pDevice->ldBmThreshold[0] = -70;
+ pDevice->ldBmThreshold[1] = -48;
+ pDevice->ldBmThreshold[2] = 0;
+ pDevice->ldBmThreshold[3] = 0;
+ // Fix VT3226 DFC system timing issue
+ MACvRegBitsOn(pDevice, MAC_REG_SOFTPWRCTL2, SOFTPWRCTL_RFLEOPT);
+ //}}
+ //{{RobertYu:20060609
+ } else if ( (pDevice->byRFType == RF_VT3342A0) ) {
+ pDevice->byBBRxConf = abyVT3184_VT3226D0[10];
+ wLength = sizeof(abyVT3184_VT3226D0);
+ pbyAddr = abyVT3184_VT3226D0;
+ pbyAgc = abyVT3184_AGC;
+ wLengthAgc = sizeof(abyVT3184_AGC);
+
+ pDevice->abyBBVGA[0] = 0x20;
+ pDevice->abyBBVGA[1] = 0x10;
+ pDevice->abyBBVGA[2] = 0x0;
+ pDevice->abyBBVGA[3] = 0x0;
+ pDevice->ldBmThreshold[0] = -70;
+ pDevice->ldBmThreshold[1] = -48;
+ pDevice->ldBmThreshold[2] = 0;
+ pDevice->ldBmThreshold[3] = 0;
+ // Fix VT3226 DFC system timing issue
+ MACvRegBitsOn(pDevice, MAC_REG_SOFTPWRCTL2, SOFTPWRCTL_RFLEOPT);
+ //}}
+ } else {
+ return true;
+ }
+
+ memcpy(abyArray, pbyAddr, wLength);
+ CONTROLnsRequestOut(pDevice,
+ MESSAGE_TYPE_WRITE,
+ 0,
+ MESSAGE_REQUEST_BBREG,
+ wLength,
+ abyArray
+ );
+
+ memcpy(abyArray, pbyAgc, wLengthAgc);
+ CONTROLnsRequestOut(pDevice,
+ MESSAGE_TYPE_WRITE,
+ 0,
+ MESSAGE_REQUEST_BBAGC,
+ wLengthAgc,
+ abyArray
+ );
+
+ if ((pDevice->byRFType == RF_VT3226) || //RobertYu:20051116, 20060111 remove VT3226D0
+ (pDevice->byRFType == RF_VT3342A0) //RobertYu:20060609
+ ) {
+ ControlvWriteByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_ITRTMSET,0x23);
+ MACvRegBitsOn(pDevice,MAC_REG_PAPEDELAY,0x01);
+ }
+ else if (pDevice->byRFType == RF_VT3226D0)
+ {
+ ControlvWriteByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_ITRTMSET,0x11);
+ MACvRegBitsOn(pDevice,MAC_REG_PAPEDELAY,0x01);
+ }
+
+ ControlvWriteByte(pDevice,MESSAGE_REQUEST_BBREG,0x04,0x7F);
+ ControlvWriteByte(pDevice,MESSAGE_REQUEST_BBREG,0x0D,0x01);
+
+ RFbRFTableDownload(pDevice);
+
+ /* Fix for TX USB resets from vendors driver */
+ CONTROLnsRequestIn(pDevice, MESSAGE_TYPE_READ, USB_REG4,
+ MESSAGE_REQUEST_MEM, sizeof(data), &data);
+
+ data |= 0x2;
+
+ CONTROLnsRequestOut(pDevice, MESSAGE_TYPE_WRITE, USB_REG4,
+ MESSAGE_REQUEST_MEM, sizeof(data), &data);
+
+ return true;//ntStatus;
+}
+
+/*
+ * Description: Set ShortSlotTime mode
+ *
+ * Parameters:
+ * In:
+ * pDevice - Device Structure
+ * Out:
+ * none
+ *
+ * Return Value: none
+ *
+ */
+void BBvSetShortSlotTime(struct vnt_private *pDevice)
+{
+ u8 byBBVGA=0;
+
+ if (pDevice->bShortSlotTime)
+ pDevice->byBBRxConf &= 0xDF;//1101 1111
+ else
+ pDevice->byBBRxConf |= 0x20;//0010 0000
+
+ ControlvReadByte (pDevice, MESSAGE_REQUEST_BBREG, 0xE7, &byBBVGA);
+ if (byBBVGA == pDevice->abyBBVGA[0])
+ pDevice->byBBRxConf |= 0x20;//0010 0000
+
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x0A, pDevice->byBBRxConf);
+}
+
+void BBvSetVGAGainOffset(struct vnt_private *pDevice, u8 byData)
+{
+
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xE7, byData);
+
+ // patch for 3253B0 Baseband with Cardbus module
+ if (pDevice->bShortSlotTime)
+ pDevice->byBBRxConf &= 0xDF; /* 1101 1111 */
+ else
+ pDevice->byBBRxConf |= 0x20; /* 0010 0000 */
+
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x0A, pDevice->byBBRxConf);//CR10
+}
+
+/*
+ * Description: BBvSetDeepSleep
+ *
+ * Parameters:
+ * In:
+ * pDevice - Device Structure
+ * Out:
+ * none
+ *
+ * Return Value: none
+ *
+ */
+void BBvSetDeepSleep(struct vnt_private *pDevice)
+{
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x0c, 0x17);//CR12
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x0D, 0xB9);//CR13
+}
+
+void BBvExitDeepSleep(struct vnt_private *pDevice)
+{
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x0C, 0x00);//CR12
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x0D, 0x01);//CR13
+}
+
+static unsigned long s_ulGetLowSQ3(struct vnt_private *pDevice)
+{
+ int ii;
+ unsigned long ulSQ3 = 0;
+ unsigned long ulMaxPacket;
+
+ ulMaxPacket = pDevice->aulPktNum[RATE_54M];
+ if (pDevice->aulPktNum[RATE_54M] != 0)
+ ulSQ3 = pDevice->aulSQ3Val[RATE_54M] / pDevice->aulPktNum[RATE_54M];
+
+ for (ii = RATE_48M; ii >= RATE_6M; ii--)
+ if (pDevice->aulPktNum[ii] > ulMaxPacket) {
+ ulMaxPacket = pDevice->aulPktNum[ii];
+ ulSQ3 = pDevice->aulSQ3Val[ii] / pDevice->aulPktNum[ii];
+ }
+
+ return ulSQ3;
+}
+
+static unsigned long s_ulGetRatio(struct vnt_private *pDevice)
+{
+ int ii, jj;
+ unsigned long ulRatio = 0;
+ unsigned long ulMaxPacket;
+ unsigned long ulPacketNum;
+
+ //This is a thousand-ratio
+ ulMaxPacket = pDevice->aulPktNum[RATE_54M];
+ if ( pDevice->aulPktNum[RATE_54M] != 0 ) {
+ ulPacketNum = pDevice->aulPktNum[RATE_54M];
+ ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt);
+ ulRatio += TOP_RATE_54M;
+ }
+ for (ii = RATE_48M; ii >= RATE_1M; ii--)
+ if ( pDevice->aulPktNum[ii] > ulMaxPacket ) {
+ ulPacketNum = 0;
+ for ( jj=RATE_54M;jj>=ii;jj--)
+ ulPacketNum += pDevice->aulPktNum[jj];
+ ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt);
+ ulRatio += TOP_RATE_48M;
+ ulMaxPacket = pDevice->aulPktNum[ii];
+ }
+
+ return ulRatio;
+}
+
+static void s_vClearSQ3Value(struct vnt_private *pDevice)
+{
+ int ii;
+ pDevice->uDiversityCnt = 0;
+
+ for ( ii=RATE_1M;ii<MAX_RATE;ii++) {
+ pDevice->aulPktNum[ii] = 0;
+ pDevice->aulSQ3Val[ii] = 0;
+ }
+}
+
+/*
+ * Description: Antenna Diversity
+ *
+ * Parameters:
+ * In:
+ * pDevice - Device Structure
+ * byRSR - RSR from received packet
+ * bySQ3 - SQ3 value from received packet
+ * Out:
+ * none
+ *
+ * Return Value: none
+ *
+ */
+
+void BBvAntennaDiversity(struct vnt_private *pDevice,
+ u8 byRxRate, u8 bySQ3)
+{
+
+ pDevice->uDiversityCnt++;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pDevice->uDiversityCnt = %d\n", (int)pDevice->uDiversityCnt);
+
+ if (byRxRate == 2) {
+ pDevice->aulPktNum[RATE_1M]++;
+ }
+ else if (byRxRate==4) {
+ pDevice->aulPktNum[RATE_2M]++;
+ }
+ else if (byRxRate==11) {
+ pDevice->aulPktNum[RATE_5M]++;
+ }
+ else if (byRxRate==22) {
+ pDevice->aulPktNum[RATE_11M]++;
+ }
+ else if(byRxRate==12){
+ pDevice->aulPktNum[RATE_6M]++;
+ pDevice->aulSQ3Val[RATE_6M] += bySQ3;
+ }
+ else if(byRxRate==18){
+ pDevice->aulPktNum[RATE_9M]++;
+ pDevice->aulSQ3Val[RATE_9M] += bySQ3;
+ }
+ else if(byRxRate==24){
+ pDevice->aulPktNum[RATE_12M]++;
+ pDevice->aulSQ3Val[RATE_12M] += bySQ3;
+ }
+ else if(byRxRate==36){
+ pDevice->aulPktNum[RATE_18M]++;
+ pDevice->aulSQ3Val[RATE_18M] += bySQ3;
+ }
+ else if(byRxRate==48){
+ pDevice->aulPktNum[RATE_24M]++;
+ pDevice->aulSQ3Val[RATE_24M] += bySQ3;
+ }
+ else if(byRxRate==72){
+ pDevice->aulPktNum[RATE_36M]++;
+ pDevice->aulSQ3Val[RATE_36M] += bySQ3;
+ }
+ else if(byRxRate==96){
+ pDevice->aulPktNum[RATE_48M]++;
+ pDevice->aulSQ3Val[RATE_48M] += bySQ3;
+ }
+ else if(byRxRate==108){
+ pDevice->aulPktNum[RATE_54M]++;
+ pDevice->aulSQ3Val[RATE_54M] += bySQ3;
+ }
+
+ if (pDevice->byAntennaState == 0) {
+
+ if (pDevice->uDiversityCnt > pDevice->ulDiversityNValue) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ulDiversityNValue=[%d],54M-[%d]\n",(int)pDevice->ulDiversityNValue, (int)pDevice->aulPktNum[RATE_54M]);
+
+ pDevice->ulSQ3_State0 = s_ulGetLowSQ3(pDevice);
+ pDevice->ulRatio_State0 = s_ulGetRatio(pDevice);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"SQ3_State0, SQ3= [%08x] rate = [%08x]\n",(int)pDevice->ulSQ3_State0,(int)pDevice->ulRatio_State0);
+
+ if ( ((pDevice->aulPktNum[RATE_54M] < pDevice->ulDiversityNValue/2) &&
+ (pDevice->ulSQ3_State0 > pDevice->ulSQ3TH) ) ||
+ (pDevice->ulSQ3_State0 == 0 ) ) {
+
+ if ( pDevice->byTMax == 0 )
+ return;
+
+ bScheduleCommand((void *) pDevice,
+ WLAN_CMD_CHANGE_ANTENNA,
+ NULL);
+
+ pDevice->byAntennaState = 1;
+
+ del_timer(&pDevice->TimerSQ3Tmax3);
+ del_timer(&pDevice->TimerSQ3Tmax2);
+ pDevice->TimerSQ3Tmax1.expires = RUN_AT(pDevice->byTMax * HZ);
+ add_timer(&pDevice->TimerSQ3Tmax1);
+
+ } else {
+ pDevice->TimerSQ3Tmax3.expires = RUN_AT(pDevice->byTMax3 * HZ);
+ add_timer(&pDevice->TimerSQ3Tmax3);
+ }
+ s_vClearSQ3Value(pDevice);
+
+ }
+ } else { //byAntennaState == 1
+
+ if (pDevice->uDiversityCnt > pDevice->ulDiversityMValue) {
+
+ del_timer(&pDevice->TimerSQ3Tmax1);
+ pDevice->ulSQ3_State1 = s_ulGetLowSQ3(pDevice);
+ pDevice->ulRatio_State1 = s_ulGetRatio(pDevice);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"SQ3_State1, rate0 = %08x,rate1 = %08x\n",(int)pDevice->ulRatio_State0,(int)pDevice->ulRatio_State1);
+
+ if ( ((pDevice->ulSQ3_State1 == 0) && (pDevice->ulSQ3_State0 != 0)) ||
+ ((pDevice->ulSQ3_State1 == 0) && (pDevice->ulSQ3_State0 == 0) && (pDevice->ulRatio_State1 < pDevice->ulRatio_State0)) ||
+ ((pDevice->ulSQ3_State1 != 0) && (pDevice->ulSQ3_State0 != 0) && (pDevice->ulSQ3_State0 < pDevice->ulSQ3_State1))
+ ) {
+
+ bScheduleCommand((void *) pDevice,
+ WLAN_CMD_CHANGE_ANTENNA,
+ NULL);
+
+ pDevice->TimerSQ3Tmax3.expires = RUN_AT(pDevice->byTMax3 * HZ);
+ pDevice->TimerSQ3Tmax2.expires = RUN_AT(pDevice->byTMax2 * HZ);
+ add_timer(&pDevice->TimerSQ3Tmax3);
+ add_timer(&pDevice->TimerSQ3Tmax2);
+
+ }
+ pDevice->byAntennaState = 0;
+ s_vClearSQ3Value(pDevice);
+ }
+ } //byAntennaState
+}
+
+/*+
+ *
+ * Description:
+ * Timer for SQ3 antenna diversity
+ *
+ * Parameters:
+ * In:
+ * pvSysSpec1
+ * hDeviceContext - Pointer to the adapter
+ * pvSysSpec2
+ * pvSysSpec3
+ * Out:
+ * none
+ *
+ * Return Value: none
+ *
+-*/
+
+void TimerSQ3CallBack(struct vnt_private *pDevice)
+{
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"TimerSQ3CallBack...");
+ spin_lock_irq(&pDevice->lock);
+
+ bScheduleCommand((void *) pDevice, WLAN_CMD_CHANGE_ANTENNA, NULL);
+ pDevice->byAntennaState = 0;
+ s_vClearSQ3Value(pDevice);
+ pDevice->TimerSQ3Tmax3.expires = RUN_AT(pDevice->byTMax3 * HZ);
+ pDevice->TimerSQ3Tmax2.expires = RUN_AT(pDevice->byTMax2 * HZ);
+ add_timer(&pDevice->TimerSQ3Tmax3);
+ add_timer(&pDevice->TimerSQ3Tmax2);
+
+ spin_unlock_irq(&pDevice->lock);
+}
+
+/*+
+ *
+ * Description:
+ * Timer for SQ3 antenna diversity
+ *
+ * Parameters:
+ * In:
+ * pvSysSpec1
+ * hDeviceContext - Pointer to the adapter
+ * pvSysSpec2
+ * pvSysSpec3
+ * Out:
+ * none
+ *
+ * Return Value: none
+ *
+-*/
+
+void TimerSQ3Tmax3CallBack(struct vnt_private *pDevice)
+{
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"TimerSQ3Tmax3CallBack...");
+ spin_lock_irq(&pDevice->lock);
+
+ pDevice->ulRatio_State0 = s_ulGetRatio(pDevice);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"SQ3_State0 = [%08x]\n",(int)pDevice->ulRatio_State0);
+
+ s_vClearSQ3Value(pDevice);
+ if ( pDevice->byTMax == 0 ) {
+ pDevice->TimerSQ3Tmax3.expires = RUN_AT(pDevice->byTMax3 * HZ);
+ add_timer(&pDevice->TimerSQ3Tmax3);
+ spin_unlock_irq(&pDevice->lock);
+ return;
+ }
+
+ bScheduleCommand((void *) pDevice, WLAN_CMD_CHANGE_ANTENNA, NULL);
+ pDevice->byAntennaState = 1;
+ del_timer(&pDevice->TimerSQ3Tmax3);
+ del_timer(&pDevice->TimerSQ3Tmax2);
+ pDevice->TimerSQ3Tmax1.expires = RUN_AT(pDevice->byTMax * HZ);
+ add_timer(&pDevice->TimerSQ3Tmax1);
+
+ spin_unlock_irq(&pDevice->lock);
+}
+
+void BBvUpdatePreEDThreshold(struct vnt_private *pDevice, int bScanning)
+{
+
+ switch(pDevice->byRFType)
+ {
+ case RF_AL2230:
+ case RF_AL2230S:
+ case RF_AIROHA7230:
+ //RobertYu:20060627, update new table
+
+ if( bScanning )
+ { // need Max sensitivity //RSSI -69, -70,....
+ pDevice->byBBPreEDIndex = 0;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x30); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -69, -70, -71,...\n");
+ break;
+ }
+
+ if(pDevice->byBBPreEDRSSI <= 45) { // RSSI 0, -1,-2,....-45
+ if(pDevice->byBBPreEDIndex == 20) break;
+ pDevice->byBBPreEDIndex = 20;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0xFF); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI 0, -1,-2,..-45\n");
+ } else if(pDevice->byBBPreEDRSSI <= 46) { //RSSI -46
+ if(pDevice->byBBPreEDIndex == 19) break;
+ pDevice->byBBPreEDIndex = 19;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x1A); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -46\n");
+ } else if(pDevice->byBBPreEDRSSI <= 47) { //RSSI -47
+ if(pDevice->byBBPreEDIndex == 18) break;
+ pDevice->byBBPreEDIndex = 18;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x15); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -47\n");
+ } else if(pDevice->byBBPreEDRSSI <= 49) { //RSSI -48, -49
+ if(pDevice->byBBPreEDIndex == 17) break;
+ pDevice->byBBPreEDIndex = 17;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x0E); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -48,-49\n");
+ } else if(pDevice->byBBPreEDRSSI <= 51) { //RSSI -50, -51
+ if(pDevice->byBBPreEDIndex == 16) break;
+ pDevice->byBBPreEDIndex = 16;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x09); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -50,-51\n");
+ } else if(pDevice->byBBPreEDRSSI <= 53) { //RSSI -52, -53
+ if(pDevice->byBBPreEDIndex == 15) break;
+ pDevice->byBBPreEDIndex = 15;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x06); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -52,-53\n");
+ } else if(pDevice->byBBPreEDRSSI <= 55) { //RSSI -54, -55
+ if(pDevice->byBBPreEDIndex == 14) break;
+ pDevice->byBBPreEDIndex = 14;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x03); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -54,-55\n");
+ } else if(pDevice->byBBPreEDRSSI <= 56) { //RSSI -56
+ if(pDevice->byBBPreEDIndex == 13) break;
+ pDevice->byBBPreEDIndex = 13;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x02); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0xA0); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -56\n");
+ } else if(pDevice->byBBPreEDRSSI <= 57) { //RSSI -57
+ if(pDevice->byBBPreEDIndex == 12) break;
+ pDevice->byBBPreEDIndex = 12;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x02); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x20); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -57\n");
+ } else if(pDevice->byBBPreEDRSSI <= 58) { //RSSI -58
+ if(pDevice->byBBPreEDIndex == 11) break;
+ pDevice->byBBPreEDIndex = 11;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x01); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0xA0); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -58\n");
+ } else if(pDevice->byBBPreEDRSSI <= 59) { //RSSI -59
+ if(pDevice->byBBPreEDIndex == 10) break;
+ pDevice->byBBPreEDIndex = 10;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x01); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x54); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -59\n");
+ } else if(pDevice->byBBPreEDRSSI <= 60) { //RSSI -60
+ if(pDevice->byBBPreEDIndex == 9) break;
+ pDevice->byBBPreEDIndex = 9;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x01); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x18); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -60\n");
+ } else if(pDevice->byBBPreEDRSSI <= 61) { //RSSI -61
+ if(pDevice->byBBPreEDIndex == 8) break;
+ pDevice->byBBPreEDIndex = 8;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0xE3); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -61\n");
+ } else if(pDevice->byBBPreEDRSSI <= 62) { //RSSI -62
+ if(pDevice->byBBPreEDIndex == 7) break;
+ pDevice->byBBPreEDIndex = 7;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0xB9); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -62\n");
+ } else if(pDevice->byBBPreEDRSSI <= 63) { //RSSI -63
+ if(pDevice->byBBPreEDIndex == 6) break;
+ pDevice->byBBPreEDIndex = 6;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x93); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -63\n");
+ } else if(pDevice->byBBPreEDRSSI <= 64) { //RSSI -64
+ if(pDevice->byBBPreEDIndex == 5) break;
+ pDevice->byBBPreEDIndex = 5;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x79); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -64\n");
+ } else if(pDevice->byBBPreEDRSSI <= 65) { //RSSI -65
+ if(pDevice->byBBPreEDIndex == 4) break;
+ pDevice->byBBPreEDIndex = 4;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x62); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -65\n");
+ } else if(pDevice->byBBPreEDRSSI <= 66) { //RSSI -66
+ if(pDevice->byBBPreEDIndex == 3) break;
+ pDevice->byBBPreEDIndex = 3;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x51); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -66\n");
+ } else if(pDevice->byBBPreEDRSSI <= 67) { //RSSI -67
+ if(pDevice->byBBPreEDIndex == 2) break;
+ pDevice->byBBPreEDIndex = 2;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x43); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -67\n");
+ } else if(pDevice->byBBPreEDRSSI <= 68) { //RSSI -68
+ if(pDevice->byBBPreEDIndex == 1) break;
+ pDevice->byBBPreEDIndex = 1;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x36); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -68\n");
+ } else { //RSSI -69, -70,....
+ if(pDevice->byBBPreEDIndex == 0) break;
+ pDevice->byBBPreEDIndex = 0;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x30); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -69, -70,...\n");
+ }
+ break;
+
+ case RF_VT3226:
+ case RF_VT3226D0:
+ //RobertYu:20060627, update new table
+
+ if( bScanning )
+ { // need Max sensitivity //RSSI -69, -70, ...
+ pDevice->byBBPreEDIndex = 0;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x24); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -69, -70,..\n");
+ break;
+ }
+
+ if(pDevice->byBBPreEDRSSI <= 41) { // RSSI 0, -1,-2,....-41
+ if(pDevice->byBBPreEDIndex == 22) break;
+ pDevice->byBBPreEDIndex = 22;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0xFF); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI 0, -1,-2,..-41\n");
+ } else if(pDevice->byBBPreEDRSSI <= 42) { //RSSI -42
+ if(pDevice->byBBPreEDIndex == 21) break;
+ pDevice->byBBPreEDIndex = 21;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x36); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -42\n");
+ } else if(pDevice->byBBPreEDRSSI <= 43) { //RSSI -43
+ if(pDevice->byBBPreEDIndex == 20) break;
+ pDevice->byBBPreEDIndex = 20;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x26); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -43\n");
+ } else if(pDevice->byBBPreEDRSSI <= 45) { //RSSI -44, -45
+ if(pDevice->byBBPreEDIndex == 19) break;
+ pDevice->byBBPreEDIndex = 19;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x18); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -44,-45\n");
+ } else if(pDevice->byBBPreEDRSSI <= 47) { //RSSI -46, -47
+ if(pDevice->byBBPreEDIndex == 18) break;
+ pDevice->byBBPreEDIndex = 18;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x11); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -46,-47\n");
+ } else if(pDevice->byBBPreEDRSSI <= 49) { //RSSI -48, -49
+ if(pDevice->byBBPreEDIndex == 17) break;
+ pDevice->byBBPreEDIndex = 17;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x0a); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -48,-49\n");
+ } else if(pDevice->byBBPreEDRSSI <= 51) { //RSSI -50, -51
+ if(pDevice->byBBPreEDIndex == 16) break;
+ pDevice->byBBPreEDIndex = 16;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x07); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -50,-51\n");
+ } else if(pDevice->byBBPreEDRSSI <= 53) { //RSSI -52, -53
+ if(pDevice->byBBPreEDIndex == 15) break;
+ pDevice->byBBPreEDIndex = 15;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x04); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -52,-53\n");
+ } else if(pDevice->byBBPreEDRSSI <= 55) { //RSSI -54, -55
+ if(pDevice->byBBPreEDIndex == 14) break;
+ pDevice->byBBPreEDIndex = 14;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x02); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0xC0); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -54,-55\n");
+ } else if(pDevice->byBBPreEDRSSI <= 56) { //RSSI -56
+ if(pDevice->byBBPreEDIndex == 13) break;
+ pDevice->byBBPreEDIndex = 13;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x02); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x30); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -56\n");
+ } else if(pDevice->byBBPreEDRSSI <= 57) { //RSSI -57
+ if(pDevice->byBBPreEDIndex == 12) break;
+ pDevice->byBBPreEDIndex = 12;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x01); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0xB0); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -57\n");
+ } else if(pDevice->byBBPreEDRSSI <= 58) { //RSSI -58
+ if(pDevice->byBBPreEDIndex == 11) break;
+ pDevice->byBBPreEDIndex = 11;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x01); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x70); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -58\n");
+ } else if(pDevice->byBBPreEDRSSI <= 59) { //RSSI -59
+ if(pDevice->byBBPreEDIndex == 10) break;
+ pDevice->byBBPreEDIndex = 10;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x01); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x30); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -59\n");
+ } else if(pDevice->byBBPreEDRSSI <= 60) { //RSSI -60
+ if(pDevice->byBBPreEDIndex == 9) break;
+ pDevice->byBBPreEDIndex = 9;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0xEA); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -60\n");
+ } else if(pDevice->byBBPreEDRSSI <= 61) { //RSSI -61
+ if(pDevice->byBBPreEDIndex == 8) break;
+ pDevice->byBBPreEDIndex = 8;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0xC0); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -61\n");
+ } else if(pDevice->byBBPreEDRSSI <= 62) { //RSSI -62
+ if(pDevice->byBBPreEDIndex == 7) break;
+ pDevice->byBBPreEDIndex = 7;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x9C); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -62\n");
+ } else if(pDevice->byBBPreEDRSSI <= 63) { //RSSI -63
+ if(pDevice->byBBPreEDIndex == 6) break;
+ pDevice->byBBPreEDIndex = 6;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x80); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -63\n");
+ } else if(pDevice->byBBPreEDRSSI <= 64) { //RSSI -64
+ if(pDevice->byBBPreEDIndex == 5) break;
+ pDevice->byBBPreEDIndex = 5;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x68); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -64\n");
+ } else if(pDevice->byBBPreEDRSSI <= 65) { //RSSI -65
+ if(pDevice->byBBPreEDIndex == 4) break;
+ pDevice->byBBPreEDIndex = 4;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x52); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -65\n");
+ } else if(pDevice->byBBPreEDRSSI <= 66) { //RSSI -66
+ if(pDevice->byBBPreEDIndex == 3) break;
+ pDevice->byBBPreEDIndex = 3;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x43); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -66\n");
+ } else if(pDevice->byBBPreEDRSSI <= 67) { //RSSI -67
+ if(pDevice->byBBPreEDIndex == 2) break;
+ pDevice->byBBPreEDIndex = 2;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x36); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -67\n");
+ } else if(pDevice->byBBPreEDRSSI <= 68) { //RSSI -68
+ if(pDevice->byBBPreEDIndex == 1) break;
+ pDevice->byBBPreEDIndex = 1;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x2D); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -68\n");
+ } else { //RSSI -69, -70, ...
+ if(pDevice->byBBPreEDIndex == 0) break;
+ pDevice->byBBPreEDIndex = 0;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x24); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -69, -70,..\n");
+ }
+ break;
+
+ case RF_VT3342A0: //RobertYu:20060627, testing table
+ if( bScanning )
+ { // need Max sensitivity //RSSI -67, -68, ...
+ pDevice->byBBPreEDIndex = 0;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x38); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -67, -68,..\n");
+ break;
+ }
+
+ if(pDevice->byBBPreEDRSSI <= 41) { // RSSI 0, -1,-2,....-41
+ if(pDevice->byBBPreEDIndex == 20) break;
+ pDevice->byBBPreEDIndex = 20;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0xFF); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI 0, -1,-2,..-41\n");
+ } else if(pDevice->byBBPreEDRSSI <= 42) { //RSSI -42
+ if(pDevice->byBBPreEDIndex == 19) break;
+ pDevice->byBBPreEDIndex = 19;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x36); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -42\n");
+ } else if(pDevice->byBBPreEDRSSI <= 43) { //RSSI -43
+ if(pDevice->byBBPreEDIndex == 18) break;
+ pDevice->byBBPreEDIndex = 18;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x26); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -43\n");
+ } else if(pDevice->byBBPreEDRSSI <= 45) { //RSSI -44, -45
+ if(pDevice->byBBPreEDIndex == 17) break;
+ pDevice->byBBPreEDIndex = 17;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x18); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -44,-45\n");
+ } else if(pDevice->byBBPreEDRSSI <= 47) { //RSSI -46, -47
+ if(pDevice->byBBPreEDIndex == 16) break;
+ pDevice->byBBPreEDIndex = 16;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x11); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -46,-47\n");
+ } else if(pDevice->byBBPreEDRSSI <= 49) { //RSSI -48, -49
+ if(pDevice->byBBPreEDIndex == 15) break;
+ pDevice->byBBPreEDIndex = 15;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x0a); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -48,-49\n");
+ } else if(pDevice->byBBPreEDRSSI <= 51) { //RSSI -50, -51
+ if(pDevice->byBBPreEDIndex == 14) break;
+ pDevice->byBBPreEDIndex = 14;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x07); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -50,-51\n");
+ } else if(pDevice->byBBPreEDRSSI <= 53) { //RSSI -52, -53
+ if(pDevice->byBBPreEDIndex == 13) break;
+ pDevice->byBBPreEDIndex = 13;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x04); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -52,-53\n");
+ } else if(pDevice->byBBPreEDRSSI <= 55) { //RSSI -54, -55
+ if(pDevice->byBBPreEDIndex == 12) break;
+ pDevice->byBBPreEDIndex = 12;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x02); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0xC0); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -54,-55\n");
+ } else if(pDevice->byBBPreEDRSSI <= 56) { //RSSI -56
+ if(pDevice->byBBPreEDIndex == 11) break;
+ pDevice->byBBPreEDIndex = 11;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x02); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x30); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -56\n");
+ } else if(pDevice->byBBPreEDRSSI <= 57) { //RSSI -57
+ if(pDevice->byBBPreEDIndex == 10) break;
+ pDevice->byBBPreEDIndex = 10;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x01); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0xB0); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -57\n");
+ } else if(pDevice->byBBPreEDRSSI <= 58) { //RSSI -58
+ if(pDevice->byBBPreEDIndex == 9) break;
+ pDevice->byBBPreEDIndex = 9;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x01); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x70); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -58\n");
+ } else if(pDevice->byBBPreEDRSSI <= 59) { //RSSI -59
+ if(pDevice->byBBPreEDIndex == 8) break;
+ pDevice->byBBPreEDIndex = 8;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x01); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x30); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -59\n");
+ } else if(pDevice->byBBPreEDRSSI <= 60) { //RSSI -60
+ if(pDevice->byBBPreEDIndex == 7) break;
+ pDevice->byBBPreEDIndex = 7;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0xEA); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -60\n");
+ } else if(pDevice->byBBPreEDRSSI <= 61) { //RSSI -61
+ if(pDevice->byBBPreEDIndex == 6) break;
+ pDevice->byBBPreEDIndex = 6;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0xC0); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -61\n");
+ } else if(pDevice->byBBPreEDRSSI <= 62) { //RSSI -62
+ if(pDevice->byBBPreEDIndex == 5) break;
+ pDevice->byBBPreEDIndex = 5;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x9C); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -62\n");
+ } else if(pDevice->byBBPreEDRSSI <= 63) { //RSSI -63
+ if(pDevice->byBBPreEDIndex == 4) break;
+ pDevice->byBBPreEDIndex = 4;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x80); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -63\n");
+ } else if(pDevice->byBBPreEDRSSI <= 64) { //RSSI -64
+ if(pDevice->byBBPreEDIndex == 3) break;
+ pDevice->byBBPreEDIndex = 3;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x68); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -64\n");
+ } else if(pDevice->byBBPreEDRSSI <= 65) { //RSSI -65
+ if(pDevice->byBBPreEDIndex == 2) break;
+ pDevice->byBBPreEDIndex = 2;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x52); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -65\n");
+ } else if(pDevice->byBBPreEDRSSI <= 66) { //RSSI -66
+ if(pDevice->byBBPreEDIndex == 1) break;
+ pDevice->byBBPreEDIndex = 1;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x43); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -66\n");
+ } else { //RSSI -67, -68, ...
+ if(pDevice->byBBPreEDIndex == 0) break;
+ pDevice->byBBPreEDIndex = 0;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x38); //CR206(0xCE)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->byBBPreEDRSSI -67, -68,..\n");
+ }
+ break;
+
+ }
+
+}
+
diff --git a/drivers/staging/vt6656/baseband.h b/drivers/staging/vt6656/baseband.h
new file mode 100644
index 00000000..0a634ada
--- /dev/null
+++ b/drivers/staging/vt6656/baseband.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: baseband.h
+ *
+ * Purpose: Implement functions to access baseband
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Jun. 5, 2002
+ *
+ * Revision History:
+ * 06-10-2003 Bryan YC Fan: Re-write codes to support VT3253 spec.
+ * 08-26-2003 Kyle Hsu : Add defines of packet type and TX rate.
+ */
+
+#ifndef __BASEBAND_H__
+#define __BASEBAND_H__
+
+#include "tether.h"
+#include "device.h"
+
+#define PREAMBLE_LONG 0
+#define PREAMBLE_SHORT 1
+
+/*
+ * Registers in the BASEBAND
+ */
+#define BB_MAX_CONTEXT_SIZE 256
+
+#define C_SIFS_A 16 /* usec */
+#define C_SIFS_BG 10
+
+#define C_EIFS 80 /* usec */
+
+#define C_SLOT_SHORT 9 /* usec */
+#define C_SLOT_LONG 20
+
+#define C_CWMIN_A 15 /* slot time */
+#define C_CWMIN_B 31
+
+#define C_CWMAX 1023 /* slot time */
+
+/* 0:11A 1:11B 2:11G */
+#define BB_TYPE_11A 0
+#define BB_TYPE_11B 1
+#define BB_TYPE_11G 2
+
+/* 0:11a, 1:11b, 2:11gb (only CCK in BasicRate), 3:11ga (OFDM in BasicRate) */
+#define PK_TYPE_11A 0
+#define PK_TYPE_11B 1
+#define PK_TYPE_11GB 2
+#define PK_TYPE_11GA 3
+
+#define TOP_RATE_54M 0x80000000
+#define TOP_RATE_48M 0x40000000
+#define TOP_RATE_36M 0x20000000
+#define TOP_RATE_24M 0x10000000
+#define TOP_RATE_18M 0x08000000
+#define TOP_RATE_12M 0x04000000
+#define TOP_RATE_11M 0x02000000
+#define TOP_RATE_9M 0x01000000
+#define TOP_RATE_6M 0x00800000
+#define TOP_RATE_55M 0x00400000
+#define TOP_RATE_2M 0x00200000
+#define TOP_RATE_1M 0x00100000
+
+unsigned int
+BBuGetFrameTime(
+ u8 byPreambleType,
+ u8 byFreqType,
+ unsigned int cbFrameLength,
+ u16 wRate
+ );
+
+void BBvCalculateParameter(struct vnt_private *, u32 cbFrameLength,
+ u16 wRate, u8 byPacketType, u16 *pwPhyLen, u8 *pbyPhySrv,
+ u8 *pbyPhySgn);
+
+/* timer for antenna diversity */
+
+void TimerSQ3CallBack(struct vnt_private *);
+void TimerSQ3Tmax3CallBack(struct vnt_private *);
+
+void BBvAntennaDiversity(struct vnt_private *, u8 byRxRate, u8 bySQ3);
+
+void BBvSetShortSlotTime(struct vnt_private *);
+void BBvSetVGAGainOffset(struct vnt_private *, u8 byData);
+void BBvSetAntennaMode(struct vnt_private *, u8 byAntennaMode);
+int BBbVT3184Init(struct vnt_private *);
+void BBvSetDeepSleep(struct vnt_private *);
+void BBvExitDeepSleep(struct vnt_private *);
+void BBvUpdatePreEDThreshold(struct vnt_private *, int bScanning);
+
+#endif /* __BASEBAND_H__ */
diff --git a/drivers/staging/vt6656/bssdb.c b/drivers/staging/vt6656/bssdb.c
new file mode 100644
index 00000000..ee79bbdf
--- /dev/null
+++ b/drivers/staging/vt6656/bssdb.c
@@ -0,0 +1,1435 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: bssdb.c
+ *
+ * Purpose: Handles the Basic Service Set & Node Database functions
+ *
+ * Functions:
+ * BSSpSearchBSSList - Search known BSS list for Desire SSID or BSSID
+ * BSSvClearBSSList - Clear BSS List
+ * BSSbInsertToBSSList - Insert a BSS set into known BSS list
+ * BSSbUpdateToBSSList - Update BSS set in known BSS list
+ * BSSbIsSTAInNodeDB - Search Node DB table to find the index of matched DstAddr
+ * BSSvCreateOneNode - Allocate an Node for Node DB
+ * BSSvUpdateAPNode - Update AP Node content in Index 0 of KnownNodeDB
+ * BSSvSecondCallBack - One second timer callback function to update Node DB info & AP link status
+ * BSSvUpdateNodeTxCounter - Update Tx attemps, Tx failure counter in Node DB for auto-fall back rate control
+ *
+ * Revision History:
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: July 17, 2002
+ *
+ */
+
+#include "tmacro.h"
+#include "tether.h"
+#include "device.h"
+#include "80211hdr.h"
+#include "bssdb.h"
+#include "wmgr.h"
+#include "datarate.h"
+#include "desc.h"
+#include "wcmd.h"
+#include "wpa.h"
+#include "baseband.h"
+#include "rf.h"
+#include "card.h"
+#include "mac.h"
+#include "wpa2.h"
+#include "control.h"
+#include "rndis.h"
+#include "iowpa.h"
+
+static int msglevel =MSG_LEVEL_INFO;
+//static int msglevel =MSG_LEVEL_DEBUG;
+
+const u16 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 u16 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 void s_vCheckSensitivity(struct vnt_private *pDevice);
+static void s_vCheckPreEDThreshold(struct vnt_private *pDevice);
+static void s_uCalculateLinkQual(struct vnt_private *pDevice);
+
+/*+
+ *
+ * Routine Description:
+ * Search known BSS list for Desire SSID or BSSID.
+ *
+ * Return Value:
+ * PTR to KnownBSS or NULL
+ *
+-*/
+
+PKnownBSS BSSpSearchBSSList(struct vnt_private *pDevice,
+ u8 *pbyDesireBSSID, u8 *pbyDesireSSID,
+ CARD_PHY_TYPE ePhyType)
+{
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ u8 *pbyBSSID = NULL;
+ PWLAN_IE_SSID pSSID = NULL;
+ PKnownBSS pCurrBSS = NULL;
+ PKnownBSS pSelect = NULL;
+ u8 ZeroBSSID[WLAN_BSSID_LEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+ int ii = 0;
+ int jj = 0;
+
+ if (pbyDesireBSSID != NULL) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
+ "BSSpSearchBSSList BSSID[%pM]\n", pbyDesireBSSID);
+ if ((!is_broadcast_ether_addr(pbyDesireBSSID)) &&
+ (memcmp(pbyDesireBSSID, ZeroBSSID, 6)!= 0)){
+ pbyBSSID = pbyDesireBSSID;
+ }
+ }
+ if (pbyDesireSSID != NULL) {
+ if (((PWLAN_IE_SSID)pbyDesireSSID)->len != 0) {
+ pSSID = (PWLAN_IE_SSID) pbyDesireSSID;
+ }
+ }
+
+ if ((pbyBSSID != NULL)&&(pDevice->bRoaming == false)) {
+ // match BSSID first
+ for (ii = 0; ii <MAX_BSS_NUM; ii++) {
+ pCurrBSS = &(pMgmt->sBSSList[ii]);
+
+ pCurrBSS->bSelected = false;
+
+ if ((pCurrBSS->bActive) &&
+ (pCurrBSS->bSelected == false)) {
+ if (!compare_ether_addr(pCurrBSS->abyBSSID, pbyBSSID)) {
+ if (pSSID != NULL) {
+ // compare ssid
+ if ( !memcmp(pSSID->abySSID,
+ ((PWLAN_IE_SSID)pCurrBSS->abySSID)->abySSID,
+ pSSID->len)) {
+ if ((pMgmt->eConfigMode == WMAC_CONFIG_AUTO) ||
+ ((pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) && WLAN_GET_CAP_INFO_IBSS(pCurrBSS->wCapInfo)) ||
+ ((pMgmt->eConfigMode == WMAC_CONFIG_ESS_STA) && WLAN_GET_CAP_INFO_ESS(pCurrBSS->wCapInfo))
+ ) {
+ pCurrBSS->bSelected = true;
+ return(pCurrBSS);
+ }
+ }
+ } else {
+ if ((pMgmt->eConfigMode == WMAC_CONFIG_AUTO) ||
+ ((pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) && WLAN_GET_CAP_INFO_IBSS(pCurrBSS->wCapInfo)) ||
+ ((pMgmt->eConfigMode == WMAC_CONFIG_ESS_STA) && WLAN_GET_CAP_INFO_ESS(pCurrBSS->wCapInfo))
+ ) {
+ pCurrBSS->bSelected = true;
+ return(pCurrBSS);
+ }
+ }
+ }
+ }
+ }
+ } else {
+ // ignore BSSID
+ for (ii = 0; ii <MAX_BSS_NUM; ii++) {
+ pCurrBSS = &(pMgmt->sBSSList[ii]);
+
+ //2007-0721-01<Mark>by MikeLiu
+ // if ((pCurrBSS->bActive) &&
+ // (pCurrBSS->bSelected == false)) {
+
+ pCurrBSS->bSelected = false;
+ if (pCurrBSS->bActive) {
+
+ if (pSSID != NULL) {
+ // matched SSID
+ if (memcmp(pSSID->abySSID,
+ ((PWLAN_IE_SSID)pCurrBSS->abySSID)->abySSID,
+ pSSID->len) ||
+ (pSSID->len != ((PWLAN_IE_SSID)pCurrBSS->abySSID)->len)) {
+ // SSID not match skip this BSS
+ continue;
+ }
+ }
+ if (((pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) && WLAN_GET_CAP_INFO_ESS(pCurrBSS->wCapInfo)) ||
+ ((pMgmt->eConfigMode == WMAC_CONFIG_ESS_STA) && WLAN_GET_CAP_INFO_IBSS(pCurrBSS->wCapInfo))
+ ){
+ // Type not match skip this BSS
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BSS type mismatch.... Config[%d] BSS[0x%04x]\n", pMgmt->eConfigMode, pCurrBSS->wCapInfo);
+ continue;
+ }
+
+ if (ePhyType != PHY_TYPE_AUTO) {
+ if (((ePhyType == PHY_TYPE_11A) && (PHY_TYPE_11A != pCurrBSS->eNetworkTypeInUse)) ||
+ ((ePhyType != PHY_TYPE_11A) && (PHY_TYPE_11A == pCurrBSS->eNetworkTypeInUse))) {
+ // PhyType not match skip this BSS
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Physical type mismatch.... ePhyType[%d] BSS[%d]\n", ePhyType, pCurrBSS->eNetworkTypeInUse);
+ continue;
+ }
+ }
+
+ pMgmt->pSameBSS[jj].uChannel = pCurrBSS->uChannel;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
+ "BSSpSearchBSSList pSelect1[%pM]\n",
+ pCurrBSS->abyBSSID);
+ jj++;
+
+ if (pSelect == NULL) {
+ pSelect = pCurrBSS;
+ } else {
+ // compare RSSI, select the strongest signal
+ if (pCurrBSS->uRSSI < pSelect->uRSSI) {
+ pSelect = pCurrBSS;
+ }
+ }
+ }
+ }
+
+pDevice->bSameBSSMaxNum = jj;
+
+ if (pSelect != NULL) {
+ pSelect->bSelected = true;
+ if (pDevice->bRoaming == false) {
+ // Einsn Add @20070907
+ memcpy(pbyDesireSSID,pCurrBSS->abySSID,WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1) ;
+ }
+
+ return(pSelect);
+ }
+ }
+ return(NULL);
+
+}
+
+/*+
+ *
+ * Routine Description:
+ * Clear BSS List
+ *
+ * Return Value:
+ * None.
+ *
+-*/
+
+void BSSvClearBSSList(struct vnt_private *pDevice, int bKeepCurrBSSID)
+{
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ int ii;
+
+ for (ii = 0; ii < MAX_BSS_NUM; ii++) {
+ if (bKeepCurrBSSID) {
+ if (pMgmt->sBSSList[ii].bActive &&
+ !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID,
+ pMgmt->abyCurrBSSID)) {
+ //mike mark: there are two BSSID's in list. If that AP is in hidden ssid mode, one SSID is null,
+ // but other's might not be obvious, so if it associate's with your STA,
+ // you must keep the two of them!!
+ // bKeepCurrBSSID = false;
+ continue;
+ }
+ }
+
+ pMgmt->sBSSList[ii].bActive = false;
+ memset(&pMgmt->sBSSList[ii], 0, sizeof(KnownBSS));
+ }
+ BSSvClearAnyBSSJoinRecord(pDevice);
+}
+
+/*+
+ *
+ * Routine Description:
+ * search BSS list by BSSID & SSID if matched
+ *
+ * Return Value:
+ * true if found.
+ *
+-*/
+PKnownBSS BSSpAddrIsInBSSList(struct vnt_private *pDevice,
+ u8 *abyBSSID, PWLAN_IE_SSID pSSID)
+{
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ PKnownBSS pBSSList = NULL;
+ int ii;
+
+ for (ii = 0; ii < MAX_BSS_NUM; ii++) {
+ pBSSList = &(pMgmt->sBSSList[ii]);
+ if (pBSSList->bActive) {
+ if (!compare_ether_addr(pBSSList->abyBSSID, abyBSSID)) {
+ if (pSSID->len == ((PWLAN_IE_SSID)pBSSList->abySSID)->len){
+ if (memcmp(pSSID->abySSID,
+ ((PWLAN_IE_SSID)pBSSList->abySSID)->abySSID,
+ pSSID->len) == 0)
+ return pBSSList;
+ }
+ }
+ }
+ }
+
+ return NULL;
+};
+
+/*+
+ *
+ * Routine Description:
+ * Insert a BSS set into known BSS list
+ *
+ * Return Value:
+ * true if success.
+ *
+-*/
+
+int BSSbInsertToBSSList(struct vnt_private *pDevice,
+ u8 *abyBSSIDAddr,
+ u64 qwTimestamp,
+ u16 wBeaconInterval,
+ u16 wCapInfo,
+ u8 byCurrChannel,
+ PWLAN_IE_SSID pSSID,
+ PWLAN_IE_SUPP_RATES pSuppRates,
+ PWLAN_IE_SUPP_RATES pExtSuppRates,
+ PERPObject psERP,
+ PWLAN_IE_RSN pRSN,
+ PWLAN_IE_RSN_EXT pRSNWPA,
+ PWLAN_IE_COUNTRY pIE_Country,
+ PWLAN_IE_QUIET pIE_Quiet,
+ u32 uIELength,
+ u8 *pbyIEs,
+ void *pRxPacketContext)
+{
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ struct vnt_rx_mgmt *pRxPacket =
+ (struct vnt_rx_mgmt *)pRxPacketContext;
+ PKnownBSS pBSSList = NULL;
+ unsigned int ii;
+ bool bParsingQuiet = false;
+
+ pBSSList = (PKnownBSS)&(pMgmt->sBSSList[0]);
+
+ for (ii = 0; ii < MAX_BSS_NUM; ii++) {
+ pBSSList = (PKnownBSS)&(pMgmt->sBSSList[ii]);
+ if (!pBSSList->bActive)
+ break;
+ }
+
+ if (ii == MAX_BSS_NUM){
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Get free KnowBSS node failed.\n");
+ return false;
+ }
+ // save the BSS info
+ pBSSList->bActive = true;
+ memcpy( pBSSList->abyBSSID, abyBSSIDAddr, WLAN_BSSID_LEN);
+ pBSSList->qwBSSTimestamp = cpu_to_le64(qwTimestamp);
+ pBSSList->wBeaconInterval = cpu_to_le16(wBeaconInterval);
+ pBSSList->wCapInfo = cpu_to_le16(wCapInfo);
+ pBSSList->uClearCount = 0;
+
+ if (pSSID->len > WLAN_SSID_MAXLEN)
+ pSSID->len = WLAN_SSID_MAXLEN;
+ memcpy( pBSSList->abySSID, pSSID, pSSID->len + WLAN_IEHDR_LEN);
+
+ pBSSList->uChannel = byCurrChannel;
+
+ if (pSuppRates->len > WLAN_RATES_MAXLEN)
+ pSuppRates->len = WLAN_RATES_MAXLEN;
+ memcpy( pBSSList->abySuppRates, pSuppRates, pSuppRates->len + WLAN_IEHDR_LEN);
+
+ if (pExtSuppRates != NULL) {
+ if (pExtSuppRates->len > WLAN_RATES_MAXLEN)
+ pExtSuppRates->len = WLAN_RATES_MAXLEN;
+ memcpy(pBSSList->abyExtSuppRates, pExtSuppRates, pExtSuppRates->len + WLAN_IEHDR_LEN);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BSSbInsertToBSSList: pExtSuppRates->len = %d\n", pExtSuppRates->len);
+
+ } else {
+ memset(pBSSList->abyExtSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1);
+ }
+ pBSSList->sERP.byERP = psERP->byERP;
+ pBSSList->sERP.bERPExist = psERP->bERPExist;
+
+ // Check if BSS is 802.11a/b/g
+ if (pBSSList->uChannel > CB_MAX_CHANNEL_24G) {
+ pBSSList->eNetworkTypeInUse = PHY_TYPE_11A;
+ } else {
+ if (pBSSList->sERP.bERPExist == true) {
+ pBSSList->eNetworkTypeInUse = PHY_TYPE_11G;
+ } else {
+ pBSSList->eNetworkTypeInUse = PHY_TYPE_11B;
+ }
+ }
+
+ pBSSList->byRxRate = pRxPacket->byRxRate;
+ pBSSList->qwLocalTSF = pRxPacket->qwLocalTSF;
+ pBSSList->uRSSI = pRxPacket->uRSSI;
+ pBSSList->bySQ = pRxPacket->bySQ;
+
+ if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
+ (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
+ // assoc with BSS
+ if (pBSSList == pMgmt->pCurrBSS) {
+ bParsingQuiet = true;
+ }
+ }
+
+ WPA_ClearRSN(pBSSList);
+
+ if (pRSNWPA != NULL) {
+ unsigned int uLen = pRSNWPA->len + 2;
+
+ if (uLen <= (uIELength -
+ (unsigned int) (u32) ((u8 *) pRSNWPA - pbyIEs))) {
+ pBSSList->wWPALen = uLen;
+ memcpy(pBSSList->byWPAIE, pRSNWPA, uLen);
+ WPA_ParseRSN(pBSSList, pRSNWPA);
+ }
+ }
+
+ WPA2_ClearRSN(pBSSList);
+
+ if (pRSN != NULL) {
+ unsigned int uLen = pRSN->len + 2;
+
+ if (uLen <= (uIELength -
+ (unsigned int) (u32) ((u8 *) 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) &&
+ ( !memcmp(pSSID->abySSID, ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySSID, pSSID->len))) {
+
+ bAdd_PMKID_Candidate((void *) 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) {
+ // Monitor if RSSI is too strong.
+ pBSSList->byRSSIStatCnt = 0;
+ RFvRSSITodBm(pDevice, (u8)(pRxPacket->uRSSI), &pBSSList->ldBmMAX);
+ pBSSList->ldBmAverage[0] = pBSSList->ldBmMAX;
+ pBSSList->ldBmAverRange = pBSSList->ldBmMAX;
+ for (ii = 1; ii < RSSI_STAT_COUNT; ii++)
+ pBSSList->ldBmAverage[ii] = 0;
+ }
+
+ 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:
+ * Update BSS set in known BSS list
+ *
+ * Return Value:
+ * true if success.
+ *
+-*/
+// TODO: input structure modify
+
+int BSSbUpdateToBSSList(struct vnt_private *pDevice,
+ u64 qwTimestamp,
+ u16 wBeaconInterval,
+ u16 wCapInfo,
+ u8 byCurrChannel,
+ int bChannelHit,
+ PWLAN_IE_SSID pSSID,
+ PWLAN_IE_SUPP_RATES pSuppRates,
+ PWLAN_IE_SUPP_RATES pExtSuppRates,
+ PERPObject psERP,
+ PWLAN_IE_RSN pRSN,
+ PWLAN_IE_RSN_EXT pRSNWPA,
+ PWLAN_IE_COUNTRY pIE_Country,
+ PWLAN_IE_QUIET pIE_Quiet,
+ PKnownBSS pBSSList,
+ u32 uIELength,
+ u8 *pbyIEs,
+ void *pRxPacketContext)
+{
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ struct vnt_rx_mgmt *pRxPacket =
+ (struct vnt_rx_mgmt *)pRxPacketContext;
+ int ii, jj;
+ signed long ldBm, ldBmSum;
+ bool bParsingQuiet = false;
+
+ if (pBSSList == NULL)
+ return false;
+
+ pBSSList->qwBSSTimestamp = cpu_to_le64(qwTimestamp);
+
+ pBSSList->wBeaconInterval = cpu_to_le16(wBeaconInterval);
+ pBSSList->wCapInfo = cpu_to_le16(wCapInfo);
+ pBSSList->uClearCount = 0;
+ pBSSList->uChannel = byCurrChannel;
+
+ 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) {
+ unsigned int uLen = pRSNWPA->len + 2;
+ if (uLen <= (uIELength -
+ (unsigned int) (u32) ((u8 *) pRSNWPA - pbyIEs))) {
+ pBSSList->wWPALen = uLen;
+ memcpy(pBSSList->byWPAIE, pRSNWPA, uLen);
+ WPA_ParseRSN(pBSSList, pRSNWPA);
+ }
+ }
+
+ WPA2_ClearRSN(pBSSList); //mike update
+
+ if (pRSN != NULL) {
+ unsigned int uLen = pRSN->len + 2;
+ if (uLen <= (uIELength -
+ (unsigned int) (u32) ((u8 *) pRSN - pbyIEs))) {
+ pBSSList->wRSNLen = uLen;
+ memcpy(pBSSList->byRSNIE, pRSN, uLen);
+ WPA2vParseRSN(pBSSList, pRSN);
+ }
+ }
+
+ if (pRxPacket->uRSSI != 0) {
+ RFvRSSITodBm(pDevice, (u8)(pRxPacket->uRSSI), &ldBm);
+ // Monitor if RSSI is too strong.
+ pBSSList->byRSSIStatCnt++;
+ pBSSList->byRSSIStatCnt %= RSSI_STAT_COUNT;
+ pBSSList->ldBmAverage[pBSSList->byRSSIStatCnt] = ldBm;
+ ldBmSum = 0;
+ for (ii = 0, jj = 0; ii < RSSI_STAT_COUNT; ii++) {
+ if (pBSSList->ldBmAverage[ii] != 0) {
+ pBSSList->ldBmMAX =
+ max(pBSSList->ldBmAverage[ii], ldBm);
+ ldBmSum +=
+ pBSSList->ldBmAverage[ii];
+ jj++;
+ }
+ }
+ pBSSList->ldBmAverRange = ldBmSum /jj;
+ }
+
+ pBSSList->uIELength = uIELength;
+ if (pBSSList->uIELength > WLAN_BEACON_FR_MAXLEN)
+ pBSSList->uIELength = WLAN_BEACON_FR_MAXLEN;
+ memcpy(pBSSList->abyIEs, pbyIEs, pBSSList->uIELength);
+
+ return true;
+}
+
+/*+
+ *
+ * Routine Description:
+ * Search Node DB table to find the index of matched DstAddr
+ *
+ * Return Value:
+ * None
+ *
+-*/
+
+int BSSbIsSTAInNodeDB(struct vnt_private *pDevice,
+ u8 *abyDstAddr, u32 *puNodeIndex)
+{
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ unsigned int ii;
+
+ // Index = 0 reserved for AP Node
+ for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) {
+ if (pMgmt->sNodeDBTable[ii].bActive) {
+ if (!compare_ether_addr(abyDstAddr,
+ pMgmt->sNodeDBTable[ii].abyMACAddr)) {
+ *puNodeIndex = ii;
+ return true;
+ }
+ }
+ }
+
+ return false;
+};
+
+/*+
+ *
+ * Routine Description:
+ * Find an empty node and allocate it; if no empty node
+ * is found, then use the most inactive one.
+ *
+ * Return Value:
+ * None
+ *
+-*/
+void BSSvCreateOneNode(struct vnt_private *pDevice, u32 *puNodeIndex)
+{
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ int ii;
+ u32 BigestCount = 0;
+ u32 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 with the largest one.
+ if ( ii == (MAX_NODE_NUM + 1)) {
+ *puNodeIndex = SelectIndex;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Replace inactive node = %d\n", SelectIndex);
+ // clear ps buffer
+ if (pMgmt->sNodeDBTable[*puNodeIndex].sTxPSQueue.next != NULL) {
+ while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[*puNodeIndex].sTxPSQueue)) != NULL)
+ dev_kfree_skb(skb);
+ }
+ }
+ else {
+ *puNodeIndex = ii;
+ }
+
+ memset(&pMgmt->sNodeDBTable[*puNodeIndex], 0, sizeof(KnownNodeDB));
+ pMgmt->sNodeDBTable[*puNodeIndex].bActive = true;
+ pMgmt->sNodeDBTable[*puNodeIndex].uRatePollTimeout = FALLBACK_POLL_SECOND;
+ // for AP mode PS queue
+ skb_queue_head_init(&pMgmt->sNodeDBTable[*puNodeIndex].sTxPSQueue);
+ pMgmt->sNodeDBTable[*puNodeIndex].byAuthSequence = 0;
+ pMgmt->sNodeDBTable[*puNodeIndex].wEnQueueCnt = 0;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Create node index = %d\n", ii);
+};
+
+/*+
+ *
+ * Routine Description:
+ * Remove Node by NodeIndex
+ *
+ *
+ * Return Value:
+ * None
+ *
+-*/
+
+void BSSvRemoveOneNode(struct vnt_private *pDevice, u32 uNodeIndex)
+{
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ u8 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];
+};
+/*+
+ *
+ * Routine Description:
+ * Update AP Node content in Index 0 of KnownNodeDB
+ *
+ *
+ * Return Value:
+ * None
+ *
+-*/
+
+void BSSvUpdateAPNode(struct vnt_private *pDevice, u16 *pwCapInfo,
+ PWLAN_IE_SUPP_RATES pSuppRates, PWLAN_IE_SUPP_RATES pExtSuppRates)
+{
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ u32 uRateLen = WLAN_RATES_MAXLEN;
+
+ memset(&pMgmt->sNodeDBTable[0], 0, sizeof(KnownNodeDB));
+
+ pMgmt->sNodeDBTable[0].bActive = true;
+ if (pDevice->byBBType == BB_TYPE_11B) {
+ uRateLen = WLAN_RATES_MAXLEN_11B;
+ }
+ pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pSuppRates,
+ (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
+ uRateLen);
+ pMgmt->abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pExtSuppRates,
+ (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates,
+ uRateLen);
+ RATEvParseMaxRate((void *) pDevice,
+ (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
+ (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates,
+ true,
+ &(pMgmt->sNodeDBTable[0].wMaxBasicRate),
+ &(pMgmt->sNodeDBTable[0].wMaxSuppRate),
+ &(pMgmt->sNodeDBTable[0].wSuppRate),
+ &(pMgmt->sNodeDBTable[0].byTopCCKBasicRate),
+ &(pMgmt->sNodeDBTable[0].byTopOFDMBasicRate)
+ );
+ memcpy(pMgmt->sNodeDBTable[0].abyMACAddr, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN);
+ pMgmt->sNodeDBTable[0].wTxDataRate = pMgmt->sNodeDBTable[0].wMaxSuppRate;
+ pMgmt->sNodeDBTable[0].bShortPreamble = WLAN_GET_CAP_INFO_SHORTPREAMBLE(*pwCapInfo);
+ pMgmt->sNodeDBTable[0].uRatePollTimeout = FALLBACK_POLL_SECOND;
+ // Auto rate fallback function initiation.
+ // RATEbInit(pDevice);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pMgmt->sNodeDBTable[0].wTxDataRate = %d \n", pMgmt->sNodeDBTable[0].wTxDataRate);
+
+};
+
+/*+
+ *
+ * Routine Description:
+ * Add Multicast Node content in Index 0 of KnownNodeDB
+ *
+ *
+ * Return Value:
+ * None
+ *
+-*/
+
+void BSSvAddMulticastNode(struct vnt_private *pDevice)
+{
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+
+ 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((void *) pDevice,
+ (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
+ (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates,
+ true,
+ &(pMgmt->sNodeDBTable[0].wMaxBasicRate),
+ &(pMgmt->sNodeDBTable[0].wMaxSuppRate),
+ &(pMgmt->sNodeDBTable[0].wSuppRate),
+ &(pMgmt->sNodeDBTable[0].byTopCCKBasicRate),
+ &(pMgmt->sNodeDBTable[0].byTopOFDMBasicRate)
+ );
+ pMgmt->sNodeDBTable[0].wTxDataRate = pMgmt->sNodeDBTable[0].wMaxBasicRate;
+ pMgmt->sNodeDBTable[0].uRatePollTimeout = FALLBACK_POLL_SECOND;
+
+};
+
+/*+
+ *
+ * Routine Description:
+ *
+ *
+ * Second call back function to update Node DB info & AP link status
+ *
+ *
+ * Return Value:
+ * none.
+ *
+-*/
+
+void BSSvSecondCallBack(struct vnt_private *pDevice)
+{
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ int ii;
+ PWLAN_IE_SSID pItemSSID, pCurrSSID;
+ u32 uSleepySTACnt = 0;
+ u32 uNonShortSlotSTACnt = 0;
+ u32 uLongPreambleSTACnt = 0;
+
+ spin_lock_irq(&pDevice->lock);
+
+ pDevice->uAssocCount = 0;
+
+ //Power Saving Mode Tx Burst
+ if ( pDevice->bEnablePSMode == true ) {
+ pDevice->ulPSModeWaitTx++;
+ if ( pDevice->ulPSModeWaitTx >= 2 ) {
+ pDevice->ulPSModeWaitTx = 0;
+ pDevice->bPSModeTxBurst = false;
+ }
+ }
+
+ pDevice->byERPFlag &=
+ ~(WLAN_SET_ERP_BARKER_MODE(1) | WLAN_SET_ERP_NONERP_PRESENT(1));
+
+ if (pDevice->wUseProtectCntDown > 0) {
+ pDevice->wUseProtectCntDown --;
+ }
+ else {
+ // disable protect mode
+ pDevice->byERPFlag &= ~(WLAN_SET_ERP_USE_PROTECTION(1));
+ }
+
+if(pDevice->byReAssocCount > 0) {
+ pDevice->byReAssocCount++;
+ if((pDevice->byReAssocCount > 10) && (pDevice->bLinkPass != true)) { //10 sec timeout
+ printk("Re-association timeout!!!\n");
+ pDevice->byReAssocCount = 0;
+ // if(pDevice->bWPASuppWextEnabled == true)
+ {
+ union iwreq_data wrqu;
+ memset(&wrqu, 0, sizeof (wrqu));
+ wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+ PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n");
+ wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
+ }
+ }
+ else if(pDevice->bLinkPass == true)
+ pDevice->byReAssocCount = 0;
+}
+
+ pMgmt->eLastState = pMgmt->eCurrState ;
+
+ s_uCalculateLinkQual(pDevice);
+
+ for (ii = 0; ii < (MAX_NODE_NUM + 1); ii++) {
+
+ if (pMgmt->sNodeDBTable[ii].bActive) {
+ // Increase in-activity counter
+ pMgmt->sNodeDBTable[ii].uInActiveCount++;
+
+ if (ii > 0) {
+ if (pMgmt->sNodeDBTable[ii].uInActiveCount > MAX_INACTIVE_COUNT) {
+ BSSvRemoveOneNode(pDevice, ii);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
+ "Inactive timeout [%d] sec, STA index = [%d] remove\n", MAX_INACTIVE_COUNT, ii);
+ continue;
+ }
+
+ if (pMgmt->sNodeDBTable[ii].eNodeState >= NODE_ASSOC) {
+
+ pDevice->uAssocCount++;
+
+ // check if Non ERP exist
+ if (pMgmt->sNodeDBTable[ii].uInActiveCount < ERP_RECOVER_COUNT) {
+ if (!pMgmt->sNodeDBTable[ii].bShortPreamble) {
+ pDevice->byERPFlag |= WLAN_SET_ERP_BARKER_MODE(1);
+ uLongPreambleSTACnt ++;
+ }
+ if (!pMgmt->sNodeDBTable[ii].bERPExist) {
+ pDevice->byERPFlag |= WLAN_SET_ERP_NONERP_PRESENT(1);
+ pDevice->byERPFlag |= WLAN_SET_ERP_USE_PROTECTION(1);
+ }
+ if (!pMgmt->sNodeDBTable[ii].bShortSlotTime)
+ uNonShortSlotSTACnt++;
+ }
+ }
+
+ // check if any STA in PS mode
+ if (pMgmt->sNodeDBTable[ii].bPSEnable)
+ uSleepySTACnt++;
+
+ }
+
+ // Rate fallback check
+ if (!pDevice->bFixRate) {
+ if (ii > 0) {
+ // ii = 0 for multicast node (AP & Adhoc)
+ RATEvTxRateFallBack((void *)pDevice,
+ &(pMgmt->sNodeDBTable[ii]));
+ }
+ else {
+ // ii = 0 reserved for unicast AP node (Infra STA)
+ if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA)
+ RATEvTxRateFallBack((void *)pDevice,
+ &(pMgmt->sNodeDBTable[ii]));
+ }
+
+ }
+
+ // check if pending PS queue
+ if (pMgmt->sNodeDBTable[ii].wEnQueueCnt != 0) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index= %d, Queue = %d pending \n",
+ ii, pMgmt->sNodeDBTable[ii].wEnQueueCnt);
+ if ((ii >0) && (pMgmt->sNodeDBTable[ii].wEnQueueCnt > 15)) {
+ BSSvRemoveOneNode(pDevice, ii);
+ DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Pending many queues PS STA Index = %d remove \n", ii);
+ continue;
+ }
+ }
+ }
+
+ }
+
+ if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && (pDevice->byBBType == BB_TYPE_11G)) {
+
+ // on/off protect mode
+ if (WLAN_GET_ERP_USE_PROTECTION(pDevice->byERPFlag)) {
+ if (!pDevice->bProtectMode) {
+ MACvEnableProtectMD(pDevice);
+ pDevice->bProtectMode = true;
+ }
+ }
+ else {
+ if (pDevice->bProtectMode) {
+ MACvDisableProtectMD(pDevice);
+ pDevice->bProtectMode = false;
+ }
+ }
+ // on/off short slot time
+
+ if (uNonShortSlotSTACnt > 0) {
+ if (pDevice->bShortSlotTime) {
+ pDevice->bShortSlotTime = false;
+ BBvSetShortSlotTime(pDevice);
+ vUpdateIFS((void *)pDevice);
+ }
+ }
+ else {
+ if (!pDevice->bShortSlotTime) {
+ pDevice->bShortSlotTime = true;
+ BBvSetShortSlotTime(pDevice);
+ vUpdateIFS((void *)pDevice);
+ }
+ }
+
+ // on/off barker long preamble mode
+
+ if (uLongPreambleSTACnt > 0) {
+ if (!pDevice->bBarkerPreambleMd) {
+ MACvEnableBarkerPreambleMd(pDevice);
+ pDevice->bBarkerPreambleMd = true;
+ }
+ }
+ else {
+ if (pDevice->bBarkerPreambleMd) {
+ MACvDisableBarkerPreambleMd(pDevice);
+ pDevice->bBarkerPreambleMd = false;
+ }
+ }
+
+ }
+
+ // Check if any STA in PS mode, enable DTIM multicast deliver
+ if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
+ if (uSleepySTACnt > 0)
+ pMgmt->sNodeDBTable[0].bPSEnable = true;
+ else
+ pMgmt->sNodeDBTable[0].bPSEnable = false;
+ }
+
+ pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
+ pCurrSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
+
+ if ((pMgmt->eCurrMode == WMAC_MODE_STANDBY) ||
+ (pMgmt->eCurrMode == WMAC_MODE_ESS_STA)) {
+
+ if (pMgmt->sNodeDBTable[0].bActive) { // Assoc with BSS
+
+ if (pDevice->bUpdateBBVGA) {
+ s_vCheckSensitivity(pDevice);
+ s_vCheckPreEDThreshold(pDevice);
+ }
+
+ if ((pMgmt->sNodeDBTable[0].uInActiveCount >= (LOST_BEACON_COUNT/2)) &&
+ (pDevice->byBBVGACurrent != pDevice->abyBBVGA[0]) ) {
+ pDevice->byBBVGANew = pDevice->abyBBVGA[0];
+ bScheduleCommand((void *) pDevice,
+ WLAN_CMD_CHANGE_BBSENSITIVITY,
+ NULL);
+ }
+
+ if (pMgmt->sNodeDBTable[0].uInActiveCount >= LOST_BEACON_COUNT) {
+ pMgmt->sNodeDBTable[0].bActive = false;
+ pMgmt->eCurrMode = WMAC_MODE_STANDBY;
+ pMgmt->eCurrState = WMAC_STATE_IDLE;
+ netif_stop_queue(pDevice->dev);
+ pDevice->bLinkPass = false;
+ ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW);
+ pDevice->bRoaming = true;
+ pDevice->bIsRoaming = false;
+
+ DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Lost AP beacon [%d] sec, disconnected !\n", pMgmt->sNodeDBTable[0].uInActiveCount);
+ /* let wpa supplicant know AP may disconnect */
+ {
+ union iwreq_data wrqu;
+ memset(&wrqu, 0, sizeof (wrqu));
+ wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+ PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n");
+ wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
+ }
+ }
+ }
+ else if (pItemSSID->len != 0) {
+//Davidwang
+ if ((pDevice->bEnableRoaming == true)&&(!(pMgmt->Cisco_cckm))) {
+DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "bRoaming %d, !\n", pDevice->bRoaming );
+DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "bIsRoaming %d, !\n", pDevice->bIsRoaming );
+ if ((pDevice->bRoaming == true)&&(pDevice->bIsRoaming == true)){
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Fast Roaming ...\n");
+ BSSvClearBSSList((void *) pDevice, pDevice->bLinkPass);
+ bScheduleCommand((void *) pDevice,
+ WLAN_CMD_BSSID_SCAN,
+ pMgmt->abyDesireSSID);
+ bScheduleCommand((void *) pDevice,
+ WLAN_CMD_SSID,
+ pMgmt->abyDesireSSID);
+ pDevice->uAutoReConnectTime = 0;
+ pDevice->uIsroamingTime = 0;
+ pDevice->bRoaming = false;
+ }
+ else if ((pDevice->bRoaming == false)&&(pDevice->bIsRoaming == true)) {
+ pDevice->uIsroamingTime++;
+ if (pDevice->uIsroamingTime >= 20)
+ pDevice->bIsRoaming = false;
+ }
+
+ }
+else {
+ if (pDevice->uAutoReConnectTime < 10) {
+ pDevice->uAutoReConnectTime++;
+ //network manager support need not do Roaming scan???
+ if(pDevice->bWPASuppWextEnabled ==true)
+ pDevice->uAutoReConnectTime = 0;
+ }
+ else {
+ //mike use old encryption status for wpa reauthen
+ if(pDevice->bWPADEVUp)
+ pDevice->eEncryptionStatus = pDevice->eOldEncryptionStatus;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Roaming ...\n");
+ BSSvClearBSSList((void *) pDevice, pDevice->bLinkPass);
+ pMgmt->eScanType = WMAC_SCAN_ACTIVE;
+ bScheduleCommand((void *) pDevice,
+ WLAN_CMD_BSSID_SCAN,
+ pMgmt->abyDesireSSID);
+ bScheduleCommand((void *) pDevice,
+ WLAN_CMD_SSID,
+ pMgmt->abyDesireSSID);
+ pDevice->uAutoReConnectTime = 0;
+ }
+ }
+ }
+ }
+
+ if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
+ // if adhoc started which essid is NULL string, rescanning.
+ if ((pMgmt->eCurrState == WMAC_STATE_STARTED) && (pCurrSSID->len == 0)) {
+ if (pDevice->uAutoReConnectTime < 10) {
+ pDevice->uAutoReConnectTime++;
+ }
+ else {
+ DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Adhoc re-scanning ...\n");
+ pMgmt->eScanType = WMAC_SCAN_ACTIVE;
+ bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, NULL);
+ bScheduleCommand((void *) pDevice, WLAN_CMD_SSID, NULL);
+ pDevice->uAutoReConnectTime = 0;
+ };
+ }
+ if (pMgmt->eCurrState == WMAC_STATE_JOINTED) {
+
+ if (pDevice->bUpdateBBVGA) {
+ s_vCheckSensitivity(pDevice);
+ s_vCheckPreEDThreshold(pDevice);
+ }
+ if (pMgmt->sNodeDBTable[0].uInActiveCount >=ADHOC_LOST_BEACON_COUNT) {
+ DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Lost other STA beacon [%d] sec, started !\n", pMgmt->sNodeDBTable[0].uInActiveCount);
+ pMgmt->sNodeDBTable[0].uInActiveCount = 0;
+ pMgmt->eCurrState = WMAC_STATE_STARTED;
+ netif_stop_queue(pDevice->dev);
+ pDevice->bLinkPass = false;
+ ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW);
+ }
+ }
+ }
+
+ if (pDevice->bLinkPass == true) {
+ if (netif_queue_stopped(pDevice->dev))
+ netif_wake_queue(pDevice->dev);
+ }
+
+ spin_unlock_irq(&pDevice->lock);
+
+ pMgmt->sTimerSecondCallback.expires = RUN_AT(HZ);
+ add_timer(&pMgmt->sTimerSecondCallback);
+}
+
+/*+
+ *
+ * Routine Description:
+ *
+ *
+ * Update Tx attemps, Tx failure counter in Node DB
+ *
+ *
+ * Return Value:
+ * none.
+ *
+-*/
+
+void BSSvUpdateNodeTxCounter(struct vnt_private *pDevice,
+ PSStatCounter pStatistic, u8 byTSR, u8 byPktNO)
+{
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ u32 uNodeIndex = 0;
+ u8 byTxRetry;
+ u16 wRate;
+ u16 wFallBackRate = RATE_1M;
+ u8 byFallBack;
+ int ii;
+ u8 *pbyDestAddr;
+ u8 byPktNum;
+ u16 wFIFOCtl;
+
+ byPktNum = (byPktNO & 0x0F) >> 4;
+ byTxRetry = (byTSR & 0xF0) >> 4;
+ wRate = (u16) (byPktNO & 0xF0) >> 4;
+ wFIFOCtl = pStatistic->abyTxPktInfo[byPktNum].wFIFOCtl;
+ pbyDestAddr = (u8 *) &( pStatistic->abyTxPktInfo[byPktNum].abyDestAddr[0]);
+
+ if (wFIFOCtl & FIFOCTL_AUTO_FB_0) {
+ byFallBack = AUTO_FB_0;
+ } else if (wFIFOCtl & FIFOCTL_AUTO_FB_1) {
+ byFallBack = AUTO_FB_1;
+ } else {
+ byFallBack = AUTO_FB_NONE;
+ }
+
+ // Only Unicast using support rates
+ if (wFIFOCtl & FIFOCTL_NEEDACK) {
+ if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) {
+ pMgmt->sNodeDBTable[0].uTxAttempts += 1;
+ if ( !(byTSR & (TSR_TMO | TSR_RETRYTMO))) {
+ // transmit success, TxAttempts at least plus one
+ pMgmt->sNodeDBTable[0].uTxOk[MAX_RATE]++;
+ if ( (byFallBack == AUTO_FB_NONE) ||
+ (wRate < RATE_18M) ) {
+ wFallBackRate = wRate;
+ } else if (byFallBack == AUTO_FB_0) {
+ if (byTxRetry < 5)
+ wFallBackRate = awHWRetry0[wRate-RATE_18M][byTxRetry];
+ else
+ wFallBackRate = awHWRetry0[wRate-RATE_18M][4];
+ } else if (byFallBack == AUTO_FB_1) {
+ if (byTxRetry < 5)
+ wFallBackRate = awHWRetry1[wRate-RATE_18M][byTxRetry];
+ else
+ wFallBackRate = awHWRetry1[wRate-RATE_18M][4];
+ }
+ pMgmt->sNodeDBTable[0].uTxOk[wFallBackRate]++;
+ } else {
+ pMgmt->sNodeDBTable[0].uTxFailures ++;
+ }
+ pMgmt->sNodeDBTable[0].uTxRetry += byTxRetry;
+ if (byTxRetry != 0) {
+ pMgmt->sNodeDBTable[0].uTxFail[MAX_RATE]+=byTxRetry;
+ if ( (byFallBack == AUTO_FB_NONE) ||
+ (wRate < RATE_18M) ) {
+ pMgmt->sNodeDBTable[0].uTxFail[wRate]+=byTxRetry;
+ } else if (byFallBack == AUTO_FB_0) {
+ for (ii = 0; ii < byTxRetry; ii++) {
+ if (ii < 5)
+ wFallBackRate =
+ awHWRetry0[wRate-RATE_18M][ii];
+ else
+ wFallBackRate =
+ awHWRetry0[wRate-RATE_18M][4];
+ pMgmt->sNodeDBTable[0].uTxFail[wFallBackRate]++;
+ }
+ } else if (byFallBack == AUTO_FB_1) {
+ for (ii = 0; ii < byTxRetry; ii++) {
+ if (ii < 5)
+ wFallBackRate =
+ awHWRetry1[wRate-RATE_18M][ii];
+ else
+ wFallBackRate =
+ awHWRetry1[wRate-RATE_18M][4];
+ pMgmt->sNodeDBTable[0].uTxFail[wFallBackRate]++;
+ }
+ }
+ }
+ }
+
+ if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) ||
+ (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)) {
+
+ if (BSSbIsSTAInNodeDB((void *) pDevice,
+ pbyDestAddr,
+ &uNodeIndex)) {
+ pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts += 1;
+ if ( !(byTSR & (TSR_TMO | TSR_RETRYTMO))) {
+ // transmit success, TxAttempts at least plus one
+ pMgmt->sNodeDBTable[uNodeIndex].uTxOk[MAX_RATE]++;
+ if ( (byFallBack == AUTO_FB_NONE) ||
+ (wRate < RATE_18M) ) {
+ wFallBackRate = wRate;
+ } else if (byFallBack == AUTO_FB_0) {
+ if (byTxRetry < 5)
+ wFallBackRate = awHWRetry0[wRate-RATE_18M][byTxRetry];
+ else
+ wFallBackRate = awHWRetry0[wRate-RATE_18M][4];
+ } else if (byFallBack == AUTO_FB_1) {
+ if (byTxRetry < 5)
+ wFallBackRate = awHWRetry1[wRate-RATE_18M][byTxRetry];
+ else
+ wFallBackRate = awHWRetry1[wRate-RATE_18M][4];
+ }
+ pMgmt->sNodeDBTable[uNodeIndex].uTxOk[wFallBackRate]++;
+ } else {
+ pMgmt->sNodeDBTable[uNodeIndex].uTxFailures ++;
+ }
+ pMgmt->sNodeDBTable[uNodeIndex].uTxRetry += byTxRetry;
+ if (byTxRetry != 0) {
+ pMgmt->sNodeDBTable[uNodeIndex].uTxFail[MAX_RATE]+=byTxRetry;
+ if ( (byFallBack == AUTO_FB_NONE) ||
+ (wRate < RATE_18M) ) {
+ pMgmt->sNodeDBTable[uNodeIndex].uTxFail[wRate]+=byTxRetry;
+ } else if (byFallBack == AUTO_FB_0) {
+ for (ii = 0; ii < byTxRetry; ii++) {
+ if (ii < 5)
+ wFallBackRate =
+ awHWRetry0[wRate-RATE_18M][ii];
+ else
+ wFallBackRate =
+ awHWRetry0[wRate-RATE_18M][4];
+ pMgmt->sNodeDBTable[uNodeIndex].uTxFail[wFallBackRate]++;
+ }
+ } else if (byFallBack == AUTO_FB_1) {
+ for (ii = 0; ii < byTxRetry; ii++) {
+ if (ii < 5)
+ wFallBackRate = awHWRetry1[wRate-RATE_18M][ii];
+ else
+ wFallBackRate = awHWRetry1[wRate-RATE_18M][4];
+ pMgmt->sNodeDBTable[uNodeIndex].uTxFail[wFallBackRate]++;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+/*+
+ *
+ * Routine Description:
+ * Clear Nodes & skb in DB Table
+ *
+ *
+ * Parameters:
+ * In:
+ * hDeviceContext - The adapter context.
+ * uStartIndex - starting index
+ * Out:
+ * none
+ *
+ * Return Value:
+ * None.
+ *
+-*/
+
+void BSSvClearNodeDBTable(struct vnt_private *pDevice, u32 uStartIndex)
+{
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ struct sk_buff *skb;
+ int ii;
+
+ for (ii = uStartIndex; ii < (MAX_NODE_NUM + 1); ii++) {
+ if (pMgmt->sNodeDBTable[ii].bActive) {
+ // check if sTxPSQueue has been initial
+ if (pMgmt->sNodeDBTable[ii].sTxPSQueue.next != NULL) {
+ while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) != NULL){
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "PS skb != NULL %d\n", ii);
+ dev_kfree_skb(skb);
+ }
+ }
+ memset(&pMgmt->sNodeDBTable[ii], 0, sizeof(KnownNodeDB));
+ }
+ }
+};
+
+static void s_vCheckSensitivity(struct vnt_private *pDevice)
+{
+ PKnownBSS pBSSList = NULL;
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ int ii;
+
+ if ((pMgmt->eCurrState == WMAC_STATE_ASSOC) ||
+ ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED))) {
+ pBSSList = BSSpAddrIsInBSSList(pDevice, pMgmt->abyCurrBSSID, (PWLAN_IE_SSID)pMgmt->abyCurrSSID);
+ if (pBSSList != NULL) {
+ /* Update BB register if RSSI is too strong */
+ signed long LocalldBmAverage = 0;
+ signed long uNumofdBm = 0;
+ for (ii = 0; ii < RSSI_STAT_COUNT; ii++) {
+ if (pBSSList->ldBmAverage[ii] != 0) {
+ uNumofdBm ++;
+ LocalldBmAverage += pBSSList->ldBmAverage[ii];
+ }
+ }
+ if (uNumofdBm > 0) {
+ LocalldBmAverage = LocalldBmAverage/uNumofdBm;
+ for (ii=0;ii<BB_VGA_LEVEL;ii++) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"LocalldBmAverage:%ld, %ld %02x\n", LocalldBmAverage, pDevice->ldBmThreshold[ii], pDevice->abyBBVGA[ii]);
+ if (LocalldBmAverage < pDevice->ldBmThreshold[ii]) {
+ pDevice->byBBVGANew = pDevice->abyBBVGA[ii];
+ break;
+ }
+ }
+ if (pDevice->byBBVGANew != pDevice->byBBVGACurrent) {
+ pDevice->uBBVGADiffCount++;
+ if (pDevice->uBBVGADiffCount >= BB_VGA_CHANGE_THRESHOLD)
+ bScheduleCommand(pDevice,
+ WLAN_CMD_CHANGE_BBSENSITIVITY,
+ NULL);
+ } else {
+ pDevice->uBBVGADiffCount = 0;
+ }
+ }
+ }
+ }
+}
+
+static void s_uCalculateLinkQual(struct vnt_private *pDevice)
+{
+ unsigned long TxOkRatio, TxCnt;
+ unsigned long RxOkRatio, RxCnt;
+ unsigned long 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)
+{
+ pDevice->scStatistic.LinkQuality = 0;
+ pDevice->scStatistic.SignalStren = 0;
+}
+else
+{
+ RFvRSSITodBm(pDevice, (u8)(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;
+}
+
+void BSSvClearAnyBSSJoinRecord(struct vnt_private *pDevice)
+{
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ int ii;
+
+ for (ii = 0; ii < MAX_BSS_NUM; ii++)
+ pMgmt->sBSSList[ii].bSelected = false;
+
+ return;
+}
+
+static void s_vCheckPreEDThreshold(struct vnt_private *pDevice)
+{
+ PKnownBSS pBSSList = NULL;
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+
+ 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 = (u8) (~(pBSSList->ldBmAverRange) + 1);
+ BBvUpdatePreEDThreshold(pDevice, false);
+ }
+ }
+}
+
diff --git a/drivers/staging/vt6656/bssdb.h b/drivers/staging/vt6656/bssdb.h
new file mode 100644
index 00000000..bce3b465
--- /dev/null
+++ b/drivers/staging/vt6656/bssdb.h
@@ -0,0 +1,278 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: bssdb.h
+ *
+ * Purpose: Handles the Basic Service Set & Node Database functions
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: July 16, 2002
+ *
+ */
+
+#ifndef __BSSDB_H__
+#define __BSSDB_H__
+
+#include <linux/skbuff.h>
+#include "80211hdr.h"
+#include "80211mgr.h"
+#include "card.h"
+#include "mib.h"
+
+#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_WPA_IE_LEN 64
+
+//
+// IEEE 802.11 Structures and definitions
+//
+
+typedef struct tagSERPObject {
+ bool bERPExist;
+ u8 byERP;
+} ERPObject, *PERPObject;
+
+typedef struct tagSRSNCapObject {
+ bool bRSNCapExist;
+ u16 wRSNCap;
+} SRSNCapObject, *PSRSNCapObject;
+
+// BSS info(AP)
+typedef struct tagKnownBSS {
+ // BSS info
+ bool bActive;
+ u8 abyBSSID[WLAN_BSSID_LEN];
+ unsigned int uChannel;
+ u8 abySuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
+ u8 abyExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
+ unsigned int uRSSI;
+ u8 bySQ;
+ u16 wBeaconInterval;
+ u16 wCapInfo;
+ u8 abySSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
+ u8 byRxRate;
+
+// u16 wATIMWindow;
+ u8 byRSSIStatCnt;
+ signed long ldBmMAX;
+ signed long ldBmAverage[RSSI_STAT_COUNT];
+ signed long ldBmAverRange;
+ //For any BSSID selection improvment
+ bool bSelected;
+
+ //++ WPA informations
+ bool bWPAValid;
+ u8 byGKType;
+ u8 abyPKType[4];
+ u16 wPKCount;
+ u8 abyAuthType[4];
+ u16 wAuthCount;
+ u8 byDefaultK_as_PK;
+ u8 byReplayIdx;
+ //--
+
+ //++ WPA2 informations
+ bool bWPA2Valid;
+ u8 byCSSGK;
+ u16 wCSSPKCount;
+ u8 abyCSSPK[4];
+ u16 wAKMSSAuthCount;
+ u8 abyAKMSSAuthType[4];
+
+ //++ wpactl
+ u8 byWPAIE[MAX_WPA_IE_LEN];
+ u8 byRSNIE[MAX_WPA_IE_LEN];
+ u16 wWPALen;
+ u16 wRSNLen;
+
+ // Clear count
+ unsigned int uClearCount;
+// u8 abyIEs[WLAN_BEACON_FR_MAXLEN];
+ unsigned int uIELength;
+ u64 qwBSSTimestamp;
+ u64 qwLocalTSF;/* local TSF timer */
+
+ CARD_PHY_TYPE eNetworkTypeInUse;
+
+ ERPObject sERP;
+ SRSNCapObject sRSNCapObj;
+ u8 abyIEs[1024]; // don't move this field !!
+
+} __attribute__ ((__packed__))
+KnownBSS , *PKnownBSS;
+
+typedef enum tagNODE_STATE {
+ NODE_FREE,
+ NODE_AGED,
+ NODE_KNOWN,
+ NODE_AUTH,
+ NODE_ASSOC
+} NODE_STATE, *PNODE_STATE;
+
+// STA node info
+typedef struct tagKnownNodeDB {
+ // STA info
+ bool bActive;
+ u8 abyMACAddr[WLAN_ADDR_LEN];
+ u8 abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN];
+ u8 abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN];
+ u16 wTxDataRate;
+ bool bShortPreamble;
+ bool bERPExist;
+ bool bShortSlotTime;
+ unsigned int uInActiveCount;
+ u16 wMaxBasicRate; //Get from byTopOFDMBasicRate or byTopCCKBasicRate which depends on packetTyp.
+ u16 wMaxSuppRate; //Records the highest supported rate getting from SuppRates IE and ExtSuppRates IE in Beacon.
+ u16 wSuppRate;
+ u8 byTopOFDMBasicRate;//Records the highest basic rate in OFDM mode
+ u8 byTopCCKBasicRate; //Records the highest basic rate in CCK mode
+
+ // For AP mode
+ struct sk_buff_head sTxPSQueue;
+ u16 wCapInfo;
+ u16 wListenInterval;
+ u16 wAID;
+ NODE_STATE eNodeState;
+ bool bPSEnable;
+ bool bRxPSPoll;
+ u8 byAuthSequence;
+ unsigned long ulLastRxJiffer;
+ u8 bySuppRate;
+ u32 dwFlags;
+ u16 wEnQueueCnt;
+
+ bool bOnFly;
+ unsigned long long KeyRSC;
+ u8 byKeyIndex;
+ u32 dwKeyIndex;
+ u8 byCipherSuite;
+ u32 dwTSC47_16;
+ u16 wTSC15_0;
+ unsigned int uWepKeyLength;
+ u8 abyWepKey[WLAN_WEPMAX_KEYLEN];
+ //
+ // Auto rate fallback vars
+ bool bIsInFallback;
+ unsigned int uAverageRSSI;
+ unsigned int uRateRecoveryTimeout;
+ unsigned int uRatePollTimeout;
+ unsigned int uTxFailures;
+ unsigned int uTxAttempts;
+
+ unsigned int uTxRetry;
+ unsigned int uFailureRatio;
+ unsigned int uRetryRatio;
+ unsigned int uTxOk[MAX_RATE+1];
+ unsigned int uTxFail[MAX_RATE+1];
+ unsigned int uTimeCount;
+
+} KnownNodeDB, *PKnownNodeDB;
+
+PKnownBSS BSSpSearchBSSList(struct vnt_private *, u8 *pbyDesireBSSID,
+ u8 *pbyDesireSSID, CARD_PHY_TYPE ePhyType);
+
+PKnownBSS BSSpAddrIsInBSSList(struct vnt_private *, u8 *abyBSSID,
+ PWLAN_IE_SSID pSSID);
+
+void BSSvClearBSSList(struct vnt_private *, int bKeepCurrBSSID);
+
+int BSSbInsertToBSSList(struct vnt_private *,
+ u8 *abyBSSIDAddr,
+ u64 qwTimestamp,
+ u16 wBeaconInterval,
+ u16 wCapInfo,
+ u8 byCurrChannel,
+ PWLAN_IE_SSID pSSID,
+ PWLAN_IE_SUPP_RATES pSuppRates,
+ PWLAN_IE_SUPP_RATES pExtSuppRates,
+ PERPObject psERP,
+ PWLAN_IE_RSN pRSN,
+ PWLAN_IE_RSN_EXT pRSNWPA,
+ PWLAN_IE_COUNTRY pIE_Country,
+ PWLAN_IE_QUIET pIE_Quiet,
+ u32 uIELength,
+ u8 *pbyIEs,
+ void *pRxPacketContext);
+
+int BSSbUpdateToBSSList(struct vnt_private *,
+ u64 qwTimestamp,
+ u16 wBeaconInterval,
+ u16 wCapInfo,
+ u8 byCurrChannel,
+ int bChannelHit,
+ PWLAN_IE_SSID pSSID,
+ PWLAN_IE_SUPP_RATES pSuppRates,
+ PWLAN_IE_SUPP_RATES pExtSuppRates,
+ PERPObject psERP,
+ PWLAN_IE_RSN pRSN,
+ PWLAN_IE_RSN_EXT pRSNWPA,
+ PWLAN_IE_COUNTRY pIE_Country,
+ PWLAN_IE_QUIET pIE_Quiet,
+ PKnownBSS pBSSList,
+ u32 uIELength,
+ u8 *pbyIEs,
+ void *pRxPacketContext);
+
+int BSSbIsSTAInNodeDB(struct vnt_private *, u8 * abyDstAddr,
+ u32 *puNodeIndex);
+
+void BSSvCreateOneNode(struct vnt_private *, u32 *puNodeIndex);
+
+void BSSvUpdateAPNode(struct vnt_private *, u16 *pwCapInfo,
+ PWLAN_IE_SUPP_RATES pItemRates, PWLAN_IE_SUPP_RATES pExtSuppRates);
+
+void BSSvSecondCallBack(struct vnt_private *);
+
+void BSSvUpdateNodeTxCounter(struct vnt_private *, PSStatCounter pStatistic,
+ u8 byTSR, u8 byPktNO);
+
+void BSSvRemoveOneNode(struct vnt_private *, u32 uNodeIndex);
+
+void BSSvAddMulticastNode(struct vnt_private *);
+
+void BSSvClearNodeDBTable(struct vnt_private *, u32 uStartIndex);
+
+void BSSvClearAnyBSSJoinRecord(struct vnt_private *);
+
+#endif /* __BSSDB_H__ */
diff --git a/drivers/staging/vt6656/card.c b/drivers/staging/vt6656/card.c
new file mode 100644
index 00000000..0beb246a
--- /dev/null
+++ b/drivers/staging/vt6656/card.c
@@ -0,0 +1,996 @@
+/*
+ * 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 - Calculate TSFOffset
+ * CARDbGetCurrentTSF - Read Current NIC TSF counter
+ * CARDqGetNextTBTT - Calculate 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 definition type of dwIoBase.
+ * 09-01-2003 Bryan YC Fan: Add vUpdateIFS().
+ *
+ */
+
+#include "device.h"
+#include "tmacro.h"
+#include "card.h"
+#include "baseband.h"
+#include "mac.h"
+#include "desc.h"
+#include "rf.h"
+#include "power.h"
+#include "key.h"
+#include "rc4.h"
+#include "country.h"
+#include "datarate.h"
+#include "rndis.h"
+#include "control.h"
+
+//static int msglevel =MSG_LEVEL_DEBUG;
+static int msglevel =MSG_LEVEL_INFO;
+
+//const u16 cwRXBCNTSFOff[MAX_RATE] =
+//{17, 34, 96, 192, 34, 23, 17, 11, 8, 5, 4, 3};
+
+const u16 cwRXBCNTSFOff[MAX_RATE] =
+{192, 96, 34, 17, 34, 23, 17, 11, 8, 5, 4, 3};
+
+/*
+ * Description: Set NIC media channel
+ *
+ * Parameters:
+ * In:
+ * pDevice - The adapter to be set
+ * uConnectionChannel - Channel to be set
+ * Out:
+ * none
+ */
+void CARDbSetMediaChannel(struct vnt_private *pDevice, u32 uConnectionChannel)
+{
+
+ if (pDevice->byBBType == BB_TYPE_11A) { // 15 ~ 38
+ if ((uConnectionChannel < (CB_MAX_CHANNEL_24G+1)) || (uConnectionChannel > CB_MAX_CHANNEL))
+ uConnectionChannel = (CB_MAX_CHANNEL_24G+1);
+ } else {
+ if ((uConnectionChannel > CB_MAX_CHANNEL_24G) || (uConnectionChannel == 0)) // 1 ~ 14
+ uConnectionChannel = 1;
+ }
+
+ // clear NAV
+ MACvRegBitsOn(pDevice, MAC_REG_MACCR, MACCR_CLRNAV);
+
+ // Set Channel[7] = 0 to tell H/W channel is changing now.
+ MACvRegBitsOff(pDevice, MAC_REG_CHANNEL, 0x80);
+
+ //if (pMgmt->uCurrChannel == uConnectionChannel)
+ // return bResult;
+
+ CONTROLnsRequestOut(pDevice,
+ MESSAGE_TYPE_SELECT_CHANNLE,
+ (u16) uConnectionChannel,
+ 0,
+ 0,
+ NULL
+ );
+
+ //{{ RobertYu: 20041202
+ //// TX_PE will reserve 3 us for MAX2829 A mode only, it is for better TX throughput
+
+ if (pDevice->byBBType == BB_TYPE_11A) {
+ pDevice->byCurPwr = 0xFF;
+ RFbRawSetPower(pDevice, pDevice->abyOFDMAPwrTbl[uConnectionChannel-15], RATE_54M);
+ } else if (pDevice->byBBType == BB_TYPE_11G) {
+ pDevice->byCurPwr = 0xFF;
+ RFbRawSetPower(pDevice, pDevice->abyOFDMPwrTbl[uConnectionChannel-1], RATE_54M);
+ } else {
+ pDevice->byCurPwr = 0xFF;
+ RFbRawSetPower(pDevice, pDevice->abyCCKPwrTbl[uConnectionChannel-1], RATE_1M);
+ }
+ ControlvWriteByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_CHANNEL,(u8)(uConnectionChannel|0x80));
+}
+
+/*
+ * Description: Get CCK mode basic rate
+ *
+ * Parameters:
+ * In:
+ * pDevice - The adapter to be set
+ * wRateIdx - Receiving data rate
+ * Out:
+ * none
+ *
+ * Return Value: response Control frame rate
+ *
+ */
+static u16 swGetCCKControlRate(struct vnt_private *pDevice, u16 wRateIdx)
+{
+ u16 ui = wRateIdx;
+
+ while (ui > RATE_1M) {
+ if (pDevice->wBasicRate & (1 << ui))
+ return ui;
+ ui--;
+ }
+
+ return RATE_1M;
+}
+
+/*
+ * Description: Get OFDM mode basic rate
+ *
+ * Parameters:
+ * In:
+ * pDevice - The adapter to be set
+ * wRateIdx - Receiving data rate
+ * Out:
+ * none
+ *
+ * Return Value: response Control frame rate
+ *
+ */
+static u16 swGetOFDMControlRate(struct vnt_private *pDevice, u16 wRateIdx)
+{
+ u16 ui = wRateIdx;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BASIC RATE: %X\n",
+ pDevice->wBasicRate);
+
+ if (!CARDbIsOFDMinBasicRate(pDevice)) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
+ "swGetOFDMControlRate:(NO OFDM) %d\n", wRateIdx);
+ if (wRateIdx > RATE_24M)
+ wRateIdx = RATE_24M;
+ return wRateIdx;
+ }
+
+ while (ui > RATE_11M) {
+ if (pDevice->wBasicRate & (1 << ui)) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
+ "swGetOFDMControlRate: %d\n", ui);
+ return ui;
+ }
+ ui--;
+ }
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"swGetOFDMControlRate: 6M\n");
+
+ return RATE_24M;
+}
+
+/*
+ * Description: Calculate TxRate and RsvTime fields for RSPINF in OFDM mode.
+ *
+ * Parameters:
+ * In:
+ * wRate - Tx Rate
+ * byPktType - Tx Packet type
+ * Out:
+ * pbyTxRate - pointer to RSPINF TxRate field
+ * pbyRsvTime - pointer to RSPINF RsvTime field
+ *
+ * Return Value: none
+ *
+ */
+void
+CARDvCalculateOFDMRParameter (
+ u16 wRate,
+ u8 byBBType,
+ u8 * pbyTxRate,
+ u8 * pbyRsvTime
+ )
+{
+ switch (wRate) {
+ case RATE_6M :
+ if (byBBType == BB_TYPE_11A) {//5GHZ
+ *pbyTxRate = 0x9B;
+ *pbyRsvTime = 24;
+ }
+ else {
+ *pbyTxRate = 0x8B;
+ *pbyRsvTime = 30;
+ }
+ break;
+
+ case RATE_9M :
+ if (byBBType == BB_TYPE_11A) {//5GHZ
+ *pbyTxRate = 0x9F;
+ *pbyRsvTime = 16;
+ }
+ else {
+ *pbyTxRate = 0x8F;
+ *pbyRsvTime = 22;
+ }
+ break;
+
+ case RATE_12M :
+ if (byBBType == BB_TYPE_11A) {//5GHZ
+ *pbyTxRate = 0x9A;
+ *pbyRsvTime = 12;
+ }
+ else {
+ *pbyTxRate = 0x8A;
+ *pbyRsvTime = 18;
+ }
+ break;
+
+ case RATE_18M :
+ if (byBBType == BB_TYPE_11A) {//5GHZ
+ *pbyTxRate = 0x9E;
+ *pbyRsvTime = 8;
+ }
+ else {
+ *pbyTxRate = 0x8E;
+ *pbyRsvTime = 14;
+ }
+ break;
+
+ case RATE_36M :
+ if (byBBType == BB_TYPE_11A) {//5GHZ
+ *pbyTxRate = 0x9D;
+ *pbyRsvTime = 4;
+ }
+ else {
+ *pbyTxRate = 0x8D;
+ *pbyRsvTime = 10;
+ }
+ break;
+
+ case RATE_48M :
+ if (byBBType == BB_TYPE_11A) {//5GHZ
+ *pbyTxRate = 0x98;
+ *pbyRsvTime = 4;
+ }
+ else {
+ *pbyTxRate = 0x88;
+ *pbyRsvTime = 10;
+ }
+ break;
+
+ case RATE_54M :
+ if (byBBType == BB_TYPE_11A) {//5GHZ
+ *pbyTxRate = 0x9C;
+ *pbyRsvTime = 4;
+ }
+ else {
+ *pbyTxRate = 0x8C;
+ *pbyRsvTime = 10;
+ }
+ break;
+
+ case RATE_24M :
+ default :
+ if (byBBType == BB_TYPE_11A) {//5GHZ
+ *pbyTxRate = 0x99;
+ *pbyRsvTime = 8;
+ }
+ else {
+ *pbyTxRate = 0x89;
+ *pbyRsvTime = 14;
+ }
+ break;
+ }
+}
+
+/*
+ * Description: Set RSPINF
+ *
+ * Parameters:
+ * In:
+ * pDevice - The adapter to be set
+ * Out:
+ * none
+ *
+ * Return Value: None.
+ *
+ */
+void CARDvSetRSPINF(struct vnt_private *pDevice, u8 byBBType)
+{
+ u8 abyServ[4] = {0, 0, 0, 0}; /* For CCK */
+ u8 abySignal[4] = {0, 0, 0, 0};
+ u16 awLen[4] = {0, 0, 0, 0};
+ u8 abyTxRate[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; /* For OFDM */
+ u8 abyRsvTime[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
+ u8 abyData[34];
+ int i;
+
+ //RSPINF_b_1
+ BBvCalculateParameter(pDevice,
+ 14,
+ swGetCCKControlRate(pDevice, RATE_1M),
+ PK_TYPE_11B,
+ &awLen[0],
+ &abyServ[0],
+ &abySignal[0]
+ );
+
+ ///RSPINF_b_2
+ BBvCalculateParameter(pDevice,
+ 14,
+ swGetCCKControlRate(pDevice, RATE_2M),
+ PK_TYPE_11B,
+ &awLen[1],
+ &abyServ[1],
+ &abySignal[1]
+ );
+
+ //RSPINF_b_5
+ BBvCalculateParameter(pDevice,
+ 14,
+ swGetCCKControlRate(pDevice, RATE_5M),
+ PK_TYPE_11B,
+ &awLen[2],
+ &abyServ[2],
+ &abySignal[2]
+ );
+
+ //RSPINF_b_11
+ BBvCalculateParameter(pDevice,
+ 14,
+ swGetCCKControlRate(pDevice, RATE_11M),
+ PK_TYPE_11B,
+ &awLen[3],
+ &abyServ[3],
+ &abySignal[3]
+ );
+
+ //RSPINF_a_6
+ CARDvCalculateOFDMRParameter (RATE_6M,
+ byBBType,
+ &abyTxRate[0],
+ &abyRsvTime[0]);
+
+ //RSPINF_a_9
+ CARDvCalculateOFDMRParameter (RATE_9M,
+ byBBType,
+ &abyTxRate[1],
+ &abyRsvTime[1]);
+
+ //RSPINF_a_12
+ CARDvCalculateOFDMRParameter (RATE_12M,
+ byBBType,
+ &abyTxRate[2],
+ &abyRsvTime[2]);
+
+ //RSPINF_a_18
+ CARDvCalculateOFDMRParameter (RATE_18M,
+ byBBType,
+ &abyTxRate[3],
+ &abyRsvTime[3]);
+
+ //RSPINF_a_24
+ CARDvCalculateOFDMRParameter (RATE_24M,
+ byBBType,
+ &abyTxRate[4],
+ &abyRsvTime[4]);
+
+ //RSPINF_a_36
+ CARDvCalculateOFDMRParameter (swGetOFDMControlRate(pDevice, RATE_36M),
+ byBBType,
+ &abyTxRate[5],
+ &abyRsvTime[5]);
+
+ //RSPINF_a_48
+ CARDvCalculateOFDMRParameter (swGetOFDMControlRate(pDevice, RATE_48M),
+ byBBType,
+ &abyTxRate[6],
+ &abyRsvTime[6]);
+
+ //RSPINF_a_54
+ CARDvCalculateOFDMRParameter (swGetOFDMControlRate(pDevice, RATE_54M),
+ byBBType,
+ &abyTxRate[7],
+ &abyRsvTime[7]);
+
+ //RSPINF_a_72
+ CARDvCalculateOFDMRParameter (swGetOFDMControlRate(pDevice, RATE_54M),
+ byBBType,
+ &abyTxRate[8],
+ &abyRsvTime[8]);
+
+ abyData[0] = (u8)(awLen[0]&0xFF);
+ abyData[1] = (u8)(awLen[0]>>8);
+ abyData[2] = abySignal[0];
+ abyData[3] = abyServ[0];
+
+ abyData[4] = (u8)(awLen[1]&0xFF);
+ abyData[5] = (u8)(awLen[1]>>8);
+ abyData[6] = abySignal[1];
+ abyData[7] = abyServ[1];
+
+ abyData[8] = (u8)(awLen[2]&0xFF);
+ abyData[9] = (u8)(awLen[2]>>8);
+ abyData[10] = abySignal[2];
+ abyData[11] = abyServ[2];
+
+ abyData[12] = (u8)(awLen[3]&0xFF);
+ abyData[13] = (u8)(awLen[3]>>8);
+ abyData[14] = abySignal[3];
+ abyData[15] = abyServ[3];
+
+ for (i = 0; i < 9; i++) {
+ abyData[16+i*2] = abyTxRate[i];
+ abyData[16+i*2+1] = abyRsvTime[i];
+ }
+
+ CONTROLnsRequestOut(pDevice,
+ MESSAGE_TYPE_WRITE,
+ MAC_REG_RSPINF_B_1,
+ MESSAGE_REQUEST_MACREG,
+ 34,
+ &abyData[0]);
+
+}
+
+/*
+ * Description: Update IFS
+ *
+ * Parameters:
+ * In:
+ * pDevice - The adapter to be set
+ * Out:
+ * none
+ *
+ * Return Value: None.
+ *
+ */
+void vUpdateIFS(struct vnt_private *pDevice)
+{
+ u8 byMaxMin = 0;
+ u8 byData[4];
+
+ if (pDevice->byPacketType==PK_TYPE_11A) {//0000 0000 0000 0000,11a
+ pDevice->uSlot = C_SLOT_SHORT;
+ pDevice->uSIFS = C_SIFS_A;
+ pDevice->uDIFS = C_SIFS_A + 2*C_SLOT_SHORT;
+ pDevice->uCwMin = C_CWMIN_A;
+ byMaxMin = 4;
+ }
+ else if (pDevice->byPacketType==PK_TYPE_11B) {//0000 0001 0000 0000,11b
+ pDevice->uSlot = C_SLOT_LONG;
+ pDevice->uSIFS = C_SIFS_BG;
+ pDevice->uDIFS = C_SIFS_BG + 2*C_SLOT_LONG;
+ pDevice->uCwMin = C_CWMIN_B;
+ byMaxMin = 5;
+ }
+ else {// PK_TYPE_11GA & PK_TYPE_11GB
+ u8 byRate = 0;
+ bool bOFDMRate = false;
+ unsigned int ii = 0;
+ PWLAN_IE_SUPP_RATES pItemRates = NULL;
+
+ pDevice->uSIFS = C_SIFS_BG;
+ if (pDevice->bShortSlotTime) {
+ pDevice->uSlot = C_SLOT_SHORT;
+ } else {
+ pDevice->uSlot = C_SLOT_LONG;
+ }
+ pDevice->uDIFS = C_SIFS_BG + 2*pDevice->uSlot;
+
+ pItemRates = (PWLAN_IE_SUPP_RATES)pDevice->vnt_mgmt.abyCurrSuppRates;
+ for (ii = 0; ii < pItemRates->len; ii++) {
+ byRate = (u8)(pItemRates->abyRates[ii]&0x7F);
+ if (RATEwGetRateIdx(byRate) > RATE_11M) {
+ bOFDMRate = true;
+ break;
+ }
+ }
+ if (bOFDMRate == false) {
+ pItemRates = (PWLAN_IE_SUPP_RATES)pDevice->vnt_mgmt
+ .abyCurrExtSuppRates;
+ for (ii = 0; ii < pItemRates->len; ii++) {
+ byRate = (u8)(pItemRates->abyRates[ii]&0x7F);
+ if (RATEwGetRateIdx(byRate) > RATE_11M) {
+ bOFDMRate = true;
+ break;
+ }
+ }
+ }
+ if (bOFDMRate == true) {
+ pDevice->uCwMin = C_CWMIN_A;
+ byMaxMin = 4;
+ } else {
+ pDevice->uCwMin = C_CWMIN_B;
+ byMaxMin = 5;
+ }
+ }
+
+ pDevice->uCwMax = C_CWMAX;
+ pDevice->uEIFS = C_EIFS;
+
+ byData[0] = (u8)pDevice->uSIFS;
+ byData[1] = (u8)pDevice->uDIFS;
+ byData[2] = (u8)pDevice->uEIFS;
+ byData[3] = (u8)pDevice->uSlot;
+ CONTROLnsRequestOut(pDevice,
+ MESSAGE_TYPE_WRITE,
+ MAC_REG_SIFS,
+ MESSAGE_REQUEST_MACREG,
+ 4,
+ &byData[0]);
+
+ byMaxMin |= 0xA0;//1010 1111,C_CWMAX = 1023
+ CONTROLnsRequestOut(pDevice,
+ MESSAGE_TYPE_WRITE,
+ MAC_REG_CWMAXMIN0,
+ MESSAGE_REQUEST_MACREG,
+ 1,
+ &byMaxMin);
+}
+
+void CARDvUpdateBasicTopRate(struct vnt_private *pDevice)
+{
+ u8 byTopOFDM = RATE_24M, byTopCCK = RATE_1M;
+ u8 ii;
+
+ //Determines the highest basic rate.
+ for (ii = RATE_54M; ii >= RATE_6M; ii --) {
+ if ( (pDevice->wBasicRate) & ((u16)(1<<ii)) ) {
+ byTopOFDM = ii;
+ break;
+ }
+ }
+ pDevice->byTopOFDMBasicRate = byTopOFDM;
+
+ for (ii = RATE_11M;; ii --) {
+ if ( (pDevice->wBasicRate) & ((u16)(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.
+ *
+ */
+void CARDbAddBasicRate(struct vnt_private *pDevice, u16 wRateIdx)
+{
+ u16 wRate = (1 << wRateIdx);
+
+ pDevice->wBasicRate |= wRate;
+
+ //Determines the highest basic rate.
+ CARDvUpdateBasicTopRate(pDevice);
+}
+
+int CARDbIsOFDMinBasicRate(struct vnt_private *pDevice)
+{
+ int ii;
+
+ for (ii = RATE_54M; ii >= RATE_6M; ii --) {
+ if ((pDevice->wBasicRate) & ((u16)(1<<ii)))
+ return true;
+ }
+ return false;
+}
+
+u8 CARDbyGetPktType(struct vnt_private *pDevice)
+{
+
+ if (pDevice->byBBType == BB_TYPE_11A || pDevice->byBBType == BB_TYPE_11B) {
+ return (u8)pDevice->byBBType;
+ }
+ else if (CARDbIsOFDMinBasicRate(pDevice)) {
+ return PK_TYPE_11GA;
+ }
+ else {
+ return PK_TYPE_11GB;
+ }
+}
+
+/*
+ * Description: Calculate 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
+ *
+ */
+u64 CARDqGetTSFOffset(u8 byRxRate, u64 qwTSF1, u64 qwTSF2)
+{
+ u64 qwTSFOffset = 0;
+ u16 wRxBcnTSFOffst = 0;
+
+ wRxBcnTSFOffst = cwRXBCNTSFOff[byRxRate % MAX_RATE];
+
+ qwTSF2 += (u64)wRxBcnTSFOffst;
+
+ qwTSFOffset = qwTSF1 - qwTSF2;
+
+ return qwTSFOffset;
+}
+
+/*
+ * Description: Sync. TSF counter to BSS
+ * Get TSF offset and write to HW
+ *
+ * Parameters:
+ * In:
+ * pDevice - The adapter to be sync.
+ * qwBSSTimestamp - Rx BCN's TSF
+ * qwLocalTSF - Local TSF
+ * Out:
+ * none
+ *
+ * Return Value: none
+ *
+ */
+void CARDvAdjustTSF(struct vnt_private *pDevice, u8 byRxRate,
+ u64 qwBSSTimestamp, u64 qwLocalTSF)
+{
+ u64 qwTSFOffset = 0;
+ u8 pbyData[8];
+
+ qwTSFOffset = CARDqGetTSFOffset(byRxRate, qwBSSTimestamp, qwLocalTSF);
+ // adjust TSF
+ // HW's TSF add TSF Offset reg
+
+ pbyData[0] = (u8)qwTSFOffset;
+ pbyData[1] = (u8)(qwTSFOffset >> 8);
+ pbyData[2] = (u8)(qwTSFOffset >> 16);
+ pbyData[3] = (u8)(qwTSFOffset >> 24);
+ pbyData[4] = (u8)(qwTSFOffset >> 32);
+ pbyData[5] = (u8)(qwTSFOffset >> 40);
+ pbyData[6] = (u8)(qwTSFOffset >> 48);
+ pbyData[7] = (u8)(qwTSFOffset >> 56);
+
+ CONTROLnsRequestOut(pDevice,
+ MESSAGE_TYPE_SET_TSFTBTT,
+ MESSAGE_REQUEST_TSF,
+ 0,
+ 8,
+ pbyData
+ );
+
+}
+/*
+ * Description: Read NIC TSF counter
+ * Get local TSF counter
+ *
+ * Parameters:
+ * In:
+ * pDevice - The adapter to be read
+ * Out:
+ * qwCurrTSF - Current TSF counter
+ *
+ * Return Value: true if success; otherwise false
+ *
+ */
+bool CARDbGetCurrentTSF(struct vnt_private *pDevice, u64 *pqwCurrTSF)
+{
+
+ *pqwCurrTSF = pDevice->qwCurrTSF;
+
+ return true;
+}
+
+/*
+ * Description: Clear NIC TSF counter
+ * Clear local TSF counter
+ *
+ * Parameters:
+ * In:
+ * pDevice - The adapter to be read
+ *
+ * Return Value: true if success; otherwise false
+ *
+ */
+bool CARDbClearCurrentTSF(struct vnt_private *pDevice)
+{
+
+ MACvRegBitsOn(pDevice, MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);
+
+ pDevice->qwCurrTSF = 0;
+
+ return true;
+}
+
+/*
+ * Description: Read NIC TSF counter
+ * Get NEXTTBTT from adjusted TSF and Beacon Interval
+ *
+ * Parameters:
+ * In:
+ * qwTSF - Current TSF counter
+ * wbeaconInterval - Beacon Interval
+ * Out:
+ * qwCurrTSF - Current TSF counter
+ *
+ * Return Value: TSF value of next Beacon
+ *
+ */
+u64 CARDqGetNextTBTT(u64 qwTSF, u16 wBeaconInterval)
+{
+
+ unsigned int uLowNextTBTT;
+ unsigned int uHighRemain, uLowRemain;
+ unsigned int uBeaconInterval;
+
+ uBeaconInterval = wBeaconInterval * 1024;
+ // Next TBTT = ((local_current_TSF / beacon_interval) + 1 ) * beacon_interval
+ uLowNextTBTT = ((qwTSF & 0xffffffffULL) >> 10) << 10;
+ uLowRemain = (uLowNextTBTT) % uBeaconInterval;
+ uHighRemain = ((0x80000000 % uBeaconInterval) * 2 * (u32)(qwTSF >> 32))
+ % uBeaconInterval;
+ uLowRemain = (uHighRemain + uLowRemain) % uBeaconInterval;
+ uLowRemain = uBeaconInterval - uLowRemain;
+
+ // check if carry when add one beacon interval
+ if ((~uLowNextTBTT) < uLowRemain)
+ qwTSF = ((qwTSF >> 32) + 1) << 32;
+
+ qwTSF = (qwTSF & 0xffffffff00000000ULL) |
+ (u64)(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(struct vnt_private *pDevice, u16 wBeaconInterval)
+{
+ u64 qwNextTBTT = 0;
+ u8 pbyData[8];
+
+ CARDbClearCurrentTSF(pDevice);
+ //CARDbGetCurrentTSF(pDevice, &qwNextTBTT); //Get Local TSF counter
+ qwNextTBTT = CARDqGetNextTBTT(qwNextTBTT, wBeaconInterval);
+ // Set NextTBTT
+
+ pbyData[0] = (u8)qwNextTBTT;
+ pbyData[1] = (u8)(qwNextTBTT >> 8);
+ pbyData[2] = (u8)(qwNextTBTT >> 16);
+ pbyData[3] = (u8)(qwNextTBTT >> 24);
+ pbyData[4] = (u8)(qwNextTBTT >> 32);
+ pbyData[5] = (u8)(qwNextTBTT >> 40);
+ pbyData[6] = (u8)(qwNextTBTT >> 48);
+ pbyData[7] = (u8)(qwNextTBTT >> 56);
+
+ CONTROLnsRequestOut(pDevice,
+ MESSAGE_TYPE_SET_TSFTBTT,
+ MESSAGE_REQUEST_TBTT,
+ 0,
+ 8,
+ pbyData
+ );
+
+ return;
+}
+
+/*
+ * Description: Sync NIC TSF counter for Beacon time
+ * Get NEXTTBTT and write to HW
+ *
+ * Parameters:
+ * In:
+ * pDevice - The adapter to be set
+ * qwTSF - Current TSF counter
+ * wBeaconInterval - Beacon Interval
+ * Out:
+ * none
+ *
+ * Return Value: none
+ *
+ */
+void CARDvUpdateNextTBTT(struct vnt_private *pDevice, u64 qwTSF,
+ u16 wBeaconInterval)
+{
+ u8 pbyData[8];
+
+ qwTSF = CARDqGetNextTBTT(qwTSF, wBeaconInterval);
+
+ // Set NextTBTT
+
+ pbyData[0] = (u8)qwTSF;
+ pbyData[1] = (u8)(qwTSF >> 8);
+ pbyData[2] = (u8)(qwTSF >> 16);
+ pbyData[3] = (u8)(qwTSF >> 24);
+ pbyData[4] = (u8)(qwTSF >> 32);
+ pbyData[5] = (u8)(qwTSF >> 40);
+ pbyData[6] = (u8)(qwTSF >> 48);
+ pbyData[7] = (u8)(qwTSF >> 56);
+
+ CONTROLnsRequestOut(pDevice,
+ MESSAGE_TYPE_SET_TSFTBTT,
+ MESSAGE_REQUEST_TBTT,
+ 0,
+ 8,
+ pbyData
+ );
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
+ "Card:Update Next TBTT[%8lx]\n", (unsigned long)qwTSF);
+
+ return;
+}
+
+/*
+ * Description: Turn off Radio power
+ *
+ * Parameters:
+ * In:
+ * pDevice - The adapter to be turned off
+ * Out:
+ * none
+ *
+ * Return Value: true if success; otherwise false
+ *
+ */
+int CARDbRadioPowerOff(struct vnt_private *pDevice)
+{
+ int bResult = true;
+
+ //if (pDevice->bRadioOff == true)
+ // return true;
+
+ pDevice->bRadioOff = true;
+
+ switch (pDevice->byRFType) {
+ case RF_AL2230:
+ case RF_AL2230S:
+ case RF_AIROHA7230:
+ case RF_VT3226: //RobertYu:20051111
+ case RF_VT3226D0:
+ case RF_VT3342A0: //RobertYu:20060609
+ MACvRegBitsOff(pDevice, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPE2 | SOFTPWRCTL_SWPE3));
+ break;
+ }
+
+ MACvRegBitsOff(pDevice, MAC_REG_HOSTCR, HOSTCR_RXON);
+
+ BBvSetDeepSleep(pDevice);
+
+ return bResult;
+}
+
+/*
+ * Description: Turn on Radio power
+ *
+ * Parameters:
+ * In:
+ * pDevice - The adapter to be turned on
+ * Out:
+ * none
+ *
+ * Return Value: true if success; otherwise false
+ *
+ */
+int CARDbRadioPowerOn(struct vnt_private *pDevice)
+{
+ int bResult = true;
+
+ if ((pDevice->bHWRadioOff == true) || (pDevice->bRadioControlOff == true)) {
+ return false;
+ }
+
+ //if (pDevice->bRadioOff == false)
+ // return true;
+
+ pDevice->bRadioOff = false;
+
+ BBvExitDeepSleep(pDevice);
+
+ MACvRegBitsOn(pDevice, MAC_REG_HOSTCR, HOSTCR_RXON);
+
+ switch (pDevice->byRFType) {
+ case RF_AL2230:
+ case RF_AL2230S:
+ case RF_AIROHA7230:
+ case RF_VT3226: //RobertYu:20051111
+ case RF_VT3226D0:
+ case RF_VT3342A0: //RobertYu:20060609
+ MACvRegBitsOn(pDevice, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPE2 | SOFTPWRCTL_SWPE3));
+ break;
+ }
+
+ return bResult;
+}
+
+void CARDvSetBSSMode(struct vnt_private *pDevice)
+{
+ // Set BB and packet type at the same time.//{{RobertYu:20050222, AL7230 have two TX PA output, only connet to b/g now
+ // so in 11a mode need to set the MAC Reg0x4C to 11b/g mode to turn on PA
+ if( (pDevice->byRFType == RF_AIROHA7230 ) && (pDevice->byBBType == BB_TYPE_11A) )
+ {
+ MACvSetBBType(pDevice, BB_TYPE_11G);
+ }
+ else
+ {
+ MACvSetBBType(pDevice, pDevice->byBBType);
+ }
+ pDevice->byPacketType = CARDbyGetPktType(pDevice);
+
+ if (pDevice->byBBType == BB_TYPE_11A) {
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x88, 0x03);
+ } else if (pDevice->byBBType == BB_TYPE_11B) {
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x88, 0x02);
+ } else if (pDevice->byBBType == BB_TYPE_11G) {
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x88, 0x08);
+ }
+
+ vUpdateIFS(pDevice);
+ CARDvSetRSPINF(pDevice, (u8)pDevice->byBBType);
+
+ if ( pDevice->byBBType == BB_TYPE_11A ) {
+ //request by Jack 2005-04-26
+ if (pDevice->byRFType == RF_AIROHA7230) {
+ pDevice->abyBBVGA[0] = 0x20;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xE7, pDevice->abyBBVGA[0]);
+ }
+ pDevice->abyBBVGA[2] = 0x10;
+ pDevice->abyBBVGA[3] = 0x10;
+ } else {
+ //request by Jack 2005-04-26
+ if (pDevice->byRFType == RF_AIROHA7230) {
+ pDevice->abyBBVGA[0] = 0x1C;
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xE7, pDevice->abyBBVGA[0]);
+ }
+ pDevice->abyBBVGA[2] = 0x0;
+ pDevice->abyBBVGA[3] = 0x0;
+ }
+}
diff --git a/drivers/staging/vt6656/card.h b/drivers/staging/vt6656/card.h
new file mode 100644
index 00000000..c3017a74
--- /dev/null
+++ b/drivers/staging/vt6656/card.h
@@ -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: card.h
+ *
+ * Purpose: Provide functions to setup NIC operation mode
+ *
+ * Author: Tevin Chen
+ *
+ * Date: May 21, 1996
+ *
+ */
+
+#ifndef __CARD_H__
+#define __CARD_H__
+#include "device.h"
+
+/* init card type */
+
+typedef enum _CARD_PHY_TYPE {
+ PHY_TYPE_AUTO = 0,
+ PHY_TYPE_11B,
+ PHY_TYPE_11G,
+ PHY_TYPE_11A
+} CARD_PHY_TYPE, *PCARD_PHY_TYPE;
+
+typedef enum _CARD_OP_MODE {
+ OP_MODE_INFRASTRUCTURE = 0,
+ OP_MODE_ADHOC,
+ OP_MODE_AP,
+ OP_MODE_UNKNOWN
+} CARD_OP_MODE, *PCARD_OP_MODE;
+
+#define CB_MAX_CHANNEL_24G 14
+#define CB_MAX_CHANNEL_5G 42 /* add channel9(5045MHz), 41==>42 */
+#define CB_MAX_CHANNEL (CB_MAX_CHANNEL_24G+CB_MAX_CHANNEL_5G)
+
+struct vnt_private;
+
+void CARDbSetMediaChannel(struct vnt_private *pDevice, u32 uConnectionChannel);
+void CARDvSetRSPINF(struct vnt_private *pDevice, u8 byBBType);
+void vUpdateIFS(struct vnt_private *pDevice);
+void CARDvUpdateBasicTopRate(struct vnt_private *pDevice);
+void CARDbAddBasicRate(struct vnt_private *pDevice, u16 wRateIdx);
+int CARDbIsOFDMinBasicRate(struct vnt_private *pDevice);
+void CARDvAdjustTSF(struct vnt_private *pDevice, u8 byRxRate,
+ u64 qwBSSTimestamp, u64 qwLocalTSF);
+bool CARDbGetCurrentTSF(struct vnt_private *pDevice, u64 *pqwCurrTSF);
+bool CARDbClearCurrentTSF(struct vnt_private *pDevice);
+void CARDvSetFirstNextTBTT(struct vnt_private *pDevice, u16 wBeaconInterval);
+void CARDvUpdateNextTBTT(struct vnt_private *pDevice, u64 qwTSF,
+ u16 wBeaconInterval);
+u64 CARDqGetNextTBTT(u64 qwTSF, u16 wBeaconInterval);
+u64 CARDqGetTSFOffset(u8 byRxRate, u64 qwTSF1, u64 qwTSF2);
+int CARDbRadioPowerOff(struct vnt_private *pDevice);
+int CARDbRadioPowerOn(struct vnt_private *pDevice);
+u8 CARDbyGetPktType(struct vnt_private *pDevice);
+void CARDvSetBSSMode(struct vnt_private *pDevice);
+
+#endif /* __CARD_H__ */
diff --git a/drivers/staging/vt6656/channel.c b/drivers/staging/vt6656/channel.c
new file mode 100644
index 00000000..5158ff4b
--- /dev/null
+++ b/drivers/staging/vt6656/channel.c
@@ -0,0 +1,474 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: channel.c
+ *
+ * Purpose: Channel number mapping
+ *
+ * Author: Lucas Lin
+ *
+ * Date: Dec 24, 2004
+ *
+ *
+ *
+ * Revision History:
+ * 01-18-2005 RobertYu: remove the for loop searching in ChannelValid,
+ * change ChannelRuleTab to lookup-type, reorder table items.
+ *
+ *
+ */
+
+#include <linux/kernel.h>
+#include "country.h"
+#include "channel.h"
+#include "rf.h"
+
+static int msglevel = MSG_LEVEL_INFO;
+//static int msglevel =MSG_LEVEL_DEBUG;
+
+static SChannelTblElement sChannelTbl[CB_MAX_CHANNEL+1] =
+{
+ {0, 0, false},
+ {1, 2412, true},
+ {2, 2417, true},
+ {3, 2422, true},
+ {4, 2427, true},
+ {5, 2432, true},
+ {6, 2437, true},
+ {7, 2442, true},
+ {8, 2447, true},
+ {9, 2452, true},
+ {10, 2457, true},
+ {11, 2462, true},
+ {12, 2467, true},
+ {13, 2472, true},
+ {14, 2484, true},
+ {183, 4915, true}, //15
+ {184, 4920, true}, //16
+ {185, 4925, true}, //17
+ {187, 4935, true}, //18
+ {188, 4940, true}, //19
+ {189, 4945, true}, //20
+ {192, 4960, true}, //21
+ {196, 4980, true}, //22
+ {7, 5035, true}, //23
+ {8, 5040, true}, //24
+ {9, 5045, true}, //25
+ {11, 5055, true}, //26
+ {12, 5060, true}, //27
+ {16, 5080, true}, //28
+ {34, 5170, true}, //29
+ {36, 5180, true}, //30
+ {38, 5190, true}, //31
+ {40, 5200, true}, //32
+ {42, 5210, true}, //33
+ {44, 5220, true}, //34
+ {46, 5230, true}, //35
+ {48, 5240, true}, //36
+ {52, 5260, true}, //37
+ {56, 5280, true}, //38
+ {60, 5300, true}, //39
+ {64, 5320, true}, //40
+ {100, 5500, true}, //41
+ {104, 5520, true}, //42
+ {108, 5540, true}, //43
+ {112, 5560, true}, //44
+ {116, 5580, true}, //45
+ {120, 5600, true}, //46
+ {124, 5620, true}, //47
+ {128, 5640, true}, //48
+ {132, 5660, true}, //49
+ {136, 5680, true}, //50
+ {140, 5700, true}, //51
+ {149, 5745, true}, //52
+ {153, 5765, true}, //53
+ {157, 5785, true}, //54
+ {161, 5805, true}, //55
+ {165, 5825, true} //56
+};
+
+/************************************************************************
+ * The Radar regulation rules for each country
+ ************************************************************************/
+static struct
+{
+ u8 byChannelCountryCode; /* The country code */
+ char chCountryCode[2];
+ u8 bChannelIdxList[CB_MAX_CHANNEL]; /* Available channels Index */
+ u8 byPower[CB_MAX_CHANNEL];
+} ChannelRuleTab[] =
+{
+/************************************************************************
+ * This table is based on Athero driver rules
+ ************************************************************************/
+/* Country Available channels, ended with 0 */
+/* 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 */
+{CCODE_FCC, {'U','S'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
+ , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} },
+{CCODE_TELEC, {'J','P'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 23, 0, 0, 23, 0, 23, 23, 0, 23, 0, 0, 23, 23, 23, 0, 23, 0, 23, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_ETSI, {'E','U'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} },
+{CCODE_RESV3, {' ',' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_RESV4, {' ',' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_RESV5, {' ',' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_RESV6, {' ',' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_RESV7, {' ',' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_RESV8, {' ',' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_RESV9, {' ',' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_RESVa, {' ',' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_RESVb, {' ',' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_RESVc, {' ',' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_RESVd, {' ',' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_RESVe, {' ',' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_ALLBAND, {' ',' '}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_ALBANIA, {'A','L'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_ALGERIA, {'D','Z'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_ARGENTINA, {'A','R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 0} },
+{CCODE_ARMENIA, {'A','M'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_AUSTRALIA, {'A','U'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 23, 0, 23, 0, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} },
+{CCODE_AUSTRIA, {'A','T'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 15, 0, 15, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_AZERBAIJAN, {'A','Z'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_BAHRAIN, {'B','H'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_BELARUS, {'B','Y'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_BELGIUM, {'B','E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_BELIZE, {'B','Z'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
+ , { 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} },
+{CCODE_BOLIVIA, {'B','O'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
+ , { 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} },
+{CCODE_BRAZIL, {'B','R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_BRUNEI_DARUSSALAM, {'B','N'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} },
+{CCODE_BULGARIA, {'B','G'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 23, 0, 23, 0, 23, 23, 23, 0, 0, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 0, 0, 0, 0, 0} },
+{CCODE_CANADA, {'C','A'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
+ , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} },
+{CCODE_CHILE, {'C','L'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17} },
+{CCODE_CHINA, {'C','N'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} },
+{CCODE_COLOMBIA, {'C','O'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
+ , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} },
+{CCODE_COSTA_RICA, {'C','R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_CROATIA, {'H','R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_CYPRUS, {'C','Y'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} },
+{CCODE_CZECH, {'C','Z'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_DENMARK, {'D','K'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} },
+{CCODE_DOMINICAN_REPUBLIC, {'D','O'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
+ , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} },
+{CCODE_ECUADOR, {'E','C'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_EGYPT, {'E','G'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_EL_SALVADOR, {'S','V'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_ESTONIA, {'E','E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} },
+{CCODE_FINLAND, {'F','I'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} },
+{CCODE_FRANCE, {'F','R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_GERMANY, {'D','E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} },
+{CCODE_GREECE, {'G','R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_GEORGIA, {'G','E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_GUATEMALA, {'G','T'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
+ , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} },
+{CCODE_HONDURAS, {'H','N'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_HONG_KONG, {'H','K'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 23, 0, 23, 0, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} },
+{CCODE_HUNGARY, {'H','U'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_ICELAND, {'I','S'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} },
+{CCODE_INDIA, {'I','N'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_INDONESIA, {'I','D'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_IRAN, {'I','R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} },
+{CCODE_IRELAND, {'I','E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} },
+{CCODE_ITALY, {'I','T'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} },
+{CCODE_ISRAEL, {'I','L'}, { 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_JAPAN, {'J','P'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 23, 0, 23, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_JORDAN, {'J','O'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_KAZAKHSTAN, {'K','Z'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_KUWAIT, {'K','W'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_LATVIA, {'L','V'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_LEBANON, {'L','B'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_LEICHTENSTEIN, {'L','I'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_LITHUANIA, {'L','T'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} },
+{CCODE_LUXEMBURG, {'L','U'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} },
+{CCODE_MACAU, {'M','O'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 23, 0, 23, 0, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} },
+{CCODE_MACEDONIA, {'M','K'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_MALTA, {'M','T'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0}
+ , { 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 16, 0, 16, 0, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 0} },
+{CCODE_MALAYSIA, {'M','Y'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_MEXICO, {'M','X'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
+ , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} },
+{CCODE_MONACO, {'M','C'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_MOROCCO, {'M','A'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_NETHERLANDS, {'N','L'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} },
+{CCODE_NEW_ZEALAND, {'N','Z'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
+ , { 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 23, 0, 23, 0, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} },
+{CCODE_NORTH_KOREA, {'K','P'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 23, 23, 23, 0} },
+{CCODE_NORWAY, {'N','O'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} },
+{CCODE_OMAN, {'O','M'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_PAKISTAN, {'P','K'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_PANAMA, {'P','A'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
+ , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} },
+{CCODE_PERU, {'P','E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_PHILIPPINES, {'P','H'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} },
+{CCODE_POLAND, {'P','L'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} },
+{CCODE_PORTUGAL, {'P','T'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} },
+{CCODE_PUERTO_RICO, {'P','R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
+ , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} },
+{CCODE_QATAR, {'Q','A'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_ROMANIA, {'R','O'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_RUSSIA, {'R','U'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_SAUDI_ARABIA, {'S','A'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_SINGAPORE, {'S','G'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 20, 20, 20, 20} },
+{CCODE_SLOVAKIA, {'S','K'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0}
+ , { 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 16, 0, 16, 0, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 0} },
+{CCODE_SLOVENIA, {'S','I'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} },
+{CCODE_SOUTH_AFRICA, {'Z','A'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} },
+{CCODE_SOUTH_KOREA, {'K','R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 23, 23, 23, 0} },
+{CCODE_SPAIN, {'E','S'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0}
+ , { 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 16, 0, 16, 0, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 0} },
+{CCODE_SWEDEN, {'S','E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} },
+{CCODE_SWITZERLAND, {'C','H'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_SYRIA, {'S','Y'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_TAIWAN, {'T','W'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 0} },
+{CCODE_THAILAND, {'T','H'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 23, 23, 23, 0} },
+{CCODE_TRINIDAD_TOBAGO, {'T','T'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_TUNISIA, {'T','N'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_TURKEY, {'T','R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_UK, {'G','B'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} },
+{CCODE_UKRAINE, {'U','A'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_UNITED_ARAB_EMIRATES, {'A','E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_UNITED_STATES, {'U','S'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
+ , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} },
+{CCODE_URUGUAY, {'U','Y'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 23, 23, 23, 0} },
+{CCODE_UZBEKISTAN, {'U','Z'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_VENEZUELA, {'V','E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0}
+ , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 23, 23, 23, 0} },
+{CCODE_VIETNAM, {'V','N'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_YEMEN, {'Y','E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_ZIMBABWE, {'Z','W'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_JAPAN_W52_W53, {'J','J'}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+{CCODE_MAX, {'U','N'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
+ , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }
+/* 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 */
+};
+
+/************************************************************************
+ * Country Channel Valid
+ * Input: CountryCode, ChannelNum
+ * ChanneIndex is defined as VT3253 MAC channel:
+ * 1 = 2.4G channel 1
+ * 2 = 2.4G channel 2
+ * ...
+ * 14 = 2.4G channel 14
+ * 15 = 4.9G channel 183
+ * 16 = 4.9G channel 184
+ * .....
+ * Output: true if the specified 5GHz band is allowed to be used.
+ False otherwise.
+// 4.9G => Ch 183, 184, 185, 187, 188, 189, 192, 196 (Value:15 ~ 22)
+
+// 5G => Ch 7, 8, 9, 11, 12, 16, 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64,
+// 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165 (Value 23 ~ 56)
+ ************************************************************************/
+bool
+ChannelValid(unsigned int CountryCode, unsigned int 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 */
+
+void CHvInitChannelTable(struct vnt_private *pDevice)
+{
+ int bMultiBand = false;
+ int ii;
+
+ for (ii = 1; ii <= CB_MAX_CHANNEL; ii++)
+ sChannelTbl[ii].bValid = false;
+
+ switch (pDevice->byRFType) {
+ case RF_AL2230:
+ case RF_AL2230S:
+ case RF_VT3226:
+ case RF_VT3226D0:
+ bMultiBand = false;
+ break;
+ case RF_AIROHA7230:
+ case RF_VT3342A0:
+ default :
+ bMultiBand = true;
+ break;
+ }
+
+ if ((pDevice->dwDiagRefCount != 0) ||
+ (pDevice->b11hEable == true)) {
+ if (bMultiBand == true) {
+ for (ii = 0; ii < CB_MAX_CHANNEL; ii++) {
+ sChannelTbl[ii+1].bValid = true;
+ //pDevice->abyRegPwr[ii+1] = pDevice->abyOFDMDefaultPwr[ii+1];
+ //pDevice->abyLocalPwr[ii+1] = pDevice->abyOFDMDefaultPwr[ii+1];
+ }
+ for (ii = 0; ii < CB_MAX_CHANNEL_24G; ii++) {
+ //pDevice->abyRegPwr[ii+1] = pDevice->abyCCKDefaultPwr[ii+1];
+ //pDevice->abyLocalPwr[ii+1] = pDevice->abyCCKDefaultPwr[ii+1];
+ }
+ } else {
+ for (ii = 0; ii < CB_MAX_CHANNEL_24G; ii++) {
+ sChannelTbl[ii+1].bValid = true;
+ //pDevice->abyRegPwr[ii+1] = pDevice->abyCCKDefaultPwr[ii+1];
+ //pDevice->abyLocalPwr[ii+1] = pDevice->abyCCKDefaultPwr[ii+1];
+ }
+ }
+ } else if (pDevice->byZoneType <= CCODE_MAX) {
+ if (bMultiBand == true) {
+ for (ii = 0; ii < CB_MAX_CHANNEL; ii++) {
+ if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] != 0) {
+ sChannelTbl[ii+1].bValid = true;
+ //pDevice->abyRegPwr[ii+1] = ChannelRuleTab[pDevice->byZoneType].byPower[ii];
+ //pDevice->abyLocalPwr[ii+1] = ChannelRuleTab[pDevice->byZoneType].byPower[ii];
+ }
+ }
+ } else {
+ for (ii = 0; ii < CB_MAX_CHANNEL_24G; ii++) {
+ if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] != 0) {
+ sChannelTbl[ii+1].bValid = true;
+ //pDevice->abyRegPwr[ii+1] = ChannelRuleTab[pDevice->byZoneType].byPower[ii];
+ //pDevice->abyLocalPwr[ii+1] = ChannelRuleTab[pDevice->byZoneType].byPower[ii];
+ }
+ }
+ }
+ }
+ DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO"Zone=[%d][%c][%c]!!\n",pDevice->byZoneType,ChannelRuleTab[pDevice->byZoneType].chCountryCode[0],ChannelRuleTab[pDevice->byZoneType].chCountryCode[1]);
+ for (ii = 0; ii < CB_MAX_CHANNEL; ii++) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Channel[%d] is [%d]\n",sChannelTbl[ii].byChannelNumber,sChannelTbl[ii+1].bValid);
+ /*if (pDevice->abyRegPwr[ii+1] == 0) {
+ pDevice->abyRegPwr[ii+1] = pDevice->abyOFDMDefaultPwr[ii+1];
+ }
+ if (pDevice->abyLocalPwr[ii+1] == 0) {
+ pDevice->abyLocalPwr[ii+1] = pDevice->abyOFDMDefaultPwr[ii+1];
+ }*/
+ }
+}
diff --git a/drivers/staging/vt6656/channel.h b/drivers/staging/vt6656/channel.h
new file mode 100644
index 00000000..95701e0c
--- /dev/null
+++ b/drivers/staging/vt6656/channel.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: channel.h
+ *
+ * Purpose: Country Regulation Rules header file
+ *
+ * Author: Lucas Lin
+ *
+ * Date: Dec 23, 2004
+ *
+ */
+
+#ifndef _CHANNEL_H_
+#define _CHANNEL_H_
+
+#include "device.h"
+
+typedef struct tagSChannelTblElement {
+ u8 byChannelNumber;
+ unsigned int uFrequency;
+ bool bValid;
+} SChannelTblElement, *PSChannelTblElement;
+
+bool ChannelValid(unsigned int CountryCode, unsigned int ChannelNum);
+void CHvInitChannelTable(struct vnt_private *pDevice);
+
+#endif /* _CHANNEL_H_ */
diff --git a/drivers/staging/vt6656/control.c b/drivers/staging/vt6656/control.c
new file mode 100644
index 00000000..026784fc
--- /dev/null
+++ b/drivers/staging/vt6656/control.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: control.c
+ *
+ * Purpose: Handle USB control endpoint
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Apr. 5, 2004
+ *
+ * Functions:
+ * CONTROLnsRequestOut - Write variable length bytes to MEM/BB/MAC/EEPROM
+ * CONTROLnsRequestIn - Read variable length bytes from MEM/BB/MAC/EEPROM
+ * ControlvWriteByte - Write one byte to MEM/BB/MAC/EEPROM
+ * ControlvReadByte - Read one byte from MEM/BB/MAC/EEPROM
+ * ControlvMaskByte - Read one byte from MEM/BB/MAC/EEPROM and clear/set
+ * some bits in the same address
+ *
+ * Revision History:
+ * 04-05-2004 Jerry Chen: Initial release
+ * 11-24-2004 Warren Hsu: Add ControlvWriteByte, ControlvReadByte,
+ * ControlvMaskByte
+ *
+ */
+
+#include "control.h"
+#include "rndis.h"
+
+/* static int msglevel =MSG_LEVEL_INFO; */
+/* static int msglevel =MSG_LEVEL_DEBUG; */
+
+void ControlvWriteByte(struct vnt_private *pDevice, u8 reg, u8 reg_off,
+ u8 data)
+{
+
+ CONTROLnsRequestOut(pDevice, MESSAGE_TYPE_WRITE, reg_off, reg,
+ sizeof(u8), &data);
+
+ return;
+}
+
+void ControlvReadByte(struct vnt_private *pDevice, u8 reg, u8 reg_off,
+ u8 *data)
+{
+ CONTROLnsRequestIn(pDevice, MESSAGE_TYPE_READ,
+ reg_off, reg, sizeof(u8), data);
+ return;
+}
+
+void ControlvMaskByte(struct vnt_private *pDevice, u8 reg_type, u8 reg_off,
+ u8 reg_mask, u8 data)
+{
+ u8 reg_data[2];
+
+ reg_data[0] = data;
+ reg_data[1] = reg_mask;
+
+ CONTROLnsRequestOut(pDevice, MESSAGE_TYPE_WRITE_MASK, reg_off,
+ reg_type, ARRAY_SIZE(reg_data), reg_data);
+
+ return;
+}
diff --git a/drivers/staging/vt6656/control.h b/drivers/staging/vt6656/control.h
new file mode 100644
index 00000000..9da9b96a
--- /dev/null
+++ b/drivers/staging/vt6656/control.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: control.h
+ *
+ * Purpose:
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Apr. 5, 2004
+ *
+ */
+
+#ifndef __CONTROL_H__
+#define __CONTROL_H__
+
+#include "device.h"
+#include "usbpipe.h"
+
+#define CONTROLnsRequestOut(Device, Request, Value, Index, Length, Buffer) \
+ PIPEnsControlOut(Device, Request, Value, Index, Length, Buffer)
+
+#define CONTROLnsRequestOutAsyn(Device, Request, Value, Index, Length, Buffer) \
+ PIPEnsControlOutAsyn(Device, Request, Value, Index, Length, Buffer)
+
+#define CONTROLnsRequestIn(Device, Request, Value, Index, Length, Buffer) \
+ PIPEnsControlIn(Device, Request, Value, Index, Length, Buffer)
+
+void ControlvWriteByte(struct vnt_private *pDevice, u8 reg, u8 reg_off,
+ u8 data);
+
+void ControlvReadByte(struct vnt_private *pDevice, u8 reg, u8 reg_off,
+ u8 *data);
+
+void ControlvMaskByte(struct vnt_private *pDevice, u8 reg_type, u8 reg_off,
+ u8 reg_mask, u8 data);
+
+#endif /* __CONTROL_H__ */
diff --git a/drivers/staging/vt6656/country.h b/drivers/staging/vt6656/country.h
new file mode 100644
index 00000000..a0320d8f
--- /dev/null
+++ b/drivers/staging/vt6656/country.h
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: country.h
+ *
+ * Purpose: Country Code information
+ *
+ * Author: Lucas Lin
+ *
+ * Date: Dec 23, 2004
+ *
+ */
+
+#ifndef __COUNTRY_H__
+#define __COUNTRY_H__
+
+/************************************************************************
+ * The definition here should be complied with the INF country order
+ * Please check with VNWL.inf/VNWL64.inf/VNWL*.inf
+ ************************************************************************/
+typedef enum _COUNTRY_CODE {
+ CCODE_FCC = 0,
+ CCODE_TELEC,
+ CCODE_ETSI,
+ CCODE_RESV3,
+ CCODE_RESV4,
+ CCODE_RESV5,
+ CCODE_RESV6,
+ CCODE_RESV7,
+ CCODE_RESV8,
+ CCODE_RESV9,
+ CCODE_RESVa,
+ CCODE_RESVb,
+ CCODE_RESVc,
+ CCODE_RESVd,
+ CCODE_RESVe,
+ CCODE_ALLBAND,
+ CCODE_ALBANIA,
+ CCODE_ALGERIA,
+ CCODE_ARGENTINA,
+ CCODE_ARMENIA,
+ CCODE_AUSTRALIA,
+ CCODE_AUSTRIA,
+ CCODE_AZERBAIJAN,
+ CCODE_BAHRAIN,
+ CCODE_BELARUS,
+ CCODE_BELGIUM,
+ CCODE_BELIZE,
+ CCODE_BOLIVIA,
+ CCODE_BRAZIL,
+ CCODE_BRUNEI_DARUSSALAM,
+ CCODE_BULGARIA,
+ CCODE_CANADA,
+ CCODE_CHILE,
+ CCODE_CHINA,
+ CCODE_COLOMBIA,
+ CCODE_COSTA_RICA,
+ CCODE_CROATIA,
+ CCODE_CYPRUS,
+ CCODE_CZECH,
+ CCODE_DENMARK,
+ CCODE_DOMINICAN_REPUBLIC,
+ CCODE_ECUADOR,
+ CCODE_EGYPT,
+ CCODE_EL_SALVADOR,
+ CCODE_ESTONIA,
+ CCODE_FINLAND,
+ CCODE_FRANCE,
+ CCODE_GERMANY,
+ CCODE_GREECE,
+ CCODE_GEORGIA,
+ CCODE_GUATEMALA,
+ CCODE_HONDURAS,
+ CCODE_HONG_KONG,
+ CCODE_HUNGARY,
+ CCODE_ICELAND,
+ CCODE_INDIA,
+ CCODE_INDONESIA,
+ CCODE_IRAN,
+ CCODE_IRELAND,
+ CCODE_ITALY,
+ CCODE_ISRAEL,
+ CCODE_JAPAN,
+ CCODE_JORDAN,
+ CCODE_KAZAKHSTAN,
+ CCODE_KUWAIT,
+ CCODE_LATVIA,
+ CCODE_LEBANON,
+ CCODE_LEICHTENSTEIN,
+ CCODE_LITHUANIA,
+ CCODE_LUXEMBURG,
+ CCODE_MACAU,
+ CCODE_MACEDONIA,
+ CCODE_MALTA,
+ CCODE_MALAYSIA,
+ CCODE_MEXICO,
+ CCODE_MONACO,
+ CCODE_MOROCCO,
+ CCODE_NETHERLANDS,
+ CCODE_NEW_ZEALAND,
+ CCODE_NORTH_KOREA,
+ CCODE_NORWAY,
+ CCODE_OMAN,
+ CCODE_PAKISTAN,
+ CCODE_PANAMA,
+ CCODE_PERU,
+ CCODE_PHILIPPINES,
+ CCODE_POLAND,
+ CCODE_PORTUGAL,
+ CCODE_PUERTO_RICO,
+ CCODE_QATAR,
+ CCODE_ROMANIA,
+ CCODE_RUSSIA,
+ CCODE_SAUDI_ARABIA,
+ CCODE_SINGAPORE,
+ CCODE_SLOVAKIA,
+ CCODE_SLOVENIA,
+ CCODE_SOUTH_AFRICA,
+ CCODE_SOUTH_KOREA,
+ CCODE_SPAIN,
+ CCODE_SWEDEN,
+ CCODE_SWITZERLAND,
+ CCODE_SYRIA,
+ CCODE_TAIWAN,
+ CCODE_THAILAND,
+ CCODE_TRINIDAD_TOBAGO,
+ CCODE_TUNISIA,
+ CCODE_TURKEY,
+ CCODE_UK,
+ CCODE_UKRAINE,
+ CCODE_UNITED_ARAB_EMIRATES,
+ CCODE_UNITED_STATES,
+ CCODE_URUGUAY,
+ CCODE_UZBEKISTAN,
+ CCODE_VENEZUELA,
+ CCODE_VIETNAM,
+ CCODE_YEMEN,
+ CCODE_ZIMBABWE,
+ CCODE_JAPAN_W52_W53,
+ CCODE_MAX
+} COUNTRY_CODE;
+
+/************************************************************************
+ * Function prototype
+ ************************************************************************/
+#endif /* __COUNTRY_H__ */
diff --git a/drivers/staging/vt6656/datarate.c b/drivers/staging/vt6656/datarate.c
new file mode 100644
index 00000000..17fbc35e
--- /dev/null
+++ b/drivers/staging/vt6656/datarate.c
@@ -0,0 +1,371 @@
+/*
+ * 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:
+ *
+ */
+
+#include "tmacro.h"
+#include "mac.h"
+#include "80211mgr.h"
+#include "bssdb.h"
+#include "datarate.h"
+#include "card.h"
+#include "baseband.h"
+#include "srom.h"
+#include "rf.h"
+
+/* static int msglevel = MSG_LEVEL_DEBUG; */
+static int msglevel =MSG_LEVEL_INFO;
+const u8 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
+
+void s_vResetCounter(PKnownNodeDB psNodeDBTable);
+
+void s_vResetCounter(PKnownNodeDB psNodeDBTable)
+{
+ u8 ii;
+
+ /* clear statistics counter for auto_rate */
+ for (ii = 0; ii <= MAX_RATE; ii++) {
+ psNodeDBTable->uTxOk[ii] = 0;
+ psNodeDBTable->uTxFail[ii] = 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:
+ * u8 - Rate value in SuppRates IE or ExtSuppRates IE
+ * Out:
+ * none
+ *
+ * Return Value: RateIdx
+ *
+-*/
+u16
+RATEwGetRateIdx(
+ u8 byRate
+ )
+{
+ u16 ii;
+
+ /* erase BasicRate flag */
+ byRate = byRate & 0x7F;
+
+ 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(struct vnt_private *pDevice,
+ PWLAN_IE_SUPP_RATES pItemRates, PWLAN_IE_SUPP_RATES pItemExtRates,
+ int bUpdateBasicRate, u16 *pwMaxBasicRate, u16 *pwMaxSuppRate,
+ u16 *pwSuppRate, u8 *pbyTopCCKRate, u8 *pbyTopOFDMRate)
+{
+ int ii;
+ u8 byHighSuppRate = 0, byRate = 0;
+ u16 wOldBasicRate = pDevice->wBasicRate;
+ u32 uRateLen;
+
+ if (pItemRates == NULL)
+ return;
+
+ *pwSuppRate = 0;
+ uRateLen = pItemRates->len;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ParseMaxRate Len: %d\n", uRateLen);
+ if (pDevice->byBBType != BB_TYPE_11B) {
+ if (uRateLen > WLAN_RATES_MAXLEN)
+ uRateLen = WLAN_RATES_MAXLEN;
+ } else {
+ if (uRateLen > WLAN_RATES_MAXLEN_11B)
+ uRateLen = WLAN_RATES_MAXLEN_11B;
+ }
+
+ for (ii = 0; ii < uRateLen; ii++) {
+ byRate = (u8)(pItemRates->abyRates[ii]);
+ if (WLAN_MGMT_IS_BASICRATE(byRate) &&
+ (bUpdateBasicRate == true)) {
+ /*
+ * add to basic rate set, update pDevice->byTopCCKBasicRate and
+ * pDevice->byTopOFDMBasicRate
+ */
+ CARDbAddBasicRate((void *)pDevice, RATEwGetRateIdx(byRate));
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ParseMaxRate AddBasicRate: %d\n", RATEwGetRateIdx(byRate));
+ }
+ byRate = (u8)(pItemRates->abyRates[ii]&0x7F);
+ if (byHighSuppRate == 0)
+ byHighSuppRate = byRate;
+ if (byRate > byHighSuppRate)
+ byHighSuppRate = byRate;
+ *pwSuppRate |= (1<<RATEwGetRateIdx(byRate));
+ }
+ if ((pItemExtRates != NULL) && (pItemExtRates->byElementID == WLAN_EID_EXTSUPP_RATES) &&
+ (pDevice->byBBType != BB_TYPE_11B)) {
+
+ unsigned int uExtRateLen = pItemExtRates->len;
+
+ if (uExtRateLen > WLAN_RATES_MAXLEN)
+ uExtRateLen = WLAN_RATES_MAXLEN;
+
+ for (ii = 0; ii < uExtRateLen ; ii++) {
+ byRate = (u8)(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((void *)pDevice, RATEwGetRateIdx(byRate));
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ParseMaxRate AddBasicRate: %d\n", RATEwGetRateIdx(byRate));
+ }
+ byRate = (u8)(pItemExtRates->abyRates[ii]&0x7F);
+ if (byHighSuppRate == 0)
+ byHighSuppRate = byRate;
+ if (byRate > byHighSuppRate)
+ byHighSuppRate = byRate;
+ *pwSuppRate |= (1<<RATEwGetRateIdx(byRate));
+
+ /* DBG_PRN_GRP09(("ParseMaxRate : HighSuppRate: %d, %X\n",
+ RATEwGetRateIdx(byRate), byRate)); */
+ }
+ }
+
+ if ((pDevice->byPacketType == PK_TYPE_11GB)
+ && CARDbIsOFDMinBasicRate((void *)pDevice)) {
+ pDevice->byPacketType = PK_TYPE_11GA;
+ }
+
+ *pbyTopCCKRate = pDevice->byTopCCKBasicRate;
+ *pbyTopOFDMRate = pDevice->byTopOFDMBasicRate;
+ *pwMaxSuppRate = RATEwGetRateIdx(byHighSuppRate);
+ if ((pDevice->byPacketType==PK_TYPE_11B) || (pDevice->byPacketType==PK_TYPE_11GB))
+ *pwMaxBasicRate = pDevice->byTopCCKBasicRate;
+ else
+ *pwMaxBasicRate = pDevice->byTopOFDMBasicRate;
+ if (wOldBasicRate != pDevice->wBasicRate)
+ CARDvSetRSPINF((void *)pDevice, pDevice->byBBType);
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Exit ParseMaxRate\n");
+}
+
+/*+
+ *
+ * Routine Description:
+ * Rate fallback Algorithm Implementaion
+ *
+ * Parameters:
+ * In:
+ * pDevice - Pointer to the adapter
+ * psNodeDBTable - Pointer to Node Data Base
+ * Out:
+ * none
+ *
+ * Return Value: none
+ *
+-*/
+#define AUTORATE_TXCNT_THRESHOLD 20
+#define AUTORATE_INC_THRESHOLD 30
+
+void RATEvTxRateFallBack(struct vnt_private *pDevice,
+ PKnownNodeDB psNodeDBTable)
+{
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ u16 wIdxDownRate = 0;
+ int ii;
+ int bAutoRate[MAX_RATE] = {true, true, true, true, false, false, true,
+ true, true, true, true, true};
+ u32 dwThroughputTbl[MAX_RATE] = {10, 20, 55, 110, 60, 90, 120, 180,
+ 240, 360, 480, 540};
+ u32 dwThroughput = 0;
+ u16 wIdxUpRate = 0;
+ u32 dwTxDiff = 0;
+
+ if (pMgmt->eScanState != WMAC_NO_SCANNING)
+ return; /* Don't do Fallback when scanning Channel */
+
+ 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 = (u16) ii;
+ }
+ } else {
+ bAutoRate[ii] = false;
+ }
+ }
+
+ for (ii = 0; ii <= psNodeDBTable->wTxDataRate; ii++) {
+ if ( (psNodeDBTable->uTxOk[ii] != 0) ||
+ (psNodeDBTable->uTxFail[ii] != 0) ) {
+ dwThroughputTbl[ii] *= psNodeDBTable->uTxOk[ii];
+ if (ii < RATE_11M) {
+ psNodeDBTable->uTxFail[ii] *= 4;
+ }
+ dwThroughputTbl[ii] /= (psNodeDBTable->uTxOk[ii] + psNodeDBTable->uTxFail[ii]);
+ }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Rate %d,Ok: %d, Fail:%d, Throughput:%d\n",
+ ii, (int)psNodeDBTable->uTxOk[ii], (int)psNodeDBTable->uTxFail[ii], (int)dwThroughputTbl[ii]);
+ }
+ dwThroughput = dwThroughputTbl[psNodeDBTable->wTxDataRate];
+
+ wIdxDownRate = psNodeDBTable->wTxDataRate;
+ for (ii = psNodeDBTable->wTxDataRate; ii > 0;) {
+ ii--;
+ if ( (dwThroughputTbl[ii] > dwThroughput) &&
+ (bAutoRate[ii]==true) ) {
+ dwThroughput = dwThroughputTbl[ii];
+ wIdxDownRate = (u16) ii;
+ }
+ }
+ psNodeDBTable->wTxDataRate = wIdxDownRate;
+ if (psNodeDBTable->uTxOk[MAX_RATE]) {
+ if (psNodeDBTable->uTxOk[MAX_RATE] >
+ (psNodeDBTable->uTxFail[MAX_RATE] * 4) ) {
+ psNodeDBTable->wTxDataRate = wIdxUpRate;
+ }
+ } else { /* adhoc, if uTxOk(total) == 0 & uTxFail(total) == 0 */
+ if (psNodeDBTable->uTxFail[MAX_RATE] == 0)
+ psNodeDBTable->wTxDataRate = wIdxUpRate;
+ }
+
+ if (pDevice->byBBType == BB_TYPE_11A) {
+ if (psNodeDBTable->wTxDataRate <= RATE_11M)
+ psNodeDBTable->wTxDataRate = RATE_6M;
+ }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"uTxOk[MAX_RATE] %d, uTxFail[MAX_RATE]:%d\n",(int)psNodeDBTable->uTxOk[MAX_RATE], (int)psNodeDBTable->uTxFail[MAX_RATE]);
+ s_vResetCounter(psNodeDBTable);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Rate: %d, U:%d, D:%d\n", (int)psNodeDBTable->wTxDataRate, (int)wIdxUpRate, (int)wIdxDownRate);
+ return;
+}
+
+/*+
+ *
+ * Description:
+ * This routine is used to assemble available Rate IE.
+ *
+ * Parameters:
+ * In:
+ * pDevice
+ * Out:
+ *
+ * Return Value: None
+ *
+-*/
+u8
+RATEuSetIE (
+ PWLAN_IE_SUPP_RATES pSrcRates,
+ PWLAN_IE_SUPP_RATES pDstRates,
+ unsigned int uRateLen
+ )
+{
+ unsigned int 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 (u8)uRateCnt;
+}
+
diff --git a/drivers/staging/vt6656/datarate.h b/drivers/staging/vt6656/datarate.h
new file mode 100644
index 00000000..43cb7789
--- /dev/null
+++ b/drivers/staging/vt6656/datarate.h
@@ -0,0 +1,77 @@
+/*
+ * 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__
+
+#define FALLBACK_PKT_COLLECT_TR_H 50 /* pkts */
+#define FALLBACK_PKT_COLLECT_TR_L 10 /* pkts */
+#define FALLBACK_POLL_SECOND 5 /* 5 sec */
+#define FALLBACK_RECOVER_SECOND 30 /* 30 sec */
+#define FALLBACK_THRESHOLD 15 /* percent */
+#define UPGRADE_THRESHOLD 5 /* percent */
+#define UPGRADE_CNT_THRD 3 /* times */
+#define RETRY_TIMES_THRD_H 2 /* times */
+#define RETRY_TIMES_THRD_L 1 /* times */
+
+#define RATE_1M 0
+#define RATE_2M 1
+#define RATE_5M 2
+#define RATE_11M 3
+#define RATE_6M 4
+#define RATE_9M 5
+#define RATE_12M 6
+#define RATE_18M 7
+#define RATE_24M 8
+#define RATE_36M 9
+#define RATE_48M 10
+#define RATE_54M 11
+#define RATE_AUTO 12
+#define MAX_RATE 12
+
+void RATEvParseMaxRate(struct vnt_private *, PWLAN_IE_SUPP_RATES pItemRates,
+ PWLAN_IE_SUPP_RATES pItemExtRates, int bUpdateBasicRate,
+ u16 *pwMaxBasicRate, u16 *pwMaxSuppRate, u16 *pwSuppRate,
+ u8 *pbyTopCCKRate, u8 *pbyTopOFDMRate);
+
+void RATEvTxRateFallBack(struct vnt_private *pDevice,
+ PKnownNodeDB psNodeDBTable);
+
+u8
+RATEuSetIE(
+ PWLAN_IE_SUPP_RATES pSrcRates,
+ PWLAN_IE_SUPP_RATES pDstRates,
+ unsigned int uRateLen
+ );
+
+u16
+RATEwGetRateIdx(
+ u8 byRate
+ );
+
+#endif /* __DATARATE_H__ */
diff --git a/drivers/staging/vt6656/desc.h b/drivers/staging/vt6656/desc.h
new file mode 100644
index 00000000..64cb046f
--- /dev/null
+++ b/drivers/staging/vt6656/desc.h
@@ -0,0 +1,416 @@
+/*
+ * 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>
+
+#include "tether.h"
+
+/* max transmit or receive buffer size */
+#define CB_MAX_BUF_SIZE 2900U /* NOTE: must be multiple of 4 */
+
+/* max TX buffer size */
+#define CB_MAX_TX_BUF_SIZE CB_MAX_BUF_SIZE
+/* max RX buffer size when not use Multi-RD */
+#define CB_MAX_RX_BUF_SIZE_NORMAL CB_MAX_BUF_SIZE
+
+#define CB_BEACON_BUF_SIZE 512U /* default beacon buffer size */
+
+#define MAX_TOTAL_SIZE_WITH_ALL_HEADERS CB_MAX_BUF_SIZE
+
+#define MAX_INTERRUPT_SIZE 32
+
+#define RX_BLOCKS 64 /* from 0x60 to 0xA0 */
+#define TX_BLOCKS 32 /* from 0xA0 to 0xC0 */
+
+#define CB_MAX_RX_DESC 128 /* max # of descriptors */
+#define CB_MIN_RX_DESC 16 /* min # of RX descriptors */
+#define CB_MAX_TX_DESC 128 /* max # of descriptors */
+#define CB_MIN_TX_DESC 16 /* min # of TX descriptors */
+
+#define CB_RD_NUM 64 /* default # of RD */
+#define CB_TD_NUM 64 /* default # of TD */
+
+/*
+ * bits in the RSR register
+ */
+#define RSR_ADDRBROAD 0x80
+#define RSR_ADDRMULTI 0x40
+#define RSR_ADDRUNI 0x00
+#define RSR_IVLDTYP 0x20 /* invalid packet type */
+#define RSR_IVLDLEN 0x10 /* invalid len (> 2312 byte) */
+#define RSR_BSSIDOK 0x08
+#define RSR_CRCOK 0x04
+#define RSR_BCNSSIDOK 0x02
+#define RSR_ADDROK 0x01
+
+/*
+ * bits in the new RSR register
+ */
+#define NEWRSR_DECRYPTOK 0x10
+#define NEWRSR_CFPIND 0x08
+#define NEWRSR_HWUTSF 0x04
+#define NEWRSR_BCNHITAID 0x02
+#define NEWRSR_BCNHITAID0 0x01
+
+/*
+ * bits in the TSR register
+ */
+#define TSR_RETRYTMO 0x08
+#define TSR_TMO 0x04
+#define TSR_ACKDATA 0x02
+#define TSR_VALID 0x01
+
+#define CB_PROTOCOL_RESERVED_SECTION 16
+
+/*
+ * if retries exceed 15 times, TX will abort, and
+ * if TX fifo underflow, TX will fail
+ * we should try to resend it
+ */
+#define CB_MAX_TX_ABORT_RETRY 3
+
+#define FIFOCTL_AUTO_FB_1 0x1000
+#define FIFOCTL_AUTO_FB_0 0x0800
+#define FIFOCTL_GRPACK 0x0400
+#define FIFOCTL_11GA 0x0300
+#define FIFOCTL_11GB 0x0200
+#define FIFOCTL_11B 0x0100
+#define FIFOCTL_11A 0x0000
+#define FIFOCTL_RTS 0x0080
+#define FIFOCTL_ISDMA0 0x0040
+#define FIFOCTL_GENINT 0x0020
+#define FIFOCTL_TMOEN 0x0010
+#define FIFOCTL_LRETRY 0x0008
+#define FIFOCTL_CRCDIS 0x0004
+#define FIFOCTL_NEEDACK 0x0002
+#define FIFOCTL_LHEAD 0x0001
+
+/* WMAC definition Frag Control */
+#define FRAGCTL_AES 0x0300
+#define FRAGCTL_TKIP 0x0200
+#define FRAGCTL_LEGACY 0x0100
+#define FRAGCTL_NONENCRYPT 0x0000
+#define FRAGCTL_ENDFRAG 0x0003
+#define FRAGCTL_MIDFRAG 0x0002
+#define FRAGCTL_STAFRAG 0x0001
+#define FRAGCTL_NONFRAG 0x0000
+
+#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 */
+
+/*
+ * RsvTime buffer header
+ */
+typedef struct tagSRrvTime_gRTS {
+ u16 wRTSTxRrvTime_ba;
+ u16 wRTSTxRrvTime_aa;
+ u16 wRTSTxRrvTime_bb;
+ u16 wReserved;
+ u16 wTxRrvTime_b;
+ u16 wTxRrvTime_a;
+} __attribute__ ((__packed__))
+SRrvTime_gRTS, *PSRrvTime_gRTS;
+
+typedef const SRrvTime_gRTS *PCSRrvTime_gRTS;
+
+typedef struct tagSRrvTime_gCTS {
+ u16 wCTSTxRrvTime_ba;
+ u16 wReserved;
+ u16 wTxRrvTime_b;
+ u16 wTxRrvTime_a;
+} __attribute__ ((__packed__))
+SRrvTime_gCTS, *PSRrvTime_gCTS;
+
+typedef const SRrvTime_gCTS *PCSRrvTime_gCTS;
+
+typedef struct tagSRrvTime_ab {
+ u16 wRTSTxRrvTime;
+ u16 wTxRrvTime;
+} __attribute__ ((__packed__))
+SRrvTime_ab, *PSRrvTime_ab;
+
+typedef const SRrvTime_ab *PCSRrvTime_ab;
+
+typedef struct tagSRrvTime_atim {
+ u16 wCTSTxRrvTime_ba;
+ u16 wTxRrvTime_a;
+} __attribute__ ((__packed__))
+SRrvTime_atim, *PSRrvTime_atim;
+
+typedef const SRrvTime_atim *PCSRrvTime_atim;
+
+/*
+ * RTS buffer header
+ */
+typedef struct tagSRTSData {
+ u16 wFrameControl;
+ u16 wDurationID;
+ u8 abyRA[ETH_ALEN];
+ u8 abyTA[ETH_ALEN];
+} __attribute__ ((__packed__))
+SRTSData, *PSRTSData;
+
+typedef const SRTSData *PCSRTSData;
+
+typedef struct tagSRTS_g {
+ u8 bySignalField_b;
+ u8 byServiceField_b;
+ u16 wTransmitLength_b;
+ u8 bySignalField_a;
+ u8 byServiceField_a;
+ u16 wTransmitLength_a;
+ u16 wDuration_ba;
+ u16 wDuration_aa;
+ u16 wDuration_bb;
+ u16 wReserved;
+ SRTSData Data;
+} __attribute__ ((__packed__))
+SRTS_g, *PSRTS_g;
+typedef const SRTS_g *PCSRTS_g;
+
+typedef struct tagSRTS_g_FB {
+ u8 bySignalField_b;
+ u8 byServiceField_b;
+ u16 wTransmitLength_b;
+ u8 bySignalField_a;
+ u8 byServiceField_a;
+ u16 wTransmitLength_a;
+ u16 wDuration_ba;
+ u16 wDuration_aa;
+ u16 wDuration_bb;
+ u16 wReserved;
+ u16 wRTSDuration_ba_f0;
+ u16 wRTSDuration_aa_f0;
+ u16 wRTSDuration_ba_f1;
+ u16 wRTSDuration_aa_f1;
+ SRTSData Data;
+} __attribute__ ((__packed__))
+SRTS_g_FB, *PSRTS_g_FB;
+
+typedef const SRTS_g_FB *PCSRTS_g_FB;
+
+typedef struct tagSRTS_ab {
+ u8 bySignalField;
+ u8 byServiceField;
+ u16 wTransmitLength;
+ u16 wDuration;
+ u16 wReserved;
+ SRTSData Data;
+} __attribute__ ((__packed__))
+SRTS_ab, *PSRTS_ab;
+
+typedef const SRTS_ab *PCSRTS_ab;
+
+typedef struct tagSRTS_a_FB {
+ u8 bySignalField;
+ u8 byServiceField;
+ u16 wTransmitLength;
+ u16 wDuration;
+ u16 wReserved;
+ u16 wRTSDuration_f0;
+ u16 wRTSDuration_f1;
+ SRTSData Data;
+} __attribute__ ((__packed__))
+SRTS_a_FB, *PSRTS_a_FB;
+
+typedef const SRTS_a_FB *PCSRTS_a_FB;
+
+/*
+ * CTS buffer header
+ */
+typedef struct tagSCTSData {
+ u16 wFrameControl;
+ u16 wDurationID;
+ u8 abyRA[ETH_ALEN];
+ u16 wReserved;
+} __attribute__ ((__packed__))
+SCTSData, *PSCTSData;
+
+typedef struct tagSCTS {
+ u8 bySignalField_b;
+ u8 byServiceField_b;
+ u16 wTransmitLength_b;
+ u16 wDuration_ba;
+ u16 wReserved;
+ SCTSData Data;
+} __attribute__ ((__packed__))
+SCTS, *PSCTS;
+
+typedef const SCTS *PCSCTS;
+
+typedef struct tagSCTS_FB {
+ u8 bySignalField_b;
+ u8 byServiceField_b;
+ u16 wTransmitLength_b;
+ u16 wDuration_ba;
+ u16 wReserved;
+ u16 wCTSDuration_ba_f0;
+ u16 wCTSDuration_ba_f1;
+ SCTSData Data;
+} __attribute__ ((__packed__))
+SCTS_FB, *PSCTS_FB;
+
+typedef const SCTS_FB *PCSCTS_FB;
+
+/*
+ * TX FIFO header
+ */
+typedef struct tagSTxBufHead {
+ u32 adwTxKey[4];
+ u16 wFIFOCtl;
+ u16 wTimeStamp;
+ u16 wFragCtl;
+ u16 wReserved;
+} __attribute__ ((__packed__))
+STxBufHead, *PSTxBufHead;
+typedef const STxBufHead *PCSTxBufHead;
+
+typedef struct tagSTxShortBufHead {
+ u16 wFIFOCtl;
+ u16 wTimeStamp;
+} __attribute__ ((__packed__))
+STxShortBufHead, *PSTxShortBufHead;
+typedef const STxShortBufHead *PCSTxShortBufHead;
+
+/*
+ * TX data header
+ */
+typedef struct tagSTxDataHead_g {
+ u8 bySignalField_b;
+ u8 byServiceField_b;
+ u16 wTransmitLength_b;
+ u8 bySignalField_a;
+ u8 byServiceField_a;
+ u16 wTransmitLength_a;
+ u16 wDuration_b;
+ u16 wDuration_a;
+ u16 wTimeStampOff_b;
+ u16 wTimeStampOff_a;
+} __attribute__ ((__packed__))
+STxDataHead_g, *PSTxDataHead_g;
+
+typedef const STxDataHead_g *PCSTxDataHead_g;
+
+typedef struct tagSTxDataHead_g_FB {
+ u8 bySignalField_b;
+ u8 byServiceField_b;
+ u16 wTransmitLength_b;
+ u8 bySignalField_a;
+ u8 byServiceField_a;
+ u16 wTransmitLength_a;
+ u16 wDuration_b;
+ u16 wDuration_a;
+ u16 wDuration_a_f0;
+ u16 wDuration_a_f1;
+ u16 wTimeStampOff_b;
+ u16 wTimeStampOff_a;
+} __attribute__ ((__packed__))
+STxDataHead_g_FB, *PSTxDataHead_g_FB;
+typedef const STxDataHead_g_FB *PCSTxDataHead_g_FB;
+
+typedef struct tagSTxDataHead_ab {
+ u8 bySignalField;
+ u8 byServiceField;
+ u16 wTransmitLength;
+ u16 wDuration;
+ u16 wTimeStampOff;
+} __attribute__ ((__packed__))
+STxDataHead_ab, *PSTxDataHead_ab;
+typedef const STxDataHead_ab *PCSTxDataHead_ab;
+
+typedef struct tagSTxDataHead_a_FB {
+ u8 bySignalField;
+ u8 byServiceField;
+ u16 wTransmitLength;
+ u16 wDuration;
+ u16 wTimeStampOff;
+ u16 wDuration_f0;
+ u16 wDuration_f1;
+} __attribute__ ((__packed__))
+STxDataHead_a_FB, *PSTxDataHead_a_FB;
+typedef const STxDataHead_a_FB *PCSTxDataHead_a_FB;
+
+/*
+ * MICHDR data header
+ */
+typedef struct tagSMICHDRHead {
+ u32 adwHDR0[4];
+ u32 adwHDR1[4];
+ u32 adwHDR2[4];
+} __attribute__ ((__packed__))
+SMICHDRHead, *PSMICHDRHead;
+
+typedef const SMICHDRHead *PCSMICHDRHead;
+
+typedef struct tagSBEACONCtl {
+ u32 BufReady:1;
+ u32 TSF:15;
+ u32 BufLen:11;
+ u32 Reserved:5;
+} __attribute__ ((__packed__))
+SBEACONCtl;
+
+typedef struct tagSSecretKey {
+ u32 dwLowDword;
+ u8 byHighByte;
+} __attribute__ ((__packed__))
+SSecretKey;
+
+typedef struct tagSKeyEntry {
+ u8 abyAddrHi[2];
+ u16 wKCTL;
+ u8 abyAddrLo[4];
+ u32 dwKey0[4];
+ u32 dwKey1[4];
+ u32 dwKey2[4];
+ u32 dwKey3[4];
+ u32 dwKey4[4];
+} __attribute__ ((__packed__))
+SKeyEntry;
+
+#endif /* __DESC_H__ */
diff --git a/drivers/staging/vt6656/device.h b/drivers/staging/vt6656/device.h
new file mode 100644
index 00000000..f07ba242
--- /dev/null
+++ b/drivers/staging/vt6656/device.h
@@ -0,0 +1,820 @@
+/*
+ * 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__
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/firmware.h>
+#include <linux/etherdevice.h>
+#include <linux/suspend.h>
+#include <linux/if_arp.h>
+#include <linux/wireless.h>
+#include <net/iw_handler.h>
+#include <net/cfg80211.h>
+#include <linux/timer.h>
+#include <linux/usb.h>
+
+#ifdef SIOCETHTOOL
+#define DEVICE_ETHTOOL_IOCTL_SUPPORT
+#include <linux/ethtool.h>
+#else
+#undef DEVICE_ETHTOOL_IOCTL_SUPPORT
+#endif
+
+/* please copy below macro to driver_event.c for API */
+#define RT_INSMOD_EVENT_FLAG 0x0101
+#define RT_UPDEV_EVENT_FLAG 0x0102
+#define RT_DISCONNECTED_EVENT_FLAG 0x0103
+#define RT_WPACONNECTED_EVENT_FLAG 0x0104
+#define RT_DOWNDEV_EVENT_FLAG 0x0105
+#define RT_RMMOD_EVENT_FLAG 0x0106
+
+/*
+ * device specific
+ */
+
+#include "device_cfg.h"
+#include "80211hdr.h"
+#include "tether.h"
+#include "wmgr.h"
+#include "wcmd.h"
+#include "mib.h"
+#include "srom.h"
+#include "rc4.h"
+#include "desc.h"
+#include "key.h"
+#include "card.h"
+
+#define VNT_USB_VENDOR_ID 0x160a
+#define VNT_USB_PRODUCT_ID 0x3184
+
+#define MAC_MAX_CONTEXT_REG (256+128)
+
+#define MAX_MULTICAST_ADDRESS_NUM 32
+#define MULTICAST_ADDRESS_LIST_SIZE (MAX_MULTICAST_ADDRESS_NUM * ETH_ALEN)
+
+#define DUPLICATE_RX_CACHE_LENGTH 5
+
+#define NUM_KEY_ENTRY 11
+
+#define TX_WEP_NONE 0
+#define TX_WEP_OTF 1
+#define TX_WEP_SW 2
+#define TX_WEP_SWOTP 3
+#define TX_WEP_OTPSW 4
+#define TX_WEP_SW232 5
+
+#define KEYSEL_WEP40 0
+#define KEYSEL_WEP104 1
+#define KEYSEL_TKIP 2
+#define KEYSEL_CCMP 3
+
+#define AUTO_FB_NONE 0
+#define AUTO_FB_0 1
+#define AUTO_FB_1 2
+
+#define FB_RATE0 0
+#define FB_RATE1 1
+
+/* Antenna Mode */
+#define ANT_A 0
+#define ANT_B 1
+#define ANT_DIVERSITY 2
+#define ANT_RXD_TXA 3
+#define ANT_RXD_TXB 4
+#define ANT_UNKNOWN 0xFF
+#define ANT_TXA 0
+#define ANT_TXB 1
+#define ANT_RXA 2
+#define ANT_RXB 3
+
+#define MAXCHECKHANGCNT 4
+
+/* Packet type */
+#define TX_PKT_UNI 0x00
+#define TX_PKT_MULTI 0x01
+#define TX_PKT_BROAD 0x02
+
+#define BB_VGA_LEVEL 4
+#define BB_VGA_CHANGE_THRESHOLD 3
+
+#ifndef RUN_AT
+#define RUN_AT(x) (jiffies+(x))
+#endif
+
+/* DMA related */
+#define RESERV_AC0DMA 4
+
+#define PRIVATE_Message 0
+
+#define DBG_PRT(l, p, args...) { if (l <= msglevel) printk(p, ##args); }
+#define PRINT_K(p, args...) { if (PRIVATE_Message) printk(p, ##args); }
+
+typedef enum __device_msg_level {
+ MSG_LEVEL_ERR = 0, /* Errors causing abnormal operation */
+ MSG_LEVEL_NOTICE = 1, /* Errors needing user notification */
+ 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 */
+ DEVICE_INIT_DXPL /* Dx to D0 power lost init */
+} DEVICE_INIT_TYPE, *PDEVICE_INIT_TYPE;
+
+/* USB */
+
+/*
+ * Enum of context types for SendPacket
+ */
+typedef enum _CONTEXT_TYPE {
+ CONTEXT_DATA_PACKET = 1,
+ CONTEXT_MGMT_PACKET
+} CONTEXT_TYPE;
+
+/* RCB (Receive Control Block) */
+typedef struct _RCB
+{
+ void *Next;
+ signed long Ref;
+ void *pDevice;
+ struct urb *pUrb;
+ struct vnt_rx_mgmt sMngPacket;
+ struct sk_buff *skb;
+ int bBoolInUse;
+
+} RCB, *PRCB;
+
+/* used to track bulk out irps */
+typedef struct _USB_SEND_CONTEXT {
+ void *pDevice;
+ struct sk_buff *pPacket;
+ struct urb *pUrb;
+ unsigned int uBufLen;
+ CONTEXT_TYPE Type;
+ struct ethhdr sEthHeader;
+ void *Next;
+ bool bBoolInUse;
+ unsigned char Data[MAX_TOTAL_SIZE_WITH_ALL_HEADERS];
+} USB_SEND_CONTEXT, *PUSB_SEND_CONTEXT;
+
+/* structure got from configuration file as user-desired default settings */
+typedef struct _DEFAULT_CONFIG {
+ signed int ZoneType;
+ signed int eConfigMode;
+ signed int eAuthenMode; /* open/wep/wpa */
+ signed int bShareKeyAlgorithm; /* open-open/{open,wep}-sharekey */
+ signed int keyidx; /* wepkey index */
+ signed int eEncryptionStatus;
+} DEFAULT_CONFIG, *PDEFAULT_CONFIG;
+
+/*
+ * Structure to keep track of USB interrupt packets
+ */
+typedef struct {
+ unsigned int uDataLen;
+ u8 * pDataBuf;
+ /* struct urb *pUrb; */
+ bool bInUse;
+} INT_BUFFER, *PINT_BUFFER;
+
+/* 0:11A 1:11B 2:11G */
+typedef enum _VIA_BB_TYPE
+{
+ BB_TYPE_11A = 0,
+ BB_TYPE_11B,
+ BB_TYPE_11G
+} VIA_BB_TYPE, *PVIA_BB_TYPE;
+
+/* 0:11a, 1:11b, 2:11gb (only CCK in BasicRate), 3:11ga(OFDM in BasicRate) */
+typedef enum _VIA_PKT_TYPE
+{
+ PK_TYPE_11A = 0,
+ PK_TYPE_11B,
+ PK_TYPE_11GB,
+ PK_TYPE_11GA
+} VIA_PKT_TYPE, *PVIA_PKT_TYPE;
+
+/*++ NDIS related */
+
+typedef enum __DEVICE_NDIS_STATUS {
+ STATUS_SUCCESS = 0,
+ STATUS_FAILURE,
+ STATUS_RESOURCES,
+ STATUS_PENDING,
+} DEVICE_NDIS_STATUS, *PDEVICE_NDIS_STATUS;
+
+#define MAX_BSSIDINFO_4_PMKID 16
+#define MAX_PMKIDLIST 5
+/* flags for PMKID Candidate list structure */
+#define NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED 0x01
+
+/* PMKID Structures */
+typedef unsigned char 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 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;
+ unsigned long 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 {
+ unsigned long Length;
+ unsigned long BSSIDInfoCount;
+ BSSID_INFO BSSIDInfo[MAX_BSSIDINFO_4_PMKID];
+} SPMKID, *PSPMKID;
+
+typedef struct tagSPMKIDCandidateEvent {
+ NDIS_802_11_STATUS_TYPE StatusType;
+ unsigned long Version; /* Version of the structure */
+ unsigned long NumCandidates; /* No. of pmkid candidates */
+ PMKID_CANDIDATE CandidateList[MAX_PMKIDLIST];
+} SPMKIDCandidateEvent, *PSPMKIDCandidateEvent;
+
+/*++ 802.11h related */
+#define MAX_QUIET_COUNT 8
+
+typedef struct tagSQuietControl {
+ bool bEnable;
+ u32 dwStartTime;
+ u8 byPeriod;
+ u16 wDuration;
+} SQuietControl, *PSQuietControl;
+
+/* The receive duplicate detection cache entry */
+typedef struct tagSCacheEntry{
+ u16 wFmSequence;
+ u8 abyAddr2[ETH_ALEN];
+ u16 wFrameCtl;
+} SCacheEntry, *PSCacheEntry;
+
+typedef struct tagSCache{
+/* The receive cache is updated circularly. The next entry to be written is
+ * indexed by the "InPtr".
+ */
+ unsigned int 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
+{
+ u16 wSequence;
+ u16 wFragNum;
+ u8 abyAddr2[ETH_ALEN];
+ unsigned int uLifetime;
+ struct sk_buff* skb;
+ u8 * pbyRxBuffer;
+ unsigned int cbFrameLength;
+ bool bInUse;
+} SDeFragControlBlock, *PSDeFragControlBlock;
+
+/* flags for options */
+#define DEVICE_FLAGS_UNPLUG 0x00000001UL
+#define DEVICE_FLAGS_PREAMBLE_TYPE 0x00000002UL
+#define DEVICE_FLAGS_OP_MODE 0x00000004UL
+#define DEVICE_FLAGS_PS_MODE 0x00000008UL
+#define DEVICE_FLAGS_80211h_MODE 0x00000010UL
+
+/* flags for driver status */
+#define DEVICE_FLAGS_OPENED 0x00010000UL
+#define DEVICE_FLAGS_WOL_ENABLED 0x00080000UL
+/* flags for capabilities */
+#define DEVICE_FLAGS_TX_ALIGN 0x01000000UL
+#define DEVICE_FLAGS_HAVE_CAM 0x02000000UL
+#define DEVICE_FLAGS_FLOW_CTRL 0x04000000UL
+
+/* flags for MII status */
+#define DEVICE_LINK_FAIL 0x00000001UL
+#define DEVICE_SPEED_10 0x00000002UL
+#define DEVICE_SPEED_100 0x00000004UL
+#define DEVICE_SPEED_1000 0x00000008UL
+#define DEVICE_DUPLEX_FULL 0x00000010UL
+#define DEVICE_AUTONEG_ENABLE 0x00000020UL
+#define DEVICE_FORCED_BY_EEPROM 0x00000040UL
+/* for device_set_media_duplex */
+#define DEVICE_LINK_CHANGE 0x00000001UL
+
+typedef struct __device_opt {
+ int nRxDescs0; /* number of RX descriptors 0 */
+ int nTxDescs0; /* number of TX descriptors 0, 1, 2, 3 */
+ int rts_thresh; /* RTS threshold */
+ int frag_thresh;
+ int OpMode;
+ int data_rate;
+ int channel_num;
+ int short_retry;
+ int long_retry;
+ int bbp_type;
+ u32 flags;
+} OPTIONS, *POPTIONS;
+
+struct vnt_private {
+ /* netdev */
+ struct usb_device *usb;
+ struct net_device *dev;
+ struct net_device_stats stats;
+
+ OPTIONS sOpts;
+
+ struct tasklet_struct CmdWorkItem;
+ struct tasklet_struct EventWorkItem;
+ struct tasklet_struct ReadWorkItem;
+ struct tasklet_struct RxMngWorkItem;
+
+ u32 rx_buf_sz;
+ int multicast_limit;
+ u8 byRxMode;
+
+ spinlock_t lock;
+
+ u32 rx_bytes;
+
+ u8 byRevId;
+
+ u32 flags;
+ unsigned long Flags;
+
+ SCache sDupRxCache;
+
+ SDeFragControlBlock sRxDFCB[CB_MAX_RX_FRAG];
+ u32 cbDFCB;
+ u32 cbFreeDFCB;
+ u32 uCurrentDFCBIdx;
+
+ /* USB */
+ struct urb *pControlURB;
+ struct urb *pInterruptURB;
+ struct usb_ctrlrequest sUsbCtlRequest;
+ u32 int_interval;
+
+ /* Variables to track resources for the BULK In Pipe */
+ PRCB pRCBMem;
+ PRCB apRCB[CB_MAX_RX_DESC];
+ u32 cbRD;
+ PRCB FirstRecvFreeList;
+ PRCB LastRecvFreeList;
+ u32 NumRecvFreeList;
+ PRCB FirstRecvMngList;
+ PRCB LastRecvMngList;
+ u32 NumRecvMngList;
+ int bIsRxWorkItemQueued;
+ int bIsRxMngWorkItemQueued;
+ unsigned long ulRcvRefCount; /* packets that have not returned back */
+
+ /* Variables to track resources for the BULK Out Pipe */
+ PUSB_SEND_CONTEXT apTD[CB_MAX_TX_DESC];
+ u32 cbTD;
+
+ /* Variables to track resources for the Interrupt In Pipe */
+ INT_BUFFER intBuf;
+ int fKillEventPollingThread;
+ int bEventAvailable;
+
+ /* default config from file by user setting */
+ DEFAULT_CONFIG config_file;
+
+ /* Statistic for USB */
+ unsigned long ulBulkInPosted;
+ unsigned long ulBulkInError;
+ unsigned long ulBulkInContCRCError;
+ unsigned long ulBulkInBytesRead;
+
+ unsigned long ulBulkOutPosted;
+ unsigned long ulBulkOutError;
+ unsigned long ulBulkOutContCRCError;
+ unsigned long ulBulkOutBytesWrite;
+
+ unsigned long ulIntInPosted;
+ unsigned long ulIntInError;
+ unsigned long ulIntInContCRCError;
+ unsigned long ulIntInBytesRead;
+
+ /* Version control */
+ u16 wFirmwareVersion;
+ u8 byLocalID;
+ u8 byRFType;
+ u8 byBBRxConf;
+
+ u8 byZoneType;
+ int bZoneRegExist;
+
+ u8 byOriginalZonetype;
+
+ int bLinkPass; /* link status: OK or fail */
+ u8 abyCurrentNetAddr[ETH_ALEN];
+ u8 abyPermanentNetAddr[ETH_ALEN];
+
+ int bExistSWNetAddr;
+
+ /* Adapter statistics */
+ SStatCounter scStatistic;
+ /* 802.11 counter */
+ SDot11Counters s802_11Counter;
+
+ /* Maintain statistical debug info. */
+ unsigned long packetsReceived;
+ unsigned long packetsReceivedDropped;
+ unsigned long packetsReceivedOverflow;
+ unsigned long packetsSent;
+ unsigned long packetsSentDropped;
+ unsigned long SendContextsInUse;
+ unsigned long RcvBuffersInUse;
+
+ /* 802.11 management */
+ struct vnt_manager vnt_mgmt;
+
+ u64 qwCurrTSF;
+ u32 cbBulkInMax;
+ int bPSRxBeacon;
+
+ /* 802.11 MAC specific */
+ u32 uCurrRSSI;
+ u8 byCurrSQ;
+
+ /* Antenna Diversity */
+ int bTxRxAntInv;
+ u32 dwRxAntennaSel;
+ u32 dwTxAntennaSel;
+ u8 byAntennaCount;
+ u8 byRxAntennaMode;
+ u8 byTxAntennaMode;
+ u8 byRadioCtl;
+ u8 bHWRadioOff;
+
+ /* SQ3 functions for antenna diversity */
+ struct timer_list TimerSQ3Tmax1;
+ struct timer_list TimerSQ3Tmax2;
+ struct timer_list TimerSQ3Tmax3;
+
+ int bDiversityRegCtlON;
+ int bDiversityEnable;
+ unsigned long ulDiversityNValue;
+ unsigned long ulDiversityMValue;
+ u8 byTMax;
+ u8 byTMax2;
+ u8 byTMax3;
+ unsigned long ulSQ3TH;
+
+ unsigned long uDiversityCnt;
+ u8 byAntennaState;
+ unsigned long ulRatio_State0;
+ unsigned long ulRatio_State1;
+ unsigned long ulSQ3_State0;
+ unsigned long ulSQ3_State1;
+
+ unsigned long aulSQ3Val[MAX_RATE];
+ unsigned long aulPktNum[MAX_RATE];
+
+ /* IFS & Cw */
+ u32 uSIFS; /* Current SIFS */
+ u32 uDIFS; /* Current DIFS */
+ u32 uEIFS; /* Current EIFS */
+ u32 uSlot; /* Current SlotTime */
+ u32 uCwMin; /* Current CwMin */
+ u32 uCwMax; /* CwMax is fixed on 1023 */
+
+ /* PHY parameter */
+ u8 bySIFS;
+ u8 byDIFS;
+ u8 byEIFS;
+ u8 bySlot;
+ u8 byCWMaxMin;
+
+ /* Rate */
+ VIA_BB_TYPE byBBType; /* 0: 11A, 1:11B, 2:11G */
+ VIA_PKT_TYPE byPacketType; /* 0:11a 1:11b 2:11gb 3:11ga */
+ u16 wBasicRate;
+ u8 byACKRate;
+ u8 byTopOFDMBasicRate;
+ u8 byTopCCKBasicRate;
+
+ u32 dwAotoRateTxOkCnt;
+ u32 dwAotoRateTxFailCnt;
+ u32 dwErrorRateThreshold[13];
+ u32 dwTPTable[MAX_RATE];
+ u8 abyEEPROM[EEP_MAX_CONTEXT_SIZE]; /*u32 alignment */
+
+ u8 byMinChannel;
+ u8 byMaxChannel;
+ u32 uConnectionRate;
+
+ u8 byPreambleType;
+ u8 byShortPreamble;
+ /* CARD_PHY_TYPE */
+ u8 eConfigPHYMode;
+
+ /* For RF Power table */
+ u8 byCCKPwr;
+ u8 byOFDMPwrG;
+ u8 byOFDMPwrA;
+ u8 byCurPwr;
+ u8 abyCCKPwrTbl[14];
+ u8 abyOFDMPwrTbl[14];
+ u8 abyOFDMAPwrTbl[42];
+
+ u16 wCurrentRate;
+ u16 wRTSThreshold;
+ u16 wFragmentationThreshold;
+ u8 byShortRetryLimit;
+ u8 byLongRetryLimit;
+ CARD_OP_MODE eOPMode;
+ int bBSSIDFilter;
+ u16 wMaxTransmitMSDULifetime;
+ u8 abyBSSID[ETH_ALEN];
+ u8 abyDesireBSSID[ETH_ALEN];
+
+ u16 wCTSDuration; /* update while speed change */
+ u16 wACKDuration;
+ u16 wRTSTransmitLen;
+ u8 byRTSServiceField;
+ u8 byRTSSignalField;
+
+ u32 dwMaxReceiveLifetime; /* dot11MaxReceiveLifetime */
+
+ int bCCK;
+ int bEncryptionEnable;
+ int bLongHeader;
+ int bSoftwareGenCrcErr;
+ int bShortSlotTime;
+ int bProtectMode;
+ int bNonERPPresent;
+ int bBarkerPreambleMd;
+
+ u8 byERPFlag;
+ u16 wUseProtectCntDown;
+
+ int bRadioControlOff;
+ int bRadioOff;
+
+ /* Power save */
+ int bEnablePSMode;
+ u16 wListenInterval;
+ int bPWBitOn;
+ WMAC_POWER_MODE ePSMode;
+ unsigned long ulPSModeWaitTx;
+ int bPSModeTxBurst;
+
+ /* Beacon releated */
+ u16 wSeqCounter;
+ int bBeaconBufReady;
+ int bBeaconSent;
+ int bFixRate;
+ u8 byCurrentCh;
+ u32 uScanTime;
+
+ CMD_STATE eCommandState;
+
+ CMD_CODE eCommand;
+ int bBeaconTx;
+ u8 byScanBBType;
+
+ int bStopBeacon;
+ int bStopDataPkt;
+ int bStopTx0Pkt;
+ u32 uAutoReConnectTime;
+ u32 uIsroamingTime;
+
+ /* 802.11 counter */
+
+ CMD_ITEM eCmdQueue[CMD_Q_SIZE];
+ u32 uCmdDequeueIdx;
+ u32 uCmdEnqueueIdx;
+ u32 cbFreeCmdQueue;
+ int bCmdRunning;
+ int bCmdClear;
+ int bNeedRadioOFF;
+
+ int bEnableRoaming;
+ int bIsRoaming;
+ int bFastRoaming;
+ u8 bSameBSSMaxNum;
+ u8 bSameBSSCurNum;
+ int bRoaming;
+ int b11hEable;
+ unsigned long ulTxPower;
+
+ /* Encryption */
+ NDIS_802_11_WEP_STATUS eEncryptionStatus;
+ int bTransmitKey;
+ NDIS_802_11_WEP_STATUS eOldEncryptionStatus;
+ SKeyManagement sKey;
+ u32 dwIVCounter;
+
+ RC4Ext SBox;
+ u8 abyPRNG[WLAN_WEPMAX_KEYLEN+3];
+ u8 byKeyIndex;
+
+ int bAES;
+
+ u32 uKeyLength;
+ u8 abyKey[WLAN_WEP232_KEYLEN];
+
+ /* for AP mode */
+ u32 uAssocCount;
+ int bMoreData;
+
+ /* QoS */
+ int bGrpAckPolicy;
+
+ u8 byAutoFBCtrl;
+
+ int bTxMICFail;
+ int bRxMICFail;
+
+ /* For Update BaseBand VGA Gain Offset */
+ int bUpdateBBVGA;
+ u32 uBBVGADiffCount;
+ u8 byBBVGANew;
+ u8 byBBVGACurrent;
+ u8 abyBBVGA[BB_VGA_LEVEL];
+ signed long ldBmThreshold[BB_VGA_LEVEL];
+
+ u8 byBBPreEDRSSI;
+ u8 byBBPreEDIndex;
+
+ int bRadioCmd;
+ u32 dwDiagRefCount;
+
+ /* For FOE Tuning */
+ u8 byFOETuning;
+
+ /* For Auto Power Tunning */
+ u8 byAutoPwrTunning;
+
+ /* BaseBand Loopback Use */
+ u8 byBBCR4d;
+ u8 byBBCRc9;
+ u8 byBBCR88;
+ u8 byBBCR09;
+
+ /* command timer */
+ struct timer_list sTimerCommand;
+
+ struct timer_list sTimerTxData;
+ unsigned long nTxDataTimeCout;
+ int fTxDataInSleep;
+ int IsTxDataTrigger;
+
+ int fWPA_Authened; /*is WPA/WPA-PSK or WPA2/WPA2-PSK authen?? */
+ u8 byReAssocCount;
+ u8 byLinkWaitCount;
+
+ struct ethhdr sTxEthHeader;
+ struct ethhdr sRxEthHeader;
+ u8 abyBroadcastAddr[ETH_ALEN];
+ u8 abySNAP_RFC1042[ETH_ALEN];
+ u8 abySNAP_Bridgetunnel[ETH_ALEN];
+
+ /* Pre-Authentication & PMK cache */
+ SPMKID gsPMKID;
+ SPMKIDCandidateEvent gsPMKIDCandidate;
+
+ /* for 802.11h */
+ int b11hEnable;
+
+ int bChannelSwitch;
+ u8 byNewChannel;
+ u8 byChannelSwitchCount;
+
+ /* WPA supplicant daemon */
+ int bWPADEVUp;
+ int bwextstep0;
+ int bwextstep1;
+ int bwextstep2;
+ int bwextstep3;
+ int bWPASuppWextEnabled;
+
+ /* user space daemon: hostapd, is used for HOSTAP */
+ int bEnableHostapd;
+ int bEnable8021x;
+ int bEnableHostWEP;
+ struct net_device *apdev;
+ int (*tx_80211)(struct sk_buff *skb, struct net_device *dev);
+
+ u32 uChannel;
+
+ struct iw_statistics wstats; /* wireless stats */
+
+ int bCommit;
+
+};
+
+#define EnqueueRCB(_Head, _Tail, _RCB) \
+{ \
+ if (!_Head) { \
+ _Head = _RCB; \
+ } \
+ else { \
+ _Tail->Next = _RCB; \
+ } \
+ _RCB->Next = NULL; \
+ _Tail = _RCB; \
+}
+
+#define DequeueRCB(Head, Tail) \
+{ \
+ PRCB RCB = Head; \
+ if (!RCB->Next) { \
+ Tail = NULL; \
+ } \
+ Head = RCB->Next; \
+}
+
+#define ADD_ONE_WITH_WRAP_AROUND(uVar, uModulo) { \
+ if ((uVar) >= ((uModulo) - 1)) \
+ (uVar) = 0; \
+ else \
+ (uVar)++; \
+}
+
+#define fMP_RESET_IN_PROGRESS 0x00000001
+#define fMP_DISCONNECTED 0x00000002
+#define fMP_HALT_IN_PROGRESS 0x00000004
+#define fMP_SURPRISE_REMOVED 0x00000008
+#define fMP_RECV_LOOKASIDE 0x00000010
+#define fMP_INIT_IN_PROGRESS 0x00000020
+#define fMP_SEND_SIDE_RESOURCE_ALLOCATED 0x00000040
+#define fMP_RECV_SIDE_RESOURCE_ALLOCATED 0x00000080
+#define fMP_POST_READS 0x00000100
+#define fMP_POST_WRITES 0x00000200
+#define fMP_CONTROL_READS 0x00000400
+#define fMP_CONTROL_WRITES 0x00000800
+
+#define MP_SET_FLAG(_M, _F) ((_M)->Flags |= (_F))
+#define MP_CLEAR_FLAG(_M, _F) ((_M)->Flags &= ~(_F))
+#define MP_TEST_FLAGS(_M, _F) (((_M)->Flags & (_F)) == (_F))
+
+#define MP_IS_READY(_M) (((_M)->Flags & \
+ (fMP_DISCONNECTED | fMP_RESET_IN_PROGRESS | fMP_HALT_IN_PROGRESS | fMP_INIT_IN_PROGRESS | fMP_SURPRISE_REMOVED)) == 0)
+
+int device_alloc_frag_buf(struct vnt_private *, PSDeFragControlBlock pDeF);
+
+#endif
diff --git a/drivers/staging/vt6656/device_cfg.h b/drivers/staging/vt6656/device_cfg.h
new file mode 100644
index 00000000..ea66b975
--- /dev/null
+++ b/drivers/staging/vt6656/device_cfg.h
@@ -0,0 +1,99 @@
+/*
+ * 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_cfg.h
+ *
+ * Purpose: Driver configuration header
+ * Author: Lyndon Chen
+ *
+ * Date: Dec 9, 2005
+ *
+ */
+#ifndef __DEVICE_CONFIG_H
+#define __DEVICE_CONFIG_H
+
+#include <linux/types.h>
+
+typedef
+struct _version {
+ unsigned char major;
+ unsigned char minor;
+ unsigned char build;
+} version_t, *pversion_t;
+
+#ifndef false
+#define false (0)
+#endif
+
+#ifndef true
+#define true (!(false))
+#endif
+
+#define VID_TABLE_SIZE 64
+#define MCAST_TABLE_SIZE 64
+#define MCAM_SIZE 32
+#define VCAM_SIZE 32
+#define TX_QUEUE_NO 8
+
+#define DEVICE_NAME "vt6656"
+#define DEVICE_FULL_DRV_NAM "VIA Networking Wireless LAN USB Driver"
+
+#ifndef MAJOR_VERSION
+#define MAJOR_VERSION 1
+#endif
+
+#ifndef MINOR_VERSION
+#define MINOR_VERSION 13
+#endif
+
+#ifndef DEVICE_VERSION
+#define DEVICE_VERSION "1.19_12"
+#endif
+
+/* config file */
+#include <linux/fs.h>
+#include <linux/fcntl.h>
+#ifndef CONFIG_PATH
+#define CONFIG_PATH "/etc/vntconfiguration.dat"
+#endif
+
+/* Max: 2378 = 2312 Payload + 30HD + 4CRC + 2Padding + 4Len + 8TSF + 4RSR */
+#define PKT_BUF_SZ 2390
+
+#define MAX_UINTS 8
+#define OPTION_DEFAULT { [0 ... MAX_UINTS-1] = -1}
+
+typedef enum _chip_type {
+ VT3184 = 1
+} CHIP_TYPE, *PCHIP_TYPE;
+
+#ifdef VIAWET_DEBUG
+#define ASSERT(x) { \
+ if (!(x)) { \
+ printk(KERN_ERR "assertion %s failed: file %s line %d\n", #x, \
+ __FUNCTION__, __LINE__);\
+ *(int *) 0 = 0; \
+ } \
+}
+#define DBG_PORT80(value) outb(value, 0x80)
+#else
+#define ASSERT(x)
+#define DBG_PORT80(value)
+#endif
+
+#endif
diff --git a/drivers/staging/vt6656/dpc.c b/drivers/staging/vt6656/dpc.c
new file mode 100644
index 00000000..7ec166a2
--- /dev/null
+++ b/drivers/staging/vt6656/dpc.c
@@ -0,0 +1,1430 @@
+/*
+ * 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:
+ *
+ */
+
+#include "device.h"
+#include "rxtx.h"
+#include "tether.h"
+#include "card.h"
+#include "bssdb.h"
+#include "mac.h"
+#include "baseband.h"
+#include "michael.h"
+#include "tkip.h"
+#include "tcrc.h"
+#include "wctl.h"
+#include "hostap.h"
+#include "rf.h"
+#include "iowpa.h"
+#include "aes_ccmp.h"
+#include "datarate.h"
+#include "usbpipe.h"
+
+//static int msglevel =MSG_LEVEL_DEBUG;
+static int msglevel =MSG_LEVEL_INFO;
+
+const u8 acbyRxRate[MAX_RATE] =
+{2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108};
+
+static u8 s_byGetRateIdx(u8 byRate);
+
+static
+void
+s_vGetDASA(
+ u8 * pbyRxBufferAddr,
+ unsigned int *pcbHeaderSize,
+ struct ethhdr *psEthHeader
+ );
+
+static void s_vProcessRxMACHeader(struct vnt_private *pDevice,
+ u8 *pbyRxBufferAddr, u32 cbPacketSize, int bIsWEP, int bExtIV,
+ u32 *pcbHeadSize);
+
+static int s_bAPModeRxCtl(struct vnt_private *pDevice, u8 *pbyFrame,
+ s32 iSANodeIndex);
+
+static int s_bAPModeRxData(struct vnt_private *pDevice, struct sk_buff *skb,
+ u32 FrameSize, u32 cbHeaderOffset, s32 iSANodeIndex, s32 iDANodeIndex);
+
+static int s_bHandleRxEncryption(struct vnt_private *pDevice, u8 *pbyFrame,
+ u32 FrameSize, u8 *pbyRsr, u8 *pbyNewRsr, PSKeyItem *pKeyOut,
+ s32 *pbExtIV, u16 *pwRxTSC15_0, u32 *pdwRxTSC47_16);
+
+static int s_bHostWepRxEncryption(struct vnt_private *pDevice, u8 *pbyFrame,
+ u32 FrameSize, u8 *pbyRsr, int bOnFly, PSKeyItem pKey, u8 *pbyNewRsr,
+ s32 *pbExtIV, u16 *pwRxTSC15_0, u32 *pdwRxTSC47_16);
+
+/*+
+ *
+ * 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(struct vnt_private *pDevice,
+ u8 *pbyRxBufferAddr, u32 cbPacketSize, int bIsWEP, int bExtIV,
+ u32 *pcbHeadSize)
+{
+ u8 *pbyRxBuffer;
+ u32 cbHeaderSize = 0;
+ u16 *pwType;
+ struct ieee80211_hdr *pMACHeader;
+ int ii;
+
+ pMACHeader = (struct ieee80211_hdr *) (pbyRxBufferAddr + cbHeaderSize);
+
+ s_vGetDASA((u8 *)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 = (u8 *) (pbyRxBufferAddr + cbHeaderSize);
+ if (!compare_ether_addr(pbyRxBuffer, &pDevice->abySNAP_Bridgetunnel[0])) {
+ cbHeaderSize += 6;
+ } else if (!compare_ether_addr(pbyRxBuffer, &pDevice->abySNAP_RFC1042[0])) {
+ cbHeaderSize += 6;
+ pwType = (u16 *) (pbyRxBufferAddr + cbHeaderSize);
+ if ((*pwType == cpu_to_be16(ETH_P_IPX)) ||
+ (*pwType == cpu_to_le16(0xF380))) {
+ cbHeaderSize -= 8;
+ pwType = (u16 *) (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 = (u16 *) (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 -= (ETH_ALEN * 2);
+ pbyRxBuffer = (u8 *) (pbyRxBufferAddr + cbHeaderSize);
+ for (ii = 0; ii < ETH_ALEN; ii++)
+ *pbyRxBuffer++ = pDevice->sRxEthHeader.h_dest[ii];
+ for (ii = 0; ii < ETH_ALEN; ii++)
+ *pbyRxBuffer++ = pDevice->sRxEthHeader.h_source[ii];
+
+ *pcbHeadSize = cbHeaderSize;
+}
+
+static u8 s_byGetRateIdx(u8 byRate)
+{
+ u8 byRateIdx;
+
+ for (byRateIdx = 0; byRateIdx <MAX_RATE ; byRateIdx++) {
+ if (acbyRxRate[byRateIdx%MAX_RATE] == byRate)
+ return byRateIdx;
+ }
+ return 0;
+}
+
+static
+void
+s_vGetDASA (
+ u8 * pbyRxBufferAddr,
+ unsigned int *pcbHeaderSize,
+ struct ethhdr *psEthHeader
+ )
+{
+ unsigned int cbHeaderSize = 0;
+ struct ieee80211_hdr *pMACHeader;
+ int ii;
+
+ pMACHeader = (struct ieee80211_hdr *) (pbyRxBufferAddr + cbHeaderSize);
+
+ if ((pMACHeader->frame_control & FC_TODS) == 0) {
+ if (pMACHeader->frame_control & FC_FROMDS) {
+ for (ii = 0; ii < ETH_ALEN; ii++) {
+ psEthHeader->h_dest[ii] =
+ pMACHeader->addr1[ii];
+ psEthHeader->h_source[ii] =
+ pMACHeader->addr3[ii];
+ }
+ } else {
+ /* IBSS mode */
+ for (ii = 0; ii < ETH_ALEN; ii++) {
+ psEthHeader->h_dest[ii] =
+ pMACHeader->addr1[ii];
+ psEthHeader->h_source[ii] =
+ pMACHeader->addr2[ii];
+ }
+ }
+ } else {
+ /* Is AP mode.. */
+ if (pMACHeader->frame_control & FC_FROMDS) {
+ for (ii = 0; ii < ETH_ALEN; ii++) {
+ psEthHeader->h_dest[ii] =
+ pMACHeader->addr3[ii];
+ psEthHeader->h_source[ii] =
+ pMACHeader->addr4[ii];
+ cbHeaderSize += 6;
+ }
+ } else {
+ for (ii = 0; ii < ETH_ALEN; ii++) {
+ psEthHeader->h_dest[ii] =
+ pMACHeader->addr3[ii];
+ psEthHeader->h_source[ii] =
+ pMACHeader->addr2[ii];
+ }
+ }
+ };
+ *pcbHeaderSize = cbHeaderSize;
+}
+
+int RXbBulkInProcessData(struct vnt_private *pDevice, PRCB pRCB,
+ unsigned long BytesToIndicate)
+{
+ struct net_device_stats *pStats = &pDevice->stats;
+ struct sk_buff *skb;
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ struct vnt_rx_mgmt *pRxPacket = &pMgmt->sRxPacket;
+ struct ieee80211_hdr *p802_11Header;
+ u8 *pbyRsr, *pbyNewRsr, *pbyRSSI, *pbyFrame;
+ u64 *pqwTSFTime;
+ u32 bDeFragRx = false;
+ u32 cbHeaderOffset, cbIVOffset;
+ u32 FrameSize;
+ u16 wEtherType = 0;
+ s32 iSANodeIndex = -1, iDANodeIndex = -1;
+ int ii;
+ u8 *pbyRxSts, *pbyRxRate, *pbySQ, *pby3SQ;
+ u32 cbHeaderSize;
+ PSKeyItem pKey = NULL;
+ u16 wRxTSC15_0 = 0;
+ u32 dwRxTSC47_16 = 0;
+ SKeyItem STempKey;
+ /* signed long ldBm = 0; */
+ int bIsWEP = false; int bExtIV = false;
+ u32 dwWbkStatus;
+ PRCB pRCBIndicate = pRCB;
+ u8 *pbyDAddress;
+ u16 *pwPLCP_Length;
+ u8 abyVaildRate[MAX_RATE]
+ = {2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108};
+ u16 wPLCPwithPadding;
+ struct ieee80211_hdr *pMACHeader;
+ int bRxeapol_key = false;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---------- RXbBulkInProcessData---\n");
+
+ skb = pRCB->skb;
+
+ /* [31:16]RcvByteCount ( not include 4-byte Status ) */
+ dwWbkStatus = *((u32 *)(skb->data));
+ FrameSize = dwWbkStatus >> 16;
+ FrameSize += 4;
+
+ if (BytesToIndicate != FrameSize) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"------- WRONG Length 1\n");
+ return false;
+ }
+
+ if ((BytesToIndicate > 2372) || (BytesToIndicate <= 40)) {
+ // Frame Size error drop this packet.
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "---------- WRONG Length 2\n");
+ return false;
+ }
+
+ pbyDAddress = (u8 *)(skb->data);
+ pbyRxSts = pbyDAddress+4;
+ pbyRxRate = pbyDAddress+5;
+
+ //real Frame Size = USBFrameSize -4WbkStatus - 4RxStatus - 8TSF - 4RSR - 4SQ3 - ?Padding
+ //if SQ3 the range is 24~27, if no SQ3 the range is 20~23
+ //real Frame size in PLCPLength field.
+ pwPLCP_Length = (u16 *) (pbyDAddress + 6);
+ //Fix hardware bug => PLCP_Length error
+ if ( ((BytesToIndicate - (*pwPLCP_Length)) > 27) ||
+ ((BytesToIndicate - (*pwPLCP_Length)) < 24) ||
+ (BytesToIndicate < (*pwPLCP_Length)) ) {
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Wrong PLCP Length %x\n", (int) *pwPLCP_Length);
+ ASSERT(0);
+ return false;
+ }
+ for ( ii=RATE_1M;ii<MAX_RATE;ii++) {
+ if ( *pbyRxRate == abyVaildRate[ii] ) {
+ break;
+ }
+ }
+ if ( ii==MAX_RATE ) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Wrong RxRate %x\n",(int) *pbyRxRate);
+ return false;
+ }
+
+ wPLCPwithPadding = ( (*pwPLCP_Length / 4) + ( (*pwPLCP_Length % 4) ? 1:0 ) ) *4;
+
+ pqwTSFTime = (u64 *)(pbyDAddress + 8 + wPLCPwithPadding);
+ if(pDevice->byBBType == BB_TYPE_11G) {
+ pby3SQ = pbyDAddress + 8 + wPLCPwithPadding + 12;
+ pbySQ = pby3SQ;
+ }
+ else {
+ pbySQ = pbyDAddress + 8 + wPLCPwithPadding + 8;
+ pby3SQ = pbySQ;
+ }
+ pbyNewRsr = pbyDAddress + 8 + wPLCPwithPadding + 9;
+ pbyRSSI = pbyDAddress + 8 + wPLCPwithPadding + 10;
+ pbyRsr = pbyDAddress + 8 + wPLCPwithPadding + 11;
+
+ FrameSize = *pwPLCP_Length;
+
+ pbyFrame = pbyDAddress + 8;
+ // update receive statistic counter
+
+ STAvUpdateRDStatCounter(&pDevice->scStatistic,
+ *pbyRsr,
+ *pbyNewRsr,
+ *pbyRxSts,
+ *pbyRxRate,
+ pbyFrame,
+ FrameSize
+ );
+
+ pMACHeader = (struct ieee80211_hdr *) pbyFrame;
+
+//mike add: to judge if current AP is activated?
+ if ((pMgmt->eCurrMode == WMAC_MODE_STANDBY) ||
+ (pMgmt->eCurrMode == WMAC_MODE_ESS_STA)) {
+ if (pMgmt->sNodeDBTable[0].bActive) {
+ if (!compare_ether_addr(pMgmt->abyCurrBSSID, pMACHeader->addr2)) {
+ if (pMgmt->sNodeDBTable[0].uInActiveCount != 0)
+ pMgmt->sNodeDBTable[0].uInActiveCount = 0;
+ }
+ }
+ }
+
+ if (!is_multicast_ether_addr(pMACHeader->addr1)) {
+ if (WCTLbIsDuplicate(&(pDevice->sDupRxCache), (struct ieee80211_hdr *) pbyFrame)) {
+ pDevice->s802_11Counter.FrameDuplicateCount++;
+ return false;
+ }
+
+ if (compare_ether_addr(pDevice->abyCurrentNetAddr,
+ pMACHeader->addr1)) {
+ return false;
+ }
+ }
+
+ // Use for TKIP MIC
+ s_vGetDASA(pbyFrame, &cbHeaderSize, &pDevice->sRxEthHeader);
+
+ if (!compare_ether_addr((u8 *)&(pDevice->sRxEthHeader.h_source[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 = (struct ieee80211_hdr *) (pbyFrame);
+ // get SA NodeIndex
+ if (BSSbIsSTAInNodeDB(pDevice, (u8 *)(p802_11Header->addr2), &iSANodeIndex)) {
+ pMgmt->sNodeDBTable[iSANodeIndex].ulLastRxJiffer = jiffies;
+ pMgmt->sNodeDBTable[iSANodeIndex].uInActiveCount = 0;
+ }
+ }
+ }
+
+ if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
+ if (s_bAPModeRxCtl(pDevice, pbyFrame, iSANodeIndex) == true) {
+ return false;
+ }
+ }
+
+ if (IS_FC_WEP(pbyFrame)) {
+ bool bRxDecryOK = false;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"rx WEP pkt\n");
+ bIsWEP = true;
+ if ((pDevice->bEnableHostWEP) && (iSANodeIndex >= 0)) {
+ pKey = &STempKey;
+ pKey->byCipherSuite = pMgmt->sNodeDBTable[iSANodeIndex].byCipherSuite;
+ pKey->dwKeyIndex = pMgmt->sNodeDBTable[iSANodeIndex].dwKeyIndex;
+ pKey->uKeyLength = pMgmt->sNodeDBTable[iSANodeIndex].uWepKeyLength;
+ pKey->dwTSC47_16 = pMgmt->sNodeDBTable[iSANodeIndex].dwTSC47_16;
+ pKey->wTSC15_0 = pMgmt->sNodeDBTable[iSANodeIndex].wTSC15_0;
+ memcpy(pKey->abyKey,
+ &pMgmt->sNodeDBTable[iSANodeIndex].abyWepKey[0],
+ pKey->uKeyLength
+ );
+
+ bRxDecryOK = s_bHostWepRxEncryption(pDevice,
+ pbyFrame,
+ FrameSize,
+ pbyRsr,
+ pMgmt->sNodeDBTable[iSANodeIndex].bOnFly,
+ pKey,
+ pbyNewRsr,
+ &bExtIV,
+ &wRxTSC15_0,
+ &dwRxTSC47_16);
+ } else {
+ bRxDecryOK = s_bHandleRxEncryption(pDevice,
+ pbyFrame,
+ FrameSize,
+ pbyRsr,
+ pbyNewRsr,
+ &pKey,
+ &bExtIV,
+ &wRxTSC15_0,
+ &dwRxTSC47_16);
+ }
+
+ if (bRxDecryOK) {
+ if ((*pbyNewRsr & NEWRSR_DECRYPTOK) == 0) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV Fail\n");
+ if ( (pMgmt->eAuthenMode == WMAC_AUTH_WPA) ||
+ (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) ||
+ (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) ||
+ (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) ||
+ (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) {
+
+ if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_TKIP)) {
+ pDevice->s802_11Counter.TKIPICVErrors++;
+ } else if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_CCMP)) {
+ pDevice->s802_11Counter.CCMPDecryptErrors++;
+ } else if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_WEP)) {
+// pDevice->s802_11Counter.WEPICVErrorCount.QuadPart++;
+ }
+ }
+ return false;
+ }
+ } else {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"WEP Func Fail\n");
+ return false;
+ }
+ if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_CCMP))
+ FrameSize -= 8; // Message Integrity Code
+ else
+ FrameSize -= 4; // 4 is ICV
+ }
+
+ //
+ // RX OK
+ //
+ /* remove the FCS/CRC length */
+ FrameSize -= ETH_FCS_LEN;
+
+ if ( !(*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI)) && // unicast address
+ (IS_FRAGMENT_PKT((pbyFrame)))
+ ) {
+ // defragment
+ bDeFragRx = WCTLbHandleFragment(pDevice, (struct ieee80211_hdr *) (pbyFrame), FrameSize, bIsWEP, bExtIV);
+ pDevice->s802_11Counter.ReceivedFragmentCount++;
+ if (bDeFragRx) {
+ // defrag complete
+ // TODO skb, pbyFrame
+ skb = pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].skb;
+ FrameSize = pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength;
+ pbyFrame = skb->data + 8;
+ }
+ else {
+ return false;
+ }
+ }
+
+ //
+ // Management & Control frame Handle
+ //
+ if ((IS_TYPE_DATA((pbyFrame))) == false) {
+ // Handle Control & Manage Frame
+
+ if (IS_TYPE_MGMT((pbyFrame))) {
+ u8 * pbyData1;
+ u8 * pbyData2;
+
+ pRxPacket = &(pRCB->sMngPacket);
+ pRxPacket->p80211Header = (PUWLAN_80211HDR)(pbyFrame);
+ pRxPacket->cbMPDULen = FrameSize;
+ pRxPacket->uRSSI = *pbyRSSI;
+ pRxPacket->bySQ = *pbySQ;
+ pRxPacket->qwLocalTSF = cpu_to_le64(*pqwTSFTime);
+ if (bIsWEP) {
+ // strip IV
+ pbyData1 = WLAN_HDR_A3_DATA_PTR(pbyFrame);
+ pbyData2 = WLAN_HDR_A3_DATA_PTR(pbyFrame) + 4;
+ for (ii = 0; ii < (FrameSize - 4); ii++) {
+ *pbyData1 = *pbyData2;
+ pbyData1++;
+ pbyData2++;
+ }
+ }
+
+ pRxPacket->byRxRate = s_byGetRateIdx(*pbyRxRate);
+
+ if ( *pbyRxSts == 0 ) {
+ //Discard beacon packet which channel is 0
+ if ( (WLAN_GET_FC_FSTYPE((pRxPacket->p80211Header->sA3.wFrameCtl)) == WLAN_FSTYPE_BEACON) ||
+ (WLAN_GET_FC_FSTYPE((pRxPacket->p80211Header->sA3.wFrameCtl)) == WLAN_FSTYPE_PROBERESP) ) {
+ return false;
+ }
+ }
+ pRxPacket->byRxChannel = (*pbyRxSts) >> 2;
+
+ // hostap Deamon handle 802.11 management
+ if (pDevice->bEnableHostapd) {
+ skb->dev = pDevice->apdev;
+ //skb->data += 4;
+ //skb->tail += 4;
+ skb->data += 8;
+ skb->tail += 8;
+ skb_put(skb, FrameSize);
+ skb_reset_mac_header(skb);
+ skb->pkt_type = PACKET_OTHERHOST;
+ skb->protocol = htons(ETH_P_802_2);
+ memset(skb->cb, 0, sizeof(skb->cb));
+ netif_rx(skb);
+ return true;
+ }
+
+ //
+ // Insert the RCB in the Recv Mng list
+ //
+ EnqueueRCB(pDevice->FirstRecvMngList, pDevice->LastRecvMngList, pRCBIndicate);
+ pDevice->NumRecvMngList++;
+ if ( bDeFragRx == false) {
+ pRCB->Ref++;
+ }
+ if (pDevice->bIsRxMngWorkItemQueued == false) {
+ pDevice->bIsRxMngWorkItemQueued = true;
+ tasklet_schedule(&pDevice->RxMngWorkItem);
+ }
+
+ }
+ else {
+ // Control Frame
+ };
+ return false;
+ }
+ else {
+ if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
+ //In AP mode, hw only check addr1(BSSID or RA) if equal to local MAC.
+ if ( !(*pbyRsr & RSR_BSSIDOK)) {
+ if (bDeFragRx) {
+ if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
+ DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
+ pDevice->dev->name);
+ }
+ }
+ return false;
+ }
+ }
+ else {
+ // discard DATA packet while not associate || BSSID error
+ if ((pDevice->bLinkPass == false) ||
+ !(*pbyRsr & RSR_BSSIDOK)) {
+ if (bDeFragRx) {
+ if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
+ DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
+ pDevice->dev->name);
+ }
+ }
+ return false;
+ }
+ //mike add:station mode check eapol-key challenge--->
+ {
+ u8 Protocol_Version; //802.1x Authentication
+ u8 Packet_Type; //802.1x Authentication
+ u8 Descriptor_type;
+ u16 Key_info;
+ if (bIsWEP)
+ cbIVOffset = 8;
+ else
+ cbIVOffset = 0;
+ wEtherType = (skb->data[cbIVOffset + 8 + 24 + 6] << 8) |
+ skb->data[cbIVOffset + 8 + 24 + 6 + 1];
+ Protocol_Version = skb->data[cbIVOffset + 8 + 24 + 6 + 1 +1];
+ Packet_Type = skb->data[cbIVOffset + 8 + 24 + 6 + 1 +1+1];
+ if (wEtherType == ETH_P_PAE) { //Protocol Type in LLC-Header
+ if(((Protocol_Version==1) ||(Protocol_Version==2)) &&
+ (Packet_Type==3)) { //802.1x OR eapol-key challenge frame receive
+ bRxeapol_key = true;
+ Descriptor_type = skb->data[cbIVOffset + 8 + 24 + 6 + 1 +1+1+1+2];
+ Key_info = (skb->data[cbIVOffset + 8 + 24 + 6 + 1 +1+1+1+2+1]<<8) |skb->data[cbIVOffset + 8 + 24 + 6 + 1 +1+1+1+2+2] ;
+ if(Descriptor_type==2) { //RSN
+ // printk("WPA2_Rx_eapol-key_info<-----:%x\n",Key_info);
+ }
+ else if(Descriptor_type==254) {
+ // printk("WPA_Rx_eapol-key_info<-----:%x\n",Key_info);
+ }
+ }
+ }
+ }
+ //mike add:station mode check eapol-key challenge<---
+ }
+ }
+
+// Data frame Handle
+
+ if (pDevice->bEnablePSMode) {
+ if (IS_FC_MOREDATA((pbyFrame))) {
+ if (*pbyRsr & RSR_ADDROK) {
+ //PSbSendPSPOLL((PSDevice)pDevice);
+ }
+ }
+ else {
+ if (pMgmt->bInTIMWake == true) {
+ pMgmt->bInTIMWake = false;
+ }
+ }
+ }
+
+ // Now it only supports 802.11g Infrastructure Mode, and support rate must up to 54 Mbps
+ if (pDevice->bDiversityEnable && (FrameSize>50) &&
+ (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) &&
+ (pDevice->bLinkPass == true)) {
+ BBvAntennaDiversity(pDevice, s_byGetRateIdx(*pbyRxRate), 0);
+ }
+
+ // ++++++++ For BaseBand Algorithm +++++++++++++++
+ pDevice->uCurrRSSI = *pbyRSSI;
+ pDevice->byCurrSQ = *pbySQ;
+
+ // todo
+/*
+ if ((*pbyRSSI != 0) &&
+ (pMgmt->pCurrBSS!=NULL)) {
+ RFvRSSITodBm(pDevice, *pbyRSSI, &ldBm);
+ // Monitor 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)){
+ u8 abyMacHdr[24];
+
+ // Only 802.1x packet incoming allowed
+ if (bIsWEP)
+ cbIVOffset = 8;
+ else
+ cbIVOffset = 0;
+ wEtherType = (skb->data[cbIVOffset + 8 + 24 + 6] << 8) |
+ skb->data[cbIVOffset + 8 + 24 + 6 + 1];
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wEtherType = %04x \n", wEtherType);
+ if (wEtherType == ETH_P_PAE) {
+ skb->dev = pDevice->apdev;
+
+ if (bIsWEP == true) {
+ // strip IV header(8)
+ memcpy(&abyMacHdr[0], (skb->data + 8), 24);
+ memcpy((skb->data + 8 + cbIVOffset), &abyMacHdr[0], 24);
+ }
+
+ skb->data += (cbIVOffset + 8);
+ skb->tail += (cbIVOffset + 8);
+ skb_put(skb, FrameSize);
+ skb_reset_mac_header(skb);
+ skb->pkt_type = PACKET_OTHERHOST;
+ skb->protocol = htons(ETH_P_802_2);
+ memset(skb->cb, 0, sizeof(skb->cb));
+ netif_rx(skb);
+ return true;
+
+ }
+ // check if 802.1x authorized
+ if (!(pMgmt->sNodeDBTable[iSANodeIndex].dwFlags & WLAN_STA_AUTHORIZED))
+ return false;
+ }
+
+ if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_TKIP)) {
+ if (bIsWEP) {
+ FrameSize -= 8; //MIC
+ }
+ }
+
+ //--------------------------------------------------------------------------------
+ // Soft MIC
+ if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_TKIP)) {
+ if (bIsWEP) {
+ u32 * pdwMIC_L;
+ u32 * pdwMIC_R;
+ u32 dwMIC_Priority;
+ u32 dwMICKey0 = 0, dwMICKey1 = 0;
+ u32 dwLocalMIC_L = 0;
+ u32 dwLocalMIC_R = 0;
+
+ if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
+ dwMICKey0 = cpu_to_le32(*(u32 *)(&pKey->abyKey[24]));
+ dwMICKey1 = cpu_to_le32(*(u32 *)(&pKey->abyKey[28]));
+ }
+ else {
+ if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
+ dwMICKey0 = cpu_to_le32(*(u32 *)(&pKey->abyKey[16]));
+ dwMICKey1 = cpu_to_le32(*(u32 *)(&pKey->abyKey[20]));
+ } else if ((pKey->dwKeyIndex & BIT28) == 0) {
+ dwMICKey0 = cpu_to_le32(*(u32 *)(&pKey->abyKey[16]));
+ dwMICKey1 = cpu_to_le32(*(u32 *)(&pKey->abyKey[20]));
+ } else {
+ dwMICKey0 = cpu_to_le32(*(u32 *)(&pKey->abyKey[24]));
+ dwMICKey1 = cpu_to_le32(*(u32 *)(&pKey->abyKey[28]));
+ }
+ }
+
+ MIC_vInit(dwMICKey0, dwMICKey1);
+ MIC_vAppend((u8 *)&(pDevice->sRxEthHeader.h_dest[0]), 12);
+ dwMIC_Priority = 0;
+ MIC_vAppend((u8 *)&dwMIC_Priority, 4);
+ // 4 is Rcv buffer header, 24 is MAC Header, and 8 is IV and Ext IV.
+ MIC_vAppend((u8 *)(skb->data + 8 + WLAN_HDR_ADDR3_LEN + 8),
+ FrameSize - WLAN_HDR_ADDR3_LEN - 8);
+ MIC_vGetMIC(&dwLocalMIC_L, &dwLocalMIC_R);
+ MIC_vUnInit();
+
+ pdwMIC_L = (u32 *)(skb->data + 8 + FrameSize);
+ pdwMIC_R = (u32 *)(skb->data + 8 + FrameSize + 4);
+
+ if ((cpu_to_le32(*pdwMIC_L) != dwLocalMIC_L) || (cpu_to_le32(*pdwMIC_R) != dwLocalMIC_R) ||
+ (pDevice->bRxMICFail == true)) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC comparison is fail!\n");
+ pDevice->bRxMICFail = false;
+ //pDevice->s802_11Counter.TKIPLocalMICFailures.QuadPart++;
+ pDevice->s802_11Counter.TKIPLocalMICFailures++;
+ if (bDeFragRx) {
+ if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
+ DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
+ pDevice->dev->name);
+ }
+ }
+ //send event to wpa_supplicant
+ //if(pDevice->bWPASuppWextEnabled == true)
+ {
+ union iwreq_data wrqu;
+ struct iw_michaelmicfailure ev;
+ int keyidx = pbyFrame[cbHeaderSize+3] >> 6; //top two-bits
+ memset(&ev, 0, sizeof(ev));
+ ev.flags = keyidx & IW_MICFAILURE_KEY_ID;
+ if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
+ (pMgmt->eCurrState == WMAC_STATE_ASSOC) &&
+ (*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI)) == 0) {
+ ev.flags |= IW_MICFAILURE_PAIRWISE;
+ } else {
+ ev.flags |= IW_MICFAILURE_GROUP;
+ }
+
+ ev.src_addr.sa_family = ARPHRD_ETHER;
+ memcpy(ev.src_addr.sa_data, pMACHeader->addr2, ETH_ALEN);
+ memset(&wrqu, 0, sizeof(wrqu));
+ wrqu.data.length = sizeof(ev);
+ PRINT_K("wireless_send_event--->IWEVMICHAELMICFAILURE\n");
+ wireless_send_event(pDevice->dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&ev);
+
+ }
+
+ return false;
+
+ }
+ }
+ } //---end of SOFT MIC-----------------------------------------------------------------------
+
+ // ++++++++++ Reply Counter Check +++++++++++++
+
+ if ((pKey != NULL) && ((pKey->byCipherSuite == KEY_CTL_TKIP) ||
+ (pKey->byCipherSuite == KEY_CTL_CCMP))) {
+ if (bIsWEP) {
+ u16 wLocalTSC15_0 = 0;
+ u32 dwLocalTSC47_16 = 0;
+ unsigned long long RSC = 0;
+ // endian issues
+ RSC = *((unsigned long long *) &(pKey->KeyRSC));
+ wLocalTSC15_0 = (u16) RSC;
+ dwLocalTSC47_16 = (u32) (RSC>>16);
+
+ RSC = dwRxTSC47_16;
+ RSC <<= 16;
+ RSC += wRxTSC15_0;
+ memcpy(&(pKey->KeyRSC), &RSC, sizeof(u64));
+
+ if (pDevice->vnt_mgmt.eCurrMode == WMAC_MODE_ESS_STA &&
+ pDevice->vnt_mgmt.eCurrState == WMAC_STATE_ASSOC) {
+ /* check RSC */
+ if ( (wRxTSC15_0 < wLocalTSC15_0) &&
+ (dwRxTSC47_16 <= dwLocalTSC47_16) &&
+ !((dwRxTSC47_16 == 0) && (dwLocalTSC47_16 == 0xFFFFFFFF))) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"TSC is illegal~~!\n ");
+ if (pKey->byCipherSuite == KEY_CTL_TKIP)
+ //pDevice->s802_11Counter.TKIPReplays.QuadPart++;
+ pDevice->s802_11Counter.TKIPReplays++;
+ else
+ //pDevice->s802_11Counter.CCMPReplays.QuadPart++;
+ pDevice->s802_11Counter.CCMPReplays++;
+
+ if (bDeFragRx) {
+ if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
+ DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
+ pDevice->dev->name);
+ }
+ }
+ return false;
+ }
+ }
+ }
+ } // ----- End of Reply Counter Check --------------------------
+
+ s_vProcessRxMACHeader(pDevice, (u8 *)(skb->data+8), FrameSize, bIsWEP, bExtIV, &cbHeaderOffset);
+ FrameSize -= cbHeaderOffset;
+ cbHeaderOffset += 8; // 8 is Rcv buffer header
+
+ // Null data, framesize = 12
+ if (FrameSize < 12)
+ return false;
+
+ if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
+ if (s_bAPModeRxData(pDevice,
+ skb,
+ FrameSize,
+ cbHeaderOffset,
+ iSANodeIndex,
+ iDANodeIndex
+ ) == false) {
+
+ if (bDeFragRx) {
+ if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
+ DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
+ pDevice->dev->name);
+ }
+ }
+ return false;
+ }
+
+ }
+
+ skb->data += cbHeaderOffset;
+ skb->tail += cbHeaderOffset;
+ skb_put(skb, FrameSize);
+ skb->protocol=eth_type_trans(skb, skb->dev);
+ skb->ip_summed=CHECKSUM_NONE;
+ pStats->rx_bytes +=skb->len;
+ pStats->rx_packets++;
+ netif_rx(skb);
+ if (bDeFragRx) {
+ if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
+ DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
+ pDevice->dev->name);
+ }
+ return false;
+ }
+
+ return true;
+}
+
+static int s_bAPModeRxCtl(struct vnt_private *pDevice, u8 *pbyFrame,
+ s32 iSANodeIndex)
+{
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ struct ieee80211_hdr *p802_11Header;
+ CMD_STATUS Status;
+
+ if (IS_CTL_PSPOLL(pbyFrame) || !IS_TYPE_CONTROL(pbyFrame)) {
+
+ p802_11Header = (struct ieee80211_hdr *) (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,
+ (u8 *)(p802_11Header->addr2),
+ (WLAN_MGMT_REASON_CLASS2_NONAUTH),
+ &Status
+ );
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: send vMgrDeAuthenBeginSta 1\n");
+ return true;
+ }
+ if (pMgmt->sNodeDBTable[iSANodeIndex].eNodeState < NODE_ASSOC) {
+ // send deassoc notification
+ // reason = (7) class 3 received from nonassoc sta
+ vMgrDisassocBeginSta(pDevice,
+ pMgmt,
+ (u8 *)(p802_11Header->addr2),
+ (WLAN_MGMT_REASON_CLASS3_NONASSOC),
+ &Status
+ );
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: send vMgrDisassocBeginSta 2\n");
+ return true;
+ }
+
+ if (pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable) {
+ // delcare received ps-poll event
+ if (IS_CTL_PSPOLL(pbyFrame)) {
+ pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = true;
+ bScheduleCommand((void *) pDevice,
+ WLAN_CMD_RX_PSPOLL,
+ NULL);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: WLAN_CMD_RX_PSPOLL 1\n");
+ }
+ else {
+ // check Data PS state
+ // if PW bit off, send out all PS bufferring packets.
+ if (!IS_FC_POWERMGT(pbyFrame)) {
+ pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = false;
+ pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = true;
+ bScheduleCommand((void *) pDevice,
+ WLAN_CMD_RX_PSPOLL,
+ NULL);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: WLAN_CMD_RX_PSPOLL 2\n");
+ }
+ }
+ }
+ else {
+ if (IS_FC_POWERMGT(pbyFrame)) {
+ pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = true;
+ // Once if STA in PS state, enable multicast bufferring
+ pMgmt->sNodeDBTable[0].bPSEnable = true;
+ }
+ else {
+ // clear all pending PS frame.
+ if (pMgmt->sNodeDBTable[iSANodeIndex].wEnQueueCnt > 0) {
+ pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = false;
+ pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = true;
+ bScheduleCommand((void *) pDevice,
+ WLAN_CMD_RX_PSPOLL,
+ NULL);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: WLAN_CMD_RX_PSPOLL 3\n");
+
+ }
+ }
+ }
+ }
+ else {
+ vMgrDeAuthenBeginSta(pDevice,
+ pMgmt,
+ (u8 *)(p802_11Header->addr2),
+ (WLAN_MGMT_REASON_CLASS2_NONAUTH),
+ &Status
+ );
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: send vMgrDeAuthenBeginSta 3\n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BSSID:%pM\n",
+ p802_11Header->addr3);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ADDR2:%pM\n",
+ p802_11Header->addr2);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ADDR1:%pM\n",
+ p802_11Header->addr1);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: frame_control= %x\n", p802_11Header->frame_control);
+ return true;
+ }
+ }
+ }
+ return false;
+
+}
+
+static int s_bHandleRxEncryption(struct vnt_private *pDevice, u8 *pbyFrame,
+ u32 FrameSize, u8 *pbyRsr, u8 *pbyNewRsr, PSKeyItem *pKeyOut,
+ s32 *pbExtIV, u16 *pwRxTSC15_0, u32 *pdwRxTSC47_16)
+{
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ u32 PayloadLen = FrameSize;
+ u8 *pbyIV;
+ u8 byKeyIdx;
+ PSKeyItem pKey = NULL;
+ u8 byDecMode = KEY_CTL_WEP;
+
+ *pwRxTSC15_0 = 0;
+ *pdwRxTSC47_16 = 0;
+
+ pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN;
+ if ( WLAN_GET_FC_TODS(*(u16 *)pbyFrame) &&
+ WLAN_GET_FC_FROMDS(*(u16 *)pbyFrame) ) {
+ pbyIV += 6; // 6 is 802.11 address4
+ PayloadLen -= 6;
+ }
+ byKeyIdx = (*(pbyIV+3) & 0xc0);
+ byKeyIdx >>= 6;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\nKeyIdx: %d\n", byKeyIdx);
+
+ if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA) ||
+ (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) ||
+ (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) ||
+ (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) ||
+ (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) {
+ if (((*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI)) == 0) &&
+ (pMgmt->byCSSPK != KEY_CTL_NONE)) {
+ // unicast pkt use pairwise key
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"unicast pkt\n");
+ if (KeybGetKey(&(pDevice->sKey), pDevice->abyBSSID, 0xFFFFFFFF, &pKey) == true) {
+ if (pMgmt->byCSSPK == KEY_CTL_TKIP)
+ byDecMode = KEY_CTL_TKIP;
+ else if (pMgmt->byCSSPK == KEY_CTL_CCMP)
+ byDecMode = KEY_CTL_CCMP;
+ }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"unicast pkt: %d, %p\n", byDecMode, pKey);
+ } else {
+ // use group key
+ KeybGetKey(&(pDevice->sKey), pDevice->abyBSSID, byKeyIdx, &pKey);
+ if (pMgmt->byCSSGK == KEY_CTL_TKIP)
+ byDecMode = KEY_CTL_TKIP;
+ else if (pMgmt->byCSSGK == KEY_CTL_CCMP)
+ byDecMode = KEY_CTL_CCMP;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"group pkt: %d, %d, %p\n", byKeyIdx, byDecMode, pKey);
+ }
+ }
+ // our WEP only support Default Key
+ if (pKey == NULL) {
+ // use default group key
+ KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, byKeyIdx, &pKey);
+ if (pMgmt->byCSSGK == KEY_CTL_TKIP)
+ byDecMode = KEY_CTL_TKIP;
+ else if (pMgmt->byCSSGK == KEY_CTL_CCMP)
+ byDecMode = KEY_CTL_CCMP;
+ }
+ *pKeyOut = pKey;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"AES:%d %d %d\n", pMgmt->byCSSPK, pMgmt->byCSSGK, byDecMode);
+
+ if (pKey == NULL) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey == NULL\n");
+ if (byDecMode == KEY_CTL_WEP) {
+// pDevice->s802_11Counter.WEPUndecryptableCount.QuadPart++;
+ } else if (pDevice->bLinkPass == true) {
+// pDevice->s802_11Counter.DecryptFailureCount.QuadPart++;
+ }
+ return false;
+ }
+ if (byDecMode != pKey->byCipherSuite) {
+ if (byDecMode == KEY_CTL_WEP) {
+// pDevice->s802_11Counter.WEPUndecryptableCount.QuadPart++;
+ } else if (pDevice->bLinkPass == true) {
+// pDevice->s802_11Counter.DecryptFailureCount.QuadPart++;
+ }
+ *pKeyOut = NULL;
+ return false;
+ }
+ if (byDecMode == KEY_CTL_WEP) {
+ // handle WEP
+ if ((pDevice->byLocalID <= REV_ID_VT3253_A1) ||
+ (((PSKeyTable)(pKey->pvKeyTable))->bSoftWEP == true)) {
+ // Software WEP
+ // 1. 3253A
+ // 2. WEP 256
+
+ PayloadLen -= (WLAN_HDR_ADDR3_LEN + 4 + 4); // 24 is 802.11 header,4 is IV, 4 is crc
+ memcpy(pDevice->abyPRNG, pbyIV, 3);
+ memcpy(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(*(u32 *)(pbyIV + 4));
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ExtIV: %x\n", *pdwRxTSC47_16);
+ if (byDecMode == KEY_CTL_TKIP) {
+ *pwRxTSC15_0 = cpu_to_le16(MAKEWORD(*(pbyIV+2), *pbyIV));
+ } else {
+ *pwRxTSC15_0 = cpu_to_le16(*(u16 *)pbyIV);
+ }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"TSC0_15: %x\n", *pwRxTSC15_0);
+
+ if ((byDecMode == KEY_CTL_TKIP) &&
+ (pDevice->byLocalID <= REV_ID_VT3253_A1)) {
+ // Software TKIP
+ // 1. 3253 A
+ struct ieee80211_hdr *pMACHeader = (struct ieee80211_hdr *) (pbyFrame);
+ TKIPvMixKey(pKey->abyKey, pMACHeader->addr2, *pwRxTSC15_0, *pdwRxTSC47_16, pDevice->abyPRNG);
+ rc4_init(&pDevice->SBox, pDevice->abyPRNG, TKIP_KEY_LEN);
+ rc4_encrypt(&pDevice->SBox, pbyIV+8, pbyIV+8, PayloadLen);
+ if (ETHbIsBufferCrc32Ok(pbyIV+8, PayloadLen)) {
+ *pbyNewRsr |= NEWRSR_DECRYPTOK;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV OK!\n");
+ } else {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV FAIL!!!\n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"PayloadLen = %d\n", PayloadLen);
+ }
+ }
+ }// end of TKIP/AES
+
+ if ((*(pbyIV+3) & 0x20) != 0)
+ *pbExtIV = true;
+ return true;
+}
+
+static int s_bHostWepRxEncryption(struct vnt_private *pDevice, u8 *pbyFrame,
+ u32 FrameSize, u8 *pbyRsr, int bOnFly, PSKeyItem pKey, u8 *pbyNewRsr,
+ s32 *pbExtIV, u16 *pwRxTSC15_0, u32 *pdwRxTSC47_16)
+{
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ struct ieee80211_hdr *pMACHeader;
+ u32 PayloadLen = FrameSize;
+ u8 *pbyIV;
+ u8 byKeyIdx;
+ u8 byDecMode = KEY_CTL_WEP;
+
+ *pwRxTSC15_0 = 0;
+ *pdwRxTSC47_16 = 0;
+
+ pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN;
+ if ( WLAN_GET_FC_TODS(*(u16 *)pbyFrame) &&
+ WLAN_GET_FC_FROMDS(*(u16 *)pbyFrame) ) {
+ pbyIV += 6; // 6 is 802.11 address4
+ PayloadLen -= 6;
+ }
+ byKeyIdx = (*(pbyIV+3) & 0xc0);
+ byKeyIdx >>= 6;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\nKeyIdx: %d\n", byKeyIdx);
+
+ if (pMgmt->byCSSGK == KEY_CTL_TKIP)
+ byDecMode = KEY_CTL_TKIP;
+ else if (pMgmt->byCSSGK == KEY_CTL_CCMP)
+ byDecMode = KEY_CTL_CCMP;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"AES:%d %d %d\n", pMgmt->byCSSPK, pMgmt->byCSSGK, byDecMode);
+
+ if (byDecMode != pKey->byCipherSuite) {
+ if (byDecMode == KEY_CTL_WEP) {
+// pDevice->s802_11Counter.WEPUndecryptableCount.QuadPart++;
+ } else if (pDevice->bLinkPass == true) {
+// pDevice->s802_11Counter.DecryptFailureCount.QuadPart++;
+ }
+ return false;
+ }
+
+ if (byDecMode == KEY_CTL_WEP) {
+ // handle WEP
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"byDecMode == KEY_CTL_WEP\n");
+ if ((pDevice->byLocalID <= REV_ID_VT3253_A1) ||
+ (((PSKeyTable)(pKey->pvKeyTable))->bSoftWEP == true) ||
+ (bOnFly == false)) {
+ // Software WEP
+ // 1. 3253A
+ // 2. WEP 256
+ // 3. NotOnFly
+
+ PayloadLen -= (WLAN_HDR_ADDR3_LEN + 4 + 4); // 24 is 802.11 header,4 is IV, 4 is crc
+ memcpy(pDevice->abyPRNG, pbyIV, 3);
+ memcpy(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(*(u32 *)(pbyIV + 4));
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ExtIV: %x\n", *pdwRxTSC47_16);
+
+ if (byDecMode == KEY_CTL_TKIP) {
+ *pwRxTSC15_0 = cpu_to_le16(MAKEWORD(*(pbyIV+2), *pbyIV));
+ } else {
+ *pwRxTSC15_0 = cpu_to_le16(*(u16 *)pbyIV);
+ }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"TSC0_15: %x\n", *pwRxTSC15_0);
+
+ if (byDecMode == KEY_CTL_TKIP) {
+
+ if ((pDevice->byLocalID <= REV_ID_VT3253_A1) || (bOnFly == false)) {
+ // Software TKIP
+ // 1. 3253 A
+ // 2. NotOnFly
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"soft KEY_CTL_TKIP \n");
+ pMACHeader = (struct ieee80211_hdr *) (pbyFrame);
+ TKIPvMixKey(pKey->abyKey, pMACHeader->addr2, *pwRxTSC15_0, *pdwRxTSC47_16, pDevice->abyPRNG);
+ rc4_init(&pDevice->SBox, pDevice->abyPRNG, TKIP_KEY_LEN);
+ rc4_encrypt(&pDevice->SBox, pbyIV+8, pbyIV+8, PayloadLen);
+ if (ETHbIsBufferCrc32Ok(pbyIV+8, PayloadLen)) {
+ *pbyNewRsr |= NEWRSR_DECRYPTOK;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV OK!\n");
+ } else {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV FAIL!!!\n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"PayloadLen = %d\n", PayloadLen);
+ }
+ }
+ }
+
+ if (byDecMode == KEY_CTL_CCMP) {
+ if (bOnFly == false) {
+ // Software CCMP
+ // NotOnFly
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"soft KEY_CTL_CCMP\n");
+ if (AESbGenCCMP(pKey->abyKey, pbyFrame, FrameSize)) {
+ *pbyNewRsr |= NEWRSR_DECRYPTOK;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"CCMP MIC compare OK!\n");
+ } else {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"CCMP MIC fail!\n");
+ }
+ }
+ }
+
+ }// end of TKIP/AES
+
+ if ((*(pbyIV+3) & 0x20) != 0)
+ *pbExtIV = true;
+ return true;
+}
+
+static int s_bAPModeRxData(struct vnt_private *pDevice, struct sk_buff *skb,
+ u32 FrameSize, u32 cbHeaderOffset, s32 iSANodeIndex, s32 iDANodeIndex)
+{
+ struct sk_buff *skbcpy;
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ int bRelayAndForward = false;
+ int bRelayOnly = false;
+ u8 byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
+ u16 wAID;
+
+ if (FrameSize > CB_MAX_BUF_SIZE)
+ return false;
+ // check DA
+ if (is_multicast_ether_addr((u8 *)(skb->data+cbHeaderOffset))) {
+ if (pMgmt->sNodeDBTable[0].bPSEnable) {
+
+ skbcpy = dev_alloc_skb((int)pDevice->rx_buf_sz);
+
+ // if any node in PS mode, buffer packet until DTIM.
+ if (skbcpy == NULL) {
+ DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "relay multicast no skb available \n");
+ }
+ else {
+ skbcpy->dev = pDevice->dev;
+ skbcpy->len = FrameSize;
+ memcpy(skbcpy->data, skb->data+cbHeaderOffset, FrameSize);
+ skb_queue_tail(&(pMgmt->sNodeDBTable[0].sTxPSQueue), skbcpy);
+ pMgmt->sNodeDBTable[0].wEnQueueCnt++;
+ // set tx map
+ pMgmt->abyPSTxMap[0] |= byMask[0];
+ }
+ }
+ else {
+ bRelayAndForward = true;
+ }
+ }
+ else {
+ // check if relay
+ if (BSSbIsSTAInNodeDB(pDevice, (u8 *)(skb->data+cbHeaderOffset), &iDANodeIndex)) {
+ if (pMgmt->sNodeDBTable[iDANodeIndex].eNodeState >= NODE_ASSOC) {
+ if (pMgmt->sNodeDBTable[iDANodeIndex].bPSEnable) {
+ // queue this skb until next PS tx, and then release.
+
+ skb->data += cbHeaderOffset;
+ skb->tail += cbHeaderOffset;
+ skb_put(skb, FrameSize);
+ skb_queue_tail(&pMgmt->sNodeDBTable[iDANodeIndex].sTxPSQueue, skb);
+
+ pMgmt->sNodeDBTable[iDANodeIndex].wEnQueueCnt++;
+ wAID = pMgmt->sNodeDBTable[iDANodeIndex].wAID;
+ pMgmt->abyPSTxMap[wAID >> 3] |= byMask[wAID & 7];
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "relay: index= %d, pMgmt->abyPSTxMap[%d]= %d\n",
+ iDANodeIndex, (wAID >> 3), pMgmt->abyPSTxMap[wAID >> 3]);
+ return true;
+ }
+ else {
+ bRelayOnly = true;
+ }
+ }
+ }
+ }
+
+ if (bRelayOnly || bRelayAndForward) {
+ // relay this packet right now
+ if (bRelayAndForward)
+ iDANodeIndex = 0;
+
+ if ((pDevice->uAssocCount > 1) && (iDANodeIndex >= 0)) {
+ bRelayPacketSend(pDevice, (u8 *) (skb->data + cbHeaderOffset),
+ FrameSize, (unsigned int) iDANodeIndex);
+ }
+
+ if (bRelayOnly)
+ return false;
+ }
+ // none associate, don't forward
+ if (pDevice->uAssocCount == 0)
+ return false;
+
+ return true;
+}
+
+void RXvWorkItem(struct vnt_private *pDevice)
+{
+ int ntStatus;
+ PRCB pRCB = NULL;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Rx Polling Thread\n");
+ spin_lock_irq(&pDevice->lock);
+
+ while ((pDevice->Flags & fMP_POST_READS) &&
+ MP_IS_READY(pDevice) &&
+ (pDevice->NumRecvFreeList != 0) ) {
+ pRCB = pDevice->FirstRecvFreeList;
+ pDevice->NumRecvFreeList--;
+ ASSERT(pRCB);// cannot be NULL
+ DequeueRCB(pDevice->FirstRecvFreeList, pDevice->LastRecvFreeList);
+ ntStatus = PIPEnsBulkInUsbRead(pDevice, pRCB);
+ }
+ pDevice->bIsRxWorkItemQueued = false;
+ spin_unlock_irq(&pDevice->lock);
+
+}
+
+void RXvFreeRCB(PRCB pRCB, int bReAllocSkb)
+{
+ struct vnt_private *pDevice = pRCB->pDevice;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->RXvFreeRCB\n");
+
+ ASSERT(!pRCB->Ref); // should be 0
+ ASSERT(pRCB->pDevice); // shouldn't be NULL
+
+ if (bReAllocSkb == false) {
+ kfree_skb(pRCB->skb);
+ bReAllocSkb = true;
+ }
+
+ if (bReAllocSkb == true) {
+ pRCB->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
+ // todo error handling
+ if (pRCB->skb == NULL) {
+ DBG_PRT(MSG_LEVEL_ERR,KERN_ERR" Failed to re-alloc rx skb\n");
+ }else {
+ pRCB->skb->dev = pDevice->dev;
+ }
+ }
+ //
+ // Insert the RCB back in the Recv free list
+ //
+ EnqueueRCB(pDevice->FirstRecvFreeList, pDevice->LastRecvFreeList, pRCB);
+ pDevice->NumRecvFreeList++;
+
+ if ((pDevice->Flags & fMP_POST_READS) && MP_IS_READY(pDevice) &&
+ (pDevice->bIsRxWorkItemQueued == false) ) {
+
+ pDevice->bIsRxWorkItemQueued = true;
+ tasklet_schedule(&pDevice->ReadWorkItem);
+ }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"<----RXFreeRCB %d %d\n",pDevice->NumRecvFreeList, pDevice->NumRecvMngList);
+}
+
+void RXvMngWorkItem(struct vnt_private *pDevice)
+{
+ PRCB pRCB = NULL;
+ struct vnt_rx_mgmt *pRxPacket;
+ int bReAllocSkb = false;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Rx Mng Thread\n");
+
+ spin_lock_irq(&pDevice->lock);
+ while (pDevice->NumRecvMngList!=0)
+ {
+ pRCB = pDevice->FirstRecvMngList;
+ pDevice->NumRecvMngList--;
+ DequeueRCB(pDevice->FirstRecvMngList, pDevice->LastRecvMngList);
+ if(!pRCB){
+ break;
+ }
+ ASSERT(pRCB);// cannot be NULL
+ pRxPacket = &(pRCB->sMngPacket);
+ vMgrRxManagePacket(pDevice, &pDevice->vnt_mgmt, pRxPacket);
+ pRCB->Ref--;
+ if(pRCB->Ref == 0) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"RxvFreeMng %d %d\n",pDevice->NumRecvFreeList, pDevice->NumRecvMngList);
+ RXvFreeRCB(pRCB, bReAllocSkb);
+ } else {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Rx Mng Only we have the right to free RCB\n");
+ }
+ }
+
+ pDevice->bIsRxMngWorkItemQueued = false;
+ spin_unlock_irq(&pDevice->lock);
+
+}
+
diff --git a/drivers/staging/vt6656/dpc.h b/drivers/staging/vt6656/dpc.h
new file mode 100644
index 00000000..876468f2
--- /dev/null
+++ b/drivers/staging/vt6656/dpc.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: dpc.h
+ *
+ * Purpose:
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Jun. 27, 2002
+ *
+ */
+
+#ifndef __DPC_H__
+#define __DPC_H__
+
+#include "device.h"
+#include "wcmd.h"
+
+void RXvWorkItem(void *Context);
+
+void RXvMngWorkItem(void *Context);
+
+void RXvFreeRCB(PRCB pRCB, int bReAllocSkb);
+
+int RXbBulkInProcessData(struct vnt_private *, PRCB pRCB,
+ unsigned long BytesToIndicate);
+
+#endif /* __RXTX_H__ */
diff --git a/drivers/staging/vt6656/firmware.c b/drivers/staging/vt6656/firmware.c
new file mode 100644
index 00000000..a1dc3a4c
--- /dev/null
+++ b/drivers/staging/vt6656/firmware.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: baseband.c
+ *
+ * Purpose: Implement functions to access baseband
+ *
+ * Author: Yiching Chen
+ *
+ * Date: May 20, 2004
+ *
+ * Functions:
+ *
+ * Revision History:
+ *
+ */
+
+#include "firmware.h"
+#include "control.h"
+#include "rndis.h"
+
+static int msglevel =MSG_LEVEL_INFO;
+//static int msglevel =MSG_LEVEL_DEBUG;
+
+#define FIRMWARE_VERSION 0x133 /* version 1.51 */
+#define FIRMWARE_NAME "vntwusb.fw"
+
+#define FIRMWARE_CHUNK_SIZE 0x400
+
+int FIRMWAREbDownload(struct vnt_private *pDevice)
+{
+ struct device *dev = &pDevice->usb->dev;
+ const struct firmware *fw;
+ int NdisStatus;
+ void *pBuffer = NULL;
+ bool result = false;
+ u16 wLength;
+ int ii, rc;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Download firmware\n");
+ spin_unlock_irq(&pDevice->lock);
+
+ rc = request_firmware(&fw, FIRMWARE_NAME, dev);
+ if (rc) {
+ dev_err(dev, "firmware file %s request failed (%d)\n",
+ FIRMWARE_NAME, rc);
+ goto out;
+ }
+
+ pBuffer = kmalloc(FIRMWARE_CHUNK_SIZE, GFP_KERNEL);
+ if (!pBuffer)
+ goto out;
+
+ for (ii = 0; ii < fw->size; ii += FIRMWARE_CHUNK_SIZE) {
+ wLength = min_t(int, fw->size - ii, FIRMWARE_CHUNK_SIZE);
+ memcpy(pBuffer, fw->data + ii, wLength);
+
+ NdisStatus = CONTROLnsRequestOutAsyn(pDevice,
+ 0,
+ 0x1200+ii,
+ 0x0000,
+ wLength,
+ pBuffer
+ );
+
+ DBG_PRT(MSG_LEVEL_DEBUG,
+ KERN_INFO"Download firmware...%d %zu\n", ii, fw->size);
+ if (NdisStatus != STATUS_SUCCESS)
+ goto free_fw;
+ }
+
+ result = true;
+free_fw:
+ release_firmware(fw);
+
+out:
+ kfree(pBuffer);
+
+ spin_lock_irq(&pDevice->lock);
+ return result;
+}
+MODULE_FIRMWARE(FIRMWARE_NAME);
+
+int FIRMWAREbBrach2Sram(struct vnt_private *pDevice)
+{
+ int NdisStatus;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Branch to Sram\n");
+
+ NdisStatus = CONTROLnsRequestOut(pDevice,
+ 1,
+ 0x1200,
+ 0x0000,
+ 0,
+ NULL
+ );
+
+ if (NdisStatus != STATUS_SUCCESS) {
+ return (false);
+ } else {
+ return (true);
+ }
+}
+
+int FIRMWAREbCheckVersion(struct vnt_private *pDevice)
+{
+ int ntStatus;
+
+ ntStatus = CONTROLnsRequestIn(pDevice,
+ MESSAGE_TYPE_READ,
+ 0,
+ MESSAGE_REQUEST_VERSION,
+ 2,
+ (u8 *) &(pDevice->wFirmwareVersion));
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Firmware Version [%04x]\n", pDevice->wFirmwareVersion);
+ if (ntStatus != STATUS_SUCCESS) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Firmware Invalid.\n");
+ return false;
+ }
+ if (pDevice->wFirmwareVersion == 0xFFFF) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"In Loader.\n");
+ return false;
+ }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Firmware Version [%04x]\n", pDevice->wFirmwareVersion);
+ if (pDevice->wFirmwareVersion < FIRMWARE_VERSION) {
+ // branch to loader for download new firmware
+ FIRMWAREbBrach2Sram(pDevice);
+ return false;
+ }
+ return true;
+}
diff --git a/drivers/staging/vt6656/firmware.h b/drivers/staging/vt6656/firmware.h
new file mode 100644
index 00000000..e3b08db6
--- /dev/null
+++ b/drivers/staging/vt6656/firmware.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: firmware.h
+ *
+ * Purpose: Version and Release Information
+ *
+ * Author: Yiching Chen
+ *
+ * Date: May 20, 2004
+ *
+ */
+
+#ifndef __FIRMWARE_H__
+#define __FIRMWARE_H__
+
+#include "device.h"
+
+int FIRMWAREbDownload(struct vnt_private *);
+int FIRMWAREbBrach2Sram(struct vnt_private *);
+int FIRMWAREbCheckVersion(struct vnt_private *);
+
+#endif /* __FIRMWARE_H__ */
diff --git a/drivers/staging/vt6656/hostap.c b/drivers/staging/vt6656/hostap.c
new file mode 100644
index 00000000..c699a305
--- /dev/null
+++ b/drivers/staging/vt6656/hostap.c
@@ -0,0 +1,778 @@
+/*
+ * 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 daemon ioctl input/out functions
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: Oct. 20, 2003
+ *
+ * Functions:
+ *
+ * Revision History:
+ *
+ */
+
+#include "hostap.h"
+#include "iocmd.h"
+#include "mac.h"
+#include "card.h"
+#include "baseband.h"
+#include "wpactl.h"
+#include "key.h"
+#include "datarate.h"
+
+#define VIAWGET_HOSTAPD_MAX_BUF_SIZE 1024
+#define HOSTAP_CRYPT_FLAG_SET_TX_KEY BIT0
+#define HOSTAP_CRYPT_ERR_UNKNOWN_ADDR 3
+#define HOSTAP_CRYPT_ERR_KEY_SET_FAILED 5
+
+static int msglevel =MSG_LEVEL_INFO;
+
+/*
+ * Description:
+ * register net_device (AP) for hostap daemon
+ *
+ * Parameters:
+ * In:
+ * pDevice -
+ * rtnl_locked -
+ * Out:
+ *
+ * Return Value:
+ *
+ */
+
+static int hostap_enable_hostapd(struct vnt_private *pDevice, int rtnl_locked)
+{
+ struct vnt_private *apdev_priv;
+ struct net_device *dev = pDevice->dev;
+ int ret;
+ const struct net_device_ops apdev_netdev_ops = {
+ .ndo_start_xmit = pDevice->tx_80211,
+ };
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Enabling hostapd mode\n", dev->name);
+
+ pDevice->apdev = kzalloc(sizeof(struct net_device), GFP_KERNEL);
+ if (pDevice->apdev == NULL)
+ return -ENOMEM;
+
+ apdev_priv = netdev_priv(pDevice->apdev);
+ *apdev_priv = *pDevice;
+ memcpy(pDevice->apdev->dev_addr, dev->dev_addr, ETH_ALEN);
+
+ pDevice->apdev->netdev_ops = &apdev_netdev_ops;
+
+ pDevice->apdev->type = ARPHRD_IEEE80211;
+
+ pDevice->apdev->base_addr = dev->base_addr;
+ pDevice->apdev->irq = dev->irq;
+ pDevice->apdev->mem_start = dev->mem_start;
+ pDevice->apdev->mem_end = dev->mem_end;
+ sprintf(pDevice->apdev->name, "%sap", dev->name);
+ if (rtnl_locked)
+ ret = register_netdevice(pDevice->apdev);
+ else
+ ret = register_netdev(pDevice->apdev);
+ if (ret) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: register_netdevice(AP) failed!\n",
+ dev->name);
+ return -1;
+ }
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Registered netdevice %s for AP management\n",
+ dev->name, pDevice->apdev->name);
+
+ KeyvInitTable(pDevice,&pDevice->sKey);
+
+ return 0;
+}
+
+/*
+ * Description:
+ * unregister net_device(AP)
+ *
+ * Parameters:
+ * In:
+ * pDevice -
+ * rtnl_locked -
+ * Out:
+ *
+ * Return Value:
+ *
+ */
+
+static int hostap_disable_hostapd(struct vnt_private *pDevice, int rtnl_locked)
+{
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: disabling hostapd mode\n", pDevice->dev->name);
+
+ if (pDevice->apdev && pDevice->apdev->name && pDevice->apdev->name[0]) {
+ if (rtnl_locked)
+ unregister_netdevice(pDevice->apdev);
+ else
+ unregister_netdev(pDevice->apdev);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Netdevice %s unregistered\n",
+ pDevice->dev->name, pDevice->apdev->name);
+ }
+ free_netdev(pDevice->apdev);
+ pDevice->apdev = NULL;
+ pDevice->bEnable8021x = false;
+ pDevice->bEnableHostWEP = false;
+ pDevice->bEncryptionEnable = false;
+
+ return 0;
+}
+
+/*
+ * Description:
+ * Set enable/disable hostapd mode
+ *
+ * Parameters:
+ * In:
+ * pDevice -
+ * rtnl_locked -
+ * Out:
+ *
+ * Return Value:
+ *
+ */
+
+int vt6656_hostap_set_hostapd(struct vnt_private *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 daemon
+ *
+ * Parameters:
+ * In:
+ * pDevice -
+ * param -
+ * Out:
+ *
+ * Return Value:
+ *
+ */
+static int hostap_remove_sta(struct vnt_private *pDevice,
+ struct viawget_hostapd_param *param)
+{
+ unsigned int uNodeIndex;
+
+ if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &uNodeIndex)) {
+ BSSvRemoveOneNode(pDevice, uNodeIndex);
+ }
+ else {
+ return -ENOENT;
+ }
+ return 0;
+}
+
+/*
+ * Description:
+ * add a station from hostap daemon
+ *
+ * Parameters:
+ * In:
+ * pDevice -
+ * param -
+ * Out:
+ *
+ * Return Value:
+ *
+ */
+static int hostap_add_sta(struct vnt_private *pDevice,
+ struct viawget_hostapd_param *param)
+{
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ unsigned int uNodeIndex;
+
+ if (!BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &uNodeIndex))
+ BSSvCreateOneNode(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 = (u16)param->u.add_sta.aid;
+
+ pMgmt->sNodeDBTable[uNodeIndex].ulLastRxJiffer = jiffies;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Add STA AID= %d \n", pMgmt->sNodeDBTable[uNodeIndex].wAID);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X \n",
+ param->sta_addr[0],
+ param->sta_addr[1],
+ param->sta_addr[2],
+ param->sta_addr[3],
+ param->sta_addr[4],
+ param->sta_addr[5]
+ ) ;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Max Support rate = %d \n",
+ pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate);
+
+ return 0;
+}
+
+/*
+ * Description:
+ * get station info
+ *
+ * Parameters:
+ * In:
+ * pDevice -
+ * param -
+ * Out:
+ *
+ * Return Value:
+ *
+ */
+
+static int hostap_get_info_sta(struct vnt_private *pDevice,
+ struct viawget_hostapd_param *param)
+{
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ unsigned int uNodeIndex;
+
+ if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &uNodeIndex)) {
+ param->u.get_info_sta.inactive_sec =
+ (jiffies - pMgmt->sNodeDBTable[uNodeIndex].ulLastRxJiffer) / HZ;
+
+ //param->u.get_info_sta.txexc = pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts;
+ }
+ else {
+ return -ENOENT;
+ }
+
+ return 0;
+}
+
+/*
+ * Description:
+ * set station flag
+ *
+ * Parameters:
+ * In:
+ * pDevice -
+ * param -
+ * Out:
+ *
+ * Return Value:
+ *
+ */
+static int hostap_set_flags_sta(struct vnt_private *pDevice,
+ struct viawget_hostapd_param *param)
+{
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ unsigned int uNodeIndex;
+
+ if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &uNodeIndex)) {
+ pMgmt->sNodeDBTable[uNodeIndex].dwFlags |= param->u.set_flags_sta.flags_or;
+ pMgmt->sNodeDBTable[uNodeIndex].dwFlags &= param->u.set_flags_sta.flags_and;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " dwFlags = %x\n",
+ (unsigned int) 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(struct vnt_private *pDevice,
+ struct viawget_hostapd_param *param)
+{
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+
+ memcpy( pMgmt->abyWPAIE,
+ param->u.generic_elem.data,
+ param->u.generic_elem.len
+ );
+
+ pMgmt->wWPAIELen = param->u.generic_elem.len;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pMgmt->wWPAIELen = %d\n", pMgmt->wWPAIELen);
+
+ // disable wpa
+ if (pMgmt->wWPAIELen == 0) {
+ pMgmt->eAuthenMode = WMAC_AUTH_OPEN;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " No WPAIE, Disable WPA \n");
+ } else {
+ // enable wpa
+ if ((pMgmt->abyWPAIE[0] == WLAN_EID_RSN_WPA) ||
+ (pMgmt->abyWPAIE[0] == WLAN_EID_RSN)) {
+ pMgmt->eAuthenMode = WMAC_AUTH_WPANONE;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set WPAIE enable WPA\n");
+ } else
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/*
+ * Description:
+ * flush station nodes table.
+ *
+ * Parameters:
+ * In:
+ * pDevice -
+ * Out:
+ *
+ * Return Value:
+ *
+ */
+
+static void hostap_flush_sta(struct vnt_private *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(struct vnt_private *pDevice,
+ struct viawget_hostapd_param *param, int param_len)
+{
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ u32 dwKeyIndex = 0;
+ u8 abyKey[MAX_KEY_LEN];
+ u8 abySeq[MAX_KEY_LEN];
+ NDIS_802_11_KEY_RSC KeyRSC;
+ u8 byKeyDecMode = KEY_CTL_WEP;
+ int ret = 0;
+ s32 iNodeIndex = -1;
+ int ii;
+ int bKeyTableFull = false;
+ u16 wKeyCtl = 0;
+
+ param->u.crypt.err = 0;
+
+ if (param->u.crypt.alg > WPA_ALG_CCMP)
+ return -EINVAL;
+
+ if ((param->u.crypt.idx > 3) || (param->u.crypt.key_len > MAX_KEY_LEN)) {
+ param->u.crypt.err = HOSTAP_CRYPT_ERR_KEY_SET_FAILED;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " HOSTAP_CRYPT_ERR_KEY_SET_FAILED\n");
+ return -EINVAL;
+ }
+
+ if (is_broadcast_ether_addr(param->sta_addr)) {
+ if (param->u.crypt.idx >= MAX_GROUP_KEY)
+ return -EINVAL;
+ iNodeIndex = 0;
+
+ } else {
+ if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &iNodeIndex) == false) {
+ param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " HOSTAP_CRYPT_ERR_UNKNOWN_ADDR\n");
+ return -EINVAL;
+ }
+ }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " hostap_set_encryption: sta_index %d \n", iNodeIndex);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " hostap_set_encryption: alg %d \n", param->u.crypt.alg);
+
+ if (param->u.crypt.alg == WPA_ALG_NONE) {
+
+ if (pMgmt->sNodeDBTable[iNodeIndex].bOnFly == true) {
+ if (KeybRemoveKey( pDevice,
+ &(pDevice->sKey),
+ param->sta_addr,
+ pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex
+ ) == false) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybRemoveKey fail \n");
+ }
+ pMgmt->sNodeDBTable[iNodeIndex].bOnFly = false;
+ }
+ pMgmt->sNodeDBTable[iNodeIndex].byKeyIndex = 0;
+ pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex = 0;
+ pMgmt->sNodeDBTable[iNodeIndex].uWepKeyLength = 0;
+ pMgmt->sNodeDBTable[iNodeIndex].KeyRSC = 0;
+ pMgmt->sNodeDBTable[iNodeIndex].dwTSC47_16 = 0;
+ pMgmt->sNodeDBTable[iNodeIndex].wTSC15_0 = 0;
+ pMgmt->sNodeDBTable[iNodeIndex].byCipherSuite = 0;
+ memset(&pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[0],
+ 0,
+ MAX_KEY_LEN
+ );
+
+ return ret;
+ }
+
+ memcpy(abyKey, param->u.crypt.key, param->u.crypt.key_len);
+ // copy to node key tbl
+ pMgmt->sNodeDBTable[iNodeIndex].byKeyIndex = param->u.crypt.idx;
+ pMgmt->sNodeDBTable[iNodeIndex].uWepKeyLength = param->u.crypt.key_len;
+ memcpy(&pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[0],
+ param->u.crypt.key,
+ param->u.crypt.key_len
+ );
+
+ dwKeyIndex = (u32)(param->u.crypt.idx);
+ if (param->u.crypt.flags & HOSTAP_CRYPT_FLAG_SET_TX_KEY) {
+ pDevice->byKeyIndex = (u8)dwKeyIndex;
+ pDevice->bTransmitKey = true;
+ dwKeyIndex |= (1 << 31);
+ }
+
+ if (param->u.crypt.alg == WPA_ALG_WEP) {
+
+ if ((pDevice->bEnable8021x == false) || (iNodeIndex == 0)) {
+ KeybSetDefaultKey( pDevice,
+ &(pDevice->sKey),
+ dwKeyIndex & ~(BIT30 | USE_KEYRSC),
+ param->u.crypt.key_len,
+ NULL,
+ abyKey,
+ KEY_CTL_WEP
+ );
+
+ } else {
+ // 8021x enable, individual key
+ dwKeyIndex |= (1 << 30); // set pairwise key
+ if (KeybSetKey(pDevice, &(pDevice->sKey),
+ &param->sta_addr[0],
+ dwKeyIndex & ~(USE_KEYRSC),
+ param->u.crypt.key_len,
+ &KeyRSC, (u8 *)abyKey,
+ KEY_CTL_WEP
+ ) == true) {
+
+ pMgmt->sNodeDBTable[iNodeIndex].bOnFly = true;
+
+ } else {
+ // Key Table Full
+ pMgmt->sNodeDBTable[iNodeIndex].bOnFly = false;
+ bKeyTableFull = true;
+ }
+ }
+ pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
+ pDevice->bEncryptionEnable = true;
+ pMgmt->byCSSPK = KEY_CTL_WEP;
+ pMgmt->byCSSGK = KEY_CTL_WEP;
+ pMgmt->sNodeDBTable[iNodeIndex].byCipherSuite = KEY_CTL_WEP;
+ pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex = dwKeyIndex;
+ return ret;
+ }
+
+ if (param->u.crypt.seq) {
+ memcpy(&abySeq, param->u.crypt.seq, 8);
+ for (ii = 0 ; ii < 8 ; ii++)
+ KeyRSC |= (unsigned long)abySeq[ii] << (ii * 8);
+
+ dwKeyIndex |= 1 << 29;
+ pMgmt->sNodeDBTable[iNodeIndex].KeyRSC = KeyRSC;
+ }
+
+ if (param->u.crypt.alg == WPA_ALG_TKIP) {
+ if (param->u.crypt.key_len != MAX_KEY_LEN)
+ return -EINVAL;
+ pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
+ byKeyDecMode = KEY_CTL_TKIP;
+ pMgmt->byCSSPK = KEY_CTL_TKIP;
+ pMgmt->byCSSGK = KEY_CTL_TKIP;
+ }
+
+ if (param->u.crypt.alg == WPA_ALG_CCMP) {
+ if ((param->u.crypt.key_len != AES_KEY_LEN) ||
+ (pDevice->byLocalID <= REV_ID_VT3253_A1))
+ return -EINVAL;
+ pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
+ byKeyDecMode = KEY_CTL_CCMP;
+ pMgmt->byCSSPK = KEY_CTL_CCMP;
+ pMgmt->byCSSGK = KEY_CTL_CCMP;
+ }
+
+ if (iNodeIndex == 0) {
+ KeybSetDefaultKey( pDevice,
+ &(pDevice->sKey),
+ dwKeyIndex,
+ param->u.crypt.key_len,
+ &KeyRSC,
+ abyKey,
+ byKeyDecMode
+ );
+ pMgmt->sNodeDBTable[iNodeIndex].bOnFly = true;
+
+ } else {
+ dwKeyIndex |= (1 << 30); // set pairwise key
+ if (KeybSetKey(pDevice,
+ &(pDevice->sKey),
+ &param->sta_addr[0],
+ dwKeyIndex,
+ param->u.crypt.key_len,
+ &KeyRSC,
+ (u8 *)abyKey,
+ byKeyDecMode
+ ) == true) {
+
+ pMgmt->sNodeDBTable[iNodeIndex].bOnFly = true;
+
+ } else {
+ // Key Table Full
+ pMgmt->sNodeDBTable[iNodeIndex].bOnFly = false;
+ bKeyTableFull = true;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Key Table Full\n");
+ }
+
+ }
+
+ if (bKeyTableFull == true) {
+ wKeyCtl &= 0x7F00; // clear all key control filed
+ wKeyCtl |= (byKeyDecMode << 4);
+ wKeyCtl |= (byKeyDecMode);
+ wKeyCtl |= 0x0044; // use group key for all address
+ wKeyCtl |= 0x4000; // disable KeyTable[MAX_KEY_TABLE-1] on-fly to genernate rx int
+// Todo.. xxxxxx
+ //MACvSetDefaultKeyCtl(pDevice->PortOffset, wKeyCtl, MAX_KEY_TABLE-1, pDevice->byLocalID);
+ }
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Set key sta_index= %d \n", iNodeIndex);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " tx_index=%d len=%d \n", param->u.crypt.idx,
+ param->u.crypt.key_len );
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " key=%x-%x-%x-%x-%x-xxxxx \n",
+ pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[0],
+ pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[1],
+ pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[2],
+ pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[3],
+ pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[4]
+ );
+
+ // set wep key
+ pDevice->bEncryptionEnable = true;
+ pMgmt->sNodeDBTable[iNodeIndex].byCipherSuite = byKeyDecMode;
+ pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex = dwKeyIndex;
+ pMgmt->sNodeDBTable[iNodeIndex].dwTSC47_16 = 0;
+ pMgmt->sNodeDBTable[iNodeIndex].wTSC15_0 = 0;
+
+ return ret;
+}
+
+/*
+ * Description:
+ * get each stations encryption key
+ *
+ * Parameters:
+ * In:
+ * pDevice -
+ * param -
+ * Out:
+ *
+ * Return Value:
+ *
+ */
+static int hostap_get_encryption(struct vnt_private *pDevice,
+ struct viawget_hostapd_param *param,
+ int param_len)
+{
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ int ret = 0;
+ int ii;
+ s32 iNodeIndex = 0;
+
+ param->u.crypt.err = 0;
+
+ if (is_broadcast_ether_addr(param->sta_addr)) {
+ iNodeIndex = 0;
+ } else {
+ if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &iNodeIndex) == false) {
+ param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "hostap_get_encryption: HOSTAP_CRYPT_ERR_UNKNOWN_ADDR\n");
+ return -EINVAL;
+ }
+ }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "hostap_get_encryption: %d\n", iNodeIndex);
+ memset(param->u.crypt.seq, 0, 8);
+ for (ii = 0 ; ii < 8 ; ii++) {
+ param->u.crypt.seq[ii] = (u8)pMgmt->sNodeDBTable[iNodeIndex].KeyRSC >> (ii * 8);
+ }
+
+ return ret;
+}
+
+/*
+ * Description:
+ * vt6656_hostap_ioctl main function supported for hostap daemon.
+ *
+ * Parameters:
+ * In:
+ * pDevice -
+ * iw_point -
+ * Out:
+ *
+ * Return Value:
+ *
+ */
+
+int vt6656_hostap_ioctl(struct vnt_private *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 = kmalloc((int)p->length, (int)GFP_KERNEL);
+ if (param == NULL)
+ return -ENOMEM;
+
+ if (copy_from_user(param, p->pointer, p->length)) {
+ ret = -EFAULT;
+ goto out;
+ }
+
+ switch (param->cmd) {
+ case VIAWGET_HOSTAPD_SET_ENCRYPTION:
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_ENCRYPTION \n");
+ spin_lock_irq(&pDevice->lock);
+ ret = hostap_set_encryption(pDevice, param, p->length);
+ spin_unlock_irq(&pDevice->lock);
+ break;
+ case VIAWGET_HOSTAPD_GET_ENCRYPTION:
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_GET_ENCRYPTION \n");
+ spin_lock_irq(&pDevice->lock);
+ ret = hostap_get_encryption(pDevice, param, p->length);
+ spin_unlock_irq(&pDevice->lock);
+ break;
+ case VIAWGET_HOSTAPD_SET_ASSOC_AP_ADDR:
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_ASSOC_AP_ADDR \n");
+ ret = -EOPNOTSUPP;
+ goto out;
+ case VIAWGET_HOSTAPD_FLUSH:
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_FLUSH \n");
+ spin_lock_irq(&pDevice->lock);
+ hostap_flush_sta(pDevice);
+ spin_unlock_irq(&pDevice->lock);
+ break;
+ case VIAWGET_HOSTAPD_ADD_STA:
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_ADD_STA \n");
+ spin_lock_irq(&pDevice->lock);
+ ret = hostap_add_sta(pDevice, param);
+ spin_unlock_irq(&pDevice->lock);
+ break;
+ case VIAWGET_HOSTAPD_REMOVE_STA:
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_REMOVE_STA \n");
+ spin_lock_irq(&pDevice->lock);
+ ret = hostap_remove_sta(pDevice, param);
+ spin_unlock_irq(&pDevice->lock);
+ break;
+ case VIAWGET_HOSTAPD_GET_INFO_STA:
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_GET_INFO_STA \n");
+ ret = hostap_get_info_sta(pDevice, param);
+ ap_ioctl = 1;
+ break;
+ case VIAWGET_HOSTAPD_SET_FLAGS_STA:
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_FLAGS_STA \n");
+ ret = hostap_set_flags_sta(pDevice, param);
+ break;
+
+ case VIAWGET_HOSTAPD_MLME:
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_MLME \n");
+ return -EOPNOTSUPP;
+
+ case VIAWGET_HOSTAPD_SET_GENERIC_ELEMENT:
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_GENERIC_ELEMENT \n");
+ ret = hostap_set_generic_element(pDevice, param);
+ break;
+
+ case VIAWGET_HOSTAPD_SCAN_REQ:
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SCAN_REQ \n");
+ return -EOPNOTSUPP;
+
+ case VIAWGET_HOSTAPD_STA_CLEAR_STATS:
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_STA_CLEAR_STATS \n");
+ ret = -EOPNOTSUPP;
+ goto out;
+ default:
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "vt6656_hostap_ioctl: unknown cmd=%d\n",
+ (int)param->cmd);
+ ret = -EOPNOTSUPP;
+ goto out;
+ }
+
+ if ((ret == 0) && ap_ioctl) {
+ if (copy_to_user(p->pointer, param, p->length)) {
+ ret = -EFAULT;
+ goto out;
+ }
+ }
+
+ out:
+ kfree(param);
+
+ return ret;
+}
+
diff --git a/drivers/staging/vt6656/hostap.h b/drivers/staging/vt6656/hostap.h
new file mode 100644
index 00000000..6a68f7e6
--- /dev/null
+++ b/drivers/staging/vt6656/hostap.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: hostap.h
+ *
+ * Purpose:
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: May 21, 2003
+ *
+ */
+
+#ifndef __HOSTAP_H__
+#define __HOSTAP_H__
+
+#include "device.h"
+
+#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
+
+#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 vt6656_hostap_set_hostapd(struct vnt_private *, int val, int rtnl_locked);
+int vt6656_hostap_ioctl(struct vnt_private *, struct iw_point *p);
+
+#endif /* __HOSTAP_H__ */
diff --git a/drivers/staging/vt6656/int.c b/drivers/staging/vt6656/int.c
new file mode 100644
index 00000000..a2b4ba6d
--- /dev/null
+++ b/drivers/staging/vt6656/int.c
@@ -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: int.c
+ *
+ * Purpose: Handle USB interrupt endpoint
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Apr. 2, 2004
+ *
+ * Functions:
+ *
+ * Revision History:
+ * 04-02-2004 Jerry Chen: Initial release
+ *
+ */
+
+#include "int.h"
+#include "mib.h"
+#include "tmacro.h"
+#include "mac.h"
+#include "power.h"
+#include "bssdb.h"
+#include "usbpipe.h"
+
+static int msglevel = MSG_LEVEL_INFO; /* MSG_LEVEL_DEBUG */
+
+/*+
+ *
+ * Function: InterruptPollingThread
+ *
+ * Synopsis: Thread running at IRQL PASSIVE_LEVEL.
+ *
+ * Arguments: Device Extension
+ *
+ * Returns:
+ *
+ * Algorithm: Call USBD for input data;
+ *
+ * History: dd-mm-yyyy Author Comment
+ *
+ *
+ * Notes:
+ *
+ * USB reads are by nature 'Blocking', and when in a read, the device looks
+ * like it's in a 'stall' condition, so we deliberately time out every second
+ * if we've gotten no data
+ *
+-*/
+void INTvWorkItem(struct vnt_private *pDevice)
+{
+ int ntStatus;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Interrupt Polling Thread\n");
+
+ spin_lock_irq(&pDevice->lock);
+ if (pDevice->fKillEventPollingThread != true)
+ ntStatus = PIPEnsInterruptRead(pDevice);
+ spin_unlock_irq(&pDevice->lock);
+}
+
+void INTnsProcessData(struct vnt_private *pDevice)
+{
+ PSINTData pINTData;
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ struct net_device_stats *pStats = &pDevice->stats;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsInterruptProcessData\n");
+
+ pINTData = (PSINTData) pDevice->intBuf.pDataBuf;
+ if (pINTData->byTSR0 & TSR_VALID) {
+ STAvUpdateTDStatCounter(&(pDevice->scStatistic),
+ (u8)(pINTData->byPkt0 & 0x0F),
+ (u8)(pINTData->byPkt0>>4),
+ pINTData->byTSR0);
+ BSSvUpdateNodeTxCounter(pDevice,
+ &(pDevice->scStatistic),
+ pINTData->byTSR0,
+ pINTData->byPkt0);
+ /*DBG_PRN_GRP01(("TSR0 %02x\n", pINTData->byTSR0));*/
+ }
+ if (pINTData->byTSR1 & TSR_VALID) {
+ STAvUpdateTDStatCounter(&(pDevice->scStatistic),
+ (u8)(pINTData->byPkt1 & 0x0F),
+ (u8)(pINTData->byPkt1>>4),
+ pINTData->byTSR1);
+ BSSvUpdateNodeTxCounter(pDevice,
+ &(pDevice->scStatistic),
+ pINTData->byTSR1,
+ pINTData->byPkt1);
+ /*DBG_PRN_GRP01(("TSR1 %02x\n", pINTData->byTSR1));*/
+ }
+ if (pINTData->byTSR2 & TSR_VALID) {
+ STAvUpdateTDStatCounter(&(pDevice->scStatistic),
+ (u8)(pINTData->byPkt2 & 0x0F),
+ (u8)(pINTData->byPkt2>>4),
+ pINTData->byTSR2);
+ BSSvUpdateNodeTxCounter(pDevice,
+ &(pDevice->scStatistic),
+ pINTData->byTSR2,
+ pINTData->byPkt2);
+ /*DBG_PRN_GRP01(("TSR2 %02x\n", pINTData->byTSR2));*/
+ }
+ if (pINTData->byTSR3 & TSR_VALID) {
+ STAvUpdateTDStatCounter(&(pDevice->scStatistic),
+ (u8)(pINTData->byPkt3 & 0x0F),
+ (u8)(pINTData->byPkt3>>4),
+ pINTData->byTSR3);
+ BSSvUpdateNodeTxCounter(pDevice,
+ &(pDevice->scStatistic),
+ pINTData->byTSR3,
+ pINTData->byPkt3);
+ /*DBG_PRN_GRP01(("TSR3 %02x\n", pINTData->byTSR3));*/
+ }
+ if (pINTData->byISR0 != 0) {
+ if (pINTData->byISR0 & ISR_BNTX) {
+ if (pDevice->eOPMode == OP_MODE_AP) {
+ if (pMgmt->byDTIMCount > 0) {
+ pMgmt->byDTIMCount--;
+ pMgmt->sNodeDBTable[0].bRxPSPoll =
+ false;
+ } else if (pMgmt->byDTIMCount == 0) {
+ /* check if multicast tx buffering */
+ pMgmt->byDTIMCount =
+ pMgmt->byDTIMPeriod-1;
+ pMgmt->sNodeDBTable[0].bRxPSPoll = true;
+ if (pMgmt->sNodeDBTable[0].bPSEnable)
+ bScheduleCommand((void *) pDevice,
+ WLAN_CMD_RX_PSPOLL,
+ NULL);
+ }
+ bScheduleCommand((void *) pDevice,
+ WLAN_CMD_BECON_SEND,
+ NULL);
+ } /* if (pDevice->eOPMode == OP_MODE_AP) */
+ pDevice->bBeaconSent = true;
+ } else {
+ pDevice->bBeaconSent = false;
+ }
+ if (pINTData->byISR0 & ISR_TBTT) {
+ if (pDevice->bEnablePSMode)
+ bScheduleCommand((void *) pDevice,
+ WLAN_CMD_TBTT_WAKEUP,
+ NULL);
+ if (pDevice->bChannelSwitch) {
+ pDevice->byChannelSwitchCount--;
+ if (pDevice->byChannelSwitchCount == 0)
+ bScheduleCommand((void *) pDevice,
+ WLAN_CMD_11H_CHSW,
+ NULL);
+ }
+ }
+ pDevice->qwCurrTSF = cpu_to_le64(pINTData->qwTSF);
+ /*DBG_PRN_GRP01(("ISR0 = %02x ,
+ LoTsf = %08x,
+ HiTsf = %08x\n",
+ pINTData->byISR0,
+ pINTData->dwLoTSF,
+ pINTData->dwHiTSF)); */
+
+ STAvUpdate802_11Counter(&pDevice->s802_11Counter,
+ &pDevice->scStatistic,
+ pINTData->byRTSSuccess,
+ pINTData->byRTSFail,
+ pINTData->byACKFail,
+ pINTData->byFCSErr);
+ STAvUpdateIsrStatCounter(&pDevice->scStatistic,
+ pINTData->byISR0,
+ pINTData->byISR1);
+ }
+ if (pINTData->byISR1 != 0)
+ if (pINTData->byISR1 & ISR_GPIO3)
+ bScheduleCommand((void *) pDevice,
+ WLAN_CMD_RADIO,
+ NULL);
+ pDevice->intBuf.uDataLen = 0;
+ pDevice->intBuf.bInUse = false;
+
+ pStats->tx_packets = pDevice->scStatistic.ullTsrOK;
+ pStats->tx_bytes = pDevice->scStatistic.ullTxDirectedBytes +
+ pDevice->scStatistic.ullTxMulticastBytes +
+ pDevice->scStatistic.ullTxBroadcastBytes;
+ pStats->tx_errors = pDevice->scStatistic.dwTsrErr;
+ pStats->tx_dropped = pDevice->scStatistic.dwTsrErr;
+}
diff --git a/drivers/staging/vt6656/int.h b/drivers/staging/vt6656/int.h
new file mode 100644
index 00000000..8e6e217b
--- /dev/null
+++ b/drivers/staging/vt6656/int.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: int.h
+ *
+ * Purpose:
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Apr. 2, 2004
+ *
+ */
+
+#ifndef __INT_H__
+#define __INT_H__
+
+#include "device.h"
+
+typedef struct tagSINTData {
+ u8 byTSR0;
+ u8 byPkt0;
+ u16 wTime0;
+ u8 byTSR1;
+ u8 byPkt1;
+ u16 wTime1;
+ u8 byTSR2;
+ u8 byPkt2;
+ u16 wTime2;
+ u8 byTSR3;
+ u8 byPkt3;
+ u16 wTime3;
+ u64 qwTSF;
+ u8 byISR0;
+ u8 byISR1;
+ u8 byRTSSuccess;
+ u8 byRTSFail;
+ u8 byACKFail;
+ u8 byFCSErr;
+ u8 abySW[2];
+} __attribute__ ((__packed__))
+SINTData, *PSINTData;
+
+void INTvWorkItem(struct vnt_private *);
+void INTnsProcessData(struct vnt_private *);
+
+#endif /* __INT_H__ */
diff --git a/drivers/staging/vt6656/iocmd.h b/drivers/staging/vt6656/iocmd.h
new file mode 100644
index 00000000..f3406da7
--- /dev/null
+++ b/drivers/staging/vt6656/iocmd.h
@@ -0,0 +1,425 @@
+/*
+ * 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: iocmd.h
+ *
+ * Purpose: Handles the viawget ioctl private interface functions
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: May 8, 2002
+ *
+ */
+
+#ifndef __IOCMD_H__
+#define __IOCMD_H__
+
+// ioctl Command code
+#define MAGIC_CODE 0x3142
+#define IOCTL_CMD_TEST (SIOCDEVPRIVATE + 0)
+#define IOCTL_CMD_SET (SIOCDEVPRIVATE + 1)
+#define IOCTL_CMD_HOSTAPD (SIOCDEVPRIVATE + 2)
+#define IOCTL_CMD_WPA (SIOCDEVPRIVATE + 3)
+
+typedef enum tagWMAC_CMD {
+
+ WLAN_CMD_BSS_SCAN,
+ WLAN_CMD_BSS_JOIN,
+ WLAN_CMD_DISASSOC,
+ WLAN_CMD_SET_WEP,
+ WLAN_CMD_GET_LINK,
+ WLAN_CMD_GET_LISTLEN,
+ WLAN_CMD_GET_LIST,
+ WLAN_CMD_GET_MIB,
+ WLAN_CMD_GET_STAT,
+ WLAN_CMD_STOP_MAC,
+ WLAN_CMD_START_MAC,
+ WLAN_CMD_AP_START,
+ WLAN_CMD_SET_HOSTAPD,
+ WLAN_CMD_SET_HOSTAPD_STA,
+ WLAN_CMD_SET_802_1X,
+ WLAN_CMD_SET_HOST_WEP,
+ WLAN_CMD_SET_WPA,
+ WLAN_CMD_GET_NODE_CNT,
+ WLAN_CMD_ZONETYPE_SET,
+ WLAN_CMD_GET_NODE_LIST
+
+} WMAC_CMD, *PWMAC_CMD;
+
+typedef enum tagWZONETYPE {
+ ZoneType_USA = 0,
+ ZoneType_Japan = 1,
+ ZoneType_Europe = 2
+} WZONETYPE;
+
+#define ADHOC 0
+#define INFRA 1
+#define BOTH 2
+#define AP 3
+
+#define ADHOC_STARTED 1
+#define ADHOC_JOINTED 2
+
+#define PHY80211a 0
+#define PHY80211b 1
+#define PHY80211g 2
+
+#define SSID_ID 0
+#define SSID_MAXLEN 32
+#define BSSID_LEN 6
+#define WEP_NKEYS 4
+#define WEP_KEYMAXLEN 29
+#define WEP_40BIT_LEN 5
+#define WEP_104BIT_LEN 13
+#define WEP_232BIT_LEN 16
+
+// Ioctl interface structure
+// Command structure
+//
+typedef struct tagSCmdRequest {
+ u8 name[16];
+ void *data;
+ u16 wResult;
+ u16 wCmdCode;
+} __packed SCmdRequest, *PSCmdRequest;
+
+//
+// Scan
+//
+
+typedef struct tagSCmdScan {
+
+ u8 ssid[SSID_MAXLEN + 2];
+
+} __packed SCmdScan, *PSCmdScan;
+
+//
+// BSS Join
+//
+
+typedef struct tagSCmdBSSJoin {
+
+ u16 wBSSType;
+ u16 wBBPType;
+ u8 ssid[SSID_MAXLEN + 2];
+ u32 uChannel;
+ bool bPSEnable;
+ bool bShareKeyAuth;
+
+} __packed SCmdBSSJoin, *PSCmdBSSJoin;
+
+//
+// Zonetype Setting
+//
+
+typedef struct tagSCmdZoneTypeSet {
+
+ bool bWrite;
+ WZONETYPE ZoneType;
+
+} __packed SCmdZoneTypeSet, *PSCmdZoneTypeSet;
+
+typedef struct tagSWPAResult {
+ char ifname[100];
+ u8 proto;
+ u8 key_mgmt;
+ u8 eap_type;
+ bool authenticated;
+} __packed SWPAResult, *PSWPAResult;
+
+typedef struct tagSCmdStartAP {
+
+ u16 wBSSType;
+ u16 wBBPType;
+ u8 ssid[SSID_MAXLEN + 2];
+ u32 uChannel;
+ u32 uBeaconInt;
+ bool bShareKeyAuth;
+ u8 byBasicRate;
+
+} __packed SCmdStartAP, *PSCmdStartAP;
+
+typedef struct tagSCmdSetWEP {
+
+ bool bEnableWep;
+ u8 byKeyIndex;
+ u8 abyWepKey[WEP_NKEYS][WEP_KEYMAXLEN];
+ bool bWepKeyAvailable[WEP_NKEYS];
+ u32 auWepKeyLength[WEP_NKEYS];
+
+} __packed SCmdSetWEP, *PSCmdSetWEP;
+
+typedef struct tagSBSSIDItem {
+
+ u32 uChannel;
+ u8 abyBSSID[BSSID_LEN];
+ u8 abySSID[SSID_MAXLEN + 1];
+ u16 wBeaconInterval;
+ u16 wCapInfo;
+ u8 byNetType;
+ bool bWEPOn;
+ u32 uRSSI;
+
+} __packed SBSSIDItem;
+
+typedef struct tagSBSSIDList {
+
+ u32 uItem;
+ SBSSIDItem sBSSIDList[0];
+} __packed SBSSIDList, *PSBSSIDList;
+
+typedef struct tagSNodeItem {
+ // STA info
+ u16 wAID;
+ u8 abyMACAddr[6];
+ u16 wTxDataRate;
+ u16 wInActiveCount;
+ u16 wEnQueueCnt;
+ u16 wFlags;
+ bool bPWBitOn;
+ u8 byKeyIndex;
+ u16 wWepKeyLength;
+ u8 abyWepKey[WEP_KEYMAXLEN];
+ // Auto rate fallback vars
+ bool bIsInFallback;
+ u32 uTxFailures;
+ u32 uTxAttempts;
+ u16 wFailureRatio;
+
+} __packed SNodeItem;
+
+typedef struct tagSNodeList {
+
+ u32 uItem;
+ SNodeItem sNodeList[0];
+
+} __packed SNodeList, *PSNodeList;
+
+typedef struct tagSCmdLinkStatus {
+
+ bool bLink;
+ u16 wBSSType;
+ u8 byState;
+ u8 abyBSSID[BSSID_LEN];
+ u8 abySSID[SSID_MAXLEN + 2];
+ u32 uChannel;
+ u32 uLinkRate;
+
+} __packed SCmdLinkStatus, *PSCmdLinkStatus;
+
+//
+// 802.11 counter
+//
+typedef struct tagSDot11MIBCount {
+ u32 TransmittedFragmentCount;
+ u32 MulticastTransmittedFrameCount;
+ u32 FailedCount;
+ u32 RetryCount;
+ u32 MultipleRetryCount;
+ u32 RTSSuccessCount;
+ u32 RTSFailureCount;
+ u32 ACKFailureCount;
+ u32 FrameDuplicateCount;
+ u32 ReceivedFragmentCount;
+ u32 MulticastReceivedFrameCount;
+ u32 FCSErrorCount;
+} __packed SDot11MIBCount, *PSDot11MIBCount;
+
+//
+// statistic counter
+//
+typedef struct tagSStatMIBCount {
+ //
+ // ISR status count
+ //
+ u32 dwIsrTx0OK;
+ u32 dwIsrTx1OK;
+ u32 dwIsrBeaconTxOK;
+ u32 dwIsrRxOK;
+ u32 dwIsrTBTTInt;
+ u32 dwIsrSTIMERInt;
+ u32 dwIsrUnrecoverableError;
+ u32 dwIsrSoftInterrupt;
+ u32 dwIsrRxNoBuf;
+ /////////////////////////////////////
+
+ u32 dwIsrUnknown; /* unknown interrupt count */
+
+ // RSR status count
+ //
+ u32 dwRsrFrmAlgnErr;
+ u32 dwRsrErr;
+ u32 dwRsrCRCErr;
+ u32 dwRsrCRCOk;
+ u32 dwRsrBSSIDOk;
+ u32 dwRsrADDROk;
+ u32 dwRsrICVOk;
+ u32 dwNewRsrShortPreamble;
+ u32 dwRsrLong;
+ u32 dwRsrRunt;
+
+ u32 dwRsrRxControl;
+ u32 dwRsrRxData;
+ u32 dwRsrRxManage;
+
+ u32 dwRsrRxPacket;
+ u32 dwRsrRxOctet;
+ u32 dwRsrBroadcast;
+ u32 dwRsrMulticast;
+ u32 dwRsrDirected;
+ // 64-bit OID
+ u32 ullRsrOK;
+
+ // for some optional OIDs (64 bits) and DMI support
+ u32 ullRxBroadcastBytes;
+ u32 ullRxMulticastBytes;
+ u32 ullRxDirectedBytes;
+ u32 ullRxBroadcastFrames;
+ u32 ullRxMulticastFrames;
+ u32 ullRxDirectedFrames;
+
+ u32 dwRsrRxFragment;
+ u32 dwRsrRxFrmLen64;
+ u32 dwRsrRxFrmLen65_127;
+ u32 dwRsrRxFrmLen128_255;
+ u32 dwRsrRxFrmLen256_511;
+ u32 dwRsrRxFrmLen512_1023;
+ u32 dwRsrRxFrmLen1024_1518;
+
+ // TSR0,1 status count
+ //
+ u32 dwTsrTotalRetry[2]; /* total collision retry count */
+ u32 dwTsrOnceRetry[2]; /* this packet had one collision */
+ u32 dwTsrMoreThanOnceRetry[2]; /* this packet had many collisions */
+ u32 dwTsrRetry[2]; /* this packet has ever occur collision,
+ * that is (dwTsrOnceCollision0 plus
+ * dwTsrMoreThanOnceCollision0) */
+ u32 dwTsrACKData[2];
+ u32 dwTsrErr[2];
+ u32 dwAllTsrOK[2];
+ u32 dwTsrRetryTimeout[2];
+ u32 dwTsrTransmitTimeout[2];
+
+ u32 dwTsrTxPacket[2];
+ u32 dwTsrTxOctet[2];
+ u32 dwTsrBroadcast[2];
+ u32 dwTsrMulticast[2];
+ u32 dwTsrDirected[2];
+
+ // RD/TD count
+ u32 dwCntRxFrmLength;
+ u32 dwCntTxBufLength;
+
+ u8 abyCntRxPattern[16];
+ u8 abyCntTxPattern[16];
+
+ /* Software check.... */
+ u32 dwCntRxDataErr; /* rx buffer data CRC err count */
+ u32 dwCntDecryptErr; /* rx buffer data CRC err count */
+ u32 dwCntRxICVErr; /* rx buffer data CRC err count */
+ u32 idxRxErrorDesc; /* index for rx data error RD */
+
+ /* 64-bit OID */
+ u32 ullTsrOK[2];
+
+ // for some optional OIDs (64 bits) and DMI support
+ u32 ullTxBroadcastFrames[2];
+ u32 ullTxMulticastFrames[2];
+ u32 ullTxDirectedFrames[2];
+ u32 ullTxBroadcastBytes[2];
+ u32 ullTxMulticastBytes[2];
+ u32 ullTxDirectedBytes[2];
+} __packed SStatMIBCount, *PSStatMIBCount;
+
+typedef struct tagSCmdValue {
+
+ u32 dwValue;
+
+} __packed SCmdValue, *PSCmdValue;
+
+//
+// hostapd & viawget ioctl related
+//
+
+// VIAGWET_IOCTL_HOSTAPD ioctl() cmd:
+enum {
+ VIAWGET_HOSTAPD_FLUSH = 1,
+ VIAWGET_HOSTAPD_ADD_STA = 2,
+ VIAWGET_HOSTAPD_REMOVE_STA = 3,
+ VIAWGET_HOSTAPD_GET_INFO_STA = 4,
+ VIAWGET_HOSTAPD_SET_ENCRYPTION = 5,
+ VIAWGET_HOSTAPD_GET_ENCRYPTION = 6,
+ VIAWGET_HOSTAPD_SET_FLAGS_STA = 7,
+ VIAWGET_HOSTAPD_SET_ASSOC_AP_ADDR = 8,
+ VIAWGET_HOSTAPD_SET_GENERIC_ELEMENT = 9,
+ VIAWGET_HOSTAPD_MLME = 10,
+ VIAWGET_HOSTAPD_SCAN_REQ = 11,
+ VIAWGET_HOSTAPD_STA_CLEAR_STATS = 12,
+};
+
+#define VIAWGET_HOSTAPD_GENERIC_ELEMENT_HDR_LEN \
+((int) (&((struct viawget_hostapd_param *) 0)->u.generic_elem.data))
+
+// Maximum length for algorithm names (-1 for nul termination) used in ioctl()
+
+struct viawget_hostapd_param {
+ u32 cmd;
+ u8 sta_addr[6];
+ union {
+ struct {
+ u16 aid;
+ u16 capability;
+ u8 tx_supp_rates;
+ } add_sta;
+ struct {
+ u32 inactive_sec;
+ } get_info_sta;
+ struct {
+ u8 alg;
+ u32 flags;
+ u32 err;
+ u8 idx;
+ u8 seq[8];
+ u16 key_len;
+ u8 key[0];
+ } crypt;
+ struct {
+ u32 flags_and;
+ u32 flags_or;
+ } set_flags_sta;
+ struct {
+ u16 rid;
+ u16 len;
+ u8 data[0];
+ } rid;
+ struct {
+ u8 len;
+ u8 data[0];
+ } generic_elem;
+ struct {
+ u16 cmd;
+ u16 reason_code;
+ } mlme;
+ struct {
+ u8 ssid_len;
+ u8 ssid[32];
+ } scan_req;
+ } u;
+} __packed;
+
+#endif /* __IOCMD_H__ */
diff --git a/drivers/staging/vt6656/iowpa.h b/drivers/staging/vt6656/iowpa.h
new file mode 100644
index 00000000..97af32e1
--- /dev/null
+++ b/drivers/staging/vt6656/iowpa.h
@@ -0,0 +1,128 @@
+/*
+ * 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: iowpa.h
+ *
+ * Purpose: Handles wpa supplicant ioctl interface
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: May 8, 2002
+ *
+ */
+
+#ifndef __IOWPA_H__
+#define __IOWPA_H__
+
+#define WPA_IE_LEN 64
+
+//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_PSK, KEY_MGMT_NONE,
+ KEY_MGMT_802_1X_NO_WPA, KEY_MGMT_WPA_NONE } wpa_key_mgmt;
+*/
+
+enum {
+ VIAWGET_SET_WPA = 1,
+ VIAWGET_SET_KEY = 2,
+ VIAWGET_SET_SCAN = 3,
+ VIAWGET_GET_SCAN = 4,
+ VIAWGET_GET_SSID = 5,
+ VIAWGET_GET_BSSID = 6,
+ VIAWGET_SET_DROP_UNENCRYPT = 7,
+ VIAWGET_SET_DEAUTHENTICATE = 8,
+ VIAWGET_SET_ASSOCIATE = 9,
+ VIAWGET_SET_DISASSOCIATE = 10
+};
+
+enum {
+ VIAWGET_ASSOC_MSG = 1,
+ VIAWGET_DISASSOC_MSG = 2,
+ VIAWGET_PTK_MIC_MSG = 3,
+ VIAWGET_GTK_MIC_MSG = 4,
+ VIAWGET_CCKM_ROAM_MSG = 5,
+ VIAWGET_DEVICECLOSE_MSG = 6
+};
+
+typedef struct viawget_wpa_header {
+ u8 type;
+ u16 req_ie_len;
+ u16 resp_ie_len;
+} __packed viawget_wpa_header;
+
+struct viawget_wpa_param {
+ u32 cmd;
+ u8 addr[6];
+ union {
+ struct {
+ u8 len;
+ u8 data[0];
+ } generic_elem;
+ struct {
+ u8 bssid[6];
+ u8 ssid[32];
+ u8 ssid_len;
+ u8 *wpa_ie;
+ u16 wpa_ie_len;
+ int pairwise_suite;
+ int group_suite;
+ int key_mgmt_suite;
+ int auth_alg;
+ int mode;
+ u8 roam_dbm;
+ } wpa_associate;
+ struct {
+ int alg_name;
+ u16 key_index;
+ u16 set_tx;
+ u8 *seq;
+ u16 seq_len;
+ u8 *key;
+ u16 key_len;
+ } wpa_key;
+ struct {
+ u8 ssid_len;
+ u8 ssid[32];
+ } scan_req;
+ struct {
+ u16 scan_count;
+ u8 *buf;
+ } scan_results;
+ } u;
+} __packed;
+
+struct viawget_scan_result {
+ u8 bssid[6];
+ u8 ssid[32];
+ u16 ssid_len;
+ u8 wpa_ie[WPA_IE_LEN];
+ u16 wpa_ie_len;
+ u8 rsn_ie[WPA_IE_LEN];
+ u16 rsn_ie_len;
+ int freq; // MHz
+ int caps; // e.g. privacy
+ int qual; // signal quality
+ int noise;
+ int level;
+ int maxrate;
+} __packed;
+
+#endif /* __IOWPA_H__ */
diff --git a/drivers/staging/vt6656/iwctl.c b/drivers/staging/vt6656/iwctl.c
new file mode 100644
index 00000000..8872e0f8
--- /dev/null
+++ b/drivers/staging/vt6656/iwctl.c
@@ -0,0 +1,1837 @@
+/*
+ * 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:
+ *
+ */
+
+#include "device.h"
+#include "iwctl.h"
+#include "mac.h"
+#include "card.h"
+#include "hostap.h"
+#include "power.h"
+#include "rf.h"
+#include "iowpa.h"
+#include "wpactl.h"
+#include "control.h"
+#include "rndis.h"
+
+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
+};
+
+static int msglevel = MSG_LEVEL_INFO;
+
+struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev)
+{
+ struct vnt_private *pDevice = netdev_priv(dev);
+ long ldBm;
+
+ pDevice->wstats.status = pDevice->eOPMode;
+ if (pDevice->scStatistic.LinkQuality > 100)
+ pDevice->scStatistic.LinkQuality = 100;
+ pDevice->wstats.qual.qual =(u8)pDevice->scStatistic.LinkQuality;
+ RFvRSSITodBm(pDevice, (u8)(pDevice->uCurrRSSI), &ldBm);
+ pDevice->wstats.qual.level = ldBm;
+ pDevice->wstats.qual.noise = 0;
+ pDevice->wstats.qual.updated = 1;
+ pDevice->wstats.discard.nwid = 0;
+ pDevice->wstats.discard.code = 0;
+ pDevice->wstats.discard.fragment = 0;
+ pDevice->wstats.discard.retries = pDevice->scStatistic.dwTsrErr;
+ pDevice->wstats.discard.misc = 0;
+ pDevice->wstats.miss.beacon = 0;
+ return &pDevice->wstats;
+}
+
+/*
+ * Wireless Handler: get protocol name
+ */
+int iwctl_giwname(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ strcpy(wrqu->name, "802.11-a/b/g");
+ return 0;
+}
+
+/*
+ * Wireless Handler: set scan
+ */
+int iwctl_siwscan(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct vnt_private *pDevice = netdev_priv(dev);
+ struct iw_point *wrq = &wrqu->data;
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ struct iw_scan_req *req = (struct iw_scan_req *)extra;
+ u8 abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
+ PWLAN_IE_SSID pItemSSID = NULL;
+
+ if (!(pDevice->flags & DEVICE_FLAGS_OPENED))
+ return -EINVAL;
+
+ PRINT_K(" SIOCSIWSCAN\n");
+
+ if (pMgmt == NULL)
+ return -EFAULT;
+
+ if (pMgmt->eScanState == WMAC_IS_SCANNING) {
+ // In scanning..
+ PRINT_K("SIOCSIWSCAN(overlap??)-->In scanning...\n");
+ return -EAGAIN;
+ }
+
+ if (pDevice->byReAssocCount > 0) { // reject scan when re-associating!
+ // send scan event to wpa_Supplicant
+ union iwreq_data wrqu;
+ PRINT_K("wireless_send_event--->SIOCGIWSCAN(scan done)\n");
+ memset(&wrqu, 0, sizeof(wrqu));
+ wireless_send_event(pDevice->dev, SIOCGIWSCAN, &wrqu, NULL);
+ return 0;
+ }
+
+ spin_lock_irq(&pDevice->lock);
+
+ BSSvClearBSSList((void *)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] == '\0') {
+ if (req->essid_len > 0)
+ pItemSSID->len = req->essid_len;
+ } else {
+ pItemSSID->len = req->essid_len;
+ }
+ pMgmt->eScanType = WMAC_SCAN_PASSIVE;
+ PRINT_K("SIOCSIWSCAN:[desired_ssid=%s,len=%d]\n", ((PWLAN_IE_SSID)abyScanSSID)->abySSID,
+ ((PWLAN_IE_SSID)abyScanSSID)->len);
+ bScheduleCommand((void *)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((void *)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,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct iw_point *wrq = &wrqu->data;
+ int ii;
+ int jj;
+ int kk;
+ struct vnt_private *pDevice = netdev_priv(dev);
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ PKnownBSS pBSS;
+ PWLAN_IE_SSID pItemSSID;
+ PWLAN_IE_SUPP_RATES pSuppRates;
+ PWLAN_IE_SUPP_RATES pExtSuppRates;
+ char *current_ev = extra;
+ char *end_buf = extra + IW_SCAN_MAX_DATA;
+ char *current_val = NULL;
+ struct iw_event iwe;
+ long ldBm;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSCAN\n");
+
+ if (pMgmt == NULL)
+ return -EFAULT;
+
+ if (pMgmt->eScanState == WMAC_IS_SCANNING) {
+ // In scanning..
+ return -EAGAIN;
+ }
+ pBSS = &(pMgmt->sBSSList[0]);
+ for (ii = 0, jj = 0; jj < MAX_BSS_NUM ; jj++) {
+ if (current_ev >= end_buf)
+ break;
+ pBSS = &(pMgmt->sBSSList[jj]);
+ if (pBSS->bActive) {
+ // ADD mac address
+ memset(&iwe, 0, sizeof(iwe));
+ iwe.cmd = SIOCGIWAP;
+ iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+ memcpy(iwe.u.ap_addr.sa_data, pBSS->abyBSSID, WLAN_BSSID_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
+ // 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;
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, pItemSSID->abySSID);
+ // 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;
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
+ // 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;
+ current_ev = iwe_stream_add_event(info, current_ev,end_buf, &iwe, IW_EV_FREQ_LEN);
+ {
+ int f = (int)pBSS->uChannel - 1;
+ if (f < 0)
+ f = 0;
+ iwe.u.freq.m = frequency_list[f] * 100000;
+ iwe.u.freq.e = 1;
+ }
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
+ // ADD quality
+ memset(&iwe, 0, sizeof(iwe));
+ iwe.cmd = IWEVQUAL;
+ RFvRSSITodBm(pDevice, (u8)(pBSS->uRSSI), &ldBm);
+ iwe.u.qual.level = ldBm;
+ iwe.u.qual.noise = 0;
+
+ 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;
+
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
+ // ADD encryption
+ memset(&iwe, 0, sizeof(iwe));
+ iwe.cmd = SIOCGIWENCODE;
+ iwe.u.data.length = 0;
+ if (WLAN_GET_CAP_INFO_PRIVACY(pBSS->wCapInfo))
+ iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+ else
+ iwe.u.data.flags = IW_ENCODE_DISABLED;
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, pItemSSID->abySSID);
+
+ 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);
+ current_val = iwe_stream_add_value(info, current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
+ }
+ 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);
+ current_val = iwe_stream_add_value(info, current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
+ }
+
+ if ((current_val - current_ev) > IW_EV_LCP_LEN)
+ current_ev = current_val;
+
+ if ((pBSS->wWPALen > 0) && (pBSS->wWPALen <= MAX_WPA_IE_LEN)) {
+ memset(&iwe, 0, sizeof(iwe));
+ iwe.cmd = IWEVGENIE;
+ iwe.u.data.length = pBSS->wWPALen;
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, pBSS->byWPAIE);
+ }
+
+ if ((pBSS->wRSNLen > 0) && (pBSS->wRSNLen <= MAX_WPA_IE_LEN)) {
+ memset(&iwe, 0, sizeof(iwe));
+ iwe.cmd = IWEVGENIE;
+ iwe.u.data.length = pBSS->wRSNLen;
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, pBSS->byRSNIE);
+ }
+ }
+ } // for
+ wrq->length = current_ev - extra;
+ return 0;
+}
+
+/*
+ * Wireless Handler: set frequence or channel
+ */
+int iwctl_siwfreq(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct vnt_private *pDevice = netdev_priv(dev);
+ struct iw_freq *wrq = &wrqu->freq;
+ int rc = 0;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFREQ\n");
+
+ // If setting by frequency, convert to a channel
+ if ((wrq->e == 1) && (wrq->m >= (int)2.412e8) &&
+ (wrq->m <= (int)2.487e8)) {
+ int f = wrq->m / 100000;
+ int c = 0;
+ while ((c < 14) && (f != frequency_list[c]))
+ c++;
+ wrq->e = 0;
+ wrq->m = c + 1;
+ }
+ // Setting by channel number
+ if ((wrq->m > 14) || (wrq->e > 0)) {
+ rc = -EOPNOTSUPP;
+ } else {
+ int channel = wrq->m;
+ if ((channel < 1) || (channel > 14)) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: New channel value of %d is invalid!\n", dev->name, wrq->m);
+ rc = -EINVAL;
+ } else {
+ // Yes ! We can set it !!!
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Set to channel = %d\n", channel);
+ pDevice->uChannel = channel;
+ }
+ }
+ return rc;
+}
+
+/*
+ * Wireless Handler: get frequence or channel
+ */
+int iwctl_giwfreq(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct vnt_private *pDevice = netdev_priv(dev);
+ struct iw_freq *wrq = &wrqu->freq;
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFREQ\n");
+
+ if (pMgmt == NULL)
+ return -EFAULT;
+
+#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,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct vnt_private *pDevice = netdev_priv(dev);
+ __u32 *wmode = &wrqu->mode;
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ int rc = 0;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMODE\n");
+
+ if (pMgmt == NULL)
+ return -EFAULT;
+
+ if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP && pDevice->bEnableHostapd) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
+ "Can't set operation mode, hostapd is running\n");
+ return rc;
+ }
+
+ switch (*wmode) {
+ case IW_MODE_ADHOC:
+ if (pMgmt->eConfigMode != WMAC_CONFIG_IBSS_STA) {
+ pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA;
+ if (pDevice->flags & DEVICE_FLAGS_OPENED)
+ pDevice->bCommit = true;
+ }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to ad-hoc \n");
+ break;
+ case IW_MODE_AUTO:
+ case IW_MODE_INFRA:
+ if (pMgmt->eConfigMode != WMAC_CONFIG_ESS_STA) {
+ pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA;
+ if (pDevice->flags & DEVICE_FLAGS_OPENED)
+ pDevice->bCommit = true;
+ }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to infrastructure \n");
+ break;
+ case IW_MODE_MASTER:
+
+ pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA;
+ rc = -EOPNOTSUPP;
+ break;
+
+ if (pMgmt->eConfigMode != WMAC_CONFIG_AP) {
+ pMgmt->eConfigMode = WMAC_CONFIG_AP;
+ if (pDevice->flags & DEVICE_FLAGS_OPENED)
+ pDevice->bCommit = true;
+ }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to Access Point \n");
+ break;
+
+ case IW_MODE_REPEAT:
+ pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA;
+ rc = -EOPNOTSUPP;
+ break;
+ default:
+ rc = -EINVAL;
+ }
+
+ if (pDevice->bCommit) {
+ if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
+ netif_stop_queue(pDevice->dev);
+ spin_lock_irq(&pDevice->lock);
+ bScheduleCommand((void *) pDevice,
+ WLAN_CMD_RUN_AP, NULL);
+ spin_unlock_irq(&pDevice->lock);
+ } else {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
+ "Commit the settings\n");
+
+ spin_lock_irq(&pDevice->lock);
+
+ if (pDevice->bLinkPass &&
+ memcmp(pMgmt->abyCurrSSID,
+ pMgmt->abyDesireSSID,
+ WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN)) {
+ bScheduleCommand((void *) pDevice,
+ WLAN_CMD_DISASSOCIATE, NULL);
+ } else {
+ pDevice->bLinkPass = false;
+ pMgmt->eCurrState = WMAC_STATE_IDLE;
+ memset(pMgmt->abyCurrBSSID, 0, 6);
+ }
+
+ ControlvMaskByte(pDevice,
+ MESSAGE_REQUEST_MACREG, MAC_REG_PAPEDELAY,
+ LEDSTS_STS, LEDSTS_SLOW);
+
+ netif_stop_queue(pDevice->dev);
+
+ pMgmt->eScanType = WMAC_SCAN_ACTIVE;
+
+ if (!pDevice->bWPASuppWextEnabled)
+ bScheduleCommand((void *) pDevice,
+ WLAN_CMD_BSSID_SCAN,
+ pMgmt->abyDesireSSID);
+
+ bScheduleCommand((void *) pDevice,
+ WLAN_CMD_SSID,
+ NULL);
+
+ spin_unlock_irq(&pDevice->lock);
+ }
+ pDevice->bCommit = false;
+ }
+
+ return rc;
+}
+
+/*
+ * Wireless Handler: get operation mode
+ */
+int iwctl_giwmode(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct vnt_private *pDevice = netdev_priv(dev);
+ __u32 *wmode = &wrqu->mode;
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWMODE\n");
+
+ if (pMgmt == NULL)
+ return -EFAULT;
+
+ // 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,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct iw_point *wrq = &wrqu->data;
+ struct iw_range *range = (struct iw_range *)extra;
+ int i;
+ int k;
+ u8 abySupportedRates[13] = {
+ 0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48,
+ 0x60, 0x6C, 0x90
+ };
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRANGE\n");
+ if (wrq->pointer) {
+ wrq->length = sizeof(struct iw_range);
+ memset(range, 0, sizeof(struct iw_range));
+ range->min_nwid = 0x0000;
+ range->max_nwid = 0x0000;
+ range->num_channels = 14;
+ // Should be based on cap_rid.country to give only
+ // what the current card support
+ k = 0;
+ for (i = 0; i < 14; i++) {
+ range->freq[k].i = i + 1; // List index
+ range->freq[k].m = frequency_list[i] * 100000;
+ range->freq[k++].e = 1; // Values in table in MHz -> * 10^5 * 10
+ }
+ range->num_frequency = k;
+ // Hum... Should put the right values there
+ range->max_qual.qual = 100;
+ 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;
+
+ range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
+ IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
+
+ 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;
+ range->we_version_source = 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;
+ // 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;
+ }
+
+ return 0;
+}
+
+/*
+ * Wireless Handler : set ap mac address
+ */
+int iwctl_siwap(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct vnt_private *pDevice = netdev_priv(dev);
+ struct sockaddr *wrq = &wrqu->ap_addr;
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ int rc = 0;
+ u8 ZeroBSSID[WLAN_BSSID_LEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+ PRINT_K(" SIOCSIWAP\n");
+
+ if (pMgmt == NULL)
+ return -EFAULT;
+
+ if (wrq->sa_family != ARPHRD_ETHER) {
+ rc = -EINVAL;
+ } else {
+ memcpy(pMgmt->abyDesireBSSID, wrq->sa_data, 6);
+ // mike: add
+ if ((is_broadcast_ether_addr(pMgmt->abyDesireBSSID)) ||
+ (memcmp(pMgmt->abyDesireBSSID, ZeroBSSID, 6) == 0)) {
+ PRINT_K("SIOCSIWAP:invalid desired BSSID return!\n");
+ return rc;
+ }
+ // mike add: if desired AP is hidden ssid(there are
+ // two same BSSID in list), then ignore,because you
+ // don't known which one to be connect with??
+ {
+ unsigned ii;
+ unsigned uSameBssidNum = 0;
+ for (ii = 0; ii < MAX_BSS_NUM; ii++) {
+ if (pMgmt->sBSSList[ii].bActive &&
+ !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID,
+ pMgmt->abyDesireBSSID)) {
+ uSameBssidNum++;
+ }
+ }
+ if (uSameBssidNum >= 2) { //hit: desired AP is in hidden ssid mode!!!
+ PRINT_K("SIOCSIWAP:ignore for desired AP in hidden mode\n");
+ return rc;
+ }
+ }
+
+ if (pDevice->flags & DEVICE_FLAGS_OPENED)
+ pDevice->bCommit = true;
+ }
+ return rc;
+}
+
+/*
+ * Wireless Handler: get ap mac address
+ */
+int iwctl_giwap(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct vnt_private *pDevice = netdev_priv(dev);
+ struct sockaddr *wrq = &wrqu->ap_addr;
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAP\n");
+
+ if (pMgmt == NULL)
+ return -EFAULT;
+
+ memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6);
+
+ 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,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct iw_point *wrq = &wrqu->data;
+ struct sockaddr *sock;
+ struct iw_quality *qual;
+ struct vnt_private *pDevice = netdev_priv(dev);
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ PKnownBSS pBSS = &pMgmt->sBSSList[0];
+ int ii;
+ int jj;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAPLIST\n");
+ /* Only super-user can see AP list */
+
+ if (pBSS == NULL)
+ return -ENODEV;
+
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+
+ if (!wrq->pointer)
+ return -EINVAL;
+
+ sock = kzalloc(sizeof(struct sockaddr) * IW_MAX_AP, GFP_KERNEL);
+ if (sock == NULL)
+ return -ENOMEM;
+ qual = kzalloc(sizeof(struct iw_quality) * IW_MAX_AP, GFP_KERNEL);
+ if (qual == NULL) {
+ kfree(sock);
+ return -ENOMEM;
+ }
+
+ for (ii = 0, jj = 0; ii < MAX_BSS_NUM; ii++) {
+ if (!pBSS[ii].bActive)
+ continue;
+ if (jj >= IW_MAX_AP)
+ break;
+ memcpy(sock[jj].sa_data, pBSS[ii].abyBSSID, 6);
+ sock[jj].sa_family = ARPHRD_ETHER;
+ qual[jj].level = pBSS[ii].uRSSI;
+ qual[jj].qual = qual[jj].noise = 0;
+ qual[jj].updated = 2;
+ jj++;
+ }
+
+ wrq->flags = 1; /* Should be defined */
+ wrq->length = jj;
+ memcpy(extra, sock, sizeof(struct sockaddr) * jj);
+ memcpy(extra + sizeof(struct sockaddr) * jj, qual,
+ sizeof(struct iw_quality) * jj);
+
+ kfree(sock);
+ kfree(qual);
+
+ return 0;
+}
+
+/*
+ * Wireless Handler: set essid
+ */
+int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct vnt_private *pDevice = netdev_priv(dev);
+ struct iw_point *wrq = &wrqu->essid;
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ PWLAN_IE_SSID pItemSSID;
+
+ if (pMgmt == NULL)
+ return -EFAULT;
+
+ if (!(pDevice->flags & DEVICE_FLAGS_OPENED))
+ return -EINVAL;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWESSID :\n");
+
+ pDevice->fWPA_Authened = false;
+ // Check if we asked for `any'
+ if (wrq->flags == 0) {
+ // Just send an empty SSID list
+ memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+ memset(pMgmt->abyDesireBSSID, 0xFF,6);
+ PRINT_K("set essid to 'any' \n");
+ // Unknown desired AP, so here need not associate??
+ return 0;
+ } 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] == '\0') {
+ if (wrq->length>0)
+ pItemSSID->len = wrq->length;
+ } else {
+ pItemSSID->len = wrq->length;
+ }
+ PRINT_K("set essid to %s \n", pItemSSID->abySSID);
+
+ // mike: need clear desiredBSSID
+ if (pItemSSID->len==0) {
+ memset(pMgmt->abyDesireBSSID, 0xFF, 6);
+ return 0;
+ }
+
+ // 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;
+ u8 abyTmpDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
+ unsigned ii;
+ unsigned uSameBssidNum = 0;
+
+ memcpy(abyTmpDesireSSID, pMgmt->abyDesireSSID, sizeof(abyTmpDesireSSID));
+ pCurr = BSSpSearchBSSList(pDevice, NULL,
+ abyTmpDesireSSID,
+ pDevice->eConfigPHYMode);
+
+ if (pCurr == NULL) {
+ PRINT_K("SIOCSIWESSID:hidden ssid site survey before associate.......\n");
+ vResetCommandTimer((void *)pDevice);
+ pMgmt->eScanType = WMAC_SCAN_ACTIVE;
+ bScheduleCommand((void *)pDevice,
+ WLAN_CMD_BSSID_SCAN,
+ pMgmt->abyDesireSSID);
+ bScheduleCommand((void *)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 &&
+ !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID,
+ pCurr->abyBSSID)) {
+ uSameBssidNum++;
+ }
+ }
+ if (uSameBssidNum >= 2) { // hit: desired AP is in hidden ssid mode!!!
+ PRINT_K("SIOCSIWESSID:hidden ssid directly associate.......\n");
+ vResetCommandTimer((void *)pDevice);
+ pMgmt->eScanType = WMAC_SCAN_PASSIVE; // this scan type, you'll submit scan result!
+ bScheduleCommand((void *)pDevice,
+ WLAN_CMD_BSSID_SCAN,
+ pMgmt->abyDesireSSID);
+ bScheduleCommand((void *)pDevice,
+ WLAN_CMD_SSID,
+ pMgmt->abyDesireSSID);
+ }
+ }
+ return 0;
+ }
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set essid = %s \n", pItemSSID->abySSID);
+ }
+
+ if (pDevice->flags & DEVICE_FLAGS_OPENED)
+ pDevice->bCommit = true;
+
+ return 0;
+}
+
+/*
+ * Wireless Handler: get essid
+ */
+int iwctl_giwessid(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct vnt_private *pDevice = netdev_priv(dev);
+ struct iw_point *wrq = &wrqu->essid;
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ PWLAN_IE_SSID pItemSSID;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWESSID\n");
+
+ if (pMgmt == NULL)
+ return -EFAULT;
+
+ // 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;
+ memcpy(extra, pItemSSID->abySSID, pItemSSID->len);
+ extra[pItemSSID->len] = '\0';
+
+ wrq->length = pItemSSID->len;
+ wrq->flags = 1; // active
+
+ return 0;
+}
+
+/*
+ * Wireless Handler: set data rate
+ */
+int iwctl_siwrate(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct vnt_private *pDevice = netdev_priv(dev);
+ struct iw_param *wrq = &wrqu->bitrate;
+ int rc = 0;
+ u8 brate = 0;
+ int i;
+ u8 abySupportedRates[13] = {
+ 0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48,
+ 0x60, 0x6C, 0x90
+ };
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRATE \n");
+ if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
+ rc = -EINVAL;
+ return rc;
+ }
+
+ // First: get a valid bit rate value
+
+ // Which type of value
+ if ((wrq->value < 13) && (wrq->value >= 0)) {
+ // Setting by rate index
+ // Find value in the magic rate table
+ brate = wrq->value;
+ } else {
+ // Setting by frequency value
+ u8 normvalue = (u8)(wrq->value/500000);
+
+ // Check if rate is valid
+ for (i = 0; i < 13; i++) {
+ if (normvalue == abySupportedRates[i]) {
+ brate = i;
+ break;
+ }
+ }
+ }
+ // -1 designed the max rate (mostly auto mode)
+ if (wrq->value == -1) {
+ // Get the highest available rate
+ for (i = 0; i < 13; i++) {
+ if (abySupportedRates[i] == 0)
+ break;
+ }
+ if (i != 0)
+ brate = i - 1;
+
+ }
+ // Check that it is valid
+ // brate is index of abySupportedRates[]
+ if (brate > 13 ) {
+ rc = -EINVAL;
+ return rc;
+ }
+
+ // Now, check if we want a fixed or auto value
+ if (wrq->fixed != 0) {
+ // Fixed mode
+ // One rate, fixed
+ pDevice->bFixRate = true;
+ if ((pDevice->byBBType == BB_TYPE_11B) && (brate > 3)) {
+ pDevice->uConnectionRate = 3;
+ } else {
+ pDevice->uConnectionRate = brate;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Fixed to Rate %d \n", pDevice->uConnectionRate);
+ }
+ } else {
+ pDevice->bFixRate = false;
+ pDevice->uConnectionRate = 13;
+ }
+
+ return rc;
+}
+
+/*
+ * Wireless Handler: get data rate
+ */
+int iwctl_giwrate(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct vnt_private *pDevice = netdev_priv(dev);
+ struct iw_param *wrq = &wrqu->bitrate;
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRATE\n");
+
+ if (pMgmt == NULL)
+ return -EFAULT;
+
+ {
+ u8 abySupportedRates[13] = {
+ 0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30,
+ 0x48, 0x60, 0x6C, 0x90
+ };
+ int brate = 0;
+
+ if (pDevice->uConnectionRate < 13) {
+ brate = abySupportedRates[pDevice->uConnectionRate];
+ } else {
+ if (pDevice->byBBType == BB_TYPE_11B)
+ brate = 0x16;
+ if (pDevice->byBBType == BB_TYPE_11G)
+ brate = 0x6C;
+ if (pDevice->byBBType == BB_TYPE_11A)
+ brate = 0x6C;
+ }
+ if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
+ if (pDevice->byBBType == BB_TYPE_11B)
+ brate = 0x16;
+ if (pDevice->byBBType == BB_TYPE_11G)
+ brate = 0x6C;
+ if (pDevice->byBBType == BB_TYPE_11A)
+ brate = 0x6C;
+ }
+ if (pDevice->uConnectionRate == 13)
+ brate = abySupportedRates[pDevice->wCurrentRate];
+ wrq->value = brate * 500000;
+ // If more than one rate, set auto
+ if (pDevice->bFixRate == true)
+ wrq->fixed = true;
+ }
+
+ return 0;
+}
+
+/*
+ * Wireless Handler: set rts threshold
+ */
+int iwctl_siwrts(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct vnt_private *pDevice = netdev_priv(dev);
+ struct iw_param *wrq = &wrqu->rts;
+
+ if ((wrq->value < 0 || wrq->value > 2312) && !wrq->disabled)
+ return -EINVAL;
+
+ else if (wrq->disabled)
+ pDevice->wRTSThreshold = 2312;
+ else
+ pDevice->wRTSThreshold = wrq->value;
+
+ return 0;
+}
+
+/*
+ * Wireless Handler: get rts
+ */
+int iwctl_giwrts(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct vnt_private *pDevice = netdev_priv(dev);
+ struct iw_param *wrq = &wrqu->rts;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRTS\n");
+ wrq->value = pDevice->wRTSThreshold;
+ wrq->disabled = (wrq->value >= 2312);
+ wrq->fixed = 1;
+ return 0;
+}
+
+/*
+ * Wireless Handler: set fragment threshold
+ */
+int iwctl_siwfrag(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct vnt_private *pDevice = netdev_priv(dev);
+ struct iw_param *wrq = &wrqu->frag;
+ int rc = 0;
+ int fthr = wrq->value;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFRAG\n");
+
+ if (wrq->disabled)
+ fthr = 2312;
+ if ((fthr < 256) || (fthr > 2312)) {
+ rc = -EINVAL;
+ } else {
+ fthr &= ~0x1; // Get an even value
+ pDevice->wFragmentationThreshold = (u16)fthr;
+ }
+ return rc;
+}
+
+/*
+ * Wireless Handler: get fragment threshold
+ */
+int iwctl_giwfrag(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct vnt_private *pDevice = netdev_priv(dev);
+ struct iw_param *wrq = &wrqu->frag;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFRAG\n");
+ wrq->value = pDevice->wFragmentationThreshold;
+ wrq->disabled = (wrq->value >= 2312);
+ wrq->fixed = 1;
+ return 0;
+}
+
+/*
+ * Wireless Handler: set retry threshold
+ */
+int iwctl_siwretry(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct vnt_private *pDevice = netdev_priv(dev);
+ struct iw_param *wrq = &wrqu->retry;
+ int rc = 0;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRETRY\n");
+
+ if (wrq->disabled) {
+ rc = -EINVAL;
+ return rc;
+ }
+
+ if (wrq->flags & IW_RETRY_LIMIT) {
+ if (wrq->flags & IW_RETRY_MAX) {
+ pDevice->byLongRetryLimit = wrq->value;
+ } else if (wrq->flags & IW_RETRY_MIN) {
+ pDevice->byShortRetryLimit = wrq->value;
+ } else {
+ // No modifier : set both
+ pDevice->byShortRetryLimit = wrq->value;
+ pDevice->byLongRetryLimit = wrq->value;
+ }
+ }
+ if (wrq->flags & IW_RETRY_LIFETIME)
+ pDevice->wMaxTransmitMSDULifetime = wrq->value;
+ return rc;
+}
+
+/*
+ * Wireless Handler: get retry threshold
+ */
+int iwctl_giwretry(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct vnt_private *pDevice = netdev_priv(dev);
+ struct iw_param *wrq = &wrqu->retry;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRETRY\n");
+ wrq->disabled = 0; // Can't be disabled
+
+ // Note: by default, display the min retry number
+ if ((wrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
+ wrq->flags = IW_RETRY_LIFETIME;
+ wrq->value = (int)pDevice->wMaxTransmitMSDULifetime; // ms
+ } else if ((wrq->flags & IW_RETRY_MAX)) {
+ wrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
+ wrq->value = (int)pDevice->byLongRetryLimit;
+ } else {
+ wrq->flags = IW_RETRY_LIMIT;
+ wrq->value = (int)pDevice->byShortRetryLimit;
+ if ((int)pDevice->byShortRetryLimit != (int)pDevice->byLongRetryLimit)
+ wrq->flags |= IW_RETRY_MIN;
+ }
+ return 0;
+}
+
+/*
+ * Wireless Handler: set encode mode
+ */
+int iwctl_siwencode(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct vnt_private *pDevice = netdev_priv(dev);
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ struct iw_point *wrq = &wrqu->encoding;
+ u32 dwKeyIndex = (u32)(wrq->flags & IW_ENCODE_INDEX);
+ int ii;
+ int uu;
+ int rc = 0;
+ int index = (wrq->flags & IW_ENCODE_INDEX);
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODE\n");
+
+ if (pMgmt == NULL)
+ return -EFAULT;
+
+ // Check the size of the key
+ if (wrq->length > WLAN_WEP232_KEYLEN) {
+ rc = -EINVAL;
+ return rc;
+ }
+
+ if (dwKeyIndex > WLAN_WEP_NKEYS) {
+ rc = -EINVAL;
+ return rc;
+ }
+
+ if (dwKeyIndex > 0)
+ dwKeyIndex--;
+
+ // Send the key to the card
+ if (wrq->length > 0) {
+ if (wrq->length == WLAN_WEP232_KEYLEN) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 232 bit wep key\n");
+ } else if (wrq->length == WLAN_WEP104_KEYLEN) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 104 bit wep key\n");
+ } else if (wrq->length == WLAN_WEP40_KEYLEN) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 40 bit wep key, index= %d\n", (int)dwKeyIndex);
+ }
+ memset(pDevice->abyKey, 0, WLAN_WEP232_KEYLEN);
+ memcpy(pDevice->abyKey, extra, wrq->length);
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"abyKey: ");
+ for (ii = 0; ii < wrq->length; ii++)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pDevice->abyKey[ii]);
+
+ if (pDevice->flags & DEVICE_FLAGS_OPENED) {
+ spin_lock_irq(&pDevice->lock);
+ KeybSetDefaultKey(pDevice,
+ &(pDevice->sKey),
+ dwKeyIndex | (1 << 31),
+ wrq->length, NULL,
+ pDevice->abyKey,
+ KEY_CTL_WEP);
+ spin_unlock_irq(&pDevice->lock);
+ }
+ pDevice->byKeyIndex = (u8)dwKeyIndex;
+ pDevice->uKeyLength = wrq->length;
+ pDevice->bTransmitKey = true;
+ pDevice->bEncryptionEnable = true;
+ pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
+
+ // Do we want to just set the transmit key index?
+ if (index < 4) {
+ pDevice->byKeyIndex = index;
+ } else if (!(wrq->flags & IW_ENCODE_MODE)) {
+ rc = -EINVAL;
+ return rc;
+ }
+ }
+ // Read the flags
+ if (wrq->flags & IW_ENCODE_DISABLED) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable WEP function\n");
+ pMgmt->bShareKeyAlgorithm = false;
+ pDevice->bEncryptionEnable = false;
+ pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
+ if (pDevice->flags & DEVICE_FLAGS_OPENED) {
+ spin_lock_irq(&pDevice->lock);
+ for (uu = 0; uu < MAX_KEY_TABLE; uu++)
+ MACvDisableKeyEntry(pDevice, uu);
+ spin_unlock_irq(&pDevice->lock);
+ }
+ }
+ if (wrq->flags & IW_ENCODE_RESTRICTED) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable WEP & ShareKey System\n");
+ pMgmt->bShareKeyAlgorithm = true;
+ }
+ if (wrq->flags & IW_ENCODE_OPEN) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable WEP & Open System\n");
+ pMgmt->bShareKeyAlgorithm = false;
+ }
+
+ memset(pMgmt->abyDesireBSSID, 0xFF, 6);
+
+ return rc;
+}
+
+int iwctl_giwencode(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct vnt_private *pDevice = netdev_priv(dev);
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ struct iw_point *wrq = &wrqu->encoding;
+ char abyKey[WLAN_WEP232_KEYLEN];
+
+ unsigned index = (unsigned)(wrq->flags & IW_ENCODE_INDEX);
+ PSKeyItem pKey = NULL;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODE\n");
+
+ if (pMgmt == NULL)
+ return -EFAULT;
+
+ 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, (u8)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,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct vnt_private *pDevice = netdev_priv(dev);
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ struct iw_param *wrq = &wrqu->power;
+ int rc = 0;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER\n");
+
+ if (pMgmt == NULL)
+ return -EFAULT;
+
+ if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
+ rc = -EINVAL;
+ return rc;
+ }
+
+ spin_lock_irq(&pDevice->lock);
+
+ if (wrq->disabled) {
+ pDevice->ePSMode = WMAC_POWER_CAM;
+ PSvDisablePowerSaving(pDevice);
+ spin_unlock_irq(&pDevice->lock);
+ return rc;
+ }
+ if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
+ pDevice->ePSMode = WMAC_POWER_FAST;
+ PSvEnablePowerSaving((void *)pDevice, pMgmt->wListenInterval);
+
+ } else if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) {
+ pDevice->ePSMode = WMAC_POWER_FAST;
+ PSvEnablePowerSaving((void *)pDevice, pMgmt->wListenInterval);
+ }
+
+ spin_unlock_irq(&pDevice->lock);
+
+ switch (wrq->flags & IW_POWER_MODE) {
+ case IW_POWER_UNICAST_R:
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_UNICAST_R \n");
+ rc = -EINVAL;
+ break;
+ case IW_POWER_ALL_R:
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ALL_R \n");
+ rc = -EINVAL;
+ case IW_POWER_ON:
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ON \n");
+ break;
+ default:
+ rc = -EINVAL;
+ }
+
+ return rc;
+}
+
+/*
+ * Wireless Handler: get power mode
+ */
+int iwctl_giwpower(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct vnt_private *pDevice = netdev_priv(dev);
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ struct iw_param *wrq = &wrqu->power;
+ int mode = pDevice->ePSMode;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPOWER\n");
+
+ if (pMgmt == NULL)
+ return -EFAULT;
+
+ 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) / 100);
+ wrq->flags = IW_POWER_TIMEOUT;
+ } else {
+ wrq->value = (int)((pMgmt->wListenInterval *
+ pMgmt->wCurrBeaconPeriod) / 100);
+ 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,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct vnt_private *pDevice = netdev_priv(dev);
+ struct iw_param *wrq = &wrqu->sens;
+ long ldBm;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSENS\n");
+ if (pDevice->bLinkPass == true) {
+ RFvRSSITodBm(pDevice, (u8)(pDevice->uCurrRSSI), &ldBm);
+ wrq->value = ldBm;
+ } else {
+ wrq->value = 0;
+ }
+ wrq->disabled = (wrq->value == 0);
+ wrq->fixed = 1;
+ return 0;
+}
+
+int iwctl_siwauth(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct vnt_private *pDevice = netdev_priv(dev);
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ struct iw_param *wrq = &wrqu->param;
+ int ret = 0;
+ static int wpa_version = 0; // must be static to save the last value, einsn liu
+ static int pairwise = 0;
+
+ if (pMgmt == NULL)
+ return -EFAULT;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH\n");
+ switch (wrq->flags & IW_AUTH_INDEX) {
+ case IW_AUTH_WPA_VERSION:
+ wpa_version = wrq->value;
+ if (wrq->value == IW_AUTH_WPA_VERSION_DISABLED) {
+ PRINT_K("iwctl_siwauth:set WPADEV to disable at 1??????\n");
+ } else if (wrq->value == IW_AUTH_WPA_VERSION_WPA) {
+ PRINT_K("iwctl_siwauth:set WPADEV to WPA1******\n");
+ } else {
+ PRINT_K("iwctl_siwauth:set WPADEV to WPA2******\n");
+ }
+ break;
+ case IW_AUTH_CIPHER_PAIRWISE:
+ pairwise = wrq->value;
+ PRINT_K("iwctl_siwauth:set pairwise=%d\n", pairwise);
+ if (pairwise == IW_AUTH_CIPHER_CCMP){
+ pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
+ } else if (pairwise == IW_AUTH_CIPHER_TKIP) {
+ pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
+ } else if (pairwise == IW_AUTH_CIPHER_WEP40 ||
+ pairwise == IW_AUTH_CIPHER_WEP104) {
+ pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
+ } else if (pairwise == IW_AUTH_CIPHER_NONE) {
+ // do nothing, einsn liu
+ } else {
+ pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
+ }
+ break;
+ case IW_AUTH_CIPHER_GROUP:
+ PRINT_K("iwctl_siwauth:set GROUP=%d\n", wrq->value);
+ if (wpa_version == IW_AUTH_WPA_VERSION_DISABLED)
+ break;
+ if (pairwise == IW_AUTH_CIPHER_NONE) {
+ if (wrq->value == IW_AUTH_CIPHER_CCMP)
+ pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
+ else
+ pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
+ }
+ break;
+ case IW_AUTH_KEY_MGMT:
+ PRINT_K("iwctl_siwauth(wpa_version=%d):set KEY_MGMT=%d\n", wpa_version,wrq->value);
+ if (wpa_version == IW_AUTH_WPA_VERSION_WPA2){
+ if (wrq->value == IW_AUTH_KEY_MGMT_PSK)
+ pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK;
+ else pMgmt->eAuthenMode = WMAC_AUTH_WPA2;
+ } else if (wpa_version == IW_AUTH_WPA_VERSION_WPA) {
+ if (wrq->value == 0){
+ pMgmt->eAuthenMode = WMAC_AUTH_WPANONE;
+ } else if (wrq->value == IW_AUTH_KEY_MGMT_PSK)
+ pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK;
+ } else {
+ pMgmt->eAuthenMode = WMAC_AUTH_WPA;
+ }
+ break;
+ case IW_AUTH_TKIP_COUNTERMEASURES:
+ break; /* FIXME */
+ case IW_AUTH_DROP_UNENCRYPTED:
+ break;
+ case IW_AUTH_80211_AUTH_ALG:
+ PRINT_K("iwctl_siwauth:set AUTH_ALG=%d\n", wrq->value);
+ if (wrq->value == IW_AUTH_ALG_OPEN_SYSTEM)
+ pMgmt->bShareKeyAlgorithm = false;
+ else if (wrq->value == IW_AUTH_ALG_SHARED_KEY)
+ pMgmt->bShareKeyAlgorithm = true;
+ break;
+ case IW_AUTH_WPA_ENABLED:
+ break;
+ case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+ break;
+ case IW_AUTH_ROAMING_CONTROL:
+ ret = -EOPNOTSUPP;
+ break;
+ case IW_AUTH_PRIVACY_INVOKED:
+ pDevice->bEncryptionEnable = !!wrq->value;
+ if (pDevice->bEncryptionEnable == false) {
+ wpa_version = 0;
+ pairwise = 0;
+ pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
+ pMgmt->bShareKeyAlgorithm = false;
+ pMgmt->eAuthenMode = WMAC_AUTH_OPEN;
+ PRINT_K("iwctl_siwauth:set WPADEV to disaable at 2?????\n");
+ }
+ break;
+ default:
+ PRINT_K("iwctl_siwauth: not supported %x\n", wrq->flags);
+ ret = -EOPNOTSUPP;
+ break;
+ }
+ return ret;
+}
+
+int iwctl_giwauth(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ return -EOPNOTSUPP;
+}
+
+int iwctl_siwgenie(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct vnt_private *pDevice = netdev_priv(dev);
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ struct iw_point *wrq = &wrqu->data;
+ int ret = 0;
+
+ if (pMgmt == NULL)
+ return -EFAULT;
+
+ 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 ret;
+}
+
+int iwctl_giwgenie(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct vnt_private *pDevice = netdev_priv(dev);
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ struct iw_point *wrq = &wrqu->data;
+ int ret = 0;
+ int space = wrq->length;
+
+ if (pMgmt == NULL)
+ return -EFAULT;
+
+ 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,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct vnt_private *pDevice = netdev_priv(dev);
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ struct iw_point *wrq = &wrqu->encoding;
+ 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;
+ int set_tx = 0;
+ u8 seq[IW_ENCODE_SEQ_MAX_SIZE];
+ u8 key[64];
+ size_t seq_len = 0;
+ size_t key_len = 0;
+ u8 *buf;
+ u8 key_array[64];
+ int ret = 0;
+
+ PRINT_K("SIOCSIWENCODEEXT......\n");
+
+ if (pMgmt == NULL)
+ return -EFAULT;
+
+ if (!(pDevice->flags & DEVICE_FLAGS_OPENED))
+ return -ENODEV;
+
+ buf = kzalloc(sizeof(struct viawget_wpa_param), GFP_KERNEL);
+ if (buf == NULL)
+ return -ENOMEM;
+
+ param = (struct viawget_wpa_param *)buf;
+
+// recover alg_name
+ switch (ext->alg) {
+ case IW_ENCODE_ALG_NONE:
+ alg_name = WPA_ALG_NONE;
+ break;
+ case IW_ENCODE_ALG_WEP:
+ alg_name = WPA_ALG_WEP;
+ break;
+ case IW_ENCODE_ALG_TKIP:
+ alg_name = WPA_ALG_TKIP;
+ break;
+ case IW_ENCODE_ALG_CCMP:
+ alg_name = WPA_ALG_CCMP;
+ break;
+ default:
+ PRINT_K("Unknown alg = %d\n",ext->alg);
+ ret= -ENOMEM;
+ goto error;
+ }
+// recover addr
+ memcpy(addr, ext->addr.sa_data, ETH_ALEN);
+// recover key_idx
+ key_idx = (wrq->flags&IW_ENCODE_INDEX) - 1;
+// recover set_tx
+ if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
+ set_tx = 1;
+// recover seq,seq_len
+ if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
+ seq_len=IW_ENCODE_SEQ_MAX_SIZE;
+ memcpy(seq, ext->rx_seq, seq_len);
+ }
+// recover key,key_len
+ if (ext->key_len) {
+ key_len = ext->key_len;
+ memcpy(key, &ext->key[0], key_len);
+ }
+ memset(key_array, 0, 64);
+ if (key_len > 0) {
+ memcpy(key_array, key, key_len);
+ if (key_len == 32) {
+ // notice ! the oder
+ memcpy(&key_array[16], &key[24], 8);
+ memcpy(&key_array[24], &key[16], 8);
+ }
+ }
+
+/**************Translate iw_encode_ext to viawget_wpa_param****************/
+ memcpy(param->addr, addr, ETH_ALEN);
+ param->u.wpa_key.alg_name = (int)alg_name;
+ param->u.wpa_key.set_tx = set_tx;
+ param->u.wpa_key.key_index = key_idx;
+ param->u.wpa_key.key_len = key_len;
+ param->u.wpa_key.key = (u8 *)key_array;
+ param->u.wpa_key.seq = (u8 *)seq;
+ param->u.wpa_key.seq_len = seq_len;
+
+/****set if current action is Network Manager count?? */
+/****this method is so foolish,but there is no other way??? */
+ if (param->u.wpa_key.alg_name == WPA_ALG_NONE) {
+ if (param->u.wpa_key.key_index ==0) {
+ pDevice->bwextstep0 = true;
+ }
+ if ((pDevice->bwextstep0 == true) && (param->u.wpa_key.key_index == 1)) {
+ pDevice->bwextstep0 = false;
+ pDevice->bwextstep1 = true;
+ }
+ if ((pDevice->bwextstep1 == true) && (param->u.wpa_key.key_index == 2)) {
+ pDevice->bwextstep1 = false;
+ pDevice->bwextstep2 = true;
+ }
+ if ((pDevice->bwextstep2 == true) && (param->u.wpa_key.key_index == 3)) {
+ pDevice->bwextstep2 = false;
+ pDevice->bwextstep3 = true;
+ }
+ }
+ if (pDevice->bwextstep3 == true) {
+ PRINT_K("SIOCSIWENCODEEXT:Enable WPA WEXT SUPPORT!!!!!\n");
+ pDevice->bwextstep0 = false;
+ pDevice->bwextstep1 = false;
+ pDevice->bwextstep2 = false;
+ pDevice->bwextstep3 = false;
+ pDevice->bWPASuppWextEnabled = true;
+ memset(pMgmt->abyDesireBSSID, 0xFF, 6);
+ KeyvInitTable(pDevice, &pDevice->sKey);
+ }
+/*******/
+ spin_lock_irq(&pDevice->lock);
+ ret = wpa_set_keys(pDevice, param);
+ spin_unlock_irq(&pDevice->lock);
+
+error:
+ kfree(buf);
+ return ret;
+}
+
+int iwctl_giwencodeext(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ return -EOPNOTSUPP;
+}
+
+int iwctl_siwmlme(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct vnt_private *pDevice = netdev_priv(dev);
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ struct iw_mlme *mlme = (struct iw_mlme *)extra;
+ int ret = 0;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMLME\n");
+
+ if (pMgmt == NULL)
+ return -EFAULT;
+
+ if (memcmp(pMgmt->abyCurrBSSID, mlme->addr.sa_data, ETH_ALEN)) {
+ ret = -EINVAL;
+ return ret;
+ }
+ switch (mlme->cmd){
+ case IW_MLME_DEAUTH:
+ case IW_MLME_DISASSOC:
+ if (pDevice->bLinkPass == true) {
+ PRINT_K("iwctl_siwmlme--->send DISASSOCIATE\n");
+ bScheduleCommand((void *)pDevice, WLAN_CMD_DISASSOCIATE,
+ NULL);
+ }
+ break;
+ default:
+ ret = -EOPNOTSUPP;
+ }
+ return ret;
+}
+
+static int iwctl_config_commit(struct net_device *dev,
+ struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "SIOCSIWCOMMIT\n");
+
+ return 0;
+}
+
+static const iw_handler iwctl_handler[] = {
+ IW_HANDLER(SIOCSIWCOMMIT, iwctl_config_commit),
+ IW_HANDLER(SIOCGIWNAME, iwctl_giwname),
+ IW_HANDLER(SIOCSIWFREQ, iwctl_siwfreq),
+ IW_HANDLER(SIOCGIWFREQ, iwctl_giwfreq),
+ IW_HANDLER(SIOCSIWMODE, iwctl_siwmode),
+ IW_HANDLER(SIOCGIWMODE, iwctl_giwmode),
+ IW_HANDLER(SIOCGIWSENS, iwctl_giwsens),
+ IW_HANDLER(SIOCGIWRANGE, iwctl_giwrange),
+ IW_HANDLER(SIOCSIWAP, iwctl_siwap),
+ IW_HANDLER(SIOCGIWAP, iwctl_giwap),
+ IW_HANDLER(SIOCSIWMLME, iwctl_siwmlme),
+ IW_HANDLER(SIOCGIWAPLIST, iwctl_giwaplist),
+ IW_HANDLER(SIOCSIWSCAN, iwctl_siwscan),
+ IW_HANDLER(SIOCGIWSCAN, iwctl_giwscan),
+ IW_HANDLER(SIOCSIWESSID, iwctl_siwessid),
+ IW_HANDLER(SIOCGIWESSID, iwctl_giwessid),
+ IW_HANDLER(SIOCSIWRATE, iwctl_siwrate),
+ IW_HANDLER(SIOCGIWRATE, iwctl_giwrate),
+ IW_HANDLER(SIOCSIWRTS, iwctl_siwrts),
+ IW_HANDLER(SIOCGIWRTS, iwctl_giwrts),
+ IW_HANDLER(SIOCSIWFRAG, iwctl_siwfrag),
+ IW_HANDLER(SIOCGIWFRAG, iwctl_giwfrag),
+ IW_HANDLER(SIOCSIWRETRY, iwctl_siwretry),
+ IW_HANDLER(SIOCGIWRETRY, iwctl_giwretry),
+ IW_HANDLER(SIOCSIWENCODE, iwctl_siwencode),
+ IW_HANDLER(SIOCGIWENCODE, iwctl_giwencode),
+ IW_HANDLER(SIOCSIWPOWER, iwctl_siwpower),
+ IW_HANDLER(SIOCGIWPOWER, iwctl_giwpower),
+ IW_HANDLER(SIOCSIWGENIE, iwctl_siwgenie),
+ IW_HANDLER(SIOCGIWGENIE, iwctl_giwgenie),
+ IW_HANDLER(SIOCSIWMLME, iwctl_siwmlme),
+ IW_HANDLER(SIOCSIWAUTH, iwctl_siwauth),
+ IW_HANDLER(SIOCGIWAUTH, iwctl_giwauth),
+ IW_HANDLER(SIOCSIWENCODEEXT, iwctl_siwencodeext),
+ IW_HANDLER(SIOCGIWENCODEEXT, iwctl_giwencodeext)
+};
+
+static const iw_handler iwctl_private_handler[] = {
+ NULL, // SIOCIWFIRSTPRIV
+};
+
+const struct iw_handler_def iwctl_handler_def = {
+ .get_wireless_stats = &iwctl_get_wireless_stats,
+ .num_standard = ARRAY_SIZE(iwctl_handler),
+ .num_private = 0,
+ .num_private_args = 0,
+ .standard = iwctl_handler,
+ .private = NULL,
+ .private_args = NULL,
+};
diff --git a/drivers/staging/vt6656/iwctl.h b/drivers/staging/vt6656/iwctl.h
new file mode 100644
index 00000000..dceda0db
--- /dev/null
+++ b/drivers/staging/vt6656/iwctl.h
@@ -0,0 +1,138 @@
+/*
+ * 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__
+
+#include "device.h"
+
+struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev);
+
+int iwctl_siwap(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+
+int iwctl_giwrange(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+
+int iwctl_giwmode(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+
+int iwctl_siwmode(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+
+int iwctl_giwfreq(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+
+int iwctl_siwfreq(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+
+int iwctl_giwname(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+
+int iwctl_giwsens(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+
+int iwctl_giwap(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+
+int iwctl_giwaplist(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+
+int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+
+int iwctl_giwessid(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+
+int iwctl_siwrate(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+
+int iwctl_giwrate(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+
+int iwctl_siwrts(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+
+int iwctl_giwrts(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+
+int iwctl_siwfrag(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+
+int iwctl_giwfrag(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+
+int iwctl_siwretry(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+
+int iwctl_giwretry(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+
+int iwctl_siwencode(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+
+int iwctl_giwencode(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+
+int iwctl_siwpower(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+
+int iwctl_giwpower(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+
+int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+
+int iwctl_siwscan(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+
+int iwctl_siwauth(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+
+int iwctl_giwauth(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+
+int iwctl_siwgenie(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+
+int iwctl_giwgenie(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+
+int iwctl_siwencodeext(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+
+int iwctl_giwencodeext(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+
+int iwctl_siwmlme(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+
+extern const struct iw_handler_def iwctl_handler_def;
+extern const struct iw_priv_args iwctl_priv_args;
+
+#endif /* __IWCTL_H__ */
diff --git a/drivers/staging/vt6656/key.c b/drivers/staging/vt6656/key.c
new file mode 100644
index 00000000..205590b0
--- /dev/null
+++ b/drivers/staging/vt6656/key.c
@@ -0,0 +1,737 @@
+/*
+ * 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:
+ *
+ */
+
+#include "mac.h"
+#include "tmacro.h"
+#include "key.h"
+#include "rndis.h"
+#include "control.h"
+
+static int msglevel =MSG_LEVEL_INFO;
+//static int msglevel =MSG_LEVEL_DEBUG;
+
+static void s_vCheckKeyTableValid(struct vnt_private *pDevice,
+ PSKeyManagement pTable)
+{
+ int i;
+ u16 wLength = 0;
+ u8 pbyData[MAX_KEY_TABLE];
+
+ for (i=0;i<MAX_KEY_TABLE;i++) {
+ if ((pTable->KeyTable[i].bInUse == true) &&
+ (pTable->KeyTable[i].PairwiseKey.bKeyValid == false) &&
+ (pTable->KeyTable[i].GroupKey[0].bKeyValid == false) &&
+ (pTable->KeyTable[i].GroupKey[1].bKeyValid == false) &&
+ (pTable->KeyTable[i].GroupKey[2].bKeyValid == false) &&
+ (pTable->KeyTable[i].GroupKey[3].bKeyValid == false)
+ ) {
+
+ pTable->KeyTable[i].bInUse = false;
+ pTable->KeyTable[i].wKeyCtl = 0;
+ pTable->KeyTable[i].bSoftWEP = false;
+ pbyData[wLength++] = (u8) i;
+ //MACvDisableKeyEntry(pDevice, i);
+ }
+ }
+ if ( wLength != 0 ) {
+ CONTROLnsRequestOut(pDevice,
+ MESSAGE_TYPE_CLRKEYENTRY,
+ 0,
+ 0,
+ wLength,
+ pbyData
+ );
+ }
+
+}
+
+/*
+ * Description: Init Key management table
+ *
+ * Parameters:
+ * In:
+ * pTable - Pointer to Key table
+ * Out:
+ * none
+ *
+ * Return Value: none
+ *
+ */
+void KeyvInitTable(struct vnt_private *pDevice, PSKeyManagement pTable)
+{
+ int i, jj;
+ u8 pbyData[MAX_KEY_TABLE+1];
+
+ spin_lock_irq(&pDevice->lock);
+ for (i=0;i<MAX_KEY_TABLE;i++) {
+ pTable->KeyTable[i].bInUse = false;
+ pTable->KeyTable[i].PairwiseKey.bKeyValid = false;
+ pTable->KeyTable[i].PairwiseKey.pvKeyTable =
+ (void *)&pTable->KeyTable[i];
+ for (jj=0; jj < MAX_GROUP_KEY; jj++) {
+ pTable->KeyTable[i].GroupKey[jj].bKeyValid = false;
+ pTable->KeyTable[i].GroupKey[jj].pvKeyTable =
+ (void *) &(pTable->KeyTable[i]);
+ }
+ pTable->KeyTable[i].wKeyCtl = 0;
+ pTable->KeyTable[i].dwGTKeyIndex = 0;
+ pTable->KeyTable[i].bSoftWEP = false;
+ pbyData[i] = (u8) i;
+ }
+ pbyData[i] = (u8) i;
+ CONTROLnsRequestOut(pDevice,
+ MESSAGE_TYPE_CLRKEYENTRY,
+ 0,
+ 0,
+ 11,
+ pbyData
+ );
+
+ spin_unlock_irq(&pDevice->lock);
+
+ return;
+}
+
+/*
+ * Description: Get Key from table
+ *
+ * Parameters:
+ * In:
+ * pTable - Pointer to Key table
+ * pbyBSSID - BSSID of Key
+ * dwKeyIndex - Key Index (0xFFFFFFFF means pairwise key)
+ * Out:
+ * pKey - Key return
+ *
+ * Return Value: true if found otherwise false
+ *
+ */
+int KeybGetKey(PSKeyManagement pTable, u8 *pbyBSSID, u32 dwKeyIndex,
+ PSKeyItem *pKey)
+{
+ int i;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybGetKey()\n");
+
+ *pKey = NULL;
+ for (i=0;i<MAX_KEY_TABLE;i++) {
+ if ((pTable->KeyTable[i].bInUse == true) &&
+ !compare_ether_addr(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
+ *
+ */
+int KeybSetKey(struct vnt_private *pDevice, PSKeyManagement pTable,
+ u8 *pbyBSSID, u32 dwKeyIndex, u32 uKeyLength, u64 *KeyRSC, u8 *pbyKey,
+ u8 byKeyDecMode)
+{
+ PSKeyItem pKey;
+ int i, j, ii;
+ u32 uKeyIdx;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
+ "Enter KeybSetKey: %X\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) &&
+ !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
+ // found table already exist
+ if ((dwKeyIndex & PAIRWISE_KEY) != 0) {
+ // Pairwise key
+ pKey = &(pTable->KeyTable[i].PairwiseKey);
+ pTable->KeyTable[i].wKeyCtl &= 0xFFF0; // clear pairwise key control filed
+ pTable->KeyTable[i].wKeyCtl |= byKeyDecMode;
+ uKeyIdx = 4; // use HW key entry 4 for pairwise key
+ } else {
+ // Group key
+ if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY)
+ return (false);
+ pKey = &(pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF]);
+ if ((dwKeyIndex & TRANSMIT_KEY) != 0) {
+ // Group transmit key
+ pTable->KeyTable[i].dwGTKeyIndex = dwKeyIndex;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
+ "Group transmit key(R)[%X]: %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;
+ memcpy(pKey->abyKey, pbyKey, uKeyLength);
+ if (byKeyDecMode == KEY_CTL_WEP) {
+ if (uKeyLength == WLAN_WEP40_KEYLEN)
+ pKey->abyKey[15] &= 0x7F;
+ if (uKeyLength == WLAN_WEP104_KEYLEN)
+ pKey->abyKey[15] |= 0x80;
+ }
+ MACvSetKeyEntry(pDevice, pTable->KeyTable[i].wKeyCtl, i, uKeyIdx, pbyBSSID, (u32 *)pKey->abyKey);
+
+ if ((dwKeyIndex & USE_KEYRSC) == 0)
+ pKey->KeyRSC = 0; /* RSC set by NIC */
+ else
+ pKey->KeyRSC = *KeyRSC;
+
+ pKey->dwTSC47_16 = 0;
+ pKey->wTSC15_0 = 0;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybSetKey(R): \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->bKeyValid: %d\n ", pKey->bKeyValid);
+ //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->uKeyLength: %d\n ", pKey->uKeyLength);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->abyKey: ");
+ for (ii = 0; ii < pKey->uKeyLength; ii++) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pKey->abyKey[ii]);
+ }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %x\n ",
+ pKey->dwTSC47_16);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n ",
+ pKey->wTSC15_0);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %x\n ",
+ pKey->dwKeyIndex);
+
+ return (true);
+ }
+ }
+ if (j < (MAX_KEY_TABLE-1)) {
+ memcpy(pTable->KeyTable[j].abyBSSID, pbyBSSID, ETH_ALEN);
+ pTable->KeyTable[j].bInUse = true;
+ if ((dwKeyIndex & PAIRWISE_KEY) != 0) {
+ // Pairwise key
+ pKey = &(pTable->KeyTable[j].PairwiseKey);
+ pTable->KeyTable[j].wKeyCtl &= 0xFFF0; // clear pairwise key control filed
+ pTable->KeyTable[j].wKeyCtl |= byKeyDecMode;
+ uKeyIdx = 4; // use HW key entry 4 for pairwise key
+ } else {
+ // Group key
+ if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY)
+ return (false);
+ pKey = &(pTable->KeyTable[j].GroupKey[dwKeyIndex & 0x000000FF]);
+ if ((dwKeyIndex & TRANSMIT_KEY) != 0) {
+ // Group transmit key
+ pTable->KeyTable[j].dwGTKeyIndex = dwKeyIndex;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
+ "Group transmit key(N)[%X]: %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;
+ memcpy(pKey->abyKey, pbyKey, uKeyLength);
+ if (byKeyDecMode == KEY_CTL_WEP) {
+ if (uKeyLength == WLAN_WEP40_KEYLEN)
+ pKey->abyKey[15] &= 0x7F;
+ if (uKeyLength == WLAN_WEP104_KEYLEN)
+ pKey->abyKey[15] |= 0x80;
+ }
+ MACvSetKeyEntry(pDevice, pTable->KeyTable[j].wKeyCtl, j, uKeyIdx, pbyBSSID, (u32 *)pKey->abyKey);
+
+ if ((dwKeyIndex & USE_KEYRSC) == 0)
+ pKey->KeyRSC = 0; /* RSC set by NIC */
+ else
+ pKey->KeyRSC = *KeyRSC;
+
+ pKey->dwTSC47_16 = 0;
+ pKey->wTSC15_0 = 0;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybSetKey(N): \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->bKeyValid: %d\n ", pKey->bKeyValid);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->uKeyLength: %d\n ", (int)pKey->uKeyLength);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->abyKey: ");
+ for (ii = 0; ii < pKey->uKeyLength; ii++) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pKey->abyKey[ii]);
+ }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %x\n ",
+ pKey->dwTSC47_16);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n ", pKey->wTSC15_0);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %x\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
+ *
+ */
+
+int KeybRemoveKey(struct vnt_private *pDevice, PSKeyManagement pTable,
+ u8 *pbyBSSID, u32 dwKeyIndex)
+{
+ int i;
+ int bReturnValue = false;
+
+ if (is_broadcast_ether_addr(pbyBSSID)) {
+ // delete all keys
+ if ((dwKeyIndex & PAIRWISE_KEY) != 0) {
+ for (i=0;i<MAX_KEY_TABLE;i++) {
+ pTable->KeyTable[i].PairwiseKey.bKeyValid = false;
+ }
+ bReturnValue = true;
+ }
+ else if ((dwKeyIndex & 0x000000FF) < MAX_GROUP_KEY) {
+ for (i=0;i<MAX_KEY_TABLE;i++) {
+ pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF].bKeyValid = false;
+ if ((dwKeyIndex & 0x7FFFFFFF) == (pTable->KeyTable[i].dwGTKeyIndex & 0x7FFFFFFF)) {
+ // remove Group transmit key
+ pTable->KeyTable[i].dwGTKeyIndex = 0;
+ }
+ }
+ bReturnValue = true;
+ }
+ else {
+ bReturnValue = false;
+ }
+
+ } else {
+ for (i=0;i<MAX_KEY_TABLE;i++) {
+ if ( (pTable->KeyTable[i].bInUse == true) &&
+ !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
+
+ if ((dwKeyIndex & PAIRWISE_KEY) != 0) {
+ pTable->KeyTable[i].PairwiseKey.bKeyValid = false;
+ bReturnValue = true;
+ break;
+ }
+ else if ((dwKeyIndex & 0x000000FF) < MAX_GROUP_KEY) {
+ pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF].bKeyValid = false;
+ if ((dwKeyIndex & 0x7FFFFFFF) == (pTable->KeyTable[i].dwGTKeyIndex & 0x7FFFFFFF)) {
+ // remove Group transmit key
+ pTable->KeyTable[i].dwGTKeyIndex = 0;
+ }
+ bReturnValue = true;
+ break;
+ }
+ else {
+ bReturnValue = false;
+ break;
+ }
+ } //pTable->KeyTable[i].bInUse == true
+ } //for
+ bReturnValue = true;
+ }
+
+ s_vCheckKeyTableValid(pDevice,pTable);
+ return bReturnValue;
+
+}
+
+/*
+ * Description: Remove Key from table
+ *
+ * Parameters:
+ * In:
+ * pTable - Pointer to Key table
+ * pbyBSSID - BSSID of Key
+ * Out:
+ * none
+ *
+ * Return Value: true if success otherwise false
+ *
+ */
+int KeybRemoveAllKey(struct vnt_private *pDevice, PSKeyManagement pTable,
+ u8 *pbyBSSID)
+{
+ int i, u;
+
+ for (i=0;i<MAX_KEY_TABLE;i++) {
+ if ((pTable->KeyTable[i].bInUse == true) &&
+ !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
+ pTable->KeyTable[i].PairwiseKey.bKeyValid = false;
+ for (u = 0; u < MAX_GROUP_KEY; u++)
+ pTable->KeyTable[i].GroupKey[u].bKeyValid = false;
+
+ pTable->KeyTable[i].dwGTKeyIndex = 0;
+ s_vCheckKeyTableValid(pDevice, pTable);
+ return (true);
+ }
+ }
+ return (false);
+}
+
+/*
+ * Description: 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
+ *
+ */
+int KeybGetTransmitKey(PSKeyManagement pTable, u8 *pbyBSSID, u32 dwKeyType,
+ PSKeyItem *pKey)
+{
+ int i, ii;
+
+ *pKey = NULL;
+
+ for (i = 0; i < MAX_KEY_TABLE; i++) {
+ if ((pTable->KeyTable[i].bInUse == true) &&
+ !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
+
+ if (dwKeyType == PAIRWISE_KEY) {
+
+ if (pTable->KeyTable[i].PairwiseKey.bKeyValid == true) {
+ *pKey = &(pTable->KeyTable[i].PairwiseKey);
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybGetTransmitKey:");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"PAIRWISE_KEY: KeyTable.abyBSSID: ");
+ for (ii = 0; ii < 6; ii++) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%x ", pTable->KeyTable[i].abyBSSID[ii]);
+ }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+
+ return (true);
+ }
+ else {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"PairwiseKey.bKeyValid == false\n");
+ return (false);
+ }
+ } // End of Type == PAIRWISE
+ else {
+ if (pTable->KeyTable[i].dwGTKeyIndex == 0) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ERROR: dwGTKeyIndex == 0 !!!\n");
+ return false;
+ }
+ if (pTable->KeyTable[i].GroupKey[(pTable->KeyTable[i].dwGTKeyIndex&0x000000FF)].bKeyValid == true) {
+ *pKey = &(pTable->KeyTable[i].GroupKey[(pTable->KeyTable[i].dwGTKeyIndex&0x000000FF)]);
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybGetTransmitKey:");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"GROUP_KEY: KeyTable.abyBSSID\n");
+ for (ii = 0; ii < 6; ii++) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%x ", pTable->KeyTable[i].abyBSSID[ii]);
+ }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"dwGTKeyIndex: %X\n",
+ pTable->KeyTable[i].dwGTKeyIndex);
+
+ return (true);
+ }
+ else {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"GroupKey.bKeyValid == false\n");
+ return (false);
+ }
+ } // End of Type = GROUP
+ } // BSSID match
+ }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ERROR: NO Match BSSID !!! ");
+ for (ii = 0; ii < 6; ii++) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *(pbyBSSID+ii));
+ }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+ return (false);
+}
+
+/*
+ * Description: 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
+ *
+ */
+
+int KeybSetDefaultKey(struct vnt_private *pDevice, PSKeyManagement pTable,
+ u32 dwKeyIndex, u32 uKeyLength, u64 *KeyRSC, u8 *pbyKey,
+ u8 byKeyDecMode)
+{
+ int ii;
+ PSKeyItem pKey;
+ u32 uKeyIdx;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enter KeybSetDefaultKey: %1x, %d\n",
+ (int) dwKeyIndex, (int) uKeyLength);
+
+ if ((dwKeyIndex & PAIRWISE_KEY) != 0) { // Pairwise key
+ return (false);
+ } else if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY) {
+ return (false);
+ }
+
+ if (uKeyLength > MAX_KEY_LEN)
+ return false;
+
+ pTable->KeyTable[MAX_KEY_TABLE-1].bInUse = true;
+ for (ii = 0; ii < ETH_ALEN; ii++)
+ pTable->KeyTable[MAX_KEY_TABLE-1].abyBSSID[ii] = 0xFF;
+
+ // Group key
+ pKey = &(pTable->KeyTable[MAX_KEY_TABLE-1].GroupKey[dwKeyIndex & 0x000000FF]);
+ if ((dwKeyIndex & TRANSMIT_KEY) != 0) {
+ // Group transmit key
+ pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex = dwKeyIndex;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
+ "Group transmit key(R)[%X]: %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;
+ memcpy(pKey->abyKey, pbyKey, uKeyLength);
+ if (byKeyDecMode == KEY_CTL_WEP) {
+ if (uKeyLength == WLAN_WEP40_KEYLEN)
+ pKey->abyKey[15] &= 0x7F;
+ if (uKeyLength == WLAN_WEP104_KEYLEN)
+ pKey->abyKey[15] |= 0x80;
+ }
+
+ MACvSetKeyEntry(pDevice, pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl, MAX_KEY_TABLE-1, uKeyIdx, pTable->KeyTable[MAX_KEY_TABLE-1].abyBSSID, (u32 *) pKey->abyKey);
+
+ if ((dwKeyIndex & USE_KEYRSC) == 0)
+ pKey->KeyRSC = 0; /* RSC set by NIC */
+ else
+ pKey->KeyRSC = *KeyRSC;
+
+ pKey->dwTSC47_16 = 0;
+ pKey->wTSC15_0 = 0;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybSetKey(R): \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->bKeyValid: %d\n", pKey->bKeyValid);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->uKeyLength: %d\n", (int)pKey->uKeyLength);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->abyKey: \n");
+ for (ii = 0; ii < pKey->uKeyLength; ii++) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%x", pKey->abyKey[ii]);
+ }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %x\n",
+ pKey->dwTSC47_16);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n", pKey->wTSC15_0);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %x\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
+ *
+ */
+
+int KeybSetAllGroupKey(struct vnt_private *pDevice, PSKeyManagement pTable,
+ u32 dwKeyIndex, u32 uKeyLength, u64 *KeyRSC, u8 *pbyKey,
+ u8 byKeyDecMode)
+{
+ int i, ii;
+ PSKeyItem pKey;
+ u32 uKeyIdx;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Enter KeybSetAllGroupKey: %X\n",
+ dwKeyIndex);
+
+ if ((dwKeyIndex & PAIRWISE_KEY) != 0) { // Pairwise key
+ return (false);
+ } else if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY) {
+ return (false);
+ }
+
+ for (i=0; i < MAX_KEY_TABLE-1; i++) {
+ if (pTable->KeyTable[i].bInUse == true) {
+ // found table already exist
+ // Group key
+ pKey = &(pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF]);
+ if ((dwKeyIndex & TRANSMIT_KEY) != 0) {
+ // Group transmit key
+ pTable->KeyTable[i].dwGTKeyIndex = dwKeyIndex;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
+ "Group transmit key(R)[%X]: %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;
+ memcpy(pKey->abyKey, pbyKey, uKeyLength);
+ if (byKeyDecMode == KEY_CTL_WEP) {
+ if (uKeyLength == WLAN_WEP40_KEYLEN)
+ pKey->abyKey[15] &= 0x7F;
+ if (uKeyLength == WLAN_WEP104_KEYLEN)
+ pKey->abyKey[15] |= 0x80;
+ }
+
+ MACvSetKeyEntry(pDevice, pTable->KeyTable[i].wKeyCtl, i, uKeyIdx, pTable->KeyTable[i].abyBSSID, (u32 *) pKey->abyKey);
+
+ if ((dwKeyIndex & USE_KEYRSC) == 0)
+ pKey->KeyRSC = 0; /* RSC set by NIC */
+ else
+ pKey->KeyRSC = *KeyRSC;
+
+ pKey->dwTSC47_16 = 0;
+ pKey->wTSC15_0 = 0;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybSetKey(R): \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->bKeyValid: %d\n ", pKey->bKeyValid);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->uKeyLength: %d\n ", (int)pKey->uKeyLength);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->abyKey: ");
+ for (ii = 0; ii < pKey->uKeyLength; ii++) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", pKey->abyKey[ii]);
+ }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+
+ //DBG_PRN_GRP12(("pKey->dwTSC47_16: %lX\n ", pKey->dwTSC47_16));
+ //DBG_PRN_GRP12(("pKey->wTSC15_0: %X\n ", pKey->wTSC15_0));
+ //DBG_PRN_GRP12(("pKey->dwKeyIndex: %lX\n ", pKey->dwKeyIndex));
+
+ } // (pTable->KeyTable[i].bInUse == true)
+ }
+ return (true);
+}
diff --git a/drivers/staging/vt6656/key.h b/drivers/staging/vt6656/key.h
new file mode 100644
index 00000000..23e188d1
--- /dev/null
+++ b/drivers/staging/vt6656/key.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: key.h
+ *
+ * Purpose: Implement functions for 802.11i Key management
+ *
+ * Author: Jerry Chen
+ *
+ * Date: May 29, 2003
+ *
+ */
+
+#ifndef __KEY_H__
+#define __KEY_H__
+
+#include "tether.h"
+#include "80211mgr.h"
+
+#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;
+ u32 uKeyLength;
+ u8 abyKey[MAX_KEY_LEN];
+ u64 KeyRSC;
+ u32 dwTSC47_16;
+ u16 wTSC15_0;
+ u8 byCipherSuite;
+ u8 byReserved0;
+ u32 dwKeyIndex;
+ void *pvKeyTable;
+} SKeyItem, *PSKeyItem; //64
+
+typedef struct tagSKeyTable
+{
+ u8 abyBSSID[ETH_ALEN]; /* 6 */
+ u8 byReserved0[2]; //8
+ SKeyItem PairwiseKey;
+ SKeyItem GroupKey[MAX_GROUP_KEY]; //64*5 = 320, 320+8=328
+ u32 dwGTKeyIndex; // GroupTransmitKey Index
+ bool bInUse;
+ u16 wKeyCtl;
+ bool bSoftWEP;
+ u8 byReserved1[6];
+} SKeyTable, *PSKeyTable; //352
+
+typedef struct tagSKeyManagement
+{
+ SKeyTable KeyTable[MAX_KEY_TABLE];
+} SKeyManagement, *PSKeyManagement;
+
+void KeyvInitTable(struct vnt_private *, PSKeyManagement pTable);
+
+int KeybGetKey(PSKeyManagement pTable, u8 *pbyBSSID, u32 dwKeyIndex,
+ PSKeyItem *pKey);
+
+int KeybSetKey(struct vnt_private *, PSKeyManagement pTable, u8 *pbyBSSID,
+ u32 dwKeyIndex, u32 uKeyLength, u64 *KeyRSC, u8 *pbyKey,
+ u8 byKeyDecMode);
+
+int KeybRemoveKey(struct vnt_private *, PSKeyManagement pTable,
+ u8 *pbyBSSID, u32 dwKeyIndex);
+
+int KeybRemoveAllKey(struct vnt_private *, PSKeyManagement pTable,
+ u8 *pbyBSSID);
+
+int KeybGetTransmitKey(PSKeyManagement pTable, u8 *pbyBSSID, u32 dwKeyType,
+ PSKeyItem *pKey);
+
+int KeybSetDefaultKey(struct vnt_private *, PSKeyManagement pTable,
+ u32 dwKeyIndex, u32 uKeyLength, u64 *KeyRSC, u8 *pbyKey,
+ u8 byKeyDecMode);
+
+int KeybSetAllGroupKey(struct vnt_private *, PSKeyManagement pTable,
+ u32 dwKeyIndex, u32 uKeyLength, u64 *KeyRSC, u8 *pbyKey,
+ u8 byKeyDecMode);
+
+#endif /* __KEY_H__ */
diff --git a/drivers/staging/vt6656/mac.c b/drivers/staging/vt6656/mac.c
new file mode 100644
index 00000000..343db192
--- /dev/null
+++ b/drivers/staging/vt6656/mac.c
@@ -0,0 +1,388 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: mac.c
+ *
+ * Purpose: MAC routines
+ *
+ * Author: Tevin Chen
+ *
+ * Date: May 21, 1996
+ *
+ * Functions:
+ *
+ * Revision History:
+ */
+
+#include "tmacro.h"
+#include "tether.h"
+#include "desc.h"
+#include "mac.h"
+#include "80211hdr.h"
+#include "rndis.h"
+#include "control.h"
+
+//static int msglevel =MSG_LEVEL_DEBUG;
+static int msglevel =MSG_LEVEL_INFO;
+
+/*
+ * Description:
+ * Write MAC Multicast Address Mask
+ *
+ * Parameters:
+ * In:
+ * uByteidx - Index of Mask
+ * byData - Mask Value to write
+ * Out:
+ * none
+ *
+ * Return Value: none
+ *
+ */
+void MACvWriteMultiAddr(struct vnt_private *pDevice, u32 uByteIdx, u8 byData)
+{
+ u8 byData1;
+
+ byData1 = byData;
+ CONTROLnsRequestOut(pDevice,
+ MESSAGE_TYPE_WRITE,
+ (u16) (MAC_REG_MAR0 + uByteIdx),
+ MESSAGE_REQUEST_MACREG,
+ 1,
+ &byData1);
+}
+
+/*
+ * Description:
+ * Shut Down MAC
+ *
+ * Parameters:
+ * In:
+ * Out:
+ * none
+ *
+ *
+ */
+void MACbShutdown(struct vnt_private *pDevice)
+{
+ CONTROLnsRequestOutAsyn(pDevice,
+ MESSAGE_TYPE_MACSHUTDOWN,
+ 0,
+ 0,
+ 0,
+ NULL
+ );
+}
+
+void MACvSetBBType(struct vnt_private *pDevice, u8 byType)
+{
+ u8 pbyData[2];
+
+ pbyData[0] = byType;
+ pbyData[1] = EnCFG_BBType_MASK;
+
+ CONTROLnsRequestOut(pDevice,
+ MESSAGE_TYPE_WRITE_MASK,
+ MAC_REG_ENCFG0,
+ MESSAGE_REQUEST_MACREG,
+ 2,
+ pbyData
+ );
+}
+
+/*
+ * Description:
+ * Disable the Key Entry by MISCFIFO
+ *
+ * Parameters:
+ * In:
+ * dwIoBase - Base Address for MAC
+ *
+ * Out:
+ * none
+ *
+ * Return Value: none
+ *
+ */
+void MACvDisableKeyEntry(struct vnt_private *pDevice, u32 uEntryIdx)
+{
+ u16 wOffset;
+ u8 byData;
+
+ byData = (u8) uEntryIdx;
+
+ wOffset = MISCFIFO_KEYETRY0;
+ wOffset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE);
+
+ //VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
+ //VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, 0);
+ //VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
+
+ //issue write misc fifo command to device
+ CONTROLnsRequestOut(pDevice,
+ MESSAGE_TYPE_CLRKEYENTRY,
+ 0,
+ 0,
+ 1,
+ &byData
+ );
+}
+
+/*
+ * Description:
+ * Set the Key by MISCFIFO
+ *
+ * Parameters:
+ * In:
+ * dwIoBase - Base Address for MAC
+ *
+ * Out:
+ * none
+ *
+ * Return Value: none
+ *
+ */
+void MACvSetKeyEntry(struct vnt_private *pDevice, u16 wKeyCtl, u32 uEntryIdx,
+ u32 uKeyIdx, u8 *pbyAddr, u32 *pdwKey)
+{
+ u8 *pbyKey;
+ u16 wOffset;
+ u32 dwData1, dwData2;
+ int ii;
+ u8 pbyData[24];
+
+ if (pDevice->byLocalID <= MAC_REVISION_A1)
+ if (pDevice->vnt_mgmt.byCSSPK == KEY_CTL_CCMP)
+ return;
+
+ wOffset = MISCFIFO_KEYETRY0;
+ wOffset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE);
+
+ dwData1 = 0;
+ dwData1 |= wKeyCtl;
+ dwData1 <<= 16;
+ dwData1 |= MAKEWORD(*(pbyAddr+4), *(pbyAddr+5));
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"1. wOffset: %d, Data: %X,"\
+ " KeyCtl:%X\n", wOffset, dwData1, wKeyCtl);
+
+ //VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
+ //VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
+ //VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
+
+ //wOffset++;
+
+ dwData2 = 0;
+ dwData2 |= *(pbyAddr+3);
+ dwData2 <<= 8;
+ dwData2 |= *(pbyAddr+2);
+ dwData2 <<= 8;
+ dwData2 |= *(pbyAddr+1);
+ dwData2 <<= 8;
+ dwData2 |= *(pbyAddr+0);
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"2. wOffset: %d, Data: %X\n",
+ wOffset, dwData2);
+
+ //VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
+ //VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
+ //VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
+
+ //wOffset++;
+
+ //wOffset += (uKeyIdx * 4);
+/* for (ii=0;ii<4;ii++) {
+ // alway push 128 bits
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"3.(%d) wOffset: %d, Data: %lX\n", ii, wOffset+ii, *pdwKey);
+ VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset+ii);
+ VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, *pdwKey++);
+ VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
+ }
+*/
+ pbyKey = (u8 *)pdwKey;
+
+ pbyData[0] = (u8)dwData1;
+ pbyData[1] = (u8)(dwData1>>8);
+ pbyData[2] = (u8)(dwData1>>16);
+ pbyData[3] = (u8)(dwData1>>24);
+ pbyData[4] = (u8)dwData2;
+ pbyData[5] = (u8)(dwData2>>8);
+ pbyData[6] = (u8)(dwData2>>16);
+ pbyData[7] = (u8)(dwData2>>24);
+ for (ii = 8; ii < 24; ii++)
+ pbyData[ii] = *pbyKey++;
+
+ CONTROLnsRequestOut(pDevice,
+ MESSAGE_TYPE_SETKEY,
+ wOffset,
+ (u16)uKeyIdx,
+ 24,
+ pbyData
+ );
+
+}
+
+void MACvRegBitsOff(struct vnt_private *pDevice, u8 byRegOfs, u8 byBits)
+{
+ u8 pbyData[2];
+
+ pbyData[0] = 0;
+ pbyData[1] = byBits;
+
+ CONTROLnsRequestOut(pDevice,
+ MESSAGE_TYPE_WRITE_MASK,
+ byRegOfs,
+ MESSAGE_REQUEST_MACREG,
+ 2,
+ pbyData
+ );
+}
+
+void MACvRegBitsOn(struct vnt_private *pDevice, u8 byRegOfs, u8 byBits)
+{
+ u8 pbyData[2];
+
+ pbyData[0] = byBits;
+ pbyData[1] = byBits;
+
+ CONTROLnsRequestOut(pDevice,
+ MESSAGE_TYPE_WRITE_MASK,
+ byRegOfs,
+ MESSAGE_REQUEST_MACREG,
+ 2,
+ pbyData
+ );
+}
+
+void MACvWriteWord(struct vnt_private *pDevice, u8 byRegOfs, u16 wData)
+{
+ u8 pbyData[2];
+
+ pbyData[0] = (u8)(wData & 0xff);
+ pbyData[1] = (u8)(wData >> 8);
+
+ CONTROLnsRequestOut(pDevice,
+ MESSAGE_TYPE_WRITE,
+ byRegOfs,
+ MESSAGE_REQUEST_MACREG,
+ 2,
+ pbyData
+ );
+
+}
+
+void MACvWriteBSSIDAddress(struct vnt_private *pDevice, u8 *pbyEtherAddr)
+{
+ u8 pbyData[6];
+
+ pbyData[0] = *((u8 *)pbyEtherAddr);
+ pbyData[1] = *((u8 *)pbyEtherAddr+1);
+ pbyData[2] = *((u8 *)pbyEtherAddr+2);
+ pbyData[3] = *((u8 *)pbyEtherAddr+3);
+ pbyData[4] = *((u8 *)pbyEtherAddr+4);
+ pbyData[5] = *((u8 *)pbyEtherAddr+5);
+
+ CONTROLnsRequestOut(pDevice,
+ MESSAGE_TYPE_WRITE,
+ MAC_REG_BSSID0,
+ MESSAGE_REQUEST_MACREG,
+ 6,
+ pbyData
+ );
+}
+
+void MACvEnableProtectMD(struct vnt_private *pDevice)
+{
+ u8 pbyData[2];
+
+ pbyData[0] = EnCFG_ProtectMd;
+ pbyData[1] = EnCFG_ProtectMd;
+
+ CONTROLnsRequestOut(pDevice,
+ MESSAGE_TYPE_WRITE_MASK,
+ MAC_REG_ENCFG0,
+ MESSAGE_REQUEST_MACREG,
+ 2,
+ pbyData
+ );
+}
+
+void MACvDisableProtectMD(struct vnt_private *pDevice)
+{
+ u8 pbyData[2];
+
+ pbyData[0] = 0;
+ pbyData[1] = EnCFG_ProtectMd;
+
+ CONTROLnsRequestOut(pDevice,
+ MESSAGE_TYPE_WRITE_MASK,
+ MAC_REG_ENCFG0,
+ MESSAGE_REQUEST_MACREG,
+ 2,
+ pbyData
+ );
+}
+
+void MACvEnableBarkerPreambleMd(struct vnt_private *pDevice)
+{
+ u8 pbyData[2];
+
+ pbyData[0] = EnCFG_BarkerPream;
+ pbyData[1] = EnCFG_BarkerPream;
+
+ CONTROLnsRequestOut(pDevice,
+ MESSAGE_TYPE_WRITE_MASK,
+ MAC_REG_ENCFG2,
+ MESSAGE_REQUEST_MACREG,
+ 2,
+ pbyData
+ );
+}
+
+void MACvDisableBarkerPreambleMd(struct vnt_private *pDevice)
+{
+ u8 pbyData[2];
+
+ pbyData[0] = 0;
+ pbyData[1] = EnCFG_BarkerPream;
+
+ CONTROLnsRequestOut(pDevice,
+ MESSAGE_TYPE_WRITE_MASK,
+ MAC_REG_ENCFG2,
+ MESSAGE_REQUEST_MACREG,
+ 2,
+ pbyData
+ );
+}
+
+void MACvWriteBeaconInterval(struct vnt_private *pDevice, u16 wInterval)
+{
+ u8 pbyData[2];
+
+ pbyData[0] = (u8)(wInterval & 0xff);
+ pbyData[1] = (u8)(wInterval >> 8);
+
+ CONTROLnsRequestOut(pDevice,
+ MESSAGE_TYPE_WRITE,
+ MAC_REG_BI,
+ MESSAGE_REQUEST_MACREG,
+ 2,
+ pbyData
+ );
+}
diff --git a/drivers/staging/vt6656/mac.h b/drivers/staging/vt6656/mac.h
new file mode 100644
index 00000000..0db1be5b
--- /dev/null
+++ b/drivers/staging/vt6656/mac.h
@@ -0,0 +1,421 @@
+/*
+ * 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__
+
+#include "device.h"
+#include "tmacro.h"
+
+#define REV_ID_VT3253_A0 0x00
+#define REV_ID_VT3253_A1 0x01
+#define REV_ID_VT3253_B0 0x08
+#define REV_ID_VT3253_B1 0x09
+
+//
+// Registers in the MAC
+//
+#define MAC_REG_BISTCMD 0x04
+#define MAC_REG_BISTSR0 0x05
+#define MAC_REG_BISTSR1 0x06
+#define MAC_REG_BISTSR2 0x07
+#define MAC_REG_I2MCSR 0x08
+#define MAC_REG_I2MTGID 0x09
+#define MAC_REG_I2MTGAD 0x0A
+#define MAC_REG_I2MCFG 0x0B
+#define MAC_REG_I2MDIPT 0x0C
+#define MAC_REG_I2MDOPT 0x0E
+#define MAC_REG_USBSUS 0x0F
+
+#define MAC_REG_LOCALID 0x14
+#define MAC_REG_TESTCFG 0x15
+#define MAC_REG_JUMPER0 0x16
+#define MAC_REG_JUMPER1 0x17
+#define MAC_REG_TMCTL 0x18
+#define MAC_REG_TMDATA0 0x1C
+#define MAC_REG_TMDATA1 0x1D
+#define MAC_REG_TMDATA2 0x1E
+#define MAC_REG_TMDATA3 0x1F
+
+// MAC Parameter related
+#define MAC_REG_LRT 0x20 //
+#define MAC_REG_SRT 0x21 //
+#define MAC_REG_SIFS 0x22 //
+#define MAC_REG_DIFS 0x23 //
+#define MAC_REG_EIFS 0x24 //
+#define MAC_REG_SLOT 0x25 //
+#define MAC_REG_BI 0x26 //
+#define MAC_REG_CWMAXMIN0 0x28 //
+#define MAC_REG_LINKOFFTOTM 0x2A
+#define MAC_REG_SWTMOT 0x2B
+#define MAC_REG_RTSOKCNT 0x2C
+#define MAC_REG_RTSFAILCNT 0x2D
+#define MAC_REG_ACKFAILCNT 0x2E
+#define MAC_REG_FCSERRCNT 0x2F
+// TSF Related
+#define MAC_REG_TSFCNTR 0x30 //
+#define MAC_REG_NEXTTBTT 0x38 //
+#define MAC_REG_TSFOFST 0x40 //
+#define MAC_REG_TFTCTL 0x48 //
+// WMAC Control/Status Related
+#define MAC_REG_ENCFG0 0x4C //
+#define MAC_REG_ENCFG1 0x4D //
+#define MAC_REG_ENCFG2 0x4E //
+
+#define MAC_REG_CFG 0x50 //
+#define MAC_REG_TEST 0x52 //
+#define MAC_REG_HOSTCR 0x54 //
+#define MAC_REG_MACCR 0x55 //
+#define MAC_REG_RCR 0x56 //
+#define MAC_REG_TCR 0x57 //
+#define MAC_REG_IMR 0x58 //
+#define MAC_REG_ISR 0x5C
+#define MAC_REG_ISR1 0x5D
+// Power Saving Related
+#define MAC_REG_PSCFG 0x60 //
+#define MAC_REG_PSCTL 0x61 //
+#define MAC_REG_PSPWRSIG 0x62 //
+#define MAC_REG_BBCR13 0x63
+#define MAC_REG_AIDATIM 0x64
+#define MAC_REG_PWBT 0x66
+#define MAC_REG_WAKEOKTMR 0x68
+#define MAC_REG_CALTMR 0x69
+#define MAC_REG_SYNSPACCNT 0x6A
+#define MAC_REG_WAKSYNOPT 0x6B
+// Baseband/IF Control Group
+#define MAC_REG_BBREGCTL 0x6C //
+#define MAC_REG_CHANNEL 0x6D
+#define MAC_REG_BBREGADR 0x6E
+#define MAC_REG_BBREGDATA 0x6F
+#define MAC_REG_IFREGCTL 0x70 //
+#define MAC_REG_IFDATA 0x71 //
+#define MAC_REG_ITRTMSET 0x74 //
+#define MAC_REG_PAPEDELAY 0x77
+#define MAC_REG_SOFTPWRCTL 0x78 //
+#define MAC_REG_SOFTPWRCTL2 0x79 //
+#define MAC_REG_GPIOCTL0 0x7A //
+#define MAC_REG_GPIOCTL1 0x7B //
+
+// MiscFF PIO related
+#define MAC_REG_MISCFFNDEX 0xBC
+#define MAC_REG_MISCFFCTL 0xBE
+#define MAC_REG_MISCFFDATA 0xC0
+
+// MAC Configuration Group
+#define MAC_REG_PAR0 0xC4
+#define MAC_REG_PAR4 0xC8
+#define MAC_REG_BSSID0 0xCC
+#define MAC_REG_BSSID4 0xD0
+#define MAC_REG_MAR0 0xD4
+#define MAC_REG_MAR4 0xD8
+// MAC RSPPKT INFO Group
+#define MAC_REG_RSPINF_B_1 0xDC
+#define MAC_REG_RSPINF_B_2 0xE0
+#define MAC_REG_RSPINF_B_5 0xE4
+#define MAC_REG_RSPINF_B_11 0xE8
+#define MAC_REG_RSPINF_A_6 0xEC
+#define MAC_REG_RSPINF_A_9 0xEE
+#define MAC_REG_RSPINF_A_12 0xF0
+#define MAC_REG_RSPINF_A_18 0xF2
+#define MAC_REG_RSPINF_A_24 0xF4
+#define MAC_REG_RSPINF_A_36 0xF6
+#define MAC_REG_RSPINF_A_48 0xF8
+#define MAC_REG_RSPINF_A_54 0xFA
+#define MAC_REG_RSPINF_A_72 0xFC
+
+//
+// Bits in the I2MCFG EEPROM register
+//
+#define I2MCFG_BOUNDCTL 0x80
+#define I2MCFG_WAITCTL 0x20
+#define I2MCFG_SCLOECTL 0x10
+#define I2MCFG_WBUSYCTL 0x08
+#define I2MCFG_NORETRY 0x04
+#define I2MCFG_I2MLDSEQ 0x02
+#define I2MCFG_I2CMFAST 0x01
+
+//
+// Bits in the I2MCSR EEPROM register
+//
+#define I2MCSR_EEMW 0x80
+#define I2MCSR_EEMR 0x40
+#define I2MCSR_AUTOLD 0x08
+#define I2MCSR_NACK 0x02
+#define I2MCSR_DONE 0x01
+
+//
+// Bits in the TMCTL register
+//
+#define TMCTL_TSUSP 0x04
+#define TMCTL_TMD 0x02
+#define TMCTL_TE 0x01
+
+//
+// Bits in the TFTCTL register
+//
+#define TFTCTL_HWUTSF 0x80 //
+#define TFTCTL_TBTTSYNC 0x40
+#define TFTCTL_HWUTSFEN 0x20
+#define TFTCTL_TSFCNTRRD 0x10 //
+#define TFTCTL_TBTTSYNCEN 0x08 //
+#define TFTCTL_TSFSYNCEN 0x04 //
+#define TFTCTL_TSFCNTRST 0x02 //
+#define TFTCTL_TSFCNTREN 0x01 //
+
+//
+// Bits in the EnhanceCFG_0 register
+//
+#define EnCFG_BBType_a 0x00
+#define EnCFG_BBType_b 0x01
+#define EnCFG_BBType_g 0x02
+#define EnCFG_BBType_MASK 0x03
+#define EnCFG_ProtectMd 0x20
+
+//
+// Bits in the EnhanceCFG_1 register
+//
+#define EnCFG_BcnSusInd 0x01
+#define EnCFG_BcnSusClr 0x02
+
+//
+// Bits in the EnhanceCFG_2 register
+//
+#define EnCFG_NXTBTTCFPSTR 0x01
+#define EnCFG_BarkerPream 0x02
+#define EnCFG_PktBurstMode 0x04
+
+//
+// Bits in the CFG register
+//
+#define CFG_TKIPOPT 0x80
+#define CFG_RXDMAOPT 0x40
+#define CFG_TMOT_SW 0x20
+#define CFG_TMOT_HWLONG 0x10
+#define CFG_TMOT_HW 0x00
+#define CFG_CFPENDOPT 0x08
+#define CFG_BCNSUSEN 0x04
+#define CFG_NOTXTIMEOUT 0x02
+#define CFG_NOBUFOPT 0x01
+
+//
+// Bits in the TEST register
+//
+#define TEST_LBEXT 0x80 //
+#define TEST_LBINT 0x40 //
+#define TEST_LBNONE 0x00 //
+#define TEST_SOFTINT 0x20 //
+#define TEST_CONTTX 0x10 //
+#define TEST_TXPE 0x08 //
+#define TEST_NAVDIS 0x04 //
+#define TEST_NOCTS 0x02 //
+#define TEST_NOACK 0x01 //
+
+//
+// Bits in the HOSTCR register
+//
+#define HOSTCR_TXONST 0x80 //
+#define HOSTCR_RXONST 0x40 //
+#define HOSTCR_ADHOC 0x20 // Network Type 1 = Ad-hoc
+#define HOSTCR_AP 0x10 // Port Type 1 = AP
+#define HOSTCR_TXON 0x08 //0000 1000
+#define HOSTCR_RXON 0x04 //0000 0100
+#define HOSTCR_MACEN 0x02 //0000 0010
+#define HOSTCR_SOFTRST 0x01 //0000 0001
+
+//
+// Bits in the MACCR register
+//
+#define MACCR_SYNCFLUSHOK 0x04 //
+#define MACCR_SYNCFLUSH 0x02 //
+#define MACCR_CLRNAV 0x01 //
+
+//
+// Bits in the RCR register
+//
+#define RCR_SSID 0x80
+#define RCR_RXALLTYPE 0x40 //
+#define RCR_UNICAST 0x20 //
+#define RCR_BROADCAST 0x10 //
+#define RCR_MULTICAST 0x08 //
+#define RCR_WPAERR 0x04 //
+#define RCR_ERRCRC 0x02 //
+#define RCR_BSSID 0x01 //
+
+//
+// Bits in the TCR register
+//
+#define TCR_SYNCDCFOPT 0x02 //
+#define TCR_AUTOBCNTX 0x01 // Beacon automatically transmit enable
+
+//ISR1
+#define ISR_GPIO3 0x40
+#define ISR_RXNOBUF 0x08
+#define ISR_MIBNEARFULL 0x04
+#define ISR_SOFTINT 0x02
+#define ISR_FETALERR 0x01
+
+#define LEDSTS_STS 0x06
+#define LEDSTS_TMLEN 0x78
+#define LEDSTS_OFF 0x00
+#define LEDSTS_ON 0x02
+#define LEDSTS_SLOW 0x04
+#define LEDSTS_INTER 0x06
+
+//ISR0
+#define ISR_WATCHDOG 0x80
+#define ISR_SOFTTIMER 0x40
+#define ISR_GPIO0 0x20
+#define ISR_TBTT 0x10
+#define ISR_RXDMA0 0x08
+#define ISR_BNTX 0x04
+#define ISR_ACTX 0x01
+
+//
+// Bits in the PSCFG register
+//
+#define PSCFG_PHILIPMD 0x40 //
+#define PSCFG_WAKECALEN 0x20 //
+#define PSCFG_WAKETMREN 0x10 //
+#define PSCFG_BBPSPROG 0x08 //
+#define PSCFG_WAKESYN 0x04 //
+#define PSCFG_SLEEPSYN 0x02 //
+#define PSCFG_AUTOSLEEP 0x01 //
+
+//
+// Bits in the PSCTL register
+//
+#define PSCTL_WAKEDONE 0x20 //
+#define PSCTL_PS 0x10 //
+#define PSCTL_GO2DOZE 0x08 //
+#define PSCTL_LNBCN 0x04 //
+#define PSCTL_ALBCN 0x02 //
+#define PSCTL_PSEN 0x01 //
+
+//
+// Bits in the PSPWSIG register
+//
+#define PSSIG_WPE3 0x80 //
+#define PSSIG_WPE2 0x40 //
+#define PSSIG_WPE1 0x20 //
+#define PSSIG_WRADIOPE 0x10 //
+#define PSSIG_SPE3 0x08 //
+#define PSSIG_SPE2 0x04 //
+#define PSSIG_SPE1 0x02 //
+#define PSSIG_SRADIOPE 0x01 //
+
+//
+// Bits in the BBREGCTL register
+//
+#define BBREGCTL_DONE 0x04 //
+#define BBREGCTL_REGR 0x02 //
+#define BBREGCTL_REGW 0x01 //
+
+//
+// Bits in the IFREGCTL register
+//
+#define IFREGCTL_DONE 0x04 //
+#define IFREGCTL_IFRF 0x02 //
+#define IFREGCTL_REGW 0x01 //
+
+//
+// Bits in the SOFTPWRCTL register
+//
+#define SOFTPWRCTL_RFLEOPT 0x08 //
+#define SOFTPWRCTL_TXPEINV 0x02 //
+#define SOFTPWRCTL_SWPECTI 0x01 //
+#define SOFTPWRCTL_SWPAPE 0x20 //
+#define SOFTPWRCTL_SWCALEN 0x10 //
+#define SOFTPWRCTL_SWRADIO_PE 0x08 //
+#define SOFTPWRCTL_SWPE2 0x04 //
+#define SOFTPWRCTL_SWPE1 0x02 //
+#define SOFTPWRCTL_SWPE3 0x01 //
+
+//
+// Bits in the GPIOCTL1 register
+//
+#define GPIO3_MD 0x20 //
+#define GPIO3_DATA 0x40 //
+#define GPIO3_INTMD 0x80 //
+
+//
+// Bits in the MISCFFCTL register
+//
+#define MISCFFCTL_WRITE 0x0001 //
+
+// Loopback mode
+#define MAC_LB_EXT 0x02 //
+#define MAC_LB_INTERNAL 0x01 //
+#define MAC_LB_NONE 0x00 //
+
+// Ethernet address filter type
+#define PKT_TYPE_NONE 0x00 // turn off receiver
+#define PKT_TYPE_ALL_MULTICAST 0x80
+#define PKT_TYPE_PROMISCUOUS 0x40
+#define PKT_TYPE_DIRECTED 0x20 // obselete, directed address is always accepted
+#define PKT_TYPE_BROADCAST 0x10
+#define PKT_TYPE_MULTICAST 0x08
+#define PKT_TYPE_ERROR_WPA 0x04
+#define PKT_TYPE_ERROR_CRC 0x02
+#define PKT_TYPE_BSSID 0x01
+
+#define Default_BI 0x200
+
+// MiscFIFO Offset
+#define MISCFIFO_KEYETRY0 32
+#define MISCFIFO_KEYENTRYSIZE 22
+
+// max time out delay time
+#define W_MAX_TIMEOUT 0xFFF0U //
+
+// wait time within loop
+#define CB_DELAY_LOOP_WAIT 10 // 10ms
+
+#define MAC_REVISION_A0 0x00
+#define MAC_REVISION_A1 0x01
+
+void MACvWriteMultiAddr(struct vnt_private *, u32, u8);
+void MACbShutdown(struct vnt_private *);
+void MACvSetBBType(struct vnt_private *, u8);
+void MACvDisableKeyEntry(struct vnt_private *, u32);
+void MACvSetKeyEntry(struct vnt_private *, u16, u32, u32, u8 *, u32 *);
+void MACvRegBitsOff(struct vnt_private *, u8, u8);
+void MACvRegBitsOn(struct vnt_private *, u8, u8);
+void MACvWriteWord(struct vnt_private *, u8, u16);
+void MACvWriteBSSIDAddress(struct vnt_private *, u8 *);
+void MACvEnableProtectMD(struct vnt_private *);
+void MACvDisableProtectMD(struct vnt_private *);
+void MACvEnableBarkerPreambleMd(struct vnt_private *);
+void MACvDisableBarkerPreambleMd(struct vnt_private *);
+void MACvWriteBeaconInterval(struct vnt_private *, u16);
+
+#endif /* __MAC_H__ */
diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c
new file mode 100644
index 00000000..06b966cf
--- /dev/null
+++ b/drivers/staging/vt6656/main_usb.c
@@ -0,0 +1,1490 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: main_usb.c
+ *
+ * Purpose: driver entry for initial, open, close, tx and rx.
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: Dec 8, 2005
+ *
+ * Functions:
+ *
+ * vt6656_probe - module initial (insmod) driver entry
+ * device_remove1 - module remove entry
+ * device_open - allocate dma/descripter resource & initial mac/bbp function
+ * device_xmit - asynchronous data tx function
+ * device_set_multi - set mac filter
+ * device_ioctl - ioctl entry
+ * device_close - shutdown mac/bbp & free dma/descriptor resource
+ * device_alloc_frag_buf - rx fragement pre-allocated function
+ * device_free_tx_bufs - free tx buffer function
+ * device_dma0_tx_80211- tx 802.11 frame via dma0
+ * device_dma0_xmit- tx PS buffered frame via dma0
+ * device_init_registers- initial MAC & BBP & RF internal registers.
+ * device_init_rings- initial tx/rx ring buffer
+ * device_init_defrag_cb- initial & allocate de-fragement buffer.
+ * device_tx_srv- tx interrupt service function
+ *
+ * Revision History:
+ */
+#undef __NO_VERSION__
+
+#include <linux/file.h>
+#include "device.h"
+#include "card.h"
+#include "baseband.h"
+#include "mac.h"
+#include "tether.h"
+#include "wmgr.h"
+#include "wctl.h"
+#include "power.h"
+#include "wcmd.h"
+#include "iocmd.h"
+#include "tcrc.h"
+#include "rxtx.h"
+#include "bssdb.h"
+#include "hostap.h"
+#include "wpactl.h"
+#include "iwctl.h"
+#include "dpc.h"
+#include "datarate.h"
+#include "rf.h"
+#include "firmware.h"
+#include "rndis.h"
+#include "control.h"
+#include "channel.h"
+#include "int.h"
+#include "iowpa.h"
+
+/* static int msglevel = MSG_LEVEL_DEBUG; */
+static int msglevel =MSG_LEVEL_INFO;
+
+/*
+ * define module options
+ */
+
+/* version information */
+#define DRIVER_AUTHOR \
+ "VIA Networking Technologies, Inc., <lyndonchen@vntek.com.tw>"
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION(DEVICE_FULL_DRV_NAM);
+
+#define DEVICE_PARAM(N,D) \
+ static int N[MAX_UINTS]=OPTION_DEFAULT;\
+ module_param_array(N, int, NULL, 0);\
+ MODULE_PARM_DESC(N, D);
+
+#define RX_DESC_DEF0 64
+DEVICE_PARAM(RxDescriptors0,"Number of receive usb desc buffer");
+
+#define TX_DESC_DEF0 64
+DEVICE_PARAM(TxDescriptors0,"Number of transmit usb desc buffer");
+
+#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_DEF 2347
+DEVICE_PARAM(RTSThreshold, "RTS threshold");
+
+#define FRAG_THRESH_DEF 2346
+DEVICE_PARAM(FragThreshold, "Fragmentation threshold");
+
+#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_DEF 8
+DEVICE_PARAM(ShortRetryLimit, "Short frame retry limits");
+
+#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_DEF 2
+DEVICE_PARAM(BasebandType, "baseband type");
+
+/* 80211hEnable[]
+ 0: indicate disable 802.11h
+ 1: indicate enable 802.11h
+*/
+
+#define X80211h_MODE_DEF 0
+
+DEVICE_PARAM(b80211hEnable, "802.11h mode");
+
+/*
+ * Static vars definitions
+ */
+
+static struct usb_device_id vt6656_table[] = {
+ {USB_DEVICE(VNT_USB_VENDOR_ID, VNT_USB_PRODUCT_ID)},
+ {}
+};
+
+/* frequency list (map channels to frequencies) */
+/*
+static const long frequency_list[] = {
+ 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467, 2472, 2484,
+ 4915, 4920, 4925, 4935, 4940, 4945, 4960, 4980,
+ 5035, 5040, 5045, 5055, 5060, 5080, 5170, 5180, 5190, 5200, 5210, 5220, 5230, 5240,
+ 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680,
+ 5700, 5745, 5765, 5785, 5805, 5825
+ };
+
+static const struct iw_handler_def iwctl_handler_def;
+*/
+
+static int vt6656_probe(struct usb_interface *intf,
+ const struct usb_device_id *id);
+static void vt6656_disconnect(struct usb_interface *intf);
+
+#ifdef CONFIG_PM /* Minimal support for suspend and resume */
+static int vt6656_suspend(struct usb_interface *intf, pm_message_t message);
+static int vt6656_resume(struct usb_interface *intf);
+#endif /* CONFIG_PM */
+
+static struct net_device_stats *device_get_stats(struct net_device *dev);
+static int device_open(struct net_device *dev);
+static int device_xmit(struct sk_buff *skb, struct net_device *dev);
+static void device_set_multi(struct net_device *dev);
+static int device_close(struct net_device *dev);
+static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+
+static int device_init_registers(struct vnt_private *pDevice,
+ DEVICE_INIT_TYPE InitType);
+static bool device_init_defrag_cb(struct vnt_private *pDevice);
+static void device_init_diversity_timer(struct vnt_private *pDevice);
+static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev);
+
+static int ethtool_ioctl(struct net_device *dev, void *useraddr);
+static void device_free_tx_bufs(struct vnt_private *pDevice);
+static void device_free_rx_bufs(struct vnt_private *pDevice);
+static void device_free_int_bufs(struct vnt_private *pDevice);
+static void device_free_frag_bufs(struct vnt_private *pDevice);
+static bool device_alloc_bufs(struct vnt_private *pDevice);
+
+static int Read_config_file(struct vnt_private *pDevice);
+static unsigned char *Config_FileOperation(struct vnt_private *pDevice);
+static int Config_FileGetParameter(unsigned char *string,
+ unsigned char *dest,
+ unsigned char *source);
+
+static void usb_device_reset(struct vnt_private *pDevice);
+
+static void
+device_set_options(struct vnt_private *pDevice) {
+
+ u8 abyBroadcastAddr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+ u8 abySNAP_RFC1042[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00};
+ u8 abySNAP_Bridgetunnel[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8};
+
+ memcpy(pDevice->abyBroadcastAddr, abyBroadcastAddr, ETH_ALEN);
+ memcpy(pDevice->abySNAP_RFC1042, abySNAP_RFC1042, ETH_ALEN);
+ memcpy(pDevice->abySNAP_Bridgetunnel, abySNAP_Bridgetunnel, ETH_ALEN);
+
+ pDevice->cbTD = TX_DESC_DEF0;
+ pDevice->cbRD = RX_DESC_DEF0;
+ pDevice->uChannel = CHANNEL_DEF;
+ pDevice->wRTSThreshold = RTS_THRESH_DEF;
+ pDevice->wFragmentationThreshold = FRAG_THRESH_DEF;
+ pDevice->byShortRetryLimit = SHORT_RETRY_DEF;
+ pDevice->byLongRetryLimit = LONG_RETRY_DEF;
+ pDevice->wMaxTransmitMSDULifetime = DEFAULT_MSDU_LIFETIME;
+ pDevice->byShortPreamble = PREAMBLE_TYPE_DEF;
+ pDevice->ePSMode = PS_MODE_DEF;
+ pDevice->b11hEnable = X80211h_MODE_DEF;
+ pDevice->eOPMode = OP_MODE_DEF;
+ pDevice->uConnectionRate = DATA_RATE_DEF;
+ if (pDevice->uConnectionRate < RATE_AUTO) pDevice->bFixRate = true;
+ pDevice->byBBType = BBP_TYPE_DEF;
+ pDevice->byPacketType = pDevice->byBBType;
+ pDevice->byAutoFBCtrl = AUTO_FB_0;
+ pDevice->bUpdateBBVGA = true;
+ pDevice->byFOETuning = 0;
+ pDevice->byAutoPwrTunning = 0;
+ pDevice->wCTSDuration = 0;
+ pDevice->byPreambleType = 0;
+ pDevice->bExistSWNetAddr = false;
+ /* pDevice->bDiversityRegCtlON = true; */
+ pDevice->bDiversityRegCtlON = false;
+}
+
+static void device_init_diversity_timer(struct vnt_private *pDevice)
+{
+ init_timer(&pDevice->TimerSQ3Tmax1);
+ pDevice->TimerSQ3Tmax1.data = (unsigned long)pDevice;
+ pDevice->TimerSQ3Tmax1.function = (TimerFunction)TimerSQ3CallBack;
+ pDevice->TimerSQ3Tmax1.expires = RUN_AT(HZ);
+
+ init_timer(&pDevice->TimerSQ3Tmax2);
+ pDevice->TimerSQ3Tmax2.data = (unsigned long)pDevice;
+ pDevice->TimerSQ3Tmax2.function = (TimerFunction)TimerSQ3CallBack;
+ pDevice->TimerSQ3Tmax2.expires = RUN_AT(HZ);
+
+ init_timer(&pDevice->TimerSQ3Tmax3);
+ pDevice->TimerSQ3Tmax3.data = (unsigned long)pDevice;
+ pDevice->TimerSQ3Tmax3.function = (TimerFunction)TimerSQ3Tmax3CallBack;
+ pDevice->TimerSQ3Tmax3.expires = RUN_AT(HZ);
+
+ return;
+}
+
+/*
+ * initialization of MAC & BBP registers
+ */
+
+static int device_init_registers(struct vnt_private *pDevice,
+ DEVICE_INIT_TYPE InitType)
+{
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ u8 abyBroadcastAddr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+ u8 abySNAP_RFC1042[ETH_ALEN] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
+ u8 abySNAP_Bridgetunnel[ETH_ALEN]
+ = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8};
+ u8 byAntenna;
+ int ii;
+ CMD_CARD_INIT sInitCmd;
+ int ntStatus = STATUS_SUCCESS;
+ RSP_CARD_INIT sInitRsp;
+ u8 byTmp;
+ u8 byCalibTXIQ = 0, byCalibTXDC = 0, byCalibRXIQ = 0;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "---->INIbInitAdapter. [%d][%d]\n", InitType, pDevice->byPacketType);
+ spin_lock_irq(&pDevice->lock);
+ if (InitType == DEVICE_INIT_COLD) {
+ memcpy(pDevice->abyBroadcastAddr, abyBroadcastAddr, ETH_ALEN);
+ memcpy(pDevice->abySNAP_RFC1042, abySNAP_RFC1042, ETH_ALEN);
+ memcpy(pDevice->abySNAP_Bridgetunnel,
+ abySNAP_Bridgetunnel,
+ ETH_ALEN);
+
+ if ( !FIRMWAREbCheckVersion(pDevice) ) {
+ if (FIRMWAREbDownload(pDevice) == true) {
+ if (FIRMWAREbBrach2Sram(pDevice) == false) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" FIRMWAREbBrach2Sram fail \n");
+ spin_unlock_irq(&pDevice->lock);
+ return false;
+ }
+ } else {
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" FIRMWAREbDownload fail \n");
+ spin_unlock_irq(&pDevice->lock);
+ return false;
+ }
+ }
+
+ if ( !BBbVT3184Init(pDevice) ) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" BBbVT3184Init fail \n");
+ spin_unlock_irq(&pDevice->lock);
+ return false;
+ }
+ }
+
+ sInitCmd.byInitClass = (u8)InitType;
+ sInitCmd.bExistSWNetAddr = (u8) pDevice->bExistSWNetAddr;
+ for (ii = 0; ii < 6; ii++)
+ sInitCmd.bySWNetAddr[ii] = pDevice->abyCurrentNetAddr[ii];
+ sInitCmd.byShortRetryLimit = pDevice->byShortRetryLimit;
+ sInitCmd.byLongRetryLimit = pDevice->byLongRetryLimit;
+
+ /* issue card_init command to device */
+ ntStatus = CONTROLnsRequestOut(pDevice,
+ MESSAGE_TYPE_CARDINIT,
+ 0,
+ 0,
+ sizeof(CMD_CARD_INIT),
+ (u8 *) &(sInitCmd));
+
+ if ( ntStatus != STATUS_SUCCESS ) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Issue Card init fail \n");
+ spin_unlock_irq(&pDevice->lock);
+ return false;
+ }
+ if (InitType == DEVICE_INIT_COLD) {
+
+ ntStatus = CONTROLnsRequestIn(pDevice,MESSAGE_TYPE_INIT_RSP,0,0,sizeof(RSP_CARD_INIT), (u8 *) &(sInitRsp));
+
+ if (ntStatus != STATUS_SUCCESS) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Cardinit request in status fail!\n");
+ spin_unlock_irq(&pDevice->lock);
+ return false;
+ }
+
+ /* local ID for AES functions */
+ ntStatus = CONTROLnsRequestIn(pDevice,
+ MESSAGE_TYPE_READ,
+ MAC_REG_LOCALID,
+ MESSAGE_REQUEST_MACREG,
+ 1,
+ &pDevice->byLocalID);
+
+ if ( ntStatus != STATUS_SUCCESS ) {
+ spin_unlock_irq(&pDevice->lock);
+ return false;
+ }
+
+ /* do MACbSoftwareReset in MACvInitialize */
+
+ /* force CCK */
+ pDevice->bCCK = true;
+ pDevice->bProtectMode = false;
+ /* only used in 11g type, sync with ERP IE */
+ pDevice->bNonERPPresent = false;
+ pDevice->bBarkerPreambleMd = false;
+ if ( pDevice->bFixRate ) {
+ pDevice->wCurrentRate = (u16) pDevice->uConnectionRate;
+ } else {
+ if ( pDevice->byBBType == BB_TYPE_11B )
+ pDevice->wCurrentRate = RATE_11M;
+ else
+ pDevice->wCurrentRate = RATE_54M;
+ }
+
+ CHvInitChannelTable(pDevice);
+
+ pDevice->byTopOFDMBasicRate = RATE_24M;
+ pDevice->byTopCCKBasicRate = RATE_1M;
+ pDevice->byRevId = 0;
+ /* target to IF pin while programming to RF chip */
+ pDevice->byCurPwr = 0xFF;
+
+ pDevice->byCCKPwr = pDevice->abyEEPROM[EEP_OFS_PWR_CCK];
+ pDevice->byOFDMPwrG = pDevice->abyEEPROM[EEP_OFS_PWR_OFDMG];
+ /* load power table */
+ for (ii = 0; ii < 14; ii++) {
+ pDevice->abyCCKPwrTbl[ii] = pDevice->abyEEPROM[ii + EEP_OFS_CCK_PWR_TBL];
+ if (pDevice->abyCCKPwrTbl[ii] == 0)
+ pDevice->abyCCKPwrTbl[ii] = pDevice->byCCKPwr;
+ pDevice->abyOFDMPwrTbl[ii] = pDevice->abyEEPROM[ii + EEP_OFS_OFDM_PWR_TBL];
+ if (pDevice->abyOFDMPwrTbl[ii] == 0)
+ pDevice->abyOFDMPwrTbl[ii] = pDevice->byOFDMPwrG;
+ }
+
+ /*
+ * original zonetype is USA, but custom zonetype is Europe,
+ * then need to recover 12, 13, 14 channels with 11 channel
+ */
+ if(((pDevice->abyEEPROM[EEP_OFS_ZONETYPE] == ZoneType_Japan) ||
+ (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] == ZoneType_Europe))&&
+ (pDevice->byOriginalZonetype == ZoneType_USA)) {
+ for (ii = 11; ii < 14; ii++) {
+ pDevice->abyCCKPwrTbl[ii] = pDevice->abyCCKPwrTbl[10];
+ pDevice->abyOFDMPwrTbl[ii] = pDevice->abyOFDMPwrTbl[10];
+ }
+ }
+
+ pDevice->byOFDMPwrA = 0x34; /* same as RFbMA2829SelectChannel */
+
+ /* load OFDM A power table */
+ for (ii = 0; ii < CB_MAX_CHANNEL_5G; ii++) {
+ pDevice->abyOFDMAPwrTbl[ii] = pDevice->abyEEPROM[ii + EEP_OFS_OFDMA_PWR_TBL];
+ if (pDevice->abyOFDMAPwrTbl[ii] == 0)
+ pDevice->abyOFDMAPwrTbl[ii] = pDevice->byOFDMPwrA;
+ }
+
+ byAntenna = pDevice->abyEEPROM[EEP_OFS_ANTENNA];
+ if (byAntenna & EEP_ANTINV)
+ pDevice->bTxRxAntInv = true;
+ else
+ pDevice->bTxRxAntInv = false;
+
+ byAntenna &= (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN);
+
+ if (byAntenna == 0) /* if not set default is both */
+ byAntenna = (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN);
+
+ if (byAntenna == (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN)) {
+ pDevice->byAntennaCount = 2;
+ pDevice->byTxAntennaMode = ANT_B;
+ pDevice->dwTxAntennaSel = 1;
+ pDevice->dwRxAntennaSel = 1;
+ if (pDevice->bTxRxAntInv == true)
+ pDevice->byRxAntennaMode = ANT_A;
+ else
+ pDevice->byRxAntennaMode = ANT_B;
+
+ if (pDevice->bDiversityRegCtlON)
+ pDevice->bDiversityEnable = true;
+ else
+ pDevice->bDiversityEnable = false;
+ } else {
+ pDevice->bDiversityEnable = false;
+ pDevice->byAntennaCount = 1;
+ pDevice->dwTxAntennaSel = 0;
+ pDevice->dwRxAntennaSel = 0;
+ if (byAntenna & EEP_ANTENNA_AUX) {
+ pDevice->byTxAntennaMode = ANT_A;
+ if (pDevice->bTxRxAntInv == true)
+ pDevice->byRxAntennaMode = ANT_B;
+ else
+ pDevice->byRxAntennaMode = ANT_A;
+ } else {
+ pDevice->byTxAntennaMode = ANT_B;
+ if (pDevice->bTxRxAntInv == true)
+ pDevice->byRxAntennaMode = ANT_A;
+ else
+ pDevice->byRxAntennaMode = ANT_B;
+ }
+ }
+ pDevice->ulDiversityNValue = 100*255;
+ pDevice->ulDiversityMValue = 100*16;
+ pDevice->byTMax = 1;
+ pDevice->byTMax2 = 4;
+ pDevice->ulSQ3TH = 0;
+ pDevice->byTMax3 = 64;
+
+ /* get Auto Fall Back type */
+ pDevice->byAutoFBCtrl = AUTO_FB_0;
+
+ /* set SCAN Time */
+ pDevice->uScanTime = WLAN_SCAN_MINITIME;
+
+ /* default Auto Mode */
+ /* pDevice->NetworkType = Ndis802_11Automode; */
+ pDevice->eConfigPHYMode = PHY_TYPE_AUTO;
+ pDevice->byBBType = BB_TYPE_11G;
+
+ /* initialize BBP registers */
+ pDevice->ulTxPower = 25;
+
+ /* get channel range */
+ pDevice->byMinChannel = 1;
+ pDevice->byMaxChannel = CB_MAX_CHANNEL;
+
+ /* get RFType */
+ pDevice->byRFType = sInitRsp.byRFType;
+
+ if ((pDevice->byRFType & RF_EMU) != 0) {
+ /* force change RevID for VT3253 emu */
+ pDevice->byRevId = 0x80;
+ }
+
+ /* load vt3266 calibration parameters in EEPROM */
+ if (pDevice->byRFType == RF_VT3226D0) {
+ if((pDevice->abyEEPROM[EEP_OFS_MAJOR_VER] == 0x1) &&
+ (pDevice->abyEEPROM[EEP_OFS_MINOR_VER] >= 0x4)) {
+ byCalibTXIQ = pDevice->abyEEPROM[EEP_OFS_CALIB_TX_IQ];
+ byCalibTXDC = pDevice->abyEEPROM[EEP_OFS_CALIB_TX_DC];
+ byCalibRXIQ = pDevice->abyEEPROM[EEP_OFS_CALIB_RX_IQ];
+ if( (byCalibTXIQ || byCalibTXDC || byCalibRXIQ) ) {
+ /* CR255, enable TX/RX IQ and DC compensation mode */
+ ControlvWriteByte(pDevice,
+ MESSAGE_REQUEST_BBREG,
+ 0xFF,
+ 0x03);
+ /* CR251, TX I/Q Imbalance Calibration */
+ ControlvWriteByte(pDevice,
+ MESSAGE_REQUEST_BBREG,
+ 0xFB,
+ byCalibTXIQ);
+ /* CR252, TX DC-Offset Calibration */
+ ControlvWriteByte(pDevice,
+ MESSAGE_REQUEST_BBREG,
+ 0xFC,
+ byCalibTXDC);
+ /* CR253, RX I/Q Imbalance Calibration */
+ ControlvWriteByte(pDevice,
+ MESSAGE_REQUEST_BBREG,
+ 0xFD,
+ byCalibRXIQ);
+ } else {
+ /* CR255, turn off BB Calibration compensation */
+ ControlvWriteByte(pDevice,
+ MESSAGE_REQUEST_BBREG,
+ 0xFF,
+ 0x0);
+ }
+ }
+ }
+ pMgmt->eScanType = WMAC_SCAN_PASSIVE;
+ pMgmt->uCurrChannel = pDevice->uChannel;
+ pMgmt->uIBSSChannel = pDevice->uChannel;
+ CARDbSetMediaChannel(pDevice, pMgmt->uCurrChannel);
+
+ /* get permanent network address */
+ memcpy(pDevice->abyPermanentNetAddr,&(sInitRsp.byNetAddr[0]),6);
+ memcpy(pDevice->abyCurrentNetAddr,
+ pDevice->abyPermanentNetAddr,
+ ETH_ALEN);
+
+ /* if exist SW network address, use it */
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Network address = %pM\n",
+ pDevice->abyCurrentNetAddr);
+ }
+
+ /*
+ * set BB and packet type at the same time
+ * set Short Slot Time, xIFS, and RSPINF
+ */
+ if (pDevice->byBBType == BB_TYPE_11A) {
+ CARDbAddBasicRate(pDevice, RATE_6M);
+ pDevice->bShortSlotTime = true;
+ } else {
+ CARDbAddBasicRate(pDevice, RATE_1M);
+ pDevice->bShortSlotTime = false;
+ }
+ BBvSetShortSlotTime(pDevice);
+ CARDvSetBSSMode(pDevice);
+
+ if (pDevice->bUpdateBBVGA) {
+ pDevice->byBBVGACurrent = pDevice->abyBBVGA[0];
+ pDevice->byBBVGANew = pDevice->byBBVGACurrent;
+ BBvSetVGAGainOffset(pDevice, pDevice->abyBBVGA[0]);
+ }
+
+ pDevice->byRadioCtl = pDevice->abyEEPROM[EEP_OFS_RADIOCTL];
+ pDevice->bHWRadioOff = false;
+ if ( (pDevice->byRadioCtl & EEP_RADIOCTL_ENABLE) != 0 ) {
+ ntStatus = CONTROLnsRequestIn(pDevice,
+ MESSAGE_TYPE_READ,
+ MAC_REG_GPIOCTL1,
+ MESSAGE_REQUEST_MACREG,
+ 1,
+ &byTmp);
+
+ if ( ntStatus != STATUS_SUCCESS ) {
+ spin_unlock_irq(&pDevice->lock);
+ return false;
+ }
+ if ( (byTmp & GPIO3_DATA) == 0 ) {
+ pDevice->bHWRadioOff = true;
+ MACvRegBitsOn(pDevice,MAC_REG_GPIOCTL1,GPIO3_INTMD);
+ } else {
+ MACvRegBitsOff(pDevice,MAC_REG_GPIOCTL1,GPIO3_INTMD);
+ pDevice->bHWRadioOff = false;
+ }
+
+ }
+
+ ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_TMLEN,0x38);
+ ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW);
+ MACvRegBitsOn(pDevice,MAC_REG_GPIOCTL0,0x01);
+
+ if ((pDevice->bHWRadioOff == true) || (pDevice->bRadioControlOff == true)) {
+ CARDbRadioPowerOff(pDevice);
+ } else {
+ CARDbRadioPowerOn(pDevice);
+ }
+
+ spin_unlock_irq(&pDevice->lock);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"<----INIbInitAdapter Exit\n");
+ return true;
+}
+
+#ifdef CONFIG_PM /* Minimal support for suspend and resume */
+
+static int vt6656_suspend(struct usb_interface *intf, pm_message_t message)
+{
+ struct vnt_private *device = usb_get_intfdata(intf);
+
+ if (!device || !device->dev)
+ return -ENODEV;
+
+ if (device->flags & DEVICE_FLAGS_OPENED)
+ device_close(device->dev);
+
+ return 0;
+}
+
+static int vt6656_resume(struct usb_interface *intf)
+{
+ struct vnt_private *device = usb_get_intfdata(intf);
+
+ if (!device || !device->dev)
+ return -ENODEV;
+
+ if (!(device->flags & DEVICE_FLAGS_OPENED))
+ device_open(device->dev);
+
+ return 0;
+}
+
+#endif /* CONFIG_PM */
+
+static const struct net_device_ops device_netdev_ops = {
+ .ndo_open = device_open,
+ .ndo_stop = device_close,
+ .ndo_do_ioctl = device_ioctl,
+ .ndo_get_stats = device_get_stats,
+ .ndo_start_xmit = device_xmit,
+ .ndo_set_rx_mode = device_set_multi,
+};
+
+static int
+vt6656_probe(struct usb_interface *intf, const struct usb_device_id *id)
+{
+ u8 fake_mac[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
+ struct usb_device *udev = interface_to_usbdev(intf);
+ int rc = 0;
+ struct net_device *netdev = NULL;
+ struct vnt_private *pDevice;
+
+ printk(KERN_NOTICE "%s Ver. %s\n", DEVICE_FULL_DRV_NAM, DEVICE_VERSION);
+ printk(KERN_NOTICE "Copyright (c) 2004 VIA Networking Technologies, Inc.\n");
+
+ udev = usb_get_dev(udev);
+ netdev = alloc_etherdev(sizeof(struct vnt_private));
+ if (!netdev) {
+ printk(KERN_ERR DEVICE_NAME ": allocate net device failed\n");
+ rc = -ENOMEM;
+ goto err_nomem;
+ }
+
+ pDevice = netdev_priv(netdev);
+ memset(pDevice, 0, sizeof(struct vnt_private));
+
+ pDevice->dev = netdev;
+ pDevice->usb = udev;
+
+ device_set_options(pDevice);
+ spin_lock_init(&pDevice->lock);
+
+ pDevice->tx_80211 = device_dma0_tx_80211;
+ pDevice->vnt_mgmt.pAdapter = (void *) pDevice;
+
+ netdev->netdev_ops = &device_netdev_ops;
+ netdev->wireless_handlers =
+ (struct iw_handler_def *) &iwctl_handler_def;
+
+ usb_set_intfdata(intf, pDevice);
+ SET_NETDEV_DEV(netdev, &intf->dev);
+ memcpy(pDevice->dev->dev_addr, fake_mac, ETH_ALEN);
+ rc = register_netdev(netdev);
+ if (rc) {
+ printk(KERN_ERR DEVICE_NAME " Failed to register netdev\n");
+ goto err_netdev;
+ }
+
+ usb_device_reset(pDevice);
+
+ return 0;
+
+err_netdev:
+ free_netdev(netdev);
+err_nomem:
+ usb_put_dev(udev);
+
+ return rc;
+}
+
+static void device_free_tx_bufs(struct vnt_private *pDevice)
+{
+ PUSB_SEND_CONTEXT pTxContext;
+ int ii;
+
+ for (ii = 0; ii < pDevice->cbTD; ii++) {
+
+ pTxContext = pDevice->apTD[ii];
+ /* deallocate URBs */
+ if (pTxContext->pUrb) {
+ usb_kill_urb(pTxContext->pUrb);
+ usb_free_urb(pTxContext->pUrb);
+ }
+ kfree(pTxContext);
+ }
+ return;
+}
+
+static void device_free_rx_bufs(struct vnt_private *pDevice)
+{
+ PRCB pRCB;
+ int ii;
+
+ for (ii = 0; ii < pDevice->cbRD; ii++) {
+
+ pRCB = pDevice->apRCB[ii];
+ /* deallocate URBs */
+ if (pRCB->pUrb) {
+ usb_kill_urb(pRCB->pUrb);
+ usb_free_urb(pRCB->pUrb);
+ }
+ /* deallocate skb */
+ if (pRCB->skb)
+ dev_kfree_skb(pRCB->skb);
+ }
+ kfree(pDevice->pRCBMem);
+
+ return;
+}
+
+static void usb_device_reset(struct vnt_private *pDevice)
+{
+ int status;
+ status = usb_reset_device(pDevice->usb);
+ if (status)
+ printk("usb_device_reset fail status=%d\n",status);
+ return ;
+}
+
+static void device_free_int_bufs(struct vnt_private *pDevice)
+{
+ kfree(pDevice->intBuf.pDataBuf);
+ return;
+}
+
+static bool device_alloc_bufs(struct vnt_private *pDevice)
+{
+
+ PUSB_SEND_CONTEXT pTxContext;
+ PRCB pRCB;
+ int ii;
+
+ for (ii = 0; ii < pDevice->cbTD; ii++) {
+
+ pTxContext = kmalloc(sizeof(USB_SEND_CONTEXT), GFP_KERNEL);
+ if (pTxContext == NULL) {
+ DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s : allocate tx usb context failed\n", pDevice->dev->name);
+ goto free_tx;
+ }
+ pDevice->apTD[ii] = pTxContext;
+ pTxContext->pDevice = (void *) pDevice;
+ /* allocate URBs */
+ pTxContext->pUrb = usb_alloc_urb(0, GFP_ATOMIC);
+ if (pTxContext->pUrb == NULL) {
+ DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "alloc tx urb failed\n");
+ goto free_tx;
+ }
+ pTxContext->bBoolInUse = false;
+ }
+
+ /* allocate RCB mem */
+ pDevice->pRCBMem = kzalloc((sizeof(RCB) * pDevice->cbRD), GFP_KERNEL);
+ if (pDevice->pRCBMem == NULL) {
+ DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s : alloc rx usb context failed\n", pDevice->dev->name);
+ goto free_tx;
+ }
+
+ pDevice->FirstRecvFreeList = NULL;
+ pDevice->LastRecvFreeList = NULL;
+ pDevice->FirstRecvMngList = NULL;
+ pDevice->LastRecvMngList = NULL;
+ pDevice->NumRecvFreeList = 0;
+ pRCB = (PRCB) pDevice->pRCBMem;
+
+ for (ii = 0; ii < pDevice->cbRD; ii++) {
+
+ pDevice->apRCB[ii] = pRCB;
+ pRCB->pDevice = (void *) pDevice;
+ /* allocate URBs */
+ pRCB->pUrb = usb_alloc_urb(0, GFP_ATOMIC);
+
+ if (pRCB->pUrb == NULL) {
+ DBG_PRT(MSG_LEVEL_ERR,KERN_ERR" Failed to alloc rx urb\n");
+ goto free_rx_tx;
+ }
+ pRCB->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
+ if (pRCB->skb == NULL) {
+ DBG_PRT(MSG_LEVEL_ERR,KERN_ERR" Failed to alloc rx skb\n");
+ goto free_rx_tx;
+ }
+ pRCB->skb->dev = pDevice->dev;
+ pRCB->bBoolInUse = false;
+ EnqueueRCB(pDevice->FirstRecvFreeList, pDevice->LastRecvFreeList, pRCB);
+ pDevice->NumRecvFreeList++;
+ pRCB++;
+ }
+
+ pDevice->pControlURB = usb_alloc_urb(0, GFP_ATOMIC);
+ if (pDevice->pControlURB == NULL) {
+ DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc control urb\n");
+ goto free_rx_tx;
+ }
+
+ pDevice->pInterruptURB = usb_alloc_urb(0, GFP_ATOMIC);
+ if (pDevice->pInterruptURB == NULL) {
+ DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc int urb\n");
+ usb_free_urb(pDevice->pControlURB);
+ goto free_rx_tx;
+ }
+
+ pDevice->intBuf.pDataBuf = kmalloc(MAX_INTERRUPT_SIZE, GFP_KERNEL);
+ if (pDevice->intBuf.pDataBuf == NULL) {
+ DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc int buf\n");
+ usb_free_urb(pDevice->pControlURB);
+ usb_free_urb(pDevice->pInterruptURB);
+ goto free_rx_tx;
+ }
+
+ return true;
+
+free_rx_tx:
+ device_free_rx_bufs(pDevice);
+
+free_tx:
+ device_free_tx_bufs(pDevice);
+
+ return false;
+}
+
+static bool device_init_defrag_cb(struct vnt_private *pDevice)
+{
+ int i;
+ PSDeFragControlBlock pDeF;
+
+ /* Init the fragment ctl entries */
+ for (i = 0; i < CB_MAX_RX_FRAG; i++) {
+ pDeF = &(pDevice->sRxDFCB[i]);
+ if (!device_alloc_frag_buf(pDevice, pDeF)) {
+ DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc frag bufs\n",
+ pDevice->dev->name);
+ goto free_frag;
+ }
+ }
+ pDevice->cbDFCB = CB_MAX_RX_FRAG;
+ pDevice->cbFreeDFCB = pDevice->cbDFCB;
+ return true;
+
+free_frag:
+ device_free_frag_bufs(pDevice);
+ return false;
+}
+
+static void device_free_frag_bufs(struct vnt_private *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);
+ }
+}
+
+int device_alloc_frag_buf(struct vnt_private *pDevice,
+ PSDeFragControlBlock pDeF)
+{
+
+ pDeF->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
+ if (pDeF->skb == NULL)
+ return false;
+ ASSERT(pDeF->skb);
+ pDeF->skb->dev = pDevice->dev;
+
+ return true;
+}
+
+static int device_open(struct net_device *dev)
+{
+ struct vnt_private *pDevice = netdev_priv(dev);
+
+ pDevice->fWPA_Authened = false;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " device_open...\n");
+
+ pDevice->rx_buf_sz = MAX_TOTAL_SIZE_WITH_ALL_HEADERS;
+
+ if (device_alloc_bufs(pDevice) == false) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " device_alloc_bufs fail... \n");
+ return -ENOMEM;
+ }
+
+ if (device_init_defrag_cb(pDevice)== false) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Initial defragment cb fail \n");
+ goto free_rx_tx;
+ }
+
+ MP_CLEAR_FLAG(pDevice, fMP_DISCONNECTED);
+ MP_CLEAR_FLAG(pDevice, fMP_CONTROL_READS);
+ MP_CLEAR_FLAG(pDevice, fMP_CONTROL_WRITES);
+ MP_SET_FLAG(pDevice, fMP_POST_READS);
+ MP_SET_FLAG(pDevice, fMP_POST_WRITES);
+
+ /* read config file */
+ Read_config_file(pDevice);
+
+ if (device_init_registers(pDevice, DEVICE_INIT_COLD) == false) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " init register fail\n");
+ goto free_all;
+ }
+
+ device_set_multi(pDevice->dev);
+
+ /* init for key management */
+ KeyvInitTable(pDevice,&pDevice->sKey);
+ memcpy(pDevice->vnt_mgmt.abyMACAddr,
+ pDevice->abyCurrentNetAddr, ETH_ALEN);
+ memcpy(pDevice->dev->dev_addr, pDevice->abyCurrentNetAddr, ETH_ALEN);
+ pDevice->bStopTx0Pkt = false;
+ pDevice->bStopDataPkt = false;
+ pDevice->bRoaming = false;
+ pDevice->bIsRoaming = false;
+ pDevice->bEnableRoaming = false;
+ if (pDevice->bDiversityRegCtlON) {
+ device_init_diversity_timer(pDevice);
+ }
+
+ vMgrObjectInit(pDevice);
+ tasklet_init(&pDevice->RxMngWorkItem, (void *)RXvMngWorkItem, (unsigned long)pDevice);
+ tasklet_init(&pDevice->ReadWorkItem, (void *)RXvWorkItem, (unsigned long)pDevice);
+ tasklet_init(&pDevice->EventWorkItem, (void *)INTvWorkItem, (unsigned long)pDevice);
+ add_timer(&pDevice->vnt_mgmt.sTimerSecondCallback);
+ pDevice->int_interval = 100; /* max 100 microframes */
+ pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
+
+ pDevice->bIsRxWorkItemQueued = true;
+ pDevice->fKillEventPollingThread = false;
+ pDevice->bEventAvailable = false;
+
+ pDevice->bWPADEVUp = false;
+ pDevice->bwextstep0 = false;
+ pDevice->bwextstep1 = false;
+ pDevice->bwextstep2 = false;
+ pDevice->bwextstep3 = false;
+ pDevice->bWPASuppWextEnabled = false;
+ pDevice->byReAssocCount = 0;
+
+ RXvWorkItem(pDevice);
+ INTvWorkItem(pDevice);
+
+ /* if WEP key already set by iwconfig but device not yet open */
+ if ((pDevice->bEncryptionEnable == true) && (pDevice->bTransmitKey == true)) {
+ spin_lock_irq(&pDevice->lock);
+ KeybSetDefaultKey( pDevice,
+ &(pDevice->sKey),
+ pDevice->byKeyIndex | (1 << 31),
+ pDevice->uKeyLength,
+ NULL,
+ pDevice->abyKey,
+ KEY_CTL_WEP
+ );
+ spin_unlock_irq(&pDevice->lock);
+ pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
+ }
+
+ if (pDevice->vnt_mgmt.eConfigMode == WMAC_CONFIG_AP)
+ bScheduleCommand((void *) pDevice, WLAN_CMD_RUN_AP, NULL);
+ else
+ bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, NULL);
+
+ netif_stop_queue(pDevice->dev);
+ pDevice->flags |= DEVICE_FLAGS_OPENED;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_open success..\n");
+ return 0;
+
+free_all:
+ device_free_frag_bufs(pDevice);
+free_rx_tx:
+ device_free_rx_bufs(pDevice);
+ device_free_tx_bufs(pDevice);
+ device_free_int_bufs(pDevice);
+ usb_kill_urb(pDevice->pControlURB);
+ usb_kill_urb(pDevice->pInterruptURB);
+ usb_free_urb(pDevice->pControlURB);
+ usb_free_urb(pDevice->pInterruptURB);
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_open fail.. \n");
+ return -ENOMEM;
+}
+
+static int device_close(struct net_device *dev)
+{
+ struct vnt_private *pDevice = netdev_priv(dev);
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ int uu;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_close1\n");
+ if (pDevice == NULL)
+ return -ENODEV;
+
+ if (pDevice->bLinkPass) {
+ bScheduleCommand((void *) pDevice, WLAN_CMD_DISASSOCIATE, NULL);
+ mdelay(30);
+ }
+
+ memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+ pMgmt->bShareKeyAlgorithm = false;
+ pDevice->bEncryptionEnable = false;
+ pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
+ spin_lock_irq(&pDevice->lock);
+ for (uu = 0; uu < MAX_KEY_TABLE; uu++)
+ MACvDisableKeyEntry(pDevice,uu);
+ spin_unlock_irq(&pDevice->lock);
+
+ if ((pDevice->flags & DEVICE_FLAGS_UNPLUG) == false) {
+ MACbShutdown(pDevice);
+ }
+ netif_stop_queue(pDevice->dev);
+ MP_SET_FLAG(pDevice, fMP_DISCONNECTED);
+ MP_CLEAR_FLAG(pDevice, fMP_POST_WRITES);
+ MP_CLEAR_FLAG(pDevice, fMP_POST_READS);
+ pDevice->fKillEventPollingThread = true;
+ del_timer(&pDevice->sTimerCommand);
+ del_timer(&pMgmt->sTimerSecondCallback);
+
+ del_timer(&pDevice->sTimerTxData);
+
+ if (pDevice->bDiversityRegCtlON) {
+ del_timer(&pDevice->TimerSQ3Tmax1);
+ del_timer(&pDevice->TimerSQ3Tmax2);
+ del_timer(&pDevice->TimerSQ3Tmax3);
+ }
+ tasklet_kill(&pDevice->RxMngWorkItem);
+ tasklet_kill(&pDevice->ReadWorkItem);
+ tasklet_kill(&pDevice->EventWorkItem);
+
+ pDevice->bRoaming = false;
+ pDevice->bIsRoaming = false;
+ pDevice->bEnableRoaming = false;
+ pDevice->bCmdRunning = false;
+ pDevice->bLinkPass = false;
+ memset(pMgmt->abyCurrBSSID, 0, 6);
+ pMgmt->eCurrState = WMAC_STATE_IDLE;
+
+ pDevice->flags &= ~DEVICE_FLAGS_OPENED;
+
+ device_free_tx_bufs(pDevice);
+ device_free_rx_bufs(pDevice);
+ device_free_int_bufs(pDevice);
+ device_free_frag_bufs(pDevice);
+
+ usb_kill_urb(pDevice->pControlURB);
+ usb_kill_urb(pDevice->pInterruptURB);
+ usb_free_urb(pDevice->pControlURB);
+ usb_free_urb(pDevice->pInterruptURB);
+
+ BSSvClearNodeDBTable(pDevice, 0);
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_close2 \n");
+
+ return 0;
+}
+
+static void vt6656_disconnect(struct usb_interface *intf)
+{
+ struct vnt_private *device = usb_get_intfdata(intf);
+
+ if (!device)
+ return;
+
+ usb_set_intfdata(intf, NULL);
+ usb_put_dev(interface_to_usbdev(intf));
+
+ device->flags |= DEVICE_FLAGS_UNPLUG;
+
+ if (device->dev) {
+ unregister_netdev(device->dev);
+ free_netdev(device->dev);
+ }
+
+}
+
+static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev)
+{
+ struct vnt_private *pDevice = netdev_priv(dev);
+
+ spin_lock_irq(&pDevice->lock);
+
+ if (unlikely(pDevice->bStopTx0Pkt))
+ dev_kfree_skb_irq(skb);
+ else
+ vDMA0_tx_80211(pDevice, skb);
+
+ spin_unlock_irq(&pDevice->lock);
+
+ return NETDEV_TX_OK;
+}
+
+static int device_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct vnt_private *pDevice = netdev_priv(dev);
+ struct net_device_stats *stats = &pDevice->stats;
+
+ spin_lock_irq(&pDevice->lock);
+
+ netif_stop_queue(dev);
+
+ if (!pDevice->bLinkPass) {
+ dev_kfree_skb_irq(skb);
+ goto out;
+ }
+
+ if (pDevice->bStopDataPkt) {
+ dev_kfree_skb_irq(skb);
+ stats->tx_dropped++;
+ goto out;
+ }
+
+ if (nsDMA_tx_packet(pDevice, TYPE_AC0DMA, skb)) {
+ if (netif_queue_stopped(dev))
+ netif_wake_queue(dev);
+ }
+
+out:
+ spin_unlock_irq(&pDevice->lock);
+
+ return NETDEV_TX_OK;
+}
+
+static unsigned const ethernet_polynomial = 0x04c11db7U;
+static inline u32 ether_crc(int length, unsigned char *data)
+{
+ int crc = -1;
+
+ while(--length >= 0) {
+ unsigned char current_octet = *data++;
+ int bit;
+ for (bit = 0; bit < 8; bit++, current_octet >>= 1) {
+ crc = (crc << 1) ^
+ ((crc < 0) ^ (current_octet & 1) ? ethernet_polynomial : 0);
+ }
+ }
+ return crc;
+}
+
+/* find out the start position of str2 from str1 */
+static unsigned char *kstrstr(const unsigned char *str1,
+ const unsigned char *str2) {
+ int str1_len = strlen(str1);
+ int str2_len = strlen(str2);
+
+ while (str1_len >= str2_len) {
+ str1_len--;
+ if(memcmp(str1,str2,str2_len)==0)
+ return (unsigned char *) str1;
+ str1++;
+ }
+ return NULL;
+}
+
+static int Config_FileGetParameter(unsigned char *string,
+ unsigned char *dest,
+ unsigned char *source)
+{
+ unsigned char buf1[100];
+ unsigned char buf2[100];
+ unsigned char *start_p = NULL, *end_p = NULL, *tmp_p = NULL;
+ int ii;
+
+ memset(buf1,0,100);
+ strcat(buf1, string);
+ strcat(buf1, "=");
+ source+=strlen(buf1);
+
+ /* find target string start point */
+ start_p = kstrstr(source,buf1);
+ if (start_p == NULL)
+ return false;
+
+ /* check if current config line is marked by "#" */
+ for (ii = 1; ; ii++) {
+ if (memcmp(start_p - ii, "\n", 1) == 0)
+ break;
+ if (memcmp(start_p - ii, "#", 1) == 0)
+ return false;
+ }
+
+ /* find target string end point */
+ end_p = kstrstr(start_p,"\n");
+ if (end_p == NULL) { /* can't find "\n", but don't care */
+ end_p = start_p + strlen(start_p); /* no include "\n" */
+ }
+
+ memset(buf2,0,100);
+ memcpy(buf2, start_p, end_p-start_p); /* get the target line */
+ buf2[end_p-start_p]='\0';
+
+ /* find value */
+ start_p = kstrstr(buf2,"=");
+ if (start_p == NULL)
+ return false;
+ memset(buf1,0,100);
+ strcpy(buf1,start_p+1);
+
+ /* except space */
+ tmp_p = buf1;
+ while(*tmp_p != 0x00) {
+ if(*tmp_p==' ')
+ tmp_p++;
+ else
+ break;
+ }
+
+ memcpy(dest,tmp_p,strlen(tmp_p));
+ return true;
+}
+
+/* if read fails, return NULL, or return data pointer */
+static unsigned char *Config_FileOperation(struct vnt_private *pDevice)
+{
+ unsigned char *buffer = kmalloc(1024, GFP_KERNEL);
+ struct file *file;
+
+ if (!buffer) {
+ printk("allocate mem for file fail?\n");
+ return NULL;
+ }
+
+ file = filp_open(CONFIG_PATH, O_RDONLY, 0);
+ if (IS_ERR(file)) {
+ kfree(buffer);
+ printk("Config_FileOperation file Not exist\n");
+ return NULL;
+ }
+
+ if (kernel_read(file, 0, buffer, 1024) < 0) {
+ printk("read file error?\n");
+ kfree(buffer);
+ buffer = NULL;
+ }
+
+ fput(file);
+ return buffer;
+}
+
+/* return --->-1:fail; >=0:successful */
+static int Read_config_file(struct vnt_private *pDevice)
+{
+ int result = 0;
+ unsigned char tmpbuffer[100];
+ unsigned char *buffer = NULL;
+
+ /* init config setting */
+ pDevice->config_file.ZoneType = -1;
+ pDevice->config_file.eAuthenMode = -1;
+ pDevice->config_file.eEncryptionStatus = -1;
+
+ buffer = Config_FileOperation(pDevice);
+ if (buffer == NULL) {
+ result =-1;
+ return result;
+ }
+
+/* get zonetype */
+{
+ memset(tmpbuffer,0,sizeof(tmpbuffer));
+ if(Config_FileGetParameter("ZONETYPE",tmpbuffer,buffer) ==true) {
+ if(memcmp(tmpbuffer,"USA",3)==0) {
+ pDevice->config_file.ZoneType=ZoneType_USA;
+ }
+ else if(memcmp(tmpbuffer,"JAPAN",5)==0) {
+ pDevice->config_file.ZoneType=ZoneType_Japan;
+ }
+ else if(memcmp(tmpbuffer,"EUROPE",6)==0) {
+ pDevice->config_file.ZoneType=ZoneType_Europe;
+ }
+ else {
+ printk("Unknown Zonetype[%s]?\n",tmpbuffer);
+ }
+ }
+}
+
+/* get other parameter */
+ {
+ memset(tmpbuffer,0,sizeof(tmpbuffer));
+ if(Config_FileGetParameter("AUTHENMODE",tmpbuffer,buffer)==true) {
+ pDevice->config_file.eAuthenMode = (int) simple_strtol(tmpbuffer, NULL, 10);
+ }
+
+ memset(tmpbuffer,0,sizeof(tmpbuffer));
+ if(Config_FileGetParameter("ENCRYPTIONMODE",tmpbuffer,buffer)==true) {
+ pDevice->config_file.eEncryptionStatus= (int) simple_strtol(tmpbuffer, NULL, 10);
+ }
+ }
+
+ kfree(buffer);
+ return result;
+}
+
+static void device_set_multi(struct net_device *dev)
+{
+ struct vnt_private *pDevice = netdev_priv(dev);
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ struct netdev_hw_addr *ha;
+ u32 mc_filter[2];
+ int ii;
+ u8 pbyData[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+ u8 byTmpMode = 0;
+ int rc;
+
+ spin_lock_irq(&pDevice->lock);
+ rc = CONTROLnsRequestIn(pDevice,
+ MESSAGE_TYPE_READ,
+ MAC_REG_RCR,
+ MESSAGE_REQUEST_MACREG,
+ 1,
+ &byTmpMode
+ );
+ if (rc == 0) pDevice->byRxMode = byTmpMode;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRxMode in= %x\n", pDevice->byRxMode);
+
+ if (dev->flags & IFF_PROMISC) { /* set promiscuous mode */
+ DBG_PRT(MSG_LEVEL_ERR,KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name);
+ /* unconditionally log net taps */
+ pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST|RCR_UNICAST);
+ }
+ else if ((netdev_mc_count(dev) > pDevice->multicast_limit) ||
+ (dev->flags & IFF_ALLMULTI)) {
+ CONTROLnsRequestOut(pDevice,
+ MESSAGE_TYPE_WRITE,
+ MAC_REG_MAR0,
+ MESSAGE_REQUEST_MACREG,
+ 8,
+ pbyData
+ );
+ pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
+ }
+ else {
+ memset(mc_filter, 0, sizeof(mc_filter));
+ netdev_for_each_mc_addr(ha, dev) {
+ int bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26;
+ mc_filter[bit_nr >> 5] |= cpu_to_le32(1 << (bit_nr & 31));
+ }
+ for (ii = 0; ii < 4; ii++) {
+ MACvWriteMultiAddr(pDevice, ii, *((u8 *)&mc_filter[0] + ii));
+ MACvWriteMultiAddr(pDevice, ii+ 4, *((u8 *)&mc_filter[1] + ii));
+ }
+ pDevice->byRxMode &= ~(RCR_UNICAST);
+ pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
+ }
+
+ if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
+ /*
+ * If AP mode, don't enable RCR_UNICAST since HW only compares
+ * addr1 with local MAC
+ */
+ pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
+ pDevice->byRxMode &= ~(RCR_UNICAST);
+ }
+ ControlvWriteByte(pDevice, MESSAGE_REQUEST_MACREG, MAC_REG_RCR, pDevice->byRxMode);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRxMode out= %x\n", pDevice->byRxMode);
+ spin_unlock_irq(&pDevice->lock);
+
+}
+
+static struct net_device_stats *device_get_stats(struct net_device *dev)
+{
+ struct vnt_private *pDevice = netdev_priv(dev);
+
+ return &pDevice->stats;
+}
+
+static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+ struct vnt_private *pDevice = netdev_priv(dev);
+ struct iwreq *wrq = (struct iwreq *) rq;
+ int rc = 0;
+
+ switch (cmd) {
+
+ case IOCTL_CMD_HOSTAPD:
+
+ if (!(pDevice->flags & DEVICE_FLAGS_OPENED))
+ rc = -EFAULT;
+
+ rc = vt6656_hostap_ioctl(pDevice, &wrq->u.data);
+ break;
+
+ case SIOCETHTOOL:
+ return ethtool_ioctl(dev, (void *) rq->ifr_data);
+
+ }
+
+ return rc;
+}
+
+static int ethtool_ioctl(struct net_device *dev, void *useraddr)
+{
+ u32 ethcmd;
+
+ if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
+ return -EFAULT;
+
+ switch (ethcmd) {
+ case ETHTOOL_GDRVINFO: {
+ struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
+ strncpy(info.driver, DEVICE_NAME, sizeof(info.driver)-1);
+ strncpy(info.version, DEVICE_VERSION, sizeof(info.version)-1);
+ if (copy_to_user(useraddr, &info, sizeof(info)))
+ return -EFAULT;
+ return 0;
+ }
+
+ }
+
+ return -EOPNOTSUPP;
+}
+
+MODULE_DEVICE_TABLE(usb, vt6656_table);
+
+static struct usb_driver vt6656_driver = {
+ .name = DEVICE_NAME,
+ .probe = vt6656_probe,
+ .disconnect = vt6656_disconnect,
+ .id_table = vt6656_table,
+#ifdef CONFIG_PM
+ .suspend = vt6656_suspend,
+ .resume = vt6656_resume,
+#endif /* CONFIG_PM */
+};
+
+module_usb_driver(vt6656_driver);
diff --git a/drivers/staging/vt6656/mib.c b/drivers/staging/vt6656/mib.c
new file mode 100644
index 00000000..12333cdc
--- /dev/null
+++ b/drivers/staging/vt6656/mib.c
@@ -0,0 +1,489 @@
+/*
+ * 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:
+ * STAvUpdateIstStatCounter - Update ISR statistic counter
+ * STAvUpdateRDStatCounter - Update Rx statistic counter
+ * STAvUpdateTDStatCounter - Update Tx statistic counter
+ * STAvUpdateTDStatCounterEx - Update Tx statistic counter and copy tx data
+ * STAvUpdate802_11Counter - Update 802.11 mib counter
+ *
+ * Revision History:
+ *
+ */
+
+#include "mac.h"
+#include "tether.h"
+#include "mib.h"
+#include "wctl.h"
+#include "baseband.h"
+
+static int msglevel =MSG_LEVEL_INFO;
+
+/*
+ * 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, u8 byIsr0, u8 byIsr1)
+{
+ /**********************/
+ /* ABNORMAL interrupt */
+ /**********************/
+ // not any IMR bit invoke irq
+ if (byIsr0 == 0) {
+ pStatistic->ISRStat.dwIsrUnknown++;
+ return;
+ }
+
+ if (byIsr0 & ISR_ACTX) // ISR, bit0
+ pStatistic->ISRStat.dwIsrTx0OK++; // TXDMA0 successful
+
+ if (byIsr0 & ISR_BNTX) // ISR, bit2
+ pStatistic->ISRStat.dwIsrBeaconTxOK++; // BeaconTx successful
+
+ if (byIsr0 & ISR_RXDMA0) // ISR, bit3
+ pStatistic->ISRStat.dwIsrRx0OK++; // Rx0 successful
+
+ if (byIsr0 & ISR_TBTT) // ISR, bit4
+ pStatistic->ISRStat.dwIsrTBTTInt++; // TBTT successful
+
+ if (byIsr0 & ISR_SOFTTIMER) // ISR, bit6
+ pStatistic->ISRStat.dwIsrSTIMERInt++;
+
+ if (byIsr0 & ISR_WATCHDOG) // ISR, bit7
+ pStatistic->ISRStat.dwIsrWatchDog++;
+
+ if (byIsr1 & ISR_FETALERR) // ISR, bit8
+ pStatistic->ISRStat.dwIsrUnrecoverableError++;
+
+ if (byIsr1 & ISR_SOFTINT) // ISR, bit9
+ pStatistic->ISRStat.dwIsrSoftInterrupt++; // software interrupt
+
+ if (byIsr1 & ISR_MIBNEARFULL) // ISR, bit10
+ pStatistic->ISRStat.dwIsrMIBNearfull++;
+
+ if (byIsr1 & ISR_RXNOBUF) // ISR, bit11
+ pStatistic->ISRStat.dwIsrRxNoBuf++; // Rx No Buff
+
+}
+
+/*
+ * Description: Update Rx Statistic Counter
+ *
+ * Parameters:
+ * In:
+ * pStatistic - Pointer to Statistic Counter Data Structure
+ * byRSR - Rx Status
+ * byNewRSR - Rx Status
+ * pbyBuffer - Rx Buffer
+ * cbFrameLength - Rx Length
+ * Out:
+ * none
+ *
+ * Return Value: none
+ *
+ */
+void STAvUpdateRDStatCounter(PSStatCounter pStatistic,
+ u8 byRSR, u8 byNewRSR,
+ u8 byRxSts, u8 byRxRate,
+ u8 * pbyBuffer, unsigned int cbFrameLength)
+{
+ /* need change */
+ struct ieee80211_hdr *pHeader = (struct ieee80211_hdr *)pbyBuffer;
+
+ if (byRSR & RSR_ADDROK)
+ pStatistic->dwRsrADDROk++;
+ if (byRSR & RSR_CRCOK) {
+ pStatistic->dwRsrCRCOk++;
+ pStatistic->ullRsrOK++;
+
+ if (cbFrameLength >= ETH_ALEN) {
+ /* update counters in case of successful transmission */
+ if (byRSR & RSR_ADDRBROAD) {
+ pStatistic->ullRxBroadcastFrames++;
+ pStatistic->ullRxBroadcastBytes +=
+ (unsigned long long) cbFrameLength;
+ }
+ else if (byRSR & RSR_ADDRMULTI) {
+ pStatistic->ullRxMulticastFrames++;
+ pStatistic->ullRxMulticastBytes +=
+ (unsigned long long) cbFrameLength;
+ }
+ else {
+ pStatistic->ullRxDirectedFrames++;
+ pStatistic->ullRxDirectedBytes +=
+ (unsigned long long) cbFrameLength;
+ }
+ }
+ }
+
+ if(byRxRate==22) {
+ pStatistic->CustomStat.ullRsr11M++;
+ if(byRSR & RSR_CRCOK) {
+ pStatistic->CustomStat.ullRsr11MCRCOk++;
+ }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "11M: ALL[%d], OK[%d]:[%02x]\n",
+ (signed int) pStatistic->CustomStat.ullRsr11M,
+ (signed int) pStatistic->CustomStat.ullRsr11MCRCOk, byRSR);
+ }
+ else if(byRxRate==11) {
+ pStatistic->CustomStat.ullRsr5M++;
+ if(byRSR & RSR_CRCOK) {
+ pStatistic->CustomStat.ullRsr5MCRCOk++;
+ }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " 5M: ALL[%d], OK[%d]:[%02x]\n",
+ (signed int) pStatistic->CustomStat.ullRsr5M,
+ (signed int) pStatistic->CustomStat.ullRsr5MCRCOk, byRSR);
+ }
+ else if(byRxRate==4) {
+ pStatistic->CustomStat.ullRsr2M++;
+ if(byRSR & RSR_CRCOK) {
+ pStatistic->CustomStat.ullRsr2MCRCOk++;
+ }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " 2M: ALL[%d], OK[%d]:[%02x]\n",
+ (signed int) pStatistic->CustomStat.ullRsr2M,
+ (signed int) pStatistic->CustomStat.ullRsr2MCRCOk, byRSR);
+ }
+ else if(byRxRate==2){
+ pStatistic->CustomStat.ullRsr1M++;
+ if(byRSR & RSR_CRCOK) {
+ pStatistic->CustomStat.ullRsr1MCRCOk++;
+ }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " 1M: ALL[%d], OK[%d]:[%02x]\n",
+ (signed int) pStatistic->CustomStat.ullRsr1M,
+ (signed int) pStatistic->CustomStat.ullRsr1MCRCOk, byRSR);
+ }
+ else if(byRxRate==12){
+ pStatistic->CustomStat.ullRsr6M++;
+ if(byRSR & RSR_CRCOK) {
+ pStatistic->CustomStat.ullRsr6MCRCOk++;
+ }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " 6M: ALL[%d], OK[%d]\n",
+ (signed int) pStatistic->CustomStat.ullRsr6M,
+ (signed int) pStatistic->CustomStat.ullRsr6MCRCOk);
+ }
+ else if(byRxRate==18){
+ pStatistic->CustomStat.ullRsr9M++;
+ if(byRSR & RSR_CRCOK) {
+ pStatistic->CustomStat.ullRsr9MCRCOk++;
+ }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " 9M: ALL[%d], OK[%d]\n",
+ (signed int) pStatistic->CustomStat.ullRsr9M,
+ (signed int) pStatistic->CustomStat.ullRsr9MCRCOk);
+ }
+ else if(byRxRate==24){
+ pStatistic->CustomStat.ullRsr12M++;
+ if(byRSR & RSR_CRCOK) {
+ pStatistic->CustomStat.ullRsr12MCRCOk++;
+ }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "12M: ALL[%d], OK[%d]\n",
+ (signed int) pStatistic->CustomStat.ullRsr12M,
+ (signed int) pStatistic->CustomStat.ullRsr12MCRCOk);
+ }
+ else if(byRxRate==36){
+ pStatistic->CustomStat.ullRsr18M++;
+ if(byRSR & RSR_CRCOK) {
+ pStatistic->CustomStat.ullRsr18MCRCOk++;
+ }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "18M: ALL[%d], OK[%d]\n",
+ (signed int) pStatistic->CustomStat.ullRsr18M,
+ (signed int) pStatistic->CustomStat.ullRsr18MCRCOk);
+ }
+ else if(byRxRate==48){
+ pStatistic->CustomStat.ullRsr24M++;
+ if(byRSR & RSR_CRCOK) {
+ pStatistic->CustomStat.ullRsr24MCRCOk++;
+ }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "24M: ALL[%d], OK[%d]\n",
+ (signed int) pStatistic->CustomStat.ullRsr24M,
+ (signed int) pStatistic->CustomStat.ullRsr24MCRCOk);
+ }
+ else if(byRxRate==72){
+ pStatistic->CustomStat.ullRsr36M++;
+ if(byRSR & RSR_CRCOK) {
+ pStatistic->CustomStat.ullRsr36MCRCOk++;
+ }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "36M: ALL[%d], OK[%d]\n",
+ (signed int) pStatistic->CustomStat.ullRsr36M,
+ (signed int) pStatistic->CustomStat.ullRsr36MCRCOk);
+ }
+ else if(byRxRate==96){
+ pStatistic->CustomStat.ullRsr48M++;
+ if(byRSR & RSR_CRCOK) {
+ pStatistic->CustomStat.ullRsr48MCRCOk++;
+ }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "48M: ALL[%d], OK[%d]\n",
+ (signed int) pStatistic->CustomStat.ullRsr48M,
+ (signed int) pStatistic->CustomStat.ullRsr48MCRCOk);
+ }
+ else if(byRxRate==108){
+ pStatistic->CustomStat.ullRsr54M++;
+ if(byRSR & RSR_CRCOK) {
+ pStatistic->CustomStat.ullRsr54MCRCOk++;
+ }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "54M: ALL[%d], OK[%d]\n",
+ (signed int) pStatistic->CustomStat.ullRsr54M,
+ (signed int) pStatistic->CustomStat.ullRsr54MCRCOk);
+ }
+ else {
+ DBG_PRT(MSG_LEVEL_DEBUG,
+ KERN_INFO "Unknown: Total[%d], CRCOK[%d]\n",
+ (signed int) pStatistic->dwRsrRxPacket+1,
+ (signed int)pStatistic->dwRsrCRCOk);
+ }
+
+ if (byRSR & RSR_BSSIDOK)
+ pStatistic->dwRsrBSSIDOk++;
+
+ if (byRSR & RSR_BCNSSIDOK)
+ pStatistic->dwRsrBCNSSIDOk++;
+ if (byRSR & RSR_IVLDLEN) //invalid len (> 2312 byte)
+ pStatistic->dwRsrLENErr++;
+ if (byRSR & RSR_IVLDTYP) //invalid packet type
+ pStatistic->dwRsrTYPErr++;
+ if ((byRSR & (RSR_IVLDTYP | RSR_IVLDLEN)) || !(byRSR & RSR_CRCOK))
+ pStatistic->dwRsrErr++;
+
+ if (byNewRSR & NEWRSR_DECRYPTOK)
+ pStatistic->dwNewRsrDECRYPTOK++;
+ if (byNewRSR & NEWRSR_CFPIND)
+ pStatistic->dwNewRsrCFP++;
+ if (byNewRSR & NEWRSR_HWUTSF)
+ pStatistic->dwNewRsrUTSF++;
+ if (byNewRSR & NEWRSR_BCNHITAID)
+ pStatistic->dwNewRsrHITAID++;
+ if (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 (byRSR & RSR_ADDRBROAD)
+ pStatistic->dwRsrBroadcast++;
+ else if (byRSR & RSR_ADDRMULTI)
+ pStatistic->dwRsrMulticast++;
+ else
+ pStatistic->dwRsrDirected++;
+
+ if (WLAN_GET_FC_MOREFRAG(pHeader->frame_control))
+ pStatistic->dwRsrRxFragment++;
+
+ if (cbFrameLength < ETH_ZLEN + 4) {
+ pStatistic->dwRsrRunt++;
+ } else if (cbFrameLength == ETH_ZLEN + 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 <= ETH_FRAME_LEN + 4)) {
+ pStatistic->dwRsrRxFrmLen1024_1518++;
+ } else if (cbFrameLength > ETH_FRAME_LEN + 4) {
+ pStatistic->dwRsrLong++;
+ }
+}
+
+/*
+ * 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,
+ u8 byPktNum,
+ u8 byRate,
+ u8 byTSR
+ )
+{
+ u8 byRetyCnt;
+ // increase tx packet count
+ pStatistic->dwTsrTxPacket++;
+
+ byRetyCnt = (byTSR & 0xF0) >> 4;
+ if (byRetyCnt != 0) {
+ pStatistic->dwTsrRetry++;
+ pStatistic->dwTsrTotalRetry += byRetyCnt;
+ pStatistic->dwTxFail[byRate]+= byRetyCnt;
+ pStatistic->dwTxFail[MAX_RATE] += byRetyCnt;
+
+ if ( byRetyCnt == 0x1)
+ pStatistic->dwTsrOnceRetry++;
+ else
+ pStatistic->dwTsrMoreThanOnceRetry++;
+
+ if (byRetyCnt <= 8)
+ pStatistic->dwTxRetryCount[byRetyCnt-1]++;
+
+ }
+ if ( !(byTSR & (TSR_TMO | TSR_RETRYTMO))) {
+
+ if (byRetyCnt < 2)
+ pStatistic->TxNoRetryOkCount ++;
+ else
+ pStatistic->TxRetryOkCount ++;
+
+ pStatistic->ullTsrOK++;
+ pStatistic->CustomStat.ullTsrAllOK++;
+ // update counters in case that successful transmit
+ pStatistic->dwTxOk[byRate]++;
+ pStatistic->dwTxOk[MAX_RATE]++;
+
+ if ( pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni == TX_PKT_BROAD ) {
+ pStatistic->ullTxBroadcastFrames++;
+ pStatistic->ullTxBroadcastBytes += pStatistic->abyTxPktInfo[byPktNum].wLength;
+ } else if ( pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni == TX_PKT_MULTI ) {
+ pStatistic->ullTxMulticastFrames++;
+ pStatistic->ullTxMulticastBytes += pStatistic->abyTxPktInfo[byPktNum].wLength;
+ } else if ( pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni == TX_PKT_UNI ) {
+ pStatistic->ullTxDirectedFrames++;
+ pStatistic->ullTxDirectedBytes += pStatistic->abyTxPktInfo[byPktNum].wLength;
+ }
+ }
+ else {
+
+ pStatistic->TxFailCount ++;
+
+ pStatistic->dwTsrErr++;
+ if (byTSR & TSR_RETRYTMO)
+ pStatistic->dwTsrRetryTimeout++;
+ if (byTSR & TSR_TMO)
+ pStatistic->dwTsrTransmitTimeout++;
+ }
+
+ if ( pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni == TX_PKT_BROAD ) {
+ pStatistic->dwTsrBroadcast++;
+ } else if ( pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni == TX_PKT_MULTI ) {
+ pStatistic->dwTsrMulticast++;
+ } else if ( pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni == TX_PKT_UNI ) {
+ pStatistic->dwTsrDirected++;
+ }
+}
+
+/*
+ * Description: Update 802.11 mib counter
+ *
+ * Parameters:
+ * In:
+ * p802_11Counter - Pointer to 802.11 mib counter
+ * pStatistic - Pointer to Statistic Counter Data Structure
+ * dwCounter - hardware counter for 802.11 mib
+ * Out:
+ * none
+ *
+ * Return Value: none
+ *
+ */
+void
+STAvUpdate802_11Counter(
+ PSDot11Counters p802_11Counter,
+ PSStatCounter pStatistic,
+ u8 byRTSSuccess,
+ u8 byRTSFail,
+ u8 byACKFail,
+ u8 byFCSErr
+ )
+{
+ //p802_11Counter->TransmittedFragmentCount
+ p802_11Counter->MulticastTransmittedFrameCount =
+ (unsigned long long) (pStatistic->dwTsrBroadcast +
+ pStatistic->dwTsrMulticast);
+ p802_11Counter->FailedCount = (unsigned long long) (pStatistic->dwTsrErr);
+ p802_11Counter->RetryCount = (unsigned long long) (pStatistic->dwTsrRetry);
+ p802_11Counter->MultipleRetryCount =
+ (unsigned long long) (pStatistic->dwTsrMoreThanOnceRetry);
+ //p802_11Counter->FrameDuplicateCount
+ p802_11Counter->RTSSuccessCount += (unsigned long long) byRTSSuccess;
+ p802_11Counter->RTSFailureCount += (unsigned long long) byRTSFail;
+ p802_11Counter->ACKFailureCount += (unsigned long long) byACKFail;
+ p802_11Counter->FCSErrorCount += (unsigned long long) byFCSErr;
+ //p802_11Counter->ReceivedFragmentCount
+ p802_11Counter->MulticastReceivedFrameCount =
+ (unsigned long long) (pStatistic->dwRsrBroadcast +
+ pStatistic->dwRsrMulticast);
+}
+
+/*
+ * Description: Clear 802.11 mib counter
+ *
+ * Parameters:
+ * In:
+ * pUsbCounter - Pointer to USB mib counter
+ * ntStatus - URB status
+ * Out:
+ * none
+ *
+ * Return Value: none
+ *
+ */
+
+void STAvUpdateUSBCounter(PSUSBCounter pUsbCounter, int ntStatus)
+{
+
+// if ( ntStatus == USBD_STATUS_CRC ) {
+ pUsbCounter->dwCrc++;
+// }
+
+}
diff --git a/drivers/staging/vt6656/mib.h b/drivers/staging/vt6656/mib.h
new file mode 100644
index 00000000..35375325
--- /dev/null
+++ b/drivers/staging/vt6656/mib.h
@@ -0,0 +1,378 @@
+/*
+ * 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__
+
+#include "tether.h"
+#include "desc.h"
+
+//
+// USB counter
+//
+typedef struct tagSUSBCounter {
+ u32 dwCrc;
+
+} SUSBCounter, *PSUSBCounter;
+
+//
+// 802.11 counter
+//
+
+typedef struct tagSDot11Counters {
+ /* unsigned long Length; // Length of structure */
+ unsigned long long TransmittedFragmentCount;
+ unsigned long long MulticastTransmittedFrameCount;
+ unsigned long long FailedCount;
+ unsigned long long RetryCount;
+ unsigned long long MultipleRetryCount;
+ unsigned long long RTSSuccessCount;
+ unsigned long long RTSFailureCount;
+ unsigned long long ACKFailureCount;
+ unsigned long long FrameDuplicateCount;
+ unsigned long long ReceivedFragmentCount;
+ unsigned long long MulticastReceivedFrameCount;
+ unsigned long long FCSErrorCount;
+ unsigned long long TKIPLocalMICFailures;
+ unsigned long long TKIPRemoteMICFailures;
+ unsigned long long TKIPICVErrors;
+ unsigned long long TKIPReplays;
+ unsigned long long CCMPFormatErrors;
+ unsigned long long CCMPReplays;
+ unsigned long long CCMPDecryptErrors;
+ unsigned long long FourWayHandshakeFailures;
+ /*
+ * unsigned long long WEPUndecryptableCount;
+ * unsigned long long WEPICVErrorCount;
+ * unsigned long long DecryptSuccessCount;
+ * unsigned long long DecryptFailureCount;
+ */
+} SDot11Counters, *PSDot11Counters;
+
+//
+// MIB2 counter
+//
+typedef struct tagSMib2Counter {
+ signed long ifIndex;
+ char ifDescr[256]; // max size 255 plus zero ending
+ // e.g. "interface 1"
+ signed long ifType;
+ signed long ifMtu;
+ u32 ifSpeed;
+ u8 ifPhysAddress[ETH_ALEN];
+ signed long ifAdminStatus;
+ signed long ifOperStatus;
+ u32 ifLastChange;
+ u32 ifInOctets;
+ u32 ifInUcastPkts;
+ u32 ifInNUcastPkts;
+ u32 ifInDiscards;
+ u32 ifInErrors;
+ u32 ifInUnknownProtos;
+ u32 ifOutOctets;
+ u32 ifOutUcastPkts;
+ u32 ifOutNUcastPkts;
+ u32 ifOutDiscards;
+ u32 ifOutErrors;
+ u32 ifOutQLen;
+ u32 ifSpecific;
+} SMib2Counter, *PSMib2Counter;
+
+// Value in the ifType entry
+#define WIRELESSLANIEEE80211b 6 //
+
+// Value in the ifAdminStatus/ifOperStatus entry
+#define UP 1 //
+#define DOWN 2 //
+#define TESTING 3 //
+
+//
+// RMON counter
+//
+typedef struct tagSRmonCounter {
+ signed long etherStatsIndex;
+ u32 etherStatsDataSource;
+ u32 etherStatsDropEvents;
+ u32 etherStatsOctets;
+ u32 etherStatsPkts;
+ u32 etherStatsBroadcastPkts;
+ u32 etherStatsMulticastPkts;
+ u32 etherStatsCRCAlignErrors;
+ u32 etherStatsUndersizePkts;
+ u32 etherStatsOversizePkts;
+ u32 etherStatsFragments;
+ u32 etherStatsJabbers;
+ u32 etherStatsCollisions;
+ u32 etherStatsPkt64Octets;
+ u32 etherStatsPkt65to127Octets;
+ u32 etherStatsPkt128to255Octets;
+ u32 etherStatsPkt256to511Octets;
+ u32 etherStatsPkt512to1023Octets;
+ u32 etherStatsPkt1024to1518Octets;
+ u32 etherStatsOwners;
+ u32 etherStatsStatus;
+} SRmonCounter, *PSRmonCounter;
+
+//
+// Custom counter
+//
+typedef struct tagSCustomCounters {
+ unsigned long Length;
+
+ unsigned long long ullTsrAllOK;
+
+ unsigned long long ullRsr11M;
+ unsigned long long ullRsr5M;
+ unsigned long long ullRsr2M;
+ unsigned long long ullRsr1M;
+
+ unsigned long long ullRsr11MCRCOk;
+ unsigned long long ullRsr5MCRCOk;
+ unsigned long long ullRsr2MCRCOk;
+ unsigned long long ullRsr1MCRCOk;
+
+ unsigned long long ullRsr54M;
+ unsigned long long ullRsr48M;
+ unsigned long long ullRsr36M;
+ unsigned long long ullRsr24M;
+ unsigned long long ullRsr18M;
+ unsigned long long ullRsr12M;
+ unsigned long long ullRsr9M;
+ unsigned long long ullRsr6M;
+
+ unsigned long long ullRsr54MCRCOk;
+ unsigned long long ullRsr48MCRCOk;
+ unsigned long long ullRsr36MCRCOk;
+ unsigned long long ullRsr24MCRCOk;
+ unsigned long long ullRsr18MCRCOk;
+ unsigned long long ullRsr12MCRCOk;
+ unsigned long long ullRsr9MCRCOk;
+ unsigned long long ullRsr6MCRCOk;
+
+} SCustomCounters, *PSCustomCounters;
+
+//
+// Custom counter
+//
+typedef struct tagSISRCounters {
+ unsigned long Length;
+
+ u32 dwIsrTx0OK;
+ u32 dwIsrAC0TxOK;
+ u32 dwIsrBeaconTxOK;
+ u32 dwIsrRx0OK;
+ u32 dwIsrTBTTInt;
+ u32 dwIsrSTIMERInt;
+ u32 dwIsrWatchDog;
+ u32 dwIsrUnrecoverableError;
+ u32 dwIsrSoftInterrupt;
+ u32 dwIsrMIBNearfull;
+ u32 dwIsrRxNoBuf;
+
+ u32 dwIsrUnknown; // unknown interrupt count
+
+ u32 dwIsrRx1OK;
+ u32 dwIsrATIMTxOK;
+ u32 dwIsrSYNCTxOK;
+ u32 dwIsrCFPEnd;
+ u32 dwIsrATIMEnd;
+ u32 dwIsrSYNCFlushOK;
+ u32 dwIsrSTIMER1Int;
+ /////////////////////////////////////
+} SISRCounters, *PSISRCounters;
+
+// Value in the etherStatsStatus entry
+#define VALID 1 //
+#define CREATE_REQUEST 2 //
+#define UNDER_CREATION 3 //
+#define INVALID 4 //
+
+//
+// Tx packet information
+//
+typedef struct tagSTxPktInfo {
+ u8 byBroadMultiUni;
+ u16 wLength;
+ u16 wFIFOCtl;
+ u8 abyDestAddr[ETH_ALEN];
+} STxPktInfo, *PSTxPktInfo;
+
+#define MAX_RATE 12
+//
+// statistic counter
+//
+typedef struct tagSStatCounter {
+ //
+ // ISR status count
+ //
+
+ SISRCounters ISRStat;
+
+ // RSR status count
+ //
+ u32 dwRsrFrmAlgnErr;
+ u32 dwRsrErr;
+ u32 dwRsrCRCErr;
+ u32 dwRsrCRCOk;
+ u32 dwRsrBSSIDOk;
+ u32 dwRsrADDROk;
+ u32 dwRsrBCNSSIDOk;
+ u32 dwRsrLENErr;
+ u32 dwRsrTYPErr;
+
+ u32 dwNewRsrDECRYPTOK;
+ u32 dwNewRsrCFP;
+ u32 dwNewRsrUTSF;
+ u32 dwNewRsrHITAID;
+ u32 dwNewRsrHITAID0;
+
+ u32 dwRsrLong;
+ u32 dwRsrRunt;
+
+ u32 dwRsrRxControl;
+ u32 dwRsrRxData;
+ u32 dwRsrRxManage;
+
+ u32 dwRsrRxPacket;
+ u32 dwRsrRxOctet;
+ u32 dwRsrBroadcast;
+ u32 dwRsrMulticast;
+ u32 dwRsrDirected;
+ // 64-bit OID
+ unsigned long long ullRsrOK;
+
+ // for some optional OIDs (64 bits) and DMI support
+ unsigned long long ullRxBroadcastBytes;
+ unsigned long long ullRxMulticastBytes;
+ unsigned long long ullRxDirectedBytes;
+ unsigned long long ullRxBroadcastFrames;
+ unsigned long long ullRxMulticastFrames;
+ unsigned long long ullRxDirectedFrames;
+
+ u32 dwRsrRxFragment;
+ u32 dwRsrRxFrmLen64;
+ u32 dwRsrRxFrmLen65_127;
+ u32 dwRsrRxFrmLen128_255;
+ u32 dwRsrRxFrmLen256_511;
+ u32 dwRsrRxFrmLen512_1023;
+ u32 dwRsrRxFrmLen1024_1518;
+
+ // TSR status count
+ //
+ u32 dwTsrTotalRetry; // total collision retry count
+ u32 dwTsrOnceRetry; // this packet only occur one collision
+ u32 dwTsrMoreThanOnceRetry; // this packet occur more than one collision
+ u32 dwTsrRetry; // this packet has ever occur collision,
+ // that is (dwTsrOnceCollision0 + dwTsrMoreThanOnceCollision0)
+ u32 dwTsrACKData;
+ u32 dwTsrErr;
+ u32 dwAllTsrOK;
+ u32 dwTsrRetryTimeout;
+ u32 dwTsrTransmitTimeout;
+
+ u32 dwTsrTxPacket;
+ u32 dwTsrTxOctet;
+ u32 dwTsrBroadcast;
+ u32 dwTsrMulticast;
+ u32 dwTsrDirected;
+
+ // RD/TD count
+ u32 dwCntRxFrmLength;
+ u32 dwCntTxBufLength;
+
+ u8 abyCntRxPattern[16];
+ u8 abyCntTxPattern[16];
+
+ // Software check....
+ u32 dwCntRxDataErr; // rx buffer data software compare CRC err count
+ u32 dwCntDecryptErr; // rx buffer data software compare CRC err count
+ u32 dwCntRxICVErr; // rx buffer data software compare CRC err count
+
+ // 64-bit OID
+ unsigned long long ullTsrOK;
+
+ // for some optional OIDs (64 bits) and DMI support
+ unsigned long long ullTxBroadcastFrames;
+ unsigned long long ullTxMulticastFrames;
+ unsigned long long ullTxDirectedFrames;
+ unsigned long long ullTxBroadcastBytes;
+ unsigned long long ullTxMulticastBytes;
+ unsigned long long ullTxDirectedBytes;
+
+ // for autorate
+ u32 dwTxOk[MAX_RATE+1];
+ u32 dwTxFail[MAX_RATE+1];
+ u32 dwTxRetryCount[8];
+
+ STxPktInfo abyTxPktInfo[16];
+
+ SUSBCounter USB_EP0Stat;
+ SUSBCounter USB_BulkInStat;
+ SUSBCounter USB_BulkOutStat;
+ SUSBCounter USB_InterruptStat;
+
+ SCustomCounters CustomStat;
+
+ //Tx count:
+ unsigned long TxNoRetryOkCount; /* success tx no retry ! */
+ unsigned long TxRetryOkCount; /* success tx but retry ! */
+ unsigned long TxFailCount; /* fail tx ? */
+ //Rx count:
+ unsigned long RxOkCnt; /* success rx ! */
+ unsigned long RxFcsErrCnt; /* fail rx ? */
+ //statistic
+ unsigned long SignalStren;
+ unsigned long LinkQuality;
+
+} SStatCounter, *PSStatCounter;
+
+void STAvUpdateIsrStatCounter(PSStatCounter pStatistic,
+ u8 byIsr0,
+ u8 byIsr1);
+
+void STAvUpdateRDStatCounter(PSStatCounter pStatistic,
+ u8 byRSR, u8 byNewRSR, u8 byRxSts,
+ u8 byRxRate, u8 * pbyBuffer,
+ unsigned int cbFrameLength);
+
+void STAvUpdateTDStatCounter(PSStatCounter pStatistic, u8 byPktNum,
+ u8 byRate, u8 byTSR);
+
+void
+STAvUpdate802_11Counter(
+ PSDot11Counters p802_11Counter,
+ PSStatCounter pStatistic,
+ u8 byRTSSuccess,
+ u8 byRTSFail,
+ u8 byACKFail,
+ u8 byFCSErr
+ );
+
+void STAvUpdateUSBCounter(PSUSBCounter pUsbCounter, int ntStatus);
+
+#endif /* __MIB_H__ */
diff --git a/drivers/staging/vt6656/michael.c b/drivers/staging/vt6656/michael.c
new file mode 100644
index 00000000..9a5a0b67
--- /dev/null
+++ b/drivers/staging/vt6656/michael.c
@@ -0,0 +1,167 @@
+/*
+ * 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 u8[] to u32 in a portable way
+ * s_vPutUINT32 - Convert from u32 to u8[] 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:
+ *
+ */
+
+#include "tmacro.h"
+#include "michael.h"
+
+/*
+ * static u32 s_dwGetUINT32(u8 * p); Get u32 from
+ * 4 bytes LSByte first
+ * static void s_vPutUINT32(u8* p, u32 val); Put u32 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(u32 dwK0, u32 dwK1);
+static void s_vAppendByte(u8 b); /* Add a single byte to the internal
+ * message */
+
+static u32 L, R; /* Current state */
+static u32 K0, K1; /* Key */
+static u32 M; /* Message accumulator (single word) */
+static unsigned int nBytesInM; /* # bytes in M */
+
+/*
+static u32 s_dwGetUINT32 (u8 * p)
+// Convert from u8[] to u32 in a portable way
+{
+ u32 res = 0;
+ unsigned int i;
+ for (i = 0; i < 4; i++)
+ res |= (*p++) << (8*i);
+ return res;
+}
+
+static void s_vPutUINT32(u8 *p, u32 val)
+// Convert from u32 to u8[] in a portable way
+{
+ unsigned int i;
+ for (i = 0; i < 4; i++) {
+ *p++ = (u8) (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(u32 dwK0, u32 dwK1)
+{
+ /* Set the key */
+ K0 = dwK0;
+ K1 = dwK1;
+ /* and reset the message */
+ s_vClear();
+}
+
+static void s_vAppendByte(u8 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(u32 dwK0, u32 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(u8 * src, unsigned int nBytes)
+{
+ /* This is simple */
+ while (nBytes > 0) {
+ s_vAppendByte(*src++);
+ nBytes--;
+ }
+}
+
+void MIC_vGetMIC(u32 * pdwL, u32 * pdwR)
+{
+ /* Append the minimum padding */
+ s_vAppendByte(0x5a);
+ s_vAppendByte(0);
+ s_vAppendByte(0);
+ s_vAppendByte(0);
+ s_vAppendByte(0);
+ /* and then zeroes until the length is a multiple of 4 */
+ while (nBytesInM != 0)
+ s_vAppendByte(0);
+ /* The s_vAppendByte function has already computed the result. */
+ *pdwL = L;
+ *pdwR = R;
+ /* Reset to the empty message. */
+ s_vClear();
+}
diff --git a/drivers/staging/vt6656/michael.h b/drivers/staging/vt6656/michael.h
new file mode 100644
index 00000000..9c69a426
--- /dev/null
+++ b/drivers/staging/vt6656/michael.h
@@ -0,0 +1,52 @@
+/*
+ * 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__
+
+#include <linux/types.h>
+
+void MIC_vInit(u32 dwK0, u32 dwK1);
+
+void MIC_vUnInit(void);
+
+// Append bytes to the message to be MICed
+void MIC_vAppend(u8 * src, unsigned int nBytes);
+
+// Get the MIC result. Destination should accept 8 bytes of result.
+// This also resets the message to empty.
+void MIC_vGetMIC(u32 * pdwL, u32 * pdwR);
+
+// Rotation functions on 32 bit values
+#define ROL32(A, n) \
+ (((A) << (n)) | (((A)>>(32-(n))) & ((1UL << (n)) - 1)))
+#define ROR32(A, n) ROL32((A), 32-(n))
+
+#endif /* __MICHAEL_H__ */
diff --git a/drivers/staging/vt6656/power.c b/drivers/staging/vt6656/power.c
new file mode 100644
index 00000000..edc8975b
--- /dev/null
+++ b/drivers/staging/vt6656/power.c
@@ -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: power.c
+ *
+ * Purpose: Handles 802.11 power management 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:
+ *
+ */
+
+#include "mac.h"
+#include "device.h"
+#include "wmgr.h"
+#include "power.h"
+#include "wcmd.h"
+#include "rxtx.h"
+#include "card.h"
+#include "control.h"
+#include "rndis.h"
+
+static int msglevel = MSG_LEVEL_INFO;
+
+/*
+ *
+ * Routine Description:
+ * Enable hw power saving functions
+ *
+ * Return Value:
+ * None.
+ *
+ */
+
+void PSvEnablePowerSaving(struct vnt_private *pDevice, u16 wListenInterval)
+{
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ u16 wAID = pMgmt->wCurrAID | BIT14 | BIT15;
+
+ /* set period of power up before TBTT */
+ MACvWriteWord(pDevice, MAC_REG_PWBT, C_PWBT);
+
+ if (pDevice->eOPMode != OP_MODE_ADHOC) {
+ /* set AID */
+ MACvWriteWord(pDevice, MAC_REG_AIDATIM, wAID);
+ } else {
+ /* set ATIM Window */
+ /* MACvWriteATIMW(pDevice->PortOffset, pMgmt->wCurrATIMWindow); */
+ }
+
+ /* Warren:06-18-2004,the sequence must follow PSEN->AUTOSLEEP->GO2DOZE */
+ /* enable power saving hw function */
+ MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_PSEN);
+
+ /* Set AutoSleep */
+ MACvRegBitsOn(pDevice, MAC_REG_PSCFG, PSCFG_AUTOSLEEP);
+
+ /* Warren:MUST turn on this once before turn on AUTOSLEEP ,or the AUTOSLEEP doesn't work */
+ MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_GO2DOZE);
+
+ if (wListenInterval >= 2) {
+
+ /* clear always listen beacon */
+ MACvRegBitsOff(pDevice, MAC_REG_PSCTL, PSCTL_ALBCN);
+
+ /* first time set listen next beacon */
+ MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_LNBCN);
+
+ pMgmt->wCountToWakeUp = wListenInterval;
+
+ } else {
+
+ /* always listen beacon */
+ MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_ALBCN);
+
+ pMgmt->wCountToWakeUp = 0;
+ }
+
+ pDevice->bEnablePSMode = true;
+
+ /* We don't send null pkt in ad hoc mode since beacon will handle this. */
+ if (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE)
+ PSbSendNullPacket(pDevice);
+
+ pDevice->bPWBitOn = true;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "PS:Power Saving Mode Enable...\n");
+}
+
+/*
+ *
+ * Routine Description:
+ * Disable hw power saving functions
+ *
+ * Return Value:
+ * None.
+ *
+ */
+
+void PSvDisablePowerSaving(struct vnt_private *pDevice)
+{
+
+ /* disable power saving hw function */
+ CONTROLnsRequestOut(pDevice, MESSAGE_TYPE_DISABLE_PS, 0,
+ 0, 0, NULL);
+
+ /* clear AutoSleep */
+ MACvRegBitsOff(pDevice, MAC_REG_PSCFG, PSCFG_AUTOSLEEP);
+
+ /* set always listen beacon */
+ MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_ALBCN);
+ pDevice->bEnablePSMode = false;
+
+ if (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE)
+ PSbSendNullPacket(pDevice);
+
+ pDevice->bPWBitOn = false;
+}
+
+/*
+ *
+ * Routine Description:
+ * Consider to power down when no more packets to tx or rx.
+ *
+ * Return Value:
+ * true, if power down success
+ * false, if fail
+ */
+
+int PSbConsiderPowerDown(struct vnt_private *pDevice, int bCheckRxDMA,
+ int bCheckCountToWakeUp)
+{
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ u8 byData;
+
+ /* check if already in Doze mode */
+ ControlvReadByte(pDevice, MESSAGE_REQUEST_MACREG,
+ MAC_REG_PSCTL, &byData);
+
+ if ((byData & PSCTL_PS) != 0)
+ return true;
+
+ if (pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) {
+ /* check if in TIM wake period */
+ if (pMgmt->bInTIMWake)
+ return false;
+ }
+
+ /* check scan state */
+ if (pDevice->bCmdRunning)
+ return false;
+
+ /* Tx Burst */
+ if (pDevice->bPSModeTxBurst)
+ return false;
+
+ /* Froce PSEN on */
+ MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_PSEN);
+
+ if (pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) {
+ if (bCheckCountToWakeUp && (pMgmt->wCountToWakeUp == 0
+ || pMgmt->wCountToWakeUp == 1)) {
+ return false;
+ }
+ }
+
+ pDevice->bPSRxBeacon = true;
+
+ /* no Tx, no Rx isr, now go to Doze */
+ MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_GO2DOZE);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Go to Doze ZZZZZZZZZZZZZZZ\n");
+ return true;
+}
+
+/*
+ *
+ * Routine Description:
+ * Send PS-POLL packet
+ *
+ * Return Value:
+ * None.
+ *
+ */
+
+void PSvSendPSPOLL(struct vnt_private *pDevice)
+{
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ struct vnt_tx_mgmt *pTxPacket = NULL;
+
+ memset(pMgmt->pbyPSPacketPool, 0, sizeof(struct vnt_tx_mgmt)
+ + WLAN_HDR_ADDR2_LEN);
+ pTxPacket = (struct vnt_tx_mgmt *)pMgmt->pbyPSPacketPool;
+ pTxPacket->p80211Header = (PUWLAN_80211HDR)((u8 *)pTxPacket
+ + sizeof(struct vnt_tx_mgmt));
+
+ 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;
+
+ /* log failure if sending failed */
+ if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send PS-Poll packet failed..\n");
+ }
+}
+
+/*
+ *
+ * Routine Description:
+ * Send NULL packet to AP for notification power state of STA
+ *
+ * Return Value:
+ * None.
+ *
+ */
+
+int PSbSendNullPacket(struct vnt_private *pDevice)
+{
+ struct vnt_tx_mgmt *pTxPacket = NULL;
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ u16 flags = 0;
+
+ if (pDevice->bLinkPass == false)
+ return false;
+
+ if ((pDevice->bEnablePSMode == false) &&
+ (pDevice->fTxDataInSleep == false)) {
+ return false;
+ }
+
+ memset(pMgmt->pbyPSPacketPool, 0, sizeof(struct vnt_tx_mgmt)
+ + WLAN_NULLDATA_FR_MAXLEN);
+ pTxPacket = (struct vnt_tx_mgmt *)pMgmt->pbyPSPacketPool;
+ pTxPacket->p80211Header = (PUWLAN_80211HDR)((u8 *)pTxPacket
+ + sizeof(struct vnt_tx_mgmt));
+
+ flags = WLAN_SET_FC_FTYPE(WLAN_TYPE_DATA) |
+ WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_NULL);
+
+ if (pDevice->bEnablePSMode)
+ flags |= WLAN_SET_FC_PWRMGT(1);
+ else
+ flags |= WLAN_SET_FC_PWRMGT(0);
+
+ pTxPacket->p80211Header->sA3.wFrameCtl = cpu_to_le16(flags);
+
+ if (pMgmt->eCurrMode != WMAC_MODE_IBSS_STA)
+ pTxPacket->p80211Header->sA3.wFrameCtl |= cpu_to_le16((u16)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;
+ /* log error if sending failed */
+ if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send Null Packet failed !\n");
+ return false;
+ }
+ return true;
+}
+
+/*
+ *
+ * Routine Description:
+ * Check if Next TBTT must wake up
+ *
+ * Return Value:
+ * None.
+ *
+ */
+
+int PSbIsNextTBTTWakeUp(struct vnt_private *pDevice)
+{
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ int bWakeUp = false;
+
+ if (pMgmt->wListenInterval >= 2) {
+ if (pMgmt->wCountToWakeUp == 0)
+ pMgmt->wCountToWakeUp = pMgmt->wListenInterval;
+
+ pMgmt->wCountToWakeUp--;
+
+ if (pMgmt->wCountToWakeUp == 1) {
+ /* Turn on wake up to listen next beacon */
+ MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_LNBCN);
+ pDevice->bPSRxBeacon = false;
+ bWakeUp = true;
+ } else if (!pDevice->bPSRxBeacon) {
+ /* Listen until RxBeacon */
+ MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_LNBCN);
+ }
+ }
+ return bWakeUp;
+}
+
diff --git a/drivers/staging/vt6656/power.h b/drivers/staging/vt6656/power.h
new file mode 100644
index 00000000..77835823
--- /dev/null
+++ b/drivers/staging/vt6656/power.h
@@ -0,0 +1,47 @@
+/*
+ * 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 management functions
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: July 17, 2002
+ *
+ */
+
+#ifndef __POWER_H__
+#define __POWER_H__
+
+#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
+
+/* PSDevice pDevice */
+/* PSDevice hDeviceContext */
+
+int PSbConsiderPowerDown(struct vnt_private *, int bCheckRxDMA,
+ int bCheckCountToWakeUp);
+void PSvDisablePowerSaving(struct vnt_private *);
+void PSvEnablePowerSaving(struct vnt_private *, u16 wListenInterval);
+void PSvSendPSPOLL(struct vnt_private *);
+int PSbSendNullPacket(struct vnt_private *);
+int PSbIsNextTBTTWakeUp(struct vnt_private *);
+
+#endif /* __POWER_H__ */
diff --git a/drivers/staging/vt6656/rc4.c b/drivers/staging/vt6656/rc4.c
new file mode 100644
index 00000000..2fd836f0
--- /dev/null
+++ b/drivers/staging/vt6656/rc4.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: rc4.c
+ *
+ * Purpose:
+ *
+ * Functions:
+ *
+ * Revision History:
+ *
+ * Author: Kyle Hsu
+ *
+ * Date: Sep 4, 2002
+ *
+ */
+
+#include "rc4.h"
+
+void rc4_init(PRC4Ext pRC4, u8 * pbyKey, unsigned int cbKey_len)
+{
+ unsigned int ust1, ust2;
+ unsigned int keyindex;
+ unsigned int stateindex;
+ u8 * pbyst;
+ unsigned int idx;
+
+ pbyst = pRC4->abystate;
+ pRC4->ux = 0;
+ pRC4->uy = 0;
+ for (idx = 0; idx < 256; idx++)
+ pbyst[idx] = (u8)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] = (u8)ust1;
+ pbyst[idx] = (u8)ust2;
+ if (++keyindex >= cbKey_len)
+ keyindex = 0;
+ }
+}
+
+unsigned int rc4_byte(PRC4Ext pRC4)
+{
+ unsigned int ux;
+ unsigned int uy;
+ unsigned int ustx, usty;
+ u8 * 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] = (u8)ustx;
+ pbyst[ux] = (u8)usty;
+
+ return pbyst[(ustx + usty) & 0xff];
+}
+
+void rc4_encrypt(PRC4Ext pRC4, u8 * pbyDest,
+ u8 * pbySrc, unsigned int cbData_len)
+{
+ unsigned int ii;
+ for (ii = 0; ii < cbData_len; ii++)
+ pbyDest[ii] = (u8)(pbySrc[ii] ^ rc4_byte(pRC4));
+}
diff --git a/drivers/staging/vt6656/rc4.h b/drivers/staging/vt6656/rc4.h
new file mode 100644
index 00000000..d376e1ad
--- /dev/null
+++ b/drivers/staging/vt6656/rc4.h
@@ -0,0 +1,46 @@
+/*
+ * 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__
+
+#include <linux/types.h>
+
+typedef struct {
+ unsigned int ux;
+ unsigned int uy;
+ u8 abystate[256];
+} RC4Ext, *PRC4Ext;
+
+void rc4_init(PRC4Ext pRC4, u8 * pbyKey, unsigned int cbKey_len);
+unsigned int rc4_byte(PRC4Ext pRC4);
+void rc4_encrypt(PRC4Ext pRC4, u8 * pbyDest, u8 * pbySrc,
+ unsigned int cbData_len);
+
+#endif /* __RC4_H__ */
diff --git a/drivers/staging/vt6656/rf.c b/drivers/staging/vt6656/rf.c
new file mode 100644
index 00000000..44cfe0b1
--- /dev/null
+++ b/drivers/staging/vt6656/rf.c
@@ -0,0 +1,1099 @@
+/*
+ * 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:
+ * IFRFbWriteEmbedded - Embedded write RF register via MAC
+ *
+ * Revision History:
+ *
+ */
+
+#include "mac.h"
+#include "rf.h"
+#include "baseband.h"
+#include "control.h"
+#include "rndis.h"
+#include "datarate.h"
+
+static int msglevel =MSG_LEVEL_INFO;
+//static int msglevel =MSG_LEVEL_DEBUG;
+#define BY_AL2230_REG_LEN 23 //24bit
+#define CB_AL2230_INIT_SEQ 15
+#define AL2230_PWR_IDX_LEN 64
+
+#define BY_AL7230_REG_LEN 23 //24bit
+#define CB_AL7230_INIT_SEQ 16
+#define AL7230_PWR_IDX_LEN 64
+
+//{{RobertYu:20051111
+#define BY_VT3226_REG_LEN 23
+#define CB_VT3226_INIT_SEQ 11
+#define VT3226_PWR_IDX_LEN 64
+//}}
+
+//{{RobertYu:20060609
+#define BY_VT3342_REG_LEN 23
+#define CB_VT3342_INIT_SEQ 13
+#define VT3342_PWR_IDX_LEN 64
+//}}
+
+u8 abyAL2230InitTable[CB_AL2230_INIT_SEQ][3] = {
+ {0x03, 0xF7, 0x90},
+ {0x03, 0x33, 0x31},
+ {0x01, 0xB8, 0x02},
+ {0x00, 0xFF, 0xF3},
+ {0x00, 0x05, 0xA4},
+ {0x0F, 0x4D, 0xC5}, //RobertYu:20060814
+ {0x08, 0x05, 0xB6},
+ {0x01, 0x47, 0xC7},
+ {0x00, 0x06, 0x88},
+ {0x04, 0x03, 0xB9},
+ {0x00, 0xDB, 0xBA},
+ {0x00, 0x09, 0x9B},
+ {0x0B, 0xDF, 0xFC},
+ {0x00, 0x00, 0x0D},
+ {0x00, 0x58, 0x0F}
+ };
+
+u8 abyAL2230ChannelTable0[CB_MAX_CHANNEL_24G][3] = {
+ {0x03, 0xF7, 0x90}, // channel = 1, Tf = 2412MHz
+ {0x03, 0xF7, 0x90}, // channel = 2, Tf = 2417MHz
+ {0x03, 0xE7, 0x90}, // channel = 3, Tf = 2422MHz
+ {0x03, 0xE7, 0x90}, // channel = 4, Tf = 2427MHz
+ {0x03, 0xF7, 0xA0}, // channel = 5, Tf = 2432MHz
+ {0x03, 0xF7, 0xA0}, // channel = 6, Tf = 2437MHz
+ {0x03, 0xE7, 0xA0}, // channel = 7, Tf = 2442MHz
+ {0x03, 0xE7, 0xA0}, // channel = 8, Tf = 2447MHz
+ {0x03, 0xF7, 0xB0}, // channel = 9, Tf = 2452MHz
+ {0x03, 0xF7, 0xB0}, // channel = 10, Tf = 2457MHz
+ {0x03, 0xE7, 0xB0}, // channel = 11, Tf = 2462MHz
+ {0x03, 0xE7, 0xB0}, // channel = 12, Tf = 2467MHz
+ {0x03, 0xF7, 0xC0}, // channel = 13, Tf = 2472MHz
+ {0x03, 0xE7, 0xC0} // channel = 14, Tf = 2412M
+ };
+
+u8 abyAL2230ChannelTable1[CB_MAX_CHANNEL_24G][3] = {
+ {0x03, 0x33, 0x31}, // channel = 1, Tf = 2412MHz
+ {0x0B, 0x33, 0x31}, // channel = 2, Tf = 2417MHz
+ {0x03, 0x33, 0x31}, // channel = 3, Tf = 2422MHz
+ {0x0B, 0x33, 0x31}, // channel = 4, Tf = 2427MHz
+ {0x03, 0x33, 0x31}, // channel = 5, Tf = 2432MHz
+ {0x0B, 0x33, 0x31}, // channel = 6, Tf = 2437MHz
+ {0x03, 0x33, 0x31}, // channel = 7, Tf = 2442MHz
+ {0x0B, 0x33, 0x31}, // channel = 8, Tf = 2447MHz
+ {0x03, 0x33, 0x31}, // channel = 9, Tf = 2452MHz
+ {0x0B, 0x33, 0x31}, // channel = 10, Tf = 2457MHz
+ {0x03, 0x33, 0x31}, // channel = 11, Tf = 2462MHz
+ {0x0B, 0x33, 0x31}, // channel = 12, Tf = 2467MHz
+ {0x03, 0x33, 0x31}, // channel = 13, Tf = 2472MHz
+ {0x06, 0x66, 0x61} // channel = 14, Tf = 2412M
+ };
+
+// 40MHz reference frequency
+// Need to Pull PLLON(PE3) low when writing channel registers through 3-wire.
+u8 abyAL7230InitTable[CB_AL7230_INIT_SEQ][3] = {
+ {0x20, 0x37, 0x90}, // Channel1 // Need modify for 11a
+ {0x13, 0x33, 0x31}, // Channel1 // Need modify for 11a
+ {0x84, 0x1F, 0xF2}, // Need modify for 11a: 451FE2
+ {0x3F, 0xDF, 0xA3}, // Need modify for 11a: 5FDFA3
+ {0x7F, 0xD7, 0x84}, // 11b/g // Need modify for 11a
+ //0x802B4500+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11a: 8D1B45
+ // RoberYu:20050113, Rev0.47 Regsiter Setting Guide
+ {0x80, 0x2B, 0x55}, // Need modify for 11a: 8D1B55
+ {0x56, 0xAF, 0x36},
+ {0xCE, 0x02, 0x07}, // Need modify for 11a: 860207
+ {0x6E, 0xBC, 0x98},
+ {0x22, 0x1B, 0xB9},
+ {0xE0, 0x00, 0x0A}, // Need modify for 11a: E0600A
+ {0x08, 0x03, 0x1B}, // init 0x080B1B00 => 0x080F1B00 for 3 wire control TxGain(D10)
+ //0x00093C00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11a: 00143C
+ // RoberYu:20050113, Rev0.47 Regsiter Setting Guide
+ {0x00, 0x0A, 0x3C}, // Need modify for 11a: 00143C
+ {0xFF, 0xFF, 0xFD},
+ {0x00, 0x00, 0x0E},
+ {0x1A, 0xBA, 0x8F} // Need modify for 11a: 12BACF
+ };
+
+u8 abyAL7230InitTableAMode[CB_AL7230_INIT_SEQ][3] = {
+ {0x2F, 0xF5, 0x20}, // Channel184 // Need modify for 11b/g
+ {0x00, 0x00, 0x01}, // Channel184 // Need modify for 11b/g
+ {0x45, 0x1F, 0xE2}, // Need modify for 11b/g
+ {0x5F, 0xDF, 0xA3}, // Need modify for 11b/g
+ {0x6F, 0xD7, 0x84}, // 11a // Need modify for 11b/g
+ {0x85, 0x3F, 0x55}, // Need modify for 11b/g, RoberYu:20050113
+ {0x56, 0xAF, 0x36},
+ {0xCE, 0x02, 0x07}, // Need modify for 11b/g
+ {0x6E, 0xBC, 0x98},
+ {0x22, 0x1B, 0xB9},
+ {0xE0, 0x60, 0x0A}, // Need modify for 11b/g
+ {0x08, 0x03, 0x1B}, // init 0x080B1B00 => 0x080F1B00 for 3 wire control TxGain(D10)
+ {0x00, 0x14, 0x7C}, // Need modify for 11b/g
+ {0xFF, 0xFF, 0xFD},
+ {0x00, 0x00, 0x0E},
+ {0x12, 0xBA, 0xCF} // Need modify for 11b/g
+ };
+
+u8 abyAL7230ChannelTable0[CB_MAX_CHANNEL][3] = {
+ {0x20, 0x37, 0x90}, // channel = 1, Tf = 2412MHz
+ {0x20, 0x37, 0x90}, // channel = 2, Tf = 2417MHz
+ {0x20, 0x37, 0x90}, // channel = 3, Tf = 2422MHz
+ {0x20, 0x37, 0x90}, // channel = 4, Tf = 2427MHz
+ {0x20, 0x37, 0xA0}, // channel = 5, Tf = 2432MHz
+ {0x20, 0x37, 0xA0}, // channel = 6, Tf = 2437MHz
+ {0x20, 0x37, 0xA0}, // channel = 7, Tf = 2442MHz
+ {0x20, 0x37, 0xA0}, // channel = 8, Tf = 2447MHz //RobertYu: 20050218, update for APNode 0.49
+ {0x20, 0x37, 0xB0}, // channel = 9, Tf = 2452MHz //RobertYu: 20050218, update for APNode 0.49
+ {0x20, 0x37, 0xB0}, // channel = 10, Tf = 2457MHz //RobertYu: 20050218, update for APNode 0.49
+ {0x20, 0x37, 0xB0}, // channel = 11, Tf = 2462MHz //RobertYu: 20050218, update for APNode 0.49
+ {0x20, 0x37, 0xB0}, // channel = 12, Tf = 2467MHz //RobertYu: 20050218, update for APNode 0.49
+ {0x20, 0x37, 0xC0}, // channel = 13, Tf = 2472MHz //RobertYu: 20050218, update for APNode 0.49
+ {0x20, 0x37, 0xC0}, // channel = 14, Tf = 2484MHz
+
+ // 4.9G => Ch 183, 184, 185, 187, 188, 189, 192, 196 (Value:15 ~ 22)
+ {0x0F, 0xF5, 0x20}, // channel = 183, Tf = 4915MHz (15)
+ {0x2F, 0xF5, 0x20}, // channel = 184, Tf = 4920MHz (16)
+ {0x0F, 0xF5, 0x20}, // channel = 185, Tf = 4925MHz (17)
+ {0x0F, 0xF5, 0x20}, // channel = 187, Tf = 4935MHz (18)
+ {0x2F, 0xF5, 0x20}, // channel = 188, Tf = 4940MHz (19)
+ {0x0F, 0xF5, 0x20}, // channel = 189, Tf = 4945MHz (20)
+ {0x2F, 0xF5, 0x30}, // channel = 192, Tf = 4960MHz (21)
+ {0x2F, 0xF5, 0x30}, // channel = 196, Tf = 4980MHz (22)
+
+ // 5G => Ch 7, 8, 9, 11, 12, 16, 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64,
+ // 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165 (Value 23 ~ 56)
+
+ {0x0F, 0xF5, 0x40}, // channel = 7, Tf = 5035MHz (23)
+ {0x2F, 0xF5, 0x40}, // channel = 8, Tf = 5040MHz (24)
+ {0x0F, 0xF5, 0x40}, // channel = 9, Tf = 5045MHz (25)
+ {0x0F, 0xF5, 0x40}, // channel = 11, Tf = 5055MHz (26)
+ {0x2F, 0xF5, 0x40}, // channel = 12, Tf = 5060MHz (27)
+ {0x2F, 0xF5, 0x50}, // channel = 16, Tf = 5080MHz (28)
+ {0x2F, 0xF5, 0x60}, // channel = 34, Tf = 5170MHz (29)
+ {0x2F, 0xF5, 0x60}, // channel = 36, Tf = 5180MHz (30)
+ {0x2F, 0xF5, 0x70}, // channel = 38, Tf = 5190MHz (31) //RobertYu: 20050218, update for APNode 0.49
+ {0x2F, 0xF5, 0x70}, // channel = 40, Tf = 5200MHz (32)
+ {0x2F, 0xF5, 0x70}, // channel = 42, Tf = 5210MHz (33)
+ {0x2F, 0xF5, 0x70}, // channel = 44, Tf = 5220MHz (34)
+ {0x2F, 0xF5, 0x70}, // channel = 46, Tf = 5230MHz (35)
+ {0x2F, 0xF5, 0x70}, // channel = 48, Tf = 5240MHz (36)
+ {0x2F, 0xF5, 0x80}, // channel = 52, Tf = 5260MHz (37)
+ {0x2F, 0xF5, 0x80}, // channel = 56, Tf = 5280MHz (38)
+ {0x2F, 0xF5, 0x80}, // channel = 60, Tf = 5300MHz (39)
+ {0x2F, 0xF5, 0x90}, // channel = 64, Tf = 5320MHz (40)
+
+ {0x2F, 0xF5, 0xC0}, // channel = 100, Tf = 5500MHz (41)
+ {0x2F, 0xF5, 0xC0}, // channel = 104, Tf = 5520MHz (42)
+ {0x2F, 0xF5, 0xC0}, // channel = 108, Tf = 5540MHz (43)
+ {0x2F, 0xF5, 0xD0}, // channel = 112, Tf = 5560MHz (44)
+ {0x2F, 0xF5, 0xD0}, // channel = 116, Tf = 5580MHz (45)
+ {0x2F, 0xF5, 0xD0}, // channel = 120, Tf = 5600MHz (46)
+ {0x2F, 0xF5, 0xE0}, // channel = 124, Tf = 5620MHz (47)
+ {0x2F, 0xF5, 0xE0}, // channel = 128, Tf = 5640MHz (48)
+ {0x2F, 0xF5, 0xE0}, // channel = 132, Tf = 5660MHz (49)
+ {0x2F, 0xF5, 0xF0}, // channel = 136, Tf = 5680MHz (50)
+ {0x2F, 0xF5, 0xF0}, // channel = 140, Tf = 5700MHz (51)
+ {0x2F, 0xF6, 0x00}, // channel = 149, Tf = 5745MHz (52)
+ {0x2F, 0xF6, 0x00}, // channel = 153, Tf = 5765MHz (53)
+ {0x2F, 0xF6, 0x00}, // channel = 157, Tf = 5785MHz (54)
+ {0x2F, 0xF6, 0x10}, // channel = 161, Tf = 5805MHz (55)
+ {0x2F, 0xF6, 0x10} // channel = 165, Tf = 5825MHz (56)
+ };
+
+u8 abyAL7230ChannelTable1[CB_MAX_CHANNEL][3] = {
+ {0x13, 0x33, 0x31}, // channel = 1, Tf = 2412MHz
+ {0x1B, 0x33, 0x31}, // channel = 2, Tf = 2417MHz
+ {0x03, 0x33, 0x31}, // channel = 3, Tf = 2422MHz
+ {0x0B, 0x33, 0x31}, // channel = 4, Tf = 2427MHz
+ {0x13, 0x33, 0x31}, // channel = 5, Tf = 2432MHz
+ {0x1B, 0x33, 0x31}, // channel = 6, Tf = 2437MHz
+ {0x03, 0x33, 0x31}, // channel = 7, Tf = 2442MHz
+ {0x0B, 0x33, 0x31}, // channel = 8, Tf = 2447MHz
+ {0x13, 0x33, 0x31}, // channel = 9, Tf = 2452MHz
+ {0x1B, 0x33, 0x31}, // channel = 10, Tf = 2457MHz
+ {0x03, 0x33, 0x31}, // channel = 11, Tf = 2462MHz
+ {0x0B, 0x33, 0x31}, // channel = 12, Tf = 2467MHz
+ {0x13, 0x33, 0x31}, // channel = 13, Tf = 2472MHz
+ {0x06, 0x66, 0x61}, // channel = 14, Tf = 2484MHz
+
+ // 4.9G => Ch 183, 184, 185, 187, 188, 189, 192, 196 (Value:15 ~ 22)
+ {0x1D, 0x55, 0x51}, // channel = 183, Tf = 4915MHz (15)
+ {0x00, 0x00, 0x01}, // channel = 184, Tf = 4920MHz (16)
+ {0x02, 0xAA, 0xA1}, // channel = 185, Tf = 4925MHz (17)
+ {0x08, 0x00, 0x01}, // channel = 187, Tf = 4935MHz (18)
+ {0x0A, 0xAA, 0xA1}, // channel = 188, Tf = 4940MHz (19)
+ {0x0D, 0x55, 0x51}, // channel = 189, Tf = 4945MHz (20)
+ {0x15, 0x55, 0x51}, // channel = 192, Tf = 4960MHz (21)
+ {0x00, 0x00, 0x01}, // channel = 196, Tf = 4980MHz (22)
+
+ // 5G => Ch 7, 8, 9, 11, 12, 16, 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64,
+ // 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165 (Value 23 ~ 56)
+ {0x1D, 0x55, 0x51}, // channel = 7, Tf = 5035MHz (23)
+ {0x00, 0x00, 0x01}, // channel = 8, Tf = 5040MHz (24)
+ {0x02, 0xAA, 0xA1}, // channel = 9, Tf = 5045MHz (25)
+ {0x08, 0x00, 0x01}, // channel = 11, Tf = 5055MHz (26)
+ {0x0A, 0xAA, 0xA1}, // channel = 12, Tf = 5060MHz (27)
+ {0x15, 0x55, 0x51}, // channel = 16, Tf = 5080MHz (28)
+ {0x05, 0x55, 0x51}, // channel = 34, Tf = 5170MHz (29)
+ {0x0A, 0xAA, 0xA1}, // channel = 36, Tf = 5180MHz (30)
+ {0x10, 0x00, 0x01}, // channel = 38, Tf = 5190MHz (31)
+ {0x15, 0x55, 0x51}, // channel = 40, Tf = 5200MHz (32)
+ {0x1A, 0xAA, 0xA1}, // channel = 42, Tf = 5210MHz (33)
+ {0x00, 0x00, 0x01}, // channel = 44, Tf = 5220MHz (34)
+ {0x05, 0x55, 0x51}, // channel = 46, Tf = 5230MHz (35)
+ {0x0A, 0xAA, 0xA1}, // channel = 48, Tf = 5240MHz (36)
+ {0x15, 0x55, 0x51}, // channel = 52, Tf = 5260MHz (37)
+ {0x00, 0x00, 0x01}, // channel = 56, Tf = 5280MHz (38)
+ {0x0A, 0xAA, 0xA1}, // channel = 60, Tf = 5300MHz (39)
+ {0x15, 0x55, 0x51}, // channel = 64, Tf = 5320MHz (40)
+ {0x15, 0x55, 0x51}, // channel = 100, Tf = 5500MHz (41)
+ {0x00, 0x00, 0x01}, // channel = 104, Tf = 5520MHz (42)
+ {0x0A, 0xAA, 0xA1}, // channel = 108, Tf = 5540MHz (43)
+ {0x15, 0x55, 0x51}, // channel = 112, Tf = 5560MHz (44)
+ {0x00, 0x00, 0x01}, // channel = 116, Tf = 5580MHz (45)
+ {0x0A, 0xAA, 0xA1}, // channel = 120, Tf = 5600MHz (46)
+ {0x15, 0x55, 0x51}, // channel = 124, Tf = 5620MHz (47)
+ {0x00, 0x00, 0x01}, // channel = 128, Tf = 5640MHz (48)
+ {0x0A, 0xAA, 0xA1}, // channel = 132, Tf = 5660MHz (49)
+ {0x15, 0x55, 0x51}, // channel = 136, Tf = 5680MHz (50)
+ {0x00, 0x00, 0x01}, // channel = 140, Tf = 5700MHz (51)
+ {0x18, 0x00, 0x01}, // channel = 149, Tf = 5745MHz (52)
+ {0x02, 0xAA, 0xA1}, // channel = 153, Tf = 5765MHz (53)
+ {0x0D, 0x55, 0x51}, // channel = 157, Tf = 5785MHz (54)
+ {0x18, 0x00, 0x01}, // channel = 161, Tf = 5805MHz (55)
+ {0x02, 0xAA, 0xB1} // channel = 165, Tf = 5825MHz (56)
+ };
+
+u8 abyAL7230ChannelTable2[CB_MAX_CHANNEL][3] = {
+ {0x7F, 0xD7, 0x84}, // channel = 1, Tf = 2412MHz
+ {0x7F, 0xD7, 0x84}, // channel = 2, Tf = 2417MHz
+ {0x7F, 0xD7, 0x84}, // channel = 3, Tf = 2422MHz
+ {0x7F, 0xD7, 0x84}, // channel = 4, Tf = 2427MHz
+ {0x7F, 0xD7, 0x84}, // channel = 5, Tf = 2432MHz
+ {0x7F, 0xD7, 0x84}, // channel = 6, Tf = 2437MHz
+ {0x7F, 0xD7, 0x84}, // channel = 7, Tf = 2442MHz
+ {0x7F, 0xD7, 0x84}, // channel = 8, Tf = 2447MHz
+ {0x7F, 0xD7, 0x84}, // channel = 9, Tf = 2452MHz
+ {0x7F, 0xD7, 0x84}, // channel = 10, Tf = 2457MHz
+ {0x7F, 0xD7, 0x84}, // channel = 11, Tf = 2462MHz
+ {0x7F, 0xD7, 0x84}, // channel = 12, Tf = 2467MHz
+ {0x7F, 0xD7, 0x84}, // channel = 13, Tf = 2472MHz
+ {0x7F, 0xD7, 0x84}, // channel = 14, Tf = 2484MHz
+
+ // 4.9G => Ch 183, 184, 185, 187, 188, 189, 192, 196 (Value:15 ~ 22)
+ {0x7F, 0xD7, 0x84}, // channel = 183, Tf = 4915MHz (15)
+ {0x6F, 0xD7, 0x84}, // channel = 184, Tf = 4920MHz (16)
+ {0x7F, 0xD7, 0x84}, // channel = 185, Tf = 4925MHz (17)
+ {0x7F, 0xD7, 0x84}, // channel = 187, Tf = 4935MHz (18)
+ {0x7F, 0xD7, 0x84}, // channel = 188, Tf = 4940MHz (19)
+ {0x7F, 0xD7, 0x84}, // channel = 189, Tf = 4945MHz (20)
+ {0x7F, 0xD7, 0x84}, // channel = 192, Tf = 4960MHz (21)
+ {0x6F, 0xD7, 0x84}, // channel = 196, Tf = 4980MHz (22)
+
+ // 5G => Ch 7, 8, 9, 11, 12, 16, 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64,
+ // 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165 (Value 23 ~ 56)
+ {0x7F, 0xD7, 0x84}, // channel = 7, Tf = 5035MHz (23)
+ {0x6F, 0xD7, 0x84}, // channel = 8, Tf = 5040MHz (24)
+ {0x7F, 0xD7, 0x84}, // channel = 9, Tf = 5045MHz (25)
+ {0x7F, 0xD7, 0x84}, // channel = 11, Tf = 5055MHz (26)
+ {0x7F, 0xD7, 0x84}, // channel = 12, Tf = 5060MHz (27)
+ {0x7F, 0xD7, 0x84}, // channel = 16, Tf = 5080MHz (28)
+ {0x7F, 0xD7, 0x84}, // channel = 34, Tf = 5170MHz (29)
+ {0x7F, 0xD7, 0x84}, // channel = 36, Tf = 5180MHz (30)
+ {0x7F, 0xD7, 0x84}, // channel = 38, Tf = 5190MHz (31)
+ {0x7F, 0xD7, 0x84}, // channel = 40, Tf = 5200MHz (32)
+ {0x7F, 0xD7, 0x84}, // channel = 42, Tf = 5210MHz (33)
+ {0x6F, 0xD7, 0x84}, // channel = 44, Tf = 5220MHz (34)
+ {0x7F, 0xD7, 0x84}, // channel = 46, Tf = 5230MHz (35)
+ {0x7F, 0xD7, 0x84}, // channel = 48, Tf = 5240MHz (36)
+ {0x7F, 0xD7, 0x84}, // channel = 52, Tf = 5260MHz (37)
+ {0x6F, 0xD7, 0x84}, // channel = 56, Tf = 5280MHz (38)
+ {0x7F, 0xD7, 0x84}, // channel = 60, Tf = 5300MHz (39)
+ {0x7F, 0xD7, 0x84}, // channel = 64, Tf = 5320MHz (40)
+ {0x7F, 0xD7, 0x84}, // channel = 100, Tf = 5500MHz (41)
+ {0x6F, 0xD7, 0x84}, // channel = 104, Tf = 5520MHz (42)
+ {0x7F, 0xD7, 0x84}, // channel = 108, Tf = 5540MHz (43)
+ {0x7F, 0xD7, 0x84}, // channel = 112, Tf = 5560MHz (44)
+ {0x6F, 0xD7, 0x84}, // channel = 116, Tf = 5580MHz (45)
+ {0x7F, 0xD7, 0x84}, // channel = 120, Tf = 5600MHz (46)
+ {0x7F, 0xD7, 0x84}, // channel = 124, Tf = 5620MHz (47)
+ {0x6F, 0xD7, 0x84}, // channel = 128, Tf = 5640MHz (48)
+ {0x7F, 0xD7, 0x84}, // channel = 132, Tf = 5660MHz (49)
+ {0x7F, 0xD7, 0x84}, // channel = 136, Tf = 5680MHz (50)
+ {0x6F, 0xD7, 0x84}, // channel = 140, Tf = 5700MHz (51)
+ {0x7F, 0xD7, 0x84}, // channel = 149, Tf = 5745MHz (52)
+ {0x7F, 0xD7, 0x84}, // channel = 153, Tf = 5765MHz (53)
+ {0x7F, 0xD7, 0x84}, // channel = 157, Tf = 5785MHz (54)
+ {0x7F, 0xD7, 0x84}, // channel = 161, Tf = 5805MHz (55)
+ {0x7F, 0xD7, 0x84} // channel = 165, Tf = 5825MHz (56)
+ };
+
+///{{RobertYu:20051111
+u8 abyVT3226_InitTable[CB_VT3226_INIT_SEQ][3] = {
+ {0x03, 0xFF, 0x80},
+ {0x02, 0x82, 0xA1},
+ {0x03, 0xC6, 0xA2},
+ {0x01, 0x97, 0x93},
+ {0x03, 0x66, 0x64},
+ {0x00, 0x61, 0xA5},
+ {0x01, 0x7B, 0xD6},
+ {0x00, 0x80, 0x17},
+ {0x03, 0xF8, 0x08},
+ {0x00, 0x02, 0x39}, //RobertYu:20051116
+ {0x02, 0x00, 0x2A}
+ };
+
+u8 abyVT3226D0_InitTable[CB_VT3226_INIT_SEQ][3] = {
+ {0x03, 0xFF, 0x80},
+ {0x03, 0x02, 0x21}, //RobertYu:20060327
+ {0x03, 0xC6, 0xA2},
+ {0x01, 0x97, 0x93},
+ {0x03, 0x66, 0x64},
+ {0x00, 0x71, 0xA5}, //RobertYu:20060103
+ {0x01, 0x15, 0xC6}, //RobertYu:20060420
+ {0x01, 0x2E, 0x07}, //RobertYu:20060420
+ {0x00, 0x58, 0x08}, //RobertYu:20060111
+ {0x00, 0x02, 0x79}, //RobertYu:20060420
+ {0x02, 0x01, 0xAA} //RobertYu:20060523
+ };
+
+u8 abyVT3226_ChannelTable0[CB_MAX_CHANNEL_24G][3] = {
+ {0x01, 0x97, 0x83}, // channel = 1, Tf = 2412MHz
+ {0x01, 0x97, 0x83}, // channel = 2, Tf = 2417MHz
+ {0x01, 0x97, 0x93}, // channel = 3, Tf = 2422MHz
+ {0x01, 0x97, 0x93}, // channel = 4, Tf = 2427MHz
+ {0x01, 0x97, 0x93}, // channel = 5, Tf = 2432MHz
+ {0x01, 0x97, 0x93}, // channel = 6, Tf = 2437MHz
+ {0x01, 0x97, 0xA3}, // channel = 7, Tf = 2442MHz
+ {0x01, 0x97, 0xA3}, // channel = 8, Tf = 2447MHz
+ {0x01, 0x97, 0xA3}, // channel = 9, Tf = 2452MHz
+ {0x01, 0x97, 0xA3}, // channel = 10, Tf = 2457MHz
+ {0x01, 0x97, 0xB3}, // channel = 11, Tf = 2462MHz
+ {0x01, 0x97, 0xB3}, // channel = 12, Tf = 2467MHz
+ {0x01, 0x97, 0xB3}, // channel = 13, Tf = 2472MHz
+ {0x03, 0x37, 0xC3} // channel = 14, Tf = 2484MHz
+ };
+
+u8 abyVT3226_ChannelTable1[CB_MAX_CHANNEL_24G][3] = {
+ {0x02, 0x66, 0x64}, // channel = 1, Tf = 2412MHz
+ {0x03, 0x66, 0x64}, // channel = 2, Tf = 2417MHz
+ {0x00, 0x66, 0x64}, // channel = 3, Tf = 2422MHz
+ {0x01, 0x66, 0x64}, // channel = 4, Tf = 2427MHz
+ {0x02, 0x66, 0x64}, // channel = 5, Tf = 2432MHz
+ {0x03, 0x66, 0x64}, // channel = 6, Tf = 2437MHz
+ {0x00, 0x66, 0x64}, // channel = 7, Tf = 2442MHz
+ {0x01, 0x66, 0x64}, // channel = 8, Tf = 2447MHz
+ {0x02, 0x66, 0x64}, // channel = 9, Tf = 2452MHz
+ {0x03, 0x66, 0x64}, // channel = 10, Tf = 2457MHz
+ {0x00, 0x66, 0x64}, // channel = 11, Tf = 2462MHz
+ {0x01, 0x66, 0x64}, // channel = 12, Tf = 2467MHz
+ {0x02, 0x66, 0x64}, // channel = 13, Tf = 2472MHz
+ {0x00, 0xCC, 0xC4} // channel = 14, Tf = 2484MHz
+ };
+///}}RobertYu
+
+//{{RobertYu:20060502, TWIF 1.14, LO Current for 11b mode
+u32 dwVT3226D0LoCurrentTable[CB_MAX_CHANNEL_24G] = {
+ 0x0135C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 1, Tf = 2412MHz
+ 0x0135C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 2, Tf = 2417MHz
+ 0x0235C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 3, Tf = 2422MHz
+ 0x0235C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 4, Tf = 2427MHz
+ 0x0235C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 5, Tf = 2432MHz
+ 0x0335C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 6, Tf = 2437MHz
+ 0x0335C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 7, Tf = 2442MHz
+ 0x0335C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 8, Tf = 2447MHz
+ 0x0335C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 9, Tf = 2452MHz
+ 0x0335C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 10, Tf = 2457MHz
+ 0x0335C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 11, Tf = 2462MHz
+ 0x0335C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 12, Tf = 2467MHz
+ 0x0335C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 13, Tf = 2472MHz
+ 0x0135C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW // channel = 14, Tf = 2484MHz
+};
+//}}
+
+//{{RobertYu:20060609
+u8 abyVT3342A0_InitTable[CB_VT3342_INIT_SEQ][3] = { /* 11b/g mode */
+ {0x03, 0xFF, 0x80}, //update for mode//
+ {0x02, 0x08, 0x81},
+ {0x00, 0xC6, 0x02},
+ {0x03, 0xC5, 0x13}, // channel6
+ {0x00, 0xEE, 0xE4}, // channel6
+ {0x00, 0x71, 0xA5},
+ {0x01, 0x75, 0x46},
+ {0x01, 0x40, 0x27},
+ {0x01, 0x54, 0x08},
+ {0x00, 0x01, 0x69},
+ {0x02, 0x00, 0xAA},
+ {0x00, 0x08, 0xCB},
+ {0x01, 0x70, 0x0C}
+ };
+
+ //11b/g mode: 0x03, 0xFF, 0x80,
+ //11a mode: 0x03, 0xFF, 0xC0,
+
+ // channel44, 5220MHz 0x00C402
+ // channel56, 5280MHz 0x00C402 for disable Frac
+ // other channels 0x00C602
+
+u8 abyVT3342_ChannelTable0[CB_MAX_CHANNEL][3] = {
+ {0x02, 0x05, 0x03}, // channel = 1, Tf = 2412MHz
+ {0x01, 0x15, 0x03}, // channel = 2, Tf = 2417MHz
+ {0x03, 0xC5, 0x03}, // channel = 3, Tf = 2422MHz
+ {0x02, 0x65, 0x03}, // channel = 4, Tf = 2427MHz
+ {0x01, 0x15, 0x13}, // channel = 5, Tf = 2432MHz
+ {0x03, 0xC5, 0x13}, // channel = 6, Tf = 2437MHz
+ {0x02, 0x05, 0x13}, // channel = 7, Tf = 2442MHz
+ {0x01, 0x15, 0x13}, // channel = 8, Tf = 2447MHz
+ {0x03, 0xC5, 0x13}, // channel = 9, Tf = 2452MHz
+ {0x02, 0x65, 0x13}, // channel = 10, Tf = 2457MHz
+ {0x01, 0x15, 0x23}, // channel = 11, Tf = 2462MHz
+ {0x03, 0xC5, 0x23}, // channel = 12, Tf = 2467MHz
+ {0x02, 0x05, 0x23}, // channel = 13, Tf = 2472MHz
+ {0x00, 0xD5, 0x23}, // channel = 14, Tf = 2484MHz
+
+ // 4.9G => Ch 183, 184, 185, 187, 188, 189, 192, 196 (Value:15 ~ 22)
+ {0x01, 0x15, 0x13}, // channel = 183, Tf = 4915MHz (15), TBD
+ {0x01, 0x15, 0x13}, // channel = 184, Tf = 4920MHz (16), TBD
+ {0x01, 0x15, 0x13}, // channel = 185, Tf = 4925MHz (17), TBD
+ {0x01, 0x15, 0x13}, // channel = 187, Tf = 4935MHz (18), TBD
+ {0x01, 0x15, 0x13}, // channel = 188, Tf = 4940MHz (19), TBD
+ {0x01, 0x15, 0x13}, // channel = 189, Tf = 4945MHz (20), TBD
+ {0x01, 0x15, 0x13}, // channel = 192, Tf = 4960MHz (21), TBD
+ {0x01, 0x15, 0x13}, // channel = 196, Tf = 4980MHz (22), TBD
+
+ // 5G => Ch 7, 8, 9, 11, 12, 16, 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64,
+ // 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165 (Value 23 ~ 56)
+ {0x01, 0x15, 0x13}, // channel = 7, Tf = 5035MHz (23), TBD
+ {0x01, 0x15, 0x13}, // channel = 8, Tf = 5040MHz (24), TBD
+ {0x01, 0x15, 0x13}, // channel = 9, Tf = 5045MHz (25), TBD
+ {0x01, 0x15, 0x13}, // channel = 11, Tf = 5055MHz (26), TBD
+ {0x01, 0x15, 0x13}, // channel = 12, Tf = 5060MHz (27), TBD
+ {0x01, 0x15, 0x13}, // channel = 16, Tf = 5080MHz (28), TBD
+ {0x01, 0x15, 0x13}, // channel = 34, Tf = 5170MHz (29), TBD
+ {0x01, 0x55, 0x63}, // channel = 36, Tf = 5180MHz (30)
+ {0x01, 0x55, 0x63}, // channel = 38, Tf = 5190MHz (31), TBD
+ {0x02, 0xA5, 0x63}, // channel = 40, Tf = 5200MHz (32)
+ {0x02, 0xA5, 0x63}, // channel = 42, Tf = 5210MHz (33), TBD
+ {0x00, 0x05, 0x73}, // channel = 44, Tf = 5220MHz (34)
+ {0x00, 0x05, 0x73}, // channel = 46, Tf = 5230MHz (35), TBD
+ {0x01, 0x55, 0x73}, // channel = 48, Tf = 5240MHz (36)
+ {0x02, 0xA5, 0x73}, // channel = 52, Tf = 5260MHz (37)
+ {0x00, 0x05, 0x83}, // channel = 56, Tf = 5280MHz (38)
+ {0x01, 0x55, 0x83}, // channel = 60, Tf = 5300MHz (39)
+ {0x02, 0xA5, 0x83}, // channel = 64, Tf = 5320MHz (40)
+
+ {0x02, 0xA5, 0x83}, // channel = 100, Tf = 5500MHz (41), TBD
+ {0x02, 0xA5, 0x83}, // channel = 104, Tf = 5520MHz (42), TBD
+ {0x02, 0xA5, 0x83}, // channel = 108, Tf = 5540MHz (43), TBD
+ {0x02, 0xA5, 0x83}, // channel = 112, Tf = 5560MHz (44), TBD
+ {0x02, 0xA5, 0x83}, // channel = 116, Tf = 5580MHz (45), TBD
+ {0x02, 0xA5, 0x83}, // channel = 120, Tf = 5600MHz (46), TBD
+ {0x02, 0xA5, 0x83}, // channel = 124, Tf = 5620MHz (47), TBD
+ {0x02, 0xA5, 0x83}, // channel = 128, Tf = 5640MHz (48), TBD
+ {0x02, 0xA5, 0x83}, // channel = 132, Tf = 5660MHz (49), TBD
+ {0x02, 0xA5, 0x83}, // channel = 136, Tf = 5680MHz (50), TBD
+ {0x02, 0xA5, 0x83}, // channel = 140, Tf = 5700MHz (51), TBD
+
+ {0x00, 0x05, 0xF3}, // channel = 149, Tf = 5745MHz (52)
+ {0x01, 0x56, 0x03}, // channel = 153, Tf = 5765MHz (53)
+ {0x02, 0xA6, 0x03}, // channel = 157, Tf = 5785MHz (54)
+ {0x00, 0x06, 0x03}, // channel = 161, Tf = 5805MHz (55)
+ {0x00, 0x06, 0x03} // channel = 165, Tf = 5825MHz (56), TBD
+ };
+
+u8 abyVT3342_ChannelTable1[CB_MAX_CHANNEL][3] = {
+ {0x01, 0x99, 0x94}, // channel = 1, Tf = 2412MHz
+ {0x02, 0x44, 0x44}, // channel = 2, Tf = 2417MHz
+ {0x02, 0xEE, 0xE4}, // channel = 3, Tf = 2422MHz
+ {0x03, 0x99, 0x94}, // channel = 4, Tf = 2427MHz
+ {0x00, 0x44, 0x44}, // channel = 5, Tf = 2432MHz
+ {0x00, 0xEE, 0xE4}, // channel = 6, Tf = 2437MHz
+ {0x01, 0x99, 0x94}, // channel = 7, Tf = 2442MHz
+ {0x02, 0x44, 0x44}, // channel = 8, Tf = 2447MHz
+ {0x02, 0xEE, 0xE4}, // channel = 9, Tf = 2452MHz
+ {0x03, 0x99, 0x94}, // channel = 10, Tf = 2457MHz
+ {0x00, 0x44, 0x44}, // channel = 11, Tf = 2462MHz
+ {0x00, 0xEE, 0xE4}, // channel = 12, Tf = 2467MHz
+ {0x01, 0x99, 0x94}, // channel = 13, Tf = 2472MHz
+ {0x03, 0x33, 0x34}, // channel = 14, Tf = 2484MHz
+
+ // 4.9G => Ch 183, 184, 185, 187, 188, 189, 192, 196 (Value:15 ~ 22)
+ {0x00, 0x44, 0x44}, // channel = 183, Tf = 4915MHz (15), TBD
+ {0x00, 0x44, 0x44}, // channel = 184, Tf = 4920MHz (16), TBD
+ {0x00, 0x44, 0x44}, // channel = 185, Tf = 4925MHz (17), TBD
+ {0x00, 0x44, 0x44}, // channel = 187, Tf = 4935MHz (18), TBD
+ {0x00, 0x44, 0x44}, // channel = 188, Tf = 4940MHz (19), TBD
+ {0x00, 0x44, 0x44}, // channel = 189, Tf = 4945MHz (20), TBD
+ {0x00, 0x44, 0x44}, // channel = 192, Tf = 4960MHz (21), TBD
+ {0x00, 0x44, 0x44}, // channel = 196, Tf = 4980MHz (22), TBD
+
+ // 5G => Ch 7, 8, 9, 11, 12, 16, 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64,
+ // 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165 (Value 23 ~ 56)
+ {0x00, 0x44, 0x44}, // channel = 7, Tf = 5035MHz (23), TBD
+ {0x00, 0x44, 0x44}, // channel = 8, Tf = 5040MHz (24), TBD
+ {0x00, 0x44, 0x44}, // channel = 9, Tf = 5045MHz (25), TBD
+ {0x00, 0x44, 0x44}, // channel = 11, Tf = 5055MHz (26), TBD
+ {0x00, 0x44, 0x44}, // channel = 12, Tf = 5060MHz (27), TBD
+ {0x00, 0x44, 0x44}, // channel = 16, Tf = 5080MHz (28), TBD
+ {0x00, 0x44, 0x44}, // channel = 34, Tf = 5170MHz (29), TBD
+ {0x01, 0x55, 0x54}, // channel = 36, Tf = 5180MHz (30)
+ {0x01, 0x55, 0x54}, // channel = 38, Tf = 5190MHz (31), TBD
+ {0x02, 0xAA, 0xA4}, // channel = 40, Tf = 5200MHz (32)
+ {0x02, 0xAA, 0xA4}, // channel = 42, Tf = 5210MHz (33), TBD
+ {0x00, 0x00, 0x04}, // channel = 44, Tf = 5220MHz (34)
+ {0x00, 0x00, 0x04}, // channel = 46, Tf = 5230MHz (35), TBD
+ {0x01, 0x55, 0x54}, // channel = 48, Tf = 5240MHz (36)
+ {0x02, 0xAA, 0xA4}, // channel = 52, Tf = 5260MHz (37)
+ {0x00, 0x00, 0x04}, // channel = 56, Tf = 5280MHz (38)
+ {0x01, 0x55, 0x54}, // channel = 60, Tf = 5300MHz (39)
+ {0x02, 0xAA, 0xA4}, // channel = 64, Tf = 5320MHz (40)
+ {0x02, 0xAA, 0xA4}, // channel = 100, Tf = 5500MHz (41), TBD
+ {0x02, 0xAA, 0xA4}, // channel = 104, Tf = 5520MHz (42), TBD
+ {0x02, 0xAA, 0xA4}, // channel = 108, Tf = 5540MHz (43), TBD
+ {0x02, 0xAA, 0xA4}, // channel = 112, Tf = 5560MHz (44), TBD
+ {0x02, 0xAA, 0xA4}, // channel = 116, Tf = 5580MHz (45), TBD
+ {0x02, 0xAA, 0xA4}, // channel = 120, Tf = 5600MHz (46), TBD
+ {0x02, 0xAA, 0xA4}, // channel = 124, Tf = 5620MHz (47), TBD
+ {0x02, 0xAA, 0xA4}, // channel = 128, Tf = 5640MHz (48), TBD
+ {0x02, 0xAA, 0xA4}, // channel = 132, Tf = 5660MHz (49), TBD
+ {0x02, 0xAA, 0xA4}, // channel = 136, Tf = 5680MHz (50), TBD
+ {0x02, 0xAA, 0xA4}, // channel = 140, Tf = 5700MHz (51), TBD
+ {0x03, 0x00, 0x04}, // channel = 149, Tf = 5745MHz (52)
+ {0x00, 0x55, 0x54}, // channel = 153, Tf = 5765MHz (53)
+ {0x01, 0xAA, 0xA4}, // channel = 157, Tf = 5785MHz (54)
+ {0x03, 0x00, 0x04}, // channel = 161, Tf = 5805MHz (55)
+ {0x03, 0x00, 0x04} // channel = 165, Tf = 5825MHz (56), TBD
+ };
+
+/*+
+ *
+ * Power Table
+ *
+-*/
+
+const u32 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:20050103, Channel 11a Number To Index
+// 4.9G => Ch 183, 184, 185, 187, 188, 189, 192, 196 (Value:15 ~ 22)
+// 5G => Ch 7, 8, 9, 11, 12, 16, 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64,
+// 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165 (Value 23 ~ 56)
+
+const u8 RFaby11aChannelIndex[200] = {
+ // 1 2 3 4 5 6 7 8 9 10
+ 00, 00, 00, 00, 00, 00, 23, 24, 25, 00, // 10
+ 26, 27, 00, 00, 00, 28, 00, 00, 00, 00, // 20
+ 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, // 30
+ 00, 00, 00, 29, 00, 30, 00, 31, 00, 32, // 40
+ 00, 33, 00, 34, 00, 35, 00, 36, 00, 00, // 50
+ 00, 37, 00, 00, 00, 38, 00, 00, 00, 39, // 60
+ 00, 00, 00, 40, 00, 00, 00, 00, 00, 00, // 70
+ 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, // 80
+ 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, // 90
+ 00, 00, 00, 00, 00, 00, 00, 00, 00, 41, //100
+
+ 00, 00, 00, 42, 00, 00, 00, 43, 00, 00, //110
+ 00, 44, 00, 00, 00, 45, 00, 00, 00, 46, //120
+ 00, 00, 00, 47, 00, 00, 00, 48, 00, 00, //130
+ 00, 49, 00, 00, 00, 50, 00, 00, 00, 51, //140
+ 00, 00, 00, 00, 00, 00, 00, 00, 52, 00, //150
+ 00, 00, 53, 00, 00, 00, 54, 00, 00, 00, //160
+ 55, 00, 00, 00, 56, 00, 00, 00, 00, 00, //170
+ 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, //180
+ 00, 00, 15, 16, 17, 00, 18, 19, 20, 00, //190
+ 00, 21, 00, 00, 00, 22, 00, 00, 00, 00 //200
+};
+//}} RobertYu
+
+/*
+ * Description: Write to IF/RF, by embedded programming
+ *
+ * Parameters:
+ * In:
+ * dwData - data to write
+ * Out:
+ * none
+ *
+ * Return Value: true if succeeded; false if failed.
+ *
+ */
+int IFRFbWriteEmbedded(struct vnt_private *pDevice, u32 dwData)
+{
+ u8 pbyData[4];
+
+ pbyData[0] = (u8)dwData;
+ pbyData[1] = (u8)(dwData >> 8);
+ pbyData[2] = (u8)(dwData >> 16);
+ pbyData[3] = (u8)(dwData >> 24);
+
+ CONTROLnsRequestOut(pDevice,
+ MESSAGE_TYPE_WRITE_IFRF, 0, 0, 4, pbyData);
+
+ return true;
+}
+
+/*
+ * Description: Set Tx power
+ *
+ * Parameters:
+ * In:
+ * dwIoBase - I/O base address
+ * dwRFPowerTable - RF Tx Power Setting
+ * Out:
+ * none
+ *
+ * Return Value: true if succeeded; false if failed.
+ *
+ */
+int RFbSetPower(struct vnt_private *pDevice, u32 uRATE, u32 uCH)
+{
+ int bResult = true;
+ u8 byPwr = pDevice->byCCKPwr;
+
+ if (pDevice->dwDiagRefCount)
+ return true;
+
+ if (uCH == 0)
+ return -EINVAL;
+
+ switch (uRATE) {
+ case RATE_1M:
+ case RATE_2M:
+ case RATE_5M:
+ case RATE_11M:
+ byPwr = pDevice->abyCCKPwrTbl[uCH-1];
+ break;
+ case RATE_6M:
+ case RATE_9M:
+ case RATE_18M:
+ case RATE_24M:
+ case RATE_36M:
+ case RATE_48M:
+ case RATE_54M:
+ if (uCH > CB_MAX_CHANNEL_24G) {
+ byPwr = pDevice->abyOFDMAPwrTbl[uCH-15];
+ } else {
+ byPwr = pDevice->abyOFDMPwrTbl[uCH-1];
+ }
+ break;
+ }
+
+ bResult = RFbRawSetPower(pDevice, byPwr, uRATE);
+
+ return bResult;
+}
+
+/*
+ * Description: Set Tx power
+ *
+ * Parameters:
+ * In:
+ * dwIoBase - I/O base address
+ * dwRFPowerTable - RF Tx Power Setting
+ * Out:
+ * none
+ *
+ * Return Value: true if succeeded; false if failed.
+ *
+ */
+
+int RFbRawSetPower(struct vnt_private *pDevice, u8 byPwr, u32 uRATE)
+{
+ int bResult = true;
+
+ if (pDevice->byCurPwr == byPwr)
+ return true;
+
+ pDevice->byCurPwr = byPwr;
+
+ switch (pDevice->byRFType) {
+
+ case RF_AL2230 :
+ if (pDevice->byCurPwr >= AL2230_PWR_IDX_LEN)
+ return false;
+ bResult &= IFRFbWriteEmbedded(pDevice, dwAL2230PowerTable[pDevice->byCurPwr]);
+ if (uRATE <= RATE_11M)
+ bResult &= IFRFbWriteEmbedded(pDevice, 0x0001B400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW);
+ else
+ bResult &= IFRFbWriteEmbedded(pDevice, 0x0005A400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW);
+ break;
+
+ case RF_AL2230S :
+ if (pDevice->byCurPwr >= AL2230_PWR_IDX_LEN)
+ return false;
+ bResult &= IFRFbWriteEmbedded(pDevice, dwAL2230PowerTable[pDevice->byCurPwr]);
+ if (uRATE <= RATE_11M) {
+ bResult &= IFRFbWriteEmbedded(pDevice, 0x040C1400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW);
+ bResult &= IFRFbWriteEmbedded(pDevice, 0x00299B00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW);
+ }else {
+ bResult &= IFRFbWriteEmbedded(pDevice, 0x0005A400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW);
+ bResult &= IFRFbWriteEmbedded(pDevice, 0x00099B00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW);
+ }
+ break;
+
+ case RF_AIROHA7230:
+ {
+ u32 dwMax7230Pwr;
+
+ if (uRATE <= RATE_11M) { //RobertYu:20060426, for better 11b mask
+ bResult &= IFRFbWriteEmbedded(pDevice, 0x111BB900+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW);
+ }
+ else {
+ bResult &= IFRFbWriteEmbedded(pDevice, 0x221BB900+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW);
+ }
+
+ if (pDevice->byCurPwr > AL7230_PWR_IDX_LEN) return false;
+
+ // 0x080F1B00 for 3 wire control TxGain(D10) and 0x31 as TX Gain value
+ dwMax7230Pwr = 0x080C0B00 | ( (pDevice->byCurPwr) << 12 ) |
+ (BY_AL7230_REG_LEN << 3 ) | IFREGCTL_REGW;
+
+ bResult &= IFRFbWriteEmbedded(pDevice, dwMax7230Pwr);
+ break;
+ }
+ break;
+
+ case RF_VT3226: //RobertYu:20051111, VT3226C0 and before
+ {
+ u32 dwVT3226Pwr;
+
+ if (pDevice->byCurPwr >= VT3226_PWR_IDX_LEN)
+ return false;
+ dwVT3226Pwr = ((0x3F-pDevice->byCurPwr) << 20 ) | ( 0x17 << 8 ) /* Reg7 */ |
+ (BY_VT3226_REG_LEN << 3 ) | IFREGCTL_REGW;
+ bResult &= IFRFbWriteEmbedded(pDevice, dwVT3226Pwr);
+ break;
+ }
+
+ case RF_VT3226D0: //RobertYu:20051228
+ {
+ u32 dwVT3226Pwr;
+
+ if (pDevice->byCurPwr >= VT3226_PWR_IDX_LEN)
+ return false;
+
+ if (uRATE <= RATE_11M) {
+
+ dwVT3226Pwr = ((0x3F-pDevice->byCurPwr) << 20 ) | ( 0xE07 << 8 ) /* Reg7 */ | //RobertYu:20060420, TWIF 1.10
+ (BY_VT3226_REG_LEN << 3 ) | IFREGCTL_REGW;
+ bResult &= IFRFbWriteEmbedded(pDevice, dwVT3226Pwr);
+
+ bResult &= IFRFbWriteEmbedded(pDevice, 0x03C6A200+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW);
+ if (pDevice->vnt_mgmt.eScanState != WMAC_NO_SCANNING) {
+ /* scanning, channel number is pDevice->uScanChannel */
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
+ "RFbRawSetPower> 11B mode uCurrChannel[%d]\n",
+ pDevice->vnt_mgmt.uScanChannel);
+ bResult &= IFRFbWriteEmbedded(pDevice,
+ dwVT3226D0LoCurrentTable[pDevice->
+ vnt_mgmt.uScanChannel - 1]);
+ } else {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
+ "RFbRawSetPower> 11B mode uCurrChannel[%d]\n",
+ pDevice->vnt_mgmt.uCurrChannel);
+ bResult &= IFRFbWriteEmbedded(pDevice,
+ dwVT3226D0LoCurrentTable[pDevice->
+ vnt_mgmt.uCurrChannel - 1]);
+ }
+
+ bResult &= IFRFbWriteEmbedded(pDevice, 0x015C0800+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW); //RobertYu:20060420, ok now, new switching power (mini-pci can have bigger power consumption)
+ } else {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"@@@@ RFbRawSetPower> 11G mode\n");
+ dwVT3226Pwr = ((0x3F-pDevice->byCurPwr) << 20 ) | ( 0x7 << 8 ) /* Reg7 */ | //RobertYu:20060420, TWIF 1.10
+ (BY_VT3226_REG_LEN << 3 ) | IFREGCTL_REGW;
+ bResult &= IFRFbWriteEmbedded(pDevice, dwVT3226Pwr);
+ bResult &= IFRFbWriteEmbedded(pDevice, 0x00C6A200+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW); //RobertYu:20060327
+ bResult &= IFRFbWriteEmbedded(pDevice, 0x016BC600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW); //RobertYu:20060111
+ bResult &= IFRFbWriteEmbedded(pDevice, 0x00900800+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW); //RobertYu:20060111
+ }
+ break;
+ }
+
+ //{{RobertYu:20060609
+ case RF_VT3342A0:
+ {
+ u32 dwVT3342Pwr;
+
+ if (pDevice->byCurPwr >= VT3342_PWR_IDX_LEN)
+ return false;
+
+ dwVT3342Pwr = ((0x3F-pDevice->byCurPwr) << 20 ) | ( 0x27 << 8 ) /* Reg7 */ |
+ (BY_VT3342_REG_LEN << 3 ) | IFREGCTL_REGW;
+ bResult &= IFRFbWriteEmbedded(pDevice, dwVT3342Pwr);
+ break;
+ }
+
+ default :
+ break;
+ }
+ return bResult;
+}
+
+/*+
+ *
+ * Routine Description:
+ * Translate RSSI to dBm
+ *
+ * Parameters:
+ * In:
+ * pDevice - The adapter to be translated
+ * byCurrRSSI - RSSI to be translated
+ * Out:
+ * pdwdbm - Translated dbm number
+ *
+ * Return Value: none
+ *
+-*/
+void RFvRSSITodBm(struct vnt_private *pDevice, u8 byCurrRSSI, long *pldBm)
+{
+ u8 byIdx = (((byCurrRSSI & 0xC0) >> 6) & 0x03);
+ signed long b = (byCurrRSSI & 0x3F);
+ signed long a = 0;
+ u8 abyAIROHARF[4] = {0, 18, 0, 40};
+
+ switch (pDevice->byRFType) {
+ case RF_AL2230:
+ case RF_AL2230S:
+ case RF_AIROHA7230:
+ case RF_VT3226: //RobertYu:20051111
+ case RF_VT3226D0:
+ case RF_VT3342A0: //RobertYu:20060609
+ a = abyAIROHARF[byIdx];
+ break;
+ default:
+ break;
+ }
+
+ *pldBm = -1 * (a + b * 2);
+}
+
+void RFbRFTableDownload(struct vnt_private *pDevice)
+{
+ u16 wLength1 = 0, wLength2 = 0, wLength3 = 0;
+ u8 *pbyAddr1 = NULL, *pbyAddr2 = NULL, *pbyAddr3 = NULL;
+ u16 wLength, wValue;
+ u8 abyArray[256];
+
+ switch ( pDevice->byRFType ) {
+ case RF_AL2230:
+ case RF_AL2230S:
+ wLength1 = CB_AL2230_INIT_SEQ * 3;
+ wLength2 = CB_MAX_CHANNEL_24G * 3;
+ wLength3 = CB_MAX_CHANNEL_24G * 3;
+ pbyAddr1 = &(abyAL2230InitTable[0][0]);
+ pbyAddr2 = &(abyAL2230ChannelTable0[0][0]);
+ pbyAddr3 = &(abyAL2230ChannelTable1[0][0]);
+ break;
+ case RF_AIROHA7230:
+ wLength1 = CB_AL7230_INIT_SEQ * 3;
+ wLength2 = CB_MAX_CHANNEL * 3;
+ wLength3 = CB_MAX_CHANNEL * 3;
+ pbyAddr1 = &(abyAL7230InitTable[0][0]);
+ pbyAddr2 = &(abyAL7230ChannelTable0[0][0]);
+ pbyAddr3 = &(abyAL7230ChannelTable1[0][0]);
+ break;
+ case RF_VT3226: //RobertYu:20051111
+ wLength1 = CB_VT3226_INIT_SEQ * 3;
+ wLength2 = CB_MAX_CHANNEL_24G * 3;
+ wLength3 = CB_MAX_CHANNEL_24G * 3;
+ pbyAddr1 = &(abyVT3226_InitTable[0][0]);
+ pbyAddr2 = &(abyVT3226_ChannelTable0[0][0]);
+ pbyAddr3 = &(abyVT3226_ChannelTable1[0][0]);
+ break;
+ case RF_VT3226D0: //RobertYu:20051114
+ wLength1 = CB_VT3226_INIT_SEQ * 3;
+ wLength2 = CB_MAX_CHANNEL_24G * 3;
+ wLength3 = CB_MAX_CHANNEL_24G * 3;
+ pbyAddr1 = &(abyVT3226D0_InitTable[0][0]);
+ pbyAddr2 = &(abyVT3226_ChannelTable0[0][0]);
+ pbyAddr3 = &(abyVT3226_ChannelTable1[0][0]);
+ break;
+ case RF_VT3342A0: //RobertYu:20060609
+ wLength1 = CB_VT3342_INIT_SEQ * 3;
+ wLength2 = CB_MAX_CHANNEL * 3;
+ wLength3 = CB_MAX_CHANNEL * 3;
+ pbyAddr1 = &(abyVT3342A0_InitTable[0][0]);
+ pbyAddr2 = &(abyVT3342_ChannelTable0[0][0]);
+ pbyAddr3 = &(abyVT3342_ChannelTable1[0][0]);
+ break;
+
+ }
+ //Init Table
+
+ memcpy(abyArray, pbyAddr1, wLength1);
+ CONTROLnsRequestOut(pDevice,
+ MESSAGE_TYPE_WRITE,
+ 0,
+ MESSAGE_REQUEST_RF_INIT,
+ wLength1,
+ abyArray
+ );
+ //Channel Table 0
+ wValue = 0;
+ while ( wLength2 > 0 ) {
+
+ if ( wLength2 >= 64 ) {
+ wLength = 64;
+ } else {
+ wLength = wLength2;
+ }
+ memcpy(abyArray, pbyAddr2, wLength);
+ CONTROLnsRequestOut(pDevice,
+ MESSAGE_TYPE_WRITE,
+ wValue,
+ MESSAGE_REQUEST_RF_CH0,
+ wLength,
+ abyArray);
+
+ wLength2 -= wLength;
+ wValue += wLength;
+ pbyAddr2 += wLength;
+ }
+ //Channel table 1
+ wValue = 0;
+ while ( wLength3 > 0 ) {
+
+ if ( wLength3 >= 64 ) {
+ wLength = 64;
+ } else {
+ wLength = wLength3;
+ }
+ memcpy(abyArray, pbyAddr3, wLength);
+ CONTROLnsRequestOut(pDevice,
+ MESSAGE_TYPE_WRITE,
+ wValue,
+ MESSAGE_REQUEST_RF_CH1,
+ wLength,
+ abyArray);
+
+ wLength3 -= wLength;
+ wValue += wLength;
+ pbyAddr3 += wLength;
+ }
+
+ //7230 needs 2 InitTable and 3 Channel Table
+ if ( pDevice->byRFType == RF_AIROHA7230 ) {
+ wLength1 = CB_AL7230_INIT_SEQ * 3;
+ wLength2 = CB_MAX_CHANNEL * 3;
+ pbyAddr1 = &(abyAL7230InitTableAMode[0][0]);
+ pbyAddr2 = &(abyAL7230ChannelTable2[0][0]);
+ memcpy(abyArray, pbyAddr1, wLength1);
+ //Init Table 2
+ CONTROLnsRequestOut(pDevice,
+ MESSAGE_TYPE_WRITE,
+ 0,
+ MESSAGE_REQUEST_RF_INIT2,
+ wLength1,
+ abyArray);
+
+ //Channel Table 0
+ wValue = 0;
+ while ( wLength2 > 0 ) {
+
+ if ( wLength2 >= 64 ) {
+ wLength = 64;
+ } else {
+ wLength = wLength2;
+ }
+ memcpy(abyArray, pbyAddr2, wLength);
+ CONTROLnsRequestOut(pDevice,
+ MESSAGE_TYPE_WRITE,
+ wValue,
+ MESSAGE_REQUEST_RF_CH2,
+ wLength,
+ abyArray);
+
+ wLength2 -= wLength;
+ wValue += wLength;
+ pbyAddr2 += wLength;
+ }
+ }
+
+}
diff --git a/drivers/staging/vt6656/rf.h b/drivers/staging/vt6656/rf.h
new file mode 100644
index 00000000..de5c613b
--- /dev/null
+++ b/drivers/staging/vt6656/rf.h
@@ -0,0 +1,64 @@
+/*
+ * 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__
+
+#include "device.h"
+
+//
+// Baseband RF pair definition in eeprom (Bits 6..0)
+//
+#define RF_RFMD2959 0x01
+#define RF_MAXIMAG 0x02
+#define RF_AL2230 0x03
+#define RF_GCT5103 0x04
+#define RF_UW2451 0x05
+#define RF_MAXIMG 0x06
+#define RF_MAXIM2829 0x07
+#define RF_UW2452 0x08
+#define RF_VT3226 0x09
+#define RF_AIROHA7230 0x0a
+#define RF_UW2453 0x0b
+#define RF_VT3226D0 0x0c //RobertYu:20051114
+#define RF_VT3342A0 0x0d //RobertYu:20060609
+#define RF_AL2230S 0x0e
+
+#define RF_EMU 0x80
+#define RF_MASK 0x7F
+
+extern const u8 RFaby11aChannelIndex[200];
+
+int IFRFbWriteEmbedded(struct vnt_private *, u32 dwData);
+int RFbSetPower(struct vnt_private *, u32 uRATE, u32 uCH);
+int RFbRawSetPower(struct vnt_private *, u8 byPwr, u32 uRATE);
+void RFvRSSITodBm(struct vnt_private *, u8 byCurrRSSI, long *pldBm);
+void RFbRFTableDownload(struct vnt_private *pDevice);
+
+#endif /* __RF_H__ */
diff --git a/drivers/staging/vt6656/rndis.h b/drivers/staging/vt6656/rndis.h
new file mode 100644
index 00000000..5cf5e732
--- /dev/null
+++ b/drivers/staging/vt6656/rndis.h
@@ -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: rndis.h
+ *
+ * Purpose: Interface between firmware and driver
+ *
+ * Author: Warren Hsu
+ *
+ * Date: Nov 24, 2004
+ *
+ */
+
+#ifndef __RNDIS_H__
+#define __RNDIS_H__
+
+#define MESSAGE_TYPE_READ 0x01
+#define MESSAGE_TYPE_WRITE 0x00
+#define MESSAGE_TYPE_LOCK_OR 0x02
+#define MESSAGE_TYPE_LOCK_AND 0x03
+#define MESSAGE_TYPE_WRITE_MASK 0x04
+#define MESSAGE_TYPE_CARDINIT 0x05
+#define MESSAGE_TYPE_INIT_RSP 0x06
+#define MESSAGE_TYPE_MACSHUTDOWN 0x07
+#define MESSAGE_TYPE_SETKEY 0x08
+#define MESSAGE_TYPE_CLRKEYENTRY 0x09
+#define MESSAGE_TYPE_WRITE_MISCFF 0x0A
+#define MESSAGE_TYPE_SET_ANTMD 0x0B
+#define MESSAGE_TYPE_SELECT_CHANNLE 0x0C
+#define MESSAGE_TYPE_SET_TSFTBTT 0x0D
+#define MESSAGE_TYPE_SET_SSTIFS 0x0E
+#define MESSAGE_TYPE_CHANGE_BBTYPE 0x0F
+#define MESSAGE_TYPE_DISABLE_PS 0x10
+#define MESSAGE_TYPE_WRITE_IFRF 0x11
+
+//used for read/write(index)
+#define MESSAGE_REQUEST_MEM 0x01
+#define MESSAGE_REQUEST_BBREG 0x02
+#define MESSAGE_REQUEST_MACREG 0x03
+#define MESSAGE_REQUEST_EEPROM 0x04
+#define MESSAGE_REQUEST_TSF 0x05
+#define MESSAGE_REQUEST_TBTT 0x06
+#define MESSAGE_REQUEST_BBAGC 0x07
+#define MESSAGE_REQUEST_VERSION 0x08
+#define MESSAGE_REQUEST_RF_INIT 0x09
+#define MESSAGE_REQUEST_RF_INIT2 0x0A
+#define MESSAGE_REQUEST_RF_CH0 0x0B
+#define MESSAGE_REQUEST_RF_CH1 0x0C
+#define MESSAGE_REQUEST_RF_CH2 0x0D
+
+#define VIAUSB20_PACKET_HEADER 0x04
+
+#define USB_REG4 0x604
+
+typedef struct _CMD_MESSAGE
+{
+ u8 byData[256];
+} CMD_MESSAGE, *PCMD_MESSAGE;
+
+typedef struct _CMD_WRITE_MASK
+{
+ u8 byData;
+ u8 byMask;
+} CMD_WRITE_MASK, *PCMD_WRITE_MASK;
+
+typedef struct _CMD_CARD_INIT
+{
+ u8 byInitClass;
+ u8 bExistSWNetAddr;
+ u8 bySWNetAddr[6];
+ u8 byShortRetryLimit;
+ u8 byLongRetryLimit;
+} CMD_CARD_INIT, *PCMD_CARD_INIT;
+
+typedef struct _RSP_CARD_INIT
+{
+ u8 byStatus;
+ u8 byNetAddr[6];
+ u8 byRFType;
+ u8 byMinChannel;
+ u8 byMaxChannel;
+} RSP_CARD_INIT, *PRSP_CARD_INIT;
+
+typedef struct _CMD_SET_KEY
+{
+ u16 wKCTL;
+ u8 abyMacAddr[6];
+ u8 abyKey[16];
+} CMD_SET_KEY, *PCMD_SET_KEY;
+
+typedef struct _CMD_CLRKEY_ENTRY
+{
+ u8 abyKeyEntry[11];
+} CMD_CLRKEY_ENTRY, *PCMD_CLRKEY_ENTRY;
+
+typedef struct _CMD_WRITE_MISCFF
+{
+ u32 adwMiscFFData[22][4]; //a key entry has only 22 dwords
+} CMD_WRITE_MISCFF, *PCMD_WRITE_MISCFF;
+
+typedef struct _CMD_SET_TSFTBTT
+{
+ u8 abyTSF_TBTT[8];
+} CMD_SET_TSFTBTT, *PCMD_SET_TSFTBTT;
+
+typedef struct _CMD_SET_SSTIFS
+{
+ u8 bySIFS;
+ u8 byDIFS;
+ u8 byEIFS;
+ u8 bySlotTime;
+ u8 byCwMax_Min;
+ u8 byBBCR10;
+} CMD_SET_SSTIFS, *PCMD_SET_SSTIFS;
+
+typedef struct _CMD_CHANGE_BBTYPE
+{
+ u8 bySIFS;
+ u8 byDIFS;
+ u8 byEIFS;
+ u8 bySlotTime;
+ u8 byCwMax_Min;
+ u8 byBBCR10;
+ u8 byBB_BBType; //CR88
+ u8 byMAC_BBType;
+ u32 dwRSPINF_b_1;
+ u32 dwRSPINF_b_2;
+ u32 dwRSPINF_b_55;
+ u32 dwRSPINF_b_11;
+ u16 wRSPINF_a[9];
+} CMD_CHANGE_BBTYPE, *PCMD_CHANGE_BBTYPE;
+
+#define EXCH_WORD(w) ((u16)((u16)(w)<<8) | (u16)((u16)(w)>>8))
+
+#endif /* _RNDIS_H_ */
diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c
new file mode 100644
index 00000000..9bf2f8d5
--- /dev/null
+++ b/drivers/staging/vt6656/rxtx.c
@@ -0,0 +1,2928 @@
+/*
+ * 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 required parameter.
+ * s_vGenerateMACHeader - Translate 802.3 to 802.11 header
+ * csBeacon_xmit - beacon tx function
+ * csMgmt_xmit - management tx function
+ * s_uGetDataDuration - get tx data required duration
+ * s_uFillDataHead- fulfill tx data duration header
+ * s_uGetRTSCTSDuration- get rtx/cts required duration
+ * s_uGetRTSCTSRsvTime- get rts/cts reserved time
+ * s_uGetTxRsvTime- get frame reserved time
+ * s_vFillCTSHead- fulfill CTS ctl header
+ * s_vFillFragParameter- Set fragment 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:
+ *
+ */
+
+#include "device.h"
+#include "rxtx.h"
+#include "tether.h"
+#include "card.h"
+#include "bssdb.h"
+#include "mac.h"
+#include "baseband.h"
+#include "michael.h"
+#include "tkip.h"
+#include "tcrc.h"
+#include "wctl.h"
+#include "hostap.h"
+#include "rf.h"
+#include "datarate.h"
+#include "usbpipe.h"
+#include "iocmd.h"
+
+static int msglevel = MSG_LEVEL_INFO;
+
+const u16 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 u16 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 u16 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 void s_vSaveTxPktInfo(struct vnt_private *pDevice, u8 byPktNum,
+ u8 *pbyDestAddr, u16 wPktLength, u16 wFIFOCtl);
+
+static void *s_vGetFreeContext(struct vnt_private *pDevice);
+
+static void s_vGenerateTxParameter(struct vnt_private *pDevice,
+ u8 byPktType, u16 wCurrentRate, void *pTxBufHead, void *pvRrvTime,
+ void *pvRTS, void *pvCTS, u32 cbFrameSize, int bNeedACK, u32 uDMAIdx,
+ struct ethhdr *psEthHeader);
+
+static u32 s_uFillDataHead(struct vnt_private *pDevice,
+ u8 byPktType, u16 wCurrentRate, void *pTxDataHead, u32 cbFrameLength,
+ u32 uDMAIdx, int bNeedAck, u32 uFragIdx, u32 cbLastFragmentSize,
+ u32 uMACfragNum, u8 byFBOption);
+
+static void s_vGenerateMACHeader(struct vnt_private *pDevice,
+ u8 *pbyBufferAddr, u16 wDuration, struct ethhdr *psEthHeader,
+ int bNeedEncrypt, u16 wFragType, u32 uDMAIdx, u32 uFragIdx);
+
+static void s_vFillTxKey(struct vnt_private *pDevice, u8 *pbyBuf,
+ u8 *pbyIVHead, PSKeyItem pTransmitKey, u8 *pbyHdrBuf, u16 wPayloadLen,
+ u8 *pMICHDR);
+
+static void s_vSWencryption(struct vnt_private *pDevice,
+ PSKeyItem pTransmitKey, u8 *pbyPayloadHead, u16 wPayloadSize);
+
+static unsigned int s_uGetTxRsvTime(struct vnt_private *pDevice, u8 byPktType,
+ u32 cbFrameLength, u16 wRate, int bNeedAck);
+
+static u32 s_uGetRTSCTSRsvTime(struct vnt_private *pDevice, u8 byRTSRsvType,
+ u8 byPktType, u32 cbFrameLength, u16 wCurrentRate);
+
+static void s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx,
+ u8 byPktType, void *pvCTS, u32 cbFrameLength, int bNeedAck,
+ int bDisCRC, u16 wCurrentRate, u8 byFBOption);
+
+static void s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType,
+ void *pvRTS, u32 cbFrameLength, int bNeedAck, int bDisCRC,
+ struct ethhdr *psEthHeader, u16 wCurrentRate, u8 byFBOption);
+
+static u32 s_uGetDataDuration(struct vnt_private *pDevice, u8 byDurType,
+ u32 cbFrameLength, u8 byPktType, u16 wRate, int bNeedAck,
+ u32 uFragIdx, u32 cbLastFragmentSize, u32 uMACfragNum,
+ u8 byFBOption);
+
+static unsigned int s_uGetRTSCTSDuration(struct vnt_private *pDevice,
+ u8 byDurType, u32 cbFrameLength, u8 byPktType, u16 wRate,
+ int bNeedAck, u8 byFBOption);
+
+static void *s_vGetFreeContext(struct vnt_private *pDevice)
+{
+ PUSB_SEND_CONTEXT pContext = NULL;
+ PUSB_SEND_CONTEXT pReturnContext = NULL;
+ int ii;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"GetFreeContext()\n");
+
+ for (ii = 0; ii < pDevice->cbTD; ii++) {
+ pContext = pDevice->apTD[ii];
+ if (pContext->bBoolInUse == false) {
+ pContext->bBoolInUse = true;
+ pReturnContext = pContext;
+ break;
+ }
+ }
+ if ( ii == pDevice->cbTD ) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No Free Tx Context\n");
+ }
+ return (void *) pReturnContext;
+}
+
+static void s_vSaveTxPktInfo(struct vnt_private *pDevice, u8 byPktNum,
+ u8 *pbyDestAddr, u16 wPktLength, u16 wFIFOCtl)
+{
+ PSStatCounter pStatistic = &pDevice->scStatistic;
+
+ if (is_broadcast_ether_addr(pbyDestAddr))
+ pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni = TX_PKT_BROAD;
+ else if (is_multicast_ether_addr(pbyDestAddr))
+ pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni = TX_PKT_MULTI;
+ else
+ pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni = TX_PKT_UNI;
+
+ pStatistic->abyTxPktInfo[byPktNum].wLength = wPktLength;
+ pStatistic->abyTxPktInfo[byPktNum].wFIFOCtl = wFIFOCtl;
+ memcpy(pStatistic->abyTxPktInfo[byPktNum].abyDestAddr,
+ pbyDestAddr,
+ ETH_ALEN);
+}
+
+static void s_vFillTxKey(struct vnt_private *pDevice, u8 *pbyBuf,
+ u8 *pbyIVHead, PSKeyItem pTransmitKey, u8 *pbyHdrBuf,
+ u16 wPayloadLen, u8 *pMICHDR)
+{
+ u32 *pdwIV = (u32 *)pbyIVHead;
+ u32 *pdwExtIV = (u32 *)((u8 *)pbyIVHead + 4);
+ u16 wValue;
+ struct ieee80211_hdr *pMACHeader = (struct ieee80211_hdr *)pbyHdrBuf;
+ u32 dwRevIVCounter;
+
+ //Fill TXKEY
+ if (pTransmitKey == NULL)
+ return;
+
+ dwRevIVCounter = cpu_to_le32(pDevice->dwIVCounter);
+ *pdwIV = pDevice->dwIVCounter;
+ pDevice->byKeyIndex = pTransmitKey->dwKeyIndex & 0xf;
+
+ if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) {
+ if (pTransmitKey->uKeyLength == WLAN_WEP232_KEYLEN ){
+ memcpy(pDevice->abyPRNG, (u8 *)&(dwRevIVCounter), 3);
+ memcpy(pDevice->abyPRNG+3, pTransmitKey->abyKey, pTransmitKey->uKeyLength);
+ } else {
+ memcpy(pbyBuf, (u8 *)&(dwRevIVCounter), 3);
+ memcpy(pbyBuf+3, pTransmitKey->abyKey, pTransmitKey->uKeyLength);
+ if(pTransmitKey->uKeyLength == WLAN_WEP40_KEYLEN) {
+ memcpy(pbyBuf+8, (u8 *)&(dwRevIVCounter), 3);
+ memcpy(pbyBuf+11, pTransmitKey->abyKey, pTransmitKey->uKeyLength);
+ }
+ memcpy(pDevice->abyPRNG, pbyBuf, 16);
+ }
+ // Append IV after Mac Header
+ *pdwIV &= WEP_IV_MASK;//00000000 11111111 11111111 11111111
+ *pdwIV |= (u32)pDevice->byKeyIndex << 30;
+ *pdwIV = cpu_to_le32(*pdwIV);
+ pDevice->dwIVCounter++;
+ if (pDevice->dwIVCounter > WEP_IV_MASK) {
+ pDevice->dwIVCounter = 0;
+ }
+ } else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
+ pTransmitKey->wTSC15_0++;
+ if (pTransmitKey->wTSC15_0 == 0) {
+ pTransmitKey->dwTSC47_16++;
+ }
+ TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr,
+ pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, pDevice->abyPRNG);
+ memcpy(pbyBuf, pDevice->abyPRNG, 16);
+ // Make IV
+ memcpy(pdwIV, pDevice->abyPRNG, 3);
+
+ *(pbyIVHead+3) = (u8)(((pDevice->byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV
+ // Append IV&ExtIV after Mac Header
+ *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vFillTxKey()---- pdwExtIV: %x\n",
+ *pdwExtIV);
+
+ } else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) {
+ pTransmitKey->wTSC15_0++;
+ if (pTransmitKey->wTSC15_0 == 0) {
+ pTransmitKey->dwTSC47_16++;
+ }
+ memcpy(pbyBuf, pTransmitKey->abyKey, 16);
+
+ // Make IV
+ *pdwIV = 0;
+ *(pbyIVHead+3) = (u8)(((pDevice->byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV
+ *pdwIV |= cpu_to_le16((u16)(pTransmitKey->wTSC15_0));
+ //Append IV&ExtIV after Mac Header
+ *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16);
+
+ //Fill MICHDR0
+ *pMICHDR = 0x59;
+ *((u8 *)(pMICHDR+1)) = 0; // TxPriority
+ memcpy(pMICHDR+2, &(pMACHeader->addr2[0]), 6);
+ *((u8 *)(pMICHDR+8)) = HIBYTE(HIWORD(pTransmitKey->dwTSC47_16));
+ *((u8 *)(pMICHDR+9)) = LOBYTE(HIWORD(pTransmitKey->dwTSC47_16));
+ *((u8 *)(pMICHDR+10)) = HIBYTE(LOWORD(pTransmitKey->dwTSC47_16));
+ *((u8 *)(pMICHDR+11)) = LOBYTE(LOWORD(pTransmitKey->dwTSC47_16));
+ *((u8 *)(pMICHDR+12)) = HIBYTE(pTransmitKey->wTSC15_0);
+ *((u8 *)(pMICHDR+13)) = LOBYTE(pTransmitKey->wTSC15_0);
+ *((u8 *)(pMICHDR+14)) = HIBYTE(wPayloadLen);
+ *((u8 *)(pMICHDR+15)) = LOBYTE(wPayloadLen);
+
+ //Fill MICHDR1
+ *((u8 *)(pMICHDR+16)) = 0; // HLEN[15:8]
+ if (pDevice->bLongHeader) {
+ *((u8 *)(pMICHDR+17)) = 28; // HLEN[7:0]
+ } else {
+ *((u8 *)(pMICHDR+17)) = 22; // HLEN[7:0]
+ }
+ wValue = cpu_to_le16(pMACHeader->frame_control & 0xC78F);
+ memcpy(pMICHDR+18, (u8 *)&wValue, 2); // MSKFRACTL
+ memcpy(pMICHDR+20, &(pMACHeader->addr1[0]), 6);
+ memcpy(pMICHDR+26, &(pMACHeader->addr2[0]), 6);
+
+ //Fill MICHDR2
+ memcpy(pMICHDR+32, &(pMACHeader->addr3[0]), 6);
+ wValue = pMACHeader->seq_ctrl;
+ wValue &= 0x000F;
+ wValue = cpu_to_le16(wValue);
+ memcpy(pMICHDR+38, (u8 *)&wValue, 2); // MSKSEQCTL
+ if (pDevice->bLongHeader) {
+ memcpy(pMICHDR+40, &(pMACHeader->addr4[0]), 6);
+ }
+ }
+}
+
+static void s_vSWencryption(struct vnt_private *pDevice,
+ PSKeyItem pTransmitKey, u8 *pbyPayloadHead, u16 wPayloadSize)
+{
+ u32 cbICVlen = 4;
+ u32 dwICV = 0xffffffff;
+ u32 *pdwICV;
+
+ if (pTransmitKey == NULL)
+ return;
+
+ if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) {
+ //=======================================================================
+ // Append ICV after payload
+ dwICV = CRCdwGetCrc32Ex(pbyPayloadHead, wPayloadSize, dwICV);//ICV(Payload)
+ pdwICV = (u32 *)(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 = (u32 *)(pbyPayloadHead + wPayloadSize);
+ // finally, we must invert dwCRC to get the correct answer
+ *pdwICV = cpu_to_le32(~dwICV);
+ // RC4 encryption
+ rc4_init(&pDevice->SBox, pDevice->abyPRNG, TKIP_KEY_LEN);
+ rc4_encrypt(&pDevice->SBox, pbyPayloadHead, pbyPayloadHead, wPayloadSize+cbICVlen);
+ //=======================================================================
+ }
+}
+
+/*byPktType : PK_TYPE_11A 0
+ PK_TYPE_11B 1
+ PK_TYPE_11GB 2
+ PK_TYPE_11GA 3
+*/
+static u32 s_uGetTxRsvTime(struct vnt_private *pDevice, u8 byPktType,
+ u32 cbFrameLength, u16 wRate, int bNeedAck)
+{
+ u32 uDataTime, uAckTime;
+
+ uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wRate);
+ if (byPktType == PK_TYPE_11B) {//llb,CCK mode
+ uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (u16)pDevice->byTopCCKBasicRate);
+ } else {//11g 2.4G OFDM mode & 11a 5G OFDM mode
+ uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (u16)pDevice->byTopOFDMBasicRate);
+ }
+
+ if (bNeedAck) {
+ return (uDataTime + pDevice->uSIFS + uAckTime);
+ }
+ else {
+ return uDataTime;
+ }
+}
+
+//byFreqType: 0=>5GHZ 1=>2.4GHZ
+static u32 s_uGetRTSCTSRsvTime(struct vnt_private *pDevice,
+ u8 byRTSRsvType, u8 byPktType, u32 cbFrameLength, u16 wCurrentRate)
+{
+ u32 uRrvTime, uRTSTime, uCTSTime, uAckTime, uDataTime;
+
+ uRrvTime = uRTSTime = uCTSTime = uAckTime = uDataTime = 0;
+
+ uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wCurrentRate);
+ if (byRTSRsvType == 0) { //RTSTxRrvTime_bb
+ uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
+ uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
+ }
+ else if (byRTSRsvType == 1){ //RTSTxRrvTime_ba, only in 2.4GHZ
+ uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
+ uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
+ uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
+ }
+ else if (byRTSRsvType == 2) { //RTSTxRrvTime_aa
+ uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopOFDMBasicRate);
+ uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
+ }
+ else if (byRTSRsvType == 3) { //CTSTxRrvTime_ba, only in 2.4GHZ
+ uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
+ uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
+ uRrvTime = uCTSTime + uAckTime + uDataTime + 2*pDevice->uSIFS;
+ return uRrvTime;
+ }
+
+ //RTSRrvTime
+ uRrvTime = uRTSTime + uCTSTime + uAckTime + uDataTime + 3*pDevice->uSIFS;
+ return uRrvTime;
+}
+
+//byFreqType 0: 5GHz, 1:2.4Ghz
+static u32 s_uGetDataDuration(struct vnt_private *pDevice, u8 byDurType,
+ u32 cbFrameLength, u8 byPktType, u16 wRate, int bNeedAck,
+ u32 uFragIdx, u32 cbLastFragmentSize, u32 uMACfragNum,
+ u8 byFBOption)
+{
+ int bLastFrag = 0;
+ u32 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 u32 s_uGetRTSCTSDuration(struct vnt_private *pDevice, u8 byDurType,
+ u32 cbFrameLength, u8 byPktType, u16 wRate, int bNeedAck,
+ u8 byFBOption)
+{
+ u32 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 u32 s_uFillDataHead(struct vnt_private *pDevice,
+ u8 byPktType, u16 wCurrentRate, void *pTxDataHead, u32 cbFrameLength,
+ u32 uDMAIdx, int bNeedAck, u32 uFragIdx, u32 cbLastFragmentSize,
+ u32 uMACfragNum, u8 byFBOption)
+{
+
+ if (pTxDataHead == NULL) {
+ return 0;
+ }
+
+ if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
+ if ((uDMAIdx == TYPE_ATIMDMA) || (uDMAIdx == TYPE_BEACONDMA)) {
+ PSTxDataHead_ab pBuf = (PSTxDataHead_ab) pTxDataHead;
+ //Get SignalField,ServiceField,Length
+ BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
+ (u16 *)&(pBuf->wTransmitLength), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField)
+ );
+ //Get Duration and TimeStampOff
+ pBuf->wDuration = (u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
+ wCurrentRate, bNeedAck, uFragIdx,
+ cbLastFragmentSize, uMACfragNum,
+ byFBOption); //1: 2.4GHz
+ if(uDMAIdx!=TYPE_ATIMDMA) {
+ pBuf->wTimeStampOff = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
+ }
+ return (pBuf->wDuration);
+ }
+ else { // DATA & MANAGE Frame
+ if (byFBOption == AUTO_FB_NONE) {
+ PSTxDataHead_g pBuf = (PSTxDataHead_g)pTxDataHead;
+ //Get SignalField,ServiceField,Length
+ BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
+ (u16 *)&(pBuf->wTransmitLength_a), (u8 *)&(pBuf->byServiceField_a), (u8 *)&(pBuf->bySignalField_a)
+ );
+ BBvCalculateParameter(pDevice, cbFrameLength, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
+ (u16 *)&(pBuf->wTransmitLength_b), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b)
+ );
+ //Get Duration and TimeStamp
+ pBuf->wDuration_a = (u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength,
+ byPktType, wCurrentRate, bNeedAck, uFragIdx,
+ cbLastFragmentSize, uMACfragNum,
+ byFBOption); //1: 2.4GHz
+ pBuf->wDuration_b = (u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength,
+ PK_TYPE_11B, pDevice->byTopCCKBasicRate,
+ bNeedAck, uFragIdx, cbLastFragmentSize,
+ uMACfragNum, byFBOption); //1: 2.4GHz
+
+ pBuf->wTimeStampOff_a = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
+ pBuf->wTimeStampOff_b = 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
+ BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
+ (u16 *)&(pBuf->wTransmitLength_a), (u8 *)&(pBuf->byServiceField_a), (u8 *)&(pBuf->bySignalField_a)
+ );
+ BBvCalculateParameter(pDevice, cbFrameLength, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
+ (u16 *)&(pBuf->wTransmitLength_b), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b)
+ );
+ //Get Duration and TimeStamp
+ pBuf->wDuration_a = (u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
+ wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption); //1: 2.4GHz
+ pBuf->wDuration_b = (u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, PK_TYPE_11B,
+ pDevice->byTopCCKBasicRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption); //1: 2.4GHz
+ pBuf->wDuration_a_f0 = (u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
+ wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption); //1: 2.4GHz
+ pBuf->wDuration_a_f1 = (u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
+ wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption); //1: 2.4GHz
+ pBuf->wTimeStampOff_a = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
+ pBuf->wTimeStampOff_b = wTimeStampOff[pDevice->byPreambleType%2][pDevice->byTopCCKBasicRate%MAX_RATE];
+ return (pBuf->wDuration_a);
+ } //if (byFBOption == AUTO_FB_NONE)
+ }
+ }
+ else if (byPktType == PK_TYPE_11A) {
+ if ((byFBOption != AUTO_FB_NONE) && (uDMAIdx != TYPE_ATIMDMA) && (uDMAIdx != TYPE_BEACONDMA)) {
+ // Auto Fallback
+ PSTxDataHead_a_FB pBuf = (PSTxDataHead_a_FB)pTxDataHead;
+ //Get SignalField,ServiceField,Length
+ BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
+ (u16 *)&(pBuf->wTransmitLength), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField)
+ );
+ //Get Duration and TimeStampOff
+ pBuf->wDuration = (u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
+ wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption); //0: 5GHz
+ pBuf->wDuration_f0 = (u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
+ wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption); //0: 5GHz
+ pBuf->wDuration_f1 = (u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
+ wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption); //0: 5GHz
+ if(uDMAIdx!=TYPE_ATIMDMA) {
+ pBuf->wTimeStampOff = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
+ }
+ return (pBuf->wDuration);
+ } else {
+ PSTxDataHead_ab pBuf = (PSTxDataHead_ab)pTxDataHead;
+ //Get SignalField,ServiceField,Length
+ BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
+ (u16 *)&(pBuf->wTransmitLength), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField)
+ );
+ //Get Duration and TimeStampOff
+ pBuf->wDuration = (u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
+ wCurrentRate, bNeedAck, uFragIdx,
+ cbLastFragmentSize, uMACfragNum,
+ byFBOption);
+
+ if(uDMAIdx!=TYPE_ATIMDMA) {
+ pBuf->wTimeStampOff = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
+ }
+ return (pBuf->wDuration);
+ }
+ }
+ else if (byPktType == PK_TYPE_11B) {
+ PSTxDataHead_ab pBuf = (PSTxDataHead_ab)pTxDataHead;
+ //Get SignalField,ServiceField,Length
+ BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
+ (u16 *)&(pBuf->wTransmitLength), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField)
+ );
+ //Get Duration and TimeStampOff
+ pBuf->wDuration = (u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType,
+ wCurrentRate, bNeedAck, uFragIdx,
+ cbLastFragmentSize, uMACfragNum,
+ byFBOption);
+ if (uDMAIdx != TYPE_ATIMDMA) {
+ pBuf->wTimeStampOff = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
+ }
+ return (pBuf->wDuration);
+ }
+ return 0;
+}
+
+static void s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType,
+ void *pvRTS, u32 cbFrameLength, int bNeedAck, int bDisCRC,
+ struct ethhdr *psEthHeader, u16 wCurrentRate, u8 byFBOption)
+{
+ u32 uRTSFrameLen = 20;
+ u16 wLen = 0;
+
+ 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 doesn'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 (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
+ if (byFBOption == AUTO_FB_NONE) {
+ PSRTS_g pBuf = (PSRTS_g)pvRTS;
+ //Get SignalField,ServiceField,Length
+ BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
+ (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b)
+ );
+ pBuf->wTransmitLength_b = cpu_to_le16(wLen);
+ BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType,
+ (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField_a), (u8 *)&(pBuf->bySignalField_a)
+ );
+ pBuf->wTransmitLength_a = cpu_to_le16(wLen);
+ //Get Duration
+ pBuf->wDuration_bb = cpu_to_le16((u16)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((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //2:RTSDuration_aa, 1:2.4G, 2,3: 2.4G OFDMData
+ pBuf->wDuration_ba = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA, cbFrameLength, byPktType, 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)) {
+ memcpy(&(pBuf->Data.abyRA[0]),
+ &(psEthHeader->h_dest[0]),
+ ETH_ALEN);
+ }
+ else {
+ memcpy(&(pBuf->Data.abyRA[0]),
+ &(pDevice->abyBSSID[0]),
+ ETH_ALEN);
+ }
+ if (pDevice->eOPMode == OP_MODE_AP) {
+ memcpy(&(pBuf->Data.abyTA[0]),
+ &(pDevice->abyBSSID[0]),
+ ETH_ALEN);
+ }
+ else {
+ memcpy(&(pBuf->Data.abyTA[0]),
+ &(psEthHeader->h_source[0]),
+ ETH_ALEN);
+ }
+ }
+ else {
+ PSRTS_g_FB pBuf = (PSRTS_g_FB)pvRTS;
+ //Get SignalField,ServiceField,Length
+ BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
+ (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b)
+ );
+ pBuf->wTransmitLength_b = cpu_to_le16(wLen);
+ BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType,
+ (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField_a), (u8 *)&(pBuf->bySignalField_a)
+ );
+ pBuf->wTransmitLength_a = cpu_to_le16(wLen);
+ //Get Duration
+ pBuf->wDuration_bb = cpu_to_le16((u16)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((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //2:RTSDuration_aa, 1:2.4G, 2,3:2.4G OFDMData
+ pBuf->wDuration_ba = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //1:RTSDuration_ba, 1:2.4G, 2,3:2.4G OFDMData
+ pBuf->wRTSDuration_ba_f0 = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //4:wRTSDuration_ba_f0, 1:2.4G, 1:CCKData
+ pBuf->wRTSDuration_aa_f0 = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //5:wRTSDuration_aa_f0, 1:2.4G, 1:CCKData
+ pBuf->wRTSDuration_ba_f1 = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //6:wRTSDuration_ba_f1, 1:2.4G, 1:CCKData
+ pBuf->wRTSDuration_aa_f1 = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1, cbFrameLength, byPktType, 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)) {
+ memcpy(&(pBuf->Data.abyRA[0]),
+ &(psEthHeader->h_dest[0]),
+ ETH_ALEN);
+ }
+ else {
+ memcpy(&(pBuf->Data.abyRA[0]),
+ &(pDevice->abyBSSID[0]),
+ ETH_ALEN);
+ }
+
+ if (pDevice->eOPMode == OP_MODE_AP) {
+ memcpy(&(pBuf->Data.abyTA[0]),
+ &(pDevice->abyBSSID[0]),
+ ETH_ALEN);
+ }
+ else {
+ memcpy(&(pBuf->Data.abyTA[0]),
+ &(psEthHeader->h_source[0]),
+ ETH_ALEN);
+ }
+
+ } // if (byFBOption == AUTO_FB_NONE)
+ }
+ else if (byPktType == PK_TYPE_11A) {
+ if (byFBOption == AUTO_FB_NONE) {
+ PSRTS_ab pBuf = (PSRTS_ab)pvRTS;
+ //Get SignalField,ServiceField,Length
+ BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType,
+ (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField)
+ );
+ pBuf->wTransmitLength = cpu_to_le16(wLen);
+ //Get Duration
+ pBuf->wDuration = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, 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)) {
+ memcpy(&(pBuf->Data.abyRA[0]),
+ &(psEthHeader->h_dest[0]),
+ ETH_ALEN);
+ } else {
+ memcpy(&(pBuf->Data.abyRA[0]),
+ &(pDevice->abyBSSID[0]),
+ ETH_ALEN);
+ }
+
+ if (pDevice->eOPMode == OP_MODE_AP) {
+ memcpy(&(pBuf->Data.abyTA[0]),
+ &(pDevice->abyBSSID[0]),
+ ETH_ALEN);
+ } else {
+ memcpy(&(pBuf->Data.abyTA[0]),
+ &(psEthHeader->h_source[0]),
+ ETH_ALEN);
+ }
+
+ }
+ else {
+ PSRTS_a_FB pBuf = (PSRTS_a_FB)pvRTS;
+ //Get SignalField,ServiceField,Length
+ BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType,
+ (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField)
+ );
+ pBuf->wTransmitLength = cpu_to_le16(wLen);
+ //Get Duration
+ pBuf->wDuration = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_aa, 0:5G, 0: 5G OFDMData
+ pBuf->wRTSDuration_f0 = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //5:RTSDuration_aa_f0, 0:5G, 0: 5G OFDMData
+ pBuf->wRTSDuration_f1 = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1, cbFrameLength, byPktType, 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)) {
+ memcpy(&(pBuf->Data.abyRA[0]),
+ &(psEthHeader->h_dest[0]),
+ ETH_ALEN);
+ } else {
+ memcpy(&(pBuf->Data.abyRA[0]),
+ &(pDevice->abyBSSID[0]),
+ ETH_ALEN);
+ }
+ if (pDevice->eOPMode == OP_MODE_AP) {
+ memcpy(&(pBuf->Data.abyTA[0]),
+ &(pDevice->abyBSSID[0]),
+ ETH_ALEN);
+ } else {
+ memcpy(&(pBuf->Data.abyTA[0]),
+ &(psEthHeader->h_source[0]),
+ ETH_ALEN);
+ }
+ }
+ }
+ else if (byPktType == PK_TYPE_11B) {
+ PSRTS_ab pBuf = (PSRTS_ab)pvRTS;
+ //Get SignalField,ServiceField,Length
+ BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
+ (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField)
+ );
+ pBuf->wTransmitLength = cpu_to_le16(wLen);
+ //Get Duration
+ pBuf->wDuration = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, byPktType, 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)) {
+ memcpy(&(pBuf->Data.abyRA[0]),
+ &(psEthHeader->h_dest[0]),
+ ETH_ALEN);
+ }
+ else {
+ memcpy(&(pBuf->Data.abyRA[0]),
+ &(pDevice->abyBSSID[0]),
+ ETH_ALEN);
+ }
+
+ if (pDevice->eOPMode == OP_MODE_AP) {
+ memcpy(&(pBuf->Data.abyTA[0]),
+ &(pDevice->abyBSSID[0]),
+ ETH_ALEN);
+ } else {
+ memcpy(&(pBuf->Data.abyTA[0]),
+ &(psEthHeader->h_source[0]),
+ ETH_ALEN);
+ }
+ }
+}
+
+static void s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx,
+ u8 byPktType, void *pvCTS, u32 cbFrameLength, int bNeedAck,
+ int bDisCRC, u16 wCurrentRate, u8 byFBOption)
+{
+ u32 uCTSFrameLen = 14;
+ u16 wLen = 0;
+
+ 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 (byPktType == PK_TYPE_11GB || byPktType == 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
+ BBvCalculateParameter(pDevice, uCTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
+ (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b)
+ );
+ pBuf->wTransmitLength_b = cpu_to_le16(wLen);
+ pBuf->wDuration_ba = (u16)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA, cbFrameLength, byPktType, 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 = (u16)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F0, cbFrameLength, byPktType, 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 = (u16)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F1, cbFrameLength, byPktType, 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;
+ memcpy(&(pBuf->Data.abyRA[0]),
+ &(pDevice->abyCurrentNetAddr[0]),
+ ETH_ALEN);
+ } else { //if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA)
+ PSCTS pBuf = (PSCTS)pvCTS;
+ //Get SignalField,ServiceField,Length
+ BBvCalculateParameter(pDevice, uCTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
+ (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b)
+ );
+ pBuf->wTransmitLength_b = cpu_to_le16(wLen);
+ //Get CTSDuration_ba
+ pBuf->wDuration_ba = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA, cbFrameLength, byPktType, 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;
+ memcpy(&(pBuf->Data.abyRA[0]),
+ &(pDevice->abyCurrentNetAddr[0]),
+ ETH_ALEN);
+ }
+ }
+}
+
+/*+
+ *
+ * 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
+ * uDMAIdx - DMA Index
+ * Out:
+ * none
+ *
+ * Return Value: none
+ *
+-*/
+
+static void s_vGenerateTxParameter(struct vnt_private *pDevice,
+ u8 byPktType, u16 wCurrentRate, void *pTxBufHead, void *pvRrvTime,
+ void *pvRTS, void *pvCTS, u32 cbFrameSize, int bNeedACK, u32 uDMAIdx,
+ struct ethhdr *psEthHeader)
+{
+ u32 cbMACHdLen = WLAN_HDR_ADDR3_LEN; /* 24 */
+ u16 wFifoCtl;
+ int bDisCRC = false;
+ u8 byFBOption = AUTO_FB_NONE;
+
+ //DBG_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 (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
+
+ if (pvRTS != NULL) { //RTS_need
+ //Fill RsvTime
+ if (pvRrvTime) {
+ PSRrvTime_gRTS pBuf = (PSRrvTime_gRTS)pvRrvTime;
+ pBuf->wRTSTxRrvTime_aa = cpu_to_le16((u16)s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate));//2:RTSTxRrvTime_aa, 1:2.4GHz
+ pBuf->wRTSTxRrvTime_ba = cpu_to_le16((u16)s_uGetRTSCTSRsvTime(pDevice, 1, byPktType, cbFrameSize, wCurrentRate));//1:RTSTxRrvTime_ba, 1:2.4GHz
+ pBuf->wRTSTxRrvTime_bb = cpu_to_le16((u16)s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate));//0:RTSTxRrvTime_bb, 1:2.4GHz
+ pBuf->wTxRrvTime_a = cpu_to_le16((u16) s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//2.4G OFDM
+ pBuf->wTxRrvTime_b = cpu_to_le16((u16) s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK));//1:CCK
+ }
+ //Fill RTS
+ s_vFillRTSHead(pDevice, byPktType, 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((u16)s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//2.4G OFDM
+ pBuf->wTxRrvTime_b = cpu_to_le16((u16)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK));//1:CCK
+ pBuf->wCTSTxRrvTime_ba = cpu_to_le16((u16)s_uGetRTSCTSRsvTime(pDevice, 3, byPktType, cbFrameSize, wCurrentRate));//3:CTSTxRrvTime_Ba, 1:2.4GHz
+ }
+ //Fill CTS
+ s_vFillCTSHead(pDevice, uDMAIdx, byPktType, pvCTS, cbFrameSize, bNeedACK, bDisCRC, wCurrentRate, byFBOption);
+ }
+ }
+ else if (byPktType == 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((u16)s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate));//2:RTSTxRrvTime_aa, 0:5GHz
+ pBuf->wTxRrvTime = cpu_to_le16((u16)s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//0:OFDM
+ }
+ //Fill RTS
+ s_vFillRTSHead(pDevice, byPktType, 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((u16)s_uGetTxRsvTime(pDevice, PK_TYPE_11A, cbFrameSize, wCurrentRate, bNeedACK)); //0:OFDM
+ }
+ }
+ }
+ else if (byPktType == 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((u16)s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate));//0:RTSTxRrvTime_bb, 1:2.4GHz
+ pBuf->wTxRrvTime = cpu_to_le16((u16)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK));//1:CCK
+ }
+ //Fill RTS
+ s_vFillRTSHead(pDevice, byPktType, 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((u16)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK)); //1:CCK
+ }
+ }
+ }
+ //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vGenerateTxParameter END.\n");
+}
+/*
+ u8 * pbyBuffer,//point to pTxBufHead
+ u16 wFragType,//00:Non-Frag, 01:Start, 02:Mid, 03:Last
+ unsigned int cbFragmentSize,//Hdr+payoad+FCS
+*/
+
+static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType,
+ u8 *usbPacketBuf, int bNeedEncryption, u32 uSkbPacketLen, u32 uDMAIdx,
+ struct ethhdr *psEthHeader, u8 *pPacket, PSKeyItem pTransmitKey,
+ u32 uNodeIndex, u16 wCurrentRate, u32 *pcbHeaderLen, u32 *pcbTotalLen)
+{
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ u32 cbFrameSize, cbFrameBodySize;
+ PTX_BUFFER pTxBufHead;
+ u32 cb802_1_H_len;
+ u32 cbIVlen = 0, cbICVlen = 0, cbMIClen = 0, cbMACHdLen = 0;
+ u32 cbFCSlen = 4, cbMICHDR = 0;
+ int bNeedACK, bRTS;
+ u8 *pbyType, *pbyMacHdr, *pbyIVHead, *pbyPayloadHead, *pbyTxBufferAddr;
+ u8 abySNAP_RFC1042[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00};
+ u8 abySNAP_Bridgetunnel[ETH_ALEN]
+ = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8};
+ u32 uDuration;
+ u32 cbHeaderLength = 0, uPadding = 0;
+ void *pvRrvTime;
+ PSMICHDRHead pMICHDR;
+ void *pvRTS;
+ void *pvCTS;
+ void *pvTxDataHd;
+ u8 byFBOption = AUTO_FB_NONE, byFragType;
+ u16 wTxBufSize;
+ u32 dwMICKey0, dwMICKey1, dwMIC_Priority, dwCRC;
+ u32 *pdwMIC_L, *pdwMIC_R;
+ int bSoftWEP = false;
+
+ pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL;
+
+ if (bNeedEncryption && pTransmitKey->pvKeyTable) {
+ if (((PSKeyTable)pTransmitKey->pvKeyTable)->bSoftWEP == true)
+ bSoftWEP = true; /* WEP 256 */
+ }
+
+ pTxBufHead = (PTX_BUFFER) usbPacketBuf;
+ memset(pTxBufHead, 0, sizeof(TX_BUFFER));
+
+ // Get pkt type
+ if (ntohs(psEthHeader->h_proto) > ETH_DATA_LEN) {
+ if (pDevice->dwDiagRefCount == 0) {
+ cb802_1_H_len = 8;
+ } else {
+ cb802_1_H_len = 2;
+ }
+ } else {
+ cb802_1_H_len = 0;
+ }
+
+ cbFrameBodySize = uSkbPacketLen - ETH_HLEN + cb802_1_H_len;
+
+ //Set packet type
+ pTxBufHead->wFIFOCtl |= (u16)(byPktType<<8);
+
+ if (pDevice->dwDiagRefCount != 0) {
+ bNeedACK = false;
+ pTxBufHead->wFIFOCtl = pTxBufHead->wFIFOCtl & (~FIFOCTL_NEEDACK);
+ } else { //if (pDevice->dwDiagRefCount != 0) {
+ if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
+ (pDevice->eOPMode == OP_MODE_AP)) {
+ if (is_multicast_ether_addr(psEthHeader->h_dest)) {
+ bNeedACK = false;
+ pTxBufHead->wFIFOCtl =
+ pTxBufHead->wFIFOCtl & (~FIFOCTL_NEEDACK);
+ } else {
+ bNeedACK = true;
+ pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
+ }
+ }
+ else {
+ // MSDUs in Infra mode always need ACK
+ bNeedACK = true;
+ pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
+ }
+ } //if (pDevice->dwDiagRefCount != 0) {
+
+ pTxBufHead->wTimeStamp = DEFAULT_MSDU_LIFETIME_RES_64us;
+
+ //Set FIFOCTL_LHEAD
+ if (pDevice->bLongHeader)
+ pTxBufHead->wFIFOCtl |= FIFOCTL_LHEAD;
+
+ if (pDevice->bSoftwareGenCrcErr) {
+ pTxBufHead->wFIFOCtl |= FIFOCTL_CRCDIS; // set tx descriptors to NO hardware CRC
+ }
+
+ //Set FRAGCTL_MACHDCNT
+ if (pDevice->bLongHeader) {
+ cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6;
+ } else {
+ cbMACHdLen = WLAN_HDR_ADDR3_LEN;
+ }
+ pTxBufHead->wFragCtl |= (u16)(cbMACHdLen << 10);
+
+ //Set FIFOCTL_GrpAckPolicy
+ if (pDevice->bGrpAckPolicy == true) {//0000 0100 0000 0000
+ pTxBufHead->wFIFOCtl |= FIFOCTL_GRPACK;
+ }
+
+ //Set Auto Fallback Ctl
+ if (wCurrentRate >= RATE_18M) {
+ if (pDevice->byAutoFBCtrl == AUTO_FB_0) {
+ pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_0;
+ byFBOption = AUTO_FB_0;
+ } else if (pDevice->byAutoFBCtrl == AUTO_FB_1) {
+ pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_1;
+ byFBOption = AUTO_FB_1;
+ }
+ }
+
+ if (bSoftWEP != true) {
+ if ((bNeedEncryption) && (pTransmitKey != NULL)) { //WEP enabled
+ if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) { //WEP40 or WEP104
+ pTxBufHead->wFragCtl |= FRAGCTL_LEGACY;
+ }
+ if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Tx Set wFragCtl == FRAGCTL_TKIP\n");
+ pTxBufHead->wFragCtl |= FRAGCTL_TKIP;
+ }
+ else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) { //CCMP
+ pTxBufHead->wFragCtl |= FRAGCTL_AES;
+ }
+ }
+ }
+
+ if ((bNeedEncryption) && (pTransmitKey != NULL)) {
+ 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;
+ }
+ if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) {
+ cbIVlen = 8;//RSN Header
+ cbICVlen = 8;//MIC
+ cbMICHDR = sizeof(SMICHDRHead);
+ }
+ if (bSoftWEP == false) {
+ //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) ) {
+ bRTS = false;
+ } else {
+ bRTS = true;
+ pTxBufHead->wFIFOCtl |= (FIFOCTL_RTS | FIFOCTL_LRETRY);
+ }
+
+ pbyTxBufferAddr = (u8 *) &(pTxBufHead->adwTxKey[0]);
+ wTxBufSize = sizeof(STxBufHead);
+ if (byPktType == PK_TYPE_11GB || byPktType == 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 if (bRTS == false) { //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) {//RTS_need
+ 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(SRrvTime_ab) + cbMICHDR + sizeof(SRTS_ab));
+ cbHeaderLength = wTxBufSize + sizeof(PSRrvTime_ab) + cbMICHDR + sizeof(SRTS_ab) + sizeof(STxDataHead_ab);
+ }
+ else if (bRTS == false) { //RTS_needless, no 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(SRrvTime_ab) + cbMICHDR + sizeof(SRTS_a_FB));
+ cbHeaderLength = wTxBufSize + sizeof(PSRrvTime_ab) + cbMICHDR + sizeof(SRTS_a_FB) + sizeof(STxDataHead_a_FB);
+ }
+ else if (bRTS == false) { //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
+ }
+
+ pbyMacHdr = (u8 *)(pbyTxBufferAddr + cbHeaderLength);
+ pbyIVHead = (u8 *)(pbyMacHdr + cbMACHdLen + uPadding);
+ pbyPayloadHead = (u8 *)(pbyMacHdr + cbMACHdLen + uPadding + cbIVlen);
+
+ //=========================
+ // No Fragmentation
+ //=========================
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No Fragmentation...\n");
+ byFragType = FRAGCTL_NONFRAG;
+ //uDMAIdx = TYPE_AC0DMA;
+ //pTxBufHead = (PSTxBufHead) &(pTxBufHead->adwTxKey[0]);
+
+ //Fill FIFO,RrvTime,RTS,and CTS
+ s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate,
+ (void *)pbyTxBufferAddr, pvRrvTime, pvRTS, pvCTS,
+ cbFrameSize, bNeedACK, uDMAIdx, psEthHeader);
+ //Fill DataHead
+ uDuration = s_uFillDataHead(pDevice, byPktType, wCurrentRate, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK,
+ 0, 0, 1/*uMACfragNum*/, byFBOption);
+ // Generate TX MAC Header
+ s_vGenerateMACHeader(pDevice, pbyMacHdr, (u16)uDuration, psEthHeader, bNeedEncryption,
+ byFragType, uDMAIdx, 0);
+
+ if (bNeedEncryption == true) {
+ //Fill TXKEY
+ s_vFillTxKey(pDevice, (u8 *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey,
+ pbyMacHdr, (u16)cbFrameBodySize, (u8 *)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->h_proto) > ETH_DATA_LEN) {
+ if (pDevice->dwDiagRefCount == 0) {
+ if ((psEthHeader->h_proto == cpu_to_be16(ETH_P_IPX)) ||
+ (psEthHeader->h_proto == cpu_to_le16(0xF380))) {
+ memcpy((u8 *) (pbyPayloadHead),
+ abySNAP_Bridgetunnel, 6);
+ } else {
+ memcpy((u8 *) (pbyPayloadHead), &abySNAP_RFC1042[0], 6);
+ }
+ pbyType = (u8 *) (pbyPayloadHead + 6);
+ memcpy(pbyType, &(psEthHeader->h_proto), sizeof(u16));
+ } else {
+ memcpy((u8 *) (pbyPayloadHead), &(psEthHeader->h_proto), sizeof(u16));
+
+ }
+
+ }
+
+ if (pPacket != NULL) {
+ // Copy the Packet into a tx Buffer
+ memcpy((pbyPayloadHead + cb802_1_H_len),
+ (pPacket + ETH_HLEN),
+ uSkbPacketLen - ETH_HLEN
+ );
+
+ } else {
+ // while bRelayPacketSend psEthHeader is point to header+payload
+ memcpy((pbyPayloadHead + cb802_1_H_len), ((u8 *)psEthHeader) + ETH_HLEN, uSkbPacketLen - ETH_HLEN);
+ }
+
+ ASSERT(uLength == cbNdisBodySize);
+
+ if ((bNeedEncryption == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
+
+ ///////////////////////////////////////////////////////////////////
+
+ if (pDevice->vnt_mgmt.eAuthenMode == WMAC_AUTH_WPANONE) {
+ dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[16]);
+ dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[20]);
+ }
+ else if ((pTransmitKey->dwKeyIndex & AUTHENTICATOR_KEY) != 0) {
+ dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[16]);
+ dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[20]);
+ }
+ else {
+ dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[24]);
+ dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[28]);
+ }
+ // DO Software Michael
+ MIC_vInit(dwMICKey0, dwMICKey1);
+ MIC_vAppend((u8 *)&(psEthHeader->h_dest[0]), 12);
+ dwMIC_Priority = 0;
+ MIC_vAppend((u8 *)&dwMIC_Priority, 4);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC KEY: %X, %X\n",
+ dwMICKey0, dwMICKey1);
+
+ ///////////////////////////////////////////////////////////////////
+
+ //DBG_PRN_GRP12(("Length:%d, %d\n", cbFrameBodySize, uFromHDtoPLDLength));
+ //for (ii = 0; ii < cbFrameBodySize; ii++) {
+ // DBG_PRN_GRP12(("%02x ", *((u8 *)((pbyPayloadHead + cb802_1_H_len) + ii))));
+ //}
+ //DBG_PRN_GRP12(("\n\n\n"));
+
+ MIC_vAppend(pbyPayloadHead, cbFrameBodySize);
+
+ pdwMIC_L = (u32 *)(pbyPayloadHead + cbFrameBodySize);
+ pdwMIC_R = (u32 *)(pbyPayloadHead + cbFrameBodySize + 4);
+
+ MIC_vGetMIC(pdwMIC_L, pdwMIC_R);
+ MIC_vUnInit();
+
+ if (pDevice->bTxMICFail == true) {
+ *pdwMIC_L = 0;
+ *pdwMIC_R = 0;
+ pDevice->bTxMICFail = false;
+ }
+ //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"uLength: %d, %d\n", uLength, cbFrameBodySize);
+ //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"cbReqCount:%d, %d, %d, %d\n", cbReqCount, cbHeaderLength, uPadding, cbIVlen);
+ //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC:%lX, %lX\n", *pdwMIC_L, *pdwMIC_R);
+ }
+
+ if (bSoftWEP == true) {
+
+ s_vSWencryption(pDevice, pTransmitKey, (pbyPayloadHead), (u16)(cbFrameBodySize + cbMIClen));
+
+ } else if ( ((pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) && (bNeedEncryption == true)) ||
+ ((pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) && (bNeedEncryption == true)) ||
+ ((pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) && (bNeedEncryption == true)) ) {
+ cbFrameSize -= cbICVlen;
+ }
+
+ if (pDevice->bSoftwareGenCrcErr == true) {
+ unsigned int cbLen;
+ u32 * pdwCRC;
+
+ dwCRC = 0xFFFFFFFFL;
+ cbLen = cbFrameSize - cbFCSlen;
+ // calculate CRC, and wrtie CRC value to end of TD
+ dwCRC = CRCdwGetCrc32Ex(pbyMacHdr, cbLen, dwCRC);
+ pdwCRC = (u32 *)(pbyMacHdr + cbLen);
+ // finally, we must invert dwCRC to get the correct answer
+ *pdwCRC = ~dwCRC;
+ // Force Error
+ *pdwCRC -= 1;
+ } else {
+ cbFrameSize -= cbFCSlen;
+ }
+
+ *pcbHeaderLen = cbHeaderLength;
+ *pcbTotalLen = cbHeaderLength + cbFrameSize ;
+
+ //Set FragCtl in TxBufferHead
+ pTxBufHead->wFragCtl |= (u16)byFragType;
+
+ return true;
+
+}
+
+/*+
+ *
+ * Description:
+ * Translate 802.3 to 802.11 header
+ *
+ * Parameters:
+ * In:
+ * pDevice - Pointer to adapter
+ * 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
+ *
+-*/
+
+static void s_vGenerateMACHeader(struct vnt_private *pDevice,
+ u8 *pbyBufferAddr, u16 wDuration, struct ethhdr *psEthHeader,
+ int bNeedEncrypt, u16 wFragType, u32 uDMAIdx, u32 uFragIdx)
+{
+ struct ieee80211_hdr *pMACHeader = (struct ieee80211_hdr *)pbyBufferAddr;
+
+ memset(pMACHeader, 0, (sizeof(struct ieee80211_hdr)));
+
+ if (uDMAIdx == TYPE_ATIMDMA) {
+ pMACHeader->frame_control = TYPE_802_11_ATIM;
+ } else {
+ pMACHeader->frame_control = TYPE_802_11_DATA;
+ }
+
+ if (pDevice->eOPMode == OP_MODE_AP) {
+ memcpy(&(pMACHeader->addr1[0]),
+ &(psEthHeader->h_dest[0]),
+ ETH_ALEN);
+ memcpy(&(pMACHeader->addr2[0]), &(pDevice->abyBSSID[0]), ETH_ALEN);
+ memcpy(&(pMACHeader->addr3[0]),
+ &(psEthHeader->h_source[0]),
+ ETH_ALEN);
+ pMACHeader->frame_control |= FC_FROMDS;
+ } else {
+ if (pDevice->eOPMode == OP_MODE_ADHOC) {
+ memcpy(&(pMACHeader->addr1[0]),
+ &(psEthHeader->h_dest[0]),
+ ETH_ALEN);
+ memcpy(&(pMACHeader->addr2[0]),
+ &(psEthHeader->h_source[0]),
+ ETH_ALEN);
+ memcpy(&(pMACHeader->addr3[0]),
+ &(pDevice->abyBSSID[0]),
+ ETH_ALEN);
+ } else {
+ memcpy(&(pMACHeader->addr3[0]),
+ &(psEthHeader->h_dest[0]),
+ ETH_ALEN);
+ memcpy(&(pMACHeader->addr2[0]),
+ &(psEthHeader->h_source[0]),
+ ETH_ALEN);
+ memcpy(&(pMACHeader->addr1[0]),
+ &(pDevice->abyBSSID[0]),
+ ETH_ALEN);
+ pMACHeader->frame_control |= FC_TODS;
+ }
+ }
+
+ if (bNeedEncrypt)
+ pMACHeader->frame_control |= cpu_to_le16((u16)WLAN_SET_FC_ISWEP(1));
+
+ pMACHeader->duration_id = cpu_to_le16(wDuration);
+
+ if (pDevice->bLongHeader) {
+ PWLAN_80211HDR_A4 pMACA4Header = (PWLAN_80211HDR_A4) pbyBufferAddr;
+ pMACHeader->frame_control |= (FC_TODS | FC_FROMDS);
+ memcpy(pMACA4Header->abyAddr4, pDevice->abyBSSID, WLAN_ADDR_LEN);
+ }
+ pMACHeader->seq_ctrl = cpu_to_le16(pDevice->wSeqCounter << 4);
+
+ //Set FragNumber in Sequence Control
+ pMACHeader->seq_ctrl |= cpu_to_le16((u16)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->frame_control |= FC_MOREFRAG;
+ }
+}
+
+/*+
+ *
+ * Description:
+ * Request instructs a MAC to transmit a 802.11 management packet through
+ * the adapter onto the medium.
+ *
+ * Parameters:
+ * In:
+ * hDeviceContext - Pointer to the adapter
+ * pPacket - A pointer to a descriptor for the packet to transmit
+ * Out:
+ * none
+ *
+ * Return Value: CMD_STATUS_PENDING if MAC Tx resource available; otherwise false
+ *
+-*/
+
+CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice,
+ struct vnt_tx_mgmt *pPacket)
+{
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ PTX_BUFFER pTX_Buffer;
+ PSTxBufHead pTxBufHead;
+ PUSB_SEND_CONTEXT pContext;
+ struct ieee80211_hdr *pMACHeader;
+ PSCTS pCTS;
+ struct ethhdr sEthHeader;
+ u8 byPktType, *pbyTxBufferAddr;
+ void *pvRTS, *pvTxDataHd, *pvRrvTime, *pMICHDR;
+ u32 uDuration, cbReqCount, cbHeaderSize, cbFrameBodySize, cbFrameSize;
+ int bNeedACK, bIsPSPOLL = false;
+ u32 cbIVlen = 0, cbICVlen = 0, cbMIClen = 0, cbFCSlen = 4;
+ u32 uPadding = 0;
+ u16 wTxBufSize;
+ u32 cbMacHdLen;
+ u16 wCurrentRate = RATE_1M;
+
+ pContext = (PUSB_SEND_CONTEXT)s_vGetFreeContext(pDevice);
+
+ if (NULL == pContext) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ManagementSend TX...NO CONTEXT!\n");
+ return CMD_STATUS_RESOURCES;
+ }
+
+ pTX_Buffer = (PTX_BUFFER) (&pContext->Data[0]);
+ pbyTxBufferAddr = (u8 *)&(pTX_Buffer->adwTxKey[0]);
+ cbFrameBodySize = pPacket->cbPayloadLen;
+ pTxBufHead = (PSTxBufHead) pbyTxBufferAddr;
+ wTxBufSize = sizeof(STxBufHead);
+ memset(pTxBufHead, 0, wTxBufSize);
+
+ if (pDevice->byBBType == BB_TYPE_11A) {
+ wCurrentRate = RATE_6M;
+ byPktType = PK_TYPE_11A;
+ } else {
+ wCurrentRate = RATE_1M;
+ byPktType = 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 (pMgmt->eScanState != WMAC_NO_SCANNING) {
+ RFbSetPower(pDevice, wCurrentRate, pDevice->byCurrentCh);
+ } else {
+ RFbSetPower(pDevice, wCurrentRate, pMgmt->uCurrChannel);
+ }
+ pDevice->wCurrentRate = wCurrentRate;
+
+ //Set packet type
+ if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000
+ pTxBufHead->wFIFOCtl = 0;
+ }
+ else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000
+ pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
+ }
+ else if (byPktType == PK_TYPE_11GB) {//0000 0010 0000 0000
+ pTxBufHead->wFIFOCtl |= FIFOCTL_11GB;
+ }
+ else if (byPktType == 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_ether_addr(pPacket->p80211Header->sA3.abyAddr1)) {
+ 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((u16)(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 (byPktType == PK_TYPE_11GB || byPktType == 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);
+ }
+
+ memset((void *)(pbyTxBufferAddr + wTxBufSize), 0,
+ (cbHeaderSize - wTxBufSize));
+
+ memcpy(&(sEthHeader.h_dest[0]),
+ &(pPacket->p80211Header->sA3.abyAddr1[0]),
+ ETH_ALEN);
+ memcpy(&(sEthHeader.h_source[0]),
+ &(pPacket->p80211Header->sA3.abyAddr2[0]),
+ ETH_ALEN);
+ //=========================
+ // No Fragmentation
+ //=========================
+ pTxBufHead->wFragCtl |= (u16)FRAGCTL_NONFRAG;
+
+ //Fill FIFO,RrvTime,RTS,and CTS
+ s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate, pbyTxBufferAddr, pvRrvTime, pvRTS, pCTS,
+ cbFrameSize, bNeedACK, TYPE_TXDMA0, &sEthHeader);
+
+ //Fill DataHead
+ uDuration = s_uFillDataHead(pDevice, byPktType, wCurrentRate, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK,
+ 0, 0, 1, AUTO_FB_NONE);
+
+ pMACHeader = (struct ieee80211_hdr *) (pbyTxBufferAddr + cbHeaderSize);
+
+ cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + cbFrameBodySize;
+
+ if (WLAN_GET_FC_ISWEP(pPacket->p80211Header->sA4.wFrameCtl) != 0) {
+ u8 * pbyIVHead;
+ u8 * pbyPayloadHead;
+ u8 * pbyBSSID;
+ PSKeyItem pTransmitKey = NULL;
+
+ pbyIVHead = (u8 *)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding);
+ pbyPayloadHead = (u8 *)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding + cbIVlen);
+ 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) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get GTK.\n");
+ break;
+ }
+ } else {
+ DBG_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;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KEY is NULL. OP Mode[%d]\n", pDevice->eOPMode);
+ } else {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get GTK.\n");
+ }
+ } while(false);
+ //Fill TXKEY
+ s_vFillTxKey(pDevice, (u8 *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey,
+ (u8 *)pMACHeader, (u16)cbFrameBodySize, NULL);
+
+ memcpy(pMACHeader, pPacket->p80211Header, cbMacHdLen);
+ memcpy(pbyPayloadHead, ((u8 *)(pPacket->p80211Header) + cbMacHdLen),
+ cbFrameBodySize);
+ }
+ else {
+ // Copy the Packet into a tx Buffer
+ memcpy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen);
+ }
+
+ pMACHeader->seq_ctrl = 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 (byPktType == PK_TYPE_11GB || byPktType == 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);
+ }
+ }
+
+ pTX_Buffer->wTxByteCount = cpu_to_le16((u16)(cbReqCount));
+ pTX_Buffer->byPKTNO = (u8) (((wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
+ pTX_Buffer->byType = 0x00;
+
+ pContext->pPacket = NULL;
+ pContext->Type = CONTEXT_MGMT_PACKET;
+ pContext->uBufLen = (u16)cbReqCount + 4; //USB header
+
+ if (WLAN_GET_FC_TODS(pMACHeader->frame_control) == 0) {
+ s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->addr1[0]), (u16)cbFrameSize, pTX_Buffer->wFIFOCtl);
+ }
+ else {
+ s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->addr3[0]), (u16)cbFrameSize, pTX_Buffer->wFIFOCtl);
+ }
+
+ PIPEnsSendBulkOut(pDevice,pContext);
+ return CMD_STATUS_PENDING;
+}
+
+CMD_STATUS csBeacon_xmit(struct vnt_private *pDevice,
+ struct vnt_tx_mgmt *pPacket)
+{
+ u32 cbFrameSize = pPacket->cbMPDULen + WLAN_FCS_LEN;
+ u32 cbHeaderSize = 0;
+ u16 wTxBufSize = sizeof(STxShortBufHead);
+ PSTxShortBufHead pTxBufHead;
+ struct ieee80211_hdr *pMACHeader;
+ PSTxDataHead_ab pTxDataHead;
+ u16 wCurrentRate;
+ u32 cbFrameBodySize;
+ u32 cbReqCount;
+ PBEACON_BUFFER pTX_Buffer;
+ u8 *pbyTxBufferAddr;
+ PUSB_SEND_CONTEXT pContext;
+ CMD_STATUS status;
+
+ pContext = (PUSB_SEND_CONTEXT)s_vGetFreeContext(pDevice);
+ if (NULL == pContext) {
+ status = CMD_STATUS_RESOURCES;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ManagementSend TX...NO CONTEXT!\n");
+ return status ;
+ }
+ pTX_Buffer = (PBEACON_BUFFER) (&pContext->Data[0]);
+ pbyTxBufferAddr = (u8 *)&(pTX_Buffer->wFIFOCtl);
+
+ cbFrameBodySize = pPacket->cbPayloadLen;
+
+ pTxBufHead = (PSTxShortBufHead) pbyTxBufferAddr;
+ wTxBufSize = sizeof(STxShortBufHead);
+ memset(pTxBufHead, 0, wTxBufSize);
+
+ if (pDevice->byBBType == BB_TYPE_11A) {
+ wCurrentRate = RATE_6M;
+ pTxDataHead = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize);
+ //Get SignalField,ServiceField,Length
+ BBvCalculateParameter(pDevice, cbFrameSize, wCurrentRate, PK_TYPE_11A,
+ (u16 *)&(pTxDataHead->wTransmitLength), (u8 *)&(pTxDataHead->byServiceField), (u8 *)&(pTxDataHead->bySignalField)
+ );
+ //Get Duration and TimeStampOff
+ pTxDataHead->wDuration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameSize, PK_TYPE_11A,
+ wCurrentRate, false, 0, 0, 1, AUTO_FB_NONE));
+ pTxDataHead->wTimeStampOff = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
+ cbHeaderSize = wTxBufSize + sizeof(STxDataHead_ab);
+ } else {
+ wCurrentRate = RATE_1M;
+ pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
+ pTxDataHead = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize);
+ //Get SignalField,ServiceField,Length
+ BBvCalculateParameter(pDevice, cbFrameSize, wCurrentRate, PK_TYPE_11B,
+ (u16 *)&(pTxDataHead->wTransmitLength), (u8 *)&(pTxDataHead->byServiceField), (u8 *)&(pTxDataHead->bySignalField)
+ );
+ //Get Duration and TimeStampOff
+ pTxDataHead->wDuration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameSize, PK_TYPE_11B,
+ wCurrentRate, false, 0, 0, 1, AUTO_FB_NONE));
+ pTxDataHead->wTimeStampOff = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
+ cbHeaderSize = wTxBufSize + sizeof(STxDataHead_ab);
+ }
+
+ //Generate Beacon Header
+ pMACHeader = (struct ieee80211_hdr *)(pbyTxBufferAddr + cbHeaderSize);
+ memcpy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen);
+
+ pMACHeader->duration_id = 0;
+ pMACHeader->seq_ctrl = cpu_to_le16(pDevice->wSeqCounter << 4);
+ pDevice->wSeqCounter++ ;
+ if (pDevice->wSeqCounter > 0x0fff)
+ pDevice->wSeqCounter = 0;
+
+ cbReqCount = cbHeaderSize + WLAN_HDR_ADDR3_LEN + cbFrameBodySize;
+
+ pTX_Buffer->wTxByteCount = (u16)cbReqCount;
+ pTX_Buffer->byPKTNO = (u8) (((wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
+ pTX_Buffer->byType = 0x01;
+
+ pContext->pPacket = NULL;
+ pContext->Type = CONTEXT_MGMT_PACKET;
+ pContext->uBufLen = (u16)cbReqCount + 4; //USB header
+
+ PIPEnsSendBulkOut(pDevice,pContext);
+ return CMD_STATUS_PENDING;
+
+}
+
+void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb)
+{
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ u8 byPktType;
+ u8 *pbyTxBufferAddr;
+ void *pvRTS, *pvCTS, *pvTxDataHd;
+ u32 uDuration, cbReqCount;
+ struct ieee80211_hdr *pMACHeader;
+ u32 cbHeaderSize, cbFrameBodySize;
+ int bNeedACK, bIsPSPOLL = false;
+ PSTxBufHead pTxBufHead;
+ u32 cbFrameSize;
+ u32 cbIVlen = 0, cbICVlen = 0, cbMIClen = 0, cbFCSlen = 4;
+ u32 uPadding = 0;
+ u32 cbMICHDR = 0, uLength = 0;
+ u32 dwMICKey0, dwMICKey1;
+ u32 dwMIC_Priority;
+ u32 *pdwMIC_L, *pdwMIC_R;
+ u16 wTxBufSize;
+ u32 cbMacHdLen;
+ struct ethhdr sEthHeader;
+ void *pvRrvTime, *pMICHDR;
+ u32 wCurrentRate = RATE_1M;
+ PUWLAN_80211HDR p80211Header;
+ u32 uNodeIndex = 0;
+ int bNodeExist = false;
+ SKeyItem STempKey;
+ PSKeyItem pTransmitKey = NULL;
+ u8 *pbyIVHead, *pbyPayloadHead, *pbyMacHdr;
+ u32 cbExtSuppRate = 0;
+ PTX_BUFFER pTX_Buffer;
+ PUSB_SEND_CONTEXT pContext;
+
+ pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL;
+
+ if(skb->len <= WLAN_HDR_ADDR3_LEN) {
+ cbFrameBodySize = 0;
+ }
+ else {
+ cbFrameBodySize = skb->len - WLAN_HDR_ADDR3_LEN;
+ }
+ p80211Header = (PUWLAN_80211HDR)skb->data;
+
+ pContext = (PUSB_SEND_CONTEXT)s_vGetFreeContext(pDevice);
+
+ if (NULL == pContext) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"DMA0 TX...NO CONTEXT!\n");
+ dev_kfree_skb_irq(skb);
+ return ;
+ }
+
+ pTX_Buffer = (PTX_BUFFER)(&pContext->Data[0]);
+ pbyTxBufferAddr = (u8 *)(&pTX_Buffer->adwTxKey[0]);
+ pTxBufHead = (PSTxBufHead) pbyTxBufferAddr;
+ wTxBufSize = sizeof(STxBufHead);
+ memset(pTxBufHead, 0, wTxBufSize);
+
+ if (pDevice->byBBType == BB_TYPE_11A) {
+ wCurrentRate = RATE_6M;
+ byPktType = PK_TYPE_11A;
+ } else {
+ wCurrentRate = RATE_1M;
+ byPktType = 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 (pMgmt->eScanState != WMAC_NO_SCANNING) {
+ RFbSetPower(pDevice, wCurrentRate, pDevice->byCurrentCh);
+ } else {
+ RFbSetPower(pDevice, wCurrentRate, pMgmt->uCurrChannel);
+ }
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vDMA0_tx_80211: p80211Header->sA3.wFrameCtl = %x \n", p80211Header->sA3.wFrameCtl);
+
+ //Set packet type
+ if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000
+ pTxBufHead->wFIFOCtl = 0;
+ }
+ else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000
+ pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
+ }
+ else if (byPktType == PK_TYPE_11GB) {//0000 0010 0000 0000
+ pTxBufHead->wFIFOCtl |= FIFOCTL_11GB;
+ }
+ else if (byPktType == 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_ether_addr(p80211Header->sA3.abyAddr1)) {
+ bNeedACK = false;
+ if (pDevice->bEnableHostWEP) {
+ uNodeIndex = 0;
+ bNodeExist = true;
+ }
+ }
+ else {
+ if (pDevice->bEnableHostWEP) {
+ if (BSSbIsSTAInNodeDB(pDevice, (u8 *)(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 daemon 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((u16)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 (byPktType == PK_TYPE_11GB || byPktType == 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);
+ }
+ memset((void *)(pbyTxBufferAddr + wTxBufSize), 0,
+ (cbHeaderSize - wTxBufSize));
+ memcpy(&(sEthHeader.h_dest[0]),
+ &(p80211Header->sA3.abyAddr1[0]),
+ ETH_ALEN);
+ memcpy(&(sEthHeader.h_source[0]),
+ &(p80211Header->sA3.abyAddr2[0]),
+ ETH_ALEN);
+ //=========================
+ // No Fragmentation
+ //=========================
+ pTxBufHead->wFragCtl |= (u16)FRAGCTL_NONFRAG;
+
+ //Fill FIFO,RrvTime,RTS,and CTS
+ s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate, pbyTxBufferAddr, pvRrvTime, pvRTS, pvCTS,
+ cbFrameSize, bNeedACK, TYPE_TXDMA0, &sEthHeader);
+
+ //Fill DataHead
+ uDuration = s_uFillDataHead(pDevice, byPktType, wCurrentRate, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK,
+ 0, 0, 1, AUTO_FB_NONE);
+
+ pMACHeader = (struct ieee80211_hdr *) (pbyTxBufferAddr + cbHeaderSize);
+
+ cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + (cbFrameBodySize + cbMIClen) + cbExtSuppRate;
+
+ pbyMacHdr = (u8 *)(pbyTxBufferAddr + cbHeaderSize);
+ pbyPayloadHead = (u8 *)(pbyMacHdr + cbMacHdLen + uPadding + cbIVlen);
+ pbyIVHead = (u8 *)(pbyMacHdr + cbMacHdLen + uPadding);
+
+ // Copy the Packet into a tx Buffer
+ memcpy(pbyMacHdr, skb->data, cbMacHdLen);
+
+ // version set to 0, patch for hostapd deamon
+ pMACHeader->frame_control &= cpu_to_le16(0xfffc);
+ memcpy(pbyPayloadHead, (skb->data + cbMacHdLen), cbFrameBodySize);
+
+ // replace support rate, patch for hostapd daemon( 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 = *(u32 *)(&pTransmitKey->abyKey[16]);
+ dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[20]);
+
+ // DO Software Michael
+ MIC_vInit(dwMICKey0, dwMICKey1);
+ MIC_vAppend((u8 *)&(sEthHeader.h_dest[0]), 12);
+ dwMIC_Priority = 0;
+ MIC_vAppend((u8 *)&dwMIC_Priority, 4);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"DMA0_tx_8021:MIC KEY:"\
+ " %X, %X\n", dwMICKey0, dwMICKey1);
+
+ uLength = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen;
+
+ MIC_vAppend((pbyTxBufferAddr + uLength), cbFrameBodySize);
+
+ pdwMIC_L = (u32 *)(pbyTxBufferAddr + uLength + cbFrameBodySize);
+ pdwMIC_R = (u32 *)(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;
+ }
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"uLength: %d, %d\n", uLength, cbFrameBodySize);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"cbReqCount:%d, %d, %d, %d\n", cbReqCount, cbHeaderSize, uPadding, cbIVlen);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC:%x, %x\n",
+ *pdwMIC_L, *pdwMIC_R);
+
+ }
+
+ s_vFillTxKey(pDevice, (u8 *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey,
+ pbyMacHdr, (u16)cbFrameBodySize, (u8 *)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, (u16)(cbFrameBodySize + cbMIClen));
+ }
+ }
+
+ pMACHeader->seq_ctrl = 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 (byPktType == PK_TYPE_11GB || byPktType == 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);
+ }
+ }
+
+ pTX_Buffer->wTxByteCount = cpu_to_le16((u16)(cbReqCount));
+ pTX_Buffer->byPKTNO = (u8) (((wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
+ pTX_Buffer->byType = 0x00;
+
+ pContext->pPacket = skb;
+ pContext->Type = CONTEXT_MGMT_PACKET;
+ pContext->uBufLen = (u16)cbReqCount + 4; //USB header
+
+ if (WLAN_GET_FC_TODS(pMACHeader->frame_control) == 0) {
+ s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->addr1[0]), (u16)cbFrameSize, pTX_Buffer->wFIFOCtl);
+ }
+ else {
+ s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->addr3[0]), (u16)cbFrameSize, pTX_Buffer->wFIFOCtl);
+ }
+ PIPEnsSendBulkOut(pDevice,pContext);
+ return ;
+
+}
+
+//TYPE_AC0DMA data tx
+/*
+ * Description:
+ * Tx packet via AC0DMA(DMA1)
+ *
+ * Parameters:
+ * In:
+ * pDevice - Pointer to the adapter
+ * skb - Pointer to tx skb packet
+ * Out:
+ * void
+ *
+ * Return Value: NULL
+ */
+
+int nsDMA_tx_packet(struct vnt_private *pDevice,
+ u32 uDMAIdx, struct sk_buff *skb)
+{
+ struct net_device_stats *pStats = &pDevice->stats;
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ u32 BytesToWrite = 0, uHeaderLen = 0;
+ u32 uNodeIndex = 0;
+ u8 byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
+ u16 wAID;
+ u8 byPktType;
+ int bNeedEncryption = false;
+ PSKeyItem pTransmitKey = NULL;
+ SKeyItem STempKey;
+ int ii;
+ int bTKIP_UseGTK = false;
+ int bNeedDeAuth = false;
+ u8 *pbyBSSID;
+ int bNodeExist = false;
+ PUSB_SEND_CONTEXT pContext;
+ bool fConvertedPacket;
+ PTX_BUFFER pTX_Buffer;
+ u32 status;
+ u16 wKeepRate = pDevice->wCurrentRate;
+ int bTxeapol_key = false;
+
+ if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
+
+ if (pDevice->uAssocCount == 0) {
+ dev_kfree_skb_irq(skb);
+ return 0;
+ }
+
+ if (is_multicast_ether_addr((u8 *)(skb->data))) {
+ uNodeIndex = 0;
+ bNodeExist = true;
+ if (pMgmt->sNodeDBTable[0].bPSEnable) {
+
+ skb_queue_tail(&(pMgmt->sNodeDBTable[0].sTxPSQueue), skb);
+ pMgmt->sNodeDBTable[0].wEnQueueCnt++;
+ // set tx map
+ pMgmt->abyPSTxMap[0] |= byMask[0];
+ return 0;
+ }
+ // multicast/broadcast data rate
+
+ if (pDevice->byBBType != BB_TYPE_11A)
+ pDevice->wCurrentRate = RATE_2M;
+ else
+ pDevice->wCurrentRate = RATE_24M;
+ // long preamble type
+ pDevice->byPreambleType = PREAMBLE_SHORT;
+
+ }else {
+
+ if (BSSbIsSTAInNodeDB(pDevice, (u8 *)(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];
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set:pMgmt->abyPSTxMap[%d]= %d\n",
+ (wAID >> 3), pMgmt->abyPSTxMap[wAID >> 3]);
+
+ return 0;
+ }
+ // AP rate decided from node
+ pDevice->wCurrentRate = pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate;
+ // tx preamble decided from node
+
+ if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble) {
+ pDevice->byPreambleType = pDevice->byShortPreamble;
+
+ }else {
+ pDevice->byPreambleType = PREAMBLE_LONG;
+ }
+ bNodeExist = true;
+ }
+ }
+
+ if (bNodeExist == false) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Unknown STA not found in node DB \n");
+ dev_kfree_skb_irq(skb);
+ return 0;
+ }
+ }
+
+ pContext = (PUSB_SEND_CONTEXT)s_vGetFreeContext(pDevice);
+
+ if (pContext == NULL) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG" pContext == NULL\n");
+ dev_kfree_skb_irq(skb);
+ return STATUS_RESOURCES;
+ }
+
+ memcpy(pDevice->sTxEthHeader.h_dest, (u8 *)(skb->data), ETH_HLEN);
+
+//mike add:station mode check eapol-key challenge--->
+{
+ u8 Protocol_Version; //802.1x Authentication
+ u8 Packet_Type; //802.1x Authentication
+ u8 Descriptor_type;
+ u16 Key_info;
+
+ Protocol_Version = skb->data[ETH_HLEN];
+ Packet_Type = skb->data[ETH_HLEN+1];
+ Descriptor_type = skb->data[ETH_HLEN+1+1+2];
+ Key_info = (skb->data[ETH_HLEN+1+1+2+1] << 8)|(skb->data[ETH_HLEN+1+1+2+2]);
+ if (pDevice->sTxEthHeader.h_proto == cpu_to_be16(ETH_P_PAE)) {
+ /* 802.1x OR eapol-key challenge frame transfer */
+ if (((Protocol_Version == 1) || (Protocol_Version == 2)) &&
+ (Packet_Type == 3)) {
+ bTxeapol_key = true;
+ if(!(Key_info & BIT3) && //WPA or RSN group-key challenge
+ (Key_info & BIT8) && (Key_info & BIT9)) { //send 2/2 key
+ if(Descriptor_type==254) {
+ pDevice->fWPA_Authened = true;
+ PRINT_K("WPA ");
+ }
+ else {
+ pDevice->fWPA_Authened = true;
+ PRINT_K("WPA2(re-keying) ");
+ }
+ PRINT_K("Authentication completed!!\n");
+ }
+ else if((Key_info & BIT3) && (Descriptor_type==2) && //RSN pairwise-key challenge
+ (Key_info & BIT8) && (Key_info & BIT9)) {
+ pDevice->fWPA_Authened = true;
+ PRINT_K("WPA2 Authentication completed!!\n");
+ }
+ }
+ }
+}
+//mike add:station mode check eapol-key challenge<---
+
+ if (pDevice->bEncryptionEnable == true) {
+ bNeedEncryption = true;
+ // get Transmit key
+ do {
+ if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
+ (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;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n");
+ break;
+ }
+ } else {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get PTK.\n");
+ break;
+ }
+ }else if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
+ /* TO_DS = 0 and FROM_DS = 0 --> 802.11 MAC Address1 */
+ pbyBSSID = pDevice->sTxEthHeader.h_dest;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"IBSS Serach Key: \n");
+ for (ii = 0; ii< 6; ii++)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"%x \n", *(pbyBSSID+ii));
+ DBG_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 (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"IBSS and KEY is NULL. [%d]\n", pMgmt->eCurrMode);
+ }
+ else
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"NOT IBSS and KEY is NULL. [%d]\n", pMgmt->eCurrMode);
+ } else {
+ bTKIP_UseGTK = true;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n");
+ }
+ } while(false);
+ }
+
+ if (pDevice->bEnableHostWEP) {
+ DBG_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
+ );
+ }
+ }
+
+ byPktType = (u8)pDevice->byPacketType;
+
+ if (pDevice->bFixRate) {
+ if (pDevice->byBBType == BB_TYPE_11B) {
+ if (pDevice->uConnectionRate >= RATE_11M) {
+ pDevice->wCurrentRate = RATE_11M;
+ } else {
+ pDevice->wCurrentRate = (u16)pDevice->uConnectionRate;
+ }
+ } else {
+ if ((pDevice->byBBType == BB_TYPE_11A) &&
+ (pDevice->uConnectionRate <= RATE_6M)) {
+ pDevice->wCurrentRate = RATE_6M;
+ } else {
+ if (pDevice->uConnectionRate >= RATE_54M)
+ pDevice->wCurrentRate = RATE_54M;
+ else
+ pDevice->wCurrentRate = (u16)pDevice->uConnectionRate;
+ }
+ }
+ }
+ else {
+ if (pDevice->eOPMode == OP_MODE_ADHOC) {
+ // Adhoc Tx rate decided from node DB
+ if (is_multicast_ether_addr(pDevice->sTxEthHeader.h_dest)) {
+ // Multicast use highest data rate
+ pDevice->wCurrentRate = pMgmt->sNodeDBTable[0].wTxDataRate;
+ // preamble type
+ pDevice->byPreambleType = pDevice->byShortPreamble;
+ }
+ else {
+ if (BSSbIsSTAInNodeDB(pDevice, &(pDevice->sTxEthHeader.h_dest[0]), &uNodeIndex)) {
+ pDevice->wCurrentRate = pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate;
+ if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble) {
+ pDevice->byPreambleType = pDevice->byShortPreamble;
+
+ }
+ else {
+ pDevice->byPreambleType = PREAMBLE_LONG;
+ }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Found Node Index is [%d] Tx Data Rate:[%d]\n",uNodeIndex, pDevice->wCurrentRate);
+ }
+ else {
+ if (pDevice->byBBType != BB_TYPE_11A)
+ pDevice->wCurrentRate = RATE_2M;
+ else
+ pDevice->wCurrentRate = RATE_24M; // refer to vMgrCreateOwnIBSS()'s
+ // abyCurrExtSuppRates[]
+ pDevice->byPreambleType = PREAMBLE_SHORT;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Not Found Node use highest basic Rate.....\n");
+ }
+ }
+ }
+ if (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) {
+ // Infra STA rate decided from AP Node, index = 0
+ pDevice->wCurrentRate = pMgmt->sNodeDBTable[0].wTxDataRate;
+ }
+ }
+
+ if (pDevice->sTxEthHeader.h_proto == cpu_to_be16(ETH_P_PAE)) {
+ if (pDevice->byBBType != BB_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;
+ }
+ }
+
+ DBG_PRT(MSG_LEVEL_DEBUG,
+ KERN_INFO "dma_tx: pDevice->wCurrentRate = %d\n",
+ pDevice->wCurrentRate);
+
+ if (wKeepRate != pDevice->wCurrentRate) {
+ bScheduleCommand((void *) pDevice, WLAN_CMD_SETPOWER, NULL);
+ }
+
+ if (pDevice->wCurrentRate <= RATE_11M) {
+ byPktType = PK_TYPE_11B;
+ }
+
+ if (bNeedEncryption == true) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ntohs Pkt Type=%04x\n", ntohs(pDevice->sTxEthHeader.h_proto));
+ if ((pDevice->sTxEthHeader.h_proto) == cpu_to_be16(ETH_P_PAE)) {
+ bNeedEncryption = false;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Pkt Type=%04x\n", (pDevice->sTxEthHeader.h_proto));
+ if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
+ if (pTransmitKey == NULL) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Don't Find TX KEY\n");
+ }
+ else {
+ if (bTKIP_UseGTK == true) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"error: KEY is GTK!!~~\n");
+ }
+ else {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Find PTK [%X]\n",
+ pTransmitKey->dwKeyIndex);
+ bNeedEncryption = true;
+ }
+ }
+ }
+
+ if (pDevice->bEnableHostWEP) {
+ if ((uNodeIndex != 0) &&
+ (pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex & PAIRWISE_KEY)) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Find PTK [%X]\n",
+ pTransmitKey->dwKeyIndex);
+ bNeedEncryption = true;
+ }
+ }
+ }
+ else {
+
+ if (pTransmitKey == NULL) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"return no tx key\n");
+ pContext->bBoolInUse = false;
+ dev_kfree_skb_irq(skb);
+ pStats->tx_dropped++;
+ return STATUS_FAILURE;
+ }
+ }
+ }
+
+ fConvertedPacket = s_bPacketToWirelessUsb(pDevice, byPktType,
+ (u8 *)(&pContext->Data[0]), bNeedEncryption,
+ skb->len, uDMAIdx, &pDevice->sTxEthHeader,
+ (u8 *)skb->data, pTransmitKey, uNodeIndex,
+ pDevice->wCurrentRate,
+ &uHeaderLen, &BytesToWrite
+ );
+
+ if (fConvertedPacket == false) {
+ pContext->bBoolInUse = false;
+ dev_kfree_skb_irq(skb);
+ return STATUS_FAILURE;
+ }
+
+ if ( pDevice->bEnablePSMode == true ) {
+ if ( !pDevice->bPSModeTxBurst ) {
+ bScheduleCommand((void *) pDevice,
+ WLAN_CMD_MAC_DISPOWERSAVING,
+ NULL);
+ pDevice->bPSModeTxBurst = true;
+ }
+ }
+
+ pTX_Buffer = (PTX_BUFFER)&(pContext->Data[0]);
+ pTX_Buffer->byPKTNO = (u8) (((pDevice->wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
+ pTX_Buffer->wTxByteCount = (u16)BytesToWrite;
+
+ pContext->pPacket = skb;
+ pContext->Type = CONTEXT_DATA_PACKET;
+ pContext->uBufLen = (u16)BytesToWrite + 4 ; //USB header
+
+ s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pContext->sEthHeader.h_dest[0]), (u16) (BytesToWrite-uHeaderLen), pTX_Buffer->wFIFOCtl);
+
+ status = PIPEnsSendBulkOut(pDevice,pContext);
+
+ if (bNeedDeAuth == true) {
+ u16 wReason = WLAN_MGMT_REASON_MIC_FAILURE;
+
+ bScheduleCommand((void *) pDevice, WLAN_CMD_DEAUTH, (u8 *) &wReason);
+ }
+
+ if(status!=STATUS_PENDING) {
+ pContext->bBoolInUse = false;
+ dev_kfree_skb_irq(skb);
+ return STATUS_FAILURE;
+ }
+ else
+ return 0;
+
+}
+
+/*
+ * Description:
+ * Relay packet send (AC1DMA) from rx dpc.
+ *
+ * Parameters:
+ * In:
+ * pDevice - Pointer to the adapter
+ * pPacket - Pointer to rx packet
+ * cbPacketSize - rx ethernet frame size
+ * Out:
+ * TURE, false
+ *
+ * Return Value: Return true if packet is copy to dma1; otherwise false
+ */
+
+int bRelayPacketSend(struct vnt_private *pDevice, u8 *pbySkbData, u32 uDataLen,
+ u32 uNodeIndex)
+{
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ u32 BytesToWrite = 0, uHeaderLen = 0;
+ u8 byPktType = PK_TYPE_11B;
+ int bNeedEncryption = false;
+ SKeyItem STempKey;
+ PSKeyItem pTransmitKey = NULL;
+ u8 *pbyBSSID;
+ PUSB_SEND_CONTEXT pContext;
+ u8 byPktTyp;
+ int fConvertedPacket;
+ PTX_BUFFER pTX_Buffer;
+ u32 status;
+ u16 wKeepRate = pDevice->wCurrentRate;
+
+ pContext = (PUSB_SEND_CONTEXT)s_vGetFreeContext(pDevice);
+
+ if (NULL == pContext) {
+ return false;
+ }
+
+ memcpy(pDevice->sTxEthHeader.h_dest, (u8 *)pbySkbData, ETH_HLEN);
+
+ if (pDevice->bEncryptionEnable == true) {
+ bNeedEncryption = true;
+ // get group key
+ pbyBSSID = pDevice->abyBroadcastAddr;
+ if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) {
+ pTransmitKey = NULL;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"KEY is NULL. [%d]\n", pMgmt->eCurrMode);
+ } else {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n");
+ }
+ }
+
+ if (pDevice->bEnableHostWEP) {
+ if (uNodeIndex < MAX_NODE_NUM + 1) {
+ 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 ( bNeedEncryption && (pTransmitKey == NULL) ) {
+ pContext->bBoolInUse = false;
+ return false;
+ }
+
+ byPktTyp = (u8)pDevice->byPacketType;
+
+ if (pDevice->bFixRate) {
+ if (pDevice->byBBType == BB_TYPE_11B) {
+ if (pDevice->uConnectionRate >= RATE_11M) {
+ pDevice->wCurrentRate = RATE_11M;
+ } else {
+ pDevice->wCurrentRate = (u16)pDevice->uConnectionRate;
+ }
+ } else {
+ if ((pDevice->byBBType == BB_TYPE_11A) &&
+ (pDevice->uConnectionRate <= RATE_6M)) {
+ pDevice->wCurrentRate = RATE_6M;
+ } else {
+ if (pDevice->uConnectionRate >= RATE_54M)
+ pDevice->wCurrentRate = RATE_54M;
+ else
+ pDevice->wCurrentRate = (u16)pDevice->uConnectionRate;
+ }
+ }
+ }
+ else {
+ pDevice->wCurrentRate = pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate;
+ }
+
+ if (wKeepRate != pDevice->wCurrentRate) {
+ bScheduleCommand((void *) pDevice, WLAN_CMD_SETPOWER, NULL);
+ }
+
+ if (pDevice->wCurrentRate <= RATE_11M)
+ byPktType = PK_TYPE_11B;
+
+ BytesToWrite = uDataLen + ETH_FCS_LEN;
+
+ // Convert the packet to an usb frame and copy into our buffer
+ // and send the irp.
+
+ fConvertedPacket = s_bPacketToWirelessUsb(pDevice, byPktType,
+ (u8 *)(&pContext->Data[0]), bNeedEncryption,
+ uDataLen, TYPE_AC0DMA, &pDevice->sTxEthHeader,
+ pbySkbData, pTransmitKey, uNodeIndex,
+ pDevice->wCurrentRate,
+ &uHeaderLen, &BytesToWrite
+ );
+
+ if (fConvertedPacket == false) {
+ pContext->bBoolInUse = false;
+ return false;
+ }
+
+ pTX_Buffer = (PTX_BUFFER)&(pContext->Data[0]);
+ pTX_Buffer->byPKTNO = (u8) (((pDevice->wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
+ pTX_Buffer->wTxByteCount = (u16)BytesToWrite;
+
+ pContext->pPacket = NULL;
+ pContext->Type = CONTEXT_DATA_PACKET;
+ pContext->uBufLen = (u16)BytesToWrite + 4 ; //USB header
+
+ s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pContext->sEthHeader.h_dest[0]), (u16) (BytesToWrite-uHeaderLen), pTX_Buffer->wFIFOCtl);
+
+ status = PIPEnsSendBulkOut(pDevice,pContext);
+
+ return true;
+}
+
diff --git a/drivers/staging/vt6656/rxtx.h b/drivers/staging/vt6656/rxtx.h
new file mode 100644
index 00000000..dd7e85dd
--- /dev/null
+++ b/drivers/staging/vt6656/rxtx.h
@@ -0,0 +1,638 @@
+/*
+ * 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.h
+ *
+ * Purpose:
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Jun. 27, 2002
+ *
+ */
+
+#ifndef __RXTX_H__
+#define __RXTX_H__
+
+#include "device.h"
+#include "wcmd.h"
+
+//
+// RTS buffer header
+//
+typedef struct tagSRTSDataF {
+ u16 wFrameControl;
+ u16 wDurationID;
+ u8 abyRA[ETH_ALEN];
+ u8 abyTA[ETH_ALEN];
+} SRTSDataF, *PSRTSDataF;
+
+//
+// CTS buffer header
+//
+typedef struct tagSCTSDataF {
+ u16 wFrameControl;
+ u16 wDurationID;
+ u8 abyRA[ETH_ALEN];
+ u16 wReserved;
+} SCTSDataF, *PSCTSDataF;
+
+//
+// MICHDR data header
+//
+typedef struct tagSMICHDR {
+ u32 adwHDR0[4];
+ u32 adwHDR1[4];
+ u32 adwHDR2[4];
+} SMICHDR, *PSMICHDR;
+
+typedef struct tagSTX_NAF_G_RTS
+{
+ //RsvTime
+ u16 wRTSTxRrvTime_ba;
+ u16 wRTSTxRrvTime_aa;
+ u16 wRTSTxRrvTime_bb;
+ u16 wReserved2;
+ u16 wTxRrvTime_b;
+ u16 wTxRrvTime_a;
+
+ //RTS
+ u8 byRTSSignalField_b;
+ u8 byRTSServiceField_b;
+ u16 wRTSTransmitLength_b;
+ u8 byRTSSignalField_a;
+ u8 byRTSServiceField_a;
+ u16 wRTSTransmitLength_a;
+ u16 wRTSDuration_ba;
+ u16 wRTSDuration_aa;
+ u16 wRTSDuration_bb;
+ u16 wReserved3;
+ SRTSDataF sRTS;
+
+ //Data
+ u8 bySignalField_b;
+ u8 byServiceField_b;
+ u16 wTransmitLength_b;
+ u8 bySignalField_a;
+ u8 byServiceField_a;
+ u16 wTransmitLength_a;
+ u16 wDuration_b;
+ u16 wDuration_a;
+ u16 wTimeStampOff_b;
+ u16 wTimeStampOff_a;
+
+} TX_NAF_G_RTS, *PTX_NAF_G_RTS;
+
+typedef struct tagSTX_NAF_G_RTS_MIC
+{
+ //RsvTime
+ u16 wRTSTxRrvTime_ba;
+ u16 wRTSTxRrvTime_aa;
+ u16 wRTSTxRrvTime_bb;
+ u16 wReserved2;
+ u16 wTxRrvTime_b;
+ u16 wTxRrvTime_a;
+
+ SMICHDR sMICHDR;
+
+ //RTS
+ u8 byRTSSignalField_b;
+ u8 byRTSServiceField_b;
+ u16 wRTSTransmitLength_b;
+ u8 byRTSSignalField_a;
+ u8 byRTSServiceField_a;
+ u16 wRTSTransmitLength_a;
+ u16 wRTSDuration_ba;
+ u16 wRTSDuration_aa;
+ u16 wRTSDuration_bb;
+ u16 wReserved3;
+ SRTSDataF sRTS;
+
+ //Data
+ u8 bySignalField_b;
+ u8 byServiceField_b;
+ u16 wTransmitLength_b;
+ u8 bySignalField_a;
+ u8 byServiceField_a;
+ u16 wTransmitLength_a;
+ u16 wDuration_b;
+ u16 wDuration_a;
+ u16 wTimeStampOff_b;
+ u16 wTimeStampOff_a;
+
+} TX_NAF_G_RTS_MIC, *PTX_NAF_G_RTS_MIC;
+
+typedef struct tagSTX_NAF_G_CTS
+{
+ //RsvTime
+ u16 wCTSTxRrvTime_ba;
+ u16 wReserved2;
+ u16 wTxRrvTime_b;
+ u16 wTxRrvTime_a;
+
+ //CTS
+ u8 byCTSSignalField_b;
+ u8 byCTSServiceField_b;
+ u16 wCTSTransmitLength_b;
+ u16 wCTSDuration_ba;
+ u16 wReserved3;
+ SCTSDataF sCTS;
+
+ //Data
+ u8 bySignalField_b;
+ u8 byServiceField_b;
+ u16 wTransmitLength_b;
+ u8 bySignalField_a;
+ u8 byServiceField_a;
+ u16 wTransmitLength_a;
+ u16 wDuration_b;
+ u16 wDuration_a;
+ u16 wTimeStampOff_b;
+ u16 wTimeStampOff_a;
+
+} TX_NAF_G_CTS, *PTX_NAF_G_CTS;
+
+typedef struct tagSTX_NAF_G_CTS_MIC
+{
+ //RsvTime
+ u16 wCTSTxRrvTime_ba;
+ u16 wReserved2;
+ u16 wTxRrvTime_b;
+ u16 wTxRrvTime_a;
+
+ SMICHDR sMICHDR;
+
+ //CTS
+ u8 byCTSSignalField_b;
+ u8 byCTSServiceField_b;
+ u16 wCTSTransmitLength_b;
+ u16 wCTSDuration_ba;
+ u16 wReserved3;
+ SCTSDataF sCTS;
+
+ //Data
+ u8 bySignalField_b;
+ u8 byServiceField_b;
+ u16 wTransmitLength_b;
+ u8 bySignalField_a;
+ u8 byServiceField_a;
+ u16 wTransmitLength_a;
+ u16 wDuration_b;
+ u16 wDuration_a;
+ u16 wTimeStampOff_b;
+ u16 wTimeStampOff_a;
+
+} TX_NAF_G_CTS_MIC, *PTX_NAF_G_CTS_MIC;
+
+typedef struct tagSTX_NAF_G_BEACON
+{
+ u16 wFIFOCtl;
+ u16 wTimeStamp;
+
+ //CTS
+ u8 byCTSSignalField_b;
+ u8 byCTSServiceField_b;
+ u16 wCTSTransmitLength_b;
+ u16 wCTSDuration_ba;
+ u16 wReserved1;
+ SCTSDataF sCTS;
+
+ //Data
+ u8 bySignalField_a;
+ u8 byServiceField_a;
+ u16 wTransmitLength_a;
+ u16 wDuration_a;
+ u16 wTimeStampOff_a;
+
+} TX_NAF_G_BEACON, *PTX_NAF_G_BEACON;
+
+typedef struct tagSTX_NAF_AB_RTS
+{
+ //RsvTime
+ u16 wRTSTxRrvTime_ab;
+ u16 wTxRrvTime_ab;
+
+ //RTS
+ u8 byRTSSignalField_ab;
+ u8 byRTSServiceField_ab;
+ u16 wRTSTransmitLength_ab;
+ u16 wRTSDuration_ab;
+ u16 wReserved2;
+ SRTSDataF sRTS;
+
+ //Data
+ u8 bySignalField_ab;
+ u8 byServiceField_ab;
+ u16 wTransmitLength_ab;
+ u16 wDuration_ab;
+ u16 wTimeStampOff_ab;
+
+} TX_NAF_AB_RTS, *PTX_NAF_AB_RTS;
+
+typedef struct tagSTX_NAF_AB_RTS_MIC
+{
+ //RsvTime
+ u16 wRTSTxRrvTime_ab;
+ u16 wTxRrvTime_ab;
+
+ SMICHDR sMICHDR;
+
+ //RTS
+ u8 byRTSSignalField_ab;
+ u8 byRTSServiceField_ab;
+ u16 wRTSTransmitLength_ab;
+ u16 wRTSDuration_ab;
+ u16 wReserved2;
+ SRTSDataF sRTS;
+
+ //Data
+ u8 bySignalField_ab;
+ u8 byServiceField_ab;
+ u16 wTransmitLength_ab;
+ u16 wDuration_ab;
+ u16 wTimeStampOff_ab;
+
+} TX_NAF_AB_RTS_MIC, *PTX_NAF_AB_RTS_MIC;
+
+typedef struct tagSTX_NAF_AB_CTS
+{
+ //RsvTime
+ u16 wReserved2;
+ u16 wTxRrvTime_ab;
+
+ //Data
+ u8 bySignalField_ab;
+ u8 byServiceField_ab;
+ u16 wTransmitLength_ab;
+ u16 wDuration_ab;
+ u16 wTimeStampOff_ab;
+
+} TX_NAF_AB_CTS, *PTX_NAF_AB_CTS;
+
+typedef struct tagSTX_NAF_AB_CTS_MIC
+{
+ //RsvTime
+ u16 wReserved2;
+ u16 wTxRrvTime_ab;
+
+ SMICHDR sMICHDR;
+
+ //Data
+ u8 bySignalField_ab;
+ u8 byServiceField_ab;
+ u16 wTransmitLength_ab;
+ u16 wDuration_ab;
+ u16 wTimeStampOff_ab;
+
+} TX_NAF_AB_CTS_MIC, *PTX_NAF_AB_CTS_MIC;
+
+typedef struct tagSTX_NAF_AB_BEACON
+{
+ u16 wFIFOCtl;
+ u16 wTimeStamp;
+
+ //Data
+ u8 bySignalField_ab;
+ u8 byServiceField_ab;
+ u16 wTransmitLength_ab;
+ u16 wDuration_ab;
+ u16 wTimeStampOff_ab;
+
+} TX_NAF_AB_BEACON, *PTX_NAF_AB_BEACON;
+
+typedef struct tagSTX_AF_G_RTS
+{
+ //RsvTime
+ u16 wRTSTxRrvTime_ba;
+ u16 wRTSTxRrvTime_aa;
+ u16 wRTSTxRrvTime_bb;
+ u16 wReserved2;
+ u16 wTxRrvTime_b;
+ u16 wTxRrvTime_a;
+
+ //RTS
+ u8 byRTSSignalField_b;
+ u8 byRTSServiceField_b;
+ u16 wRTSTransmitLength_b;
+ u8 byRTSSignalField_a;
+ u8 byRTSServiceField_a;
+ u16 wRTSTransmitLength_a;
+ u16 wRTSDuration_ba;
+ u16 wRTSDuration_aa;
+ u16 wRTSDuration_bb;
+ u16 wReserved3;
+ u16 wRTSDuration_ba_f0;
+ u16 wRTSDuration_aa_f0;
+ u16 wRTSDuration_ba_f1;
+ u16 wRTSDuration_aa_f1;
+ SRTSDataF sRTS;
+
+ //Data
+ u8 bySignalField_b;
+ u8 byServiceField_b;
+ u16 wTransmitLength_b;
+ u8 bySignalField_a;
+ u8 byServiceField_a;
+ u16 wTransmitLength_a;
+ u16 wDuration_b;
+ u16 wDuration_a;
+ u16 wDuration_a_f0;
+ u16 wDuration_a_f1;
+ u16 wTimeStampOff_b;
+ u16 wTimeStampOff_a;
+
+} TX_AF_G_RTS, *PTX_AF_G_RTS;
+
+typedef struct tagSTX_AF_G_RTS_MIC
+{
+ //RsvTime
+ u16 wRTSTxRrvTime_ba;
+ u16 wRTSTxRrvTime_aa;
+ u16 wRTSTxRrvTime_bb;
+ u16 wReserved2;
+ u16 wTxRrvTime_b;
+ u16 wTxRrvTime_a;
+
+ SMICHDR sMICHDR;
+
+ //RTS
+ u8 byRTSSignalField_b;
+ u8 byRTSServiceField_b;
+ u16 wRTSTransmitLength_b;
+ u8 byRTSSignalField_a;
+ u8 byRTSServiceField_a;
+ u16 wRTSTransmitLength_a;
+ u16 wRTSDuration_ba;
+ u16 wRTSDuration_aa;
+ u16 wRTSDuration_bb;
+ u16 wReserved3;
+ u16 wRTSDuration_ba_f0;
+ u16 wRTSDuration_aa_f0;
+ u16 wRTSDuration_ba_f1;
+ u16 wRTSDuration_aa_f1;
+ SRTSDataF sRTS;
+
+ //Data
+ u8 bySignalField_b;
+ u8 byServiceField_b;
+ u16 wTransmitLength_b;
+ u8 bySignalField_a;
+ u8 byServiceField_a;
+ u16 wTransmitLength_a;
+ u16 wDuration_b;
+ u16 wDuration_a;
+ u16 wDuration_a_f0;
+ u16 wDuration_a_f1;
+ u16 wTimeStampOff_b;
+ u16 wTimeStampOff_a;
+
+} TX_AF_G_RTS_MIC, *PTX_AF_G_RTS_MIC;
+
+typedef struct tagSTX_AF_G_CTS
+{
+ //RsvTime
+ u16 wCTSTxRrvTime_ba;
+ u16 wReserved2;
+ u16 wTxRrvTime_b;
+ u16 wTxRrvTime_a;
+
+ //CTS
+ u8 byCTSSignalField_b;
+ u8 byCTSServiceField_b;
+ u16 wCTSTransmitLength_b;
+ u16 wCTSDuration_ba;
+ u16 wReserved3;
+ u16 wCTSDuration_ba_f0;
+ u16 wCTSDuration_ba_f1;
+ SCTSDataF sCTS;
+
+ //Data
+ u8 bySignalField_b;
+ u8 byServiceField_b;
+ u16 wTransmitLength_b;
+ u8 bySignalField_a;
+ u8 byServiceField_a;
+ u16 wTransmitLength_a;
+ u16 wDuration_b;
+ u16 wDuration_a;
+ u16 wDuration_a_f0;
+ u16 wDuration_a_f1;
+ u16 wTimeStampOff_b;
+ u16 wTimeStampOff_a;
+
+} TX_AF_G_CTS, *PTX_AF_G_CTS;
+
+typedef struct tagSTX_AF_G_CTS_MIC
+{
+ //RsvTime
+ u16 wCTSTxRrvTime_ba;
+ u16 wReserved2;
+ u16 wTxRrvTime_b;
+ u16 wTxRrvTime_a;
+
+ SMICHDR sMICHDR;
+
+ //CTS
+ u8 byCTSSignalField_b;
+ u8 byCTSServiceField_b;
+ u16 wCTSTransmitLength_b;
+ u16 wCTSDuration_ba;
+ u16 wReserved3;
+ u16 wCTSDuration_ba_f0;
+ u16 wCTSDuration_ba_f1;
+ SCTSDataF sCTS;
+
+ //Data
+ u8 bySignalField_b;
+ u8 byServiceField_b;
+ u16 wTransmitLength_b;
+ u8 bySignalField_a;
+ u8 byServiceField_a;
+ u16 wTransmitLength_a;
+ u16 wDuration_b;
+ u16 wDuration_a;
+ u16 wDuration_a_f0;
+ u16 wDuration_a_f1;
+ u16 wTimeStampOff_b;
+ u16 wTimeStampOff_a;
+
+} TX_AF_G_CTS_MIC, *PTX_AF_G_CTS_MIC;
+
+typedef struct tagSTX_AF_A_RTS
+{
+ //RsvTime
+ u16 wRTSTxRrvTime_a;
+ u16 wTxRrvTime_a;
+
+ //RTS
+ u8 byRTSSignalField_a;
+ u8 byRTSServiceField_a;
+ u16 wRTSTransmitLength_a;
+ u16 wRTSDuration_a;
+ u16 wReserved2;
+ u16 wRTSDuration_a_f0;
+ u16 wRTSDuration_a_f1;
+ SRTSDataF sRTS;
+
+ //Data
+ u8 bySignalField_a;
+ u8 byServiceField_a;
+ u16 wTransmitLength_a;
+ u16 wDuration_a;
+ u16 wTimeStampOff_a;
+ u16 wDuration_a_f0;
+ u16 wDuration_a_f1;
+
+} TX_AF_A_RTS, *PTX_AF_A_RTS;
+
+typedef struct tagSTX_AF_A_RTS_MIC
+{
+ //RsvTime
+ u16 wRTSTxRrvTime_a;
+ u16 wTxRrvTime_a;
+
+ SMICHDR sMICHDR;
+
+ //RTS
+ u8 byRTSSignalField_a;
+ u8 byRTSServiceField_a;
+ u16 wRTSTransmitLength_a;
+ u16 wRTSDuration_a;
+ u16 wReserved2;
+ u16 wRTSDuration_a_f0;
+ u16 wRTSDuration_a_f1;
+ SRTSDataF sRTS;
+
+ //Data
+ u8 bySignalField_a;
+ u8 byServiceField_a;
+ u16 wTransmitLength_a;
+ u16 wDuration_a;
+ u16 wTimeStampOff_a;
+ u16 wDuration_a_f0;
+ u16 wDuration_a_f1;
+
+} TX_AF_A_RTS_MIC, *PTX_AF_A_RTS_MIC;
+
+typedef struct tagSTX_AF_A_CTS
+{
+ //RsvTime
+ u16 wReserved2;
+ u16 wTxRrvTime_a;
+
+ //Data
+ u8 bySignalField_a;
+ u8 byServiceField_a;
+ u16 wTransmitLength_a;
+ u16 wDuration_a;
+ u16 wTimeStampOff_a;
+ u16 wDuration_a_f0;
+ u16 wDuration_a_f1;
+
+} TX_AF_A_CTS, *PTX_AF_A_CTS;
+
+typedef struct tagSTX_AF_A_CTS_MIC
+{
+ //RsvTime
+ u16 wReserved2;
+ u16 wTxRrvTime_a;
+
+ SMICHDR sMICHDR;
+
+ //Data
+ u8 bySignalField_a;
+ u8 byServiceField_a;
+ u16 wTransmitLength_a;
+ u16 wDuration_a;
+ u16 wTimeStampOff_a;
+ u16 wDuration_a_f0;
+ u16 wDuration_a_f1;
+
+} TX_AF_A_CTS_MIC, *PTX_AF_A_CTS_MIC;
+
+//
+// union with all of the TX Buffer Type
+//
+typedef union tagUTX_BUFFER_CONTAINER
+{
+ TX_NAF_G_RTS RTS_G;
+ TX_NAF_G_RTS_MIC RTS_G_MIC;
+ TX_NAF_G_CTS CTS_G;
+ TX_NAF_G_CTS_MIC CTS_G_MIC;
+ //TX_NAF_G_BEACON Beacon_G;
+ TX_NAF_AB_RTS RTS_AB;
+ TX_NAF_AB_RTS_MIC RTS_AB_MIC;
+ TX_NAF_AB_CTS CTS_AB;
+ TX_NAF_AB_CTS_MIC CTS_AB_MIC;
+ //TX_NAF_AB_BEACON Beacon_AB;
+ TX_AF_G_RTS RTS_G_AutoFB;
+ TX_AF_G_RTS_MIC RTS_G_AutoFB_MIC;
+ TX_AF_G_CTS CTS_G_AutoFB;
+ TX_AF_G_CTS_MIC CTS_G_AutoFB_MIC;
+ TX_AF_A_RTS RTS_A_AutoFB;
+ TX_AF_A_RTS_MIC RTS_A_AutoFB_MIC;
+ TX_AF_A_CTS CTS_A_AutoFB;
+ TX_AF_A_CTS_MIC CTS_A_AutoFB_MIC;
+
+} TX_BUFFER_CONTAINER, *PTX_BUFFER_CONTAINER;
+
+//
+// Remote NDIS message format
+//
+typedef struct tagSTX_BUFFER
+{
+ u8 byType;
+ u8 byPKTNO;
+ u16 wTxByteCount;
+
+ u32 adwTxKey[4];
+ u16 wFIFOCtl;
+ u16 wTimeStamp;
+ u16 wFragCtl;
+ u16 wReserved;
+
+ // Actual message
+ TX_BUFFER_CONTAINER BufferHeader;
+
+} TX_BUFFER, *PTX_BUFFER;
+
+//
+// Remote NDIS message format
+//
+typedef struct tagSBEACON_BUFFER
+{
+ u8 byType;
+ u8 byPKTNO;
+ u16 wTxByteCount;
+
+ u16 wFIFOCtl;
+ u16 wTimeStamp;
+
+ // Actual message
+ TX_BUFFER_CONTAINER BufferHeader;
+
+} BEACON_BUFFER, *PBEACON_BUFFER;
+
+void vDMA0_tx_80211(struct vnt_private *, struct sk_buff *skb);
+int nsDMA_tx_packet(struct vnt_private *, u32 uDMAIdx, struct sk_buff *skb);
+CMD_STATUS csMgmt_xmit(struct vnt_private *, struct vnt_tx_mgmt *);
+CMD_STATUS csBeacon_xmit(struct vnt_private *, struct vnt_tx_mgmt *);
+int bRelayPacketSend(struct vnt_private *, u8 *pbySkbData, u32 uDataLen,
+ u32 uNodeIndex);
+
+#endif /* __RXTX_H__ */
diff --git a/drivers/staging/vt6656/srom.h b/drivers/staging/vt6656/srom.h
new file mode 100644
index 00000000..488192d7
--- /dev/null
+++ b/drivers/staging/vt6656/srom.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: srom.h
+ *
+ * Purpose: Implement functions to access eeprom
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Jan 29, 2003
+ *
+ */
+
+#ifndef __SROM_H__
+#define __SROM_H__
+
+#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 0x17
+#define EEP_OFS_RADIOCTL 0x18
+#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_CALIB_TX_IQ 0x24
+#define EEP_OFS_CALIB_TX_DC 0x25
+#define EEP_OFS_CALIB_RX_IQ 0x26
+
+#define EEP_OFS_MAJOR_VER 0x2E
+#define EEP_OFS_MINOR_VER 0x2F
+
+#define EEP_OFS_CCK_PWR_TBL 0x30
+#define EEP_OFS_OFDM_PWR_TBL 0x40
+#define EEP_OFS_OFDMA_PWR_TBL 0x50
+
+//
+// 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
+
+// AT24C02 eeprom contents
+// 2048 bits = 256 bytes = 128 words
+//
+typedef struct tagSSromReg {
+ u8 abyPAR[6]; // 0x00 (u16)
+
+ u16 wSUB_VID; // 0x03 (u16)
+ u16 wSUB_SID;
+
+ u8 byBCFG0; // 0x05 (u16)
+ u8 byBCFG1;
+
+ u8 byFCR0; // 0x06 (u16)
+ u8 byFCR1;
+ u8 byPMC0; // 0x07 (u16)
+ u8 byPMC1;
+ u8 byMAXLAT; // 0x08 (u16)
+ u8 byMINGNT;
+ u8 byCFG0; // 0x09 (u16)
+ u8 byCFG1;
+ u16 wCISPTR; // 0x0A (u16)
+ u16 wRsv0; // 0x0B (u16)
+ u16 wRsv1; // 0x0C (u16)
+ u8 byBBPAIR; // 0x0D (u16)
+ u8 byRFTYPE;
+ u8 byMinChannel; // 0x0E (u16)
+ u8 byMaxChannel;
+ u8 bySignature; // 0x0F (u16)
+ u8 byCheckSum;
+
+ u8 abyReserved0[96]; // 0x10 (u16)
+ u8 abyCIS[128]; // 0x80 (u16)
+} SSromReg, *PSSromReg;
+
+#endif /* __EEPROM_H__ */
diff --git a/drivers/staging/vt6656/tcrc.c b/drivers/staging/vt6656/tcrc.c
new file mode 100644
index 00000000..7229f26c
--- /dev/null
+++ b/drivers/staging/vt6656/tcrc.c
@@ -0,0 +1,183 @@
+/*
+ * 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 calculate CRC
+ *
+ * Author: Tevin Chen
+ *
+ * Date: May 21, 1996
+ *
+ * Functions:
+ * CRCdwCrc32 -
+ * CRCdwGetCrc32 -
+ * CRCdwGetCrc32Ex -
+ *
+ * Revision History:
+ *
+ */
+
+#include "tcrc.h"
+
+/* 32-bit CRC table */
+static const u32 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
+};
+
+/*+
+ *
+ * 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
+ *
+-*/
+u32 CRCdwCrc32(u8 * pbyData, unsigned int cbByte, u32 dwCrcSeed)
+{
+ u32 dwCrc;
+
+ dwCrc = dwCrcSeed;
+ while (cbByte--) {
+ dwCrc = s_adwCrc32Table[(u8)((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
+ *
+-*/
+u32 CRCdwGetCrc32(u8 * pbyData, unsigned int 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
+ *
+-*/
+u32 CRCdwGetCrc32Ex(u8 * pbyData, unsigned int cbByte, u32 dwPreCRC)
+{
+ return CRCdwCrc32(pbyData, cbByte, dwPreCRC);
+}
+
diff --git a/drivers/staging/vt6656/tcrc.h b/drivers/staging/vt6656/tcrc.h
new file mode 100644
index 00000000..5b1f3689
--- /dev/null
+++ b/drivers/staging/vt6656/tcrc.h
@@ -0,0 +1,38 @@
+/*
+ * 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 calculate CRC
+ *
+ * Author: Tevin Chen
+ *
+ * Date: Jan. 28, 1997
+ *
+ */
+
+#ifndef __TCRC_H__
+#define __TCRC_H__
+
+#include <linux/types.h>
+
+u32 CRCdwCrc32(u8 * pbyData, unsigned int cbByte, u32 dwCrcSeed);
+u32 CRCdwGetCrc32(u8 * pbyData, unsigned int cbByte);
+u32 CRCdwGetCrc32Ex(u8 * pbyData, unsigned int cbByte, u32 dwPreCRC);
+
+#endif /* __TCRC_H__ */
diff --git a/drivers/staging/vt6656/tether.c b/drivers/staging/vt6656/tether.c
new file mode 100644
index 00000000..1db1e841
--- /dev/null
+++ b/drivers/staging/vt6656/tether.c
@@ -0,0 +1,61 @@
+/*
+ * 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:
+ * ETHbIsBufferCrc32Ok - Check CRC value of the buffer if Ok or not
+ *
+ * Revision History:
+ *
+ */
+
+#include "device.h"
+#include "tmacro.h"
+#include "tcrc.h"
+#include "tether.h"
+
+/*
+ * 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(u8 * pbyBuffer, unsigned int cbFrameLength)
+{
+ u32 dwCRC;
+
+ dwCRC = CRCdwGetCrc32(pbyBuffer, cbFrameLength - 4);
+ if (cpu_to_le32(*((u32 *)(pbyBuffer + cbFrameLength - 4))) != dwCRC)
+ return false;
+ return true;
+}
+
diff --git a/drivers/staging/vt6656/tether.h b/drivers/staging/vt6656/tether.h
new file mode 100644
index 00000000..24465cfe
--- /dev/null
+++ b/drivers/staging/vt6656/tether.h
@@ -0,0 +1,115 @@
+/*
+ * 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__
+
+#include <linux/if_ether.h>
+
+//
+// constants
+//
+#define U_ETHER_ADDR_STR_LEN (ETH_ALEN * 2 + 1)
+ // Ethernet address string length
+#define U_MULTI_ADDR_LEN 8 // multicast address length
+
+#ifdef __BIG_ENDIAN
+
+#define TYPE_MGMT_PROBE_RSP 0x5000
+
+#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
+
+#else //if LITTLE_ENDIAN
+//
+// wType field in the SEthernetHeader
+//
+// NOTE....
+// in network byte order, high byte is going first
+
+#define TYPE_MGMT_PROBE_RSP 0x0050
+
+#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
+
+#endif //#ifdef __BIG_ENDIAN
+
+#define WEP_IV_MASK 0x00FFFFFF
+
+//
+// 802_3 packet
+//
+typedef struct tagS802_3Header {
+ u8 abyDstAddr[ETH_ALEN];
+ u8 abySrcAddr[ETH_ALEN];
+ u16 wLen;
+} __attribute__ ((__packed__))
+S802_3Header, *PS802_3Header;
+
+//u8 ETHbyGetHashIndexByCrc(u8 * pbyMultiAddr);
+bool ETHbIsBufferCrc32Ok(u8 * pbyBuffer, unsigned int cbFrameLength);
+
+#endif /* __TETHER_H__ */
diff --git a/drivers/staging/vt6656/tkip.c b/drivers/staging/vt6656/tkip.c
new file mode 100644
index 00000000..9d643e44
--- /dev/null
+++ b/drivers/staging/vt6656/tkip.c
@@ -0,0 +1,246 @@
+/*
+ * 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:
+ *
+ */
+
+#include "tmacro.h"
+#include "tkip.h"
+
+/* 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 u8 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 u8 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];
+
+/************************************************************/
+/* tkip_sbox() */
+/* Returns a 16 bit value from a 64K entry table. The Table */
+/* is synthesized from two 256 entry byte wide tables. */
+/************************************************************/
+static 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);
+};
+
+static 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: Calculate RC4Key fom TK, TA, and TSC
+ *
+ * Parameters:
+ * In:
+ * pbyTKey - TKey
+ * pbyTA - TA
+ * dwTSC - TSC
+ * Out:
+ * pbyRC4Key - RC4Key
+ *
+ * Return Value: none
+ *
+ */
+void TKIPvMixKey(
+ u8 * pbyTKey,
+ u8 * pbyTA,
+ u16 wTSC15_0,
+ u32 dwTSC47_16,
+ u8 * pbyRC4Key
+ )
+{
+ u32 p1k[5];
+ u32 tsc0, tsc1, tsc2;
+ u32 ppk0, ppk1, ppk2, ppk3, ppk4, ppk5;
+ u32 pnl, pnh;
+ int i, j;
+
+ pnl = (u32)wTSC15_0;
+ pnh = (u32)(dwTSC47_16 & 0xffffffff);
+
+ tsc0 = (u32)((pnh >> 16) % 65536); /* msb */
+ tsc1 = (u32)(pnh % 65536);
+ tsc2 = (u32)(pnl % 65536); /* lsb */
+
+ /* Phase 1, step 1 */
+ p1k[0] = tsc1;
+ p1k[1] = tsc0;
+ p1k[2] = (u32)(pbyTA[0] + (pbyTA[1]*256));
+ p1k[3] = (u32)(pbyTA[2] + (pbyTA[3]*256));
+ p1k[4] = (u32)(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/vt6656/tkip.h b/drivers/staging/vt6656/tkip.h
new file mode 100644
index 00000000..4fba7ef3
--- /dev/null
+++ b/drivers/staging/vt6656/tkip.h
@@ -0,0 +1,45 @@
+/*
+ * 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__
+
+#include "tether.h"
+
+#define TKIP_KEY_LEN 16
+
+void TKIPvMixKey(
+ u8 * pbyTKey,
+ u8 * pbyTA,
+ u16 wTSC15_0,
+ u32 dwTSC47_16,
+ u8 * pbyRC4Key
+ );
+
+#endif /* __TKIP_H__ */
diff --git a/drivers/staging/vt6656/tmacro.h b/drivers/staging/vt6656/tmacro.h
new file mode 100644
index 00000000..15cd5abb
--- /dev/null
+++ b/drivers/staging/vt6656/tmacro.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: tmacro.h
+ *
+ * Purpose: define basic common types and macros
+ *
+ * Author: Tevin Chen
+ *
+ * Date: May 21, 1996
+ *
+ */
+
+#ifndef __TMACRO_H__
+#define __TMACRO_H__
+
+/****** Common helper macros ***********************************************/
+
+#if !defined(LOBYTE)
+#define LOBYTE(w) ((u8)(w))
+#endif
+#if !defined(HIBYTE)
+#define HIBYTE(w) ((u8)(((u16)(w) >> 8) & 0xFF))
+#endif
+
+#if !defined(LOWORD)
+#define LOWORD(d) ((u16)(d))
+#endif
+#if !defined(HIWORD)
+#define HIWORD(d) ((u16)((((u32)(d)) >> 16) & 0xFFFF))
+#endif
+
+#define LODWORD(q) ((q).u.dwLowDword)
+#define HIDWORD(q) ((q).u.dwHighDword)
+
+#if !defined(MAKEWORD)
+#define MAKEWORD(lb, hb) ((u16)(((u8)(lb)) | (((u16)((u8)(hb))) << 8)))
+#endif
+#if !defined(MAKEDWORD)
+#define MAKEDWORD(lw, hw) ((u32)(((u16)(lw)) | (((u32)((u16)(hw))) << 16)))
+#endif
+
+#endif /* __TMACRO_H__ */
diff --git a/drivers/staging/vt6656/usbpipe.c b/drivers/staging/vt6656/usbpipe.c
new file mode 100644
index 00000000..098be609
--- /dev/null
+++ b/drivers/staging/vt6656/usbpipe.c
@@ -0,0 +1,696 @@
+/*
+ * 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: usbpipe.c
+ *
+ * Purpose: Handle USB control endpoint
+ *
+ * Author: Warren Hsu
+ *
+ * Date: Mar. 29, 2005
+ *
+ * Functions:
+ * CONTROLnsRequestOut - Write variable length bytes to MEM/BB/MAC/EEPROM
+ * CONTROLnsRequestIn - Read variable length bytes from MEM/BB/MAC/EEPROM
+ * ControlvWriteByte - Write one byte to MEM/BB/MAC/EEPROM
+ * ControlvReadByte - Read one byte from MEM/BB/MAC/EEPROM
+ * ControlvMaskByte - Read one byte from MEM/BB/MAC/EEPROM and clear/set some bits in the same address
+ *
+ * Revision History:
+ * 04-05-2004 Jerry Chen: Initial release
+ * 11-24-2004 Warren Hsu: Add ControlvWriteByte,ControlvReadByte,ControlvMaskByte
+ *
+ */
+
+#include "int.h"
+#include "rxtx.h"
+#include "dpc.h"
+#include "control.h"
+#include "desc.h"
+#include "device.h"
+
+//endpoint def
+//endpoint 0: control
+//endpoint 1: interrupt
+//endpoint 2: read bulk
+//endpoint 3: write bulk
+
+//static int msglevel =MSG_LEVEL_DEBUG;
+static int msglevel =MSG_LEVEL_INFO;
+
+#define USB_CTL_WAIT 500 //ms
+
+#ifndef URB_ASYNC_UNLINK
+#define URB_ASYNC_UNLINK 0
+#endif
+
+static void s_nsInterruptUsbIoCompleteRead(struct urb *urb);
+static void s_nsBulkInUsbIoCompleteRead(struct urb *urb);
+static void s_nsBulkOutIoCompleteWrite(struct urb *urb);
+static void s_nsControlInUsbIoCompleteRead(struct urb *urb);
+static void s_nsControlInUsbIoCompleteWrite(struct urb *urb);
+
+int PIPEnsControlOutAsyn(struct vnt_private *pDevice, u8 byRequest,
+ u16 wValue, u16 wIndex, u16 wLength, u8 *pbyBuffer)
+{
+ int ntStatus;
+
+ if (pDevice->Flags & fMP_DISCONNECTED)
+ return STATUS_FAILURE;
+
+ if (pDevice->Flags & fMP_CONTROL_WRITES)
+ return STATUS_FAILURE;
+
+ if (in_interrupt()) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"in_interrupt return ..byRequest %x\n", byRequest);
+ return STATUS_FAILURE;
+ }
+
+ ntStatus = usb_control_msg(
+ pDevice->usb,
+ usb_sndctrlpipe(pDevice->usb , 0),
+ byRequest,
+ 0x40, // RequestType
+ wValue,
+ wIndex,
+ (void *) pbyBuffer,
+ wLength,
+ HZ
+ );
+ if (ntStatus >= 0) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"usb_sndctrlpipe ntStatus= %d\n", ntStatus);
+ ntStatus = 0;
+ } else {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"usb_sndctrlpipe fail, ntStatus= %d\n", ntStatus);
+ }
+
+ return ntStatus;
+}
+
+int PIPEnsControlOut(struct vnt_private *pDevice, u8 byRequest, u16 wValue,
+ u16 wIndex, u16 wLength, u8 *pbyBuffer)
+{
+ int ntStatus = 0;
+ int ii;
+
+ if (pDevice->Flags & fMP_DISCONNECTED)
+ return STATUS_FAILURE;
+
+ if (pDevice->Flags & fMP_CONTROL_WRITES)
+ return STATUS_FAILURE;
+
+ if (pDevice->Flags & fMP_CONTROL_READS)
+ return STATUS_FAILURE;
+
+ MP_SET_FLAG(pDevice, fMP_CONTROL_WRITES);
+
+ pDevice->sUsbCtlRequest.bRequestType = 0x40;
+ pDevice->sUsbCtlRequest.bRequest = byRequest;
+ pDevice->sUsbCtlRequest.wValue = cpu_to_le16p(&wValue);
+ pDevice->sUsbCtlRequest.wIndex = cpu_to_le16p(&wIndex);
+ pDevice->sUsbCtlRequest.wLength = cpu_to_le16p(&wLength);
+ pDevice->pControlURB->transfer_flags |= URB_ASYNC_UNLINK;
+ pDevice->pControlURB->actual_length = 0;
+ // Notice, pbyBuffer limited point to variable buffer, can't be constant.
+ usb_fill_control_urb(pDevice->pControlURB, pDevice->usb,
+ usb_sndctrlpipe(pDevice->usb , 0), (char *) &pDevice->sUsbCtlRequest,
+ pbyBuffer, wLength, s_nsControlInUsbIoCompleteWrite, pDevice);
+
+ ntStatus = usb_submit_urb(pDevice->pControlURB, GFP_ATOMIC);
+ if (ntStatus != 0) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
+ "control send request submission failed: %d\n",
+ ntStatus);
+ MP_CLEAR_FLAG(pDevice, fMP_CONTROL_WRITES);
+ return STATUS_FAILURE;
+ }
+
+ spin_unlock_irq(&pDevice->lock);
+ for (ii = 0; ii <= USB_CTL_WAIT; ii ++) {
+
+ if (pDevice->Flags & fMP_CONTROL_WRITES)
+ mdelay(1);
+ else
+ break;
+
+ if (ii >= USB_CTL_WAIT) {
+ DBG_PRT(MSG_LEVEL_DEBUG,
+ KERN_INFO "control send request submission timeout\n");
+ spin_lock_irq(&pDevice->lock);
+ MP_CLEAR_FLAG(pDevice, fMP_CONTROL_WRITES);
+ return STATUS_FAILURE;
+ }
+ }
+ spin_lock_irq(&pDevice->lock);
+
+ return STATUS_SUCCESS;
+}
+
+int PIPEnsControlIn(struct vnt_private *pDevice, u8 byRequest, u16 wValue,
+ u16 wIndex, u16 wLength, u8 *pbyBuffer)
+{
+ int ntStatus = 0;
+ int ii;
+
+ if (pDevice->Flags & fMP_DISCONNECTED)
+ return STATUS_FAILURE;
+
+ if (pDevice->Flags & fMP_CONTROL_READS)
+ return STATUS_FAILURE;
+
+ if (pDevice->Flags & fMP_CONTROL_WRITES)
+ return STATUS_FAILURE;
+
+ MP_SET_FLAG(pDevice, fMP_CONTROL_READS);
+
+ pDevice->sUsbCtlRequest.bRequestType = 0xC0;
+ pDevice->sUsbCtlRequest.bRequest = byRequest;
+ pDevice->sUsbCtlRequest.wValue = cpu_to_le16p(&wValue);
+ pDevice->sUsbCtlRequest.wIndex = cpu_to_le16p(&wIndex);
+ pDevice->sUsbCtlRequest.wLength = cpu_to_le16p(&wLength);
+ pDevice->pControlURB->transfer_flags |= URB_ASYNC_UNLINK;
+ pDevice->pControlURB->actual_length = 0;
+ usb_fill_control_urb(pDevice->pControlURB, pDevice->usb,
+ usb_rcvctrlpipe(pDevice->usb , 0), (char *) &pDevice->sUsbCtlRequest,
+ pbyBuffer, wLength, s_nsControlInUsbIoCompleteRead, pDevice);
+
+ ntStatus = usb_submit_urb(pDevice->pControlURB, GFP_ATOMIC);
+ if (ntStatus != 0) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
+ "control request submission failed: %d\n", ntStatus);
+ MP_CLEAR_FLAG(pDevice, fMP_CONTROL_READS);
+ return STATUS_FAILURE;
+ }
+
+ spin_unlock_irq(&pDevice->lock);
+ for (ii = 0; ii <= USB_CTL_WAIT; ii ++) {
+
+ if (pDevice->Flags & fMP_CONTROL_READS)
+ mdelay(1);
+ else
+ break;
+
+ if (ii >= USB_CTL_WAIT) {
+ DBG_PRT(MSG_LEVEL_DEBUG,
+ KERN_INFO "control rcv request submission timeout\n");
+ spin_lock_irq(&pDevice->lock);
+ MP_CLEAR_FLAG(pDevice, fMP_CONTROL_READS);
+ return STATUS_FAILURE;
+ }
+ }
+ spin_lock_irq(&pDevice->lock);
+
+ return ntStatus;
+}
+
+static void s_nsControlInUsbIoCompleteWrite(struct urb *urb)
+{
+ struct vnt_private *pDevice = (struct vnt_private *)urb->context;
+
+ pDevice = urb->context;
+ switch (urb->status) {
+ case 0:
+ break;
+ case -EINPROGRESS:
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ctrl write urb status EINPROGRESS%d\n", urb->status);
+ break;
+ case -ENOENT:
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ctrl write urb status ENOENT %d\n", urb->status);
+ break;
+ default:
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ctrl write urb status %d\n", urb->status);
+ }
+
+ MP_CLEAR_FLAG(pDevice, fMP_CONTROL_WRITES);
+}
+
+/*
+ * Description:
+ * Complete function of usb Control callback
+ *
+ * Parameters:
+ * In:
+ * pDevice - Pointer to the adapter
+ *
+ * Out:
+ * none
+ *
+ * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver
+ *
+ */
+
+static void s_nsControlInUsbIoCompleteRead(struct urb *urb)
+{
+ struct vnt_private *pDevice = (struct vnt_private *)urb->context;
+
+ switch (urb->status) {
+ case 0:
+ break;
+ case -EINPROGRESS:
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ctrl read urb status EINPROGRESS%d\n", urb->status);
+ break;
+ case -ENOENT:
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ctrl read urb status = ENOENT %d\n", urb->status);
+ break;
+ default:
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ctrl read urb status %d\n", urb->status);
+ }
+
+ MP_CLEAR_FLAG(pDevice, fMP_CONTROL_READS);
+}
+
+/*
+ * Description:
+ * Allocates an usb interrupt in irp and calls USBD.
+ *
+ * Parameters:
+ * In:
+ * pDevice - Pointer to the adapter
+ * Out:
+ * none
+ *
+ * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver
+ *
+ */
+
+int PIPEnsInterruptRead(struct vnt_private *pDevice)
+{
+ int ntStatus = STATUS_FAILURE;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsStartInterruptUsbRead()\n");
+
+ if(pDevice->intBuf.bInUse == true){
+ return (STATUS_FAILURE);
+ }
+ pDevice->intBuf.bInUse = true;
+// pDevice->bEventAvailable = false;
+ pDevice->ulIntInPosted++;
+
+ //
+ // Now that we have created the urb, we will send a
+ // request to the USB device object.
+ //
+ pDevice->pInterruptURB->interval = pDevice->int_interval;
+
+usb_fill_bulk_urb(pDevice->pInterruptURB,
+ pDevice->usb,
+ usb_rcvbulkpipe(pDevice->usb, 1),
+ (void *) pDevice->intBuf.pDataBuf,
+ MAX_INTERRUPT_SIZE,
+ s_nsInterruptUsbIoCompleteRead,
+ pDevice);
+
+ ntStatus = usb_submit_urb(pDevice->pInterruptURB, GFP_ATOMIC);
+ if (ntStatus != 0) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Submit int URB failed %d\n", ntStatus);
+ }
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"<----s_nsStartInterruptUsbRead Return(%x)\n",ntStatus);
+ return ntStatus;
+}
+
+/*
+ * Description:
+ * Complete function of usb interrupt in irp.
+ *
+ * Parameters:
+ * In:
+ * pDevice - Pointer to the adapter
+ *
+ * Out:
+ * none
+ *
+ * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver
+ *
+ */
+
+static void s_nsInterruptUsbIoCompleteRead(struct urb *urb)
+{
+ struct vnt_private *pDevice = (struct vnt_private *)urb->context;
+ int ntStatus;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsInterruptUsbIoCompleteRead\n");
+ //
+ // The context given to IoSetCompletionRoutine is the receive buffer object
+ //
+
+ //
+ // We have a number of cases:
+ // 1) The USB read timed out and we received no data.
+ // 2) The USB read timed out and we received some data.
+ // 3) The USB read was successful and fully filled our irp buffer.
+ // 4) The irp was cancelled.
+ // 5) Some other failure from the USB device object.
+ //
+ ntStatus = urb->status;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_nsInterruptUsbIoCompleteRead Status %d\n", ntStatus);
+
+ // if we were not successful, we need to free the int buffer for future use right here
+ // otherwise interrupt data handler will free int buffer after it handle it.
+ if (( ntStatus != STATUS_SUCCESS )) {
+ pDevice->ulBulkInError++;
+ pDevice->intBuf.bInUse = false;
+
+// if (ntStatus == USBD_STATUS_CRC) {
+// pDevice->ulIntInContCRCError++;
+// }
+
+// if (ntStatus == STATUS_NOT_CONNECTED )
+// {
+ pDevice->fKillEventPollingThread = true;
+// }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"IntUSBIoCompleteControl STATUS = %d\n", ntStatus );
+ } else {
+ pDevice->ulIntInBytesRead += (unsigned long) urb->actual_length;
+ pDevice->ulIntInContCRCError = 0;
+ pDevice->bEventAvailable = true;
+ INTnsProcessData(pDevice);
+ }
+
+ STAvUpdateUSBCounter(&pDevice->scStatistic.USB_InterruptStat, ntStatus);
+
+ if (pDevice->fKillEventPollingThread != true) {
+ usb_fill_bulk_urb(pDevice->pInterruptURB,
+ pDevice->usb,
+ usb_rcvbulkpipe(pDevice->usb, 1),
+ (void *) pDevice->intBuf.pDataBuf,
+ MAX_INTERRUPT_SIZE,
+ s_nsInterruptUsbIoCompleteRead,
+ pDevice);
+
+ ntStatus = usb_submit_urb(pDevice->pInterruptURB, GFP_ATOMIC);
+ if (ntStatus != 0) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Submit int URB failed %d\n", ntStatus);
+ }
+ }
+ //
+ // We return STATUS_MORE_PROCESSING_REQUIRED so that the completion
+ // routine (IofCompleteRequest) will stop working on the irp.
+ //
+ return ;
+}
+
+/*
+ * Description:
+ * Allocates an usb BulkIn irp and calls USBD.
+ *
+ * Parameters:
+ * In:
+ * pDevice - Pointer to the adapter
+ * Out:
+ * none
+ *
+ * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver
+ *
+ */
+
+int PIPEnsBulkInUsbRead(struct vnt_private *pDevice, PRCB pRCB)
+{
+ int ntStatus = 0;
+ struct urb *pUrb;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsStartBulkInUsbRead\n");
+
+ if (pDevice->Flags & fMP_DISCONNECTED)
+ return STATUS_FAILURE;
+
+ pDevice->ulBulkInPosted++;
+
+ pUrb = pRCB->pUrb;
+ //
+ // Now that we have created the urb, we will send a
+ // request to the USB device object.
+ //
+ if (pRCB->skb == NULL) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pRCB->skb is null \n");
+ return ntStatus;
+ }
+
+ usb_fill_bulk_urb(pUrb,
+ pDevice->usb,
+ usb_rcvbulkpipe(pDevice->usb, 2),
+ (void *) (pRCB->skb->data),
+ MAX_TOTAL_SIZE_WITH_ALL_HEADERS,
+ s_nsBulkInUsbIoCompleteRead,
+ pRCB);
+
+ ntStatus = usb_submit_urb(pUrb, GFP_ATOMIC);
+ if (ntStatus != 0) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Submit Rx URB failed %d\n", ntStatus);
+ return STATUS_FAILURE ;
+ }
+ pRCB->Ref = 1;
+ pRCB->bBoolInUse= true;
+
+ return ntStatus;
+}
+
+/*
+ * Description:
+ * Complete function of usb BulkIn irp.
+ *
+ * Parameters:
+ * In:
+ * pDevice - Pointer to the adapter
+ *
+ * Out:
+ * none
+ *
+ * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver
+ *
+ */
+
+static void s_nsBulkInUsbIoCompleteRead(struct urb *urb)
+{
+ PRCB pRCB = (PRCB)urb->context;
+ struct vnt_private *pDevice = pRCB->pDevice;
+ unsigned long bytesRead;
+ int bIndicateReceive = false;
+ int bReAllocSkb = false;
+ int status;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsBulkInUsbIoCompleteRead\n");
+ status = urb->status;
+ bytesRead = urb->actual_length;
+
+ if (status) {
+ pDevice->ulBulkInError++;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BULK In failed %d\n", status);
+
+ pDevice->scStatistic.RxFcsErrCnt ++;
+//todo...xxxxxx
+// if (status == USBD_STATUS_CRC) {
+// pDevice->ulBulkInContCRCError++;
+// }
+// if (status == STATUS_DEVICE_NOT_CONNECTED )
+// {
+// MP_SET_FLAG(pDevice, fMP_DISCONNECTED);
+// }
+ } else {
+ if (bytesRead)
+ bIndicateReceive = true;
+ pDevice->ulBulkInContCRCError = 0;
+ pDevice->ulBulkInBytesRead += bytesRead;
+
+ pDevice->scStatistic.RxOkCnt ++;
+ }
+
+ STAvUpdateUSBCounter(&pDevice->scStatistic.USB_BulkInStat, status);
+
+ if (bIndicateReceive) {
+ spin_lock(&pDevice->lock);
+ if (RXbBulkInProcessData(pDevice, pRCB, bytesRead) == true)
+ bReAllocSkb = true;
+ spin_unlock(&pDevice->lock);
+ }
+ pRCB->Ref--;
+ if (pRCB->Ref == 0)
+ {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"RxvFreeNormal %d \n",pDevice->NumRecvFreeList);
+ spin_lock(&pDevice->lock);
+ RXvFreeRCB(pRCB, bReAllocSkb);
+ spin_unlock(&pDevice->lock);
+ }
+
+ return;
+}
+
+/*
+ * Description:
+ * Allocates an usb BulkOut irp and calls USBD.
+ *
+ * Parameters:
+ * In:
+ * pDevice - Pointer to the adapter
+ * Out:
+ * none
+ *
+ * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver
+ *
+ */
+
+int PIPEnsSendBulkOut(struct vnt_private *pDevice, PUSB_SEND_CONTEXT pContext)
+{
+ int status;
+ struct urb *pUrb;
+
+ pDevice->bPWBitOn = false;
+
+/*
+ if (pDevice->pPendingBulkOutContext != NULL) {
+ pDevice->NumContextsQueued++;
+ EnqueueContext(pDevice->FirstTxContextQueue, pDevice->LastTxContextQueue, pContext);
+ status = STATUS_PENDING;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Send pending!\n");
+ return status;
+ }
+*/
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_nsSendBulkOut\n");
+
+ if (MP_IS_READY(pDevice) && (pDevice->Flags & fMP_POST_WRITES)) {
+
+ pUrb = pContext->pUrb;
+ pDevice->ulBulkOutPosted++;
+// pDevice->pPendingBulkOutContext = pContext;
+ usb_fill_bulk_urb(
+ pUrb,
+ pDevice->usb,
+ usb_sndbulkpipe(pDevice->usb, 3),
+ (void *) &(pContext->Data[0]),
+ pContext->uBufLen,
+ s_nsBulkOutIoCompleteWrite,
+ pContext);
+
+ status = usb_submit_urb(pUrb, GFP_ATOMIC);
+ if (status != 0)
+ {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Submit Tx URB failed %d\n", status);
+ pContext->bBoolInUse = false;
+ return STATUS_FAILURE;
+ }
+ return STATUS_PENDING;
+ }
+ else {
+ pContext->bBoolInUse = false;
+ return STATUS_RESOURCES;
+ }
+}
+
+/*
+ * Description: s_nsBulkOutIoCompleteWrite
+ * 1a) Indicate to the protocol the status of the write.
+ * 1b) Return ownership of the packet to the protocol.
+ *
+ * 2) If any more packets are queue for sending, send another packet
+ * to USBD.
+ * If the attempt to send the packet to the driver fails,
+ * return ownership of the packet to the protocol and
+ * try another packet (until one succeeds).
+ *
+ * Parameters:
+ * In:
+ * pdoUsbDevObj - pointer to the USB device object which
+ * completed the irp
+ * pIrp - the irp which was completed by the
+ * device object
+ * pContext - the context given to IoSetCompletionRoutine
+ * before calling IoCallDriver on the irp
+ * The pContext is a pointer to the USB device object.
+ * Out:
+ * none
+ *
+ * Return Value: STATUS_MORE_PROCESSING_REQUIRED - allows the completion routine
+ * (IofCompleteRequest) to stop working on the irp.
+ *
+ */
+
+static void s_nsBulkOutIoCompleteWrite(struct urb *urb)
+{
+ struct vnt_private *pDevice;
+ int status;
+ CONTEXT_TYPE ContextType;
+ unsigned long ulBufLen;
+ PUSB_SEND_CONTEXT pContext;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsBulkOutIoCompleteWrite\n");
+ //
+ // The context given to IoSetCompletionRoutine is an USB_CONTEXT struct
+ //
+ pContext = (PUSB_SEND_CONTEXT) urb->context;
+ ASSERT( NULL != pContext );
+
+ pDevice = pContext->pDevice;
+ ContextType = pContext->Type;
+ ulBufLen = pContext->uBufLen;
+
+ if (!netif_device_present(pDevice->dev))
+ return;
+
+ //
+ // Perform various IRP, URB, and buffer 'sanity checks'
+ //
+
+ status = urb->status;
+ //we should have failed, succeeded, or cancelled, but NOT be pending
+ STAvUpdateUSBCounter(&pDevice->scStatistic.USB_BulkOutStat, status);
+
+ if(status == STATUS_SUCCESS) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Write %d bytes\n",(int)ulBufLen);
+ pDevice->ulBulkOutBytesWrite += ulBufLen;
+ pDevice->ulBulkOutContCRCError = 0;
+ pDevice->nTxDataTimeCout = 0;
+
+ } else {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BULK Out failed %d\n", status);
+ pDevice->ulBulkOutError++;
+ }
+
+// pDevice->ulCheckForHangCount = 0;
+// pDevice->pPendingBulkOutContext = NULL;
+
+ if ( CONTEXT_DATA_PACKET == ContextType ) {
+ // Indicate to the protocol the status of the sent packet and return
+ // ownership of the packet.
+ if (pContext->pPacket != NULL) {
+ dev_kfree_skb_irq(pContext->pPacket);
+ pContext->pPacket = NULL;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"tx %d bytes\n",(int)ulBufLen);
+ }
+
+ pDevice->dev->trans_start = jiffies;
+
+ if (status == STATUS_SUCCESS) {
+ pDevice->packetsSent++;
+ }
+ else {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Send USB error! [%08xh]\n", status);
+ pDevice->packetsSentDropped++;
+ }
+
+ }
+ if (pDevice->bLinkPass == true) {
+ if (netif_queue_stopped(pDevice->dev))
+ netif_wake_queue(pDevice->dev);
+ }
+ pContext->bBoolInUse = false;
+
+ return;
+}
diff --git a/drivers/staging/vt6656/usbpipe.h b/drivers/staging/vt6656/usbpipe.h
new file mode 100644
index 00000000..bb7a6111
--- /dev/null
+++ b/drivers/staging/vt6656/usbpipe.h
@@ -0,0 +1,46 @@
+/*
+ * 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: usbpipe.h
+ *
+ * Purpose:
+ *
+ * Author: Warren Hsu
+ *
+ * Date: Mar. 30, 2005
+ *
+ */
+
+#ifndef __USBPIPE_H__
+#define __USBPIPE_H__
+
+#include "device.h"
+
+int PIPEnsControlOut(struct vnt_private *, u8 byRequest, u16 wValue,
+ u16 wIndex, u16 wLength, u8 *pbyBuffer);
+int PIPEnsControlOutAsyn(struct vnt_private *, u8 byRequest,
+ u16 wValue, u16 wIndex, u16 wLength, u8 *pbyBuffer);
+int PIPEnsControlIn(struct vnt_private *, u8 byRequest, u16 wValue,
+ u16 wIndex, u16 wLength, u8 *pbyBuffer);
+
+int PIPEnsInterruptRead(struct vnt_private *);
+int PIPEnsBulkInUsbRead(struct vnt_private *, PRCB pRCB);
+int PIPEnsSendBulkOut(struct vnt_private *, PUSB_SEND_CONTEXT pContext);
+
+#endif /* __USBPIPE_H__ */
diff --git a/drivers/staging/vt6656/vntconfiguration.dat b/drivers/staging/vt6656/vntconfiguration.dat
new file mode 100644
index 00000000..933774c7
--- /dev/null
+++ b/drivers/staging/vt6656/vntconfiguration.dat
@@ -0,0 +1,6 @@
+#VNT Configuration
+[start]
+ZONETYPE=EUROPE
+AUTHENMODE=12
+ENCRYPTIONMODE=34
+[end] \ No newline at end of file
diff --git a/drivers/staging/vt6656/wcmd.c b/drivers/staging/vt6656/wcmd.c
new file mode 100644
index 00000000..0013cb73
--- /dev/null
+++ b/drivers/staging/vt6656/wcmd.c
@@ -0,0 +1,1203 @@
+/*
+ * 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
+ * s_bClearBSSID_SCAN- Clear BSSID_SCAN cmd in CMD Queue
+ *
+ * Revision History:
+ *
+ */
+
+#include "tmacro.h"
+#include "device.h"
+#include "mac.h"
+#include "card.h"
+#include "80211hdr.h"
+#include "wcmd.h"
+#include "wmgr.h"
+#include "power.h"
+#include "wctl.h"
+#include "baseband.h"
+#include "control.h"
+#include "rxtx.h"
+#include "rf.h"
+#include "rndis.h"
+#include "channel.h"
+#include "iowpa.h"
+
+static int msglevel =MSG_LEVEL_INFO;
+//static int msglevel =MSG_LEVEL_DEBUG;
+
+static void s_vProbeChannel(struct vnt_private *);
+
+static struct vnt_tx_mgmt *s_MgrMakeProbeRequest(struct vnt_private *,
+ struct vnt_manager *pMgmt, u8 *pScanBSSID, PWLAN_IE_SSID pSSID,
+ PWLAN_IE_SUPP_RATES pCurrRates, PWLAN_IE_SUPP_RATES pCurrExtSuppRates);
+
+static int s_bCommandComplete(struct vnt_private *);
+
+static int s_bClearBSSID_SCAN(struct vnt_private *);
+
+/*
+ * Description:
+ * Stop AdHoc beacon during scan process
+ *
+ * Parameters:
+ * In:
+ * pDevice - Pointer to the adapter
+ * Out:
+ * none
+ *
+ * Return Value: none
+ *
+ */
+
+static void vAdHocBeaconStop(struct vnt_private *pDevice)
+{
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ int 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)
+ {
+ //PMESG(("STOP_BEACON: IBSSChannel = %u, ScanChannel = %u\n",
+ // pMgmt->uIBSSChannel, pMgmt->uScanChannel));
+ MACvRegBitsOff(pDevice, MAC_REG_TCR, TCR_AUTOBCNTX);
+ }
+
+} /* vAdHocBeaconStop */
+
+/*
+ * Description:
+ * Restart AdHoc beacon after scan process complete
+ *
+ * Parameters:
+ * In:
+ * pDevice - Pointer to the adapter
+ * Out:
+ * none
+ *
+ * Return Value: none
+ *
+ */
+static void vAdHocBeaconRestart(struct vnt_private *pDevice)
+{
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+
+ /*
+ * 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))
+ {
+ //PMESG(("RESTART_BEACON\n"));
+ MACvRegBitsOn(pDevice, MAC_REG_TCR, TCR_AUTOBCNTX);
+ }
+
+}
+
+/*+
+ *
+ * Routine Description:
+ * Prepare and send probe request management frames.
+ *
+ *
+ * Return Value:
+ * none.
+ *
+-*/
+
+static void s_vProbeChannel(struct vnt_private *pDevice)
+{
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ struct vnt_tx_mgmt *pTxPacket;
+ u8 abyCurrSuppRatesG[] = {WLAN_EID_SUPP_RATES,
+ 8, 0x02, 0x04, 0x0B, 0x16, 0x24, 0x30, 0x48, 0x6C};
+ /* 1M, 2M, 5M, 11M, 18M, 24M, 36M, 54M*/
+ u8 abyCurrExtSuppRatesG[] = {WLAN_EID_EXTSUPP_RATES,
+ 4, 0x0C, 0x12, 0x18, 0x60};
+ /* 6M, 9M, 12M, 48M*/
+ u8 abyCurrSuppRatesA[] = {WLAN_EID_SUPP_RATES,
+ 8, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C};
+ u8 abyCurrSuppRatesB[] = {WLAN_EID_SUPP_RATES,
+ 4, 0x02, 0x04, 0x0B, 0x16};
+ u8 *pbyRate;
+ int ii;
+
+ if (pDevice->byBBType == BB_TYPE_11A) {
+ pbyRate = &abyCurrSuppRatesA[0];
+ } else if (pDevice->byBBType == BB_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 < 1 ; ii++) {
+ if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request sending fail.. \n");
+ }
+ else {
+ DBG_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 failure
+ *
+-*/
+
+struct vnt_tx_mgmt *s_MgrMakeProbeRequest(struct vnt_private *pDevice,
+ struct vnt_manager *pMgmt, u8 *pScanBSSID, PWLAN_IE_SSID pSSID,
+ PWLAN_IE_SUPP_RATES pCurrRates, PWLAN_IE_SUPP_RATES pCurrExtSuppRates)
+{
+ struct vnt_tx_mgmt *pTxPacket = NULL;
+ WLAN_FR_PROBEREQ sFrame;
+
+ pTxPacket = (struct vnt_tx_mgmt *)pMgmt->pbyMgmtPacketPool;
+ memset(pTxPacket, 0, sizeof(struct vnt_tx_mgmt)
+ + WLAN_PROBEREQ_FR_MAXLEN);
+ pTxPacket->p80211Header = (PUWLAN_80211HDR)((u8 *)pTxPacket
+ + sizeof(struct vnt_tx_mgmt));
+ sFrame.pBuf = (u8 *)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->byBBType == BB_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(struct vnt_private *pDevice, unsigned long MSecond)
+{
+
+ init_timer(&pDevice->sTimerCommand);
+
+ pDevice->sTimerCommand.data = (unsigned long)pDevice;
+ pDevice->sTimerCommand.function = (TimerFunction)vRunCommand;
+ pDevice->sTimerCommand.expires = RUN_AT((MSecond * HZ) / 1000);
+
+ add_timer(&pDevice->sTimerCommand);
+
+ return;
+}
+
+void vRunCommand(struct vnt_private *pDevice)
+{
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ PWLAN_IE_SSID pItemSSID;
+ PWLAN_IE_SSID pItemSSIDCurr;
+ CMD_STATUS Status;
+ struct sk_buff *skb;
+ union iwreq_data wrqu;
+ int ii;
+ u8 byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
+ u8 byData;
+
+ 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);
+ spin_unlock_irq(&pDevice->lock);
+ return;
+ }
+
+ pItemSSID = (PWLAN_IE_SSID)pMgmt->abyScanSSID;
+
+ if (pMgmt->uScanChannel == 0 ) {
+ pMgmt->uScanChannel = pDevice->byMinChannel;
+ }
+ if (pMgmt->uScanChannel > pDevice->byMaxChannel) {
+ pDevice->eCommandState = WLAN_CMD_SCAN_END;
+ s_bCommandComplete(pDevice);
+ spin_unlock_irq(&pDevice->lock);
+ return;
+
+ } else {
+ if (!ChannelValid(pDevice->byZoneType, pMgmt->uScanChannel)) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Invalid channel pMgmt->uScanChannel = %d \n",pMgmt->uScanChannel);
+ pMgmt->uScanChannel++;
+ s_bCommandComplete(pDevice);
+ spin_unlock_irq(&pDevice->lock);
+ return;
+ }
+ if (pMgmt->uScanChannel == pDevice->byMinChannel) {
+ // pMgmt->eScanType = WMAC_SCAN_ACTIVE; //mike mark
+ 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((void *) pDevice,
+ pDevice->bLinkPass); */
+ pMgmt->eScanState = WMAC_IS_SCANNING;
+ pDevice->byScanBBType = pDevice->byBBType; //lucas
+ pDevice->bStopDataPkt = true;
+ // Turn off RCR_BSSID filter every time
+ MACvRegBitsOff(pDevice, MAC_REG_RCR, RCR_BSSID);
+ pDevice->byRxMode &= ~RCR_BSSID;
+
+ }
+ //lucas
+ vAdHocBeaconStop(pDevice);
+ if ((pDevice->byBBType != BB_TYPE_11A) && (pMgmt->uScanChannel > CB_MAX_CHANNEL_24G)) {
+ pDevice->byBBType = BB_TYPE_11A;
+ CARDvSetBSSMode(pDevice);
+ }
+ else if ((pDevice->byBBType == BB_TYPE_11A) && (pMgmt->uScanChannel <= CB_MAX_CHANNEL_24G)) {
+ pDevice->byBBType = BB_TYPE_11G;
+ CARDvSetBSSMode(pDevice);
+ }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Scanning.... channel: [%d]\n", pMgmt->uScanChannel);
+ // Set channel
+ CARDbSetMediaChannel(pDevice, pMgmt->uScanChannel);
+ // Set Baseband to be more sensitive.
+
+ if (pDevice->bUpdateBBVGA) {
+ BBvSetShortSlotTime(pDevice);
+ BBvSetVGAGainOffset(pDevice, pDevice->abyBBVGA[0]);
+ BBvUpdatePreEDThreshold(pDevice, true);
+ }
+ pMgmt->uScanChannel++;
+
+ while (!ChannelValid(pDevice->byZoneType, pMgmt->uScanChannel) &&
+ pMgmt->uScanChannel <= pDevice->byMaxChannel ){
+ pMgmt->uScanChannel++;
+ }
+
+ if (pMgmt->uScanChannel > pDevice->byMaxChannel) {
+ // Set Baseband to be not sensitive and rescan
+ pDevice->eCommandState = WLAN_CMD_SCAN_END;
+
+ }
+ if ((pMgmt->b11hEnable == false) ||
+ (pMgmt->uScanChannel < CB_MAX_CHANNEL_24G)) {
+ s_vProbeChannel(pDevice);
+ spin_unlock_irq(&pDevice->lock);
+ vCommandTimerWait((void *) pDevice, 100);
+ return;
+ } else {
+ spin_unlock_irq(&pDevice->lock);
+ vCommandTimerWait((void *) pDevice, WCMD_PASSIVE_SCAN_TIME);
+ return;
+ }
+
+ }
+
+ break;
+
+ case WLAN_CMD_SCAN_END:
+
+ // Set Baseband's sensitivity back.
+ if (pDevice->byBBType != pDevice->byScanBBType) {
+ pDevice->byBBType = pDevice->byScanBBType;
+ CARDvSetBSSMode(pDevice);
+ }
+
+ if (pDevice->bUpdateBBVGA) {
+ BBvSetShortSlotTime(pDevice);
+ BBvSetVGAGainOffset(pDevice, pDevice->byBBVGACurrent);
+ BBvUpdatePreEDThreshold(pDevice, false);
+ }
+
+ // Set channel back
+ vAdHocBeaconRestart(pDevice);
+ // Set channel back
+ CARDbSetMediaChannel(pDevice, pMgmt->uCurrChannel);
+ // Set Filter
+ if (pMgmt->bCurrBSSIDFilterOn) {
+ MACvRegBitsOn(pDevice, MAC_REG_RCR, RCR_BSSID);
+ pDevice->byRxMode |= RCR_BSSID;
+ }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Scanning, set back to channel: [%d]\n", pMgmt->uCurrChannel);
+ pMgmt->uScanChannel = 0;
+ pMgmt->eScanState = WMAC_NO_SCANNING;
+ pDevice->bStopDataPkt = false;
+
+ /*send scan event to wpa_Supplicant*/
+ PRINT_K("wireless_send_event--->SIOCGIWSCAN(scan done)\n");
+ memset(&wrqu, 0, sizeof(wrqu));
+ wireless_send_event(pDevice->dev, SIOCGIWSCAN, &wrqu, NULL);
+
+ 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 {
+
+ pDevice->bwextstep0 = false;
+ pDevice->bwextstep1 = false;
+ pDevice->bwextstep2 = false;
+ pDevice->bwextstep3 = false;
+ pDevice->bWPASuppWextEnabled = false;
+ pDevice->fWPA_Authened = false;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Send Disassociation Packet..\n");
+ // reason = 8 : disassoc because sta has left
+ vMgrDisassocBeginSta((void *) pDevice,
+ pMgmt,
+ pMgmt->abyCurrBSSID,
+ (8),
+ &Status);
+ pDevice->bLinkPass = false;
+ ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW);
+ // 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);
+ if (pDevice->bNeedRadioOFF == true)
+ 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;
+ }
+
+ 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;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" cmd: desire ssid = %s\n", pItemSSID->abySSID);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" cmd: curr ssid = %s\n", pItemSSIDCurr->abySSID);
+
+ if (pMgmt->eCurrState == WMAC_STATE_ASSOC) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Cmd pMgmt->eCurrState == WMAC_STATE_ASSOC\n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pItemSSID->len =%d\n",pItemSSID->len);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pItemSSIDCurr->len = %d\n",pItemSSIDCurr->len);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" desire ssid = %s\n", pItemSSID->abySSID);
+ DBG_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;
+ ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW);
+ }
+ // set initial state
+ pMgmt->eCurrState = WMAC_STATE_IDLE;
+ pMgmt->eCurrMode = WMAC_MODE_STANDBY;
+ PSvDisablePowerSaving((void *) pDevice);
+ BSSvClearNodeDBTable(pDevice, 0);
+ vMgrJoinBSSBegin((void *) 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) because sta has left ESS
+ if (pMgmt->eCurrState >= WMAC_STATE_AUTH) {
+ vMgrDeAuthenBeginSta((void *)pDevice,
+ pMgmt,
+ pMgmt->abyCurrBSSID,
+ (3),
+ &Status);
+ }
+ // Call mgr to begin the authentication
+ vMgrAuthenBeginSta((void *) pDevice, pMgmt, &Status);
+ if (Status == CMD_STATUS_SUCCESS) {
+ pDevice->byLinkWaitCount = 0;
+ pDevice->eCommandState = WLAN_AUTHENTICATE_WAIT;
+ vCommandTimerWait((void *) pDevice, AUTHENTICATE_TIMEOUT);
+ spin_unlock_irq(&pDevice->lock);
+ DBG_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;
+ ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_INTER);
+ pMgmt->sNodeDBTable[0].bActive = true;
+ pMgmt->sNodeDBTable[0].uInActiveCount = 0;
+ }
+ else {
+ // start own IBSS
+ DBG_PRT(MSG_LEVEL_DEBUG,
+ KERN_INFO "CreateOwn IBSS by CurrMode = IBSS_STA\n");
+ vMgrCreateOwnIBSS((void *) pDevice, &Status);
+ if (Status != CMD_STATUS_SUCCESS){
+ DBG_PRT(MSG_LEVEL_DEBUG,
+ KERN_INFO "WLAN_CMD_IBSS_CREATE fail!\n");
+ }
+ BSSvAddMulticastNode(pDevice);
+ }
+ s_bClearBSSID_SCAN(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
+ DBG_PRT(MSG_LEVEL_DEBUG,
+ KERN_INFO "CreateOwn IBSS by CurrMode = STANDBY\n");
+ vMgrCreateOwnIBSS((void *) pDevice, &Status);
+ if (Status != CMD_STATUS_SUCCESS){
+ DBG_PRT(MSG_LEVEL_DEBUG,
+ KERN_INFO "WLAN_CMD_IBSS_CREATE fail!\n");
+ }
+ BSSvAddMulticastNode(pDevice);
+ s_bClearBSSID_SCAN(pDevice);
+/*
+ pDevice->bLinkPass = true;
+ ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_INTER);
+ if (netif_queue_stopped(pDevice->dev)){
+ netif_wake_queue(pDevice->dev);
+ }
+ s_bClearBSSID_SCAN(pDevice);
+*/
+ }
+ else {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disconnect SSID none\n");
+ // if(pDevice->bWPASuppWextEnabled == true)
+ {
+ union iwreq_data wrqu;
+ memset(&wrqu, 0, sizeof (wrqu));
+ wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+ PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated:vMgrJoinBSSBegin Fail !!)\n");
+ wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
+ }
+ }
+ }
+ s_bCommandComplete(pDevice);
+ break;
+
+ case WLAN_AUTHENTICATE_WAIT :
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState == WLAN_AUTHENTICATE_WAIT\n");
+ if (pMgmt->eCurrState == WMAC_STATE_AUTH) {
+ pDevice->byLinkWaitCount = 0;
+ // Call mgr to begin the association
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCurrState == WMAC_STATE_AUTH\n");
+ vMgrAssocBeginSta((void *) pDevice, pMgmt, &Status);
+ if (Status == CMD_STATUS_SUCCESS) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState = WLAN_ASSOCIATE_WAIT\n");
+ pDevice->byLinkWaitCount = 0;
+ pDevice->eCommandState = WLAN_ASSOCIATE_WAIT;
+ vCommandTimerWait((void *) 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((void *) pDevice, AUTHENTICATE_TIMEOUT/2);
+ return;
+ }
+ pDevice->byLinkWaitCount = 0;
+
+ s_bCommandComplete(pDevice);
+ break;
+
+ case WLAN_ASSOCIATE_WAIT :
+ if (pMgmt->eCurrState == WMAC_STATE_ASSOC) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCurrState == WMAC_STATE_ASSOC\n");
+ if (pDevice->ePSMode != WMAC_POWER_CAM) {
+ PSvEnablePowerSaving((void *) pDevice,
+ pMgmt->wListenInterval);
+ }
+/*
+ if (pMgmt->eAuthenMode >= WMAC_AUTH_WPA) {
+ KeybRemoveAllKey(pDevice, &(pDevice->sKey), pDevice->abyBSSID);
+ }
+*/
+ pDevice->byLinkWaitCount = 0;
+ pDevice->byReAssocCount = 0;
+ pDevice->bLinkPass = true;
+ ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_INTER);
+ s_bClearBSSID_SCAN(pDevice);
+
+ if (netif_queue_stopped(pDevice->dev)){
+ netif_wake_queue(pDevice->dev);
+ }
+
+ 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 = (unsigned long) 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 trigger TimerTxData InSleep\n");
+ }
+ pDevice->IsTxDataTrigger = true;
+ add_timer(&pDevice->sTimerTxData);
+
+ }
+ 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((void *) pDevice, ASSOCIATE_TIMEOUT/2);
+ return;
+ }
+ pDevice->byLinkWaitCount = 0;
+
+ s_bCommandComplete(pDevice);
+ break;
+
+ case WLAN_CMD_AP_MODE_START :
+ DBG_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;
+ ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW);
+ if (pDevice->bEnableHostWEP == true)
+ BSSvClearNodeDBTable(pDevice, 1);
+ else
+ BSSvClearNodeDBTable(pDevice, 0);
+ pDevice->uAssocCount = 0;
+ pMgmt->eCurrState = WMAC_STATE_IDLE;
+ pDevice->bFixRate = false;
+
+ vMgrCreateOwnIBSS((void *) pDevice, &Status);
+ if (Status != CMD_STATUS_SUCCESS) {
+ DBG_PRT(MSG_LEVEL_DEBUG,
+ KERN_INFO "vMgrCreateOwnIBSS fail!\n");
+ }
+ // always turn off unicast bit
+ MACvRegBitsOff(pDevice, MAC_REG_RCR, RCR_UNICAST);
+ pDevice->byRxMode &= ~RCR_UNICAST;
+ DBG_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;
+ ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_INTER);
+ 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 (nsDMA_tx_packet(pDevice, TYPE_AC0DMA, skb) != 0) {
+ DBG_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) {
+ DBG_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 (nsDMA_tx_packet(pDevice, TYPE_AC0DMA, skb) != 0) {
+ DBG_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];
+ DBG_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:
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState == WLAN_CMD_RADIO_START\n");
+ // if (pDevice->bRadioCmd == true)
+ // CARDbRadioPowerOn(pDevice);
+ // else
+ // CARDbRadioPowerOff(pDevice);
+
+ {
+ int ntStatus = STATUS_SUCCESS;
+ u8 byTmp;
+
+ ntStatus = CONTROLnsRequestIn(pDevice,
+ MESSAGE_TYPE_READ,
+ MAC_REG_GPIOCTL1,
+ MESSAGE_REQUEST_MACREG,
+ 1,
+ &byTmp);
+
+ if ( ntStatus != STATUS_SUCCESS ) {
+ s_bCommandComplete(pDevice);
+ spin_unlock_irq(&pDevice->lock);
+ return;
+ }
+ if ( (byTmp & GPIO3_DATA) == 0 ) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" WLAN_CMD_RADIO_START_OFF........................\n");
+ // Old commands are useless.
+ // empty command Q
+ pDevice->cbFreeCmdQueue = CMD_Q_SIZE;
+ pDevice->uCmdDequeueIdx = 0;
+ pDevice->uCmdEnqueueIdx = 0;
+ //0415pDevice->bCmdRunning = false;
+ pDevice->bCmdClear = true;
+ pDevice->bStopTx0Pkt = false;
+ pDevice->bStopDataPkt = true;
+
+ pDevice->byKeyIndex = 0;
+ pDevice->bTransmitKey = false;
+ spin_unlock_irq(&pDevice->lock);
+ KeyvInitTable(pDevice,&pDevice->sKey);
+ spin_lock_irq(&pDevice->lock);
+ pMgmt->byCSSPK = KEY_CTL_NONE;
+ pMgmt->byCSSGK = KEY_CTL_NONE;
+
+ if (pDevice->bLinkPass == true) {
+ // reason = 8 : disassoc because sta has left
+ vMgrDisassocBeginSta((void *) pDevice,
+ pMgmt,
+ pMgmt->abyCurrBSSID,
+ (8),
+ &Status);
+ pDevice->bLinkPass = false;
+ // unlock command busy
+ pMgmt->eCurrState = WMAC_STATE_IDLE;
+ pMgmt->sNodeDBTable[0].bActive = false;
+ // if(pDevice->bWPASuppWextEnabled == true)
+ {
+ union iwreq_data wrqu;
+ memset(&wrqu, 0, sizeof (wrqu));
+ wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+ PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n");
+ wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
+ }
+ }
+ pDevice->bwextstep0 = false;
+ pDevice->bwextstep1 = false;
+ pDevice->bwextstep2 = false;
+ pDevice->bwextstep3 = false;
+ pDevice->bWPASuppWextEnabled = false;
+ //clear current SSID
+ pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
+ pItemSSID->len = 0;
+ memset(pItemSSID->abySSID, 0, WLAN_SSID_MAXLEN);
+ //clear desired SSID
+ pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
+ pItemSSID->len = 0;
+ memset(pItemSSID->abySSID, 0, WLAN_SSID_MAXLEN);
+
+ netif_stop_queue(pDevice->dev);
+ CARDbRadioPowerOff(pDevice);
+ MACvRegBitsOn(pDevice,MAC_REG_GPIOCTL1,GPIO3_INTMD);
+ ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_OFF);
+ pDevice->bHWRadioOff = true;
+ } else {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" WLAN_CMD_RADIO_START_ON........................\n");
+ pDevice->bHWRadioOff = false;
+ CARDbRadioPowerOn(pDevice);
+ MACvRegBitsOff(pDevice,MAC_REG_GPIOCTL1,GPIO3_INTMD);
+ ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_ON);
+ }
+ }
+
+ s_bCommandComplete(pDevice);
+ break;
+
+ case WLAN_CMD_CHANGE_BBSENSITIVITY_START:
+
+ pDevice->bStopDataPkt = true;
+ pDevice->byBBVGACurrent = pDevice->byBBVGANew;
+ BBvSetVGAGainOffset(pDevice, pDevice->byBBVGACurrent);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Change sensitivity pDevice->byBBVGACurrent = %x\n", pDevice->byBBVGACurrent);
+ pDevice->bStopDataPkt = false;
+ s_bCommandComplete(pDevice);
+ break;
+
+ case WLAN_CMD_TBTT_WAKEUP_START:
+ PSbIsNextTBTTWakeUp(pDevice);
+ s_bCommandComplete(pDevice);
+ break;
+
+ case WLAN_CMD_BECON_SEND_START:
+ bMgrPrepareBeaconToSend(pDevice, pMgmt);
+ s_bCommandComplete(pDevice);
+ break;
+
+ case WLAN_CMD_SETPOWER_START:
+
+ RFbSetPower(pDevice, pDevice->wCurrentRate, pMgmt->uCurrChannel);
+
+ s_bCommandComplete(pDevice);
+ break;
+
+ case WLAN_CMD_CHANGE_ANTENNA_START:
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Change from Antenna%d to", (int)pDevice->dwRxAntennaSel);
+ if ( pDevice->dwRxAntennaSel == 0) {
+ pDevice->dwRxAntennaSel=1;
+ if (pDevice->bTxRxAntInv == true)
+ BBvSetAntennaMode(pDevice, ANT_RXA);
+ else
+ BBvSetAntennaMode(pDevice, ANT_RXB);
+ } else {
+ pDevice->dwRxAntennaSel=0;
+ if (pDevice->bTxRxAntInv == true)
+ BBvSetAntennaMode(pDevice, ANT_RXB);
+ else
+ BBvSetAntennaMode(pDevice, ANT_RXA);
+ }
+ s_bCommandComplete(pDevice);
+ break;
+
+ case WLAN_CMD_REMOVE_ALLKEY_START:
+ KeybRemoveAllKey(pDevice, &(pDevice->sKey), pDevice->abyBSSID);
+ s_bCommandComplete(pDevice);
+ break;
+
+ case WLAN_CMD_MAC_DISPOWERSAVING_START:
+ ControlvReadByte (pDevice, MESSAGE_REQUEST_MACREG, MAC_REG_PSCTL, &byData);
+ if ( (byData & PSCTL_PS) != 0 ) {
+ // disable power saving hw function
+ CONTROLnsRequestOut(pDevice,
+ MESSAGE_TYPE_DISABLE_PS,
+ 0,
+ 0,
+ 0,
+ NULL
+ );
+ }
+ s_bCommandComplete(pDevice);
+ break;
+
+ case WLAN_CMD_11H_CHSW_START:
+ CARDbSetMediaChannel(pDevice, pDevice->byNewChannel);
+ pDevice->bChannelSwitch = false;
+ pMgmt->uCurrChannel = pDevice->byNewChannel;
+ pDevice->bStopDataPkt = false;
+ s_bCommandComplete(pDevice);
+ break;
+
+ default:
+ s_bCommandComplete(pDevice);
+ break;
+ } //switch
+
+ spin_unlock_irq(&pDevice->lock);
+ return;
+}
+
+static int s_bCommandComplete(struct vnt_private *pDevice)
+{
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ PWLAN_IE_SSID pSSID;
+ int bRadioCmd = false;
+ int bForceSCAN = true;
+
+ 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:
+ DBG_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) {
+ memcpy(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) &&
+ ( !memcmp(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)
+ memcpy(pMgmt->abyDesireSSID, pSSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+ DBG_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_CHANGE_BBSENSITIVITY_START;
+ break;
+
+ case WLAN_CMD_TBTT_WAKEUP:
+ pDevice->eCommandState = WLAN_CMD_TBTT_WAKEUP_START;
+ break;
+
+ case WLAN_CMD_BECON_SEND:
+ pDevice->eCommandState = WLAN_CMD_BECON_SEND_START;
+ break;
+
+ case WLAN_CMD_SETPOWER:
+ pDevice->eCommandState = WLAN_CMD_SETPOWER_START;
+ break;
+
+ case WLAN_CMD_CHANGE_ANTENNA:
+ pDevice->eCommandState = WLAN_CMD_CHANGE_ANTENNA_START;
+ break;
+
+ case WLAN_CMD_REMOVE_ALLKEY:
+ pDevice->eCommandState = WLAN_CMD_REMOVE_ALLKEY_START;
+ break;
+
+ case WLAN_CMD_MAC_DISPOWERSAVING:
+ pDevice->eCommandState = WLAN_CMD_MAC_DISPOWERSAVING_START;
+ break;
+
+ case WLAN_CMD_11H_CHSW:
+ pDevice->eCommandState = WLAN_CMD_11H_CHSW_START;
+ break;
+
+ default:
+ break;
+
+ }
+ vCommandTimerWait(pDevice, 0);
+ }
+
+ return true;
+}
+
+int bScheduleCommand(struct vnt_private *pDevice,
+ CMD_CODE eCommand, u8 *pbyItem0)
+{
+
+ 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:
+ pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bForceSCAN = false;
+ memcpy(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID,
+ pbyItem0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+ break;
+
+ case WLAN_CMD_SSID:
+ memcpy(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID,
+ pbyItem0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+ break;
+
+ case WLAN_CMD_DISASSOCIATE:
+ pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bNeedRadioOFF = *((int *)pbyItem0);
+ break;
+/*
+ case WLAN_CMD_DEAUTH:
+ pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].wDeAuthenReason = *((u16 *)pbyItem0);
+ break;
+*/
+
+ case WLAN_CMD_RADIO:
+ pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bRadioCmd = *((int *)pbyItem0);
+ 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
+ *
+ */
+static int s_bClearBSSID_SCAN(struct vnt_private *pDevice)
+{
+ unsigned int uCmdDequeueIdx = pDevice->uCmdDequeueIdx;
+ unsigned int 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(struct vnt_private *pDevice)
+{
+
+ //delete timer
+ del_timer(&pDevice->sTimerCommand);
+ //init timer
+ init_timer(&pDevice->sTimerCommand);
+ pDevice->sTimerCommand.data = (unsigned long)pDevice;
+ pDevice->sTimerCommand.function = (TimerFunction)vRunCommand;
+ 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;
+}
+
+void BSSvSecondTxData(struct vnt_private *pDevice)
+{
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+
+ 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);
+ //is wap_supplicant running successful OR only open && sharekey mode!
+ if (((pDevice->bLinkPass == true) &&
+ (pMgmt->eAuthenMode < WMAC_AUTH_WPA)) || //open && sharekey linking
+ (pDevice->fWPA_Authened == true)) { //wpa linking
+ // 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);
+}
diff --git a/drivers/staging/vt6656/wcmd.h b/drivers/staging/vt6656/wcmd.h
new file mode 100644
index 00000000..db8b4cf7
--- /dev/null
+++ b/drivers/staging/vt6656/wcmd.h
@@ -0,0 +1,119 @@
+/*
+ * 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__
+
+#include "80211hdr.h"
+#include "80211mgr.h"
+
+#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, *PCMD_CODE;
+
+#define CMD_Q_SIZE 32
+
+typedef enum tagCMD_STATUS {
+
+ CMD_STATUS_SUCCESS = 0,
+ CMD_STATUS_FAILURE,
+ CMD_STATUS_RESOURCES,
+ CMD_STATUS_TIMEOUT,
+ CMD_STATUS_PENDING
+
+} CMD_STATUS, *PCMD_STATUS;
+
+typedef struct tagCMD_ITEM {
+ CMD_CODE eCmd;
+ u8 abyCmdDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
+ bool bNeedRadioOFF;
+ bool bRadioCmd;
+ bool bForceSCAN;
+ u16 wDeAuthenReason;
+} CMD_ITEM, *PCMD_ITEM;
+
+// Command state
+typedef enum tagCMD_STATE {
+ WLAN_CMD_SCAN_START,
+ WLAN_CMD_SCAN_END,
+ WLAN_CMD_DISASSOCIATE_START,
+ WLAN_CMD_DEAUTHEN_START,
+ WLAN_CMD_SSID_START,
+ WLAN_AUTHENTICATE_WAIT,
+ WLAN_ASSOCIATE_WAIT,
+ WLAN_DISASSOCIATE_WAIT,
+ WLAN_CMD_TX_PSPACKET_START,
+ WLAN_CMD_RADIO_START,
+ WLAN_CMD_CHANGE_BBSENSITIVITY_START,
+ WLAN_CMD_SETPOWER_START,
+ WLAN_CMD_AP_MODE_START,
+ WLAN_CMD_TBTT_WAKEUP_START,
+ WLAN_CMD_BECON_SEND_START,
+ WLAN_CMD_CHANGE_ANTENNA_START,
+ WLAN_CMD_REMOVE_ALLKEY_START,
+ WLAN_CMD_MAC_DISPOWERSAVING_START,
+ WLAN_CMD_11H_CHSW_START,
+ WLAN_CMD_IDLE
+} CMD_STATE, *PCMD_STATE;
+
+struct vnt_private;
+
+void vResetCommandTimer(struct vnt_private *);
+
+int bScheduleCommand(struct vnt_private *, CMD_CODE eCommand, u8 *pbyItem0);
+
+void vRunCommand(struct vnt_private *);
+
+/*
+void
+WCMDvCommandThread(
+ void * Context
+ );
+*/
+
+void BSSvSecondTxData(struct vnt_private *);
+
+#endif /* __WCMD_H__ */
diff --git a/drivers/staging/vt6656/wctl.c b/drivers/staging/vt6656/wctl.c
new file mode 100644
index 00000000..47a655db
--- /dev/null
+++ b/drivers/staging/vt6656/wctl.c
@@ -0,0 +1,245 @@
+/*
+ * 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:
+ *
+ */
+
+#include "wctl.h"
+#include "device.h"
+#include "card.h"
+#include "tmacro.h"
+
+// static int msglevel =MSG_LEVEL_INFO;
+
+/*
+ * 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, struct ieee80211_hdr *pMACHeader)
+{
+ unsigned int uIndex;
+ unsigned int 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->seq_ctrl) &&
+ (!compare_ether_addr(&(pCacheEntry->abyAddr2[0]),
+ &(pMACHeader->addr2[0]))) &&
+ (LOBYTE(pCacheEntry->wFrameCtl) == LOBYTE(pMACHeader->frame_control))
+ ) {
+ /* Duplicate match */
+ return true;
+ }
+ ADD_ONE_WITH_WRAP_AROUND(uIndex, DUPLICATE_RX_CACHE_LENGTH);
+ }
+ }
+ /* Not found in cache - insert */
+ pCacheEntry = &pCache->asCacheEntry[pCache->uInPtr];
+ pCacheEntry->wFmSequence = pMACHeader->seq_ctrl;
+ memcpy(&(pCacheEntry->abyAddr2[0]), &(pMACHeader->addr2[0]), ETH_ALEN);
+ pCacheEntry->wFrameCtl = pMACHeader->frame_control;
+ 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
+ *
+ */
+
+unsigned int WCTLuSearchDFCB(struct vnt_private *pDevice,
+ struct ieee80211_hdr *pMACHeader)
+{
+ unsigned int ii;
+
+ for (ii = 0; ii < pDevice->cbDFCB; ii++) {
+ if ((pDevice->sRxDFCB[ii].bInUse == true) &&
+ (!compare_ether_addr(&(pDevice->sRxDFCB[ii].abyAddr2[0]),
+ &(pMACHeader->addr2[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
+ *
+ */
+unsigned int WCTLuInsertDFCB(struct vnt_private *pDevice,
+ struct ieee80211_hdr *pMACHeader)
+{
+ unsigned int 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->seq_ctrl >> 4);
+ pDevice->sRxDFCB[ii].wFragNum = (pMACHeader->seq_ctrl & 0x000F);
+ memcpy(&(pDevice->sRxDFCB[ii].abyAddr2[0]),
+ &(pMACHeader->addr2[0]),
+ ETH_ALEN);
+ 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(struct vnt_private *pDevice, struct ieee80211_hdr *pMACHeader, unsigned int cbFrameLength, bool bWEP, bool bExtIV)
+{
+ unsigned int 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->seq_ctrl >> 4);
+ pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wFragNum = (pMACHeader->seq_ctrl & 0x000F);
+ }
+ else {
+ pDevice->uCurrentDFCBIdx = WCTLuInsertDFCB(pDevice, pMACHeader);
+ if (pDevice->uCurrentDFCBIdx == pDevice->cbDFCB) {
+ return(false);
+ }
+ }
+ // reserve 8 byte to match MAC RX Buffer
+ pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer = (u8 *) (pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].skb->data + 8);
+// pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer = (u8 *) (pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].skb->data + 4);
+ 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++;
+ //DBG_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->seq_ctrl >> 4)) &&
+ (pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wFragNum == (pMACHeader->seq_ctrl & 0x000F)) &&
+ ((pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength + cbFrameLength - uHeaderSize) < 2346)) {
+
+ memcpy(pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer, ((u8 *) (pMACHeader) + uHeaderSize), (cbFrameLength - uHeaderSize));
+ pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength += (cbFrameLength - uHeaderSize);
+ pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer += (cbFrameLength - uHeaderSize);
+ pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wFragNum++;
+ //DBG_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;
+ //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Last pDevice->uCurrentDFCBIdx= %d\n", pDevice->uCurrentDFCBIdx);
+ return(true);
+ }
+ return(false);
+ }
+}
+
diff --git a/drivers/staging/vt6656/wctl.h b/drivers/staging/vt6656/wctl.h
new file mode 100644
index 00000000..14cb4117
--- /dev/null
+++ b/drivers/staging/vt6656/wctl.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: wctl.h
+ *
+ * Purpose:
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Jun. 27, 2002
+ *
+ */
+
+#ifndef __WCTL_H__
+#define __WCTL_H__
+
+#include "tether.h"
+#include "device.h"
+
+#define IS_TYPE_DATA(pMACHeader) \
+ ((((struct ieee80211_hdr *) pMACHeader)->frame_control & TYPE_802_11_MASK) == TYPE_802_11_DATA)
+
+#define IS_TYPE_MGMT(pMACHeader) \
+ ((((struct ieee80211_hdr *) pMACHeader)->frame_control & TYPE_802_11_MASK) == TYPE_802_11_MGMT)
+
+#define IS_TYPE_CONTROL(pMACHeader) \
+ ((((struct ieee80211_hdr *) pMACHeader)->frame_control & TYPE_802_11_MASK) == TYPE_802_11_CTL)
+
+#define IS_FC_MOREDATA(pMACHeader) \
+ ((((struct ieee80211_hdr *) pMACHeader)->frame_control & FC_MOREDATA) == FC_MOREDATA)
+
+#define IS_FC_POWERMGT(pMACHeader) \
+ ((((struct ieee80211_hdr *) pMACHeader)->frame_control & FC_POWERMGT) == FC_POWERMGT)
+
+#define IS_FC_RETRY(pMACHeader) \
+ ((((struct ieee80211_hdr *) pMACHeader)->frame_control & FC_RETRY) == FC_RETRY)
+
+#define IS_FC_WEP(pMACHeader) \
+ ((((struct ieee80211_hdr *) pMACHeader)->frame_control & FC_WEP) == FC_WEP)
+
+#ifdef __BIG_ENDIAN
+
+#define IS_FRAGMENT_PKT(pMACHeader) \
+ (((((struct ieee80211_hdr *) pMACHeader)->frame_control & FC_MOREFRAG) != 0) | \
+ ((((struct ieee80211_hdr *) pMACHeader)->seq_ctrl & 0x0F00) != 0))
+
+#define IS_FIRST_FRAGMENT_PKT(pMACHeader) \
+ ((((struct ieee80211_hdr *) pMACHeader)->seq_ctrl & 0x0F00) == 0)
+
+#else
+
+#define IS_FRAGMENT_PKT(pMACHeader) \
+ (((((struct ieee80211_hdr *) pMACHeader)->frame_control & FC_MOREFRAG) != 0) | \
+ ((((struct ieee80211_hdr *) pMACHeader)->seq_ctrl & 0x000F) != 0))
+
+#define IS_FIRST_FRAGMENT_PKT(pMACHeader) \
+ ((((struct ieee80211_hdr *) pMACHeader)->seq_ctrl & 0x000F) == 0)
+
+#endif//#ifdef __BIG_ENDIAN
+
+#define IS_LAST_FRAGMENT_PKT(pMACHeader) \
+ ((((struct ieee80211_hdr *) pMACHeader)->frame_control & FC_MOREFRAG) == 0)
+
+#define IS_CTL_PSPOLL(pMACHeader) \
+ ((((struct ieee80211_hdr *) pMACHeader)->frame_control & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL)
+
+#define ADD_ONE_WITH_WRAP_AROUND(uVar, uModulo) { \
+ if ((uVar) >= ((uModulo) - 1)) \
+ (uVar) = 0; \
+ else \
+ (uVar)++; \
+}
+
+bool WCTLbIsDuplicate(PSCache pCache, struct ieee80211_hdr *pMACHeader);
+bool WCTLbHandleFragment(struct vnt_private *, struct ieee80211_hdr *pMACHeader, unsigned int cbFrameLength, bool bWEP, bool bExtIV);
+unsigned int WCTLuSearchDFCB(struct vnt_private *, struct ieee80211_hdr *pMACHeader);
+unsigned int WCTLuInsertDFCB(struct vnt_private *, struct ieee80211_hdr *pMACHeader);
+
+#endif /* __WCTL_H__ */
diff --git a/drivers/staging/vt6656/wmgr.c b/drivers/staging/vt6656/wmgr.c
new file mode 100644
index 00000000..6d1ff5ee
--- /dev/null
+++ b/drivers/staging/vt6656/wmgr.c
@@ -0,0 +1,4408 @@
+/*
+ * 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 Object 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- Assembler TIM field of beacon
+ * vMgrTimerInit- Initial 1-sec and command call back funtions
+ *
+ * Revision History:
+ *
+ */
+
+#include "tmacro.h"
+#include "desc.h"
+#include "device.h"
+#include "card.h"
+#include "80211hdr.h"
+#include "80211mgr.h"
+#include "wmgr.h"
+#include "wcmd.h"
+#include "mac.h"
+#include "bssdb.h"
+#include "power.h"
+#include "datarate.h"
+#include "baseband.h"
+#include "rxtx.h"
+#include "wpa.h"
+#include "rf.h"
+#include "iowpa.h"
+#include "control.h"
+#include "rndis.h"
+
+static int msglevel =MSG_LEVEL_INFO;
+//static int msglevel =MSG_LEVEL_DEBUG;
+
+static int ChannelExceedZoneType(struct vnt_private *, u8 byCurrChannel);
+
+/* Association/diassociation functions */
+static struct vnt_tx_mgmt *s_MgrMakeAssocRequest(struct vnt_private *,
+ struct vnt_manager *pMgmt, u8 *pDAddr, u16 wCurrCapInfo,
+ u16 wListenInterval, PWLAN_IE_SSID pCurrSSID,
+ PWLAN_IE_SUPP_RATES pCurrRates, PWLAN_IE_SUPP_RATES pCurrExtSuppRates);
+
+static void s_vMgrRxAssocRequest(struct vnt_private *,
+ struct vnt_manager *pMgmt, struct vnt_rx_mgmt *pRxPacket,
+ u32 uNodeIndex);
+
+static struct vnt_tx_mgmt *s_MgrMakeReAssocRequest(struct vnt_private *,
+ struct vnt_manager *pMgmt, u8 *pDAddr, u16 wCurrCapInfo,
+ u16 wListenInterval, PWLAN_IE_SSID pCurrSSID,
+ PWLAN_IE_SUPP_RATES pCurrRates, PWLAN_IE_SUPP_RATES pCurrExtSuppRates);
+
+static void s_vMgrRxAssocResponse(struct vnt_private *,
+ struct vnt_manager *pMgmt, struct vnt_rx_mgmt *pRxPacket,
+ int bReAssocType);
+
+static void s_vMgrRxDisassociation(struct vnt_private *,
+ struct vnt_manager *pMgmt, struct vnt_rx_mgmt *pRxPacket);
+
+/* Authentication/deauthen functions */
+static void s_vMgrRxAuthenSequence_1(struct vnt_private *,
+ struct vnt_manager *pMgmt, PWLAN_FR_AUTHEN pFrame);
+
+static void s_vMgrRxAuthenSequence_2(struct vnt_private *,
+ struct vnt_manager *pMgmt, PWLAN_FR_AUTHEN pFrame);
+
+static void s_vMgrRxAuthenSequence_3(struct vnt_private *,
+ struct vnt_manager *pMgmt, PWLAN_FR_AUTHEN pFrame);
+
+static void s_vMgrRxAuthenSequence_4(struct vnt_private *,
+ struct vnt_manager *pMgmt, PWLAN_FR_AUTHEN pFrame);
+
+static void s_vMgrRxAuthentication(struct vnt_private *,
+ struct vnt_manager *pMgmt, struct vnt_rx_mgmt *pRxPacket);
+
+static void s_vMgrRxDeauthentication(struct vnt_private *,
+ struct vnt_manager *pMgmt, struct vnt_rx_mgmt *pRxPacket);
+
+/* Scan functions
+* probe request/response functions */
+
+static void s_vMgrRxProbeRequest(struct vnt_private *,
+ struct vnt_manager *pMgmt, struct vnt_rx_mgmt *pRxPacket);
+
+static void s_vMgrRxProbeResponse(struct vnt_private *,
+ struct vnt_manager *pMgmt, struct vnt_rx_mgmt *pRxPacket);
+
+/* beacon functions */
+static void s_vMgrRxBeacon(struct vnt_private *pDevice,
+ struct vnt_manager *pMgmt, struct vnt_rx_mgmt *pRxPacket,
+ int bInScan);
+
+static void s_vMgrFormatTIM(struct vnt_manager *pMgmt, PWLAN_IE_TIM pTIM);
+
+static struct vnt_tx_mgmt *s_MgrMakeBeacon(struct vnt_private *pDevice,
+ struct vnt_manager *pMgmt, u16 wCurrCapInfo, u16 wCurrBeaconPeriod,
+ u32 uCurrChannel, u16 wCurrATIMWinodw, PWLAN_IE_SSID pCurrSSID,
+ u8 *pCurrBSSID, PWLAN_IE_SUPP_RATES pCurrSuppRates,
+ PWLAN_IE_SUPP_RATES pCurrExtSuppRates);
+
+/* Association response */
+static struct vnt_tx_mgmt *s_MgrMakeAssocResponse(struct vnt_private *,
+ struct vnt_manager *pMgmt, u16 wCurrCapInfo, u16 wAssocStatus,
+ u16 wAssocAID, u8 *pDstAddr, PWLAN_IE_SUPP_RATES pCurrSuppRates,
+ PWLAN_IE_SUPP_RATES pCurrExtSuppRates);
+
+/* ReAssociation response */
+static struct vnt_tx_mgmt *s_MgrMakeReAssocResponse(struct vnt_private *,
+ struct vnt_manager *pMgmt, u16 wCurrCapInfo, u16 wAssocStatus,
+ u16 wAssocAID, u8 *pDstAddr, PWLAN_IE_SUPP_RATES pCurrSuppRates,
+ PWLAN_IE_SUPP_RATES pCurrExtSuppRates);
+
+/* Probe response */
+static struct vnt_tx_mgmt *s_MgrMakeProbeResponse(struct vnt_private *,
+ struct vnt_manager *pMgmt, u16 wCurrCapInfo, u16 wCurrBeaconPeriod,
+ u32 uCurrChannel, u16 wCurrATIMWinodw, u8 *pDstAddr,
+ PWLAN_IE_SSID pCurrSSID, u8 *pCurrBSSID,
+ PWLAN_IE_SUPP_RATES pCurrSuppRates,
+ PWLAN_IE_SUPP_RATES pCurrExtSuppRates, u8 byPHYType);
+
+/* received status */
+static void s_vMgrLogStatus(struct vnt_manager *pMgmt, u16 wStatus);
+
+static void s_vMgrSynchBSS(struct vnt_private *, u32 uBSSMode,
+ PKnownBSS pCurr, PCMD_STATUS pStatus);
+
+static bool
+s_bCipherMatch (
+ PKnownBSS pBSSNode,
+ NDIS_802_11_ENCRYPTION_STATUS EncStatus,
+ u8 * pbyCCSPK,
+ u8 * pbyCCSGK
+ );
+
+static void Encyption_Rebuild(struct vnt_private *, PKnownBSS pCurr);
+
+/*+
+ *
+ * Routine Description:
+ * Allocates and initializes the Management object.
+ *
+ * Return Value:
+ * Ndis_staus.
+ *
+-*/
+
+void vMgrObjectInit(struct vnt_private *pDevice)
+{
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ 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((void *) pDevice, false);
+
+ init_timer(&pMgmt->sTimerSecondCallback);
+ pMgmt->sTimerSecondCallback.data = (unsigned long)pDevice;
+ pMgmt->sTimerSecondCallback.function = (TimerFunction)BSSvSecondCallBack;
+ pMgmt->sTimerSecondCallback.expires = RUN_AT(HZ);
+
+ init_timer(&pDevice->sTimerCommand);
+ pDevice->sTimerCommand.data = (unsigned long)pDevice;
+ pDevice->sTimerCommand.function = (TimerFunction)vRunCommand;
+ pDevice->sTimerCommand.expires = RUN_AT(HZ);
+
+ init_timer(&pDevice->sTimerTxData);
+ pDevice->sTimerTxData.data = (unsigned long)pDevice;
+ pDevice->sTimerTxData.function = (TimerFunction)BSSvSecondTxData;
+ pDevice->sTimerTxData.expires = RUN_AT(10*HZ); //10s callback
+ pDevice->fTxDataInSleep = false;
+ pDevice->IsTxDataTrigger = false;
+ pDevice->nTxDataTimeCout = 0;
+
+ pDevice->cbFreeCmdQueue = CMD_Q_SIZE;
+ pDevice->uCmdDequeueIdx = 0;
+ pDevice->uCmdEnqueueIdx = 0;
+ pDevice->eCommandState = WLAN_CMD_IDLE;
+ pDevice->bCmdRunning = false;
+ pDevice->bCmdClear = false;
+
+ return;
+}
+
+/*+
+ *
+ * Routine Description:
+ * Start the station association procedure. Namely, send an
+ * association request frame to the AP.
+ *
+ * Return Value:
+ * None.
+ *
+-*/
+
+void vMgrAssocBeginSta(struct vnt_private *pDevice,
+ struct vnt_manager *pMgmt, PCMD_STATUS pStatus)
+{
+ struct vnt_tx_mgmt *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 (pDevice->bShortSlotTime == true)
+ pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTSLOTTIME(1);
+
+ } else if (pMgmt->eCurrentPHYMode == PHY_TYPE_11B) {
+ if (pDevice->byPreambleType == 1) {
+ 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(struct vnt_private *pDevice,
+ struct vnt_manager *pMgmt, PCMD_STATUS pStatus)
+{
+ struct vnt_tx_mgmt *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 (pDevice->bShortSlotTime == true)
+ pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTSLOTTIME(1);
+
+ } else if (pMgmt->eCurrentPHYMode == PHY_TYPE_11B) {
+ if (pDevice->byPreambleType == 1) {
+ 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) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Reassociation tx failed.\n");
+ }
+ else {
+ DBG_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(struct vnt_private *pDevice,
+ struct vnt_manager *pMgmt, u8 *abyDestAddress, u16 wReason,
+ PCMD_STATUS pStatus)
+{
+ struct vnt_tx_mgmt *pTxPacket = NULL;
+ WLAN_FR_DISASSOC sFrame;
+
+ pTxPacket = (struct vnt_tx_mgmt *)pMgmt->pbyMgmtPacketPool;
+ memset(pTxPacket, 0, sizeof(struct vnt_tx_mgmt)
+ + WLAN_DISASSOC_FR_MAXLEN);
+ pTxPacket->p80211Header = (PUWLAN_80211HDR)((u8 *)pTxPacket
+ + sizeof(struct vnt_tx_mgmt));
+
+ // Setup the sFrame structure
+ sFrame.pBuf = (u8 *)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(struct vnt_private *pDevice,
+ struct vnt_manager *pMgmt, struct vnt_rx_mgmt *pRxPacket,
+ u32 uNodeIndex)
+{
+ WLAN_FR_ASSOCREQ sFrame;
+ CMD_STATUS Status;
+ struct vnt_tx_mgmt *pTxPacket;
+ u16 wAssocStatus = 0;
+ u16 wAssocAID = 0;
+ u32 uRateLen = WLAN_RATES_MAXLEN;
+ u8 abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
+ u8 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 = (u8 *)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->byBBType == BB_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->byBBType == BB_TYPE_11G) {
+ abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pExtSuppRates,
+ (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates,
+ uRateLen);
+ } else {
+ abyCurrExtSuppRates[1] = 0;
+ }
+
+ RATEvParseMaxRate((void *)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;
+ // 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 = (u16)uNodeIndex;
+ wAssocStatus = WLAN_MGMT_STATUS_SUCCESS;
+ wAssocAID = (u16)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;
+ }
+
+ DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Associate AID= %d \n", wAssocAID);
+ DBG_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]
+ ) ;
+ DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Max Support rate = %d \n",
+ pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate);
+ }
+
+ // 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) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Assoc response tx failed\n");
+ }
+ else {
+ DBG_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(struct vnt_private *pDevice,
+ struct vnt_manager *pMgmt, struct vnt_rx_mgmt *pRxPacket,
+ u32 uNodeIndex)
+{
+ WLAN_FR_REASSOCREQ sFrame;
+ CMD_STATUS Status;
+ struct vnt_tx_mgmt *pTxPacket;
+ u16 wAssocStatus = 0;
+ u16 wAssocAID = 0;
+ u32 uRateLen = WLAN_RATES_MAXLEN;
+ u8 abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
+ u8 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 = (u8 *)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->byBBType == BB_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->byBBType == BB_TYPE_11G) {
+ abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pExtSuppRates,
+ (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates,
+ uRateLen);
+ } else {
+ abyCurrExtSuppRates[1] = 0;
+ }
+
+ RATEvParseMaxRate((void *)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;
+ // 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 = (u16)uNodeIndex;
+ wAssocStatus = WLAN_MGMT_STATUS_SUCCESS;
+ wAssocAID = (u16)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;
+ }
+
+ DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Rx ReAssociate AID= %d \n", wAssocAID);
+ DBG_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]
+ ) ;
+ DBG_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) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:ReAssoc response tx failed\n");
+ }
+ else {
+ DBG_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(struct vnt_private *pDevice,
+ struct vnt_manager *pMgmt, struct vnt_rx_mgmt *pRxPacket,
+ int bReAssocType)
+{
+ WLAN_FR_ASSOCRESP sFrame;
+ PWLAN_IE_SSID pItemSSID;
+ u8 *pbyIEs;
+
+ if (pMgmt->eCurrState == WMAC_STATE_ASSOCPENDING ||
+ pMgmt->eCurrState == WMAC_STATE_ASSOC) {
+
+ sFrame.len = pRxPacket->cbMPDULen;
+ sFrame.pBuf = (u8 *)pRxPacket->p80211Header;
+ // decode the frame
+ vMgrDecodeAssocResponse(&sFrame);
+ if ((sFrame.pwCapInfo == NULL)
+ || (sFrame.pwStatus == NULL)
+ || (sFrame.pwAid == NULL)
+ || (sFrame.pSuppRates == NULL)) {
+ 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) )
+ {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "AID from AP, has two msb clear.\n");
+ }
+ DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Association Successful, AID=%d.\n", pMgmt->wCurrAID & ~(BIT14|BIT15));
+ pMgmt->eCurrState = WMAC_STATE_ASSOC;
+ BSSvUpdateAPNode((void *) pDevice,
+ sFrame.pwCapInfo,
+ sFrame.pSuppRates,
+ sFrame.pExtSuppRates);
+ pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
+ DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Link with AP(SSID): %s\n", pItemSSID->abySSID);
+ pDevice->bLinkPass = true;
+ ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_INTER);
+
+ //if(pDevice->bWPASuppWextEnabled == true)
+ {
+ u8 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;
+ PRINT_K("wireless_send_event--->IWEVASSOCREQIE\n");
+ 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;
+ PRINT_K("wireless_send_event--->IWEVASSOCRESPIE\n");
+ 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;
+ PRINT_K("wireless_send_event--->SIOCGIWAP(associated)\n");
+ wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
+
+ }
+
+ }
+ 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))));
+ }
+
+ }
+
+//need clear flags related to Networkmanager
+ pDevice->bwextstep0 = false;
+ pDevice->bwextstep1 = false;
+ pDevice->bwextstep2 = false;
+ pDevice->bwextstep3 = false;
+ pDevice->bWPASuppWextEnabled = false;
+
+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(struct vnt_private *pDevice,
+ struct vnt_manager *pMgmt, PCMD_STATUS pStatus)
+{
+ WLAN_FR_AUTHEN sFrame;
+ struct vnt_tx_mgmt *pTxPacket =
+ (struct vnt_tx_mgmt *)pMgmt->pbyMgmtPacketPool;
+
+ memset(pTxPacket, 0, sizeof(struct vnt_tx_mgmt)
+ + WLAN_AUTHEN_FR_MAXLEN);
+ pTxPacket->p80211Header = (PUWLAN_80211HDR)((u8 *)pTxPacket
+ + sizeof(struct vnt_tx_mgmt));
+ sFrame.pBuf = (u8 *)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(struct vnt_private *pDevice,
+ struct vnt_manager *pMgmt, u8 *abyDestAddress, u16 wReason,
+ PCMD_STATUS pStatus)
+{
+ WLAN_FR_DEAUTHEN sFrame;
+ struct vnt_tx_mgmt *pTxPacket =
+ (struct vnt_tx_mgmt *)pMgmt->pbyMgmtPacketPool;
+
+ memset(pTxPacket, 0, sizeof(struct vnt_tx_mgmt)
+ + WLAN_DEAUTHEN_FR_MAXLEN);
+ pTxPacket->p80211Header = (PUWLAN_80211HDR)((u8 *)pTxPacket
+ + sizeof(struct vnt_tx_mgmt));
+ sFrame.pBuf = (u8 *)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(struct vnt_private *pDevice,
+ struct vnt_manager *pMgmt, struct vnt_rx_mgmt *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 = (u8 *)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:
+ DBG_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(struct vnt_private *pDevice,
+ struct vnt_manager *pMgmt, PWLAN_FR_AUTHEN pFrame)
+{
+ struct vnt_tx_mgmt *pTxPacket = NULL;
+ u32 uNodeIndex;
+ WLAN_FR_AUTHEN sFrame;
+ PSKeyItem pTransmitKey;
+
+ /* Insert a Node entry */
+ if (!BSSbIsSTAInNodeDB(pDevice, pFrame->pHdr->sA3.abyAddr2,
+ &uNodeIndex)) {
+ BSSvCreateOneNode(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 = (struct vnt_tx_mgmt *)pMgmt->pbyMgmtPacketPool;
+ memset(pTxPacket, 0, sizeof(struct vnt_tx_mgmt)
+ + WLAN_AUTHEN_FR_MAXLEN);
+ pTxPacket->p80211Header = (PUWLAN_80211HDR)((u8 *)pTxPacket
+ + sizeof(struct vnt_tx_mgmt));
+ sFrame.pBuf = (u8 *)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;
+ }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Authreq_reply sequence_1 tx.. \n");
+ if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) {
+ DBG_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(struct vnt_private *pDevice,
+ struct vnt_manager *pMgmt, PWLAN_FR_AUTHEN pFrame)
+{
+ WLAN_FR_AUTHEN sFrame;
+ struct vnt_tx_mgmt *pTxPacket = NULL;
+
+ switch (cpu_to_le16((*(pFrame->pwAuthAlgorithm))))
+ {
+ case WLAN_AUTH_ALG_OPENSYSTEM:
+ if ( cpu_to_le16((*(pFrame->pwStatus))) == WLAN_MGMT_STATUS_SUCCESS ){
+ DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (OPEN) Successful.\n");
+ pMgmt->eCurrState = WMAC_STATE_AUTH;
+ timer_expire(pDevice->sTimerCommand, 0);
+ }
+ else {
+ DBG_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((void *) pDevice, 0);
+ spin_lock_irq(&pDevice->lock); */
+ }
+ break;
+
+ case WLAN_AUTH_ALG_SHAREDKEY:
+
+ if (cpu_to_le16((*(pFrame->pwStatus))) == WLAN_MGMT_STATUS_SUCCESS) {
+ pTxPacket = (struct vnt_tx_mgmt *)
+ pMgmt->pbyMgmtPacketPool;
+ memset(pTxPacket, 0, sizeof(struct vnt_tx_mgmt)
+ + WLAN_AUTHEN_FR_MAXLEN);
+ pTxPacket->p80211Header
+ = (PUWLAN_80211HDR)((u8 *)pTxPacket
+ + sizeof(struct vnt_tx_mgmt));
+ sFrame.pBuf = (u8 *)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) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Auth_reply sequence_2 tx failed.\n");
+ }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Auth_reply sequence_2 tx ...\n");
+ }
+ else {
+ DBG_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((void *) pDevice, 0);
+ spin_lock_irq(&pDevice->lock); */
+ }
+ s_vMgrLogStatus(pMgmt, cpu_to_le16((*(pFrame->pwStatus))));
+ }
+ break;
+ default:
+ DBG_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(struct vnt_private *pDevice,
+ struct vnt_manager *pMgmt, PWLAN_FR_AUTHEN pFrame)
+{
+ struct vnt_tx_mgmt *pTxPacket = NULL;
+ u32 uStatusCode = 0 ;
+ u32 uNodeIndex = 0;
+ WLAN_FR_AUTHEN sFrame;
+
+ if (!WLAN_GET_FC_ISWEP(pFrame->pHdr->sA3.wFrameCtl)) {
+ uStatusCode = WLAN_MGMT_STATUS_CHALLENGE_FAIL;
+ goto reply;
+ }
+ if (BSSbIsSTAInNodeDB(pDevice, 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;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Challenge text check ok..\n");
+
+reply:
+ // send auth reply
+ pTxPacket = (struct vnt_tx_mgmt *)pMgmt->pbyMgmtPacketPool;
+ memset(pTxPacket, 0, sizeof(struct vnt_tx_mgmt)
+ + WLAN_AUTHEN_FR_MAXLEN);
+ pTxPacket->p80211Header = (PUWLAN_80211HDR)((u8 *)pTxPacket
+ + sizeof(struct vnt_tx_mgmt));
+ sFrame.pBuf = (u8 *)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) {
+ DBG_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(struct vnt_private *pDevice,
+ struct vnt_manager *pMgmt, PWLAN_FR_AUTHEN pFrame)
+{
+
+ if ( cpu_to_le16((*(pFrame->pwStatus))) == WLAN_MGMT_STATUS_SUCCESS ){
+ DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (SHAREDKEY) Successful.\n");
+ pMgmt->eCurrState = WMAC_STATE_AUTH;
+ timer_expire(pDevice->sTimerCommand, 0);
+ }
+ else{
+ DBG_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((void *) pDevice, 0);
+ spin_lock_irq(&pDevice->lock); */
+ }
+}
+
+/*+
+ *
+ * Routine Description:
+ * Handles incoming disassociation frames
+ *
+ *
+ * Return Value:
+ * None.
+ *
+-*/
+
+static void s_vMgrRxDisassociation(struct vnt_private *pDevice,
+ struct vnt_manager *pMgmt, struct vnt_rx_mgmt *pRxPacket)
+{
+ WLAN_FR_DISASSOC sFrame;
+ u32 uNodeIndex = 0;
+ CMD_STATUS CmdStatus;
+
+ if ( pMgmt->eCurrMode == WMAC_MODE_ESS_AP ){
+ // if is acting an AP..
+ // a STA is leaving this BSS..
+ sFrame.len = pRxPacket->cbMPDULen;
+ sFrame.pBuf = (u8 *)pRxPacket->p80211Header;
+ if (BSSbIsSTAInNodeDB(pDevice, pRxPacket->p80211Header->sA3.abyAddr2, &uNodeIndex)) {
+ BSSvRemoveOneNode(pDevice, uNodeIndex);
+ }
+ else {
+ DBG_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 = (u8 *)pRxPacket->p80211Header;
+ vMgrDecodeDisassociation(&sFrame);
+ DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "AP disassociated me, reason=%d.\n", cpu_to_le16(*(sFrame.pwReason)));
+
+ pDevice->fWPA_Authened = false;
+
+ //TODO: do something let upper layer know or
+ //try to send associate packet again because of inactivity timeout
+ if (pMgmt->eCurrState == WMAC_STATE_ASSOC) {
+ pDevice->bLinkPass = false;
+ pMgmt->sNodeDBTable[0].bActive = false;
+ pDevice->byReAssocCount = 0;
+ pMgmt->eCurrState = WMAC_STATE_AUTH; // jump back to the auth state!
+ pDevice->eCommandState = WLAN_ASSOCIATE_WAIT;
+ vMgrReAssocBeginSta(pDevice, pMgmt, &CmdStatus);
+ if(CmdStatus == CMD_STATUS_PENDING) {
+ pDevice->byReAssocCount ++;
+ return; //mike add: you'll retry for many times, so it cann't be regarded as disconnected!
+ }
+ }
+
+ // if(pDevice->bWPASuppWextEnabled == true)
+ {
+ union iwreq_data wrqu;
+ memset(&wrqu, 0, sizeof (wrqu));
+ wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+ PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n");
+ wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
+ }
+ }
+ /* else, ignore it */
+
+ return;
+}
+
+/*+
+ *
+ * Routine Description:
+ * Handles incoming deauthentication frames
+ *
+ *
+ * Return Value:
+ * None.
+ *
+-*/
+
+static void s_vMgrRxDeauthentication(struct vnt_private *pDevice,
+ struct vnt_manager *pMgmt, struct vnt_rx_mgmt *pRxPacket)
+{
+ WLAN_FR_DEAUTHEN sFrame;
+ u32 uNodeIndex = 0;
+
+ 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 = (u8 *)pRxPacket->p80211Header;
+ if (BSSbIsSTAInNodeDB(pDevice, pRxPacket->p80211Header->sA3.abyAddr2, &uNodeIndex)) {
+ BSSvRemoveOneNode(pDevice, uNodeIndex);
+ }
+ else {
+ DBG_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 = (u8 *)pRxPacket->p80211Header;
+ vMgrDecodeDeauthen(&sFrame);
+ pDevice->fWPA_Authened = false;
+ DBG_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 (!compare_ether_addr(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;
+ ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW);
+ }
+ }
+
+ // if(pDevice->bWPASuppWextEnabled == true)
+ {
+ union iwreq_data wrqu;
+ memset(&wrqu, 0, sizeof (wrqu));
+ wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+ PRINT_K("wireless_send_event--->SIOCGIWAP(disauthen)\n");
+ wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
+ }
+
+ }
+ /* else, ignore it. TODO: IBSS authentication service
+ would be implemented here */
+ };
+ return;
+}
+
+/*+
+ *
+ * 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 int ChannelExceedZoneType(struct vnt_private *pDevice, u8 byCurrChannel)
+{
+ int 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(struct vnt_private *pDevice,
+ struct vnt_manager *pMgmt, struct vnt_rx_mgmt *pRxPacket,
+ int bInScan)
+{
+ PKnownBSS pBSSList;
+ WLAN_FR_BEACON sFrame;
+ u64 qwTSFOffset;
+ int bIsBSSIDEqual = false;
+ int bIsSSIDEqual = false;
+ int bTSFLargeDiff = false;
+ int bTSFOffsetPostive = false;
+ int bUpdateTSF = false;
+ int bIsAPBeacon = false;
+ int bIsChannelEqual = false;
+ u32 uLocateByteIndex;
+ u8 byTIMBitOn = 0;
+ u16 wAIDNumber = 0;
+ u32 uNodeIndex;
+ u64 qwTimestamp, qwLocalTSF;
+ u64 qwCurrTSF;
+ u16 wStartIndex = 0;
+ u16 wAIDIndex = 0;
+ u8 byCurrChannel = pRxPacket->byRxChannel;
+ ERPObject sERP;
+ u32 uRateLen = WLAN_RATES_MAXLEN;
+ int bChannelHit = false;
+ u8 byOldPreambleType;
+
+ if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)
+ return;
+
+ memset(&sFrame, 0, sizeof(WLAN_FR_BEACON));
+ sFrame.len = pRxPacket->cbMPDULen;
+ sFrame.pBuf = (u8 *)pRxPacket->p80211Header;
+
+ // decode the beacon frame
+ vMgrDecodeBeacon(&sFrame);
+
+ if ((sFrame.pwBeaconInterval == NULL)
+ || (sFrame.pwCapInfo == NULL)
+ || (sFrame.pSSID == NULL)
+ || (sFrame.pSuppRates == NULL)) {
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx beacon frame error\n");
+ return;
+ }
+
+ if( byCurrChannel > CB_MAX_CHANNEL_24G )
+ {
+ if (sFrame.pDSParms != NULL) {
+ if (byCurrChannel == RFaby11aChannelIndex[sFrame.pDSParms->byCurrChannel-1])
+ bChannelHit = true;
+ byCurrChannel = RFaby11aChannelIndex[sFrame.pDSParms->byCurrChannel-1];
+ } else {
+ bChannelHit = true;
+ }
+
+ } else {
+ if (sFrame.pDSParms != NULL) {
+ if (byCurrChannel == sFrame.pDSParms->byCurrChannel)
+ bChannelHit = true;
+ byCurrChannel = sFrame.pDSParms->byCurrChannel;
+ } else {
+ bChannelHit = true;
+ }
+ }
+
+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((void *) pDevice,
+ sFrame.pHdr->sA3.abyAddr3,
+ sFrame.pSSID);
+ if (pBSSList == NULL) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Beacon/insert: RxChannel = : %d\n", byCurrChannel);
+ BSSbInsertToBSSList((void *) 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
+ (void *) pRxPacket);
+ }
+ else {
+// DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"update bcn: RxChannel = : %d\n", byCurrChannel);
+ BSSbUpdateToBSSList((void *) 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
+ (void *) pRxPacket);
+
+ }
+
+ if (bInScan) {
+ return;
+ }
+
+ if(byCurrChannel == (u8)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);
+ }
+ }
+
+ // check if BSSID the same
+ if (memcmp(sFrame.pHdr->sA3.abyAddr3,
+ pMgmt->abyCurrBSSID,
+ WLAN_BSSID_LEN) == 0) {
+
+ bIsBSSIDEqual = true;
+ pDevice->uCurrRSSI = pRxPacket->uRSSI;
+ pDevice->byCurrSQ = pRxPacket->bySQ;
+ if (pMgmt->sNodeDBTable[0].uInActiveCount != 0) {
+ pMgmt->sNodeDBTable[0].uInActiveCount = 0;
+ //DBG_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) {
+
+ // Sync ERP field
+ if ((pBSSList->sERP.bERPExist == true) && (pDevice->byBBType == BB_TYPE_11G)) {
+ if ((pBSSList->sERP.byERP & WLAN_EID_ERP_USE_PROTECTION) != pDevice->bProtectMode) {//0000 0010
+ pDevice->bProtectMode = (pBSSList->sERP.byERP & WLAN_EID_ERP_USE_PROTECTION);
+ if (pDevice->bProtectMode) {
+ MACvEnableProtectMD(pDevice);
+ } else {
+ MACvDisableProtectMD(pDevice);
+ }
+ vUpdateIFS(pDevice);
+ }
+ if ((pBSSList->sERP.byERP & WLAN_EID_ERP_NONERP_PRESENT) != pDevice->bNonERPPresent) {//0000 0001
+ pDevice->bNonERPPresent = (pBSSList->sERP.byERP & WLAN_EID_ERP_USE_PROTECTION);
+ }
+ if ((pBSSList->sERP.byERP & WLAN_EID_ERP_BARKER_MODE) != pDevice->bBarkerPreambleMd) {//0000 0100
+ pDevice->bBarkerPreambleMd = (pBSSList->sERP.byERP & WLAN_EID_ERP_BARKER_MODE);
+ //BarkerPreambleMd has higher priority than shortPreamble bit in Cap
+ if (pDevice->bBarkerPreambleMd) {
+ MACvEnableBarkerPreambleMd(pDevice);
+ } else {
+ MACvDisableBarkerPreambleMd(pDevice);
+ }
+ }
+ }
+ // Sync Short Slot Time
+ if (WLAN_GET_CAP_INFO_SHORTSLOTTIME(pBSSList->wCapInfo) != pDevice->bShortSlotTime) {
+ bool bShortSlotTime;
+
+ bShortSlotTime = WLAN_GET_CAP_INFO_SHORTSLOTTIME(pBSSList->wCapInfo);
+ //DBG_PRN_WLAN05(("Set Short Slot Time: %d\n", pDevice->bShortSlotTime));
+ //Kyle check if it is OK to set G.
+ if (pDevice->byBBType == BB_TYPE_11A) {
+ bShortSlotTime = true;
+ }
+ else if (pDevice->byBBType == BB_TYPE_11B) {
+ bShortSlotTime = false;
+ }
+ if (bShortSlotTime != pDevice->bShortSlotTime) {
+ pDevice->bShortSlotTime = bShortSlotTime;
+ BBvSetShortSlotTime(pDevice);
+ vUpdateIFS(pDevice);
+ }
+ }
+
+ //
+ // Preamble may change dynamically
+ //
+ byOldPreambleType = pDevice->byPreambleType;
+ if (WLAN_GET_CAP_INFO_SHORTPREAMBLE(pBSSList->wCapInfo)) {
+ pDevice->byPreambleType = pDevice->byShortPreamble;
+ }
+ else {
+ pDevice->byPreambleType = 0;
+ }
+ if (pDevice->byPreambleType != byOldPreambleType)
+ CARDvSetRSPINF(pDevice, (u8)pDevice->byBBType);
+ //
+ // Basic Rate Set may change dynamically
+ //
+ 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((void *)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)
+ );
+
+ }
+ }
+
+// DBG_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
+ }
+ }
+
+ qwTimestamp = cpu_to_le64(*sFrame.pqwTimestamp);
+ qwLocalTSF = pRxPacket->qwLocalTSF;
+
+ // check if beacon TSF larger or small than our local TSF
+ if (qwTimestamp >= qwLocalTSF)
+ bTSFOffsetPostive = true;
+ else
+ bTSFOffsetPostive = false;
+
+ if (bTSFOffsetPostive) {
+ qwTSFOffset = CARDqGetTSFOffset(pRxPacket->byRxRate, (qwTimestamp), (qwLocalTSF));
+ }
+ else {
+ qwTSFOffset = CARDqGetTSFOffset(pRxPacket->byRxRate, (qwLocalTSF), (qwTimestamp));
+ }
+
+ if (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)) {
+
+ /* 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 */
+ if (pMgmt->bInTIM)
+ PSvSendPSPOLL(pDevice);
+
+ }
+ else {
+ pMgmt->bInTIMWake = false;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Not In TIM..\n");
+ if (pDevice->bPWBitOn == false) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Send Null Packet\n");
+ if (PSbSendNullPacket(pDevice))
+ pDevice->bPWBitOn = true;
+ }
+ if(PSbConsiderPowerDown(pDevice, false, false)) {
+ DBG_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 (BSSbIsSTAInNodeDB(pDevice, sFrame.pHdr->sA3.abyAddr2, &uNodeIndex)) {
+
+ // Update the STA, (Technically 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((void *)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(pDevice, &uNodeIndex);
+
+ pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates,
+ (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
+ WLAN_RATES_MAXLEN_11B);
+ RATEvParseMaxRate((void *)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;
+/*
+ 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) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Current IBSS State: [Started]........to: [Jointed] \n");
+ pMgmt->eCurrState = WMAC_STATE_JOINTED;
+ pDevice->bLinkPass = true;
+ ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_INTER);
+ 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....
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rejoining to Other Adhoc group with same SSID........\n");
+
+ MACvWriteBeaconInterval(pDevice, pMgmt->wCurrBeaconPeriod);
+ CARDvAdjustTSF(pDevice, pRxPacket->byRxRate, qwTimestamp, pRxPacket->qwLocalTSF);
+ CARDvUpdateNextTBTT(pDevice, qwTimestamp, pMgmt->wCurrBeaconPeriod);
+
+ // Turn off bssid filter to avoid filter others adhoc station which bssid is different.
+ MACvWriteBSSIDAddress(pDevice, pMgmt->abyCurrBSSID);
+
+ byOldPreambleType = pDevice->byPreambleType;
+ if (WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo)) {
+ pDevice->byPreambleType = pDevice->byShortPreamble;
+ }
+ else {
+ pDevice->byPreambleType = 0;
+ }
+ if (pDevice->byPreambleType != byOldPreambleType)
+ CARDvSetRSPINF(pDevice, (u8)pDevice->byBBType);
+
+ // 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((void *) pDevice, pMgmt);
+ // }
+ }
+ }
+ }
+ // endian issue ???
+ // Update TSF
+ if (bUpdateTSF) {
+ CARDbGetCurrentTSF(pDevice, &qwCurrTSF);
+ CARDvAdjustTSF(pDevice, pRxPacket->byRxRate, qwTimestamp , pRxPacket->qwLocalTSF);
+ CARDbGetCurrentTSF(pDevice, &qwCurrTSF);
+ CARDvUpdateNextTBTT(pDevice, 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(struct vnt_private *pDevice, PCMD_STATUS pStatus)
+{
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ u16 wMaxBasicRate;
+ u16 wMaxSuppRate;
+ u8 byTopCCKBasicRate;
+ u8 byTopOFDMBasicRate;
+ u64 qwCurrTSF = 0;
+ int ii;
+ u8 abyRATE[] = {0x82, 0x84, 0x8B, 0x96, 0x24, 0x30, 0x48, 0x6C, 0x0C,
+ 0x12, 0x18, 0x60};
+ u8 abyCCK_RATE[] = {0x82, 0x84, 0x8B, 0x96};
+ u8 abyOFDM_RATE[] = {0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C};
+ u16 wSuppRate;
+
+ DBG_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);
+
+ pDevice->bBarkerPreambleMd = 0;
+ MACvDisableBarkerPreambleMd(pDevice);
+
+ // Kyle Test 2003.11.04
+
+ // set HW beacon interval
+ if (pMgmt->wIBSSBeaconPeriod == 0)
+ pMgmt->wIBSSBeaconPeriod = DEFAULT_IBSS_BI;
+ MACvWriteBeaconInterval(pDevice, pMgmt->wIBSSBeaconPeriod);
+
+ CARDbGetCurrentTSF(pDevice, &qwCurrTSF);
+ // clear TSF counter
+ CARDbClearCurrentTSF(pDevice);
+
+ // enable TSF counter
+ MACvRegBitsOn(pDevice,MAC_REG_TFTCTL,TFTCTL_TSFCNTREN);
+ // set Next TBTT
+ CARDvSetFirstNextTBTT(pDevice, pMgmt->wIBSSBeaconPeriod);
+
+ pMgmt->uIBSSChannel = pDevice->uChannel;
+
+ if (pMgmt->uIBSSChannel == 0)
+ pMgmt->uIBSSChannel = DEFAULT_IBSS_CHANNEL;
+
+ // set channel and clear NAV
+ CARDbSetMediaChannel(pDevice, pMgmt->uIBSSChannel);
+ pMgmt->uCurrChannel = pMgmt->uIBSSChannel;
+
+ pDevice->byPreambleType = pDevice->byShortPreamble;
+
+ // set basic rate
+
+ RATEvParseMaxRate((void *)pDevice,
+ (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
+ (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, true,
+ &wMaxBasicRate, &wMaxSuppRate, &wSuppRate,
+ &byTopCCKBasicRate, &byTopOFDMBasicRate);
+
+ if (pDevice->byBBType == BB_TYPE_11A) {
+ pDevice->bShortSlotTime = true;
+ } else {
+ pDevice->bShortSlotTime = false;
+ }
+ BBvSetShortSlotTime(pDevice);
+ // vUpdateIFS() use pDevice->bShortSlotTime as parameter so it must be called
+ // after setting ShortSlotTime.
+ // CARDvSetBSSMode call vUpdateIFS()
+ CARDvSetBSSMode(pDevice);
+
+ if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
+ MACvRegBitsOn(pDevice, MAC_REG_HOSTCR, HOSTCR_AP);
+ pMgmt->eCurrMode = WMAC_MODE_ESS_AP;
+ }
+
+ if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) {
+ MACvRegBitsOn(pDevice, MAC_REG_HOSTCR, HOSTCR_ADHOC);
+ 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;
+ 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);
+ DBG_PRT(MSG_LEVEL_INFO, KERN_INFO"AP beacon created BSSID:"
+ "%pM\n", pMgmt->abyCurrBSSID);
+ }
+
+ if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
+
+ // BSSID selected must be randomized as spec 11.1.3
+ pMgmt->abyCurrBSSID[5] = (u8)(qwCurrTSF & 0x000000ff);
+ pMgmt->abyCurrBSSID[4] = (u8)((qwCurrTSF & 0x0000ff00) >> 8);
+ pMgmt->abyCurrBSSID[3] = (u8)((qwCurrTSF & 0x00ff0000) >> 16);
+ pMgmt->abyCurrBSSID[2] = (u8)((qwCurrTSF & 0x00000ff0) >> 4);
+ pMgmt->abyCurrBSSID[1] = (u8)((qwCurrTSF & 0x000ff000) >> 12);
+ pMgmt->abyCurrBSSID[0] = (u8)((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;
+
+ DBG_PRT(MSG_LEVEL_INFO, KERN_INFO"Adhoc beacon created bssid:"
+ "%pM\n", pMgmt->abyCurrBSSID);
+ }
+
+ // set BSSID filter
+ MACvWriteBSSIDAddress(pDevice, pMgmt->abyCurrBSSID);
+ memcpy(pDevice->abyBSSID, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN);
+
+ MACvRegBitsOn(pDevice, MAC_REG_RCR, RCR_BSSID);
+ pDevice->byRxMode |= RCR_BSSID;
+ pMgmt->bCurrBSSIDFilterOn = true;
+
+ // 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;
+ pDevice->eOPMode = OP_MODE_AP;
+ }
+
+ if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
+ pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_IBSS(1);
+ pDevice->eOPMode = OP_MODE_ADHOC;
+ }
+
+ 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;
+
+ if (pDevice->byPreambleType == 1) {
+ pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
+ } else {
+ pMgmt->wCurrCapInfo &= (~WLAN_SET_CAP_INFO_SHORTPREAMBLE(1));
+ }
+
+ pMgmt->eCurrState = WMAC_STATE_STARTED;
+ // Prepare beacon to send
+ if (bMgrPrepareBeaconToSend((void *) 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(struct vnt_private *pDevice, PCMD_STATUS pStatus)
+{
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ PKnownBSS pCurr = NULL;
+ int ii, uu;
+ PWLAN_IE_SUPP_RATES pItemRates = NULL;
+ PWLAN_IE_SUPP_RATES pItemExtRates = NULL;
+ PWLAN_IE_SSID pItemSSID;
+ u32 uRateLen = WLAN_RATES_MAXLEN;
+ u16 wMaxBasicRate = RATE_1M;
+ u16 wMaxSuppRate = RATE_1M;
+ u16 wSuppRate;
+ u8 byTopCCKBasicRate = RATE_1M;
+ u8 byTopOFDMBasicRate = RATE_1M;
+ u8 bShortSlotTime = false;
+
+ for (ii = 0; ii < MAX_BSS_NUM; ii++) {
+ if (pMgmt->sBSSList[ii].bActive == true)
+ break;
+ }
+
+ if (ii == MAX_BSS_NUM) {
+ *pStatus = CMD_STATUS_RESOURCES;
+ DBG_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,
+ pDevice->eConfigPHYMode
+ );
+
+ if (pCurr == NULL){
+ *pStatus = CMD_STATUS_RESOURCES;
+ pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
+ DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Scanning [%s] not found, disconnected !\n", pItemSSID->abySSID);
+ return;
+ }
+
+ DBG_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)) {
+ /*
+ if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
+ if (WPA_SearchRSN(0, WPA_TKIP, pCurr) == false) {
+ DBG_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) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No match RSN info. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
+ // encryption mode error
+ pMgmt->eCurrState = WMAC_STATE_IDLE;
+ return;
+ }
+ }
+*/
+ }
+
+ //if(pDevice->bWPASuppWextEnabled == true)
+ Encyption_Rebuild(pDevice, pCurr);
+
+ // 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 < (unsigned int) (8 - pItemRates->len); ) {
+ pItemRates->abyRates[pItemRates->len + ii] =
+ pItemExtRates->abyRates[ii];
+ ii++;
+ if (pItemExtRates->len <= ii)
+ break;
+ }
+ pItemRates->len += (u8)ii;
+ if (pItemExtRates->len - ii > 0) {
+ pItemExtRates->len -= (u8)ii;
+ for (uu = 0; uu < pItemExtRates->len; uu ++) {
+ pItemExtRates->abyRates[uu] = pItemExtRates->abyRates[uu + ii];
+ }
+ } else {
+ pItemExtRates->len = 0;
+ }
+ }
+
+ RATEvParseMaxRate((void *)pDevice, pItemRates, pItemExtRates, true,
+ &wMaxBasicRate, &wMaxSuppRate, &wSuppRate,
+ &byTopCCKBasicRate, &byTopOFDMBasicRate);
+ vUpdateIFS(pDevice);
+ // 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->eOPMode = OP_MODE_INFRASTRUCTURE;
+ memcpy(pDevice->abyBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN);
+
+ // Add current BSS to Candidate list
+ // This should only work for WPA2 BSS, and WPA2 BSS check must be done before.
+ if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) {
+ bool bResult = bAdd_PMKID_Candidate((void *) pDevice,
+ pMgmt->abyCurrBSSID,
+ &pCurr->sRSNCapObj);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"bAdd_PMKID_Candidate: 1(%d)\n", bResult);
+ if (bResult == false) {
+ vFlush_PMKID_Candidate((void *) pDevice);
+ DBG_PRT(MSG_LEVEL_DEBUG,
+ KERN_INFO "vFlush_PMKID_Candidate: 4\n");
+ bAdd_PMKID_Candidate((void *) pDevice,
+ pMgmt->abyCurrBSSID,
+ &pCurr->sRSNCapObj);
+ }
+ }
+
+ // Preamble type auto-switch: if AP can receive short-preamble cap,
+ // we can turn on too.
+ if (WLAN_GET_CAP_INFO_SHORTPREAMBLE(pCurr->wCapInfo)) {
+ pDevice->byPreambleType = pDevice->byShortPreamble;
+ }
+ else {
+ pDevice->byPreambleType = 0;
+ }
+ // Change PreambleType must set RSPINF again
+ CARDvSetRSPINF(pDevice, (u8)pDevice->byBBType);
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Join ESS\n");
+
+ if (pCurr->eNetworkTypeInUse == PHY_TYPE_11G) {
+
+ if ((pCurr->sERP.byERP & WLAN_EID_ERP_USE_PROTECTION) != pDevice->bProtectMode) {//0000 0010
+ pDevice->bProtectMode = (pCurr->sERP.byERP & WLAN_EID_ERP_USE_PROTECTION);
+ if (pDevice->bProtectMode) {
+ MACvEnableProtectMD(pDevice);
+ } else {
+ MACvDisableProtectMD(pDevice);
+ }
+ vUpdateIFS(pDevice);
+ }
+ if ((pCurr->sERP.byERP & WLAN_EID_ERP_NONERP_PRESENT) != pDevice->bNonERPPresent) {//0000 0001
+ pDevice->bNonERPPresent = (pCurr->sERP.byERP & WLAN_EID_ERP_USE_PROTECTION);
+ }
+ if ((pCurr->sERP.byERP & WLAN_EID_ERP_BARKER_MODE) != pDevice->bBarkerPreambleMd) {//0000 0100
+ pDevice->bBarkerPreambleMd = (pCurr->sERP.byERP & WLAN_EID_ERP_BARKER_MODE);
+ //BarkerPreambleMd has higher priority than shortPreamble bit in Cap
+ if (pDevice->bBarkerPreambleMd) {
+ MACvEnableBarkerPreambleMd(pDevice);
+ } else {
+ MACvDisableBarkerPreambleMd(pDevice);
+ }
+ }
+ }
+ //DBG_PRN_WLAN05(("wCapInfo: %X\n", pCurr->wCapInfo));
+ if (WLAN_GET_CAP_INFO_SHORTSLOTTIME(pCurr->wCapInfo) != pDevice->bShortSlotTime) {
+ if (pDevice->byBBType == BB_TYPE_11A) {
+ bShortSlotTime = true;
+ }
+ else if (pDevice->byBBType == BB_TYPE_11B) {
+ bShortSlotTime = false;
+ }
+ else {
+ bShortSlotTime = WLAN_GET_CAP_INFO_SHORTSLOTTIME(pCurr->wCapInfo);
+ }
+ //DBG_PRN_WLAN05(("Set Short Slot Time: %d\n", pDevice->bShortSlotTime));
+ if (bShortSlotTime != pDevice->bShortSlotTime) {
+ pDevice->bShortSlotTime = bShortSlotTime;
+ BBvSetShortSlotTime(pDevice);
+ vUpdateIFS(pDevice);
+ }
+ }
+
+ DBG_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((void *)pDevice,
+ (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
+ NULL, true, &wMaxBasicRate, &wMaxSuppRate, &wSuppRate,
+ &byTopCCKBasicRate, &byTopOFDMBasicRate);
+ vUpdateIFS(pDevice);
+ 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;
+ pMgmt->eCurrMode = WMAC_MODE_IBSS_STA;
+ pMgmt->eCurrState = WMAC_STATE_STARTED;
+ // Adopt BSS state in Adapter Device Object
+ pDevice->eOPMode = OP_MODE_ADHOC;
+ pDevice->bLinkPass = true;
+ ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_INTER);
+ memcpy(pDevice->abyBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN);
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Join IBSS ok:%pM\n",
+ pMgmt->abyCurrBSSID);
+ // Preamble type auto-switch: if AP can receive short-preamble cap,
+ // and if registry setting is short preamble we can turn on too.
+
+ if (WLAN_GET_CAP_INFO_SHORTPREAMBLE(pCurr->wCapInfo)) {
+ pDevice->byPreambleType = pDevice->byShortPreamble;
+ }
+ else {
+ pDevice->byPreambleType = 0;
+ }
+ // Change PreambleType must set RSPINF again
+ CARDvSetRSPINF(pDevice, (u8)pDevice->byBBType);
+
+ // Prepare beacon
+ bMgrPrepareBeaconToSend((void *) 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(struct vnt_private *pDevice, u32 uBSSMode,
+ PKnownBSS pCurr, PCMD_STATUS pStatus)
+{
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ u8 abyCurrSuppRatesG[] = {WLAN_EID_SUPP_RATES,
+ 8, 0x02, 0x04, 0x0B, 0x16, 0x24, 0x30, 0x48, 0x6C};
+ /* 1M, 2M, 5M, 11M, 18M, 24M, 36M, 54M*/
+ u8 abyCurrExtSuppRatesG[] = {WLAN_EID_EXTSUPP_RATES,
+ 4, 0x0C, 0x12, 0x18, 0x60};
+ /* 6M, 9M, 12M, 48M*/
+ u8 abyCurrSuppRatesA[] = {WLAN_EID_SUPP_RATES,
+ 8, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C};
+ u8 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) {
+ DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "s_bCipherMatch Fail .......\n");
+ return;
+ }
+
+ pMgmt->pCurrBSS = pCurr;
+
+ // if previous mode is IBSS.
+ if(pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
+ MACvRegBitsOff(pDevice, MAC_REG_TCR, TCR_AUTOBCNTX);
+ }
+
+ // Init the BSS informations
+ pDevice->bCCK = true;
+ pDevice->bProtectMode = false;
+ MACvDisableProtectMD(pDevice);
+ pDevice->bBarkerPreambleMd = false;
+ MACvDisableBarkerPreambleMd(pDevice);
+ pDevice->bNonERPPresent = false;
+ pDevice->byPreambleType = 0;
+ pDevice->wBasicRate = 0;
+ // Set Basic Rate
+ CARDbAddBasicRate((void *)pDevice, RATE_1M);
+
+ // calculate TSF offset
+ // TSF Offset = Received Timestamp TSF - Marked Local's TSF
+ CARDvAdjustTSF(pDevice, pCurr->byRxRate, pCurr->qwBSSTimestamp, pCurr->qwLocalTSF);
+
+ // set HW beacon interval
+ MACvWriteBeaconInterval(pDevice, pCurr->wBeaconInterval);
+
+ // set Next TBTT
+ // Next TBTT = ((local_current_TSF / beacon_interval) + 1 ) * beacon_interval
+ CARDvSetFirstNextTBTT(pDevice, pCurr->wBeaconInterval);
+
+ // set BSSID
+ MACvWriteBSSIDAddress(pDevice, pCurr->abyBSSID);
+
+ memcpy(pMgmt->abyCurrBSSID, pCurr->abyBSSID, 6);
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Sync:set CurrBSSID address = "
+ "%pM\n", pMgmt->abyCurrBSSID);
+
+ if (pCurr->eNetworkTypeInUse == PHY_TYPE_11A) {
+ if ((pDevice->eConfigPHYMode == PHY_TYPE_11A) ||
+ (pDevice->eConfigPHYMode == PHY_TYPE_AUTO)) {
+ pDevice->byBBType = BB_TYPE_11A;
+ pMgmt->eCurrentPHYMode = PHY_TYPE_11A;
+ pDevice->bShortSlotTime = true;
+ BBvSetShortSlotTime(pDevice);
+ CARDvSetBSSMode(pDevice);
+ } else {
+ return;
+ }
+ } else if (pCurr->eNetworkTypeInUse == PHY_TYPE_11B) {
+ if ((pDevice->eConfigPHYMode == PHY_TYPE_11B) ||
+ (pDevice->eConfigPHYMode == PHY_TYPE_11G) ||
+ (pDevice->eConfigPHYMode == PHY_TYPE_AUTO)) {
+ pDevice->byBBType = BB_TYPE_11B;
+ pMgmt->eCurrentPHYMode = PHY_TYPE_11B;
+ pDevice->bShortSlotTime = false;
+ BBvSetShortSlotTime(pDevice);
+ CARDvSetBSSMode(pDevice);
+ } else {
+ return;
+ }
+ } else {
+ if ((pDevice->eConfigPHYMode == PHY_TYPE_11G) ||
+ (pDevice->eConfigPHYMode == PHY_TYPE_AUTO)) {
+ pDevice->byBBType = BB_TYPE_11G;
+ pMgmt->eCurrentPHYMode = PHY_TYPE_11G;
+ pDevice->bShortSlotTime = true;
+ BBvSetShortSlotTime(pDevice);
+ CARDvSetBSSMode(pDevice);
+ } else if (pDevice->eConfigPHYMode == PHY_TYPE_11B) {
+ pDevice->byBBType = BB_TYPE_11B;
+ pDevice->bShortSlotTime = false;
+ BBvSetShortSlotTime(pDevice);
+ CARDvSetBSSMode(pDevice);
+ } else {
+ return;
+ }
+ }
+
+ if (uBSSMode == WMAC_MODE_ESS_STA) {
+ MACvRegBitsOff(pDevice, MAC_REG_HOSTCR, HOSTCR_ADHOC);
+ MACvRegBitsOn(pDevice, MAC_REG_RCR, RCR_BSSID);
+ pDevice->byRxMode |= RCR_BSSID;
+ pMgmt->bCurrBSSIDFilterOn = true;
+ }
+
+ // set channel and clear NAV
+ CARDbSetMediaChannel(pDevice, pCurr->uChannel);
+ pMgmt->uCurrChannel = pCurr->uChannel;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "<----s_bSynchBSS Set Channel [%d]\n", pCurr->uChannel);
+
+ if ((pDevice->bUpdateBBVGA) &&
+ (pDevice->byBBVGACurrent != pDevice->abyBBVGA[0])) {
+ pDevice->byBBVGACurrent = pDevice->abyBBVGA[0];
+ BBvSetVGAGainOffset(pDevice, pDevice->byBBVGACurrent);
+ BBvSetShortSlotTime(pDevice);
+ }
+ //
+ // Notes:
+ // 1. In Ad-hoc mode : check if received others beacon as jointed indication,
+ // otherwise we will start own IBSS.
+ // 2. In Infra mode : Supposed we already synchronized with AP right now.
+
+ if (uBSSMode == WMAC_MODE_IBSS_STA) {
+ MACvRegBitsOn(pDevice, MAC_REG_HOSTCR, HOSTCR_ADHOC);
+ MACvRegBitsOn(pDevice, MAC_REG_RCR, RCR_BSSID);
+ pDevice->byRxMode |= RCR_BSSID;
+ pMgmt->bCurrBSSIDFilterOn = true;
+ }
+
+ if (pDevice->byBBType == BB_TYPE_11A) {
+ memcpy(pMgmt->abyCurrSuppRates, &abyCurrSuppRatesA[0], sizeof(abyCurrSuppRatesA));
+ pMgmt->abyCurrExtSuppRates[1] = 0;
+ } else if (pDevice->byBBType == BB_TYPE_11B) {
+ memcpy(pMgmt->abyCurrSuppRates, &abyCurrSuppRatesB[0], sizeof(abyCurrSuppRatesB));
+ pMgmt->abyCurrExtSuppRates[1] = 0;
+ } else {
+ memcpy(pMgmt->abyCurrSuppRates, &abyCurrSuppRatesG[0], sizeof(abyCurrSuppRatesG));
+ memcpy(pMgmt->abyCurrExtSuppRates, &abyCurrExtSuppRatesG[0], sizeof(abyCurrExtSuppRatesG));
+ }
+ pMgmt->byERPContext = pCurr->sERP.byERP;
+
+ *pStatus = CMD_STATUS_SUCCESS;
+
+ return;
+};
+
+static void Encyption_Rebuild(struct vnt_private *pDevice, PKnownBSS pCurr)
+ {
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+
+ if ((pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) ||
+ (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) {
+ if (pCurr->bWPAValid == true) { /*WPA-PSK */
+ pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK;
+ if(pCurr->abyPKType[0] == WPA_TKIP) {
+ pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; //TKIP
+ PRINT_K("Encyption_Rebuild--->ssid reset config to [WPAPSK-TKIP]\n");
+ }
+ else if(pCurr->abyPKType[0] == WPA_AESCCMP) {
+ pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; //AES
+ PRINT_K("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
+ PRINT_K("Encyption_Rebuild--->ssid reset config to [WPA2PSK-TKIP]\n");
+ }
+ else if(pCurr->abyCSSPK[0] == WLAN_11i_CSS_CCMP) {
+ pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; //AES
+ PRINT_K("Encyption_Rebuild--->ssid reset config to [WPA2PSK-AES]\n");
+ }
+ }
+ }
+ // }
+ return;
+ }
+
+/*+
+ *
+ * Routine Description:
+ * Format TIM field
+ *
+ *
+ * Return Value:
+ * void
+ *
+-*/
+
+static void s_vMgrFormatTIM(struct vnt_manager *pMgmt, PWLAN_IE_TIM pTIM)
+{
+ u8 byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
+ u8 byMap;
+ int ii, jj;
+ int bStartFound = false;
+ int bMulticast = false;
+ u16 wStartIndex = 0;
+ u16 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 = (u16)ii;
+ }
+ wEndIndex = (u16)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 failure
+ *
+-*/
+
+static struct vnt_tx_mgmt *s_MgrMakeBeacon(struct vnt_private *pDevice,
+ struct vnt_manager *pMgmt, u16 wCurrCapInfo, u16 wCurrBeaconPeriod,
+ u32 uCurrChannel, u16 wCurrATIMWinodw, PWLAN_IE_SSID pCurrSSID,
+ u8 *pCurrBSSID, PWLAN_IE_SUPP_RATES pCurrSuppRates,
+ PWLAN_IE_SUPP_RATES pCurrExtSuppRates)
+{
+ struct vnt_tx_mgmt *pTxPacket = NULL;
+ WLAN_FR_BEACON sFrame;
+ u8 abyBroadcastAddr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
+ /* prepare beacon frame */
+ pTxPacket = (struct vnt_tx_mgmt *)pMgmt->pbyMgmtPacketPool;
+ memset(pTxPacket, 0, sizeof(struct vnt_tx_mgmt)
+ + WLAN_BEACON_FR_MAXLEN);
+ pTxPacket->p80211Header = (PUWLAN_80211HDR)((u8 *)pTxPacket
+ + sizeof(struct vnt_tx_mgmt));
+ // Setup the sFrame structure.
+ sFrame.pBuf = (u8 *)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((u16)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->byBBType != BB_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 = (u8)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
+ *((u16 *)(sFrame.pBuf + sFrame.len + sFrame.pRSNWPA->len))=0;
+ sFrame.pRSNWPA->len +=2;
+
+ // RSN Capabilites
+ *((u16 *)(sFrame.pBuf + sFrame.len + sFrame.pRSNWPA->len))=0;
+ sFrame.pRSNWPA->len +=2;
+ sFrame.len += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
+ }
+ }
+
+ 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;
+ memcpy(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 failure
+ *
+-*/
+
+struct vnt_tx_mgmt *s_MgrMakeProbeResponse(struct vnt_private *pDevice,
+ struct vnt_manager *pMgmt, u16 wCurrCapInfo, u16 wCurrBeaconPeriod,
+ u32 uCurrChannel, u16 wCurrATIMWinodw, u8 *pDstAddr,
+ PWLAN_IE_SSID pCurrSSID, u8 *pCurrBSSID,
+ PWLAN_IE_SUPP_RATES pCurrSuppRates,
+ PWLAN_IE_SUPP_RATES pCurrExtSuppRates, u8 byPHYType)
+{
+ struct vnt_tx_mgmt *pTxPacket = NULL;
+ WLAN_FR_PROBERESP sFrame;
+
+ pTxPacket = (struct vnt_tx_mgmt *)pMgmt->pbyMgmtPacketPool;
+ memset(pTxPacket, 0, sizeof(struct vnt_tx_mgmt)
+ + WLAN_PROBERESP_FR_MAXLEN);
+ pTxPacket->p80211Header = (PUWLAN_80211HDR)((u8 *)pTxPacket
+ + sizeof(struct vnt_tx_mgmt));
+ // Setup the sFrame structure.
+ sFrame.pBuf = (u8 *)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((u16)~(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->byBBType != BB_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 = (u8)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->byBBType == BB_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;
+ memcpy(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
+ *
+-*/
+
+struct vnt_tx_mgmt *s_MgrMakeAssocRequest(struct vnt_private *pDevice,
+ struct vnt_manager *pMgmt, u8 *pDAddr, u16 wCurrCapInfo,
+ u16 wListenInterval,
+ PWLAN_IE_SSID pCurrSSID,
+ PWLAN_IE_SUPP_RATES pCurrRates,
+ PWLAN_IE_SUPP_RATES pCurrExtSuppRates)
+{
+ struct vnt_tx_mgmt *pTxPacket = NULL;
+ WLAN_FR_ASSOCREQ sFrame;
+ u8 *pbyIEs;
+ u8 *pbyRSN;
+
+ pTxPacket = (struct vnt_tx_mgmt *)pMgmt->pbyMgmtPacketPool;
+ memset(pTxPacket, 0, sizeof(struct vnt_tx_mgmt)
+ + WLAN_ASSOCREQ_FR_MAXLEN);
+ pTxPacket->p80211Header = (PUWLAN_80211HDR)((u8 *)pTxPacket
+ + sizeof(struct vnt_tx_mgmt));
+ // Setup the sFrame structure.
+ sFrame.pBuf = (u8 *)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 capability 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;
+ memcpy(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->byBBType == BB_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->byBBType == BB_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;
+ memcpy(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 = (u8 *)(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;
+ memcpy(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)) {
+ unsigned int ii;
+ u16 * 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) {
+ memcpy(&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 = (u16 *)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 (!memcmp(&pDevice->gsPMKID.BSSIDInfo[ii].BSSID[0],
+ pMgmt->abyCurrBSSID,
+ ETH_ALEN)) {
+ (*pwPMKID)++;
+ memcpy(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;
+ memcpy(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 failure
+ *
+-*/
+
+struct vnt_tx_mgmt *s_MgrMakeReAssocRequest(struct vnt_private *pDevice,
+ struct vnt_manager *pMgmt, u8 *pDAddr, u16 wCurrCapInfo,
+ u16 wListenInterval, PWLAN_IE_SSID pCurrSSID,
+ PWLAN_IE_SUPP_RATES pCurrRates,
+ PWLAN_IE_SUPP_RATES pCurrExtSuppRates)
+{
+ struct vnt_tx_mgmt *pTxPacket = NULL;
+ WLAN_FR_REASSOCREQ sFrame;
+ u8 *pbyIEs;
+ u8 *pbyRSN;
+
+ pTxPacket = (struct vnt_tx_mgmt *)pMgmt->pbyMgmtPacketPool;
+ memset(pTxPacket, 0, sizeof(struct vnt_tx_mgmt)
+ + WLAN_REASSOCREQ_FR_MAXLEN);
+ pTxPacket->p80211Header = (PUWLAN_80211HDR)((u8 *)pTxPacket
+ + sizeof(struct vnt_tx_mgmt));
+ /* Setup the sFrame structure. */
+ sFrame.pBuf = (u8 *)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 capability 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;
+ memcpy(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;
+ memcpy(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 = (u8 *)(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;
+ memcpy(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)) {
+ unsigned int ii;
+ u16 * 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) {
+ memcpy(&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 = (u16 *)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 (!memcmp(&pDevice->gsPMKID.BSSIDInfo[ii].BSSID[0],
+ pMgmt->abyCurrBSSID,
+ ETH_ALEN)) {
+ (*pwPMKID)++;
+ memcpy(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;
+ memcpy(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 failure
+ *
+-*/
+
+struct vnt_tx_mgmt *s_MgrMakeAssocResponse(struct vnt_private *pDevice,
+ struct vnt_manager *pMgmt, u16 wCurrCapInfo, u16 wAssocStatus,
+ u16 wAssocAID, u8 *pDstAddr, PWLAN_IE_SUPP_RATES pCurrSuppRates,
+ PWLAN_IE_SUPP_RATES pCurrExtSuppRates)
+{
+ struct vnt_tx_mgmt *pTxPacket = NULL;
+ WLAN_FR_ASSOCRESP sFrame;
+
+ pTxPacket = (struct vnt_tx_mgmt *)pMgmt->pbyMgmtPacketPool;
+ memset(pTxPacket, 0, sizeof(struct vnt_tx_mgmt)
+ + WLAN_ASSOCREQ_FR_MAXLEN);
+ pTxPacket->p80211Header = (PUWLAN_80211HDR)((u8 *)pTxPacket
+ + sizeof(struct vnt_tx_mgmt));
+ // Setup the sFrame structure
+ sFrame.pBuf = (u8 *)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((u16)(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;
+ memcpy(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 failure
+ *
+-*/
+
+struct vnt_tx_mgmt *s_MgrMakeReAssocResponse(struct vnt_private *pDevice,
+ struct vnt_manager *pMgmt, u16 wCurrCapInfo, u16 wAssocStatus,
+ u16 wAssocAID, u8 *pDstAddr, PWLAN_IE_SUPP_RATES pCurrSuppRates,
+ PWLAN_IE_SUPP_RATES pCurrExtSuppRates)
+{
+ struct vnt_tx_mgmt *pTxPacket = NULL;
+ WLAN_FR_REASSOCRESP sFrame;
+
+ pTxPacket = (struct vnt_tx_mgmt *)pMgmt->pbyMgmtPacketPool;
+ memset(pTxPacket, 0, sizeof(struct vnt_tx_mgmt)
+ + WLAN_ASSOCREQ_FR_MAXLEN);
+ pTxPacket->p80211Header = (PUWLAN_80211HDR)((u8 *)pTxPacket
+ + sizeof(struct vnt_tx_mgmt));
+ // Setup the sFrame structure
+ sFrame.pBuf = (u8 *)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((u16)(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;
+ memcpy(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(struct vnt_private *pDevice,
+ struct vnt_manager *pMgmt, struct vnt_rx_mgmt *pRxPacket)
+{
+ PKnownBSS pBSSList = NULL;
+ WLAN_FR_PROBERESP sFrame;
+ u8 byCurrChannel = pRxPacket->byRxChannel;
+ ERPObject sERP;
+ int bChannelHit = true;
+
+ memset(&sFrame, 0, sizeof(WLAN_FR_PROBERESP));
+ // decode the frame
+ sFrame.len = pRxPacket->cbMPDULen;
+ sFrame.pBuf = (u8 *)pRxPacket->p80211Header;
+ vMgrDecodeProbeResponse(&sFrame);
+
+ if ((sFrame.pqwTimestamp == NULL)
+ || (sFrame.pwBeaconInterval == NULL)
+ || (sFrame.pwCapInfo == NULL)
+ || (sFrame.pSSID == NULL)
+ || (sFrame.pSuppRates == NULL)) {
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe resp:Fail addr:[%p]\n",
+ pRxPacket->p80211Header);
+ DBG_PORT80(0xCC);
+ return;
+ }
+
+ if(sFrame.pSSID->len == 0)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx Probe resp: SSID len = 0 \n");
+
+ //{{ RobertYu:20050201, 11a byCurrChannel != sFrame.pDSParms->byCurrChannel mapping
+ if( byCurrChannel > CB_MAX_CHANNEL_24G )
+ {
+ if (sFrame.pDSParms) {
+ if (byCurrChannel ==
+ RFaby11aChannelIndex[sFrame.pDSParms->byCurrChannel-1])
+ bChannelHit = true;
+ byCurrChannel =
+ RFaby11aChannelIndex[sFrame.pDSParms->byCurrChannel-1];
+ } else {
+ bChannelHit = true;
+ }
+ } else {
+ if (sFrame.pDSParms) {
+ if (byCurrChannel == sFrame.pDSParms->byCurrChannel)
+ bChannelHit = true;
+ byCurrChannel = sFrame.pDSParms->byCurrChannel;
+ } else {
+ bChannelHit = true;
+ }
+ }
+ //RobertYu:20050201
+
+if(ChannelExceedZoneType(pDevice,byCurrChannel)==true)
+ return;
+
+ if (sFrame.pERP) {
+ sERP.byERP = sFrame.pERP->byContext;
+ sERP.bERPExist = true;
+ } else {
+ sERP.bERPExist = false;
+ sERP.byERP = 0;
+ }
+
+ // update or insert the bss
+ pBSSList = BSSpAddrIsInBSSList((void *) pDevice,
+ sFrame.pHdr->sA3.abyAddr3,
+ sFrame.pSSID);
+ if (pBSSList) {
+ BSSbUpdateToBSSList((void *) 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,
+ /* payload of probresponse */
+ sFrame.pHdr->sA4.abyAddr4,
+ (void *) pRxPacket);
+ } else {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Probe resp/insert: RxChannel = : %d\n", byCurrChannel);
+ BSSbInsertToBSSList((void *) 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 */
+ (void *) pRxPacket);
+ }
+ return;
+
+}
+
+/*+
+ *
+ * Routine Description:(AP)or(Ad-hoc STA)
+ * Handles probe request management frames.
+ *
+ *
+ * Return Value:
+ * none.
+ *
+-*/
+
+static void s_vMgrRxProbeRequest(struct vnt_private *pDevice,
+ struct vnt_manager *pMgmt, struct vnt_rx_mgmt *pRxPacket)
+{
+ WLAN_FR_PROBEREQ sFrame;
+ CMD_STATUS Status;
+ struct vnt_tx_mgmt *pTxPacket;
+ u8 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 = (u8 *)pRxPacket->p80211Header;
+ vMgrDecodeProbeRequest(&sFrame);
+/*
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request rx:MAC addr:%pM\n",
+ sFrame.pHdr->sA3.abyAddr2);
+*/
+ 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,
+ (u8 *)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) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Probe response tx failed\n");
+ }
+ else {
+// DBG_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(struct vnt_private *pDevice, struct vnt_manager *pMgmt,
+ struct vnt_rx_mgmt *pRxPacket)
+{
+ int bInScan = false;
+ u32 uNodeIndex = 0;
+ NODE_STATE eNodeState = 0;
+ CMD_STATUS Status;
+
+ if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
+ if (BSSbIsSTAInNodeDB(pDevice, 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
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx assocreq\n");
+ if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) &&
+ (eNodeState < NODE_AUTH)) {
+ // send deauth notification
+ // reason = (6) class 2 received from nonauth sta
+ vMgrDeAuthenBeginSta(pDevice,
+ pMgmt,
+ pRxPacket->p80211Header->sA3.abyAddr2,
+ (6),
+ &Status
+ );
+ DBG_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
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx assocresp1\n");
+ s_vMgrRxAssocResponse(pDevice, pMgmt, pRxPacket, false);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx assocresp2\n");
+ break;
+
+ case WLAN_FSTYPE_REASSOCREQ:
+ // Frame Clase = 2
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx reassocreq\n");
+ // Todo: reassoc
+ if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) &&
+ (eNodeState < NODE_AUTH)) {
+ // send deauth notification
+ // reason = (6) class 2 received from nonauth sta
+ vMgrDeAuthenBeginSta(pDevice,
+ pMgmt,
+ pRxPacket->p80211Header->sA3.abyAddr2,
+ (6),
+ &Status
+ );
+ DBG_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
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx reassocresp\n");
+ s_vMgrRxAssocResponse(pDevice, pMgmt, pRxPacket, true);
+ break;
+
+ case WLAN_FSTYPE_PROBEREQ:
+ // Frame Clase = 0
+ //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx probereq\n");
+ s_vMgrRxProbeRequest(pDevice, pMgmt, pRxPacket);
+ break;
+
+ case WLAN_FSTYPE_PROBERESP:
+ // Frame Clase = 0
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx proberesp\n");
+
+ s_vMgrRxProbeResponse(pDevice, pMgmt, pRxPacket);
+ break;
+
+ case WLAN_FSTYPE_BEACON:
+ // Frame Clase = 0
+ //DBG_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
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx atim\n");
+ break;
+
+ case WLAN_FSTYPE_DISASSOC:
+ // Frame Clase = 2
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx disassoc\n");
+ if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) &&
+ (eNodeState < NODE_AUTH)) {
+ // send deauth notification
+ // reason = (6) class 2 received from nonauth sta
+ vMgrDeAuthenBeginSta(pDevice,
+ pMgmt,
+ pRxPacket->p80211Header->sA3.abyAddr2,
+ (6),
+ &Status
+ );
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: send vMgrDeAuthenBeginSta 3\n");
+ }
+ s_vMgrRxDisassociation(pDevice, pMgmt, pRxPacket);
+ break;
+
+ case WLAN_FSTYPE_AUTHEN:
+ // Frame Clase = 1
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx authen\n");
+ s_vMgrRxAuthentication(pDevice, pMgmt, pRxPacket);
+ break;
+
+ case WLAN_FSTYPE_DEAUTHEN:
+ // Frame Clase = 1
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx deauthen\n");
+ s_vMgrRxDeauthentication(pDevice, pMgmt, pRxPacket);
+ break;
+
+ default:
+ DBG_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.
+ *
+-*/
+int bMgrPrepareBeaconToSend(struct vnt_private *pDevice,
+ struct vnt_manager *pMgmt)
+{
+ struct vnt_tx_mgmt *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,
+ (u8 *)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);
+ MACvRegBitsOn(pDevice, MAC_REG_TCR, TCR_AUTOBCNTX);
+
+ 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(struct vnt_manager *pMgmt, u16 wStatus)
+{
+ switch( wStatus ){
+ case WLAN_MGMT_STATUS_UNSPEC_FAILURE:
+ DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Unspecified error.\n");
+ break;
+ case WLAN_MGMT_STATUS_CAPS_UNSUPPORTED:
+ DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Can't support all requested capabilities.\n");
+ break;
+ case WLAN_MGMT_STATUS_REASSOC_NO_ASSOC:
+ DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Reassoc denied, can't confirm original Association.\n");
+ break;
+ case WLAN_MGMT_STATUS_ASSOC_DENIED_UNSPEC:
+ DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, undefine in spec\n");
+ break;
+ case WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG:
+ DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Peer doesn't support authen algorithm.\n");
+ break;
+ case WLAN_MGMT_STATUS_RX_AUTH_NOSEQ:
+ DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Authen frame received out of sequence.\n");
+ break;
+ case WLAN_MGMT_STATUS_CHALLENGE_FAIL:
+ DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Authen rejected, challenge failure.\n");
+ break;
+ case WLAN_MGMT_STATUS_AUTH_TIMEOUT:
+ DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Authen rejected, timeout waiting for next frame.\n");
+ break;
+ case WLAN_MGMT_STATUS_ASSOC_DENIED_BUSY:
+ DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, AP too busy.\n");
+ break;
+ case WLAN_MGMT_STATUS_ASSOC_DENIED_RATES:
+ DBG_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:
+ DBG_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:
+ DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we do not support PBCC.\n");
+ break;
+ case WLAN_MGMT_STATUS_ASSOC_DENIED_AGILITY:
+ DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we do not support channel agility.\n");
+ break;
+ default:
+ DBG_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.
+ *
+-*/
+
+int bAdd_PMKID_Candidate(struct vnt_private *pDevice, u8 *pbyBSSID,
+ PSRSNCapObject psRSNCapObj)
+{
+ PPMKID_CANDIDATE pCandidateList;
+ int ii = 0;
+
+ DBG_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 (!memcmp(pCandidateList->BSSID, pbyBSSID, ETH_ALEN)) {
+ 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);
+ }
+ memcpy(pCandidateList->BSSID, pbyBSSID, ETH_ALEN);
+ pDevice->gsPMKIDCandidate.NumCandidates++;
+ DBG_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(struct vnt_private *pDevice)
+{
+ if (pDevice == NULL)
+ return;
+
+ memset(&pDevice->gsPMKIDCandidate, 0, sizeof(SPMKIDCandidateEvent));
+
+ return;
+}
+
+static bool
+s_bCipherMatch (
+ PKnownBSS pBSSNode,
+ NDIS_802_11_ENCRYPTION_STATUS EncStatus,
+ u8 * pbyCCSPK,
+ u8 * pbyCCSGK
+ )
+{
+ u8 byMulticastCipher = KEY_CTL_INVALID;
+ u8 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_11Encryption2Enabled) || (EncStatus == Ndis802_11Encryption3Enabled))) {
+ //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;
+ }
+ }
+ }
+
+ DBG_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)) {
+ 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/vt6656/wmgr.h b/drivers/staging/vt6656/wmgr.h
new file mode 100644
index 00000000..5424c7f8
--- /dev/null
+++ b/drivers/staging/vt6656/wmgr.h
@@ -0,0 +1,400 @@
+/*
+ * 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__
+
+#include "80211mgr.h"
+#include "80211hdr.h"
+#include "wcmd.h"
+#include "bssdb.h"
+#include "wpa2.h"
+#include "card.h"
+
+// 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 20 //(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
+
+//mike define: make timer to expire after desired times
+#define timer_expire(timer, next_tick) mod_timer(&timer, RUN_AT(next_tick))
+
+typedef void (*TimerFunction)(unsigned long);
+
+//+++ NDIS related
+
+typedef u8 NDIS_802_11_MAC_ADDRESS[ETH_ALEN];
+typedef struct _NDIS_802_11_AI_REQFI
+{
+ u16 Capabilities;
+ u16 ListenInterval;
+ NDIS_802_11_MAC_ADDRESS CurrentAPAddress;
+} NDIS_802_11_AI_REQFI, *PNDIS_802_11_AI_REQFI;
+
+typedef struct _NDIS_802_11_AI_RESFI
+{
+ u16 Capabilities;
+ u16 StatusCode;
+ u16 AssociationId;
+} NDIS_802_11_AI_RESFI, *PNDIS_802_11_AI_RESFI;
+
+typedef struct _NDIS_802_11_ASSOCIATION_INFORMATION
+{
+ u32 Length;
+ u16 AvailableRequestFixedIEs;
+ NDIS_802_11_AI_REQFI RequestFixedIEs;
+ u32 RequestIELength;
+ u32 OffsetRequestIEs;
+ u16 AvailableResponseFixedIEs;
+ NDIS_802_11_AI_RESFI ResponseFixedIEs;
+ u32 ResponseIELength;
+ u32 OffsetResponseIEs;
+} NDIS_802_11_ASSOCIATION_INFORMATION, *PNDIS_802_11_ASSOCIATION_INFORMATION;
+
+typedef struct tagSAssocInfo {
+ NDIS_802_11_ASSOCIATION_INFORMATION AssocInfo;
+ u8 abyIEs[WLAN_BEACON_FR_MAXLEN+WLAN_BEACON_FR_MAXLEN];
+ /* store ReqIEs set by OID_802_11_ASSOCIATION_INFORMATION */
+ u32 RequestIELength;
+ u8 abyReqIEs[WLAN_BEACON_FR_MAXLEN];
+} SAssocInfo, *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 Management Packet descriptor */
+struct vnt_tx_mgmt {
+ PUWLAN_80211HDR p80211Header;
+ u32 cbMPDULen;
+ u32 cbPayloadLen;
+};
+
+/* Rx Management Packet descriptor */
+struct vnt_rx_mgmt {
+ PUWLAN_80211HDR p80211Header;
+ u64 qwLocalTSF;
+ u32 cbMPDULen;
+ u32 cbPayloadLen;
+ u32 uRSSI;
+ u8 bySQ;
+ u8 byRxRate;
+ u8 byRxChannel;
+};
+
+struct vnt_manager {
+ void *pAdapter;
+
+ /* MAC address */
+ u8 abyMACAddr[WLAN_ADDR_LEN];
+
+ /* Configuration Mode */
+ WMAC_CONFIG_MODE eConfigMode; /* MAC pre-configed mode */
+
+ CARD_PHY_TYPE eCurrentPHYMode;
+
+ /* Operation state variables */
+ WMAC_CURRENT_MODE eCurrMode; /* MAC current connection mode */
+ WMAC_BSS_STATE eCurrState; /* MAC current BSS state */
+ WMAC_BSS_STATE eLastState; /* MAC last BSS state */
+
+ PKnownBSS pCurrBSS;
+ u8 byCSSGK;
+ u8 byCSSPK;
+
+ int bCurrBSSIDFilterOn;
+
+ /* Current state vars */
+ u32 uCurrChannel;
+ u8 abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
+ u8 abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
+ u8 abyCurrSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
+ u8 abyCurrBSSID[WLAN_BSSID_LEN];
+ u16 wCurrCapInfo;
+ u16 wCurrAID;
+ u32 uRSSITrigger;
+ u16 wCurrATIMWindow;
+ u16 wCurrBeaconPeriod;
+ int bIsDS;
+ u8 byERPContext;
+
+ CMD_STATE eCommandState;
+ u32 uScanChannel;
+
+ /* Desire joinning BSS vars */
+ u8 abyDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
+ u8 abyDesireBSSID[WLAN_BSSID_LEN];
+
+ /*restore BSS info for Ad-Hoc mode */
+ u8 abyAdHocSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
+
+ /* Adhoc or AP configuration vars */
+ u16 wIBSSBeaconPeriod;
+ u16 wIBSSATIMWindow;
+ u32 uIBSSChannel;
+ u8 abyIBSSSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
+ u8 byAPBBType;
+ u8 abyWPAIE[MAX_WPA_IE_LEN];
+ u16 wWPAIELen;
+
+ u32 uAssocCount;
+ int bMoreData;
+
+ /* Scan state vars */
+ WMAC_SCAN_STATE eScanState;
+ WMAC_SCAN_TYPE eScanType;
+ u32 uScanStartCh;
+ u32 uScanEndCh;
+ u16 wScanSteps;
+ u32 uScanBSSType;
+ /* Desire scannig vars */
+ u8 abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
+ u8 abyScanBSSID[WLAN_BSSID_LEN];
+
+ /* Privacy */
+ WMAC_AUTHENTICATION_MODE eAuthenMode;
+ int bShareKeyAlgorithm;
+ u8 abyChallenge[WLAN_CHALLENGE_LEN];
+ int bPrivacyInvoked;
+
+ /* Received beacon state vars */
+ int bInTIM;
+ int bMulticastTIM;
+ u8 byDTIMCount;
+ u8 byDTIMPeriod;
+
+ /* Power saving state vars */
+ WMAC_POWER_MODE ePSMode;
+ u16 wListenInterval;
+ u16 wCountToWakeUp;
+ int bInTIMWake;
+ u8 *pbyPSPacketPool;
+ u8 byPSPacketPool[sizeof(struct vnt_tx_mgmt)
+ + WLAN_NULLDATA_FR_MAXLEN];
+ int bRxBeaconInTBTTWake;
+ u8 abyPSTxMap[MAX_NODE_NUM + 1];
+
+ /* management command related */
+ u32 uCmdBusy;
+ u32 uCmdHostAPBusy;
+
+ /* management packet pool */
+ u8 *pbyMgmtPacketPool;
+ u8 byMgmtPacketPool[sizeof(struct vnt_tx_mgmt)
+ + WLAN_A3FR_MAXLEN];
+
+ /* One second callback timer */
+ struct timer_list sTimerSecondCallback;
+
+ /* Temporarily Rx Mgmt Packet Descriptor */
+ struct vnt_rx_mgmt sRxPacket;
+
+ /* link list of known bss's (scan results) */
+ KnownBSS sBSSList[MAX_BSS_NUM];
+ /* link list of same bss's */
+ KnownBSS pSameBSS[6];
+ int Cisco_cckm;
+ u8 Roam_dbm;
+
+ /* 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;
+ int bRoaming;
+
+ /* associate info */
+ SAssocInfo sAssocInfo;
+
+ /* for 802.11h */
+ int b11hEnable;
+ int bSwitchChannel;
+ u8 byNewChannel;
+ PWLAN_IE_MEASURE_REP pCurrMeasureEIDRep;
+ u32 uLengthOfRepEIDs;
+ u8 abyCurrentMSRReq[sizeof(struct vnt_tx_mgmt)
+ + WLAN_A3FR_MAXLEN];
+ u8 abyCurrentMSRRep[sizeof(struct vnt_tx_mgmt)
+ + WLAN_A3FR_MAXLEN];
+ u8 abyIECountry[WLAN_A3FR_MAXLEN];
+ u8 abyIBSSDFSOwner[6];
+ u8 byIBSSDFSRecovery;
+
+ struct sk_buff skb;
+
+};
+
+void vMgrObjectInit(struct vnt_private *pDevice);
+
+void vMgrAssocBeginSta(struct vnt_private *pDevice,
+ struct vnt_manager *, PCMD_STATUS pStatus);
+
+void vMgrReAssocBeginSta(struct vnt_private *pDevice,
+ struct vnt_manager *, PCMD_STATUS pStatus);
+
+void vMgrDisassocBeginSta(struct vnt_private *pDevice,
+ struct vnt_manager *, u8 *abyDestAddress, u16 wReason,
+ PCMD_STATUS pStatus);
+
+void vMgrAuthenBeginSta(struct vnt_private *pDevice,
+ struct vnt_manager *, PCMD_STATUS pStatus);
+
+void vMgrCreateOwnIBSS(struct vnt_private *pDevice,
+ PCMD_STATUS pStatus);
+
+void vMgrJoinBSSBegin(struct vnt_private *pDevice,
+ PCMD_STATUS pStatus);
+
+void vMgrRxManagePacket(struct vnt_private *pDevice,
+ struct vnt_manager *, struct vnt_rx_mgmt *);
+
+/*
+void
+vMgrScanBegin(
+ void *hDeviceContext,
+ PCMD_STATUS pStatus
+ );
+*/
+
+void vMgrDeAuthenBeginSta(struct vnt_private *pDevice,
+ struct vnt_manager *, u8 *abyDestAddress, u16 wReason,
+ PCMD_STATUS pStatus);
+
+int bMgrPrepareBeaconToSend(struct vnt_private *pDevice,
+ struct vnt_manager *);
+
+int bAdd_PMKID_Candidate(struct vnt_private *pDevice,
+ u8 *pbyBSSID, PSRSNCapObject psRSNCapObj);
+
+void vFlush_PMKID_Candidate(struct vnt_private *pDevice);
+
+#endif /* __WMGR_H__ */
diff --git a/drivers/staging/vt6656/wpa.c b/drivers/staging/vt6656/wpa.c
new file mode 100644
index 00000000..01db4e71
--- /dev/null
+++ b/drivers/staging/vt6656/wpa.c
@@ -0,0 +1,314 @@
+/*
+ * 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
+ *
+ */
+
+#include "tmacro.h"
+#include "tether.h"
+#include "device.h"
+#include "80211hdr.h"
+#include "bssdb.h"
+#include "wmgr.h"
+#include "wpa.h"
+#include "80211mgr.h"
+
+static int msglevel =MSG_LEVEL_INFO;
+
+const u8 abyOUI00[4] = { 0x00, 0x50, 0xf2, 0x00 };
+const u8 abyOUI01[4] = { 0x00, 0x50, 0xf2, 0x01 };
+const u8 abyOUI02[4] = { 0x00, 0x50, 0xf2, 0x02 };
+const u8 abyOUI03[4] = { 0x00, 0x50, 0xf2, 0x03 };
+const u8 abyOUI04[4] = { 0x00, 0x50, 0xf2, 0x04 };
+const u8 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(
+ 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(
+ PKnownBSS pBSSList,
+ PWLAN_IE_RSN_EXT pRSN
+ )
+{
+ PWLAN_IE_RSN_AUTH pIE_RSN_Auth = NULL;
+ int i, j, m, n = 0;
+ u8 * pbyCaps;
+
+ WPA_ClearRSN(pBSSList);
+
+ DBG_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) && !memcmp(pRSN->abyOUI, abyOUI01, 4)
+ && (pRSN->wVersion == 1)) {
+
+ DBG_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 ( !memcmp(pRSN->abyMulticast, abyOUI01, 4))
+ pBSSList->byGKType = WPA_WEP40;
+ else if ( !memcmp(pRSN->abyMulticast, abyOUI02, 4))
+ pBSSList->byGKType = WPA_TKIP;
+ else if ( !memcmp(pRSN->abyMulticast, abyOUI03, 4))
+ pBSSList->byGKType = WPA_AESWRAP;
+ else if ( !memcmp(pRSN->abyMulticast, abyOUI04, 4))
+ pBSSList->byGKType = WPA_AESCCMP;
+ else if ( !memcmp(pRSN->abyMulticast, abyOUI05, 4))
+ pBSSList->byGKType = WPA_WEP104;
+ else
+ // any vendor checks here
+ pBSSList->byGKType = WPA_NONE;
+
+ DBG_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;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wPKCount: %d, sizeof(pBSSList->abyPKType): %zu\n", pRSN->wPKCount, sizeof(pBSSList->abyPKType));
+ for (i = 0; (i < pRSN->wPKCount) &&
+ (j < ARRAY_SIZE(pBSSList->abyPKType)); i++) {
+ if(pRSN->len >= 12+i*4+4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*i)
+ if ( !memcmp(pRSN->PKSList[i].abyOUI, abyOUI00, 4))
+ pBSSList->abyPKType[j++] = WPA_NONE;
+ else if ( !memcmp(pRSN->PKSList[i].abyOUI, abyOUI02, 4))
+ pBSSList->abyPKType[j++] = WPA_TKIP;
+ else if ( !memcmp(pRSN->PKSList[i].abyOUI, abyOUI03, 4))
+ pBSSList->abyPKType[j++] = WPA_AESWRAP;
+ else if ( !memcmp(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 = (u16)j;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wPKCount: %d\n", pBSSList->wPKCount);
+ }
+
+ m = pRSN->wPKCount;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"m: %d\n", m);
+ DBG_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;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wAuthCount: %d, sizeof(pBSSList->abyAuthType): %zu\n",
+ pIE_RSN_Auth->wAuthCount, sizeof(pBSSList->abyAuthType));
+ for (i = 0; (i < pIE_RSN_Auth->wAuthCount) &&
+ (j < ARRAY_SIZE(pBSSList->abyAuthType)); 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 ( !memcmp(pIE_RSN_Auth->AuthKSList[i].abyOUI, abyOUI01, 4))
+ pBSSList->abyAuthType[j++] = WPA_AUTH_IEEE802_1X;
+ else if ( !memcmp(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 = (u16)j;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wAuthCount: %d\n", pBSSList->wAuthCount);
+ }
+
+ if (pIE_RSN_Auth != NULL) {
+
+ n = pIE_RSN_Auth->wAuthCount;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"n: %d\n", n);
+ DBG_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 = (u8 *)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 = *(u16 *)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- Encrypt Type
+ * pBSSList - BSS list
+ * Out:
+ * none
+ *
+ * Return Value: none.
+ *
+-*/
+bool
+WPA_SearchRSN(
+ u8 byCmd,
+ u8 byEncrypt,
+ PKnownBSS pBSSList
+ )
+{
+ int ii;
+ u8 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(
+ PWLAN_IE_RSN_EXT pRSN
+ )
+{
+ if (pRSN == NULL)
+ return false;
+
+ if ((pRSN->len >= 6) && // oui1(4)+ver(2)
+ (pRSN->byElementID == WLAN_EID_RSN_WPA) && !memcmp(pRSN->abyOUI, abyOUI01, 4) &&
+ (pRSN->wVersion == 1)) {
+ return true;
+ }
+ else
+ return false;
+}
+
diff --git a/drivers/staging/vt6656/wpa.h b/drivers/staging/vt6656/wpa.h
new file mode 100644
index 00000000..2a724c06
--- /dev/null
+++ b/drivers/staging/vt6656/wpa.h
@@ -0,0 +1,72 @@
+/*
+ * 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__
+
+#include "80211hdr.h"
+
+#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
+
+void
+WPA_ClearRSN(
+ PKnownBSS pBSSList
+ );
+
+void
+WPA_ParseRSN(
+ PKnownBSS pBSSList,
+ PWLAN_IE_RSN_EXT pRSN
+ );
+
+bool
+WPA_SearchRSN(
+ u8 byCmd,
+ u8 byEncrypt,
+ PKnownBSS pBSSList
+ );
+
+bool
+WPAb_Is_RSN(
+ PWLAN_IE_RSN_EXT pRSN
+ );
+
+#endif /* __WPA_H__ */
diff --git a/drivers/staging/vt6656/wpa2.c b/drivers/staging/vt6656/wpa2.c
new file mode 100644
index 00000000..aa221618
--- /dev/null
+++ b/drivers/staging/vt6656/wpa2.c
@@ -0,0 +1,235 @@
+/*
+ * 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
+ *
+ */
+
+#include "device.h"
+#include "wpa2.h"
+
+static int msglevel =MSG_LEVEL_INFO;
+//static int msglevel =MSG_LEVEL_DEBUG;
+
+const u8 abyOUIGK[4] = { 0x00, 0x0F, 0xAC, 0x00 };
+const u8 abyOUIWEP40[4] = { 0x00, 0x0F, 0xAC, 0x01 };
+const u8 abyOUIWEP104[4] = { 0x00, 0x0F, 0xAC, 0x05 };
+const u8 abyOUITKIP[4] = { 0x00, 0x0F, 0xAC, 0x02 };
+const u8 abyOUICCMP[4] = { 0x00, 0x0F, 0xAC, 0x04 };
+
+const u8 abyOUI8021X[4] = { 0x00, 0x0F, 0xAC, 0x01 };
+const u8 abyOUIPSK[4] = { 0x00, 0x0F, 0xAC, 0x02 };
+
+/*+
+ *
+ * Description:
+ * Clear RSN information in BSSList.
+ *
+ * Parameters:
+ * In:
+ * pBSSNode - BSS list.
+ * Out:
+ * none
+ *
+ * Return Value: none.
+ *
+-*/
+void
+WPA2_ClearRSN (
+ 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 (
+ PKnownBSS pBSSNode,
+ PWLAN_IE_RSN pRSN
+ )
+{
+ int i, j;
+ u16 m = 0, n = 0;
+ u8 * pbyOUI;
+ bool bUseGK = false;
+
+ DBG_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)) {
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Legal 802.11i RSN\n");
+
+ pbyOUI = &(pRSN->abyRSN[0]);
+ if ( !memcmp(pbyOUI, abyOUIWEP40, 4))
+ pBSSNode->byCSSGK = WLAN_11i_CSS_WEP40;
+ else if ( !memcmp(pbyOUI, abyOUITKIP, 4))
+ pBSSNode->byCSSGK = WLAN_11i_CSS_TKIP;
+ else if ( !memcmp(pbyOUI, abyOUICCMP, 4))
+ pBSSNode->byCSSGK = WLAN_11i_CSS_CCMP;
+ else if ( !memcmp(pbyOUI, abyOUIWEP104, 4))
+ pBSSNode->byCSSGK = WLAN_11i_CSS_WEP104;
+ else if ( !memcmp(pbyOUI, abyOUIGK, 4)) {
+ // invalid CSS, P802.11i/D10.0, p32
+ return;
+ } else
+ // any vendor checks here
+ pBSSNode->byCSSGK = WLAN_11i_CSS_UNKNOWN;
+
+ DBG_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 = *((u16 *) &(pRSN->abyRSN[4]));
+ j = 0;
+ pbyOUI = &(pRSN->abyRSN[6]);
+
+ for (i = 0; (i < pBSSNode->wCSSPKCount) && (j < sizeof(pBSSNode->abyCSSPK)/sizeof(u8)); i++) {
+
+ if (pRSN->len >= 8+i*4+4) { // ver(2)+GK(4)+PKCnt(2)+PKS(4*i)
+ if ( !memcmp(pbyOUI, abyOUIGK, 4)) {
+ pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_USE_GROUP;
+ bUseGK = true;
+ } else if ( !memcmp(pbyOUI, abyOUIWEP40, 4)) {
+ // Invalid CSS, continue parsing
+ } else if ( !memcmp(pbyOUI, abyOUITKIP, 4)) {
+ if (pBSSNode->byCSSGK != WLAN_11i_CSS_CCMP)
+ pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_TKIP;
+ else
+ ; // Invalid CSS, continue parsing
+ } else if ( !memcmp(pbyOUI, abyOUICCMP, 4)) {
+ pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_CCMP;
+ } else if ( !memcmp(pbyOUI, abyOUIWEP104, 4)) {
+ // Invalid CSS, continue parsing
+ } else {
+ // any vendor checks here
+ pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_UNKNOWN;
+ }
+ pbyOUI += 4;
+ DBG_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 = (u16)j;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wCSSPKCount: %d\n", pBSSNode->wCSSPKCount);
+ }
+
+ m = *((u16 *) &(pRSN->abyRSN[4]));
+
+ if (pRSN->len >= 10+m*4) { // ver(2) + GK(4) + PK count(2) + PKS(4*m) + AKMSS count(2)
+ pBSSNode->wAKMSSAuthCount = *((u16 *) &(pRSN->abyRSN[6+4*m]));
+ j = 0;
+ pbyOUI = &(pRSN->abyRSN[8+4*m]);
+ for (i = 0; (i < pBSSNode->wAKMSSAuthCount) && (j < sizeof(pBSSNode->abyAKMSSAuthType)/sizeof(u8)); i++) {
+ if (pRSN->len >= 10+(m+i)*4+4) { // ver(2)+GK(4)+PKCnt(2)+PKS(4*m)+AKMSS(2)+AKS(4*i)
+ if ( !memcmp(pbyOUI, abyOUI8021X, 4))
+ pBSSNode->abyAKMSSAuthType[j++] = WLAN_11i_AKMSS_802_1X;
+ else if ( !memcmp(pbyOUI, abyOUIPSK, 4))
+ pBSSNode->abyAKMSSAuthType[j++] = WLAN_11i_AKMSS_PSK;
+ else
+ // any vendor checks here
+ pBSSNode->abyAKMSSAuthType[j++] = WLAN_11i_AKMSS_UNKNOWN;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"abyAKMSSAuthType[%d]: %X\n", j-1, pBSSNode->abyAKMSSAuthType[j-1]);
+ } else
+ break;
+ }
+ pBSSNode->wAKMSSAuthCount = (u16)j;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wAKMSSAuthCount: %d\n", pBSSNode->wAKMSSAuthCount);
+
+ n = *((u16 *) &(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 = *((u16 *) &(pRSN->abyRSN[8+4*m+4*n]));
+ }
+ }
+ //ignore PMKID lists bcs only (Re)Assocrequest has this field
+ pBSSNode->bWPA2Valid = true;
+ }
+}
diff --git a/drivers/staging/vt6656/wpa2.h b/drivers/staging/vt6656/wpa2.h
new file mode 100644
index 00000000..dc505ce7
--- /dev/null
+++ b/drivers/staging/vt6656/wpa2.h
@@ -0,0 +1,53 @@
+/*
+ * 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__
+
+#include "80211mgr.h"
+#include "80211hdr.h"
+#include "bssdb.h"
+
+#define MAX_PMKID_CACHE 16
+
+typedef struct tagsPMKIDInfo {
+ u8 abyBSSID[6];
+ u8 abyPMKID[16];
+} PMKIDInfo, *PPMKIDInfo;
+
+typedef struct tagSPMKIDCache {
+ u32 BSSIDInfoCount;
+ PMKIDInfo BSSIDInfo[MAX_PMKID_CACHE];
+} SPMKIDCache, *PSPMKIDCache;
+
+void WPA2_ClearRSN(PKnownBSS pBSSNode);
+void WPA2vParseRSN(PKnownBSS pBSSNode, PWLAN_IE_RSN pRSN);
+
+#endif /* __WPA2_H__ */
diff --git a/drivers/staging/vt6656/wpactl.c b/drivers/staging/vt6656/wpactl.c
new file mode 100644
index 00000000..9f1b413c
--- /dev/null
+++ b/drivers/staging/vt6656/wpactl.c
@@ -0,0 +1,248 @@
+/*
+ * 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: July 28, 2006
+ *
+ * Functions:
+ *
+ * Revision History:
+ *
+ */
+
+#include "wpactl.h"
+#include "key.h"
+#include "mac.h"
+#include "device.h"
+#include "wmgr.h"
+#include "iocmd.h"
+#include "iowpa.h"
+#include "control.h"
+#include "rndis.h"
+#include "rf.h"
+
+static int msglevel = MSG_LEVEL_INFO;
+
+/*
+ * Description:
+ * Set WPA algorithm & keys
+ *
+ * Parameters:
+ * In:
+ * pDevice -
+ * param -
+ * Out:
+ *
+ * Return Value:
+ *
+ */
+int wpa_set_keys(struct vnt_private *pDevice, void *ctx)
+{
+ struct viawget_wpa_param *param = ctx;
+ struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
+ u32 dwKeyIndex = 0;
+ u8 abyKey[MAX_KEY_LEN];
+ u8 abySeq[MAX_KEY_LEN];
+ u64 KeyRSC;
+ u8 byKeyDecMode = KEY_CTL_WEP;
+ int ret = 0;
+ int uu;
+ int ii;
+
+ if (param->u.wpa_key.alg_name > WPA_ALG_CCMP)
+ return -EINVAL;
+
+ DBG_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;
+ for (uu=0; uu<MAX_KEY_TABLE; uu++) {
+ MACvDisableKeyEntry(pDevice, uu);
+ }
+ return ret;
+ }
+
+ if (param->u.wpa_key.key && param->u.wpa_key.key_len > sizeof(abyKey))
+ return -EINVAL;
+
+ memcpy(&abyKey[0], param->u.wpa_key.key, param->u.wpa_key.key_len);
+
+ dwKeyIndex = (u32)(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 = (u8)dwKeyIndex;
+ pDevice->bTransmitKey = true;
+ dwKeyIndex |= (1 << 31);
+ }
+ KeybSetDefaultKey( pDevice,
+ &(pDevice->sKey),
+ dwKeyIndex & ~(BIT30 | USE_KEYRSC),
+ param->u.wpa_key.key_len,
+ NULL,
+ abyKey,
+ KEY_CTL_WEP
+ );
+
+ }
+ pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
+ pDevice->bEncryptionEnable = true;
+ return ret;
+ }
+
+ if (param->u.wpa_key.seq && param->u.wpa_key.seq_len > sizeof(abySeq))
+ return -EINVAL;
+
+ memcpy(&abySeq[0], param->u.wpa_key.seq, param->u.wpa_key.seq_len);
+
+ if (param->u.wpa_key.seq_len > 0) {
+ for (ii = 0 ; ii < param->u.wpa_key.seq_len ; ii++) {
+ if (ii < 4)
+ KeyRSC |= (abySeq[ii] << (ii * 8));
+ else
+ KeyRSC |= (abySeq[ii] << ((ii-4) * 8));
+ }
+ dwKeyIndex |= 1 << 29;
+ }
+
+ if (param->u.wpa_key.key_index >= MAX_GROUP_KEY) {
+ DBG_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_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_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return - AES Key must be 128 bits\n");
+ return -EINVAL;
+ }
+
+ if (is_broadcast_ether_addr(&param->addr[0]) || (param->addr == NULL)) {
+ /* if broadcast, set the key as every key entry's group key */
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Groupe Key Assign.\n");
+
+ if ((KeybSetAllGroupKey(pDevice, &(pDevice->sKey), dwKeyIndex,
+ param->u.wpa_key.key_len,
+ &KeyRSC,
+ (u8 *)abyKey,
+ byKeyDecMode
+ ) == true) &&
+ (KeybSetDefaultKey(pDevice,
+ &(pDevice->sKey),
+ dwKeyIndex,
+ param->u.wpa_key.key_len,
+ &KeyRSC,
+ (u8 *)abyKey,
+ byKeyDecMode
+ ) == true) ) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "GROUP Key Assign.\n");
+ } else {
+ return -EINVAL;
+ }
+ } else {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key Assign.\n");
+ // BSSID not 0xffffffffffff
+ // Pairwise Key can't be WEP
+ if (byKeyDecMode == KEY_CTL_WEP) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key can't be WEP\n");
+ 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"));
+ return -EINVAL;
+ }
+ if (KeybSetKey(pDevice, &(pDevice->sKey), &param->addr[0],
+ dwKeyIndex, param->u.wpa_key.key_len,
+ &KeyRSC, (u8 *)abyKey, byKeyDecMode
+ ) == true) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key Set\n");
+ } else {
+ // Key Table Full
+ if (!compare_ether_addr(&param->addr[0], pDevice->abyBSSID)) {
+ //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA -Key Table Full.2\n"));
+ return -EINVAL;
+ } else {
+ // Save Key and configure just before associate/reassociate to BSSID
+ // we do not implement now
+ return -EINVAL;
+ }
+ }
+ } // BSSID not 0xffffffffffff
+ if ((ret == 0) && ((param->u.wpa_key.set_tx) != 0)) {
+ pDevice->byKeyIndex = (u8)param->u.wpa_key.key_index;
+ pDevice->bTransmitKey = true;
+ }
+ pDevice->bEncryptionEnable = true;
+
+ return ret;
+}
+
diff --git a/drivers/staging/vt6656/wpactl.h b/drivers/staging/vt6656/wpactl.h
new file mode 100644
index 00000000..e032a1b9
--- /dev/null
+++ b/drivers/staging/vt6656/wpactl.h
@@ -0,0 +1,47 @@
+/*
+ * 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__
+
+#include "device.h"
+#include "iowpa.h"
+
+//WPA related
+
+typedef enum { WPA_ALG_NONE, WPA_ALG_WEP, WPA_ALG_TKIP, WPA_ALG_CCMP } wpa_alg;
+
+#define AUTH_ALG_OPEN_SYSTEM 0x01
+#define AUTH_ALG_SHARED_KEY 0x02
+#define AUTH_ALG_LEAP 0x04
+
+typedef unsigned long long NDIS_802_11_KEY_RSC;
+
+int wpa_set_keys(struct vnt_private *, void *ctx);
+
+#endif /* __WPACL_H__ */