aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2008-12-04 23:01:41 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2009-01-06 16:52:31 -0500
commitc8d86be38785705aca77e33933298c320a1bf2a5 (patch)
treeb188305415619e6901fb2f259861110d5762041a /drivers/staging
parentc8801d8c9f639153afb7c4926654f0769483348e (diff)
Staging: add rtl8187se driver
This is a driver for the Realtek 8187 "SE" wireless PCI devices in some netbook computers (MSI Wind, and others). It includes its own copy of the ieee80211 stack, but it is compiled into the driver to prevend duplicate symbol issues. This version comes from Ralink with no authorship, but it is based on an old version of the rtl8180 driver from Andrea Merello. It was hacked up a bit to get it to build properly within the kernel tree and to properly handle the merged wireless stack within the driver. Cc: Andrea Merello <andreamrl@tiscali.it> Cc: linux-wireless <linux-wireless@vger.kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging')
-rw-r--r--drivers/staging/Kconfig2
-rw-r--r--drivers/staging/Makefile1
-rw-r--r--drivers/staging/rtl8187se/Kconfig5
-rw-r--r--drivers/staging/rtl8187se/Makefile54
-rw-r--r--drivers/staging/rtl8187se/dot11d.h101
-rw-r--r--drivers/staging/rtl8187se/ieee80211.h1755
-rw-r--r--drivers/staging/rtl8187se/ieee80211/Makefile35
-rw-r--r--drivers/staging/rtl8187se/ieee80211/aes.c469
-rw-r--r--drivers/staging/rtl8187se/ieee80211/api.c246
-rw-r--r--drivers/staging/rtl8187se/ieee80211/arc4.c103
-rw-r--r--drivers/staging/rtl8187se/ieee80211/autoload.c40
-rw-r--r--drivers/staging/rtl8187se/ieee80211/cipher.c299
-rw-r--r--drivers/staging/rtl8187se/ieee80211/compress.c64
-rw-r--r--drivers/staging/rtl8187se/ieee80211/digest.c108
-rw-r--r--drivers/staging/rtl8187se/ieee80211/dot11d.c246
-rw-r--r--drivers/staging/rtl8187se/ieee80211/dot11d.h102
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211.h1755
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c265
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.h86
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c533
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c1001
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c394
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_module.c301
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c1971
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c4029
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c602
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c828
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c884
-rw-r--r--drivers/staging/rtl8187se/ieee80211/internal.h115
-rw-r--r--drivers/staging/rtl8187se/ieee80211/kmap_types.h20
-rw-r--r--drivers/staging/rtl8187se/ieee80211/michael_mic.c194
-rw-r--r--drivers/staging/rtl8187se/ieee80211/proc.c116
-rw-r--r--drivers/staging/rtl8187se/ieee80211/rtl_crypto.h399
-rw-r--r--drivers/staging/rtl8187se/ieee80211/scatterwalk.c126
-rw-r--r--drivers/staging/rtl8187se/ieee80211/scatterwalk.h51
-rw-r--r--drivers/staging/rtl8187se/ieee80211_crypt.h86
-rw-r--r--drivers/staging/rtl8187se/r8180.h761
-rw-r--r--drivers/staging/rtl8187se/r8180_93cx6.c146
-rw-r--r--drivers/staging/rtl8187se/r8180_93cx6.h59
-rw-r--r--drivers/staging/rtl8187se/r8180_core.c6826
-rw-r--r--drivers/staging/rtl8187se/r8180_dm.c1725
-rw-r--r--drivers/staging/rtl8187se/r8180_dm.h41
-rw-r--r--drivers/staging/rtl8187se/r8180_gct.c296
-rw-r--r--drivers/staging/rtl8187se/r8180_gct.h25
-rw-r--r--drivers/staging/rtl8187se/r8180_hw.h956
-rw-r--r--drivers/staging/rtl8187se/r8180_max2820.c240
-rw-r--r--drivers/staging/rtl8187se/r8180_max2820.h21
-rw-r--r--drivers/staging/rtl8187se/r8180_pm.c90
-rw-r--r--drivers/staging/rtl8187se/r8180_pm.h28
-rw-r--r--drivers/staging/rtl8187se/r8180_rtl8225.c933
-rw-r--r--drivers/staging/rtl8187se/r8180_rtl8225.h44
-rw-r--r--drivers/staging/rtl8187se/r8180_rtl8225z2.c1587
-rw-r--r--drivers/staging/rtl8187se/r8180_rtl8255.c1838
-rw-r--r--drivers/staging/rtl8187se/r8180_rtl8255.h19
-rw-r--r--drivers/staging/rtl8187se/r8180_sa2400.c233
-rw-r--r--drivers/staging/rtl8187se/r8180_sa2400.h26
-rw-r--r--drivers/staging/rtl8187se/r8180_wx.c1644
-rw-r--r--drivers/staging/rtl8187se/r8180_wx.h21
-rw-r--r--drivers/staging/rtl8187se/r8185b_init.c3342
59 files changed, 38287 insertions, 0 deletions
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 48e2e064a654..53404a4018fe 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -81,5 +81,7 @@ source "drivers/staging/panel/Kconfig"
81 81
82source "drivers/staging/altpciechdma/Kconfig" 82source "drivers/staging/altpciechdma/Kconfig"
83 83
84source "drivers/staging/rtl8187se/Kconfig"
85
84endif # !STAGING_EXCLUDE_BUILD 86endif # !STAGING_EXCLUDE_BUILD
85endif # STAGING 87endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index b301be8af942..170789f3c4ca 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -23,3 +23,4 @@ obj-$(CONFIG_COMEDI) += comedi/
23obj-$(CONFIG_ASUS_OLED) += asus_oled/ 23obj-$(CONFIG_ASUS_OLED) += asus_oled/
24obj-$(CONFIG_PANEL) += panel/ 24obj-$(CONFIG_PANEL) += panel/
25obj-$(CONFIG_ALTERA_PCIE_CHDMA) += altpciechdma/ 25obj-$(CONFIG_ALTERA_PCIE_CHDMA) += altpciechdma/
26obj-$(CONFIG_RTL8187SE) += rtl8187se/
diff --git a/drivers/staging/rtl8187se/Kconfig b/drivers/staging/rtl8187se/Kconfig
new file mode 100644
index 000000000000..79c225acd1ad
--- /dev/null
+++ b/drivers/staging/rtl8187se/Kconfig
@@ -0,0 +1,5 @@
1config RTL8187SE
2 tristate "RealTek RTL8187SE Wireless LAN NIC driver"
3 depends on PCI
4 default N
5 ---help---
diff --git a/drivers/staging/rtl8187se/Makefile b/drivers/staging/rtl8187se/Makefile
new file mode 100644
index 000000000000..cc1c24074026
--- /dev/null
+++ b/drivers/staging/rtl8187se/Makefile
@@ -0,0 +1,54 @@
1
2#EXTRA_CFLAGS += -DCONFIG_IEEE80211_NOWEP=y
3#EXTRA_CFLAGS += -DCONFIG_RTL8180_IOMAP
4#EXTRA_CFLAGS += -std=gnu89
5#EXTRA_CFLAGS += -O2
6#CC = gcc
7EXTRA_CFLAGS += -DTHOMAS_TURBO
8#CFLAGS += -DCONFIG_RTL8185B
9#CFLAGS += -DCONFIG_RTL818x_S
10
11#added for EeePC testing
12EXTRA_CFLAGS += -DENABLE_IPS
13EXTRA_CFLAGS += -DSW_ANTE
14EXTRA_CFLAGS += -DTX_TRACK
15EXTRA_CFLAGS += -DHIGH_POWER
16EXTRA_CFLAGS += -DSW_DIG
17EXTRA_CFLAGS += -DRATE_ADAPT
18EXTRA_CFLAGS += -DCONFIG_RTL8180_PM
19
20#+YJ,080626
21EXTRA_CFLAGS += -DENABLE_DOT11D
22
23#enable it for legacy power save, disable it for leisure power save
24EXTRA_CFLAGS += -DENABLE_LPS
25
26
27#EXTRA_CFLAGS += -mhard-float -DCONFIG_FORCE_HARD_FLOAT=y
28
29r8187se-objs := r8180_core.o \
30 r8180_sa2400.o \
31 r8180_93cx6.o \
32 r8180_wx.o \
33 r8180_max2820.o \
34 r8180_gct.o \
35 r8180_rtl8225.o \
36 r8180_rtl8255.o \
37 r8180_rtl8225z2.o \
38 r8185b_init.o \
39 r8180_dm.o \
40 r8180_pm.o \
41 ieee80211/dot11d.o \
42 ieee80211/ieee80211_softmac.o \
43 ieee80211/ieee80211_rx.o \
44 ieee80211/ieee80211_tx.o \
45 ieee80211/ieee80211_wx.o \
46 ieee80211/ieee80211_module.o \
47 ieee80211/ieee80211_softmac_wx.o \
48 ieee80211/ieee80211_crypt.o \
49 ieee80211/ieee80211_crypt_tkip.o \
50 ieee80211/ieee80211_crypt_ccmp.o \
51 ieee80211/ieee80211_crypt_wep.o
52
53obj-$(CONFIG_RTL8187SE) += r8187se.o
54
diff --git a/drivers/staging/rtl8187se/dot11d.h b/drivers/staging/rtl8187se/dot11d.h
new file mode 100644
index 000000000000..49f53fe52af4
--- /dev/null
+++ b/drivers/staging/rtl8187se/dot11d.h
@@ -0,0 +1,101 @@
1#ifndef __INC_DOT11D_H
2#define __INC_DOT11D_H
3
4#include "ieee80211.h"
5
6//#define ENABLE_DOT11D
7
8//#define DOT11D_MAX_CHNL_NUM 83
9
10typedef struct _CHNL_TXPOWER_TRIPLE {
11 u8 FirstChnl;
12 u8 NumChnls;
13 u8 MaxTxPowerInDbm;
14}CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;
15
16typedef enum _DOT11D_STATE {
17 DOT11D_STATE_NONE = 0,
18 DOT11D_STATE_LEARNED,
19 DOT11D_STATE_DONE,
20}DOT11D_STATE;
21
22typedef struct _RT_DOT11D_INFO {
23 //DECLARE_RT_OBJECT(RT_DOT11D_INFO);
24
25 bool bEnabled; // dot11MultiDomainCapabilityEnabled
26
27 u16 CountryIeLen; // > 0 if CountryIeBuf[] contains valid country information element.
28 u8 CountryIeBuf[MAX_IE_LEN];
29 u8 CountryIeSrcAddr[6]; // Source AP of the country IE.
30 u8 CountryIeWatchdog;
31
32 u8 channel_map[MAX_CHANNEL_NUMBER+1]; //!!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan)
33 //u8 ChnlListLen; // #Bytes valid in ChnlList[].
34 //u8 ChnlList[DOT11D_MAX_CHNL_NUM];
35 u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];
36
37 DOT11D_STATE State;
38}RT_DOT11D_INFO, *PRT_DOT11D_INFO;
39#define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 )
40#define cpMacAddr(des,src) ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3],(des)[4]=(src)[4],(des)[5]=(src)[5])
41#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo))
42
43#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled
44#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0)
45
46#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
47#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
48
49#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \
50 (((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \
51 FALSE : \
52 (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length)))
53
54#define CIE_WATCHDOG_TH 1
55#define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog
56#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0
57#define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev)
58
59#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)
60
61
62void
63Dot11d_Init(
64 struct ieee80211_device *dev
65 );
66
67void
68Dot11d_Reset(
69 struct ieee80211_device *dev
70 );
71
72void
73Dot11d_UpdateCountryIe(
74 struct ieee80211_device *dev,
75 u8 * pTaddr,
76 u16 CoutryIeLen,
77 u8 * pCoutryIe
78 );
79
80u8
81DOT11D_GetMaxTxPwrInDbm(
82 struct ieee80211_device *dev,
83 u8 Channel
84 );
85
86void
87DOT11D_ScanComplete(
88 struct ieee80211_device * dev
89 );
90
91int IsLegalChannel(
92 struct ieee80211_device * dev,
93 u8 channel
94);
95
96int ToLegalChannel(
97 struct ieee80211_device * dev,
98 u8 channel
99);
100
101#endif // #ifndef __INC_DOT11D_H
diff --git a/drivers/staging/rtl8187se/ieee80211.h b/drivers/staging/rtl8187se/ieee80211.h
new file mode 100644
index 000000000000..bf06abeeaeb8
--- /dev/null
+++ b/drivers/staging/rtl8187se/ieee80211.h
@@ -0,0 +1,1755 @@
1/*
2 * Merged with mainline ieee80211.h in Aug 2004. Original ieee802_11
3 * remains copyright by the original authors
4 *
5 * Portions of the merged code are based on Host AP (software wireless
6 * LAN access point) driver for Intersil Prism2/2.5/3.
7 *
8 * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
9 * <jkmaline@cc.hut.fi>
10 * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
11 *
12 * Adaption to a generic IEEE 802.11 stack by James Ketrenos
13 * <jketreno@linux.intel.com>
14 * Copyright (c) 2004, Intel Corporation
15 *
16 * Modified for Realtek's wi-fi cards by Andrea Merello
17 * <andreamrl@tiscali.it>
18 *
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License version 2 as
21 * published by the Free Software Foundation. See README and COPYING for
22 * more details.
23 */
24#ifndef IEEE80211_H
25#define IEEE80211_H
26#include <linux/if_ether.h> /* ETH_ALEN */
27#include <linux/kernel.h> /* ARRAY_SIZE */
28#include <linux/version.h>
29#include <linux/jiffies.h>
30#include <linux/timer.h>
31#include <linux/sched.h>
32
33#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13))
34#include <linux/wireless.h>
35#endif
36
37/*
38#ifndef bool
39#define bool int
40#endif
41
42#ifndef true
43#define true 1
44#endif
45
46#ifndef false
47#define false 0
48#endif
49*/
50#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
51#ifndef bool
52typedef enum{false = 0, true} bool;
53#endif
54#endif
55//#ifdef JOHN_HWSEC
56#define KEY_TYPE_NA 0x0
57#define KEY_TYPE_WEP40 0x1
58#define KEY_TYPE_TKIP 0x2
59#define KEY_TYPE_CCMP 0x4
60#define KEY_TYPE_WEP104 0x5
61//#endif
62
63
64#define aSifsTime 10
65
66#define MGMT_QUEUE_NUM 5
67
68
69#define IEEE_CMD_SET_WPA_PARAM 1
70#define IEEE_CMD_SET_WPA_IE 2
71#define IEEE_CMD_SET_ENCRYPTION 3
72#define IEEE_CMD_MLME 4
73
74#define IEEE_PARAM_WPA_ENABLED 1
75#define IEEE_PARAM_TKIP_COUNTERMEASURES 2
76#define IEEE_PARAM_DROP_UNENCRYPTED 3
77#define IEEE_PARAM_PRIVACY_INVOKED 4
78#define IEEE_PARAM_AUTH_ALGS 5
79#define IEEE_PARAM_IEEE_802_1X 6
80//It should consistent with the driver_XXX.c
81// David, 2006.9.26
82#define IEEE_PARAM_WPAX_SELECT 7
83//Added for notify the encryption type selection
84// David, 2006.9.26
85#define IEEE_PROTO_WPA 1
86#define IEEE_PROTO_RSN 2
87//Added for notify the encryption type selection
88// David, 2006.9.26
89#define IEEE_WPAX_USEGROUP 0
90#define IEEE_WPAX_WEP40 1
91#define IEEE_WPAX_TKIP 2
92#define IEEE_WPAX_WRAP 3
93#define IEEE_WPAX_CCMP 4
94#define IEEE_WPAX_WEP104 5
95
96#define IEEE_KEY_MGMT_IEEE8021X 1
97#define IEEE_KEY_MGMT_PSK 2
98
99
100
101#define IEEE_MLME_STA_DEAUTH 1
102#define IEEE_MLME_STA_DISASSOC 2
103
104
105#define IEEE_CRYPT_ERR_UNKNOWN_ALG 2
106#define IEEE_CRYPT_ERR_UNKNOWN_ADDR 3
107#define IEEE_CRYPT_ERR_CRYPT_INIT_FAILED 4
108#define IEEE_CRYPT_ERR_KEY_SET_FAILED 5
109#define IEEE_CRYPT_ERR_TX_KEY_SET_FAILED 6
110#define IEEE_CRYPT_ERR_CARD_CONF_FAILED 7
111
112
113#define IEEE_CRYPT_ALG_NAME_LEN 16
114
115#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,10))
116#define ieee80211_wx_get_scan ieee80211_wx_get_scan_rtl
117#define ieee80211_wx_set_encode ieee80211_wx_set_encode_rtl
118#define ieee80211_wx_get_encode ieee80211_wx_get_encode_rtl
119////////////////////////////////
120// added for kernel conflict under FC5
121#define ieee80211_wx_get_name ieee80211_wx_get_name_rtl
122#define free_ieee80211 free_ieee80211_rtl
123#define alloc_ieee80211 alloc_ieee80211_rtl
124///////////////////////////////
125#endif
126//error in ubuntu2.6.22,so add these
127#define ieee80211_wake_queue ieee80211_wake_queue_rtl
128#define ieee80211_stop_queue ieee80211_stop_queue_rtl
129
130#define ieee80211_rx ieee80211_rx_rtl
131
132#define ieee80211_register_crypto_ops ieee80211_register_crypto_ops_rtl
133#define ieee80211_unregister_crypto_ops ieee80211_unregister_crypto_ops_rtl
134#define ieee80211_get_crypto_ops ieee80211_get_crypto_ops_rtl
135#define ieee80211_crypt_deinit_entries ieee80211_crypt_deinit_entries_rtl
136#define ieee80211_crypt_deinit_handler ieee80211_crypt_deinit_handler_rtl
137#define ieee80211_crypt_delayed_deinit ieee80211_crypt_delayed_deinit_rtl
138
139#define ieee80211_txb_free ieee80211_txb_free_rtl
140#define ieee80211_wx_get_essid ieee80211_wx_get_essid_rtl
141#define ieee80211_wx_set_essid ieee80211_wx_set_essid_rtl
142#define ieee80211_wx_set_rate ieee80211_wx_set_rate_rtl
143#define ieee80211_wx_get_rate ieee80211_wx_get_rate_rtl
144#define ieee80211_wx_set_wap ieee80211_wx_set_wap_rtl
145#define ieee80211_wx_get_wap ieee80211_wx_get_wap_rtl
146#define ieee80211_wx_set_mode ieee80211_wx_set_mode_rtl
147#define ieee80211_wx_get_mode ieee80211_wx_get_mode_rtl
148#define ieee80211_wx_set_scan ieee80211_wx_set_scan_rtl
149#define ieee80211_wx_get_freq ieee80211_wx_get_freq_rtl
150#define ieee80211_wx_set_freq ieee80211_wx_set_freq_rtl
151#define ieee80211_wx_set_rawtx ieee80211_wx_set_rawtx_rtl
152#define ieee80211_wx_set_power ieee80211_wx_set_power_rtl
153#define ieee80211_wx_get_power ieee80211_wx_get_power_rtl
154#define ieee80211_wlan_frequencies ieee80211_wlan_frequencies_rtl
155#define ieee80211_softmac_stop_protocol ieee80211_softmac_stop_protocol_rtl
156#define ieee80211_softmac_start_protocol ieee80211_softmac_start_protocol_rtl
157#define ieee80211_start_protocol ieee80211_start_protocol_rtl
158#define ieee80211_stop_protocol ieee80211_stop_protocol_rtl
159#define ieee80211_rx_mgt ieee80211_rx_mgt_rtl
160
161#define ieee80211_wx_set_auth ieee80211_wx_set_auth_rtl
162//by amy for ps
163#define notify_wx_assoc_event notify_wx_assoc_event_rtl
164#define ieee80211_stop_send_beacons ieee80211_stop_send_beacons_rtl
165#define ieee80211_disassociate ieee80211_disassociate_rtl
166#define ieee80211_start_scan ieee80211_start_scan_rtl
167//by amy for ps
168typedef struct ieee_param {
169 u32 cmd;
170 u8 sta_addr[ETH_ALEN];
171 union {
172 struct {
173 u8 name;
174 u32 value;
175 } wpa_param;
176 struct {
177 u32 len;
178 u8 reserved[32];
179 u8 data[0];
180 } wpa_ie;
181 struct{
182 int command;
183 int reason_code;
184 } mlme;
185 struct {
186 u8 alg[IEEE_CRYPT_ALG_NAME_LEN];
187 u8 set_tx;
188 u32 err;
189 u8 idx;
190 u8 seq[8]; /* sequence counter (set: RX, get: TX) */
191 u16 key_len;
192 u8 key[0];
193 } crypt;
194
195 } u;
196}ieee_param;
197
198
199#if WIRELESS_EXT < 17
200#define IW_QUAL_QUAL_INVALID 0x10
201#define IW_QUAL_LEVEL_INVALID 0x20
202#define IW_QUAL_NOISE_INVALID 0x40
203#define IW_QUAL_QUAL_UPDATED 0x1
204#define IW_QUAL_LEVEL_UPDATED 0x2
205#define IW_QUAL_NOISE_UPDATED 0x4
206#endif
207
208// linux under 2.6.9 release may not support it, so modify it for common use
209#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9))
210#define MSECS(t) (1000 * ((t) / HZ) + 1000 * ((t) % HZ) / HZ)
211static inline unsigned long msleep_interruptible_rtl(unsigned int msecs)
212{
213 unsigned long timeout = MSECS(msecs) + 1;
214
215 while (timeout) {
216 set_current_state(TASK_UNINTERRUPTIBLE);
217 timeout = schedule_timeout(timeout);
218 }
219 return timeout;
220}
221#else
222#define MSECS(t) msecs_to_jiffies(t)
223#define msleep_interruptible_rtl msleep_interruptible
224#endif
225
226#define IEEE80211_DATA_LEN 2304
227/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
228 6.2.1.1.2.
229
230 The figure in section 7.1.2 suggests a body size of up to 2312
231 bytes is allowed, which is a bit confusing, I suspect this
232 represents the 2304 bytes of real data, plus a possible 8 bytes of
233 WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */
234
235
236#define IEEE80211_HLEN 30
237#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN)
238
239/* this is stolen and modified from the madwifi driver*/
240#define IEEE80211_FC0_TYPE_MASK 0x0c
241#define IEEE80211_FC0_TYPE_DATA 0x08
242#define IEEE80211_FC0_SUBTYPE_MASK 0xB0
243#define IEEE80211_FC0_SUBTYPE_QOS 0x80
244
245#define IEEE80211_QOS_HAS_SEQ(fc) \
246 (((fc) & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == \
247 (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS))
248
249/* this is stolen from ipw2200 driver */
250#define IEEE_IBSS_MAC_HASH_SIZE 31
251struct ieee_ibss_seq {
252 u8 mac[ETH_ALEN];
253 u16 seq_num[17];
254 u16 frag_num[17];
255 unsigned long packet_time[17];
256 struct list_head list;
257};
258
259struct ieee80211_hdr {
260 u16 frame_ctl;
261 u16 duration_id;
262 u8 addr1[ETH_ALEN];
263 u8 addr2[ETH_ALEN];
264 u8 addr3[ETH_ALEN];
265 u16 seq_ctl;
266 u8 addr4[ETH_ALEN];
267} __attribute__ ((packed));
268
269struct ieee80211_hdr_QOS {
270 u16 frame_ctl;
271 u16 duration_id;
272 u8 addr1[ETH_ALEN];
273 u8 addr2[ETH_ALEN];
274 u8 addr3[ETH_ALEN];
275 u16 seq_ctl;
276 u8 addr4[ETH_ALEN];
277 u16 QOS_ctl;
278} __attribute__ ((packed));
279
280struct ieee80211_hdr_3addr {
281 u16 frame_ctl;
282 u16 duration_id;
283 u8 addr1[ETH_ALEN];
284 u8 addr2[ETH_ALEN];
285 u8 addr3[ETH_ALEN];
286 u16 seq_ctl;
287} __attribute__ ((packed));
288
289struct ieee80211_hdr_3addr_QOS {
290 u16 frame_ctl;
291 u16 duration_id;
292 u8 addr1[ETH_ALEN];
293 u8 addr2[ETH_ALEN];
294 u8 addr3[ETH_ALEN];
295 u16 seq_ctl;
296 u16 QOS_ctl;
297} __attribute__ ((packed));
298
299enum eap_type {
300 EAP_PACKET = 0,
301 EAPOL_START,
302 EAPOL_LOGOFF,
303 EAPOL_KEY,
304 EAPOL_ENCAP_ASF_ALERT
305};
306
307static const char *eap_types[] = {
308 [EAP_PACKET] = "EAP-Packet",
309 [EAPOL_START] = "EAPOL-Start",
310 [EAPOL_LOGOFF] = "EAPOL-Logoff",
311 [EAPOL_KEY] = "EAPOL-Key",
312 [EAPOL_ENCAP_ASF_ALERT] = "EAPOL-Encap-ASF-Alert"
313};
314
315static inline const char *eap_get_type(int type)
316{
317 return (type >= ARRAY_SIZE(eap_types)) ? "Unknown" : eap_types[type];
318}
319
320struct eapol {
321 u8 snap[6];
322 u16 ethertype;
323 u8 version;
324 u8 type;
325 u16 length;
326} __attribute__ ((packed));
327
328#define IEEE80211_3ADDR_LEN 24
329#define IEEE80211_4ADDR_LEN 30
330#define IEEE80211_FCS_LEN 4
331
332#define MIN_FRAG_THRESHOLD 256U
333#define MAX_FRAG_THRESHOLD 2346U
334
335/* Frame control field constants */
336#define IEEE80211_FCTL_VERS 0x0002
337#define IEEE80211_FCTL_FTYPE 0x000c
338#define IEEE80211_FCTL_STYPE 0x00f0
339#define IEEE80211_FCTL_TODS 0x0100
340#define IEEE80211_FCTL_FROMDS 0x0200
341#define IEEE80211_FCTL_DSTODS 0x0300 //added by david
342#define IEEE80211_FCTL_MOREFRAGS 0x0400
343#define IEEE80211_FCTL_RETRY 0x0800
344#define IEEE80211_FCTL_PM 0x1000
345#define IEEE80211_FCTL_MOREDATA 0x2000
346#define IEEE80211_FCTL_WEP 0x4000
347#define IEEE80211_FCTL_ORDER 0x8000
348
349#define IEEE80211_FTYPE_MGMT 0x0000
350#define IEEE80211_FTYPE_CTL 0x0004
351#define IEEE80211_FTYPE_DATA 0x0008
352
353/* management */
354#define IEEE80211_STYPE_ASSOC_REQ 0x0000
355#define IEEE80211_STYPE_ASSOC_RESP 0x0010
356#define IEEE80211_STYPE_REASSOC_REQ 0x0020
357#define IEEE80211_STYPE_REASSOC_RESP 0x0030
358#define IEEE80211_STYPE_PROBE_REQ 0x0040
359#define IEEE80211_STYPE_PROBE_RESP 0x0050
360#define IEEE80211_STYPE_BEACON 0x0080
361#define IEEE80211_STYPE_ATIM 0x0090
362#define IEEE80211_STYPE_DISASSOC 0x00A0
363#define IEEE80211_STYPE_AUTH 0x00B0
364#define IEEE80211_STYPE_DEAUTH 0x00C0
365#define IEEE80211_STYPE_MANAGE_ACT 0x00D0
366
367/* control */
368#define IEEE80211_STYPE_PSPOLL 0x00A0
369#define IEEE80211_STYPE_RTS 0x00B0
370#define IEEE80211_STYPE_CTS 0x00C0
371#define IEEE80211_STYPE_ACK 0x00D0
372#define IEEE80211_STYPE_CFEND 0x00E0
373#define IEEE80211_STYPE_CFENDACK 0x00F0
374
375/* data */
376#define IEEE80211_STYPE_DATA 0x0000
377#define IEEE80211_STYPE_DATA_CFACK 0x0010
378#define IEEE80211_STYPE_DATA_CFPOLL 0x0020
379#define IEEE80211_STYPE_DATA_CFACKPOLL 0x0030
380#define IEEE80211_STYPE_NULLFUNC 0x0040
381#define IEEE80211_STYPE_CFACK 0x0050
382#define IEEE80211_STYPE_CFPOLL 0x0060
383#define IEEE80211_STYPE_CFACKPOLL 0x0070
384#define IEEE80211_STYPE_QOS_DATA 0x0080 //added for WMM 2006/8/2
385#define IEEE80211_STYPE_QOS_NULL 0x00C0
386
387
388#define IEEE80211_SCTL_FRAG 0x000F
389#define IEEE80211_SCTL_SEQ 0xFFF0
390
391
392/* debug macros */
393
394#ifdef CONFIG_IEEE80211_DEBUG
395extern u32 ieee80211_debug_level;
396#define IEEE80211_DEBUG(level, fmt, args...) \
397do { if (ieee80211_debug_level & (level)) \
398 printk(KERN_DEBUG "ieee80211: %c %s " fmt, \
399 in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0)
400#else
401#define IEEE80211_DEBUG(level, fmt, args...) do {} while (0)
402#endif /* CONFIG_IEEE80211_DEBUG */
403
404/*
405 * To use the debug system;
406 *
407 * If you are defining a new debug classification, simply add it to the #define
408 * list here in the form of:
409 *
410 * #define IEEE80211_DL_xxxx VALUE
411 *
412 * shifting value to the left one bit from the previous entry. xxxx should be
413 * the name of the classification (for example, WEP)
414 *
415 * You then need to either add a IEEE80211_xxxx_DEBUG() macro definition for your
416 * classification, or use IEEE80211_DEBUG(IEEE80211_DL_xxxx, ...) whenever you want
417 * to send output to that classification.
418 *
419 * To add your debug level to the list of levels seen when you perform
420 *
421 * % cat /proc/net/ipw/debug_level
422 *
423 * you simply need to add your entry to the ipw_debug_levels array.
424 *
425 * If you do not see debug_level in /proc/net/ipw then you do not have
426 * CONFIG_IEEE80211_DEBUG defined in your kernel configuration
427 *
428 */
429
430#define IEEE80211_DL_INFO (1<<0)
431#define IEEE80211_DL_WX (1<<1)
432#define IEEE80211_DL_SCAN (1<<2)
433#define IEEE80211_DL_STATE (1<<3)
434#define IEEE80211_DL_MGMT (1<<4)
435#define IEEE80211_DL_FRAG (1<<5)
436#define IEEE80211_DL_EAP (1<<6)
437#define IEEE80211_DL_DROP (1<<7)
438
439#define IEEE80211_DL_TX (1<<8)
440#define IEEE80211_DL_RX (1<<9)
441
442#define IEEE80211_ERROR(f, a...) printk(KERN_ERR "ieee80211: " f, ## a)
443#define IEEE80211_WARNING(f, a...) printk(KERN_WARNING "ieee80211: " f, ## a)
444#define IEEE80211_DEBUG_INFO(f, a...) IEEE80211_DEBUG(IEEE80211_DL_INFO, f, ## a)
445
446#define IEEE80211_DEBUG_WX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_WX, f, ## a)
447#define IEEE80211_DEBUG_SCAN(f, a...) IEEE80211_DEBUG(IEEE80211_DL_SCAN, f, ## a)
448//#define IEEE_DEBUG_SCAN IEEE80211_WARNING
449#define IEEE80211_DEBUG_STATE(f, a...) IEEE80211_DEBUG(IEEE80211_DL_STATE, f, ## a)
450#define IEEE80211_DEBUG_MGMT(f, a...) IEEE80211_DEBUG(IEEE80211_DL_MGMT, f, ## a)
451#define IEEE80211_DEBUG_FRAG(f, a...) IEEE80211_DEBUG(IEEE80211_DL_FRAG, f, ## a)
452#define IEEE80211_DEBUG_EAP(f, a...) IEEE80211_DEBUG(IEEE80211_DL_EAP, f, ## a)
453#define IEEE80211_DEBUG_DROP(f, a...) IEEE80211_DEBUG(IEEE80211_DL_DROP, f, ## a)
454#define IEEE80211_DEBUG_TX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_TX, f, ## a)
455#define IEEE80211_DEBUG_RX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_RX, f, ## a)
456#include <linux/netdevice.h>
457#include <linux/wireless.h>
458#include <linux/if_arp.h> /* ARPHRD_ETHER */
459
460#ifndef WIRELESS_SPY
461#define WIRELESS_SPY // enable iwspy support
462#endif
463#include <net/iw_handler.h> // new driver API
464
465#ifndef ETH_P_PAE
466#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
467#endif /* ETH_P_PAE */
468
469#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */
470
471#ifndef ETH_P_80211_RAW
472#define ETH_P_80211_RAW (ETH_P_ECONET + 1)
473#endif
474
475/* IEEE 802.11 defines */
476
477#define P80211_OUI_LEN 3
478
479struct ieee80211_snap_hdr {
480
481 u8 dsap; /* always 0xAA */
482 u8 ssap; /* always 0xAA */
483 u8 ctrl; /* always 0x03 */
484 u8 oui[P80211_OUI_LEN]; /* organizational universal id */
485
486} __attribute__ ((packed));
487
488#define SNAP_SIZE sizeof(struct ieee80211_snap_hdr)
489
490#define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE)
491#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE)
492
493#define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG)
494#define WLAN_GET_SEQ_SEQ(seq) ((seq) & IEEE80211_SCTL_SEQ)
495
496/* Authentication algorithms */
497#define WLAN_AUTH_OPEN 0
498#define WLAN_AUTH_SHARED_KEY 1
499
500#define WLAN_AUTH_CHALLENGE_LEN 128
501
502#define WLAN_CAPABILITY_BSS (1<<0)
503#define WLAN_CAPABILITY_IBSS (1<<1)
504#define WLAN_CAPABILITY_CF_POLLABLE (1<<2)
505#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3)
506#define WLAN_CAPABILITY_PRIVACY (1<<4)
507#define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5)
508#define WLAN_CAPABILITY_PBCC (1<<6)
509#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7)
510#define WLAN_CAPABILITY_SHORT_SLOT (1<<10)
511
512/* Status codes */
513#define WLAN_STATUS_SUCCESS 0
514#define WLAN_STATUS_UNSPECIFIED_FAILURE 1
515#define WLAN_STATUS_CAPS_UNSUPPORTED 10
516#define WLAN_STATUS_REASSOC_NO_ASSOC 11
517#define WLAN_STATUS_ASSOC_DENIED_UNSPEC 12
518#define WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG 13
519#define WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION 14
520#define WLAN_STATUS_CHALLENGE_FAIL 15
521#define WLAN_STATUS_AUTH_TIMEOUT 16
522#define WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA 17
523#define WLAN_STATUS_ASSOC_DENIED_RATES 18
524/* 802.11b */
525#define WLAN_STATUS_ASSOC_DENIED_NOSHORT 19
526#define WLAN_STATUS_ASSOC_DENIED_NOPBCC 20
527#define WLAN_STATUS_ASSOC_DENIED_NOAGILITY 21
528
529/* Reason codes */
530#define WLAN_REASON_UNSPECIFIED 1
531#define WLAN_REASON_PREV_AUTH_NOT_VALID 2
532#define WLAN_REASON_DEAUTH_LEAVING 3
533#define WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY 4
534#define WLAN_REASON_DISASSOC_AP_BUSY 5
535#define WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA 6
536#define WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA 7
537#define WLAN_REASON_DISASSOC_STA_HAS_LEFT 8
538#define WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH 9
539
540
541/* Information Element IDs */
542#define WLAN_EID_SSID 0
543#define WLAN_EID_SUPP_RATES 1
544#define WLAN_EID_FH_PARAMS 2
545#define WLAN_EID_DS_PARAMS 3
546#define WLAN_EID_CF_PARAMS 4
547#define WLAN_EID_TIM 5
548#define WLAN_EID_IBSS_PARAMS 6
549#define WLAN_EID_CHALLENGE 16
550#define WLAN_EID_RSN 48
551#define WLAN_EID_GENERIC 221
552
553#define IEEE80211_MGMT_HDR_LEN 24
554#define IEEE80211_DATA_HDR3_LEN 24
555#define IEEE80211_DATA_HDR4_LEN 30
556
557
558#define IEEE80211_STATMASK_SIGNAL (1<<0)
559#define IEEE80211_STATMASK_RSSI (1<<1)
560#define IEEE80211_STATMASK_NOISE (1<<2)
561#define IEEE80211_STATMASK_RATE (1<<3)
562#define IEEE80211_STATMASK_WEMASK 0x7
563
564
565#define IEEE80211_CCK_MODULATION (1<<0)
566#define IEEE80211_OFDM_MODULATION (1<<1)
567
568#define IEEE80211_24GHZ_BAND (1<<0)
569#define IEEE80211_52GHZ_BAND (1<<1)
570
571#define IEEE80211_CCK_RATE_LEN 4
572#define IEEE80211_CCK_RATE_1MB 0x02
573#define IEEE80211_CCK_RATE_2MB 0x04
574#define IEEE80211_CCK_RATE_5MB 0x0B
575#define IEEE80211_CCK_RATE_11MB 0x16
576#define IEEE80211_OFDM_RATE_LEN 8
577#define IEEE80211_OFDM_RATE_6MB 0x0C
578#define IEEE80211_OFDM_RATE_9MB 0x12
579#define IEEE80211_OFDM_RATE_12MB 0x18
580#define IEEE80211_OFDM_RATE_18MB 0x24
581#define IEEE80211_OFDM_RATE_24MB 0x30
582#define IEEE80211_OFDM_RATE_36MB 0x48
583#define IEEE80211_OFDM_RATE_48MB 0x60
584#define IEEE80211_OFDM_RATE_54MB 0x6C
585#define IEEE80211_BASIC_RATE_MASK 0x80
586
587#define IEEE80211_CCK_RATE_1MB_MASK (1<<0)
588#define IEEE80211_CCK_RATE_2MB_MASK (1<<1)
589#define IEEE80211_CCK_RATE_5MB_MASK (1<<2)
590#define IEEE80211_CCK_RATE_11MB_MASK (1<<3)
591#define IEEE80211_OFDM_RATE_6MB_MASK (1<<4)
592#define IEEE80211_OFDM_RATE_9MB_MASK (1<<5)
593#define IEEE80211_OFDM_RATE_12MB_MASK (1<<6)
594#define IEEE80211_OFDM_RATE_18MB_MASK (1<<7)
595#define IEEE80211_OFDM_RATE_24MB_MASK (1<<8)
596#define IEEE80211_OFDM_RATE_36MB_MASK (1<<9)
597#define IEEE80211_OFDM_RATE_48MB_MASK (1<<10)
598#define IEEE80211_OFDM_RATE_54MB_MASK (1<<11)
599
600#define IEEE80211_CCK_RATES_MASK 0x0000000F
601#define IEEE80211_CCK_BASIC_RATES_MASK (IEEE80211_CCK_RATE_1MB_MASK | \
602 IEEE80211_CCK_RATE_2MB_MASK)
603#define IEEE80211_CCK_DEFAULT_RATES_MASK (IEEE80211_CCK_BASIC_RATES_MASK | \
604 IEEE80211_CCK_RATE_5MB_MASK | \
605 IEEE80211_CCK_RATE_11MB_MASK)
606
607#define IEEE80211_OFDM_RATES_MASK 0x00000FF0
608#define IEEE80211_OFDM_BASIC_RATES_MASK (IEEE80211_OFDM_RATE_6MB_MASK | \
609 IEEE80211_OFDM_RATE_12MB_MASK | \
610 IEEE80211_OFDM_RATE_24MB_MASK)
611#define IEEE80211_OFDM_DEFAULT_RATES_MASK (IEEE80211_OFDM_BASIC_RATES_MASK | \
612 IEEE80211_OFDM_RATE_9MB_MASK | \
613 IEEE80211_OFDM_RATE_18MB_MASK | \
614 IEEE80211_OFDM_RATE_36MB_MASK | \
615 IEEE80211_OFDM_RATE_48MB_MASK | \
616 IEEE80211_OFDM_RATE_54MB_MASK)
617#define IEEE80211_DEFAULT_RATES_MASK (IEEE80211_OFDM_DEFAULT_RATES_MASK | \
618 IEEE80211_CCK_DEFAULT_RATES_MASK)
619
620#define IEEE80211_NUM_OFDM_RATES 8
621#define IEEE80211_NUM_CCK_RATES 4
622#define IEEE80211_OFDM_SHIFT_MASK_A 4
623
624
625
626
627/* NOTE: This data is for statistical purposes; not all hardware provides this
628 * information for frames received. Not setting these will not cause
629 * any adverse affects. */
630struct ieee80211_rx_stats {
631 u32 mac_time[2];
632 u8 signalstrength;
633 s8 rssi;
634 u8 signal;
635 u8 noise;
636 u16 rate; /* in 100 kbps */
637 u8 received_channel;
638 u8 control;
639 u8 mask;
640 u8 freq;
641 u16 len;
642 u8 nic_type;
643};
644
645/* IEEE 802.11 requires that STA supports concurrent reception of at least
646 * three fragmented frames. This define can be increased to support more
647 * concurrent frames, but it should be noted that each entry can consume about
648 * 2 kB of RAM and increasing cache size will slow down frame reassembly. */
649#define IEEE80211_FRAG_CACHE_LEN 4
650
651struct ieee80211_frag_entry {
652 unsigned long first_frag_time;
653 unsigned int seq;
654 unsigned int last_frag;
655 struct sk_buff *skb;
656 u8 src_addr[ETH_ALEN];
657 u8 dst_addr[ETH_ALEN];
658};
659
660struct ieee80211_stats {
661 unsigned int tx_unicast_frames;
662 unsigned int tx_multicast_frames;
663 unsigned int tx_fragments;
664 unsigned int tx_unicast_octets;
665 unsigned int tx_multicast_octets;
666 unsigned int tx_deferred_transmissions;
667 unsigned int tx_single_retry_frames;
668 unsigned int tx_multiple_retry_frames;
669 unsigned int tx_retry_limit_exceeded;
670 unsigned int tx_discards;
671 unsigned int rx_unicast_frames;
672 unsigned int rx_multicast_frames;
673 unsigned int rx_fragments;
674 unsigned int rx_unicast_octets;
675 unsigned int rx_multicast_octets;
676 unsigned int rx_fcs_errors;
677 unsigned int rx_discards_no_buffer;
678 unsigned int tx_discards_wrong_sa;
679 unsigned int rx_discards_undecryptable;
680 unsigned int rx_message_in_msg_fragments;
681 unsigned int rx_message_in_bad_msg_fragments;
682};
683
684struct ieee80211_softmac_stats{
685 unsigned int rx_ass_ok;
686 unsigned int rx_ass_err;
687 unsigned int rx_probe_rq;
688 unsigned int tx_probe_rs;
689 unsigned int tx_beacons;
690 unsigned int rx_auth_rq;
691 unsigned int rx_auth_rs_ok;
692 unsigned int rx_auth_rs_err;
693 unsigned int tx_auth_rq;
694 unsigned int no_auth_rs;
695 unsigned int no_ass_rs;
696 unsigned int tx_ass_rq;
697 unsigned int rx_ass_rq;
698 unsigned int tx_probe_rq;
699 unsigned int reassoc;
700 unsigned int swtxstop;
701 unsigned int swtxawake;
702};
703
704struct ieee80211_device;
705
706#include "ieee80211_crypt.h"
707
708#define SEC_KEY_1 (1<<0)
709#define SEC_KEY_2 (1<<1)
710#define SEC_KEY_3 (1<<2)
711#define SEC_KEY_4 (1<<3)
712#define SEC_ACTIVE_KEY (1<<4)
713#define SEC_AUTH_MODE (1<<5)
714#define SEC_UNICAST_GROUP (1<<6)
715#define SEC_LEVEL (1<<7)
716#define SEC_ENABLED (1<<8)
717
718#define SEC_LEVEL_0 0 /* None */
719#define SEC_LEVEL_1 1 /* WEP 40 and 104 bit */
720#define SEC_LEVEL_2 2 /* Level 1 + TKIP */
721#define SEC_LEVEL_2_CKIP 3 /* Level 1 + CKIP */
722#define SEC_LEVEL_3 4 /* Level 2 + CCMP */
723
724#define WEP_KEYS 4
725#define WEP_KEY_LEN 13
726
727#define WEP_KEY_LEN_MODIF 32
728
729struct ieee80211_security {
730 u16 active_key:2,
731 enabled:1,
732 auth_mode:2,
733 auth_algo:4,
734 unicast_uses_group:1;
735 u8 key_sizes[WEP_KEYS];
736 u8 keys[WEP_KEYS][WEP_KEY_LEN_MODIF];
737 u8 level;
738 u16 flags;
739} __attribute__ ((packed));
740
741
742/*
743
744 802.11 data frame from AP
745
746 ,-------------------------------------------------------------------.
747Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 |
748 |------|------|---------|---------|---------|------|---------|------|
749Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | frame | fcs |
750 | | tion | (BSSID) | | | ence | data | |
751 `-------------------------------------------------------------------'
752
753Total: 28-2340 bytes
754
755*/
756
757struct ieee80211_header_data {
758 u16 frame_ctl;
759 u16 duration_id;
760 u8 addr1[6];
761 u8 addr2[6];
762 u8 addr3[6];
763 u16 seq_ctrl;
764};
765
766#define BEACON_PROBE_SSID_ID_POSITION 12
767
768/* Management Frame Information Element Types */
769#define MFIE_TYPE_SSID 0
770#define MFIE_TYPE_RATES 1
771#define MFIE_TYPE_FH_SET 2
772#define MFIE_TYPE_DS_SET 3
773#define MFIE_TYPE_CF_SET 4
774#define MFIE_TYPE_TIM 5
775#define MFIE_TYPE_IBSS_SET 6
776#define MFIE_TYPE_COUNTRY 7 //+YJ,080625
777#define MFIE_TYPE_CHALLENGE 16
778#define MFIE_TYPE_ERP 42
779#define MFIE_TYPE_RSN 48
780#define MFIE_TYPE_RATES_EX 50
781#define MFIE_TYPE_GENERIC 221
782
783#ifdef ENABLE_DOT11D
784typedef enum
785{
786 COUNTRY_CODE_FCC = 0,
787 COUNTRY_CODE_IC = 1,
788 COUNTRY_CODE_ETSI = 2,
789 COUNTRY_CODE_SPAIN = 3,
790 COUNTRY_CODE_FRANCE = 4,
791 COUNTRY_CODE_MKK = 5,
792 COUNTRY_CODE_MKK1 = 6,
793 COUNTRY_CODE_ISRAEL = 7,
794 COUNTRY_CODE_TELEC = 8,
795 COUNTRY_CODE_GLOBAL_DOMAIN = 9,
796 COUNTRY_CODE_WORLD_WIDE_13_INDEX = 10
797}country_code_type_t;
798#endif
799
800struct ieee80211_info_element_hdr {
801 u8 id;
802 u8 len;
803} __attribute__ ((packed));
804
805struct ieee80211_info_element {
806 u8 id;
807 u8 len;
808 u8 data[0];
809} __attribute__ ((packed));
810
811/*
812 * These are the data types that can make up management packets
813 *
814 u16 auth_algorithm;
815 u16 auth_sequence;
816 u16 beacon_interval;
817 u16 capability;
818 u8 current_ap[ETH_ALEN];
819 u16 listen_interval;
820 struct {
821 u16 association_id:14, reserved:2;
822 } __attribute__ ((packed));
823 u32 time_stamp[2];
824 u16 reason;
825 u16 status;
826*/
827
828#define IEEE80211_DEFAULT_TX_ESSID "Penguin"
829#define IEEE80211_DEFAULT_BASIC_RATE 10
830
831struct ieee80211_authentication {
832 struct ieee80211_header_data header;
833 u16 algorithm;
834 u16 transaction;
835 u16 status;
836 //struct ieee80211_info_element_hdr info_element;
837} __attribute__ ((packed));
838
839
840struct ieee80211_probe_response {
841 struct ieee80211_header_data header;
842 u32 time_stamp[2];
843 u16 beacon_interval;
844 u16 capability;
845 struct ieee80211_info_element info_element;
846} __attribute__ ((packed));
847
848struct ieee80211_probe_request {
849 struct ieee80211_header_data header;
850 /*struct ieee80211_info_element info_element;*/
851} __attribute__ ((packed));
852
853struct ieee80211_assoc_request_frame {
854 struct ieee80211_hdr_3addr header;
855 u16 capability;
856 u16 listen_interval;
857 //u8 current_ap[ETH_ALEN];
858 struct ieee80211_info_element_hdr info_element;
859} __attribute__ ((packed));
860
861struct ieee80211_assoc_response_frame {
862 struct ieee80211_hdr_3addr header;
863 u16 capability;
864 u16 status;
865 u16 aid;
866 struct ieee80211_info_element info_element; /* supported rates */
867} __attribute__ ((packed));
868
869struct ieee80211_disassoc_frame{
870 struct ieee80211_hdr_3addr header;
871 u16 reasoncode;
872}__attribute__ ((packed));
873
874struct ieee80211_txb {
875 u8 nr_frags;
876 u8 encrypted;
877 u16 reserved;
878 u16 frag_size;
879 u16 payload_size;
880 struct sk_buff *fragments[0];
881};
882
883struct ieee80211_wmm_ac_param {
884 u8 ac_aci_acm_aifsn;
885 u8 ac_ecwmin_ecwmax;
886 u16 ac_txop_limit;
887};
888
889struct ieee80211_wmm_ts_info {
890 u8 ac_dir_tid;
891 u8 ac_up_psb;
892 u8 reserved;
893} __attribute__ ((packed));
894
895struct ieee80211_wmm_tspec_elem {
896 struct ieee80211_wmm_ts_info ts_info;
897 u16 norm_msdu_size;
898 u16 max_msdu_size;
899 u32 min_serv_inter;
900 u32 max_serv_inter;
901 u32 inact_inter;
902 u32 suspen_inter;
903 u32 serv_start_time;
904 u32 min_data_rate;
905 u32 mean_data_rate;
906 u32 peak_data_rate;
907 u32 max_burst_size;
908 u32 delay_bound;
909 u32 min_phy_rate;
910 u16 surp_band_allow;
911 u16 medium_time;
912}__attribute__((packed));
913
914enum {WMM_all_frame, WMM_two_frame, WMM_four_frame, WMM_six_frame};
915#define MAX_SP_Len (WMM_all_frame << 4)
916#define IEEE80211_QOS_TID 0x0f
917#define QOS_CTL_NOTCONTAIN_ACK (0x01 << 5)
918
919/* SWEEP TABLE ENTRIES NUMBER*/
920#define MAX_SWEEP_TAB_ENTRIES 42
921#define MAX_SWEEP_TAB_ENTRIES_PER_PACKET 7
922/* MAX_RATES_LENGTH needs to be 12. The spec says 8, and many APs
923 * only use 8, and then use extended rates for the remaining supported
924 * rates. Other APs, however, stick all of their supported rates on the
925 * main rates information element... */
926#define MAX_RATES_LENGTH ((u8)12)
927#define MAX_RATES_EX_LENGTH ((u8)16)
928#define MAX_NETWORK_COUNT 128
929//#define MAX_CHANNEL_NUMBER 161
930#define MAX_CHANNEL_NUMBER 165 //YJ,modified,080625
931#define MAX_IE_LEN 0xFF //+YJ,080625
932
933typedef struct _CHANNEL_LIST{
934 u8 Channel[MAX_CHANNEL_NUMBER + 1];
935 u8 Len;
936}CHANNEL_LIST, *PCHANNEL_LIST;
937
938#define IEEE80211_SOFTMAC_SCAN_TIME 100//400
939//(HZ / 2)
940//by amy for ps
941#define IEEE80211_WATCH_DOG_TIME 2000
942//by amy for ps
943//by amy for antenna
944#define ANTENNA_DIVERSITY_TIMER_PERIOD 1000 // 1000 m
945//by amy for antenna
946#define IEEE80211_SOFTMAC_ASSOC_RETRY_TIME (HZ * 2)
947
948#define CRC_LENGTH 4U
949
950#define MAX_WPA_IE_LEN 64
951
952#define NETWORK_EMPTY_ESSID (1<<0)
953#define NETWORK_HAS_OFDM (1<<1)
954#define NETWORK_HAS_CCK (1<<2)
955
956#define IEEE80211_DTIM_MBCAST 4
957#define IEEE80211_DTIM_UCAST 2
958#define IEEE80211_DTIM_VALID 1
959#define IEEE80211_DTIM_INVALID 0
960
961#define IEEE80211_PS_DISABLED 0
962#define IEEE80211_PS_UNICAST IEEE80211_DTIM_UCAST
963#define IEEE80211_PS_MBCAST IEEE80211_DTIM_MBCAST
964#define IEEE80211_PS_ENABLE IEEE80211_DTIM_VALID
965//added by David for QoS 2006/6/30
966//#define WMM_Hang_8187
967#ifdef WMM_Hang_8187
968#undef WMM_Hang_8187
969#endif
970
971#define WME_AC_BE 0x00
972#define WME_AC_BK 0x01
973#define WME_AC_VI 0x02
974#define WME_AC_VO 0x03
975#define WME_ACI_MASK 0x03
976#define WME_AIFSN_MASK 0x03
977#define WME_AC_PRAM_LEN 16
978
979//UP Mapping to AC, using in MgntQuery_SequenceNumber() and maybe for DSCP
980//#define UP2AC(up) ((up<3) ? ((up==0)?1:0) : (up>>1))
981#define UP2AC(up) ( \
982 ((up) < 1) ? WME_AC_BE : \
983 ((up) < 3) ? WME_AC_BK : \
984 ((up) < 4) ? WME_AC_BE : \
985 ((up) < 6) ? WME_AC_VI : \
986 WME_AC_VO)
987//AC Mapping to UP, using in Tx part for selecting the corresponding TX queue
988#define AC2UP(_ac) ( \
989 ((_ac) == WME_AC_VO) ? 6 : \
990 ((_ac) == WME_AC_VI) ? 5 : \
991 ((_ac) == WME_AC_BK) ? 1 : \
992 0)
993
994#define ETHER_ADDR_LEN 6 /* length of an Ethernet address */
995struct ether_header {
996 u8 ether_dhost[ETHER_ADDR_LEN];
997 u8 ether_shost[ETHER_ADDR_LEN];
998 u16 ether_type;
999} __attribute__((packed));
1000
1001#ifndef ETHERTYPE_PAE
1002#define ETHERTYPE_PAE 0x888e /* EAPOL PAE/802.1x */
1003#endif
1004#ifndef ETHERTYPE_IP
1005#define ETHERTYPE_IP 0x0800 /* IP protocol */
1006#endif
1007
1008struct ieee80211_network {
1009 /* These entries are used to identify a unique network */
1010 u8 bssid[ETH_ALEN];
1011 u8 channel;
1012 /* Ensure null-terminated for any debug msgs */
1013 u8 ssid[IW_ESSID_MAX_SIZE + 1];
1014 u8 ssid_len;
1015
1016 /* These are network statistics */
1017 struct ieee80211_rx_stats stats;
1018 u16 capability;
1019 u8 rates[MAX_RATES_LENGTH];
1020 u8 rates_len;
1021 u8 rates_ex[MAX_RATES_EX_LENGTH];
1022 u8 rates_ex_len;
1023 unsigned long last_scanned;
1024 u8 mode;
1025 u8 flags;
1026 u32 last_associate;
1027 u32 time_stamp[2];
1028 u16 beacon_interval;
1029 u16 listen_interval;
1030 u16 atim_window;
1031 u8 wpa_ie[MAX_WPA_IE_LEN];
1032 size_t wpa_ie_len;
1033 u8 rsn_ie[MAX_WPA_IE_LEN];
1034 size_t rsn_ie_len;
1035 u8 dtim_period;
1036 u8 dtim_data;
1037 u32 last_dtim_sta_time[2];
1038 struct list_head list;
1039 //appeded for QoS
1040 u8 wmm_info;
1041 struct ieee80211_wmm_ac_param wmm_param[4];
1042 u8 QoS_Enable;
1043 u8 SignalStrength;
1044//by amy 080312
1045 u8 HighestOperaRate;
1046//by amy 080312
1047#ifdef THOMAS_TURBO
1048 u8 Turbo_Enable;//enable turbo mode, added by thomas
1049#endif
1050#ifdef ENABLE_DOT11D
1051 u16 CountryIeLen;
1052 u8 CountryIeBuf[MAX_IE_LEN];
1053#endif
1054};
1055
1056enum ieee80211_state {
1057
1058 /* the card is not linked at all */
1059 IEEE80211_NOLINK = 0,
1060
1061 /* IEEE80211_ASSOCIATING* are for BSS client mode
1062 * the driver shall not perform RX filtering unless
1063 * the state is LINKED.
1064 * The driver shall just check for the state LINKED and
1065 * defaults to NOLINK for ALL the other states (including
1066 * LINKED_SCANNING)
1067 */
1068
1069 /* the association procedure will start (wq scheduling)*/
1070 IEEE80211_ASSOCIATING,
1071 IEEE80211_ASSOCIATING_RETRY,
1072
1073 /* the association procedure is sending AUTH request*/
1074 IEEE80211_ASSOCIATING_AUTHENTICATING,
1075
1076 /* the association procedure has successfully authentcated
1077 * and is sending association request
1078 */
1079 IEEE80211_ASSOCIATING_AUTHENTICATED,
1080
1081 /* the link is ok. the card associated to a BSS or linked
1082 * to a ibss cell or acting as an AP and creating the bss
1083 */
1084 IEEE80211_LINKED,
1085
1086 /* same as LINKED, but the driver shall apply RX filter
1087 * rules as we are in NO_LINK mode. As the card is still
1088 * logically linked, but it is doing a syncro site survey
1089 * then it will be back to LINKED state.
1090 */
1091 IEEE80211_LINKED_SCANNING,
1092
1093};
1094
1095#define DEFAULT_MAX_SCAN_AGE (15 * HZ)
1096#define DEFAULT_FTS 2346
1097#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
1098#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
1099
1100
1101#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,11))
1102extern inline int is_multicast_ether_addr(const u8 *addr)
1103{
1104 return ((addr[0] != 0xff) && (0x01 & addr[0]));
1105}
1106#endif
1107
1108#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,13))
1109extern inline int is_broadcast_ether_addr(const u8 *addr)
1110{
1111 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) && \
1112 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
1113}
1114#endif
1115
1116#define CFG_IEEE80211_RESERVE_FCS (1<<0)
1117#define CFG_IEEE80211_COMPUTE_FCS (1<<1)
1118
1119typedef struct tx_pending_t{
1120 int frag;
1121 struct ieee80211_txb *txb;
1122}tx_pending_t;
1123
1124
1125struct ieee80211_device {
1126 struct net_device *dev;
1127
1128 /* Bookkeeping structures */
1129 struct net_device_stats stats;
1130 struct ieee80211_stats ieee_stats;
1131 struct ieee80211_softmac_stats softmac_stats;
1132
1133 /* Probe / Beacon management */
1134 struct list_head network_free_list;
1135 struct list_head network_list;
1136 struct ieee80211_network *networks;
1137 int scans;
1138 int scan_age;
1139
1140 int iw_mode; /* operating mode (IW_MODE_*) */
1141
1142 spinlock_t lock;
1143 spinlock_t wpax_suitlist_lock;
1144
1145 int tx_headroom; /* Set to size of any additional room needed at front
1146 * of allocated Tx SKBs */
1147 u32 config;
1148
1149 /* WEP and other encryption related settings at the device level */
1150 int open_wep; /* Set to 1 to allow unencrypted frames */
1151
1152 int reset_on_keychange; /* Set to 1 if the HW needs to be reset on
1153 * WEP key changes */
1154
1155 /* If the host performs {en,de}cryption, then set to 1 */
1156 int host_encrypt;
1157 int host_decrypt;
1158 int ieee802_1x; /* is IEEE 802.1X used */
1159
1160 /* WPA data */
1161 int wpa_enabled;
1162 int drop_unencrypted;
1163 int tkip_countermeasures;
1164 int privacy_invoked;
1165 size_t wpa_ie_len;
1166 u8 *wpa_ie;
1167
1168 u8 ap_mac_addr[6];
1169 u16 pairwise_key_type;
1170 u16 broadcast_key_type;
1171
1172 struct list_head crypt_deinit_list;
1173 struct ieee80211_crypt_data *crypt[WEP_KEYS];
1174 int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */
1175 struct timer_list crypt_deinit_timer;
1176
1177 int bcrx_sta_key; /* use individual keys to override default keys even
1178 * with RX of broad/multicast frames */
1179
1180 /* Fragmentation structures */
1181 // each streaming contain a entry
1182 struct ieee80211_frag_entry frag_cache[17][IEEE80211_FRAG_CACHE_LEN];
1183 unsigned int frag_next_idx[17];
1184 u16 fts; /* Fragmentation Threshold */
1185
1186 /* This stores infos for the current network.
1187 * Either the network we are associated in INFRASTRUCTURE
1188 * or the network that we are creating in MASTER mode.
1189 * ad-hoc is a mixture ;-).
1190 * Note that in infrastructure mode, even when not associated,
1191 * fields bssid and essid may be valid (if wpa_set and essid_set
1192 * are true) as thy carry the value set by the user via iwconfig
1193 */
1194 struct ieee80211_network current_network;
1195
1196
1197 enum ieee80211_state state;
1198
1199 int short_slot;
1200 int mode; /* A, B, G */
1201 int modulation; /* CCK, OFDM */
1202 int freq_band; /* 2.4Ghz, 5.2Ghz, Mixed */
1203 int abg_true; /* ABG flag */
1204
1205 /* used for forcing the ibss workqueue to terminate
1206 * without wait for the syncro scan to terminate
1207 */
1208 short sync_scan_hurryup;
1209
1210#ifdef ENABLE_DOT11D
1211 void * pDot11dInfo;
1212 bool bGlobalDomain;
1213
1214 // For Liteon Ch12~13 passive scan
1215 u8 MinPassiveChnlNum;
1216 u8 IbssStartChnl;
1217#else
1218 /* map of allowed channels. 0 is dummy */
1219 // FIXME: remeber to default to a basic channel plan depending of the PHY type
1220 int channel_map[MAX_CHANNEL_NUMBER+1];
1221#endif
1222
1223 int rate; /* current rate */
1224 int basic_rate;
1225 //FIXME: pleace callback, see if redundant with softmac_features
1226 short active_scan;
1227
1228 /* this contains flags for selectively enable softmac support */
1229 u16 softmac_features;
1230
1231 /* if the sequence control field is not filled by HW */
1232 u16 seq_ctrl[5];
1233
1234 /* association procedure transaction sequence number */
1235 u16 associate_seq;
1236
1237 /* AID for RTXed association responses */
1238 u16 assoc_id;
1239
1240 /* power save mode related*/
1241 short ps;
1242 short sta_sleep;
1243 int ps_timeout;
1244 struct tasklet_struct ps_task;
1245 u32 ps_th;
1246 u32 ps_tl;
1247
1248 short raw_tx;
1249 /* used if IEEE_SOFTMAC_TX_QUEUE is set */
1250 short queue_stop;
1251 short scanning;
1252 short proto_started;
1253
1254 struct semaphore wx_sem;
1255 struct semaphore scan_sem;
1256
1257 spinlock_t mgmt_tx_lock;
1258 spinlock_t beacon_lock;
1259
1260 short beacon_txing;
1261
1262 short wap_set;
1263 short ssid_set;
1264
1265 u8 wpax_type_set; //{added by David, 2006.9.28}
1266 u32 wpax_type_notify; //{added by David, 2006.9.26}
1267
1268 /* QoS related flag */
1269 char init_wmmparam_flag;
1270
1271 /* for discarding duplicated packets in IBSS */
1272 struct list_head ibss_mac_hash[IEEE_IBSS_MAC_HASH_SIZE];
1273
1274 /* for discarding duplicated packets in BSS */
1275 u16 last_rxseq_num[17]; /* rx seq previous per-tid */
1276 u16 last_rxfrag_num[17];/* tx frag previous per-tid */
1277 unsigned long last_packet_time[17];
1278
1279 /* for PS mode */
1280 unsigned long last_rx_ps_time;
1281
1282 /* used if IEEE_SOFTMAC_SINGLE_QUEUE is set */
1283 struct sk_buff *mgmt_queue_ring[MGMT_QUEUE_NUM];
1284 int mgmt_queue_head;
1285 int mgmt_queue_tail;
1286
1287
1288 /* used if IEEE_SOFTMAC_TX_QUEUE is set */
1289 struct tx_pending_t tx_pending;
1290
1291 /* used if IEEE_SOFTMAC_ASSOCIATE is set */
1292 struct timer_list associate_timer;
1293
1294 /* used if IEEE_SOFTMAC_BEACONS is set */
1295 struct timer_list beacon_timer;
1296
1297 struct work_struct associate_complete_wq;
1298// struct work_struct associate_retry_wq;
1299 struct work_struct associate_procedure_wq;
1300// struct work_struct softmac_scan_wq;
1301 struct work_struct wx_sync_scan_wq;
1302 struct work_struct wmm_param_update_wq;
1303 struct work_struct ps_request_tx_ack_wq;//for ps
1304// struct work_struct hw_wakeup_wq;
1305// struct work_struct hw_sleep_wq;
1306// struct work_struct watch_dog_wq;
1307 bool bInactivePs;
1308 bool actscanning;
1309 bool beinretry;
1310 u16 ListenInterval;
1311 unsigned long NumRxDataInPeriod; //YJ,add,080828
1312 unsigned long NumRxBcnInPeriod; //YJ,add,080828
1313 unsigned long NumRxOkTotal;
1314 unsigned long NumRxUnicast;//YJ,add,080828,for keep alive
1315 bool bHwRadioOff;
1316#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
1317 struct delayed_work softmac_scan_wq;
1318 struct delayed_work associate_retry_wq;
1319 struct delayed_work hw_wakeup_wq;
1320 struct delayed_work hw_sleep_wq;//+by amy 080324
1321 struct delayed_work watch_dog_wq;
1322 struct delayed_work sw_antenna_wq;
1323 struct delayed_work start_ibss_wq;
1324//by amy for rate adaptive 080312
1325 struct delayed_work rate_adapter_wq;
1326//by amy for rate adaptive
1327 struct delayed_work hw_dig_wq;
1328 struct delayed_work tx_pw_wq;
1329
1330//Added for RF power on power off by lizhaoming 080512
1331 struct delayed_work GPIOChangeRFWorkItem;
1332#else
1333
1334 struct work_struct start_ibss_wq;
1335 struct work_struct softmac_scan_wq;
1336 struct work_struct associate_retry_wq;
1337 struct work_struct hw_wakeup_wq;
1338 struct work_struct hw_sleep_wq;
1339 struct work_struct watch_dog_wq;
1340 struct work_struct sw_antenna_wq;
1341//by amy for rate adaptive 080312
1342 struct work_struct rate_adapter_wq;
1343//by amy for rate adaptive
1344 struct work_struct hw_dig_wq;
1345 struct work_struct tx_pw_wq;
1346
1347//Added for RF power on power off by lizhaoming 080512
1348 struct work_struct GPIOChangeRFWorkItem;
1349#endif
1350 struct workqueue_struct *wq;
1351
1352 /* Callback functions */
1353 void (*set_security)(struct net_device *dev,
1354 struct ieee80211_security *sec);
1355
1356 /* Used to TX data frame by using txb structs.
1357 * this is not used if in the softmac_features
1358 * is set the flag IEEE_SOFTMAC_TX_QUEUE
1359 */
1360 int (*hard_start_xmit)(struct ieee80211_txb *txb,
1361 struct net_device *dev);
1362
1363 int (*reset_port)(struct net_device *dev);
1364
1365 /* Softmac-generated frames (mamagement) are TXed via this
1366 * callback if the flag IEEE_SOFTMAC_SINGLE_QUEUE is
1367 * not set. As some cards may have different HW queues that
1368 * one might want to use for data and management frames
1369 * the option to have two callbacks might be useful.
1370 * This fucntion can't sleep.
1371 */
1372 int (*softmac_hard_start_xmit)(struct sk_buff *skb,
1373 struct net_device *dev);
1374
1375 /* used instead of hard_start_xmit (not softmac_hard_start_xmit)
1376 * if the IEEE_SOFTMAC_TX_QUEUE feature is used to TX data
1377 * frames. I the option IEEE_SOFTMAC_SINGLE_QUEUE is also set
1378 * then also management frames are sent via this callback.
1379 * This function can't sleep.
1380 */
1381 void (*softmac_data_hard_start_xmit)(struct sk_buff *skb,
1382 struct net_device *dev,int rate);
1383
1384 /* stops the HW queue for DATA frames. Useful to avoid
1385 * waste time to TX data frame when we are reassociating
1386 * This function can sleep.
1387 */
1388 void (*data_hard_stop)(struct net_device *dev);
1389
1390 /* OK this is complementar to data_poll_hard_stop */
1391 void (*data_hard_resume)(struct net_device *dev);
1392
1393 /* ask to the driver to retune the radio .
1394 * This function can sleep. the driver should ensure
1395 * the radio has been swithced before return.
1396 */
1397 void (*set_chan)(struct net_device *dev,short ch);
1398
1399 /* These are not used if the ieee stack takes care of
1400 * scanning (IEEE_SOFTMAC_SCAN feature set).
1401 * In this case only the set_chan is used.
1402 *
1403 * The syncro version is similar to the start_scan but
1404 * does not return until all channels has been scanned.
1405 * this is called in user context and should sleep,
1406 * it is called in a work_queue when swithcing to ad-hoc mode
1407 * or in behalf of iwlist scan when the card is associated
1408 * and root user ask for a scan.
1409 * the fucntion stop_scan should stop both the syncro and
1410 * background scanning and can sleep.
1411 * The fucntion start_scan should initiate the background
1412 * scanning and can't sleep.
1413 */
1414 void (*scan_syncro)(struct net_device *dev);
1415 void (*start_scan)(struct net_device *dev);
1416 void (*stop_scan)(struct net_device *dev);
1417
1418 /* indicate the driver that the link state is changed
1419 * for example it may indicate the card is associated now.
1420 * Driver might be interested in this to apply RX filter
1421 * rules or simply light the LINK led
1422 */
1423 void (*link_change)(struct net_device *dev);
1424
1425 /* these two function indicates to the HW when to start
1426 * and stop to send beacons. This is used when the
1427 * IEEE_SOFTMAC_BEACONS is not set. For now the
1428 * stop_send_bacons is NOT guaranteed to be called only
1429 * after start_send_beacons.
1430 */
1431 void (*start_send_beacons) (struct net_device *dev);
1432 void (*stop_send_beacons) (struct net_device *dev);
1433
1434 /* power save mode related */
1435 void (*sta_wake_up) (struct net_device *dev);
1436 void (*ps_request_tx_ack) (struct net_device *dev);
1437 void (*enter_sleep_state) (struct net_device *dev, u32 th, u32 tl);
1438 short (*ps_is_queue_empty) (struct net_device *dev);
1439
1440 /* QoS related */
1441 //void (*wmm_param_update) (struct net_device *dev, u8 *ac_param);
1442 //void (*wmm_param_update) (struct ieee80211_device *ieee);
1443
1444 /* This must be the last item so that it points to the data
1445 * allocated beyond this structure by alloc_ieee80211 */
1446 u8 priv[0];
1447};
1448
1449#define IEEE_A (1<<0)
1450#define IEEE_B (1<<1)
1451#define IEEE_G (1<<2)
1452#define IEEE_MODE_MASK (IEEE_A|IEEE_B|IEEE_G)
1453
1454/* Generate a 802.11 header */
1455
1456/* Uses the channel change callback directly
1457 * instead of [start/stop] scan callbacks
1458 */
1459#define IEEE_SOFTMAC_SCAN (1<<2)
1460
1461/* Perform authentication and association handshake */
1462#define IEEE_SOFTMAC_ASSOCIATE (1<<3)
1463
1464/* Generate probe requests */
1465#define IEEE_SOFTMAC_PROBERQ (1<<4)
1466
1467/* Generate respones to probe requests */
1468#define IEEE_SOFTMAC_PROBERS (1<<5)
1469
1470/* The ieee802.11 stack will manages the netif queue
1471 * wake/stop for the driver, taking care of 802.11
1472 * fragmentation. See softmac.c for details. */
1473#define IEEE_SOFTMAC_TX_QUEUE (1<<7)
1474
1475/* Uses only the softmac_data_hard_start_xmit
1476 * even for TX management frames.
1477 */
1478#define IEEE_SOFTMAC_SINGLE_QUEUE (1<<8)
1479
1480/* Generate beacons. The stack will enqueue beacons
1481 * to the card
1482 */
1483#define IEEE_SOFTMAC_BEACONS (1<<6)
1484
1485
1486
1487static inline void *ieee80211_priv(struct net_device *dev)
1488{
1489 return ((struct ieee80211_device *)netdev_priv(dev))->priv;
1490}
1491
1492extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
1493{
1494 /* Single white space is for Linksys APs */
1495 if (essid_len == 1 && essid[0] == ' ')
1496 return 1;
1497
1498 /* Otherwise, if the entire essid is 0, we assume it is hidden */
1499 while (essid_len) {
1500 essid_len--;
1501 if (essid[essid_len] != '\0')
1502 return 0;
1503 }
1504
1505 return 1;
1506}
1507
1508extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode)
1509{
1510 /*
1511 * It is possible for both access points and our device to support
1512 * combinations of modes, so as long as there is one valid combination
1513 * of ap/device supported modes, then return success
1514 *
1515 */
1516 if ((mode & IEEE_A) &&
1517 (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
1518 (ieee->freq_band & IEEE80211_52GHZ_BAND))
1519 return 1;
1520
1521 if ((mode & IEEE_G) &&
1522 (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
1523 (ieee->freq_band & IEEE80211_24GHZ_BAND))
1524 return 1;
1525
1526 if ((mode & IEEE_B) &&
1527 (ieee->modulation & IEEE80211_CCK_MODULATION) &&
1528 (ieee->freq_band & IEEE80211_24GHZ_BAND))
1529 return 1;
1530
1531 return 0;
1532}
1533
1534extern inline int ieee80211_get_hdrlen(u16 fc)
1535{
1536 int hdrlen = 24;
1537
1538 switch (WLAN_FC_GET_TYPE(fc)) {
1539 case IEEE80211_FTYPE_DATA:
1540 if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
1541 hdrlen = 30; /* Addr4 */
1542 if(IEEE80211_QOS_HAS_SEQ(fc))
1543 hdrlen += 2; /* QOS ctrl*/
1544 break;
1545 case IEEE80211_FTYPE_CTL:
1546 switch (WLAN_FC_GET_STYPE(fc)) {
1547 case IEEE80211_STYPE_CTS:
1548 case IEEE80211_STYPE_ACK:
1549 hdrlen = 10;
1550 break;
1551 default:
1552 hdrlen = 16;
1553 break;
1554 }
1555 break;
1556 }
1557
1558 return hdrlen;
1559}
1560
1561
1562
1563/* ieee80211.c */
1564extern void free_ieee80211(struct net_device *dev);
1565extern struct net_device *alloc_ieee80211(int sizeof_priv);
1566
1567extern int ieee80211_set_encryption(struct ieee80211_device *ieee);
1568
1569/* ieee80211_tx.c */
1570
1571extern int ieee80211_encrypt_fragment(
1572 struct ieee80211_device *ieee,
1573 struct sk_buff *frag,
1574 int hdr_len);
1575
1576extern int ieee80211_xmit(struct sk_buff *skb,
1577 struct net_device *dev);
1578extern void ieee80211_txb_free(struct ieee80211_txb *);
1579
1580
1581/* ieee80211_rx.c */
1582extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
1583 struct ieee80211_rx_stats *rx_stats);
1584extern void ieee80211_rx_mgt(struct ieee80211_device *ieee,
1585 struct ieee80211_hdr *header,
1586 struct ieee80211_rx_stats *stats);
1587
1588/* ieee80211_wx.c */
1589extern int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
1590 struct iw_request_info *info,
1591 union iwreq_data *wrqu, char *key);
1592extern int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
1593 struct iw_request_info *info,
1594 union iwreq_data *wrqu, char *key);
1595extern int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
1596 struct iw_request_info *info,
1597 union iwreq_data *wrqu, char *key);
1598extern int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
1599 struct iw_request_info *info,
1600 union iwreq_data* wrqu, char *extra);
1601int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
1602 struct iw_request_info *info,
1603 struct iw_param *data, char *extra);
1604int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
1605 struct iw_request_info *info,
1606 union iwreq_data *wrqu, char *extra);
1607
1608int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len);
1609/* ieee80211_softmac.c */
1610extern short ieee80211_is_54g(struct ieee80211_network net);
1611extern short ieee80211_is_shortslot(struct ieee80211_network net);
1612extern int ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
1613 struct ieee80211_rx_stats *rx_stats, u16 type,
1614 u16 stype);
1615extern void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net);
1616
1617extern void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee);
1618extern void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee);
1619extern void ieee80211_start_bss(struct ieee80211_device *ieee);
1620extern void ieee80211_start_master_bss(struct ieee80211_device *ieee);
1621extern void ieee80211_start_ibss(struct ieee80211_device *ieee);
1622extern void ieee80211_softmac_init(struct ieee80211_device *ieee);
1623extern void ieee80211_softmac_free(struct ieee80211_device *ieee);
1624extern void ieee80211_associate_abort(struct ieee80211_device *ieee);
1625extern void ieee80211_disassociate(struct ieee80211_device *ieee);
1626extern void ieee80211_stop_scan(struct ieee80211_device *ieee);
1627extern void ieee80211_start_scan_syncro(struct ieee80211_device *ieee);
1628extern void ieee80211_check_all_nets(struct ieee80211_device *ieee);
1629extern void ieee80211_start_protocol(struct ieee80211_device *ieee);
1630extern void ieee80211_stop_protocol(struct ieee80211_device *ieee);
1631extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee);
1632extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee);
1633extern void ieee80211_reset_queue(struct ieee80211_device *ieee);
1634extern void ieee80211_wake_queue(struct ieee80211_device *ieee);
1635extern void ieee80211_stop_queue(struct ieee80211_device *ieee);
1636extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee);
1637extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee);
1638extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee);
1639extern int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p);
1640extern void notify_wx_assoc_event(struct ieee80211_device *ieee);
1641extern void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success);
1642extern void SendDisassociation(struct ieee80211_device *ieee,u8* asSta,u8 asRsn);
1643extern void ieee80211_start_scan(struct ieee80211_device *ieee);
1644
1645//Add for RF power on power off by lizhaoming 080512
1646extern void SendDisassociation(struct ieee80211_device *ieee,
1647 u8* asSta,
1648 u8 asRsn);
1649
1650/* ieee80211_crypt_ccmp&tkip&wep.c */
1651extern void ieee80211_tkip_null(void);
1652extern void ieee80211_wep_null(void);
1653extern void ieee80211_ccmp_null(void);
1654/* ieee80211_softmac_wx.c */
1655
1656extern int ieee80211_wx_get_wap(struct ieee80211_device *ieee,
1657 struct iw_request_info *info,
1658 union iwreq_data *wrqu, char *ext);
1659
1660extern int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
1661 struct iw_request_info *info,
1662 union iwreq_data *awrq,
1663 char *extra);
1664
1665extern int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b);
1666
1667extern int ieee80211_wx_set_rate(struct ieee80211_device *ieee,
1668 struct iw_request_info *info,
1669 union iwreq_data *wrqu, char *extra);
1670
1671extern int ieee80211_wx_get_rate(struct ieee80211_device *ieee,
1672 struct iw_request_info *info,
1673 union iwreq_data *wrqu, char *extra);
1674
1675extern int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
1676 union iwreq_data *wrqu, char *b);
1677
1678extern int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a,
1679 union iwreq_data *wrqu, char *b);
1680
1681extern int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
1682 struct iw_request_info *a,
1683 union iwreq_data *wrqu, char *extra);
1684
1685extern int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
1686 union iwreq_data *wrqu, char *b);
1687
1688extern int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
1689 union iwreq_data *wrqu, char *b);
1690
1691extern int ieee80211_wx_get_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
1692 union iwreq_data *wrqu, char *b);
1693#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
1694extern void ieee80211_wx_sync_scan_wq(struct work_struct *work);
1695#else
1696 extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee);
1697#endif
1698//extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee);
1699
1700extern int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee,
1701 struct iw_request_info *info,
1702 union iwreq_data *wrqu, char *extra);
1703
1704extern int ieee80211_wx_get_name(struct ieee80211_device *ieee,
1705 struct iw_request_info *info,
1706 union iwreq_data *wrqu, char *extra);
1707
1708extern int ieee80211_wx_set_power(struct ieee80211_device *ieee,
1709 struct iw_request_info *info,
1710 union iwreq_data *wrqu, char *extra);
1711
1712extern int ieee80211_wx_get_power(struct ieee80211_device *ieee,
1713 struct iw_request_info *info,
1714 union iwreq_data *wrqu, char *extra);
1715
1716extern void ieee80211_softmac_ips_scan_syncro(struct ieee80211_device *ieee);
1717
1718extern void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr);
1719
1720extern const long ieee80211_wlan_frequencies[];
1721
1722extern inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
1723{
1724 ieee->scans++;
1725}
1726
1727extern inline int ieee80211_get_scans(struct ieee80211_device *ieee)
1728{
1729 return ieee->scans;
1730}
1731
1732static inline const char *escape_essid(const char *essid, u8 essid_len) {
1733 static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
1734 const char *s = essid;
1735 char *d = escaped;
1736
1737 if (ieee80211_is_empty_essid(essid, essid_len)) {
1738 memcpy(escaped, "<hidden>", sizeof("<hidden>"));
1739 return escaped;
1740 }
1741
1742 essid_len = min(essid_len, (u8)IW_ESSID_MAX_SIZE);
1743 while (essid_len--) {
1744 if (*s == '\0') {
1745 *d++ = '\\';
1746 *d++ = '0';
1747 s++;
1748 } else {
1749 *d++ = *s++;
1750 }
1751 }
1752 *d = '\0';
1753 return escaped;
1754}
1755#endif /* IEEE80211_H */
diff --git a/drivers/staging/rtl8187se/ieee80211/Makefile b/drivers/staging/rtl8187se/ieee80211/Makefile
new file mode 100644
index 000000000000..b5b78dcd209d
--- /dev/null
+++ b/drivers/staging/rtl8187se/ieee80211/Makefile
@@ -0,0 +1,35 @@
1
2#EXTRA_CFLAGS += -I$(TOPDIR)/drivers/net/wireless
3#EXTRA_CFLAGS += -O2
4
5EXTRA_CFLAGS += -DTHOMAS_TURBO
6EXTRA_CFLAGS += -DENABLE_IPS
7
8ifeq ($(shell uname -r|cut -d. -f1,2,3,4), 2.6.16.60-0)
9EXTRA_CFLAGS += -DOPENSUSE_SLED
10endif
11
12ifeq ($(shell uname -r|cut -d. -f1,2,3,4), 2.6.26.3-29)
13EXTRA_CFLAGS += -DFEDORACORE_9
14endif
15
16
17#+YJ,080626
18EXTRA_CFLAGS += -DENABLE_DOT11D
19
20#enable it for legacy power save, disable it for leisure power save
21#CFLAGS += -DENABLE_LPS
22
23ieee80211-rtl-objs := dot11d.o ieee80211_softmac.o ieee80211_rx.o ieee80211_tx.o ieee80211_wx.o ieee80211_module.o ieee80211_softmac_wx.o
24
25ieee80211_crypt-rtl-objs := ieee80211_crypt.o
26ieee80211_crypt_tkip-rtl-objs := ieee80211_crypt_tkip.o
27ieee80211_crypt_ccmp-rtl-objs := ieee80211_crypt_ccmp.o
28ieee80211_crypt_wep-rtl-objs := ieee80211_crypt_wep.o
29
30obj-m +=ieee80211-rtl.o
31obj-m +=ieee80211_crypt-rtl.o
32obj-m +=ieee80211_crypt_wep-rtl.o
33obj-m +=ieee80211_crypt_tkip-rtl.o
34obj-m +=ieee80211_crypt_ccmp-rtl.o
35
diff --git a/drivers/staging/rtl8187se/ieee80211/aes.c b/drivers/staging/rtl8187se/ieee80211/aes.c
new file mode 100644
index 000000000000..0c176e29a797
--- /dev/null
+++ b/drivers/staging/rtl8187se/ieee80211/aes.c
@@ -0,0 +1,469 @@
1/*
2 * Cryptographic API.
3 *
4 * AES Cipher Algorithm.
5 *
6 * Based on Brian Gladman's code.
7 *
8 * Linux developers:
9 * Alexander Kjeldaas <astor@fast.no>
10 * Herbert Valerio Riedel <hvr@hvrlab.org>
11 * Kyle McMartin <kyle@debian.org>
12 * Adam J. Richter <adam@yggdrasil.com> (conversion to 2.5 API).
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * ---------------------------------------------------------------------------
20 * Copyright (c) 2002, Dr Brian Gladman <brg@gladman.me.uk>, Worcester, UK.
21 * All rights reserved.
22 *
23 * LICENSE TERMS
24 *
25 * The free distribution and use of this software in both source and binary
26 * form is allowed (with or without changes) provided that:
27 *
28 * 1. distributions of this source code include the above copyright
29 * notice, this list of conditions and the following disclaimer;
30 *
31 * 2. distributions in binary form include the above copyright
32 * notice, this list of conditions and the following disclaimer
33 * in the documentation and/or other associated materials;
34 *
35 * 3. the copyright holder's name is not used to endorse products
36 * built using this software without specific written permission.
37 *
38 * ALTERNATIVELY, provided that this notice is retained in full, this product
39 * may be distributed under the terms of the GNU General Public License (GPL),
40 * in which case the provisions of the GPL apply INSTEAD OF those given above.
41 *
42 * DISCLAIMER
43 *
44 * This software is provided 'as is' with no explicit or implied warranties
45 * in respect of its properties, including, but not limited to, correctness
46 * and/or fitness for purpose.
47 * ---------------------------------------------------------------------------
48 */
49
50/* Some changes from the Gladman version:
51 s/RIJNDAEL(e_key)/E_KEY/g
52 s/RIJNDAEL(d_key)/D_KEY/g
53*/
54
55#include <linux/module.h>
56#include <linux/init.h>
57#include <linux/types.h>
58#include <linux/errno.h>
59//#include <linux/crypto.h>
60#include "rtl_crypto.h"
61#include <asm/byteorder.h>
62
63#define AES_MIN_KEY_SIZE 16
64#define AES_MAX_KEY_SIZE 32
65
66#define AES_BLOCK_SIZE 16
67
68static inline
69u32 generic_rotr32 (const u32 x, const unsigned bits)
70{
71 const unsigned n = bits % 32;
72 return (x >> n) | (x << (32 - n));
73}
74
75static inline
76u32 generic_rotl32 (const u32 x, const unsigned bits)
77{
78 const unsigned n = bits % 32;
79 return (x << n) | (x >> (32 - n));
80}
81
82#define rotl generic_rotl32
83#define rotr generic_rotr32
84
85/*
86 * #define byte(x, nr) ((unsigned char)((x) >> (nr*8)))
87 */
88inline static u8
89byte(const u32 x, const unsigned n)
90{
91 return x >> (n << 3);
92}
93
94#define u32_in(x) le32_to_cpu(*(const u32 *)(x))
95#define u32_out(to, from) (*(u32 *)(to) = cpu_to_le32(from))
96
97struct aes_ctx {
98 int key_length;
99 u32 E[60];
100 u32 D[60];
101};
102
103#define E_KEY ctx->E
104#define D_KEY ctx->D
105
106static u8 pow_tab[256] __initdata;
107static u8 log_tab[256] __initdata;
108static u8 sbx_tab[256] __initdata;
109static u8 isb_tab[256] __initdata;
110static u32 rco_tab[10];
111static u32 ft_tab[4][256];
112static u32 it_tab[4][256];
113
114static u32 fl_tab[4][256];
115static u32 il_tab[4][256];
116
117static inline u8 __init
118f_mult (u8 a, u8 b)
119{
120 u8 aa = log_tab[a], cc = aa + log_tab[b];
121
122 return pow_tab[cc + (cc < aa ? 1 : 0)];
123}
124
125#define ff_mult(a,b) (a && b ? f_mult(a, b) : 0)
126
127#define f_rn(bo, bi, n, k) \
128 bo[n] = ft_tab[0][byte(bi[n],0)] ^ \
129 ft_tab[1][byte(bi[(n + 1) & 3],1)] ^ \
130 ft_tab[2][byte(bi[(n + 2) & 3],2)] ^ \
131 ft_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n)
132
133#define i_rn(bo, bi, n, k) \
134 bo[n] = it_tab[0][byte(bi[n],0)] ^ \
135 it_tab[1][byte(bi[(n + 3) & 3],1)] ^ \
136 it_tab[2][byte(bi[(n + 2) & 3],2)] ^ \
137 it_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n)
138
139#define ls_box(x) \
140 ( fl_tab[0][byte(x, 0)] ^ \
141 fl_tab[1][byte(x, 1)] ^ \
142 fl_tab[2][byte(x, 2)] ^ \
143 fl_tab[3][byte(x, 3)] )
144
145#define f_rl(bo, bi, n, k) \
146 bo[n] = fl_tab[0][byte(bi[n],0)] ^ \
147 fl_tab[1][byte(bi[(n + 1) & 3],1)] ^ \
148 fl_tab[2][byte(bi[(n + 2) & 3],2)] ^ \
149 fl_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n)
150
151#define i_rl(bo, bi, n, k) \
152 bo[n] = il_tab[0][byte(bi[n],0)] ^ \
153 il_tab[1][byte(bi[(n + 3) & 3],1)] ^ \
154 il_tab[2][byte(bi[(n + 2) & 3],2)] ^ \
155 il_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n)
156
157static void __init
158gen_tabs (void)
159{
160 u32 i, t;
161 u8 p, q;
162
163 /* log and power tables for GF(2**8) finite field with
164 0x011b as modular polynomial - the simplest primitive
165 root is 0x03, used here to generate the tables */
166
167 for (i = 0, p = 1; i < 256; ++i) {
168 pow_tab[i] = (u8) p;
169 log_tab[p] = (u8) i;
170
171 p ^= (p << 1) ^ (p & 0x80 ? 0x01b : 0);
172 }
173
174 log_tab[1] = 0;
175
176 for (i = 0, p = 1; i < 10; ++i) {
177 rco_tab[i] = p;
178
179 p = (p << 1) ^ (p & 0x80 ? 0x01b : 0);
180 }
181
182 for (i = 0; i < 256; ++i) {
183 p = (i ? pow_tab[255 - log_tab[i]] : 0);
184 q = ((p >> 7) | (p << 1)) ^ ((p >> 6) | (p << 2));
185 p ^= 0x63 ^ q ^ ((q >> 6) | (q << 2));
186 sbx_tab[i] = p;
187 isb_tab[p] = (u8) i;
188 }
189
190 for (i = 0; i < 256; ++i) {
191 p = sbx_tab[i];
192
193 t = p;
194 fl_tab[0][i] = t;
195 fl_tab[1][i] = rotl (t, 8);
196 fl_tab[2][i] = rotl (t, 16);
197 fl_tab[3][i] = rotl (t, 24);
198
199 t = ((u32) ff_mult (2, p)) |
200 ((u32) p << 8) |
201 ((u32) p << 16) | ((u32) ff_mult (3, p) << 24);
202
203 ft_tab[0][i] = t;
204 ft_tab[1][i] = rotl (t, 8);
205 ft_tab[2][i] = rotl (t, 16);
206 ft_tab[3][i] = rotl (t, 24);
207
208 p = isb_tab[i];
209
210 t = p;
211 il_tab[0][i] = t;
212 il_tab[1][i] = rotl (t, 8);
213 il_tab[2][i] = rotl (t, 16);
214 il_tab[3][i] = rotl (t, 24);
215
216 t = ((u32) ff_mult (14, p)) |
217 ((u32) ff_mult (9, p) << 8) |
218 ((u32) ff_mult (13, p) << 16) |
219 ((u32) ff_mult (11, p) << 24);
220
221 it_tab[0][i] = t;
222 it_tab[1][i] = rotl (t, 8);
223 it_tab[2][i] = rotl (t, 16);
224 it_tab[3][i] = rotl (t, 24);
225 }
226}
227
228#define star_x(x) (((x) & 0x7f7f7f7f) << 1) ^ ((((x) & 0x80808080) >> 7) * 0x1b)
229
230#define imix_col(y,x) \
231 u = star_x(x); \
232 v = star_x(u); \
233 w = star_x(v); \
234 t = w ^ (x); \
235 (y) = u ^ v ^ w; \
236 (y) ^= rotr(u ^ t, 8) ^ \
237 rotr(v ^ t, 16) ^ \
238 rotr(t,24)
239
240/* initialise the key schedule from the user supplied key */
241
242#define loop4(i) \
243{ t = rotr(t, 8); t = ls_box(t) ^ rco_tab[i]; \
244 t ^= E_KEY[4 * i]; E_KEY[4 * i + 4] = t; \
245 t ^= E_KEY[4 * i + 1]; E_KEY[4 * i + 5] = t; \
246 t ^= E_KEY[4 * i + 2]; E_KEY[4 * i + 6] = t; \
247 t ^= E_KEY[4 * i + 3]; E_KEY[4 * i + 7] = t; \
248}
249
250#define loop6(i) \
251{ t = rotr(t, 8); t = ls_box(t) ^ rco_tab[i]; \
252 t ^= E_KEY[6 * i]; E_KEY[6 * i + 6] = t; \
253 t ^= E_KEY[6 * i + 1]; E_KEY[6 * i + 7] = t; \
254 t ^= E_KEY[6 * i + 2]; E_KEY[6 * i + 8] = t; \
255 t ^= E_KEY[6 * i + 3]; E_KEY[6 * i + 9] = t; \
256 t ^= E_KEY[6 * i + 4]; E_KEY[6 * i + 10] = t; \
257 t ^= E_KEY[6 * i + 5]; E_KEY[6 * i + 11] = t; \
258}
259
260#define loop8(i) \
261{ t = rotr(t, 8); ; t = ls_box(t) ^ rco_tab[i]; \
262 t ^= E_KEY[8 * i]; E_KEY[8 * i + 8] = t; \
263 t ^= E_KEY[8 * i + 1]; E_KEY[8 * i + 9] = t; \
264 t ^= E_KEY[8 * i + 2]; E_KEY[8 * i + 10] = t; \
265 t ^= E_KEY[8 * i + 3]; E_KEY[8 * i + 11] = t; \
266 t = E_KEY[8 * i + 4] ^ ls_box(t); \
267 E_KEY[8 * i + 12] = t; \
268 t ^= E_KEY[8 * i + 5]; E_KEY[8 * i + 13] = t; \
269 t ^= E_KEY[8 * i + 6]; E_KEY[8 * i + 14] = t; \
270 t ^= E_KEY[8 * i + 7]; E_KEY[8 * i + 15] = t; \
271}
272
273static int
274aes_set_key(void *ctx_arg, const u8 *in_key, unsigned int key_len, u32 *flags)
275{
276 struct aes_ctx *ctx = ctx_arg;
277 u32 i, t, u, v, w;
278
279 if (key_len != 16 && key_len != 24 && key_len != 32) {
280 *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
281 return -EINVAL;
282 }
283
284 ctx->key_length = key_len;
285
286 E_KEY[0] = u32_in (in_key);
287 E_KEY[1] = u32_in (in_key + 4);
288 E_KEY[2] = u32_in (in_key + 8);
289 E_KEY[3] = u32_in (in_key + 12);
290
291 switch (key_len) {
292 case 16:
293 t = E_KEY[3];
294 for (i = 0; i < 10; ++i)
295 loop4 (i);
296 break;
297
298 case 24:
299 E_KEY[4] = u32_in (in_key + 16);
300 t = E_KEY[5] = u32_in (in_key + 20);
301 for (i = 0; i < 8; ++i)
302 loop6 (i);
303 break;
304
305 case 32:
306 E_KEY[4] = u32_in (in_key + 16);
307 E_KEY[5] = u32_in (in_key + 20);
308 E_KEY[6] = u32_in (in_key + 24);
309 t = E_KEY[7] = u32_in (in_key + 28);
310 for (i = 0; i < 7; ++i)
311 loop8 (i);
312 break;
313 }
314
315 D_KEY[0] = E_KEY[0];
316 D_KEY[1] = E_KEY[1];
317 D_KEY[2] = E_KEY[2];
318 D_KEY[3] = E_KEY[3];
319
320 for (i = 4; i < key_len + 24; ++i) {
321 imix_col (D_KEY[i], E_KEY[i]);
322 }
323
324 return 0;
325}
326
327/* encrypt a block of text */
328
329#define f_nround(bo, bi, k) \
330 f_rn(bo, bi, 0, k); \
331 f_rn(bo, bi, 1, k); \
332 f_rn(bo, bi, 2, k); \
333 f_rn(bo, bi, 3, k); \
334 k += 4
335
336#define f_lround(bo, bi, k) \
337 f_rl(bo, bi, 0, k); \
338 f_rl(bo, bi, 1, k); \
339 f_rl(bo, bi, 2, k); \
340 f_rl(bo, bi, 3, k)
341
342static void aes_encrypt(void *ctx_arg, u8 *out, const u8 *in)
343{
344 const struct aes_ctx *ctx = ctx_arg;
345 u32 b0[4], b1[4];
346 const u32 *kp = E_KEY + 4;
347
348 b0[0] = u32_in (in) ^ E_KEY[0];
349 b0[1] = u32_in (in + 4) ^ E_KEY[1];
350 b0[2] = u32_in (in + 8) ^ E_KEY[2];
351 b0[3] = u32_in (in + 12) ^ E_KEY[3];
352
353 if (ctx->key_length > 24) {
354 f_nround (b1, b0, kp);
355 f_nround (b0, b1, kp);
356 }
357
358 if (ctx->key_length > 16) {
359 f_nround (b1, b0, kp);
360 f_nround (b0, b1, kp);
361 }
362
363 f_nround (b1, b0, kp);
364 f_nround (b0, b1, kp);
365 f_nround (b1, b0, kp);
366 f_nround (b0, b1, kp);
367 f_nround (b1, b0, kp);
368 f_nround (b0, b1, kp);
369 f_nround (b1, b0, kp);
370 f_nround (b0, b1, kp);
371 f_nround (b1, b0, kp);
372 f_lround (b0, b1, kp);
373
374 u32_out (out, b0[0]);
375 u32_out (out + 4, b0[1]);
376 u32_out (out + 8, b0[2]);
377 u32_out (out + 12, b0[3]);
378}
379
380/* decrypt a block of text */
381
382#define i_nround(bo, bi, k) \
383 i_rn(bo, bi, 0, k); \
384 i_rn(bo, bi, 1, k); \
385 i_rn(bo, bi, 2, k); \
386 i_rn(bo, bi, 3, k); \
387 k -= 4
388
389#define i_lround(bo, bi, k) \
390 i_rl(bo, bi, 0, k); \
391 i_rl(bo, bi, 1, k); \
392 i_rl(bo, bi, 2, k); \
393 i_rl(bo, bi, 3, k)
394
395static void aes_decrypt(void *ctx_arg, u8 *out, const u8 *in)
396{
397 const struct aes_ctx *ctx = ctx_arg;
398 u32 b0[4], b1[4];
399 const int key_len = ctx->key_length;
400 const u32 *kp = D_KEY + key_len + 20;
401
402 b0[0] = u32_in (in) ^ E_KEY[key_len + 24];
403 b0[1] = u32_in (in + 4) ^ E_KEY[key_len + 25];
404 b0[2] = u32_in (in + 8) ^ E_KEY[key_len + 26];
405 b0[3] = u32_in (in + 12) ^ E_KEY[key_len + 27];
406
407 if (key_len > 24) {
408 i_nround (b1, b0, kp);
409 i_nround (b0, b1, kp);
410 }
411
412 if (key_len > 16) {
413 i_nround (b1, b0, kp);
414 i_nround (b0, b1, kp);
415 }
416
417 i_nround (b1, b0, kp);
418 i_nround (b0, b1, kp);
419 i_nround (b1, b0, kp);
420 i_nround (b0, b1, kp);
421 i_nround (b1, b0, kp);
422 i_nround (b0, b1, kp);
423 i_nround (b1, b0, kp);
424 i_nround (b0, b1, kp);
425 i_nround (b1, b0, kp);
426 i_lround (b0, b1, kp);
427
428 u32_out (out, b0[0]);
429 u32_out (out + 4, b0[1]);
430 u32_out (out + 8, b0[2]);
431 u32_out (out + 12, b0[3]);
432}
433
434
435static struct crypto_alg aes_alg = {
436 .cra_name = "aes",
437 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
438 .cra_blocksize = AES_BLOCK_SIZE,
439 .cra_ctxsize = sizeof(struct aes_ctx),
440 .cra_module = THIS_MODULE,
441 .cra_list = LIST_HEAD_INIT(aes_alg.cra_list),
442 .cra_u = {
443 .cipher = {
444 .cia_min_keysize = AES_MIN_KEY_SIZE,
445 .cia_max_keysize = AES_MAX_KEY_SIZE,
446 .cia_setkey = aes_set_key,
447 .cia_encrypt = aes_encrypt,
448 .cia_decrypt = aes_decrypt
449 }
450 }
451};
452
453static int __init aes_init(void)
454{
455 gen_tabs();
456 return crypto_register_alg(&aes_alg);
457}
458
459static void __exit aes_fini(void)
460{
461 crypto_unregister_alg(&aes_alg);
462}
463
464module_init(aes_init);
465module_exit(aes_fini);
466
467MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm");
468MODULE_LICENSE("Dual BSD/GPL");
469
diff --git a/drivers/staging/rtl8187se/ieee80211/api.c b/drivers/staging/rtl8187se/ieee80211/api.c
new file mode 100644
index 000000000000..c627d029528b
--- /dev/null
+++ b/drivers/staging/rtl8187se/ieee80211/api.c
@@ -0,0 +1,246 @@
1/*
2 * Scatterlist Cryptographic API.
3 *
4 * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
5 * Copyright (c) 2002 David S. Miller (davem@redhat.com)
6 *
7 * Portions derived from Cryptoapi, by Alexander Kjeldaas <astor@fast.no>
8 * and Nettle, by Niels Mé°ˆler.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the Free
12 * Software Foundation; either version 2 of the License, or (at your option)
13 * any later version.
14 *
15 */
16#include "kmap_types.h"
17
18#include <linux/init.h>
19#include <linux/module.h>
20//#include <linux/crypto.h>
21#include "rtl_crypto.h"
22#include <linux/errno.h>
23#include <linux/rwsem.h>
24#include <linux/slab.h>
25#include "internal.h"
26
27LIST_HEAD(crypto_alg_list);
28DECLARE_RWSEM(crypto_alg_sem);
29
30static inline int crypto_alg_get(struct crypto_alg *alg)
31{
32 return try_inc_mod_count(alg->cra_module);
33}
34
35static inline void crypto_alg_put(struct crypto_alg *alg)
36{
37 if (alg->cra_module)
38 __MOD_DEC_USE_COUNT(alg->cra_module);
39}
40
41struct crypto_alg *crypto_alg_lookup(const char *name)
42{
43 struct crypto_alg *q, *alg = NULL;
44
45 if (!name)
46 return NULL;
47
48 down_read(&crypto_alg_sem);
49
50 list_for_each_entry(q, &crypto_alg_list, cra_list) {
51 if (!(strcmp(q->cra_name, name))) {
52 if (crypto_alg_get(q))
53 alg = q;
54 break;
55 }
56 }
57
58 up_read(&crypto_alg_sem);
59 return alg;
60}
61
62static int crypto_init_flags(struct crypto_tfm *tfm, u32 flags)
63{
64 tfm->crt_flags = 0;
65
66 switch (crypto_tfm_alg_type(tfm)) {
67 case CRYPTO_ALG_TYPE_CIPHER:
68 return crypto_init_cipher_flags(tfm, flags);
69
70 case CRYPTO_ALG_TYPE_DIGEST:
71 return crypto_init_digest_flags(tfm, flags);
72
73 case CRYPTO_ALG_TYPE_COMPRESS:
74 return crypto_init_compress_flags(tfm, flags);
75
76 default:
77 break;
78 }
79
80 BUG();
81 return -EINVAL;
82}
83
84static int crypto_init_ops(struct crypto_tfm *tfm)
85{
86 switch (crypto_tfm_alg_type(tfm)) {
87 case CRYPTO_ALG_TYPE_CIPHER:
88 return crypto_init_cipher_ops(tfm);
89
90 case CRYPTO_ALG_TYPE_DIGEST:
91 return crypto_init_digest_ops(tfm);
92
93 case CRYPTO_ALG_TYPE_COMPRESS:
94 return crypto_init_compress_ops(tfm);
95
96 default:
97 break;
98 }
99
100 BUG();
101 return -EINVAL;
102}
103
104static void crypto_exit_ops(struct crypto_tfm *tfm)
105{
106 switch (crypto_tfm_alg_type(tfm)) {
107 case CRYPTO_ALG_TYPE_CIPHER:
108 crypto_exit_cipher_ops(tfm);
109 break;
110
111 case CRYPTO_ALG_TYPE_DIGEST:
112 crypto_exit_digest_ops(tfm);
113 break;
114
115 case CRYPTO_ALG_TYPE_COMPRESS:
116 crypto_exit_compress_ops(tfm);
117 break;
118
119 default:
120 BUG();
121
122 }
123}
124
125struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags)
126{
127 struct crypto_tfm *tfm = NULL;
128 struct crypto_alg *alg;
129
130 alg = crypto_alg_mod_lookup(name);
131 if (alg == NULL)
132 goto out;
133
134 tfm = kmalloc(sizeof(*tfm) + alg->cra_ctxsize, GFP_KERNEL);
135 if (tfm == NULL)
136 goto out_put;
137
138 memset(tfm, 0, sizeof(*tfm) + alg->cra_ctxsize);
139
140 tfm->__crt_alg = alg;
141
142 if (crypto_init_flags(tfm, flags))
143 goto out_free_tfm;
144
145 if (crypto_init_ops(tfm)) {
146 crypto_exit_ops(tfm);
147 goto out_free_tfm;
148 }
149
150 goto out;
151
152out_free_tfm:
153 kfree(tfm);
154 tfm = NULL;
155out_put:
156 crypto_alg_put(alg);
157out:
158 return tfm;
159}
160
161void crypto_free_tfm(struct crypto_tfm *tfm)
162{
163 struct crypto_alg *alg = tfm->__crt_alg;
164 int size = sizeof(*tfm) + alg->cra_ctxsize;
165
166 crypto_exit_ops(tfm);
167 crypto_alg_put(alg);
168 memset(tfm, 0, size);
169 kfree(tfm);
170}
171
172int crypto_register_alg(struct crypto_alg *alg)
173{
174 int ret = 0;
175 struct crypto_alg *q;
176
177 down_write(&crypto_alg_sem);
178
179 list_for_each_entry(q, &crypto_alg_list, cra_list) {
180 if (!(strcmp(q->cra_name, alg->cra_name))) {
181 ret = -EEXIST;
182 goto out;
183 }
184 }
185
186 list_add_tail(&alg->cra_list, &crypto_alg_list);
187out:
188 up_write(&crypto_alg_sem);
189 return ret;
190}
191
192int crypto_unregister_alg(struct crypto_alg *alg)
193{
194 int ret = -ENOENT;
195 struct crypto_alg *q;
196
197 BUG_ON(!alg->cra_module);
198
199 down_write(&crypto_alg_sem);
200 list_for_each_entry(q, &crypto_alg_list, cra_list) {
201 if (alg == q) {
202 list_del(&alg->cra_list);
203 ret = 0;
204 goto out;
205 }
206 }
207out:
208 up_write(&crypto_alg_sem);
209 return ret;
210}
211
212int crypto_alg_available(const char *name, u32 flags)
213{
214 int ret = 0;
215 struct crypto_alg *alg = crypto_alg_mod_lookup(name);
216
217 if (alg) {
218 crypto_alg_put(alg);
219 ret = 1;
220 }
221
222 return ret;
223}
224
225static int __init init_crypto(void)
226{
227 printk(KERN_INFO "Initializing Cryptographic API\n");
228 crypto_init_proc();
229 return 0;
230}
231
232__initcall(init_crypto);
233
234/*
235EXPORT_SYMBOL_GPL(crypto_register_alg);
236EXPORT_SYMBOL_GPL(crypto_unregister_alg);
237EXPORT_SYMBOL_GPL(crypto_alloc_tfm);
238EXPORT_SYMBOL_GPL(crypto_free_tfm);
239EXPORT_SYMBOL_GPL(crypto_alg_available);
240*/
241
242EXPORT_SYMBOL_NOVERS(crypto_register_alg);
243EXPORT_SYMBOL_NOVERS(crypto_unregister_alg);
244EXPORT_SYMBOL_NOVERS(crypto_alloc_tfm);
245EXPORT_SYMBOL_NOVERS(crypto_free_tfm);
246EXPORT_SYMBOL_NOVERS(crypto_alg_available);
diff --git a/drivers/staging/rtl8187se/ieee80211/arc4.c b/drivers/staging/rtl8187se/ieee80211/arc4.c
new file mode 100644
index 000000000000..654f0e90af8e
--- /dev/null
+++ b/drivers/staging/rtl8187se/ieee80211/arc4.c
@@ -0,0 +1,103 @@
1/*
2 * Cryptographic API
3 *
4 * ARC4 Cipher Algorithm
5 *
6 * Jon Oberheide <jon@oberheide.org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 */
14#include <linux/module.h>
15#include <linux/init.h>
16#include "rtl_crypto.h"
17
18#define ARC4_MIN_KEY_SIZE 1
19#define ARC4_MAX_KEY_SIZE 256
20#define ARC4_BLOCK_SIZE 1
21
22struct arc4_ctx {
23 u8 S[256];
24 u8 x, y;
25};
26
27static int arc4_set_key(void *ctx_arg, const u8 *in_key, unsigned int key_len, u32 *flags)
28{
29 struct arc4_ctx *ctx = ctx_arg;
30 int i, j = 0, k = 0;
31
32 ctx->x = 1;
33 ctx->y = 0;
34
35 for(i = 0; i < 256; i++)
36 ctx->S[i] = i;
37
38 for(i = 0; i < 256; i++)
39 {
40 u8 a = ctx->S[i];
41 j = (j + in_key[k] + a) & 0xff;
42 ctx->S[i] = ctx->S[j];
43 ctx->S[j] = a;
44 if(++k >= key_len)
45 k = 0;
46 }
47
48 return 0;
49}
50
51static void arc4_crypt(void *ctx_arg, u8 *out, const u8 *in)
52{
53 struct arc4_ctx *ctx = ctx_arg;
54
55 u8 *const S = ctx->S;
56 u8 x = ctx->x;
57 u8 y = ctx->y;
58 u8 a, b;
59
60 a = S[x];
61 y = (y + a) & 0xff;
62 b = S[y];
63 S[x] = b;
64 S[y] = a;
65 x = (x + 1) & 0xff;
66 *out++ = *in ^ S[(a + b) & 0xff];
67
68 ctx->x = x;
69 ctx->y = y;
70}
71
72static struct crypto_alg arc4_alg = {
73 .cra_name = "arc4",
74 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
75 .cra_blocksize = ARC4_BLOCK_SIZE,
76 .cra_ctxsize = sizeof(struct arc4_ctx),
77 .cra_module = THIS_MODULE,
78 .cra_list = LIST_HEAD_INIT(arc4_alg.cra_list),
79 .cra_u = { .cipher = {
80 .cia_min_keysize = ARC4_MIN_KEY_SIZE,
81 .cia_max_keysize = ARC4_MAX_KEY_SIZE,
82 .cia_setkey = arc4_set_key,
83 .cia_encrypt = arc4_crypt,
84 .cia_decrypt = arc4_crypt } }
85};
86
87static int __init arc4_init(void)
88{
89 return crypto_register_alg(&arc4_alg);
90}
91
92
93static void __exit arc4_exit(void)
94{
95 crypto_unregister_alg(&arc4_alg);
96}
97
98module_init(arc4_init);
99module_exit(arc4_exit);
100
101MODULE_LICENSE("GPL");
102MODULE_DESCRIPTION("ARC4 Cipher Algorithm");
103MODULE_AUTHOR("Jon Oberheide <jon@oberheide.org>");
diff --git a/drivers/staging/rtl8187se/ieee80211/autoload.c b/drivers/staging/rtl8187se/ieee80211/autoload.c
new file mode 100644
index 000000000000..c97756f3b2ea
--- /dev/null
+++ b/drivers/staging/rtl8187se/ieee80211/autoload.c
@@ -0,0 +1,40 @@
1/*
2 * Cryptographic API.
3 *
4 * Algorithm autoloader.
5 *
6 * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 *
13 */
14#include "kmap_types.h"
15
16#include <linux/kernel.h>
17//#include <linux/crypto.h>
18#include "rtl_crypto.h"
19#include <linux/string.h>
20#include <linux/kmod.h>
21#include "internal.h"
22
23/*
24 * A far more intelligent version of this is planned. For now, just
25 * try an exact match on the name of the algorithm.
26 */
27void crypto_alg_autoload(const char *name)
28{
29 request_module(name);
30}
31
32struct crypto_alg *crypto_alg_mod_lookup(const char *name)
33{
34 struct crypto_alg *alg = crypto_alg_lookup(name);
35 if (alg == NULL) {
36 crypto_alg_autoload(name);
37 alg = crypto_alg_lookup(name);
38 }
39 return alg;
40}
diff --git a/drivers/staging/rtl8187se/ieee80211/cipher.c b/drivers/staging/rtl8187se/ieee80211/cipher.c
new file mode 100644
index 000000000000..1968acfe32b1
--- /dev/null
+++ b/drivers/staging/rtl8187se/ieee80211/cipher.c
@@ -0,0 +1,299 @@
1/*
2 * Cryptographic API.
3 *
4 * Cipher operations.
5 *
6 * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 *
13 */
14#include <linux/kernel.h>
15//#include <linux/crypto.h>
16#include "rtl_crypto.h"
17#include <linux/errno.h>
18#include <linux/mm.h>
19#include <linux/slab.h>
20#include <asm/scatterlist.h>
21#include "internal.h"
22#include "scatterwalk.h"
23
24typedef void (cryptfn_t)(void *, u8 *, const u8 *);
25typedef void (procfn_t)(struct crypto_tfm *, u8 *,
26 u8*, cryptfn_t, int enc, void *, int);
27
28static inline void xor_64(u8 *a, const u8 *b)
29{
30 ((u32 *)a)[0] ^= ((u32 *)b)[0];
31 ((u32 *)a)[1] ^= ((u32 *)b)[1];
32}
33
34static inline void xor_128(u8 *a, const u8 *b)
35{
36 ((u32 *)a)[0] ^= ((u32 *)b)[0];
37 ((u32 *)a)[1] ^= ((u32 *)b)[1];
38 ((u32 *)a)[2] ^= ((u32 *)b)[2];
39 ((u32 *)a)[3] ^= ((u32 *)b)[3];
40}
41
42
43/*
44 * Generic encrypt/decrypt wrapper for ciphers, handles operations across
45 * multiple page boundaries by using temporary blocks. In user context,
46 * the kernel is given a chance to schedule us once per block.
47 */
48static int crypt(struct crypto_tfm *tfm,
49 struct scatterlist *dst,
50 struct scatterlist *src,
51 unsigned int nbytes, cryptfn_t crfn,
52 procfn_t prfn, int enc, void *info)
53{
54 struct scatter_walk walk_in, walk_out;
55 const unsigned int bsize = crypto_tfm_alg_blocksize(tfm);
56 u8 tmp_src[bsize];
57 u8 tmp_dst[bsize];
58
59 if (!nbytes)
60 return 0;
61
62 if (nbytes % bsize) {
63 tfm->crt_flags |= CRYPTO_TFM_RES_BAD_BLOCK_LEN;
64 return -EINVAL;
65 }
66
67 scatterwalk_start(&walk_in, src);
68 scatterwalk_start(&walk_out, dst);
69
70 for(;;) {
71 u8 *src_p, *dst_p;
72 int in_place;
73
74 scatterwalk_map(&walk_in, 0);
75 scatterwalk_map(&walk_out, 1);
76 src_p = scatterwalk_whichbuf(&walk_in, bsize, tmp_src);
77 dst_p = scatterwalk_whichbuf(&walk_out, bsize, tmp_dst);
78 in_place = scatterwalk_samebuf(&walk_in, &walk_out,
79 src_p, dst_p);
80
81 nbytes -= bsize;
82
83 scatterwalk_copychunks(src_p, &walk_in, bsize, 0);
84
85 prfn(tfm, dst_p, src_p, crfn, enc, info, in_place);
86
87 scatterwalk_done(&walk_in, 0, nbytes);
88
89 scatterwalk_copychunks(dst_p, &walk_out, bsize, 1);
90 scatterwalk_done(&walk_out, 1, nbytes);
91
92 if (!nbytes)
93 return 0;
94
95 crypto_yield(tfm);
96 }
97}
98
99static void cbc_process(struct crypto_tfm *tfm, u8 *dst, u8 *src,
100 cryptfn_t fn, int enc, void *info, int in_place)
101{
102 u8 *iv = info;
103
104 /* Null encryption */
105 if (!iv)
106 return;
107
108 if (enc) {
109 tfm->crt_u.cipher.cit_xor_block(iv, src);
110 fn(crypto_tfm_ctx(tfm), dst, iv);
111 memcpy(iv, dst, crypto_tfm_alg_blocksize(tfm));
112 } else {
113 u8 stack[in_place ? crypto_tfm_alg_blocksize(tfm) : 0];
114 u8 *buf = in_place ? stack : dst;
115
116 fn(crypto_tfm_ctx(tfm), buf, src);
117 tfm->crt_u.cipher.cit_xor_block(buf, iv);
118 memcpy(iv, src, crypto_tfm_alg_blocksize(tfm));
119 if (buf != dst)
120 memcpy(dst, buf, crypto_tfm_alg_blocksize(tfm));
121 }
122}
123
124static void ecb_process(struct crypto_tfm *tfm, u8 *dst, u8 *src,
125 cryptfn_t fn, int enc, void *info, int in_place)
126{
127 fn(crypto_tfm_ctx(tfm), dst, src);
128}
129
130static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
131{
132 struct cipher_alg *cia = &tfm->__crt_alg->cra_cipher;
133
134 if (keylen < cia->cia_min_keysize || keylen > cia->cia_max_keysize) {
135 tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
136 return -EINVAL;
137 } else
138 return cia->cia_setkey(crypto_tfm_ctx(tfm), key, keylen,
139 &tfm->crt_flags);
140}
141
142static int ecb_encrypt(struct crypto_tfm *tfm,
143 struct scatterlist *dst,
144 struct scatterlist *src, unsigned int nbytes)
145{
146 return crypt(tfm, dst, src, nbytes,
147 tfm->__crt_alg->cra_cipher.cia_encrypt,
148 ecb_process, 1, NULL);
149}
150
151static int ecb_decrypt(struct crypto_tfm *tfm,
152 struct scatterlist *dst,
153 struct scatterlist *src,
154 unsigned int nbytes)
155{
156 return crypt(tfm, dst, src, nbytes,
157 tfm->__crt_alg->cra_cipher.cia_decrypt,
158 ecb_process, 1, NULL);
159}
160
161static int cbc_encrypt(struct crypto_tfm *tfm,
162 struct scatterlist *dst,
163 struct scatterlist *src,
164 unsigned int nbytes)
165{
166 return crypt(tfm, dst, src, nbytes,
167 tfm->__crt_alg->cra_cipher.cia_encrypt,
168 cbc_process, 1, tfm->crt_cipher.cit_iv);
169}
170
171static int cbc_encrypt_iv(struct crypto_tfm *tfm,
172 struct scatterlist *dst,
173 struct scatterlist *src,
174 unsigned int nbytes, u8 *iv)
175{
176 return crypt(tfm, dst, src, nbytes,
177 tfm->__crt_alg->cra_cipher.cia_encrypt,
178 cbc_process, 1, iv);
179}
180
181static int cbc_decrypt(struct crypto_tfm *tfm,
182 struct scatterlist *dst,
183 struct scatterlist *src,
184 unsigned int nbytes)
185{
186 return crypt(tfm, dst, src, nbytes,
187 tfm->__crt_alg->cra_cipher.cia_decrypt,
188 cbc_process, 0, tfm->crt_cipher.cit_iv);
189}
190
191static int cbc_decrypt_iv(struct crypto_tfm *tfm,
192 struct scatterlist *dst,
193 struct scatterlist *src,
194 unsigned int nbytes, u8 *iv)
195{
196 return crypt(tfm, dst, src, nbytes,
197 tfm->__crt_alg->cra_cipher.cia_decrypt,
198 cbc_process, 0, iv);
199}
200
201static int nocrypt(struct crypto_tfm *tfm,
202 struct scatterlist *dst,
203 struct scatterlist *src,
204 unsigned int nbytes)
205{
206 return -ENOSYS;
207}
208
209static int nocrypt_iv(struct crypto_tfm *tfm,
210 struct scatterlist *dst,
211 struct scatterlist *src,
212 unsigned int nbytes, u8 *iv)
213{
214 return -ENOSYS;
215}
216
217int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags)
218{
219 u32 mode = flags & CRYPTO_TFM_MODE_MASK;
220
221 tfm->crt_cipher.cit_mode = mode ? mode : CRYPTO_TFM_MODE_ECB;
222 if (flags & CRYPTO_TFM_REQ_WEAK_KEY)
223 tfm->crt_flags = CRYPTO_TFM_REQ_WEAK_KEY;
224
225 return 0;
226}
227
228int crypto_init_cipher_ops(struct crypto_tfm *tfm)
229{
230 int ret = 0;
231 struct cipher_tfm *ops = &tfm->crt_cipher;
232
233 ops->cit_setkey = setkey;
234
235 switch (tfm->crt_cipher.cit_mode) {
236 case CRYPTO_TFM_MODE_ECB:
237 ops->cit_encrypt = ecb_encrypt;
238 ops->cit_decrypt = ecb_decrypt;
239 break;
240
241 case CRYPTO_TFM_MODE_CBC:
242 ops->cit_encrypt = cbc_encrypt;
243 ops->cit_decrypt = cbc_decrypt;
244 ops->cit_encrypt_iv = cbc_encrypt_iv;
245 ops->cit_decrypt_iv = cbc_decrypt_iv;
246 break;
247
248 case CRYPTO_TFM_MODE_CFB:
249 ops->cit_encrypt = nocrypt;
250 ops->cit_decrypt = nocrypt;
251 ops->cit_encrypt_iv = nocrypt_iv;
252 ops->cit_decrypt_iv = nocrypt_iv;
253 break;
254
255 case CRYPTO_TFM_MODE_CTR:
256 ops->cit_encrypt = nocrypt;
257 ops->cit_decrypt = nocrypt;
258 ops->cit_encrypt_iv = nocrypt_iv;
259 ops->cit_decrypt_iv = nocrypt_iv;
260 break;
261
262 default:
263 BUG();
264 }
265
266 if (ops->cit_mode == CRYPTO_TFM_MODE_CBC) {
267
268 switch (crypto_tfm_alg_blocksize(tfm)) {
269 case 8:
270 ops->cit_xor_block = xor_64;
271 break;
272
273 case 16:
274 ops->cit_xor_block = xor_128;
275 break;
276
277 default:
278 printk(KERN_WARNING "%s: block size %u not supported\n",
279 crypto_tfm_alg_name(tfm),
280 crypto_tfm_alg_blocksize(tfm));
281 ret = -EINVAL;
282 goto out;
283 }
284
285 ops->cit_ivsize = crypto_tfm_alg_blocksize(tfm);
286 ops->cit_iv = kmalloc(ops->cit_ivsize, GFP_KERNEL);
287 if (ops->cit_iv == NULL)
288 ret = -ENOMEM;
289 }
290
291out:
292 return ret;
293}
294
295void crypto_exit_cipher_ops(struct crypto_tfm *tfm)
296{
297 if (tfm->crt_cipher.cit_iv)
298 kfree(tfm->crt_cipher.cit_iv);
299}
diff --git a/drivers/staging/rtl8187se/ieee80211/compress.c b/drivers/staging/rtl8187se/ieee80211/compress.c
new file mode 100644
index 000000000000..c2df80e2ed9d
--- /dev/null
+++ b/drivers/staging/rtl8187se/ieee80211/compress.c
@@ -0,0 +1,64 @@
1/*
2 * Cryptographic API.
3 *
4 * Compression operations.
5 *
6 * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 *
13 */
14#include <linux/types.h>
15//#include <linux/crypto.h>
16#include "rtl_crypto.h"
17#include <linux/errno.h>
18#include <asm/scatterlist.h>
19#include <linux/string.h>
20#include "internal.h"
21
22static int crypto_compress(struct crypto_tfm *tfm,
23 const u8 *src, unsigned int slen,
24 u8 *dst, unsigned int *dlen)
25{
26 return tfm->__crt_alg->cra_compress.coa_compress(crypto_tfm_ctx(tfm),
27 src, slen, dst,
28 dlen);
29}
30
31static int crypto_decompress(struct crypto_tfm *tfm,
32 const u8 *src, unsigned int slen,
33 u8 *dst, unsigned int *dlen)
34{
35 return tfm->__crt_alg->cra_compress.coa_decompress(crypto_tfm_ctx(tfm),
36 src, slen, dst,
37 dlen);
38}
39
40int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags)
41{
42 return flags ? -EINVAL : 0;
43}
44
45int crypto_init_compress_ops(struct crypto_tfm *tfm)
46{
47 int ret = 0;
48 struct compress_tfm *ops = &tfm->crt_compress;
49
50 ret = tfm->__crt_alg->cra_compress.coa_init(crypto_tfm_ctx(tfm));
51 if (ret)
52 goto out;
53
54 ops->cot_compress = crypto_compress;
55 ops->cot_decompress = crypto_decompress;
56
57out:
58 return ret;
59}
60
61void crypto_exit_compress_ops(struct crypto_tfm *tfm)
62{
63 tfm->__crt_alg->cra_compress.coa_exit(crypto_tfm_ctx(tfm));
64}
diff --git a/drivers/staging/rtl8187se/ieee80211/digest.c b/drivers/staging/rtl8187se/ieee80211/digest.c
new file mode 100644
index 000000000000..1a95f2d37837
--- /dev/null
+++ b/drivers/staging/rtl8187se/ieee80211/digest.c
@@ -0,0 +1,108 @@
1/*
2 * Cryptographic API.
3 *
4 * Digest operations.
5 *
6 * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 *
13 */
14//#include <linux/crypto.h>
15#include "rtl_crypto.h"
16#include <linux/mm.h>
17#include <linux/errno.h>
18#include <linux/highmem.h>
19#include <asm/scatterlist.h>
20#include "internal.h"
21
22static void init(struct crypto_tfm *tfm)
23{
24 tfm->__crt_alg->cra_digest.dia_init(crypto_tfm_ctx(tfm));
25}
26
27static void update(struct crypto_tfm *tfm,
28 struct scatterlist *sg, unsigned int nsg)
29{
30 unsigned int i;
31
32 for (i = 0; i < nsg; i++) {
33
34 struct page *pg = sg[i].page;
35 unsigned int offset = sg[i].offset;
36 unsigned int l = sg[i].length;
37
38 do {
39 unsigned int bytes_from_page = min(l, ((unsigned int)
40 (PAGE_SIZE)) -
41 offset);
42 char *p = crypto_kmap(pg, 0) + offset;
43
44 tfm->__crt_alg->cra_digest.dia_update
45 (crypto_tfm_ctx(tfm), p,
46 bytes_from_page);
47 crypto_kunmap(p, 0);
48 crypto_yield(tfm);
49 offset = 0;
50 pg++;
51 l -= bytes_from_page;
52 } while (l > 0);
53 }
54}
55
56static void final(struct crypto_tfm *tfm, u8 *out)
57{
58 tfm->__crt_alg->cra_digest.dia_final(crypto_tfm_ctx(tfm), out);
59}
60
61static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
62{
63 u32 flags;
64 if (tfm->__crt_alg->cra_digest.dia_setkey == NULL)
65 return -ENOSYS;
66 return tfm->__crt_alg->cra_digest.dia_setkey(crypto_tfm_ctx(tfm),
67 key, keylen, &flags);
68}
69
70static void digest(struct crypto_tfm *tfm,
71 struct scatterlist *sg, unsigned int nsg, u8 *out)
72{
73 unsigned int i;
74
75 tfm->crt_digest.dit_init(tfm);
76
77 for (i = 0; i < nsg; i++) {
78 char *p = crypto_kmap(sg[i].page, 0) + sg[i].offset;
79 tfm->__crt_alg->cra_digest.dia_update(crypto_tfm_ctx(tfm),
80 p, sg[i].length);
81 crypto_kunmap(p, 0);
82 crypto_yield(tfm);
83 }
84 crypto_digest_final(tfm, out);
85}
86
87int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags)
88{
89 return flags ? -EINVAL : 0;
90}
91
92int crypto_init_digest_ops(struct crypto_tfm *tfm)
93{
94 struct digest_tfm *ops = &tfm->crt_digest;
95
96 ops->dit_init = init;
97 ops->dit_update = update;
98 ops->dit_final = final;
99 ops->dit_digest = digest;
100 ops->dit_setkey = setkey;
101
102 return crypto_alloc_hmac_block(tfm);
103}
104
105void crypto_exit_digest_ops(struct crypto_tfm *tfm)
106{
107 crypto_free_hmac_block(tfm);
108}
diff --git a/drivers/staging/rtl8187se/ieee80211/dot11d.c b/drivers/staging/rtl8187se/ieee80211/dot11d.c
new file mode 100644
index 000000000000..5d8b752fc0fb
--- /dev/null
+++ b/drivers/staging/rtl8187se/ieee80211/dot11d.c
@@ -0,0 +1,246 @@
1#ifdef ENABLE_DOT11D
2//-----------------------------------------------------------------------------
3// File:
4// Dot11d.c
5//
6// Description:
7// Implement 802.11d.
8//
9//-----------------------------------------------------------------------------
10
11#include "dot11d.h"
12
13void
14Dot11d_Init(struct ieee80211_device *ieee)
15{
16 PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);
17
18 pDot11dInfo->bEnabled = 0;
19
20 pDot11dInfo->State = DOT11D_STATE_NONE;
21 pDot11dInfo->CountryIeLen = 0;
22 memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
23 memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
24 RESET_CIE_WATCHDOG(ieee);
25
26 printk("Dot11d_Init()\n");
27}
28
29//
30// Description:
31// Reset to the state as we are just entering a regulatory domain.
32//
33void
34Dot11d_Reset(struct ieee80211_device *ieee)
35{
36 u32 i;
37 PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);
38
39 // Clear old channel map
40 memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
41 memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
42 // Set new channel map
43 for (i=1; i<=11; i++) {
44 (pDot11dInfo->channel_map)[i] = 1;
45 }
46 for (i=12; i<=14; i++) {
47 (pDot11dInfo->channel_map)[i] = 2;
48 }
49
50 pDot11dInfo->State = DOT11D_STATE_NONE;
51 pDot11dInfo->CountryIeLen = 0;
52 RESET_CIE_WATCHDOG(ieee);
53
54 //printk("Dot11d_Reset()\n");
55}
56
57//
58// Description:
59// Update country IE from Beacon or Probe Resopnse
60// and configure PHY for operation in the regulatory domain.
61//
62// TODO:
63// Configure Tx power.
64//
65// Assumption:
66// 1. IS_DOT11D_ENABLE() is TRUE.
67// 2. Input IE is an valid one.
68//
69void
70Dot11d_UpdateCountryIe(
71 struct ieee80211_device *dev,
72 u8 * pTaddr,
73 u16 CoutryIeLen,
74 u8 * pCoutryIe
75 )
76{
77 PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
78 u8 i, j, NumTriples, MaxChnlNum;
79 PCHNL_TXPOWER_TRIPLE pTriple;
80
81 if((CoutryIeLen - 3)%3 != 0)
82 {
83 printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
84 Dot11d_Reset(dev);
85 return;
86 }
87
88 memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
89 memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
90 MaxChnlNum = 0;
91 NumTriples = (CoutryIeLen - 3) / 3; // skip 3-byte country string.
92 pTriple = (PCHNL_TXPOWER_TRIPLE)(pCoutryIe + 3);
93 for(i = 0; i < NumTriples; i++)
94 {
95 if(MaxChnlNum >= pTriple->FirstChnl)
96 { // It is not in a monotonically increasing order, so stop processing.
97 printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
98 Dot11d_Reset(dev);
99 return;
100 }
101 if(MAX_CHANNEL_NUMBER < (pTriple->FirstChnl + pTriple->NumChnls))
102 { // It is not a valid set of channel id, so stop processing.
103 printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........2\n");
104 Dot11d_Reset(dev);
105 return;
106 }
107
108 for(j = 0 ; j < pTriple->NumChnls; j++)
109 {
110 pDot11dInfo->channel_map[pTriple->FirstChnl + j] = 1;
111 pDot11dInfo->MaxTxPwrDbmList[pTriple->FirstChnl + j] = pTriple->MaxTxPowerInDbm;
112 MaxChnlNum = pTriple->FirstChnl + j;
113 }
114
115 pTriple = (PCHNL_TXPOWER_TRIPLE)((u8*)pTriple + 3);
116 }
117#if 1
118 //printk("Dot11d_UpdateCountryIe(): Channel List:\n");
119 printk("Channel List:");
120 for(i=1; i<= MAX_CHANNEL_NUMBER; i++)
121 if(pDot11dInfo->channel_map[i] > 0)
122 printk(" %d", i);
123 printk("\n");
124#endif
125
126 UPDATE_CIE_SRC(dev, pTaddr);
127
128 pDot11dInfo->CountryIeLen = CoutryIeLen;
129 memcpy(pDot11dInfo->CountryIeBuf, pCoutryIe,CoutryIeLen);
130 pDot11dInfo->State = DOT11D_STATE_LEARNED;
131}
132
133void dump_chnl_map(u8 * channel_map)
134{
135 int i;
136 printk("Channel List:");
137 for(i=1; i<= MAX_CHANNEL_NUMBER; i++)
138 if(channel_map[i] > 0)
139 printk(" %d(%d)", i, channel_map[i]);
140 printk("\n");
141}
142
143u8
144DOT11D_GetMaxTxPwrInDbm(
145 struct ieee80211_device *dev,
146 u8 Channel
147 )
148{
149 PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
150 u8 MaxTxPwrInDbm = 255;
151
152 if(MAX_CHANNEL_NUMBER < Channel)
153 {
154 printk("DOT11D_GetMaxTxPwrInDbm(): Invalid Channel\n");
155 return MaxTxPwrInDbm;
156 }
157 if(pDot11dInfo->channel_map[Channel])
158 {
159 MaxTxPwrInDbm = pDot11dInfo->MaxTxPwrDbmList[Channel];
160 }
161
162 return MaxTxPwrInDbm;
163}
164
165
166void
167DOT11D_ScanComplete(
168 struct ieee80211_device * dev
169 )
170{
171 PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
172
173 switch(pDot11dInfo->State)
174 {
175 case DOT11D_STATE_LEARNED:
176 pDot11dInfo->State = DOT11D_STATE_DONE;
177 break;
178
179 case DOT11D_STATE_DONE:
180 if( GET_CIE_WATCHDOG(dev) == 0 )
181 { // Reset country IE if previous one is gone.
182 Dot11d_Reset(dev);
183 }
184 break;
185 case DOT11D_STATE_NONE:
186 break;
187 }
188}
189
190int IsLegalChannel(
191 struct ieee80211_device * dev,
192 u8 channel
193)
194{
195 PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
196
197 if(MAX_CHANNEL_NUMBER < channel)
198 {
199 printk("IsLegalChannel(): Invalid Channel\n");
200 return 0;
201 }
202 if(pDot11dInfo->channel_map[channel] > 0)
203 return 1;
204 return 0;
205}
206
207int ToLegalChannel(
208 struct ieee80211_device * dev,
209 u8 channel
210)
211{
212 PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
213 u8 default_chn = 0;
214 u32 i = 0;
215
216 for (i=1; i<= MAX_CHANNEL_NUMBER; i++)
217 {
218 if(pDot11dInfo->channel_map[i] > 0)
219 {
220 default_chn = i;
221 break;
222 }
223 }
224
225 if(MAX_CHANNEL_NUMBER < channel)
226 {
227 printk("IsLegalChannel(): Invalid Channel\n");
228 return default_chn;
229 }
230
231 if(pDot11dInfo->channel_map[channel] > 0)
232 return channel;
233
234 return default_chn;
235}
236
237#if 0
238EXPORT_SYMBOL(Dot11d_Init);
239EXPORT_SYMBOL(Dot11d_Reset);
240EXPORT_SYMBOL(Dot11d_UpdateCountryIe);
241EXPORT_SYMBOL(DOT11D_GetMaxTxPwrInDbm);
242EXPORT_SYMBOL(DOT11D_ScanComplete);
243EXPORT_SYMBOL(IsLegalChannel);
244EXPORT_SYMBOL(ToLegalChannel);
245#endif
246#endif
diff --git a/drivers/staging/rtl8187se/ieee80211/dot11d.h b/drivers/staging/rtl8187se/ieee80211/dot11d.h
new file mode 100644
index 000000000000..64bcf15bd219
--- /dev/null
+++ b/drivers/staging/rtl8187se/ieee80211/dot11d.h
@@ -0,0 +1,102 @@
1#ifndef __INC_DOT11D_H
2#define __INC_DOT11D_H
3
4#include "ieee80211.h"
5
6//#define ENABLE_DOT11D
7
8//#define DOT11D_MAX_CHNL_NUM 83
9
10typedef struct _CHNL_TXPOWER_TRIPLE {
11 u8 FirstChnl;
12 u8 NumChnls;
13 u8 MaxTxPowerInDbm;
14}CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;
15
16typedef enum _DOT11D_STATE {
17 DOT11D_STATE_NONE = 0,
18 DOT11D_STATE_LEARNED,
19 DOT11D_STATE_DONE,
20}DOT11D_STATE;
21
22typedef struct _RT_DOT11D_INFO {
23 //DECLARE_RT_OBJECT(RT_DOT11D_INFO);
24
25 bool bEnabled; // dot11MultiDomainCapabilityEnabled
26
27 u16 CountryIeLen; // > 0 if CountryIeBuf[] contains valid country information element.
28 u8 CountryIeBuf[MAX_IE_LEN];
29 u8 CountryIeSrcAddr[6]; // Source AP of the country IE.
30 u8 CountryIeWatchdog;
31
32 u8 channel_map[MAX_CHANNEL_NUMBER+1]; //!!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan)
33 //u8 ChnlListLen; // #Bytes valid in ChnlList[].
34 //u8 ChnlList[DOT11D_MAX_CHNL_NUM];
35 u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];
36
37 DOT11D_STATE State;
38}RT_DOT11D_INFO, *PRT_DOT11D_INFO;
39#define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 )
40#define cpMacAddr(des,src) ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3],(des)[4]=(src)[4],(des)[5]=(src)[5])
41#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo))
42
43#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled
44#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0)
45
46#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
47#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
48
49#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \
50 (((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \
51 FALSE : \
52 (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length)))
53
54#define CIE_WATCHDOG_TH 1
55#define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog
56#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0
57#define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev)
58
59#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)
60
61
62void
63Dot11d_Init(
64 struct ieee80211_device *dev
65 );
66
67void
68Dot11d_Reset(
69 struct ieee80211_device *dev
70 );
71
72void
73Dot11d_UpdateCountryIe(
74 struct ieee80211_device *dev,
75 u8 * pTaddr,
76 u16 CoutryIeLen,
77 u8 * pCoutryIe
78 );
79
80u8
81DOT11D_GetMaxTxPwrInDbm(
82 struct ieee80211_device *dev,
83 u8 Channel
84 );
85
86void
87DOT11D_ScanComplete(
88 struct ieee80211_device * dev
89 );
90
91int IsLegalChannel(
92 struct ieee80211_device * dev,
93 u8 channel
94);
95
96int ToLegalChannel(
97 struct ieee80211_device * dev,
98 u8 channel
99);
100
101void dump_chnl_map(u8 * channel_map);
102#endif // #ifndef __INC_DOT11D_H
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211.h b/drivers/staging/rtl8187se/ieee80211/ieee80211.h
new file mode 100644
index 000000000000..bf06abeeaeb8
--- /dev/null
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211.h
@@ -0,0 +1,1755 @@
1/*
2 * Merged with mainline ieee80211.h in Aug 2004. Original ieee802_11
3 * remains copyright by the original authors
4 *
5 * Portions of the merged code are based on Host AP (software wireless
6 * LAN access point) driver for Intersil Prism2/2.5/3.
7 *
8 * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
9 * <jkmaline@cc.hut.fi>
10 * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
11 *
12 * Adaption to a generic IEEE 802.11 stack by James Ketrenos
13 * <jketreno@linux.intel.com>
14 * Copyright (c) 2004, Intel Corporation
15 *
16 * Modified for Realtek's wi-fi cards by Andrea Merello
17 * <andreamrl@tiscali.it>
18 *
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License version 2 as
21 * published by the Free Software Foundation. See README and COPYING for
22 * more details.
23 */
24#ifndef IEEE80211_H
25#define IEEE80211_H
26#include <linux/if_ether.h> /* ETH_ALEN */
27#include <linux/kernel.h> /* ARRAY_SIZE */
28#include <linux/version.h>
29#include <linux/jiffies.h>
30#include <linux/timer.h>
31#include <linux/sched.h>
32
33#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13))
34#include <linux/wireless.h>
35#endif
36
37/*
38#ifndef bool
39#define bool int
40#endif
41
42#ifndef true
43#define true 1
44#endif
45
46#ifndef false
47#define false 0
48#endif
49*/
50#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
51#ifndef bool
52typedef enum{false = 0, true} bool;
53#endif
54#endif
55//#ifdef JOHN_HWSEC
56#define KEY_TYPE_NA 0x0
57#define KEY_TYPE_WEP40 0x1
58#define KEY_TYPE_TKIP 0x2
59#define KEY_TYPE_CCMP 0x4
60#define KEY_TYPE_WEP104 0x5
61//#endif
62
63
64#define aSifsTime 10
65
66#define MGMT_QUEUE_NUM 5
67
68
69#define IEEE_CMD_SET_WPA_PARAM 1
70#define IEEE_CMD_SET_WPA_IE 2
71#define IEEE_CMD_SET_ENCRYPTION 3
72#define IEEE_CMD_MLME 4
73
74#define IEEE_PARAM_WPA_ENABLED 1
75#define IEEE_PARAM_TKIP_COUNTERMEASURES 2
76#define IEEE_PARAM_DROP_UNENCRYPTED 3
77#define IEEE_PARAM_PRIVACY_INVOKED 4
78#define IEEE_PARAM_AUTH_ALGS 5
79#define IEEE_PARAM_IEEE_802_1X 6
80//It should consistent with the driver_XXX.c
81// David, 2006.9.26
82#define IEEE_PARAM_WPAX_SELECT 7
83//Added for notify the encryption type selection
84// David, 2006.9.26
85#define IEEE_PROTO_WPA 1
86#define IEEE_PROTO_RSN 2
87//Added for notify the encryption type selection
88// David, 2006.9.26
89#define IEEE_WPAX_USEGROUP 0
90#define IEEE_WPAX_WEP40 1
91#define IEEE_WPAX_TKIP 2
92#define IEEE_WPAX_WRAP 3
93#define IEEE_WPAX_CCMP 4
94#define IEEE_WPAX_WEP104 5
95
96#define IEEE_KEY_MGMT_IEEE8021X 1
97#define IEEE_KEY_MGMT_PSK 2
98
99
100
101#define IEEE_MLME_STA_DEAUTH 1
102#define IEEE_MLME_STA_DISASSOC 2
103
104
105#define IEEE_CRYPT_ERR_UNKNOWN_ALG 2
106#define IEEE_CRYPT_ERR_UNKNOWN_ADDR 3
107#define IEEE_CRYPT_ERR_CRYPT_INIT_FAILED 4
108#define IEEE_CRYPT_ERR_KEY_SET_FAILED 5
109#define IEEE_CRYPT_ERR_TX_KEY_SET_FAILED 6
110#define IEEE_CRYPT_ERR_CARD_CONF_FAILED 7
111
112
113#define IEEE_CRYPT_ALG_NAME_LEN 16
114
115#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,10))
116#define ieee80211_wx_get_scan ieee80211_wx_get_scan_rtl
117#define ieee80211_wx_set_encode ieee80211_wx_set_encode_rtl
118#define ieee80211_wx_get_encode ieee80211_wx_get_encode_rtl
119////////////////////////////////
120// added for kernel conflict under FC5
121#define ieee80211_wx_get_name ieee80211_wx_get_name_rtl
122#define free_ieee80211 free_ieee80211_rtl
123#define alloc_ieee80211 alloc_ieee80211_rtl
124///////////////////////////////
125#endif
126//error in ubuntu2.6.22,so add these
127#define ieee80211_wake_queue ieee80211_wake_queue_rtl
128#define ieee80211_stop_queue ieee80211_stop_queue_rtl
129
130#define ieee80211_rx ieee80211_rx_rtl
131
132#define ieee80211_register_crypto_ops ieee80211_register_crypto_ops_rtl
133#define ieee80211_unregister_crypto_ops ieee80211_unregister_crypto_ops_rtl
134#define ieee80211_get_crypto_ops ieee80211_get_crypto_ops_rtl
135#define ieee80211_crypt_deinit_entries ieee80211_crypt_deinit_entries_rtl
136#define ieee80211_crypt_deinit_handler ieee80211_crypt_deinit_handler_rtl
137#define ieee80211_crypt_delayed_deinit ieee80211_crypt_delayed_deinit_rtl
138
139#define ieee80211_txb_free ieee80211_txb_free_rtl
140#define ieee80211_wx_get_essid ieee80211_wx_get_essid_rtl
141#define ieee80211_wx_set_essid ieee80211_wx_set_essid_rtl
142#define ieee80211_wx_set_rate ieee80211_wx_set_rate_rtl
143#define ieee80211_wx_get_rate ieee80211_wx_get_rate_rtl
144#define ieee80211_wx_set_wap ieee80211_wx_set_wap_rtl
145#define ieee80211_wx_get_wap ieee80211_wx_get_wap_rtl
146#define ieee80211_wx_set_mode ieee80211_wx_set_mode_rtl
147#define ieee80211_wx_get_mode ieee80211_wx_get_mode_rtl
148#define ieee80211_wx_set_scan ieee80211_wx_set_scan_rtl
149#define ieee80211_wx_get_freq ieee80211_wx_get_freq_rtl
150#define ieee80211_wx_set_freq ieee80211_wx_set_freq_rtl
151#define ieee80211_wx_set_rawtx ieee80211_wx_set_rawtx_rtl
152#define ieee80211_wx_set_power ieee80211_wx_set_power_rtl
153#define ieee80211_wx_get_power ieee80211_wx_get_power_rtl
154#define ieee80211_wlan_frequencies ieee80211_wlan_frequencies_rtl
155#define ieee80211_softmac_stop_protocol ieee80211_softmac_stop_protocol_rtl
156#define ieee80211_softmac_start_protocol ieee80211_softmac_start_protocol_rtl
157#define ieee80211_start_protocol ieee80211_start_protocol_rtl
158#define ieee80211_stop_protocol ieee80211_stop_protocol_rtl
159#define ieee80211_rx_mgt ieee80211_rx_mgt_rtl
160
161#define ieee80211_wx_set_auth ieee80211_wx_set_auth_rtl
162//by amy for ps
163#define notify_wx_assoc_event notify_wx_assoc_event_rtl
164#define ieee80211_stop_send_beacons ieee80211_stop_send_beacons_rtl
165#define ieee80211_disassociate ieee80211_disassociate_rtl
166#define ieee80211_start_scan ieee80211_start_scan_rtl
167//by amy for ps
168typedef struct ieee_param {
169 u32 cmd;
170 u8 sta_addr[ETH_ALEN];
171 union {
172 struct {
173 u8 name;
174 u32 value;
175 } wpa_param;
176 struct {
177 u32 len;
178 u8 reserved[32];
179 u8 data[0];
180 } wpa_ie;
181 struct{
182 int command;
183 int reason_code;
184 } mlme;
185 struct {
186 u8 alg[IEEE_CRYPT_ALG_NAME_LEN];
187 u8 set_tx;
188 u32 err;
189 u8 idx;
190 u8 seq[8]; /* sequence counter (set: RX, get: TX) */
191 u16 key_len;
192 u8 key[0];
193 } crypt;
194
195 } u;
196}ieee_param;
197
198
199#if WIRELESS_EXT < 17
200#define IW_QUAL_QUAL_INVALID 0x10
201#define IW_QUAL_LEVEL_INVALID 0x20
202#define IW_QUAL_NOISE_INVALID 0x40
203#define IW_QUAL_QUAL_UPDATED 0x1
204#define IW_QUAL_LEVEL_UPDATED 0x2
205#define IW_QUAL_NOISE_UPDATED 0x4
206#endif
207
208// linux under 2.6.9 release may not support it, so modify it for common use
209#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9))
210#define MSECS(t) (1000 * ((t) / HZ) + 1000 * ((t) % HZ) / HZ)
211static inline unsigned long msleep_interruptible_rtl(unsigned int msecs)
212{
213 unsigned long timeout = MSECS(msecs) + 1;
214
215 while (timeout) {
216 set_current_state(TASK_UNINTERRUPTIBLE);
217 timeout = schedule_timeout(timeout);
218 }
219 return timeout;
220}
221#else
222#define MSECS(t) msecs_to_jiffies(t)
223#define msleep_interruptible_rtl msleep_interruptible
224#endif
225
226#define IEEE80211_DATA_LEN 2304
227/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
228 6.2.1.1.2.
229
230 The figure in section 7.1.2 suggests a body size of up to 2312
231 bytes is allowed, which is a bit confusing, I suspect this
232 represents the 2304 bytes of real data, plus a possible 8 bytes of
233 WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */
234
235
236#define IEEE80211_HLEN 30
237#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN)
238
239/* this is stolen and modified from the madwifi driver*/
240#define IEEE80211_FC0_TYPE_MASK 0x0c
241#define IEEE80211_FC0_TYPE_DATA 0x08
242#define IEEE80211_FC0_SUBTYPE_MASK 0xB0
243#define IEEE80211_FC0_SUBTYPE_QOS 0x80
244
245#define IEEE80211_QOS_HAS_SEQ(fc) \
246 (((fc) & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == \
247 (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS))
248
249/* this is stolen from ipw2200 driver */
250#define IEEE_IBSS_MAC_HASH_SIZE 31
251struct ieee_ibss_seq {
252 u8 mac[ETH_ALEN];
253 u16 seq_num[17];
254 u16 frag_num[17];
255 unsigned long packet_time[17];
256 struct list_head list;
257};
258
259struct ieee80211_hdr {
260 u16 frame_ctl;
261 u16 duration_id;
262 u8 addr1[ETH_ALEN];
263 u8 addr2[ETH_ALEN];
264 u8 addr3[ETH_ALEN];
265 u16 seq_ctl;
266 u8 addr4[ETH_ALEN];
267} __attribute__ ((packed));
268
269struct ieee80211_hdr_QOS {
270 u16 frame_ctl;
271 u16 duration_id;
272 u8 addr1[ETH_ALEN];
273 u8 addr2[ETH_ALEN];
274 u8 addr3[ETH_ALEN];
275 u16 seq_ctl;
276 u8 addr4[ETH_ALEN];
277 u16 QOS_ctl;
278} __attribute__ ((packed));
279
280struct ieee80211_hdr_3addr {
281 u16 frame_ctl;
282 u16 duration_id;
283 u8 addr1[ETH_ALEN];
284 u8 addr2[ETH_ALEN];
285 u8 addr3[ETH_ALEN];
286 u16 seq_ctl;
287} __attribute__ ((packed));
288
289struct ieee80211_hdr_3addr_QOS {
290 u16 frame_ctl;
291 u16 duration_id;
292 u8 addr1[ETH_ALEN];
293 u8 addr2[ETH_ALEN];
294 u8 addr3[ETH_ALEN];
295 u16 seq_ctl;
296 u16 QOS_ctl;
297} __attribute__ ((packed));
298
299enum eap_type {
300 EAP_PACKET = 0,
301 EAPOL_START,
302 EAPOL_LOGOFF,
303 EAPOL_KEY,
304 EAPOL_ENCAP_ASF_ALERT
305};
306
307static const char *eap_types[] = {
308 [EAP_PACKET] = "EAP-Packet",
309 [EAPOL_START] = "EAPOL-Start",
310 [EAPOL_LOGOFF] = "EAPOL-Logoff",
311 [EAPOL_KEY] = "EAPOL-Key",
312 [EAPOL_ENCAP_ASF_ALERT] = "EAPOL-Encap-ASF-Alert"
313};
314
315static inline const char *eap_get_type(int type)
316{
317 return (type >= ARRAY_SIZE(eap_types)) ? "Unknown" : eap_types[type];
318}
319
320struct eapol {
321 u8 snap[6];
322 u16 ethertype;
323 u8 version;
324 u8 type;
325 u16 length;
326} __attribute__ ((packed));
327
328#define IEEE80211_3ADDR_LEN 24
329#define IEEE80211_4ADDR_LEN 30
330#define IEEE80211_FCS_LEN 4
331
332#define MIN_FRAG_THRESHOLD 256U
333#define MAX_FRAG_THRESHOLD 2346U
334
335/* Frame control field constants */
336#define IEEE80211_FCTL_VERS 0x0002
337#define IEEE80211_FCTL_FTYPE 0x000c
338#define IEEE80211_FCTL_STYPE 0x00f0
339#define IEEE80211_FCTL_TODS 0x0100
340#define IEEE80211_FCTL_FROMDS 0x0200
341#define IEEE80211_FCTL_DSTODS 0x0300 //added by david
342#define IEEE80211_FCTL_MOREFRAGS 0x0400
343#define IEEE80211_FCTL_RETRY 0x0800
344#define IEEE80211_FCTL_PM 0x1000
345#define IEEE80211_FCTL_MOREDATA 0x2000
346#define IEEE80211_FCTL_WEP 0x4000
347#define IEEE80211_FCTL_ORDER 0x8000
348
349#define IEEE80211_FTYPE_MGMT 0x0000
350#define IEEE80211_FTYPE_CTL 0x0004
351#define IEEE80211_FTYPE_DATA 0x0008
352
353/* management */
354#define IEEE80211_STYPE_ASSOC_REQ 0x0000
355#define IEEE80211_STYPE_ASSOC_RESP 0x0010
356#define IEEE80211_STYPE_REASSOC_REQ 0x0020
357#define IEEE80211_STYPE_REASSOC_RESP 0x0030
358#define IEEE80211_STYPE_PROBE_REQ 0x0040
359#define IEEE80211_STYPE_PROBE_RESP 0x0050
360#define IEEE80211_STYPE_BEACON 0x0080
361#define IEEE80211_STYPE_ATIM 0x0090
362#define IEEE80211_STYPE_DISASSOC 0x00A0
363#define IEEE80211_STYPE_AUTH 0x00B0
364#define IEEE80211_STYPE_DEAUTH 0x00C0
365#define IEEE80211_STYPE_MANAGE_ACT 0x00D0
366
367/* control */
368#define IEEE80211_STYPE_PSPOLL 0x00A0
369#define IEEE80211_STYPE_RTS 0x00B0
370#define IEEE80211_STYPE_CTS 0x00C0
371#define IEEE80211_STYPE_ACK 0x00D0
372#define IEEE80211_STYPE_CFEND 0x00E0
373#define IEEE80211_STYPE_CFENDACK 0x00F0
374
375/* data */
376#define IEEE80211_STYPE_DATA 0x0000
377#define IEEE80211_STYPE_DATA_CFACK 0x0010
378#define IEEE80211_STYPE_DATA_CFPOLL 0x0020
379#define IEEE80211_STYPE_DATA_CFACKPOLL 0x0030
380#define IEEE80211_STYPE_NULLFUNC 0x0040
381#define IEEE80211_STYPE_CFACK 0x0050
382#define IEEE80211_STYPE_CFPOLL 0x0060
383#define IEEE80211_STYPE_CFACKPOLL 0x0070
384#define IEEE80211_STYPE_QOS_DATA 0x0080 //added for WMM 2006/8/2
385#define IEEE80211_STYPE_QOS_NULL 0x00C0
386
387
388#define IEEE80211_SCTL_FRAG 0x000F
389#define IEEE80211_SCTL_SEQ 0xFFF0
390
391
392/* debug macros */
393
394#ifdef CONFIG_IEEE80211_DEBUG
395extern u32 ieee80211_debug_level;
396#define IEEE80211_DEBUG(level, fmt, args...) \
397do { if (ieee80211_debug_level & (level)) \
398 printk(KERN_DEBUG "ieee80211: %c %s " fmt, \
399 in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0)
400#else
401#define IEEE80211_DEBUG(level, fmt, args...) do {} while (0)
402#endif /* CONFIG_IEEE80211_DEBUG */
403
404/*
405 * To use the debug system;
406 *
407 * If you are defining a new debug classification, simply add it to the #define
408 * list here in the form of:
409 *
410 * #define IEEE80211_DL_xxxx VALUE
411 *
412 * shifting value to the left one bit from the previous entry. xxxx should be
413 * the name of the classification (for example, WEP)
414 *
415 * You then need to either add a IEEE80211_xxxx_DEBUG() macro definition for your
416 * classification, or use IEEE80211_DEBUG(IEEE80211_DL_xxxx, ...) whenever you want
417 * to send output to that classification.
418 *
419 * To add your debug level to the list of levels seen when you perform
420 *
421 * % cat /proc/net/ipw/debug_level
422 *
423 * you simply need to add your entry to the ipw_debug_levels array.
424 *
425 * If you do not see debug_level in /proc/net/ipw then you do not have
426 * CONFIG_IEEE80211_DEBUG defined in your kernel configuration
427 *
428 */
429
430#define IEEE80211_DL_INFO (1<<0)
431#define IEEE80211_DL_WX (1<<1)
432#define IEEE80211_DL_SCAN (1<<2)
433#define IEEE80211_DL_STATE (1<<3)
434#define IEEE80211_DL_MGMT (1<<4)
435#define IEEE80211_DL_FRAG (1<<5)
436#define IEEE80211_DL_EAP (1<<6)
437#define IEEE80211_DL_DROP (1<<7)
438
439#define IEEE80211_DL_TX (1<<8)
440#define IEEE80211_DL_RX (1<<9)
441
442#define IEEE80211_ERROR(f, a...) printk(KERN_ERR "ieee80211: " f, ## a)
443#define IEEE80211_WARNING(f, a...) printk(KERN_WARNING "ieee80211: " f, ## a)
444#define IEEE80211_DEBUG_INFO(f, a...) IEEE80211_DEBUG(IEEE80211_DL_INFO, f, ## a)
445
446#define IEEE80211_DEBUG_WX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_WX, f, ## a)
447#define IEEE80211_DEBUG_SCAN(f, a...) IEEE80211_DEBUG(IEEE80211_DL_SCAN, f, ## a)
448//#define IEEE_DEBUG_SCAN IEEE80211_WARNING
449#define IEEE80211_DEBUG_STATE(f, a...) IEEE80211_DEBUG(IEEE80211_DL_STATE, f, ## a)
450#define IEEE80211_DEBUG_MGMT(f, a...) IEEE80211_DEBUG(IEEE80211_DL_MGMT, f, ## a)
451#define IEEE80211_DEBUG_FRAG(f, a...) IEEE80211_DEBUG(IEEE80211_DL_FRAG, f, ## a)
452#define IEEE80211_DEBUG_EAP(f, a...) IEEE80211_DEBUG(IEEE80211_DL_EAP, f, ## a)
453#define IEEE80211_DEBUG_DROP(f, a...) IEEE80211_DEBUG(IEEE80211_DL_DROP, f, ## a)
454#define IEEE80211_DEBUG_TX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_TX, f, ## a)
455#define IEEE80211_DEBUG_RX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_RX, f, ## a)
456#include <linux/netdevice.h>
457#include <linux/wireless.h>
458#include <linux/if_arp.h> /* ARPHRD_ETHER */
459
460#ifndef WIRELESS_SPY
461#define WIRELESS_SPY // enable iwspy support
462#endif
463#include <net/iw_handler.h> // new driver API
464
465#ifndef ETH_P_PAE
466#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
467#endif /* ETH_P_PAE */
468
469#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */
470
471#ifndef ETH_P_80211_RAW
472#define ETH_P_80211_RAW (ETH_P_ECONET + 1)
473#endif
474
475/* IEEE 802.11 defines */
476
477#define P80211_OUI_LEN 3
478
479struct ieee80211_snap_hdr {
480
481 u8 dsap; /* always 0xAA */
482 u8 ssap; /* always 0xAA */
483 u8 ctrl; /* always 0x03 */
484 u8 oui[P80211_OUI_LEN]; /* organizational universal id */
485
486} __attribute__ ((packed));
487
488#define SNAP_SIZE sizeof(struct ieee80211_snap_hdr)
489
490#define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE)
491#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE)
492
493#define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG)
494#define WLAN_GET_SEQ_SEQ(seq) ((seq) & IEEE80211_SCTL_SEQ)
495
496/* Authentication algorithms */
497#define WLAN_AUTH_OPEN 0
498#define WLAN_AUTH_SHARED_KEY 1
499
500#define WLAN_AUTH_CHALLENGE_LEN 128
501
502#define WLAN_CAPABILITY_BSS (1<<0)
503#define WLAN_CAPABILITY_IBSS (1<<1)
504#define WLAN_CAPABILITY_CF_POLLABLE (1<<2)
505#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3)
506#define WLAN_CAPABILITY_PRIVACY (1<<4)
507#define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5)
508#define WLAN_CAPABILITY_PBCC (1<<6)
509#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7)
510#define WLAN_CAPABILITY_SHORT_SLOT (1<<10)
511
512/* Status codes */
513#define WLAN_STATUS_SUCCESS 0
514#define WLAN_STATUS_UNSPECIFIED_FAILURE 1
515#define WLAN_STATUS_CAPS_UNSUPPORTED 10
516#define WLAN_STATUS_REASSOC_NO_ASSOC 11
517#define WLAN_STATUS_ASSOC_DENIED_UNSPEC 12
518#define WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG 13
519#define WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION 14
520#define WLAN_STATUS_CHALLENGE_FAIL 15
521#define WLAN_STATUS_AUTH_TIMEOUT 16
522#define WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA 17
523#define WLAN_STATUS_ASSOC_DENIED_RATES 18
524/* 802.11b */
525#define WLAN_STATUS_ASSOC_DENIED_NOSHORT 19
526#define WLAN_STATUS_ASSOC_DENIED_NOPBCC 20
527#define WLAN_STATUS_ASSOC_DENIED_NOAGILITY 21
528
529/* Reason codes */
530#define WLAN_REASON_UNSPECIFIED 1
531#define WLAN_REASON_PREV_AUTH_NOT_VALID 2
532#define WLAN_REASON_DEAUTH_LEAVING 3
533#define WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY 4
534#define WLAN_REASON_DISASSOC_AP_BUSY 5
535#define WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA 6
536#define WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA 7
537#define WLAN_REASON_DISASSOC_STA_HAS_LEFT 8
538#define WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH 9
539
540
541/* Information Element IDs */
542#define WLAN_EID_SSID 0
543#define WLAN_EID_SUPP_RATES 1
544#define WLAN_EID_FH_PARAMS 2
545#define WLAN_EID_DS_PARAMS 3
546#define WLAN_EID_CF_PARAMS 4
547#define WLAN_EID_TIM 5
548#define WLAN_EID_IBSS_PARAMS 6
549#define WLAN_EID_CHALLENGE 16
550#define WLAN_EID_RSN 48
551#define WLAN_EID_GENERIC 221
552
553#define IEEE80211_MGMT_HDR_LEN 24
554#define IEEE80211_DATA_HDR3_LEN 24
555#define IEEE80211_DATA_HDR4_LEN 30
556
557
558#define IEEE80211_STATMASK_SIGNAL (1<<0)
559#define IEEE80211_STATMASK_RSSI (1<<1)
560#define IEEE80211_STATMASK_NOISE (1<<2)
561#define IEEE80211_STATMASK_RATE (1<<3)
562#define IEEE80211_STATMASK_WEMASK 0x7
563
564
565#define IEEE80211_CCK_MODULATION (1<<0)
566#define IEEE80211_OFDM_MODULATION (1<<1)
567
568#define IEEE80211_24GHZ_BAND (1<<0)
569#define IEEE80211_52GHZ_BAND (1<<1)
570
571#define IEEE80211_CCK_RATE_LEN 4
572#define IEEE80211_CCK_RATE_1MB 0x02
573#define IEEE80211_CCK_RATE_2MB 0x04
574#define IEEE80211_CCK_RATE_5MB 0x0B
575#define IEEE80211_CCK_RATE_11MB 0x16
576#define IEEE80211_OFDM_RATE_LEN 8
577#define IEEE80211_OFDM_RATE_6MB 0x0C
578#define IEEE80211_OFDM_RATE_9MB 0x12
579#define IEEE80211_OFDM_RATE_12MB 0x18
580#define IEEE80211_OFDM_RATE_18MB 0x24
581#define IEEE80211_OFDM_RATE_24MB 0x30
582#define IEEE80211_OFDM_RATE_36MB 0x48
583#define IEEE80211_OFDM_RATE_48MB 0x60
584#define IEEE80211_OFDM_RATE_54MB 0x6C
585#define IEEE80211_BASIC_RATE_MASK 0x80
586
587#define IEEE80211_CCK_RATE_1MB_MASK (1<<0)
588#define IEEE80211_CCK_RATE_2MB_MASK (1<<1)
589#define IEEE80211_CCK_RATE_5MB_MASK (1<<2)
590#define IEEE80211_CCK_RATE_11MB_MASK (1<<3)
591#define IEEE80211_OFDM_RATE_6MB_MASK (1<<4)
592#define IEEE80211_OFDM_RATE_9MB_MASK (1<<5)
593#define IEEE80211_OFDM_RATE_12MB_MASK (1<<6)
594#define IEEE80211_OFDM_RATE_18MB_MASK (1<<7)
595#define IEEE80211_OFDM_RATE_24MB_MASK (1<<8)
596#define IEEE80211_OFDM_RATE_36MB_MASK (1<<9)
597#define IEEE80211_OFDM_RATE_48MB_MASK (1<<10)
598#define IEEE80211_OFDM_RATE_54MB_MASK (1<<11)
599
600#define IEEE80211_CCK_RATES_MASK 0x0000000F
601#define IEEE80211_CCK_BASIC_RATES_MASK (IEEE80211_CCK_RATE_1MB_MASK | \
602 IEEE80211_CCK_RATE_2MB_MASK)
603#define IEEE80211_CCK_DEFAULT_RATES_MASK (IEEE80211_CCK_BASIC_RATES_MASK | \
604 IEEE80211_CCK_RATE_5MB_MASK | \
605 IEEE80211_CCK_RATE_11MB_MASK)
606
607#define IEEE80211_OFDM_RATES_MASK 0x00000FF0
608#define IEEE80211_OFDM_BASIC_RATES_MASK (IEEE80211_OFDM_RATE_6MB_MASK | \
609 IEEE80211_OFDM_RATE_12MB_MASK | \
610 IEEE80211_OFDM_RATE_24MB_MASK)
611#define IEEE80211_OFDM_DEFAULT_RATES_MASK (IEEE80211_OFDM_BASIC_RATES_MASK | \
612 IEEE80211_OFDM_RATE_9MB_MASK | \
613 IEEE80211_OFDM_RATE_18MB_MASK | \
614 IEEE80211_OFDM_RATE_36MB_MASK | \
615 IEEE80211_OFDM_RATE_48MB_MASK | \
616 IEEE80211_OFDM_RATE_54MB_MASK)
617#define IEEE80211_DEFAULT_RATES_MASK (IEEE80211_OFDM_DEFAULT_RATES_MASK | \
618 IEEE80211_CCK_DEFAULT_RATES_MASK)
619
620#define IEEE80211_NUM_OFDM_RATES 8
621#define IEEE80211_NUM_CCK_RATES 4
622#define IEEE80211_OFDM_SHIFT_MASK_A 4
623
624
625
626
627/* NOTE: This data is for statistical purposes; not all hardware provides this
628 * information for frames received. Not setting these will not cause
629 * any adverse affects. */
630struct ieee80211_rx_stats {
631 u32 mac_time[2];
632 u8 signalstrength;
633 s8 rssi;
634 u8 signal;
635 u8 noise;
636 u16 rate; /* in 100 kbps */
637 u8 received_channel;
638 u8 control;
639 u8 mask;
640 u8 freq;
641 u16 len;
642 u8 nic_type;
643};
644
645/* IEEE 802.11 requires that STA supports concurrent reception of at least
646 * three fragmented frames. This define can be increased to support more
647 * concurrent frames, but it should be noted that each entry can consume about
648 * 2 kB of RAM and increasing cache size will slow down frame reassembly. */
649#define IEEE80211_FRAG_CACHE_LEN 4
650
651struct ieee80211_frag_entry {
652 unsigned long first_frag_time;
653 unsigned int seq;
654 unsigned int last_frag;
655 struct sk_buff *skb;
656 u8 src_addr[ETH_ALEN];
657 u8 dst_addr[ETH_ALEN];
658};
659
660struct ieee80211_stats {
661 unsigned int tx_unicast_frames;
662 unsigned int tx_multicast_frames;
663 unsigned int tx_fragments;
664 unsigned int tx_unicast_octets;
665 unsigned int tx_multicast_octets;
666 unsigned int tx_deferred_transmissions;
667 unsigned int tx_single_retry_frames;
668 unsigned int tx_multiple_retry_frames;
669 unsigned int tx_retry_limit_exceeded;
670 unsigned int tx_discards;
671 unsigned int rx_unicast_frames;
672 unsigned int rx_multicast_frames;
673 unsigned int rx_fragments;
674 unsigned int rx_unicast_octets;
675 unsigned int rx_multicast_octets;
676 unsigned int rx_fcs_errors;
677 unsigned int rx_discards_no_buffer;
678 unsigned int tx_discards_wrong_sa;
679 unsigned int rx_discards_undecryptable;
680 unsigned int rx_message_in_msg_fragments;
681 unsigned int rx_message_in_bad_msg_fragments;
682};
683
684struct ieee80211_softmac_stats{
685 unsigned int rx_ass_ok;
686 unsigned int rx_ass_err;
687 unsigned int rx_probe_rq;
688 unsigned int tx_probe_rs;
689 unsigned int tx_beacons;
690 unsigned int rx_auth_rq;
691 unsigned int rx_auth_rs_ok;
692 unsigned int rx_auth_rs_err;
693 unsigned int tx_auth_rq;
694 unsigned int no_auth_rs;
695 unsigned int no_ass_rs;
696 unsigned int tx_ass_rq;
697 unsigned int rx_ass_rq;
698 unsigned int tx_probe_rq;
699 unsigned int reassoc;
700 unsigned int swtxstop;
701 unsigned int swtxawake;
702};
703
704struct ieee80211_device;
705
706#include "ieee80211_crypt.h"
707
708#define SEC_KEY_1 (1<<0)
709#define SEC_KEY_2 (1<<1)
710#define SEC_KEY_3 (1<<2)
711#define SEC_KEY_4 (1<<3)
712#define SEC_ACTIVE_KEY (1<<4)
713#define SEC_AUTH_MODE (1<<5)
714#define SEC_UNICAST_GROUP (1<<6)
715#define SEC_LEVEL (1<<7)
716#define SEC_ENABLED (1<<8)
717
718#define SEC_LEVEL_0 0 /* None */
719#define SEC_LEVEL_1 1 /* WEP 40 and 104 bit */
720#define SEC_LEVEL_2 2 /* Level 1 + TKIP */
721#define SEC_LEVEL_2_CKIP 3 /* Level 1 + CKIP */
722#define SEC_LEVEL_3 4 /* Level 2 + CCMP */
723
724#define WEP_KEYS 4
725#define WEP_KEY_LEN 13
726
727#define WEP_KEY_LEN_MODIF 32
728
729struct ieee80211_security {
730 u16 active_key:2,
731 enabled:1,
732 auth_mode:2,
733 auth_algo:4,
734 unicast_uses_group:1;
735 u8 key_sizes[WEP_KEYS];
736 u8 keys[WEP_KEYS][WEP_KEY_LEN_MODIF];
737 u8 level;
738 u16 flags;
739} __attribute__ ((packed));
740
741
742/*
743
744 802.11 data frame from AP
745
746 ,-------------------------------------------------------------------.
747Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 |
748 |------|------|---------|---------|---------|------|---------|------|
749Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | frame | fcs |
750 | | tion | (BSSID) | | | ence | data | |
751 `-------------------------------------------------------------------'
752
753Total: 28-2340 bytes
754
755*/
756
757struct ieee80211_header_data {
758 u16 frame_ctl;
759 u16 duration_id;
760 u8 addr1[6];
761 u8 addr2[6];
762 u8 addr3[6];
763 u16 seq_ctrl;
764};
765
766#define BEACON_PROBE_SSID_ID_POSITION 12
767
768/* Management Frame Information Element Types */
769#define MFIE_TYPE_SSID 0
770#define MFIE_TYPE_RATES 1
771#define MFIE_TYPE_FH_SET 2
772#define MFIE_TYPE_DS_SET 3
773#define MFIE_TYPE_CF_SET 4
774#define MFIE_TYPE_TIM 5
775#define MFIE_TYPE_IBSS_SET 6
776#define MFIE_TYPE_COUNTRY 7 //+YJ,080625
777#define MFIE_TYPE_CHALLENGE 16
778#define MFIE_TYPE_ERP 42
779#define MFIE_TYPE_RSN 48
780#define MFIE_TYPE_RATES_EX 50
781#define MFIE_TYPE_GENERIC 221
782
783#ifdef ENABLE_DOT11D
784typedef enum
785{
786 COUNTRY_CODE_FCC = 0,
787 COUNTRY_CODE_IC = 1,
788 COUNTRY_CODE_ETSI = 2,
789 COUNTRY_CODE_SPAIN = 3,
790 COUNTRY_CODE_FRANCE = 4,
791 COUNTRY_CODE_MKK = 5,
792 COUNTRY_CODE_MKK1 = 6,
793 COUNTRY_CODE_ISRAEL = 7,
794 COUNTRY_CODE_TELEC = 8,
795 COUNTRY_CODE_GLOBAL_DOMAIN = 9,
796 COUNTRY_CODE_WORLD_WIDE_13_INDEX = 10
797}country_code_type_t;
798#endif
799
800struct ieee80211_info_element_hdr {
801 u8 id;
802 u8 len;
803} __attribute__ ((packed));
804
805struct ieee80211_info_element {
806 u8 id;
807 u8 len;
808 u8 data[0];
809} __attribute__ ((packed));
810
811/*
812 * These are the data types that can make up management packets
813 *
814 u16 auth_algorithm;
815 u16 auth_sequence;
816 u16 beacon_interval;
817 u16 capability;
818 u8 current_ap[ETH_ALEN];
819 u16 listen_interval;
820 struct {
821 u16 association_id:14, reserved:2;
822 } __attribute__ ((packed));
823 u32 time_stamp[2];
824 u16 reason;
825 u16 status;
826*/
827
828#define IEEE80211_DEFAULT_TX_ESSID "Penguin"
829#define IEEE80211_DEFAULT_BASIC_RATE 10
830
831struct ieee80211_authentication {
832 struct ieee80211_header_data header;
833 u16 algorithm;
834 u16 transaction;
835 u16 status;
836 //struct ieee80211_info_element_hdr info_element;
837} __attribute__ ((packed));
838
839
840struct ieee80211_probe_response {
841 struct ieee80211_header_data header;
842 u32 time_stamp[2];
843 u16 beacon_interval;
844 u16 capability;
845 struct ieee80211_info_element info_element;
846} __attribute__ ((packed));
847
848struct ieee80211_probe_request {
849 struct ieee80211_header_data header;
850 /*struct ieee80211_info_element info_element;*/
851} __attribute__ ((packed));
852
853struct ieee80211_assoc_request_frame {
854 struct ieee80211_hdr_3addr header;
855 u16 capability;
856 u16 listen_interval;
857 //u8 current_ap[ETH_ALEN];
858 struct ieee80211_info_element_hdr info_element;
859} __attribute__ ((packed));
860
861struct ieee80211_assoc_response_frame {
862 struct ieee80211_hdr_3addr header;
863 u16 capability;
864 u16 status;
865 u16 aid;
866 struct ieee80211_info_element info_element; /* supported rates */
867} __attribute__ ((packed));
868
869struct ieee80211_disassoc_frame{
870 struct ieee80211_hdr_3addr header;
871 u16 reasoncode;
872}__attribute__ ((packed));
873
874struct ieee80211_txb {
875 u8 nr_frags;
876 u8 encrypted;
877 u16 reserved;
878 u16 frag_size;
879 u16 payload_size;
880 struct sk_buff *fragments[0];
881};
882
883struct ieee80211_wmm_ac_param {
884 u8 ac_aci_acm_aifsn;
885 u8 ac_ecwmin_ecwmax;
886 u16 ac_txop_limit;
887};
888
889struct ieee80211_wmm_ts_info {
890 u8 ac_dir_tid;
891 u8 ac_up_psb;
892 u8 reserved;
893} __attribute__ ((packed));
894
895struct ieee80211_wmm_tspec_elem {
896 struct ieee80211_wmm_ts_info ts_info;
897 u16 norm_msdu_size;
898 u16 max_msdu_size;
899 u32 min_serv_inter;
900 u32 max_serv_inter;
901 u32 inact_inter;
902 u32 suspen_inter;
903 u32 serv_start_time;
904 u32 min_data_rate;
905 u32 mean_data_rate;
906 u32 peak_data_rate;
907 u32 max_burst_size;
908 u32 delay_bound;
909 u32 min_phy_rate;
910 u16 surp_band_allow;
911 u16 medium_time;
912}__attribute__((packed));
913
914enum {WMM_all_frame, WMM_two_frame, WMM_four_frame, WMM_six_frame};
915#define MAX_SP_Len (WMM_all_frame << 4)
916#define IEEE80211_QOS_TID 0x0f
917#define QOS_CTL_NOTCONTAIN_ACK (0x01 << 5)
918
919/* SWEEP TABLE ENTRIES NUMBER*/
920#define MAX_SWEEP_TAB_ENTRIES 42
921#define MAX_SWEEP_TAB_ENTRIES_PER_PACKET 7
922/* MAX_RATES_LENGTH needs to be 12. The spec says 8, and many APs
923 * only use 8, and then use extended rates for the remaining supported
924 * rates. Other APs, however, stick all of their supported rates on the
925 * main rates information element... */
926#define MAX_RATES_LENGTH ((u8)12)
927#define MAX_RATES_EX_LENGTH ((u8)16)
928#define MAX_NETWORK_COUNT 128
929//#define MAX_CHANNEL_NUMBER 161
930#define MAX_CHANNEL_NUMBER 165 //YJ,modified,080625
931#define MAX_IE_LEN 0xFF //+YJ,080625
932
933typedef struct _CHANNEL_LIST{
934 u8 Channel[MAX_CHANNEL_NUMBER + 1];
935 u8 Len;
936}CHANNEL_LIST, *PCHANNEL_LIST;
937
938#define IEEE80211_SOFTMAC_SCAN_TIME 100//400
939//(HZ / 2)
940//by amy for ps
941#define IEEE80211_WATCH_DOG_TIME 2000
942//by amy for ps
943//by amy for antenna
944#define ANTENNA_DIVERSITY_TIMER_PERIOD 1000 // 1000 m
945//by amy for antenna
946#define IEEE80211_SOFTMAC_ASSOC_RETRY_TIME (HZ * 2)
947
948#define CRC_LENGTH 4U
949
950#define MAX_WPA_IE_LEN 64
951
952#define NETWORK_EMPTY_ESSID (1<<0)
953#define NETWORK_HAS_OFDM (1<<1)
954#define NETWORK_HAS_CCK (1<<2)
955
956#define IEEE80211_DTIM_MBCAST 4
957#define IEEE80211_DTIM_UCAST 2
958#define IEEE80211_DTIM_VALID 1
959#define IEEE80211_DTIM_INVALID 0
960
961#define IEEE80211_PS_DISABLED 0
962#define IEEE80211_PS_UNICAST IEEE80211_DTIM_UCAST
963#define IEEE80211_PS_MBCAST IEEE80211_DTIM_MBCAST
964#define IEEE80211_PS_ENABLE IEEE80211_DTIM_VALID
965//added by David for QoS 2006/6/30
966//#define WMM_Hang_8187
967#ifdef WMM_Hang_8187
968#undef WMM_Hang_8187
969#endif
970
971#define WME_AC_BE 0x00
972#define WME_AC_BK 0x01
973#define WME_AC_VI 0x02
974#define WME_AC_VO 0x03
975#define WME_ACI_MASK 0x03
976#define WME_AIFSN_MASK 0x03
977#define WME_AC_PRAM_LEN 16
978
979//UP Mapping to AC, using in MgntQuery_SequenceNumber() and maybe for DSCP
980//#define UP2AC(up) ((up<3) ? ((up==0)?1:0) : (up>>1))
981#define UP2AC(up) ( \
982 ((up) < 1) ? WME_AC_BE : \
983 ((up) < 3) ? WME_AC_BK : \
984 ((up) < 4) ? WME_AC_BE : \
985 ((up) < 6) ? WME_AC_VI : \
986 WME_AC_VO)
987//AC Mapping to UP, using in Tx part for selecting the corresponding TX queue
988#define AC2UP(_ac) ( \
989 ((_ac) == WME_AC_VO) ? 6 : \
990 ((_ac) == WME_AC_VI) ? 5 : \
991 ((_ac) == WME_AC_BK) ? 1 : \
992 0)
993
994#define ETHER_ADDR_LEN 6 /* length of an Ethernet address */
995struct ether_header {
996 u8 ether_dhost[ETHER_ADDR_LEN];
997 u8 ether_shost[ETHER_ADDR_LEN];
998 u16 ether_type;
999} __attribute__((packed));
1000
1001#ifndef ETHERTYPE_PAE
1002#define ETHERTYPE_PAE 0x888e /* EAPOL PAE/802.1x */
1003#endif
1004#ifndef ETHERTYPE_IP
1005#define ETHERTYPE_IP 0x0800 /* IP protocol */
1006#endif
1007
1008struct ieee80211_network {
1009 /* These entries are used to identify a unique network */
1010 u8 bssid[ETH_ALEN];
1011 u8 channel;
1012 /* Ensure null-terminated for any debug msgs */
1013 u8 ssid[IW_ESSID_MAX_SIZE + 1];
1014 u8 ssid_len;
1015
1016 /* These are network statistics */
1017 struct ieee80211_rx_stats stats;
1018 u16 capability;
1019 u8 rates[MAX_RATES_LENGTH];
1020 u8 rates_len;
1021 u8 rates_ex[MAX_RATES_EX_LENGTH];
1022 u8 rates_ex_len;
1023 unsigned long last_scanned;
1024 u8 mode;
1025 u8 flags;
1026 u32 last_associate;
1027 u32 time_stamp[2];
1028 u16 beacon_interval;
1029 u16 listen_interval;
1030 u16 atim_window;
1031 u8 wpa_ie[MAX_WPA_IE_LEN];
1032 size_t wpa_ie_len;
1033 u8 rsn_ie[MAX_WPA_IE_LEN];
1034 size_t rsn_ie_len;
1035 u8 dtim_period;
1036 u8 dtim_data;
1037 u32 last_dtim_sta_time[2];
1038 struct list_head list;
1039 //appeded for QoS
1040 u8 wmm_info;
1041 struct ieee80211_wmm_ac_param wmm_param[4];
1042 u8 QoS_Enable;
1043 u8 SignalStrength;
1044//by amy 080312
1045 u8 HighestOperaRate;
1046//by amy 080312
1047#ifdef THOMAS_TURBO
1048 u8 Turbo_Enable;//enable turbo mode, added by thomas
1049#endif
1050#ifdef ENABLE_DOT11D
1051 u16 CountryIeLen;
1052 u8 CountryIeBuf[MAX_IE_LEN];
1053#endif
1054};
1055
1056enum ieee80211_state {
1057
1058 /* the card is not linked at all */
1059 IEEE80211_NOLINK = 0,
1060
1061 /* IEEE80211_ASSOCIATING* are for BSS client mode
1062 * the driver shall not perform RX filtering unless
1063 * the state is LINKED.
1064 * The driver shall just check for the state LINKED and
1065 * defaults to NOLINK for ALL the other states (including
1066 * LINKED_SCANNING)
1067 */
1068
1069 /* the association procedure will start (wq scheduling)*/
1070 IEEE80211_ASSOCIATING,
1071 IEEE80211_ASSOCIATING_RETRY,
1072
1073 /* the association procedure is sending AUTH request*/
1074 IEEE80211_ASSOCIATING_AUTHENTICATING,
1075
1076 /* the association procedure has successfully authentcated
1077 * and is sending association request
1078 */
1079 IEEE80211_ASSOCIATING_AUTHENTICATED,
1080
1081 /* the link is ok. the card associated to a BSS or linked
1082 * to a ibss cell or acting as an AP and creating the bss
1083 */
1084 IEEE80211_LINKED,
1085
1086 /* same as LINKED, but the driver shall apply RX filter
1087 * rules as we are in NO_LINK mode. As the card is still
1088 * logically linked, but it is doing a syncro site survey
1089 * then it will be back to LINKED state.
1090 */
1091 IEEE80211_LINKED_SCANNING,
1092
1093};
1094
1095#define DEFAULT_MAX_SCAN_AGE (15 * HZ)
1096#define DEFAULT_FTS 2346
1097#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
1098#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
1099
1100
1101#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,11))
1102extern inline int is_multicast_ether_addr(const u8 *addr)
1103{
1104 return ((addr[0] != 0xff) && (0x01 & addr[0]));
1105}
1106#endif
1107
1108#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,13))
1109extern inline int is_broadcast_ether_addr(const u8 *addr)
1110{
1111 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) && \
1112 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
1113}
1114#endif
1115
1116#define CFG_IEEE80211_RESERVE_FCS (1<<0)
1117#define CFG_IEEE80211_COMPUTE_FCS (1<<1)
1118
1119typedef struct tx_pending_t{
1120 int frag;
1121 struct ieee80211_txb *txb;
1122}tx_pending_t;
1123
1124
1125struct ieee80211_device {
1126 struct net_device *dev;
1127
1128 /* Bookkeeping structures */
1129 struct net_device_stats stats;
1130 struct ieee80211_stats ieee_stats;
1131 struct ieee80211_softmac_stats softmac_stats;
1132
1133 /* Probe / Beacon management */
1134 struct list_head network_free_list;
1135 struct list_head network_list;
1136 struct ieee80211_network *networks;
1137 int scans;
1138 int scan_age;
1139
1140 int iw_mode; /* operating mode (IW_MODE_*) */
1141
1142 spinlock_t lock;
1143 spinlock_t wpax_suitlist_lock;
1144
1145 int tx_headroom; /* Set to size of any additional room needed at front
1146 * of allocated Tx SKBs */
1147 u32 config;
1148
1149 /* WEP and other encryption related settings at the device level */
1150 int open_wep; /* Set to 1 to allow unencrypted frames */
1151
1152 int reset_on_keychange; /* Set to 1 if the HW needs to be reset on
1153 * WEP key changes */
1154
1155 /* If the host performs {en,de}cryption, then set to 1 */
1156 int host_encrypt;
1157 int host_decrypt;
1158 int ieee802_1x; /* is IEEE 802.1X used */
1159
1160 /* WPA data */
1161 int wpa_enabled;
1162 int drop_unencrypted;
1163 int tkip_countermeasures;
1164 int privacy_invoked;
1165 size_t wpa_ie_len;
1166 u8 *wpa_ie;
1167
1168 u8 ap_mac_addr[6];
1169 u16 pairwise_key_type;
1170 u16 broadcast_key_type;
1171
1172 struct list_head crypt_deinit_list;
1173 struct ieee80211_crypt_data *crypt[WEP_KEYS];
1174 int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */
1175 struct timer_list crypt_deinit_timer;
1176
1177 int bcrx_sta_key; /* use individual keys to override default keys even
1178 * with RX of broad/multicast frames */
1179
1180 /* Fragmentation structures */
1181 // each streaming contain a entry
1182 struct ieee80211_frag_entry frag_cache[17][IEEE80211_FRAG_CACHE_LEN];
1183 unsigned int frag_next_idx[17];
1184 u16 fts; /* Fragmentation Threshold */
1185
1186 /* This stores infos for the current network.
1187 * Either the network we are associated in INFRASTRUCTURE
1188 * or the network that we are creating in MASTER mode.
1189 * ad-hoc is a mixture ;-).
1190 * Note that in infrastructure mode, even when not associated,
1191 * fields bssid and essid may be valid (if wpa_set and essid_set
1192 * are true) as thy carry the value set by the user via iwconfig
1193 */
1194 struct ieee80211_network current_network;
1195
1196
1197 enum ieee80211_state state;
1198
1199 int short_slot;
1200 int mode; /* A, B, G */
1201 int modulation; /* CCK, OFDM */
1202 int freq_band; /* 2.4Ghz, 5.2Ghz, Mixed */
1203 int abg_true; /* ABG flag */
1204
1205 /* used for forcing the ibss workqueue to terminate
1206 * without wait for the syncro scan to terminate
1207 */
1208 short sync_scan_hurryup;
1209
1210#ifdef ENABLE_DOT11D
1211 void * pDot11dInfo;
1212 bool bGlobalDomain;
1213
1214 // For Liteon Ch12~13 passive scan
1215 u8 MinPassiveChnlNum;
1216 u8 IbssStartChnl;
1217#else
1218 /* map of allowed channels. 0 is dummy */
1219 // FIXME: remeber to default to a basic channel plan depending of the PHY type
1220 int channel_map[MAX_CHANNEL_NUMBER+1];
1221#endif
1222
1223 int rate; /* current rate */
1224 int basic_rate;
1225 //FIXME: pleace callback, see if redundant with softmac_features
1226 short active_scan;
1227
1228 /* this contains flags for selectively enable softmac support */
1229 u16 softmac_features;
1230
1231 /* if the sequence control field is not filled by HW */
1232 u16 seq_ctrl[5];
1233
1234 /* association procedure transaction sequence number */
1235 u16 associate_seq;
1236
1237 /* AID for RTXed association responses */
1238 u16 assoc_id;
1239
1240 /* power save mode related*/
1241 short ps;
1242 short sta_sleep;
1243 int ps_timeout;
1244 struct tasklet_struct ps_task;
1245 u32 ps_th;
1246 u32 ps_tl;
1247
1248 short raw_tx;
1249 /* used if IEEE_SOFTMAC_TX_QUEUE is set */
1250 short queue_stop;
1251 short scanning;
1252 short proto_started;
1253
1254 struct semaphore wx_sem;
1255 struct semaphore scan_sem;
1256
1257 spinlock_t mgmt_tx_lock;
1258 spinlock_t beacon_lock;
1259
1260 short beacon_txing;
1261
1262 short wap_set;
1263 short ssid_set;
1264
1265 u8 wpax_type_set; //{added by David, 2006.9.28}
1266 u32 wpax_type_notify; //{added by David, 2006.9.26}
1267
1268 /* QoS related flag */
1269 char init_wmmparam_flag;
1270
1271 /* for discarding duplicated packets in IBSS */
1272 struct list_head ibss_mac_hash[IEEE_IBSS_MAC_HASH_SIZE];
1273
1274 /* for discarding duplicated packets in BSS */
1275 u16 last_rxseq_num[17]; /* rx seq previous per-tid */
1276 u16 last_rxfrag_num[17];/* tx frag previous per-tid */
1277 unsigned long last_packet_time[17];
1278
1279 /* for PS mode */
1280 unsigned long last_rx_ps_time;
1281
1282 /* used if IEEE_SOFTMAC_SINGLE_QUEUE is set */
1283 struct sk_buff *mgmt_queue_ring[MGMT_QUEUE_NUM];
1284 int mgmt_queue_head;
1285 int mgmt_queue_tail;
1286
1287
1288 /* used if IEEE_SOFTMAC_TX_QUEUE is set */
1289 struct tx_pending_t tx_pending;
1290
1291 /* used if IEEE_SOFTMAC_ASSOCIATE is set */
1292 struct timer_list associate_timer;
1293
1294 /* used if IEEE_SOFTMAC_BEACONS is set */
1295 struct timer_list beacon_timer;
1296
1297 struct work_struct associate_complete_wq;
1298// struct work_struct associate_retry_wq;
1299 struct work_struct associate_procedure_wq;
1300// struct work_struct softmac_scan_wq;
1301 struct work_struct wx_sync_scan_wq;
1302 struct work_struct wmm_param_update_wq;
1303 struct work_struct ps_request_tx_ack_wq;//for ps
1304// struct work_struct hw_wakeup_wq;
1305// struct work_struct hw_sleep_wq;
1306// struct work_struct watch_dog_wq;
1307 bool bInactivePs;
1308 bool actscanning;
1309 bool beinretry;
1310 u16 ListenInterval;
1311 unsigned long NumRxDataInPeriod; //YJ,add,080828
1312 unsigned long NumRxBcnInPeriod; //YJ,add,080828
1313 unsigned long NumRxOkTotal;
1314 unsigned long NumRxUnicast;//YJ,add,080828,for keep alive
1315 bool bHwRadioOff;
1316#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
1317 struct delayed_work softmac_scan_wq;
1318 struct delayed_work associate_retry_wq;
1319 struct delayed_work hw_wakeup_wq;
1320 struct delayed_work hw_sleep_wq;//+by amy 080324
1321 struct delayed_work watch_dog_wq;
1322 struct delayed_work sw_antenna_wq;
1323 struct delayed_work start_ibss_wq;
1324//by amy for rate adaptive 080312
1325 struct delayed_work rate_adapter_wq;
1326//by amy for rate adaptive
1327 struct delayed_work hw_dig_wq;
1328 struct delayed_work tx_pw_wq;
1329
1330//Added for RF power on power off by lizhaoming 080512
1331 struct delayed_work GPIOChangeRFWorkItem;
1332#else
1333
1334 struct work_struct start_ibss_wq;
1335 struct work_struct softmac_scan_wq;
1336 struct work_struct associate_retry_wq;
1337 struct work_struct hw_wakeup_wq;
1338 struct work_struct hw_sleep_wq;
1339 struct work_struct watch_dog_wq;
1340 struct work_struct sw_antenna_wq;
1341//by amy for rate adaptive 080312
1342 struct work_struct rate_adapter_wq;
1343//by amy for rate adaptive
1344 struct work_struct hw_dig_wq;
1345 struct work_struct tx_pw_wq;
1346
1347//Added for RF power on power off by lizhaoming 080512
1348 struct work_struct GPIOChangeRFWorkItem;
1349#endif
1350 struct workqueue_struct *wq;
1351
1352 /* Callback functions */
1353 void (*set_security)(struct net_device *dev,
1354 struct ieee80211_security *sec);
1355
1356 /* Used to TX data frame by using txb structs.
1357 * this is not used if in the softmac_features
1358 * is set the flag IEEE_SOFTMAC_TX_QUEUE
1359 */
1360 int (*hard_start_xmit)(struct ieee80211_txb *txb,
1361 struct net_device *dev);
1362
1363 int (*reset_port)(struct net_device *dev);
1364
1365 /* Softmac-generated frames (mamagement) are TXed via this
1366 * callback if the flag IEEE_SOFTMAC_SINGLE_QUEUE is
1367 * not set. As some cards may have different HW queues that
1368 * one might want to use for data and management frames
1369 * the option to have two callbacks might be useful.
1370 * This fucntion can't sleep.
1371 */
1372 int (*softmac_hard_start_xmit)(struct sk_buff *skb,
1373 struct net_device *dev);
1374
1375 /* used instead of hard_start_xmit (not softmac_hard_start_xmit)
1376 * if the IEEE_SOFTMAC_TX_QUEUE feature is used to TX data
1377 * frames. I the option IEEE_SOFTMAC_SINGLE_QUEUE is also set
1378 * then also management frames are sent via this callback.
1379 * This function can't sleep.
1380 */
1381 void (*softmac_data_hard_start_xmit)(struct sk_buff *skb,
1382 struct net_device *dev,int rate);
1383
1384 /* stops the HW queue for DATA frames. Useful to avoid
1385 * waste time to TX data frame when we are reassociating
1386 * This function can sleep.
1387 */
1388 void (*data_hard_stop)(struct net_device *dev);
1389
1390 /* OK this is complementar to data_poll_hard_stop */
1391 void (*data_hard_resume)(struct net_device *dev);
1392
1393 /* ask to the driver to retune the radio .
1394 * This function can sleep. the driver should ensure
1395 * the radio has been swithced before return.
1396 */
1397 void (*set_chan)(struct net_device *dev,short ch);
1398
1399 /* These are not used if the ieee stack takes care of
1400 * scanning (IEEE_SOFTMAC_SCAN feature set).
1401 * In this case only the set_chan is used.
1402 *
1403 * The syncro version is similar to the start_scan but
1404 * does not return until all channels has been scanned.
1405 * this is called in user context and should sleep,
1406 * it is called in a work_queue when swithcing to ad-hoc mode
1407 * or in behalf of iwlist scan when the card is associated
1408 * and root user ask for a scan.
1409 * the fucntion stop_scan should stop both the syncro and
1410 * background scanning and can sleep.
1411 * The fucntion start_scan should initiate the background
1412 * scanning and can't sleep.
1413 */
1414 void (*scan_syncro)(struct net_device *dev);
1415 void (*start_scan)(struct net_device *dev);
1416 void (*stop_scan)(struct net_device *dev);
1417
1418 /* indicate the driver that the link state is changed
1419 * for example it may indicate the card is associated now.
1420 * Driver might be interested in this to apply RX filter
1421 * rules or simply light the LINK led
1422 */
1423 void (*link_change)(struct net_device *dev);
1424
1425 /* these two function indicates to the HW when to start
1426 * and stop to send beacons. This is used when the
1427 * IEEE_SOFTMAC_BEACONS is not set. For now the
1428 * stop_send_bacons is NOT guaranteed to be called only
1429 * after start_send_beacons.
1430 */
1431 void (*start_send_beacons) (struct net_device *dev);
1432 void (*stop_send_beacons) (struct net_device *dev);
1433
1434 /* power save mode related */
1435 void (*sta_wake_up) (struct net_device *dev);
1436 void (*ps_request_tx_ack) (struct net_device *dev);
1437 void (*enter_sleep_state) (struct net_device *dev, u32 th, u32 tl);
1438 short (*ps_is_queue_empty) (struct net_device *dev);
1439
1440 /* QoS related */
1441 //void (*wmm_param_update) (struct net_device *dev, u8 *ac_param);
1442 //void (*wmm_param_update) (struct ieee80211_device *ieee);
1443
1444 /* This must be the last item so that it points to the data
1445 * allocated beyond this structure by alloc_ieee80211 */
1446 u8 priv[0];
1447};
1448
1449#define IEEE_A (1<<0)
1450#define IEEE_B (1<<1)
1451#define IEEE_G (1<<2)
1452#define IEEE_MODE_MASK (IEEE_A|IEEE_B|IEEE_G)
1453
1454/* Generate a 802.11 header */
1455
1456/* Uses the channel change callback directly
1457 * instead of [start/stop] scan callbacks
1458 */
1459#define IEEE_SOFTMAC_SCAN (1<<2)
1460
1461/* Perform authentication and association handshake */
1462#define IEEE_SOFTMAC_ASSOCIATE (1<<3)
1463
1464/* Generate probe requests */
1465#define IEEE_SOFTMAC_PROBERQ (1<<4)
1466
1467/* Generate respones to probe requests */
1468#define IEEE_SOFTMAC_PROBERS (1<<5)
1469
1470/* The ieee802.11 stack will manages the netif queue
1471 * wake/stop for the driver, taking care of 802.11
1472 * fragmentation. See softmac.c for details. */
1473#define IEEE_SOFTMAC_TX_QUEUE (1<<7)
1474
1475/* Uses only the softmac_data_hard_start_xmit
1476 * even for TX management frames.
1477 */
1478#define IEEE_SOFTMAC_SINGLE_QUEUE (1<<8)
1479
1480/* Generate beacons. The stack will enqueue beacons
1481 * to the card
1482 */
1483#define IEEE_SOFTMAC_BEACONS (1<<6)
1484
1485
1486
1487static inline void *ieee80211_priv(struct net_device *dev)
1488{
1489 return ((struct ieee80211_device *)netdev_priv(dev))->priv;
1490}
1491
1492extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
1493{
1494 /* Single white space is for Linksys APs */
1495 if (essid_len == 1 && essid[0] == ' ')
1496 return 1;
1497
1498 /* Otherwise, if the entire essid is 0, we assume it is hidden */
1499 while (essid_len) {
1500 essid_len--;
1501 if (essid[essid_len] != '\0')
1502 return 0;
1503 }
1504
1505 return 1;
1506}
1507
1508extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode)
1509{
1510 /*
1511 * It is possible for both access points and our device to support
1512 * combinations of modes, so as long as there is one valid combination
1513 * of ap/device supported modes, then return success
1514 *
1515 */
1516 if ((mode & IEEE_A) &&
1517 (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
1518 (ieee->freq_band & IEEE80211_52GHZ_BAND))
1519 return 1;
1520
1521 if ((mode & IEEE_G) &&
1522 (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
1523 (ieee->freq_band & IEEE80211_24GHZ_BAND))
1524 return 1;
1525
1526 if ((mode & IEEE_B) &&
1527 (ieee->modulation & IEEE80211_CCK_MODULATION) &&
1528 (ieee->freq_band & IEEE80211_24GHZ_BAND))
1529 return 1;
1530
1531 return 0;
1532}
1533
1534extern inline int ieee80211_get_hdrlen(u16 fc)
1535{
1536 int hdrlen = 24;
1537
1538 switch (WLAN_FC_GET_TYPE(fc)) {
1539 case IEEE80211_FTYPE_DATA:
1540 if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
1541 hdrlen = 30; /* Addr4 */
1542 if(IEEE80211_QOS_HAS_SEQ(fc))
1543 hdrlen += 2; /* QOS ctrl*/
1544 break;
1545 case IEEE80211_FTYPE_CTL:
1546 switch (WLAN_FC_GET_STYPE(fc)) {
1547 case IEEE80211_STYPE_CTS:
1548 case IEEE80211_STYPE_ACK:
1549 hdrlen = 10;
1550 break;
1551 default:
1552 hdrlen = 16;
1553 break;
1554 }
1555 break;
1556 }
1557
1558 return hdrlen;
1559}
1560
1561
1562
1563/* ieee80211.c */
1564extern void free_ieee80211(struct net_device *dev);
1565extern struct net_device *alloc_ieee80211(int sizeof_priv);
1566
1567extern int ieee80211_set_encryption(struct ieee80211_device *ieee);
1568
1569/* ieee80211_tx.c */
1570
1571extern int ieee80211_encrypt_fragment(
1572 struct ieee80211_device *ieee,
1573 struct sk_buff *frag,
1574 int hdr_len);
1575
1576extern int ieee80211_xmit(struct sk_buff *skb,
1577 struct net_device *dev);
1578extern void ieee80211_txb_free(struct ieee80211_txb *);
1579
1580
1581/* ieee80211_rx.c */
1582extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
1583 struct ieee80211_rx_stats *rx_stats);
1584extern void ieee80211_rx_mgt(struct ieee80211_device *ieee,
1585 struct ieee80211_hdr *header,
1586 struct ieee80211_rx_stats *stats);
1587
1588/* ieee80211_wx.c */
1589extern int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
1590 struct iw_request_info *info,
1591 union iwreq_data *wrqu, char *key);
1592extern int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
1593 struct iw_request_info *info,
1594 union iwreq_data *wrqu, char *key);
1595extern int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
1596 struct iw_request_info *info,
1597 union iwreq_data *wrqu, char *key);
1598extern int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
1599 struct iw_request_info *info,
1600 union iwreq_data* wrqu, char *extra);
1601int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
1602 struct iw_request_info *info,
1603 struct iw_param *data, char *extra);
1604int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
1605 struct iw_request_info *info,
1606 union iwreq_data *wrqu, char *extra);
1607
1608int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len);
1609/* ieee80211_softmac.c */
1610extern short ieee80211_is_54g(struct ieee80211_network net);
1611extern short ieee80211_is_shortslot(struct ieee80211_network net);
1612extern int ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
1613 struct ieee80211_rx_stats *rx_stats, u16 type,
1614 u16 stype);
1615extern void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net);
1616
1617extern void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee);
1618extern void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee);
1619extern void ieee80211_start_bss(struct ieee80211_device *ieee);
1620extern void ieee80211_start_master_bss(struct ieee80211_device *ieee);
1621extern void ieee80211_start_ibss(struct ieee80211_device *ieee);
1622extern void ieee80211_softmac_init(struct ieee80211_device *ieee);
1623extern void ieee80211_softmac_free(struct ieee80211_device *ieee);
1624extern void ieee80211_associate_abort(struct ieee80211_device *ieee);
1625extern void ieee80211_disassociate(struct ieee80211_device *ieee);
1626extern void ieee80211_stop_scan(struct ieee80211_device *ieee);
1627extern void ieee80211_start_scan_syncro(struct ieee80211_device *ieee);
1628extern void ieee80211_check_all_nets(struct ieee80211_device *ieee);
1629extern void ieee80211_start_protocol(struct ieee80211_device *ieee);
1630extern void ieee80211_stop_protocol(struct ieee80211_device *ieee);
1631extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee);
1632extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee);
1633extern void ieee80211_reset_queue(struct ieee80211_device *ieee);
1634extern void ieee80211_wake_queue(struct ieee80211_device *ieee);
1635extern void ieee80211_stop_queue(struct ieee80211_device *ieee);
1636extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee);
1637extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee);
1638extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee);
1639extern int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p);
1640extern void notify_wx_assoc_event(struct ieee80211_device *ieee);
1641extern void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success);
1642extern void SendDisassociation(struct ieee80211_device *ieee,u8* asSta,u8 asRsn);
1643extern void ieee80211_start_scan(struct ieee80211_device *ieee);
1644
1645//Add for RF power on power off by lizhaoming 080512
1646extern void SendDisassociation(struct ieee80211_device *ieee,
1647 u8* asSta,
1648 u8 asRsn);
1649
1650/* ieee80211_crypt_ccmp&tkip&wep.c */
1651extern void ieee80211_tkip_null(void);
1652extern void ieee80211_wep_null(void);
1653extern void ieee80211_ccmp_null(void);
1654/* ieee80211_softmac_wx.c */
1655
1656extern int ieee80211_wx_get_wap(struct ieee80211_device *ieee,
1657 struct iw_request_info *info,
1658 union iwreq_data *wrqu, char *ext);
1659
1660extern int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
1661 struct iw_request_info *info,
1662 union iwreq_data *awrq,
1663 char *extra);
1664
1665extern int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b);
1666
1667extern int ieee80211_wx_set_rate(struct ieee80211_device *ieee,
1668 struct iw_request_info *info,
1669 union iwreq_data *wrqu, char *extra);
1670
1671extern int ieee80211_wx_get_rate(struct ieee80211_device *ieee,
1672 struct iw_request_info *info,
1673 union iwreq_data *wrqu, char *extra);
1674
1675extern int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
1676 union iwreq_data *wrqu, char *b);
1677
1678extern int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a,
1679 union iwreq_data *wrqu, char *b);
1680
1681extern int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
1682 struct iw_request_info *a,
1683 union iwreq_data *wrqu, char *extra);
1684
1685extern int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
1686 union iwreq_data *wrqu, char *b);
1687
1688extern int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
1689 union iwreq_data *wrqu, char *b);
1690
1691extern int ieee80211_wx_get_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
1692 union iwreq_data *wrqu, char *b);
1693#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
1694extern void ieee80211_wx_sync_scan_wq(struct work_struct *work);
1695#else
1696 extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee);
1697#endif
1698//extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee);
1699
1700extern int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee,
1701 struct iw_request_info *info,
1702 union iwreq_data *wrqu, char *extra);
1703
1704extern int ieee80211_wx_get_name(struct ieee80211_device *ieee,
1705 struct iw_request_info *info,
1706 union iwreq_data *wrqu, char *extra);
1707
1708extern int ieee80211_wx_set_power(struct ieee80211_device *ieee,
1709 struct iw_request_info *info,
1710 union iwreq_data *wrqu, char *extra);
1711
1712extern int ieee80211_wx_get_power(struct ieee80211_device *ieee,
1713 struct iw_request_info *info,
1714 union iwreq_data *wrqu, char *extra);
1715
1716extern void ieee80211_softmac_ips_scan_syncro(struct ieee80211_device *ieee);
1717
1718extern void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr);
1719
1720extern const long ieee80211_wlan_frequencies[];
1721
1722extern inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
1723{
1724 ieee->scans++;
1725}
1726
1727extern inline int ieee80211_get_scans(struct ieee80211_device *ieee)
1728{
1729 return ieee->scans;
1730}
1731
1732static inline const char *escape_essid(const char *essid, u8 essid_len) {
1733 static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
1734 const char *s = essid;
1735 char *d = escaped;
1736
1737 if (ieee80211_is_empty_essid(essid, essid_len)) {
1738 memcpy(escaped, "<hidden>", sizeof("<hidden>"));
1739 return escaped;
1740 }
1741
1742 essid_len = min(essid_len, (u8)IW_ESSID_MAX_SIZE);
1743 while (essid_len--) {
1744 if (*s == '\0') {
1745 *d++ = '\\';
1746 *d++ = '0';
1747 s++;
1748 } else {
1749 *d++ = *s++;
1750 }
1751 }
1752 *d = '\0';
1753 return escaped;
1754}
1755#endif /* IEEE80211_H */
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c
new file mode 100644
index 000000000000..af64cfbe16db
--- /dev/null
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c
@@ -0,0 +1,265 @@
1/*
2 * Host AP crypto routines
3 *
4 * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
5 * Portions Copyright (C) 2004, Intel Corporation <jketreno@linux.intel.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation. See README and COPYING for
10 * more details.
11 *
12 */
13
14//#include <linux/config.h>
15#include <linux/version.h>
16#include <linux/module.h>
17#include <linux/init.h>
18#include <linux/slab.h>
19#include <asm/string.h>
20#include <asm/errno.h>
21
22#if (LINUX_VERSION_CODE<KERNEL_VERSION(2,6,18))
23#include<linux/config.h>
24#endif
25
26#include "ieee80211.h"
27
28MODULE_AUTHOR("Jouni Malinen");
29MODULE_DESCRIPTION("HostAP crypto");
30MODULE_LICENSE("GPL");
31
32struct ieee80211_crypto_alg {
33 struct list_head list;
34 struct ieee80211_crypto_ops *ops;
35};
36
37
38struct ieee80211_crypto {
39 struct list_head algs;
40 spinlock_t lock;
41};
42
43static struct ieee80211_crypto *hcrypt;
44
45void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee,
46 int force)
47{
48 struct list_head *ptr, *n;
49 struct ieee80211_crypt_data *entry;
50
51 for (ptr = ieee->crypt_deinit_list.next, n = ptr->next;
52 ptr != &ieee->crypt_deinit_list; ptr = n, n = ptr->next) {
53 entry = list_entry(ptr, struct ieee80211_crypt_data, list);
54
55 if (atomic_read(&entry->refcnt) != 0 && !force)
56 continue;
57
58 list_del(ptr);
59
60 if (entry->ops) {
61 entry->ops->deinit(entry->priv);
62 module_put(entry->ops->owner);
63 }
64 kfree(entry);
65 }
66}
67
68void ieee80211_crypt_deinit_handler(unsigned long data)
69{
70 struct ieee80211_device *ieee = (struct ieee80211_device *)data;
71 unsigned long flags;
72
73 spin_lock_irqsave(&ieee->lock, flags);
74 ieee80211_crypt_deinit_entries(ieee, 0);
75 if (!list_empty(&ieee->crypt_deinit_list)) {
76 printk(KERN_DEBUG "%s: entries remaining in delayed crypt "
77 "deletion list\n", ieee->dev->name);
78 ieee->crypt_deinit_timer.expires = jiffies + HZ;
79 add_timer(&ieee->crypt_deinit_timer);
80 }
81 spin_unlock_irqrestore(&ieee->lock, flags);
82
83}
84
85void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
86 struct ieee80211_crypt_data **crypt)
87{
88 struct ieee80211_crypt_data *tmp;
89 unsigned long flags;
90
91 if (*crypt == NULL)
92 return;
93
94 tmp = *crypt;
95 *crypt = NULL;
96
97 /* must not run ops->deinit() while there may be pending encrypt or
98 * decrypt operations. Use a list of delayed deinits to avoid needing
99 * locking. */
100
101 spin_lock_irqsave(&ieee->lock, flags);
102 list_add(&tmp->list, &ieee->crypt_deinit_list);
103 if (!timer_pending(&ieee->crypt_deinit_timer)) {
104 ieee->crypt_deinit_timer.expires = jiffies + HZ;
105 add_timer(&ieee->crypt_deinit_timer);
106 }
107 spin_unlock_irqrestore(&ieee->lock, flags);
108}
109
110int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops)
111{
112 unsigned long flags;
113 struct ieee80211_crypto_alg *alg;
114
115 if (hcrypt == NULL)
116 return -1;
117
118 alg = kmalloc(sizeof(*alg), GFP_KERNEL);
119 if (alg == NULL)
120 return -ENOMEM;
121
122 memset(alg, 0, sizeof(*alg));
123 alg->ops = ops;
124
125 spin_lock_irqsave(&hcrypt->lock, flags);
126 list_add(&alg->list, &hcrypt->algs);
127 spin_unlock_irqrestore(&hcrypt->lock, flags);
128
129 printk(KERN_DEBUG "ieee80211_crypt: registered algorithm '%s'\n",
130 ops->name);
131
132 return 0;
133}
134
135int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops)
136{
137 unsigned long flags;
138 struct list_head *ptr;
139 struct ieee80211_crypto_alg *del_alg = NULL;
140
141 if (hcrypt == NULL)
142 return -1;
143
144 spin_lock_irqsave(&hcrypt->lock, flags);
145 for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
146 struct ieee80211_crypto_alg *alg =
147 (struct ieee80211_crypto_alg *) ptr;
148 if (alg->ops == ops) {
149 list_del(&alg->list);
150 del_alg = alg;
151 break;
152 }
153 }
154 spin_unlock_irqrestore(&hcrypt->lock, flags);
155
156 if (del_alg) {
157 printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
158 "'%s'\n", ops->name);
159 kfree(del_alg);
160 }
161
162 return del_alg ? 0 : -1;
163}
164
165
166struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name)
167{
168 unsigned long flags;
169 struct list_head *ptr;
170 struct ieee80211_crypto_alg *found_alg = NULL;
171
172 if (hcrypt == NULL)
173 return NULL;
174
175 spin_lock_irqsave(&hcrypt->lock, flags);
176 for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
177 struct ieee80211_crypto_alg *alg =
178 (struct ieee80211_crypto_alg *) ptr;
179 if (strcmp(alg->ops->name, name) == 0) {
180 found_alg = alg;
181 break;
182 }
183 }
184 spin_unlock_irqrestore(&hcrypt->lock, flags);
185
186 if (found_alg)
187 return found_alg->ops;
188 else
189 return NULL;
190}
191
192
193static void * ieee80211_crypt_null_init(int keyidx) { return (void *) 1; }
194static void ieee80211_crypt_null_deinit(void *priv) {}
195
196static struct ieee80211_crypto_ops ieee80211_crypt_null = {
197 .name = "NULL",
198 .init = ieee80211_crypt_null_init,
199 .deinit = ieee80211_crypt_null_deinit,
200 .encrypt_mpdu = NULL,
201 .decrypt_mpdu = NULL,
202 .encrypt_msdu = NULL,
203 .decrypt_msdu = NULL,
204 .set_key = NULL,
205 .get_key = NULL,
206 .extra_prefix_len = 0,
207 .extra_postfix_len = 0,
208 .owner = THIS_MODULE,
209};
210
211
212int ieee80211_crypto_init(void)
213{
214 int ret = -ENOMEM;
215
216 hcrypt = kmalloc(sizeof(*hcrypt), GFP_KERNEL);
217 if (!hcrypt)
218 goto out;
219
220 memset(hcrypt, 0, sizeof(*hcrypt));
221 INIT_LIST_HEAD(&hcrypt->algs);
222 spin_lock_init(&hcrypt->lock);
223
224 ret = ieee80211_register_crypto_ops(&ieee80211_crypt_null);
225 if (ret < 0) {
226 kfree(hcrypt);
227 hcrypt = NULL;
228 }
229out:
230 return ret;
231}
232
233
234void ieee80211_crypto_deinit(void)
235{
236 struct list_head *ptr, *n;
237
238 if (hcrypt == NULL)
239 return;
240
241 for (ptr = hcrypt->algs.next, n = ptr->next; ptr != &hcrypt->algs;
242 ptr = n, n = ptr->next) {
243 struct ieee80211_crypto_alg *alg =
244 (struct ieee80211_crypto_alg *) ptr;
245 list_del(ptr);
246 printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
247 "'%s' (deinit)\n", alg->ops->name);
248 kfree(alg);
249 }
250
251 kfree(hcrypt);
252}
253
254#if 0
255EXPORT_SYMBOL(ieee80211_crypt_deinit_entries);
256EXPORT_SYMBOL(ieee80211_crypt_deinit_handler);
257EXPORT_SYMBOL(ieee80211_crypt_delayed_deinit);
258
259EXPORT_SYMBOL(ieee80211_register_crypto_ops);
260EXPORT_SYMBOL(ieee80211_unregister_crypto_ops);
261EXPORT_SYMBOL(ieee80211_get_crypto_ops);
262#endif
263
264//module_init(ieee80211_crypto_init);
265//module_exit(ieee80211_crypto_deinit);
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.h b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.h
new file mode 100644
index 000000000000..b58a3bcc0dc0
--- /dev/null
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.h
@@ -0,0 +1,86 @@
1/*
2 * Original code based on Host AP (software wireless LAN access point) driver
3 * for Intersil Prism2/2.5/3.
4 *
5 * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
6 * <jkmaline@cc.hut.fi>
7 * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
8 *
9 * Adaption to a generic IEEE 802.11 stack by James Ketrenos
10 * <jketreno@linux.intel.com>
11 *
12 * Copyright (c) 2004, Intel Corporation
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation. See README and COPYING for
17 * more details.
18 */
19
20/*
21 * This file defines the interface to the ieee80211 crypto module.
22 */
23#ifndef IEEE80211_CRYPT_H
24#define IEEE80211_CRYPT_H
25
26#include <linux/skbuff.h>
27
28struct ieee80211_crypto_ops {
29 const char *name;
30
31 /* init new crypto context (e.g., allocate private data space,
32 * select IV, etc.); returns NULL on failure or pointer to allocated
33 * private data on success */
34 void * (*init)(int keyidx);
35
36 /* deinitialize crypto context and free allocated private data */
37 void (*deinit)(void *priv);
38
39 /* encrypt/decrypt return < 0 on error or >= 0 on success. The return
40 * value from decrypt_mpdu is passed as the keyidx value for
41 * decrypt_msdu. skb must have enough head and tail room for the
42 * encryption; if not, error will be returned; these functions are
43 * called for all MPDUs (i.e., fragments).
44 */
45 int (*encrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
46 int (*decrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
47
48 /* These functions are called for full MSDUs, i.e. full frames.
49 * These can be NULL if full MSDU operations are not needed. */
50 int (*encrypt_msdu)(struct sk_buff *skb, int hdr_len, void *priv);
51 int (*decrypt_msdu)(struct sk_buff *skb, int keyidx, int hdr_len,
52 void *priv);
53
54 int (*set_key)(void *key, int len, u8 *seq, void *priv);
55 int (*get_key)(void *key, int len, u8 *seq, void *priv);
56
57 /* procfs handler for printing out key information and possible
58 * statistics */
59 char * (*print_stats)(char *p, void *priv);
60
61 /* maximum number of bytes added by encryption; encrypt buf is
62 * allocated with extra_prefix_len bytes, copy of in_buf, and
63 * extra_postfix_len; encrypt need not use all this space, but
64 * the result must start at the beginning of the buffer and correct
65 * length must be returned */
66 int extra_prefix_len, extra_postfix_len;
67
68 struct module *owner;
69};
70
71struct ieee80211_crypt_data {
72 struct list_head list; /* delayed deletion list */
73 struct ieee80211_crypto_ops *ops;
74 void *priv;
75 atomic_t refcnt;
76};
77
78int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops);
79int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops);
80struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name);
81void ieee80211_crypt_deinit_entries(struct ieee80211_device *, int);
82void ieee80211_crypt_deinit_handler(unsigned long);
83void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
84 struct ieee80211_crypt_data **crypt);
85
86#endif
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c
new file mode 100644
index 000000000000..7d890c328b0e
--- /dev/null
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c
@@ -0,0 +1,533 @@
1/*
2 * Host AP crypt: host-based CCMP encryption implementation for Host AP driver
3 *
4 * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation. See README and COPYING for
9 * more details.
10 */
11
12//#include <linux/config.h>
13#include <linux/version.h>
14#include <linux/module.h>
15#include <linux/init.h>
16#include <linux/slab.h>
17#include <linux/random.h>
18#include <linux/skbuff.h>
19#include <linux/netdevice.h>
20#include <linux/if_ether.h>
21#include <linux/if_arp.h>
22#include <asm/string.h>
23#include <linux/wireless.h>
24
25#include "ieee80211.h"
26
27#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
28#include "rtl_crypto.h"
29#else
30#include <linux/crypto.h>
31#endif
32#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
33 #include <asm/scatterlist.h>
34#else
35 #include <linux/scatterlist.h>
36#endif
37
38//#include <asm/scatterlist.h>
39
40MODULE_AUTHOR("Jouni Malinen");
41MODULE_DESCRIPTION("Host AP crypt: CCMP");
42MODULE_LICENSE("GPL");
43
44#ifdef OPENSUSE_SLED
45#ifndef IN_OPENSUSE_SLED
46#define IN_OPENSUSE_SLED 1
47#endif
48#endif
49
50#define AES_BLOCK_LEN 16
51#define CCMP_HDR_LEN 8
52#define CCMP_MIC_LEN 8
53#define CCMP_TK_LEN 16
54#define CCMP_PN_LEN 6
55
56struct ieee80211_ccmp_data {
57 u8 key[CCMP_TK_LEN];
58 int key_set;
59
60 u8 tx_pn[CCMP_PN_LEN];
61 u8 rx_pn[CCMP_PN_LEN];
62
63 u32 dot11RSNAStatsCCMPFormatErrors;
64 u32 dot11RSNAStatsCCMPReplays;
65 u32 dot11RSNAStatsCCMPDecryptErrors;
66
67 int key_idx;
68
69 struct crypto_tfm *tfm;
70
71 /* scratch buffers for virt_to_page() (crypto API) */
72 u8 tx_b0[AES_BLOCK_LEN], tx_b[AES_BLOCK_LEN],
73 tx_e[AES_BLOCK_LEN], tx_s0[AES_BLOCK_LEN];
74 u8 rx_b0[AES_BLOCK_LEN], rx_b[AES_BLOCK_LEN], rx_a[AES_BLOCK_LEN];
75};
76
77void ieee80211_ccmp_aes_encrypt(struct crypto_tfm *tfm,
78 const u8 pt[16], u8 ct[16])
79{
80 #if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))||(IN_OPENSUSE_SLED))
81 crypto_cipher_encrypt_one((void *)tfm, ct, pt);
82 #else
83 struct scatterlist src, dst;
84
85 src.page = virt_to_page(pt);
86 src.offset = offset_in_page(pt);
87 src.length = AES_BLOCK_LEN;
88
89 dst.page = virt_to_page(ct);
90 dst.offset = offset_in_page(ct);
91 dst.length = AES_BLOCK_LEN;
92
93 crypto_cipher_encrypt(tfm, &dst, &src, AES_BLOCK_LEN);
94 #endif
95}
96
97static void * ieee80211_ccmp_init(int key_idx)
98{
99 struct ieee80211_ccmp_data *priv;
100
101 priv = kmalloc(sizeof(*priv), GFP_ATOMIC);
102 if (priv == NULL)
103 goto fail;
104 memset(priv, 0, sizeof(*priv));
105 priv->key_idx = key_idx;
106
107 #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!IN_OPENSUSE_SLED))
108 priv->tfm = crypto_alloc_tfm("aes", 0);
109 if (priv->tfm == NULL) {
110 printk(KERN_DEBUG "ieee80211_crypt_ccmp: could not allocate "
111 "crypto API aes\n");
112 goto fail;
113 }
114 #else
115 priv->tfm = (void *)crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
116 if (IS_ERR(priv->tfm)) {
117 printk(KERN_DEBUG "ieee80211_crypt_ccmp: could not allocate "
118 "crypto API aes\n");
119 priv->tfm = NULL;
120 goto fail;
121 }
122 #endif
123 return priv;
124
125fail:
126 if (priv) {
127 if (priv->tfm)
128 //#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
129 #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!IN_OPENSUSE_SLED))
130 crypto_free_tfm(priv->tfm);
131 #else
132 crypto_free_cipher((void *)priv->tfm);
133 #endif
134 kfree(priv);
135 }
136
137 return NULL;
138}
139
140
141static void ieee80211_ccmp_deinit(void *priv)
142{
143 struct ieee80211_ccmp_data *_priv = priv;
144 if (_priv && _priv->tfm)
145 //#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
146 #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!IN_OPENSUSE_SLED))
147 crypto_free_tfm(_priv->tfm);
148 #else
149 crypto_free_cipher((void *)_priv->tfm);
150 #endif
151 kfree(priv);
152}
153
154
155static inline void xor_block(u8 *b, u8 *a, size_t len)
156{
157 int i;
158 for (i = 0; i < len; i++)
159 b[i] ^= a[i];
160}
161
162#ifndef JOHN_CCMP
163static void ccmp_init_blocks(struct crypto_tfm *tfm,
164 struct ieee80211_hdr *hdr,
165 u8 *pn, size_t dlen, u8 *b0, u8 *auth,
166 u8 *s0)
167{
168 u8 *pos, qc = 0;
169 size_t aad_len;
170 u16 fc;
171 int a4_included, qc_included;
172 u8 aad[2 * AES_BLOCK_LEN];
173
174 fc = le16_to_cpu(hdr->frame_ctl);
175 a4_included = ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
176 (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS));
177 /*
178 qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) &&
179 (WLAN_FC_GET_STYPE(fc) & 0x08));
180 */
181 // fixed by David :2006.9.6
182 qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) &&
183 (WLAN_FC_GET_STYPE(fc) & 0x80));
184 aad_len = 22;
185 if (a4_included)
186 aad_len += 6;
187 if (qc_included) {
188 pos = (u8 *) &hdr->addr4;
189 if (a4_included)
190 pos += 6;
191 qc = *pos & 0x0f;
192 aad_len += 2;
193 }
194 /* CCM Initial Block:
195 * Flag (Include authentication header, M=3 (8-octet MIC),
196 * L=1 (2-octet Dlen))
197 * Nonce: 0x00 | A2 | PN
198 * Dlen */
199 b0[0] = 0x59;
200 b0[1] = qc;
201 memcpy(b0 + 2, hdr->addr2, ETH_ALEN);
202 memcpy(b0 + 8, pn, CCMP_PN_LEN);
203 b0[14] = (dlen >> 8) & 0xff;
204 b0[15] = dlen & 0xff;
205
206 /* AAD:
207 * FC with bits 4..6 and 11..13 masked to zero; 14 is always one
208 * A1 | A2 | A3
209 * SC with bits 4..15 (seq#) masked to zero
210 * A4 (if present)
211 * QC (if present)
212 */
213 pos = (u8 *) hdr;
214 aad[0] = 0; /* aad_len >> 8 */
215 aad[1] = aad_len & 0xff;
216 aad[2] = pos[0] & 0x8f;
217 aad[3] = pos[1] & 0xc7;
218 memcpy(aad + 4, hdr->addr1, 3 * ETH_ALEN);
219 pos = (u8 *) &hdr->seq_ctl;
220 aad[22] = pos[0] & 0x0f;
221 aad[23] = 0; /* all bits masked */
222 memset(aad + 24, 0, 8);
223 if (a4_included)
224 memcpy(aad + 24, hdr->addr4, ETH_ALEN);
225 if (qc_included) {
226 aad[a4_included ? 30 : 24] = qc;
227 /* rest of QC masked */
228 }
229
230 /* Start with the first block and AAD */
231 ieee80211_ccmp_aes_encrypt(tfm, b0, auth);
232 xor_block(auth, aad, AES_BLOCK_LEN);
233 ieee80211_ccmp_aes_encrypt(tfm, auth, auth);
234 xor_block(auth, &aad[AES_BLOCK_LEN], AES_BLOCK_LEN);
235 ieee80211_ccmp_aes_encrypt(tfm, auth, auth);
236 b0[0] &= 0x07;
237 b0[14] = b0[15] = 0;
238 ieee80211_ccmp_aes_encrypt(tfm, b0, s0);
239}
240#endif
241
242static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
243{
244 struct ieee80211_ccmp_data *key = priv;
245 int data_len, i;
246 u8 *pos;
247 struct ieee80211_hdr *hdr;
248#ifndef JOHN_CCMP
249 int blocks, last, len;
250 u8 *mic;
251 u8 *b0 = key->tx_b0;
252 u8 *b = key->tx_b;
253 u8 *e = key->tx_e;
254 u8 *s0 = key->tx_s0;
255#endif
256 if (skb_headroom(skb) < CCMP_HDR_LEN ||
257 skb_tailroom(skb) < CCMP_MIC_LEN ||
258 skb->len < hdr_len)
259 return -1;
260
261 data_len = skb->len - hdr_len;
262 pos = skb_push(skb, CCMP_HDR_LEN);
263 memmove(pos, pos + CCMP_HDR_LEN, hdr_len);
264 pos += hdr_len;
265// mic = skb_put(skb, CCMP_MIC_LEN);
266
267 i = CCMP_PN_LEN - 1;
268 while (i >= 0) {
269 key->tx_pn[i]++;
270 if (key->tx_pn[i] != 0)
271 break;
272 i--;
273 }
274
275 *pos++ = key->tx_pn[5];
276 *pos++ = key->tx_pn[4];
277 *pos++ = 0;
278 *pos++ = (key->key_idx << 6) | (1 << 5) /* Ext IV included */;
279 *pos++ = key->tx_pn[3];
280 *pos++ = key->tx_pn[2];
281 *pos++ = key->tx_pn[1];
282 *pos++ = key->tx_pn[0];
283
284 hdr = (struct ieee80211_hdr *) skb->data;
285#ifndef JOHN_CCMP
286 //mic is moved to here by john
287 mic = skb_put(skb, CCMP_MIC_LEN);
288
289 ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0);
290
291 blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
292 last = data_len % AES_BLOCK_LEN;
293
294 for (i = 1; i <= blocks; i++) {
295 len = (i == blocks && last) ? last : AES_BLOCK_LEN;
296 /* Authentication */
297 xor_block(b, pos, len);
298 ieee80211_ccmp_aes_encrypt(key->tfm, b, b);
299 /* Encryption, with counter */
300 b0[14] = (i >> 8) & 0xff;
301 b0[15] = i & 0xff;
302 ieee80211_ccmp_aes_encrypt(key->tfm, b0, e);
303 xor_block(pos, e, len);
304 pos += len;
305 }
306
307 for (i = 0; i < CCMP_MIC_LEN; i++)
308 mic[i] = b[i] ^ s0[i];
309#endif
310 return 0;
311}
312
313
314static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
315{
316 struct ieee80211_ccmp_data *key = priv;
317 u8 keyidx, *pos;
318 struct ieee80211_hdr *hdr;
319 u8 pn[6];
320#ifndef JOHN_CCMP
321 size_t data_len = skb->len - hdr_len - CCMP_HDR_LEN - CCMP_MIC_LEN;
322 u8 *mic = skb->data + skb->len - CCMP_MIC_LEN;
323 u8 *b0 = key->rx_b0;
324 u8 *b = key->rx_b;
325 u8 *a = key->rx_a;
326 int i, blocks, last, len;
327#endif
328 if (skb->len < hdr_len + CCMP_HDR_LEN + CCMP_MIC_LEN) {
329 key->dot11RSNAStatsCCMPFormatErrors++;
330 return -1;
331 }
332
333 hdr = (struct ieee80211_hdr *) skb->data;
334 pos = skb->data + hdr_len;
335 keyidx = pos[3];
336 if (!(keyidx & (1 << 5))) {
337 if (net_ratelimit()) {
338 printk(KERN_DEBUG "CCMP: received packet without ExtIV"
339 " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2));
340 }
341 key->dot11RSNAStatsCCMPFormatErrors++;
342 return -2;
343 }
344 keyidx >>= 6;
345 if (key->key_idx != keyidx) {
346 printk(KERN_DEBUG "CCMP: RX tkey->key_idx=%d frame "
347 "keyidx=%d priv=%p\n", key->key_idx, keyidx, priv);
348 return -6;
349 }
350 if (!key->key_set) {
351 if (net_ratelimit()) {
352 printk(KERN_DEBUG "CCMP: received packet from " MAC_FMT
353 " with keyid=%d that does not have a configured"
354 " key\n", MAC_ARG(hdr->addr2), keyidx);
355 }
356 return -3;
357 }
358
359 pn[0] = pos[7];
360 pn[1] = pos[6];
361 pn[2] = pos[5];
362 pn[3] = pos[4];
363 pn[4] = pos[1];
364 pn[5] = pos[0];
365 pos += 8;
366
367 if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) {
368 if (net_ratelimit()) {
369 printk(KERN_DEBUG "CCMP: replay detected: STA=" MAC_FMT
370 " previous PN %02x%02x%02x%02x%02x%02x "
371 "received PN %02x%02x%02x%02x%02x%02x\n",
372 MAC_ARG(hdr->addr2), MAC_ARG(key->rx_pn),
373 MAC_ARG(pn));
374 }
375 key->dot11RSNAStatsCCMPReplays++;
376 return -4;
377 }
378
379#ifndef JOHN_CCMP
380 ccmp_init_blocks(key->tfm, hdr, pn, data_len, b0, a, b);
381 xor_block(mic, b, CCMP_MIC_LEN);
382
383 blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
384 last = data_len % AES_BLOCK_LEN;
385
386 for (i = 1; i <= blocks; i++) {
387 len = (i == blocks && last) ? last : AES_BLOCK_LEN;
388 /* Decrypt, with counter */
389 b0[14] = (i >> 8) & 0xff;
390 b0[15] = i & 0xff;
391 ieee80211_ccmp_aes_encrypt(key->tfm, b0, b);
392 xor_block(pos, b, len);
393 /* Authentication */
394 xor_block(a, pos, len);
395 ieee80211_ccmp_aes_encrypt(key->tfm, a, a);
396 pos += len;
397 }
398
399 if (memcmp(mic, a, CCMP_MIC_LEN) != 0) {
400 if (net_ratelimit()) {
401 printk(KERN_DEBUG "CCMP: decrypt failed: STA="
402 MAC_FMT "\n", MAC_ARG(hdr->addr2));
403 }
404 key->dot11RSNAStatsCCMPDecryptErrors++;
405 return -5;
406 }
407
408 memcpy(key->rx_pn, pn, CCMP_PN_LEN);
409
410#endif
411 /* Remove hdr and MIC */
412 memmove(skb->data + CCMP_HDR_LEN, skb->data, hdr_len);
413 skb_pull(skb, CCMP_HDR_LEN);
414 skb_trim(skb, skb->len - CCMP_MIC_LEN);
415
416 return keyidx;
417}
418
419
420static int ieee80211_ccmp_set_key(void *key, int len, u8 *seq, void *priv)
421{
422 struct ieee80211_ccmp_data *data = priv;
423 int keyidx;
424 struct crypto_tfm *tfm = data->tfm;
425
426 keyidx = data->key_idx;
427 memset(data, 0, sizeof(*data));
428 data->key_idx = keyidx;
429 data->tfm = tfm;
430 if (len == CCMP_TK_LEN) {
431 memcpy(data->key, key, CCMP_TK_LEN);
432 data->key_set = 1;
433 if (seq) {
434 data->rx_pn[0] = seq[5];
435 data->rx_pn[1] = seq[4];
436 data->rx_pn[2] = seq[3];
437 data->rx_pn[3] = seq[2];
438 data->rx_pn[4] = seq[1];
439 data->rx_pn[5] = seq[0];
440 }
441 crypto_cipher_setkey((void *)data->tfm, data->key, CCMP_TK_LEN);
442 } else if (len == 0)
443 data->key_set = 0;
444 else
445 return -1;
446
447 return 0;
448}
449
450
451static int ieee80211_ccmp_get_key(void *key, int len, u8 *seq, void *priv)
452{
453 struct ieee80211_ccmp_data *data = priv;
454
455 if (len < CCMP_TK_LEN)
456 return -1;
457
458 if (!data->key_set)
459 return 0;
460 memcpy(key, data->key, CCMP_TK_LEN);
461
462 if (seq) {
463 seq[0] = data->tx_pn[5];
464 seq[1] = data->tx_pn[4];
465 seq[2] = data->tx_pn[3];
466 seq[3] = data->tx_pn[2];
467 seq[4] = data->tx_pn[1];
468 seq[5] = data->tx_pn[0];
469 }
470
471 return CCMP_TK_LEN;
472}
473
474
475static char * ieee80211_ccmp_print_stats(char *p, void *priv)
476{
477 struct ieee80211_ccmp_data *ccmp = priv;
478 p += sprintf(p, "key[%d] alg=CCMP key_set=%d "
479 "tx_pn=%02x%02x%02x%02x%02x%02x "
480 "rx_pn=%02x%02x%02x%02x%02x%02x "
481 "format_errors=%d replays=%d decrypt_errors=%d\n",
482 ccmp->key_idx, ccmp->key_set,
483 MAC_ARG(ccmp->tx_pn), MAC_ARG(ccmp->rx_pn),
484 ccmp->dot11RSNAStatsCCMPFormatErrors,
485 ccmp->dot11RSNAStatsCCMPReplays,
486 ccmp->dot11RSNAStatsCCMPDecryptErrors);
487
488 return p;
489}
490
491void ieee80211_ccmp_null(void)
492{
493// printk("============>%s()\n", __FUNCTION__);
494 return;
495}
496static struct ieee80211_crypto_ops ieee80211_crypt_ccmp = {
497 .name = "CCMP",
498 .init = ieee80211_ccmp_init,
499 .deinit = ieee80211_ccmp_deinit,
500 .encrypt_mpdu = ieee80211_ccmp_encrypt,
501 .decrypt_mpdu = ieee80211_ccmp_decrypt,
502 .encrypt_msdu = NULL,
503 .decrypt_msdu = NULL,
504 .set_key = ieee80211_ccmp_set_key,
505 .get_key = ieee80211_ccmp_get_key,
506 .print_stats = ieee80211_ccmp_print_stats,
507 .extra_prefix_len = CCMP_HDR_LEN,
508 .extra_postfix_len = CCMP_MIC_LEN,
509 .owner = THIS_MODULE,
510};
511
512
513int ieee80211_crypto_ccmp_init(void)
514{
515 return ieee80211_register_crypto_ops(&ieee80211_crypt_ccmp);
516}
517
518
519void ieee80211_crypto_ccmp_exit(void)
520{
521 ieee80211_unregister_crypto_ops(&ieee80211_crypt_ccmp);
522}
523
524#if 0
525#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
526EXPORT_SYMBOL(ieee80211_ccmp_null);
527#else
528EXPORT_SYMBOL_NOVERS(ieee80211_ccmp_null);
529#endif
530#endif
531
532//module_init(ieee80211_crypto_ccmp_init);
533//module_exit(ieee80211_crypto_ccmp_exit);
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c
new file mode 100644
index 000000000000..e560b1e11020
--- /dev/null
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c
@@ -0,0 +1,1001 @@
1/*
2 * Host AP crypt: host-based TKIP encryption implementation for Host AP driver
3 *
4 * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation. See README and COPYING for
9 * more details.
10 */
11
12//#include <linux/config.h>
13#include <linux/version.h>
14#include <linux/module.h>
15#include <linux/init.h>
16#include <linux/slab.h>
17#include <linux/random.h>
18#include <linux/skbuff.h>
19#include <linux/netdevice.h>
20#include <linux/if_ether.h>
21#include <linux/if_arp.h>
22#include <asm/string.h>
23
24#include "ieee80211.h"
25
26#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
27#include "rtl_crypto.h"
28#else
29#include <linux/crypto.h>
30#endif
31//#include <asm/scatterlist.h>
32#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
33 #include <asm/scatterlist.h>
34#else
35 #include <linux/scatterlist.h>
36#endif
37
38#include <linux/crc32.h>
39
40MODULE_AUTHOR("Jouni Malinen");
41MODULE_DESCRIPTION("Host AP crypt: TKIP");
42MODULE_LICENSE("GPL");
43
44#ifdef OPENSUSE_SLED
45#ifndef IN_OPENSUSE_SLED
46#define IN_OPENSUSE_SLED 1
47#endif
48#endif
49
50struct ieee80211_tkip_data {
51#define TKIP_KEY_LEN 32
52 u8 key[TKIP_KEY_LEN];
53 int key_set;
54
55 u32 tx_iv32;
56 u16 tx_iv16;
57 u16 tx_ttak[5];
58 int tx_phase1_done;
59
60 u32 rx_iv32;
61 u16 rx_iv16;
62 u16 rx_ttak[5];
63 int rx_phase1_done;
64 u32 rx_iv32_new;
65 u16 rx_iv16_new;
66
67 u32 dot11RSNAStatsTKIPReplays;
68 u32 dot11RSNAStatsTKIPICVErrors;
69 u32 dot11RSNAStatsTKIPLocalMICFailures;
70
71 int key_idx;
72
73 #if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))||(IN_OPENSUSE_SLED))
74 struct crypto_blkcipher *rx_tfm_arc4;
75 struct crypto_hash *rx_tfm_michael;
76 struct crypto_blkcipher *tx_tfm_arc4;
77 struct crypto_hash *tx_tfm_michael;
78 #endif
79
80 struct crypto_tfm *tfm_arc4;
81 struct crypto_tfm *tfm_michael;
82
83 /* scratch buffers for virt_to_page() (crypto API) */
84 u8 rx_hdr[16], tx_hdr[16];
85};
86
87static void * ieee80211_tkip_init(int key_idx)
88{
89 struct ieee80211_tkip_data *priv;
90
91 priv = kmalloc(sizeof(*priv), GFP_ATOMIC);
92 if (priv == NULL)
93 goto fail;
94 memset(priv, 0, sizeof(*priv));
95 priv->key_idx = key_idx;
96
97 #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
98 priv->tfm_arc4 = crypto_alloc_tfm("arc4", 0);
99 if (priv->tfm_arc4 == NULL) {
100 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
101 "crypto API arc4\n");
102 goto fail;
103 }
104
105 priv->tfm_michael = crypto_alloc_tfm("michael_mic", 0);
106 if (priv->tfm_michael == NULL) {
107 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
108 "crypto API michael_mic\n");
109 goto fail;
110 }
111
112 #else
113 priv->tx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
114 CRYPTO_ALG_ASYNC);
115 if (IS_ERR(priv->tx_tfm_arc4)) {
116 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
117 "crypto API arc4\n");
118 priv->tx_tfm_arc4 = NULL;
119 goto fail;
120 }
121
122 priv->tx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
123 CRYPTO_ALG_ASYNC);
124 if (IS_ERR(priv->tx_tfm_michael)) {
125 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
126 "crypto API michael_mic\n");
127 priv->tx_tfm_michael = NULL;
128 goto fail;
129 }
130
131 priv->rx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
132 CRYPTO_ALG_ASYNC);
133 if (IS_ERR(priv->rx_tfm_arc4)) {
134 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
135 "crypto API arc4\n");
136 priv->rx_tfm_arc4 = NULL;
137 goto fail;
138 }
139
140 priv->rx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
141 CRYPTO_ALG_ASYNC);
142 if (IS_ERR(priv->rx_tfm_michael)) {
143 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
144 "crypto API michael_mic\n");
145 priv->rx_tfm_michael = NULL;
146 goto fail;
147 }
148 #endif
149 return priv;
150
151fail:
152 if (priv) {
153 #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
154 if (priv->tfm_michael)
155 crypto_free_tfm(priv->tfm_michael);
156 if (priv->tfm_arc4)
157 crypto_free_tfm(priv->tfm_arc4);
158 #else
159 if (priv->tx_tfm_michael)
160 crypto_free_hash(priv->tx_tfm_michael);
161 if (priv->tx_tfm_arc4)
162 crypto_free_blkcipher(priv->tx_tfm_arc4);
163 if (priv->rx_tfm_michael)
164 crypto_free_hash(priv->rx_tfm_michael);
165 if (priv->rx_tfm_arc4)
166 crypto_free_blkcipher(priv->rx_tfm_arc4);
167 #endif
168 kfree(priv);
169 }
170
171 return NULL;
172}
173
174
175static void ieee80211_tkip_deinit(void *priv)
176{
177 struct ieee80211_tkip_data *_priv = priv;
178 #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
179 if (_priv && _priv->tfm_michael)
180 crypto_free_tfm(_priv->tfm_michael);
181 if (_priv && _priv->tfm_arc4)
182 crypto_free_tfm(_priv->tfm_arc4);
183 #else
184 if (_priv) {
185 if (_priv->tx_tfm_michael)
186 crypto_free_hash(_priv->tx_tfm_michael);
187 if (_priv->tx_tfm_arc4)
188 crypto_free_blkcipher(_priv->tx_tfm_arc4);
189 if (_priv->rx_tfm_michael)
190 crypto_free_hash(_priv->rx_tfm_michael);
191 if (_priv->rx_tfm_arc4)
192 crypto_free_blkcipher(_priv->rx_tfm_arc4);
193 }
194 #endif
195 kfree(priv);
196}
197
198
199static inline u16 RotR1(u16 val)
200{
201 return (val >> 1) | (val << 15);
202}
203
204
205static inline u8 Lo8(u16 val)
206{
207 return val & 0xff;
208}
209
210
211static inline u8 Hi8(u16 val)
212{
213 return val >> 8;
214}
215
216
217static inline u16 Lo16(u32 val)
218{
219 return val & 0xffff;
220}
221
222
223static inline u16 Hi16(u32 val)
224{
225 return val >> 16;
226}
227
228
229static inline u16 Mk16(u8 hi, u8 lo)
230{
231 return lo | (((u16) hi) << 8);
232}
233
234
235static inline u16 Mk16_le(u16 *v)
236{
237 return le16_to_cpu(*v);
238}
239
240
241static const u16 Sbox[256] =
242{
243 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
244 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
245 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
246 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
247 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
248 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
249 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
250 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
251 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
252 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
253 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
254 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
255 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
256 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
257 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
258 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
259 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
260 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
261 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
262 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
263 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
264 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
265 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
266 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
267 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
268 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
269 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
270 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
271 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
272 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
273 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
274 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
275};
276
277
278static inline u16 _S_(u16 v)
279{
280 u16 t = Sbox[Hi8(v)];
281 return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8));
282}
283
284#ifndef JOHN_TKIP
285#define PHASE1_LOOP_COUNT 8
286
287static void tkip_mixing_phase1(u16 *TTAK, const u8 *TK, const u8 *TA, u32 IV32)
288{
289 int i, j;
290
291 /* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */
292 TTAK[0] = Lo16(IV32);
293 TTAK[1] = Hi16(IV32);
294 TTAK[2] = Mk16(TA[1], TA[0]);
295 TTAK[3] = Mk16(TA[3], TA[2]);
296 TTAK[4] = Mk16(TA[5], TA[4]);
297
298 for (i = 0; i < PHASE1_LOOP_COUNT; i++) {
299 j = 2 * (i & 1);
300 TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j]));
301 TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j]));
302 TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j]));
303 TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j]));
304 TTAK[4] += _S_(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j])) + i;
305 }
306}
307
308
309static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK,
310 u16 IV16)
311{
312 /* Make temporary area overlap WEP seed so that the final copy can be
313 * avoided on little endian hosts. */
314 u16 *PPK = (u16 *) &WEPSeed[4];
315
316 /* Step 1 - make copy of TTAK and bring in TSC */
317 PPK[0] = TTAK[0];
318 PPK[1] = TTAK[1];
319 PPK[2] = TTAK[2];
320 PPK[3] = TTAK[3];
321 PPK[4] = TTAK[4];
322 PPK[5] = TTAK[4] + IV16;
323
324 /* Step 2 - 96-bit bijective mixing using S-box */
325 PPK[0] += _S_(PPK[5] ^ Mk16_le((u16 *) &TK[0]));
326 PPK[1] += _S_(PPK[0] ^ Mk16_le((u16 *) &TK[2]));
327 PPK[2] += _S_(PPK[1] ^ Mk16_le((u16 *) &TK[4]));
328 PPK[3] += _S_(PPK[2] ^ Mk16_le((u16 *) &TK[6]));
329 PPK[4] += _S_(PPK[3] ^ Mk16_le((u16 *) &TK[8]));
330 PPK[5] += _S_(PPK[4] ^ Mk16_le((u16 *) &TK[10]));
331
332 PPK[0] += RotR1(PPK[5] ^ Mk16_le((u16 *) &TK[12]));
333 PPK[1] += RotR1(PPK[0] ^ Mk16_le((u16 *) &TK[14]));
334 PPK[2] += RotR1(PPK[1]);
335 PPK[3] += RotR1(PPK[2]);
336 PPK[4] += RotR1(PPK[3]);
337 PPK[5] += RotR1(PPK[4]);
338
339 /* Step 3 - bring in last of TK bits, assign 24-bit WEP IV value
340 * WEPSeed[0..2] is transmitted as WEP IV */
341 WEPSeed[0] = Hi8(IV16);
342 WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F;
343 WEPSeed[2] = Lo8(IV16);
344 WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((u16 *) &TK[0])) >> 1);
345
346#ifdef __BIG_ENDIAN
347 {
348 int i;
349 for (i = 0; i < 6; i++)
350 PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8);
351 }
352#endif
353}
354#endif
355static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
356{
357 struct ieee80211_tkip_data *tkey = priv;
358 #if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))||(IN_OPENSUSE_SLED))
359 struct blkcipher_desc desc = {.tfm = tkey->tx_tfm_arc4};
360 #endif
361 int len;
362 u8 *pos;
363 struct ieee80211_hdr *hdr;
364#ifndef JOHN_TKIP
365 u8 rc4key[16],*icv;
366 u32 crc;
367 struct scatterlist sg;
368#endif
369 int ret;
370
371 ret = 0;
372 if (skb_headroom(skb) < 8 || skb_tailroom(skb) < 4 ||
373 skb->len < hdr_len)
374 return -1;
375
376 hdr = (struct ieee80211_hdr *) skb->data;
377#if 0
378printk("@@ tkey\n");
379printk("%x|", ((u32*)tkey->key)[0]);
380printk("%x|", ((u32*)tkey->key)[1]);
381printk("%x|", ((u32*)tkey->key)[2]);
382printk("%x|", ((u32*)tkey->key)[3]);
383printk("%x|", ((u32*)tkey->key)[4]);
384printk("%x|", ((u32*)tkey->key)[5]);
385printk("%x|", ((u32*)tkey->key)[6]);
386printk("%x\n", ((u32*)tkey->key)[7]);
387#endif
388
389#ifndef JOHN_TKIP
390 if (!tkey->tx_phase1_done) {
391 tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2,
392 tkey->tx_iv32);
393 tkey->tx_phase1_done = 1;
394 }
395 tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16);
396
397#else
398 tkey->tx_phase1_done = 1;
399#endif /*JOHN_TKIP*/
400
401 len = skb->len - hdr_len;
402 pos = skb_push(skb, 8);
403 memmove(pos, pos + 8, hdr_len);
404 pos += hdr_len;
405
406#ifdef JOHN_TKIP
407 *pos++ = Hi8(tkey->tx_iv16);
408 *pos++ = (Hi8(tkey->tx_iv16) | 0x20) & 0x7F;
409 *pos++ = Lo8(tkey->tx_iv16);
410#else
411 *pos++ = rc4key[0];
412 *pos++ = rc4key[1];
413 *pos++ = rc4key[2];
414#endif
415 *pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */;
416 *pos++ = tkey->tx_iv32 & 0xff;
417 *pos++ = (tkey->tx_iv32 >> 8) & 0xff;
418 *pos++ = (tkey->tx_iv32 >> 16) & 0xff;
419 *pos++ = (tkey->tx_iv32 >> 24) & 0xff;
420#ifndef JOHN_TKIP
421 icv = skb_put(skb, 4);
422#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
423 crc = ~crc32_le(~0, pos, len);
424#else
425 crc = ~ether_crc_le(len, pos);
426#endif
427 icv[0] = crc;
428 icv[1] = crc >> 8;
429 icv[2] = crc >> 16;
430 icv[3] = crc >> 24;
431 #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
432 crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16);
433 sg.page = virt_to_page(pos);
434 sg.offset = offset_in_page(pos);
435 sg.length = len + 4;
436 crypto_cipher_encrypt(tkey->tfm_arc4, &sg, &sg, len + 4);
437 #else
438 crypto_blkcipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
439 #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
440 sg.page = virt_to_page(pos);
441 sg.offset = offset_in_page(pos);
442 sg.length = len + 4;
443 #else
444 sg_init_one(&sg, pos, len+4);
445 #endif
446 ret= crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
447 #endif
448#endif
449 tkey->tx_iv16++;
450 if (tkey->tx_iv16 == 0) {
451 tkey->tx_phase1_done = 0;
452 tkey->tx_iv32++;
453 }
454#ifndef JOHN_TKIP
455 #if((LINUX_VERSION_CODE <KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
456 return 0;
457 #else
458 return ret;
459 #endif
460#else
461 return 0;
462#endif
463}
464
465static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
466{
467 struct ieee80211_tkip_data *tkey = priv;
468 #if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) ||(IN_OPENSUSE_SLED))
469 struct blkcipher_desc desc = {.tfm = tkey->rx_tfm_arc4};
470 #endif
471 u8 keyidx, *pos;
472 u32 iv32;
473 u16 iv16;
474 struct ieee80211_hdr *hdr;
475#ifndef JOHN_TKIP
476 u8 icv[4];
477 u32 crc;
478 struct scatterlist sg;
479 u8 rc4key[16];
480 int plen;
481#endif
482 if (skb->len < hdr_len + 8 + 4)
483 return -1;
484
485 hdr = (struct ieee80211_hdr *) skb->data;
486 pos = skb->data + hdr_len;
487 keyidx = pos[3];
488 if (!(keyidx & (1 << 5))) {
489 if (net_ratelimit()) {
490 printk(KERN_DEBUG "TKIP: received packet without ExtIV"
491 " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2));
492 }
493 return -2;
494 }
495 keyidx >>= 6;
496 if (tkey->key_idx != keyidx) {
497 printk(KERN_DEBUG "TKIP: RX tkey->key_idx=%d frame "
498 "keyidx=%d priv=%p\n", tkey->key_idx, keyidx, priv);
499 return -6;
500 }
501 if (!tkey->key_set) {
502 if (net_ratelimit()) {
503 printk(KERN_DEBUG "TKIP: received packet from " MAC_FMT
504 " with keyid=%d that does not have a configured"
505 " key\n", MAC_ARG(hdr->addr2), keyidx);
506 }
507 return -3;
508 }
509 iv16 = (pos[0] << 8) | pos[2];
510 iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24);
511 pos += 8;
512#ifndef JOHN_TKIP
513
514 if (iv32 < tkey->rx_iv32 ||
515 (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) {
516 if (net_ratelimit()) {
517 printk(KERN_DEBUG "TKIP: replay detected: STA=" MAC_FMT
518 " previous TSC %08x%04x received TSC "
519 "%08x%04x\n", MAC_ARG(hdr->addr2),
520 tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
521 }
522 tkey->dot11RSNAStatsTKIPReplays++;
523 return -4;
524 }
525
526 if (iv32 != tkey->rx_iv32 || !tkey->rx_phase1_done) {
527 tkip_mixing_phase1(tkey->rx_ttak, tkey->key, hdr->addr2, iv32);
528 tkey->rx_phase1_done = 1;
529 }
530 tkip_mixing_phase2(rc4key, tkey->key, tkey->rx_ttak, iv16);
531
532 plen = skb->len - hdr_len - 12;
533 #if((LINUX_VERSION_CODE <KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
534 crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16);
535 sg.page = virt_to_page(pos);
536 sg.offset = offset_in_page(pos);
537 sg.length = plen + 4;
538 crypto_cipher_decrypt(tkey->tfm_arc4, &sg, &sg, plen + 4);
539 #else
540 crypto_blkcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
541 #if(LINUX_VERSION_CODE <KERNEL_VERSION(2,6,24))
542 sg.page = virt_to_page(pos);
543 sg.offset = offset_in_page(pos);
544 sg.length = plen + 4;
545 #else
546 sg_init_one(&sg, pos, plen+4);
547 #endif
548 if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
549 if (net_ratelimit()) {
550 printk(KERN_DEBUG ": TKIP: failed to decrypt "
551 "received packet from " MAC_FMT "\n",
552 MAC_ARG(hdr->addr2));
553 }
554 return -7;
555 }
556 #endif
557
558#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
559 crc = ~crc32_le(~0, pos, plen);
560#else
561 crc = ~ether_crc_le(plen, pos);
562#endif
563 icv[0] = crc;
564 icv[1] = crc >> 8;
565 icv[2] = crc >> 16;
566 icv[3] = crc >> 24;
567 if (memcmp(icv, pos + plen, 4) != 0) {
568 if (iv32 != tkey->rx_iv32) {
569 /* Previously cached Phase1 result was already lost, so
570 * it needs to be recalculated for the next packet. */
571 tkey->rx_phase1_done = 0;
572 }
573 if (net_ratelimit()) {
574 printk(KERN_DEBUG "TKIP: ICV error detected: STA="
575 MAC_FMT "\n", MAC_ARG(hdr->addr2));
576 }
577 tkey->dot11RSNAStatsTKIPICVErrors++;
578 return -5;
579 }
580
581#endif /* JOHN_TKIP */
582
583 /* Update real counters only after Michael MIC verification has
584 * completed */
585 tkey->rx_iv32_new = iv32;
586 tkey->rx_iv16_new = iv16;
587
588 /* Remove IV and ICV */
589 memmove(skb->data + 8, skb->data, hdr_len);
590 skb_pull(skb, 8);
591 skb_trim(skb, skb->len - 4);
592
593//john's test
594#ifdef JOHN_DUMP
595if( ((u16*)skb->data)[0] & 0x4000){
596 printk("@@ rx decrypted skb->data");
597 int i;
598 for(i=0;i<skb->len;i++){
599 if( (i%24)==0 ) printk("\n");
600 printk("%2x ", ((u8*)skb->data)[i]);
601 }
602 printk("\n");
603}
604#endif /*JOHN_DUMP*/
605 return keyidx;
606}
607
608#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!IN_OPENSUSE_SLED))
609static int michael_mic(struct ieee80211_tkip_data *tkey, u8 *key, u8 *hdr,
610 u8 *data, size_t data_len, u8 *mic)
611{
612 struct scatterlist sg[2];
613#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
614 struct hash_desc desc;
615 int ret=0;
616#endif
617 if (tkey->tfm_michael == NULL) {
618 printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
619 return -1;
620 }
621 sg[0].page = virt_to_page(hdr);
622 sg[0].offset = offset_in_page(hdr);
623 sg[0].length = 16;
624
625 sg[1].page = virt_to_page(data);
626 sg[1].offset = offset_in_page(data);
627 sg[1].length = data_len;
628
629 //crypto_digest_init(tkey->tfm_michael);
630 //crypto_digest_setkey(tkey->tfm_michael, key, 8);
631 //crypto_digest_update(tkey->tfm_michael, sg, 2);
632 //crypto_digest_final(tkey->tfm_michael, mic);
633
634 //return 0;
635#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
636 crypto_digest_init(tkey->tfm_michael);
637 crypto_digest_setkey(tkey->tfm_michael, key, 8);
638 crypto_digest_update(tkey->tfm_michael, sg, 2);
639 crypto_digest_final(tkey->tfm_michael, mic);
640
641 return 0;
642#else
643if (crypto_hash_setkey(tkey->tfm_michael, key, 8))
644 return -1;
645
646// return 0;
647 desc.tfm = tkey->tfm_michael;
648 desc.flags = 0;
649 ret = crypto_hash_digest(&desc, sg, data_len + 16, mic);
650 return ret;
651#endif
652}
653#else
654static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
655 u8 * data, size_t data_len, u8 * mic)
656{
657 struct hash_desc desc;
658 struct scatterlist sg[2];
659
660 if (tfm_michael == NULL) {
661 printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
662 return -1;
663 }
664 #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
665 sg[0].page = virt_to_page(hdr);
666 sg[0].offset = offset_in_page(hdr);
667 sg[0].length = 16;
668 sg[1].page = virt_to_page(data);
669 sg[1].offset = offset_in_page(data);
670 sg[1].length = data_len;
671 #else
672 sg_init_table(sg, 2);
673 sg_set_buf(&sg[0], hdr, 16);
674 sg_set_buf(&sg[1], data, data_len);
675 #endif
676
677 if (crypto_hash_setkey(tfm_michael, key, 8))
678 return -1;
679
680 desc.tfm = tfm_michael;
681 desc.flags = 0;
682 return crypto_hash_digest(&desc, sg, data_len + 16, mic);
683}
684#endif
685
686
687
688static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr)
689{
690 struct ieee80211_hdr *hdr11;
691
692 hdr11 = (struct ieee80211_hdr *) skb->data;
693 switch (le16_to_cpu(hdr11->frame_ctl) &
694 (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
695 case IEEE80211_FCTL_TODS:
696 memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
697 memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
698 break;
699 case IEEE80211_FCTL_FROMDS:
700 memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
701 memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */
702 break;
703 case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
704 memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
705 memcpy(hdr + ETH_ALEN, hdr11->addr4, ETH_ALEN); /* SA */
706 break;
707 case 0:
708 memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
709 memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
710 break;
711 }
712
713 hdr[12] = 0; /* priority */
714
715 hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */
716}
717
718
719static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv)
720{
721 struct ieee80211_tkip_data *tkey = priv;
722 u8 *pos;
723 struct ieee80211_hdr *hdr;
724
725 hdr = (struct ieee80211_hdr *) skb->data;
726
727 if (skb_tailroom(skb) < 8 || skb->len < hdr_len) {
728 printk(KERN_DEBUG "Invalid packet for Michael MIC add "
729 "(tailroom=%d hdr_len=%d skb->len=%d)\n",
730 skb_tailroom(skb), hdr_len, skb->len);
731 return -1;
732 }
733
734 michael_mic_hdr(skb, tkey->tx_hdr);
735
736 // { david, 2006.9.1
737 // fix the wpa process with wmm enabled.
738 if(IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) {
739 tkey->tx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
740 }
741 // }
742 pos = skb_put(skb, 8);
743 #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
744 if (michael_mic(tkey, &tkey->key[16], tkey->tx_hdr,
745 skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
746 #else
747 if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr,
748 skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
749 #endif
750 return -1;
751
752 return 0;
753}
754
755
756#if WIRELESS_EXT >= 18
757static void ieee80211_michael_mic_failure(struct net_device *dev,
758 struct ieee80211_hdr *hdr,
759 int keyidx)
760{
761 union iwreq_data wrqu;
762 struct iw_michaelmicfailure ev;
763
764 /* TODO: needed parameters: count, keyid, key type, TSC */
765 memset(&ev, 0, sizeof(ev));
766 ev.flags = keyidx & IW_MICFAILURE_KEY_ID;
767 if (hdr->addr1[0] & 0x01)
768 ev.flags |= IW_MICFAILURE_GROUP;
769 else
770 ev.flags |= IW_MICFAILURE_PAIRWISE;
771 ev.src_addr.sa_family = ARPHRD_ETHER;
772 memcpy(ev.src_addr.sa_data, hdr->addr2, ETH_ALEN);
773 memset(&wrqu, 0, sizeof(wrqu));
774 wrqu.data.length = sizeof(ev);
775 wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *) &ev);
776}
777#elif WIRELESS_EXT >= 15
778static void ieee80211_michael_mic_failure(struct net_device *dev,
779 struct ieee80211_hdr *hdr,
780 int keyidx)
781{
782 union iwreq_data wrqu;
783 char buf[128];
784
785 /* TODO: needed parameters: count, keyid, key type, TSC */
786 sprintf(buf, "MLME-MICHAELMICFAILURE.indication(keyid=%d %scast addr="
787 MAC_FMT ")", keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni",
788 MAC_ARG(hdr->addr2));
789 memset(&wrqu, 0, sizeof(wrqu));
790 wrqu.data.length = strlen(buf);
791 wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
792}
793#else /* WIRELESS_EXT >= 15 */
794static inline void ieee80211_michael_mic_failure(struct net_device *dev,
795 struct ieee80211_hdr *hdr,
796 int keyidx)
797{
798}
799#endif /* WIRELESS_EXT >= 15 */
800
801
802static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
803 int hdr_len, void *priv)
804{
805 struct ieee80211_tkip_data *tkey = priv;
806 u8 mic[8];
807 struct ieee80211_hdr *hdr;
808
809 hdr = (struct ieee80211_hdr *) skb->data;
810
811 if (!tkey->key_set)
812 return -1;
813
814 michael_mic_hdr(skb, tkey->rx_hdr);
815 // { david, 2006.9.1
816 // fix the wpa process with wmm enabled.
817 if(IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) {
818 tkey->rx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
819 }
820 // }
821 #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
822 if (michael_mic(tkey, &tkey->key[24], tkey->rx_hdr,
823 skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
824 #else
825 if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr,
826 skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
827 #endif
828 return -1;
829 if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
830 struct ieee80211_hdr *hdr;
831 hdr = (struct ieee80211_hdr *) skb->data;
832 printk(KERN_DEBUG "%s: Michael MIC verification failed for "
833 "MSDU from " MAC_FMT " keyidx=%d\n",
834 skb->dev ? skb->dev->name : "N/A", MAC_ARG(hdr->addr2),
835 keyidx);
836 if (skb->dev)
837 ieee80211_michael_mic_failure(skb->dev, hdr, keyidx);
838 tkey->dot11RSNAStatsTKIPLocalMICFailures++;
839 return -1;
840 }
841
842 /* Update TSC counters for RX now that the packet verification has
843 * completed. */
844 tkey->rx_iv32 = tkey->rx_iv32_new;
845 tkey->rx_iv16 = tkey->rx_iv16_new;
846
847 skb_trim(skb, skb->len - 8);
848
849 return 0;
850}
851
852
853static int ieee80211_tkip_set_key(void *key, int len, u8 *seq, void *priv)
854{
855 struct ieee80211_tkip_data *tkey = priv;
856 int keyidx;
857 #if ((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
858 struct crypto_tfm *tfm = tkey->tfm_michael;
859 struct crypto_tfm *tfm2 = tkey->tfm_arc4;
860 #else
861 struct crypto_hash *tfm = tkey->tx_tfm_michael;
862 struct crypto_blkcipher *tfm2 = tkey->tx_tfm_arc4;
863 struct crypto_hash *tfm3 = tkey->rx_tfm_michael;
864 struct crypto_blkcipher *tfm4 = tkey->rx_tfm_arc4;
865 #endif
866
867 keyidx = tkey->key_idx;
868 memset(tkey, 0, sizeof(*tkey));
869 tkey->key_idx = keyidx;
870
871 #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
872 tkey->tfm_michael = tfm;
873 tkey->tfm_arc4 = tfm2;
874 #else
875 tkey->tx_tfm_michael = tfm;
876 tkey->tx_tfm_arc4 = tfm2;
877 tkey->rx_tfm_michael = tfm3;
878 tkey->rx_tfm_arc4 = tfm4;
879 #endif
880
881 if (len == TKIP_KEY_LEN) {
882 memcpy(tkey->key, key, TKIP_KEY_LEN);
883 tkey->key_set = 1;
884 tkey->tx_iv16 = 1; /* TSC is initialized to 1 */
885 if (seq) {
886 tkey->rx_iv32 = (seq[5] << 24) | (seq[4] << 16) |
887 (seq[3] << 8) | seq[2];
888 tkey->rx_iv16 = (seq[1] << 8) | seq[0];
889 }
890 } else if (len == 0)
891 tkey->key_set = 0;
892 else
893 return -1;
894
895 return 0;
896}
897
898
899static int ieee80211_tkip_get_key(void *key, int len, u8 *seq, void *priv)
900{
901 struct ieee80211_tkip_data *tkey = priv;
902
903 if (len < TKIP_KEY_LEN)
904 return -1;
905
906 if (!tkey->key_set)
907 return 0;
908 memcpy(key, tkey->key, TKIP_KEY_LEN);
909
910 if (seq) {
911 /* Return the sequence number of the last transmitted frame. */
912 u16 iv16 = tkey->tx_iv16;
913 u32 iv32 = tkey->tx_iv32;
914 if (iv16 == 0)
915 iv32--;
916 iv16--;
917 seq[0] = tkey->tx_iv16;
918 seq[1] = tkey->tx_iv16 >> 8;
919 seq[2] = tkey->tx_iv32;
920 seq[3] = tkey->tx_iv32 >> 8;
921 seq[4] = tkey->tx_iv32 >> 16;
922 seq[5] = tkey->tx_iv32 >> 24;
923 }
924
925 return TKIP_KEY_LEN;
926}
927
928
929static char * ieee80211_tkip_print_stats(char *p, void *priv)
930{
931 struct ieee80211_tkip_data *tkip = priv;
932 p += sprintf(p, "key[%d] alg=TKIP key_set=%d "
933 "tx_pn=%02x%02x%02x%02x%02x%02x "
934 "rx_pn=%02x%02x%02x%02x%02x%02x "
935 "replays=%d icv_errors=%d local_mic_failures=%d\n",
936 tkip->key_idx, tkip->key_set,
937 (tkip->tx_iv32 >> 24) & 0xff,
938 (tkip->tx_iv32 >> 16) & 0xff,
939 (tkip->tx_iv32 >> 8) & 0xff,
940 tkip->tx_iv32 & 0xff,
941 (tkip->tx_iv16 >> 8) & 0xff,
942 tkip->tx_iv16 & 0xff,
943 (tkip->rx_iv32 >> 24) & 0xff,
944 (tkip->rx_iv32 >> 16) & 0xff,
945 (tkip->rx_iv32 >> 8) & 0xff,
946 tkip->rx_iv32 & 0xff,
947 (tkip->rx_iv16 >> 8) & 0xff,
948 tkip->rx_iv16 & 0xff,
949 tkip->dot11RSNAStatsTKIPReplays,
950 tkip->dot11RSNAStatsTKIPICVErrors,
951 tkip->dot11RSNAStatsTKIPLocalMICFailures);
952 return p;
953}
954
955
956static struct ieee80211_crypto_ops ieee80211_crypt_tkip = {
957 .name = "TKIP",
958 .init = ieee80211_tkip_init,
959 .deinit = ieee80211_tkip_deinit,
960 .encrypt_mpdu = ieee80211_tkip_encrypt,
961 .decrypt_mpdu = ieee80211_tkip_decrypt,
962 .encrypt_msdu = ieee80211_michael_mic_add,
963 .decrypt_msdu = ieee80211_michael_mic_verify,
964 .set_key = ieee80211_tkip_set_key,
965 .get_key = ieee80211_tkip_get_key,
966 .print_stats = ieee80211_tkip_print_stats,
967 .extra_prefix_len = 4 + 4, /* IV + ExtIV */
968 .extra_postfix_len = 8 + 4, /* MIC + ICV */
969 .owner = THIS_MODULE,
970};
971
972
973int ieee80211_crypto_tkip_init(void)
974{
975 return ieee80211_register_crypto_ops(&ieee80211_crypt_tkip);
976}
977
978
979void ieee80211_crypto_tkip_exit(void)
980{
981 ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip);
982}
983
984
985void ieee80211_tkip_null(void)
986{
987// printk("============>%s()\n", __FUNCTION__);
988 return;
989}
990
991#if 0
992#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
993EXPORT_SYMBOL(ieee80211_tkip_null);
994#else
995EXPORT_SYMBOL_NOVERS(ieee80211_tkip_null);
996#endif
997#endif
998
999
1000//module_init(ieee80211_crypto_tkip_init);
1001//module_exit(ieee80211_crypto_tkip_exit);
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c
new file mode 100644
index 000000000000..f973daeeeb0f
--- /dev/null
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c
@@ -0,0 +1,394 @@
1/*
2 * Host AP crypt: host-based WEP encryption implementation for Host AP driver
3 *
4 * Copyright (c) 2002-2004, Jouni Malinen <jkmaline@cc.hut.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation. See README and COPYING for
9 * more details.
10 */
11
12//#include <linux/config.h>
13#include <linux/version.h>
14#include <linux/module.h>
15#include <linux/init.h>
16#include <linux/slab.h>
17#include <linux/random.h>
18#include <linux/skbuff.h>
19#include <asm/string.h>
20
21#include "ieee80211.h"
22
23#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
24#include "rtl_crypto.h"
25#else
26#include <linux/crypto.h>
27#endif
28
29#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
30 #include <asm/scatterlist.h>
31#else
32 #include <linux/scatterlist.h>
33#endif
34//#include <asm/scatterlist.h>
35#include <linux/crc32.h>
36
37MODULE_AUTHOR("Jouni Malinen");
38MODULE_DESCRIPTION("Host AP crypt: WEP");
39MODULE_LICENSE("GPL");
40
41#ifdef OPENSUSE_SLED
42#ifndef IN_OPENSUSE_SLED
43#define IN_OPENSUSE_SLED 1
44#endif
45#endif
46
47
48struct prism2_wep_data {
49 u32 iv;
50#define WEP_KEY_LEN 13
51 u8 key[WEP_KEY_LEN + 1];
52 u8 key_len;
53 u8 key_idx;
54 #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
55 struct crypto_tfm *tfm;
56 #else
57 struct crypto_blkcipher *tx_tfm;
58 struct crypto_blkcipher *rx_tfm;
59 #endif
60};
61
62
63static void * prism2_wep_init(int keyidx)
64{
65 struct prism2_wep_data *priv;
66
67 priv = kmalloc(sizeof(*priv), GFP_ATOMIC);
68 if (priv == NULL)
69 goto fail;
70 memset(priv, 0, sizeof(*priv));
71 priv->key_idx = keyidx;
72 #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
73 priv->tfm = crypto_alloc_tfm("arc4", 0);
74 if (priv->tfm == NULL) {
75 printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
76 "crypto API arc4\n");
77 goto fail;
78 }
79 #else
80 priv->tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
81 if (IS_ERR(priv->tx_tfm)) {
82 printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
83 "crypto API arc4\n");
84 priv->tx_tfm = NULL;
85 goto fail;
86 }
87 priv->rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
88 if (IS_ERR(priv->rx_tfm)) {
89 printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
90 "crypto API arc4\n");
91 priv->rx_tfm = NULL;
92 goto fail;
93 }
94 #endif
95
96 /* start WEP IV from a random value */
97 get_random_bytes(&priv->iv, 4);
98
99 return priv;
100
101fail:
102 //#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
103 #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
104 if (priv) {
105 if (priv->tfm)
106 crypto_free_tfm(priv->tfm);
107 kfree(priv);
108 }
109 #else
110 if (priv) {
111 if (priv->tx_tfm)
112 crypto_free_blkcipher(priv->tx_tfm);
113 if (priv->rx_tfm)
114 crypto_free_blkcipher(priv->rx_tfm);
115 kfree(priv);
116 }
117 #endif
118 return NULL;
119}
120
121
122static void prism2_wep_deinit(void *priv)
123{
124 struct prism2_wep_data *_priv = priv;
125 //#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
126 #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
127 if (_priv && _priv->tfm)
128 crypto_free_tfm(_priv->tfm);
129 #else
130 if (_priv) {
131 if (_priv->tx_tfm)
132 crypto_free_blkcipher(_priv->tx_tfm);
133 if (_priv->rx_tfm)
134 crypto_free_blkcipher(_priv->rx_tfm);
135 }
136 #endif
137 kfree(priv);
138}
139
140
141/* Perform WEP encryption on given skb that has at least 4 bytes of headroom
142 * for IV and 4 bytes of tailroom for ICV. Both IV and ICV will be transmitted,
143 * so the payload length increases with 8 bytes.
144 *
145 * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data))
146 */
147static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
148{
149 struct prism2_wep_data *wep = priv;
150//#if(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))
151#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))||(IN_OPENSUSE_SLED))
152 struct blkcipher_desc desc = {.tfm = wep->tx_tfm};
153#endif
154 u32 klen, len;
155 u8 key[WEP_KEY_LEN + 3];
156 u8 *pos;
157#ifndef JOHN_HWSEC
158 u32 crc;
159 u8 *icv;
160 struct scatterlist sg;
161#endif
162 if (skb_headroom(skb) < 4 || skb_tailroom(skb) < 4 ||
163 skb->len < hdr_len)
164 return -1;
165
166 len = skb->len - hdr_len;
167 pos = skb_push(skb, 4);
168 memmove(pos, pos + 4, hdr_len);
169 pos += hdr_len;
170
171 klen = 3 + wep->key_len;
172
173 wep->iv++;
174
175 /* Fluhrer, Mantin, and Shamir have reported weaknesses in the key
176 * scheduling algorithm of RC4. At least IVs (KeyByte + 3, 0xff, N)
177 * can be used to speedup attacks, so avoid using them. */
178 if ((wep->iv & 0xff00) == 0xff00) {
179 u8 B = (wep->iv >> 16) & 0xff;
180 if (B >= 3 && B < klen)
181 wep->iv += 0x0100;
182 }
183
184 /* Prepend 24-bit IV to RC4 key and TX frame */
185 *pos++ = key[0] = (wep->iv >> 16) & 0xff;
186 *pos++ = key[1] = (wep->iv >> 8) & 0xff;
187 *pos++ = key[2] = wep->iv & 0xff;
188 *pos++ = wep->key_idx << 6;
189
190 /* Copy rest of the WEP key (the secret part) */
191 memcpy(key + 3, wep->key, wep->key_len);
192
193#ifndef JOHN_HWSEC
194 /* Append little-endian CRC32 and encrypt it to produce ICV */
195#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
196 crc = ~crc32_le(~0, pos, len);
197#else
198 crc = ~ether_crc_le(len, pos);
199#endif
200 icv = skb_put(skb, 4);
201 icv[0] = crc;
202 icv[1] = crc >> 8;
203 icv[2] = crc >> 16;
204 icv[3] = crc >> 24;
205
206 //#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
207 #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
208 crypto_cipher_setkey(wep->tfm, key, klen);
209 sg.page = virt_to_page(pos);
210 sg.offset = offset_in_page(pos);
211 sg.length = len + 4;
212 crypto_cipher_encrypt(wep->tfm, &sg, &sg, len + 4);
213
214 return 0;
215 #else
216 crypto_blkcipher_setkey(wep->tx_tfm, key, klen);
217 #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
218 sg.page = virt_to_page(pos);
219 sg.offset = offset_in_page(pos);
220 sg.length = len + 4;
221 #else
222 sg_init_one(&sg, pos, len+4);
223 #endif
224 return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
225 #endif
226#endif /* JOHN_HWSEC */
227 return 0;
228}
229
230
231/* Perform WEP decryption on given buffer. Buffer includes whole WEP part of
232 * the frame: IV (4 bytes), encrypted payload (including SNAP header),
233 * ICV (4 bytes). len includes both IV and ICV.
234 *
235 * Returns 0 if frame was decrypted successfully and ICV was correct and -1 on
236 * failure. If frame is OK, IV and ICV will be removed.
237 */
238static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
239{
240 struct prism2_wep_data *wep = priv;
241 //#if(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))
242 #if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))||(IN_OPENSUSE_SLED))
243 struct blkcipher_desc desc = {.tfm = wep->rx_tfm};
244 #endif
245 u32 klen, plen;
246 u8 key[WEP_KEY_LEN + 3];
247 u8 keyidx, *pos;
248#ifndef JOHN_HWSEC
249 u32 crc;
250 u8 icv[4];
251 struct scatterlist sg;
252#endif
253 if (skb->len < hdr_len + 8)
254 return -1;
255
256 pos = skb->data + hdr_len;
257 key[0] = *pos++;
258 key[1] = *pos++;
259 key[2] = *pos++;
260 keyidx = *pos++ >> 6;
261 if (keyidx != wep->key_idx)
262 return -1;
263
264 klen = 3 + wep->key_len;
265
266 /* Copy rest of the WEP key (the secret part) */
267 memcpy(key + 3, wep->key, wep->key_len);
268
269 /* Apply RC4 to data and compute CRC32 over decrypted data */
270 plen = skb->len - hdr_len - 8;
271#ifndef JOHN_HWSEC
272//#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
273#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
274 crypto_cipher_setkey(wep->tfm, key, klen);
275 sg.page = virt_to_page(pos);
276 sg.offset = offset_in_page(pos);
277 sg.length = plen + 4;
278 crypto_cipher_decrypt(wep->tfm, &sg, &sg, plen + 4);
279#else
280 crypto_blkcipher_setkey(wep->rx_tfm, key, klen);
281 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
282 sg.page = virt_to_page(pos);
283 sg.offset = offset_in_page(pos);
284 sg.length = plen + 4;
285 #else
286 sg_init_one(&sg, pos, plen+4);
287 #endif
288 if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4))
289 return -7;
290#endif
291
292#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
293 crc = ~crc32_le(~0, pos, plen);
294#else
295 crc = ~ether_crc_le(plen, pos);
296#endif
297 icv[0] = crc;
298 icv[1] = crc >> 8;
299 icv[2] = crc >> 16;
300 icv[3] = crc >> 24;
301
302 if (memcmp(icv, pos + plen, 4) != 0) {
303 /* ICV mismatch - drop frame */
304 return -2;
305 }
306#endif /* JOHN_HWSEC */
307
308 /* Remove IV and ICV */
309 memmove(skb->data + 4, skb->data, hdr_len);
310 skb_pull(skb, 4);
311 skb_trim(skb, skb->len - 4);
312 return 0;
313}
314
315
316static int prism2_wep_set_key(void *key, int len, u8 *seq, void *priv)
317{
318 struct prism2_wep_data *wep = priv;
319
320 if (len < 0 || len > WEP_KEY_LEN)
321 return -1;
322
323 memcpy(wep->key, key, len);
324 wep->key_len = len;
325
326 return 0;
327}
328
329
330static int prism2_wep_get_key(void *key, int len, u8 *seq, void *priv)
331{
332 struct prism2_wep_data *wep = priv;
333
334 if (len < wep->key_len)
335 return -1;
336
337 memcpy(key, wep->key, wep->key_len);
338
339 return wep->key_len;
340}
341
342
343static char * prism2_wep_print_stats(char *p, void *priv)
344{
345 struct prism2_wep_data *wep = priv;
346 p += sprintf(p, "key[%d] alg=WEP len=%d\n",
347 wep->key_idx, wep->key_len);
348 return p;
349}
350
351
352static struct ieee80211_crypto_ops ieee80211_crypt_wep = {
353 .name = "WEP",
354 .init = prism2_wep_init,
355 .deinit = prism2_wep_deinit,
356 .encrypt_mpdu = prism2_wep_encrypt,
357 .decrypt_mpdu = prism2_wep_decrypt,
358 .encrypt_msdu = NULL,
359 .decrypt_msdu = NULL,
360 .set_key = prism2_wep_set_key,
361 .get_key = prism2_wep_get_key,
362 .print_stats = prism2_wep_print_stats,
363 .extra_prefix_len = 4, /* IV */
364 .extra_postfix_len = 4, /* ICV */
365 .owner = THIS_MODULE,
366};
367
368
369int ieee80211_crypto_wep_init(void)
370{
371 return ieee80211_register_crypto_ops(&ieee80211_crypt_wep);
372}
373
374
375void ieee80211_crypto_wep_exit(void)
376{
377 ieee80211_unregister_crypto_ops(&ieee80211_crypt_wep);
378}
379
380
381void ieee80211_wep_null(void)
382{
383// printk("============>%s()\n", __FUNCTION__);
384 return;
385}
386#if 0
387#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
388EXPORT_SYMBOL(ieee80211_wep_null);
389#else
390EXPORT_SYMBOL_NOVERS(ieee80211_wep_null);
391#endif
392#endif
393//module_init(ieee80211_crypto_wep_init);
394//module_exit(ieee80211_crypto_wep_exit);
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c
new file mode 100644
index 000000000000..0c9fef0b4e3f
--- /dev/null
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c
@@ -0,0 +1,301 @@
1/*******************************************************************************
2
3 Copyright(c) 2004 Intel Corporation. All rights reserved.
4
5 Portions of this file are based on the WEP enablement code provided by the
6 Host AP project hostap-drivers v0.1.3
7 Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
8 <jkmaline@cc.hut.fi>
9 Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
10
11 This program is free software; you can redistribute it and/or modify it
12 under the terms of version 2 of the GNU General Public License as
13 published by the Free Software Foundation.
14
15 This program is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18 more details.
19
20 You should have received a copy of the GNU General Public License along with
21 this program; if not, write to the Free Software Foundation, Inc., 59
22 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
24 The full GNU General Public License is included in this distribution in the
25 file called LICENSE.
26
27 Contact Information:
28 James P. Ketrenos <ipw2100-admin@linux.intel.com>
29 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30
31*******************************************************************************/
32
33#include <linux/compiler.h>
34//#include <linux/config.h>
35#include <linux/errno.h>
36#include <linux/if_arp.h>
37#include <linux/in6.h>
38#include <linux/in.h>
39#include <linux/ip.h>
40#include <linux/kernel.h>
41#include <linux/module.h>
42#include <linux/netdevice.h>
43#include <linux/pci.h>
44#include <linux/proc_fs.h>
45#include <linux/skbuff.h>
46#include <linux/slab.h>
47#include <linux/tcp.h>
48#include <linux/types.h>
49#include <linux/version.h>
50#include <linux/wireless.h>
51#include <linux/etherdevice.h>
52#include <asm/uaccess.h>
53#include <net/arp.h>
54#include <net/net_namespace.h>
55
56#include "ieee80211.h"
57
58MODULE_DESCRIPTION("802.11 data/management/control stack");
59MODULE_AUTHOR("Copyright (C) 2004 Intel Corporation <jketreno@linux.intel.com>");
60MODULE_LICENSE("GPL");
61
62#define DRV_NAME "ieee80211"
63
64static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee)
65{
66 if (ieee->networks)
67 return 0;
68
69 ieee->networks = kmalloc(
70 MAX_NETWORK_COUNT * sizeof(struct ieee80211_network),
71 GFP_KERNEL);
72 if (!ieee->networks) {
73 printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
74 ieee->dev->name);
75 return -ENOMEM;
76 }
77
78 memset(ieee->networks, 0,
79 MAX_NETWORK_COUNT * sizeof(struct ieee80211_network));
80
81 return 0;
82}
83
84static inline void ieee80211_networks_free(struct ieee80211_device *ieee)
85{
86 if (!ieee->networks)
87 return;
88 kfree(ieee->networks);
89 ieee->networks = NULL;
90}
91
92static inline void ieee80211_networks_initialize(struct ieee80211_device *ieee)
93{
94 int i;
95
96 INIT_LIST_HEAD(&ieee->network_free_list);
97 INIT_LIST_HEAD(&ieee->network_list);
98 for (i = 0; i < MAX_NETWORK_COUNT; i++)
99 list_add_tail(&ieee->networks[i].list, &ieee->network_free_list);
100}
101
102
103struct net_device *alloc_ieee80211(int sizeof_priv)
104{
105 struct ieee80211_device *ieee;
106 struct net_device *dev;
107 int i,err;
108
109 IEEE80211_DEBUG_INFO("Initializing...\n");
110
111 dev = alloc_etherdev(sizeof(struct ieee80211_device) + sizeof_priv);
112 if (!dev) {
113 IEEE80211_ERROR("Unable to network device.\n");
114 goto failed;
115 }
116 ieee = netdev_priv(dev);
117 dev->hard_start_xmit = ieee80211_xmit;
118
119 ieee->dev = dev;
120
121 err = ieee80211_networks_allocate(ieee);
122 if (err) {
123 IEEE80211_ERROR("Unable to allocate beacon storage: %d\n",
124 err);
125 goto failed;
126 }
127 ieee80211_networks_initialize(ieee);
128
129 /* Default fragmentation threshold is maximum payload size */
130 ieee->fts = DEFAULT_FTS;
131 ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
132 ieee->open_wep = 1;
133
134 /* Default to enabling full open WEP with host based encrypt/decrypt */
135 ieee->host_encrypt = 1;
136 ieee->host_decrypt = 1;
137 ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
138
139 INIT_LIST_HEAD(&ieee->crypt_deinit_list);
140 init_timer(&ieee->crypt_deinit_timer);
141 ieee->crypt_deinit_timer.data = (unsigned long)ieee;
142 ieee->crypt_deinit_timer.function = ieee80211_crypt_deinit_handler;
143
144 spin_lock_init(&ieee->lock);
145 spin_lock_init(&ieee->wpax_suitlist_lock);
146
147 ieee->wpax_type_set = 0;
148 ieee->wpa_enabled = 0;
149 ieee->tkip_countermeasures = 0;
150 ieee->drop_unencrypted = 0;
151 ieee->privacy_invoked = 0;
152 ieee->ieee802_1x = 1;
153 ieee->raw_tx = 0;
154
155 ieee80211_softmac_init(ieee);
156
157 for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++)
158 INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]);
159
160 for (i = 0; i < 17; i++) {
161 ieee->last_rxseq_num[i] = -1;
162 ieee->last_rxfrag_num[i] = -1;
163 ieee->last_packet_time[i] = 0;
164 }
165//These function were added to load crypte module autoly
166 ieee80211_tkip_null();
167 ieee80211_wep_null();
168 ieee80211_ccmp_null();
169 return dev;
170
171 failed:
172 if (dev)
173 free_netdev(dev);
174 return NULL;
175}
176
177
178void free_ieee80211(struct net_device *dev)
179{
180 struct ieee80211_device *ieee = netdev_priv(dev);
181
182 int i;
183 struct list_head *p, *q;
184
185
186 ieee80211_softmac_free(ieee);
187 del_timer_sync(&ieee->crypt_deinit_timer);
188 ieee80211_crypt_deinit_entries(ieee, 1);
189
190 for (i = 0; i < WEP_KEYS; i++) {
191 struct ieee80211_crypt_data *crypt = ieee->crypt[i];
192 if (crypt) {
193 if (crypt->ops) {
194 crypt->ops->deinit(crypt->priv);
195 module_put(crypt->ops->owner);
196 }
197 kfree(crypt);
198 ieee->crypt[i] = NULL;
199 }
200 }
201
202 ieee80211_networks_free(ieee);
203
204 for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++) {
205 list_for_each_safe(p, q, &ieee->ibss_mac_hash[i]) {
206 kfree(list_entry(p, struct ieee_ibss_seq, list));
207 list_del(p);
208 }
209 }
210
211
212 free_netdev(dev);
213}
214
215//#ifdef CONFIG_IEEE80211_DEBUG
216#if 0
217
218static int debug = 0;
219u32 ieee80211_debug_level = 0;
220struct proc_dir_entry *ieee80211_proc = NULL;
221
222static int show_debug_level(char *page, char **start, off_t offset,
223 int count, int *eof, void *data)
224{
225 return snprintf(page, count, "0x%08X\n", ieee80211_debug_level);
226}
227
228static int store_debug_level(struct file *file, const char *buffer,
229 unsigned long count, void *data)
230{
231 char buf[] = "0x00000000";
232 unsigned long len = min(sizeof(buf) - 1, (u32)count);
233 char *p = (char *)buf;
234 unsigned long val;
235
236 if (copy_from_user(buf, buffer, len))
237 return count;
238 buf[len] = 0;
239 if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
240 p++;
241 if (p[0] == 'x' || p[0] == 'X')
242 p++;
243 val = simple_strtoul(p, &p, 16);
244 } else
245 val = simple_strtoul(p, &p, 10);
246 if (p == buf)
247 printk(KERN_INFO DRV_NAME
248 ": %s is not in hex or decimal form.\n", buf);
249 else
250 ieee80211_debug_level = val;
251
252 return strnlen(buf, count);
253}
254
255static int __init ieee80211_init(void)
256{
257 struct proc_dir_entry *e;
258
259 ieee80211_debug_level = debug;
260 ieee80211_proc = create_proc_entry(DRV_NAME, S_IFDIR, proc_net);
261 if (ieee80211_proc == NULL) {
262 IEEE80211_ERROR("Unable to create " DRV_NAME
263 " proc directory\n");
264 return -EIO;
265 }
266 e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
267 ieee80211_proc);
268 if (!e) {
269 remove_proc_entry(DRV_NAME, proc_net);
270 ieee80211_proc = NULL;
271 return -EIO;
272 }
273 e->read_proc = show_debug_level;
274 e->write_proc = store_debug_level;
275 e->data = NULL;
276
277 return 0;
278}
279
280static void __exit ieee80211_exit(void)
281{
282 if (ieee80211_proc) {
283 remove_proc_entry("debug_level", ieee80211_proc);
284 remove_proc_entry(DRV_NAME, proc_net);
285 ieee80211_proc = NULL;
286 }
287}
288
289#include <linux/moduleparam.h>
290module_param(debug, int, 0444);
291MODULE_PARM_DESC(debug, "debug output mask");
292
293
294module_exit(ieee80211_exit);
295module_init(ieee80211_init);
296#endif
297
298#if 0
299EXPORT_SYMBOL(alloc_ieee80211);
300EXPORT_SYMBOL(free_ieee80211);
301#endif
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c
new file mode 100644
index 000000000000..79ec64959cf6
--- /dev/null
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c
@@ -0,0 +1,1971 @@
1/*
2 * Original code based Host AP (software wireless LAN access point) driver
3 * for Intersil Prism2/2.5/3 - hostap.o module, common routines
4 *
5 * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
6 * <jkmaline@cc.hut.fi>
7 * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
8 * Copyright (c) 2004, Intel Corporation
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation. See README and COPYING for
13 * more details.
14 ******************************************************************************
15
16 Few modifications for Realtek's Wi-Fi drivers by
17 Andrea Merello <andreamrl@tiscali.it>
18
19 A special thanks goes to Realtek for their support !
20
21******************************************************************************/
22
23
24#include <linux/compiler.h>
25//#include <linux/config.h>
26#include <linux/errno.h>
27#include <linux/if_arp.h>
28#include <linux/in6.h>
29#include <linux/in.h>
30#include <linux/ip.h>
31#include <linux/kernel.h>
32#include <linux/module.h>
33#include <linux/netdevice.h>
34#include <linux/pci.h>
35#include <linux/proc_fs.h>
36#include <linux/skbuff.h>
37#include <linux/slab.h>
38#include <linux/tcp.h>
39#include <linux/types.h>
40#include <linux/version.h>
41#include <linux/wireless.h>
42#include <linux/etherdevice.h>
43#include <asm/uaccess.h>
44#include <linux/ctype.h>
45
46#include "ieee80211.h"
47#ifdef ENABLE_DOT11D
48#include "dot11d.h"
49#endif
50static inline void ieee80211_monitor_rx(struct ieee80211_device *ieee,
51 struct sk_buff *skb,
52 struct ieee80211_rx_stats *rx_stats)
53{
54 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
55 u16 fc = le16_to_cpu(hdr->frame_ctl);
56
57 skb->dev = ieee->dev;
58#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
59 skb_reset_mac_header(skb);
60#else
61 skb->mac.raw = skb->data;
62#endif
63 skb_pull(skb, ieee80211_get_hdrlen(fc));
64 skb->pkt_type = PACKET_OTHERHOST;
65 skb->protocol = __constant_htons(ETH_P_80211_RAW);
66 memset(skb->cb, 0, sizeof(skb->cb));
67 netif_rx(skb);
68}
69
70
71/* Called only as a tasklet (software IRQ) */
72static struct ieee80211_frag_entry *
73ieee80211_frag_cache_find(struct ieee80211_device *ieee, unsigned int seq,
74 unsigned int frag, u8 tid,u8 *src, u8 *dst)
75{
76 struct ieee80211_frag_entry *entry;
77 int i;
78
79 for (i = 0; i < IEEE80211_FRAG_CACHE_LEN; i++) {
80 entry = &ieee->frag_cache[tid][i];
81 if (entry->skb != NULL &&
82 time_after(jiffies, entry->first_frag_time + 2 * HZ)) {
83 IEEE80211_DEBUG_FRAG(
84 "expiring fragment cache entry "
85 "seq=%u last_frag=%u\n",
86 entry->seq, entry->last_frag);
87 dev_kfree_skb_any(entry->skb);
88 entry->skb = NULL;
89 }
90
91 if (entry->skb != NULL && entry->seq == seq &&
92 (entry->last_frag + 1 == frag || frag == -1) &&
93 memcmp(entry->src_addr, src, ETH_ALEN) == 0 &&
94 memcmp(entry->dst_addr, dst, ETH_ALEN) == 0)
95 return entry;
96 }
97
98 return NULL;
99}
100
101/* Called only as a tasklet (software IRQ) */
102static struct sk_buff *
103ieee80211_frag_cache_get(struct ieee80211_device *ieee,
104 struct ieee80211_hdr *hdr)
105{
106 struct sk_buff *skb = NULL;
107 u16 fc = le16_to_cpu(hdr->frame_ctl);
108 u16 sc = le16_to_cpu(hdr->seq_ctl);
109 unsigned int frag = WLAN_GET_SEQ_FRAG(sc);
110 unsigned int seq = WLAN_GET_SEQ_SEQ(sc);
111 struct ieee80211_frag_entry *entry;
112 struct ieee80211_hdr_3addr_QOS *hdr_3addr_QoS;
113 struct ieee80211_hdr_QOS *hdr_4addr_QoS;
114 u8 tid;
115
116#ifdef _RTL8187_EXT_PATCH_
117 if(ieee->iw_mode == ieee->iw_ext_mode)
118 {
119 tid = (hdr->addr2[ETH_ALEN-2] ^ hdr->addr2[ETH_ALEN-1]) & IEEE80211_QOS_TID;
120 }
121 else
122#endif
123 if (((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) {
124 hdr_4addr_QoS = (struct ieee80211_hdr_QOS *)hdr;
125 tid = le16_to_cpu(hdr_4addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
126 tid = UP2AC(tid);
127 tid ++;
128 } else if (IEEE80211_QOS_HAS_SEQ(fc)) {
129 hdr_3addr_QoS = (struct ieee80211_hdr_3addr_QOS *)hdr;
130 tid = le16_to_cpu(hdr_3addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
131 tid = UP2AC(tid);
132 tid ++;
133 } else {
134 tid = 0;
135 }
136
137 if (frag == 0) {
138 /* Reserve enough space to fit maximum frame length */
139 skb = dev_alloc_skb(ieee->dev->mtu +
140 sizeof(struct ieee80211_hdr) +
141 8 /* LLC */ +
142 2 /* alignment */ +
143 8 /* WEP */ +
144 ETH_ALEN /* WDS */ +
145 (IEEE80211_QOS_HAS_SEQ(fc)?2:0) /* QOS Control */);
146 if (skb == NULL)
147 return NULL;
148
149 entry = &ieee->frag_cache[tid][ieee->frag_next_idx[tid]];
150 ieee->frag_next_idx[tid]++;
151 if (ieee->frag_next_idx[tid] >= IEEE80211_FRAG_CACHE_LEN)
152 ieee->frag_next_idx[tid] = 0;
153
154 if (entry->skb != NULL)
155 dev_kfree_skb_any(entry->skb);
156
157 entry->first_frag_time = jiffies;
158 entry->seq = seq;
159 entry->last_frag = frag;
160 entry->skb = skb;
161 memcpy(entry->src_addr, hdr->addr2, ETH_ALEN);
162 memcpy(entry->dst_addr, hdr->addr1, ETH_ALEN);
163 } else {
164 /* received a fragment of a frame for which the head fragment
165 * should have already been received */
166 entry = ieee80211_frag_cache_find(ieee, seq, frag, tid,hdr->addr2,
167 hdr->addr1);
168 if (entry != NULL) {
169 entry->last_frag = frag;
170 skb = entry->skb;
171 }
172 }
173
174 return skb;
175}
176
177
178/* Called only as a tasklet (software IRQ) */
179static int ieee80211_frag_cache_invalidate(struct ieee80211_device *ieee,
180 struct ieee80211_hdr *hdr)
181{
182 u16 fc = le16_to_cpu(hdr->frame_ctl);
183 u16 sc = le16_to_cpu(hdr->seq_ctl);
184 unsigned int seq = WLAN_GET_SEQ_SEQ(sc);
185 struct ieee80211_frag_entry *entry;
186 struct ieee80211_hdr_3addr_QOS *hdr_3addr_QoS;
187 struct ieee80211_hdr_QOS *hdr_4addr_QoS;
188 u8 tid;
189
190#ifdef _RTL8187_EXT_PATCH_
191 if(ieee->iw_mode == ieee->iw_ext_mode)
192 {
193 tid = (hdr->addr2[ETH_ALEN-2] ^ hdr->addr2[ETH_ALEN-1]) & IEEE80211_QOS_TID;
194 }
195 else
196#endif
197 if(((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) {
198 hdr_4addr_QoS = (struct ieee80211_hdr_QOS *)hdr;
199 tid = le16_to_cpu(hdr_4addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
200 tid = UP2AC(tid);
201 tid ++;
202 } else if (IEEE80211_QOS_HAS_SEQ(fc)) {
203 hdr_3addr_QoS = (struct ieee80211_hdr_3addr_QOS *)hdr;
204 tid = le16_to_cpu(hdr_3addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
205 tid = UP2AC(tid);
206 tid ++;
207 } else {
208 tid = 0;
209 }
210
211 entry = ieee80211_frag_cache_find(ieee, seq, -1, tid,hdr->addr2,
212 hdr->addr1);
213
214 if (entry == NULL) {
215 IEEE80211_DEBUG_FRAG(
216 "could not invalidate fragment cache "
217 "entry (seq=%u)\n", seq);
218 return -1;
219 }
220
221 entry->skb = NULL;
222 return 0;
223}
224
225
226
227/* ieee80211_rx_frame_mgtmt
228 *
229 * Responsible for handling management control frames
230 *
231 * Called by ieee80211_rx */
232static inline int
233ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb,
234 struct ieee80211_rx_stats *rx_stats, u16 type,
235 u16 stype)
236{
237 struct ieee80211_hdr *hdr;
238
239 // cheat the the hdr type
240 hdr = (struct ieee80211_hdr *)skb->data;
241
242 /* On the struct stats definition there is written that
243 * this is not mandatory.... but seems that the probe
244 * response parser uses it
245 */
246 rx_stats->len = skb->len;
247 ieee80211_rx_mgt(ieee,(struct ieee80211_hdr *)skb->data,rx_stats);
248
249 if((ieee->state == IEEE80211_LINKED)&&(memcmp(hdr->addr3,ieee->current_network.bssid,ETH_ALEN))) {
250 dev_kfree_skb_any(skb);
251 return 0;
252 }
253
254 ieee80211_rx_frame_softmac(ieee, skb, rx_stats, type, stype);
255
256 dev_kfree_skb_any(skb);
257
258 return 0;
259
260 #ifdef NOT_YET
261 if (ieee->iw_mode == IW_MODE_MASTER) {
262 printk(KERN_DEBUG "%s: Master mode not yet suppported.\n",
263 ieee->dev->name);
264 return 0;
265/*
266 hostap_update_sta_ps(ieee, (struct hostap_ieee80211_hdr *)
267 skb->data);*/
268 }
269
270 if (ieee->hostapd && type == IEEE80211_TYPE_MGMT) {
271 if (stype == WLAN_FC_STYPE_BEACON &&
272 ieee->iw_mode == IW_MODE_MASTER) {
273 struct sk_buff *skb2;
274 /* Process beacon frames also in kernel driver to
275 * update STA(AP) table statistics */
276 skb2 = skb_clone(skb, GFP_ATOMIC);
277 if (skb2)
278 hostap_rx(skb2->dev, skb2, rx_stats);
279 }
280
281 /* send management frames to the user space daemon for
282 * processing */
283 ieee->apdevstats.rx_packets++;
284 ieee->apdevstats.rx_bytes += skb->len;
285 prism2_rx_80211(ieee->apdev, skb, rx_stats, PRISM2_RX_MGMT);
286 return 0;
287 }
288
289 if (ieee->iw_mode == IW_MODE_MASTER) {
290 if (type != WLAN_FC_TYPE_MGMT && type != WLAN_FC_TYPE_CTRL) {
291 printk(KERN_DEBUG "%s: unknown management frame "
292 "(type=0x%02x, stype=0x%02x) dropped\n",
293 skb->dev->name, type, stype);
294 return -1;
295 }
296
297 hostap_rx(skb->dev, skb, rx_stats);
298 return 0;
299 }
300
301 printk(KERN_DEBUG "%s: hostap_rx_frame_mgmt: management frame "
302 "received in non-Host AP mode\n", skb->dev->name);
303 return -1;
304 #endif
305}
306
307
308
309/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
310/* Ethernet-II snap header (RFC1042 for most EtherTypes) */
311static unsigned char rfc1042_header[] =
312{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
313/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
314static unsigned char bridge_tunnel_header[] =
315{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
316/* No encapsulation header if EtherType < 0x600 (=length) */
317
318/* Called by ieee80211_rx_frame_decrypt */
319static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee,
320 struct sk_buff *skb, size_t hdrlen)
321{
322 struct net_device *dev = ieee->dev;
323 u16 fc, ethertype;
324 struct ieee80211_hdr *hdr;
325 u8 *pos;
326
327 if (skb->len < 24)
328 return 0;
329
330 hdr = (struct ieee80211_hdr *) skb->data;
331 fc = le16_to_cpu(hdr->frame_ctl);
332
333 /* check that the frame is unicast frame to us */
334 if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
335 IEEE80211_FCTL_TODS &&
336 memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0 &&
337 memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) {
338 /* ToDS frame with own addr BSSID and DA */
339 } else if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
340 IEEE80211_FCTL_FROMDS &&
341 memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) {
342 /* FromDS frame with own addr as DA */
343 } else
344 return 0;
345
346 if (skb->len < 24 + 8)
347 return 0;
348
349 /* check for port access entity Ethernet type */
350// pos = skb->data + 24;
351 pos = skb->data + hdrlen;
352 ethertype = (pos[6] << 8) | pos[7];
353 if (ethertype == ETH_P_PAE)
354 return 1;
355
356 return 0;
357}
358
359/* Called only as a tasklet (software IRQ), by ieee80211_rx */
360static inline int
361ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb,
362 struct ieee80211_crypt_data *crypt)
363{
364 struct ieee80211_hdr *hdr;
365 int res, hdrlen;
366
367 if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
368 return 0;
369
370 hdr = (struct ieee80211_hdr *) skb->data;
371#ifdef _RTL8187_EXT_PATCH_
372 if((ieee->iw_mode == ieee->iw_ext_mode) && (ieee->ext_patch_ieee80211_rx_frame_get_hdrlen))
373 {
374 hdrlen = ieee->ext_patch_ieee80211_rx_frame_get_hdrlen(ieee, skb);
375 }
376 else
377#endif
378 hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
379
380#ifdef CONFIG_IEEE80211_CRYPT_TKIP
381 if (ieee->tkip_countermeasures &&
382 strcmp(crypt->ops->name, "TKIP") == 0) {
383 if (net_ratelimit()) {
384 printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
385 "received packet from " MAC_FMT "\n",
386 ieee->dev->name, MAC_ARG(hdr->addr2));
387 }
388 return -1;
389 }
390#endif
391
392 atomic_inc(&crypt->refcnt);
393 res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv);
394 atomic_dec(&crypt->refcnt);
395 if (res < 0) {
396 IEEE80211_DEBUG_DROP(
397 "decryption failed (SA=" MAC_FMT
398 ") res=%d\n", MAC_ARG(hdr->addr2), res);
399 if (res == -2)
400 IEEE80211_DEBUG_DROP("Decryption failed ICV "
401 "mismatch (key %d)\n",
402 skb->data[hdrlen + 3] >> 6);
403 ieee->ieee_stats.rx_discards_undecryptable++;
404 return -1;
405 }
406
407 return res;
408}
409
410
411/* Called only as a tasklet (software IRQ), by ieee80211_rx */
412static inline int
413ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device* ieee, struct sk_buff *skb,
414 int keyidx, struct ieee80211_crypt_data *crypt)
415{
416 struct ieee80211_hdr *hdr;
417 int res, hdrlen;
418
419 if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
420 return 0;
421
422 hdr = (struct ieee80211_hdr *) skb->data;
423#ifdef _RTL8187_EXT_PATCH_
424 if((ieee->iw_mode == ieee->iw_ext_mode) && (ieee->ext_patch_ieee80211_rx_frame_get_hdrlen))
425 {
426 hdrlen = ieee->ext_patch_ieee80211_rx_frame_get_hdrlen(ieee, skb);
427 }
428 else
429#endif
430 hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
431
432 atomic_inc(&crypt->refcnt);
433 res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv);
434 atomic_dec(&crypt->refcnt);
435 if (res < 0) {
436 printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
437 " (SA=" MAC_FMT " keyidx=%d)\n",
438 ieee->dev->name, MAC_ARG(hdr->addr2), keyidx);
439 return -1;
440 }
441
442 return 0;
443}
444
445
446/* this function is stolen from ipw2200 driver*/
447#define IEEE_PACKET_RETRY_TIME (5*HZ)
448static int is_duplicate_packet(struct ieee80211_device *ieee,
449 struct ieee80211_hdr *header)
450{
451 u16 fc = le16_to_cpu(header->frame_ctl);
452 u16 sc = le16_to_cpu(header->seq_ctl);
453 u16 seq = WLAN_GET_SEQ_SEQ(sc);
454 u16 frag = WLAN_GET_SEQ_FRAG(sc);
455 u16 *last_seq, *last_frag;
456 unsigned long *last_time;
457 struct ieee80211_hdr_3addr_QOS *hdr_3addr_QoS;
458 struct ieee80211_hdr_QOS *hdr_4addr_QoS;
459 u8 tid;
460
461#ifdef _RTL8187_EXT_PATCH_
462 if(ieee->iw_mode == ieee->iw_ext_mode)
463 {
464 tid = (header->addr2[ETH_ALEN-2] ^ header->addr2[ETH_ALEN-1]) & IEEE80211_QOS_TID;
465 }
466 else
467#endif
468 //TO2DS and QoS
469 if(((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) {
470 hdr_4addr_QoS = (struct ieee80211_hdr_QOS *)header;
471 tid = le16_to_cpu(hdr_4addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
472 tid = UP2AC(tid);
473 tid ++;
474 } else if(IEEE80211_QOS_HAS_SEQ(fc)) { //QoS
475 hdr_3addr_QoS = (struct ieee80211_hdr_3addr_QOS*)header;
476 tid = le16_to_cpu(hdr_3addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
477 tid = UP2AC(tid);
478 tid ++;
479 } else { // no QoS
480 tid = 0;
481 }
482 switch (ieee->iw_mode) {
483 case IW_MODE_ADHOC:
484 {
485 struct list_head *p;
486 struct ieee_ibss_seq *entry = NULL;
487 u8 *mac = header->addr2;
488 int index = mac[5] % IEEE_IBSS_MAC_HASH_SIZE;
489 //for (pos = (head)->next; pos != (head); pos = pos->next)
490 __list_for_each(p, &ieee->ibss_mac_hash[index]) {
491 entry = list_entry(p, struct ieee_ibss_seq, list);
492 if (!memcmp(entry->mac, mac, ETH_ALEN))
493 break;
494 }
495 // if (memcmp(entry->mac, mac, ETH_ALEN)){
496 if (p == &ieee->ibss_mac_hash[index]) {
497 entry = kmalloc(sizeof(struct ieee_ibss_seq), GFP_ATOMIC);
498 if (!entry) {
499 printk(KERN_WARNING "Cannot malloc new mac entry\n");
500 return 0;
501 }
502 memcpy(entry->mac, mac, ETH_ALEN);
503 entry->seq_num[tid] = seq;
504 entry->frag_num[tid] = frag;
505 entry->packet_time[tid] = jiffies;
506 list_add(&entry->list, &ieee->ibss_mac_hash[index]);
507 return 0;
508 }
509 last_seq = &entry->seq_num[tid];
510 last_frag = &entry->frag_num[tid];
511 last_time = &entry->packet_time[tid];
512 break;
513 }
514
515 case IW_MODE_INFRA:
516 last_seq = &ieee->last_rxseq_num[tid];
517 last_frag = &ieee->last_rxfrag_num[tid];
518 last_time = &ieee->last_packet_time[tid];
519
520 break;
521 default:
522#ifdef _RTL8187_EXT_PATCH_
523 if(ieee->iw_mode == ieee->iw_ext_mode)
524 {
525 last_seq = &ieee->last_rxseq_num[tid];
526 last_frag = &ieee->last_rxfrag_num[tid];
527 last_time = &ieee->last_packet_time[tid];
528 break;
529 }
530 else
531#endif
532 return 0;
533 }
534
535// if(tid != 0) {
536// printk(KERN_WARNING ":)))))))))))%x %x %x, fc(%x)\n", tid, *last_seq, seq, header->frame_ctl);
537// }
538 if ((*last_seq == seq) &&
539 time_after(*last_time + IEEE_PACKET_RETRY_TIME, jiffies)) {
540 if (*last_frag == frag){
541 //printk(KERN_WARNING "[1] go drop!\n");
542 goto drop;
543
544 }
545 if (*last_frag + 1 != frag)
546 /* out-of-order fragment */
547 //printk(KERN_WARNING "[2] go drop!\n");
548 goto drop;
549 } else
550 *last_seq = seq;
551
552 *last_frag = frag;
553 *last_time = jiffies;
554 return 0;
555
556drop:
557// BUG_ON(!(fc & IEEE80211_FCTL_RETRY));
558// printk("DUP\n");
559
560 return 1;
561}
562
563
564/* All received frames are sent to this function. @skb contains the frame in
565 * IEEE 802.11 format, i.e., in the format it was sent over air.
566 * This function is called only as a tasklet (software IRQ). */
567int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
568 struct ieee80211_rx_stats *rx_stats)
569{
570 struct net_device *dev = ieee->dev;
571 //struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
572 struct ieee80211_hdr *hdr;
573 //struct ieee80211_hdr_3addr_QOS *hdr;
574
575 size_t hdrlen;
576 u16 fc, type, stype, sc;
577 struct net_device_stats *stats;
578 unsigned int frag;
579 u8 *payload;
580 u16 ethertype;
581#ifdef NOT_YET
582 struct net_device *wds = NULL;
583 struct sk_buff *skb2 = NULL;
584 struct net_device *wds = NULL;
585 int frame_authorized = 0;
586 int from_assoc_ap = 0;
587 void *sta = NULL;
588#endif
589// u16 QOS_ctl = 0;
590 u8 dst[ETH_ALEN];
591 u8 src[ETH_ALEN];
592 u8 bssid[ETH_ALEN];
593 struct ieee80211_crypt_data *crypt = NULL;
594 int keyidx = 0;
595
596 //Added for mesh by Lawrence.
597#ifdef _RTL8187_EXT_PATCH_
598 u8 status;
599 u32 flags;
600#endif
601 // cheat the the hdr type
602 hdr = (struct ieee80211_hdr *)skb->data;
603 stats = &ieee->stats;
604
605 if (skb->len < 10) {
606 printk(KERN_INFO "%s: SKB length < 10\n",
607 dev->name);
608 goto rx_dropped;
609 }
610
611 fc = le16_to_cpu(hdr->frame_ctl);
612 type = WLAN_FC_GET_TYPE(fc);
613 stype = WLAN_FC_GET_STYPE(fc);
614 sc = le16_to_cpu(hdr->seq_ctl);
615
616 frag = WLAN_GET_SEQ_FRAG(sc);
617
618//YJ,add,080828,for keep alive
619 if((fc & IEEE80211_FCTL_TODS) != IEEE80211_FCTL_TODS)
620 {
621 if(!memcmp(hdr->addr1,dev->dev_addr, ETH_ALEN))
622 {
623 ieee->NumRxUnicast++;
624 }
625 }
626 else
627 {
628 if(!memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN))
629 {
630 ieee->NumRxUnicast++;
631 }
632 }
633//YJ,add,080828,for keep alive,end
634
635#ifdef _RTL8187_EXT_PATCH_
636 if((ieee->iw_mode == ieee->iw_ext_mode) && (ieee->ext_patch_ieee80211_rx_frame_get_hdrlen))
637 {
638 hdrlen = ieee->ext_patch_ieee80211_rx_frame_get_hdrlen(ieee, skb);
639 if(skb->len < hdrlen)
640 goto rx_dropped;
641 }
642 else
643#endif
644 hdrlen = ieee80211_get_hdrlen(fc);
645
646#ifdef NOT_YET
647#if WIRELESS_EXT > 15
648 /* Put this code here so that we avoid duplicating it in all
649 * Rx paths. - Jean II */
650#ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */
651 /* If spy monitoring on */
652 if (iface->spy_data.spy_number > 0) {
653 struct iw_quality wstats;
654 wstats.level = rx_stats->signal;
655 wstats.noise = rx_stats->noise;
656 wstats.updated = 6; /* No qual value */
657 /* Update spy records */
658 wireless_spy_update(dev, hdr->addr2, &wstats);
659 }
660#endif /* IW_WIRELESS_SPY */
661#endif /* WIRELESS_EXT > 15 */
662 hostap_update_rx_stats(local->ap, hdr, rx_stats);
663#endif
664
665#if WIRELESS_EXT > 15
666 if (ieee->iw_mode == IW_MODE_MONITOR) {
667 ieee80211_monitor_rx(ieee, skb, rx_stats);
668 stats->rx_packets++;
669 stats->rx_bytes += skb->len;
670 return 1;
671 }
672#endif
673 if (ieee->host_decrypt) {
674 int idx = 0;
675 if (skb->len >= hdrlen + 3)
676 idx = skb->data[hdrlen + 3] >> 6;
677 crypt = ieee->crypt[idx];
678#ifdef NOT_YET
679 sta = NULL;
680
681 /* Use station specific key to override default keys if the
682 * receiver address is a unicast address ("individual RA"). If
683 * bcrx_sta_key parameter is set, station specific key is used
684 * even with broad/multicast targets (this is against IEEE
685 * 802.11, but makes it easier to use different keys with
686 * stations that do not support WEP key mapping). */
687
688 if (!(hdr->addr1[0] & 0x01) || local->bcrx_sta_key)
689 (void) hostap_handle_sta_crypto(local, hdr, &crypt,
690 &sta);
691#endif
692
693 /* allow NULL decrypt to indicate an station specific override
694 * for default encryption */
695 if (crypt && (crypt->ops == NULL ||
696 crypt->ops->decrypt_mpdu == NULL))
697 crypt = NULL;
698
699 if (!crypt && (fc & IEEE80211_FCTL_WEP)) {
700 /* This seems to be triggered by some (multicast?)
701 * frames from other than current BSS, so just drop the
702 * frames silently instead of filling system log with
703 * these reports. */
704 IEEE80211_DEBUG_DROP("Decryption failed (not set)"
705 " (SA=" MAC_FMT ")\n",
706 MAC_ARG(hdr->addr2));
707 ieee->ieee_stats.rx_discards_undecryptable++;
708 goto rx_dropped;
709 }
710 }
711
712 if (skb->len < IEEE80211_DATA_HDR3_LEN)
713 goto rx_dropped;
714
715#ifdef _RTL8187_EXT_PATCH_
716 if( ieee->iw_mode == ieee->iw_ext_mode && ieee->ext_patch_ieee80211_rx_mgt_update_expire )
717 ieee->ext_patch_ieee80211_rx_mgt_update_expire( ieee, skb );
718#endif
719
720 // if QoS enabled, should check the sequence for each of the AC
721 if (is_duplicate_packet(ieee, hdr))
722 goto rx_dropped;
723
724
725 if (type == IEEE80211_FTYPE_MGMT) {
726
727 #if 0
728 if ( stype == IEEE80211_STYPE_AUTH &&
729 fc & IEEE80211_FCTL_WEP && ieee->host_decrypt &&
730 (keyidx = hostap_rx_frame_decrypt(ieee, skb, crypt)) < 0)
731 {
732 printk(KERN_DEBUG "%s: failed to decrypt mgmt::auth "
733 "from " MAC_FMT "\n", dev->name,
734 MAC_ARG(hdr->addr2));
735 /* TODO: could inform hostapd about this so that it
736 * could send auth failure report */
737 goto rx_dropped;
738 }
739 #endif
740
741
742 if (ieee80211_rx_frame_mgmt(ieee, skb, rx_stats, type, stype))
743 goto rx_dropped;
744 else
745 goto rx_exit;
746 }
747#ifdef _RTL8187_EXT_PATCH_
748 if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_on_rx)
749 {
750 if(ieee->ext_patch_ieee80211_rx_on_rx(ieee, skb, rx_stats, type, stype)==0)
751 {
752 goto rx_exit;
753 }
754 }
755#endif
756
757 /* Data frame - extract src/dst addresses */
758 switch (fc & (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
759 case IEEE80211_FCTL_FROMDS:
760 memcpy(dst, hdr->addr1, ETH_ALEN);
761 memcpy(src, hdr->addr3, ETH_ALEN);
762 memcpy(bssid,hdr->addr2,ETH_ALEN);
763 break;
764 case IEEE80211_FCTL_TODS:
765 memcpy(dst, hdr->addr3, ETH_ALEN);
766 memcpy(src, hdr->addr2, ETH_ALEN);
767 memcpy(bssid,hdr->addr1,ETH_ALEN);
768 break;
769 case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
770 if (skb->len < IEEE80211_DATA_HDR4_LEN)
771 goto rx_dropped;
772 memcpy(dst, hdr->addr3, ETH_ALEN);
773 memcpy(src, hdr->addr4, ETH_ALEN);
774 memcpy(bssid, ieee->current_network.bssid, ETH_ALEN);
775 break;
776 case 0:
777 memcpy(dst, hdr->addr1, ETH_ALEN);
778 memcpy(src, hdr->addr2, ETH_ALEN);
779 memcpy(bssid,hdr->addr3,ETH_ALEN);
780 break;
781 }
782
783#ifdef NOT_YET
784 if (hostap_rx_frame_wds(ieee, hdr, fc, &wds))
785 goto rx_dropped;
786 if (wds) {
787 skb->dev = dev = wds;
788 stats = hostap_get_stats(dev);
789 }
790
791 if (ieee->iw_mode == IW_MODE_MASTER && !wds &&
792 (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == IEEE80211_FCTL_FROMDS &&
793 ieee->stadev &&
794 memcmp(hdr->addr2, ieee->assoc_ap_addr, ETH_ALEN) == 0) {
795 /* Frame from BSSID of the AP for which we are a client */
796 skb->dev = dev = ieee->stadev;
797 stats = hostap_get_stats(dev);
798 from_assoc_ap = 1;
799 }
800#endif
801
802 dev->last_rx = jiffies;
803
804#ifdef NOT_YET
805 if ((ieee->iw_mode == IW_MODE_MASTER ||
806 ieee->iw_mode == IW_MODE_REPEAT) &&
807 !from_assoc_ap) {
808 switch (hostap_handle_sta_rx(ieee, dev, skb, rx_stats,
809 wds != NULL)) {
810 case AP_RX_CONTINUE_NOT_AUTHORIZED:
811 frame_authorized = 0;
812 break;
813 case AP_RX_CONTINUE:
814 frame_authorized = 1;
815 break;
816 case AP_RX_DROP:
817 goto rx_dropped;
818 case AP_RX_EXIT:
819 goto rx_exit;
820 }
821 }
822#endif
823
824#ifdef _RTL8187_EXT_PATCH_
825 if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_is_valid_framectl)
826 {
827 if(ieee->ext_patch_ieee80211_rx_is_valid_framectl(ieee, fc, type, stype)==0)
828 goto rx_dropped;
829 }
830 else
831#endif
832 /* Nullfunc frames may have PS-bit set, so they must be passed to
833 * hostap_handle_sta_rx() before being dropped here. */
834 if (stype != IEEE80211_STYPE_DATA &&
835 stype != IEEE80211_STYPE_DATA_CFACK &&
836 stype != IEEE80211_STYPE_DATA_CFPOLL &&
837 stype != IEEE80211_STYPE_DATA_CFACKPOLL&&
838 stype != IEEE80211_STYPE_QOS_DATA//add by David,2006.8.4
839 ) {
840 if (stype != IEEE80211_STYPE_NULLFUNC)
841 IEEE80211_DEBUG_DROP(
842 "RX: dropped data frame "
843 "with no data (type=0x%02x, "
844 "subtype=0x%02x, len=%d)\n",
845 type, stype, skb->len);
846 goto rx_dropped;
847 }
848 if(memcmp(bssid,ieee->current_network.bssid,ETH_ALEN)) {
849 goto rx_dropped;
850 }
851
852 ieee->NumRxDataInPeriod++;
853 ieee->NumRxOkTotal++;
854 /* skb: hdr + (possibly fragmented, possibly encrypted) payload */
855
856 if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
857 (keyidx = ieee80211_rx_frame_decrypt(ieee, skb, crypt)) < 0)
858 goto rx_dropped;
859
860 hdr = (struct ieee80211_hdr *) skb->data;
861
862 /* skb: hdr + (possibly fragmented) plaintext payload */
863 // PR: FIXME: hostap has additional conditions in the "if" below:
864 // ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
865 if ((frag != 0 || (fc & IEEE80211_FCTL_MOREFRAGS))) {
866 int flen;
867 struct sk_buff *frag_skb = ieee80211_frag_cache_get(ieee, hdr);
868 IEEE80211_DEBUG_FRAG("Rx Fragment received (%u)\n", frag);
869
870 if (!frag_skb) {
871 IEEE80211_DEBUG(IEEE80211_DL_RX | IEEE80211_DL_FRAG,
872 "Rx cannot get skb from fragment "
873 "cache (morefrag=%d seq=%u frag=%u)\n",
874 (fc & IEEE80211_FCTL_MOREFRAGS) != 0,
875 WLAN_GET_SEQ_SEQ(sc), frag);
876 goto rx_dropped;
877 }
878 flen = skb->len;
879 if (frag != 0)
880 flen -= hdrlen;
881
882 if (frag_skb->tail + flen > frag_skb->end) {
883 printk(KERN_WARNING "%s: host decrypted and "
884 "reassembled frame did not fit skb\n",
885 dev->name);
886 ieee80211_frag_cache_invalidate(ieee, hdr);
887 goto rx_dropped;
888 }
889
890 if (frag == 0) {
891 /* copy first fragment (including full headers) into
892 * beginning of the fragment cache skb */
893 memcpy(skb_put(frag_skb, flen), skb->data, flen);
894 } else {
895 /* append frame payload to the end of the fragment
896 * cache skb */
897 memcpy(skb_put(frag_skb, flen), skb->data + hdrlen,
898 flen);
899 }
900 dev_kfree_skb_any(skb);
901 skb = NULL;
902
903 if (fc & IEEE80211_FCTL_MOREFRAGS) {
904 /* more fragments expected - leave the skb in fragment
905 * cache for now; it will be delivered to upper layers
906 * after all fragments have been received */
907 goto rx_exit;
908 }
909
910 /* this was the last fragment and the frame will be
911 * delivered, so remove skb from fragment cache */
912 skb = frag_skb;
913 hdr = (struct ieee80211_hdr *) skb->data;
914 ieee80211_frag_cache_invalidate(ieee, hdr);
915 }
916
917 /* skb: hdr + (possible reassembled) full MSDU payload; possibly still
918 * encrypted/authenticated */
919 if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
920 ieee80211_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt))
921 goto rx_dropped;
922
923 hdr = (struct ieee80211_hdr *) skb->data;
924 if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep) {
925 if (/*ieee->ieee802_1x &&*/
926 ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
927
928#ifdef CONFIG_IEEE80211_DEBUG
929 /* pass unencrypted EAPOL frames even if encryption is
930 * configured */
931 struct eapol *eap = (struct eapol *)(skb->data +
932 24);
933 IEEE80211_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n",
934 eap_get_type(eap->type));
935#endif
936 } else {
937 IEEE80211_DEBUG_DROP(
938 "encryption configured, but RX "
939 "frame not encrypted (SA=" MAC_FMT ")\n",
940 MAC_ARG(hdr->addr2));
941 goto rx_dropped;
942 }
943 }
944
945#ifdef CONFIG_IEEE80211_DEBUG
946 if (crypt && !(fc & IEEE80211_FCTL_WEP) &&
947 ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
948 struct eapol *eap = (struct eapol *)(skb->data +
949 24);
950 IEEE80211_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n",
951 eap_get_type(eap->type));
952 }
953#endif
954
955 if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep &&
956 !ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
957 IEEE80211_DEBUG_DROP(
958 "dropped unencrypted RX data "
959 "frame from " MAC_FMT
960 " (drop_unencrypted=1)\n",
961 MAC_ARG(hdr->addr2));
962 goto rx_dropped;
963 }
964/*
965 if(ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
966 printk(KERN_WARNING "RX: IEEE802.1X EPAOL frame!\n");
967 }
968*/
969 /* skb: hdr + (possible reassembled) full plaintext payload */
970 payload = skb->data + hdrlen;
971 ethertype = (payload[6] << 8) | payload[7];
972
973#ifdef NOT_YET
974 /* If IEEE 802.1X is used, check whether the port is authorized to send
975 * the received frame. */
976 if (ieee->ieee802_1x && ieee->iw_mode == IW_MODE_MASTER) {
977 if (ethertype == ETH_P_PAE) {
978 printk(KERN_DEBUG "%s: RX: IEEE 802.1X frame\n",
979 dev->name);
980 if (ieee->hostapd && ieee->apdev) {
981 /* Send IEEE 802.1X frames to the user
982 * space daemon for processing */
983 prism2_rx_80211(ieee->apdev, skb, rx_stats,
984 PRISM2_RX_MGMT);
985 ieee->apdevstats.rx_packets++;
986 ieee->apdevstats.rx_bytes += skb->len;
987 goto rx_exit;
988 }
989 } else if (!frame_authorized) {
990 printk(KERN_DEBUG "%s: dropped frame from "
991 "unauthorized port (IEEE 802.1X): "
992 "ethertype=0x%04x\n",
993 dev->name, ethertype);
994 goto rx_dropped;
995 }
996 }
997#endif
998
999#ifdef _RTL8187_EXT_PATCH_
1000 if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_process_dataframe)
1001 {
1002 //Added for mesh rx interrupt.
1003 //spin_lock_irqsave(&ieee->lock,flags);
1004 status = ieee->ext_patch_ieee80211_rx_process_dataframe(ieee, skb, rx_stats);
1005 //spin_unlock_irqrestore(&ieee->lock,flags);
1006
1007 if(status)
1008// if(ieee->ext_patch_ieee80211_rx_process_dataframe(ieee, skb, rx_stats))
1009 goto rx_exit;
1010 else
1011 goto rx_dropped;
1012 }
1013#endif
1014
1015 /* convert hdr + possible LLC headers into Ethernet header */
1016 if (skb->len - hdrlen >= 8 &&
1017 ((memcmp(payload, rfc1042_header, SNAP_SIZE) == 0 &&
1018 ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
1019 memcmp(payload, bridge_tunnel_header, SNAP_SIZE) == 0)) {
1020 /* remove RFC1042 or Bridge-Tunnel encapsulation and
1021 * replace EtherType */
1022 skb_pull(skb, hdrlen + SNAP_SIZE);
1023 memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
1024 memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
1025 } else {
1026 u16 len;
1027 /* Leave Ethernet header part of hdr and full payload */
1028 skb_pull(skb, hdrlen);
1029 len = htons(skb->len);
1030 memcpy(skb_push(skb, 2), &len, 2);
1031 memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
1032 memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
1033 }
1034
1035#ifdef NOT_YET
1036 if (wds && ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
1037 IEEE80211_FCTL_TODS) &&
1038 skb->len >= ETH_HLEN + ETH_ALEN) {
1039 /* Non-standard frame: get addr4 from its bogus location after
1040 * the payload */
1041 memcpy(skb->data + ETH_ALEN,
1042 skb->data + skb->len - ETH_ALEN, ETH_ALEN);
1043 skb_trim(skb, skb->len - ETH_ALEN);
1044 }
1045#endif
1046
1047 stats->rx_packets++;
1048 stats->rx_bytes += skb->len;
1049
1050#ifdef NOT_YET
1051 if (ieee->iw_mode == IW_MODE_MASTER && !wds &&
1052 ieee->ap->bridge_packets) {
1053 if (dst[0] & 0x01) {
1054 /* copy multicast frame both to the higher layers and
1055 * to the wireless media */
1056 ieee->ap->bridged_multicast++;
1057 skb2 = skb_clone(skb, GFP_ATOMIC);
1058 if (skb2 == NULL)
1059 printk(KERN_DEBUG "%s: skb_clone failed for "
1060 "multicast frame\n", dev->name);
1061 } else if (hostap_is_sta_assoc(ieee->ap, dst)) {
1062 /* send frame directly to the associated STA using
1063 * wireless media and not passing to higher layers */
1064 ieee->ap->bridged_unicast++;
1065 skb2 = skb;
1066 skb = NULL;
1067 }
1068 }
1069
1070 if (skb2 != NULL) {
1071 /* send to wireless media */
1072 skb2->protocol = __constant_htons(ETH_P_802_3);
1073 skb2->mac.raw = skb2->nh.raw = skb2->data;
1074 /* skb2->nh.raw = skb2->data + ETH_HLEN; */
1075 skb2->dev = dev;
1076 dev_queue_xmit(skb2);
1077 }
1078
1079#endif
1080 if (skb) {
1081 skb->protocol = eth_type_trans(skb, dev);
1082 memset(skb->cb, 0, sizeof(skb->cb));
1083 skb->dev = dev;
1084 skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */
1085 ieee->last_rx_ps_time = jiffies;
1086 netif_rx(skb);
1087 }
1088
1089 rx_exit:
1090#ifdef NOT_YET
1091 if (sta)
1092 hostap_handle_sta_release(sta);
1093#endif
1094 return 1;
1095
1096 rx_dropped:
1097 stats->rx_dropped++;
1098
1099 /* Returning 0 indicates to caller that we have not handled the SKB--
1100 * so it is still allocated and can be used again by underlying
1101 * hardware as a DMA target */
1102 return 0;
1103}
1104
1105#ifdef _RTL8187_EXT_PATCH_
1106int ieee_ext_skb_p80211_to_ether(struct sk_buff *skb, int hdrlen, u8 *dst, u8 *src)
1107{
1108 u8 *payload;
1109 u16 ethertype;
1110
1111 /* skb: hdr + (possible reassembled) full plaintext payload */
1112 payload = skb->data + hdrlen;
1113 ethertype = (payload[6] << 8) | payload[7];
1114
1115 /* convert hdr + possible LLC headers into Ethernet header */
1116 if (skb->len - hdrlen >= 8 &&
1117 ((memcmp(payload, rfc1042_header, SNAP_SIZE) == 0 &&
1118 ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
1119 memcmp(payload, bridge_tunnel_header, SNAP_SIZE) == 0)) {
1120 /* remove RFC1042 or Bridge-Tunnel encapsulation and
1121 * replace EtherType */
1122 skb_pull(skb, hdrlen + SNAP_SIZE);
1123 memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
1124 memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
1125 } else {
1126 u16 len;
1127 /* Leave Ethernet header part of hdr and full payload */
1128 skb_pull(skb, hdrlen);
1129 len = htons(skb->len);
1130 memcpy(skb_push(skb, 2), &len, 2);
1131 memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
1132 memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
1133 }
1134
1135 return 1;
1136}
1137#endif // _RTL8187_EXT_PATCH_
1138
1139
1140#define MGMT_FRAME_FIXED_PART_LENGTH 0x24
1141
1142static inline int ieee80211_is_ofdm_rate(u8 rate)
1143{
1144 switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
1145 case IEEE80211_OFDM_RATE_6MB:
1146 case IEEE80211_OFDM_RATE_9MB:
1147 case IEEE80211_OFDM_RATE_12MB:
1148 case IEEE80211_OFDM_RATE_18MB:
1149 case IEEE80211_OFDM_RATE_24MB:
1150 case IEEE80211_OFDM_RATE_36MB:
1151 case IEEE80211_OFDM_RATE_48MB:
1152 case IEEE80211_OFDM_RATE_54MB:
1153 return 1;
1154 }
1155 return 0;
1156}
1157
1158static inline int ieee80211_SignalStrengthTranslate(
1159 int CurrSS
1160 )
1161{
1162 int RetSS;
1163
1164 // Step 1. Scale mapping.
1165 if(CurrSS >= 71 && CurrSS <= 100)
1166 {
1167 RetSS = 90 + ((CurrSS - 70) / 3);
1168 }
1169 else if(CurrSS >= 41 && CurrSS <= 70)
1170 {
1171 RetSS = 78 + ((CurrSS - 40) / 3);
1172 }
1173 else if(CurrSS >= 31 && CurrSS <= 40)
1174 {
1175 RetSS = 66 + (CurrSS - 30);
1176 }
1177 else if(CurrSS >= 21 && CurrSS <= 30)
1178 {
1179 RetSS = 54 + (CurrSS - 20);
1180 }
1181 else if(CurrSS >= 5 && CurrSS <= 20)
1182 {
1183 RetSS = 42 + (((CurrSS - 5) * 2) / 3);
1184 }
1185 else if(CurrSS == 4)
1186 {
1187 RetSS = 36;
1188 }
1189 else if(CurrSS == 3)
1190 {
1191 RetSS = 27;
1192 }
1193 else if(CurrSS == 2)
1194 {
1195 RetSS = 18;
1196 }
1197 else if(CurrSS == 1)
1198 {
1199 RetSS = 9;
1200 }
1201 else
1202 {
1203 RetSS = CurrSS;
1204 }
1205 //RT_TRACE(COMP_DBG, DBG_LOUD, ("##### After Mapping: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
1206
1207 // Step 2. Smoothing.
1208
1209 //RT_TRACE(COMP_DBG, DBG_LOUD, ("$$$$$ After Smoothing: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
1210
1211 return RetSS;
1212}
1213
1214#ifdef ENABLE_DOT11D
1215static inline void ieee80211_extract_country_ie(
1216 struct ieee80211_device *ieee,
1217 struct ieee80211_info_element *info_element,
1218 struct ieee80211_network *network,
1219 u8 * addr2
1220)
1221{
1222#if 0
1223 u32 i = 0;
1224 u8 * p = (u8*)info_element->data;
1225 printk("-----------------------\n");
1226 printk("%s Country IE:", network->ssid);
1227 for(i=0; i<info_element->len; i++)
1228 printk("\t%2.2x", *(p+i));
1229 printk("\n-----------------------\n");
1230#endif
1231 if(IS_DOT11D_ENABLE(ieee))
1232 {
1233 if(info_element->len!= 0)
1234 {
1235 memcpy(network->CountryIeBuf, info_element->data, info_element->len);
1236 network->CountryIeLen = info_element->len;
1237
1238 if(!IS_COUNTRY_IE_VALID(ieee))
1239 {
1240 Dot11d_UpdateCountryIe(ieee, addr2, info_element->len, info_element->data);
1241 }
1242 }
1243
1244 //
1245 // 070305, rcnjko: I update country IE watch dog here because
1246 // some AP (e.g. Cisco 1242) don't include country IE in their
1247 // probe response frame.
1248 //
1249 if(IS_EQUAL_CIE_SRC(ieee, addr2) )
1250 {
1251 UPDATE_CIE_WATCHDOG(ieee);
1252 }
1253 }
1254
1255}
1256#endif
1257
1258int
1259ieee80211_TranslateToDbm(
1260 unsigned char SignalStrengthIndex // 0-100 index.
1261 )
1262{
1263 unsigned char SignalPower; // in dBm.
1264
1265 // Translate to dBm (x=0.5y-95).
1266 SignalPower = (int)SignalStrengthIndex * 7 / 10;
1267 SignalPower -= 95;
1268
1269 return SignalPower;
1270}
1271inline int ieee80211_network_init(
1272 struct ieee80211_device *ieee,
1273 struct ieee80211_probe_response *beacon,
1274 struct ieee80211_network *network,
1275 struct ieee80211_rx_stats *stats)
1276{
1277#ifdef CONFIG_IEEE80211_DEBUG
1278 char rates_str[64];
1279 char *p;
1280#endif
1281 struct ieee80211_info_element *info_element;
1282 u16 left;
1283 u8 i;
1284 short offset;
1285 u8 curRate = 0,hOpRate = 0,curRate_ex = 0;
1286
1287 /* Pull out fixed field data */
1288 memcpy(network->bssid, beacon->header.addr3, ETH_ALEN);
1289 network->capability = beacon->capability;
1290 network->last_scanned = jiffies;
1291 network->time_stamp[0] = beacon->time_stamp[0];
1292 network->time_stamp[1] = beacon->time_stamp[1];
1293 network->beacon_interval = beacon->beacon_interval;
1294 /* Where to pull this? beacon->listen_interval;*/
1295 network->listen_interval = 0x0A;
1296 network->rates_len = network->rates_ex_len = 0;
1297 network->last_associate = 0;
1298 network->ssid_len = 0;
1299 network->flags = 0;
1300 network->atim_window = 0;
1301 network->QoS_Enable = 0;
1302//by amy 080312
1303 network->HighestOperaRate = 0;
1304//by amy 080312
1305#ifdef THOMAS_TURBO
1306 network->Turbo_Enable = 0;
1307#endif
1308#ifdef ENABLE_DOT11D
1309 network->CountryIeLen = 0;
1310 memset(network->CountryIeBuf, 0, MAX_IE_LEN);
1311#endif
1312
1313 if (stats->freq == IEEE80211_52GHZ_BAND) {
1314 /* for A band (No DS info) */
1315 network->channel = stats->received_channel;
1316 } else
1317 network->flags |= NETWORK_HAS_CCK;
1318
1319 network->wpa_ie_len = 0;
1320 network->rsn_ie_len = 0;
1321
1322 info_element = &beacon->info_element;
1323 left = stats->len - ((void *)info_element - (void *)beacon);
1324 while (left >= sizeof(struct ieee80211_info_element_hdr)) {
1325 if (sizeof(struct ieee80211_info_element_hdr) + info_element->len > left) {
1326 IEEE80211_DEBUG_SCAN("SCAN: parse failed: info_element->len + 2 > left : info_element->len+2=%d left=%d.\n",
1327 info_element->len + sizeof(struct ieee80211_info_element),
1328 left);
1329 return 1;
1330 }
1331
1332 switch (info_element->id) {
1333 case MFIE_TYPE_SSID:
1334 if (ieee80211_is_empty_essid(info_element->data,
1335 info_element->len)) {
1336 network->flags |= NETWORK_EMPTY_ESSID;
1337 break;
1338 }
1339
1340 network->ssid_len = min(info_element->len,
1341 (u8)IW_ESSID_MAX_SIZE);
1342 memcpy(network->ssid, info_element->data, network->ssid_len);
1343 if (network->ssid_len < IW_ESSID_MAX_SIZE)
1344 memset(network->ssid + network->ssid_len, 0,
1345 IW_ESSID_MAX_SIZE - network->ssid_len);
1346
1347 IEEE80211_DEBUG_SCAN("MFIE_TYPE_SSID: '%s' len=%d.\n",
1348 network->ssid, network->ssid_len);
1349 break;
1350
1351 case MFIE_TYPE_RATES:
1352#ifdef CONFIG_IEEE80211_DEBUG
1353 p = rates_str;
1354#endif
1355 network->rates_len = min(info_element->len, MAX_RATES_LENGTH);
1356 for (i = 0; i < network->rates_len; i++) {
1357 network->rates[i] = info_element->data[i];
1358 curRate = network->rates[i] & 0x7f;
1359 if( hOpRate < curRate )
1360 hOpRate = curRate;
1361#ifdef CONFIG_IEEE80211_DEBUG
1362 p += snprintf(p, sizeof(rates_str) - (p - rates_str), "%02X ", network->rates[i]);
1363#endif
1364 if (ieee80211_is_ofdm_rate(info_element->data[i])) {
1365 network->flags |= NETWORK_HAS_OFDM;
1366 if (info_element->data[i] &
1367 IEEE80211_BASIC_RATE_MASK)
1368 network->flags &=
1369 ~NETWORK_HAS_CCK;
1370 }
1371 }
1372
1373 IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES: '%s' (%d)\n",
1374 rates_str, network->rates_len);
1375 break;
1376
1377 case MFIE_TYPE_RATES_EX:
1378#ifdef CONFIG_IEEE80211_DEBUG
1379 p = rates_str;
1380#endif
1381 network->rates_ex_len = min(info_element->len, MAX_RATES_EX_LENGTH);
1382 for (i = 0; i < network->rates_ex_len; i++) {
1383 network->rates_ex[i] = info_element->data[i];
1384 curRate_ex = network->rates_ex[i] & 0x7f;
1385 if( hOpRate < curRate_ex )
1386 hOpRate = curRate_ex;
1387#ifdef CONFIG_IEEE80211_DEBUG
1388 p += snprintf(p, sizeof(rates_str) - (p - rates_str), "%02X ", network->rates[i]);
1389#endif
1390 if (ieee80211_is_ofdm_rate(info_element->data[i])) {
1391 network->flags |= NETWORK_HAS_OFDM;
1392 if (info_element->data[i] &
1393 IEEE80211_BASIC_RATE_MASK)
1394 network->flags &=
1395 ~NETWORK_HAS_CCK;
1396 }
1397 }
1398
1399 IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES_EX: '%s' (%d)\n",
1400 rates_str, network->rates_ex_len);
1401 break;
1402
1403 case MFIE_TYPE_DS_SET:
1404 IEEE80211_DEBUG_SCAN("MFIE_TYPE_DS_SET: %d\n",
1405 info_element->data[0]);
1406 if (stats->freq == IEEE80211_24GHZ_BAND)
1407 network->channel = info_element->data[0];
1408 break;
1409
1410 case MFIE_TYPE_FH_SET:
1411 IEEE80211_DEBUG_SCAN("MFIE_TYPE_FH_SET: ignored\n");
1412 break;
1413
1414 case MFIE_TYPE_CF_SET:
1415 IEEE80211_DEBUG_SCAN("MFIE_TYPE_CF_SET: ignored\n");
1416 break;
1417
1418 case MFIE_TYPE_TIM:
1419
1420 if(info_element->len < 4)
1421 break;
1422
1423 network->dtim_period = info_element->data[1];
1424
1425 if(ieee->state != IEEE80211_LINKED)
1426 break;
1427#if 0
1428 network->last_dtim_sta_time[0] = stats->mac_time[0];
1429#else
1430 network->last_dtim_sta_time[0] = jiffies;
1431#endif
1432 network->last_dtim_sta_time[1] = stats->mac_time[1];
1433
1434 network->dtim_data = IEEE80211_DTIM_VALID;
1435
1436 if(info_element->data[0] != 0)
1437 break;
1438
1439 if(info_element->data[2] & 1)
1440 network->dtim_data |= IEEE80211_DTIM_MBCAST;
1441
1442 offset = (info_element->data[2] >> 1)*2;
1443
1444 //printk("offset1:%x aid:%x\n",offset, ieee->assoc_id);
1445
1446 /* add and modified for ps 2008.1.22 */
1447 if(ieee->assoc_id < 8*offset ||
1448 ieee->assoc_id > 8*(offset + info_element->len -3)) {
1449 break;
1450 }
1451
1452 offset = (ieee->assoc_id/8) - offset;// + ((aid % 8)? 0 : 1) ;
1453
1454 // printk("offset:%x data:%x, ucast:%d\n", offset,
1455 // info_element->data[3+offset] ,
1456 // info_element->data[3+offset] & (1<<(ieee->assoc_id%8)));
1457
1458 if(info_element->data[3+offset] & (1<<(ieee->assoc_id%8))) {
1459 network->dtim_data |= IEEE80211_DTIM_UCAST;
1460 }
1461 break;
1462
1463 case MFIE_TYPE_IBSS_SET:
1464 IEEE80211_DEBUG_SCAN("MFIE_TYPE_IBSS_SET: ignored\n");
1465 break;
1466
1467 case MFIE_TYPE_CHALLENGE:
1468 IEEE80211_DEBUG_SCAN("MFIE_TYPE_CHALLENGE: ignored\n");
1469 break;
1470
1471 case MFIE_TYPE_GENERIC:
1472 //nic is 87B
1473 IEEE80211_DEBUG_SCAN("MFIE_TYPE_GENERIC: %d bytes\n",
1474 info_element->len);
1475 if (info_element->len >= 4 &&
1476 info_element->data[0] == 0x00 &&
1477 info_element->data[1] == 0x50 &&
1478 info_element->data[2] == 0xf2 &&
1479 info_element->data[3] == 0x01) {
1480 network->wpa_ie_len = min(info_element->len + 2,
1481 MAX_WPA_IE_LEN);
1482 memcpy(network->wpa_ie, info_element,
1483 network->wpa_ie_len);
1484 }
1485
1486#ifdef THOMAS_TURBO
1487 if (info_element->len == 7 &&
1488 info_element->data[0] == 0x00 &&
1489 info_element->data[1] == 0xe0 &&
1490 info_element->data[2] == 0x4c &&
1491 info_element->data[3] == 0x01 &&
1492 info_element->data[4] == 0x02) {
1493 network->Turbo_Enable = 1;
1494 }
1495#endif
1496 if (1 == stats->nic_type) {//nic 87
1497 break;
1498 }
1499
1500 if (info_element->len >= 5 &&
1501 info_element->data[0] == 0x00 &&
1502 info_element->data[1] == 0x50 &&
1503 info_element->data[2] == 0xf2 &&
1504 info_element->data[3] == 0x02 &&
1505 info_element->data[4] == 0x00) {
1506 //printk(KERN_WARNING "wmm info updated: %x\n", info_element->data[6]);
1507 //WMM Information Element
1508 network->wmm_info = info_element->data[6];
1509 network->QoS_Enable = 1;
1510 }
1511
1512 if (info_element->len >= 8 &&
1513 info_element->data[0] == 0x00 &&
1514 info_element->data[1] == 0x50 &&
1515 info_element->data[2] == 0xf2 &&
1516 info_element->data[3] == 0x02 &&
1517 info_element->data[4] == 0x01) {
1518 // Not care about version at present.
1519 //WMM Information Element
1520 //printk(KERN_WARNING "wmm info&param updated: %x\n", info_element->data[6]);
1521 network->wmm_info = info_element->data[6];
1522 //WMM Parameter Element
1523 memcpy(network->wmm_param, (u8 *)(info_element->data + 8),(info_element->len - 8));
1524 network->QoS_Enable = 1;
1525 }
1526 break;
1527
1528 case MFIE_TYPE_RSN:
1529 IEEE80211_DEBUG_SCAN("MFIE_TYPE_RSN: %d bytes\n",
1530 info_element->len);
1531 network->rsn_ie_len = min(info_element->len + 2,
1532 MAX_WPA_IE_LEN);
1533 memcpy(network->rsn_ie, info_element,
1534 network->rsn_ie_len);
1535 break;
1536#ifdef ENABLE_DOT11D
1537 case MFIE_TYPE_COUNTRY:
1538 IEEE80211_DEBUG_SCAN("MFIE_TYPE_COUNTRY: %d bytes\n",
1539 info_element->len);
1540// printk("=====>Receive <%s> Country IE\n",network->ssid);
1541 ieee80211_extract_country_ie(ieee, info_element, network, beacon->header.addr2);
1542 break;
1543#endif
1544 default:
1545 IEEE80211_DEBUG_SCAN("unsupported IE %d\n",
1546 info_element->id);
1547 break;
1548 }
1549
1550 left -= sizeof(struct ieee80211_info_element_hdr) +
1551 info_element->len;
1552 info_element = (struct ieee80211_info_element *)
1553 &info_element->data[info_element->len];
1554 }
1555//by amy 080312
1556 network->HighestOperaRate = hOpRate;
1557//by amy 080312
1558 network->mode = 0;
1559 if (stats->freq == IEEE80211_52GHZ_BAND)
1560 network->mode = IEEE_A;
1561 else {
1562 if (network->flags & NETWORK_HAS_OFDM)
1563 network->mode |= IEEE_G;
1564 if (network->flags & NETWORK_HAS_CCK)
1565 network->mode |= IEEE_B;
1566 }
1567
1568 if (network->mode == 0) {
1569 IEEE80211_DEBUG_SCAN("Filtered out '%s (" MAC_FMT ")' "
1570 "network.\n",
1571 escape_essid(network->ssid,
1572 network->ssid_len),
1573 MAC_ARG(network->bssid));
1574 return 1;
1575 }
1576
1577 if (ieee80211_is_empty_essid(network->ssid, network->ssid_len))
1578 network->flags |= NETWORK_EMPTY_ESSID;
1579#if 0
1580 stats->signal = ieee80211_SignalStrengthTranslate(stats->signal);
1581#endif
1582 stats->signal = ieee80211_TranslateToDbm(stats->signalstrength);
1583 //stats->noise = stats->signal - stats->noise;
1584 stats->noise = ieee80211_TranslateToDbm(100 - stats->signalstrength) - 25;
1585 memcpy(&network->stats, stats, sizeof(network->stats));
1586
1587 return 0;
1588}
1589
1590static inline int is_same_network(struct ieee80211_network *src,
1591 struct ieee80211_network *dst,
1592 struct ieee80211_device * ieee)
1593{
1594 /* A network is only a duplicate if the channel, BSSID, ESSID
1595 * and the capability field (in particular IBSS and BSS) all match.
1596 * We treat all <hidden> with the same BSSID and channel
1597 * as one network */
1598 return (((src->ssid_len == dst->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && //YJ,mod,080819,for hidden ap
1599 //((src->ssid_len == dst->ssid_len) &&
1600 (src->channel == dst->channel) &&
1601 !memcmp(src->bssid, dst->bssid, ETH_ALEN) &&
1602 (!memcmp(src->ssid, dst->ssid, src->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && //YJ,mod,080819,for hidden ap
1603 //!memcmp(src->ssid, dst->ssid, src->ssid_len) &&
1604 ((src->capability & WLAN_CAPABILITY_IBSS) ==
1605 (dst->capability & WLAN_CAPABILITY_IBSS)) &&
1606 ((src->capability & WLAN_CAPABILITY_BSS) ==
1607 (dst->capability & WLAN_CAPABILITY_BSS)));
1608}
1609
1610inline void update_network(struct ieee80211_network *dst,
1611 struct ieee80211_network *src)
1612{
1613 unsigned char quality = src->stats.signalstrength;
1614 unsigned char signal = 0;
1615 unsigned char noise = 0;
1616 if(dst->stats.signalstrength > 0) {
1617 quality = (dst->stats.signalstrength * 5 + src->stats.signalstrength + 5)/6;
1618 }
1619 signal = ieee80211_TranslateToDbm(quality);
1620 //noise = signal - src->stats.noise;
1621 if(dst->stats.noise > 0)
1622 noise = (dst->stats.noise * 5 + src->stats.noise)/6;
1623 //if(strcmp(dst->ssid, "linksys_lzm000") == 0)
1624// printk("ssid:%s, quality:%d, signal:%d\n", dst->ssid, quality, signal);
1625 memcpy(&dst->stats, &src->stats, sizeof(struct ieee80211_rx_stats));
1626 dst->stats.signalstrength = quality;
1627 dst->stats.signal = signal;
1628// printk("==================>stats.signal is %d\n",dst->stats.signal);
1629 dst->stats.noise = noise;
1630
1631
1632 dst->capability = src->capability;
1633 memcpy(dst->rates, src->rates, src->rates_len);
1634 dst->rates_len = src->rates_len;
1635 memcpy(dst->rates_ex, src->rates_ex, src->rates_ex_len);
1636 dst->rates_ex_len = src->rates_ex_len;
1637 dst->HighestOperaRate= src->HighestOperaRate;
1638 //printk("==========>in %s: src->ssid is %s,chan is %d\n",__FUNCTION__,src->ssid,src->channel);
1639
1640 //YJ,add,080819,for hidden ap
1641 if(src->ssid_len > 0)
1642 {
1643 //if(src->ssid_len == 13)
1644 // printk("=====================>>>>>>>> Dst ssid: %s Src ssid: %s\n", dst->ssid, src->ssid);
1645 memset(dst->ssid, 0, dst->ssid_len);
1646 dst->ssid_len = src->ssid_len;
1647 memcpy(dst->ssid, src->ssid, src->ssid_len);
1648 }
1649 //YJ,add,080819,for hidden ap,end
1650
1651 dst->channel = src->channel;
1652 dst->mode = src->mode;
1653 dst->flags = src->flags;
1654 dst->time_stamp[0] = src->time_stamp[0];
1655 dst->time_stamp[1] = src->time_stamp[1];
1656
1657 dst->beacon_interval = src->beacon_interval;
1658 dst->listen_interval = src->listen_interval;
1659 dst->atim_window = src->atim_window;
1660 dst->dtim_period = src->dtim_period;
1661 dst->dtim_data = src->dtim_data;
1662 dst->last_dtim_sta_time[0] = src->last_dtim_sta_time[0];
1663 dst->last_dtim_sta_time[1] = src->last_dtim_sta_time[1];
1664// printk("update:%s, dtim_period:%x, dtim_data:%x\n", src->ssid, src->dtim_period, src->dtim_data);
1665 memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len);
1666 dst->wpa_ie_len = src->wpa_ie_len;
1667 memcpy(dst->rsn_ie, src->rsn_ie, src->rsn_ie_len);
1668 dst->rsn_ie_len = src->rsn_ie_len;
1669
1670 dst->last_scanned = jiffies;
1671 /* dst->last_associate is not overwritten */
1672// disable QoS process now, added by David 2006/7/25
1673#if 1
1674 dst->wmm_info = src->wmm_info; //sure to exist in beacon or probe response frame.
1675/*
1676 if((dst->wmm_info^src->wmm_info)&0x0f) {//Param Set Count change, update Parameter
1677 memcpy(dst->wmm_param, src->wmm_param, IEEE80211_AC_PRAM_LEN);
1678 }
1679*/
1680 if(src->wmm_param[0].ac_aci_acm_aifsn|| \
1681 src->wmm_param[1].ac_aci_acm_aifsn|| \
1682 src->wmm_param[2].ac_aci_acm_aifsn|| \
1683 src->wmm_param[1].ac_aci_acm_aifsn) {
1684 memcpy(dst->wmm_param, src->wmm_param, WME_AC_PRAM_LEN);
1685 }
1686 dst->QoS_Enable = src->QoS_Enable;
1687#else
1688 dst->QoS_Enable = 1;//for Rtl8187 simulation
1689#endif
1690 dst->SignalStrength = src->SignalStrength;
1691#ifdef THOMAS_TURBO
1692 dst->Turbo_Enable = src->Turbo_Enable;
1693#endif
1694#ifdef ENABLE_DOT11D
1695 dst->CountryIeLen = src->CountryIeLen;
1696 memcpy(dst->CountryIeBuf, src->CountryIeBuf, src->CountryIeLen);
1697#endif
1698}
1699
1700
1701inline void ieee80211_process_probe_response(
1702 struct ieee80211_device *ieee,
1703 struct ieee80211_probe_response *beacon,
1704 struct ieee80211_rx_stats *stats)
1705{
1706 struct ieee80211_network network;
1707 struct ieee80211_network *target;
1708 struct ieee80211_network *oldest = NULL;
1709#ifdef CONFIG_IEEE80211_DEBUG
1710 struct ieee80211_info_element *info_element = &beacon->info_element;
1711#endif
1712 unsigned long flags;
1713 short renew;
1714 u8 wmm_info;
1715 u8 is_beacon = (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_BEACON)? 1:0; //YJ,add,080819,for hidden ap
1716
1717 memset(&network, 0, sizeof(struct ieee80211_network));
1718//rz
1719#ifdef _RTL8187_EXT_PATCH_
1720 if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_process_probe_response_1) {
1721 ieee->ext_patch_ieee80211_process_probe_response_1(ieee, beacon, stats);
1722 return;
1723 }
1724#endif
1725
1726 IEEE80211_DEBUG_SCAN(
1727 "'%s' (" MAC_FMT "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
1728 escape_essid(info_element->data, info_element->len),
1729 MAC_ARG(beacon->header.addr3),
1730 (beacon->capability & (1<<0xf)) ? '1' : '0',
1731 (beacon->capability & (1<<0xe)) ? '1' : '0',
1732 (beacon->capability & (1<<0xd)) ? '1' : '0',
1733 (beacon->capability & (1<<0xc)) ? '1' : '0',
1734 (beacon->capability & (1<<0xb)) ? '1' : '0',
1735 (beacon->capability & (1<<0xa)) ? '1' : '0',
1736 (beacon->capability & (1<<0x9)) ? '1' : '0',
1737 (beacon->capability & (1<<0x8)) ? '1' : '0',
1738 (beacon->capability & (1<<0x7)) ? '1' : '0',
1739 (beacon->capability & (1<<0x6)) ? '1' : '0',
1740 (beacon->capability & (1<<0x5)) ? '1' : '0',
1741 (beacon->capability & (1<<0x4)) ? '1' : '0',
1742 (beacon->capability & (1<<0x3)) ? '1' : '0',
1743 (beacon->capability & (1<<0x2)) ? '1' : '0',
1744 (beacon->capability & (1<<0x1)) ? '1' : '0',
1745 (beacon->capability & (1<<0x0)) ? '1' : '0');
1746#if 0
1747 if(strcmp(escape_essid(beacon->info_element.data, beacon->info_element.len), "rtl_softap") == 0)
1748 {
1749 if(WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_BEACON)
1750 {
1751 u32 i = 0, len = stats->len;
1752 u8 * p = (u8*)beacon;
1753 printk("-----------------------\n");
1754 printk("rtl_softap Beacon:");
1755 for(i=0; i<len; i++)
1756 printk("\t%2.2x", *(p+i));
1757 printk("\n-----------------------\n");
1758 }
1759 }
1760#endif
1761 if (ieee80211_network_init(ieee, beacon, &network, stats)) {
1762 IEEE80211_DEBUG_SCAN("Dropped '%s' (" MAC_FMT ") via %s.\n",
1763 escape_essid(info_element->data,
1764 info_element->len),
1765 MAC_ARG(beacon->header.addr3),
1766 WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
1767 IEEE80211_STYPE_PROBE_RESP ?
1768 "PROBE RESPONSE" : "BEACON");
1769 return;
1770 }
1771
1772#ifdef ENABLE_DOT11D
1773 // For Asus EeePc request,
1774 // (1) if wireless adapter receive get any 802.11d country code in AP beacon,
1775 // wireless adapter should follow the country code.
1776 // (2) If there is no any country code in beacon,
1777 // then wireless adapter should do active scan from ch1~11 and
1778 // passive scan from ch12~14
1779 if(ieee->bGlobalDomain)
1780 {
1781 if (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_PROBE_RESP)
1782 {
1783 // Case 1: Country code
1784 if(IS_COUNTRY_IE_VALID(ieee) )
1785 {
1786 if( !IsLegalChannel(ieee, network.channel) )
1787 {
1788 printk("GetScanInfo(): For Country code, filter probe response at channel(%d).\n", network.channel);
1789 return;
1790 }
1791 }
1792 // Case 2: No any country code.
1793 else
1794 {
1795 // Filter over channel ch12~14
1796 if(network.channel > 11)
1797 {
1798 printk("GetScanInfo(): For Global Domain, filter probe response at channel(%d).\n", network.channel);
1799 return;
1800 }
1801 }
1802 }
1803 else
1804 {
1805 // Case 1: Country code
1806 if(IS_COUNTRY_IE_VALID(ieee) )
1807 {
1808 if( !IsLegalChannel(ieee, network.channel) )
1809 {
1810 printk("GetScanInfo(): For Country code, filter beacon at channel(%d).\n",network.channel);
1811 return;
1812 }
1813 }
1814 // Case 2: No any country code.
1815 else
1816 {
1817 // Filter over channel ch12~14
1818 if(network.channel > 14)
1819 {
1820 printk("GetScanInfo(): For Global Domain, filter beacon at channel(%d).\n",network.channel);
1821 return;
1822 }
1823 }
1824 }
1825 }
1826#endif
1827 /* The network parsed correctly -- so now we scan our known networks
1828 * to see if we can find it in our list.
1829 *
1830 * NOTE: This search is definitely not optimized. Once its doing
1831 * the "right thing" we'll optimize it for efficiency if
1832 * necessary */
1833
1834 /* Search for this entry in the list and update it if it is
1835 * already there. */
1836
1837 spin_lock_irqsave(&ieee->lock, flags);
1838
1839 if(is_same_network(&ieee->current_network, &network, ieee)) {
1840 wmm_info = ieee->current_network.wmm_info;
1841 //YJ,add,080819,for hidden ap
1842 if(is_beacon == 0)
1843 network.flags = (~NETWORK_EMPTY_ESSID & network.flags)|(NETWORK_EMPTY_ESSID & ieee->current_network.flags);
1844 else if(ieee->state == IEEE80211_LINKED)
1845 ieee->NumRxBcnInPeriod++;
1846 //YJ,add,080819,for hidden ap,end
1847 //printk("====>network.ssid=%s cur_ssid=%s\n", network.ssid, ieee->current_network.ssid);
1848 update_network(&ieee->current_network, &network);
1849 }
1850
1851 list_for_each_entry(target, &ieee->network_list, list) {
1852 if (is_same_network(target, &network, ieee))
1853 break;
1854 if ((oldest == NULL) ||
1855 (target->last_scanned < oldest->last_scanned))
1856 oldest = target;
1857 }
1858
1859 /* If we didn't find a match, then get a new network slot to initialize
1860 * with this beacon's information */
1861 if (&target->list == &ieee->network_list) {
1862 if (list_empty(&ieee->network_free_list)) {
1863 /* If there are no more slots, expire the oldest */
1864 list_del(&oldest->list);
1865 target = oldest;
1866 IEEE80211_DEBUG_SCAN("Expired '%s' (" MAC_FMT ") from "
1867 "network list.\n",
1868 escape_essid(target->ssid,
1869 target->ssid_len),
1870 MAC_ARG(target->bssid));
1871 } else {
1872 /* Otherwise just pull from the free list */
1873 target = list_entry(ieee->network_free_list.next,
1874 struct ieee80211_network, list);
1875 list_del(ieee->network_free_list.next);
1876 }
1877
1878
1879#ifdef CONFIG_IEEE80211_DEBUG
1880 IEEE80211_DEBUG_SCAN("Adding '%s' (" MAC_FMT ") via %s.\n",
1881 escape_essid(network.ssid,
1882 network.ssid_len),
1883 MAC_ARG(network.bssid),
1884 WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
1885 IEEE80211_STYPE_PROBE_RESP ?
1886 "PROBE RESPONSE" : "BEACON");
1887#endif
1888
1889#ifdef _RTL8187_EXT_PATCH_
1890 network.ext_entry = target->ext_entry;
1891#endif
1892 memcpy(target, &network, sizeof(*target));
1893 list_add_tail(&target->list, &ieee->network_list);
1894 if(ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE)
1895 ieee80211_softmac_new_net(ieee,&network);
1896 } else {
1897 IEEE80211_DEBUG_SCAN("Updating '%s' (" MAC_FMT ") via %s.\n",
1898 escape_essid(target->ssid,
1899 target->ssid_len),
1900 MAC_ARG(target->bssid),
1901 WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
1902 IEEE80211_STYPE_PROBE_RESP ?
1903 "PROBE RESPONSE" : "BEACON");
1904
1905 /* we have an entry and we are going to update it. But this entry may
1906 * be already expired. In this case we do the same as we found a new
1907 * net and call the new_net handler
1908 */
1909 renew = !time_after(target->last_scanned + ieee->scan_age, jiffies);
1910 //YJ,add,080819,for hidden ap
1911 if(is_beacon == 0)
1912 network.flags = (~NETWORK_EMPTY_ESSID & network.flags)|(NETWORK_EMPTY_ESSID & target->flags);
1913 //if(strncmp(network.ssid, "linksys-c",9) == 0)
1914 // printk("====>2 network.ssid=%s FLAG=%d target.ssid=%s FLAG=%d\n", network.ssid, network.flags, target->ssid, target->flags);
1915 if(((network.flags & NETWORK_EMPTY_ESSID) == NETWORK_EMPTY_ESSID) \
1916 && (((network.ssid_len > 0) && (strncmp(target->ssid, network.ssid, network.ssid_len)))\
1917 ||((ieee->current_network.ssid_len == network.ssid_len)&&(strncmp(ieee->current_network.ssid, network.ssid, network.ssid_len) == 0)&&(ieee->state == IEEE80211_NOLINK))))
1918 renew = 1;
1919 //YJ,add,080819,for hidden ap,end
1920 update_network(target, &network);
1921 if(renew && (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE))
1922 ieee80211_softmac_new_net(ieee,&network);
1923 }
1924
1925 spin_unlock_irqrestore(&ieee->lock, flags);
1926}
1927
1928void ieee80211_rx_mgt(struct ieee80211_device *ieee,
1929 struct ieee80211_hdr *header,
1930 struct ieee80211_rx_stats *stats)
1931{
1932 switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
1933
1934 case IEEE80211_STYPE_BEACON:
1935 IEEE80211_DEBUG_MGMT("received BEACON (%d)\n",
1936 WLAN_FC_GET_STYPE(header->frame_ctl));
1937 IEEE80211_DEBUG_SCAN("Beacon\n");
1938 ieee80211_process_probe_response(
1939 ieee, (struct ieee80211_probe_response *)header, stats);
1940 break;
1941
1942 case IEEE80211_STYPE_PROBE_RESP:
1943 IEEE80211_DEBUG_MGMT("received PROBE RESPONSE (%d)\n",
1944 WLAN_FC_GET_STYPE(header->frame_ctl));
1945 IEEE80211_DEBUG_SCAN("Probe response\n");
1946 ieee80211_process_probe_response(
1947 ieee, (struct ieee80211_probe_response *)header, stats);
1948 break;
1949//rz
1950#ifdef _RTL8187_EXT_PATCH_
1951 case IEEE80211_STYPE_PROBE_REQ:
1952 IEEE80211_DEBUG_MGMT("received PROBE REQUEST (%d)\n",
1953 WLAN_FC_GET_STYPE(header->frame_ctl));
1954 IEEE80211_DEBUG_SCAN("Probe request\n");
1955 ///
1956 if( ieee->iw_mode == ieee->iw_ext_mode && ieee->ext_patch_ieee80211_rx_mgt_on_probe_req )
1957 ieee->ext_patch_ieee80211_rx_mgt_on_probe_req( ieee, (struct ieee80211_probe_request *)header, stats);
1958 break;
1959#endif // _RTL8187_EXT_PATCH_
1960
1961 }
1962}
1963
1964#if 0
1965EXPORT_SYMBOL(ieee80211_rx_mgt);
1966EXPORT_SYMBOL(ieee80211_rx);
1967EXPORT_SYMBOL(ieee80211_network_init);
1968#ifdef _RTL8187_EXT_PATCH_
1969EXPORT_SYMBOL(ieee_ext_skb_p80211_to_ether);
1970#endif
1971#endif
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
new file mode 100644
index 000000000000..fcffee516d51
--- /dev/null
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
@@ -0,0 +1,4029 @@
1/* IEEE 802.11 SoftMAC layer
2 * Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
3 *
4 * Mostly extracted from the rtl8180-sa2400 driver for the
5 * in-kernel generic ieee802.11 stack.
6 *
7 * Few lines might be stolen from other part of the ieee80211
8 * stack. Copyright who own it's copyright
9 *
10 * WPA code stolen from the ipw2200 driver.
11 * Copyright who own it's copyright.
12 *
13 * released under the GPL
14 */
15
16
17#include "ieee80211.h"
18
19#include <linux/random.h>
20#include <linux/delay.h>
21#include <linux/version.h>
22#include <asm/uaccess.h>
23
24#ifdef ENABLE_DOT11D
25#include "dot11d.h"
26#endif
27u8 rsn_authen_cipher_suite[16][4] = {
28 {0x00,0x0F,0xAC,0x00}, //Use group key, //Reserved
29 {0x00,0x0F,0xAC,0x01}, //WEP-40 //RSNA default
30 {0x00,0x0F,0xAC,0x02}, //TKIP //NONE //{used just as default}
31 {0x00,0x0F,0xAC,0x03}, //WRAP-historical
32 {0x00,0x0F,0xAC,0x04}, //CCMP
33 {0x00,0x0F,0xAC,0x05}, //WEP-104
34};
35
36short ieee80211_is_54g(struct ieee80211_network net)
37{
38 return ((net.rates_ex_len > 0) || (net.rates_len > 4));
39}
40
41short ieee80211_is_shortslot(struct ieee80211_network net)
42{
43 return (net.capability & WLAN_CAPABILITY_SHORT_SLOT);
44}
45
46/* returns the total length needed for pleacing the RATE MFIE
47 * tag and the EXTENDED RATE MFIE tag if needed.
48 * It encludes two bytes per tag for the tag itself and its len
49 */
50unsigned int ieee80211_MFIE_rate_len(struct ieee80211_device *ieee)
51{
52 unsigned int rate_len = 0;
53
54 if (ieee->modulation & IEEE80211_CCK_MODULATION)
55 rate_len = IEEE80211_CCK_RATE_LEN + 2;
56
57 if (ieee->modulation & IEEE80211_OFDM_MODULATION)
58
59 rate_len += IEEE80211_OFDM_RATE_LEN + 2;
60
61 return rate_len;
62}
63
64/* pleace the MFIE rate, tag to the memory (double) poined.
65 * Then it updates the pointer so that
66 * it points after the new MFIE tag added.
67 */
68void ieee80211_MFIE_Brate(struct ieee80211_device *ieee, u8 **tag_p)
69{
70 u8 *tag = *tag_p;
71
72 if (ieee->modulation & IEEE80211_CCK_MODULATION){
73 *tag++ = MFIE_TYPE_RATES;
74 *tag++ = 4;
75 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
76 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
77 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
78 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
79 }
80
81 /* We may add an option for custom rates that specific HW might support */
82 *tag_p = tag;
83}
84
85void ieee80211_MFIE_Grate(struct ieee80211_device *ieee, u8 **tag_p)
86{
87 u8 *tag = *tag_p;
88
89 if (ieee->modulation & IEEE80211_OFDM_MODULATION){
90
91 *tag++ = MFIE_TYPE_RATES_EX;
92 *tag++ = 8;
93 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
94 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
95 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
96 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
97 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
98 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
99 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
100 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
101
102 }
103
104 /* We may add an option for custom rates that specific HW might support */
105 *tag_p = tag;
106}
107
108
109void ieee80211_WMM_Info(struct ieee80211_device *ieee, u8 **tag_p) {
110 u8 *tag = *tag_p;
111
112 *tag++ = MFIE_TYPE_GENERIC; //0
113 *tag++ = 7;
114 *tag++ = 0x00;
115 *tag++ = 0x50;
116 *tag++ = 0xf2;
117 *tag++ = 0x02;//5
118 *tag++ = 0x00;
119 *tag++ = 0x01;
120#ifdef SUPPORT_USPD
121 if(ieee->current_network.wmm_info & 0x80) {
122 *tag++ = 0x0f|MAX_SP_Len;
123 } else {
124 *tag++ = MAX_SP_Len;
125 }
126#else
127 *tag++ = MAX_SP_Len;
128#endif
129 *tag_p = tag;
130}
131
132#ifdef THOMAS_TURBO
133void ieee80211_TURBO_Info(struct ieee80211_device *ieee, u8 **tag_p) {
134 u8 *tag = *tag_p;
135
136 *tag++ = MFIE_TYPE_GENERIC; //0
137 *tag++ = 7;
138 *tag++ = 0x00;
139 *tag++ = 0xe0;
140 *tag++ = 0x4c;
141 *tag++ = 0x01;//5
142 *tag++ = 0x02;
143 *tag++ = 0x11;
144 *tag++ = 0x00;
145
146 *tag_p = tag;
147 printk(KERN_ALERT "This is enable turbo mode IE process\n");
148}
149#endif
150
151void enqueue_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb)
152{
153 int nh;
154 nh = (ieee->mgmt_queue_head +1) % MGMT_QUEUE_NUM;
155
156/*
157 * if the queue is full but we have newer frames then
158 * just overwrites the oldest.
159 *
160 * if (nh == ieee->mgmt_queue_tail)
161 * return -1;
162 */
163 ieee->mgmt_queue_head = nh;
164 ieee->mgmt_queue_ring[nh] = skb;
165
166 //return 0;
167}
168
169struct sk_buff *dequeue_mgmt(struct ieee80211_device *ieee)
170{
171 struct sk_buff *ret;
172
173 if(ieee->mgmt_queue_tail == ieee->mgmt_queue_head)
174 return NULL;
175
176 ret = ieee->mgmt_queue_ring[ieee->mgmt_queue_tail];
177
178 ieee->mgmt_queue_tail =
179 (ieee->mgmt_queue_tail+1) % MGMT_QUEUE_NUM;
180
181 return ret;
182}
183
184void init_mgmt_queue(struct ieee80211_device *ieee)
185{
186 ieee->mgmt_queue_tail = ieee->mgmt_queue_head = 0;
187}
188
189
190void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl);
191
192inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
193{
194 unsigned long flags;
195 short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
196 struct ieee80211_hdr_3addr *header=
197 (struct ieee80211_hdr_3addr *) skb->data;
198
199
200 spin_lock_irqsave(&ieee->lock, flags);
201
202 /* called with 2nd param 0, no mgmt lock required */
203 ieee80211_sta_wakeup(ieee,0);
204
205 if(single){
206 if(ieee->queue_stop){
207
208 enqueue_mgmt(ieee,skb);
209 }else{
210 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4);
211
212 if (ieee->seq_ctrl[0] == 0xFFF)
213 ieee->seq_ctrl[0] = 0;
214 else
215 ieee->seq_ctrl[0]++;
216
217 /* avoid watchdog triggers */
218 ieee->dev->trans_start = jiffies;
219 ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
220 }
221
222 spin_unlock_irqrestore(&ieee->lock, flags);
223 }else{
224 spin_unlock_irqrestore(&ieee->lock, flags);
225 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags);
226
227 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
228
229 if (ieee->seq_ctrl[0] == 0xFFF)
230 ieee->seq_ctrl[0] = 0;
231 else
232 ieee->seq_ctrl[0]++;
233
234 /* avoid watchdog triggers */
235 ieee->dev->trans_start = jiffies;
236 ieee->softmac_hard_start_xmit(skb,ieee->dev);
237
238 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags);
239 }
240}
241
242
243inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
244{
245
246 short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
247 struct ieee80211_hdr_3addr *header =
248 (struct ieee80211_hdr_3addr *) skb->data;
249
250
251 if(single){
252
253 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
254
255 if (ieee->seq_ctrl[0] == 0xFFF)
256 ieee->seq_ctrl[0] = 0;
257 else
258 ieee->seq_ctrl[0]++;
259
260 /* avoid watchdog triggers */
261 ieee->dev->trans_start = jiffies;
262 ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
263
264 }else{
265
266 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
267
268 if (ieee->seq_ctrl[0] == 0xFFF)
269 ieee->seq_ctrl[0] = 0;
270 else
271 ieee->seq_ctrl[0]++;
272
273 /* avoid watchdog triggers */
274 ieee->dev->trans_start = jiffies;
275 ieee->softmac_hard_start_xmit(skb,ieee->dev);
276
277 }
278// dev_kfree_skb_any(skb);//edit by thomas
279}
280//by amy for power save
281inline struct sk_buff *ieee80211_disassociate_skb(
282 struct ieee80211_network *beacon,
283 struct ieee80211_device *ieee,
284 u8 asRsn)
285{
286 struct sk_buff *skb;
287 struct ieee80211_disassoc_frame *disass;
288
289 skb = dev_alloc_skb(sizeof(struct ieee80211_disassoc_frame));
290 if (!skb)
291 return NULL;
292
293 disass = (struct ieee80211_disassoc_frame *) skb_put(skb,sizeof(struct ieee80211_disassoc_frame));
294 disass->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_DISASSOC);
295 disass->header.duration_id = 0;
296
297 memcpy(disass->header.addr1, beacon->bssid, ETH_ALEN);
298 memcpy(disass->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
299 memcpy(disass->header.addr3, beacon->bssid, ETH_ALEN);
300
301 disass->reasoncode = asRsn;
302 return skb;
303}
304void
305SendDisassociation(
306 struct ieee80211_device *ieee,
307 u8* asSta,
308 u8 asRsn
309)
310{
311 struct ieee80211_network *beacon = &ieee->current_network;
312 struct sk_buff *skb;
313 skb = ieee80211_disassociate_skb(beacon,ieee,asRsn);
314 if (skb){
315 softmac_mgmt_xmit(skb, ieee);
316 //dev_kfree_skb_any(skb);//edit by thomas
317 }
318}
319
320//by amy for power save
321inline struct sk_buff *ieee80211_probe_req(struct ieee80211_device *ieee)
322{
323 unsigned int len,rate_len;
324 u8 *tag;
325 struct sk_buff *skb;
326 struct ieee80211_probe_request *req;
327
328#ifdef _RTL8187_EXT_PATCH_
329 short extMore = 0;
330 if(ieee->ext_patch_ieee80211_probe_req_1)
331 extMore = ieee->ext_patch_ieee80211_probe_req_1(ieee);
332#endif
333
334 len = ieee->current_network.ssid_len;
335
336 rate_len = ieee80211_MFIE_rate_len(ieee);
337
338#ifdef _RTL8187_EXT_PATCH_
339 if(!extMore)
340#endif
341 skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
342 2 + len + rate_len);
343#ifdef _RTL8187_EXT_PATCH_
344 else
345 skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
346 2 + len + rate_len+128); // MESHID + CAP
347#endif
348
349 if (!skb)
350 return NULL;
351
352 req = (struct ieee80211_probe_request *) skb_put(skb,sizeof(struct ieee80211_probe_request));
353 req->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
354 req->header.duration_id = 0; //FIXME: is this OK ?
355
356 memset(req->header.addr1, 0xff, ETH_ALEN);
357 memcpy(req->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
358 memset(req->header.addr3, 0xff, ETH_ALEN);
359
360 tag = (u8 *) skb_put(skb,len+2+rate_len);
361
362 *tag++ = MFIE_TYPE_SSID;
363 *tag++ = len;
364 memcpy(tag, ieee->current_network.ssid, len);
365 tag += len;
366 ieee80211_MFIE_Brate(ieee,&tag);
367 ieee80211_MFIE_Grate(ieee,&tag);
368
369#ifdef _RTL8187_EXT_PATCH_
370 if(extMore)
371 ieee->ext_patch_ieee80211_probe_req_2(ieee, skb, tag);
372#endif
373 return skb;
374}
375
376struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee);
377
378//#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
379//void ext_ieee80211_send_beacon_wq(struct work_struct *work)
380//{
381// struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, ext_send_beacon_wq);
382//#else
383void ext_ieee80211_send_beacon_wq(struct ieee80211_device *ieee)
384{
385//#endif
386
387 struct sk_buff *skb;
388
389 //unsigned long flags;
390
391 skb = ieee80211_get_beacon_(ieee);
392
393 if (skb){
394 softmac_mgmt_xmit(skb, ieee);
395 ieee->softmac_stats.tx_beacons++;
396 dev_kfree_skb_any(skb);//edit by thomas
397 }
398
399
400 //printk(KERN_WARNING "[1] beacon sending!\n");
401 ieee->beacon_timer.expires = jiffies +
402 (MSECS( ieee->current_network.beacon_interval -5));
403
404 //spin_lock_irqsave(&ieee->beacon_lock,flags);
405 if(ieee->beacon_txing)
406 add_timer(&ieee->beacon_timer);
407 //spin_unlock_irqrestore(&ieee->beacon_lock,flags);
408}
409
410void ieee80211_send_beacon(struct ieee80211_device *ieee)
411{
412 struct sk_buff *skb;
413
414 //unsigned long flags;
415
416 skb = ieee80211_get_beacon_(ieee);
417
418 if (skb){
419 softmac_mgmt_xmit(skb, ieee);
420 ieee->softmac_stats.tx_beacons++;
421 dev_kfree_skb_any(skb);//edit by thomas
422 }
423
424 //printk(KERN_WARNING "[1] beacon sending!\n");
425 ieee->beacon_timer.expires = jiffies +
426 (MSECS( ieee->current_network.beacon_interval -5));
427
428 //spin_lock_irqsave(&ieee->beacon_lock,flags);
429 if(ieee->beacon_txing)
430 add_timer(&ieee->beacon_timer);
431 //spin_unlock_irqrestore(&ieee->beacon_lock,flags);
432}
433
434
435void ieee80211_send_beacon_cb(unsigned long _ieee)
436{
437 struct ieee80211_device *ieee =
438 (struct ieee80211_device *) _ieee;
439 unsigned long flags;
440
441 spin_lock_irqsave(&ieee->beacon_lock, flags);
442 ieee80211_send_beacon(ieee);
443 spin_unlock_irqrestore(&ieee->beacon_lock, flags);
444}
445
446#ifdef _RTL8187_EXT_PATCH_
447
448inline struct sk_buff *ieee80211_probe_req_with_SSID(struct ieee80211_device *ieee, char *ssid, int len_ssid)
449{
450 unsigned int len,rate_len;
451 u8 *tag;
452 struct sk_buff *skb;
453 struct ieee80211_probe_request *req;
454
455#ifdef _RTL8187_EXT_PATCH_
456 short extMore = 0;
457 if(ieee->ext_patch_ieee80211_probe_req_1)
458 extMore = ieee->ext_patch_ieee80211_probe_req_1(ieee);
459#endif
460
461 len = len_ssid;
462
463 rate_len = ieee80211_MFIE_rate_len(ieee);
464
465#ifdef _RTL8187_EXT_PATCH_
466 if(!extMore)
467#endif
468 skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
469 2 + len + rate_len);
470#ifdef _RTL8187_EXT_PATCH_
471 else
472 skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
473 2 + len + rate_len+128); // MESHID + CAP
474#endif
475
476 if (!skb)
477 return NULL;
478
479 req = (struct ieee80211_probe_request *) skb_put(skb,sizeof(struct ieee80211_probe_request));
480 req->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
481 req->header.duration_id = 0; //FIXME: is this OK ?
482
483 memset(req->header.addr1, 0xff, ETH_ALEN);
484 memcpy(req->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
485 memset(req->header.addr3, 0xff, ETH_ALEN);
486
487 tag = (u8 *) skb_put(skb,len+2+rate_len);
488
489 *tag++ = MFIE_TYPE_SSID;
490 *tag++ = len;
491 if(len)
492 {
493 memcpy(tag, ssid, len);
494 tag += len;
495 }
496
497 ieee80211_MFIE_Brate(ieee,&tag);
498 ieee80211_MFIE_Grate(ieee,&tag);
499
500#ifdef _RTL8187_EXT_PATCH_
501 if(extMore)
502 ieee->ext_patch_ieee80211_probe_req_2(ieee, skb, tag);
503#endif
504 return skb;
505}
506
507#endif // _RTL8187_EXT_PATCH_
508
509
510void ieee80211_send_probe(struct ieee80211_device *ieee)
511{
512 struct sk_buff *skb;
513
514#ifdef _RTL8187_EXT_PATCH_
515 if(ieee->iw_mode == ieee->iw_ext_mode)
516 skb = ieee80211_probe_req_with_SSID(ieee, NULL, 0);
517 else
518#endif
519 skb = ieee80211_probe_req(ieee);
520 if (skb){
521 softmac_mgmt_xmit(skb, ieee);
522 ieee->softmac_stats.tx_probe_rq++;
523 //dev_kfree_skb_any(skb);//edit by thomas
524 }
525}
526
527void ieee80211_send_probe_requests(struct ieee80211_device *ieee)
528{
529 if (ieee->active_scan && (ieee->softmac_features & IEEE_SOFTMAC_PROBERQ)){
530 ieee80211_send_probe(ieee);
531 ieee80211_send_probe(ieee);
532 }
533}
534
535/* this performs syncro scan blocking the caller until all channels
536 * in the allowed channel map has been checked.
537 */
538void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee)
539{
540 short ch = 0;
541#ifdef ENABLE_DOT11D
542 u8 channel_map[MAX_CHANNEL_NUMBER+1];
543 memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
544#endif
545 down(&ieee->scan_sem);
546// printk("==================> Sync scan\n");
547// dump_chnl_map(channel_map);
548
549 while(1)
550 {
551
552 do{
553 ch++;
554 if (ch > MAX_CHANNEL_NUMBER)
555 goto out; /* scan completed */
556
557#ifdef ENABLE_DOT11D
558 }while(!channel_map[ch]);
559#else
560 }while(!ieee->channel_map[ch]);
561#endif
562 /* this fuction can be called in two situations
563 * 1- We have switched to ad-hoc mode and we are
564 * performing a complete syncro scan before conclude
565 * there are no interesting cell and to create a
566 * new one. In this case the link state is
567 * IEEE80211_NOLINK until we found an interesting cell.
568 * If so the ieee8021_new_net, called by the RX path
569 * will set the state to IEEE80211_LINKED, so we stop
570 * scanning
571 * 2- We are linked and the root uses run iwlist scan.
572 * So we switch to IEEE80211_LINKED_SCANNING to remember
573 * that we are still logically linked (not interested in
574 * new network events, despite for updating the net list,
575 * but we are temporarly 'unlinked' as the driver shall
576 * not filter RX frames and the channel is changing.
577 * So the only situation in witch are interested is to check
578 * if the state become LINKED because of the #1 situation
579 */
580
581 if (ieee->state == IEEE80211_LINKED)
582 goto out;
583
584 ieee->set_chan(ieee->dev, ch);
585// printk("=====>channel=%d ",ch);
586#ifdef ENABLE_DOT11D
587 if(channel_map[ch] == 1)
588#endif
589 {
590// printk("====send probe request\n");
591 ieee80211_send_probe_requests(ieee);
592 }
593 /* this prevent excessive time wait when we
594 * need to wait for a syncro scan to end..
595 */
596 if (ieee->sync_scan_hurryup)
597 goto out;
598
599
600 msleep_interruptible_rtl(IEEE80211_SOFTMAC_SCAN_TIME);
601
602 }
603out:
604 ieee->sync_scan_hurryup = 0;
605 up(&ieee->scan_sem);
606#ifdef ENABLE_DOT11D
607 if(IS_DOT11D_ENABLE(ieee))
608 DOT11D_ScanComplete(ieee);
609#endif
610}
611
612void ieee80211_softmac_ips_scan_syncro(struct ieee80211_device *ieee)
613{
614 int ch;
615 unsigned int watch_dog = 0;
616#ifdef ENABLE_DOT11D
617 u8 channel_map[MAX_CHANNEL_NUMBER+1];
618 memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
619#endif
620 down(&ieee->scan_sem);
621 ch = ieee->current_network.channel;
622// if(ieee->sync_scan_hurryup)
623// {
624
625// printk("stop scan sync\n");
626// goto out;
627// }
628// printk("=======hh===============>ips scan\n");
629 while(1)
630 {
631 /* this fuction can be called in two situations
632 * 1- We have switched to ad-hoc mode and we are
633 * performing a complete syncro scan before conclude
634 * there are no interesting cell and to create a
635 * new one. In this case the link state is
636 * IEEE80211_NOLINK until we found an interesting cell.
637 * If so the ieee8021_new_net, called by the RX path
638 * will set the state to IEEE80211_LINKED, so we stop
639 * scanning
640 * 2- We are linked and the root uses run iwlist scan.
641 * So we switch to IEEE80211_LINKED_SCANNING to remember
642 * that we are still logically linked (not interested in
643 * new network events, despite for updating the net list,
644 * but we are temporarly 'unlinked' as the driver shall
645 * not filter RX frames and the channel is changing.
646 * So the only situation in witch are interested is to check
647 * if the state become LINKED because of the #1 situation
648 */
649 if (ieee->state == IEEE80211_LINKED)
650 {
651 goto out;
652 }
653#ifdef ENABLE_DOT11D
654 if(channel_map[ieee->current_network.channel] > 0)
655#endif
656 {
657 ieee->set_chan(ieee->dev, ieee->current_network.channel);
658// printk("======>channel=%d ",ieee->current_network.channel);
659 }
660#ifdef ENABLE_DOT11D
661 if(channel_map[ieee->current_network.channel] == 1)
662#endif
663 {
664// printk("====send probe request\n");
665 ieee80211_send_probe_requests(ieee);
666 }
667 /* this prevent excessive time wait when we
668 * need to wait for a syncro scan to end..
669 */
670// if (ieee->sync_scan_hurryup)
671// goto out;
672
673 msleep_interruptible_rtl(IEEE80211_SOFTMAC_SCAN_TIME);
674
675 do{
676 if (watch_dog++ >= MAX_CHANNEL_NUMBER)
677 // if (++watch_dog >= 15);//MAX_CHANNEL_NUMBER) //YJ,modified,080630
678 goto out; /* scan completed */
679
680 ieee->current_network.channel = (ieee->current_network.channel + 1)%MAX_CHANNEL_NUMBER;
681#ifdef ENABLE_DOT11D
682 }while(!channel_map[ieee->current_network.channel]);
683#else
684 }while(!ieee->channel_map[ieee->current_network.channel]);
685#endif
686 }
687out:
688 //ieee->sync_scan_hurryup = 0;
689 //ieee->set_chan(ieee->dev, ch);
690 //ieee->current_network.channel = ch;
691 ieee->actscanning = false;
692 up(&ieee->scan_sem);
693#ifdef ENABLE_DOT11D
694 if(IS_DOT11D_ENABLE(ieee))
695 DOT11D_ScanComplete(ieee);
696#endif
697}
698
699
700#if 0
701/* called both by wq with ieee->lock held */
702void ieee80211_softmac_scan(struct ieee80211_device *ieee)
703{
704 short watchdog = 0;
705
706 do{
707 ieee->current_network.channel =
708 (ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER;
709 if (watchdog++ > MAX_CHANNEL_NUMBER)
710 return; /* no good chans */
711
712 }while(!ieee->channel_map[ieee->current_network.channel]);
713
714
715 schedule_work(&ieee->softmac_scan_wq);
716}
717#endif
718#ifdef ENABLE_IPS
719#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
720void ieee80211_softmac_scan_wq(struct work_struct *work)
721{
722 struct delayed_work *dwork = container_of(work, struct delayed_work, work);
723 struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, softmac_scan_wq);
724#else
725void ieee80211_softmac_scan_wq(struct ieee80211_device *ieee)
726{
727#endif
728 static short watchdog = 0;
729#ifdef ENABLE_DOT11D
730 u8 channel_map[MAX_CHANNEL_NUMBER+1];
731 memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
732#endif
733// printk("ieee80211_softmac_scan_wq ENABLE_IPS\n");
734// printk("in %s\n",__FUNCTION__);
735 down(&ieee->scan_sem);
736
737 do{
738 ieee->current_network.channel =
739 (ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER;
740 if (watchdog++ > MAX_CHANNEL_NUMBER)
741 goto out; /* no good chans */
742
743#ifdef ENABLE_DOT11D
744 }while(!channel_map[ieee->current_network.channel]);
745#else
746 }while(!ieee->channel_map[ieee->current_network.channel]);
747#endif
748
749 //printk("current_network.channel:%d\n", ieee->current_network.channel);
750 if (ieee->scanning == 0 )
751 {
752 printk("error out, scanning = 0\n");
753 goto out;
754 }
755 ieee->set_chan(ieee->dev, ieee->current_network.channel);
756#ifdef ENABLE_DOT11D
757 if(channel_map[ieee->current_network.channel] == 1)
758#endif
759 ieee80211_send_probe_requests(ieee);
760
761 queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, IEEE80211_SOFTMAC_SCAN_TIME);
762 up(&ieee->scan_sem);
763 return;
764out:
765 ieee->actscanning = false;
766 watchdog = 0;
767 ieee->scanning = 0;
768 up(&ieee->scan_sem);
769
770#ifdef ENABLE_DOT11D
771 if(IS_DOT11D_ENABLE(ieee))
772 DOT11D_ScanComplete(ieee);
773#endif
774 return;
775}
776#else
777#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
778void ieee80211_softmac_scan_wq(struct work_struct *work)
779{
780 struct delayed_work *dwork = container_of(work, struct delayed_work, work);
781 struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, softmac_scan_wq);
782#else
783void ieee80211_softmac_scan_wq(struct ieee80211_device *ieee)
784{
785#endif
786
787 short watchdog = 0;
788#ifdef ENABLE_DOT11D
789 u8 channel_map[MAX_CHANNEL_NUMBER+1];
790 memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
791#endif
792// printk("enter scan wq,watchdog is %d\n",watchdog);
793 down(&ieee->scan_sem);
794
795 do{
796 ieee->current_network.channel =
797 (ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER;
798 if (watchdog++ > MAX_CHANNEL_NUMBER)
799 goto out; /* no good chans */
800
801#ifdef ENABLE_DOT11D
802 }while(!channel_map[ieee->current_network.channel]);
803#else
804 }while(!ieee->channel_map[ieee->current_network.channel]);
805#endif
806
807// printk("current_network.channel:%d\n", ieee->current_network.channel);
808 if (ieee->scanning == 0 )
809 {
810 printk("error out, scanning = 0\n");
811 goto out;
812 }
813 ieee->set_chan(ieee->dev, ieee->current_network.channel);
814#ifdef ENABLE_DOT11D
815 if(channel_map[ieee->current_network.channel] == 1)
816#endif
817 ieee80211_send_probe_requests(ieee);
818
819 queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, IEEE80211_SOFTMAC_SCAN_TIME);
820out:
821 up(&ieee->scan_sem);
822#ifdef ENABLE_DOT11D
823 if(IS_DOT11D_ENABLE(ieee))
824 DOT11D_ScanComplete(ieee);
825#endif
826}
827
828#endif
829#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
830void ieee80211_softmac_scan_cb(unsigned long _dev)
831{
832 unsigned long flags;
833 struct ieee80211_device *ieee = (struct ieee80211_device *)_dev;
834
835 spin_lock_irqsave(&ieee->lock, flags);
836 ieee80211_softmac_scan(ieee);
837 spin_unlock_irqrestore(&ieee->lock, flags);
838}
839#endif
840
841
842void ieee80211_beacons_start(struct ieee80211_device *ieee)
843{
844 unsigned long flags;
845
846 spin_lock_irqsave(&ieee->beacon_lock,flags);
847
848 ieee->beacon_txing = 1;
849 ieee80211_send_beacon(ieee);
850
851 spin_unlock_irqrestore(&ieee->beacon_lock,flags);
852}
853
854void ieee80211_beacons_stop(struct ieee80211_device *ieee)
855{
856 unsigned long flags;
857
858 spin_lock_irqsave(&ieee->beacon_lock,flags);
859
860 ieee->beacon_txing = 0;
861 del_timer_sync(&ieee->beacon_timer);
862
863 spin_unlock_irqrestore(&ieee->beacon_lock,flags);
864
865}
866
867
868void ieee80211_stop_send_beacons(struct ieee80211_device *ieee)
869{
870 if(ieee->stop_send_beacons)
871 ieee->stop_send_beacons(ieee->dev);
872 if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
873 ieee80211_beacons_stop(ieee);
874}
875
876
877void ieee80211_start_send_beacons(struct ieee80211_device *ieee)
878{
879 if(ieee->start_send_beacons)
880 ieee->start_send_beacons(ieee->dev);
881 if(ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
882 ieee80211_beacons_start(ieee);
883}
884
885
886void ieee80211_softmac_stop_scan(struct ieee80211_device *ieee)
887{
888// unsigned long flags;
889
890 //ieee->sync_scan_hurryup = 1;
891
892 down(&ieee->scan_sem);
893// spin_lock_irqsave(&ieee->lock, flags);
894
895 if (ieee->scanning == 1){
896 ieee->scanning = 0;
897 //del_timer_sync(&ieee->scan_timer);
898 cancel_delayed_work(&ieee->softmac_scan_wq);
899 }
900
901// spin_unlock_irqrestore(&ieee->lock, flags);
902 up(&ieee->scan_sem);
903}
904
905void ieee80211_stop_scan(struct ieee80211_device *ieee)
906{
907 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
908 ieee80211_softmac_stop_scan(ieee);
909 else
910 ieee->stop_scan(ieee->dev);
911}
912
913/* called with ieee->lock held */
914void ieee80211_start_scan(struct ieee80211_device *ieee)
915{
916#ifdef ENABLE_DOT11D
917 if(IS_DOT11D_ENABLE(ieee) )
918 {
919 if(IS_COUNTRY_IE_VALID(ieee))
920 {
921 RESET_CIE_WATCHDOG(ieee);
922 }
923 }
924#endif
925 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN){
926 if (ieee->scanning == 0)
927 {
928 ieee->scanning = 1;
929 //ieee80211_softmac_scan(ieee);
930 // queue_work(ieee->wq, &ieee->softmac_scan_wq);
931 //care this,1203,2007,by lawrence
932#if 1
933 queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq,0);
934#endif
935 }
936 }else
937 ieee->start_scan(ieee->dev);
938
939}
940
941/* called with wx_sem held */
942void ieee80211_start_scan_syncro(struct ieee80211_device *ieee)
943{
944#ifdef ENABLE_DOT11D
945 if(IS_DOT11D_ENABLE(ieee) )
946 {
947 if(IS_COUNTRY_IE_VALID(ieee))
948 {
949 RESET_CIE_WATCHDOG(ieee);
950 }
951 }
952#endif
953 ieee->sync_scan_hurryup = 0;
954
955 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
956 ieee80211_softmac_scan_syncro(ieee);
957 else
958 ieee->scan_syncro(ieee->dev);
959
960}
961
962inline struct sk_buff *ieee80211_authentication_req(struct ieee80211_network *beacon,
963 struct ieee80211_device *ieee, int challengelen)
964{
965 struct sk_buff *skb;
966 struct ieee80211_authentication *auth;
967
968 skb = dev_alloc_skb(sizeof(struct ieee80211_authentication) + challengelen);
969
970 if (!skb) return NULL;
971
972 auth = (struct ieee80211_authentication *)
973 skb_put(skb, sizeof(struct ieee80211_authentication));
974
975 auth->header.frame_ctl = IEEE80211_STYPE_AUTH;
976 if (challengelen) auth->header.frame_ctl |= IEEE80211_FCTL_WEP;
977
978 auth->header.duration_id = 0x013a; //FIXME
979
980 memcpy(auth->header.addr1, beacon->bssid, ETH_ALEN);
981 memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
982 memcpy(auth->header.addr3, beacon->bssid, ETH_ALEN);
983
984 auth->algorithm = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
985
986 auth->transaction = cpu_to_le16(ieee->associate_seq);
987 ieee->associate_seq++;
988
989 auth->status = cpu_to_le16(WLAN_STATUS_SUCCESS);
990
991 return skb;
992
993}
994
995static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *dest)
996{
997 u8 *tag;
998 int beacon_size;
999 struct ieee80211_probe_response *beacon_buf;
1000 struct sk_buff *skb;
1001 int encrypt;
1002 int atim_len,erp_len;
1003 struct ieee80211_crypt_data* crypt;
1004
1005 char *ssid = ieee->current_network.ssid;
1006 int ssid_len = ieee->current_network.ssid_len;
1007 int rate_len = ieee->current_network.rates_len+2;
1008 int rate_ex_len = ieee->current_network.rates_ex_len;
1009 int wpa_ie_len = ieee->wpa_ie_len;
1010 if(rate_ex_len > 0) rate_ex_len+=2;
1011
1012 if(ieee->current_network.capability & WLAN_CAPABILITY_IBSS)
1013 atim_len = 4;
1014 else
1015 atim_len = 0;
1016
1017 if(ieee80211_is_54g(ieee->current_network))
1018 erp_len = 3;
1019 else
1020 erp_len = 0;
1021
1022 beacon_size = sizeof(struct ieee80211_probe_response)+
1023 ssid_len
1024 +3 //channel
1025 +rate_len
1026 +rate_ex_len
1027 +atim_len
1028 +wpa_ie_len
1029 +erp_len;
1030
1031 skb = dev_alloc_skb(beacon_size);
1032
1033 if (!skb)
1034 return NULL;
1035
1036 beacon_buf = (struct ieee80211_probe_response*) skb_put(skb, beacon_size);
1037
1038 memcpy (beacon_buf->header.addr1, dest,ETH_ALEN);
1039 memcpy (beacon_buf->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
1040 memcpy (beacon_buf->header.addr3, ieee->current_network.bssid, ETH_ALEN);
1041
1042 beacon_buf->header.duration_id = 0; //FIXME
1043 beacon_buf->beacon_interval =
1044 cpu_to_le16(ieee->current_network.beacon_interval);
1045 beacon_buf->capability =
1046 cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_IBSS);
1047
1048 if(ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT))
1049 cpu_to_le16((beacon_buf->capability |= WLAN_CAPABILITY_SHORT_SLOT));
1050
1051 crypt = ieee->crypt[ieee->tx_keyidx];
1052
1053 encrypt = ieee->host_encrypt && crypt && crypt->ops &&
1054 ((0 == strcmp(crypt->ops->name, "WEP")) || wpa_ie_len);
1055
1056 if (encrypt)
1057 beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
1058
1059
1060 beacon_buf->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_RESP);
1061
1062 beacon_buf->info_element.id = MFIE_TYPE_SSID;
1063 beacon_buf->info_element.len = ssid_len;
1064
1065 tag = (u8*) beacon_buf->info_element.data;
1066
1067 memcpy(tag, ssid, ssid_len);
1068
1069 tag += ssid_len;
1070
1071 *(tag++) = MFIE_TYPE_RATES;
1072 *(tag++) = rate_len-2;
1073 memcpy(tag,ieee->current_network.rates,rate_len-2);
1074 tag+=rate_len-2;
1075
1076 *(tag++) = MFIE_TYPE_DS_SET;
1077 *(tag++) = 1;
1078 *(tag++) = ieee->current_network.channel;
1079
1080 if(atim_len){
1081 *(tag++) = MFIE_TYPE_IBSS_SET;
1082 *(tag++) = 2;
1083 *((u16*)(tag)) = cpu_to_le16(ieee->current_network.atim_window);
1084 tag+=2;
1085 }
1086
1087 if(erp_len){
1088 *(tag++) = MFIE_TYPE_ERP;
1089 *(tag++) = 1;
1090 *(tag++) = 0;
1091 }
1092
1093 if(rate_ex_len){
1094 *(tag++) = MFIE_TYPE_RATES_EX;
1095 *(tag++) = rate_ex_len-2;
1096 memcpy(tag,ieee->current_network.rates_ex,rate_ex_len-2);
1097 tag+=rate_ex_len-2;
1098 }
1099
1100 if (wpa_ie_len)
1101 {
1102 if (ieee->iw_mode == IW_MODE_ADHOC)
1103 {//as Windows will set pairwise key same as the group key which is not allowed in Linux, so set this for IOT issue. WB 2008.07.07
1104 memcpy(&ieee->wpa_ie[14], &ieee->wpa_ie[8], 4);
1105 }
1106
1107 memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
1108 }
1109
1110 skb->dev = ieee->dev;
1111 return skb;
1112}
1113#ifdef _RTL8187_EXT_PATCH_
1114struct sk_buff* ieee80211_ext_probe_resp_by_net(struct ieee80211_device *ieee, u8 *dest, struct ieee80211_network *net)
1115{
1116 u8 *tag;
1117 int beacon_size;
1118 struct ieee80211_probe_response *beacon_buf;
1119 struct sk_buff *skb;
1120 int encrypt;
1121 int atim_len,erp_len;
1122 struct ieee80211_crypt_data* crypt;
1123 u8 broadcast_addr[] = {0xff,0xff,0xff,0xff,0xff,0xff};
1124 int wpa_ie_len = ieee->wpa_ie_len;
1125 char *ssid = net->ssid;
1126 int ssid_len = net->ssid_len;
1127
1128 int rate_len = ieee->current_network.rates_len+2;
1129 int rate_ex_len = ieee->current_network.rates_ex_len;
1130 if(rate_ex_len > 0) rate_ex_len+=2;
1131
1132 if( ieee->meshScanMode&4)
1133 ieee->current_network.channel = ieee->ext_patch_ieee80211_ext_stop_scan_wq_set_channel(ieee);
1134 if( ieee->meshScanMode&6)
1135 {
1136
1137#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
1138 queue_work(ieee->wq, &ieee->ext_stop_scan_wq);
1139#else
1140 schedule_task(&ieee->ext_stop_scan_wq);
1141#endif
1142 }
1143 if(ieee->current_network.capability & WLAN_CAPABILITY_IBSS) // use current_network here
1144 atim_len = 4;
1145 else
1146 atim_len = 0;
1147
1148 if(ieee80211_is_54g(*net))
1149 erp_len = 3;
1150 else
1151 erp_len = 0;
1152
1153 beacon_size = sizeof(struct ieee80211_probe_response)+
1154 ssid_len
1155 +3 //channel
1156 +rate_len
1157 +rate_ex_len
1158 +atim_len
1159 +erp_len;
1160//b
1161 skb = dev_alloc_skb(beacon_size+196);
1162
1163 if (!skb)
1164 return NULL;
1165
1166 beacon_buf = (struct ieee80211_probe_response*) skb_put(skb, beacon_size);
1167
1168 memcpy (beacon_buf->header.addr1, dest,ETH_ALEN);
1169 memcpy (beacon_buf->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
1170 memcpy (beacon_buf->header.addr3, ieee->current_network.bssid, ETH_ALEN);
1171
1172 beacon_buf->header.duration_id = 0; //FIXME
1173
1174 beacon_buf->beacon_interval =
1175 cpu_to_le16(ieee->current_network.beacon_interval); // use current_network here
1176 beacon_buf->capability =
1177 cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_IBSS);
1178
1179 if(ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT))
1180 cpu_to_le16((beacon_buf->capability |= WLAN_CAPABILITY_SHORT_SLOT));
1181
1182 crypt = ieee->crypt[ieee->tx_keyidx];
1183
1184 encrypt = ieee->host_encrypt && crypt && crypt->ops &&
1185 ((0 == strcmp(crypt->ops->name, "WEP"))||wpa_ie_len);
1186
1187 if (encrypt)
1188 beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
1189
1190
1191 beacon_buf->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_RESP);
1192
1193 beacon_buf->info_element.id = MFIE_TYPE_SSID;
1194 beacon_buf->info_element.len = ssid_len;
1195
1196 tag = (u8*) beacon_buf->info_element.data;
1197
1198 // brocad cast / probe rsp
1199 if(memcmp(dest, broadcast_addr, ETH_ALEN ))
1200 memcpy(tag, ssid, ssid_len);
1201 else
1202 ssid_len=0;
1203
1204 tag += ssid_len;
1205
1206//get_bssrate_set(priv, _SUPPORTEDRATES_IE_, &pbssrate, &bssrate_len);
1207//pbuf = set_ie(pbuf, _SUPPORTEDRATES_IE_, bssrate_len, pbssrate, &frlen);
1208
1209 *(tag++) = MFIE_TYPE_RATES;
1210 *(tag++) = rate_len-2;
1211 memcpy(tag,ieee->current_network.rates,rate_len-2);
1212 tag+=rate_len-2;
1213
1214 *(tag++) = MFIE_TYPE_DS_SET;
1215 *(tag++) = 1;
1216 *(tag++) = ieee->current_network.channel; // use current_network here
1217
1218
1219 if(atim_len){
1220 *(tag++) = MFIE_TYPE_IBSS_SET;
1221 *(tag++) = 2;
1222 *((u16*)(tag)) = cpu_to_le16(ieee->current_network.atim_window); // use current_network here
1223 tag+=2;
1224 }
1225
1226 if(erp_len){
1227 *(tag++) = MFIE_TYPE_ERP;
1228 *(tag++) = 1;
1229 *(tag++) = 0;
1230 }
1231
1232 if(rate_ex_len){
1233 *(tag++) = MFIE_TYPE_RATES_EX;
1234 *(tag++) = rate_ex_len-2;
1235 memcpy(tag,ieee->current_network.rates_ex,rate_ex_len-2);
1236 tag+=rate_ex_len-2;
1237 }
1238 if (wpa_ie_len)
1239 memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
1240
1241 skb->dev = ieee->dev;
1242 return skb;
1243}
1244#endif // _RTL8187_EXT_PATCH_
1245
1246struct sk_buff* ieee80211_assoc_resp(struct ieee80211_device *ieee, u8 *dest)
1247{
1248 struct sk_buff *skb;
1249 u8* tag;
1250
1251 struct ieee80211_crypt_data* crypt;
1252 struct ieee80211_assoc_response_frame *assoc;
1253 short encrypt;
1254
1255 unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
1256 int len = sizeof(struct ieee80211_assoc_response_frame) + rate_len;
1257
1258 skb = dev_alloc_skb(len);
1259
1260 if (!skb)
1261 return NULL;
1262
1263 assoc = (struct ieee80211_assoc_response_frame *)
1264 skb_put(skb,sizeof(struct ieee80211_assoc_response_frame));
1265
1266 assoc->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP);
1267 memcpy(assoc->header.addr1, dest,ETH_ALEN);
1268 memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
1269 memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
1270 assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ?
1271 WLAN_CAPABILITY_BSS : WLAN_CAPABILITY_IBSS);
1272
1273
1274 if(ieee->short_slot)
1275 assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
1276
1277 if (ieee->host_encrypt)
1278 crypt = ieee->crypt[ieee->tx_keyidx];
1279 else crypt = NULL;
1280
1281 encrypt = ( crypt && crypt->ops);
1282
1283 if (encrypt)
1284 assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
1285
1286 assoc->status = 0;
1287 assoc->aid = cpu_to_le16(ieee->assoc_id);
1288 if (ieee->assoc_id == 0x2007) ieee->assoc_id=0;
1289 else ieee->assoc_id++;
1290
1291 tag = (u8*) skb_put(skb, rate_len);
1292
1293 ieee80211_MFIE_Brate(ieee, &tag);
1294 ieee80211_MFIE_Grate(ieee, &tag);
1295
1296 return skb;
1297}
1298
1299struct sk_buff* ieee80211_auth_resp(struct ieee80211_device *ieee,int status, u8 *dest)
1300{
1301 struct sk_buff *skb;
1302 struct ieee80211_authentication *auth;
1303
1304 skb = dev_alloc_skb(sizeof(struct ieee80211_authentication)+1);
1305
1306 if (!skb)
1307 return NULL;
1308
1309 skb->len = sizeof(struct ieee80211_authentication);
1310
1311 auth = (struct ieee80211_authentication *)skb->data;
1312
1313 auth->status = cpu_to_le16(status);
1314 auth->transaction = cpu_to_le16(2);
1315 auth->algorithm = cpu_to_le16(WLAN_AUTH_OPEN);
1316
1317#ifdef _RTL8187_EXT_PATCH_
1318 if(ieee->iw_mode == ieee->iw_ext_mode)
1319 memcpy(auth->header.addr3, dest, ETH_ALEN);
1320#else
1321 memcpy(auth->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
1322#endif
1323 memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
1324 memcpy(auth->header.addr1, dest, ETH_ALEN);
1325 auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH);
1326 return skb;
1327
1328
1329}
1330
1331struct sk_buff* ieee80211_null_func(struct ieee80211_device *ieee,short pwr)
1332{
1333 struct sk_buff *skb;
1334 struct ieee80211_hdr_3addr* hdr;
1335
1336 skb = dev_alloc_skb(sizeof(struct ieee80211_hdr_3addr));
1337
1338 if (!skb)
1339 return NULL;
1340
1341 hdr = (struct ieee80211_hdr_3addr*)skb_put(skb,sizeof(struct ieee80211_hdr_3addr));
1342
1343 memcpy(hdr->addr1, ieee->current_network.bssid, ETH_ALEN);
1344 memcpy(hdr->addr2, ieee->dev->dev_addr, ETH_ALEN);
1345 memcpy(hdr->addr3, ieee->current_network.bssid, ETH_ALEN);
1346
1347 hdr->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA |
1348 IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS |
1349 (pwr ? IEEE80211_FCTL_PM:0));
1350
1351 return skb;
1352
1353
1354}
1355
1356
1357void ieee80211_resp_to_assoc_rq(struct ieee80211_device *ieee, u8* dest)
1358{
1359 struct sk_buff *buf = ieee80211_assoc_resp(ieee, dest);
1360
1361 if (buf){
1362 softmac_mgmt_xmit(buf, ieee);
1363 dev_kfree_skb_any(buf);//edit by thomas
1364 }
1365}
1366
1367
1368void ieee80211_resp_to_auth(struct ieee80211_device *ieee, int s, u8* dest)
1369{
1370 struct sk_buff *buf = ieee80211_auth_resp(ieee, s, dest);
1371
1372 if (buf){
1373 softmac_mgmt_xmit(buf, ieee);
1374 dev_kfree_skb_any(buf);//edit by thomas
1375 }
1376}
1377
1378
1379void ieee80211_resp_to_probe(struct ieee80211_device *ieee, u8 *dest)
1380{
1381
1382 struct sk_buff *buf = ieee80211_probe_resp(ieee, dest);
1383
1384 if (buf) {
1385 softmac_mgmt_xmit(buf, ieee);
1386 dev_kfree_skb_any(buf);//edit by thomas
1387 }
1388}
1389
1390
1391inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beacon,struct ieee80211_device *ieee)
1392{
1393 struct sk_buff *skb;
1394 //unsigned long flags;
1395
1396 struct ieee80211_assoc_request_frame *hdr;
1397 u8 *tag;
1398 //short info_addr = 0;
1399 //int i;
1400 //u16 suite_count = 0;
1401 //u8 suit_select = 0;
1402 unsigned int wpa_len = beacon->wpa_ie_len;
1403 //struct net_device *dev = ieee->dev;
1404 //union iwreq_data wrqu;
1405 //u8 *buff;
1406 //u8 *p;
1407#if 1
1408 // for testing purpose
1409 unsigned int rsn_len = beacon->rsn_ie_len;
1410#else
1411 unsigned int rsn_len = beacon->rsn_ie_len - 4;
1412#endif
1413 unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
1414 unsigned int wmm_info_len = beacon->QoS_Enable?9:0;
1415#ifdef THOMAS_TURBO
1416 unsigned int turbo_info_len = beacon->Turbo_Enable?9:0;
1417#endif
1418
1419 u8 encry_proto = ieee->wpax_type_notify & 0xff;
1420 //u8 pairwise_type = (ieee->wpax_type_notify >> 8) & 0xff;
1421 //u8 authen_type = (ieee->wpax_type_notify >> 16) & 0xff;
1422
1423 int len = 0;
1424
1425 //[0] Notify type of encryption: WPA/WPA2
1426 //[1] pair wise type
1427 //[2] authen type
1428 if(ieee->wpax_type_set) {
1429 if (IEEE_PROTO_WPA == encry_proto) {
1430 rsn_len = 0;
1431 } else if (IEEE_PROTO_RSN == encry_proto) {
1432 wpa_len = 0;
1433 }
1434 }
1435#ifdef THOMAS_TURBO
1436 len = sizeof(struct ieee80211_assoc_request_frame)+
1437 + beacon->ssid_len//essid tagged val
1438 + rate_len//rates tagged val
1439 + wpa_len
1440 + rsn_len
1441 + wmm_info_len
1442 + turbo_info_len;
1443#else
1444 len = sizeof(struct ieee80211_assoc_request_frame)+
1445 + beacon->ssid_len//essid tagged val
1446 + rate_len//rates tagged val
1447 + wpa_len
1448 + rsn_len
1449 + wmm_info_len;
1450#endif
1451
1452#ifdef _RTL8187_EXT_PATCH_
1453 if(ieee->iw_mode == ieee->iw_ext_mode)
1454 skb = dev_alloc_skb(len+256); // stanley
1455 else
1456#endif
1457 skb = dev_alloc_skb(len);
1458
1459 if (!skb)
1460 return NULL;
1461
1462 hdr = (struct ieee80211_assoc_request_frame *)
1463 skb_put(skb, sizeof(struct ieee80211_assoc_request_frame));
1464
1465
1466 hdr->header.frame_ctl = IEEE80211_STYPE_ASSOC_REQ;
1467 hdr->header.duration_id= 37; //FIXME
1468 memcpy(hdr->header.addr1, beacon->bssid, ETH_ALEN);
1469 memcpy(hdr->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
1470 memcpy(hdr->header.addr3, beacon->bssid, ETH_ALEN);
1471 memcpy(ieee->ap_mac_addr, beacon->bssid, ETH_ALEN);//for HW security, John
1472
1473 hdr->capability = cpu_to_le16(WLAN_CAPABILITY_BSS);
1474 if (beacon->capability & WLAN_CAPABILITY_PRIVACY )
1475 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
1476 if (beacon->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
1477 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE);
1478
1479 if(ieee->short_slot)
1480 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
1481
1482#ifdef _RTL8187_EXT_PATCH_
1483 if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_association_req_1)
1484 ieee->ext_patch_ieee80211_association_req_1(hdr);
1485#endif
1486
1487 hdr->listen_interval = 0xa; //FIXME
1488
1489 hdr->info_element.id = MFIE_TYPE_SSID;
1490
1491 hdr->info_element.len = beacon->ssid_len;
1492 tag = skb_put(skb, beacon->ssid_len);
1493 memcpy(tag, beacon->ssid, beacon->ssid_len);
1494
1495 tag = skb_put(skb, rate_len);
1496
1497 ieee80211_MFIE_Brate(ieee, &tag);
1498 ieee80211_MFIE_Grate(ieee, &tag);
1499
1500 //add rsn==0 condition for ap's mix security mode(wpa+wpa2), john2007.8.9
1501 //choose AES encryption as default algorithm while using mixed mode
1502#if 0
1503 if(rsn_len == 0){
1504
1505 tag = skb_put(skb,wpa_len);
1506
1507 if(wpa_len) {
1508
1509
1510 //{add by david. 2006.8.31
1511 //fix linksys compatibility bug
1512 //}
1513 if(wpa_len > 24) {//22+2, mean include the capability
1514 beacon->wpa_ie[wpa_len - 2] = 0;
1515 }
1516 //multicast cipher OUI
1517 if( beacon->wpa_ie[11]==0x2 ){ //0x0050f202 is the oui of tkip
1518 ieee->broadcast_key_type = KEY_TYPE_TKIP;
1519 }
1520 else if( beacon->wpa_ie[11]==0x4 ){//0x0050f204 is the oui of ccmp
1521 ieee->broadcast_key_type = KEY_TYPE_CCMP;
1522 }
1523 //unicast cipher OUI
1524 if( beacon->wpa_ie[14]==0
1525 && beacon->wpa_ie[15]==0x50
1526 && beacon->wpa_ie[16]==0xf2
1527 && beacon->wpa_ie[17]==0x2 ){ //0x0050f202 is the oui of tkip
1528 ieee->pairwise_key_type = KEY_TYPE_TKIP;
1529 }
1530
1531 else if( beacon->wpa_ie[14]==0
1532 && beacon->wpa_ie[15]==0x50
1533 && beacon->wpa_ie[16]==0xf2
1534 && beacon->wpa_ie[17]==0x4 ){//0x0050f204 is the oui of ccmp
1535 ieee->pairwise_key_type = KEY_TYPE_CCMP;
1536 }
1537 //indicate the wpa_ie content to WPA_SUPPLICANT
1538 buff = kmalloc(IW_CUSTOM_MAX, GFP_ATOMIC);
1539 memset(buff, 0, IW_CUSTOM_MAX);
1540 p=buff;
1541 p += sprintf(p, "ASSOCINFO(ReqIEs=");
1542 for(i=0;i<wpa_len;i++){
1543 p += sprintf(p, "%02x", beacon->wpa_ie[i]);
1544 }
1545 p += sprintf(p, ")");
1546 memset(&wrqu, 0, sizeof(wrqu) );
1547 wrqu.data.length = p - buff;
1548
1549 wireless_send_event(dev, IWEVCUSTOM, &wrqu, buff);
1550 memcpy(tag,beacon->wpa_ie,wpa_len);
1551 }
1552
1553 }
1554
1555 if(rsn_len > 22) {
1556
1557 if( beacon->rsn_ie[4]==0x0 &&
1558 beacon->rsn_ie[5]==0xf &&
1559 beacon->rsn_ie[6]==0xac){
1560
1561 switch(beacon->rsn_ie[7]){
1562 case 0x1:
1563 ieee->broadcast_key_type = KEY_TYPE_WEP40;
1564 break;
1565 case 0x2:
1566 ieee->broadcast_key_type = KEY_TYPE_TKIP;
1567 break;
1568 case 0x4:
1569 ieee->broadcast_key_type = KEY_TYPE_CCMP;
1570 break;
1571 case 0x5:
1572 ieee->broadcast_key_type = KEY_TYPE_WEP104;
1573 break;
1574 default:
1575 printk("fault suite type in RSN broadcast key\n");
1576 break;
1577 }
1578 }
1579
1580 if( beacon->rsn_ie[10]==0x0 &&
1581 beacon->rsn_ie[11]==0xf &&
1582 beacon->rsn_ie[12]==0xac){
1583 if(beacon->rsn_ie[8]==1){//not mixed mode
1584 switch(beacon->rsn_ie[13]){
1585 case 0x2:
1586 ieee->pairwise_key_type = KEY_TYPE_TKIP;
1587 break;
1588 case 0x4:
1589 ieee->pairwise_key_type = KEY_TYPE_CCMP;
1590 break;
1591 default:
1592 printk("fault suite type in RSN pairwise key\n");
1593 break;
1594 }
1595 }
1596 else if(beacon->rsn_ie[8]==2){//mixed mode
1597 ieee->pairwise_key_type = KEY_TYPE_CCMP;
1598 }
1599 }
1600
1601
1602
1603 tag = skb_put(skb,22);
1604 memcpy(tag,(beacon->rsn_ie + info_addr),8);
1605 tag[1] = 20;
1606 tag += 8;
1607 info_addr += 8;
1608
1609 spin_lock_irqsave(&ieee->wpax_suitlist_lock,flags);
1610 for (i = 0; i < 2; i++) {
1611 tag[0] = 1;
1612 tag[1] = 0;
1613 tag += 2;
1614 suite_count = beacon->rsn_ie[info_addr] + \
1615 (beacon->rsn_ie[info_addr + 1] << 8);
1616 info_addr += 2;
1617 if(1 == suite_count) {
1618 memcpy(tag,(beacon->rsn_ie + info_addr),4);
1619 info_addr += 4;
1620 } else {
1621 // if the wpax_type_notify has been set by the application,
1622 // just use it, otherwise just use the default one.
1623 if(ieee->wpax_type_set) {
1624 suit_select = ((0 == i) ? pairwise_type:authen_type)&0x0f ;
1625 memcpy(tag,rsn_authen_cipher_suite[suit_select],4);
1626 } else {
1627 //default set as ccmp, or none authentication
1628 if(i == 0) {
1629 memcpy(tag,rsn_authen_cipher_suite[4],4);
1630 } else {
1631 memcpy(tag,rsn_authen_cipher_suite[2],4);
1632 }
1633
1634 }
1635
1636 info_addr += (suite_count * 4);
1637 }
1638 tag += 4;
1639 }
1640 spin_unlock_irqrestore(&ieee->wpax_suitlist_lock,flags);
1641
1642 tag[0] = 0;
1643 tag[1] = beacon->rsn_ie[info_addr+1];
1644
1645 } else {
1646 tag = skb_put(skb,rsn_len);
1647 if(rsn_len) {
1648
1649
1650 if( beacon->rsn_ie[4]==0x0 &&
1651 beacon->rsn_ie[5]==0xf &&
1652 beacon->rsn_ie[6]==0xac){
1653 switch(beacon->rsn_ie[7]){
1654 case 0x1:
1655 ieee->broadcast_key_type = KEY_TYPE_WEP40;
1656 break;
1657 case 0x2:
1658 ieee->broadcast_key_type = KEY_TYPE_TKIP;
1659 break;
1660 case 0x4:
1661 ieee->broadcast_key_type = KEY_TYPE_CCMP;
1662 break;
1663 case 0x5:
1664 ieee->broadcast_key_type = KEY_TYPE_WEP104;
1665 break;
1666 default:
1667 printk("fault suite type in RSN broadcast key\n");
1668 break;
1669 }
1670 }
1671 if( beacon->rsn_ie[10]==0x0 &&
1672 beacon->rsn_ie[11]==0xf &&
1673 beacon->rsn_ie[12]==0xac){
1674 if(beacon->rsn_ie[8]==1){//not mixed mode
1675 switch(beacon->rsn_ie[13]){
1676 case 0x2:
1677 ieee->pairwise_key_type = KEY_TYPE_TKIP;
1678 break;
1679 case 0x4:
1680 ieee->pairwise_key_type = KEY_TYPE_CCMP;
1681 break;
1682 default:
1683 printk("fault suite type in RSN pairwise key\n");
1684 break;
1685 }
1686
1687 }
1688 else if(beacon->rsn_ie[8]==2){//mixed mode
1689 ieee->pairwise_key_type = KEY_TYPE_CCMP;
1690 }
1691 }
1692
1693
1694 beacon->rsn_ie[rsn_len - 2] = 0;
1695 memcpy(tag,beacon->rsn_ie,rsn_len);
1696 }
1697 }
1698#else
1699 tag = skb_put(skb,ieee->wpa_ie_len);
1700 memcpy(tag,ieee->wpa_ie,ieee->wpa_ie_len);
1701#endif
1702 tag = skb_put(skb,wmm_info_len);
1703 if(wmm_info_len) {
1704 ieee80211_WMM_Info(ieee, &tag);
1705 }
1706#ifdef THOMAS_TURBO
1707 tag = skb_put(skb,turbo_info_len);
1708 if(turbo_info_len) {
1709 ieee80211_TURBO_Info(ieee, &tag);
1710 }
1711#endif
1712
1713#ifdef _RTL8187_EXT_PATCH_
1714 if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_association_req_2)
1715 ieee->ext_patch_ieee80211_association_req_2(ieee, beacon, skb);
1716#endif
1717
1718 return skb;
1719}
1720
1721void ieee80211_associate_abort(struct ieee80211_device *ieee)
1722{
1723
1724 unsigned long flags;
1725 spin_lock_irqsave(&ieee->lock, flags);
1726
1727 ieee->associate_seq++;
1728
1729 /* don't scan, and avoid to have the RX path possibily
1730 * try again to associate. Even do not react to AUTH or
1731 * ASSOC response. Just wait for the retry wq to be scheduled.
1732 * Here we will check if there are good nets to associate
1733 * with, so we retry or just get back to NO_LINK and scanning
1734 */
1735 if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING){
1736 IEEE80211_DEBUG_MGMT("Authentication failed\n");
1737 ieee->softmac_stats.no_auth_rs++;
1738 }else{
1739 IEEE80211_DEBUG_MGMT("Association failed\n");
1740 ieee->softmac_stats.no_ass_rs++;
1741 }
1742
1743 ieee->state = IEEE80211_ASSOCIATING_RETRY;
1744
1745 queue_delayed_work(ieee->wq, &ieee->associate_retry_wq,IEEE80211_SOFTMAC_ASSOC_RETRY_TIME);
1746
1747 spin_unlock_irqrestore(&ieee->lock, flags);
1748}
1749
1750void ieee80211_associate_abort_cb(unsigned long dev)
1751{
1752 ieee80211_associate_abort((struct ieee80211_device *) dev);
1753}
1754
1755
1756void ieee80211_associate_step1(struct ieee80211_device *ieee)
1757{
1758 struct ieee80211_network *beacon = &ieee->current_network;
1759 struct sk_buff *skb;
1760
1761 IEEE80211_DEBUG_MGMT("Stopping scan\n");
1762 ieee->softmac_stats.tx_auth_rq++;
1763 skb=ieee80211_authentication_req(beacon, ieee, 0);
1764#ifdef _RTL8187_EXT_PATCH_
1765 if(ieee->iw_mode == ieee->iw_ext_mode ) {
1766 if(skb)
1767 softmac_mgmt_xmit(skb, ieee);
1768 return;
1769 }else
1770#endif
1771 if (!skb){
1772
1773 ieee80211_associate_abort(ieee);
1774 }
1775 else{
1776 ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATING ;
1777 IEEE80211_DEBUG_MGMT("Sending authentication request\n");
1778 //printk("---Sending authentication request\n");
1779 softmac_mgmt_xmit(skb, ieee);
1780 //BUGON when you try to add_timer twice, using mod_timer may be better, john0709
1781 if(!timer_pending(&ieee->associate_timer)){
1782 ieee->associate_timer.expires = jiffies + (HZ / 2);
1783 add_timer(&ieee->associate_timer);
1784 }
1785 //If call dev_kfree_skb_any,a warning will ocur....
1786 //KERNEL: assertion (!atomic_read(&skb->users)) failed at net/core/dev.c (1708)
1787 //So ... 1204 by lawrence.
1788 //printk("\nIn %s,line %d call kfree skb.",__FUNCTION__,__LINE__);
1789 //dev_kfree_skb_any(skb);//edit by thomas
1790 }
1791}
1792
1793void ieee80211_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int chlen)
1794{
1795 u8 *c;
1796 struct sk_buff *skb;
1797 struct ieee80211_network *beacon = &ieee->current_network;
1798// int hlen = sizeof(struct ieee80211_authentication);
1799 del_timer_sync(&ieee->associate_timer);
1800 ieee->associate_seq++;
1801 ieee->softmac_stats.tx_auth_rq++;
1802
1803 skb = ieee80211_authentication_req(beacon, ieee, chlen+2);
1804 if (!skb)
1805 ieee80211_associate_abort(ieee);
1806 else{
1807 c = skb_put(skb, chlen+2);
1808 *(c++) = MFIE_TYPE_CHALLENGE;
1809 *(c++) = chlen;
1810 memcpy(c, challenge, chlen);
1811
1812 IEEE80211_DEBUG_MGMT("Sending authentication challenge response\n");
1813
1814 ieee80211_encrypt_fragment(ieee, skb, sizeof(struct ieee80211_hdr_3addr ));
1815
1816 softmac_mgmt_xmit(skb, ieee);
1817 if (!timer_pending(&ieee->associate_timer)){
1818 //printk("=========>add timer again, to crash\n");
1819 ieee->associate_timer.expires = jiffies + (HZ / 2);
1820 add_timer(&ieee->associate_timer);
1821 }
1822 dev_kfree_skb_any(skb);//edit by thomas
1823 }
1824 kfree(challenge);
1825}
1826
1827#ifdef _RTL8187_EXT_PATCH_
1828
1829// based on ieee80211_assoc_resp
1830struct sk_buff* ieee80211_assoc_resp_by_net(struct ieee80211_device *ieee, u8 *dest, unsigned short status, struct ieee80211_network *pstat, int pkt_type)
1831{
1832 struct sk_buff *skb;
1833 u8* tag;
1834
1835 struct ieee80211_crypt_data* crypt;
1836 struct ieee80211_assoc_response_frame *assoc;
1837 short encrypt;
1838
1839 unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
1840 int len = sizeof(struct ieee80211_assoc_response_frame) + rate_len;
1841
1842 if(ieee->iw_mode == ieee->iw_ext_mode)
1843 skb = dev_alloc_skb(len+256); // stanley
1844 else
1845 skb = dev_alloc_skb(len);
1846
1847 if (!skb)
1848 return NULL;
1849
1850 assoc = (struct ieee80211_assoc_response_frame *)
1851 skb_put(skb,sizeof(struct ieee80211_assoc_response_frame));
1852
1853 assoc->header.frame_ctl = cpu_to_le16(pkt_type);
1854
1855 memcpy(assoc->header.addr1, dest,ETH_ALEN);
1856 memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
1857 memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
1858 assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ?
1859 WLAN_CAPABILITY_BSS : WLAN_CAPABILITY_IBSS);
1860
1861 if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_assoc_resp_by_net_1)
1862 ieee->ext_patch_ieee80211_assoc_resp_by_net_1(assoc);
1863
1864 if(ieee->short_slot)
1865 assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
1866
1867 if (ieee->host_encrypt)
1868 crypt = ieee->crypt[ieee->tx_keyidx];
1869 else crypt = NULL;
1870
1871 encrypt = ( crypt && crypt->ops);
1872
1873 if (encrypt)
1874 assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
1875
1876 assoc->status = 0;
1877 assoc->aid = cpu_to_le16(ieee->assoc_id);
1878 if (ieee->assoc_id == 0x2007) ieee->assoc_id=0;
1879 else ieee->assoc_id++;
1880
1881 assoc->info_element.id = 230; // Stanley, an unused id (just a hot fix)
1882 assoc->info_element.len = 0;
1883
1884 tag = (u8*) skb_put(skb, rate_len);
1885
1886 ieee80211_MFIE_Brate(ieee, &tag);
1887 ieee80211_MFIE_Grate(ieee, &tag);
1888
1889 if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_assoc_resp_by_net_2)
1890 ieee->ext_patch_ieee80211_assoc_resp_by_net_2(ieee, pstat, pkt_type, skb);
1891
1892 return skb;
1893}
1894
1895// based on ieee80211_resp_to_assoc_rq
1896void ieee80211_ext_issue_assoc_rsp(struct ieee80211_device *ieee, u8 *dest, unsigned short status, struct ieee80211_network *pstat, int pkt_type)
1897{
1898 struct sk_buff *buf = ieee80211_assoc_resp_by_net(ieee, dest, status, pstat, pkt_type);
1899
1900 if (buf)
1901 softmac_mgmt_xmit(buf, ieee);
1902}
1903
1904// based on ieee80211_associate_step2
1905void ieee80211_ext_issue_assoc_req(struct ieee80211_device *ieee, struct ieee80211_network *pstat)
1906{
1907
1908 struct sk_buff* skb;
1909
1910 // printk("@@@@@ ieee80211_ext_issue_assoc_req on channel: %d\n", ieee->current_network.channel);
1911
1912 ieee->softmac_stats.tx_ass_rq++;
1913 skb=ieee80211_association_req(pstat, ieee);
1914 if (skb)
1915 softmac_mgmt_xmit(skb, ieee);
1916}
1917
1918void ieee80211_ext_issue_disassoc(struct ieee80211_device *ieee, struct ieee80211_network *pstat, int reason, unsigned char extReason)
1919{
1920 // do nothing
1921 // printk("@@@@@ ieee80211_ext_issue_disassoc\n");
1922 return;
1923}
1924#endif // _RTL8187_EXT_PATCH_
1925
1926void ieee80211_associate_step2(struct ieee80211_device *ieee)
1927{
1928 struct sk_buff* skb;
1929 struct ieee80211_network *beacon = &ieee->current_network;
1930
1931 del_timer_sync(&ieee->associate_timer);
1932
1933 IEEE80211_DEBUG_MGMT("Sending association request\n");
1934 ieee->softmac_stats.tx_ass_rq++;
1935 skb=ieee80211_association_req(beacon, ieee);
1936 if (!skb)
1937 ieee80211_associate_abort(ieee);
1938 else{
1939 softmac_mgmt_xmit(skb, ieee);
1940 if (!timer_pending(&ieee->associate_timer)){
1941 ieee->associate_timer.expires = jiffies + (HZ / 2);
1942 add_timer(&ieee->associate_timer);
1943 }
1944 //dev_kfree_skb_any(skb);//edit by thomas
1945 }
1946}
1947
1948#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
1949void ieee80211_associate_complete_wq(struct work_struct *work)
1950{
1951 struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_complete_wq);
1952#else
1953void ieee80211_associate_complete_wq(struct ieee80211_device *ieee)
1954{
1955#endif
1956 printk(KERN_INFO "Associated successfully\n");
1957 if(ieee80211_is_54g(ieee->current_network) &&
1958 (ieee->modulation & IEEE80211_OFDM_MODULATION)){
1959
1960 ieee->rate = 540;
1961 printk(KERN_INFO"Using G rates\n");
1962 }else{
1963 ieee->rate = 110;
1964 printk(KERN_INFO"Using B rates\n");
1965 }
1966 ieee->link_change(ieee->dev);
1967 notify_wx_assoc_event(ieee);
1968 if (ieee->data_hard_resume)
1969 ieee->data_hard_resume(ieee->dev);
1970 netif_carrier_on(ieee->dev);
1971}
1972
1973void ieee80211_associate_complete(struct ieee80211_device *ieee)
1974{
1975 int i;
1976 del_timer_sync(&ieee->associate_timer);
1977
1978 for(i = 0; i < 6; i++) {
1979 //ieee->seq_ctrl[i] = 0;
1980 }
1981 ieee->state = IEEE80211_LINKED;
1982 IEEE80211_DEBUG_MGMT("Successfully associated\n");
1983
1984 queue_work(ieee->wq, &ieee->associate_complete_wq);
1985}
1986
1987#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
1988void ieee80211_associate_procedure_wq(struct work_struct *work)
1989{
1990 struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_procedure_wq);
1991#else
1992void ieee80211_associate_procedure_wq(struct ieee80211_device *ieee)
1993{
1994#endif
1995 ieee->sync_scan_hurryup = 1;
1996 down(&ieee->wx_sem);
1997
1998 if (ieee->data_hard_stop)
1999 ieee->data_hard_stop(ieee->dev);
2000
2001 ieee80211_stop_scan(ieee);
2002 ieee->set_chan(ieee->dev, ieee->current_network.channel);
2003
2004 ieee->associate_seq = 1;
2005 ieee80211_associate_step1(ieee);
2006
2007 up(&ieee->wx_sem);
2008}
2009#ifdef _RTL8187_EXT_PATCH_
2010// based on ieee80211_associate_procedure_wq
2011
2012#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
2013void ieee80211_ext_stop_scan_wq(struct work_struct *work)
2014{
2015 struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, ext_stop_scan_wq);
2016#else
2017void ieee80211_ext_stop_scan_wq(struct ieee80211_device *ieee)
2018{
2019#endif
2020 if (ieee->scanning == 0)
2021 {
2022 if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_ext_stop_scan_wq_set_channel
2023 && ( ieee->current_network.channel == ieee->ext_patch_ieee80211_ext_stop_scan_wq_set_channel(ieee) ) )
2024 return;
2025 }
2026
2027 ieee->sync_scan_hurryup = 1;
2028
2029 down(&ieee->wx_sem);
2030
2031 // printk("@@@@@@@@@@ ieee80211_ext_stop_scan_wq\n");
2032 if (ieee->data_hard_stop)
2033 ieee->data_hard_stop(ieee->dev);
2034
2035 ieee80211_stop_scan(ieee);
2036
2037 // set channel
2038 if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_ext_stop_scan_wq_set_channel)
2039 ieee->set_chan(ieee->dev, ieee->ext_patch_ieee80211_ext_stop_scan_wq_set_channel(ieee));
2040 else
2041 ieee->set_chan(ieee->dev, ieee->current_network.channel);
2042 //
2043 up(&ieee->wx_sem);
2044}
2045
2046
2047void ieee80211_ext_send_11s_beacon(struct ieee80211_device *ieee)
2048{
2049 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
2050 queue_work(ieee->wq, &ieee->ext_send_beacon_wq);
2051 #else
2052 schedule_task(&ieee->ext_send_beacon_wq);
2053 #endif
2054
2055}
2056
2057#endif // _RTL8187_EXT_PATCH_
2058
2059inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net)
2060{
2061 u8 tmp_ssid[IW_ESSID_MAX_SIZE+1];
2062 int tmp_ssid_len = 0;
2063
2064 short apset,ssidset,ssidbroad,apmatch,ssidmatch;
2065
2066 /* we are interested in new new only if we are not associated
2067 * and we are not associating / authenticating
2068 */
2069 if (ieee->state != IEEE80211_NOLINK)
2070 return;
2071
2072 if ((ieee->iw_mode == IW_MODE_INFRA) && !(net->capability & WLAN_CAPABILITY_BSS))
2073 return;
2074
2075 if ((ieee->iw_mode == IW_MODE_ADHOC) && !(net->capability & WLAN_CAPABILITY_IBSS))
2076 return;
2077
2078
2079 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC){
2080 /* if the user specified the AP MAC, we need also the essid
2081 * This could be obtained by beacons or, if the network does not
2082 * broadcast it, it can be put manually.
2083 */
2084 apset = ieee->wap_set;//(memcmp(ieee->current_network.bssid, zero,ETH_ALEN)!=0 );
2085 ssidset = ieee->ssid_set;//ieee->current_network.ssid[0] != '\0';
2086 ssidbroad = !(net->ssid_len == 0 || net->ssid[0]== '\0');
2087 apmatch = (memcmp(ieee->current_network.bssid, net->bssid, ETH_ALEN)==0);
2088
2089 if(ieee->current_network.ssid_len != net->ssid_len)
2090 ssidmatch = 0;
2091 else
2092 ssidmatch = (0==strncmp(ieee->current_network.ssid, net->ssid, net->ssid_len));
2093
2094 //printk("cur: %s, %d, net:%s, %d\n", ieee->current_network.ssid, ieee->current_network.ssid_len, net->ssid, net->ssid_len);
2095 //printk("apset=%d apmatch=%d ssidset=%d ssidbroad=%d ssidmatch=%d\n",apset,apmatch,ssidset,ssidbroad,ssidmatch);
2096
2097 if ( /* if the user set the AP check if match.
2098 * if the network does not broadcast essid we check the user supplyed ANY essid
2099 * if the network does broadcast and the user does not set essid it is OK
2100 * if the network does broadcast and the user did set essid chech if essid match
2101 */
2102 ( apset && apmatch &&
2103 ((ssidset && ssidbroad && ssidmatch) || (ssidbroad && !ssidset) || (!ssidbroad && ssidset)) ) ||
2104 /* if the ap is not set, check that the user set the bssid
2105 * and the network does bradcast and that those two bssid matches
2106 */
2107 (!apset && ssidset && ssidbroad && ssidmatch)
2108 ){
2109
2110
2111 /* if the essid is hidden replace it with the
2112 * essid provided by the user.
2113 */
2114 if (!ssidbroad){
2115 strncpy(tmp_ssid, ieee->current_network.ssid, IW_ESSID_MAX_SIZE);
2116 tmp_ssid_len = ieee->current_network.ssid_len;
2117 }
2118 memcpy(&ieee->current_network, net, sizeof(struct ieee80211_network));
2119
2120 if (!ssidbroad){
2121 strncpy(ieee->current_network.ssid, tmp_ssid, IW_ESSID_MAX_SIZE);
2122 ieee->current_network.ssid_len = tmp_ssid_len;
2123 }
2124 printk(KERN_INFO"Linking with %s: channel is %d\n",ieee->current_network.ssid,ieee->current_network.channel);
2125
2126 if (ieee->iw_mode == IW_MODE_INFRA){
2127 ieee->state = IEEE80211_ASSOCIATING;
2128 ieee->beinretry = false;
2129 queue_work(ieee->wq, &ieee->associate_procedure_wq);
2130 }else{
2131 if(ieee80211_is_54g(ieee->current_network) &&
2132 (ieee->modulation & IEEE80211_OFDM_MODULATION)){
2133 ieee->rate = 540;
2134 printk(KERN_INFO"Using G rates\n");
2135 }else{
2136 ieee->rate = 110;
2137 printk(KERN_INFO"Using B rates\n");
2138 }
2139 ieee->state = IEEE80211_LINKED;
2140 ieee->beinretry = false;
2141 }
2142
2143 }
2144 }
2145
2146}
2147
2148void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee)
2149{
2150 unsigned long flags;
2151 struct ieee80211_network *target;
2152
2153 spin_lock_irqsave(&ieee->lock, flags);
2154 list_for_each_entry(target, &ieee->network_list, list) {
2155
2156 /* if the state become different that NOLINK means
2157 * we had found what we are searching for
2158 */
2159
2160 if (ieee->state != IEEE80211_NOLINK)
2161 break;
2162
2163 if (ieee->scan_age == 0 || time_after(target->last_scanned + ieee->scan_age, jiffies))
2164 ieee80211_softmac_new_net(ieee, target);
2165 }
2166
2167 spin_unlock_irqrestore(&ieee->lock, flags);
2168
2169}
2170
2171
2172static inline u16 auth_parse(struct sk_buff *skb, u8** challenge, int *chlen)
2173{
2174 struct ieee80211_authentication *a;
2175 u8 *t;
2176 if (skb->len < (sizeof(struct ieee80211_authentication)-sizeof(struct ieee80211_info_element))){
2177 IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n",skb->len);
2178 return 0xcafe;
2179 }
2180 *challenge = NULL;
2181 a = (struct ieee80211_authentication*) skb->data;
2182 if(skb->len > (sizeof(struct ieee80211_authentication) +3)){
2183 t = skb->data + sizeof(struct ieee80211_authentication);
2184
2185 if(*(t++) == MFIE_TYPE_CHALLENGE){
2186 *chlen = *(t++);
2187 *challenge = (u8*)kmalloc(*chlen, GFP_ATOMIC);
2188 memcpy(*challenge, t, *chlen);
2189 }
2190 }
2191
2192 return cpu_to_le16(a->status);
2193
2194}
2195
2196
2197int auth_rq_parse(struct sk_buff *skb,u8* dest)
2198{
2199 struct ieee80211_authentication *a;
2200
2201 if (skb->len < (sizeof(struct ieee80211_authentication)-sizeof(struct ieee80211_info_element))){
2202 IEEE80211_DEBUG_MGMT("invalid len in auth request: %d\n",skb->len);
2203 return -1;
2204 }
2205 a = (struct ieee80211_authentication*) skb->data;
2206
2207 memcpy(dest,a->header.addr2, ETH_ALEN);
2208
2209 if (le16_to_cpu(a->algorithm) != WLAN_AUTH_OPEN)
2210 return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
2211
2212 return WLAN_STATUS_SUCCESS;
2213}
2214
2215static short probe_rq_parse(struct ieee80211_device *ieee, struct sk_buff *skb, u8 *src)
2216{
2217 u8 *tag;
2218 u8 *skbend;
2219 u8 *ssid=NULL;
2220 u8 ssidlen = 0;
2221
2222 struct ieee80211_hdr_3addr *header =
2223 (struct ieee80211_hdr_3addr *) skb->data;
2224
2225 if (skb->len < sizeof (struct ieee80211_hdr_3addr ))
2226 return -1; /* corrupted */
2227
2228 memcpy(src,header->addr2, ETH_ALEN);
2229
2230 skbend = (u8*)skb->data + skb->len;
2231
2232 tag = skb->data + sizeof (struct ieee80211_hdr_3addr );
2233
2234 while (tag+1 < skbend){
2235 if (*tag == 0){
2236 ssid = tag+2;
2237 ssidlen = *(tag+1);
2238 break;
2239 }
2240 tag++; /* point to the len field */
2241 tag = tag + *(tag); /* point to the last data byte of the tag */
2242 tag++; /* point to the next tag */
2243 }
2244
2245 //IEEE80211DMESG("Card MAC address is "MACSTR, MAC2STR(src));
2246 if (ssidlen == 0) return 1;
2247
2248 if (!ssid) return 1; /* ssid not found in tagged param */
2249 return (!strncmp(ssid, ieee->current_network.ssid, ssidlen));
2250
2251}
2252
2253int assoc_rq_parse(struct sk_buff *skb,u8* dest)
2254{
2255 struct ieee80211_assoc_request_frame *a;
2256
2257 if (skb->len < (sizeof(struct ieee80211_assoc_request_frame) -
2258 sizeof(struct ieee80211_info_element))) {
2259
2260 IEEE80211_DEBUG_MGMT("invalid len in auth request:%d \n", skb->len);
2261 return -1;
2262 }
2263
2264 a = (struct ieee80211_assoc_request_frame*) skb->data;
2265
2266 memcpy(dest,a->header.addr2,ETH_ALEN);
2267
2268 return 0;
2269}
2270
2271static inline u16 assoc_parse(struct sk_buff *skb, int *aid)
2272{
2273 struct ieee80211_assoc_response_frame *a;
2274 if (skb->len < sizeof(struct ieee80211_assoc_response_frame)){
2275 IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len);
2276 return 0xcafe;
2277 }
2278
2279 a = (struct ieee80211_assoc_response_frame*) skb->data;
2280 *aid = le16_to_cpu(a->aid) & 0x3fff;
2281 return le16_to_cpu(a->status);
2282}
2283
2284static inline void
2285ieee80211_rx_probe_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
2286{
2287 u8 dest[ETH_ALEN];
2288
2289 //IEEE80211DMESG("Rx probe");
2290 ieee->softmac_stats.rx_probe_rq++;
2291 //DMESG("Dest is "MACSTR, MAC2STR(dest));
2292 if (probe_rq_parse(ieee, skb, dest)){
2293 //IEEE80211DMESG("Was for me!");
2294 ieee->softmac_stats.tx_probe_rs++;
2295 ieee80211_resp_to_probe(ieee, dest);
2296 }
2297}
2298
2299inline void
2300ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
2301{
2302 u8 dest[ETH_ALEN];
2303 int status;
2304 //IEEE80211DMESG("Rx probe");
2305 ieee->softmac_stats.rx_auth_rq++;
2306
2307 if ((status = auth_rq_parse(skb, dest))!= -1){
2308 ieee80211_resp_to_auth(ieee, status, dest);
2309 }
2310 //DMESG("Dest is "MACSTR, MAC2STR(dest));
2311
2312}
2313
2314 inline void
2315ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
2316{
2317
2318 u8 dest[ETH_ALEN];
2319 //unsigned long flags;
2320
2321 ieee->softmac_stats.rx_ass_rq++;
2322 if (assoc_rq_parse(skb,dest) != -1){
2323 ieee80211_resp_to_assoc_rq(ieee, dest);
2324 }
2325
2326 printk(KERN_INFO"New client associated: "MAC_FMT"\n", MAC_ARG(dest));
2327 //FIXME
2328 #if 0
2329 spin_lock_irqsave(&ieee->lock,flags);
2330 add_associate(ieee,dest);
2331 spin_unlock_irqrestore(&ieee->lock,flags);
2332 #endif
2333}
2334
2335
2336
2337void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr)
2338{
2339
2340 struct sk_buff *buf = ieee80211_null_func(ieee, pwr);
2341
2342 if (buf)
2343 softmac_ps_mgmt_xmit(buf, ieee);
2344
2345}
2346
2347
2348short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, u32 *time_l)
2349{
2350#if 0
2351 int timeout = ieee->ps_timeout;
2352#else
2353 int timeout = 0;
2354#endif
2355 u8 dtim;
2356 /*if(ieee->ps == IEEE80211_PS_DISABLED ||
2357 ieee->iw_mode != IW_MODE_INFRA ||
2358 ieee->state != IEEE80211_LINKED)
2359
2360 return 0;
2361 */
2362 dtim = ieee->current_network.dtim_data;
2363 //printk("DTIM\n");
2364
2365 if(!(dtim & IEEE80211_DTIM_VALID))
2366 return 0;
2367 else
2368 timeout = ieee->current_network.beacon_interval;
2369
2370 //printk("VALID\n");
2371 ieee->current_network.dtim_data = IEEE80211_DTIM_INVALID;
2372
2373 if(dtim & ((IEEE80211_DTIM_UCAST | IEEE80211_DTIM_MBCAST)& ieee->ps))
2374 return 2;
2375
2376 if(!time_after(jiffies, ieee->dev->trans_start + MSECS(timeout)))
2377 return 0;
2378
2379 if(!time_after(jiffies, ieee->last_rx_ps_time + MSECS(timeout)))
2380 return 0;
2381
2382 if((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE ) &&
2383 (ieee->mgmt_queue_tail != ieee->mgmt_queue_head))
2384 return 0;
2385#if 0
2386 if(time_l){
2387 *time_l = ieee->current_network.last_dtim_sta_time[0]
2388 + (ieee->current_network.beacon_interval
2389 * ieee->current_network.dtim_period) * 1000;
2390 }
2391#else
2392 if(time_l){
2393 *time_l = ieee->current_network.last_dtim_sta_time[0]
2394 + MSECS((ieee->current_network.beacon_interval));
2395 //* ieee->current_network.dtim_period));
2396 //printk("beacon_interval:%x, dtim_period:%x, totol to Msecs:%x, HZ:%x\n", ieee->current_network.beacon_interval, ieee->current_network.dtim_period, MSECS(((ieee->current_network.beacon_interval * ieee->current_network.dtim_period))), HZ);
2397 }
2398
2399#endif
2400 if(time_h){
2401 *time_h = ieee->current_network.last_dtim_sta_time[1];
2402 if(time_l && *time_l < ieee->current_network.last_dtim_sta_time[0])
2403 *time_h += 1;
2404 }
2405
2406 return 1;
2407
2408
2409}
2410
2411inline void ieee80211_sta_ps(struct ieee80211_device *ieee)
2412{
2413
2414 u32 th,tl;
2415 short sleep;
2416
2417 unsigned long flags,flags2;
2418
2419 spin_lock_irqsave(&ieee->lock, flags);
2420
2421 if((ieee->ps == IEEE80211_PS_DISABLED ||
2422
2423 ieee->iw_mode != IW_MODE_INFRA ||
2424 ieee->state != IEEE80211_LINKED)){
2425
2426 //#warning CHECK_LOCK_HERE
2427 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
2428
2429 ieee80211_sta_wakeup(ieee, 1);
2430
2431 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
2432 }
2433
2434 sleep = ieee80211_sta_ps_sleep(ieee,&th, &tl);
2435// printk("===>%s,%d[2 wake, 1 sleep, 0 do nothing], ieee->sta_sleep = %d\n",__FUNCTION__, sleep,ieee->sta_sleep);
2436 /* 2 wake, 1 sleep, 0 do nothing */
2437 if(sleep == 0)
2438 goto out;
2439
2440 if(sleep == 1){
2441
2442 if(ieee->sta_sleep == 1)
2443 ieee->enter_sleep_state(ieee->dev,th,tl);
2444
2445 else if(ieee->sta_sleep == 0){
2446 // printk("send null 1\n");
2447 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
2448
2449 if(ieee->ps_is_queue_empty(ieee->dev)){
2450
2451
2452 ieee->sta_sleep = 2;
2453
2454 ieee->ps_request_tx_ack(ieee->dev);
2455
2456 ieee80211_sta_ps_send_null_frame(ieee,1);
2457
2458 ieee->ps_th = th;
2459 ieee->ps_tl = tl;
2460 }
2461 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
2462
2463 }
2464
2465
2466 }else if(sleep == 2){
2467//#warning CHECK_LOCK_HERE
2468 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
2469
2470 // printk("send wakeup packet\n");
2471 ieee80211_sta_wakeup(ieee,1);
2472
2473 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
2474 }
2475
2476out:
2477 spin_unlock_irqrestore(&ieee->lock, flags);
2478
2479}
2480
2481void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl)
2482{
2483 if(ieee->sta_sleep == 0){
2484 if(nl){
2485 // printk("Warning: driver is probably failing to report TX ps error\n");
2486 ieee->ps_request_tx_ack(ieee->dev);
2487 ieee80211_sta_ps_send_null_frame(ieee, 0);
2488 }
2489 return;
2490
2491 }
2492
2493 if(ieee->sta_sleep == 1)
2494 ieee->sta_wake_up(ieee->dev);
2495
2496 ieee->sta_sleep = 0;
2497
2498 if(nl){
2499 ieee->ps_request_tx_ack(ieee->dev);
2500 ieee80211_sta_ps_send_null_frame(ieee, 0);
2501 }
2502}
2503
2504void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success)
2505{
2506 unsigned long flags,flags2;
2507
2508 spin_lock_irqsave(&ieee->lock, flags);
2509 if(ieee->sta_sleep == 2){
2510 /* Null frame with PS bit set */
2511 if(success){
2512
2513 // printk("==================> %s::enter sleep state\n",__FUNCTION__);
2514 ieee->sta_sleep = 1;
2515 ieee->enter_sleep_state(ieee->dev,ieee->ps_th,ieee->ps_tl);
2516 }
2517 /* if the card report not success we can't be sure the AP
2518 * has not RXed so we can't assume the AP believe us awake
2519 */
2520 }
2521 /* 21112005 - tx again null without PS bit if lost */
2522 else {
2523
2524 if((ieee->sta_sleep == 0) && !success){
2525 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
2526 ieee80211_sta_ps_send_null_frame(ieee, 0);
2527 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
2528 }
2529 }
2530 spin_unlock_irqrestore(&ieee->lock, flags);
2531}
2532
2533inline int
2534ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
2535 struct ieee80211_rx_stats *rx_stats, u16 type,
2536 u16 stype)
2537{
2538 struct ieee80211_hdr_3addr *header = (struct ieee80211_hdr_3addr *) skb->data;
2539 u16 errcode;
2540 u8* challenge=NULL;
2541 int chlen=0;
2542 int aid=0;
2543 struct ieee80211_assoc_response_frame *assoc_resp;
2544 struct ieee80211_info_element *info_element;
2545
2546 if(!ieee->proto_started)
2547 return 0;
2548
2549 if(ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED &&
2550 ieee->iw_mode == IW_MODE_INFRA &&
2551 ieee->state == IEEE80211_LINKED))
2552
2553 tasklet_schedule(&ieee->ps_task);
2554
2555 if(WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_PROBE_RESP &&
2556 WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_BEACON)
2557 ieee->last_rx_ps_time = jiffies;
2558
2559 switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
2560
2561 case IEEE80211_STYPE_ASSOC_RESP:
2562 case IEEE80211_STYPE_REASSOC_RESP:
2563
2564 IEEE80211_DEBUG_MGMT("received [RE]ASSOCIATION RESPONSE (%d)\n",
2565 WLAN_FC_GET_STYPE(header->frame_ctl));
2566 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2567 ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATED &&
2568 ieee->iw_mode == IW_MODE_INFRA){
2569 if (0 == (errcode=assoc_parse(skb, &aid))){
2570 u16 left;
2571
2572 ieee->state=IEEE80211_LINKED;
2573 ieee->assoc_id = aid;
2574 ieee->softmac_stats.rx_ass_ok++;
2575
2576 //printk(KERN_WARNING "nic_type = %s", (rx_stats->nic_type == 1)?"rtl8187":"rtl8187B");
2577 if(1 == rx_stats->nic_type) //card type is 8187
2578 {
2579 goto associate_complete;
2580 }
2581 assoc_resp = (struct ieee80211_assoc_response_frame*)skb->data;
2582 info_element = &assoc_resp->info_element;
2583 left = skb->len - ((void*)info_element - (void*)assoc_resp);
2584
2585 while (left >= sizeof(struct ieee80211_info_element_hdr)) {
2586 if (sizeof(struct ieee80211_info_element_hdr) + info_element->len > left) {
2587 printk(KERN_WARNING "[re]associate reeponse error!");
2588 return 1;
2589 }
2590 switch (info_element->id) {
2591 case MFIE_TYPE_GENERIC:
2592 IEEE80211_DEBUG_SCAN("MFIE_TYPE_GENERIC: %d bytes\n", info_element->len);
2593 if (info_element->len >= 8 &&
2594 info_element->data[0] == 0x00 &&
2595 info_element->data[1] == 0x50 &&
2596 info_element->data[2] == 0xf2 &&
2597 info_element->data[3] == 0x02 &&
2598 info_element->data[4] == 0x01) {
2599 // Not care about version at present.
2600 //WMM Parameter Element
2601 memcpy(ieee->current_network.wmm_param,(u8*)(info_element->data\
2602 + 8),(info_element->len - 8));
2603
2604 if (((ieee->current_network.wmm_info^info_element->data[6])& \
2605 0x0f)||(!ieee->init_wmmparam_flag)) {
2606 //refresh paramete element for current network
2607 // update the register parameter for hardware
2608 ieee->init_wmmparam_flag = 1;
2609 queue_work(ieee->wq, &ieee->wmm_param_update_wq);
2610
2611 }
2612 //update info_element for current network
2613 ieee->current_network.wmm_info = info_element->data[6];
2614 }
2615 break;
2616 default:
2617 //nothing to do at present!!!
2618 break;
2619 }
2620
2621 left -= sizeof(struct ieee80211_info_element_hdr) +
2622 info_element->len;
2623 info_element = (struct ieee80211_info_element *)
2624 &info_element->data[info_element->len];
2625 }
2626 if(!ieee->init_wmmparam_flag) //legacy AP, reset the AC_xx_param register
2627 {
2628 queue_work(ieee->wq,&ieee->wmm_param_update_wq);
2629 ieee->init_wmmparam_flag = 1;//indicate AC_xx_param upated since last associate
2630 }
2631associate_complete:
2632 ieee80211_associate_complete(ieee);
2633 }else{
2634 ieee->softmac_stats.rx_ass_err++;
2635 IEEE80211_DEBUG_MGMT(
2636 "Association response status code 0x%x\n",
2637 errcode);
2638 ieee80211_associate_abort(ieee);
2639 }
2640 }
2641#ifdef _RTL8187_EXT_PATCH_
2642 else if ((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_frame_softmac_on_assoc_rsp)
2643 {
2644 ieee->ext_patch_ieee80211_rx_frame_softmac_on_assoc_rsp(ieee, skb);
2645 }
2646#endif
2647 break;
2648
2649 case IEEE80211_STYPE_ASSOC_REQ:
2650 case IEEE80211_STYPE_REASSOC_REQ:
2651
2652 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2653 ieee->iw_mode == IW_MODE_MASTER)
2654
2655 ieee80211_rx_assoc_rq(ieee, skb);
2656#ifdef _RTL8187_EXT_PATCH_
2657 else if ((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_frame_softmac_on_assoc_req)
2658 {
2659 ieee->ext_patch_ieee80211_rx_frame_softmac_on_assoc_req(ieee, skb);
2660 }
2661#endif
2662 break;
2663
2664 case IEEE80211_STYPE_AUTH:
2665
2666#ifdef _RTL8187_EXT_PATCH_
2667printk("IEEE80211_STYPE_AUTH\n");
2668 if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_frame_softmac_on_auth)
2669 if( ieee->ext_patch_ieee80211_rx_frame_softmac_on_auth(ieee, skb, rx_stats) );
2670#endif
2671 if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE){
2672 if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING &&
2673 ieee->iw_mode == IW_MODE_INFRA){
2674
2675 IEEE80211_DEBUG_MGMT("Received authentication response");
2676
2677 if (0 == (errcode=auth_parse(skb, &challenge, &chlen))){
2678 if(ieee->open_wep || !challenge){
2679 ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATED;
2680 ieee->softmac_stats.rx_auth_rs_ok++;
2681
2682 ieee80211_associate_step2(ieee);
2683 }else{
2684 ieee80211_auth_challenge(ieee, challenge, chlen);
2685 }
2686 }else{
2687 ieee->softmac_stats.rx_auth_rs_err++;
2688 IEEE80211_DEBUG_MGMT("Authentication respose status code 0x%x",errcode);
2689 ieee80211_associate_abort(ieee);
2690 }
2691
2692 }else if (ieee->iw_mode == IW_MODE_MASTER){
2693 ieee80211_rx_auth_rq(ieee, skb);
2694 }
2695 }
2696 break;
2697
2698 case IEEE80211_STYPE_PROBE_REQ:
2699
2700 if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) &&
2701 ((ieee->iw_mode == IW_MODE_ADHOC ||
2702 ieee->iw_mode == IW_MODE_MASTER) &&
2703 ieee->state == IEEE80211_LINKED))
2704
2705 ieee80211_rx_probe_rq(ieee, skb);
2706 break;
2707
2708 case IEEE80211_STYPE_DISASSOC:
2709 case IEEE80211_STYPE_DEAUTH:
2710#ifdef _RTL8187_EXT_PATCH_
2711printk("IEEE80211_STYPE_DEAUTH\n");
2712 if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_frame_softmac_on_deauth)
2713 if( ieee->ext_patch_ieee80211_rx_frame_softmac_on_deauth(ieee, skb, rx_stats) ) ;
2714#endif
2715 /* FIXME for now repeat all the association procedure
2716 * both for disassociation and deauthentication
2717 */
2718 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2719 (ieee->state == IEEE80211_LINKED) &&
2720 (ieee->iw_mode == IW_MODE_INFRA) &&
2721 (!memcmp(header->addr2,ieee->current_network.bssid,ETH_ALEN))){
2722 ieee->state = IEEE80211_ASSOCIATING;
2723 ieee->softmac_stats.reassoc++;
2724
2725 //notify_wx_assoc_event(ieee); //YJ,del,080828, do not notify os here
2726 queue_work(ieee->wq, &ieee->associate_procedure_wq);
2727 }
2728
2729 break;
2730
2731 default:
2732 return -1;
2733 break;
2734 }
2735
2736 //dev_kfree_skb_any(skb);
2737 return 0;
2738}
2739
2740
2741
2742/* following are for a simplier TX queue management.
2743 * Instead of using netif_[stop/wake]_queue the driver
2744 * will uses these two function (plus a reset one), that
2745 * will internally uses the kernel netif_* and takes
2746 * care of the ieee802.11 fragmentation.
2747 * So the driver receives a fragment per time and might
2748 * call the stop function when it want without take care
2749 * to have enought room to TX an entire packet.
2750 * This might be useful if each fragment need it's own
2751 * descriptor, thus just keep a total free memory > than
2752 * the max fragmentation treshold is not enought.. If the
2753 * ieee802.11 stack passed a TXB struct then you needed
2754 * to keep N free descriptors where
2755 * N = MAX_PACKET_SIZE / MIN_FRAG_TRESHOLD
2756 * In this way you need just one and the 802.11 stack
2757 * will take care of buffering fragments and pass them to
2758 * to the driver later, when it wakes the queue.
2759 */
2760
2761void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee)
2762{
2763
2764
2765 unsigned long flags;
2766 int i;
2767#ifdef _RTL8187_EXT_PATCH_
2768 int rate = ieee->rate;
2769#endif
2770
2771 spin_lock_irqsave(&ieee->lock,flags);
2772 #if 0
2773 if(ieee->queue_stop){
2774 IEEE80211DMESG("EE: IEEE hard_start_xmit invoked when kernel queue should be stopped");
2775 netif_stop_queue(ieee->dev);
2776 ieee->ieee_stats.swtxstop++;
2777 //dev_kfree_skb_any(skb);
2778 err = 1;
2779 goto exit;
2780 }
2781
2782 ieee->stats.tx_bytes+=skb->len;
2783
2784
2785 txb=ieee80211_skb_to_txb(ieee,skb);
2786
2787
2788 if(txb==NULL){
2789 IEEE80211DMESG("WW: IEEE stack failed to provide txb");
2790 //dev_kfree_skb_any(skb);
2791 err = 1;
2792 goto exit;
2793 }
2794 #endif
2795
2796#ifdef _RTL8187_EXT_PATCH_
2797 if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_softmac_xmit_get_rate && txb->nr_frags)
2798 {
2799 rate = ieee->ext_patch_ieee80211_softmac_xmit_get_rate(ieee, txb->fragments[0]);
2800 }
2801#endif
2802 /* called with 2nd parm 0, no tx mgmt lock required */
2803 ieee80211_sta_wakeup(ieee,0);
2804
2805 for(i = 0; i < txb->nr_frags; i++) {
2806
2807 if (ieee->queue_stop){
2808 ieee->tx_pending.txb = txb;
2809 ieee->tx_pending.frag = i;
2810 goto exit;
2811 }else{
2812 ieee->softmac_data_hard_start_xmit(
2813 txb->fragments[i],
2814#ifdef _RTL8187_EXT_PATCH_
2815 ieee->dev, rate);
2816#else
2817 ieee->dev,ieee->rate);
2818#endif
2819 //(i+1)<txb->nr_frags);
2820 ieee->stats.tx_packets++;
2821 ieee->stats.tx_bytes += txb->fragments[i]->len;
2822 ieee->dev->trans_start = jiffies;
2823 }
2824 }
2825
2826 ieee80211_txb_free(txb);
2827
2828 exit:
2829 spin_unlock_irqrestore(&ieee->lock,flags);
2830
2831}
2832
2833/* called with ieee->lock acquired */
2834void ieee80211_resume_tx(struct ieee80211_device *ieee)
2835{
2836 int i;
2837 for(i = ieee->tx_pending.frag; i < ieee->tx_pending.txb->nr_frags; i++) {
2838
2839 if (ieee->queue_stop){
2840 ieee->tx_pending.frag = i;
2841 return;
2842 }else{
2843
2844 ieee->softmac_data_hard_start_xmit(
2845 ieee->tx_pending.txb->fragments[i],
2846 ieee->dev,ieee->rate);
2847 //(i+1)<ieee->tx_pending.txb->nr_frags);
2848 ieee->stats.tx_packets++;
2849 ieee->dev->trans_start = jiffies;
2850 }
2851 }
2852
2853
2854 ieee80211_txb_free(ieee->tx_pending.txb);
2855 ieee->tx_pending.txb = NULL;
2856}
2857
2858
2859void ieee80211_reset_queue(struct ieee80211_device *ieee)
2860{
2861 unsigned long flags;
2862
2863 spin_lock_irqsave(&ieee->lock,flags);
2864 init_mgmt_queue(ieee);
2865 if (ieee->tx_pending.txb){
2866 ieee80211_txb_free(ieee->tx_pending.txb);
2867 ieee->tx_pending.txb = NULL;
2868 }
2869 ieee->queue_stop = 0;
2870 spin_unlock_irqrestore(&ieee->lock,flags);
2871
2872}
2873
2874void ieee80211_wake_queue(struct ieee80211_device *ieee)
2875{
2876
2877 unsigned long flags;
2878 struct sk_buff *skb;
2879 struct ieee80211_hdr_3addr *header;
2880
2881 spin_lock_irqsave(&ieee->lock,flags);
2882 if (! ieee->queue_stop) goto exit;
2883
2884 ieee->queue_stop = 0;
2885
2886 if(ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE){
2887 while (!ieee->queue_stop && (skb = dequeue_mgmt(ieee))){
2888
2889 header = (struct ieee80211_hdr_3addr *) skb->data;
2890
2891 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
2892
2893 if (ieee->seq_ctrl[0] == 0xFFF)
2894 ieee->seq_ctrl[0] = 0;
2895 else
2896 ieee->seq_ctrl[0]++;
2897
2898 //printk(KERN_ALERT "ieee80211_wake_queue \n");
2899 ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
2900 dev_kfree_skb_any(skb);//edit by thomas
2901 }
2902 }
2903 if (!ieee->queue_stop && ieee->tx_pending.txb)
2904 ieee80211_resume_tx(ieee);
2905
2906 if (!ieee->queue_stop && netif_queue_stopped(ieee->dev)){
2907 ieee->softmac_stats.swtxawake++;
2908 netif_wake_queue(ieee->dev);
2909 }
2910
2911exit :
2912 spin_unlock_irqrestore(&ieee->lock,flags);
2913}
2914
2915
2916void ieee80211_stop_queue(struct ieee80211_device *ieee)
2917{
2918 //unsigned long flags;
2919 //spin_lock_irqsave(&ieee->lock,flags);
2920
2921 if (! netif_queue_stopped(ieee->dev)){
2922 netif_stop_queue(ieee->dev);
2923 ieee->softmac_stats.swtxstop++;
2924 }
2925 ieee->queue_stop = 1;
2926 //spin_unlock_irqrestore(&ieee->lock,flags);
2927
2928}
2929
2930
2931inline void ieee80211_randomize_cell(struct ieee80211_device *ieee)
2932{
2933
2934 get_random_bytes(ieee->current_network.bssid, ETH_ALEN);
2935
2936 /* an IBSS cell address must have the two less significant
2937 * bits of the first byte = 2
2938 */
2939 ieee->current_network.bssid[0] &= ~0x01;
2940 ieee->current_network.bssid[0] |= 0x02;
2941}
2942
2943/* called in user context only */
2944void ieee80211_start_master_bss(struct ieee80211_device *ieee)
2945{
2946 ieee->assoc_id = 1;
2947
2948 if (ieee->current_network.ssid_len == 0){
2949 strncpy(ieee->current_network.ssid,
2950 IEEE80211_DEFAULT_TX_ESSID,
2951 IW_ESSID_MAX_SIZE);
2952
2953 ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
2954 ieee->ssid_set = 1;
2955 }
2956
2957 memcpy(ieee->current_network.bssid, ieee->dev->dev_addr, ETH_ALEN);
2958
2959 ieee->set_chan(ieee->dev, ieee->current_network.channel);
2960 ieee->state = IEEE80211_LINKED;
2961 ieee->link_change(ieee->dev);
2962 notify_wx_assoc_event(ieee);
2963
2964 if (ieee->data_hard_resume)
2965 ieee->data_hard_resume(ieee->dev);
2966
2967 netif_carrier_on(ieee->dev);
2968}
2969
2970void ieee80211_start_monitor_mode(struct ieee80211_device *ieee)
2971{
2972 if(ieee->raw_tx){
2973
2974 if (ieee->data_hard_resume)
2975 ieee->data_hard_resume(ieee->dev);
2976
2977 netif_carrier_on(ieee->dev);
2978 }
2979}
2980#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
2981void ieee80211_start_ibss_wq(struct work_struct *work)
2982{
2983 struct delayed_work *dwork = container_of(work, struct delayed_work, work);
2984 struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, start_ibss_wq);
2985#else
2986void ieee80211_start_ibss_wq(struct ieee80211_device *ieee)
2987{
2988#endif
2989
2990 /* iwconfig mode ad-hoc will schedule this and return
2991 * on the other hand this will block further iwconfig SET
2992 * operations because of the wx_sem hold.
2993 * Anyway some most set operations set a flag to speed-up
2994 * (abort) this wq (when syncro scanning) before sleeping
2995 * on the semaphore
2996 */
2997
2998 down(&ieee->wx_sem);
2999
3000
3001 if (ieee->current_network.ssid_len == 0){
3002 strcpy(ieee->current_network.ssid,IEEE80211_DEFAULT_TX_ESSID);
3003 ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
3004 ieee->ssid_set = 1;
3005 }
3006
3007 /* check if we have this cell in our network list */
3008 ieee80211_softmac_check_all_nets(ieee);
3009
3010#ifdef ENABLE_DOT11D
3011 if(ieee->state == IEEE80211_NOLINK)
3012 ieee->current_network.channel = 10;
3013#endif
3014 /* if not then the state is not linked. Maybe the user swithced to
3015 * ad-hoc mode just after being in monitor mode, or just after
3016 * being very few time in managed mode (so the card have had no
3017 * time to scan all the chans..) or we have just run up the iface
3018 * after setting ad-hoc mode. So we have to give another try..
3019 * Here, in ibss mode, should be safe to do this without extra care
3020 * (in bss mode we had to make sure no-one tryed to associate when
3021 * we had just checked the ieee->state and we was going to start the
3022 * scan) beacause in ibss mode the ieee80211_new_net function, when
3023 * finds a good net, just set the ieee->state to IEEE80211_LINKED,
3024 * so, at worst, we waste a bit of time to initiate an unneeded syncro
3025 * scan, that will stop at the first round because it sees the state
3026 * associated.
3027 */
3028 if (ieee->state == IEEE80211_NOLINK)
3029 ieee80211_start_scan_syncro(ieee);
3030
3031 /* the network definitively is not here.. create a new cell */
3032 if (ieee->state == IEEE80211_NOLINK){
3033 printk("creating new IBSS cell\n");
3034 if(!ieee->wap_set)
3035 ieee80211_randomize_cell(ieee);
3036
3037 if(ieee->modulation & IEEE80211_CCK_MODULATION){
3038
3039 ieee->current_network.rates_len = 4;
3040
3041 ieee->current_network.rates[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
3042 ieee->current_network.rates[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
3043 ieee->current_network.rates[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
3044 ieee->current_network.rates[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
3045
3046 }else
3047 ieee->current_network.rates_len = 0;
3048
3049 if(ieee->modulation & IEEE80211_OFDM_MODULATION){
3050 ieee->current_network.rates_ex_len = 8;
3051
3052 ieee->current_network.rates_ex[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
3053 ieee->current_network.rates_ex[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
3054 ieee->current_network.rates_ex[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
3055 ieee->current_network.rates_ex[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
3056 ieee->current_network.rates_ex[4] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
3057 ieee->current_network.rates_ex[5] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
3058 ieee->current_network.rates_ex[6] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
3059 ieee->current_network.rates_ex[7] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
3060
3061 ieee->rate = 540;
3062 }else{
3063 ieee->current_network.rates_ex_len = 0;
3064 ieee->rate = 110;
3065 }
3066
3067 // By default, WMM function will be disabled in IBSS mode
3068 ieee->current_network.QoS_Enable = 0;
3069
3070 ieee->current_network.atim_window = 0;
3071 ieee->current_network.capability = WLAN_CAPABILITY_IBSS;
3072 if(ieee->short_slot)
3073 ieee->current_network.capability |= WLAN_CAPABILITY_SHORT_SLOT;
3074
3075 }
3076
3077 ieee->state = IEEE80211_LINKED;
3078 ieee->set_chan(ieee->dev, ieee->current_network.channel);
3079 ieee->link_change(ieee->dev);
3080
3081 notify_wx_assoc_event(ieee);
3082
3083 ieee80211_start_send_beacons(ieee);
3084 printk(KERN_WARNING "after sending beacon packet!\n");
3085
3086 if (ieee->data_hard_resume)
3087 ieee->data_hard_resume(ieee->dev);
3088
3089 netif_carrier_on(ieee->dev);
3090
3091 up(&ieee->wx_sem);
3092}
3093inline void ieee80211_start_ibss(struct ieee80211_device *ieee)
3094{
3095 queue_delayed_work(ieee->wq, &ieee->start_ibss_wq, 100);
3096}
3097
3098/* this is called only in user context, with wx_sem held */
3099void ieee80211_start_bss(struct ieee80211_device *ieee)
3100{
3101 unsigned long flags;
3102#ifdef ENABLE_DOT11D
3103 //
3104 // Ref: 802.11d 11.1.3.3
3105 // STA shall not start a BSS unless properly formed Beacon frame including a Country IE.
3106 //
3107 if(IS_DOT11D_ENABLE(ieee) && !IS_COUNTRY_IE_VALID(ieee))
3108 {
3109 if(! ieee->bGlobalDomain)
3110 {
3111 return;
3112 }
3113 }
3114#endif
3115 /* check if we have already found the net we
3116 * are interested in (if any).
3117 * if not (we are disassociated and we are not
3118 * in associating / authenticating phase) start the background scanning.
3119 */
3120 ieee80211_softmac_check_all_nets(ieee);
3121
3122 /* ensure no-one start an associating process (thus setting
3123 * the ieee->state to ieee80211_ASSOCIATING) while we
3124 * have just cheked it and we are going to enable scan.
3125 * The ieee80211_new_net function is always called with
3126 * lock held (from both ieee80211_softmac_check_all_nets and
3127 * the rx path), so we cannot be in the middle of such function
3128 */
3129 spin_lock_irqsave(&ieee->lock, flags);
3130
3131//#ifdef ENABLE_IPS
3132// printk("start bss ENABLE_IPS\n");
3133//#else
3134 if (ieee->state == IEEE80211_NOLINK){
3135 ieee->actscanning = true;
3136 ieee80211_start_scan(ieee);
3137 }
3138//#endif
3139 spin_unlock_irqrestore(&ieee->lock, flags);
3140}
3141
3142/* called only in userspace context */
3143void ieee80211_disassociate(struct ieee80211_device *ieee)
3144{
3145 netif_carrier_off(ieee->dev);
3146
3147 if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)
3148 ieee80211_reset_queue(ieee);
3149
3150 if (ieee->data_hard_stop)
3151 ieee->data_hard_stop(ieee->dev);
3152
3153#ifdef ENABLE_DOT11D
3154 if(IS_DOT11D_ENABLE(ieee))
3155 Dot11d_Reset(ieee);
3156#endif
3157 ieee->state = IEEE80211_NOLINK;
3158 ieee->link_change(ieee->dev);
3159 notify_wx_assoc_event(ieee);
3160
3161}
3162#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
3163void ieee80211_associate_retry_wq(struct work_struct *work)
3164{
3165 struct delayed_work *dwork = container_of(work, struct delayed_work, work);
3166 struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, associate_retry_wq);
3167#else
3168void ieee80211_associate_retry_wq(struct ieee80211_device *ieee)
3169{
3170#endif
3171 unsigned long flags;
3172 down(&ieee->wx_sem);
3173 if(!ieee->proto_started)
3174 goto exit;
3175 if(ieee->state != IEEE80211_ASSOCIATING_RETRY)
3176 goto exit;
3177 /* until we do not set the state to IEEE80211_NOLINK
3178 * there are no possibility to have someone else trying
3179 * to start an association procdure (we get here with
3180 * ieee->state = IEEE80211_ASSOCIATING).
3181 * When we set the state to IEEE80211_NOLINK it is possible
3182 * that the RX path run an attempt to associate, but
3183 * both ieee80211_softmac_check_all_nets and the
3184 * RX path works with ieee->lock held so there are no
3185 * problems. If we are still disassociated then start a scan.
3186 * the lock here is necessary to ensure no one try to start
3187 * an association procedure when we have just checked the
3188 * state and we are going to start the scan.
3189 */
3190 ieee->state = IEEE80211_NOLINK;
3191 ieee->beinretry = true;
3192 ieee80211_softmac_check_all_nets(ieee);
3193
3194 spin_lock_irqsave(&ieee->lock, flags);
3195
3196 if(ieee->state == IEEE80211_NOLINK){
3197 ieee->beinretry = false;
3198 ieee->actscanning = true;
3199 ieee80211_start_scan(ieee);
3200 }
3201 //YJ,add,080828, notify os here
3202 if(ieee->state == IEEE80211_NOLINK)
3203 {
3204 notify_wx_assoc_event(ieee);
3205 }
3206 //YJ,add,080828,end
3207 spin_unlock_irqrestore(&ieee->lock, flags);
3208
3209exit:
3210 up(&ieee->wx_sem);
3211}
3212
3213struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee)
3214{
3215 u8 broadcast_addr[] = {0xff,0xff,0xff,0xff,0xff,0xff};
3216
3217 struct sk_buff *skb = NULL;
3218 struct ieee80211_probe_response *b;
3219
3220//rz
3221#ifdef _RTL8187_EXT_PATCH_
3222 if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_get_beacon_get_probersp )
3223 skb = ieee->ext_patch_get_beacon_get_probersp(ieee, broadcast_addr, &(ieee->current_network));
3224 else
3225 skb = ieee80211_probe_resp(ieee, broadcast_addr);
3226#else
3227 skb = ieee80211_probe_resp(ieee, broadcast_addr);
3228#endif
3229//
3230 if (!skb)
3231 return NULL;
3232
3233 b = (struct ieee80211_probe_response *) skb->data;
3234 b->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_BEACON);
3235
3236 return skb;
3237
3238}
3239
3240struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee)
3241{
3242 struct sk_buff *skb;
3243 struct ieee80211_probe_response *b;
3244
3245 skb = ieee80211_get_beacon_(ieee);
3246 if(!skb)
3247 return NULL;
3248
3249 b = (struct ieee80211_probe_response *) skb->data;
3250 b->header.seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
3251
3252 if (ieee->seq_ctrl[0] == 0xFFF)
3253 ieee->seq_ctrl[0] = 0;
3254 else
3255 ieee->seq_ctrl[0]++;
3256
3257 return skb;
3258}
3259
3260void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee)
3261{
3262 ieee->sync_scan_hurryup = 1;
3263 down(&ieee->wx_sem);
3264 ieee80211_stop_protocol(ieee);
3265 up(&ieee->wx_sem);
3266}
3267
3268
3269void ieee80211_stop_protocol(struct ieee80211_device *ieee)
3270{
3271 if (!ieee->proto_started)
3272 return;
3273
3274 ieee->proto_started = 0;
3275
3276#ifdef _RTL8187_EXT_PATCH_
3277 if(ieee->ext_patch_ieee80211_stop_protocol)
3278 ieee->ext_patch_ieee80211_stop_protocol(ieee);
3279//if call queue_delayed_work,can call this,or do nothing..
3280//edit by lawrence,20071118
3281#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
3282// cancel_delayed_work(&ieee->ext_stop_scan_wq);
3283// cancel_delayed_work(&ieee->ext_send_beacon_wq);
3284#endif
3285#endif // _RTL8187_EXT_PATCH_
3286
3287 ieee80211_stop_send_beacons(ieee);
3288 if((ieee->iw_mode == IW_MODE_INFRA)&&(ieee->state == IEEE80211_LINKED)) {
3289 SendDisassociation(ieee,NULL,WLAN_REASON_DISASSOC_STA_HAS_LEFT);
3290 }
3291 del_timer_sync(&ieee->associate_timer);
3292 cancel_delayed_work(&ieee->associate_retry_wq);
3293 cancel_delayed_work(&ieee->start_ibss_wq);
3294 ieee80211_stop_scan(ieee);
3295
3296 ieee80211_disassociate(ieee);
3297}
3298
3299void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee)
3300{
3301 ieee->sync_scan_hurryup = 0;
3302 down(&ieee->wx_sem);
3303 ieee80211_start_protocol(ieee);
3304 up(&ieee->wx_sem);
3305}
3306
3307void ieee80211_start_protocol(struct ieee80211_device *ieee)
3308{
3309 short ch = 0;
3310 int i = 0;
3311
3312 if (ieee->proto_started)
3313 return;
3314
3315 ieee->proto_started = 1;
3316
3317 if (ieee->current_network.channel == 0){
3318 do{
3319 ch++;
3320 if (ch > MAX_CHANNEL_NUMBER)
3321 return; /* no channel found */
3322
3323#ifdef ENABLE_DOT11D
3324 }while(!GET_DOT11D_INFO(ieee)->channel_map[ch]);
3325#else
3326 }while(!ieee->channel_map[ch]);
3327#endif
3328
3329 ieee->current_network.channel = ch;
3330 }
3331
3332 if (ieee->current_network.beacon_interval == 0)
3333 ieee->current_network.beacon_interval = 100;
3334 ieee->set_chan(ieee->dev,ieee->current_network.channel);
3335
3336 for(i = 0; i < 17; i++) {
3337 ieee->last_rxseq_num[i] = -1;
3338 ieee->last_rxfrag_num[i] = -1;
3339 ieee->last_packet_time[i] = 0;
3340 }
3341
3342 ieee->init_wmmparam_flag = 0;//reinitialize AC_xx_PARAM registers.
3343
3344
3345 /* if the user set the MAC of the ad-hoc cell and then
3346 * switch to managed mode, shall we make sure that association
3347 * attempts does not fail just because the user provide the essid
3348 * and the nic is still checking for the AP MAC ??
3349 */
3350 switch (ieee->iw_mode) {
3351 case IW_MODE_AUTO:
3352 ieee->iw_mode = IW_MODE_INFRA;
3353 //not set break here intentionly
3354 case IW_MODE_INFRA:
3355 ieee80211_start_bss(ieee);
3356 break;
3357
3358 case IW_MODE_ADHOC:
3359 ieee80211_start_ibss(ieee);
3360 break;
3361
3362 case IW_MODE_MASTER:
3363 ieee80211_start_master_bss(ieee);
3364 break;
3365
3366 case IW_MODE_MONITOR:
3367 ieee80211_start_monitor_mode(ieee);
3368 break;
3369
3370 default:
3371#ifdef _RTL8187_EXT_PATCH_
3372 if((ieee->iw_mode == ieee->iw_ext_mode) &&\
3373 ieee->ext_patch_ieee80211_start_protocol &&\
3374 ieee->ext_patch_ieee80211_start_protocol(ieee)) {
3375#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
3376 queue_work(ieee->wq, &ieee->ext_stop_scan_wq);
3377#endif
3378 // By default, WMM function will be disabled in
3379 // EXTENSION mode
3380 ieee->current_network.QoS_Enable = 0;
3381
3382 if(ieee->modulation & IEEE80211_CCK_MODULATION){
3383 ieee->current_network.rates_len = 4;
3384 ieee->current_network.rates[0] = \
3385 IEEE80211_BASIC_RATE_MASK | \
3386 IEEE80211_CCK_RATE_1MB;
3387 ieee->current_network.rates[1] = \
3388 IEEE80211_BASIC_RATE_MASK |\
3389 IEEE80211_CCK_RATE_2MB;
3390 ieee->current_network.rates[2] = \
3391 IEEE80211_BASIC_RATE_MASK |\
3392 IEEE80211_CCK_RATE_5MB;
3393 ieee->current_network.rates[3] = \
3394 IEEE80211_BASIC_RATE_MASK |\
3395 IEEE80211_CCK_RATE_11MB;
3396 }else
3397 ieee->current_network.rates_len = 0;
3398
3399 if(ieee->modulation & IEEE80211_OFDM_MODULATION){
3400 ieee->current_network.rates_ex_len = 8;
3401 ieee->current_network.rates_ex[0] = \
3402 IEEE80211_BASIC_RATE_MASK |\
3403 IEEE80211_OFDM_RATE_6MB;
3404 ieee->current_network.rates_ex[1] = \
3405 IEEE80211_BASIC_RATE_MASK |\
3406 IEEE80211_OFDM_RATE_9MB;
3407 ieee->current_network.rates_ex[2] = \
3408 IEEE80211_BASIC_RATE_MASK |\
3409 IEEE80211_OFDM_RATE_12MB;
3410 ieee->current_network.rates_ex[3] = \
3411 IEEE80211_BASIC_RATE_MASK | \
3412 IEEE80211_OFDM_RATE_18MB;
3413 ieee->current_network.rates_ex[4] =\
3414 IEEE80211_BASIC_RATE_MASK |\
3415 IEEE80211_OFDM_RATE_24MB;
3416 ieee->current_network.rates_ex[5] =\
3417 IEEE80211_BASIC_RATE_MASK |\
3418 IEEE80211_OFDM_RATE_36MB;
3419 ieee->current_network.rates_ex[6] = \
3420 IEEE80211_BASIC_RATE_MASK |\
3421 IEEE80211_OFDM_RATE_48MB;
3422 ieee->current_network.rates_ex[7] =\
3423 IEEE80211_BASIC_RATE_MASK |\
3424 IEEE80211_OFDM_RATE_54MB;
3425 ieee->rate = 540;
3426 }else{
3427 ieee->current_network.rates_ex_len = 0;
3428 ieee->rate = 110;
3429 }
3430
3431 /*
3432 spin_lock_irqsave(&ieee->lock, flags);
3433 if (ieee->state == IEEE80211_NOLINK)
3434 ieee80211_start_scan(ieee);
3435 // ieee->set_chan(ieee->dev, 8);
3436
3437 spin_unlock_irqrestore(&ieee->lock, flags);
3438 */
3439 memcpy(ieee->current_network.bssid, ieee->dev->dev_addr,\
3440 ETH_ALEN);
3441 ieee->link_change(ieee->dev);
3442 notify_wx_assoc_event(ieee);
3443
3444 if (ieee->data_hard_resume)
3445 ieee->data_hard_resume(ieee->dev);
3446
3447 netif_carrier_on(ieee->dev);
3448 } else {
3449 ieee->iw_mode = IW_MODE_INFRA;
3450 ieee80211_start_bss(ieee);
3451 }
3452#else
3453 ieee->iw_mode = IW_MODE_INFRA;
3454 ieee80211_start_bss(ieee);
3455
3456#endif
3457 break;
3458 }
3459}
3460
3461
3462#define DRV_NAME "Ieee80211"
3463void ieee80211_softmac_init(struct ieee80211_device *ieee)
3464{
3465 int i;
3466 memset(&ieee->current_network, 0, sizeof(struct ieee80211_network));
3467
3468 ieee->state = IEEE80211_NOLINK;
3469 ieee->sync_scan_hurryup = 0;
3470 for(i = 0; i < 5; i++) {
3471 ieee->seq_ctrl[i] = 0;
3472 }
3473
3474 ieee->assoc_id = 0;
3475 ieee->queue_stop = 0;
3476 ieee->scanning = 0;
3477 ieee->softmac_features = 0; //so IEEE2100-like driver are happy
3478 ieee->wap_set = 0;
3479 ieee->ssid_set = 0;
3480 ieee->proto_started = 0;
3481 ieee->basic_rate = IEEE80211_DEFAULT_BASIC_RATE;
3482 ieee->rate = 3;
3483//#ifdef ENABLE_LPS
3484 ieee->ps = IEEE80211_PS_MBCAST|IEEE80211_PS_UNICAST;
3485//#else
3486// ieee->ps = IEEE80211_PS_DISABLED;
3487//#endif
3488 ieee->sta_sleep = 0;
3489//by amy
3490 ieee->bInactivePs = false;
3491 ieee->actscanning = false;
3492 ieee->ListenInterval = 2;
3493 ieee->NumRxDataInPeriod = 0; //YJ,add,080828
3494 ieee->NumRxBcnInPeriod = 0; //YJ,add,080828
3495 ieee->NumRxOkTotal = 0;//+by amy 080312
3496 ieee->NumRxUnicast = 0;//YJ,add,080828,for keep alive
3497 ieee->beinretry = false;
3498 ieee->bHwRadioOff = false;
3499//by amy
3500#ifdef _RTL8187_EXT_PATCH_
3501 ieee->iw_ext_mode = 999;
3502#endif
3503
3504 init_mgmt_queue(ieee);
3505#if 0
3506 init_timer(&ieee->scan_timer);
3507 ieee->scan_timer.data = (unsigned long)ieee;
3508 ieee->scan_timer.function = ieee80211_softmac_scan_cb;
3509#endif
3510 ieee->tx_pending.txb = NULL;
3511
3512 init_timer(&ieee->associate_timer);
3513 ieee->associate_timer.data = (unsigned long)ieee;
3514 ieee->associate_timer.function = ieee80211_associate_abort_cb;
3515
3516 init_timer(&ieee->beacon_timer);
3517 ieee->beacon_timer.data = (unsigned long) ieee;
3518 ieee->beacon_timer.function = ieee80211_send_beacon_cb;
3519
3520#ifdef PF_SYNCTHREAD
3521 ieee->wq = create_workqueue(DRV_NAME,0);
3522#else
3523 ieee->wq = create_workqueue(DRV_NAME);
3524#endif
3525#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)//added by lawrence,070702
3526 INIT_DELAYED_WORK(&ieee->start_ibss_wq,(void*) ieee80211_start_ibss_wq);
3527 INIT_WORK(&ieee->associate_complete_wq,(void*) ieee80211_associate_complete_wq);
3528 INIT_WORK(&ieee->associate_procedure_wq,(void*) ieee80211_associate_procedure_wq);
3529 INIT_DELAYED_WORK(&ieee->softmac_scan_wq,(void*) ieee80211_softmac_scan_wq);
3530 INIT_DELAYED_WORK(&ieee->associate_retry_wq,(void*) ieee80211_associate_retry_wq);
3531 INIT_WORK(&ieee->wx_sync_scan_wq,(void*) ieee80211_wx_sync_scan_wq);
3532// INIT_WORK(&ieee->watch_dog_wq,(void*) ieee80211_watch_dog_wq);
3533//added by lawrence,20071118
3534#ifdef _RTL8187_EXT_PATCH_
3535 INIT_WORK(&ieee->ext_stop_scan_wq,(void*) ieee80211_ext_stop_scan_wq);
3536 //INIT_WORK(&ieee->ext_send_beacon_wq,(void*) ieee80211_beacons_start,ieee);
3537 INIT_WORK(&ieee->ext_send_beacon_wq,(void*) ext_ieee80211_send_beacon_wq);
3538#endif //_RTL8187_EXT_PATCH_
3539#else
3540 INIT_WORK(&ieee->start_ibss_wq,(void*) ieee80211_start_ibss_wq,ieee);
3541 INIT_WORK(&ieee->associate_retry_wq,(void*) ieee80211_associate_retry_wq,ieee);
3542 INIT_WORK(&ieee->associate_complete_wq,(void*) ieee80211_associate_complete_wq,ieee);
3543 INIT_WORK(&ieee->associate_procedure_wq,(void*) ieee80211_associate_procedure_wq,ieee);
3544 INIT_WORK(&ieee->softmac_scan_wq,(void*) ieee80211_softmac_scan_wq,ieee);
3545 INIT_WORK(&ieee->wx_sync_scan_wq,(void*) ieee80211_wx_sync_scan_wq,ieee);
3546// INIT_WORK(&ieee->watch_dog_wq,(void*) ieee80211_watch_dog_wq,ieee);
3547#ifdef _RTL8187_EXT_PATCH_
3548 INIT_WORK(&ieee->ext_stop_scan_wq,(void*) ieee80211_ext_stop_scan_wq,ieee);
3549 //INIT_WORK(&ieee->ext_send_beacon_wq,(void*) ieee80211_beacons_start,ieee);
3550 INIT_WORK(&ieee->ext_send_beacon_wq,(void*) ext_ieee80211_send_beacon_wq,ieee);
3551#endif
3552#endif
3553 sema_init(&ieee->wx_sem, 1);
3554 sema_init(&ieee->scan_sem, 1);
3555
3556 spin_lock_init(&ieee->mgmt_tx_lock);
3557 spin_lock_init(&ieee->beacon_lock);
3558
3559 tasklet_init(&ieee->ps_task,
3560 (void(*)(unsigned long)) ieee80211_sta_ps,
3561 (unsigned long)ieee);
3562#ifdef ENABLE_DOT11D
3563 ieee->pDot11dInfo = kmalloc(sizeof(RT_DOT11D_INFO), GFP_ATOMIC);
3564#endif
3565}
3566
3567void ieee80211_softmac_free(struct ieee80211_device *ieee)
3568{
3569 down(&ieee->wx_sem);
3570
3571 del_timer_sync(&ieee->associate_timer);
3572 cancel_delayed_work(&ieee->associate_retry_wq);
3573
3574
3575 //add for RF power on power of by lizhaoming 080512
3576 cancel_delayed_work(&ieee->GPIOChangeRFWorkItem);
3577
3578#ifdef _RTL8187_EXT_PATCH_
3579 cancel_delayed_work(&ieee->ext_stop_scan_wq);
3580 cancel_delayed_work(&ieee->ext_send_beacon_wq);
3581#endif
3582 destroy_workqueue(ieee->wq);
3583#ifdef ENABLE_DOT11D
3584 if(NULL != ieee->pDot11dInfo)
3585 kfree(ieee->pDot11dInfo);
3586#endif
3587 up(&ieee->wx_sem);
3588}
3589
3590/********************************************************
3591 * Start of WPA code. *
3592 * this is stolen from the ipw2200 driver *
3593 ********************************************************/
3594
3595
3596static int ieee80211_wpa_enable(struct ieee80211_device *ieee, int value)
3597{
3598 /* This is called when wpa_supplicant loads and closes the driver
3599 * interface. */
3600 printk("%s WPA\n",value ? "enabling" : "disabling");
3601 ieee->wpa_enabled = value;
3602 return 0;
3603}
3604
3605
3606void ieee80211_wpa_assoc_frame(struct ieee80211_device *ieee, char *wpa_ie, int wpa_ie_len)
3607{
3608 /* make sure WPA is enabled */
3609 ieee80211_wpa_enable(ieee, 1);
3610
3611 ieee80211_disassociate(ieee);
3612}
3613
3614
3615static int ieee80211_wpa_mlme(struct ieee80211_device *ieee, int command, int reason)
3616{
3617
3618 int ret = 0;
3619
3620 switch (command) {
3621 case IEEE_MLME_STA_DEAUTH:
3622 // silently ignore
3623 break;
3624
3625 case IEEE_MLME_STA_DISASSOC:
3626 ieee80211_disassociate(ieee);
3627 break;
3628
3629 default:
3630 printk("Unknown MLME request: %d\n", command);
3631 ret = -EOPNOTSUPP;
3632 }
3633
3634 return ret;
3635}
3636
3637
3638static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device *ieee,
3639 struct ieee_param *param, int plen)
3640{
3641 u8 *buf;
3642
3643 if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
3644 (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL))
3645 return -EINVAL;
3646
3647 if (param->u.wpa_ie.len) {
3648 buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL);
3649 if (buf == NULL)
3650 return -ENOMEM;
3651
3652 memcpy(buf, param->u.wpa_ie.data, param->u.wpa_ie.len);
3653 kfree(ieee->wpa_ie);
3654 ieee->wpa_ie = buf;
3655 ieee->wpa_ie_len = param->u.wpa_ie.len;
3656 } else {
3657 kfree(ieee->wpa_ie);
3658 ieee->wpa_ie = NULL;
3659 ieee->wpa_ie_len = 0;
3660 }
3661
3662 ieee80211_wpa_assoc_frame(ieee, ieee->wpa_ie, ieee->wpa_ie_len);
3663 return 0;
3664}
3665
3666#define AUTH_ALG_OPEN_SYSTEM 0x1
3667#define AUTH_ALG_SHARED_KEY 0x2
3668
3669static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value)
3670{
3671
3672 struct ieee80211_security sec = {
3673 .flags = SEC_AUTH_MODE,
3674 };
3675 int ret = 0;
3676
3677 if (value & AUTH_ALG_SHARED_KEY) {
3678 sec.auth_mode = WLAN_AUTH_SHARED_KEY;
3679 ieee->open_wep = 0;
3680 } else {
3681 sec.auth_mode = WLAN_AUTH_OPEN;
3682 ieee->open_wep = 1;
3683 }
3684
3685 if (ieee->set_security)
3686 ieee->set_security(ieee->dev, &sec);
3687 else
3688 ret = -EOPNOTSUPP;
3689
3690 return ret;
3691}
3692
3693static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 value)
3694{
3695 int ret=0;
3696 unsigned long flags;
3697
3698 switch (name) {
3699 case IEEE_PARAM_WPA_ENABLED:
3700 ret = ieee80211_wpa_enable(ieee, value);
3701 break;
3702
3703 case IEEE_PARAM_TKIP_COUNTERMEASURES:
3704 ieee->tkip_countermeasures=value;
3705 break;
3706
3707 case IEEE_PARAM_DROP_UNENCRYPTED: {
3708 /* HACK:
3709 *
3710 * wpa_supplicant calls set_wpa_enabled when the driver
3711 * is loaded and unloaded, regardless of if WPA is being
3712 * used. No other calls are made which can be used to
3713 * determine if encryption will be used or not prior to
3714 * association being expected. If encryption is not being
3715 * used, drop_unencrypted is set to false, else true -- we
3716 * can use this to determine if the CAP_PRIVACY_ON bit should
3717 * be set.
3718 */
3719 struct ieee80211_security sec = {
3720 .flags = SEC_ENABLED,
3721 .enabled = value,
3722 };
3723 ieee->drop_unencrypted = value;
3724 /* We only change SEC_LEVEL for open mode. Others
3725 * are set by ipw_wpa_set_encryption.
3726 */
3727 if (!value) {
3728 sec.flags |= SEC_LEVEL;
3729 sec.level = SEC_LEVEL_0;
3730 }
3731 else {
3732 sec.flags |= SEC_LEVEL;
3733 sec.level = SEC_LEVEL_1;
3734 }
3735 if (ieee->set_security)
3736 ieee->set_security(ieee->dev, &sec);
3737 break;
3738 }
3739
3740 case IEEE_PARAM_PRIVACY_INVOKED:
3741 ieee->privacy_invoked=value;
3742 break;
3743
3744 case IEEE_PARAM_AUTH_ALGS:
3745 ret = ieee80211_wpa_set_auth_algs(ieee, value);
3746 break;
3747
3748 case IEEE_PARAM_IEEE_802_1X:
3749 ieee->ieee802_1x=value;
3750 break;
3751 case IEEE_PARAM_WPAX_SELECT:
3752 // added for WPA2 mixed mode
3753 //printk(KERN_WARNING "------------------------>wpax value = %x\n", value);
3754 spin_lock_irqsave(&ieee->wpax_suitlist_lock,flags);
3755 ieee->wpax_type_set = 1;
3756 ieee->wpax_type_notify = value;
3757 spin_unlock_irqrestore(&ieee->wpax_suitlist_lock,flags);
3758 break;
3759
3760 default:
3761 printk("Unknown WPA param: %d\n",name);
3762 ret = -EOPNOTSUPP;
3763 }
3764
3765 return ret;
3766}
3767
3768/* implementation borrowed from hostap driver */
3769
3770static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
3771 struct ieee_param *param, int param_len)
3772{
3773 int ret = 0;
3774
3775 struct ieee80211_crypto_ops *ops;
3776 struct ieee80211_crypt_data **crypt;
3777
3778 struct ieee80211_security sec = {
3779 .flags = 0,
3780 };
3781
3782 param->u.crypt.err = 0;
3783 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
3784
3785 if (param_len !=
3786 (int) ((char *) param->u.crypt.key - (char *) param) +
3787 param->u.crypt.key_len) {
3788 printk("Len mismatch %d, %d\n", param_len,
3789 param->u.crypt.key_len);
3790 return -EINVAL;
3791 }
3792 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
3793 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
3794 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
3795 if (param->u.crypt.idx >= WEP_KEYS)
3796 return -EINVAL;
3797 crypt = &ieee->crypt[param->u.crypt.idx];
3798 } else {
3799 return -EINVAL;
3800 }
3801
3802 if (strcmp(param->u.crypt.alg, "none") == 0) {
3803 if (crypt) {
3804 sec.enabled = 0;
3805 // FIXME FIXME
3806 //sec.encrypt = 0;
3807 sec.level = SEC_LEVEL_0;
3808 sec.flags |= SEC_ENABLED | SEC_LEVEL;
3809 ieee80211_crypt_delayed_deinit(ieee, crypt);
3810 }
3811 goto done;
3812 }
3813 sec.enabled = 1;
3814// FIXME FIXME
3815// sec.encrypt = 1;
3816 sec.flags |= SEC_ENABLED;
3817
3818 /* IPW HW cannot build TKIP MIC, host decryption still needed. */
3819 if (!(ieee->host_encrypt || ieee->host_decrypt) &&
3820 strcmp(param->u.crypt.alg, "TKIP"))
3821 goto skip_host_crypt;
3822
3823 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3824 if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
3825 request_module("ieee80211_crypt_wep");
3826 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3827 } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
3828 request_module("ieee80211_crypt_tkip");
3829 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3830 } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
3831 request_module("ieee80211_crypt_ccmp");
3832 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3833 }
3834 if (ops == NULL) {
3835 printk("unknown crypto alg '%s'\n", param->u.crypt.alg);
3836 param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG;
3837 ret = -EINVAL;
3838 goto done;
3839 }
3840
3841 if (*crypt == NULL || (*crypt)->ops != ops) {
3842 struct ieee80211_crypt_data *new_crypt;
3843
3844 ieee80211_crypt_delayed_deinit(ieee, crypt);
3845
3846 new_crypt = (struct ieee80211_crypt_data *)
3847 kmalloc(sizeof(*new_crypt), GFP_KERNEL);
3848 if (new_crypt == NULL) {
3849 ret = -ENOMEM;
3850 goto done;
3851 }
3852 memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
3853 new_crypt->ops = ops;
3854 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
3855 new_crypt->priv =
3856 new_crypt->ops->init(param->u.crypt.idx);
3857
3858 if (new_crypt->priv == NULL) {
3859 kfree(new_crypt);
3860 param->u.crypt.err = IEEE_CRYPT_ERR_CRYPT_INIT_FAILED;
3861 ret = -EINVAL;
3862 goto done;
3863 }
3864
3865 *crypt = new_crypt;
3866 }
3867
3868 if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key &&
3869 (*crypt)->ops->set_key(param->u.crypt.key,
3870 param->u.crypt.key_len, param->u.crypt.seq,
3871 (*crypt)->priv) < 0) {
3872 printk("key setting failed\n");
3873 param->u.crypt.err = IEEE_CRYPT_ERR_KEY_SET_FAILED;
3874 ret = -EINVAL;
3875 goto done;
3876 }
3877
3878 skip_host_crypt:
3879 if (param->u.crypt.set_tx) {
3880 ieee->tx_keyidx = param->u.crypt.idx;
3881 sec.active_key = param->u.crypt.idx;
3882 sec.flags |= SEC_ACTIVE_KEY;
3883 } else
3884 sec.flags &= ~SEC_ACTIVE_KEY;
3885
3886 if (param->u.crypt.alg != NULL) {
3887 memcpy(sec.keys[param->u.crypt.idx],
3888 param->u.crypt.key,
3889 param->u.crypt.key_len);
3890 sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len;
3891 sec.flags |= (1 << param->u.crypt.idx);
3892
3893 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
3894 sec.flags |= SEC_LEVEL;
3895 sec.level = SEC_LEVEL_1;
3896 } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
3897 sec.flags |= SEC_LEVEL;
3898 sec.level = SEC_LEVEL_2;
3899 } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
3900 sec.flags |= SEC_LEVEL;
3901 sec.level = SEC_LEVEL_3;
3902 }
3903 }
3904 done:
3905 if (ieee->set_security)
3906 ieee->set_security(ieee->dev, &sec);
3907
3908 /* Do not reset port if card is in Managed mode since resetting will
3909 * generate new IEEE 802.11 authentication which may end up in looping
3910 * with IEEE 802.1X. If your hardware requires a reset after WEP
3911 * configuration (for example... Prism2), implement the reset_port in
3912 * the callbacks structures used to initialize the 802.11 stack. */
3913 if (ieee->reset_on_keychange &&
3914 ieee->iw_mode != IW_MODE_INFRA &&
3915 ieee->reset_port &&
3916 ieee->reset_port(ieee->dev)) {
3917 printk("reset_port failed\n");
3918 param->u.crypt.err = IEEE_CRYPT_ERR_CARD_CONF_FAILED;
3919 return -EINVAL;
3920 }
3921
3922 return ret;
3923}
3924
3925int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p)
3926{
3927 struct ieee_param *param;
3928 int ret=0;
3929
3930 down(&ieee->wx_sem);
3931 //IEEE_DEBUG_INFO("wpa_supplicant: len=%d\n", p->length);
3932
3933 if (p->length < sizeof(struct ieee_param) || !p->pointer){
3934 ret = -EINVAL;
3935 goto out;
3936 }
3937
3938 param = (struct ieee_param *)kmalloc(p->length, GFP_KERNEL);
3939 if (param == NULL){
3940 ret = -ENOMEM;
3941 goto out;
3942 }
3943 if (copy_from_user(param, p->pointer, p->length)) {
3944 kfree(param);
3945 ret = -EFAULT;
3946 goto out;
3947 }
3948
3949 switch (param->cmd) {
3950
3951 case IEEE_CMD_SET_WPA_PARAM:
3952 ret = ieee80211_wpa_set_param(ieee, param->u.wpa_param.name,
3953 param->u.wpa_param.value);
3954 break;
3955
3956 case IEEE_CMD_SET_WPA_IE:
3957 ret = ieee80211_wpa_set_wpa_ie(ieee, param, p->length);
3958 break;
3959
3960 case IEEE_CMD_SET_ENCRYPTION:
3961 ret = ieee80211_wpa_set_encryption(ieee, param, p->length);
3962 break;
3963
3964 case IEEE_CMD_MLME:
3965 ret = ieee80211_wpa_mlme(ieee, param->u.mlme.command,
3966 param->u.mlme.reason_code);
3967 break;
3968
3969 default:
3970 printk("Unknown WPA supplicant request: %d\n",param->cmd);
3971 ret = -EOPNOTSUPP;
3972 break;
3973 }
3974
3975 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
3976 ret = -EFAULT;
3977
3978 kfree(param);
3979out:
3980 up(&ieee->wx_sem);
3981
3982 return ret;
3983}
3984
3985void notify_wx_assoc_event(struct ieee80211_device *ieee)
3986{
3987 union iwreq_data wrqu;
3988 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3989 if (ieee->state == IEEE80211_LINKED)
3990 memcpy(wrqu.ap_addr.sa_data, ieee->current_network.bssid, ETH_ALEN);
3991 else
3992 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
3993 wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL);
3994}
3995
3996
3997#if 0
3998EXPORT_SYMBOL(ieee80211_get_beacon);
3999EXPORT_SYMBOL(ieee80211_wake_queue);
4000EXPORT_SYMBOL(ieee80211_stop_queue);
4001EXPORT_SYMBOL(ieee80211_reset_queue);
4002EXPORT_SYMBOL(ieee80211_softmac_stop_protocol);
4003EXPORT_SYMBOL(ieee80211_softmac_start_protocol);
4004EXPORT_SYMBOL(ieee80211_is_shortslot);
4005EXPORT_SYMBOL(ieee80211_is_54g);
4006EXPORT_SYMBOL(ieee80211_wpa_supplicant_ioctl);
4007EXPORT_SYMBOL(ieee80211_ps_tx_ack);
4008EXPORT_SYMBOL(ieee80211_start_protocol);
4009EXPORT_SYMBOL(ieee80211_stop_protocol);
4010EXPORT_SYMBOL(notify_wx_assoc_event);
4011EXPORT_SYMBOL(ieee80211_stop_send_beacons);
4012EXPORT_SYMBOL(SendDisassociation);
4013EXPORT_SYMBOL(ieee80211_disassociate);
4014EXPORT_SYMBOL(ieee80211_start_scan);
4015EXPORT_SYMBOL(ieee80211_softmac_ips_scan_syncro);
4016#ifdef _RTL8187_EXT_PATCH_
4017EXPORT_SYMBOL(ieee80211_ext_issue_assoc_req);
4018EXPORT_SYMBOL(ieee80211_ext_issue_disassoc);
4019EXPORT_SYMBOL(ieee80211_ext_issue_assoc_rsp);
4020EXPORT_SYMBOL(softmac_mgmt_xmit);
4021EXPORT_SYMBOL(ieee80211_ext_probe_resp_by_net);
4022EXPORT_SYMBOL(ieee80211_start_scan);
4023EXPORT_SYMBOL(ieee80211_stop_scan);
4024EXPORT_SYMBOL(ieee80211_ext_send_11s_beacon);
4025EXPORT_SYMBOL(ieee80211_rx_auth_rq);
4026EXPORT_SYMBOL(ieee80211_associate_step1);
4027#endif // _RTL8187_EXT_PATCH_
4028EXPORT_SYMBOL(ieee80211_sta_ps_send_null_frame);
4029#endif
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c
new file mode 100644
index 000000000000..43b8aecee9de
--- /dev/null
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c
@@ -0,0 +1,602 @@
1/* IEEE 802.11 SoftMAC layer
2 * Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
3 *
4 * Mostly extracted from the rtl8180-sa2400 driver for the
5 * in-kernel generic ieee802.11 stack.
6 *
7 * Some pieces of code might be stolen from ipw2100 driver
8 * copyright of who own it's copyright ;-)
9 *
10 * PS wx handler mostly stolen from hostap, copyright who
11 * own it's copyright ;-)
12 *
13 * released under the GPL
14 */
15
16
17#include "ieee80211.h"
18
19/* FIXME: add A freqs */
20
21const long ieee80211_wlan_frequencies[] = {
22 2412, 2417, 2422, 2427,
23 2432, 2437, 2442, 2447,
24 2452, 2457, 2462, 2467,
25 2472, 2484
26};
27
28
29int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
30 union iwreq_data *wrqu, char *b)
31{
32 int ret;
33 struct iw_freq *fwrq = & wrqu->freq;
34// printk("in %s\n",__FUNCTION__);
35 down(&ieee->wx_sem);
36
37 if(ieee->iw_mode == IW_MODE_INFRA){
38 ret = -EOPNOTSUPP;
39 goto out;
40 }
41
42 /* if setting by freq convert to channel */
43 if (fwrq->e == 1) {
44 if ((fwrq->m >= (int) 2.412e8 &&
45 fwrq->m <= (int) 2.487e8)) {
46 int f = fwrq->m / 100000;
47 int c = 0;
48
49 while ((c < 14) && (f != ieee80211_wlan_frequencies[c]))
50 c++;
51
52 /* hack to fall through */
53 fwrq->e = 0;
54 fwrq->m = c + 1;
55 }
56 }
57
58 if (fwrq->e > 0 || fwrq->m > 14 || fwrq->m < 1 ){
59 ret = -EOPNOTSUPP;
60 goto out;
61
62 }else { /* Set the channel */
63
64
65 ieee->current_network.channel = fwrq->m;
66 ieee->set_chan(ieee->dev, ieee->current_network.channel);
67
68 if(ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER)
69 if(ieee->state == IEEE80211_LINKED){
70
71 ieee80211_stop_send_beacons(ieee);
72 ieee80211_start_send_beacons(ieee);
73 }
74 }
75
76 ret = 0;
77out:
78 up(&ieee->wx_sem);
79 return ret;
80}
81
82
83int ieee80211_wx_get_freq(struct ieee80211_device *ieee,
84 struct iw_request_info *a,
85 union iwreq_data *wrqu, char *b)
86{
87 struct iw_freq *fwrq = & wrqu->freq;
88
89 if (ieee->current_network.channel == 0)
90 return -1;
91
92 fwrq->m = ieee->current_network.channel;
93 fwrq->e = 0;
94
95 return 0;
96}
97
98int ieee80211_wx_get_wap(struct ieee80211_device *ieee,
99 struct iw_request_info *info,
100 union iwreq_data *wrqu, char *extra)
101{
102 unsigned long flags;
103
104 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
105
106 if (ieee->iw_mode == IW_MODE_MONITOR)
107 return -1;
108
109 /* We want avoid to give to the user inconsistent infos*/
110 spin_lock_irqsave(&ieee->lock, flags);
111
112 if (ieee->state != IEEE80211_LINKED &&
113 ieee->state != IEEE80211_LINKED_SCANNING &&
114 ieee->wap_set == 0)
115
116 memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
117 else
118 memcpy(wrqu->ap_addr.sa_data,
119 ieee->current_network.bssid, ETH_ALEN);
120
121 spin_unlock_irqrestore(&ieee->lock, flags);
122
123 return 0;
124}
125
126
127int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
128 struct iw_request_info *info,
129 union iwreq_data *awrq,
130 char *extra)
131{
132
133 int ret = 0;
134 u8 zero[] = {0,0,0,0,0,0};
135 unsigned long flags;
136
137 short ifup = ieee->proto_started;//dev->flags & IFF_UP;
138 struct sockaddr *temp = (struct sockaddr *)awrq;
139
140 //printk("=======Set WAP:");
141 ieee->sync_scan_hurryup = 1;
142
143 down(&ieee->wx_sem);
144 /* use ifconfig hw ether */
145 if (ieee->iw_mode == IW_MODE_MASTER){
146 ret = -1;
147 goto out;
148 }
149
150 if (temp->sa_family != ARPHRD_ETHER){
151 ret = -EINVAL;
152 goto out;
153 }
154
155 if (ifup)
156 ieee80211_stop_protocol(ieee);
157
158 /* just to avoid to give inconsistent infos in the
159 * get wx method. not really needed otherwise
160 */
161 spin_lock_irqsave(&ieee->lock, flags);
162
163 memcpy(ieee->current_network.bssid, temp->sa_data, ETH_ALEN);
164 ieee->wap_set = memcmp(temp->sa_data, zero,ETH_ALEN)!=0;
165 //printk(" %x:%x:%x:%x:%x:%x\n", ieee->current_network.bssid[0],ieee->current_network.bssid[1],ieee->current_network.bssid[2],ieee->current_network.bssid[3],ieee->current_network.bssid[4],ieee->current_network.bssid[5]);
166
167 spin_unlock_irqrestore(&ieee->lock, flags);
168
169 if (ifup)
170 ieee80211_start_protocol(ieee);
171
172out:
173 up(&ieee->wx_sem);
174 return ret;
175}
176
177 int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b)
178{
179 int len,ret = 0;
180 unsigned long flags;
181
182 if (ieee->iw_mode == IW_MODE_MONITOR)
183 return -1;
184
185 /* We want avoid to give to the user inconsistent infos*/
186 spin_lock_irqsave(&ieee->lock, flags);
187
188 if (ieee->current_network.ssid[0] == '\0' ||
189 ieee->current_network.ssid_len == 0){
190 ret = -1;
191 goto out;
192 }
193
194 if (ieee->state != IEEE80211_LINKED &&
195 ieee->state != IEEE80211_LINKED_SCANNING &&
196 ieee->ssid_set == 0){
197 ret = -1;
198 goto out;
199 }
200 len = ieee->current_network.ssid_len;
201 wrqu->essid.length = len;
202 strncpy(b,ieee->current_network.ssid,len);
203 wrqu->essid.flags = 1;
204
205out:
206 spin_unlock_irqrestore(&ieee->lock, flags);
207
208 return ret;
209
210}
211
212int ieee80211_wx_set_rate(struct ieee80211_device *ieee,
213 struct iw_request_info *info,
214 union iwreq_data *wrqu, char *extra)
215{
216
217 u32 target_rate = wrqu->bitrate.value;
218
219 //added by lizhaoming for auto mode
220 if(target_rate == -1){
221 ieee->rate = 110;
222 } else {
223 ieee->rate = target_rate/100000;
224 }
225 //FIXME: we might want to limit rate also in management protocols.
226 return 0;
227}
228
229
230
231int ieee80211_wx_get_rate(struct ieee80211_device *ieee,
232 struct iw_request_info *info,
233 union iwreq_data *wrqu, char *extra)
234{
235
236 wrqu->bitrate.value = ieee->rate * 100000;
237
238 return 0;
239}
240
241int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
242 union iwreq_data *wrqu, char *b)
243{
244
245 ieee->sync_scan_hurryup = 1;
246
247 down(&ieee->wx_sem);
248
249 if (wrqu->mode == ieee->iw_mode)
250 goto out;
251
252 if (wrqu->mode == IW_MODE_MONITOR){
253
254 ieee->dev->type = ARPHRD_IEEE80211;
255 }else{
256 ieee->dev->type = ARPHRD_ETHER;
257 }
258
259 if (!ieee->proto_started){
260 ieee->iw_mode = wrqu->mode;
261 }else{
262 ieee80211_stop_protocol(ieee);
263 ieee->iw_mode = wrqu->mode;
264 ieee80211_start_protocol(ieee);
265 }
266
267out:
268 up(&ieee->wx_sem);
269 return 0;
270}
271
272
273#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
274void ieee80211_wx_sync_scan_wq(struct work_struct *work)
275{
276 struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, wx_sync_scan_wq);
277#else
278void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee)
279{
280#endif
281//void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee)
282//{
283 short chan;
284
285 chan = ieee->current_network.channel;
286
287 netif_carrier_off(ieee->dev);
288
289 if (ieee->data_hard_stop)
290 ieee->data_hard_stop(ieee->dev);
291
292 ieee80211_stop_send_beacons(ieee);
293
294 ieee->state = IEEE80211_LINKED_SCANNING;
295 ieee->link_change(ieee->dev);
296
297 ieee80211_start_scan_syncro(ieee);
298
299 ieee->set_chan(ieee->dev, chan);
300
301 ieee->state = IEEE80211_LINKED;
302 ieee->link_change(ieee->dev);
303
304 if (ieee->data_hard_resume)
305 ieee->data_hard_resume(ieee->dev);
306
307 if(ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER)
308 ieee80211_start_send_beacons(ieee);
309
310 netif_carrier_on(ieee->dev);
311
312 //YJ,add,080828, In prevent of lossing ping packet during scanning
313 //ieee80211_sta_ps_send_null_frame(ieee, false);
314 //YJ,add,080828,end
315
316 up(&ieee->wx_sem);
317
318}
319
320int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a,
321 union iwreq_data *wrqu, char *b)
322{
323 int ret = 0;
324
325 down(&ieee->wx_sem);
326
327 if (ieee->iw_mode == IW_MODE_MONITOR || !(ieee->proto_started)){
328 ret = -1;
329 goto out;
330 }
331 //YJ,add,080828
332 //In prevent of lossing ping packet during scanning
333 //ieee80211_sta_ps_send_null_frame(ieee, true);
334 //YJ,add,080828,end
335
336 if ( ieee->state == IEEE80211_LINKED){
337 queue_work(ieee->wq, &ieee->wx_sync_scan_wq);
338 /* intentionally forget to up sem */
339 return 0;
340 }
341
342out:
343 up(&ieee->wx_sem);
344 return ret;
345}
346
347int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
348 struct iw_request_info *a,
349 union iwreq_data *wrqu, char *extra)
350{
351
352 int ret=0,len;
353 short proto_started;
354 unsigned long flags;
355
356 ieee->sync_scan_hurryup = 1;
357
358 down(&ieee->wx_sem);
359
360 proto_started = ieee->proto_started;
361
362 if (wrqu->essid.length > IW_ESSID_MAX_SIZE){
363 ret= -E2BIG;
364 goto out;
365 }
366
367 if (ieee->iw_mode == IW_MODE_MONITOR){
368 ret= -1;
369 goto out;
370 }
371
372 if(proto_started)
373 ieee80211_stop_protocol(ieee);
374
375 /* this is just to be sure that the GET wx callback
376 * has consisten infos. not needed otherwise
377 */
378 spin_lock_irqsave(&ieee->lock, flags);
379
380 if (wrqu->essid.flags && wrqu->essid.length) {
381//YJ,modified,080819
382#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
383 len = ((wrqu->essid.length-1) < IW_ESSID_MAX_SIZE) ? (wrqu->essid.length-1) : IW_ESSID_MAX_SIZE;
384#else
385 len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ? (wrqu->essid.length) : IW_ESSID_MAX_SIZE;
386#endif
387 memset(ieee->current_network.ssid, 0, ieee->current_network.ssid_len); //YJ,add,080819
388 strncpy(ieee->current_network.ssid, extra, len);
389 ieee->current_network.ssid_len = len;
390 ieee->ssid_set = 1;
391//YJ,modified,080819,end
392
393 //YJ,add,080819,for hidden ap
394 if(len == 0){
395 memset(ieee->current_network.bssid, 0, ETH_ALEN);
396 ieee->current_network.capability = 0;
397 }
398 //YJ,add,080819,for hidden ap,end
399 }
400 else{
401 ieee->ssid_set = 0;
402 ieee->current_network.ssid[0] = '\0';
403 ieee->current_network.ssid_len = 0;
404 }
405 //printk("==========set essid %s!\n",ieee->current_network.ssid);
406 spin_unlock_irqrestore(&ieee->lock, flags);
407
408 if (proto_started)
409 ieee80211_start_protocol(ieee);
410out:
411 up(&ieee->wx_sem);
412 return ret;
413}
414
415 int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
416 union iwreq_data *wrqu, char *b)
417{
418
419 wrqu->mode = ieee->iw_mode;
420 return 0;
421}
422
423 int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee,
424 struct iw_request_info *info,
425 union iwreq_data *wrqu, char *extra)
426{
427
428 int *parms = (int *)extra;
429 int enable = (parms[0] > 0);
430 short prev = ieee->raw_tx;
431
432 down(&ieee->wx_sem);
433
434 if(enable)
435 ieee->raw_tx = 1;
436 else
437 ieee->raw_tx = 0;
438
439 printk(KERN_INFO"raw TX is %s\n",
440 ieee->raw_tx ? "enabled" : "disabled");
441
442 if(ieee->iw_mode == IW_MODE_MONITOR)
443 {
444 if(prev == 0 && ieee->raw_tx){
445 if (ieee->data_hard_resume)
446 ieee->data_hard_resume(ieee->dev);
447
448 netif_carrier_on(ieee->dev);
449 }
450
451 if(prev && ieee->raw_tx == 1)
452 netif_carrier_off(ieee->dev);
453 }
454
455 up(&ieee->wx_sem);
456
457 return 0;
458}
459
460int ieee80211_wx_get_name(struct ieee80211_device *ieee,
461 struct iw_request_info *info,
462 union iwreq_data *wrqu, char *extra)
463{
464 strcpy(wrqu->name, "802.11");
465 if(ieee->modulation & IEEE80211_CCK_MODULATION){
466 strcat(wrqu->name, "b");
467 if(ieee->modulation & IEEE80211_OFDM_MODULATION)
468 strcat(wrqu->name, "/g");
469 }else if(ieee->modulation & IEEE80211_OFDM_MODULATION)
470 strcat(wrqu->name, "g");
471
472 if((ieee->state == IEEE80211_LINKED) ||
473 (ieee->state == IEEE80211_LINKED_SCANNING))
474 strcat(wrqu->name," linked");
475 else if(ieee->state != IEEE80211_NOLINK)
476 strcat(wrqu->name," link..");
477
478
479 return 0;
480}
481
482
483/* this is mostly stolen from hostap */
484int ieee80211_wx_set_power(struct ieee80211_device *ieee,
485 struct iw_request_info *info,
486 union iwreq_data *wrqu, char *extra)
487{
488 int ret = 0;
489
490 if(
491 (!ieee->sta_wake_up) ||
492 (!ieee->ps_request_tx_ack) ||
493 (!ieee->enter_sleep_state) ||
494 (!ieee->ps_is_queue_empty)){
495
496 printk("ERROR. PS mode is tryied to be use but\
497driver missed a callback\n\n");
498
499 return -1;
500 }
501
502 down(&ieee->wx_sem);
503
504 if (wrqu->power.disabled){
505 ieee->ps = IEEE80211_PS_DISABLED;
506
507 goto exit;
508 }
509 switch (wrqu->power.flags & IW_POWER_MODE) {
510 case IW_POWER_UNICAST_R:
511 ieee->ps = IEEE80211_PS_UNICAST;
512
513 break;
514 case IW_POWER_ALL_R:
515 ieee->ps = IEEE80211_PS_UNICAST | IEEE80211_PS_MBCAST;
516 break;
517
518 case IW_POWER_ON:
519 ieee->ps = IEEE80211_PS_DISABLED;
520 break;
521
522 default:
523 ret = -EINVAL;
524 goto exit;
525 }
526
527 if (wrqu->power.flags & IW_POWER_TIMEOUT) {
528
529 ieee->ps_timeout = wrqu->power.value / 1000;
530 printk("Timeout %d\n",ieee->ps_timeout);
531 }
532
533 if (wrqu->power.flags & IW_POWER_PERIOD) {
534
535 ret = -EOPNOTSUPP;
536 goto exit;
537 //wrq->value / 1024;
538
539 }
540exit:
541 up(&ieee->wx_sem);
542 return ret;
543
544}
545
546/* this is stolen from hostap */
547int ieee80211_wx_get_power(struct ieee80211_device *ieee,
548 struct iw_request_info *info,
549 union iwreq_data *wrqu, char *extra)
550{
551 int ret =0;
552
553 down(&ieee->wx_sem);
554
555 if(ieee->ps == IEEE80211_PS_DISABLED){
556 wrqu->power.disabled = 1;
557 goto exit;
558 }
559
560 wrqu->power.disabled = 0;
561
562// if ((wrqu->power.flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
563 wrqu->power.flags = IW_POWER_TIMEOUT;
564 wrqu->power.value = ieee->ps_timeout * 1000;
565// } else {
566// ret = -EOPNOTSUPP;
567// goto exit;
568 //wrqu->power.flags = IW_POWER_PERIOD;
569 //wrqu->power.value = ieee->current_network.dtim_period *
570 // ieee->current_network.beacon_interval * 1024;
571// }
572
573
574 if (ieee->ps & IEEE80211_PS_MBCAST)
575 wrqu->power.flags |= IW_POWER_ALL_R;
576 else
577 wrqu->power.flags |= IW_POWER_UNICAST_R;
578
579exit:
580 up(&ieee->wx_sem);
581 return ret;
582
583}
584
585#if 0
586EXPORT_SYMBOL(ieee80211_wx_get_essid);
587EXPORT_SYMBOL(ieee80211_wx_set_essid);
588EXPORT_SYMBOL(ieee80211_wx_set_rate);
589EXPORT_SYMBOL(ieee80211_wx_get_rate);
590EXPORT_SYMBOL(ieee80211_wx_set_wap);
591EXPORT_SYMBOL(ieee80211_wx_get_wap);
592EXPORT_SYMBOL(ieee80211_wx_set_mode);
593EXPORT_SYMBOL(ieee80211_wx_get_mode);
594EXPORT_SYMBOL(ieee80211_wx_set_scan);
595EXPORT_SYMBOL(ieee80211_wx_get_freq);
596EXPORT_SYMBOL(ieee80211_wx_set_freq);
597EXPORT_SYMBOL(ieee80211_wx_set_rawtx);
598EXPORT_SYMBOL(ieee80211_wx_get_name);
599EXPORT_SYMBOL(ieee80211_wx_set_power);
600EXPORT_SYMBOL(ieee80211_wx_get_power);
601EXPORT_SYMBOL(ieee80211_wlan_frequencies);
602#endif
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c
new file mode 100644
index 000000000000..33a0687252af
--- /dev/null
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c
@@ -0,0 +1,828 @@
1/******************************************************************************
2
3 Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
4
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of version 2 of the GNU General Public License as
7 published by the Free Software Foundation.
8
9 This program is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 more details.
13
14 You should have received a copy of the GNU General Public License along with
15 this program; if not, write to the Free Software Foundation, Inc., 59
16 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18 The full GNU General Public License is included in this distribution in the
19 file called LICENSE.
20
21 Contact Information:
22 James P. Ketrenos <ipw2100-admin@linux.intel.com>
23 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24
25******************************************************************************
26
27 Few modifications for Realtek's Wi-Fi drivers by
28 Andrea Merello <andreamrl@tiscali.it>
29
30 A special thanks goes to Realtek for their support !
31
32******************************************************************************/
33
34#include <linux/compiler.h>
35//#include <linux/config.h>
36#include <linux/errno.h>
37#include <linux/if_arp.h>
38#include <linux/in6.h>
39#include <linux/in.h>
40#include <linux/ip.h>
41#include <linux/kernel.h>
42#include <linux/module.h>
43#include <linux/netdevice.h>
44#include <linux/pci.h>
45#include <linux/proc_fs.h>
46#include <linux/skbuff.h>
47#include <linux/slab.h>
48#include <linux/tcp.h>
49#include <linux/types.h>
50#include <linux/version.h>
51#include <linux/wireless.h>
52#include <linux/etherdevice.h>
53#include <asm/uaccess.h>
54#include <linux/if_vlan.h>
55
56#include "ieee80211.h"
57
58
59/*
60
61
62802.11 Data Frame
63
64
65802.11 frame_contorl for data frames - 2 bytes
66 ,-----------------------------------------------------------------------------------------.
67bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e |
68 |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
69val | 0 | 0 | 0 | 1 | x | 0 | 0 | 0 | 1 | 0 | x | x | x | x | x |
70 |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
71desc | ^-ver-^ | ^type-^ | ^-----subtype-----^ | to |from |more |retry| pwr |more |wep |
72 | | | x=0 data,x=1 data+ack | DS | DS |frag | | mgm |data | |
73 '-----------------------------------------------------------------------------------------'
74 /\
75 |
76802.11 Data Frame |
77 ,--------- 'ctrl' expands to >-----------'
78 |
79 ,--'---,-------------------------------------------------------------.
80Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 |
81 |------|------|---------|---------|---------|------|---------|------|
82Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | Frame | fcs |
83 | | tion | (BSSID) | | | ence | data | |
84 `--------------------------------------------------| |------'
85Total: 28 non-data bytes `----.----'
86 |
87 .- 'Frame data' expands to <---------------------------'
88 |
89 V
90 ,---------------------------------------------------.
91Bytes | 1 | 1 | 1 | 3 | 2 | 0-2304 |
92 |------|------|---------|----------|------|---------|
93Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP |
94 | DSAP | SSAP | | | | Packet |
95 | 0xAA | 0xAA |0x03 (UI)|0x00-00-F8| | |
96 `-----------------------------------------| |
97Total: 8 non-data bytes `----.----'
98 |
99 .- 'IP Packet' expands, if WEP enabled, to <--'
100 |
101 V
102 ,-----------------------.
103Bytes | 4 | 0-2296 | 4 |
104 |-----|-----------|-----|
105Desc. | IV | Encrypted | ICV |
106 | | IP Packet | |
107 `-----------------------'
108Total: 8 non-data bytes
109
110
111802.3 Ethernet Data Frame
112
113 ,-----------------------------------------.
114Bytes | 6 | 6 | 2 | Variable | 4 |
115 |-------|-------|------|-----------|------|
116Desc. | Dest. | Source| Type | IP Packet | fcs |
117 | MAC | MAC | | | |
118 `-----------------------------------------'
119Total: 18 non-data bytes
120
121In the event that fragmentation is required, the incoming payload is split into
122N parts of size ieee->fts. The first fragment contains the SNAP header and the
123remaining packets are just data.
124
125If encryption is enabled, each fragment payload size is reduced by enough space
126to add the prefix and postfix (IV and ICV totalling 8 bytes in the case of WEP)
127So if you have 1500 bytes of payload with ieee->fts set to 500 without
128encryption it will take 3 frames. With WEP it will take 4 frames as the
129payload of each frame is reduced to 492 bytes.
130
131* SKB visualization
132*
133* ,- skb->data
134* |
135* | ETHERNET HEADER ,-<-- PAYLOAD
136* | | 14 bytes from skb->data
137* | 2 bytes for Type --> ,T. | (sizeof ethhdr)
138* | | | |
139* |,-Dest.--. ,--Src.---. | | |
140* | 6 bytes| | 6 bytes | | | |
141* v | | | | | |
142* 0 | v 1 | v | v 2
143* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
144* ^ | ^ | ^ |
145* | | | | | |
146* | | | | `T' <---- 2 bytes for Type
147* | | | |
148* | | '---SNAP--' <-------- 6 bytes for SNAP
149* | |
150* `-IV--' <-------------------- 4 bytes for IV (WEP)
151*
152* SNAP HEADER
153*
154*/
155
156static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
157static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
158
159static inline int ieee80211_put_snap(u8 *data, u16 h_proto)
160{
161 struct ieee80211_snap_hdr *snap;
162 u8 *oui;
163
164 snap = (struct ieee80211_snap_hdr *)data;
165 snap->dsap = 0xaa;
166 snap->ssap = 0xaa;
167 snap->ctrl = 0x03;
168
169 if (h_proto == 0x8137 || h_proto == 0x80f3)
170 oui = P802_1H_OUI;
171 else
172 oui = RFC1042_OUI;
173 snap->oui[0] = oui[0];
174 snap->oui[1] = oui[1];
175 snap->oui[2] = oui[2];
176
177 *(u16 *)(data + SNAP_SIZE) = htons(h_proto);
178
179 return SNAP_SIZE + sizeof(u16);
180}
181
182int ieee80211_encrypt_fragment(
183 struct ieee80211_device *ieee,
184 struct sk_buff *frag,
185 int hdr_len)
186{
187 struct ieee80211_crypt_data* crypt = ieee->crypt[ieee->tx_keyidx];
188 int res;
189
190 /*added to care about null crypt condition, to solve that system hangs when shared keys error*/
191 if (!crypt || !crypt->ops)
192 return -1;
193
194#ifdef CONFIG_IEEE80211_CRYPT_TKIP
195 struct ieee80211_hdr *header;
196
197 if (ieee->tkip_countermeasures &&
198 crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
199 header = (struct ieee80211_hdr *) frag->data;
200 if (net_ratelimit()) {
201 printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
202 "TX packet to " MAC_FMT "\n",
203 ieee->dev->name, MAC_ARG(header->addr1));
204 }
205 return -1;
206 }
207#endif
208 /* To encrypt, frame format is:
209 * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */
210
211 // PR: FIXME: Copied from hostap. Check fragmentation/MSDU/MPDU encryption.
212 /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
213 * call both MSDU and MPDU encryption functions from here. */
214 atomic_inc(&crypt->refcnt);
215 res = 0;
216 if (crypt->ops->encrypt_msdu)
217 res = crypt->ops->encrypt_msdu(frag, hdr_len, crypt->priv);
218 if (res == 0 && crypt->ops->encrypt_mpdu)
219 res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv);
220
221 atomic_dec(&crypt->refcnt);
222 if (res < 0) {
223 printk(KERN_INFO "%s: Encryption failed: len=%d.\n",
224 ieee->dev->name, frag->len);
225 ieee->ieee_stats.tx_discards++;
226 return -1;
227 }
228
229 return 0;
230}
231
232
233void ieee80211_txb_free(struct ieee80211_txb *txb) {
234 int i;
235 if (unlikely(!txb))
236 return;
237 for (i = 0; i < txb->nr_frags; i++)
238 if (txb->fragments[i])
239 dev_kfree_skb_any(txb->fragments[i]);
240 kfree(txb);
241}
242
243struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
244 int gfp_mask)
245{
246 struct ieee80211_txb *txb;
247 int i;
248 txb = kmalloc(
249 sizeof(struct ieee80211_txb) + (sizeof(u8*) * nr_frags),
250 gfp_mask);
251 if (!txb)
252 return NULL;
253
254 memset(txb, 0, sizeof(struct ieee80211_txb));
255 txb->nr_frags = nr_frags;
256 txb->frag_size = txb_size;
257
258 for (i = 0; i < nr_frags; i++) {
259 txb->fragments[i] = dev_alloc_skb(txb_size);
260 if (unlikely(!txb->fragments[i])) {
261 i--;
262 break;
263 }
264 }
265 if (unlikely(i != nr_frags)) {
266 while (i >= 0)
267 dev_kfree_skb_any(txb->fragments[i--]);
268 kfree(txb);
269 return NULL;
270 }
271 return txb;
272}
273
274// Classify the to-be send data packet
275// Need to acquire the sent queue index.
276static int
277ieee80211_classify(struct sk_buff *skb, struct ieee80211_network *network)
278{
279 struct ether_header *eh = (struct ether_header*)skb->data;
280 unsigned int wme_UP = 0;
281
282 if(!network->QoS_Enable) {
283 skb->priority = 0;
284 return(wme_UP);
285 }
286
287 if(eh->ether_type == __constant_htons(ETHERTYPE_IP)) {
288 const struct iphdr *ih = (struct iphdr*)(skb->data + \
289 sizeof(struct ether_header));
290 wme_UP = (ih->tos >> 5)&0x07;
291 } else if (vlan_tx_tag_present(skb)) {//vtag packet
292#ifndef VLAN_PRI_SHIFT
293#define VLAN_PRI_SHIFT 13 /* Shift to find VLAN user priority */
294#define VLAN_PRI_MASK 7 /* Mask for user priority bits in VLAN */
295#endif
296 u32 tag = vlan_tx_tag_get(skb);
297 wme_UP = (tag >> VLAN_PRI_SHIFT) & VLAN_PRI_MASK;
298 } else if(ETH_P_PAE == ntohs(((struct ethhdr *)skb->data)->h_proto)) {
299 //printk(KERN_WARNING "type = normal packet\n");
300 wme_UP = 7;
301 }
302
303 skb->priority = wme_UP;
304 return(wme_UP);
305}
306
307#ifdef _RTL8187_EXT_PATCH_
308// based on part of ieee80211_xmit. Mainly allocate txb. ieee->lock is held
309struct ieee80211_txb *ieee80211_ext_alloc_txb(struct sk_buff *skb, struct net_device *dev, struct ieee80211_hdr_3addr *header, int hdr_len, u8 isQoS, u16 *pQOS_ctl, int isEncrypt, struct ieee80211_crypt_data* crypt)
310{
311#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
312 struct ieee80211_device *ieee = netdev_priv(dev);
313#else
314 struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv;
315#endif
316 struct ieee80211_txb *txb = NULL;
317 struct ieee80211_hdr_3addr *frag_hdr;
318 int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
319 int ether_type;
320 int bytes, QOS_ctl;
321 struct sk_buff *skb_frag;
322
323 ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
324
325 /* Advance the SKB to the start of the payload */
326 skb_pull(skb, sizeof(struct ethhdr));
327
328 /* Determine total amount of storage required for TXB packets */
329 bytes = skb->len + SNAP_SIZE + sizeof(u16);
330
331 /* Determine fragmentation size based on destination (multicast
332 * and broadcast are not fragmented) */
333 // if (is_multicast_ether_addr(dest) ||
334 // is_broadcast_ether_addr(dest)) {
335 if (is_multicast_ether_addr(header->addr1) ||
336 is_broadcast_ether_addr(header->addr1)) {
337 frag_size = MAX_FRAG_THRESHOLD;
338 QOS_ctl = QOS_CTL_NOTCONTAIN_ACK;
339 }
340 else {
341 //printk(KERN_WARNING "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&frag_size = %d\n", frag_size);
342 frag_size = ieee->fts;//default:392
343 QOS_ctl = 0;
344 }
345
346 if(isQoS) {
347 QOS_ctl |= skb->priority; //set in the ieee80211_classify
348 *pQOS_ctl = cpu_to_le16(QOS_ctl);
349 }
350 //printk(KERN_WARNING "header size = %d, QOS_ctl = %x\n", hdr_len,QOS_ctl);
351 /* Determine amount of payload per fragment. Regardless of if
352 * this stack is providing the full 802.11 header, one will
353 * eventually be affixed to this fragment -- so we must account for
354 * it when determining the amount of payload space. */
355 //bytes_per_frag = frag_size - (IEEE80211_3ADDR_LEN + (ieee->current_network->QoS_Enable ? 2:0));
356 bytes_per_frag = frag_size - hdr_len;
357 if (ieee->config &
358 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
359 bytes_per_frag -= IEEE80211_FCS_LEN;
360
361 /* Each fragment may need to have room for encryptiong pre/postfix */
362 if (isEncrypt)
363 bytes_per_frag -= crypt->ops->extra_prefix_len +
364 crypt->ops->extra_postfix_len;
365
366 /* Number of fragments is the total bytes_per_frag /
367 * payload_per_fragment */
368 nr_frags = bytes / bytes_per_frag;
369 bytes_last_frag = bytes % bytes_per_frag;
370 if (bytes_last_frag)
371 nr_frags++;
372 else
373 bytes_last_frag = bytes_per_frag;
374
375 /* When we allocate the TXB we allocate enough space for the reserve
376 * and full fragment bytes (bytes_per_frag doesn't include prefix,
377 * postfix, header, FCS, etc.) */
378 txb = ieee80211_alloc_txb(nr_frags, frag_size, GFP_ATOMIC);
379 if (unlikely(!txb)) {
380 printk(KERN_WARNING "%s: Could not allocate TXB\n",
381 ieee->dev->name);
382 return NULL;
383 }
384 txb->encrypted = isEncrypt;
385 txb->payload_size = bytes;
386
387 for (i = 0; i < nr_frags; i++) {
388 skb_frag = txb->fragments[i];
389 skb_frag->priority = UP2AC(skb->priority);
390 if (isEncrypt)
391 skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
392
393 frag_hdr = (struct ieee80211_hdr_3addr *)skb_put(skb_frag, hdr_len);
394 memcpy(frag_hdr, (void *)header, hdr_len);
395
396 /* If this is not the last fragment, then add the MOREFRAGS
397 * bit to the frame control */
398 if (i != nr_frags - 1) {
399 frag_hdr->frame_ctl = cpu_to_le16(
400 header->frame_ctl | IEEE80211_FCTL_MOREFRAGS);
401 bytes = bytes_per_frag;
402
403 } else {
404 /* The last fragment takes the remaining length */
405 bytes = bytes_last_frag;
406 }
407
408 frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | i);
409 //frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl<<4 | i);
410 //
411
412 /* Put a SNAP header on the first fragment */
413 if (i == 0) {
414 ieee80211_put_snap(
415 skb_put(skb_frag, SNAP_SIZE + sizeof(u16)), ether_type);
416 bytes -= SNAP_SIZE + sizeof(u16);
417 }
418
419 memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
420
421 /* Advance the SKB... */
422 skb_pull(skb, bytes);
423
424 /* Encryption routine will move the header forward in order
425 * to insert the IV between the header and the payload */
426 if (isEncrypt)
427 ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
428 if (ieee->config &
429 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
430 skb_put(skb_frag, 4);
431 }
432 // Advance sequence number in data frame.
433 //printk(KERN_WARNING "QoS Enalbed? %s\n", ieee->current_network.QoS_Enable?"Y":"N");
434 if (ieee->seq_ctrl[0] == 0xFFF)
435 ieee->seq_ctrl[0] = 0;
436 else
437 ieee->seq_ctrl[0]++;
438 // stanley, just for debug
439/*
440{
441 int j=0;
442 for(j=0;j<nr_frags;j++)
443 {
444 int i;
445 struct sk_buff *skb = txb->fragments[j];
446 printk("send(%d): ", j);
447 for (i=0;i<skb->len;i++)
448 printk("%02X ", skb->data[i]&0xff);
449 printk("\n");
450 }
451}
452*/
453
454 return txb;
455}
456
457
458// based on part of ieee80211_xmit. Mainly allocate txb. ieee->lock is held
459// Assume no encryption, no FCS computing
460struct ieee80211_txb *ieee80211_ext_reuse_txb(struct sk_buff *skb, struct net_device *dev, struct ieee80211_hdr_3addr *header, int hdr_len, u8 isQoS, u16 *pQOS_ctl, int isEncrypt, struct ieee80211_crypt_data* crypt)
461{
462#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
463 struct ieee80211_device *ieee = netdev_priv(dev);
464#else
465 struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv;
466#endif
467 struct ieee80211_txb *txb = NULL;
468 struct ieee80211_hdr_3addr *frag_hdr;
469 int ether_type;
470 int bytes, QOS_ctl;
471
472 ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
473
474 /* Advance the SKB to the start of the payload */
475 skb_pull(skb, sizeof(struct ethhdr));
476
477 /* Determine total amount of storage required for TXB packets */
478 bytes = skb->len + SNAP_SIZE + sizeof(u16);
479
480 if (is_multicast_ether_addr(header->addr1) ||
481 is_broadcast_ether_addr(header->addr1)) {
482 QOS_ctl = QOS_CTL_NOTCONTAIN_ACK;
483 }
484 else {
485 QOS_ctl = 0;
486 }
487
488 if(isQoS) {
489 QOS_ctl |= skb->priority; //set in the ieee80211_classify
490 *pQOS_ctl = cpu_to_le16(QOS_ctl);
491 }
492
493 txb = kmalloc( sizeof(struct ieee80211_txb) + sizeof(u8*), GFP_ATOMIC );
494 if (unlikely(!txb)) {
495 printk(KERN_WARNING "%s: Could not allocate TXB\n",
496 ieee->dev->name);
497 return NULL;
498 }
499
500 txb->nr_frags = 1;
501 txb->frag_size = bytes;
502 txb->encrypted = isEncrypt;
503 txb->payload_size = bytes;
504
505 txb->fragments[0] = skb;
506 ieee80211_put_snap(
507 skb_push(skb, SNAP_SIZE + sizeof(u16)), ether_type);
508 frag_hdr = (struct ieee80211_hdr_3addr *)skb_push(skb, hdr_len);
509 memcpy(frag_hdr, (void *)header, hdr_len);
510 frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | 0);
511 skb->priority = UP2AC(skb->priority);
512
513 // Advance sequence number in data frame.
514 //printk(KERN_WARNING "QoS Enalbed? %s\n", ieee->current_network.QoS_Enable?"Y":"N");
515 if (ieee->seq_ctrl[0] == 0xFFF)
516 ieee->seq_ctrl[0] = 0;
517 else
518 ieee->seq_ctrl[0]++;
519
520 return txb;
521}
522
523#endif // _RTL8187_EXT_PATCH_
524
525/* SKBs are added to the ieee->tx_queue. */
526int ieee80211_xmit(struct sk_buff *skb,
527 struct net_device *dev)
528{
529 struct ieee80211_device *ieee = netdev_priv(dev);
530 struct ieee80211_txb *txb = NULL;
531 struct ieee80211_hdr_3addr_QOS *frag_hdr;
532 int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
533 unsigned long flags;
534 struct net_device_stats *stats = &ieee->stats;
535 int ether_type, encrypt;
536 int bytes, fc, QOS_ctl, hdr_len;
537 struct sk_buff *skb_frag;
538 //struct ieee80211_hdr header = { /* Ensure zero initialized */
539 // .duration_id = 0,
540 // .seq_ctl = 0
541 //};
542 struct ieee80211_hdr_3addr_QOS header = { /* Ensure zero initialized */
543 .duration_id = 0,
544 .seq_ctl = 0,
545 .QOS_ctl = 0
546 };
547 u8 dest[ETH_ALEN], src[ETH_ALEN];
548
549 struct ieee80211_crypt_data* crypt;
550
551 //printk(KERN_WARNING "upper layer packet!\n");
552 spin_lock_irqsave(&ieee->lock, flags);
553
554 /* If there is no driver handler to take the TXB, dont' bother
555 * creating it... */
556 if ((!ieee->hard_start_xmit && !(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE))||
557 ((!ieee->softmac_data_hard_start_xmit && (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) {
558 printk(KERN_WARNING "%s: No xmit handler.\n",
559 ieee->dev->name);
560 goto success;
561 }
562
563 ieee80211_classify(skb,&ieee->current_network);
564 if(likely(ieee->raw_tx == 0)){
565
566 if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
567 printk(KERN_WARNING "%s: skb too small (%d).\n",
568 ieee->dev->name, skb->len);
569 goto success;
570 }
571
572
573#ifdef _RTL8187_EXT_PATCH_
574 // note, skb->priority which was set by ieee80211_classify, and used by physical tx
575 if((ieee->iw_mode == ieee->iw_ext_mode) && (ieee->ext_patch_ieee80211_xmit))
576 {
577 txb = ieee->ext_patch_ieee80211_xmit(skb, dev);
578 goto success;
579 }
580#endif
581
582 ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
583
584 crypt = ieee->crypt[ieee->tx_keyidx];
585
586 encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
587 ieee->host_encrypt && crypt && crypt->ops;
588
589 if (!encrypt && ieee->ieee802_1x &&
590 ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
591 stats->tx_dropped++;
592 goto success;
593 }
594
595 #ifdef CONFIG_IEEE80211_DEBUG
596 if (crypt && !encrypt && ether_type == ETH_P_PAE) {
597 struct eapol *eap = (struct eapol *)(skb->data +
598 sizeof(struct ethhdr) - SNAP_SIZE - sizeof(u16));
599 IEEE80211_DEBUG_EAP("TX: IEEE 802.11 EAPOL frame: %s\n",
600 eap_get_type(eap->type));
601 }
602 #endif
603
604 /* Save source and destination addresses */
605 memcpy(&dest, skb->data, ETH_ALEN);
606 memcpy(&src, skb->data+ETH_ALEN, ETH_ALEN);
607
608 /* Advance the SKB to the start of the payload */
609 skb_pull(skb, sizeof(struct ethhdr));
610
611 /* Determine total amount of storage required for TXB packets */
612 bytes = skb->len + SNAP_SIZE + sizeof(u16);
613
614 if(ieee->current_network.QoS_Enable) {
615 if (encrypt)
616 fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA |
617 IEEE80211_FCTL_WEP;
618 else
619 fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA;
620
621 } else {
622 if (encrypt)
623 fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA |
624 IEEE80211_FCTL_WEP;
625 else
626 fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA;
627 }
628
629 if (ieee->iw_mode == IW_MODE_INFRA) {
630 fc |= IEEE80211_FCTL_TODS;
631 /* To DS: Addr1 = BSSID, Addr2 = SA,
632 Addr3 = DA */
633 memcpy(&header.addr1, ieee->current_network.bssid, ETH_ALEN);
634 memcpy(&header.addr2, &src, ETH_ALEN);
635 memcpy(&header.addr3, &dest, ETH_ALEN);
636 } else if (ieee->iw_mode == IW_MODE_ADHOC) {
637 /* not From/To DS: Addr1 = DA, Addr2 = SA,
638 Addr3 = BSSID */
639 memcpy(&header.addr1, dest, ETH_ALEN);
640 memcpy(&header.addr2, src, ETH_ALEN);
641 memcpy(&header.addr3, ieee->current_network.bssid, ETH_ALEN);
642 }
643 // printk(KERN_WARNING "essid MAC address is "MAC_FMT, MAC_ARG(&header.addr1));
644 header.frame_ctl = cpu_to_le16(fc);
645 //hdr_len = IEEE80211_3ADDR_LEN;
646
647 /* Determine fragmentation size based on destination (multicast
648 * and broadcast are not fragmented) */
649// if (is_multicast_ether_addr(dest) ||
650// is_broadcast_ether_addr(dest)) {
651 if (is_multicast_ether_addr(header.addr1) ||
652 is_broadcast_ether_addr(header.addr1)) {
653 frag_size = MAX_FRAG_THRESHOLD;
654 QOS_ctl = QOS_CTL_NOTCONTAIN_ACK;
655 }
656 else {
657 //printk(KERN_WARNING "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&frag_size = %d\n", frag_size);
658 frag_size = ieee->fts;//default:392
659 QOS_ctl = 0;
660 }
661
662 if (ieee->current_network.QoS_Enable) {
663 hdr_len = IEEE80211_3ADDR_LEN + 2;
664 QOS_ctl |= skb->priority; //set in the ieee80211_classify
665 header.QOS_ctl = cpu_to_le16(QOS_ctl);
666 } else {
667 hdr_len = IEEE80211_3ADDR_LEN;
668 }
669 //printk(KERN_WARNING "header size = %d, QOS_ctl = %x\n", hdr_len,QOS_ctl);
670 /* Determine amount of payload per fragment. Regardless of if
671 * this stack is providing the full 802.11 header, one will
672 * eventually be affixed to this fragment -- so we must account for
673 * it when determining the amount of payload space. */
674 //bytes_per_frag = frag_size - (IEEE80211_3ADDR_LEN + (ieee->current_network->QoS_Enable ? 2:0));
675 bytes_per_frag = frag_size - hdr_len;
676 if (ieee->config &
677 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
678 bytes_per_frag -= IEEE80211_FCS_LEN;
679
680 /* Each fragment may need to have room for encryptiong pre/postfix */
681 if (encrypt)
682 bytes_per_frag -= crypt->ops->extra_prefix_len +
683 crypt->ops->extra_postfix_len;
684
685 /* Number of fragments is the total bytes_per_frag /
686 * payload_per_fragment */
687 nr_frags = bytes / bytes_per_frag;
688 bytes_last_frag = bytes % bytes_per_frag;
689 if (bytes_last_frag)
690 nr_frags++;
691 else
692 bytes_last_frag = bytes_per_frag;
693
694 /* When we allocate the TXB we allocate enough space for the reserve
695 * and full fragment bytes (bytes_per_frag doesn't include prefix,
696 * postfix, header, FCS, etc.) */
697 txb = ieee80211_alloc_txb(nr_frags, frag_size, GFP_ATOMIC);
698 if (unlikely(!txb)) {
699 printk(KERN_WARNING "%s: Could not allocate TXB\n",
700 ieee->dev->name);
701 goto failed;
702 }
703 txb->encrypted = encrypt;
704 txb->payload_size = bytes;
705
706 for (i = 0; i < nr_frags; i++) {
707 skb_frag = txb->fragments[i];
708 skb_frag->priority = UP2AC(skb->priority);
709 if (encrypt)
710 skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
711
712 frag_hdr = (struct ieee80211_hdr_3addr_QOS *)skb_put(skb_frag, hdr_len);
713 memcpy(frag_hdr, &header, hdr_len);
714
715 /* If this is not the last fragment, then add the MOREFRAGS
716 * bit to the frame control */
717 if (i != nr_frags - 1) {
718 frag_hdr->frame_ctl = cpu_to_le16(
719 fc | IEEE80211_FCTL_MOREFRAGS);
720 bytes = bytes_per_frag;
721
722 } else {
723 /* The last fragment takes the remaining length */
724 bytes = bytes_last_frag;
725 }
726 if(ieee->current_network.QoS_Enable) {
727 // add 1 only indicate to corresponding seq number control 2006/7/12
728 frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[UP2AC(skb->priority)+1]<<4 | i);
729 //printk(KERN_WARNING "skb->priority = %d,", skb->priority);
730 //printk(KERN_WARNING "type:%d: seq = %d\n",UP2AC(skb->priority),ieee->seq_ctrl[UP2AC(skb->priority)+1]);
731 } else {
732 frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | i);
733 }
734 //frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl<<4 | i);
735 //
736
737 /* Put a SNAP header on the first fragment */
738 if (i == 0) {
739 ieee80211_put_snap(
740 skb_put(skb_frag, SNAP_SIZE + sizeof(u16)),
741 ether_type);
742 bytes -= SNAP_SIZE + sizeof(u16);
743 }
744
745 memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
746
747 /* Advance the SKB... */
748 skb_pull(skb, bytes);
749
750 /* Encryption routine will move the header forward in order
751 * to insert the IV between the header and the payload */
752 if (encrypt)
753 ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
754 if (ieee->config &
755 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
756 skb_put(skb_frag, 4);
757 }
758 // Advance sequence number in data frame.
759 //printk(KERN_WARNING "QoS Enalbed? %s\n", ieee->current_network.QoS_Enable?"Y":"N");
760 if (ieee->current_network.QoS_Enable) {
761 if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF)
762 ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0;
763 else
764 ieee->seq_ctrl[UP2AC(skb->priority) + 1]++;
765 } else {
766 if (ieee->seq_ctrl[0] == 0xFFF)
767 ieee->seq_ctrl[0] = 0;
768 else
769 ieee->seq_ctrl[0]++;
770 }
771 //---
772 }else{
773 if (unlikely(skb->len < sizeof(struct ieee80211_hdr_3addr))) {
774 printk(KERN_WARNING "%s: skb too small (%d).\n",
775 ieee->dev->name, skb->len);
776 goto success;
777 }
778
779 txb = ieee80211_alloc_txb(1, skb->len, GFP_ATOMIC);
780 if(!txb){
781 printk(KERN_WARNING "%s: Could not allocate TXB\n",
782 ieee->dev->name);
783 goto failed;
784 }
785
786 txb->encrypted = 0;
787 txb->payload_size = skb->len;
788 memcpy(skb_put(txb->fragments[0],skb->len), skb->data, skb->len);
789 }
790
791 success:
792 spin_unlock_irqrestore(&ieee->lock, flags);
793#ifdef _RTL8187_EXT_PATCH_
794 // Sometimes, extension mode can reuse skb (by txb->fragments[0])
795 if( ! ((ieee->iw_mode == ieee->iw_ext_mode) && txb && (txb->fragments[0] == skb)) )
796#endif
797 dev_kfree_skb_any(skb);
798 if (txb) {
799 if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE){
800 ieee80211_softmac_xmit(txb, ieee);
801 }else{
802 if ((*ieee->hard_start_xmit)(txb, dev) == 0) {
803 stats->tx_packets++;
804 stats->tx_bytes += txb->payload_size;
805 return 0;
806 }
807 ieee80211_txb_free(txb);
808 }
809 }
810
811 return 0;
812
813 failed:
814 spin_unlock_irqrestore(&ieee->lock, flags);
815 netif_stop_queue(dev);
816 stats->tx_errors++;
817 return 1;
818
819}
820
821#if 0
822EXPORT_SYMBOL(ieee80211_txb_free);
823#ifdef _RTL8187_EXT_PATCH_
824EXPORT_SYMBOL(ieee80211_alloc_txb);
825EXPORT_SYMBOL(ieee80211_ext_alloc_txb);
826EXPORT_SYMBOL(ieee80211_ext_reuse_txb);
827#endif // _RTL8187_EXT_PATCH_
828#endif
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c
new file mode 100644
index 000000000000..c7d9f4fda413
--- /dev/null
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c
@@ -0,0 +1,884 @@
1/******************************************************************************
2
3 Copyright(c) 2004 Intel Corporation. All rights reserved.
4
5 Portions of this file are based on the WEP enablement code provided by the
6 Host AP project hostap-drivers v0.1.3
7 Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
8 <jkmaline@cc.hut.fi>
9 Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
10
11 This program is free software; you can redistribute it and/or modify it
12 under the terms of version 2 of the GNU General Public License as
13 published by the Free Software Foundation.
14
15 This program is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18 more details.
19
20 You should have received a copy of the GNU General Public License along with
21 this program; if not, write to the Free Software Foundation, Inc., 59
22 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
24 The full GNU General Public License is included in this distribution in the
25 file called LICENSE.
26
27 Contact Information:
28 James P. Ketrenos <ipw2100-admin@linux.intel.com>
29 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30
31******************************************************************************/
32#include <linux/wireless.h>
33#include <linux/version.h>
34#include <linux/kmod.h>
35#include <linux/module.h>
36
37#include "ieee80211.h"
38static const char *ieee80211_modes[] = {
39 "?", "a", "b", "ab", "g", "ag", "bg", "abg"
40};
41
42#ifdef FEDORACORE_9
43#define IN_FEDORACORE_9 1
44#else
45#define IN_FEDORACORE_9 0
46#endif
47
48#define MAX_CUSTOM_LEN 64
49static inline char *rtl818x_translate_scan(struct ieee80211_device *ieee,
50 char *start, char *stop,
51 struct ieee80211_network *network,
52 struct iw_request_info *info)
53{
54 char custom[MAX_CUSTOM_LEN];
55 char *p;
56 struct iw_event iwe;
57 int i, j;
58 u8 max_rate, rate;
59
60 /* First entry *MUST* be the AP MAC address */
61 iwe.cmd = SIOCGIWAP;
62 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
63 memcpy(iwe.u.ap_addr.sa_data, network->bssid, ETH_ALEN);
64#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
65 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
66#else
67 start = iwe_stream_add_event(start, stop, &iwe, IW_EV_ADDR_LEN);
68#endif
69
70 /* Remaining entries will be displayed in the order we provide them */
71
72 /* Add the ESSID */
73 iwe.cmd = SIOCGIWESSID;
74 iwe.u.data.flags = 1;
75 //YJ,modified,080903,for hidden ap
76 //if (network->flags & NETWORK_EMPTY_ESSID) {
77 if (network->ssid_len == 0) {
78 //YJ,modified,080903,end
79 iwe.u.data.length = sizeof("<hidden>");
80#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
81 start = iwe_stream_add_point(info, start, stop, &iwe, "<hidden>");
82#else
83 start = iwe_stream_add_point(start, stop, &iwe, "<hidden>");
84#endif
85 } else {
86 iwe.u.data.length = min(network->ssid_len, (u8)32);
87#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
88 start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
89#else
90 start = iwe_stream_add_point(start, stop, &iwe, network->ssid);
91#endif
92 }
93 //printk("ESSID: %s\n",network->ssid);
94 /* Add the protocol name */
95 iwe.cmd = SIOCGIWNAME;
96 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11%s", ieee80211_modes[network->mode]);
97#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
98 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
99#else
100 start = iwe_stream_add_event(start, stop, &iwe, IW_EV_CHAR_LEN);
101#endif
102
103 /* Add mode */
104 iwe.cmd = SIOCGIWMODE;
105 if (network->capability &
106 (WLAN_CAPABILITY_BSS | WLAN_CAPABILITY_IBSS)) {
107 if (network->capability & WLAN_CAPABILITY_BSS)
108 iwe.u.mode = IW_MODE_MASTER;
109 else
110 iwe.u.mode = IW_MODE_ADHOC;
111
112#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
113 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_UINT_LEN);
114#else
115 start = iwe_stream_add_event(start, stop, &iwe, IW_EV_UINT_LEN);
116#endif
117 }
118
119 /* Add frequency/channel */
120 iwe.cmd = SIOCGIWFREQ;
121/* iwe.u.freq.m = ieee80211_frequency(network->channel, network->mode);
122 iwe.u.freq.e = 3; */
123 iwe.u.freq.m = network->channel;
124 iwe.u.freq.e = 0;
125 iwe.u.freq.i = 0;
126#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
127 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN);
128#else
129 start = iwe_stream_add_event(start, stop, &iwe, IW_EV_FREQ_LEN);
130#endif
131
132 /* Add encryption capability */
133 iwe.cmd = SIOCGIWENCODE;
134 if (network->capability & WLAN_CAPABILITY_PRIVACY)
135 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
136 else
137 iwe.u.data.flags = IW_ENCODE_DISABLED;
138 iwe.u.data.length = 0;
139#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
140 start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
141#else
142 start = iwe_stream_add_point(start, stop, &iwe, network->ssid);
143#endif
144
145 /* Add basic and extended rates */
146 max_rate = 0;
147 p = custom;
148 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
149 for (i = 0, j = 0; i < network->rates_len; ) {
150 if (j < network->rates_ex_len &&
151 ((network->rates_ex[j] & 0x7F) <
152 (network->rates[i] & 0x7F)))
153 rate = network->rates_ex[j++] & 0x7F;
154 else
155 rate = network->rates[i++] & 0x7F;
156 if (rate > max_rate)
157 max_rate = rate;
158 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
159 "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
160 }
161 for (; j < network->rates_ex_len; j++) {
162 rate = network->rates_ex[j] & 0x7F;
163 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
164 "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
165 if (rate > max_rate)
166 max_rate = rate;
167 }
168
169 iwe.cmd = SIOCGIWRATE;
170 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
171 iwe.u.bitrate.value = max_rate * 500000;
172#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
173 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_PARAM_LEN);
174#else
175 start = iwe_stream_add_event(start, stop, &iwe, IW_EV_PARAM_LEN);
176#endif
177
178 iwe.cmd = IWEVCUSTOM;
179 iwe.u.data.length = p - custom;
180 if (iwe.u.data.length)
181#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
182 start = iwe_stream_add_point(info, start, stop, &iwe, custom);
183#else
184 start = iwe_stream_add_point(start, stop, &iwe, custom);
185#endif
186
187 /* Add quality statistics */
188 /* TODO: Fix these values... */
189 if (network->stats.signal == 0 || network->stats.rssi == 0)
190 printk("========>signal:%d, rssi:%d\n", network->stats.signal, network->stats.rssi);
191 iwe.cmd = IWEVQUAL;
192// printk("SIGNAL: %d,RSSI: %d,NOISE: %d\n",network->stats.signal,network->stats.rssi,network->stats.noise);
193 iwe.u.qual.qual = network->stats.signalstrength;
194 iwe.u.qual.level = network->stats.signal;
195 iwe.u.qual.noise = network->stats.noise;
196 iwe.u.qual.updated = network->stats.mask & IEEE80211_STATMASK_WEMASK;
197 if (!(network->stats.mask & IEEE80211_STATMASK_RSSI))
198 iwe.u.qual.updated |= IW_QUAL_LEVEL_INVALID;
199 if (!(network->stats.mask & IEEE80211_STATMASK_NOISE))
200 iwe.u.qual.updated |= IW_QUAL_NOISE_INVALID;
201 if (!(network->stats.mask & IEEE80211_STATMASK_SIGNAL))
202 iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID;
203 iwe.u.qual.updated = 7;
204#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
205 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
206#else
207 start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN);
208#endif
209
210 iwe.cmd = IWEVCUSTOM;
211 p = custom;
212
213 iwe.u.data.length = p - custom;
214 if (iwe.u.data.length)
215#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
216 start = iwe_stream_add_point(info, start, stop, &iwe, custom);
217#else
218 start = iwe_stream_add_point(start, stop, &iwe, custom);
219#endif
220
221#if 0
222 if (ieee->wpa_enabled && network->wpa_ie_len){
223 char buf[MAX_WPA_IE_LEN * 2 + 30];
224 // printk("WPA IE\n");
225 u8 *p = buf;
226 p += sprintf(p, "wpa_ie=");
227 for (i = 0; i < network->wpa_ie_len; i++) {
228 p += sprintf(p, "%02x", network->wpa_ie[i]);
229 }
230
231 memset(&iwe, 0, sizeof(iwe));
232 iwe.cmd = IWEVCUSTOM;
233 iwe.u.data.length = strlen(buf);
234#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
235 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
236#else
237 start = iwe_stream_add_point(start, stop, &iwe, buf);
238#endif
239 }
240
241 if (ieee->wpa_enabled && network->rsn_ie_len){
242 char buf[MAX_WPA_IE_LEN * 2 + 30];
243
244 u8 *p = buf;
245 p += sprintf(p, "rsn_ie=");
246 for (i = 0; i < network->rsn_ie_len; i++) {
247 p += sprintf(p, "%02x", network->rsn_ie[i]);
248 }
249
250
251#else
252 memset(&iwe, 0, sizeof(iwe));
253 if (network->wpa_ie_len) {
254 // printk("wpa_ie_len:%d\n", network->wpa_ie_len);
255 char buf[MAX_WPA_IE_LEN];
256 memcpy(buf, network->wpa_ie, network->wpa_ie_len);
257 iwe.cmd = IWEVGENIE;
258 iwe.u.data.length = network->wpa_ie_len;
259#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
260 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
261#else
262 start = iwe_stream_add_point(start, stop, &iwe, buf);
263#endif
264 }
265
266 memset(&iwe, 0, sizeof(iwe));
267 if (network->rsn_ie_len) {
268 // printk("=====>rsn_ie_len:\n", network->rsn_ie_len);
269 #if 0
270 {
271 int i;
272 for (i=0; i<network->rsn_ie_len; i++);
273 printk("%2x ", network->rsn_ie[i]);
274 printk("\n");
275 }
276 #endif
277 char buf[MAX_WPA_IE_LEN];
278 memcpy(buf, network->rsn_ie, network->rsn_ie_len);
279 iwe.cmd = IWEVGENIE;
280 iwe.u.data.length = network->rsn_ie_len;
281#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
282 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
283#else
284 start = iwe_stream_add_point(start, stop, &iwe, buf);
285#endif
286 }
287
288#endif
289
290 /* Add EXTRA: Age to display seconds since last beacon/probe response
291 * for given network. */
292 iwe.cmd = IWEVCUSTOM;
293 p = custom;
294 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
295 " Last beacon: %lums ago", (jiffies - network->last_scanned) / (HZ / 100));
296 iwe.u.data.length = p - custom;
297 if (iwe.u.data.length)
298#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
299 start = iwe_stream_add_point(info, start, stop, &iwe, custom);
300#else
301 start = iwe_stream_add_point(start, stop, &iwe, custom);
302#endif
303
304 return start;
305}
306
307int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
308 struct iw_request_info *info,
309 union iwreq_data *wrqu, char *extra)
310{
311 struct ieee80211_network *network;
312 unsigned long flags;
313 int err = 0;
314 char *ev = extra;
315 char *stop = ev + wrqu->data.length;//IW_SCAN_MAX_DATA;
316 //char *stop = ev + IW_SCAN_MAX_DATA;
317 int i = 0;
318
319 IEEE80211_DEBUG_WX("Getting scan\n");
320 down(&ieee->wx_sem);
321 spin_lock_irqsave(&ieee->lock, flags);
322
323 if(!ieee->bHwRadioOff)
324 {
325 list_for_each_entry(network, &ieee->network_list, list) {
326 i++;
327
328 if((stop-ev)<200)
329 {
330 err = -E2BIG;
331 break;
332 }
333 if (ieee->scan_age == 0 ||
334 time_after(network->last_scanned + ieee->scan_age, jiffies))
335 {
336 ev = rtl818x_translate_scan(ieee, ev, stop, network, info);
337 }
338 else
339 IEEE80211_DEBUG_SCAN(
340 "Not showing network '%s ("
341 MAC_FMT ")' due to age (%lums).\n",
342 escape_essid(network->ssid,
343 network->ssid_len),
344 MAC_ARG(network->bssid),
345 (jiffies - network->last_scanned) / (HZ / 100));
346 }
347 }
348 spin_unlock_irqrestore(&ieee->lock, flags);
349 up(&ieee->wx_sem);
350 wrqu->data.length = ev - extra;
351 wrqu->data.flags = 0;
352 IEEE80211_DEBUG_WX("exit: %d networks returned.\n", i);
353
354 return err;
355}
356
357int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
358 struct iw_request_info *info,
359 union iwreq_data *wrqu, char *keybuf)
360{
361 struct iw_point *erq = &(wrqu->encoding);
362 struct net_device *dev = ieee->dev;
363 struct ieee80211_security sec = {
364 .flags = 0
365 };
366 int i, key, key_provided, len;
367 struct ieee80211_crypt_data **crypt;
368
369 IEEE80211_DEBUG_WX("SET_ENCODE\n");
370
371 key = erq->flags & IW_ENCODE_INDEX;
372 if (key) {
373 if (key > WEP_KEYS)
374 return -EINVAL;
375 key--;
376 key_provided = 1;
377 } else {
378 key_provided = 0;
379 key = ieee->tx_keyidx;
380 }
381
382 IEEE80211_DEBUG_WX("Key: %d [%s]\n", key, key_provided ?
383 "provided" : "default");
384
385 crypt = &ieee->crypt[key];
386
387 if (erq->flags & IW_ENCODE_DISABLED) {
388 if (key_provided && *crypt) {
389 IEEE80211_DEBUG_WX("Disabling encryption on key %d.\n",
390 key);
391 ieee80211_crypt_delayed_deinit(ieee, crypt);
392 } else
393 IEEE80211_DEBUG_WX("Disabling encryption.\n");
394
395 /* Check all the keys to see if any are still configured,
396 * and if no key index was provided, de-init them all */
397 for (i = 0; i < WEP_KEYS; i++) {
398 if (ieee->crypt[i] != NULL) {
399 if (key_provided)
400 break;
401 ieee80211_crypt_delayed_deinit(
402 ieee, &ieee->crypt[i]);
403 }
404 }
405
406 if (i == WEP_KEYS) {
407 sec.enabled = 0;
408 sec.level = SEC_LEVEL_0;
409 sec.flags |= SEC_ENABLED | SEC_LEVEL;
410 }
411
412 goto done;
413 }
414
415
416
417 sec.enabled = 1;
418 sec.flags |= SEC_ENABLED;
419
420 if (*crypt != NULL && (*crypt)->ops != NULL &&
421 strcmp((*crypt)->ops->name, "WEP") != 0) {
422 /* changing to use WEP; deinit previously used algorithm
423 * on this key */
424 ieee80211_crypt_delayed_deinit(ieee, crypt);
425 }
426
427 if (*crypt == NULL) {
428 struct ieee80211_crypt_data *new_crypt;
429
430 /* take WEP into use */
431 new_crypt = kmalloc(sizeof(struct ieee80211_crypt_data),
432 GFP_KERNEL);
433 if (new_crypt == NULL)
434 return -ENOMEM;
435 memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
436 new_crypt->ops = ieee80211_get_crypto_ops("WEP");
437 if (!new_crypt->ops) {
438 request_module("ieee80211_crypt_wep");
439 new_crypt->ops = ieee80211_get_crypto_ops("WEP");
440 }
441
442 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
443 new_crypt->priv = new_crypt->ops->init(key);
444
445 if (!new_crypt->ops || !new_crypt->priv) {
446 kfree(new_crypt);
447 new_crypt = NULL;
448
449 printk(KERN_WARNING "%s: could not initialize WEP: "
450 "load module ieee80211_crypt_wep\n",
451 dev->name);
452 return -EOPNOTSUPP;
453 }
454 *crypt = new_crypt;
455 }
456
457 /* If a new key was provided, set it up */
458 if (erq->length > 0) {
459 len = erq->length <= 5 ? 5 : 13;
460 memcpy(sec.keys[key], keybuf, erq->length);
461 if (len > erq->length)
462 memset(sec.keys[key] + erq->length, 0,
463 len - erq->length);
464 IEEE80211_DEBUG_WX("Setting key %d to '%s' (%d:%d bytes)\n",
465 key, escape_essid(sec.keys[key], len),
466 erq->length, len);
467 sec.key_sizes[key] = len;
468 (*crypt)->ops->set_key(sec.keys[key], len, NULL,
469 (*crypt)->priv);
470 sec.flags |= (1 << key);
471 /* This ensures a key will be activated if no key is
472 * explicitely set */
473 if (key == sec.active_key)
474 sec.flags |= SEC_ACTIVE_KEY;
475 ieee->tx_keyidx = key;//by wb 080312
476 } else {
477 len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN,
478 NULL, (*crypt)->priv);
479 if (len == 0) {
480 /* Set a default key of all 0 */
481 IEEE80211_DEBUG_WX("Setting key %d to all zero.\n",
482 key);
483 memset(sec.keys[key], 0, 13);
484 (*crypt)->ops->set_key(sec.keys[key], 13, NULL,
485 (*crypt)->priv);
486 sec.key_sizes[key] = 13;
487 sec.flags |= (1 << key);
488 }
489
490 /* No key data - just set the default TX key index */
491 if (key_provided) {
492 IEEE80211_DEBUG_WX(
493 "Setting key %d to default Tx key.\n", key);
494 ieee->tx_keyidx = key;
495 sec.active_key = key;
496 sec.flags |= SEC_ACTIVE_KEY;
497 }
498 }
499
500 done:
501 ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED);
502 sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
503 sec.flags |= SEC_AUTH_MODE;
504 IEEE80211_DEBUG_WX("Auth: %s\n", sec.auth_mode == WLAN_AUTH_OPEN ?
505 "OPEN" : "SHARED KEY");
506
507 /* For now we just support WEP, so only set that security level...
508 * TODO: When WPA is added this is one place that needs to change */
509 sec.flags |= SEC_LEVEL;
510 sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */
511
512 if (ieee->set_security)
513 ieee->set_security(dev, &sec);
514
515 /* Do not reset port if card is in Managed mode since resetting will
516 * generate new IEEE 802.11 authentication which may end up in looping
517 * with IEEE 802.1X. If your hardware requires a reset after WEP
518 * configuration (for example... Prism2), implement the reset_port in
519 * the callbacks structures used to initialize the 802.11 stack. */
520 if (ieee->reset_on_keychange &&
521 ieee->iw_mode != IW_MODE_INFRA &&
522 ieee->reset_port && ieee->reset_port(dev)) {
523 printk(KERN_DEBUG "%s: reset_port failed\n", dev->name);
524 return -EINVAL;
525 }
526 return 0;
527}
528
529int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
530 struct iw_request_info *info,
531 union iwreq_data *wrqu, char *keybuf)
532{
533 struct iw_point *erq = &(wrqu->encoding);
534 int len, key;
535 struct ieee80211_crypt_data *crypt;
536
537 IEEE80211_DEBUG_WX("GET_ENCODE\n");
538
539 if(ieee->iw_mode == IW_MODE_MONITOR)
540 return -1;
541
542 key = erq->flags & IW_ENCODE_INDEX;
543 if (key) {
544 if (key > WEP_KEYS)
545 return -EINVAL;
546 key--;
547 } else
548 key = ieee->tx_keyidx;
549
550 crypt = ieee->crypt[key];
551 erq->flags = key + 1;
552
553 if (crypt == NULL || crypt->ops == NULL) {
554 erq->length = 0;
555 erq->flags |= IW_ENCODE_DISABLED;
556 return 0;
557 }
558
559 if (strcmp(crypt->ops->name, "WEP") != 0) {
560 /* only WEP is supported with wireless extensions, so just
561 * report that encryption is used */
562 erq->length = 0;
563 erq->flags |= IW_ENCODE_ENABLED;
564 return 0;
565 }
566
567 len = crypt->ops->get_key(keybuf, WEP_KEY_LEN, NULL, crypt->priv);
568 erq->length = (len >= 0 ? len : 0);
569
570 erq->flags |= IW_ENCODE_ENABLED;
571
572 if (ieee->open_wep)
573 erq->flags |= IW_ENCODE_OPEN;
574 else
575 erq->flags |= IW_ENCODE_RESTRICTED;
576
577 return 0;
578}
579
580int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
581 struct iw_request_info *info,
582 union iwreq_data *wrqu, char *extra)
583{
584 struct net_device *dev = ieee->dev;
585 struct iw_point *encoding = &wrqu->encoding;
586 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
587 int i, idx, ret = 0;
588 int group_key = 0;
589 const char *alg, *module;
590 struct ieee80211_crypto_ops *ops;
591 struct ieee80211_crypt_data **crypt;
592
593 struct ieee80211_security sec = {
594 .flags = 0,
595 };
596 //printk("======>encoding flag:%x,ext flag:%x, ext alg:%d\n", encoding->flags,ext->ext_flags, ext->alg);
597 idx = encoding->flags & IW_ENCODE_INDEX;
598 if (idx) {
599 if (idx < 1 || idx > WEP_KEYS)
600 return -EINVAL;
601 idx--;
602 } else
603 idx = ieee->tx_keyidx;
604
605 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
606 crypt = &ieee->crypt[idx];
607 group_key = 1;
608 } else {
609 /* some Cisco APs use idx>0 for unicast in dynamic WEP */
610 //printk("not group key, flags:%x, ext->alg:%d\n", ext->ext_flags, ext->alg);
611 if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP)
612 return -EINVAL;
613 if (ieee->iw_mode == IW_MODE_INFRA)
614 crypt = &ieee->crypt[idx];
615 else
616 return -EINVAL;
617 }
618
619 sec.flags |= SEC_ENABLED;// | SEC_ENCRYPT;
620 if ((encoding->flags & IW_ENCODE_DISABLED) ||
621 ext->alg == IW_ENCODE_ALG_NONE) {
622 if (*crypt)
623 ieee80211_crypt_delayed_deinit(ieee, crypt);
624
625 for (i = 0; i < WEP_KEYS; i++)
626 if (ieee->crypt[i] != NULL)
627 break;
628
629 if (i == WEP_KEYS) {
630 sec.enabled = 0;
631 // sec.encrypt = 0;
632 sec.level = SEC_LEVEL_0;
633 sec.flags |= SEC_LEVEL;
634 }
635 //printk("disabled: flag:%x\n", encoding->flags);
636 goto done;
637 }
638
639 sec.enabled = 1;
640 // sec.encrypt = 1;
641#if 0
642 if (group_key ? !ieee->host_mc_decrypt :
643 !(ieee->host_encrypt || ieee->host_decrypt ||
644 ieee->host_encrypt_msdu))
645 goto skip_host_crypt;
646#endif
647 switch (ext->alg) {
648 case IW_ENCODE_ALG_WEP:
649 alg = "WEP";
650 module = "ieee80211_crypt_wep";
651 break;
652 case IW_ENCODE_ALG_TKIP:
653 alg = "TKIP";
654 module = "ieee80211_crypt_tkip";
655 break;
656 case IW_ENCODE_ALG_CCMP:
657 alg = "CCMP";
658 module = "ieee80211_crypt_ccmp";
659 break;
660 default:
661 IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
662 dev->name, ext->alg);
663 ret = -EINVAL;
664 goto done;
665 }
666// printk("8-09-08-9=====>%s, alg name:%s\n",__FUNCTION__, alg);
667
668 ops = ieee80211_get_crypto_ops(alg);
669 if (ops == NULL) {
670 request_module(module);
671 ops = ieee80211_get_crypto_ops(alg);
672 }
673 if (ops == NULL) {
674 IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
675 dev->name, ext->alg);
676 printk("========>unknown crypto alg %d\n", ext->alg);
677 ret = -EINVAL;
678 goto done;
679 }
680
681 if (*crypt == NULL || (*crypt)->ops != ops) {
682 struct ieee80211_crypt_data *new_crypt;
683
684 ieee80211_crypt_delayed_deinit(ieee, crypt);
685
686 new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
687 if (new_crypt == NULL) {
688 ret = -ENOMEM;
689 goto done;
690 }
691 new_crypt->ops = ops;
692 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
693 new_crypt->priv = new_crypt->ops->init(idx);
694 if (new_crypt->priv == NULL) {
695 kfree(new_crypt);
696 ret = -EINVAL;
697 goto done;
698 }
699 *crypt = new_crypt;
700
701 }
702
703 if (ext->key_len > 0 && (*crypt)->ops->set_key &&
704 (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq,
705 (*crypt)->priv) < 0) {
706 IEEE80211_DEBUG_WX("%s: key setting failed\n", dev->name);
707 printk("key setting failed\n");
708 ret = -EINVAL;
709 goto done;
710 }
711#if 1
712 //skip_host_crypt:
713 //printk("skip_host_crypt:ext_flags:%x\n", ext->ext_flags);
714 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
715 ieee->tx_keyidx = idx;
716 sec.active_key = idx;
717 sec.flags |= SEC_ACTIVE_KEY;
718 }
719
720 if (ext->alg != IW_ENCODE_ALG_NONE) {
721 memcpy(sec.keys[idx], ext->key, ext->key_len);
722 sec.key_sizes[idx] = ext->key_len;
723 sec.flags |= (1 << idx);
724 if (ext->alg == IW_ENCODE_ALG_WEP) {
725 // sec.encode_alg[idx] = SEC_ALG_WEP;
726 sec.flags |= SEC_LEVEL;
727 sec.level = SEC_LEVEL_1;
728 } else if (ext->alg == IW_ENCODE_ALG_TKIP) {
729 // sec.encode_alg[idx] = SEC_ALG_TKIP;
730 sec.flags |= SEC_LEVEL;
731 sec.level = SEC_LEVEL_2;
732 } else if (ext->alg == IW_ENCODE_ALG_CCMP) {
733 // sec.encode_alg[idx] = SEC_ALG_CCMP;
734 sec.flags |= SEC_LEVEL;
735 sec.level = SEC_LEVEL_3;
736 }
737 /* Don't set sec level for group keys. */
738 if (group_key)
739 sec.flags &= ~SEC_LEVEL;
740 }
741#endif
742done:
743 if (ieee->set_security)
744 ieee->set_security(ieee->dev, &sec);
745
746 if (ieee->reset_on_keychange &&
747 ieee->iw_mode != IW_MODE_INFRA &&
748 ieee->reset_port && ieee->reset_port(dev)) {
749 IEEE80211_DEBUG_WX("%s: reset_port failed\n", dev->name);
750 return -EINVAL;
751 }
752
753 return ret;
754}
755int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
756 struct iw_request_info *info,
757 union iwreq_data *wrqu, char *extra)
758{
759 struct iw_mlme *mlme = (struct iw_mlme *) extra;
760// printk("\ndkgadfslkdjgalskdf===============>%s(), cmd:%x\n", __FUNCTION__, mlme->cmd);
761#if 1
762 switch (mlme->cmd) {
763 case IW_MLME_DEAUTH:
764 case IW_MLME_DISASSOC:
765 // printk("disassoc now\n");
766 ieee80211_disassociate(ieee);
767 break;
768 default:
769 return -EOPNOTSUPP;
770 }
771#endif
772 return 0;
773}
774
775int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
776 struct iw_request_info *info,
777 struct iw_param *data, char *extra)
778{
779/*
780 struct ieee80211_security sec = {
781 .flags = SEC_AUTH_MODE,
782 }
783*/
784 //printk("set auth:flag:%x, data value:%x\n", data->flags, data->value);
785 switch (data->flags & IW_AUTH_INDEX) {
786 case IW_AUTH_WPA_VERSION:
787 /*need to support wpa2 here*/
788 //printk("wpa version:%x\n", data->value);
789 break;
790 case IW_AUTH_CIPHER_PAIRWISE:
791 case IW_AUTH_CIPHER_GROUP:
792 case IW_AUTH_KEY_MGMT:
793 /*
794 * * Host AP driver does not use these parameters and allows
795 * * wpa_supplicant to control them internally.
796 * */
797 break;
798 case IW_AUTH_TKIP_COUNTERMEASURES:
799 ieee->tkip_countermeasures = data->value;
800 break;
801 case IW_AUTH_DROP_UNENCRYPTED:
802 ieee->drop_unencrypted = data->value;
803 break;
804
805 case IW_AUTH_80211_AUTH_ALG:
806 ieee->open_wep = (data->value&IW_AUTH_ALG_OPEN_SYSTEM)?1:0;
807 //printk("open_wep:%d\n", ieee->open_wep);
808 break;
809
810#if 1
811 case IW_AUTH_WPA_ENABLED:
812 ieee->wpa_enabled = (data->value)?1:0;
813 //printk("enalbe wpa:%d\n", ieee->wpa_enabled);
814 break;
815
816#endif
817 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
818 ieee->ieee802_1x = data->value;
819 break;
820 case IW_AUTH_PRIVACY_INVOKED:
821 ieee->privacy_invoked = data->value;
822 break;
823 default:
824 return -EOPNOTSUPP;
825 }
826 return 0;
827}
828
829#if 1
830int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len)
831{
832#if 0
833 printk("====>%s()\n", __FUNCTION__);
834 {
835 int i;
836 for (i=0; i<len; i++)
837 printk("%2x ", ie[i]&0xff);
838 printk("\n");
839 }
840#endif
841 u8 *buf = NULL;
842
843 if (len>MAX_WPA_IE_LEN || (len && ie == NULL))
844 {
845 printk("return error out, len:%d\n", len);
846 return -EINVAL;
847 }
848
849 if (len)
850 {
851 if (len != ie[1]+2){
852 printk("len:%d, ie:%d\n", len, ie[1]);
853 return -EINVAL;
854 }
855 buf = kmalloc(len, GFP_KERNEL);
856 if (buf == NULL)
857 return -ENOMEM;
858 memcpy(buf, ie, len);
859 kfree(ieee->wpa_ie);
860 ieee->wpa_ie = buf;
861 ieee->wpa_ie_len = len;
862 }
863 else{
864 if (ieee->wpa_ie)
865 kfree(ieee->wpa_ie);
866 ieee->wpa_ie = NULL;
867 ieee->wpa_ie_len = 0;
868 }
869// printk("<=====out %s()\n", __FUNCTION__);
870
871 return 0;
872
873}
874#endif
875
876#if 0
877EXPORT_SYMBOL(ieee80211_wx_set_gen_ie);
878EXPORT_SYMBOL(ieee80211_wx_set_mlme);
879EXPORT_SYMBOL(ieee80211_wx_set_auth);
880EXPORT_SYMBOL(ieee80211_wx_set_encode_ext);
881EXPORT_SYMBOL(ieee80211_wx_get_scan);
882EXPORT_SYMBOL(ieee80211_wx_set_encode);
883EXPORT_SYMBOL(ieee80211_wx_get_encode);
884#endif
diff --git a/drivers/staging/rtl8187se/ieee80211/internal.h b/drivers/staging/rtl8187se/ieee80211/internal.h
new file mode 100644
index 000000000000..ddc22350d006
--- /dev/null
+++ b/drivers/staging/rtl8187se/ieee80211/internal.h
@@ -0,0 +1,115 @@
1/*
2 * Cryptographic API.
3 *
4 * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
9 * any later version.
10 *
11 */
12#ifndef _CRYPTO_INTERNAL_H
13#define _CRYPTO_INTERNAL_H
14
15
16//#include <linux/crypto.h>
17#include "rtl_crypto.h"
18#include <linux/mm.h>
19#include <linux/highmem.h>
20#include <linux/init.h>
21#include <asm/hardirq.h>
22#include <asm/softirq.h>
23#include <asm/kmap_types.h>
24
25#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,20))
26#define list_for_each_entry(pos, head, member) \
27 for (pos = list_entry((head)->next, typeof(*pos), member), \
28 prefetch(pos->member.next); \
29 &pos->member != (head); \
30 pos = list_entry(pos->member.next, typeof(*pos), member), \
31 prefetch(pos->member.next))
32
33static inline void cond_resched(void)
34{
35 if (need_resched()) {
36 set_current_state(TASK_RUNNING);
37 schedule();
38 }
39}
40#endif
41
42extern enum km_type crypto_km_types[];
43
44static inline enum km_type crypto_kmap_type(int out)
45{
46 return crypto_km_types[(in_softirq() ? 2 : 0) + out];
47}
48
49static inline void *crypto_kmap(struct page *page, int out)
50{
51 return kmap_atomic(page, crypto_kmap_type(out));
52}
53
54static inline void crypto_kunmap(void *vaddr, int out)
55{
56 kunmap_atomic(vaddr, crypto_kmap_type(out));
57}
58
59static inline void crypto_yield(struct crypto_tfm *tfm)
60{
61 if (!in_softirq())
62 cond_resched();
63}
64
65static inline void *crypto_tfm_ctx(struct crypto_tfm *tfm)
66{
67 return (void *)&tfm[1];
68}
69
70struct crypto_alg *crypto_alg_lookup(const char *name);
71
72#ifdef CONFIG_KMOD
73void crypto_alg_autoload(const char *name);
74struct crypto_alg *crypto_alg_mod_lookup(const char *name);
75#else
76static inline struct crypto_alg *crypto_alg_mod_lookup(const char *name)
77{
78 return crypto_alg_lookup(name);
79}
80#endif
81
82#ifdef CONFIG_CRYPTO_HMAC
83int crypto_alloc_hmac_block(struct crypto_tfm *tfm);
84void crypto_free_hmac_block(struct crypto_tfm *tfm);
85#else
86static inline int crypto_alloc_hmac_block(struct crypto_tfm *tfm)
87{
88 return 0;
89}
90
91static inline void crypto_free_hmac_block(struct crypto_tfm *tfm)
92{ }
93#endif
94
95#ifdef CONFIG_PROC_FS
96void __init crypto_init_proc(void);
97#else
98static inline void crypto_init_proc(void)
99{ }
100#endif
101
102int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags);
103int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags);
104int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags);
105
106int crypto_init_digest_ops(struct crypto_tfm *tfm);
107int crypto_init_cipher_ops(struct crypto_tfm *tfm);
108int crypto_init_compress_ops(struct crypto_tfm *tfm);
109
110void crypto_exit_digest_ops(struct crypto_tfm *tfm);
111void crypto_exit_cipher_ops(struct crypto_tfm *tfm);
112void crypto_exit_compress_ops(struct crypto_tfm *tfm);
113
114#endif /* _CRYPTO_INTERNAL_H */
115
diff --git a/drivers/staging/rtl8187se/ieee80211/kmap_types.h b/drivers/staging/rtl8187se/ieee80211/kmap_types.h
new file mode 100644
index 000000000000..de67bb01b5f5
--- /dev/null
+++ b/drivers/staging/rtl8187se/ieee80211/kmap_types.h
@@ -0,0 +1,20 @@
1#ifndef __KMAP_TYPES_H
2
3#define __KMAP_TYPES_H
4
5
6enum km_type {
7 KM_BOUNCE_READ,
8 KM_SKB_SUNRPC_DATA,
9 KM_SKB_DATA_SOFTIRQ,
10 KM_USER0,
11 KM_USER1,
12 KM_BH_IRQ,
13 KM_SOFTIRQ0,
14 KM_SOFTIRQ1,
15 KM_TYPE_NR
16};
17
18#define _ASM_KMAP_TYPES_H
19
20#endif
diff --git a/drivers/staging/rtl8187se/ieee80211/michael_mic.c b/drivers/staging/rtl8187se/ieee80211/michael_mic.c
new file mode 100644
index 000000000000..df256e487c20
--- /dev/null
+++ b/drivers/staging/rtl8187se/ieee80211/michael_mic.c
@@ -0,0 +1,194 @@
1/*
2 * Cryptographic API
3 *
4 * Michael MIC (IEEE 802.11i/TKIP) keyed digest
5 *
6 * Copyright (c) 2004 Jouni Malinen <jkmaline@cc.hut.fi>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/init.h>
14#include <linux/module.h>
15#include <linux/string.h>
16//#include <linux/crypto.h>
17#include "rtl_crypto.h"
18
19
20struct michael_mic_ctx {
21 u8 pending[4];
22 size_t pending_len;
23
24 u32 l, r;
25};
26
27
28static inline u32 rotl(u32 val, int bits)
29{
30 return (val << bits) | (val >> (32 - bits));
31}
32
33
34static inline u32 rotr(u32 val, int bits)
35{
36 return (val >> bits) | (val << (32 - bits));
37}
38
39
40static inline u32 xswap(u32 val)
41{
42 return ((val & 0x00ff00ff) << 8) | ((val & 0xff00ff00) >> 8);
43}
44
45
46#define michael_block(l, r) \
47do { \
48 r ^= rotl(l, 17); \
49 l += r; \
50 r ^= xswap(l); \
51 l += r; \
52 r ^= rotl(l, 3); \
53 l += r; \
54 r ^= rotr(l, 2); \
55 l += r; \
56} while (0)
57
58
59static inline u32 get_le32(const u8 *p)
60{
61 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
62}
63
64
65static inline void put_le32(u8 *p, u32 v)
66{
67 p[0] = v;
68 p[1] = v >> 8;
69 p[2] = v >> 16;
70 p[3] = v >> 24;
71}
72
73
74static void michael_init(void *ctx)
75{
76 struct michael_mic_ctx *mctx = ctx;
77 mctx->pending_len = 0;
78}
79
80
81static void michael_update(void *ctx, const u8 *data, unsigned int len)
82{
83 struct michael_mic_ctx *mctx = ctx;
84
85 if (mctx->pending_len) {
86 int flen = 4 - mctx->pending_len;
87 if (flen > len)
88 flen = len;
89 memcpy(&mctx->pending[mctx->pending_len], data, flen);
90 mctx->pending_len += flen;
91 data += flen;
92 len -= flen;
93
94 if (mctx->pending_len < 4)
95 return;
96
97 mctx->l ^= get_le32(mctx->pending);
98 michael_block(mctx->l, mctx->r);
99 mctx->pending_len = 0;
100 }
101
102 while (len >= 4) {
103 mctx->l ^= get_le32(data);
104 michael_block(mctx->l, mctx->r);
105 data += 4;
106 len -= 4;
107 }
108
109 if (len > 0) {
110 mctx->pending_len = len;
111 memcpy(mctx->pending, data, len);
112 }
113}
114
115
116static void michael_final(void *ctx, u8 *out)
117{
118 struct michael_mic_ctx *mctx = ctx;
119 u8 *data = mctx->pending;
120
121 /* Last block and padding (0x5a, 4..7 x 0) */
122 switch (mctx->pending_len) {
123 case 0:
124 mctx->l ^= 0x5a;
125 break;
126 case 1:
127 mctx->l ^= data[0] | 0x5a00;
128 break;
129 case 2:
130 mctx->l ^= data[0] | (data[1] << 8) | 0x5a0000;
131 break;
132 case 3:
133 mctx->l ^= data[0] | (data[1] << 8) | (data[2] << 16) |
134 0x5a000000;
135 break;
136 }
137 michael_block(mctx->l, mctx->r);
138 /* l ^= 0; */
139 michael_block(mctx->l, mctx->r);
140
141 put_le32(out, mctx->l);
142 put_le32(out + 4, mctx->r);
143}
144
145
146static int michael_setkey(void *ctx, const u8 *key, unsigned int keylen,
147 u32 *flags)
148{
149 struct michael_mic_ctx *mctx = ctx;
150 if (keylen != 8) {
151 if (flags)
152 *flags = CRYPTO_TFM_RES_BAD_KEY_LEN;
153 return -EINVAL;
154 }
155 mctx->l = get_le32(key);
156 mctx->r = get_le32(key + 4);
157 return 0;
158}
159
160
161static struct crypto_alg michael_mic_alg = {
162 .cra_name = "michael_mic",
163 .cra_flags = CRYPTO_ALG_TYPE_DIGEST,
164 .cra_blocksize = 8,
165 .cra_ctxsize = sizeof(struct michael_mic_ctx),
166 .cra_module = THIS_MODULE,
167 .cra_list = LIST_HEAD_INIT(michael_mic_alg.cra_list),
168 .cra_u = { .digest = {
169 .dia_digestsize = 8,
170 .dia_init = michael_init,
171 .dia_update = michael_update,
172 .dia_final = michael_final,
173 .dia_setkey = michael_setkey } }
174};
175
176
177static int __init michael_mic_init(void)
178{
179 return crypto_register_alg(&michael_mic_alg);
180}
181
182
183static void __exit michael_mic_exit(void)
184{
185 crypto_unregister_alg(&michael_mic_alg);
186}
187
188
189module_init(michael_mic_init);
190module_exit(michael_mic_exit);
191
192MODULE_LICENSE("GPL v2");
193MODULE_DESCRIPTION("Michael MIC");
194MODULE_AUTHOR("Jouni Malinen <jkmaline@cc.hut.fi>");
diff --git a/drivers/staging/rtl8187se/ieee80211/proc.c b/drivers/staging/rtl8187se/ieee80211/proc.c
new file mode 100644
index 000000000000..4f3f9ed7751a
--- /dev/null
+++ b/drivers/staging/rtl8187se/ieee80211/proc.c
@@ -0,0 +1,116 @@
1/*
2 * Scatterlist Cryptographic API.
3 *
4 * Procfs information.
5 *
6 * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 *
13 */
14#include <linux/init.h>
15//#include <linux/crypto.h>
16#include "rtl_crypto.h"
17#include <linux/rwsem.h>
18#include <linux/proc_fs.h>
19#include <linux/seq_file.h>
20#include "internal.h"
21
22extern struct list_head crypto_alg_list;
23extern struct rw_semaphore crypto_alg_sem;
24
25static void *c_start(struct seq_file *m, loff_t *pos)
26{
27 struct list_head *v;
28 loff_t n = *pos;
29
30 down_read(&crypto_alg_sem);
31 list_for_each(v, &crypto_alg_list)
32 if (!n--)
33 return list_entry(v, struct crypto_alg, cra_list);
34 return NULL;
35}
36
37static void *c_next(struct seq_file *m, void *p, loff_t *pos)
38{
39 struct list_head *v = p;
40
41 (*pos)++;
42 v = v->next;
43 return (v == &crypto_alg_list) ?
44 NULL : list_entry(v, struct crypto_alg, cra_list);
45}
46
47static void c_stop(struct seq_file *m, void *p)
48{
49 up_read(&crypto_alg_sem);
50}
51
52static int c_show(struct seq_file *m, void *p)
53{
54 struct crypto_alg *alg = (struct crypto_alg *)p;
55
56 seq_printf(m, "name : %s\n", alg->cra_name);
57 seq_printf(m, "module : %s\n",
58 (alg->cra_module ?
59 alg->cra_module->name :
60 "kernel"));
61
62 switch (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) {
63 case CRYPTO_ALG_TYPE_CIPHER:
64 seq_printf(m, "type : cipher\n");
65 seq_printf(m, "blocksize : %u\n", alg->cra_blocksize);
66 seq_printf(m, "min keysize : %u\n",
67 alg->cra_cipher.cia_min_keysize);
68 seq_printf(m, "max keysize : %u\n",
69 alg->cra_cipher.cia_max_keysize);
70 break;
71
72 case CRYPTO_ALG_TYPE_DIGEST:
73 seq_printf(m, "type : digest\n");
74 seq_printf(m, "blocksize : %u\n", alg->cra_blocksize);
75 seq_printf(m, "digestsize : %u\n",
76 alg->cra_digest.dia_digestsize);
77 break;
78 case CRYPTO_ALG_TYPE_COMPRESS:
79 seq_printf(m, "type : compression\n");
80 break;
81 default:
82 seq_printf(m, "type : unknown\n");
83 break;
84 }
85
86 seq_putc(m, '\n');
87 return 0;
88}
89
90static struct seq_operations crypto_seq_ops = {
91 .start = c_start,
92 .next = c_next,
93 .stop = c_stop,
94 .show = c_show
95};
96
97static int crypto_info_open(struct inode *inode, struct file *file)
98{
99 return seq_open(file, &crypto_seq_ops);
100}
101
102static struct file_operations proc_crypto_ops = {
103 .open = crypto_info_open,
104 .read = seq_read,
105 .llseek = seq_lseek,
106 .release = seq_release
107};
108
109void __init crypto_init_proc(void)
110{
111 struct proc_dir_entry *proc;
112
113 proc = create_proc_entry("crypto", 0, NULL);
114 if (proc)
115 proc->proc_fops = &proc_crypto_ops;
116}
diff --git a/drivers/staging/rtl8187se/ieee80211/rtl_crypto.h b/drivers/staging/rtl8187se/ieee80211/rtl_crypto.h
new file mode 100644
index 000000000000..9ed0ca420857
--- /dev/null
+++ b/drivers/staging/rtl8187se/ieee80211/rtl_crypto.h
@@ -0,0 +1,399 @@
1/*
2 * Scatterlist Cryptographic API.
3 *
4 * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
5 * Copyright (c) 2002 David S. Miller (davem@redhat.com)
6 *
7 * Portions derived from Cryptoapi, by Alexander Kjeldaas <astor@fast.no>
8 * and Nettle, by Niels Mé°ˆler.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the Free
12 * Software Foundation; either version 2 of the License, or (at your option)
13 * any later version.
14 *
15 */
16#ifndef _LINUX_CRYPTO_H
17#define _LINUX_CRYPTO_H
18
19#include <linux/module.h>
20#include <linux/kernel.h>
21#include <linux/types.h>
22#include <linux/list.h>
23#include <linux/string.h>
24#include <asm/page.h>
25#include <asm/errno.h>
26
27#define crypto_register_alg crypto_register_alg_rtl
28#define crypto_unregister_alg crypto_unregister_alg_rtl
29#define crypto_alloc_tfm crypto_alloc_tfm_rtl
30#define crypto_free_tfm crypto_free_tfm_rtl
31#define crypto_alg_available crypto_alg_available_rtl
32
33/*
34 * Algorithm masks and types.
35 */
36#define CRYPTO_ALG_TYPE_MASK 0x000000ff
37#define CRYPTO_ALG_TYPE_CIPHER 0x00000001
38#define CRYPTO_ALG_TYPE_DIGEST 0x00000002
39#define CRYPTO_ALG_TYPE_COMPRESS 0x00000004
40
41/*
42 * Transform masks and values (for crt_flags).
43 */
44#define CRYPTO_TFM_MODE_MASK 0x000000ff
45#define CRYPTO_TFM_REQ_MASK 0x000fff00
46#define CRYPTO_TFM_RES_MASK 0xfff00000
47
48#define CRYPTO_TFM_MODE_ECB 0x00000001
49#define CRYPTO_TFM_MODE_CBC 0x00000002
50#define CRYPTO_TFM_MODE_CFB 0x00000004
51#define CRYPTO_TFM_MODE_CTR 0x00000008
52
53#define CRYPTO_TFM_REQ_WEAK_KEY 0x00000100
54#define CRYPTO_TFM_RES_WEAK_KEY 0x00100000
55#define CRYPTO_TFM_RES_BAD_KEY_LEN 0x00200000
56#define CRYPTO_TFM_RES_BAD_KEY_SCHED 0x00400000
57#define CRYPTO_TFM_RES_BAD_BLOCK_LEN 0x00800000
58#define CRYPTO_TFM_RES_BAD_FLAGS 0x01000000
59
60/*
61 * Miscellaneous stuff.
62 */
63#define CRYPTO_UNSPEC 0
64#define CRYPTO_MAX_ALG_NAME 64
65
66struct scatterlist;
67
68/*
69 * Algorithms: modular crypto algorithm implementations, managed
70 * via crypto_register_alg() and crypto_unregister_alg().
71 */
72struct cipher_alg {
73 unsigned int cia_min_keysize;
74 unsigned int cia_max_keysize;
75 int (*cia_setkey)(void *ctx, const u8 *key,
76 unsigned int keylen, u32 *flags);
77 void (*cia_encrypt)(void *ctx, u8 *dst, const u8 *src);
78 void (*cia_decrypt)(void *ctx, u8 *dst, const u8 *src);
79};
80
81struct digest_alg {
82 unsigned int dia_digestsize;
83 void (*dia_init)(void *ctx);
84 void (*dia_update)(void *ctx, const u8 *data, unsigned int len);
85 void (*dia_final)(void *ctx, u8 *out);
86 int (*dia_setkey)(void *ctx, const u8 *key,
87 unsigned int keylen, u32 *flags);
88};
89
90struct compress_alg {
91 int (*coa_init)(void *ctx);
92 void (*coa_exit)(void *ctx);
93 int (*coa_compress)(void *ctx, const u8 *src, unsigned int slen,
94 u8 *dst, unsigned int *dlen);
95 int (*coa_decompress)(void *ctx, const u8 *src, unsigned int slen,
96 u8 *dst, unsigned int *dlen);
97};
98
99#define cra_cipher cra_u.cipher
100#define cra_digest cra_u.digest
101#define cra_compress cra_u.compress
102
103struct crypto_alg {
104 struct list_head cra_list;
105 u32 cra_flags;
106 unsigned int cra_blocksize;
107 unsigned int cra_ctxsize;
108 const char cra_name[CRYPTO_MAX_ALG_NAME];
109
110 union {
111 struct cipher_alg cipher;
112 struct digest_alg digest;
113 struct compress_alg compress;
114 } cra_u;
115
116 struct module *cra_module;
117};
118
119/*
120 * Algorithm registration interface.
121 */
122int crypto_register_alg(struct crypto_alg *alg);
123int crypto_unregister_alg(struct crypto_alg *alg);
124
125/*
126 * Algorithm query interface.
127 */
128int crypto_alg_available(const char *name, u32 flags);
129
130/*
131 * Transforms: user-instantiated objects which encapsulate algorithms
132 * and core processing logic. Managed via crypto_alloc_tfm() and
133 * crypto_free_tfm(), as well as the various helpers below.
134 */
135struct crypto_tfm;
136
137struct cipher_tfm {
138 void *cit_iv;
139 unsigned int cit_ivsize;
140 u32 cit_mode;
141 int (*cit_setkey)(struct crypto_tfm *tfm,
142 const u8 *key, unsigned int keylen);
143 int (*cit_encrypt)(struct crypto_tfm *tfm,
144 struct scatterlist *dst,
145 struct scatterlist *src,
146 unsigned int nbytes);
147 int (*cit_encrypt_iv)(struct crypto_tfm *tfm,
148 struct scatterlist *dst,
149 struct scatterlist *src,
150 unsigned int nbytes, u8 *iv);
151 int (*cit_decrypt)(struct crypto_tfm *tfm,
152 struct scatterlist *dst,
153 struct scatterlist *src,
154 unsigned int nbytes);
155 int (*cit_decrypt_iv)(struct crypto_tfm *tfm,
156 struct scatterlist *dst,
157 struct scatterlist *src,
158 unsigned int nbytes, u8 *iv);
159 void (*cit_xor_block)(u8 *dst, const u8 *src);
160};
161
162struct digest_tfm {
163 void (*dit_init)(struct crypto_tfm *tfm);
164 void (*dit_update)(struct crypto_tfm *tfm,
165 struct scatterlist *sg, unsigned int nsg);
166 void (*dit_final)(struct crypto_tfm *tfm, u8 *out);
167 void (*dit_digest)(struct crypto_tfm *tfm, struct scatterlist *sg,
168 unsigned int nsg, u8 *out);
169 int (*dit_setkey)(struct crypto_tfm *tfm,
170 const u8 *key, unsigned int keylen);
171#ifdef CONFIG_CRYPTO_HMAC
172 void *dit_hmac_block;
173#endif
174};
175
176struct compress_tfm {
177 int (*cot_compress)(struct crypto_tfm *tfm,
178 const u8 *src, unsigned int slen,
179 u8 *dst, unsigned int *dlen);
180 int (*cot_decompress)(struct crypto_tfm *tfm,
181 const u8 *src, unsigned int slen,
182 u8 *dst, unsigned int *dlen);
183};
184
185#define crt_cipher crt_u.cipher
186#define crt_digest crt_u.digest
187#define crt_compress crt_u.compress
188
189struct crypto_tfm {
190
191 u32 crt_flags;
192
193 union {
194 struct cipher_tfm cipher;
195 struct digest_tfm digest;
196 struct compress_tfm compress;
197 } crt_u;
198
199 struct crypto_alg *__crt_alg;
200};
201
202/*
203 * Transform user interface.
204 */
205
206/*
207 * crypto_alloc_tfm() will first attempt to locate an already loaded algorithm.
208 * If that fails and the kernel supports dynamically loadable modules, it
209 * will then attempt to load a module of the same name or alias. A refcount
210 * is grabbed on the algorithm which is then associated with the new transform.
211 *
212 * crypto_free_tfm() frees up the transform and any associated resources,
213 * then drops the refcount on the associated algorithm.
214 */
215struct crypto_tfm *crypto_alloc_tfm(const char *alg_name, u32 tfm_flags);
216void crypto_free_tfm(struct crypto_tfm *tfm);
217
218/*
219 * Transform helpers which query the underlying algorithm.
220 */
221static inline const char *crypto_tfm_alg_name(struct crypto_tfm *tfm)
222{
223 return tfm->__crt_alg->cra_name;
224}
225
226static inline const char *crypto_tfm_alg_modname(struct crypto_tfm *tfm)
227{
228 struct crypto_alg *alg = tfm->__crt_alg;
229
230 if (alg->cra_module)
231 return alg->cra_module->name;
232 else
233 return NULL;
234}
235
236static inline u32 crypto_tfm_alg_type(struct crypto_tfm *tfm)
237{
238 return tfm->__crt_alg->cra_flags & CRYPTO_ALG_TYPE_MASK;
239}
240
241static inline unsigned int crypto_tfm_alg_min_keysize(struct crypto_tfm *tfm)
242{
243 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
244 return tfm->__crt_alg->cra_cipher.cia_min_keysize;
245}
246
247static inline unsigned int crypto_tfm_alg_max_keysize(struct crypto_tfm *tfm)
248{
249 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
250 return tfm->__crt_alg->cra_cipher.cia_max_keysize;
251}
252
253static inline unsigned int crypto_tfm_alg_ivsize(struct crypto_tfm *tfm)
254{
255 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
256 return tfm->crt_cipher.cit_ivsize;
257}
258
259static inline unsigned int crypto_tfm_alg_blocksize(struct crypto_tfm *tfm)
260{
261 return tfm->__crt_alg->cra_blocksize;
262}
263
264static inline unsigned int crypto_tfm_alg_digestsize(struct crypto_tfm *tfm)
265{
266 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
267 return tfm->__crt_alg->cra_digest.dia_digestsize;
268}
269
270/*
271 * API wrappers.
272 */
273static inline void crypto_digest_init(struct crypto_tfm *tfm)
274{
275 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
276 tfm->crt_digest.dit_init(tfm);
277}
278
279static inline void crypto_digest_update(struct crypto_tfm *tfm,
280 struct scatterlist *sg,
281 unsigned int nsg)
282{
283 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
284 tfm->crt_digest.dit_update(tfm, sg, nsg);
285}
286
287static inline void crypto_digest_final(struct crypto_tfm *tfm, u8 *out)
288{
289 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
290 tfm->crt_digest.dit_final(tfm, out);
291}
292
293static inline void crypto_digest_digest(struct crypto_tfm *tfm,
294 struct scatterlist *sg,
295 unsigned int nsg, u8 *out)
296{
297 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
298 tfm->crt_digest.dit_digest(tfm, sg, nsg, out);
299}
300
301static inline int crypto_digest_setkey(struct crypto_tfm *tfm,
302 const u8 *key, unsigned int keylen)
303{
304 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
305 if (tfm->crt_digest.dit_setkey == NULL)
306 return -ENOSYS;
307 return tfm->crt_digest.dit_setkey(tfm, key, keylen);
308}
309
310static inline int crypto_cipher_setkey(struct crypto_tfm *tfm,
311 const u8 *key, unsigned int keylen)
312{
313 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
314 return tfm->crt_cipher.cit_setkey(tfm, key, keylen);
315}
316
317static inline int crypto_cipher_encrypt(struct crypto_tfm *tfm,
318 struct scatterlist *dst,
319 struct scatterlist *src,
320 unsigned int nbytes)
321{
322 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
323 return tfm->crt_cipher.cit_encrypt(tfm, dst, src, nbytes);
324}
325
326static inline int crypto_cipher_encrypt_iv(struct crypto_tfm *tfm,
327 struct scatterlist *dst,
328 struct scatterlist *src,
329 unsigned int nbytes, u8 *iv)
330{
331 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
332 BUG_ON(tfm->crt_cipher.cit_mode == CRYPTO_TFM_MODE_ECB);
333 return tfm->crt_cipher.cit_encrypt_iv(tfm, dst, src, nbytes, iv);
334}
335
336static inline int crypto_cipher_decrypt(struct crypto_tfm *tfm,
337 struct scatterlist *dst,
338 struct scatterlist *src,
339 unsigned int nbytes)
340{
341 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
342 return tfm->crt_cipher.cit_decrypt(tfm, dst, src, nbytes);
343}
344
345static inline int crypto_cipher_decrypt_iv(struct crypto_tfm *tfm,
346 struct scatterlist *dst,
347 struct scatterlist *src,
348 unsigned int nbytes, u8 *iv)
349{
350 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
351 BUG_ON(tfm->crt_cipher.cit_mode == CRYPTO_TFM_MODE_ECB);
352 return tfm->crt_cipher.cit_decrypt_iv(tfm, dst, src, nbytes, iv);
353}
354
355static inline void crypto_cipher_set_iv(struct crypto_tfm *tfm,
356 const u8 *src, unsigned int len)
357{
358 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
359 memcpy(tfm->crt_cipher.cit_iv, src, len);
360}
361
362static inline void crypto_cipher_get_iv(struct crypto_tfm *tfm,
363 u8 *dst, unsigned int len)
364{
365 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
366 memcpy(dst, tfm->crt_cipher.cit_iv, len);
367}
368
369static inline int crypto_comp_compress(struct crypto_tfm *tfm,
370 const u8 *src, unsigned int slen,
371 u8 *dst, unsigned int *dlen)
372{
373 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_COMPRESS);
374 return tfm->crt_compress.cot_compress(tfm, src, slen, dst, dlen);
375}
376
377static inline int crypto_comp_decompress(struct crypto_tfm *tfm,
378 const u8 *src, unsigned int slen,
379 u8 *dst, unsigned int *dlen)
380{
381 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_COMPRESS);
382 return tfm->crt_compress.cot_decompress(tfm, src, slen, dst, dlen);
383}
384
385/*
386 * HMAC support.
387 */
388#ifdef CONFIG_CRYPTO_HMAC
389void crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen);
390void crypto_hmac_update(struct crypto_tfm *tfm,
391 struct scatterlist *sg, unsigned int nsg);
392void crypto_hmac_final(struct crypto_tfm *tfm, u8 *key,
393 unsigned int *keylen, u8 *out);
394void crypto_hmac(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen,
395 struct scatterlist *sg, unsigned int nsg, u8 *out);
396#endif /* CONFIG_CRYPTO_HMAC */
397
398#endif /* _LINUX_CRYPTO_H */
399
diff --git a/drivers/staging/rtl8187se/ieee80211/scatterwalk.c b/drivers/staging/rtl8187se/ieee80211/scatterwalk.c
new file mode 100644
index 000000000000..49f401fbce88
--- /dev/null
+++ b/drivers/staging/rtl8187se/ieee80211/scatterwalk.c
@@ -0,0 +1,126 @@
1/*
2 * Cryptographic API.
3 *
4 * Cipher operations.
5 *
6 * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
7 * 2002 Adam J. Richter <adam@yggdrasil.com>
8 * 2004 Jean-Luc Cooke <jlcooke@certainkey.com>
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the Free
12 * Software Foundation; either version 2 of the License, or (at your option)
13 * any later version.
14 *
15 */
16#include "kmap_types.h"
17
18#include <linux/kernel.h>
19#include <linux/mm.h>
20#include <linux/pagemap.h>
21#include <linux/highmem.h>
22#include <asm/scatterlist.h>
23#include "internal.h"
24#include "scatterwalk.h"
25
26enum km_type crypto_km_types[] = {
27 KM_USER0,
28 KM_USER1,
29 KM_SOFTIRQ0,
30 KM_SOFTIRQ1,
31};
32
33void *scatterwalk_whichbuf(struct scatter_walk *walk, unsigned int nbytes, void *scratch)
34{
35 if (nbytes <= walk->len_this_page &&
36 (((unsigned long)walk->data) & (PAGE_CACHE_SIZE - 1)) + nbytes <=
37 PAGE_CACHE_SIZE)
38 return walk->data;
39 else
40 return scratch;
41}
42
43static void memcpy_dir(void *buf, void *sgdata, size_t nbytes, int out)
44{
45 if (out)
46 memcpy(sgdata, buf, nbytes);
47 else
48 memcpy(buf, sgdata, nbytes);
49}
50
51void scatterwalk_start(struct scatter_walk *walk, struct scatterlist *sg)
52{
53 unsigned int rest_of_page;
54
55 walk->sg = sg;
56
57 walk->page = sg->page;
58 walk->len_this_segment = sg->length;
59
60 rest_of_page = PAGE_CACHE_SIZE - (sg->offset & (PAGE_CACHE_SIZE - 1));
61 walk->len_this_page = min(sg->length, rest_of_page);
62 walk->offset = sg->offset;
63}
64
65void scatterwalk_map(struct scatter_walk *walk, int out)
66{
67 walk->data = crypto_kmap(walk->page, out) + walk->offset;
68}
69
70static void scatterwalk_pagedone(struct scatter_walk *walk, int out,
71 unsigned int more)
72{
73 /* walk->data may be pointing the first byte of the next page;
74 however, we know we transfered at least one byte. So,
75 walk->data - 1 will be a virtual address in the mapped page. */
76
77 if (out)
78 flush_dcache_page(walk->page);
79
80 if (more) {
81 walk->len_this_segment -= walk->len_this_page;
82
83 if (walk->len_this_segment) {
84 walk->page++;
85 walk->len_this_page = min(walk->len_this_segment,
86 (unsigned)PAGE_CACHE_SIZE);
87 walk->offset = 0;
88 }
89 else
90 scatterwalk_start(walk, sg_next(walk->sg));
91 }
92}
93
94void scatterwalk_done(struct scatter_walk *walk, int out, int more)
95{
96 crypto_kunmap(walk->data, out);
97 if (walk->len_this_page == 0 || !more)
98 scatterwalk_pagedone(walk, out, more);
99}
100
101/*
102 * Do not call this unless the total length of all of the fragments
103 * has been verified as multiple of the block size.
104 */
105int scatterwalk_copychunks(void *buf, struct scatter_walk *walk,
106 size_t nbytes, int out)
107{
108 if (buf != walk->data) {
109 while (nbytes > walk->len_this_page) {
110 memcpy_dir(buf, walk->data, walk->len_this_page, out);
111 buf += walk->len_this_page;
112 nbytes -= walk->len_this_page;
113
114 crypto_kunmap(walk->data, out);
115 scatterwalk_pagedone(walk, out, 1);
116 scatterwalk_map(walk, out);
117 }
118
119 memcpy_dir(buf, walk->data, nbytes, out);
120 }
121
122 walk->offset += nbytes;
123 walk->len_this_page -= nbytes;
124 walk->len_this_segment -= nbytes;
125 return 0;
126}
diff --git a/drivers/staging/rtl8187se/ieee80211/scatterwalk.h b/drivers/staging/rtl8187se/ieee80211/scatterwalk.h
new file mode 100644
index 000000000000..b16446519017
--- /dev/null
+++ b/drivers/staging/rtl8187se/ieee80211/scatterwalk.h
@@ -0,0 +1,51 @@
1/*
2 * Cryptographic API.
3 *
4 * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
5 * Copyright (c) 2002 Adam J. Richter <adam@yggdrasil.com>
6 * Copyright (c) 2004 Jean-Luc Cooke <jlcooke@certainkey.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 *
13 */
14
15#ifndef _CRYPTO_SCATTERWALK_H
16#define _CRYPTO_SCATTERWALK_H
17#include <linux/mm.h>
18#include <asm/scatterlist.h>
19
20struct scatter_walk {
21 struct scatterlist *sg;
22 struct page *page;
23 void *data;
24 unsigned int len_this_page;
25 unsigned int len_this_segment;
26 unsigned int offset;
27};
28
29/* Define sg_next is an inline routine now in case we want to change
30 scatterlist to a linked list later. */
31static inline struct scatterlist *sg_next(struct scatterlist *sg)
32{
33 return sg + 1;
34}
35
36static inline int scatterwalk_samebuf(struct scatter_walk *walk_in,
37 struct scatter_walk *walk_out,
38 void *src_p, void *dst_p)
39{
40 return walk_in->page == walk_out->page &&
41 walk_in->offset == walk_out->offset &&
42 walk_in->data == src_p && walk_out->data == dst_p;
43}
44
45void *scatterwalk_whichbuf(struct scatter_walk *walk, unsigned int nbytes, void *scratch);
46void scatterwalk_start(struct scatter_walk *walk, struct scatterlist *sg);
47int scatterwalk_copychunks(void *buf, struct scatter_walk *walk, size_t nbytes, int out);
48void scatterwalk_map(struct scatter_walk *walk, int out);
49void scatterwalk_done(struct scatter_walk *walk, int out, int more);
50
51#endif /* _CRYPTO_SCATTERWALK_H */
diff --git a/drivers/staging/rtl8187se/ieee80211_crypt.h b/drivers/staging/rtl8187se/ieee80211_crypt.h
new file mode 100644
index 000000000000..b58a3bcc0dc0
--- /dev/null
+++ b/drivers/staging/rtl8187se/ieee80211_crypt.h
@@ -0,0 +1,86 @@
1/*
2 * Original code based on Host AP (software wireless LAN access point) driver
3 * for Intersil Prism2/2.5/3.
4 *
5 * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
6 * <jkmaline@cc.hut.fi>
7 * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
8 *
9 * Adaption to a generic IEEE 802.11 stack by James Ketrenos
10 * <jketreno@linux.intel.com>
11 *
12 * Copyright (c) 2004, Intel Corporation
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation. See README and COPYING for
17 * more details.
18 */
19
20/*
21 * This file defines the interface to the ieee80211 crypto module.
22 */
23#ifndef IEEE80211_CRYPT_H
24#define IEEE80211_CRYPT_H
25
26#include <linux/skbuff.h>
27
28struct ieee80211_crypto_ops {
29 const char *name;
30
31 /* init new crypto context (e.g., allocate private data space,
32 * select IV, etc.); returns NULL on failure or pointer to allocated
33 * private data on success */
34 void * (*init)(int keyidx);
35
36 /* deinitialize crypto context and free allocated private data */
37 void (*deinit)(void *priv);
38
39 /* encrypt/decrypt return < 0 on error or >= 0 on success. The return
40 * value from decrypt_mpdu is passed as the keyidx value for
41 * decrypt_msdu. skb must have enough head and tail room for the
42 * encryption; if not, error will be returned; these functions are
43 * called for all MPDUs (i.e., fragments).
44 */
45 int (*encrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
46 int (*decrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
47
48 /* These functions are called for full MSDUs, i.e. full frames.
49 * These can be NULL if full MSDU operations are not needed. */
50 int (*encrypt_msdu)(struct sk_buff *skb, int hdr_len, void *priv);
51 int (*decrypt_msdu)(struct sk_buff *skb, int keyidx, int hdr_len,
52 void *priv);
53
54 int (*set_key)(void *key, int len, u8 *seq, void *priv);
55 int (*get_key)(void *key, int len, u8 *seq, void *priv);
56
57 /* procfs handler for printing out key information and possible
58 * statistics */
59 char * (*print_stats)(char *p, void *priv);
60
61 /* maximum number of bytes added by encryption; encrypt buf is
62 * allocated with extra_prefix_len bytes, copy of in_buf, and
63 * extra_postfix_len; encrypt need not use all this space, but
64 * the result must start at the beginning of the buffer and correct
65 * length must be returned */
66 int extra_prefix_len, extra_postfix_len;
67
68 struct module *owner;
69};
70
71struct ieee80211_crypt_data {
72 struct list_head list; /* delayed deletion list */
73 struct ieee80211_crypto_ops *ops;
74 void *priv;
75 atomic_t refcnt;
76};
77
78int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops);
79int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops);
80struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name);
81void ieee80211_crypt_deinit_entries(struct ieee80211_device *, int);
82void ieee80211_crypt_deinit_handler(unsigned long);
83void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
84 struct ieee80211_crypt_data **crypt);
85
86#endif
diff --git a/drivers/staging/rtl8187se/r8180.h b/drivers/staging/rtl8187se/r8180.h
new file mode 100644
index 000000000000..12215fc61ddc
--- /dev/null
+++ b/drivers/staging/rtl8187se/r8180.h
@@ -0,0 +1,761 @@
1/*
2 This is part of rtl8180 OpenSource driver.
3 Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it>
4 Released under the terms of GPL (General Public Licence)
5
6 Parts of this driver are based on the GPL part of the
7 official realtek driver
8
9 Parts of this driver are based on the rtl8180 driver skeleton
10 from Patric Schenke & Andres Salomon
11
12 Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
13
14 We want to tanks the Authors of those projects and the Ndiswrapper
15 project Authors.
16*/
17
18#ifndef R8180H
19#define R8180H
20
21
22#define RTL8180_MODULE_NAME "rtl8180"
23#define DMESG(x,a...) printk(KERN_INFO RTL8180_MODULE_NAME ": " x "\n", ## a)
24#define DMESGW(x,a...) printk(KERN_WARNING RTL8180_MODULE_NAME ": WW:" x "\n", ## a)
25#define DMESGE(x,a...) printk(KERN_WARNING RTL8180_MODULE_NAME ": EE:" x "\n", ## a)
26
27#include <linux/module.h>
28#include <linux/kernel.h>
29//#include <linux/config.h>
30#include <linux/init.h>
31#include <linux/ioport.h>
32#include <linux/sched.h>
33#include <linux/types.h>
34#include <linux/slab.h>
35#include <linux/netdevice.h>
36#include <linux/pci.h>
37#include <linux/etherdevice.h>
38#include <linux/delay.h>
39#include <linux/rtnetlink.h> //for rtnl_lock()
40#include <linux/wireless.h>
41#include <linux/timer.h>
42#include <linux/proc_fs.h> // Necessary because we use the proc fs
43#include <linux/if_arp.h>
44#include "ieee80211.h"
45#include <asm/io.h>
46//#include <asm/semaphore.h>
47
48#define EPROM_93c46 0
49#define EPROM_93c56 1
50
51#define RTL_IOCTL_WPA_SUPPLICANT SIOCIWFIRSTPRIV+30
52
53#define DEFAULT_FRAG_THRESHOLD 2342U
54#define MIN_FRAG_THRESHOLD 256U
55//#define MAX_FRAG_THRESHOLD 2342U
56#define DEFAULT_RTS_THRESHOLD 2342U
57#define MIN_RTS_THRESHOLD 0U
58#define MAX_RTS_THRESHOLD 2342U
59#define DEFAULT_BEACONINTERVAL 0x64U
60#define DEFAULT_BEACON_ESSID "Rtl8180"
61
62#define DEFAULT_SSID ""
63#define DEFAULT_RETRY_RTS 7
64#define DEFAULT_RETRY_DATA 7
65#define PRISM_HDR_SIZE 64
66
67#ifdef CONFIG_RTL8185B
68
69#define MGNT_QUEUE 0
70#define BK_QUEUE 1
71#define BE_QUEUE 2
72#define VI_QUEUE 3
73#define VO_QUEUE 4
74#define HIGH_QUEUE 5
75#define BEACON_QUEUE 6
76
77#define LOW_QUEUE BE_QUEUE
78#define NORMAL_QUEUE MGNT_QUEUE
79
80#define aSifsTime 10
81
82#define sCrcLng 4
83#define sAckCtsLng 112 // bits in ACK and CTS frames
84//+by amy 080312
85#define RATE_ADAPTIVE_TIMER_PERIOD 300
86
87typedef enum _WIRELESS_MODE {
88 WIRELESS_MODE_UNKNOWN = 0x00,
89 WIRELESS_MODE_A = 0x01,
90 WIRELESS_MODE_B = 0x02,
91 WIRELESS_MODE_G = 0x04,
92 WIRELESS_MODE_AUTO = 0x08,
93} WIRELESS_MODE;
94
95typedef enum _VERSION_8185{
96 // RTL8185
97 VERSION_8185_UNKNOWN,
98 VERSION_8185_C, // C-cut
99 VERSION_8185_D, // D-cut
100 // RTL8185B
101 VERSION_8185B_B, // B-cut
102 VERSION_8185B_D, // D-cut
103 VERSION_8185B_E, // E-cut
104 //RTL8187S-PCIE
105 VERSION_8187S_B, // B-cut
106 VERSION_8187S_C, // C-cut
107 VERSION_8187S_D, // D-cut
108
109}VERSION_8185,*PVERSION_8185;
110typedef struct ChnlAccessSetting {
111 u16 SIFS_Timer;
112 u16 DIFS_Timer;
113 u16 SlotTimeTimer;
114 u16 EIFS_Timer;
115 u16 CWminIndex;
116 u16 CWmaxIndex;
117}*PCHANNEL_ACCESS_SETTING,CHANNEL_ACCESS_SETTING;
118
119typedef enum{
120 NIC_8185 = 1,
121 NIC_8185B
122 } nic_t;
123
124typedef u32 AC_CODING;
125#define AC0_BE 0 // ACI: 0x00 // Best Effort
126#define AC1_BK 1 // ACI: 0x01 // Background
127#define AC2_VI 2 // ACI: 0x10 // Video
128#define AC3_VO 3 // ACI: 0x11 // Voice
129#define AC_MAX 4 // Max: define total number; Should not to be used as a real enum.
130
131//
132// ECWmin/ECWmax field.
133// Ref: WMM spec 2.2.2: WME Parameter Element, p.13.
134//
135typedef union _ECW{
136 u8 charData;
137 struct
138 {
139 u8 ECWmin:4;
140 u8 ECWmax:4;
141 }f; // Field
142}ECW, *PECW;
143
144//
145// ACI/AIFSN Field.
146// Ref: WMM spec 2.2.2: WME Parameter Element, p.12.
147//
148typedef union _ACI_AIFSN{
149 u8 charData;
150
151 struct
152 {
153 u8 AIFSN:4;
154 u8 ACM:1;
155 u8 ACI:2;
156 u8 Reserved:1;
157 }f; // Field
158}ACI_AIFSN, *PACI_AIFSN;
159
160//
161// AC Parameters Record Format.
162// Ref: WMM spec 2.2.2: WME Parameter Element, p.12.
163//
164typedef union _AC_PARAM{
165 u32 longData;
166 u8 charData[4];
167
168 struct
169 {
170 ACI_AIFSN AciAifsn;
171 ECW Ecw;
172 u16 TXOPLimit;
173 }f; // Field
174}AC_PARAM, *PAC_PARAM;
175
176/* it is a wrong definition. -xiong-2006-11-17
177typedef struct ThreeWireReg {
178 u16 longData;
179 struct {
180 u8 enableB;
181 u8 data;
182 u8 clk;
183 u8 read_write;
184 } struc;
185} ThreeWireReg;
186*/
187
188typedef union _ThreeWire{
189 struct _ThreeWireStruc{
190 u16 data:1;
191 u16 clk:1;
192 u16 enableB:1;
193 u16 read_write:1;
194 u16 resv1:12;
195// u2Byte resv2:14;
196// u2Byte ThreeWireEnable:1;
197// u2Byte resv3:1;
198 }struc;
199 u16 longData;
200}ThreeWireReg;
201
202#endif
203
204typedef struct buffer
205{
206 struct buffer *next;
207 u32 *buf;
208 dma_addr_t dma;
209} buffer;
210
211//YJ,modified,080828
212typedef struct Stats
213{
214 unsigned long txrdu;
215 unsigned long rxrdu;
216 unsigned long rxnolast;
217 unsigned long rxnodata;
218// unsigned long rxreset;
219// unsigned long rxwrkaround;
220 unsigned long rxnopointer;
221 unsigned long txnperr;
222 unsigned long txresumed;
223 unsigned long rxerr;
224 unsigned long rxoverflow;
225 unsigned long rxint;
226 unsigned long txbkpokint;
227 unsigned long txbepoking;
228 unsigned long txbkperr;
229 unsigned long txbeperr;
230 unsigned long txnpokint;
231 unsigned long txhpokint;
232 unsigned long txhperr;
233 unsigned long ints;
234 unsigned long shints;
235 unsigned long txoverflow;
236 unsigned long rxdmafail;
237 unsigned long txbeacon;
238 unsigned long txbeaconerr;
239 unsigned long txlpokint;
240 unsigned long txlperr;
241 unsigned long txretry;//retry number tony 20060601
242 unsigned long rxcrcerrmin;//crc error (0-500)
243 unsigned long rxcrcerrmid;//crc error (500-1000)
244 unsigned long rxcrcerrmax;//crc error (>1000)
245 unsigned long rxicverr;//ICV error
246} Stats;
247
248#define MAX_LD_SLOT_NUM 10
249#define KEEP_ALIVE_INTERVAL 20 // in seconds.
250#define CHECK_FOR_HANG_PERIOD 2 //be equal to watchdog check time
251#define DEFAULT_KEEP_ALIVE_LEVEL 1
252#define DEFAULT_SLOT_NUM 2
253#define POWER_PROFILE_AC 0
254#define POWER_PROFILE_BATTERY 1
255
256typedef struct _link_detect_t
257{
258 u32 RxFrameNum[MAX_LD_SLOT_NUM]; // number of Rx Frame / CheckForHang_period to determine link status
259 u16 SlotNum; // number of CheckForHang period to determine link status, default is 2
260 u16 SlotIndex;
261
262 u32 NumTxOkInPeriod; //number of packet transmitted during CheckForHang
263 u32 NumRxOkInPeriod; //number of packet received during CheckForHang
264
265 u8 IdleCount; // (KEEP_ALIVE_INTERVAL / CHECK_FOR_HANG_PERIOD)
266 u32 LastNumTxUnicast;
267 u32 LastNumRxUnicast;
268
269 bool bBusyTraffic; //when it is set to 1, UI cann't scan at will.
270}link_detect_t, *plink_detect_t;
271
272//YJ,modified,080828,end
273
274//by amy for led
275//================================================================================
276// LED customization.
277//================================================================================
278
279typedef enum _LED_STRATEGY_8185{
280 SW_LED_MODE0, //
281 SW_LED_MODE1, //
282 HW_LED, // HW control 2 LEDs, LED0 and LED1 (there are 4 different control modes)
283}LED_STRATEGY_8185, *PLED_STRATEGY_8185;
284//by amy for led
285//by amy for power save
286typedef enum _LED_CTL_MODE{
287 LED_CTL_POWER_ON = 1,
288 LED_CTL_LINK = 2,
289 LED_CTL_NO_LINK = 3,
290 LED_CTL_TX = 4,
291 LED_CTL_RX = 5,
292 LED_CTL_SITE_SURVEY = 6,
293 LED_CTL_POWER_OFF = 7
294}LED_CTL_MODE;
295
296typedef enum _RT_RF_POWER_STATE
297{
298 eRfOn,
299 eRfSleep,
300 eRfOff
301}RT_RF_POWER_STATE;
302
303enum _ReasonCode{
304 unspec_reason = 0x1,
305 auth_not_valid = 0x2,
306 deauth_lv_ss = 0x3,
307 inactivity = 0x4,
308 ap_overload = 0x5,
309 class2_err = 0x6,
310 class3_err = 0x7,
311 disas_lv_ss = 0x8,
312 asoc_not_auth = 0x9,
313
314 //----MIC_CHECK
315 mic_failure = 0xe,
316 //----END MIC_CHECK
317
318 // Reason code defined in 802.11i D10.0 p.28.
319 invalid_IE = 0x0d,
320 four_way_tmout = 0x0f,
321 two_way_tmout = 0x10,
322 IE_dismatch = 0x11,
323 invalid_Gcipher = 0x12,
324 invalid_Pcipher = 0x13,
325 invalid_AKMP = 0x14,
326 unsup_RSNIEver = 0x15,
327 invalid_RSNIE = 0x16,
328 auth_802_1x_fail= 0x17,
329 ciper_reject = 0x18,
330
331 // Reason code defined in 7.3.1.7, 802.1e D13.0, p.42. Added by Annie, 2005-11-15.
332 QoS_unspec = 0x20, // 32
333 QAP_bandwidth = 0x21, // 33
334 poor_condition = 0x22, // 34
335 no_facility = 0x23, // 35
336 // Where is 36???
337 req_declined = 0x25, // 37
338 invalid_param = 0x26, // 38
339 req_not_honored= 0x27, // 39
340 TS_not_created = 0x2F, // 47
341 DL_not_allowed = 0x30, // 48
342 dest_not_exist = 0x31, // 49
343 dest_not_QSTA = 0x32, // 50
344};
345typedef enum _RT_PS_MODE
346{
347 eActive, // Active/Continuous access.
348 eMaxPs, // Max power save mode.
349 eFastPs // Fast power save mode.
350}RT_PS_MODE;
351//by amy for power save
352typedef struct r8180_priv
353{
354 struct pci_dev *pdev;
355
356 short epromtype;
357 int irq;
358 struct ieee80211_device *ieee80211;
359
360 short card_8185; /* O: rtl8180, 1:rtl8185 V B/C, 2:rtl8185 V D, 3:rtl8185B */
361 short card_8185_Bversion; /* if TCR reports card V B/C this discriminates */
362 short phy_ver; /* meaningful for rtl8225 1:A 2:B 3:C */
363 short enable_gpio0;
364 enum card_type {PCI,MINIPCI,CARDBUS,USB/*rtl8187*/}card_type;
365 short hw_plcp_len;
366 short plcp_preamble_mode; // 0:auto 1:short 2:long
367
368 spinlock_t irq_lock;
369 spinlock_t irq_th_lock;
370 spinlock_t tx_lock;
371 spinlock_t ps_lock;
372 spinlock_t rf_ps_lock;
373
374 u16 irq_mask;
375 short irq_enabled;
376 struct net_device *dev;
377 short chan;
378 short sens;
379 short max_sens;
380 u8 chtxpwr[15]; //channels from 1 to 14, 0 not used
381 u8 chtxpwr_ofdm[15]; //channels from 1 to 14, 0 not used
382 //u8 challow[15]; //channels from 1 to 14, 0 not used
383 u8 channel_plan; // it's the channel plan index
384 short up;
385 short crcmon; //if 1 allow bad crc frame reception in monitor mode
386 short prism_hdr;
387
388 struct timer_list scan_timer;
389 /*short scanpending;
390 short stopscan;*/
391 spinlock_t scan_lock;
392 u8 active_probe;
393 //u8 active_scan_num;
394 struct semaphore wx_sem;
395 struct semaphore rf_state;
396 short hw_wep;
397
398 short digphy;
399 short antb;
400 short diversity;
401 u8 cs_treshold;
402 short rcr_csense;
403 short rf_chip;
404 u32 key0[4];
405 short (*rf_set_sens)(struct net_device *dev,short sens);
406 void (*rf_set_chan)(struct net_device *dev,short ch);
407 void (*rf_close)(struct net_device *dev);
408 void (*rf_init)(struct net_device *dev);
409 void (*rf_sleep)(struct net_device *dev);
410 void (*rf_wakeup)(struct net_device *dev);
411 //short rate;
412 short promisc;
413 /*stats*/
414 struct Stats stats;
415 struct _link_detect_t link_detect; //YJ,add,080828
416 struct iw_statistics wstats;
417 struct proc_dir_entry *dir_dev;
418
419 /*RX stuff*/
420 u32 *rxring;
421 u32 *rxringtail;
422 dma_addr_t rxringdma;
423 struct buffer *rxbuffer;
424 struct buffer *rxbufferhead;
425 int rxringcount;
426 u16 rxbuffersize;
427
428 struct sk_buff *rx_skb;
429
430 short rx_skb_complete;
431
432 u32 rx_prevlen;
433
434 /*TX stuff*/
435/*
436 u32 *txlpring;
437 u32 *txhpring;
438 u32 *txnpring;
439 dma_addr_t txlpringdma;
440 dma_addr_t txhpringdma;
441 dma_addr_t txnpringdma;
442 u32 *txlpringtail;
443 u32 *txhpringtail;
444 u32 *txnpringtail;
445 u32 *txlpringhead;
446 u32 *txhpringhead;
447 u32 *txnpringhead;
448 struct buffer *txlpbufs;
449 struct buffer *txhpbufs;
450 struct buffer *txnpbufs;
451 struct buffer *txlpbufstail;
452 struct buffer *txhpbufstail;
453 struct buffer *txnpbufstail;
454*/
455 u32 *txmapring;
456 u32 *txbkpring;
457 u32 *txbepring;
458 u32 *txvipring;
459 u32 *txvopring;
460 u32 *txhpring;
461 dma_addr_t txmapringdma;
462 dma_addr_t txbkpringdma;
463 dma_addr_t txbepringdma;
464 dma_addr_t txvipringdma;
465 dma_addr_t txvopringdma;
466 dma_addr_t txhpringdma;
467 u32 *txmapringtail;
468 u32 *txbkpringtail;
469 u32 *txbepringtail;
470 u32 *txvipringtail;
471 u32 *txvopringtail;
472 u32 *txhpringtail;
473 u32 *txmapringhead;
474 u32 *txbkpringhead;
475 u32 *txbepringhead;
476 u32 *txvipringhead;
477 u32 *txvopringhead;
478 u32 *txhpringhead;
479 struct buffer *txmapbufs;
480 struct buffer *txbkpbufs;
481 struct buffer *txbepbufs;
482 struct buffer *txvipbufs;
483 struct buffer *txvopbufs;
484 struct buffer *txhpbufs;
485 struct buffer *txmapbufstail;
486 struct buffer *txbkpbufstail;
487 struct buffer *txbepbufstail;
488 struct buffer *txvipbufstail;
489 struct buffer *txvopbufstail;
490 struct buffer *txhpbufstail;
491
492 int txringcount;
493 int txbuffsize;
494 //struct tx_pendingbuf txnp_pending;
495 //struct tasklet_struct irq_tx_tasklet;
496 struct tasklet_struct irq_rx_tasklet;
497 u8 dma_poll_mask;
498 //short tx_suspend;
499
500 /* adhoc/master mode stuff */
501 u32 *txbeaconringtail;
502 dma_addr_t txbeaconringdma;
503 u32 *txbeaconring;
504 int txbeaconcount;
505 struct buffer *txbeaconbufs;
506 struct buffer *txbeaconbufstail;
507 //char *master_essid;
508 //u16 master_beaconinterval;
509 //u32 master_beaconsize;
510 //u16 beacon_interval;
511
512 u8 retry_data;
513 u8 retry_rts;
514 u16 rts;
515
516//add for RF power on power off by lizhaoming 080512
517 u8 RegThreeWireMode; // See "Three wire mode" defined above, 2006.05.31, by rcnjko.
518
519//by amy for led
520 LED_STRATEGY_8185 LedStrategy;
521//by amy for led
522
523//by amy for power save
524 struct timer_list watch_dog_timer;
525 bool bInactivePs;
526 bool bSwRfProcessing;
527 RT_RF_POWER_STATE eInactivePowerState;
528 RT_RF_POWER_STATE eRFPowerState;
529 u32 RfOffReason;
530 bool RFChangeInProgress;
531 bool bInHctTest;
532 bool SetRFPowerStateInProgress;
533 u8 RFProgType;
534 bool bLeisurePs;
535 RT_PS_MODE dot11PowerSaveMode;
536 //u32 NumRxOkInPeriod; //YJ,del,080828
537 //u32 NumTxOkInPeriod; //YJ,del,080828
538 u8 TxPollingTimes;
539
540 bool bApBufOurFrame;// TRUE if AP buffer our unicast data , we will keep eAwake untill receive data or timeout.
541 u8 WaitBufDataBcnCount;
542 u8 WaitBufDataTimeOut;
543
544//by amy for power save
545//by amy for antenna
546 u8 EEPROMSwAntennaDiversity;
547 bool EEPROMDefaultAntenna1;
548 u8 RegSwAntennaDiversityMechanism;
549 bool bSwAntennaDiverity;
550 u8 RegDefaultAntenna;
551 bool bDefaultAntenna1;
552 u8 SignalStrength;
553 long Stats_SignalStrength;
554 long LastSignalStrengthInPercent; // In percentange, used for smoothing, e.g. Moving Average.
555 u8 SignalQuality; // in 0-100 index.
556 long Stats_SignalQuality;
557 long RecvSignalPower; // in dBm.
558 long Stats_RecvSignalPower;
559 u8 LastRxPktAntenna; // +by amy 080312 Antenn which received the lasted packet. 0: Aux, 1:Main. Added by Roger, 2008.01.25.
560 u32 AdRxOkCnt;
561 long AdRxSignalStrength;
562 u8 CurrAntennaIndex; // Index to current Antenna (both Tx and Rx).
563 u8 AdTickCount; // Times of SwAntennaDiversityTimer happened.
564 u8 AdCheckPeriod; // # of period SwAntennaDiversityTimer to check Rx signal strength for SW Antenna Diversity.
565 u8 AdMinCheckPeriod; // Min value of AdCheckPeriod.
566 u8 AdMaxCheckPeriod; // Max value of AdCheckPeriod.
567 long AdRxSsThreshold; // Signal strength threshold to switch antenna.
568 long AdMaxRxSsThreshold; // Max value of AdRxSsThreshold.
569 bool bAdSwitchedChecking; // TRUE if we shall shall check Rx signal strength for last time switching antenna.
570 long AdRxSsBeforeSwitched; // Rx signal strength before we swithed antenna.
571 struct timer_list SwAntennaDiversityTimer;
572//by amy for antenna
573//{by amy 080312
574//
575 // Crystal calibration.
576 // Added by Roger, 2007.12.11.
577 //
578 bool bXtalCalibration; // Crystal calibration.
579 u8 XtalCal_Xin; // Crystal calibration for Xin. 0~7.5pF
580 u8 XtalCal_Xout; // Crystal calibration for Xout. 0~7.5pF
581 //
582 // Tx power tracking with thermal meter indication.
583 // Added by Roger, 2007.12.11.
584 //
585 bool bTxPowerTrack; // Tx Power tracking.
586 u8 ThermalMeter; // Thermal meter reference indication.
587 //
588 // Dynamic Initial Gain Adjustment Mechanism. Added by Bruce, 2007-02-14.
589 //
590 bool bDigMechanism; // TRUE if DIG is enabled, FALSE ow.
591 bool bRegHighPowerMechanism; // For High Power Mechanism. 061010, by rcnjko.
592 u32 FalseAlarmRegValue;
593 u8 RegDigOfdmFaUpTh; // Upper threhold of OFDM false alarm, which is used in DIG.
594 u8 DIG_NumberFallbackVote;
595 u8 DIG_NumberUpgradeVote;
596 // For HW antenna diversity, added by Roger, 2008.01.30.
597 u32 AdMainAntennaRxOkCnt; // Main antenna Rx OK count.
598 u32 AdAuxAntennaRxOkCnt; // Aux antenna Rx OK count.
599 bool bHWAdSwitched; // TRUE if we has switched default antenna by HW evaluation.
600 // RF High Power upper/lower threshold.
601 u8 RegHiPwrUpperTh;
602 u8 RegHiPwrLowerTh;
603 // RF RSSI High Power upper/lower Threshold.
604 u8 RegRSSIHiPwrUpperTh;
605 u8 RegRSSIHiPwrLowerTh;
606 // Current CCK RSSI value to determine CCK high power, asked by SD3 DZ, by Bruce, 2007-04-12.
607 u8 CurCCKRSSI;
608 bool bCurCCKPkt;
609 //
610 // High Power Mechanism. Added by amy, 080312.
611 //
612 bool bToUpdateTxPwr;
613 long UndecoratedSmoothedSS;
614 long UndercorateSmoothedRxPower;
615 u8 RSSI;
616 char RxPower;
617 u8 InitialGain;
618 //For adjust Dig Threshhold during Legacy/Leisure Power Save Mode
619 u32 DozePeriodInPast2Sec;
620 // Don't access BB/RF under disable PLL situation.
621 u8 InitialGainBackUp;
622 u8 RegBModeGainStage;
623//by amy for rate adaptive
624 struct timer_list rateadapter_timer;
625 u32 RateAdaptivePeriod;
626 bool bEnhanceTxPwr;
627 bool bUpdateARFR;
628 int ForcedDataRate; // Force Data Rate. 0: Auto, 0x02: 1M ~ 0x6C: 54M.)
629 u32 NumTxUnicast; //YJ,add,080828,for keep alive
630 u8 keepAliveLevel; //YJ,add,080828,for KeepAlive
631 unsigned long NumTxOkTotal;
632 u16 LastRetryCnt;
633 u16 LastRetryRate;
634 unsigned long LastTxokCnt;
635 unsigned long LastRxokCnt;
636 u16 CurrRetryCnt;
637 unsigned long LastTxOKBytes;
638 unsigned long NumTxOkBytesTotal;
639 u8 LastFailTxRate;
640 long LastFailTxRateSS;
641 u8 FailTxRateCount;
642 u32 LastTxThroughput;
643 //for up rate
644 unsigned short bTryuping;
645 u8 CurrTxRate; //the rate before up
646 u16 CurrRetryRate;
647 u16 TryupingCount;
648 u8 TryDownCountLowData;
649 u8 TryupingCountNoData;
650
651 u8 CurrentOperaRate;
652//by amy for rate adaptive
653//by amy 080312}
654// short wq_hurryup;
655// struct workqueue_struct *workqueue;
656 struct work_struct reset_wq;
657 struct work_struct watch_dog_wq;
658 struct work_struct tx_irq_wq;
659 short ack_tx_to_ieee;
660
661 u8 PowerProfile;
662#ifdef CONFIG_RTL8185B
663 u32 CSMethod;
664 u8 cck_txpwr_base;
665 u8 ofdm_txpwr_base;
666 u8 dma_poll_stop_mask;
667
668 //u8 RegThreeWireMode;
669 u8 MWIEnable;
670 u16 ShortRetryLimit;
671 u16 LongRetryLimit;
672 u16 EarlyRxThreshold;
673 u32 TransmitConfig;
674 u32 ReceiveConfig;
675 u32 IntrMask;
676
677 struct ChnlAccessSetting ChannelAccessSetting;
678#endif
679}r8180_priv;
680
681#define MANAGE_PRIORITY 0
682#define BK_PRIORITY 1
683#define BE_PRIORITY 2
684#define VI_PRIORITY 3
685#define VO_PRIORITY 4
686#define HI_PRIORITY 5
687#define BEACON_PRIORITY 6
688
689#define LOW_PRIORITY VI_PRIORITY
690#define NORM_PRIORITY VO_PRIORITY
691//AC2Queue mapping
692#define AC2Q(_ac) (((_ac) == WME_AC_VO) ? VO_PRIORITY : \
693 ((_ac) == WME_AC_VI) ? VI_PRIORITY : \
694 ((_ac) == WME_AC_BK) ? BK_PRIORITY : \
695 BE_PRIORITY)
696
697short rtl8180_tx(struct net_device *dev,u8* skbuf, int len,int priority,
698 short morefrag,short fragdesc,int rate);
699
700u8 read_nic_byte(struct net_device *dev, int x);
701u32 read_nic_dword(struct net_device *dev, int x);
702u16 read_nic_word(struct net_device *dev, int x) ;
703void write_nic_byte(struct net_device *dev, int x,u8 y);
704void write_nic_word(struct net_device *dev, int x,u16 y);
705void write_nic_dword(struct net_device *dev, int x,u32 y);
706void force_pci_posting(struct net_device *dev);
707
708void rtl8180_rtx_disable(struct net_device *);
709void rtl8180_rx_enable(struct net_device *);
710void rtl8180_tx_enable(struct net_device *);
711void rtl8180_start_scanning(struct net_device *dev);
712void rtl8180_start_scanning_s(struct net_device *dev);
713void rtl8180_stop_scanning(struct net_device *dev);
714void rtl8180_disassociate(struct net_device *dev);
715//void fix_rx_fifo(struct net_device *dev);
716void rtl8180_set_anaparam(struct net_device *dev,u32 a);
717void rtl8185_set_anaparam2(struct net_device *dev,u32 a);
718void rtl8180_set_hw_wep(struct net_device *dev);
719void rtl8180_no_hw_wep(struct net_device *dev);
720void rtl8180_update_msr(struct net_device *dev);
721//void rtl8180_BSS_create(struct net_device *dev);
722void rtl8180_beacon_tx_disable(struct net_device *dev);
723void rtl8180_beacon_rx_disable(struct net_device *dev);
724void rtl8180_conttx_enable(struct net_device *dev);
725void rtl8180_conttx_disable(struct net_device *dev);
726int rtl8180_down(struct net_device *dev);
727int rtl8180_up(struct net_device *dev);
728void rtl8180_commit(struct net_device *dev);
729void rtl8180_set_chan(struct net_device *dev,short ch);
730void rtl8180_set_master_essid(struct net_device *dev,char *essid);
731void rtl8180_update_beacon_security(struct net_device *dev);
732void write_phy(struct net_device *dev, u8 adr, u8 data);
733void write_phy_cck(struct net_device *dev, u8 adr, u32 data);
734void write_phy_ofdm(struct net_device *dev, u8 adr, u32 data);
735void rtl8185_tx_antenna(struct net_device *dev, u8 ant);
736void rtl8185_rf_pins_enable(struct net_device *dev);
737void IBSS_randomize_cell(struct net_device *dev);
738void IPSEnter(struct net_device *dev);
739void IPSLeave(struct net_device *dev);
740int get_curr_tx_free_desc(struct net_device *dev, int priority);
741void UpdateInitialGain(struct net_device *dev);
742bool SetAntennaConfig87SE(struct net_device *dev, u8 DefaultAnt, bool bAntDiversity);
743
744//#ifdef CONFIG_RTL8185B
745void rtl8185b_adapter_start(struct net_device *dev);
746void rtl8185b_rx_enable(struct net_device *dev);
747void rtl8185b_tx_enable(struct net_device *dev);
748void rtl8180_reset(struct net_device *dev);
749void rtl8185b_irq_enable(struct net_device *dev);
750void fix_rx_fifo(struct net_device *dev);
751void fix_tx_fifo(struct net_device *dev);
752void rtl8225z2_SetTXPowerLevel(struct net_device *dev, short ch);
753#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
754void rtl8180_rate_adapter(struct work_struct * work);
755#else
756void rtl8180_rate_adapter(struct net_device *dev);
757#endif
758//#endif
759bool MgntActSet_RF_State(struct net_device *dev, RT_RF_POWER_STATE StateToSet, u32 ChangeSource);
760
761#endif
diff --git a/drivers/staging/rtl8187se/r8180_93cx6.c b/drivers/staging/rtl8187se/r8180_93cx6.c
new file mode 100644
index 000000000000..7e4711fb930c
--- /dev/null
+++ b/drivers/staging/rtl8187se/r8180_93cx6.c
@@ -0,0 +1,146 @@
1/*
2 This files contains card eeprom (93c46 or 93c56) programming routines,
3 memory is addressed by 16 bits words.
4
5 This is part of rtl8180 OpenSource driver.
6 Copyright (C) Andrea Merello 2004 <andreamrl@tiscali.it>
7 Released under the terms of GPL (General Public Licence)
8
9 Parts of this driver are based on the GPL part of the
10 official realtek driver.
11
12 Parts of this driver are based on the rtl8180 driver skeleton
13 from Patric Schenke & Andres Salomon.
14
15 Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
16
17 We want to tanks the Authors of those projects and the Ndiswrapper
18 project Authors.
19*/
20
21#include "r8180_93cx6.h"
22
23void eprom_cs(struct net_device *dev, short bit)
24{
25 if(bit)
26 write_nic_byte(dev, EPROM_CMD,
27 (1<<EPROM_CS_SHIFT) | \
28 read_nic_byte(dev, EPROM_CMD)); //enable EPROM
29 else
30 write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev, EPROM_CMD)\
31 &~(1<<EPROM_CS_SHIFT)); //disable EPROM
32
33 force_pci_posting(dev);
34 udelay(EPROM_DELAY);
35}
36
37
38void eprom_ck_cycle(struct net_device *dev)
39{
40 write_nic_byte(dev, EPROM_CMD,
41 (1<<EPROM_CK_SHIFT) | read_nic_byte(dev,EPROM_CMD));
42 force_pci_posting(dev);
43 udelay(EPROM_DELAY);
44 write_nic_byte(dev, EPROM_CMD,
45 read_nic_byte(dev, EPROM_CMD) &~ (1<<EPROM_CK_SHIFT));
46 force_pci_posting(dev);
47 udelay(EPROM_DELAY);
48}
49
50
51void eprom_w(struct net_device *dev,short bit)
52{
53 if(bit)
54 write_nic_byte(dev, EPROM_CMD, (1<<EPROM_W_SHIFT) | \
55 read_nic_byte(dev,EPROM_CMD));
56 else
57 write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev,EPROM_CMD)\
58 &~(1<<EPROM_W_SHIFT));
59
60 force_pci_posting(dev);
61 udelay(EPROM_DELAY);
62}
63
64
65short eprom_r(struct net_device *dev)
66{
67 short bit;
68
69 bit=(read_nic_byte(dev, EPROM_CMD) & (1<<EPROM_R_SHIFT) );
70 udelay(EPROM_DELAY);
71
72 if(bit) return 1;
73 return 0;
74}
75
76
77void eprom_send_bits_string(struct net_device *dev, short b[], int len)
78{
79 int i;
80
81 for(i=0; i<len; i++){
82 eprom_w(dev, b[i]);
83 eprom_ck_cycle(dev);
84 }
85}
86
87
88u32 eprom_read(struct net_device *dev, u32 addr)
89{
90 struct r8180_priv *priv = ieee80211_priv(dev);
91 short read_cmd[]={1,1,0};
92 short addr_str[8];
93 int i;
94 int addr_len;
95 u32 ret;
96
97 ret=0;
98 //enable EPROM programming
99 write_nic_byte(dev, EPROM_CMD,
100 (EPROM_CMD_PROGRAM<<EPROM_CMD_OPERATING_MODE_SHIFT));
101 force_pci_posting(dev);
102 udelay(EPROM_DELAY);
103
104 if (priv->epromtype==EPROM_93c56){
105 addr_str[7]=addr & 1;
106 addr_str[6]=addr & (1<<1);
107 addr_str[5]=addr & (1<<2);
108 addr_str[4]=addr & (1<<3);
109 addr_str[3]=addr & (1<<4);
110 addr_str[2]=addr & (1<<5);
111 addr_str[1]=addr & (1<<6);
112 addr_str[0]=addr & (1<<7);
113 addr_len=8;
114 }else{
115 addr_str[5]=addr & 1;
116 addr_str[4]=addr & (1<<1);
117 addr_str[3]=addr & (1<<2);
118 addr_str[2]=addr & (1<<3);
119 addr_str[1]=addr & (1<<4);
120 addr_str[0]=addr & (1<<5);
121 addr_len=6;
122 }
123 eprom_cs(dev, 1);
124 eprom_ck_cycle(dev);
125 eprom_send_bits_string(dev, read_cmd, 3);
126 eprom_send_bits_string(dev, addr_str, addr_len);
127
128 //keep chip pin D to low state while reading.
129 //I'm unsure if it is necessary, but anyway shouldn't hurt
130 eprom_w(dev, 0);
131
132 for(i=0;i<16;i++){
133 //eeprom needs a clk cycle between writing opcode&adr
134 //and reading data. (eeprom outs a dummy 0)
135 eprom_ck_cycle(dev);
136 ret |= (eprom_r(dev)<<(15-i));
137 }
138
139 eprom_cs(dev, 0);
140 eprom_ck_cycle(dev);
141
142 //disable EPROM programming
143 write_nic_byte(dev, EPROM_CMD,
144 (EPROM_CMD_NORMAL<<EPROM_CMD_OPERATING_MODE_SHIFT));
145 return ret;
146}
diff --git a/drivers/staging/rtl8187se/r8180_93cx6.h b/drivers/staging/rtl8187se/r8180_93cx6.h
new file mode 100644
index 000000000000..a028a51b23f0
--- /dev/null
+++ b/drivers/staging/rtl8187se/r8180_93cx6.h
@@ -0,0 +1,59 @@
1/*
2 This is part of rtl8180 OpenSource driver
3 Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it>
4 Released under the terms of GPL (General Public Licence)
5
6 Parts of this driver are based on the GPL part of the official realtek driver
7 Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon
8 Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
9
10 We want to tanks the Authors of such projects and the Ndiswrapper project Authors.
11*/
12
13/*This files contains card eeprom (93c46 or 93c56) programming routines*/
14/*memory is addressed by WORDS*/
15
16#include "r8180.h"
17#include "r8180_hw.h"
18
19#define EPROM_DELAY 10
20
21#define EPROM_ANAPARAM_ADDRLWORD 0xd
22#define EPROM_ANAPARAM_ADDRHWORD 0xe
23
24#define RFCHIPID 0x6
25#define RFCHIPID_INTERSIL 1
26#define RFCHIPID_RFMD 2
27#define RFCHIPID_PHILIPS 3
28#define RFCHIPID_MAXIM 4
29#define RFCHIPID_GCT 5
30#define RFCHIPID_RTL8225 9
31#ifdef CONFIG_RTL8185B
32#define RF_ZEBRA2 11
33#define EPROM_TXPW_BASE 0x05
34#define RF_ZEBRA4 12
35#endif
36#define RFCHIPID_RTL8255 0xa
37#define RF_PARAM 0x19
38#define RF_PARAM_DIGPHY_SHIFT 0
39#define RF_PARAM_ANTBDEFAULT_SHIFT 1
40#define RF_PARAM_CARRIERSENSE_SHIFT 2
41#define RF_PARAM_CARRIERSENSE_MASK (3<<2)
42#define ENERGY_TRESHOLD 0x17
43#define EPROM_VERSION 0x1E
44#define MAC_ADR 0x7
45
46#define CIS 0x18
47
48#define EPROM_TXPW_OFDM_CH1_2 0x20
49
50//#define EPROM_TXPW_CH1_2 0x10
51#define EPROM_TXPW_CH1_2 0x30
52#define EPROM_TXPW_CH3_4 0x11
53#define EPROM_TXPW_CH5_6 0x12
54#define EPROM_TXPW_CH7_8 0x13
55#define EPROM_TXPW_CH9_10 0x14
56#define EPROM_TXPW_CH11_12 0x15
57#define EPROM_TXPW_CH13_14 0x16
58
59u32 eprom_read(struct net_device *dev,u32 addr); //reads a 16 bits word
diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c
new file mode 100644
index 000000000000..38455983728c
--- /dev/null
+++ b/drivers/staging/rtl8187se/r8180_core.c
@@ -0,0 +1,6826 @@
1/*
2 This is part of rtl818x pci OpenSource driver - v 0.1
3 Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it>
4 Released under the terms of GPL (General Public License)
5
6 Parts of this driver are based on the GPL part of the official
7 Realtek driver.
8
9 Parts of this driver are based on the rtl8180 driver skeleton
10 from Patric Schenke & Andres Salomon.
11
12 Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
13
14 Parts of BB/RF code are derived from David Young rtl8180 netbsd driver.
15
16 RSSI calc function from 'The Deuce'
17
18 Some ideas borrowed from the 8139too.c driver included in linux kernel.
19
20 We (I?) want to thanks the Authors of those projecs and also the
21 Ndiswrapper's project Authors.
22
23 A big big thanks goes also to Realtek corp. for their help in my attempt to
24 add RTL8185 and RTL8225 support, and to David Young also.
25*/
26
27#if 0
28double __floatsidf (int i) { return i; }
29unsigned int __fixunsdfsi (double d) { return d; }
30double __adddf3(double a, double b) { return a+b; }
31double __addsf3(float a, float b) { return a+b; }
32double __subdf3(double a, double b) { return a-b; }
33double __extendsfdf2(float a) {return a;}
34#endif
35
36
37#undef DEBUG_TX_DESC2
38#undef RX_DONT_PASS_UL
39#undef DEBUG_EPROM
40#undef DEBUG_RX_VERBOSE
41#undef DUMMY_RX
42#undef DEBUG_ZERO_RX
43#undef DEBUG_RX_SKB
44#undef DEBUG_TX_FRAG
45#undef DEBUG_RX_FRAG
46#undef DEBUG_TX_FILLDESC
47#undef DEBUG_TX
48#undef DEBUG_IRQ
49#undef DEBUG_RX
50#undef DEBUG_RXALLOC
51#undef DEBUG_REGISTERS
52#undef DEBUG_RING
53#undef DEBUG_IRQ_TASKLET
54#undef DEBUG_TX_ALLOC
55#undef DEBUG_TX_DESC
56
57//#define DEBUG_TX
58//#define DEBUG_TX_DESC2
59//#define DEBUG_RX
60//#define DEBUG_RX_SKB
61
62//#define CONFIG_RTL8180_IO_MAP
63#include <linux/syscalls.h>
64//#include <linux/fcntl.h>
65//#include <asm/uaccess.h>
66#include "r8180_hw.h"
67#include "r8180.h"
68#include "r8180_sa2400.h" /* PHILIPS Radio frontend */
69#include "r8180_max2820.h" /* MAXIM Radio frontend */
70#include "r8180_gct.h" /* GCT Radio frontend */
71#include "r8180_rtl8225.h" /* RTL8225 Radio frontend */
72#include "r8180_rtl8255.h" /* RTL8255 Radio frontend */
73#include "r8180_93cx6.h" /* Card EEPROM */
74#include "r8180_wx.h"
75#include "r8180_dm.h"
76
77#ifdef CONFIG_RTL8180_PM
78#include "r8180_pm.h"
79#endif
80
81#ifdef ENABLE_DOT11D
82#include "dot11d.h"
83#endif
84
85#ifdef CONFIG_RTL8185B
86//#define CONFIG_RTL8180_IO_MAP
87#endif
88
89#ifndef PCI_VENDOR_ID_BELKIN
90 #define PCI_VENDOR_ID_BELKIN 0x1799
91#endif
92#ifndef PCI_VENDOR_ID_DLINK
93 #define PCI_VENDOR_ID_DLINK 0x1186
94#endif
95
96static struct pci_device_id rtl8180_pci_id_tbl[] __devinitdata = {
97 {
98 .vendor = PCI_VENDOR_ID_REALTEK,
99// .device = 0x8180,
100 .device = 0x8199,
101 .subvendor = PCI_ANY_ID,
102 .subdevice = PCI_ANY_ID,
103 .driver_data = 0,
104 },
105 {
106 .vendor = PCI_VENDOR_ID_BELKIN,
107 .device = 0x6001,
108 .subvendor = PCI_ANY_ID,
109 .subdevice = PCI_ANY_ID,
110 .driver_data = 1,
111 },
112 { /* Belkin F5D6020 v3 */
113 .vendor = PCI_VENDOR_ID_BELKIN,
114 .device = 0x6020,
115 .subvendor = PCI_ANY_ID,
116 .subdevice = PCI_ANY_ID,
117 .driver_data = 2,
118 },
119 { /* D-Link DWL-610 */
120 .vendor = PCI_VENDOR_ID_DLINK,
121 .device = 0x3300,
122 .subvendor = PCI_ANY_ID,
123 .subdevice = PCI_ANY_ID,
124 .driver_data = 3,
125 },
126 {
127 .vendor = PCI_VENDOR_ID_REALTEK,
128 .device = 0x8185,
129 .subvendor = PCI_ANY_ID,
130 .subdevice = PCI_ANY_ID,
131 .driver_data = 4,
132 },
133 {
134 .vendor = 0,
135 .device = 0,
136 .subvendor = 0,
137 .subdevice = 0,
138 .driver_data = 0,
139 }
140};
141
142
143static char* ifname = "wlan%d";
144static int hwseqnum = 0;
145//static char* ifname = "ath%d";
146static int hwwep = 0;
147static int channels = 0x3fff;
148
149#define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 )
150#define cpMacAddr(des,src) ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3],(des)[4]=(src)[4],(des)[5]=(src)[5])
151MODULE_LICENSE("GPL");
152MODULE_DEVICE_TABLE(pci, rtl8180_pci_id_tbl);
153MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>");
154MODULE_DESCRIPTION("Linux driver for Realtek RTL8180 / RTL8185 WiFi cards");
155
156
157
158/*
159MODULE_PARM(ifname, "s");
160MODULE_PARM_DESC(devname," Net interface name, wlan%d=default");
161
162MODULE_PARM(hwseqnum,"i");
163MODULE_PARM_DESC(hwseqnum," Try to use hardware 802.11 header sequence numbers. Zero=default");
164
165MODULE_PARM(hwwep,"i");
166MODULE_PARM_DESC(hwwep," Try to use hardware WEP support. Still broken and not available on all cards");
167
168MODULE_PARM(channels,"i");
169MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI");
170*/
171
172#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 9)
173module_param(ifname, charp, S_IRUGO|S_IWUSR );
174module_param(hwseqnum,int, S_IRUGO|S_IWUSR);
175module_param(hwwep,int, S_IRUGO|S_IWUSR);
176module_param(channels,int, S_IRUGO|S_IWUSR);
177#else
178MODULE_PARM(ifname, "s");
179MODULE_PARM(hwseqnum,"i");
180MODULE_PARM(hwwep,"i");
181MODULE_PARM(channels,"i");
182#endif
183
184MODULE_PARM_DESC(devname," Net interface name, wlan%d=default");
185//MODULE_PARM_DESC(devname," Net interface name, ath%d=default");
186MODULE_PARM_DESC(hwseqnum," Try to use hardware 802.11 header sequence numbers. Zero=default");
187MODULE_PARM_DESC(hwwep," Try to use hardware WEP support. Still broken and not available on all cards");
188MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI");
189
190
191static int __devinit rtl8180_pci_probe(struct pci_dev *pdev,
192 const struct pci_device_id *id);
193
194static void __devexit rtl8180_pci_remove(struct pci_dev *pdev);
195
196static void rtl8180_shutdown (struct pci_dev *pdev)
197{
198 struct net_device *dev = pci_get_drvdata(pdev);
199 dev->stop(dev);
200 pci_disable_device(pdev);
201}
202
203static struct pci_driver rtl8180_pci_driver = {
204 .name = RTL8180_MODULE_NAME, /* Driver name */
205 .id_table = rtl8180_pci_id_tbl, /* PCI_ID table */
206 .probe = rtl8180_pci_probe, /* probe fn */
207 .remove = __devexit_p(rtl8180_pci_remove),/* remove fn */
208#ifdef CONFIG_RTL8180_PM
209 .suspend = rtl8180_suspend, /* PM suspend fn */
210 .resume = rtl8180_resume, /* PM resume fn */
211#else
212 .suspend = NULL, /* PM suspend fn */
213 .resume = NULL, /* PM resume fn */
214#endif
215 .shutdown = rtl8180_shutdown,
216};
217
218
219
220#ifdef CONFIG_RTL8180_IO_MAP
221
222u8 read_nic_byte(struct net_device *dev, int x)
223{
224 return 0xff&inb(dev->base_addr +x);
225}
226
227u32 read_nic_dword(struct net_device *dev, int x)
228{
229 return inl(dev->base_addr +x);
230}
231
232u16 read_nic_word(struct net_device *dev, int x)
233{
234 return inw(dev->base_addr +x);
235}
236
237void write_nic_byte(struct net_device *dev, int x,u8 y)
238{
239 outb(y&0xff,dev->base_addr +x);
240}
241
242void write_nic_word(struct net_device *dev, int x,u16 y)
243{
244 outw(y,dev->base_addr +x);
245}
246
247void write_nic_dword(struct net_device *dev, int x,u32 y)
248{
249 outl(y,dev->base_addr +x);
250}
251
252#else /* RTL_IO_MAP */
253
254u8 read_nic_byte(struct net_device *dev, int x)
255{
256 return 0xff&readb((u8*)dev->mem_start +x);
257}
258
259u32 read_nic_dword(struct net_device *dev, int x)
260{
261 return readl((u8*)dev->mem_start +x);
262}
263
264u16 read_nic_word(struct net_device *dev, int x)
265{
266 return readw((u8*)dev->mem_start +x);
267}
268
269void write_nic_byte(struct net_device *dev, int x,u8 y)
270{
271 writeb(y,(u8*)dev->mem_start +x);
272 udelay(20);
273}
274
275void write_nic_dword(struct net_device *dev, int x,u32 y)
276{
277 writel(y,(u8*)dev->mem_start +x);
278 udelay(20);
279}
280
281void write_nic_word(struct net_device *dev, int x,u16 y)
282{
283 writew(y,(u8*)dev->mem_start +x);
284 udelay(20);
285}
286
287#endif /* RTL_IO_MAP */
288
289
290
291
292
293inline void force_pci_posting(struct net_device *dev)
294{
295 read_nic_byte(dev,EPROM_CMD);
296#ifndef CONFIG_RTL8180_IO_MAP
297 mb();
298#endif
299}
300
301
302irqreturn_t rtl8180_interrupt(int irq, void *netdev, struct pt_regs *regs);
303void set_nic_rxring(struct net_device *dev);
304void set_nic_txring(struct net_device *dev);
305static struct net_device_stats *rtl8180_stats(struct net_device *dev);
306void rtl8180_commit(struct net_device *dev);
307void rtl8180_start_tx_beacon(struct net_device *dev);
308
309/****************************************************************************
310 -----------------------------PROCFS STUFF-------------------------
311*****************************************************************************/
312
313static struct proc_dir_entry *rtl8180_proc = NULL;
314
315static int proc_get_registers(char *page, char **start,
316 off_t offset, int count,
317 int *eof, void *data)
318{
319 struct net_device *dev = data;
320// struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
321
322 int len = 0;
323 int i,n;
324
325 int max=0xff;
326
327 /* This dump the current register page */
328 for(n=0;n<=max;)
329 {
330 //printk( "\nD: %2x> ", n);
331 len += snprintf(page + len, count - len,
332 "\nD: %2x > ",n);
333
334 for(i=0;i<16 && n<=max;i++,n++)
335 len += snprintf(page + len, count - len,
336 "%2x ",read_nic_byte(dev,n));
337
338 // printk("%2x ",read_nic_byte(dev,n));
339 }
340 len += snprintf(page + len, count - len,"\n");
341
342
343
344 *eof = 1;
345 return len;
346
347}
348
349int get_curr_tx_free_desc(struct net_device *dev, int priority);
350
351static int proc_get_stats_hw(char *page, char **start,
352 off_t offset, int count,
353 int *eof, void *data)
354{
355 //struct net_device *dev = data;
356 //struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
357
358 int len = 0;
359#ifdef CONFIG_RTL8185B
360
361#else
362 len += snprintf(page + len, count - len,
363 "NIC int: %lu\n"
364 "Total int: %lu\n"
365 "--------------------\n"
366 "LP avail desc %d\n"
367 "NP avail desc %d\n"
368 "--------------------\n"
369 "LP phys dma addr %x\n"
370 "LP NIC ptr %x\n"
371 "LP virt 32base %x\n"
372 "LP virt 32tail %x\n"
373 "--------------------\n"
374 "NP phys dma addr %x\n"
375 "NP NIC ptr %x\n"
376 "NP virt 32base %x\n"
377 "NP virt 32tail %x\n"
378 "--------------------\n"
379 "BP phys dma addr %x\n"
380 "BP NIC ptr %x\n"
381 "BP virt 32base %x\n"
382 "BP virt 32tail %x\n",
383 priv->stats.ints,
384 priv->stats.shints,
385 get_curr_tx_free_desc(dev,LOW_PRIORITY),
386 get_curr_tx_free_desc(dev,NORM_PRIORITY),
387 (u32)priv->txvipringdma,
388 read_nic_dword(dev,TLPDA),
389 (u32)priv->txvipring,
390 (u32)priv->txvipringtail,
391 (u32)priv->txvopringdma,
392 read_nic_dword(dev,TNPDA),
393 (u32)priv->txvopring,
394 (u32)priv->txvopringtail,
395 (u32)priv->txbeaconringdma,
396 read_nic_dword(dev,TBDA),
397 (u32)priv->txbeaconring,
398 (u32)priv->txbeaconringtail);
399#endif
400 *eof = 1;
401 return len;
402}
403
404
405static int proc_get_stats_rx(char *page, char **start,
406 off_t offset, int count,
407 int *eof, void *data)
408{
409 struct net_device *dev = data;
410 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
411
412 int len = 0;
413
414 len += snprintf(page + len, count - len,
415 /* "RX descriptor not available: %lu\n"
416 "RX incomplete (missing last descriptor): %lu\n"
417 "RX not data: %lu\n"
418 //"RX descriptor pointer reset: %lu\n"
419 "RX descriptor pointer lost: %lu\n"
420 //"RX pointer workaround: %lu\n"
421 "RX error int: %lu\n"
422 "RX fifo overflow: %lu\n"
423 "RX int: %lu\n"
424 "RX packet: %lu\n"
425 "RX bytes: %lu\n"
426 "RX DMA fail: %lu\n",
427 priv->stats.rxrdu,
428 priv->stats.rxnolast,
429 priv->stats.rxnodata,
430 //priv->stats.rxreset,
431 priv->stats.rxnopointer,
432 //priv->stats.rxwrkaround,
433 priv->stats.rxerr,
434 priv->stats.rxoverflow,
435 priv->stats.rxint,
436 priv->ieee80211->stats.rx_packets,
437 priv->ieee80211->stats.rx_bytes,
438 priv->stats.rxdmafail */
439 "RX OK: %lu\n"
440 "RX Retry: %lu\n"
441 "RX CRC Error(0-500): %lu\n"
442 "RX CRC Error(500-1000): %lu\n"
443 "RX CRC Error(>1000): %lu\n"
444 "RX ICV Error: %lu\n",
445 priv->stats.rxint,
446 priv->stats.rxerr,
447 priv->stats.rxcrcerrmin,
448 priv->stats.rxcrcerrmid,
449 priv->stats.rxcrcerrmax,
450 priv->stats.rxicverr
451 );
452
453 *eof = 1;
454 return len;
455}
456
457#if 0
458static int proc_get_stats_ieee(char *page, char **start,
459 off_t offset, int count,
460 int *eof, void *data)
461{
462 struct net_device *dev = data;
463 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
464
465 int len = 0;
466
467 len += snprintf(page + len, count - len,
468 "TXed association requests: %u\n"
469 "TXed authentication requests: %u\n"
470 "RXed successful association response: %u\n"
471 "RXed failed association response: %u\n"
472 "RXed successful authentication response: %u\n"
473 "RXed failed authentication response: %u\n"
474 "Association requests without response: %u\n"
475 "Authentication requests without response: %u\n"
476 "TX probe response: %u\n"
477 "RX probe request: %u\n"
478 "TX probe request: %lu\n"
479 "RX authentication requests: %lu\n"
480 "RX association requests: %lu\n"
481 "Reassociations: %lu\n",
482 priv->ieee80211->ieee_stats.tx_ass,
483 priv->ieee80211->ieee_stats.tx_aut,
484 priv->ieee80211->ieee_stats.rx_ass_ok,
485 priv->ieee80211->ieee_stats.rx_ass_err,
486 priv->ieee80211->ieee_stats.rx_aut_ok,
487 priv->ieee80211->ieee_stats.rx_aut_err,
488 priv->ieee80211->ieee_stats.ass_noresp,
489 priv->ieee80211->ieee_stats.aut_noresp,
490 priv->ieee80211->ieee_stats.tx_probe,
491 priv->ieee80211->ieee_stats.rx_probe,
492 priv->ieee80211->ieee_stats.tx_probe_rq,
493 priv->ieee80211->ieee_stats.rx_auth_rq,
494 priv->ieee80211->ieee_stats.rx_assoc_rq,
495 priv->ieee80211->ieee_stats.reassoc);
496
497 *eof = 1;
498 return len;
499}
500#endif
501#if 0
502static int proc_get_stats_ap(char *page, char **start,
503 off_t offset, int count,
504 int *eof, void *data)
505{
506 struct net_device *dev = data;
507 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
508 struct mac_htable_t *list;
509 int i;
510 int len = 0;
511
512 if(priv->ieee80211->iw_mode != IW_MODE_MASTER){
513 len += snprintf(page + len, count - len,
514 "Card is not acting as AP...\n"
515 );
516 }else{
517 len += snprintf(page + len, count - len,
518 "List of associated STA:\n"
519 );
520
521 for(i=0;i<MAC_HTABLE_ENTRY;i++)
522 for (list = priv->ieee80211->assoc_htable[i]; list!=NULL; list = list->next){
523 len += snprintf(page + len, count - len,
524 MACSTR"\n",MAC2STR(list->adr));
525 }
526
527 }
528 *eof = 1;
529 return len;
530}
531#endif
532
533static int proc_get_stats_tx(char *page, char **start,
534 off_t offset, int count,
535 int *eof, void *data)
536{
537 struct net_device *dev = data;
538 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
539
540 int len = 0;
541 unsigned long totalOK;
542
543 totalOK=priv->stats.txnpokint+priv->stats.txhpokint+priv->stats.txlpokint;
544 len += snprintf(page + len, count - len,
545 /* "TX normal priority ok int: %lu\n"
546 "TX normal priority error int: %lu\n"
547 "TX high priority ok int: %lu\n"
548 "TX high priority failed error int: %lu\n"
549 "TX low priority ok int: %lu\n"
550 "TX low priority failed error int: %lu\n"
551 "TX bytes: %lu\n"
552 "TX packets: %lu\n"
553 "TX queue resume: %lu\n"
554 "TX queue stopped?: %d\n"
555 "TX fifo overflow: %lu\n"
556 //"SW TX stop: %lu\n"
557 //"SW TX wake: %lu\n"
558 "TX beacon: %lu\n"
559 "TX beacon aborted: %lu\n",
560 priv->stats.txnpokint,
561 priv->stats.txnperr,
562 priv->stats.txhpokint,
563 priv->stats.txhperr,
564 priv->stats.txlpokint,
565 priv->stats.txlperr,
566 priv->ieee80211->stats.tx_bytes,
567 priv->ieee80211->stats.tx_packets,
568 priv->stats.txresumed,
569 netif_queue_stopped(dev),
570 priv->stats.txoverflow,
571 //priv->ieee80211->ieee_stats.swtxstop,
572 //priv->ieee80211->ieee_stats.swtxawake,
573 priv->stats.txbeacon,
574 priv->stats.txbeaconerr */
575 "TX OK: %lu\n"
576 "TX Error: %lu\n"
577 "TX Retry: %lu\n"
578 "TX beacon OK: %lu\n"
579 "TX beacon error: %lu\n",
580 totalOK,
581 priv->stats.txnperr+priv->stats.txhperr+priv->stats.txlperr,
582 priv->stats.txretry,
583 priv->stats.txbeacon,
584 priv->stats.txbeaconerr
585 );
586
587 *eof = 1;
588 return len;
589}
590
591
592#if WIRELESS_EXT < 17
593static struct iw_statistics *r8180_get_wireless_stats(struct net_device *dev)
594{
595 struct r8180_priv *priv = ieee80211_priv(dev);
596
597 return &priv->wstats;
598}
599#endif
600void rtl8180_proc_module_init(void)
601{
602 DMESG("Initializing proc filesystem");
603#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
604 rtl8180_proc=create_proc_entry(RTL8180_MODULE_NAME, S_IFDIR, proc_net);
605#else
606 rtl8180_proc=create_proc_entry(RTL8180_MODULE_NAME, S_IFDIR, init_net.proc_net);
607#endif
608}
609
610
611void rtl8180_proc_module_remove(void)
612{
613#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
614 remove_proc_entry(RTL8180_MODULE_NAME, proc_net);
615#else
616 remove_proc_entry(RTL8180_MODULE_NAME, init_net.proc_net);
617#endif
618}
619
620
621void rtl8180_proc_remove_one(struct net_device *dev)
622{
623 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
624 if (priv->dir_dev) {
625 remove_proc_entry("stats-hw", priv->dir_dev);
626 remove_proc_entry("stats-tx", priv->dir_dev);
627 remove_proc_entry("stats-rx", priv->dir_dev);
628// remove_proc_entry("stats-ieee", priv->dir_dev);
629// remove_proc_entry("stats-ap", priv->dir_dev);
630 remove_proc_entry("registers", priv->dir_dev);
631 remove_proc_entry(dev->name, rtl8180_proc);
632 priv->dir_dev = NULL;
633 }
634}
635
636
637void rtl8180_proc_init_one(struct net_device *dev)
638{
639 struct proc_dir_entry *e;
640 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
641 priv->dir_dev = create_proc_entry(dev->name,
642 S_IFDIR | S_IRUGO | S_IXUGO,
643 rtl8180_proc);
644 if (!priv->dir_dev) {
645 DMESGE("Unable to initialize /proc/net/rtl8180/%s\n",
646 dev->name);
647 return;
648 }
649
650 e = create_proc_read_entry("stats-hw", S_IFREG | S_IRUGO,
651 priv->dir_dev, proc_get_stats_hw, dev);
652
653 if (!e) {
654 DMESGE("Unable to initialize "
655 "/proc/net/rtl8180/%s/stats-hw\n",
656 dev->name);
657 }
658
659 e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO,
660 priv->dir_dev, proc_get_stats_rx, dev);
661
662 if (!e) {
663 DMESGE("Unable to initialize "
664 "/proc/net/rtl8180/%s/stats-rx\n",
665 dev->name);
666 }
667
668
669 e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO,
670 priv->dir_dev, proc_get_stats_tx, dev);
671
672 if (!e) {
673 DMESGE("Unable to initialize "
674 "/proc/net/rtl8180/%s/stats-tx\n",
675 dev->name);
676 }
677 #if 0
678 e = create_proc_read_entry("stats-ieee", S_IFREG | S_IRUGO,
679 priv->dir_dev, proc_get_stats_ieee, dev);
680
681 if (!e) {
682 DMESGE("Unable to initialize "
683 "/proc/net/rtl8180/%s/stats-ieee\n",
684 dev->name);
685 }
686 #endif
687 #if 0
688 e = create_proc_read_entry("stats-ap", S_IFREG | S_IRUGO,
689 priv->dir_dev, proc_get_stats_ap, dev);
690
691 if (!e) {
692 DMESGE("Unable to initialize "
693 "/proc/net/rtl8180/%s/stats-ap\n",
694 dev->name);
695 }
696 #endif
697
698 e = create_proc_read_entry("registers", S_IFREG | S_IRUGO,
699 priv->dir_dev, proc_get_registers, dev);
700
701 if (!e) {
702 DMESGE("Unable to initialize "
703 "/proc/net/rtl8180/%s/registers\n",
704 dev->name);
705 }
706}
707/****************************************************************************
708 -----------------------------MISC STUFF-------------------------
709*****************************************************************************/
710/*
711 FIXME: check if we can use some standard already-existent
712 data type+functions in kernel
713*/
714
715short buffer_add(struct buffer **buffer, u32 *buf, dma_addr_t dma,
716 struct buffer **bufferhead)
717{
718#ifdef DEBUG_RING
719 DMESG("adding buffer to TX/RX struct");
720#endif
721
722 struct buffer *tmp;
723
724 if(! *buffer){
725
726 *buffer = kmalloc(sizeof(struct buffer),GFP_KERNEL);
727
728 if (*buffer == NULL) {
729 DMESGE("Failed to kmalloc head of TX/RX struct");
730 return -1;
731 }
732 (*buffer)->next=*buffer;
733 (*buffer)->buf=buf;
734 (*buffer)->dma=dma;
735 if(bufferhead !=NULL)
736 (*bufferhead) = (*buffer);
737 return 0;
738 }
739 tmp=*buffer;
740
741 while(tmp->next!=(*buffer)) tmp=tmp->next;
742 if ((tmp->next= kmalloc(sizeof(struct buffer),GFP_KERNEL)) == NULL){
743 DMESGE("Failed to kmalloc TX/RX struct");
744 return -1;
745 }
746 tmp->next->buf=buf;
747 tmp->next->dma=dma;
748 tmp->next->next=*buffer;
749
750 return 0;
751}
752
753
754void buffer_free(struct net_device *dev,struct buffer **buffer,int len,short
755consistent)
756{
757
758 struct buffer *tmp,*next;
759 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
760 struct pci_dev *pdev=priv->pdev;
761 //int i;
762
763 if(! *buffer) return;
764
765 /*for(tmp=*buffer; tmp->next != *buffer; tmp=tmp->next)
766
767 */
768 tmp=*buffer;
769 do{
770 next=tmp->next;
771 if(consistent){
772 pci_free_consistent(pdev,len,
773 tmp->buf,tmp->dma);
774 }else{
775 pci_unmap_single(pdev, tmp->dma,
776 len,PCI_DMA_FROMDEVICE);
777 kfree(tmp->buf);
778 }
779 kfree(tmp);
780 tmp = next;
781 }
782 while(next != *buffer);
783
784 *buffer=NULL;
785}
786
787
788void print_buffer(u32 *buffer, int len)
789{
790 int i;
791 u8 *buf =(u8*)buffer;
792
793 printk("ASCII BUFFER DUMP (len: %x):\n",len);
794
795 for(i=0;i<len;i++)
796 printk("%c",buf[i]);
797
798 printk("\nBINARY BUFFER DUMP (len: %x):\n",len);
799
800 for(i=0;i<len;i++)
801 printk("%02x",buf[i]);
802
803 printk("\n");
804}
805
806
807int get_curr_tx_free_desc(struct net_device *dev, int priority)
808{
809 struct r8180_priv *priv = ieee80211_priv(dev);
810 u32* tail;
811 u32* head;
812 int ret;
813
814 switch (priority){
815 case MANAGE_PRIORITY:
816 head = priv->txmapringhead;
817 tail = priv->txmapringtail;
818 break;
819 case BK_PRIORITY:
820 head = priv->txbkpringhead;
821 tail = priv->txbkpringtail;
822 break;
823 case BE_PRIORITY:
824 head = priv->txbepringhead;
825 tail = priv->txbepringtail;
826 break;
827 case VI_PRIORITY:
828 head = priv->txvipringhead;
829 tail = priv->txvipringtail;
830 break;
831 case VO_PRIORITY:
832 head = priv->txvopringhead;
833 tail = priv->txvopringtail;
834 break;
835 case HI_PRIORITY:
836 head = priv->txhpringhead;
837 tail = priv->txhpringtail;
838 break;
839 default:
840 return -1;
841 }
842
843 //DMESG("%x %x", head, tail);
844
845 /* FIXME FIXME FIXME FIXME */
846
847#if 0
848 if( head <= tail ) return priv->txringcount-1 - (tail - head)/8;
849 return (head - tail)/8/4;
850#else
851 if( head <= tail )
852 ret = priv->txringcount - (tail - head)/8;
853 else
854 ret = (head - tail)/8;
855
856 if(ret > priv->txringcount ) DMESG("BUG");
857 return ret;
858#endif
859}
860
861
862short check_nic_enought_desc(struct net_device *dev, int priority)
863{
864 struct r8180_priv *priv = ieee80211_priv(dev);
865 struct ieee80211_device *ieee = netdev_priv(dev);
866
867 int requiredbyte, required;
868 requiredbyte = priv->ieee80211->fts + sizeof(struct ieee80211_header_data);
869
870 if(ieee->current_network.QoS_Enable) {
871 requiredbyte += 2;
872 };
873
874 required = requiredbyte / (priv->txbuffsize-4);
875 if (requiredbyte % priv->txbuffsize) required++;
876 /* for now we keep two free descriptor as a safety boundary
877 * between the tail and the head
878 */
879
880 return (required+2 < get_curr_tx_free_desc(dev,priority));
881}
882
883
884/* This function is only for debuging purpose */
885void check_tx_ring(struct net_device *dev, int pri)
886{
887 static int maxlog =3;
888 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
889 u32* tmp;
890 struct buffer *buf;
891 int i;
892 int nic;
893 u32* tail;
894 u32* head;
895 u32* begin;
896 u32 nicbegin;
897 struct buffer* buffer;
898
899 maxlog --;
900 if (maxlog <0 ) return;
901
902 switch(pri) {
903 case MANAGE_PRIORITY:
904 tail = priv->txmapringtail;
905 begin = priv->txmapring;
906 head = priv->txmapringhead;
907 nic = read_nic_dword(dev,TX_MANAGEPRIORITY_RING_ADDR);
908 buffer = priv->txmapbufs;
909 nicbegin = priv->txmapringdma;
910 break;
911
912
913 case BK_PRIORITY:
914 tail = priv->txbkpringtail;
915 begin = priv->txbkpring;
916 head = priv->txbkpringhead;
917 nic = read_nic_dword(dev,TX_BKPRIORITY_RING_ADDR);
918 buffer = priv->txbkpbufs;
919 nicbegin = priv->txbkpringdma;
920 break;
921
922 case BE_PRIORITY:
923 tail = priv->txbepringtail;
924 begin = priv->txbepring;
925 head = priv->txbepringhead;
926 nic = read_nic_dword(dev,TX_BEPRIORITY_RING_ADDR);
927 buffer = priv->txbepbufs;
928 nicbegin = priv->txbepringdma;
929 break;
930
931 case VI_PRIORITY:
932 tail = priv->txvipringtail;
933 begin = priv->txvipring;
934 head = priv->txvipringhead;
935 nic = read_nic_dword(dev,TX_VIPRIORITY_RING_ADDR);
936 buffer = priv->txvipbufs;
937 nicbegin = priv->txvipringdma;
938 break;
939
940
941 case VO_PRIORITY:
942 tail = priv->txvopringtail;
943 begin = priv->txvopring;
944 head = priv->txvopringhead;
945 nic = read_nic_dword(dev,TX_VOPRIORITY_RING_ADDR);
946 buffer = priv->txvopbufs;
947 nicbegin = priv->txvopringdma;
948 break;
949
950 case HI_PRIORITY:
951 tail = priv->txhpringtail;
952 begin = priv->txhpring;
953 head = priv->txhpringhead;
954 nic = read_nic_dword(dev,TX_HIGHPRIORITY_RING_ADDR);
955 buffer = priv->txhpbufs;
956 nicbegin = priv->txhpringdma;
957 break;
958
959 default:
960 return ;
961 break;
962 }
963
964 if(!priv->txvopbufs)
965 DMESGE ("NIC TX ack, but TX queue corrupted!");
966 else{
967
968 for(i=0,buf=buffer, tmp=begin;
969 tmp<begin+(priv->txringcount)*8;
970 tmp+=8,buf=buf->next,i++)
971
972 DMESG("BUF%d %s %x %s. Next : %x",i,
973 *tmp & (1<<31) ? "filled" : "empty",
974 *(buf->buf),
975 *tmp & (1<<15)? "ok": "err", *(tmp+4));
976 }
977
978 DMESG("nic at %d",
979 (nic-nicbegin) / 8 /4);
980 DMESG("tail at %d", ((int)tail - (int)begin) /8 /4);
981 DMESG("head at %d", ((int)head - (int)begin) /8 /4);
982 DMESG("check free desc returns %d", check_nic_enought_desc(dev,pri));
983 DMESG("free desc is %d\n", get_curr_tx_free_desc(dev,pri));
984 //rtl8180_reset(dev);
985 return;
986}
987
988
989
990/* this function is only for debugging purpose */
991void check_rxbuf(struct net_device *dev)
992{
993 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
994 u32* tmp;
995 struct buffer *buf;
996 u8 rx_desc_size;
997
998#ifdef CONFIG_RTL8185B
999 rx_desc_size = 8;
1000#else
1001 rx_desc_size = 4;
1002#endif
1003
1004 if(!priv->rxbuffer)
1005 DMESGE ("NIC RX ack, but RX queue corrupted!");
1006
1007 else{
1008
1009 for(buf=priv->rxbuffer, tmp=priv->rxring;
1010 tmp < priv->rxring+(priv->rxringcount)*rx_desc_size;
1011 tmp+=rx_desc_size, buf=buf->next)
1012
1013 DMESG("BUF %s %x",
1014 *tmp & (1<<31) ? "empty" : "filled",
1015 *(buf->buf));
1016 }
1017
1018 return;
1019}
1020
1021
1022void dump_eprom(struct net_device *dev)
1023{
1024 int i;
1025 for(i=0; i<63; i++)
1026 DMESG("EEPROM addr %x : %x", i, eprom_read(dev,i));
1027}
1028
1029
1030void rtl8180_dump_reg(struct net_device *dev)
1031{
1032 int i;
1033 int n;
1034 int max=0xff;
1035
1036 DMESG("Dumping NIC register map");
1037
1038 for(n=0;n<=max;)
1039 {
1040 printk( "\nD: %2x> ", n);
1041 for(i=0;i<16 && n<=max;i++,n++)
1042 printk("%2x ",read_nic_byte(dev,n));
1043 }
1044 printk("\n");
1045}
1046
1047
1048void fix_tx_fifo(struct net_device *dev)
1049{
1050 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1051 u32 *tmp;
1052 int i;
1053#ifdef DEBUG_TX_ALLOC
1054 DMESG("FIXING TX FIFOs");
1055#endif
1056 for (tmp=priv->txmapring, i=0;
1057 i < priv->txringcount;
1058 tmp+=8, i++){
1059 *tmp = *tmp &~ (1<<31);
1060 }
1061
1062 for (tmp=priv->txbkpring, i=0;
1063 i < priv->txringcount;
1064 tmp+=8, i++) {
1065 *tmp = *tmp &~ (1<<31);
1066 }
1067
1068 for (tmp=priv->txbepring, i=0;
1069 i < priv->txringcount;
1070 tmp+=8, i++){
1071 *tmp = *tmp &~ (1<<31);
1072 }
1073 for (tmp=priv->txvipring, i=0;
1074 i < priv->txringcount;
1075 tmp+=8, i++) {
1076 *tmp = *tmp &~ (1<<31);
1077 }
1078
1079 for (tmp=priv->txvopring, i=0;
1080 i < priv->txringcount;
1081 tmp+=8, i++){
1082 *tmp = *tmp &~ (1<<31);
1083 }
1084
1085 for (tmp=priv->txhpring, i=0;
1086 i < priv->txringcount;
1087 tmp+=8,i++){
1088 *tmp = *tmp &~ (1<<31);
1089 }
1090
1091 for (tmp=priv->txbeaconring, i=0;
1092 i < priv->txbeaconcount;
1093 tmp+=8, i++){
1094 *tmp = *tmp &~ (1<<31);
1095 }
1096#ifdef DEBUG_TX_ALLOC
1097 DMESG("TX FIFOs FIXED");
1098#endif
1099 priv->txmapringtail = priv->txmapring;
1100 priv->txmapringhead = priv->txmapring;
1101 priv->txmapbufstail = priv->txmapbufs;
1102
1103 priv->txbkpringtail = priv->txbkpring;
1104 priv->txbkpringhead = priv->txbkpring;
1105 priv->txbkpbufstail = priv->txbkpbufs;
1106
1107 priv->txbepringtail = priv->txbepring;
1108 priv->txbepringhead = priv->txbepring;
1109 priv->txbepbufstail = priv->txbepbufs;
1110
1111 priv->txvipringtail = priv->txvipring;
1112 priv->txvipringhead = priv->txvipring;
1113 priv->txvipbufstail = priv->txvipbufs;
1114
1115 priv->txvopringtail = priv->txvopring;
1116 priv->txvopringhead = priv->txvopring;
1117 priv->txvopbufstail = priv->txvopbufs;
1118
1119 priv->txhpringtail = priv->txhpring;
1120 priv->txhpringhead = priv->txhpring;
1121 priv->txhpbufstail = priv->txhpbufs;
1122
1123 priv->txbeaconringtail = priv->txbeaconring;
1124 priv->txbeaconbufstail = priv->txbeaconbufs;
1125 set_nic_txring(dev);
1126
1127 ieee80211_reset_queue(priv->ieee80211);
1128 priv->ack_tx_to_ieee = 0;
1129}
1130
1131
1132void fix_rx_fifo(struct net_device *dev)
1133{
1134 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1135 u32 *tmp;
1136 struct buffer *rxbuf;
1137 u8 rx_desc_size;
1138
1139#ifdef CONFIG_RTL8185B
1140 rx_desc_size = 8; // 4*8 = 32 bytes
1141#else
1142 rx_desc_size = 4;
1143#endif
1144
1145#ifdef DEBUG_RXALLOC
1146 DMESG("FIXING RX FIFO");
1147 check_rxbuf(dev);
1148#endif
1149
1150 for (tmp=priv->rxring, rxbuf=priv->rxbufferhead;
1151 (tmp < (priv->rxring)+(priv->rxringcount)*rx_desc_size);
1152 tmp+=rx_desc_size,rxbuf=rxbuf->next){
1153 *(tmp+2) = rxbuf->dma;
1154 *tmp=*tmp &~ 0xfff;
1155 *tmp=*tmp | priv->rxbuffersize;
1156 *tmp |= (1<<31);
1157 }
1158
1159#ifdef DEBUG_RXALLOC
1160 DMESG("RX FIFO FIXED");
1161 check_rxbuf(dev);
1162#endif
1163
1164 priv->rxringtail=priv->rxring;
1165 priv->rxbuffer=priv->rxbufferhead;
1166 priv->rx_skb_complete=1;
1167 set_nic_rxring(dev);
1168}
1169
1170
1171/****************************************************************************
1172 ------------------------------HW STUFF---------------------------
1173*****************************************************************************/
1174
1175unsigned char QUALITY_MAP[] = {
1176 0x64, 0x64, 0x64, 0x63, 0x63, 0x62, 0x62, 0x61,
1177 0x61, 0x60, 0x60, 0x5f, 0x5f, 0x5e, 0x5d, 0x5c,
1178 0x5b, 0x5a, 0x59, 0x57, 0x56, 0x54, 0x52, 0x4f,
1179 0x4c, 0x49, 0x45, 0x41, 0x3c, 0x37, 0x31, 0x29,
1180 0x24, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1181 0x22, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
1182 0x20, 0x20, 0x20, 0x1f, 0x1f, 0x1e, 0x1e, 0x1e,
1183 0x1d, 0x1d, 0x1c, 0x1c, 0x1b, 0x1a, 0x19, 0x19,
1184 0x18, 0x17, 0x16, 0x15, 0x14, 0x12, 0x11, 0x0f,
1185 0x0e, 0x0c, 0x0a, 0x08, 0x06, 0x04, 0x01, 0x00
1186};
1187
1188unsigned char STRENGTH_MAP[] = {
1189 0x64, 0x64, 0x63, 0x62, 0x61, 0x60, 0x5f, 0x5e,
1190 0x5d, 0x5c, 0x5b, 0x5a, 0x57, 0x54, 0x52, 0x50,
1191 0x4e, 0x4c, 0x4a, 0x48, 0x46, 0x44, 0x41, 0x3f,
1192 0x3c, 0x3a, 0x37, 0x36, 0x36, 0x1c, 0x1c, 0x1b,
1193 0x1b, 0x1a, 0x1a, 0x19, 0x19, 0x18, 0x18, 0x17,
1194 0x17, 0x16, 0x16, 0x15, 0x15, 0x14, 0x14, 0x13,
1195 0x13, 0x12, 0x12, 0x11, 0x11, 0x10, 0x10, 0x0f,
1196 0x0f, 0x0e, 0x0e, 0x0d, 0x0d, 0x0c, 0x0c, 0x0b,
1197 0x0b, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x07,
1198 0x07, 0x06, 0x06, 0x05, 0x04, 0x03, 0x02, 0x00
1199};
1200
1201void rtl8180_RSSI_calc(struct net_device *dev, u8 *rssi, u8 *qual){
1202 //void Mlme_UpdateRssiSQ(struct net_device *dev, u8 *rssi, u8 *qual){
1203 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1204 u32 temp;
1205 u32 temp2;
1206 u32 temp3;
1207 u32 lsb;
1208 u32 q;
1209 u32 orig_qual;
1210 u8 _rssi;
1211
1212 q = *qual;
1213 orig_qual = *qual;
1214 _rssi = 0; // avoid gcc complains..
1215
1216 if (q <= 0x4e) {
1217 temp = QUALITY_MAP[q];
1218 } else {
1219 if( q & 0x80 ) {
1220 temp = 0x32;
1221 } else {
1222 temp = 1;
1223 }
1224 }
1225
1226 *qual = temp;
1227 temp2 = *rssi;
1228
1229 switch(priv->rf_chip){
1230 case RFCHIPID_RFMD:
1231 lsb = temp2 & 1;
1232 temp2 &= 0x7e;
1233 if ( !lsb || !(temp2 <= 0x3c) ) {
1234 temp2 = 0x64;
1235 } else {
1236 temp2 = 100 * temp2 / 0x3c;
1237 }
1238 *rssi = temp2 & 0xff;
1239 _rssi = temp2 & 0xff;
1240 break;
1241 case RFCHIPID_INTERSIL:
1242 lsb = temp2;
1243 temp2 &= 0xfffffffe;
1244 temp2 *= 251;
1245 temp3 = temp2;
1246 temp2 <<= 6;
1247 temp3 += temp2;
1248 temp3 <<= 1;
1249 temp2 = 0x4950df;
1250 temp2 -= temp3;
1251 lsb &= 1;
1252 if ( temp2 <= 0x3e0000 ) {
1253 if ( temp2 < 0xffef0000 )
1254 temp2 = 0xffef0000;
1255 } else {
1256 temp2 = 0x3e0000;
1257 }
1258 if ( !lsb ) {
1259 temp2 -= 0xf0000;
1260 } else {
1261 temp2 += 0xf0000;
1262 }
1263
1264 temp3 = 0x4d0000;
1265 temp3 -= temp2;
1266 temp3 *= 100;
1267 temp3 = temp3 / 0x6d;
1268 temp3 >>= 0x10;
1269 _rssi = temp3 & 0xff;
1270 *rssi = temp3 & 0xff;
1271 break;
1272 case RFCHIPID_GCT:
1273 lsb = temp2 & 1;
1274 temp2 &= 0x7e;
1275 if ( ! lsb || !(temp2 <= 0x3c) ){
1276 temp2 = 0x64;
1277 } else {
1278 temp2 = (100 * temp2) / 0x3c;
1279 }
1280 *rssi = temp2 & 0xff;
1281 _rssi = temp2 & 0xff;
1282 break;
1283 case RFCHIPID_PHILIPS:
1284 if( orig_qual <= 0x4e ){
1285 _rssi = STRENGTH_MAP[orig_qual];
1286 *rssi = _rssi;
1287 } else {
1288 orig_qual -= 0x80;
1289 if ( !orig_qual ){
1290 _rssi = 1;
1291 *rssi = 1;
1292 } else {
1293 _rssi = 0x32;
1294 *rssi = 0x32;
1295 }
1296 }
1297 break;
1298
1299 /* case 4 */
1300 case RFCHIPID_MAXIM:
1301 lsb = temp2 & 1;
1302 temp2 &= 0x7e;
1303 temp2 >>= 1;
1304 temp2 += 0x42;
1305 if( lsb != 0 ){
1306 temp2 += 0xa;
1307 }
1308 *rssi = temp2 & 0xff;
1309 _rssi = temp2 & 0xff;
1310 break;
1311 }
1312
1313 if ( _rssi < 0x64 ){
1314 if ( _rssi == 0 ) {
1315 *rssi = 1;
1316 }
1317 } else {
1318 *rssi = 0x64;
1319 }
1320
1321 return;
1322}
1323
1324
1325void rtl8180_irq_enable(struct net_device *dev)
1326{
1327 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1328 priv->irq_enabled = 1;
1329/*
1330 write_nic_word(dev,INTA_MASK,INTA_RXOK | INTA_RXDESCERR | INTA_RXOVERFLOW |\
1331 INTA_TXOVERFLOW | INTA_HIPRIORITYDESCERR | INTA_HIPRIORITYDESCOK |\
1332 INTA_NORMPRIORITYDESCERR | INTA_NORMPRIORITYDESCOK |\
1333 INTA_LOWPRIORITYDESCERR | INTA_LOWPRIORITYDESCOK | INTA_TIMEOUT);
1334*/
1335 write_nic_word(dev,INTA_MASK, priv->irq_mask);
1336}
1337
1338
1339void rtl8180_irq_disable(struct net_device *dev)
1340{
1341 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1342
1343#ifdef CONFIG_RTL8185B
1344 write_nic_dword(dev,IMR,0);
1345#else
1346 write_nic_word(dev,INTA_MASK,0);
1347#endif
1348 force_pci_posting(dev);
1349 priv->irq_enabled = 0;
1350}
1351
1352
1353void rtl8180_set_mode(struct net_device *dev,int mode)
1354{
1355 u8 ecmd;
1356 ecmd=read_nic_byte(dev, EPROM_CMD);
1357 ecmd=ecmd &~ EPROM_CMD_OPERATING_MODE_MASK;
1358 ecmd=ecmd | (mode<<EPROM_CMD_OPERATING_MODE_SHIFT);
1359 ecmd=ecmd &~ (1<<EPROM_CS_SHIFT);
1360 ecmd=ecmd &~ (1<<EPROM_CK_SHIFT);
1361 write_nic_byte(dev, EPROM_CMD, ecmd);
1362}
1363
1364void rtl8180_adapter_start(struct net_device *dev);
1365void rtl8180_beacon_tx_enable(struct net_device *dev);
1366
1367void rtl8180_update_msr(struct net_device *dev)
1368{
1369 struct r8180_priv *priv = ieee80211_priv(dev);
1370 u8 msr;
1371 u32 rxconf;
1372
1373 msr = read_nic_byte(dev, MSR);
1374 msr &= ~ MSR_LINK_MASK;
1375
1376 rxconf=read_nic_dword(dev,RX_CONF);
1377
1378 if(priv->ieee80211->state == IEEE80211_LINKED)
1379 {
1380 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
1381 msr |= (MSR_LINK_ADHOC<<MSR_LINK_SHIFT);
1382 else if (priv->ieee80211->iw_mode == IW_MODE_MASTER)
1383 msr |= (MSR_LINK_MASTER<<MSR_LINK_SHIFT);
1384 else if (priv->ieee80211->iw_mode == IW_MODE_INFRA)
1385 msr |= (MSR_LINK_MANAGED<<MSR_LINK_SHIFT);
1386 else
1387 msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT);
1388 rxconf |= (1<<RX_CHECK_BSSID_SHIFT);
1389
1390 }else {
1391 msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT);
1392 rxconf &= ~(1<<RX_CHECK_BSSID_SHIFT);
1393 }
1394
1395 write_nic_byte(dev, MSR, msr);
1396 write_nic_dword(dev, RX_CONF, rxconf);
1397
1398}
1399
1400
1401
1402void rtl8180_set_chan(struct net_device *dev,short ch)
1403{
1404 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1405
1406 if((ch > 14) || (ch < 1))
1407 {
1408 printk("In %s: Invalid chnanel %d\n", __FUNCTION__, ch);
1409 return;
1410 }
1411
1412 priv->chan=ch;
1413 //printk("in %s:channel is %d\n",__FUNCTION__,ch);
1414 priv->rf_set_chan(dev,priv->chan);
1415
1416}
1417
1418
1419void rtl8180_rx_enable(struct net_device *dev)
1420{
1421 u8 cmd;
1422 u32 rxconf;
1423 /* for now we accept data, management & ctl frame*/
1424 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1425
1426 rxconf=read_nic_dword(dev,RX_CONF);
1427 rxconf = rxconf &~ MAC_FILTER_MASK;
1428 rxconf = rxconf | (1<<ACCEPT_MNG_FRAME_SHIFT);
1429 rxconf = rxconf | (1<<ACCEPT_DATA_FRAME_SHIFT);
1430 rxconf = rxconf | (1<<ACCEPT_BCAST_FRAME_SHIFT);
1431 rxconf = rxconf | (1<<ACCEPT_MCAST_FRAME_SHIFT);
1432// rxconf = rxconf | (1<<ACCEPT_CRCERR_FRAME_SHIFT);
1433 if (dev->flags & IFF_PROMISC) DMESG ("NIC in promisc mode");
1434
1435 if(priv->ieee80211->iw_mode == IW_MODE_MONITOR || \
1436 dev->flags & IFF_PROMISC){
1437 rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT);
1438 }else{
1439 rxconf = rxconf | (1<<ACCEPT_NICMAC_FRAME_SHIFT);
1440 if(priv->card_8185 == 0)
1441 rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT);
1442 }
1443
1444 /*if(priv->ieee80211->iw_mode == IW_MODE_MASTER){
1445 rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT);
1446 rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT);
1447 }*/
1448
1449 if(priv->ieee80211->iw_mode == IW_MODE_MONITOR){
1450 rxconf = rxconf | (1<<ACCEPT_CTL_FRAME_SHIFT);
1451 rxconf = rxconf | (1<<ACCEPT_ICVERR_FRAME_SHIFT);
1452 rxconf = rxconf | (1<<ACCEPT_PWR_FRAME_SHIFT);
1453 }
1454
1455 if( priv->crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR)
1456 rxconf = rxconf | (1<<ACCEPT_CRCERR_FRAME_SHIFT);
1457
1458 //if(!priv->card_8185){
1459 rxconf = rxconf &~ RX_FIFO_THRESHOLD_MASK;
1460 rxconf = rxconf | (RX_FIFO_THRESHOLD_NONE<<RX_FIFO_THRESHOLD_SHIFT);
1461 //}
1462
1463 rxconf = rxconf | (1<<RX_AUTORESETPHY_SHIFT);
1464 rxconf = rxconf &~ MAX_RX_DMA_MASK;
1465 rxconf = rxconf | (MAX_RX_DMA_2048<<MAX_RX_DMA_SHIFT);
1466
1467 //if(!priv->card_8185)
1468 rxconf = rxconf | RCR_ONLYERLPKT;
1469
1470 rxconf = rxconf &~ RCR_CS_MASK;
1471 if(!priv->card_8185)
1472 rxconf |= (priv->rcr_csense<<RCR_CS_SHIFT);
1473// rxconf &=~ 0xfff00000;
1474// rxconf |= 0x90100000;//9014f76f;
1475 write_nic_dword(dev, RX_CONF, rxconf);
1476
1477 fix_rx_fifo(dev);
1478
1479#ifdef DEBUG_RX
1480 DMESG("rxconf: %x %x",rxconf ,read_nic_dword(dev,RX_CONF));
1481#endif
1482 cmd=read_nic_byte(dev,CMD);
1483 write_nic_byte(dev,CMD,cmd | (1<<CMD_RX_ENABLE_SHIFT));
1484
1485 /* In rtl8139 driver seems that DMA threshold has to be written
1486 * after enabling RX, so we rewrite RX_CONFIG register
1487 */
1488 //mdelay(100);
1489// write_nic_dword(dev, RX_CONF, rxconf);
1490
1491}
1492
1493
1494void set_nic_txring(struct net_device *dev)
1495{
1496 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1497// DMESG("ring %x %x", priv->txlpringdma,read_nic_dword(dev,TLPDA));
1498
1499 write_nic_dword(dev, TX_MANAGEPRIORITY_RING_ADDR, priv->txmapringdma);
1500// DMESG("ring %x %x", priv->txlpringdma,read_nic_dword(dev,TLPDA));
1501 write_nic_dword(dev, TX_BKPRIORITY_RING_ADDR, priv->txbkpringdma);
1502// DMESG("ring %x %x", priv->txlpringdma,read_nic_dword(dev,TLPDA));
1503 write_nic_dword(dev, TX_BEPRIORITY_RING_ADDR, priv->txbepringdma);
1504// DMESG("ring %x %x", priv->txlpringdma,read_nic_dword(dev,TLPDA));
1505 write_nic_dword(dev, TX_VIPRIORITY_RING_ADDR, priv->txvipringdma);
1506// DMESG("ring %x %x", priv->txlpringdma,read_nic_dword(dev,TLPDA));
1507 write_nic_dword(dev, TX_VOPRIORITY_RING_ADDR, priv->txvopringdma);
1508// DMESG("ring %x %x", priv->txlpringdma,read_nic_dword(dev,TLPDA));
1509 write_nic_dword(dev, TX_HIGHPRIORITY_RING_ADDR, priv->txhpringdma);
1510// DMESG("ring %x %x", priv->txlpringdma,read_nic_dword(dev,TLPDA));
1511
1512 write_nic_dword(dev, TX_BEACON_RING_ADDR, priv->txbeaconringdma);
1513}
1514
1515
1516void rtl8180_conttx_enable(struct net_device *dev)
1517{
1518 u32 txconf;
1519 txconf = read_nic_dword(dev,TX_CONF);
1520 txconf = txconf &~ TX_LOOPBACK_MASK;
1521 txconf = txconf | (TX_LOOPBACK_CONTINUE <<TX_LOOPBACK_SHIFT);
1522 write_nic_dword(dev,TX_CONF,txconf);
1523}
1524
1525
1526void rtl8180_conttx_disable(struct net_device *dev)
1527{
1528 u32 txconf;
1529 txconf = read_nic_dword(dev,TX_CONF);
1530 txconf = txconf &~ TX_LOOPBACK_MASK;
1531 txconf = txconf | (TX_LOOPBACK_NONE <<TX_LOOPBACK_SHIFT);
1532 write_nic_dword(dev,TX_CONF,txconf);
1533}
1534
1535
1536void rtl8180_tx_enable(struct net_device *dev)
1537{
1538 u8 cmd;
1539 u8 tx_agc_ctl;
1540 u8 byte;
1541 u32 txconf;
1542 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1543 txconf= read_nic_dword(dev,TX_CONF);
1544
1545
1546 if(priv->card_8185){
1547
1548
1549 byte = read_nic_byte(dev,CW_CONF);
1550 byte &= ~(1<<CW_CONF_PERPACKET_CW_SHIFT);
1551 byte &= ~(1<<CW_CONF_PERPACKET_RETRY_SHIFT);
1552 write_nic_byte(dev, CW_CONF, byte);
1553
1554 tx_agc_ctl = read_nic_byte(dev, TX_AGC_CTL);
1555 tx_agc_ctl &= ~(1<<TX_AGC_CTL_PERPACKET_GAIN_SHIFT);
1556 tx_agc_ctl &= ~(1<<TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT);
1557 tx_agc_ctl |=(1<<TX_AGC_CTL_FEEDBACK_ANT);
1558 write_nic_byte(dev, TX_AGC_CTL, tx_agc_ctl);
1559 /*
1560 write_nic_word(dev, 0x5e, 0x01);
1561 force_pci_posting(dev);
1562 mdelay(1);
1563 write_nic_word(dev, 0xfe, 0x10);
1564 force_pci_posting(dev);
1565 mdelay(1);
1566 write_nic_word(dev, 0x5e, 0x00);
1567 force_pci_posting(dev);
1568 mdelay(1);
1569 */
1570 write_nic_byte(dev, 0xec, 0x3f); /* Disable early TX */
1571 }
1572
1573 if(priv->card_8185){
1574
1575 txconf = txconf &~ (1<<TCR_PROBE_NOTIMESTAMP_SHIFT);
1576
1577 }else{
1578
1579 if(hwseqnum)
1580 txconf= txconf &~ (1<<TX_CONF_HEADER_AUTOICREMENT_SHIFT);
1581 else
1582 txconf= txconf | (1<<TX_CONF_HEADER_AUTOICREMENT_SHIFT);
1583 }
1584
1585 txconf = txconf &~ TX_LOOPBACK_MASK;
1586 txconf = txconf | (TX_LOOPBACK_NONE <<TX_LOOPBACK_SHIFT);
1587 txconf = txconf &~ TCR_DPRETRY_MASK;
1588 txconf = txconf &~ TCR_RTSRETRY_MASK;
1589 txconf = txconf | (priv->retry_data<<TX_DPRETRY_SHIFT);
1590 txconf = txconf | (priv->retry_rts<<TX_RTSRETRY_SHIFT);
1591 txconf = txconf &~ (1<<TX_NOCRC_SHIFT);
1592
1593 if(priv->card_8185){
1594 if(priv->hw_plcp_len)
1595 txconf = txconf &~ TCR_PLCP_LEN;
1596 else
1597 txconf = txconf | TCR_PLCP_LEN;
1598 }else{
1599 txconf = txconf &~ TCR_SAT;
1600 }
1601 txconf = txconf &~ TCR_MXDMA_MASK;
1602 txconf = txconf | (TCR_MXDMA_2048<<TCR_MXDMA_SHIFT);
1603 txconf = txconf | TCR_CWMIN;
1604 txconf = txconf | TCR_DISCW;
1605
1606// if(priv->ieee80211->hw_wep)
1607// txconf=txconf &~ (1<<TX_NOICV_SHIFT);
1608// else
1609 txconf=txconf | (1<<TX_NOICV_SHIFT);
1610
1611 write_nic_dword(dev,TX_CONF,txconf);
1612
1613
1614 fix_tx_fifo(dev);
1615
1616#ifdef DEBUG_TX
1617 DMESG("txconf: %x %x",txconf,read_nic_dword(dev,TX_CONF));
1618#endif
1619
1620 cmd=read_nic_byte(dev,CMD);
1621 write_nic_byte(dev,CMD,cmd | (1<<CMD_TX_ENABLE_SHIFT));
1622
1623// mdelay(100);
1624 write_nic_dword(dev,TX_CONF,txconf);
1625// #endif
1626/*
1627 rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
1628 write_nic_byte(dev, TX_DMA_POLLING, priv->dma_poll_mask);
1629 rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
1630 */
1631}
1632
1633
1634void rtl8180_beacon_tx_enable(struct net_device *dev)
1635{
1636 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1637
1638 rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
1639#ifdef CONFIG_RTL8185B
1640 priv->dma_poll_stop_mask &= ~(TPPOLLSTOP_BQ);
1641 write_nic_byte(dev,TPPollStop, priv->dma_poll_mask);
1642#else
1643 priv->dma_poll_mask &=~(1<<TX_DMA_STOP_BEACON_SHIFT);
1644 write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
1645#endif
1646 rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
1647}
1648
1649
1650void rtl8180_beacon_tx_disable(struct net_device *dev)
1651{
1652 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1653
1654 rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
1655#ifdef CONFIG_RTL8185B
1656 priv->dma_poll_stop_mask |= TPPOLLSTOP_BQ;
1657 write_nic_byte(dev,TPPollStop, priv->dma_poll_stop_mask);
1658#else
1659 priv->dma_poll_mask |= (1<<TX_DMA_STOP_BEACON_SHIFT);
1660 write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
1661#endif
1662 rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
1663
1664}
1665
1666
1667void rtl8180_rtx_disable(struct net_device *dev)
1668{
1669 u8 cmd;
1670 struct r8180_priv *priv = ieee80211_priv(dev);
1671
1672 cmd=read_nic_byte(dev,CMD);
1673 write_nic_byte(dev, CMD, cmd &~ \
1674 ((1<<CMD_RX_ENABLE_SHIFT)|(1<<CMD_TX_ENABLE_SHIFT)));
1675 force_pci_posting(dev);
1676 mdelay(10);
1677 /*while (read_nic_byte(dev,CMD) & (1<<CMD_RX_ENABLE_SHIFT))
1678 udelay(10);
1679 */
1680
1681 if(!priv->rx_skb_complete)
1682 dev_kfree_skb_any(priv->rx_skb);
1683}
1684
1685#if 0
1686int alloc_tx_beacon_desc_ring(struct net_device *dev, int count)
1687{
1688 int i;
1689 u32 *tmp;
1690 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1691
1692 priv->txbeaconring = (u32*)pci_alloc_consistent(priv->pdev,
1693 sizeof(u32)*8*count,
1694 &priv->txbeaconringdma);
1695 if (!priv->txbeaconring) return -1;
1696 for (tmp=priv->txbeaconring,i=0;i<count;i++){
1697 *tmp = *tmp &~ (1<<31); // descriptor empty, owned by the drv
1698 /*
1699 *(tmp+2) = (u32)dma_tmp;
1700 *(tmp+3) = bufsize;
1701 */
1702 if(i+1<count)
1703 *(tmp+4) = (u32)priv->txbeaconringdma+((i+1)*8*4);
1704 else
1705 *(tmp+4) = (u32)priv->txbeaconringdma;
1706
1707 tmp=tmp+8;
1708 }
1709 return 0;
1710}
1711#endif
1712
1713short alloc_tx_desc_ring(struct net_device *dev, int bufsize, int count,
1714 int addr)
1715{
1716 int i;
1717 u32 *desc;
1718 u32 *tmp;
1719 dma_addr_t dma_desc, dma_tmp;
1720 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1721 struct pci_dev *pdev = priv->pdev;
1722 void *buf;
1723
1724 if((bufsize & 0xfff) != bufsize) {
1725 DMESGE ("TX buffer allocation too large");
1726 return 0;
1727 }
1728 desc = (u32*)pci_alloc_consistent(pdev,
1729 sizeof(u32)*8*count+256, &dma_desc);
1730 if(desc==NULL) return -1;
1731 if(dma_desc & 0xff){
1732
1733 /*
1734 * descriptor's buffer must be 256 byte aligned
1735 * we shouldn't be here, since we set DMA mask !
1736 */
1737 DMESGW("Fixing TX alignment");
1738 desc = (u32*)((u8*)desc + 256);
1739#if (defined(CONFIG_HIGHMEM64G) || defined(CONFIG_64BIT_PHYS_ADDR))
1740 desc = (u32*)((u64)desc &~ 0xff);
1741 dma_desc = (dma_addr_t)((u8*)dma_desc + 256);
1742 dma_desc = (dma_addr_t)((u64)dma_desc &~ 0xff);
1743#else
1744 desc = (u32*)((u32)desc &~ 0xff);
1745 dma_desc = (dma_addr_t)((u8*)dma_desc + 256);
1746 dma_desc = (dma_addr_t)((u32)dma_desc &~ 0xff);
1747#endif
1748 }
1749 tmp=desc;
1750 for (i=0;i<count;i++)
1751 {
1752 buf = (void*)pci_alloc_consistent(pdev,bufsize,&dma_tmp);
1753 if (buf == NULL) return -ENOMEM;
1754
1755 switch(addr) {
1756#if 0
1757 case TX_NORMPRIORITY_RING_ADDR:
1758 if(-1 == buffer_add(&(priv->txnpbufs),buf,dma_tmp,NULL)){
1759 DMESGE("Unable to allocate mem for buffer NP");
1760 return -ENOMEM;
1761 }
1762 break;
1763
1764 case TX_LOWPRIORITY_RING_ADDR:
1765 if(-1 == buffer_add(&(priv->txlpbufs),buf,dma_tmp,NULL)){
1766 DMESGE("Unable to allocate mem for buffer LP");
1767 return -ENOMEM;
1768 }
1769 break;
1770
1771 case TX_HIGHPRIORITY_RING_ADDR:
1772 if(-1 == buffer_add(&(priv->txhpbufs),buf,dma_tmp,NULL)){
1773 DMESGE("Unable to allocate mem for buffer HP");
1774 return -ENOMEM;
1775 }
1776 break;
1777#else
1778 case TX_MANAGEPRIORITY_RING_ADDR:
1779 if(-1 == buffer_add(&(priv->txmapbufs),buf,dma_tmp,NULL)){
1780 DMESGE("Unable to allocate mem for buffer NP");
1781 return -ENOMEM;
1782 }
1783 break;
1784
1785 case TX_BKPRIORITY_RING_ADDR:
1786 if(-1 == buffer_add(&(priv->txbkpbufs),buf,dma_tmp,NULL)){
1787 DMESGE("Unable to allocate mem for buffer LP");
1788 return -ENOMEM;
1789 }
1790 break;
1791 case TX_BEPRIORITY_RING_ADDR:
1792 if(-1 == buffer_add(&(priv->txbepbufs),buf,dma_tmp,NULL)){
1793 DMESGE("Unable to allocate mem for buffer NP");
1794 return -ENOMEM;
1795 }
1796 break;
1797
1798 case TX_VIPRIORITY_RING_ADDR:
1799 if(-1 == buffer_add(&(priv->txvipbufs),buf,dma_tmp,NULL)){
1800 DMESGE("Unable to allocate mem for buffer LP");
1801 return -ENOMEM;
1802 }
1803 break;
1804 case TX_VOPRIORITY_RING_ADDR:
1805 if(-1 == buffer_add(&(priv->txvopbufs),buf,dma_tmp,NULL)){
1806 DMESGE("Unable to allocate mem for buffer NP");
1807 return -ENOMEM;
1808 }
1809 break;
1810#endif
1811 case TX_HIGHPRIORITY_RING_ADDR:
1812 if(-1 == buffer_add(&(priv->txhpbufs),buf,dma_tmp,NULL)){
1813 DMESGE("Unable to allocate mem for buffer HP");
1814 return -ENOMEM;
1815 }
1816 break;
1817 case TX_BEACON_RING_ADDR:
1818 if(-1 == buffer_add(&(priv->txbeaconbufs),buf,dma_tmp,NULL)){
1819 DMESGE("Unable to allocate mem for buffer BP");
1820 return -ENOMEM;
1821 }
1822 break;
1823 }
1824 *tmp = *tmp &~ (1<<31); // descriptor empty, owned by the drv
1825 *(tmp+2) = (u32)dma_tmp;
1826 *(tmp+3) = bufsize;
1827
1828 if(i+1<count)
1829 *(tmp+4) = (u32)dma_desc+((i+1)*8*4);
1830 else
1831 *(tmp+4) = (u32)dma_desc;
1832
1833 tmp=tmp+8;
1834 }
1835
1836 switch(addr) {
1837 case TX_MANAGEPRIORITY_RING_ADDR:
1838 priv->txmapringdma=dma_desc;
1839 priv->txmapring=desc;
1840 break;
1841
1842 case TX_BKPRIORITY_RING_ADDR:
1843 priv->txbkpringdma=dma_desc;
1844 priv->txbkpring=desc;
1845 break;
1846
1847 case TX_BEPRIORITY_RING_ADDR:
1848 priv->txbepringdma=dma_desc;
1849 priv->txbepring=desc;
1850 break;
1851
1852 case TX_VIPRIORITY_RING_ADDR:
1853 priv->txvipringdma=dma_desc;
1854 priv->txvipring=desc;
1855 break;
1856
1857 case TX_VOPRIORITY_RING_ADDR:
1858 priv->txvopringdma=dma_desc;
1859 priv->txvopring=desc;
1860 break;
1861
1862 case TX_HIGHPRIORITY_RING_ADDR:
1863 priv->txhpringdma=dma_desc;
1864 priv->txhpring=desc;
1865 break;
1866
1867 case TX_BEACON_RING_ADDR:
1868 priv->txbeaconringdma=dma_desc;
1869 priv->txbeaconring=desc;
1870 break;
1871
1872 }
1873
1874#ifdef DEBUG_TX
1875 DMESG("Tx dma physical address: %x",dma_desc);
1876#endif
1877
1878 return 0;
1879}
1880
1881
1882void free_tx_desc_rings(struct net_device *dev)
1883{
1884
1885 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1886 struct pci_dev *pdev=priv->pdev;
1887 int count = priv->txringcount;
1888
1889 pci_free_consistent(pdev, sizeof(u32)*8*count+256,
1890 priv->txmapring, priv->txmapringdma);
1891 buffer_free(dev,&(priv->txmapbufs),priv->txbuffsize,1);
1892
1893 pci_free_consistent(pdev, sizeof(u32)*8*count+256,
1894 priv->txbkpring, priv->txbkpringdma);
1895 buffer_free(dev,&(priv->txbkpbufs),priv->txbuffsize,1);
1896
1897 pci_free_consistent(pdev, sizeof(u32)*8*count+256,
1898 priv->txbepring, priv->txbepringdma);
1899 buffer_free(dev,&(priv->txbepbufs),priv->txbuffsize,1);
1900
1901 pci_free_consistent(pdev, sizeof(u32)*8*count+256,
1902 priv->txvipring, priv->txvipringdma);
1903 buffer_free(dev,&(priv->txvipbufs),priv->txbuffsize,1);
1904
1905 pci_free_consistent(pdev, sizeof(u32)*8*count+256,
1906 priv->txvopring, priv->txvopringdma);
1907 buffer_free(dev,&(priv->txvopbufs),priv->txbuffsize,1);
1908
1909 pci_free_consistent(pdev, sizeof(u32)*8*count+256,
1910 priv->txhpring, priv->txhpringdma);
1911 buffer_free(dev,&(priv->txhpbufs),priv->txbuffsize,1);
1912
1913 count = priv->txbeaconcount;
1914 pci_free_consistent(pdev, sizeof(u32)*8*count+256,
1915 priv->txbeaconring, priv->txbeaconringdma);
1916 buffer_free(dev,&(priv->txbeaconbufs),priv->txbuffsize,1);
1917}
1918
1919#if 0
1920void free_beacon_desc_ring(struct net_device *dev,int count)
1921{
1922
1923 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1924 struct pci_dev *pdev=priv->pdev;
1925
1926 pci_free_consistent(pdev, sizeof(u32)*8*count+256,
1927 priv->txbeaconring, priv->txbeaconringdma);
1928
1929 if (priv->beacon_buf)
1930 pci_free_consistent(priv->pdev,
1931 priv->master_beaconsize,priv->beacon_buf,priv->beacondmabuf);
1932
1933}
1934#endif
1935void free_rx_desc_ring(struct net_device *dev)
1936{
1937 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1938 struct pci_dev *pdev = priv->pdev;
1939
1940 int count = priv->rxringcount;
1941
1942#ifdef CONFIG_RTL8185B
1943 pci_free_consistent(pdev, sizeof(u32)*8*count+256,
1944 priv->rxring, priv->rxringdma);
1945#else
1946 pci_free_consistent(pdev, sizeof(u32)*4*count+256,
1947 priv->rxring, priv->rxringdma);
1948#endif
1949
1950 buffer_free(dev,&(priv->rxbuffer),priv->rxbuffersize,0);
1951}
1952
1953
1954short alloc_rx_desc_ring(struct net_device *dev, u16 bufsize, int count)
1955{
1956 int i;
1957 u32 *desc;
1958 u32 *tmp;
1959 dma_addr_t dma_desc,dma_tmp;
1960 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1961 struct pci_dev *pdev=priv->pdev;
1962 void *buf;
1963 u8 rx_desc_size;
1964
1965#ifdef CONFIG_RTL8185B
1966 rx_desc_size = 8; // 4*8 = 32 bytes
1967#else
1968 rx_desc_size = 4;
1969#endif
1970
1971 if((bufsize & 0xfff) != bufsize){
1972 DMESGE ("RX buffer allocation too large");
1973 return -1;
1974 }
1975
1976 desc = (u32*)pci_alloc_consistent(pdev,sizeof(u32)*rx_desc_size*count+256,
1977 &dma_desc);
1978
1979 if(dma_desc & 0xff){
1980
1981 /*
1982 * descriptor's buffer must be 256 byte aligned
1983 * should never happen since we specify the DMA mask
1984 */
1985
1986 DMESGW("Fixing RX alignment");
1987 desc = (u32*)((u8*)desc + 256);
1988#if (defined(CONFIG_HIGHMEM64G) || defined(CONFIG_64BIT_PHYS_ADDR))
1989 desc = (u32*)((u64)desc &~ 0xff);
1990 dma_desc = (dma_addr_t)((u8*)dma_desc + 256);
1991 dma_desc = (dma_addr_t)((u64)dma_desc &~ 0xff);
1992#else
1993 desc = (u32*)((u32)desc &~ 0xff);
1994 dma_desc = (dma_addr_t)((u8*)dma_desc + 256);
1995 dma_desc = (dma_addr_t)((u32)dma_desc &~ 0xff);
1996#endif
1997 }
1998
1999 priv->rxring=desc;
2000 priv->rxringdma=dma_desc;
2001 tmp=desc;
2002
2003 for (i=0;i<count;i++){
2004
2005 if ((buf= kmalloc(bufsize * sizeof(u8),GFP_ATOMIC)) == NULL){
2006 DMESGE("Failed to kmalloc RX buffer");
2007 return -1;
2008 }
2009
2010 dma_tmp = pci_map_single(pdev,buf,bufsize * sizeof(u8),
2011 PCI_DMA_FROMDEVICE);
2012
2013#ifdef DEBUG_ZERO_RX
2014 int j;
2015 for(j=0;j<bufsize;j++) ((u8*)buf)[i] = 0;
2016#endif
2017
2018 //buf = (void*)pci_alloc_consistent(pdev,bufsize,&dma_tmp);
2019 if(-1 == buffer_add(&(priv->rxbuffer), buf,dma_tmp,
2020 &(priv->rxbufferhead))){
2021 DMESGE("Unable to allocate mem RX buf");
2022 return -1;
2023 }
2024 *tmp = 0; //zero pads the header of the descriptor
2025 *tmp = *tmp |( bufsize&0xfff);
2026 *(tmp+2) = (u32)dma_tmp;
2027 *tmp = *tmp |(1<<31); // descriptor void, owned by the NIC
2028
2029#ifdef DEBUG_RXALLOC
2030 DMESG("Alloc %x size buffer, DMA mem @ %x, virtual mem @ %x",
2031 (u32)(bufsize&0xfff), (u32)dma_tmp, (u32)buf);
2032#endif
2033
2034 tmp=tmp+rx_desc_size;
2035 }
2036
2037 *(tmp-rx_desc_size) = *(tmp-rx_desc_size) | (1<<30); // this is the last descriptor
2038
2039
2040#ifdef DEBUG_RXALLOC
2041 DMESG("RX DMA physical address: %x",dma_desc);
2042#endif
2043
2044 return 0;
2045}
2046
2047
2048void set_nic_rxring(struct net_device *dev)
2049{
2050 u8 pgreg;
2051 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
2052
2053 //rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
2054
2055 pgreg=read_nic_byte(dev, PGSELECT);
2056 write_nic_byte(dev, PGSELECT, pgreg &~ (1<<PGSELECT_PG_SHIFT));
2057
2058 //rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
2059
2060 write_nic_dword(dev, RXRING_ADDR,priv->rxringdma);
2061}
2062
2063
2064void rtl8180_reset(struct net_device *dev)
2065{
2066 //u32 txconf = 0x80e00707; //FIXME: Make me understandable
2067 u8 cr;
2068
2069 //write_nic_dword(dev,TX_CONF,txconf);
2070
2071 rtl8180_irq_disable(dev);
2072
2073 cr=read_nic_byte(dev,CMD);
2074 cr = cr & 2;
2075 cr = cr | (1<<CMD_RST_SHIFT);
2076 write_nic_byte(dev,CMD,cr);
2077
2078 force_pci_posting(dev);
2079
2080 mdelay(200);
2081
2082 if(read_nic_byte(dev,CMD) & (1<<CMD_RST_SHIFT))
2083 DMESGW("Card reset timeout!");
2084 else
2085 DMESG("Card successfully reset");
2086
2087//#ifndef CONFIG_RTL8185B
2088 rtl8180_set_mode(dev,EPROM_CMD_LOAD);
2089 force_pci_posting(dev);
2090 mdelay(200);
2091//#endif
2092}
2093
2094inline u16 ieeerate2rtlrate(int rate)
2095{
2096 switch(rate){
2097 case 10:
2098 return 0;
2099 case 20:
2100 return 1;
2101 case 55:
2102 return 2;
2103 case 110:
2104 return 3;
2105 case 60:
2106 return 4;
2107 case 90:
2108 return 5;
2109 case 120:
2110 return 6;
2111 case 180:
2112 return 7;
2113 case 240:
2114 return 8;
2115 case 360:
2116 return 9;
2117 case 480:
2118 return 10;
2119 case 540:
2120 return 11;
2121 default:
2122 return 3;
2123
2124 }
2125}
2126
2127static u16 rtl_rate[] = {10,20,55,110,60,90,120,180,240,360,480,540,720};
2128inline u16 rtl8180_rate2rate(short rate)
2129{
2130 if (rate >12) return 10;
2131 return rtl_rate[rate];
2132}
2133inline u8 rtl8180_IsWirelessBMode(u16 rate)
2134{
2135 if( ((rate <= 110) && (rate != 60) && (rate != 90)) || (rate == 220) )
2136 return 1;
2137 else return 0;
2138}
2139u16 N_DBPSOfRate(u16 DataRate);
2140u16 ComputeTxTime(
2141 u16 FrameLength,
2142 u16 DataRate,
2143 u8 bManagementFrame,
2144 u8 bShortPreamble
2145)
2146{
2147 u16 FrameTime;
2148 u16 N_DBPS;
2149 u16 Ceiling;
2150
2151 if( rtl8180_IsWirelessBMode(DataRate) )
2152 {
2153 if( bManagementFrame || !bShortPreamble || DataRate == 10 )
2154 { // long preamble
2155 FrameTime = (u16)(144+48+(FrameLength*8/(DataRate/10)));
2156 }
2157 else
2158 { // Short preamble
2159 FrameTime = (u16)(72+24+(FrameLength*8/(DataRate/10)));
2160 }
2161 if( ( FrameLength*8 % (DataRate/10) ) != 0 ) //Get the Ceilling
2162 FrameTime ++;
2163 } else { //802.11g DSSS-OFDM PLCP length field calculation.
2164 N_DBPS = N_DBPSOfRate(DataRate);
2165 Ceiling = (16 + 8*FrameLength + 6) / N_DBPS
2166 + (((16 + 8*FrameLength + 6) % N_DBPS) ? 1 : 0);
2167 FrameTime = (u16)(16 + 4 + 4*Ceiling + 6);
2168 }
2169 return FrameTime;
2170}
2171u16 N_DBPSOfRate(u16 DataRate)
2172{
2173 u16 N_DBPS = 24;
2174
2175 switch(DataRate)
2176 {
2177 case 60:
2178 N_DBPS = 24;
2179 break;
2180
2181 case 90:
2182 N_DBPS = 36;
2183 break;
2184
2185 case 120:
2186 N_DBPS = 48;
2187 break;
2188
2189 case 180:
2190 N_DBPS = 72;
2191 break;
2192
2193 case 240:
2194 N_DBPS = 96;
2195 break;
2196
2197 case 360:
2198 N_DBPS = 144;
2199 break;
2200
2201 case 480:
2202 N_DBPS = 192;
2203 break;
2204
2205 case 540:
2206 N_DBPS = 216;
2207 break;
2208
2209 default:
2210 break;
2211 }
2212
2213 return N_DBPS;
2214}
2215
2216//{by amy 080312
2217//
2218// Description:
2219// For Netgear case, they want good-looking singal strength.
2220// 2004.12.05, by rcnjko.
2221//
2222long
2223NetgearSignalStrengthTranslate(
2224 long LastSS,
2225 long CurrSS
2226 )
2227{
2228 long RetSS;
2229
2230 // Step 1. Scale mapping.
2231 if(CurrSS >= 71 && CurrSS <= 100)
2232 {
2233 RetSS = 90 + ((CurrSS - 70) / 3);
2234 }
2235 else if(CurrSS >= 41 && CurrSS <= 70)
2236 {
2237 RetSS = 78 + ((CurrSS - 40) / 3);
2238 }
2239 else if(CurrSS >= 31 && CurrSS <= 40)
2240 {
2241 RetSS = 66 + (CurrSS - 30);
2242 }
2243 else if(CurrSS >= 21 && CurrSS <= 30)
2244 {
2245 RetSS = 54 + (CurrSS - 20);
2246 }
2247 else if(CurrSS >= 5 && CurrSS <= 20)
2248 {
2249 RetSS = 42 + (((CurrSS - 5) * 2) / 3);
2250 }
2251 else if(CurrSS == 4)
2252 {
2253 RetSS = 36;
2254 }
2255 else if(CurrSS == 3)
2256 {
2257 RetSS = 27;
2258 }
2259 else if(CurrSS == 2)
2260 {
2261 RetSS = 18;
2262 }
2263 else if(CurrSS == 1)
2264 {
2265 RetSS = 9;
2266 }
2267 else
2268 {
2269 RetSS = CurrSS;
2270 }
2271 //RT_TRACE(COMP_DBG, DBG_LOUD, ("##### After Mapping: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
2272
2273 // Step 2. Smoothing.
2274 if(LastSS > 0)
2275 {
2276 RetSS = ((LastSS * 5) + (RetSS)+ 5) / 6;
2277 }
2278 //RT_TRACE(COMP_DBG, DBG_LOUD, ("$$$$$ After Smoothing: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
2279
2280 return RetSS;
2281}
2282//
2283// Description:
2284// Translate 0-100 signal strength index into dBm.
2285//
2286long
2287TranslateToDbm8185(
2288 u8 SignalStrengthIndex // 0-100 index.
2289 )
2290{
2291 long SignalPower; // in dBm.
2292
2293 // Translate to dBm (x=0.5y-95).
2294 SignalPower = (long)((SignalStrengthIndex + 1) >> 1);
2295 SignalPower -= 95;
2296
2297 return SignalPower;
2298}
2299//
2300// Description:
2301// Perform signal smoothing for dynamic mechanism.
2302// This is different with PerformSignalSmoothing8185 in smoothing fomula.
2303// No dramatic adjustion is apply because dynamic mechanism need some degree
2304// of correctness. Ported from 8187B.
2305// 2007-02-26, by Bruce.
2306//
2307void
2308PerformUndecoratedSignalSmoothing8185(
2309 struct r8180_priv *priv,
2310 bool bCckRate
2311 )
2312{
2313
2314
2315 // Determin the current packet is CCK rate.
2316 priv->bCurCCKPkt = bCckRate;
2317
2318 if(priv->UndecoratedSmoothedSS >= 0)
2319 {
2320 priv->UndecoratedSmoothedSS = ( (priv->UndecoratedSmoothedSS * 5) + (priv->SignalStrength * 10) ) / 6;
2321 }
2322 else
2323 {
2324 priv->UndecoratedSmoothedSS = priv->SignalStrength * 10;
2325 }
2326
2327 priv->UndercorateSmoothedRxPower = ( (priv->UndercorateSmoothedRxPower * 50) + (priv->RxPower* 11)) / 60;
2328
2329// printk("Sommthing SignalSterngth (%d) => UndecoratedSmoothedSS (%d)\n", priv->SignalStrength, priv->UndecoratedSmoothedSS);
2330// printk("Sommthing RxPower (%d) => UndecoratedRxPower (%d)\n", priv->RxPower, priv->UndercorateSmoothedRxPower);
2331
2332 //if(priv->CurCCKRSSI >= 0 && bCckRate)
2333 if(bCckRate)
2334 {
2335 priv->CurCCKRSSI = priv->RSSI;
2336 }
2337 else
2338 {
2339 priv->CurCCKRSSI = 0;
2340 }
2341
2342 // Boundary checking.
2343 // TODO: The overflow condition does happen, if we want to fix,
2344 // we shall recalculate thresholds first.
2345 if(priv->UndecoratedSmoothedSS > 100)
2346 {
2347// printk("UndecoratedSmoothedSS(%d) overflow, SignalStrength(%d)\n", priv->UndecoratedSmoothedSS, priv->SignalStrength);
2348 }
2349 if(priv->UndecoratedSmoothedSS < 0)
2350 {
2351// printk("UndecoratedSmoothedSS(%d) underflow, SignalStrength(%d)\n", priv->UndecoratedSmoothedSS, priv->SignalStrength);
2352 }
2353
2354}
2355
2356//by amy 080312}
2357
2358/* This is rough RX isr handling routine*/
2359void rtl8180_rx(struct net_device *dev)
2360{
2361 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
2362 struct sk_buff *tmp_skb;
2363
2364 //struct sk_buff *skb;
2365 short first,last;
2366 u32 len;
2367 int lastlen;
2368 unsigned char quality, signal;
2369 u8 rate;
2370 //u32 *prism_hdr;
2371 u32 *tmp,*tmp2;
2372 u8 rx_desc_size;
2373 u8 padding;
2374 //u32 count=0;
2375 char rxpower = 0;
2376 u32 RXAGC = 0;
2377 long RxAGC_dBm = 0;
2378 u8 LNA=0, BB=0;
2379 u8 LNA_gain[4]={02, 17, 29, 39};
2380 u8 Antenna = 0;
2381 struct ieee80211_hdr *hdr;//by amy
2382 u16 fc,type;
2383 u8 bHwError = 0,bCRC = 0,bICV = 0;
2384 //bHwError = 0;
2385 //bCRC = 0;
2386 //bICV = 0;
2387 bool bCckRate = false;
2388 u8 RSSI = 0;
2389 long SignalStrengthIndex = 0;//+by amy 080312
2390// u8 SignalStrength = 0;
2391 struct ieee80211_rx_stats stats = {
2392 .signal = 0,
2393 .noise = -98,
2394 .rate = 0,
2395 // .mac_time = jiffies,
2396 .freq = IEEE80211_24GHZ_BAND,
2397 };
2398
2399#ifdef CONFIG_RTL8185B
2400 stats.nic_type = NIC_8185B;
2401 rx_desc_size = 8;
2402
2403#else
2404 stats.nic_type = NIC_8185;
2405 rx_desc_size = 4;
2406#endif
2407 //printk("receive frame!%d\n",count++);
2408 //if (!priv->rxbuffer) DMESG ("EE: NIC RX ack, but RX queue corrupted!");
2409 //else {
2410
2411 if ((*(priv->rxringtail)) & (1<<31)) {
2412
2413 /* we have got an RX int, but the descriptor
2414 * we are pointing is empty*/
2415
2416 priv->stats.rxnodata++;
2417 priv->ieee80211->stats.rx_errors++;
2418
2419 /* if (! *(priv->rxring) & (1<<31)) {
2420
2421 priv->stats.rxreset++;
2422 priv->rxringtail=priv->rxring;
2423 priv->rxbuffer=priv->rxbufferhead;
2424
2425 }else{*/
2426
2427 #if 0
2428 /* Maybe it is possible that the NIC has skipped some descriptors or
2429 * it has reset its internal pointer to the beginning of the ring
2430 * we search for the first filled descriptor in the ring, or we break
2431 * putting again the pointer in the old location if we do not found any.
2432 * This is quite dangerous, what does happen if the nic writes
2433 * two descriptor (say A and B) when we have just checked the descriptor
2434 * A and we are going to check the descriptor B..This might happen if the
2435 * interrupt was dummy, there was not really filled descriptors and
2436 * the NIC didn't lose pointer
2437 */
2438
2439 //priv->stats.rxwrkaround++;
2440
2441 tmp = priv->rxringtail;
2442 while (*(priv->rxringtail) & (1<<31)){
2443
2444 priv->rxringtail+=4;
2445
2446 if(priv->rxringtail >=
2447 (priv->rxring)+(priv->rxringcount )*4)
2448 priv->rxringtail=priv->rxring;
2449
2450 priv->rxbuffer=(priv->rxbuffer->next);
2451
2452 if(priv->rxringtail == tmp ){
2453 //DMESG("EE: Could not find RX pointer");
2454 priv->stats.rxnopointer++;
2455 break;
2456 }
2457 }
2458 #else
2459
2460 tmp2 = NULL;
2461 tmp = priv->rxringtail;
2462 do{
2463 if(tmp == priv->rxring)
2464 //tmp = priv->rxring + (priv->rxringcount )*rx_desc_size; xiong-2006-11-15
2465 tmp = priv->rxring + (priv->rxringcount - 1)*rx_desc_size;
2466 else
2467 tmp -= rx_desc_size;
2468
2469 if(! (*tmp & (1<<31)))
2470 tmp2 = tmp;
2471 }while(tmp != priv->rxring);
2472
2473 if(tmp2) priv->rxringtail = tmp2;
2474 #endif
2475 //}
2476 }
2477
2478 /* while there are filled descriptors */
2479 while(!(*(priv->rxringtail) & (1<<31))){
2480 if(*(priv->rxringtail) & (1<<26))
2481 DMESGW("RX buffer overflow");
2482 if(*(priv->rxringtail) & (1<<12))
2483 priv->stats.rxicverr++;
2484
2485 if(*(priv->rxringtail) & (1<<27)){
2486 priv->stats.rxdmafail++;
2487 //DMESG("EE: RX DMA FAILED at buffer pointed by descriptor %x",(u32)priv->rxringtail);
2488 goto drop;
2489 }
2490
2491 pci_dma_sync_single_for_cpu(priv->pdev,
2492 priv->rxbuffer->dma,
2493 priv->rxbuffersize * \
2494 sizeof(u8),
2495 PCI_DMA_FROMDEVICE);
2496
2497 first = *(priv->rxringtail) & (1<<29) ? 1:0;
2498 if(first) priv->rx_prevlen=0;
2499
2500 last = *(priv->rxringtail) & (1<<28) ? 1:0;
2501 if(last){
2502 lastlen=((*priv->rxringtail) &0xfff);
2503
2504 /* if the last descriptor (that should
2505 * tell us the total packet len) tell
2506 * us something less than the descriptors
2507 * len we had until now, then there is some
2508 * problem..
2509 * workaround to prevent kernel panic
2510 */
2511 if(lastlen < priv->rx_prevlen)
2512 len=0;
2513 else
2514 len=lastlen-priv->rx_prevlen;
2515
2516 if(*(priv->rxringtail) & (1<<13)) {
2517//lastlen=((*priv->rxringtail) &0xfff);
2518 if ((*(priv->rxringtail) & 0xfff) <500)
2519 priv->stats.rxcrcerrmin++;
2520 else if ((*(priv->rxringtail) & 0x0fff) >1000)
2521 priv->stats.rxcrcerrmax++;
2522 else
2523 priv->stats.rxcrcerrmid++;
2524
2525 }
2526
2527 }else{
2528 len = priv->rxbuffersize;
2529 }
2530
2531#ifdef CONFIG_RTL8185B
2532 if(first && last) {
2533 padding = ((*(priv->rxringtail+3))&(0x04000000))>>26;
2534 }else if(first) {
2535 padding = ((*(priv->rxringtail+3))&(0x04000000))>>26;
2536 if(padding) {
2537 len -= 2;
2538 }
2539 }else {
2540 padding = 0;
2541 }
2542#ifdef CONFIG_RTL818X_S
2543 padding = 0;
2544#endif
2545#endif
2546 priv->rx_prevlen+=len;
2547
2548 if(priv->rx_prevlen > MAX_FRAG_THRESHOLD + 100){
2549 /* HW is probably passing several buggy frames
2550 * without FD or LD flag set.
2551 * Throw this garbage away to prevent skb
2552 * memory exausting
2553 */
2554 if(!priv->rx_skb_complete)
2555 dev_kfree_skb_any(priv->rx_skb);
2556 priv->rx_skb_complete = 1;
2557 }
2558
2559#ifdef DEBUG_RX_FRAG
2560 DMESG("Iteration.. len %x",len);
2561 if(first) DMESG ("First descriptor");
2562 if(last) DMESG("Last descriptor");
2563
2564#endif
2565#ifdef DEBUG_RX_VERBOSE
2566 print_buffer( priv->rxbuffer->buf, len);
2567#endif
2568
2569#ifdef CONFIG_RTL8185B
2570 signal=(unsigned char)(((*(priv->rxringtail+3))& (0x00ff0000))>>16);
2571 signal=(signal&0xfe)>>1; // Modify by hikaru 6.6
2572
2573 quality=(unsigned char)((*(priv->rxringtail+3)) & (0xff));
2574
2575 stats.mac_time[0] = *(priv->rxringtail+1);
2576 stats.mac_time[1] = *(priv->rxringtail+2);
2577 rxpower =((char)(((*(priv->rxringtail+4))& (0x00ff0000))>>16))/2 - 42;
2578 RSSI = ((u8)(((*(priv->rxringtail+3)) & (0x0000ff00))>> 8)) & (0x7f);
2579
2580#else
2581 signal=((*(priv->rxringtail+1))& (0xff0000))>>16;
2582 signal=(signal&0xfe)>>1; // Modify by hikaru 6.6
2583
2584 quality=((*(priv->rxringtail+1)) & (0xff));
2585
2586 stats.mac_time[0] = *(priv->rxringtail+2);
2587 stats.mac_time[1] = *(priv->rxringtail+3);
2588#endif
2589 rate=((*(priv->rxringtail)) &
2590 ((1<<23)|(1<<22)|(1<<21)|(1<<20)))>>20;
2591
2592 stats.rate = rtl8180_rate2rate(rate);
2593 //DMESG("%d",rate);
2594 Antenna = (((*(priv->rxringtail +3))& (0x00008000)) == 0 )? 0:1 ;
2595// printk("in rtl8180_rx():Antenna is %d\n",Antenna);
2596//by amy for antenna
2597 if(!rtl8180_IsWirelessBMode(stats.rate))
2598 { // OFDM rate.
2599
2600 RxAGC_dBm = rxpower+1; //bias
2601 }
2602 else
2603 { // CCK rate.
2604 RxAGC_dBm = signal;//bit 0 discard
2605
2606 LNA = (u8) (RxAGC_dBm & 0x60 ) >> 5 ; //bit 6~ bit 5
2607 BB = (u8) (RxAGC_dBm & 0x1F); // bit 4 ~ bit 0
2608
2609 RxAGC_dBm = -( LNA_gain[LNA] + (BB *2) ); //Pin_11b=-(LNA_gain+BB_gain) (dBm)
2610
2611 RxAGC_dBm +=4; //bias
2612 }
2613
2614 if(RxAGC_dBm & 0x80) //absolute value
2615 RXAGC= ~(RxAGC_dBm)+1;
2616 bCckRate = rtl8180_IsWirelessBMode(stats.rate);
2617 // Translate RXAGC into 1-100.
2618 if(!rtl8180_IsWirelessBMode(stats.rate))
2619 { // OFDM rate.
2620 if(RXAGC>90)
2621 RXAGC=90;
2622 else if(RXAGC<25)
2623 RXAGC=25;
2624 RXAGC=(90-RXAGC)*100/65;
2625 }
2626 else
2627 { // CCK rate.
2628 if(RXAGC>95)
2629 RXAGC=95;
2630 else if(RXAGC<30)
2631 RXAGC=30;
2632 RXAGC=(95-RXAGC)*100/65;
2633 }
2634 priv->SignalStrength = (u8)RXAGC;
2635 priv->RecvSignalPower = RxAGC_dBm ; // It can use directly by SD3 CMLin
2636 priv->RxPower = rxpower;
2637 priv->RSSI = RSSI;
2638//{by amy 080312
2639 // SQ translation formular is provided by SD3 DZ. 2006.06.27, by rcnjko.
2640 if(quality >= 127)
2641 quality = 1;//0; //0 will cause epc to show signal zero , walk aroud now;
2642 else if(quality < 27)
2643 quality = 100;
2644 else
2645 quality = 127 - quality;
2646 priv->SignalQuality = quality;
2647 if(!priv->card_8185)
2648 printk("check your card type\n");
2649
2650 stats.signal = (u8)quality;//priv->wstats.qual.level = priv->SignalStrength;
2651 stats.signalstrength = RXAGC;
2652 if(stats.signalstrength > 100)
2653 stats.signalstrength = 100;
2654 stats.signalstrength = (stats.signalstrength * 70)/100 + 30;
2655 // printk("==========================>rx : RXAGC is %d,signalstrength is %d\n",RXAGC,stats.signalstrength);
2656 stats.rssi = priv->wstats.qual.qual = priv->SignalQuality;
2657 stats.noise = priv->wstats.qual.noise = 100 - priv ->wstats.qual.qual;
2658//by amy 080312}
2659 bHwError = (((*(priv->rxringtail))& (0x00000fff)) == 4080)| (((*(priv->rxringtail))& (0x04000000)) != 0 )
2660 | (((*(priv->rxringtail))& (0x08000000)) != 0 )| (((~(*(priv->rxringtail)))& (0x10000000)) != 0 )| (((~(*(priv->rxringtail)))& (0x20000000)) != 0 );
2661 bCRC = ((*(priv->rxringtail)) & (0x00002000)) >> 13;
2662 bICV = ((*(priv->rxringtail)) & (0x00001000)) >> 12;
2663 hdr = (struct ieee80211_hdr *)priv->rxbuffer->buf;
2664 fc = le16_to_cpu(hdr->frame_ctl);
2665 type = WLAN_FC_GET_TYPE(fc);
2666
2667 if((IEEE80211_FTYPE_CTL != type) &&
2668 (eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3))
2669 && (!bHwError) && (!bCRC)&& (!bICV))
2670 {
2671//by amy 080312
2672 // Perform signal smoothing for dynamic mechanism on demand.
2673 // This is different with PerformSignalSmoothing8185 in smoothing fomula.
2674 // No dramatic adjustion is apply because dynamic mechanism need some degree
2675 // of correctness. 2007.01.23, by shien chang.
2676 PerformUndecoratedSignalSmoothing8185(priv,bCckRate);
2677 //
2678 // For good-looking singal strength.
2679 //
2680 SignalStrengthIndex = NetgearSignalStrengthTranslate(
2681 priv->LastSignalStrengthInPercent,
2682 priv->SignalStrength);
2683
2684 priv->LastSignalStrengthInPercent = SignalStrengthIndex;
2685 priv->Stats_SignalStrength = TranslateToDbm8185((u8)SignalStrengthIndex);
2686 //
2687 // We need more correct power of received packets and the "SignalStrength" of RxStats is beautified,
2688 // so we record the correct power here.
2689 //
2690 priv->Stats_SignalQuality =(long) (priv->Stats_SignalQuality * 5 + (long)priv->SignalQuality + 5) / 6;
2691 priv->Stats_RecvSignalPower = (long)(priv->Stats_RecvSignalPower * 5 + priv->RecvSignalPower -1) / 6;
2692
2693 // Figure out which antenna that received the lasted packet.
2694 priv->LastRxPktAntenna = Antenna ? 1 : 0; // 0: aux, 1: main.
2695//by amy 080312
2696 SwAntennaDiversityRxOk8185(dev, priv->SignalStrength);
2697 }
2698
2699//by amy for antenna
2700
2701
2702
2703
2704
2705
2706#ifndef DUMMY_RX
2707 if(first){
2708 if(!priv->rx_skb_complete){
2709 /* seems that HW sometimes fails to reiceve and
2710 doesn't provide the last descriptor */
2711#ifdef DEBUG_RX_SKB
2712 DMESG("going to free incomplete skb");
2713#endif
2714 dev_kfree_skb_any(priv->rx_skb);
2715 priv->stats.rxnolast++;
2716#ifdef DEBUG_RX_SKB
2717 DMESG("free incomplete skb OK");
2718#endif
2719 }
2720 /* support for prism header has been originally added by Christian */
2721 if(priv->prism_hdr && priv->ieee80211->iw_mode == IW_MODE_MONITOR){
2722
2723#if 0
2724 priv->rx_skb = dev_alloc_skb(len+2+PRISM_HDR_SIZE);
2725 if(! priv->rx_skb) goto drop;
2726
2727 prism_hdr = (u32*) skb_put(priv->rx_skb,PRISM_HDR_SIZE);
2728 prism_hdr[0]=htonl(0x80211001); //version
2729 prism_hdr[1]=htonl(0x40); //length
2730 prism_hdr[2]=htonl(stats.mac_time[1]); //mactime (HIGH)
2731 prism_hdr[3]=htonl(stats.mac_time[0]); //mactime (LOW)
2732 rdtsc(prism_hdr[5], prism_hdr[4]); //hostime (LOW+HIGH)
2733 prism_hdr[4]=htonl(prism_hdr[4]); //Byte-Order aendern
2734 prism_hdr[5]=htonl(prism_hdr[5]); //Byte-Order aendern
2735 prism_hdr[6]=0x00; //phytype
2736 prism_hdr[7]=htonl(priv->chan); //channel
2737 prism_hdr[8]=htonl(stats.rate); //datarate
2738 prism_hdr[9]=0x00; //antenna
2739 prism_hdr[10]=0x00; //priority
2740 prism_hdr[11]=0x00; //ssi_type
2741 prism_hdr[12]=htonl(stats.signal); //ssi_signal
2742 prism_hdr[13]=htonl(stats.noise); //ssi_noise
2743 prism_hdr[14]=0x00; //preamble
2744 prism_hdr[15]=0x00; //encoding
2745
2746#endif
2747 }else{
2748 priv->rx_skb = dev_alloc_skb(len+2);
2749 if( !priv->rx_skb) goto drop;
2750#ifdef DEBUG_RX_SKB
2751 DMESG("Alloc initial skb %x",len+2);
2752#endif
2753 }
2754
2755 priv->rx_skb_complete=0;
2756 priv->rx_skb->dev=dev;
2757 }else{
2758 /* if we are here we should have already RXed
2759 * the first frame.
2760 * If we get here and the skb is not allocated then
2761 * we have just throw out garbage (skb not allocated)
2762 * and we are still rxing garbage....
2763 */
2764 if(!priv->rx_skb_complete){
2765
2766 tmp_skb= dev_alloc_skb(priv->rx_skb->len +len+2);
2767
2768 if(!tmp_skb) goto drop;
2769
2770 tmp_skb->dev=dev;
2771#ifdef DEBUG_RX_SKB
2772 DMESG("Realloc skb %x",len+2);
2773#endif
2774
2775#ifdef DEBUG_RX_SKB
2776 DMESG("going copy prev frag %x",priv->rx_skb->len);
2777#endif
2778 memcpy(skb_put(tmp_skb,priv->rx_skb->len),
2779 priv->rx_skb->data,
2780 priv->rx_skb->len);
2781#ifdef DEBUG_RX_SKB
2782 DMESG("skb copy prev frag complete");
2783#endif
2784
2785 dev_kfree_skb_any(priv->rx_skb);
2786#ifdef DEBUG_RX_SKB
2787 DMESG("prev skb free ok");
2788#endif
2789
2790 priv->rx_skb=tmp_skb;
2791 }
2792 }
2793#ifdef DEBUG_RX_SKB
2794 DMESG("going to copy current payload %x",len);
2795#endif
2796 if(!priv->rx_skb_complete) {
2797#ifdef CONFIG_RTL8185B
2798 if(padding) {
2799 memcpy(skb_put(priv->rx_skb,len),
2800 (((unsigned char *)priv->rxbuffer->buf) + 2),len);
2801 } else {
2802#endif
2803 memcpy(skb_put(priv->rx_skb,len),
2804 priv->rxbuffer->buf,len);
2805#ifdef CONFIG_RTL8185B
2806 }
2807#endif
2808 }
2809#ifdef DEBUG_RX_SKB
2810 DMESG("current fragment skb copy complete");
2811#endif
2812
2813 if(last && !priv->rx_skb_complete){
2814
2815#ifdef DEBUG_RX_SKB
2816 DMESG("Got last fragment");
2817#endif
2818
2819 if(priv->rx_skb->len > 4)
2820 skb_trim(priv->rx_skb,priv->rx_skb->len-4);
2821#ifdef DEBUG_RX_SKB
2822 DMESG("yanked out crc, passing to the upper layer");
2823#endif
2824
2825#ifndef RX_DONT_PASS_UL
2826 if(!ieee80211_rx(priv->ieee80211,
2827 priv->rx_skb, &stats)){
2828#ifdef DEBUG_RX
2829 DMESGW("Packet not consumed");
2830#endif
2831#endif // RX_DONT_PASS_UL
2832
2833 dev_kfree_skb_any(priv->rx_skb);
2834#ifndef RX_DONT_PASS_UL
2835 }
2836#endif
2837#ifdef DEBUG_RX
2838 else{
2839 DMESG("Rcv frag");
2840 }
2841#endif
2842 priv->rx_skb_complete=1;
2843 }
2844
2845#endif //DUMMY_RX
2846
2847 pci_dma_sync_single_for_device(priv->pdev,
2848 priv->rxbuffer->dma,
2849 priv->rxbuffersize * \
2850 sizeof(u8),
2851 PCI_DMA_FROMDEVICE);
2852
2853
2854drop: // this is used when we have not enought mem
2855
2856 /* restore the descriptor */
2857 *(priv->rxringtail+2)=priv->rxbuffer->dma;
2858 *(priv->rxringtail)=*(priv->rxringtail) &~ 0xfff;
2859 *(priv->rxringtail)=
2860 *(priv->rxringtail) | priv->rxbuffersize;
2861
2862 *(priv->rxringtail)=
2863 *(priv->rxringtail) | (1<<31);
2864 //^empty descriptor
2865
2866 //wmb();
2867
2868#ifdef DEBUG_RX
2869 DMESG("Current descriptor: %x",(u32)priv->rxringtail);
2870#endif
2871 //unsigned long flags;
2872 //spin_lock_irqsave(&priv->irq_lock,flags);
2873
2874 priv->rxringtail+=rx_desc_size;
2875 if(priv->rxringtail >=
2876 (priv->rxring)+(priv->rxringcount )*rx_desc_size)
2877 priv->rxringtail=priv->rxring;
2878
2879 //spin_unlock_irqrestore(&priv->irq_lock,flags);
2880
2881
2882 priv->rxbuffer=(priv->rxbuffer->next);
2883
2884 }
2885
2886
2887
2888// if(get_curr_tx_free_desc(dev,priority))
2889// ieee80211_sta_ps_sleep(priv->ieee80211, &tmp, &tmp2);
2890
2891
2892
2893}
2894
2895
2896void rtl8180_dma_kick(struct net_device *dev, int priority)
2897{
2898 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
2899
2900 rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
2901/*
2902
2903 switch(priority){
2904
2905 case LOW_PRIORITY:
2906
2907 write_nic_byte(dev,TX_DMA_POLLING,
2908 (1<< TX_DMA_POLLING_LOWPRIORITY_SHIFT) |
2909 priv->dma_poll_mask);
2910 break;
2911
2912 case NORM_PRIORITY:
2913
2914 write_nic_byte(dev,TX_DMA_POLLING,
2915 (1<< TX_DMA_POLLING_NORMPRIORITY_SHIFT) |
2916 priv->dma_poll_mask);
2917 break;
2918
2919 case HI_PRIORITY:
2920
2921 write_nic_byte(dev,TX_DMA_POLLING,
2922 (1<< TX_DMA_POLLING_HIPRIORITY_SHIFT) |
2923 priv->dma_poll_mask);
2924 break;
2925
2926 }
2927*/
2928 write_nic_byte(dev, TX_DMA_POLLING,
2929 (1 << (priority + 1)) | priv->dma_poll_mask);
2930 rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
2931
2932 force_pci_posting(dev);
2933}
2934
2935#if 0
2936void rtl8180_tx_queues_stop(struct net_device *dev)
2937{
2938 //struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
2939 u8 dma_poll_mask = (1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
2940 dma_poll_mask |= (1<<TX_DMA_STOP_HIPRIORITY_SHIFT);
2941 dma_poll_mask |= (1<<TX_DMA_STOP_NORMPRIORITY_SHIFT);
2942 dma_poll_mask |= (1<<TX_DMA_STOP_BEACON_SHIFT);
2943
2944 rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
2945 write_nic_byte(dev,TX_DMA_POLLING,dma_poll_mask);
2946 rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
2947}
2948#endif
2949
2950void rtl8180_data_hard_stop(struct net_device *dev)
2951{
2952 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
2953
2954 rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
2955#ifdef CONFIG_RTL8185B
2956 priv->dma_poll_stop_mask |= TPPOLLSTOP_AC_VIQ;
2957 write_nic_byte(dev,TPPollStop, priv->dma_poll_stop_mask);
2958#else
2959 priv->dma_poll_mask |= (1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
2960 write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
2961#endif
2962 rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
2963}
2964
2965
2966void rtl8180_data_hard_resume(struct net_device *dev)
2967{
2968 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
2969
2970 rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
2971#ifdef CONFIG_RTL8185B
2972 priv->dma_poll_stop_mask &= ~(TPPOLLSTOP_AC_VIQ);
2973 write_nic_byte(dev,TPPollStop, priv->dma_poll_stop_mask);
2974#else
2975 priv->dma_poll_mask &= ~(1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
2976 write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
2977#endif
2978 rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
2979}
2980
2981
2982/* this function TX data frames when the ieee80211 stack requires this.
2983 * It checks also if we need to stop the ieee tx queue, eventually do it
2984 */
2985void rtl8180_hard_data_xmit(struct sk_buff *skb,struct net_device *dev, int
2986rate)
2987{
2988 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
2989 int mode;
2990 struct ieee80211_hdr_3addr *h = (struct ieee80211_hdr_3addr *) skb->data;
2991 short morefrag = (h->frame_ctl) & IEEE80211_FCTL_MOREFRAGS;
2992 unsigned long flags;
2993 int priority;
2994 //static int count = 0;
2995
2996 mode = priv->ieee80211->iw_mode;
2997
2998 rate = ieeerate2rtlrate(rate);
2999 /*
3000 * This function doesn't require lock because we make
3001 * sure it's called with the tx_lock already acquired.
3002 * this come from the kernel's hard_xmit callback (trought
3003 * the ieee stack, or from the try_wake_queue (again trought
3004 * the ieee stack.
3005 */
3006#ifdef CONFIG_RTL8185B
3007 priority = AC2Q(skb->priority);
3008#else
3009 priority = LOW_PRIORITY;
3010#endif
3011 spin_lock_irqsave(&priv->tx_lock,flags);
3012
3013 if(priv->ieee80211->bHwRadioOff)
3014 {
3015 spin_unlock_irqrestore(&priv->tx_lock,flags);
3016
3017 return;
3018 }
3019
3020 //printk(KERN_WARNING "priority = %d@%d\n", priority, count++);
3021 if (!check_nic_enought_desc(dev, priority)){
3022 //DMESG("Error: no descriptor left by previous TX (avail %d) ",
3023 // get_curr_tx_free_desc(dev, priority));
3024 DMESGW("Error: no descriptor left by previous TX (avail %d) ",
3025 get_curr_tx_free_desc(dev, priority));
3026 //printk(KERN_WARNING "==============================================================> \n");
3027 ieee80211_stop_queue(priv->ieee80211);
3028 }
3029 rtl8180_tx(dev, skb->data, skb->len, priority, morefrag,0,rate);
3030 if (!check_nic_enought_desc(dev, priority))
3031 ieee80211_stop_queue(priv->ieee80211);
3032
3033 //dev_kfree_skb_any(skb);
3034 spin_unlock_irqrestore(&priv->tx_lock,flags);
3035
3036}
3037
3038/* This is a rough attempt to TX a frame
3039 * This is called by the ieee 80211 stack to TX management frames.
3040 * If the ring is full packet are dropped (for data frame the queue
3041 * is stopped before this can happen). For this reason it is better
3042 * if the descriptors are larger than the largest management frame
3043 * we intend to TX: i'm unsure what the HW does if it will not found
3044 * the last fragment of a frame because it has been dropped...
3045 * Since queues for Management and Data frames are different we
3046 * might use a different lock than tx_lock (for example mgmt_tx_lock)
3047 */
3048/* these function may loops if invoked with 0 descriptors or 0 len buffer*/
3049int rtl8180_hard_start_xmit(struct sk_buff *skb,struct net_device *dev)
3050{
3051 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
3052
3053 unsigned long flags;
3054
3055 int priority;
3056
3057#ifdef CONFIG_RTL8185B
3058 priority = MANAGE_PRIORITY;
3059#else
3060 priority = NORM_PRIORITY;
3061#endif
3062
3063 spin_lock_irqsave(&priv->tx_lock,flags);
3064
3065 if(priv->ieee80211->bHwRadioOff)
3066 {
3067 spin_unlock_irqrestore(&priv->tx_lock,flags);
3068
3069 dev_kfree_skb_any(skb);
3070 return 0;
3071 }
3072
3073 rtl8180_tx(dev, skb->data, skb->len, priority,
3074 0, 0,ieeerate2rtlrate(priv->ieee80211->basic_rate));
3075
3076 priv->ieee80211->stats.tx_bytes+=skb->len;
3077 priv->ieee80211->stats.tx_packets++;
3078 spin_unlock_irqrestore(&priv->tx_lock,flags);
3079
3080 dev_kfree_skb_any(skb);
3081 return 0;
3082}
3083
3084// longpre 144+48 shortpre 72+24
3085u16 rtl8180_len2duration(u32 len, short rate,short* ext)
3086{
3087 u16 duration;
3088 u16 drift;
3089 *ext=0;
3090
3091 switch(rate){
3092 case 0://1mbps
3093 *ext=0;
3094 duration = ((len+4)<<4) /0x2;
3095 drift = ((len+4)<<4) % 0x2;
3096 if(drift ==0 ) break;
3097 duration++;
3098 break;
3099
3100 case 1://2mbps
3101 *ext=0;
3102 duration = ((len+4)<<4) /0x4;
3103 drift = ((len+4)<<4) % 0x4;
3104 if(drift ==0 ) break;
3105 duration++;
3106 break;
3107
3108 case 2: //5.5mbps
3109 *ext=0;
3110 duration = ((len+4)<<4) /0xb;
3111 drift = ((len+4)<<4) % 0xb;
3112 if(drift ==0 )
3113 break;
3114 duration++;
3115 break;
3116
3117 default:
3118 case 3://11mbps
3119 *ext=0;
3120 duration = ((len+4)<<4) /0x16;
3121 drift = ((len+4)<<4) % 0x16;
3122 if(drift ==0 )
3123 break;
3124 duration++;
3125 if(drift > 6)
3126 break;
3127 *ext=1;
3128 break;
3129 }
3130
3131 return duration;
3132}
3133
3134
3135void rtl8180_prepare_beacon(struct net_device *dev)
3136{
3137
3138 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
3139
3140 struct sk_buff *skb;
3141
3142 u16 word = read_nic_word(dev, BcnItv);
3143 word &= ~BcnItv_BcnItv; // clear Bcn_Itv
3144 word |= cpu_to_le16(priv->ieee80211->current_network.beacon_interval);//0x64;
3145 write_nic_word(dev, BcnItv, word);
3146
3147
3148 skb = ieee80211_get_beacon(priv->ieee80211);
3149 if(skb){
3150 rtl8180_tx(dev,skb->data,skb->len,BEACON_PRIORITY,
3151 0,0,ieeerate2rtlrate(priv->ieee80211->basic_rate));
3152 dev_kfree_skb_any(skb);
3153 }
3154 #if 0
3155 //DMESG("size %x",len);
3156 if(*tail & (1<<31)){
3157
3158 //DMESG("No more beacon TX desc");
3159 return ;
3160
3161 }
3162 //while(! *tail & (1<<31)){
3163 *tail= 0; // zeroes header
3164
3165 *tail = *tail| (1<<29) ; //fist segment of the packet
3166 *tail = (*tail) | (1<<28); // last segment
3167 // *tail = *tail | (1<<18); // this is a beacon frame
3168 *(tail+3)=*(tail+3) &~ 0xfff;
3169 *(tail+3)=*(tail+3) | len; // buffer lenght
3170 *tail = *tail |len;
3171 // zeroes the second 32-bits dword of the descriptor
3172 *(tail+1)= 0;
3173 *tail = *tail | (rate << 24);
3174
3175 duration = rtl8180_len2duration(len,rate,&ext);
3176
3177 *(tail+1) = *(tail+1) | ((duration & 0x7fff)<<16);
3178
3179 *tail = *tail | (1<<31);
3180 //^ descriptor ready to be txed
3181 if((tail - begin)/8 == priv->txbeaconcount-1)
3182 tail=begin;
3183 else
3184 tail=tail+8;
3185 //}
3186#endif
3187}
3188
3189/* This function do the real dirty work: it enqueues a TX command
3190 * descriptor in the ring buffer, copyes the frame in a TX buffer
3191 * and kicks the NIC to ensure it does the DMA transfer.
3192 */
3193short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority,
3194 short morefrag, short descfrag, int rate)
3195{
3196 struct r8180_priv *priv = ieee80211_priv(dev);
3197 u32 *tail,*temp_tail;
3198 u32 *begin;
3199 u32 *buf;
3200 int i;
3201 int remain;
3202 int buflen;
3203 int count;
3204 //u16 AckCtsTime;
3205 //u16 FrameTime;
3206 u16 duration;
3207 short ext;
3208 struct buffer* buflist;
3209 //unsigned long flags;
3210#ifdef CONFIG_RTL8185B
3211 struct ieee80211_hdr_3addr *frag_hdr = (struct ieee80211_hdr_3addr *)txbuf;
3212 u8 dest[ETH_ALEN];
3213 u8 bUseShortPreamble = 0;
3214 u8 bCTSEnable = 0;
3215 u8 bRTSEnable = 0;
3216 //u16 RTSRate = 22;
3217 //u8 RetryLimit = 0;
3218 u16 Duration = 0;
3219 u16 RtsDur = 0;
3220 u16 ThisFrameTime = 0;
3221 u16 TxDescDuration = 0;
3222 u8 ownbit_flag = false; //added by david woo for sync Tx, 2007.12.14
3223#endif
3224
3225 switch(priority) {
3226 case MANAGE_PRIORITY:
3227 tail=priv->txmapringtail;
3228 begin=priv->txmapring;
3229 buflist = priv->txmapbufstail;
3230 count = priv->txringcount;
3231 break;
3232
3233 case BK_PRIORITY:
3234 tail=priv->txbkpringtail;
3235 begin=priv->txbkpring;
3236 buflist = priv->txbkpbufstail;
3237 count = priv->txringcount;
3238 break;
3239
3240 case BE_PRIORITY:
3241 tail=priv->txbepringtail;
3242 begin=priv->txbepring;
3243 buflist = priv->txbepbufstail;
3244 count = priv->txringcount;
3245 break;
3246
3247 case VI_PRIORITY:
3248 tail=priv->txvipringtail;
3249 begin=priv->txvipring;
3250 buflist = priv->txvipbufstail;
3251 count = priv->txringcount;
3252 break;
3253
3254 case VO_PRIORITY:
3255 tail=priv->txvopringtail;
3256 begin=priv->txvopring;
3257 buflist = priv->txvopbufstail;
3258 count = priv->txringcount;
3259 break;
3260
3261 case HI_PRIORITY:
3262 tail=priv->txhpringtail;
3263 begin=priv->txhpring;
3264 buflist = priv->txhpbufstail;
3265 count = priv->txringcount;
3266 break;
3267
3268 case BEACON_PRIORITY:
3269 tail=priv->txbeaconringtail;
3270 begin=priv->txbeaconring;
3271 buflist = priv->txbeaconbufstail;
3272 count = priv->txbeaconcount;
3273 break;
3274
3275 default:
3276 return -1;
3277 break;
3278 }
3279
3280 //printk("in rtl8180_tx(): rate is %d\n",priv->ieee80211->rate);
3281#if 1
3282 memcpy(&dest, frag_hdr->addr1, ETH_ALEN);
3283 if (is_multicast_ether_addr(dest) ||
3284 is_broadcast_ether_addr(dest))
3285 {
3286 Duration = 0;
3287 RtsDur = 0;
3288 bRTSEnable = 0;
3289 bCTSEnable = 0;
3290
3291 ThisFrameTime = ComputeTxTime(len + sCrcLng, rtl8180_rate2rate(rate), 0, bUseShortPreamble);
3292 TxDescDuration = ThisFrameTime;
3293 } else {// Unicast packet
3294 //u8 AckRate;
3295 u16 AckTime;
3296
3297 //YJ,add,080828,for Keep alive
3298 priv->NumTxUnicast++;
3299
3300 // Figure out ACK rate according to BSS basic rate and Tx rate, 2006.03.08 by rcnjko.
3301 //AckRate = ComputeAckRate( pMgntInfo->mBrates, (u1Byte)(pTcb->DataRate) );
3302 // Figure out ACK time according to the AckRate and assume long preamble is used on receiver, 2006.03.08, by rcnjko.
3303 //AckTime = ComputeTxTime( sAckCtsLng/8, AckRate, FALSE, FALSE);
3304 //For simplicity, just use the 1M basic rate
3305 //AckTime = ComputeTxTime(14, 540,0, 0); // AckCTSLng = 14 use 1M bps send
3306 AckTime = ComputeTxTime(14, 10,0, 0); // AckCTSLng = 14 use 1M bps send
3307 //AckTime = ComputeTxTime(14, 2,false, false); // AckCTSLng = 14 use 1M bps send
3308
3309 if ( ((len + sCrcLng) > priv->rts) && priv->rts )
3310 { // RTS/CTS.
3311 u16 RtsTime, CtsTime;
3312 //u16 CtsRate;
3313 bRTSEnable = 1;
3314 bCTSEnable = 0;
3315
3316 // Rate and time required for RTS.
3317 RtsTime = ComputeTxTime( sAckCtsLng/8,priv->ieee80211->basic_rate, 0, 0);
3318 // Rate and time required for CTS.
3319 CtsTime = ComputeTxTime(14, 10,0, 0); // AckCTSLng = 14 use 1M bps send
3320
3321 // Figure out time required to transmit this frame.
3322 ThisFrameTime = ComputeTxTime(len + sCrcLng,
3323 rtl8180_rate2rate(rate),
3324 0,
3325 bUseShortPreamble);
3326
3327 // RTS-CTS-ThisFrame-ACK.
3328 RtsDur = CtsTime + ThisFrameTime + AckTime + 3*aSifsTime;
3329
3330 TxDescDuration = RtsTime + RtsDur;
3331 }
3332 else {// Normal case.
3333 bCTSEnable = 0;
3334 bRTSEnable = 0;
3335 RtsDur = 0;
3336
3337 ThisFrameTime = ComputeTxTime(len + sCrcLng, rtl8180_rate2rate(rate), 0, bUseShortPreamble);
3338 TxDescDuration = ThisFrameTime + aSifsTime + AckTime;
3339 }
3340
3341 if(!(frag_hdr->frame_ctl & IEEE80211_FCTL_MOREFRAGS)) { //no more fragment
3342 // ThisFrame-ACK.
3343 Duration = aSifsTime + AckTime;
3344 } else { // One or more fragments remained.
3345 u16 NextFragTime;
3346 NextFragTime = ComputeTxTime( len + sCrcLng, //pretend following packet length equal current packet
3347 rtl8180_rate2rate(rate),
3348 0,
3349 bUseShortPreamble );
3350
3351 //ThisFrag-ACk-NextFrag-ACK.
3352 Duration = NextFragTime + 3*aSifsTime + 2*AckTime;
3353 }
3354
3355 } // End of Unicast packet
3356
3357 frag_hdr->duration_id = Duration;
3358#endif
3359
3360 buflen=priv->txbuffsize;
3361 remain=len;
3362 temp_tail = tail;
3363//printk("================================>buflen = %d, remain = %d!\n", buflen,remain);
3364 while(remain!=0){
3365#ifdef DEBUG_TX_FRAG
3366 DMESG("TX iteration");
3367#endif
3368#ifdef DEBUG_TX
3369 DMESG("TX: filling descriptor %x",(u32)tail);
3370#endif
3371 mb();
3372 if(!buflist){
3373 DMESGE("TX buffer error, cannot TX frames. pri %d.", priority);
3374 //spin_unlock_irqrestore(&priv->tx_lock,flags);
3375 return -1;
3376 }
3377 buf=buflist->buf;
3378
3379 if( (*tail & (1<<31)) && (priority != BEACON_PRIORITY)){
3380
3381 DMESGW("No more TX desc, returning %x of %x",
3382 remain,len);
3383 priv->stats.txrdu++;
3384#ifdef DEBUG_TX_DESC
3385 check_tx_ring(dev,priority);
3386 // netif_stop_queue(dev);
3387 // netif_carrier_off(dev);
3388#endif
3389 // spin_unlock_irqrestore(&priv->tx_lock,flags);
3390
3391 return remain;
3392
3393 }
3394
3395 *tail= 0; // zeroes header
3396 *(tail+1) = 0;
3397 *(tail+3) = 0;
3398 *(tail+5) = 0;
3399 *(tail+6) = 0;
3400 *(tail+7) = 0;
3401
3402 if(priv->card_8185){
3403 //FIXME: this should be triggered by HW encryption parameters.
3404 *tail |= (1<<15); //no encrypt
3405// *tail |= (1<<30); //raise int when completed
3406 }
3407 // *tail = *tail | (1<<16);
3408 if(remain==len && !descfrag) {
3409 ownbit_flag = false; //added by david woo,2007.12.14
3410#ifdef DEBUG_TX_FRAG
3411 DMESG("First descriptor");
3412#endif
3413 *tail = *tail| (1<<29) ; //fist segment of the packet
3414 *tail = *tail |(len);
3415 } else {
3416 ownbit_flag = true;
3417 }
3418
3419 for(i=0;i<buflen&& remain >0;i++,remain--){
3420 ((u8*)buf)[i]=txbuf[i]; //copy data into descriptor pointed DMAble buffer
3421 if(remain == 4 && i+4 >= buflen) break;
3422 /* ensure the last desc has at least 4 bytes payload */
3423
3424 }
3425 txbuf = txbuf + i;
3426 *(tail+3)=*(tail+3) &~ 0xfff;
3427 *(tail+3)=*(tail+3) | i; // buffer lenght
3428 // Use short preamble or not
3429 if (priv->ieee80211->current_network.capability&WLAN_CAPABILITY_SHORT_PREAMBLE)
3430 if (priv->plcp_preamble_mode==1 && rate!=0) // short mode now, not long!
3431 // *tail |= (1<<16); // enable short preamble mode.
3432
3433#ifdef CONFIG_RTL8185B
3434 if(bCTSEnable) {
3435 *tail |= (1<<18);
3436 }
3437
3438 if(bRTSEnable) //rts enable
3439 {
3440 *tail |= ((ieeerate2rtlrate(priv->ieee80211->basic_rate))<<19);//RTS RATE
3441 *tail |= (1<<23);//rts enable
3442 *(tail+1) |=(RtsDur&0xffff);//RTS Duration
3443 }
3444 *(tail+3) |= ((TxDescDuration&0xffff)<<16); //DURATION
3445// *(tail+3) |= (0xe6<<16);
3446 *(tail+5) |= (11<<8);//(priv->retry_data<<8); //retry lim ;
3447#else
3448 //Use RTS or not
3449#ifdef CONFIG_RTL8187B
3450 if ( (len>priv->rts) && priv->rts && priority!=MANAGE_PRIORITY){
3451#else
3452 if ( (len>priv->rts) && priv->rts && priority==LOW_PRIORITY){
3453#endif
3454 *tail |= (1<<23); //enalbe RTS function
3455 *tail |= (0<<19); //use 1M bps send RTS packet
3456 AckCtsTime = ComputeTxTime(14, 10,0, 0); // AckCTSLng = 14 use 1M bps send
3457 FrameTime = ComputeTxTime(len + 4, rtl8180_rate2rate(rate), 0, *tail&(1<<16));
3458 // RTS/CTS time is calculate as follow
3459 duration = FrameTime + 3*10 + 2*AckCtsTime; //10us is the SifsTime;
3460 *(tail+1) |= duration; //Need to edit here! ----hikaru
3461 }else{
3462 *(tail+1)= 0; // zeroes the second 32-bits dword of the descriptor
3463 }
3464#endif
3465
3466 *tail = *tail | ((rate&0xf) << 24);
3467 //DMESG("rate %d",rate);
3468
3469 if(priv->card_8185){
3470
3471 #if 0
3472 *(tail+5)&= ~(1<<24); /* tx ant 0 */
3473
3474 *(tail+5) &= ~(1<<23); /* random tx agc 23-16 */
3475 *(tail+5) |= (1<<22)|(1<<21)|(1<<20)|(1<<19)|(1<<18)|(1<<17)|(1<<16);
3476
3477 *(tail+5) &=
3478~((1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9)|(1<<8));
3479 *(tail+5) |= (7<<8); // Max retry limit
3480
3481 *(tail+5) &= ~((1<<7)|(1<<6)|(1<<5)|(1<<4)|(1<<3)|(1<<2)|(1<<1)|(1<<0));
3482 *(tail+5) |= (8<<4); // Max contention window
3483 *(tail+6) |= 4; // Min contention window
3484 #endif
3485 // *(tail+5) = 0;
3486 }
3487
3488 /* hw_plcp_len is not used for rtl8180 chip */
3489 /* FIXME */
3490 if(priv->card_8185 == 0 || !priv->hw_plcp_len){
3491
3492 duration = rtl8180_len2duration(len,
3493 rate,&ext);
3494
3495
3496#ifdef DEBUG_TX
3497 DMESG("PLCP duration %d",duration );
3498 //DMESG("drift %d",drift);
3499 DMESG("extension %s", (ext==1) ? "on":"off");
3500#endif
3501 *(tail+1) = *(tail+1) | ((duration & 0x7fff)<<16);
3502 if(ext) *(tail+1) = *(tail+1) |(1<<31); //plcp length extension
3503 }
3504
3505 if(morefrag) *tail = (*tail) | (1<<17); // more fragment
3506 if(!remain) *tail = (*tail) | (1<<28); // last segment of frame
3507
3508#ifdef DEBUG_TX_FRAG
3509 if(!remain)DMESG("Last descriptor");
3510 if(morefrag)DMESG("More frag");
3511#endif
3512 *(tail+5) = *(tail+5)|(2<<27);
3513 *(tail+7) = *(tail+7)|(1<<4);
3514
3515 wmb();
3516 if(ownbit_flag)
3517 {
3518 *tail = *tail | (1<<31); // descriptor ready to be txed
3519 }
3520
3521#ifdef DEBUG_TX_DESC2
3522 printk("tx desc is:\n");
3523 DMESG("%8x %8x %8x %8x %8x %8x %8x %8x", tail[0], tail[1], tail[2], tail[3],
3524 tail[4], tail[5], tail[6], tail[7]);
3525#endif
3526
3527 if((tail - begin)/8 == count-1)
3528 tail=begin;
3529
3530 else
3531 tail=tail+8;
3532
3533 buflist=buflist->next;
3534
3535 mb();
3536
3537 switch(priority) {
3538 case MANAGE_PRIORITY:
3539 priv->txmapringtail=tail;
3540 priv->txmapbufstail=buflist;
3541 break;
3542
3543 case BK_PRIORITY:
3544 priv->txbkpringtail=tail;
3545 priv->txbkpbufstail=buflist;
3546 break;
3547
3548 case BE_PRIORITY:
3549 priv->txbepringtail=tail;
3550 priv->txbepbufstail=buflist;
3551 break;
3552
3553 case VI_PRIORITY:
3554 priv->txvipringtail=tail;
3555 priv->txvipbufstail=buflist;
3556 break;
3557
3558 case VO_PRIORITY:
3559 priv->txvopringtail=tail;
3560 priv->txvopbufstail=buflist;
3561 break;
3562
3563 case HI_PRIORITY:
3564 priv->txhpringtail=tail;
3565 priv->txhpbufstail = buflist;
3566 break;
3567
3568 case BEACON_PRIORITY:
3569 /* the HW seems to be happy with the 1st
3570 * descriptor filled and the 2nd empty...
3571 * So always update descriptor 1 and never
3572 * touch 2nd
3573 */
3574 // priv->txbeaconringtail=tail;
3575 // priv->txbeaconbufstail=buflist;
3576
3577 break;
3578
3579 }
3580
3581 //rtl8180_dma_kick(dev,priority);
3582 }
3583 *temp_tail = *temp_tail | (1<<31); // descriptor ready to be txed
3584 rtl8180_dma_kick(dev,priority);
3585 //spin_unlock_irqrestore(&priv->tx_lock,flags);
3586
3587 return 0;
3588
3589}
3590
3591
3592void rtl8180_irq_rx_tasklet(struct r8180_priv * priv);
3593
3594
3595void rtl8180_link_change(struct net_device *dev)
3596{
3597 struct r8180_priv *priv = ieee80211_priv(dev);
3598 u16 beacon_interval;
3599
3600 struct ieee80211_network *net = &priv->ieee80211->current_network;
3601// rtl8180_adapter_start(dev);
3602 rtl8180_update_msr(dev);
3603
3604
3605 rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
3606
3607 write_nic_dword(dev,BSSID,((u32*)net->bssid)[0]);
3608 write_nic_word(dev,BSSID+4,((u16*)net->bssid)[2]);
3609
3610
3611 beacon_interval = read_nic_dword(dev,BEACON_INTERVAL);
3612 beacon_interval &= ~ BEACON_INTERVAL_MASK;
3613 beacon_interval |= net->beacon_interval;
3614 write_nic_dword(dev, BEACON_INTERVAL, beacon_interval);
3615
3616 rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
3617
3618
3619 /*
3620 u16 atim = read_nic_dword(dev,ATIM);
3621 u16 = u16 &~ ATIM_MASK;
3622 u16 = u16 | beacon->atim;
3623 */
3624#if 0
3625 if (net->capability & WLAN_CAPABILITY_PRIVACY) {
3626 if (priv->hw_wep) {
3627 DMESG("Enabling hardware WEP support");
3628 rtl8180_set_hw_wep(dev);
3629 priv->ieee80211->host_encrypt=0;
3630 priv->ieee80211->host_decrypt=0;
3631 }
3632#ifndef CONFIG_IEEE80211_NOWEP
3633 else {
3634 priv->ieee80211->host_encrypt=1;
3635 priv->ieee80211->host_decrypt=1;
3636 }
3637#endif
3638 }
3639#ifndef CONFIG_IEEE80211_NOWEP
3640 else{
3641 priv->ieee80211->host_encrypt=0;
3642 priv->ieee80211->host_decrypt=0;
3643 }
3644#endif
3645#endif
3646
3647
3648 if(priv->card_8185)
3649 rtl8180_set_chan(dev, priv->chan);
3650
3651
3652}
3653
3654void rtl8180_rq_tx_ack(struct net_device *dev){
3655
3656 struct r8180_priv *priv = ieee80211_priv(dev);
3657// printk("====================>%s\n",__FUNCTION__);
3658 write_nic_byte(dev,CONFIG4,read_nic_byte(dev,CONFIG4)|CONFIG4_PWRMGT);
3659 priv->ack_tx_to_ieee = 1;
3660}
3661
3662short rtl8180_is_tx_queue_empty(struct net_device *dev){
3663
3664 struct r8180_priv *priv = ieee80211_priv(dev);
3665 u32* d;
3666
3667 for (d = priv->txmapring;
3668 d < priv->txmapring + priv->txringcount;d+=8)
3669 if(*d & (1<<31)) return 0;
3670
3671 for (d = priv->txbkpring;
3672 d < priv->txbkpring + priv->txringcount;d+=8)
3673 if(*d & (1<<31)) return 0;
3674
3675 for (d = priv->txbepring;
3676 d < priv->txbepring + priv->txringcount;d+=8)
3677 if(*d & (1<<31)) return 0;
3678
3679 for (d = priv->txvipring;
3680 d < priv->txvipring + priv->txringcount;d+=8)
3681 if(*d & (1<<31)) return 0;
3682
3683 for (d = priv->txvopring;
3684 d < priv->txvopring + priv->txringcount;d+=8)
3685 if(*d & (1<<31)) return 0;
3686
3687 for (d = priv->txhpring;
3688 d < priv->txhpring + priv->txringcount;d+=8)
3689 if(*d & (1<<31)) return 0;
3690 return 1;
3691}
3692/* FIXME FIXME 5msecs is random */
3693#define HW_WAKE_DELAY 5
3694
3695void rtl8180_hw_wakeup(struct net_device *dev)
3696{
3697 unsigned long flags;
3698
3699 struct r8180_priv *priv = ieee80211_priv(dev);
3700
3701 spin_lock_irqsave(&priv->ps_lock,flags);
3702 //DMESG("Waken up!");
3703 write_nic_byte(dev,CONFIG4,read_nic_byte(dev,CONFIG4)&~CONFIG4_PWRMGT);
3704
3705 if(priv->rf_wakeup)
3706 priv->rf_wakeup(dev);
3707// mdelay(HW_WAKE_DELAY);
3708 spin_unlock_irqrestore(&priv->ps_lock,flags);
3709}
3710
3711void rtl8180_hw_sleep_down(struct net_device *dev)
3712{
3713 unsigned long flags;
3714
3715 struct r8180_priv *priv = ieee80211_priv(dev);
3716
3717 spin_lock_irqsave(&priv->ps_lock,flags);
3718 //DMESG("Sleep!");
3719
3720 if(priv->rf_sleep)
3721 priv->rf_sleep(dev);
3722 spin_unlock_irqrestore(&priv->ps_lock,flags);
3723}
3724
3725
3726void rtl8180_hw_sleep(struct net_device *dev, u32 th, u32 tl)
3727{
3728
3729 struct r8180_priv *priv = ieee80211_priv(dev);
3730
3731 u32 rb = jiffies;
3732 unsigned long flags;
3733
3734 spin_lock_irqsave(&priv->ps_lock,flags);
3735
3736 /* Writing HW register with 0 equals to disable
3737 * the timer, that is not really what we want
3738 */
3739 tl -= MSECS(4+16+7);
3740
3741 //if(tl == 0) tl = 1;
3742
3743 /* FIXME HACK FIXME HACK */
3744// force_pci_posting(dev);
3745 //mdelay(1);
3746
3747// rb = read_nic_dword(dev, TSFTR);
3748
3749 /* If the interval in witch we are requested to sleep is too
3750 * short then give up and remain awake
3751 */
3752 if(((tl>=rb)&& (tl-rb) <= MSECS(MIN_SLEEP_TIME))
3753 ||((rb>tl)&& (rb-tl) < MSECS(MIN_SLEEP_TIME))) {
3754 spin_unlock_irqrestore(&priv->ps_lock,flags);
3755 printk("too short to sleep\n");
3756 return;
3757 }
3758
3759// write_nic_dword(dev, TimerInt, tl);
3760// rb = read_nic_dword(dev, TSFTR);
3761 {
3762 u32 tmp = (tl>rb)?(tl-rb):(rb-tl);
3763 // if (tl<rb)
3764
3765 //lzm,add,080828
3766 priv->DozePeriodInPast2Sec += jiffies_to_msecs(tmp);
3767
3768 queue_delayed_work(priv->ieee80211->wq, &priv->ieee80211->hw_wakeup_wq, tmp); //as tl may be less than rb
3769 }
3770 /* if we suspect the TimerInt is gone beyond tl
3771 * while setting it, then give up
3772 */
3773#if 1
3774 if(((tl > rb) && ((tl-rb) > MSECS(MAX_SLEEP_TIME)))||
3775 ((tl < rb) && ((rb-tl) > MSECS(MAX_SLEEP_TIME)))) {
3776 spin_unlock_irqrestore(&priv->ps_lock,flags);
3777 return;
3778 }
3779#endif
3780// if(priv->rf_sleep)
3781// priv->rf_sleep(dev);
3782
3783 queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->hw_sleep_wq);
3784 spin_unlock_irqrestore(&priv->ps_lock,flags);
3785}
3786
3787
3788//void rtl8180_wmm_param_update(struct net_device *dev,u8 *ac_param)
3789#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
3790void rtl8180_wmm_param_update(struct work_struct * work)
3791{
3792 struct ieee80211_device * ieee = container_of(work, struct ieee80211_device,wmm_param_update_wq);
3793 //struct r8180_priv *priv = (struct r8180_priv*)(ieee->priv);
3794 struct net_device *dev = ieee->dev;
3795#else
3796void rtl8180_wmm_param_update(struct ieee80211_device *ieee)
3797{
3798 struct net_device *dev = ieee->dev;
3799 struct r8180_priv *priv = ieee80211_priv(dev);
3800#endif
3801 u8 *ac_param = (u8 *)(ieee->current_network.wmm_param);
3802 u8 mode = ieee->current_network.mode;
3803 AC_CODING eACI;
3804 AC_PARAM AcParam;
3805 PAC_PARAM pAcParam;
3806 u8 i;
3807
3808#ifndef CONFIG_RTL8185B
3809 //for legacy 8185 keep the PARAM unchange.
3810 return;
3811#else
3812 if(!ieee->current_network.QoS_Enable){
3813 //legacy ac_xx_param update
3814 AcParam.longData = 0;
3815 AcParam.f.AciAifsn.f.AIFSN = 2; // Follow 802.11 DIFS.
3816 AcParam.f.AciAifsn.f.ACM = 0;
3817 AcParam.f.Ecw.f.ECWmin = 3; // Follow 802.11 CWmin.
3818 AcParam.f.Ecw.f.ECWmax = 7; // Follow 802.11 CWmax.
3819 AcParam.f.TXOPLimit = 0;
3820 for(eACI = 0; eACI < AC_MAX; eACI++){
3821 AcParam.f.AciAifsn.f.ACI = (u8)eACI;
3822 {
3823 u8 u1bAIFS;
3824 u32 u4bAcParam;
3825 pAcParam = (PAC_PARAM)(&AcParam);
3826 // Retrive paramters to udpate.
3827 u1bAIFS = pAcParam->f.AciAifsn.f.AIFSN *(((mode&IEEE_G) == IEEE_G)?9:20) + aSifsTime;
3828 u4bAcParam = ((((u32)(pAcParam->f.TXOPLimit))<<AC_PARAM_TXOP_LIMIT_OFFSET)|
3829 (((u32)(pAcParam->f.Ecw.f.ECWmax))<<AC_PARAM_ECW_MAX_OFFSET)|
3830 (((u32)(pAcParam->f.Ecw.f.ECWmin))<<AC_PARAM_ECW_MIN_OFFSET)|
3831 (((u32)u1bAIFS) << AC_PARAM_AIFS_OFFSET));
3832 switch(eACI){
3833 case AC1_BK:
3834 write_nic_dword(dev, AC_BK_PARAM, u4bAcParam);
3835 break;
3836
3837 case AC0_BE:
3838 write_nic_dword(dev, AC_BE_PARAM, u4bAcParam);
3839 break;
3840
3841 case AC2_VI:
3842 write_nic_dword(dev, AC_VI_PARAM, u4bAcParam);
3843 break;
3844
3845 case AC3_VO:
3846 write_nic_dword(dev, AC_VO_PARAM, u4bAcParam);
3847 break;
3848
3849 default:
3850 printk(KERN_WARNING "SetHwReg8185():invalid ACI: %d!\n", eACI);
3851 break;
3852 }
3853 }
3854 }
3855 return;
3856 }
3857
3858 for(i = 0; i < AC_MAX; i++){
3859 //AcParam.longData = 0;
3860 pAcParam = (AC_PARAM * )ac_param;
3861 {
3862 AC_CODING eACI;
3863 u8 u1bAIFS;
3864 u32 u4bAcParam;
3865
3866 // Retrive paramters to udpate.
3867 eACI = pAcParam->f.AciAifsn.f.ACI;
3868 //Mode G/A: slotTimeTimer = 9; Mode B: 20
3869 u1bAIFS = pAcParam->f.AciAifsn.f.AIFSN * (((mode&IEEE_G) == IEEE_G)?9:20) + aSifsTime;
3870 u4bAcParam = ( (((u32)(pAcParam->f.TXOPLimit)) << AC_PARAM_TXOP_LIMIT_OFFSET) |
3871 (((u32)(pAcParam->f.Ecw.f.ECWmax)) << AC_PARAM_ECW_MAX_OFFSET) |
3872 (((u32)(pAcParam->f.Ecw.f.ECWmin)) << AC_PARAM_ECW_MIN_OFFSET) |
3873 (((u32)u1bAIFS) << AC_PARAM_AIFS_OFFSET));
3874
3875 switch(eACI){
3876 case AC1_BK:
3877 write_nic_dword(dev, AC_BK_PARAM, u4bAcParam);
3878 break;
3879
3880 case AC0_BE:
3881 write_nic_dword(dev, AC_BE_PARAM, u4bAcParam);
3882 break;
3883
3884 case AC2_VI:
3885 write_nic_dword(dev, AC_VI_PARAM, u4bAcParam);
3886 break;
3887
3888 case AC3_VO:
3889 write_nic_dword(dev, AC_VO_PARAM, u4bAcParam);
3890 break;
3891
3892 default:
3893 printk(KERN_WARNING "SetHwReg8185(): invalid ACI: %d !\n", eACI);
3894 break;
3895 }
3896 }
3897 ac_param += (sizeof(AC_PARAM));
3898 }
3899#endif
3900}
3901
3902#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
3903void rtl8180_tx_irq_wq(struct work_struct *work);
3904#else
3905void rtl8180_tx_irq_wq(struct net_device *dev);
3906#endif
3907
3908
3909
3910
3911#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
3912void rtl8180_restart_wq(struct work_struct *work);
3913//void rtl8180_rq_tx_ack(struct work_struct *work);
3914#else
3915 void rtl8180_restart_wq(struct net_device *dev);
3916//void rtl8180_rq_tx_ack(struct net_device *dev);
3917#endif
3918#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
3919void rtl8180_watch_dog_wq(struct work_struct *work);
3920#else
3921void rtl8180_watch_dog_wq(struct net_device *dev);
3922#endif
3923#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
3924void rtl8180_hw_wakeup_wq(struct work_struct *work);
3925#else
3926void rtl8180_hw_wakeup_wq(struct net_device *dev);
3927#endif
3928
3929#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
3930void rtl8180_hw_sleep_wq(struct work_struct *work);
3931#else
3932void rtl8180_hw_sleep_wq(struct net_device *dev);
3933#endif
3934
3935
3936
3937#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
3938void rtl8180_sw_antenna_wq(struct work_struct *work);
3939#else
3940void rtl8180_sw_antenna_wq(struct net_device *dev);
3941#endif
3942 void rtl8180_watch_dog(struct net_device *dev);
3943void watch_dog_adaptive(unsigned long data)
3944{
3945 struct r8180_priv* priv = ieee80211_priv((struct net_device *)data);
3946// DMESG("---->watch_dog_adaptive()\n");
3947 if(!priv->up)
3948 {
3949 DMESG("<----watch_dog_adaptive():driver is not up!\n");
3950 return;
3951 }
3952
3953 // queue_work(priv->ieee80211->wq,&priv->ieee80211->watch_dog_wq);
3954//{by amy 080312
3955#if 1
3956 // Tx High Power Mechanism.
3957#ifdef HIGH_POWER
3958 if(CheckHighPower((struct net_device *)data))
3959 {
3960 queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->tx_pw_wq);
3961 }
3962#endif
3963
3964#ifdef CONFIG_RTL818X_S
3965 // Tx Power Tracking on 87SE.
3966#ifdef TX_TRACK
3967 //if( priv->bTxPowerTrack ) //lzm mod 080826
3968 if( CheckTxPwrTracking((struct net_device *)data));
3969 TxPwrTracking87SE((struct net_device *)data);
3970#endif
3971#endif
3972
3973 // Perform DIG immediately.
3974#ifdef SW_DIG
3975 if(CheckDig((struct net_device *)data) == true)
3976 {
3977 queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->hw_dig_wq);
3978 }
3979#endif
3980#endif
3981//by amy 080312}
3982 rtl8180_watch_dog((struct net_device *)data);
3983
3984
3985 queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->GPIOChangeRFWorkItem);
3986
3987 priv->watch_dog_timer.expires = jiffies + MSECS(IEEE80211_WATCH_DOG_TIME);
3988 add_timer(&priv->watch_dog_timer);
3989// DMESG("<----watch_dog_adaptive()\n");
3990}
3991
3992#ifdef ENABLE_DOT11D
3993
3994static CHANNEL_LIST ChannelPlan[] = {
3995 {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64},19}, //FCC
3996 {{1,2,3,4,5,6,7,8,9,10,11},11}, //IC
3997 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //ETSI
3998 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //Spain. Change to ETSI.
3999 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //France. Change to ETSI.
4000 {{14,36,40,44,48,52,56,60,64},9}, //MKK
4001 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14, 36,40,44,48,52,56,60,64},22},//MKK1
4002 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //Israel.
4003 {{1,2,3,4,5,6,7,8,9,10,11,12,13,34,38,42,46},17}, // For 11a , TELEC
4004 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14}, //For Global Domain. 1-11:active scan, 12-14 passive scan. //+YJ, 080626
4005 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13} //world wide 13: ch1~ch11 active scan, ch12~13 passive //lzm add 080826
4006};
4007
4008static void rtl8180_set_channel_map(u8 channel_plan, struct ieee80211_device *ieee)
4009{
4010 int i;
4011
4012 //lzm add 080826
4013 ieee->MinPassiveChnlNum=MAX_CHANNEL_NUMBER+1;
4014 ieee->IbssStartChnl=0;
4015
4016 switch (channel_plan)
4017 {
4018 case COUNTRY_CODE_FCC:
4019 case COUNTRY_CODE_IC:
4020 case COUNTRY_CODE_ETSI:
4021 case COUNTRY_CODE_SPAIN:
4022 case COUNTRY_CODE_FRANCE:
4023 case COUNTRY_CODE_MKK:
4024 case COUNTRY_CODE_MKK1:
4025 case COUNTRY_CODE_ISRAEL:
4026 case COUNTRY_CODE_TELEC:
4027 {
4028 Dot11d_Init(ieee);
4029 ieee->bGlobalDomain = false;
4030 if (ChannelPlan[channel_plan].Len != 0){
4031 // Clear old channel map
4032 memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map));
4033 // Set new channel map
4034 for (i=0;i<ChannelPlan[channel_plan].Len;i++)
4035 {
4036 if(ChannelPlan[channel_plan].Channel[i] <= 14)
4037 GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 1;
4038 }
4039 }
4040 break;
4041 }
4042 case COUNTRY_CODE_GLOBAL_DOMAIN:
4043 {
4044 GET_DOT11D_INFO(ieee)->bEnabled = 0;
4045 Dot11d_Reset(ieee);
4046 ieee->bGlobalDomain = true;
4047 break;
4048 }
4049 case COUNTRY_CODE_WORLD_WIDE_13_INDEX://lzm add 080826
4050 {
4051 ieee->MinPassiveChnlNum=12;
4052 ieee->IbssStartChnl= 10;
4053 break;
4054 }
4055 default:
4056 {
4057 Dot11d_Init(ieee);
4058 ieee->bGlobalDomain = false;
4059 memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map));
4060 for (i=1;i<=14;i++)
4061 {
4062 GET_DOT11D_INFO(ieee)->channel_map[i] = 1;
4063 }
4064 break;
4065 }
4066 }
4067}
4068#endif
4069
4070//Add for RF power on power off by lizhaoming 080512
4071#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
4072void GPIOChangeRFWorkItemCallBack(struct work_struct *work);
4073#else
4074void GPIOChangeRFWorkItemCallBack(struct ieee80211_device *ieee);
4075#endif
4076
4077//YJ,add,080828
4078static void rtl8180_statistics_init(struct Stats *pstats)
4079{
4080 memset(pstats, 0, sizeof(struct Stats));
4081}
4082static void rtl8180_link_detect_init(plink_detect_t plink_detect)
4083{
4084 memset(plink_detect, 0, sizeof(link_detect_t));
4085 plink_detect->SlotNum = DEFAULT_SLOT_NUM;
4086}
4087//YJ,add,080828,end
4088
4089short rtl8180_init(struct net_device *dev)
4090{
4091 struct r8180_priv *priv = ieee80211_priv(dev);
4092 u16 word;
4093 u16 version;
4094 u8 hw_version;
4095 //u8 config3;
4096 u32 usValue;
4097 u16 tmpu16;
4098 int i, j;
4099
4100#ifdef ENABLE_DOT11D
4101#if 0
4102 for(i=0;i<0xFF;i++) {
4103 if(i%16 == 0)
4104 printk("\n[%x]: ", i/16);
4105 printk("\t%4.4x", eprom_read(dev,i));
4106 }
4107#endif
4108 priv->channel_plan = eprom_read(dev, EEPROM_COUNTRY_CODE>>1) & 0xFF;
4109 if(priv->channel_plan > COUNTRY_CODE_GLOBAL_DOMAIN){
4110 printk("rtl8180_init:Error channel plan! Set to default.\n");
4111 priv->channel_plan = 0;
4112 }
4113 //priv->channel_plan = 9; //Global Domain
4114
4115 DMESG("Channel plan is %d\n",priv->channel_plan);
4116 rtl8180_set_channel_map(priv->channel_plan, priv->ieee80211);
4117#else
4118 int ch;
4119 //Set Default Channel Plan
4120 if(!channels){
4121 DMESG("No channels, aborting");
4122 return -1;
4123 }
4124 ch=channels;
4125 priv->channel_plan = 0;//hikaru
4126 // set channels 1..14 allowed in given locale
4127 for (i=1; i<=14; i++) {
4128 (priv->ieee80211->channel_map)[i] = (u8)(ch & 0x01);
4129 ch >>= 1;
4130 }
4131#endif
4132
4133 //memcpy(priv->stats,0,sizeof(struct Stats));
4134
4135 //FIXME: these constants are placed in a bad pleace.
4136 priv->txbuffsize = 2048;//1024;
4137 priv->txringcount = 32;//32;
4138 priv->rxbuffersize = 2048;//1024;
4139 priv->rxringcount = 64;//32;
4140 priv->txbeaconcount = 2;
4141 priv->rx_skb_complete = 1;
4142 //priv->txnp_pending.ispending=0;
4143 /* ^^ the SKB does not containt a partial RXed
4144 * packet (is empty)
4145 */
4146
4147#ifdef CONFIG_RTL8185B
4148#ifdef CONFIG_RTL818X_S
4149 priv->RegThreeWireMode = HW_THREE_WIRE_SI;
4150#else
4151 priv->RegThreeWireMode = SW_THREE_WIRE;
4152#endif
4153#endif
4154
4155//Add for RF power on power off by lizhaoming 080512
4156 priv->RFChangeInProgress = false;
4157 priv->SetRFPowerStateInProgress = false;
4158 priv->RFProgType = 0;
4159 priv->bInHctTest = false;
4160
4161 priv->irq_enabled=0;
4162
4163//YJ,modified,080828
4164#if 0
4165 priv->stats.rxdmafail=0;
4166 priv->stats.txrdu=0;
4167 priv->stats.rxrdu=0;
4168 priv->stats.rxnolast=0;
4169 priv->stats.rxnodata=0;
4170 //priv->stats.rxreset=0;
4171 //priv->stats.rxwrkaround=0;
4172 priv->stats.rxnopointer=0;
4173 priv->stats.txnperr=0;
4174 priv->stats.txresumed=0;
4175 priv->stats.rxerr=0;
4176 priv->stats.rxoverflow=0;
4177 priv->stats.rxint=0;
4178 priv->stats.txnpokint=0;
4179 priv->stats.txhpokint=0;
4180 priv->stats.txhperr=0;
4181 priv->stats.ints=0;
4182 priv->stats.shints=0;
4183 priv->stats.txoverflow=0;
4184 priv->stats.txbeacon=0;
4185 priv->stats.txbeaconerr=0;
4186 priv->stats.txlperr=0;
4187 priv->stats.txlpokint=0;
4188 priv->stats.txretry=0;//tony 20060601
4189 priv->stats.rxcrcerrmin=0;
4190 priv->stats.rxcrcerrmid=0;
4191 priv->stats.rxcrcerrmax=0;
4192 priv->stats.rxicverr=0;
4193#else
4194 rtl8180_statistics_init(&priv->stats);
4195 rtl8180_link_detect_init(&priv->link_detect);
4196#endif
4197//YJ,modified,080828,end
4198
4199
4200 priv->ack_tx_to_ieee = 0;
4201 priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
4202 priv->ieee80211->iw_mode = IW_MODE_INFRA;
4203 priv->ieee80211->softmac_features = IEEE_SOFTMAC_SCAN |
4204 IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ |
4205 IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE;
4206 priv->ieee80211->active_scan = 1;
4207 priv->ieee80211->rate = 110; //11 mbps
4208 priv->ieee80211->modulation = IEEE80211_CCK_MODULATION;
4209 priv->ieee80211->host_encrypt = 1;
4210 priv->ieee80211->host_decrypt = 1;
4211 priv->ieee80211->sta_wake_up = rtl8180_hw_wakeup;
4212 priv->ieee80211->ps_request_tx_ack = rtl8180_rq_tx_ack;
4213 priv->ieee80211->enter_sleep_state = rtl8180_hw_sleep;
4214 priv->ieee80211->ps_is_queue_empty = rtl8180_is_tx_queue_empty;
4215
4216 priv->hw_wep = hwwep;
4217 priv->prism_hdr=0;
4218 priv->dev=dev;
4219 priv->retry_rts = DEFAULT_RETRY_RTS;
4220 priv->retry_data = DEFAULT_RETRY_DATA;
4221 priv->RFChangeInProgress = false;
4222 priv->SetRFPowerStateInProgress = false;
4223 priv->RFProgType = 0;
4224 priv->bInHctTest = false;
4225 priv->bInactivePs = true;//false;
4226 priv->ieee80211->bInactivePs = priv->bInactivePs;
4227 priv->bSwRfProcessing = false;
4228 priv->eRFPowerState = eRfOff;
4229 priv->RfOffReason = 0;
4230 priv->LedStrategy = SW_LED_MODE0;
4231 //priv->NumRxOkInPeriod = 0; //YJ,del,080828
4232 //priv->NumTxOkInPeriod = 0; //YJ,del,080828
4233 priv->TxPollingTimes = 0;//lzm add 080826
4234 priv->bLeisurePs = true;
4235 priv->dot11PowerSaveMode = eActive;
4236//by amy for antenna
4237 priv->AdMinCheckPeriod = 5;
4238 priv->AdMaxCheckPeriod = 10;
4239// Lower signal strength threshold to fit the HW participation in antenna diversity. +by amy 080312
4240 priv->AdMaxRxSsThreshold = 30;//60->30
4241 priv->AdRxSsThreshold = 20;//50->20
4242 priv->AdCheckPeriod = priv->AdMinCheckPeriod;
4243 priv->AdTickCount = 0;
4244 priv->AdRxSignalStrength = -1;
4245 priv->RegSwAntennaDiversityMechanism = 0;
4246 priv->RegDefaultAntenna = 0;
4247 priv->SignalStrength = 0;
4248 priv->AdRxOkCnt = 0;
4249 priv->CurrAntennaIndex = 0;
4250 priv->AdRxSsBeforeSwitched = 0;
4251 init_timer(&priv->SwAntennaDiversityTimer);
4252 priv->SwAntennaDiversityTimer.data = (unsigned long)dev;
4253 priv->SwAntennaDiversityTimer.function = (void *)SwAntennaDiversityTimerCallback;
4254//by amy for antenna
4255//{by amy 080312
4256 priv->bDigMechanism = 1;
4257 priv->InitialGain = 6;
4258 priv->bXtalCalibration = false;
4259 priv->XtalCal_Xin = 0;
4260 priv->XtalCal_Xout = 0;
4261 priv->bTxPowerTrack = false;
4262 priv->ThermalMeter = 0;
4263 priv->FalseAlarmRegValue = 0;
4264 priv->RegDigOfdmFaUpTh = 0xc; // Upper threhold of OFDM false alarm, which is used in DIG.
4265 priv->DIG_NumberFallbackVote = 0;
4266 priv->DIG_NumberUpgradeVote = 0;
4267 priv->LastSignalStrengthInPercent = 0;
4268 priv->Stats_SignalStrength = 0;
4269 priv->LastRxPktAntenna = 0;
4270 priv->SignalQuality = 0; // in 0-100 index.
4271 priv->Stats_SignalQuality = 0;
4272 priv->RecvSignalPower = 0; // in dBm.
4273 priv->Stats_RecvSignalPower = 0;
4274 priv->AdMainAntennaRxOkCnt = 0;
4275 priv->AdAuxAntennaRxOkCnt = 0;
4276 priv->bHWAdSwitched = false;
4277 priv->bRegHighPowerMechanism = true;
4278 priv->RegHiPwrUpperTh = 77;
4279 priv->RegHiPwrLowerTh = 75;
4280 priv->RegRSSIHiPwrUpperTh = 70;
4281 priv->RegRSSIHiPwrLowerTh = 20;
4282 priv->bCurCCKPkt = false;
4283 priv->UndecoratedSmoothedSS = -1;
4284 priv->bToUpdateTxPwr = false;
4285 priv->CurCCKRSSI = 0;
4286 priv->RxPower = 0;
4287 priv->RSSI = 0;
4288 //YJ,add,080828
4289 priv->NumTxOkTotal = 0;
4290 priv->NumTxUnicast = 0;
4291 priv->keepAliveLevel = DEFAULT_KEEP_ALIVE_LEVEL;
4292 priv->PowerProfile = POWER_PROFILE_AC;
4293 //YJ,add,080828,end
4294//by amy for rate adaptive
4295 priv->CurrRetryCnt=0;
4296 priv->LastRetryCnt=0;
4297 priv->LastTxokCnt=0;
4298 priv->LastRxokCnt=0;
4299 priv->LastRetryRate=0;
4300 priv->bTryuping=0;
4301 priv->CurrTxRate=0;
4302 priv->CurrRetryRate=0;
4303 priv->TryupingCount=0;
4304 priv->TryupingCountNoData=0;
4305 priv->TryDownCountLowData=0;
4306 priv->LastTxOKBytes=0;
4307 priv->LastFailTxRate=0;
4308 priv->LastFailTxRateSS=0;
4309 priv->FailTxRateCount=0;
4310 priv->LastTxThroughput=0;
4311 priv->NumTxOkBytesTotal=0;
4312 priv->ForcedDataRate = 0;
4313 priv->RegBModeGainStage = 1;
4314
4315//by amy for rate adaptive
4316//by amy 080312}
4317 priv->promisc = (dev->flags & IFF_PROMISC) ? 1:0;
4318 spin_lock_init(&priv->irq_lock);
4319 spin_lock_init(&priv->irq_th_lock);
4320 spin_lock_init(&priv->tx_lock);
4321 spin_lock_init(&priv->ps_lock);
4322 spin_lock_init(&priv->rf_ps_lock);
4323 sema_init(&priv->wx_sem,1);
4324 sema_init(&priv->rf_state,1);
4325#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
4326 INIT_WORK(&priv->reset_wq,(void*) rtl8180_restart_wq);
4327 INIT_WORK(&priv->tx_irq_wq,(void*) rtl8180_tx_irq_wq);
4328 INIT_DELAYED_WORK(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8180_hw_wakeup_wq);
4329 INIT_DELAYED_WORK(&priv->ieee80211->hw_sleep_wq,(void*) rtl8180_hw_sleep_wq);
4330 //INIT_DELAYED_WORK(&priv->ieee80211->watch_dog_wq,(void*) rtl8180_watch_dog_wq);
4331 //INIT_DELAYED_WORK(&priv->ieee80211->sw_antenna_wq,(void*) rtl8180_sw_antenna_wq);
4332 INIT_WORK(&priv->ieee80211->wmm_param_update_wq,(void*) rtl8180_wmm_param_update);
4333 INIT_DELAYED_WORK(&priv->ieee80211->rate_adapter_wq,(void*)rtl8180_rate_adapter);//+by amy 080312
4334 INIT_DELAYED_WORK(&priv->ieee80211->hw_dig_wq,(void*)rtl8180_hw_dig_wq);//+by amy 080312
4335 INIT_DELAYED_WORK(&priv->ieee80211->tx_pw_wq,(void*)rtl8180_tx_pw_wq);//+by amy 080312
4336
4337 //add for RF power on power off by lizhaoming 080512
4338 INIT_DELAYED_WORK(&priv->ieee80211->GPIOChangeRFWorkItem,(void*) GPIOChangeRFWorkItemCallBack);
4339#else
4340 INIT_WORK(&priv->reset_wq,(void*) rtl8180_restart_wq,dev);
4341 INIT_WORK(&priv->tx_irq_wq,(void*) rtl8180_tx_irq_wq,dev);
4342 //INIT_WORK(&priv->ieee80211->watch_dog_wq,(void*) rtl8180_watch_dog_wq,dev);
4343 INIT_WORK(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8180_hw_wakeup_wq,dev);
4344 INIT_WORK(&priv->ieee80211->hw_sleep_wq,(void*) rtl8180_hw_sleep_wq,dev);
4345 //INIT_WORK(&priv->ieee80211->sw_antenna_wq,(void*) rtl8180_sw_antenna_wq,dev);
4346 INIT_WORK(&priv->ieee80211->wmm_param_update_wq,(void*) rtl8180_wmm_param_update,priv->ieee80211);
4347 INIT_WORK(&priv->ieee80211->rate_adapter_wq,(void*)rtl8180_rate_adapter,dev);//+by amy 080312
4348 INIT_WORK(&priv->ieee80211->hw_dig_wq,(void*)rtl8180_hw_dig_wq,dev);//+by amy 080312
4349 INIT_WORK(&priv->ieee80211->tx_pw_wq,(void*)rtl8180_tx_pw_wq,dev);//+by amy 080312
4350
4351 //add for RF power on power off by lizhaoming 080512
4352 INIT_WORK(&priv->ieee80211->GPIOChangeRFWorkItem,(void*) GPIOChangeRFWorkItemCallBack, priv->ieee80211);
4353#endif
4354 //INIT_WORK(&priv->reset_wq,(void*) rtl8180_restart_wq,dev);
4355
4356 tasklet_init(&priv->irq_rx_tasklet,
4357 (void(*)(unsigned long)) rtl8180_irq_rx_tasklet,
4358 (unsigned long)priv);
4359//by amy
4360 init_timer(&priv->watch_dog_timer);
4361 priv->watch_dog_timer.data = (unsigned long)dev;
4362 priv->watch_dog_timer.function = watch_dog_adaptive;
4363//by amy
4364
4365//{by amy 080312
4366//by amy for rate adaptive
4367 init_timer(&priv->rateadapter_timer);
4368 priv->rateadapter_timer.data = (unsigned long)dev;
4369 priv->rateadapter_timer.function = timer_rate_adaptive;
4370 priv->RateAdaptivePeriod= RATE_ADAPTIVE_TIMER_PERIOD;
4371 priv->bEnhanceTxPwr=false;
4372//by amy for rate adaptive
4373//by amy 080312}
4374 //priv->ieee80211->func =
4375 // kmalloc(sizeof(struct ieee80211_helper_functions),GFP_KERNEL);
4376 //memset(priv->ieee80211->func, 0,
4377 // sizeof(struct ieee80211_helper_functions));
4378
4379 priv->ieee80211->softmac_hard_start_xmit = rtl8180_hard_start_xmit;
4380 priv->ieee80211->set_chan = rtl8180_set_chan;
4381 priv->ieee80211->link_change = rtl8180_link_change;
4382 priv->ieee80211->softmac_data_hard_start_xmit = rtl8180_hard_data_xmit;
4383 priv->ieee80211->data_hard_stop = rtl8180_data_hard_stop;
4384 priv->ieee80211->data_hard_resume = rtl8180_data_hard_resume;
4385
4386 priv->ieee80211->init_wmmparam_flag = 0;
4387
4388 priv->ieee80211->start_send_beacons = rtl8180_start_tx_beacon;
4389 priv->ieee80211->stop_send_beacons = rtl8180_beacon_tx_disable;
4390 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
4391
4392#ifdef CONFIG_RTL8185B
4393 priv->MWIEnable = 0;
4394
4395 priv->ShortRetryLimit = 7;
4396 priv->LongRetryLimit = 7;
4397 priv->EarlyRxThreshold = 7;
4398
4399 priv->CSMethod = (0x01 << 29);
4400
4401 priv->TransmitConfig =
4402 1<<TCR_DurProcMode_OFFSET | //for RTL8185B, duration setting by HW
4403 (7<<TCR_MXDMA_OFFSET) | // Max DMA Burst Size per Tx DMA Burst, 7: reservied.
4404 (priv->ShortRetryLimit<<TCR_SRL_OFFSET) | // Short retry limit
4405 (priv->LongRetryLimit<<TCR_LRL_OFFSET) | // Long retry limit
4406 (0 ? TCR_SAT : 0); // FALSE: HW provies PLCP length and LENGEXT, TURE: SW proiveds them
4407
4408 priv->ReceiveConfig =
4409#ifdef CONFIG_RTL818X_S
4410#else
4411 priv->CSMethod |
4412#endif
4413// RCR_ENMARP |
4414 RCR_AMF | RCR_ADF | //accept management/data
4415 RCR_ACF | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
4416 RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
4417 //RCR_AICV | RCR_ACRC32 | //accept ICV/CRC error packet
4418 (7<<RCR_MXDMA_OFFSET) | // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
4419 (priv->EarlyRxThreshold<<RCR_FIFO_OFFSET) | // Rx FIFO Threshold, 7: No Rx threshold.
4420 (priv->EarlyRxThreshold == 7 ? RCR_ONLYERLPKT:0);
4421
4422 priv->IntrMask = IMR_TMGDOK | IMR_TBDER | IMR_THPDER |
4423 IMR_THPDER | IMR_THPDOK |
4424 IMR_TVODER | IMR_TVODOK |
4425 IMR_TVIDER | IMR_TVIDOK |
4426 IMR_TBEDER | IMR_TBEDOK |
4427 IMR_TBKDER | IMR_TBKDOK |
4428 IMR_RDU | // To handle the defragmentation not enough Rx descriptors case. Annie, 2006-03-27.
4429 IMR_RER | IMR_ROK |
4430 IMR_RQoSOK; // <NOTE> ROK and RQoSOK are mutually exclusive, so, we must handle RQoSOK interrupt to receive QoS frames, 2005.12.09, by rcnjko.
4431
4432 priv->InitialGain = 6;
4433#endif
4434
4435 hw_version =( read_nic_dword(dev, TCR) & TCR_HWVERID_MASK)>>TCR_HWVERID_SHIFT;
4436
4437 switch (hw_version){
4438#ifdef CONFIG_RTL8185B
4439 case HW_VERID_R8185B_B:
4440#ifdef CONFIG_RTL818X_S
4441 priv->card_8185 = VERSION_8187S_C;
4442 DMESG("MAC controller is a RTL8187SE b/g");
4443 priv->phy_ver = 2;
4444 break;
4445#else
4446 DMESG("MAC controller is a RTL8185B b/g");
4447 priv->card_8185 = 3;
4448 priv->phy_ver = 2;
4449 break;
4450#endif
4451#endif
4452 case HW_VERID_R8185_ABC:
4453 DMESG("MAC controller is a RTL8185 b/g");
4454 priv->card_8185 = 1;
4455 /* you should not find a card with 8225 PHY ver < C*/
4456 priv->phy_ver = 2;
4457 break;
4458
4459 case HW_VERID_R8185_D:
4460 DMESG("MAC controller is a RTL8185 b/g (V. D)");
4461 priv->card_8185 = 2;
4462 /* you should not find a card with 8225 PHY ver < C*/
4463 priv->phy_ver = 2;
4464 break;
4465
4466 case HW_VERID_R8180_ABCD:
4467 DMESG("MAC controller is a RTL8180");
4468 priv->card_8185 = 0;
4469 break;
4470
4471 case HW_VERID_R8180_F:
4472 DMESG("MAC controller is a RTL8180 (v. F)");
4473 priv->card_8185 = 0;
4474 break;
4475
4476 default:
4477 DMESGW("MAC chip not recognized: version %x. Assuming RTL8180",hw_version);
4478 priv->card_8185 = 0;
4479 break;
4480 }
4481
4482 if(priv->card_8185){
4483 priv->ieee80211->modulation |= IEEE80211_OFDM_MODULATION;
4484 priv->ieee80211->short_slot = 1;
4485 }
4486 /* you should not found any 8185 Ver B Card */
4487 priv->card_8185_Bversion = 0;
4488
4489#ifdef CONFIG_RTL8185B
4490#ifdef CONFIG_RTL818X_S
4491 // just for sync 85
4492 priv->card_type = PCI;
4493 DMESG("This is a PCI NIC");
4494#else
4495 config3 = read_nic_byte(dev, CONFIG3);
4496 if(config3 & 0x8){
4497 priv->card_type = CARDBUS;
4498 DMESG("This is a CARDBUS NIC");
4499 }
4500 else if( config3 & 0x4){
4501 priv->card_type = MINIPCI;
4502 DMESG("This is a MINI-PCI NIC");
4503 }else{
4504 priv->card_type = PCI;
4505 DMESG("This is a PCI NIC");
4506 }
4507#endif
4508#endif
4509 priv->enable_gpio0 = 0;
4510
4511//by amy for antenna
4512#ifdef CONFIG_RTL8185B
4513 usValue = eprom_read(dev, EEPROM_SW_REVD_OFFSET);
4514 DMESG("usValue is 0x%x\n",usValue);
4515#ifdef CONFIG_RTL818X_S
4516 //3Read AntennaDiversity
4517 // SW Antenna Diversity.
4518 if( (usValue & EEPROM_SW_AD_MASK) != EEPROM_SW_AD_ENABLE )
4519 {
4520 priv->EEPROMSwAntennaDiversity = false;
4521 //printk("EEPROM Disable SW Antenna Diversity\n");
4522 }
4523 else
4524 {
4525 priv->EEPROMSwAntennaDiversity = true;
4526 //printk("EEPROM Enable SW Antenna Diversity\n");
4527 }
4528 // Default Antenna to use.
4529 if( (usValue & EEPROM_DEF_ANT_MASK) != EEPROM_DEF_ANT_1 )
4530 {
4531 priv->EEPROMDefaultAntenna1 = false;
4532 //printk("EEPROM Default Antenna 0\n");
4533 }
4534 else
4535 {
4536 priv->EEPROMDefaultAntenna1 = true;
4537 //printk("EEPROM Default Antenna 1\n");
4538 }
4539
4540 //
4541 // Antenna diversity mechanism. Added by Roger, 2007.11.05.
4542 //
4543 if( priv->RegSwAntennaDiversityMechanism == 0 ) // Auto
4544 {// 0: default from EEPROM.
4545 priv->bSwAntennaDiverity = priv->EEPROMSwAntennaDiversity;
4546 }
4547 else
4548 {// 1:disable antenna diversity, 2: enable antenna diversity.
4549 priv->bSwAntennaDiverity = ((priv->RegSwAntennaDiversityMechanism == 1)? false : true);
4550 }
4551 //printk("bSwAntennaDiverity = %d\n", priv->bSwAntennaDiverity);
4552
4553
4554 //
4555 // Default antenna settings. Added by Roger, 2007.11.05.
4556 //
4557 if( priv->RegDefaultAntenna == 0)
4558 {// 0: default from EEPROM.
4559 priv->bDefaultAntenna1 = priv->EEPROMDefaultAntenna1;
4560 }
4561 else
4562 {// 1: main, 2: aux.
4563 priv->bDefaultAntenna1 = ((priv->RegDefaultAntenna== 2) ? true : false);
4564 }
4565 //printk("bDefaultAntenna1 = %d\n", priv->bDefaultAntenna1);
4566#endif
4567#endif
4568//by amy for antenna
4569 /* rtl8185 can calc plcp len in HW.*/
4570 priv->hw_plcp_len = 1;
4571
4572 priv->plcp_preamble_mode = 2;
4573 /*the eeprom type is stored in RCR register bit #6 */
4574 if (RCR_9356SEL & read_nic_dword(dev, RCR)){
4575 priv->epromtype=EPROM_93c56;
4576 //DMESG("Reported EEPROM chip is a 93c56 (2Kbit)");
4577 }else{
4578 priv->epromtype=EPROM_93c46;
4579 //DMESG("Reported EEPROM chip is a 93c46 (1Kbit)");
4580 }
4581
4582 dev->get_stats = rtl8180_stats;
4583
4584 dev->dev_addr[0]=eprom_read(dev,MAC_ADR) & 0xff;
4585 dev->dev_addr[1]=(eprom_read(dev,MAC_ADR) & 0xff00)>>8;
4586 dev->dev_addr[2]=eprom_read(dev,MAC_ADR+1) & 0xff;
4587 dev->dev_addr[3]=(eprom_read(dev,MAC_ADR+1) & 0xff00)>>8;
4588 dev->dev_addr[4]=eprom_read(dev,MAC_ADR+2) & 0xff;
4589 dev->dev_addr[5]=(eprom_read(dev,MAC_ADR+2) & 0xff00)>>8;
4590 //DMESG("Card MAC address is "MAC_FMT, MAC_ARG(dev->dev_addr));
4591
4592
4593 for(i=1,j=0; i<14; i+=2,j++){
4594
4595 word = eprom_read(dev,EPROM_TXPW_CH1_2 + j);
4596 priv->chtxpwr[i]=word & 0xff;
4597 priv->chtxpwr[i+1]=(word & 0xff00)>>8;
4598#ifdef DEBUG_EPROM
4599 DMESG("tx word %x:%x",j,word);
4600 DMESG("ch %d pwr %x",i,priv->chtxpwr[i]);
4601 DMESG("ch %d pwr %x",i+1,priv->chtxpwr[i+1]);
4602#endif
4603 }
4604 if(priv->card_8185){
4605 for(i=1,j=0; i<14; i+=2,j++){
4606
4607 word = eprom_read(dev,EPROM_TXPW_OFDM_CH1_2 + j);
4608 priv->chtxpwr_ofdm[i]=word & 0xff;
4609 priv->chtxpwr_ofdm[i+1]=(word & 0xff00)>>8;
4610#ifdef DEBUG_EPROM
4611 DMESG("ofdm tx word %x:%x",j,word);
4612 DMESG("ofdm ch %d pwr %x",i,priv->chtxpwr_ofdm[i]);
4613 DMESG("ofdm ch %d pwr %x",i+1,priv->chtxpwr_ofdm[i+1]);
4614#endif
4615 }
4616 }
4617//{by amy 080312
4618 //3Read crystal calibtration and thermal meter indication on 87SE.
4619
4620 // By SD3 SY's request. Added by Roger, 2007.12.11.
4621
4622 tmpu16 = eprom_read(dev, EEPROM_RSV>>1);
4623
4624 //printk("ReadAdapterInfo8185(): EEPROM_RSV(%04x)\n", tmpu16);
4625
4626 // Crystal calibration for Xin and Xout resp.
4627 priv->XtalCal_Xout = tmpu16 & EEPROM_XTAL_CAL_XOUT_MASK; // 0~7.5pF
4628 priv->XtalCal_Xin = (tmpu16 & EEPROM_XTAL_CAL_XIN_MASK)>>4; // 0~7.5pF
4629 if((tmpu16 & EEPROM_XTAL_CAL_ENABLE)>>12)
4630 priv->bXtalCalibration = true;
4631
4632 // Thermal meter reference indication.
4633 priv->ThermalMeter = (u8)((tmpu16 & EEPROM_THERMAL_METER_MASK)>>8);
4634 if((tmpu16 & EEPROM_THERMAL_METER_ENABLE)>>13)
4635 priv->bTxPowerTrack = true;
4636
4637//by amy 080312}
4638#ifdef CONFIG_RTL8185B
4639 word = eprom_read(dev,EPROM_TXPW_BASE);
4640 priv->cck_txpwr_base = word & 0xf;
4641 priv->ofdm_txpwr_base = (word>>4) & 0xf;
4642#endif
4643
4644 version = eprom_read(dev,EPROM_VERSION);
4645 DMESG("EEPROM version %x",version);
4646 if( (!priv->card_8185) && version < 0x0101){
4647 DMESG ("EEPROM version too old, assuming defaults");
4648 DMESG ("If you see this message *plase* send your \
4649DMESG output to andreamrl@tiscali.it THANKS");
4650 priv->digphy=1;
4651 priv->antb=0;
4652 priv->diversity=1;
4653 priv->cs_treshold=0xc;
4654 priv->rcr_csense=1;
4655 priv->rf_chip=RFCHIPID_PHILIPS;
4656 }else{
4657 if(!priv->card_8185){
4658 u8 rfparam = eprom_read(dev,RF_PARAM);
4659 DMESG("RfParam: %x",rfparam);
4660
4661 priv->digphy = rfparam & (1<<RF_PARAM_DIGPHY_SHIFT) ? 0:1;
4662 priv->antb = rfparam & (1<<RF_PARAM_ANTBDEFAULT_SHIFT) ? 1:0;
4663
4664 priv->rcr_csense = (rfparam & RF_PARAM_CARRIERSENSE_MASK) >>
4665 RF_PARAM_CARRIERSENSE_SHIFT;
4666
4667 priv->diversity =
4668 (read_nic_byte(dev,CONFIG2)&(1<<CONFIG2_ANTENNA_SHIFT)) ? 1:0;
4669 }else{
4670 priv->rcr_csense = 3;
4671 }
4672
4673 priv->cs_treshold = (eprom_read(dev,ENERGY_TRESHOLD)&0xff00) >>8;
4674
4675 priv->rf_chip = 0xff & eprom_read(dev,RFCHIPID);
4676 }
4677
4678#ifdef CONFIG_RTL8185B
4679#ifdef CONFIG_RTL818X_S
4680 priv->rf_chip = RF_ZEBRA4;
4681 priv->rf_sleep = rtl8225z4_rf_sleep;
4682 priv->rf_wakeup = rtl8225z4_rf_wakeup;
4683#else
4684 priv->rf_chip = RF_ZEBRA2;
4685#endif
4686 //DMESG("Card reports RF frontend Realtek 8225z2");
4687 //DMESGW("This driver has EXPERIMENTAL support for this chipset.");
4688 //DMESGW("use it with care and at your own risk and");
4689 DMESGW("**PLEASE** REPORT SUCCESSFUL/UNSUCCESSFUL TO Realtek!");
4690
4691 priv->rf_close = rtl8225z2_rf_close;
4692 priv->rf_init = rtl8225z2_rf_init;
4693 priv->rf_set_chan = rtl8225z2_rf_set_chan;
4694 priv->rf_set_sens = NULL;
4695 //priv->rf_sleep = rtl8225_rf_sleep;
4696 //priv->rf_wakeup = rtl8225_rf_wakeup;
4697
4698#else
4699 /* check RF frontend chipset */
4700 switch (priv->rf_chip) {
4701
4702 case RFCHIPID_RTL8225:
4703
4704 if(priv->card_8185){
4705 DMESG("Card reports RF frontend Realtek 8225");
4706 DMESGW("This driver has EXPERIMENTAL support for this chipset.");
4707 DMESGW("use it with care and at your own risk and");
4708 DMESGW("**PLEASE** REPORT SUCCESS/INSUCCESS TO andreamrl@tiscali.it");
4709
4710 priv->rf_close = rtl8225_rf_close;
4711 priv->rf_init = rtl8225_rf_init;
4712 priv->rf_set_chan = rtl8225_rf_set_chan;
4713 priv->rf_set_sens = NULL;
4714 priv->rf_sleep = rtl8225_rf_sleep;
4715 priv->rf_wakeup = rtl8225_rf_wakeup;
4716
4717 }else{
4718 DMESGW("Detected RTL8225 radio on a card recognized as RTL8180");
4719 DMESGW("This could not be... something went wrong....");
4720 return -ENODEV;
4721 }
4722 break;
4723
4724 case RFCHIPID_RTL8255:
4725 if(priv->card_8185){
4726 DMESG("Card reports RF frontend Realtek 8255");
4727 DMESGW("This driver has EXPERIMENTAL support for this chipset.");
4728 DMESGW("use it with care and at your own risk and");
4729 DMESGW("**PLEASE** REPORT SUCCESS/INSUCCESS TO andreamrl@tiscali.it");
4730
4731 priv->rf_close = rtl8255_rf_close;
4732 priv->rf_init = rtl8255_rf_init;
4733 priv->rf_set_chan = rtl8255_rf_set_chan;
4734 priv->rf_set_sens = NULL;
4735 priv->rf_sleep = NULL;
4736 priv->rf_wakeup = NULL;
4737
4738 }else{
4739 DMESGW("Detected RTL8255 radio on a card recognized as RTL8180");
4740 DMESGW("This could not be... something went wrong....");
4741 return -ENODEV;
4742 }
4743 break;
4744
4745
4746 case RFCHIPID_INTERSIL:
4747 DMESGW("Card reports RF frontend by Intersil.");
4748 DMESGW("This driver has NO support for this chipset.");
4749 return -ENODEV;
4750 break;
4751
4752 case RFCHIPID_RFMD:
4753 DMESGW("Card reports RF frontend by RFMD.");
4754 DMESGW("This driver has NO support for this chipset.");
4755 return -ENODEV;
4756 break;
4757
4758 case RFCHIPID_GCT:
4759 DMESGW("Card reports RF frontend by GCT.");
4760 DMESGW("This driver has EXPERIMENTAL support for this chipset.");
4761 DMESGW("use it with care and at your own risk and");
4762 DMESGW("**PLEASE** REPORT SUCCESS/INSUCCESS TO andreamrl@tiscali.it");
4763 priv->rf_close = gct_rf_close;
4764 priv->rf_init = gct_rf_init;
4765 priv->rf_set_chan = gct_rf_set_chan;
4766 priv->rf_set_sens = NULL;
4767 priv->rf_sleep = NULL;
4768 priv->rf_wakeup = NULL;
4769 break;
4770
4771 case RFCHIPID_MAXIM:
4772 DMESGW("Card reports RF frontend by MAXIM.");
4773 DMESGW("This driver has EXPERIMENTAL support for this chipset.");
4774 DMESGW("use it with care and at your own risk and");
4775 DMESGW("**PLEASE** REPORT SUCCESS/INSUCCESS TO andreamrl@tiscali.it");
4776 priv->rf_close = maxim_rf_close;
4777 priv->rf_init = maxim_rf_init;
4778 priv->rf_set_chan = maxim_rf_set_chan;
4779 priv->rf_set_sens = NULL;
4780 priv->rf_sleep = NULL;
4781 priv->rf_wakeup = NULL;
4782 break;
4783
4784 case RFCHIPID_PHILIPS:
4785 DMESG("Card reports RF frontend by Philips.");
4786 DMESG("OK! Philips SA2400 radio chipset is supported.");
4787 priv->rf_close = sa2400_rf_close;
4788 priv->rf_init = sa2400_rf_init;
4789 priv->rf_set_chan = sa2400_rf_set_chan;
4790 priv->rf_set_sens = sa2400_rf_set_sens;
4791 priv->sens = SA2400_RF_DEF_SENS; /* default sensitivity */
4792 priv->max_sens = SA2400_RF_MAX_SENS; /* maximum sensitivity */
4793 priv->rf_sleep = NULL;
4794 priv->rf_wakeup = NULL;
4795
4796 if(priv->digphy){
4797 DMESGW("Digital PHY found");
4798 DMESGW("Philips DIGITAL PHY is untested! *Please*\
4799 report success/failure to <andreamrl@tiscali.it>");
4800 }else{
4801 DMESG ("Analog PHY found");
4802 }
4803
4804 break;
4805
4806 default:
4807 DMESGW("Unknown RF module %x",priv->rf_chip);
4808 DMESGW("Exiting...");
4809 return -1;
4810
4811 }
4812#endif
4813
4814
4815 if(!priv->card_8185){
4816 if(priv->antb)
4817 DMESG ("Antenna B is default antenna");
4818 else
4819 DMESG ("Antenna A is default antenna");
4820
4821 if(priv->diversity)
4822 DMESG ("Antenna diversity is enabled");
4823 else
4824 DMESG("Antenna diversity is disabled");
4825
4826 DMESG("Carrier sense %d",priv->rcr_csense);
4827 }
4828
4829 if (0!=alloc_rx_desc_ring(dev, priv->rxbuffersize, priv->rxringcount))
4830 return -ENOMEM;
4831
4832 if (0!=alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount,
4833 TX_MANAGEPRIORITY_RING_ADDR))
4834 return -ENOMEM;
4835
4836 if (0!=alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount,
4837 TX_BKPRIORITY_RING_ADDR))
4838 return -ENOMEM;
4839
4840 if (0!=alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount,
4841 TX_BEPRIORITY_RING_ADDR))
4842 return -ENOMEM;
4843
4844 if (0!=alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount,
4845 TX_VIPRIORITY_RING_ADDR))
4846 return -ENOMEM;
4847
4848 if (0!=alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount,
4849 TX_VOPRIORITY_RING_ADDR))
4850 return -ENOMEM;
4851
4852 if (0!=alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount,
4853 TX_HIGHPRIORITY_RING_ADDR))
4854 return -ENOMEM;
4855
4856 if (0!=alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txbeaconcount,
4857 TX_BEACON_RING_ADDR))
4858 return -ENOMEM;
4859
4860
4861 //priv->beacon_buf=NULL;
4862
4863 if(!priv->card_8185){
4864
4865 if(read_nic_byte(dev, CONFIG0) & (1<<CONFIG0_WEP40_SHIFT))
4866 DMESG ("40-bit WEP is supported in hardware");
4867 else
4868 DMESG ("40-bit WEP is NOT supported in hardware");
4869
4870 if(read_nic_byte(dev,CONFIG0) & (1<<CONFIG0_WEP104_SHIFT))
4871 DMESG ("104-bit WEP is supported in hardware");
4872 else
4873 DMESG ("104-bit WEP is NOT supported in hardware");
4874 }
4875#if !defined(SA_SHIRQ)
4876 if(request_irq(dev->irq, (void *)rtl8180_interrupt, IRQF_SHARED, dev->name, dev)){
4877#else
4878 if(request_irq(dev->irq, (void *)rtl8180_interrupt, SA_SHIRQ, dev->name, dev)){
4879#endif
4880 DMESGE("Error allocating IRQ %d",dev->irq);
4881 return -1;
4882 }else{
4883 priv->irq=dev->irq;
4884 DMESG("IRQ %d",dev->irq);
4885 }
4886
4887#ifdef DEBUG_EPROM
4888 dump_eprom(dev);
4889#endif
4890
4891 return 0;
4892
4893}
4894
4895
4896void rtl8180_no_hw_wep(struct net_device *dev)
4897{
4898 struct r8180_priv *priv = ieee80211_priv(dev);
4899
4900 if(!priv->card_8185)
4901 {
4902 u8 security;
4903
4904 security = read_nic_byte(dev, SECURITY);
4905 security &=~(1<<SECURITY_WEP_TX_ENABLE_SHIFT);
4906 security &=~(1<<SECURITY_WEP_RX_ENABLE_SHIFT);
4907
4908 write_nic_byte(dev, SECURITY, security);
4909
4910 }else{
4911
4912 //FIXME!!!
4913 }
4914 /*
4915 write_nic_dword(dev,TX_CONF,read_nic_dword(dev,TX_CONF) |
4916 (1<<TX_NOICV_SHIFT) );
4917 */
4918// priv->ieee80211->hw_wep=0;
4919}
4920
4921
4922void rtl8180_set_hw_wep(struct net_device *dev)
4923{
4924 struct r8180_priv *priv = ieee80211_priv(dev);
4925 u8 pgreg;
4926 u8 security;
4927 u32 key0_word4;
4928
4929 pgreg=read_nic_byte(dev, PGSELECT);
4930 write_nic_byte(dev, PGSELECT, pgreg &~ (1<<PGSELECT_PG_SHIFT));
4931
4932 key0_word4 = read_nic_dword(dev, KEY0+4+4+4);
4933 key0_word4 &= ~ 0xff;
4934 key0_word4 |= priv->key0[3]& 0xff;
4935 write_nic_dword(dev,KEY0,(priv->key0[0]));
4936 write_nic_dword(dev,KEY0+4,(priv->key0[1]));
4937 write_nic_dword(dev,KEY0+4+4,(priv->key0[2]));
4938 write_nic_dword(dev,KEY0+4+4+4,(key0_word4));
4939
4940 /*
4941 TX_CONF,read_nic_dword(dev,TX_CONF) &~(1<<TX_NOICV_SHIFT));
4942 */
4943
4944 security = read_nic_byte(dev,SECURITY);
4945 security |= (1<<SECURITY_WEP_TX_ENABLE_SHIFT);
4946 security |= (1<<SECURITY_WEP_RX_ENABLE_SHIFT);
4947 security &= ~ SECURITY_ENCRYP_MASK;
4948 security |= (SECURITY_ENCRYP_104<<SECURITY_ENCRYP_SHIFT);
4949
4950 write_nic_byte(dev, SECURITY, security);
4951
4952 DMESG("key %x %x %x %x",read_nic_dword(dev,KEY0+4+4+4),
4953 read_nic_dword(dev,KEY0+4+4),read_nic_dword(dev,KEY0+4),
4954 read_nic_dword(dev,KEY0));
4955
4956 //priv->ieee80211->hw_wep=1;
4957}
4958
4959
4960void rtl8185_rf_pins_enable(struct net_device *dev)
4961{
4962// u16 tmp;
4963// tmp = read_nic_word(dev, RFPinsEnable);
4964 write_nic_word(dev, RFPinsEnable, 0x1fff);// | tmp);
4965// write_nic_word(dev, RFPinsEnable,7 | tmp);
4966}
4967
4968
4969void rtl8185_set_anaparam2(struct net_device *dev, u32 a)
4970{
4971 u8 conf3;
4972
4973 rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
4974
4975 conf3 = read_nic_byte(dev, CONFIG3);
4976 write_nic_byte(dev, CONFIG3, conf3 | (1<<CONFIG3_ANAPARAM_W_SHIFT));
4977 write_nic_dword(dev, ANAPARAM2, a);
4978
4979 conf3 = read_nic_byte(dev, CONFIG3);
4980 write_nic_byte(dev, CONFIG3, conf3 &~(1<<CONFIG3_ANAPARAM_W_SHIFT));
4981 rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
4982
4983}
4984
4985
4986void rtl8180_set_anaparam(struct net_device *dev, u32 a)
4987{
4988 u8 conf3;
4989
4990 rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
4991
4992 conf3 = read_nic_byte(dev, CONFIG3);
4993 write_nic_byte(dev, CONFIG3, conf3 | (1<<CONFIG3_ANAPARAM_W_SHIFT));
4994 write_nic_dword(dev, ANAPARAM, a);
4995
4996 conf3 = read_nic_byte(dev, CONFIG3);
4997 write_nic_byte(dev, CONFIG3, conf3 &~(1<<CONFIG3_ANAPARAM_W_SHIFT));
4998 rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
4999}
5000
5001
5002void rtl8185_tx_antenna(struct net_device *dev, u8 ant)
5003{
5004 write_nic_byte(dev, TX_ANTENNA, ant);
5005 force_pci_posting(dev);
5006 mdelay(1);
5007}
5008
5009
5010void rtl8185_write_phy(struct net_device *dev, u8 adr, u32 data)
5011{
5012 //u8 phyr;
5013 u32 phyw;
5014 //int i;
5015
5016 adr |= 0x80;
5017
5018 phyw= ((data<<8) | adr);
5019#if 0
5020
5021 write_nic_dword(dev, PHY_ADR, phyw);
5022
5023 //read_nic_dword(dev, PHY_ADR);
5024 for(i=0;i<10;i++){
5025 write_nic_dword(dev, PHY_ADR, 0xffffff7f & phyw);
5026 phyr = read_nic_byte(dev, PHY_READ);
5027 if(phyr == (data&0xff)) break;
5028
5029 }
5030#else
5031 // Note that, we must write 0xff7c after 0x7d-0x7f to write BB register.
5032 write_nic_byte(dev, 0x7f, ((phyw & 0xff000000) >> 24));
5033 write_nic_byte(dev, 0x7e, ((phyw & 0x00ff0000) >> 16));
5034 write_nic_byte(dev, 0x7d, ((phyw & 0x0000ff00) >> 8));
5035 write_nic_byte(dev, 0x7c, ((phyw & 0x000000ff) ));
5036#endif
5037 /* this is ok to fail when we write AGC table. check for AGC table might be
5038 * done by masking with 0x7f instead of 0xff
5039 */
5040 //if(phyr != (data&0xff)) DMESGW("Phy write timeout %x %x %x", phyr, data,adr);
5041}
5042
5043
5044inline void write_phy_ofdm (struct net_device *dev, u8 adr, u32 data)
5045{
5046 data = data & 0xff;
5047 rtl8185_write_phy(dev, adr, data);
5048}
5049
5050
5051void write_phy_cck (struct net_device *dev, u8 adr, u32 data)
5052{
5053 data = data & 0xff;
5054 rtl8185_write_phy(dev, adr, data | 0x10000);
5055}
5056
5057
5058/* 70*3 = 210 ms
5059 * I hope this is enougth
5060 */
5061#define MAX_PHY 70
5062void write_phy(struct net_device *dev, u8 adr, u8 data)
5063{
5064 u32 phy;
5065 int i;
5066
5067 phy = 0xff0000;
5068 phy |= adr;
5069 phy |= 0x80; /* this should enable writing */
5070 phy |= (data<<8);
5071
5072 //PHY_ADR, PHY_R and PHY_W are contig and treated as one dword
5073 write_nic_dword(dev,PHY_ADR, phy);
5074
5075 phy= 0xffff00;
5076 phy |= adr;
5077
5078 write_nic_dword(dev,PHY_ADR, phy);
5079 for(i=0;i<MAX_PHY;i++){
5080 phy=read_nic_dword(dev,PHY_ADR);
5081 phy= phy & 0xff0000;
5082 phy= phy >> 16;
5083 if(phy == data){ //SUCCESS!
5084 force_pci_posting(dev);
5085 mdelay(3); //random value
5086#ifdef DEBUG_BB
5087 DMESG("Phy wr %x,%x",adr,data);
5088#endif
5089 return;
5090 }else{
5091 force_pci_posting(dev);
5092 mdelay(3); //random value
5093 }
5094 }
5095 DMESGW ("Phy writing %x %x failed!", adr,data);
5096}
5097
5098void rtl8185_set_rate(struct net_device *dev)
5099{
5100 int i;
5101 u16 word;
5102 int basic_rate,min_rr_rate,max_rr_rate;
5103
5104// struct r8180_priv *priv = ieee80211_priv(dev);
5105
5106 //if (ieee80211_is_54g(priv->ieee80211->current_network) &&
5107// priv->ieee80211->state == IEEE80211_LINKED){
5108 basic_rate = ieeerate2rtlrate(240);
5109 min_rr_rate = ieeerate2rtlrate(60);
5110 max_rr_rate = ieeerate2rtlrate(240);
5111
5112//
5113// }else{
5114// basic_rate = ieeerate2rtlrate(20);
5115// min_rr_rate = ieeerate2rtlrate(10);
5116// max_rr_rate = ieeerate2rtlrate(110);
5117// }
5118
5119 write_nic_byte(dev, RESP_RATE,
5120 max_rr_rate<<MAX_RESP_RATE_SHIFT| min_rr_rate<<MIN_RESP_RATE_SHIFT);
5121
5122 word = read_nic_word(dev, BRSR);
5123 word &= ~BRSR_MBR_8185;
5124
5125
5126 for(i=0;i<=basic_rate;i++)
5127 word |= (1<<i);
5128
5129 write_nic_word(dev, BRSR, word);
5130 //DMESG("RR:%x BRSR: %x", read_nic_byte(dev,RESP_RATE),read_nic_word(dev,BRSR));
5131}
5132
5133
5134
5135void rtl8180_adapter_start(struct net_device *dev)
5136{
5137 struct r8180_priv *priv = ieee80211_priv(dev);
5138 u32 anaparam;
5139 u16 word;
5140 u8 config3;
5141// int i;
5142
5143 rtl8180_rtx_disable(dev);
5144 rtl8180_reset(dev);
5145
5146 /* seems that 0xffff or 0xafff will cause
5147 * HW interrupt line crash
5148 */
5149
5150 //priv->irq_mask = 0xafff;
5151// priv->irq_mask = 0x4fcf;
5152
5153 /* enable beacon timeout, beacon TX ok and err
5154 * LP tx ok and err, HP TX ok and err, NP TX ok and err,
5155 * RX ok and ERR, and GP timer */
5156 priv->irq_mask = 0x6fcf;
5157
5158 priv->dma_poll_mask = 0;
5159
5160 rtl8180_beacon_tx_disable(dev);
5161
5162 if(priv->card_type == CARDBUS ){
5163 config3=read_nic_byte(dev, CONFIG3);
5164 write_nic_byte(dev,CONFIG3,config3 | CONFIG3_FuncRegEn);
5165 write_nic_word(dev,FEMR, FEMR_INTR | FEMR_WKUP | FEMR_GWAKE |
5166 read_nic_word(dev, FEMR));
5167 }
5168 rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
5169 write_nic_dword(dev, MAC0, ((u32*)dev->dev_addr)[0]);
5170 write_nic_word(dev, MAC4, ((u32*)dev->dev_addr)[1] & 0xffff );
5171 rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
5172
5173 rtl8180_update_msr(dev);
5174
5175 if(!priv->card_8185){
5176 anaparam = eprom_read(dev,EPROM_ANAPARAM_ADDRLWORD);
5177 anaparam |= eprom_read(dev,EPROM_ANAPARAM_ADDRHWORD)<<16;
5178
5179 rtl8180_set_anaparam(dev,anaparam);
5180 }
5181 /* These might be unnecessary since we do in rx_enable / tx_enable */
5182 fix_rx_fifo(dev);
5183 fix_tx_fifo(dev);
5184 /*set_nic_rxring(dev);
5185 set_nic_txring(dev);*/
5186
5187 rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
5188
5189 /*
5190 The following is very strange. seems to be that 1 means test mode,
5191 but we need to acknolwledges the nic when a packet is ready
5192 altought we set it to 0
5193 */
5194
5195 write_nic_byte(dev,
5196 CONFIG2, read_nic_byte(dev,CONFIG2) &~\
5197 (1<<CONFIG2_DMA_POLLING_MODE_SHIFT));
5198 //^the nic isn't in test mode
5199 if(priv->card_8185)
5200 write_nic_byte(dev,
5201 CONFIG2, read_nic_byte(dev,CONFIG2)|(1<<4));
5202
5203 rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
5204
5205 write_nic_dword(dev,INT_TIMEOUT,0);
5206#ifdef DEBUG_REGISTERS
5207 rtl8180_dump_reg(dev);
5208#endif
5209
5210 if(!priv->card_8185)
5211 {
5212 /*
5213 experimental - this might be needed to calibrate AGC,
5214 anyway it shouldn't hurt
5215 */
5216 write_nic_byte(dev, CONFIG5,
5217 read_nic_byte(dev, CONFIG5) | (1<<AGCRESET_SHIFT));
5218 read_nic_byte(dev, CONFIG5);
5219 udelay(15);
5220 write_nic_byte(dev, CONFIG5,
5221 read_nic_byte(dev, CONFIG5) &~ (1<<AGCRESET_SHIFT));
5222 }else{
5223
5224 write_nic_byte(dev, WPA_CONFIG, 0);
5225 //write_nic_byte(dev, TESTR, 0xd);
5226 }
5227
5228 rtl8180_no_hw_wep(dev);
5229
5230 if(priv->card_8185){
5231 rtl8185_set_rate(dev);
5232 write_nic_byte(dev, RATE_FALLBACK, 0x81);
5233 // write_nic_byte(dev, 0xdf, 0x15);
5234 }else{
5235 word = read_nic_word(dev, BRSR);
5236 word &= ~BRSR_MBR;
5237 word &= ~BRSR_BPLCP;
5238 word |= ieeerate2rtlrate(priv->ieee80211->basic_rate);
5239//by amy
5240 word |= 0x0f;
5241//by amy
5242 write_nic_word(dev, BRSR, word);
5243 }
5244
5245
5246 if(priv->card_8185){
5247 write_nic_byte(dev, GP_ENABLE,read_nic_byte(dev, GP_ENABLE) & ~(1<<6));
5248
5249 //FIXME cfg 3 ClkRun enable - isn't it ReadOnly ?
5250 rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
5251 write_nic_byte(dev,CONFIG3, read_nic_byte(dev, CONFIG3)
5252|(1<<CONFIG3_CLKRUN_SHIFT));
5253 rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
5254
5255 }
5256
5257 priv->rf_init(dev);
5258
5259 if(priv->rf_set_sens != NULL)
5260 priv->rf_set_sens(dev,priv->sens);
5261 rtl8180_irq_enable(dev);
5262
5263 netif_start_queue(dev);
5264 /*DMESG ("lfree %d",get_curr_tx_free_desc(dev,LOW_PRIORITY));
5265
5266 DMESG ("nfree %d",get_curr_tx_free_desc(dev,NORM_PRIORITY));
5267
5268 DMESG ("hfree %d",get_curr_tx_free_desc(dev,HI_PRIORITY));
5269 if(check_nic_enought_desc(dev,NORM_PRIORITY)) DMESG("NORM OK");
5270 if(check_nic_enought_desc(dev,HI_PRIORITY)) DMESG("HI OK");
5271 if(check_nic_enought_desc(dev,LOW_PRIORITY)) DMESG("LOW OK");*/
5272}
5273
5274
5275
5276/* this configures registers for beacon tx and enables it via
5277 * rtl8180_beacon_tx_enable(). rtl8180_beacon_tx_disable() might
5278 * be used to stop beacon transmission
5279 */
5280void rtl8180_start_tx_beacon(struct net_device *dev)
5281{
5282// struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
5283 u16 word;
5284// DMESG("ring %x %x", priv->txlpringdma,read_nic_dword(dev,TLPDA));
5285
5286 DMESG("Enabling beacon TX");
5287 //write_nic_byte(dev, 0x42,0xe6);// TCR
5288// set_nic_txring(dev);
5289// fix_tx_fifo(dev);
5290 rtl8180_prepare_beacon(dev);
5291 rtl8180_irq_disable(dev);
5292 rtl8180_beacon_tx_enable(dev);
5293#if 0
5294 rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
5295 //write_nic_byte(dev,0x9d,0x20); //DMA Poll
5296 //write_nic_word(dev,0x7a,0);
5297 //write_nic_word(dev,0x7a,0x8000);
5298
5299#if 0
5300 word = read_nic_word(dev, BcnItv);
5301 word &= ~BcnItv_BcnItv; // clear Bcn_Itv
5302 word |= priv->ieee80211->current_network.beacon_interval;//0x64;
5303 write_nic_word(dev, BcnItv, word);
5304#endif
5305#endif
5306 word = read_nic_word(dev, AtimWnd) &~ AtimWnd_AtimWnd;
5307 write_nic_word(dev, AtimWnd,word);// word |=
5308//priv->ieee80211->current_network.atim_window);
5309
5310 word = read_nic_word(dev, BintrItv);
5311 word &= ~BintrItv_BintrItv;
5312 word |= 1000;/*priv->ieee80211->current_network.beacon_interval *
5313 ((priv->txbeaconcount > 1)?(priv->txbeaconcount-1):1);
5314 // FIXME: check if correct ^^ worked with 0x3e8;
5315 */
5316 write_nic_word(dev, BintrItv, word);
5317
5318
5319 rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
5320
5321// rtl8180_beacon_tx_enable(dev);
5322#ifdef CONFIG_RTL8185B
5323 rtl8185b_irq_enable(dev);
5324#else
5325 rtl8180_irq_enable(dev);
5326#endif
5327 /* VV !!!!!!!!!! VV*/
5328 /*
5329 rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
5330 write_nic_byte(dev,0x9d,0x00);
5331 rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
5332*/
5333// DMESG("ring %x %x", priv->txlpringdma,read_nic_dword(dev,TLPDA));
5334
5335}
5336
5337
5338
5339/***************************************************************************
5340 -------------------------------NET STUFF---------------------------
5341***************************************************************************/
5342static struct net_device_stats *rtl8180_stats(struct net_device *dev)
5343{
5344 struct r8180_priv *priv = ieee80211_priv(dev);
5345
5346 return &priv->ieee80211->stats;
5347}
5348//
5349// Change current and default preamble mode.
5350// 2005.01.06, by rcnjko.
5351//
5352bool
5353MgntActSet_802_11_PowerSaveMode(
5354 struct r8180_priv *priv,
5355 RT_PS_MODE rtPsMode
5356)
5357{
5358
5359 // Currently, we do not change power save mode on IBSS mode.
5360 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
5361 {
5362 return false;
5363 }
5364
5365 //
5366 // <RJ_NOTE> If we make HW to fill up the PwrMgt bit for us,
5367 // some AP will not response to our mgnt frames with PwrMgt bit set,
5368 // e.g. cannot associate the AP.
5369 // So I commented out it. 2005.02.16, by rcnjko.
5370 //
5371// // Change device's power save mode.
5372// Adapter->HalFunc.SetPSModeHandler( Adapter, rtPsMode );
5373
5374 // Update power save mode configured.
5375// priv->dot11PowerSaveMode = rtPsMode;
5376 priv->ieee80211->ps = rtPsMode;
5377 // Determine ListenInterval.
5378#if 0
5379 if(priv->dot11PowerSaveMode == eMaxPs)
5380 {
5381 priv->ieee80211->ListenInterval = 10;
5382 }
5383 else
5384 {
5385 priv->ieee80211->ListenInterval = 2;
5386 }
5387#endif
5388 return true;
5389}
5390
5391//================================================================================
5392// Leisure Power Save in linked state.
5393//================================================================================
5394
5395//
5396// Description:
5397// Enter the leisure power save mode.
5398//
5399void
5400LeisurePSEnter(
5401 struct r8180_priv *priv
5402 )
5403{
5404 if (priv->bLeisurePs)
5405 {
5406 if (priv->ieee80211->ps == IEEE80211_PS_DISABLED)
5407 {
5408 //printk("----Enter PS\n");
5409 MgntActSet_802_11_PowerSaveMode(priv, IEEE80211_PS_MBCAST|IEEE80211_PS_UNICAST);//IEEE80211_PS_ENABLE
5410 }
5411 }
5412}
5413
5414
5415//
5416// Description:
5417// Leave the leisure power save mode.
5418//
5419void
5420LeisurePSLeave(
5421 struct r8180_priv *priv
5422 )
5423{
5424 if (priv->bLeisurePs)
5425 {
5426 if (priv->ieee80211->ps != IEEE80211_PS_DISABLED)
5427 {
5428 //printk("----Leave PS\n");
5429 MgntActSet_802_11_PowerSaveMode(priv, IEEE80211_PS_DISABLED);
5430 }
5431 }
5432}
5433#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
5434void rtl8180_hw_wakeup_wq (struct work_struct *work)
5435{
5436// struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
5437// struct ieee80211_device * ieee = (struct ieee80211_device*)
5438// container_of(work, struct ieee80211_device, watch_dog_wq);
5439 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
5440 struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_wakeup_wq);
5441 struct net_device *dev = ieee->dev;
5442#else
5443void rtl8180_hw_wakeup_wq(struct net_device *dev)
5444{
5445 struct r8180_priv *priv = ieee80211_priv(dev);
5446#endif
5447
5448// printk("dev is %d\n",dev);
5449// printk("&*&(^*(&(&=========>%s()\n", __FUNCTION__);
5450 rtl8180_hw_wakeup(dev);
5451
5452}
5453
5454#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
5455void rtl8180_hw_sleep_wq (struct work_struct *work)
5456{
5457// struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
5458// struct ieee80211_device * ieee = (struct ieee80211_device*)
5459// container_of(work, struct ieee80211_device, watch_dog_wq);
5460 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
5461 struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_sleep_wq);
5462 struct net_device *dev = ieee->dev;
5463#else
5464void rtl8180_hw_sleep_wq(struct net_device *dev)
5465{
5466 struct r8180_priv *priv = ieee80211_priv(dev);
5467#endif
5468
5469 rtl8180_hw_sleep_down(dev);
5470}
5471
5472//YJ,add,080828,for KeepAlive
5473static void MgntLinkKeepAlive(struct r8180_priv *priv )
5474{
5475 if (priv->keepAliveLevel == 0)
5476 return;
5477
5478 if(priv->ieee80211->state == IEEE80211_LINKED)
5479 {
5480 //
5481 // Keep-Alive.
5482 //
5483 //printk("LastTx:%d Tx:%d LastRx:%d Rx:%ld Idle:%d\n",priv->link_detect.LastNumTxUnicast,priv->NumTxUnicast, priv->link_detect.LastNumRxUnicast, priv->ieee80211->NumRxUnicast, priv->link_detect.IdleCount);
5484
5485 if ( (priv->keepAliveLevel== 2) ||
5486 (priv->link_detect.LastNumTxUnicast == priv->NumTxUnicast &&
5487 priv->link_detect.LastNumRxUnicast == priv->ieee80211->NumRxUnicast )
5488 )
5489 {
5490 priv->link_detect.IdleCount++;
5491
5492 //
5493 // Send a Keep-Alive packet packet to AP if we had been idle for a while.
5494 //
5495 if(priv->link_detect.IdleCount >= ((KEEP_ALIVE_INTERVAL / CHECK_FOR_HANG_PERIOD)-1) )
5496 {
5497 priv->link_detect.IdleCount = 0;
5498 ieee80211_sta_ps_send_null_frame(priv->ieee80211, false);
5499 }
5500 }
5501 else
5502 {
5503 priv->link_detect.IdleCount = 0;
5504 }
5505 priv->link_detect.LastNumTxUnicast = priv->NumTxUnicast;
5506 priv->link_detect.LastNumRxUnicast = priv->ieee80211->NumRxUnicast;
5507 }
5508}
5509//YJ,add,080828,for KeepAlive,end
5510
5511static u8 read_acadapter_file(char *filename);
5512void rtl8180_watch_dog(struct net_device *dev)
5513{
5514 struct r8180_priv *priv = ieee80211_priv(dev);
5515 bool bEnterPS = false;
5516 bool bBusyTraffic = false;
5517 u32 TotalRxNum = 0;
5518 u16 SlotIndex = 0;
5519 u16 i = 0;
5520#ifdef ENABLE_IPS
5521 if(priv->ieee80211->actscanning == false){
5522 if((priv->ieee80211->iw_mode != IW_MODE_ADHOC) && (priv->ieee80211->state == IEEE80211_NOLINK) && (priv->ieee80211->beinretry == false) && (priv->eRFPowerState == eRfOn)){
5523 IPSEnter(dev);
5524 }
5525 }
5526#endif
5527 //YJ,add,080828,for link state check
5528 if((priv->ieee80211->state == IEEE80211_LINKED) && (priv->ieee80211->iw_mode == IW_MODE_INFRA)){
5529 SlotIndex = (priv->link_detect.SlotIndex++) % priv->link_detect.SlotNum;
5530 priv->link_detect.RxFrameNum[SlotIndex] = priv->ieee80211->NumRxDataInPeriod + priv->ieee80211->NumRxBcnInPeriod;
5531 for( i=0; i<priv->link_detect.SlotNum; i++ )
5532 TotalRxNum+= priv->link_detect.RxFrameNum[i];
5533 //printk("&&&&&=== TotalRxNum = %d\n", TotalRxNum);
5534 if(TotalRxNum == 0){
5535 priv->ieee80211->state = IEEE80211_ASSOCIATING;
5536 queue_work(priv->ieee80211->wq, &priv->ieee80211->associate_procedure_wq);
5537 }
5538 }
5539
5540 //YJ,add,080828,for KeepAlive
5541 MgntLinkKeepAlive(priv);
5542
5543 //YJ,add,080828,for LPS
5544#ifdef ENABLE_LPS
5545 if(priv->PowerProfile == POWER_PROFILE_BATTERY )
5546 {
5547 //Turn on LeisurePS on battery power
5548 //printk("!!!!!On battery power\n");
5549 priv->bLeisurePs = true;
5550 }
5551 else if(priv->PowerProfile == POWER_PROFILE_AC )
5552 {
5553 // Turn off LeisurePS on AC power
5554 //printk("----On AC power\n");
5555 LeisurePSLeave(priv);
5556 priv->bLeisurePs= false;
5557 }
5558#endif
5559
5560#if 0
5561#ifndef ENABLE_LPS
5562 if(priv->ieee80211->state == IEEE80211_LINKED){
5563 if( priv->NumRxOkInPeriod> 666 ||
5564 priv->NumTxOkInPeriod > 666 ) {
5565 bBusyTraffic = true;
5566 }
5567 if((priv->ieee80211->NumRxData + priv->NumTxOkInPeriod)<8) {
5568 bEnterPS= true;
5569 }
5570 if(bEnterPS) {
5571 LeisurePSEnter(priv);
5572 }
5573 else {
5574 LeisurePSLeave(priv);
5575 }
5576 }
5577 else {
5578 LeisurePSLeave(priv);
5579 }
5580#endif
5581 priv->NumRxOkInPeriod = 0;
5582 priv->NumTxOkInPeriod = 0;
5583 priv->ieee80211->NumRxData = 0;
5584#else
5585#ifdef ENABLE_LPS
5586 if(priv->ieee80211->state == IEEE80211_LINKED){
5587 priv->link_detect.NumRxOkInPeriod = priv->ieee80211->NumRxDataInPeriod;
5588 //printk("TxOk=%d RxOk=%d\n", priv->link_detect.NumTxOkInPeriod, priv->link_detect.NumRxOkInPeriod);
5589 if( priv->link_detect.NumRxOkInPeriod> 666 ||
5590 priv->link_detect.NumTxOkInPeriod> 666 ) {
5591 bBusyTraffic = true;
5592 }
5593 if(((priv->link_detect.NumRxOkInPeriod + priv->link_detect.NumTxOkInPeriod) > 8)
5594 || (priv->link_detect.NumRxOkInPeriod > 2)) {
5595 bEnterPS= false;
5596 }
5597 else {
5598 bEnterPS= true;
5599 }
5600
5601 if(bEnterPS) {
5602 LeisurePSEnter(priv);
5603 }
5604 else {
5605 LeisurePSLeave(priv);
5606 }
5607 }
5608 else{
5609 LeisurePSLeave(priv);
5610 }
5611#endif
5612 priv->link_detect.bBusyTraffic = bBusyTraffic;
5613 priv->link_detect.NumRxOkInPeriod = 0;
5614 priv->link_detect.NumTxOkInPeriod = 0;
5615 priv->ieee80211->NumRxDataInPeriod = 0;
5616 priv->ieee80211->NumRxBcnInPeriod = 0;
5617#endif
5618}
5619int _rtl8180_up(struct net_device *dev)
5620{
5621 struct r8180_priv *priv = ieee80211_priv(dev);
5622 //int i;
5623
5624 priv->up=1;
5625
5626 DMESG("Bringing up iface");
5627#ifdef CONFIG_RTL8185B
5628 rtl8185b_adapter_start(dev);
5629 rtl8185b_rx_enable(dev);
5630 rtl8185b_tx_enable(dev);
5631#else
5632 rtl8180_adapter_start(dev);
5633 rtl8180_rx_enable(dev);
5634 rtl8180_tx_enable(dev);
5635#endif
5636#ifdef ENABLE_IPS
5637 if(priv->bInactivePs){
5638 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
5639 IPSLeave(dev);
5640 }
5641#endif
5642//by amy 080312
5643#ifdef RATE_ADAPT
5644 timer_rate_adaptive((unsigned long)dev);
5645#endif
5646//by amy 080312
5647 watch_dog_adaptive((unsigned long)dev);
5648#ifdef SW_ANTE
5649 if(priv->bSwAntennaDiverity)
5650 SwAntennaDiversityTimerCallback(dev);
5651#endif
5652// IPSEnter(dev);
5653 ieee80211_softmac_start_protocol(priv->ieee80211);
5654
5655//Add for RF power on power off by lizhaoming 080512
5656// priv->eRFPowerState = eRfOn;
5657// printk("\n--------Start queue_work:GPIOChangeRFWorkItem");
5658// queue_delayed_work(priv->ieee80211->wq,&priv->ieee80211->GPIOChangeRFWorkItem,1000);
5659
5660 return 0;
5661}
5662
5663
5664int rtl8180_open(struct net_device *dev)
5665{
5666 struct r8180_priv *priv = ieee80211_priv(dev);
5667 int ret;
5668
5669 down(&priv->wx_sem);
5670 ret = rtl8180_up(dev);
5671 up(&priv->wx_sem);
5672 return ret;
5673
5674}
5675
5676
5677int rtl8180_up(struct net_device *dev)
5678{
5679 struct r8180_priv *priv = ieee80211_priv(dev);
5680
5681 if (priv->up == 1) return -1;
5682
5683 return _rtl8180_up(dev);
5684}
5685
5686
5687int rtl8180_close(struct net_device *dev)
5688{
5689 struct r8180_priv *priv = ieee80211_priv(dev);
5690 int ret;
5691
5692 down(&priv->wx_sem);
5693 ret = rtl8180_down(dev);
5694 up(&priv->wx_sem);
5695
5696 return ret;
5697
5698}
5699
5700int rtl8180_down(struct net_device *dev)
5701{
5702 struct r8180_priv *priv = ieee80211_priv(dev);
5703
5704 if (priv->up == 0) return -1;
5705
5706 priv->up=0;
5707
5708 ieee80211_softmac_stop_protocol(priv->ieee80211);
5709 /* FIXME */
5710 if (!netif_queue_stopped(dev))
5711 netif_stop_queue(dev);
5712 rtl8180_rtx_disable(dev);
5713 rtl8180_irq_disable(dev);
5714 del_timer_sync(&priv->watch_dog_timer);
5715 //cancel_delayed_work(&priv->ieee80211->watch_dog_wq);
5716//{by amy 080312
5717 del_timer_sync(&priv->rateadapter_timer);
5718 cancel_delayed_work(&priv->ieee80211->rate_adapter_wq);
5719//by amy 080312}
5720 cancel_delayed_work(&priv->ieee80211->hw_wakeup_wq);
5721 cancel_delayed_work(&priv->ieee80211->hw_sleep_wq);
5722 cancel_delayed_work(&priv->ieee80211->hw_dig_wq);
5723 cancel_delayed_work(&priv->ieee80211->tx_pw_wq);
5724 del_timer_sync(&priv->SwAntennaDiversityTimer);
5725 SetZebraRFPowerState8185(dev,eRfOff);
5726 //ieee80211_softmac_stop_protocol(priv->ieee80211);
5727 memset(&(priv->ieee80211->current_network),0,sizeof(struct ieee80211_network));
5728 priv->ieee80211->state = IEEE80211_NOLINK;
5729 return 0;
5730}
5731
5732#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
5733void rtl8180_restart_wq(struct work_struct *work)
5734{
5735 struct r8180_priv *priv = container_of(work, struct r8180_priv, reset_wq);
5736 struct net_device *dev = priv->dev;
5737#else
5738void rtl8180_restart_wq(struct net_device *dev)
5739{
5740 struct r8180_priv *priv = ieee80211_priv(dev);
5741#endif
5742 down(&priv->wx_sem);
5743
5744 rtl8180_commit(dev);
5745
5746 up(&priv->wx_sem);
5747}
5748
5749void rtl8180_restart(struct net_device *dev)
5750{
5751 struct r8180_priv *priv = ieee80211_priv(dev);
5752 //rtl8180_commit(dev);
5753 schedule_work(&priv->reset_wq);
5754 //DMESG("TXTIMEOUT");
5755}
5756
5757
5758void rtl8180_commit(struct net_device *dev)
5759{
5760 struct r8180_priv *priv = ieee80211_priv(dev);
5761
5762 if (priv->up == 0) return ;
5763//+by amy 080312
5764 del_timer_sync(&priv->watch_dog_timer);
5765 //cancel_delayed_work(&priv->ieee80211->watch_dog_wq);
5766//{by amy 080312
5767//by amy for rate adaptive
5768 del_timer_sync(&priv->rateadapter_timer);
5769 cancel_delayed_work(&priv->ieee80211->rate_adapter_wq);
5770//by amy for rate adaptive
5771//by amy 080312}
5772 cancel_delayed_work(&priv->ieee80211->hw_wakeup_wq);
5773 cancel_delayed_work(&priv->ieee80211->hw_sleep_wq);
5774 cancel_delayed_work(&priv->ieee80211->hw_dig_wq);
5775 cancel_delayed_work(&priv->ieee80211->tx_pw_wq);
5776 del_timer_sync(&priv->SwAntennaDiversityTimer);
5777 ieee80211_softmac_stop_protocol(priv->ieee80211);
5778 rtl8180_irq_disable(dev);
5779 rtl8180_rtx_disable(dev);
5780 _rtl8180_up(dev);
5781}
5782
5783
5784static void r8180_set_multicast(struct net_device *dev)
5785{
5786 struct r8180_priv *priv = ieee80211_priv(dev);
5787 short promisc;
5788
5789 //down(&priv->wx_sem);
5790
5791 promisc = (dev->flags & IFF_PROMISC) ? 1:0;
5792
5793 if (promisc != priv->promisc)
5794 rtl8180_restart(dev);
5795
5796 priv->promisc = promisc;
5797
5798 //up(&priv->wx_sem);
5799}
5800
5801#if 0
5802/* this is called by the kernel when it needs to TX a 802.3 encapsulated frame*/
5803int rtl8180_8023_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
5804{
5805 struct r8180_priv *priv = ieee80211_priv(dev);
5806 int ret;
5807 unsigned long flags;
5808
5809 spin_lock_irqsave(&priv->tx_lock,flags);
5810 ret = ieee80211_r8180_8023_hardstartxmit(skb,priv->ieee80211);
5811 spin_unlock_irqrestore(&priv->tx_lock,flags);
5812 return ret;
5813}
5814#endif
5815
5816int r8180_set_mac_adr(struct net_device *dev, void *mac)
5817{
5818 struct r8180_priv *priv = ieee80211_priv(dev);
5819 struct sockaddr *addr = mac;
5820
5821 down(&priv->wx_sem);
5822
5823 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
5824
5825 if(priv->ieee80211->iw_mode == IW_MODE_MASTER)
5826 memcpy(priv->ieee80211->current_network.bssid, dev->dev_addr, ETH_ALEN);
5827
5828 if (priv->up) {
5829 rtl8180_down(dev);
5830 rtl8180_up(dev);
5831 }
5832
5833 up(&priv->wx_sem);
5834
5835 return 0;
5836}
5837
5838/* based on ipw2200 driver */
5839int rtl8180_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
5840{
5841 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
5842
5843 struct iwreq *wrq = (struct iwreq *) rq;
5844 int ret=-1;
5845 switch (cmd) {
5846 case RTL_IOCTL_WPA_SUPPLICANT:
5847 ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data);
5848 return ret;
5849
5850 default:
5851 return -EOPNOTSUPP;
5852 }
5853
5854 return -EOPNOTSUPP;
5855}
5856
5857
5858
5859/****************************************************************************
5860 -----------------------------PCI STUFF---------------------------
5861*****************************************************************************/
5862
5863
5864static int __devinit rtl8180_pci_probe(struct pci_dev *pdev,
5865 const struct pci_device_id *id)
5866{
5867 unsigned long ioaddr = 0;
5868 struct net_device *dev = NULL;
5869 struct r8180_priv *priv= NULL;
5870 //u8 *ptr;
5871 u8 unit = 0;
5872
5873#ifdef CONFIG_RTL8180_IO_MAP
5874 unsigned long pio_start, pio_len, pio_flags;
5875#else
5876 unsigned long pmem_start, pmem_len, pmem_flags;
5877#endif //end #ifdef RTL_IO_MAP
5878
5879 DMESG("Configuring chip resources");
5880
5881 if( pci_enable_device (pdev) ){
5882 DMESG("Failed to enable PCI device");
5883 return -EIO;
5884 }
5885
5886 pci_set_master(pdev);
5887 //pci_set_wmi(pdev);
5888 pci_set_dma_mask(pdev, 0xffffff00ULL);
5889 pci_set_consistent_dma_mask(pdev,0xffffff00ULL);
5890 dev = alloc_ieee80211(sizeof(struct r8180_priv));
5891 if (!dev)
5892 return -ENOMEM;
5893 priv = ieee80211_priv(dev);
5894 priv->ieee80211 = netdev_priv(dev);
5895
5896#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
5897 SET_MODULE_OWNER(dev);
5898#endif
5899 pci_set_drvdata(pdev, dev);
5900 SET_NETDEV_DEV(dev, &pdev->dev);
5901
5902 priv = ieee80211_priv(dev);
5903// memset(priv,0,sizeof(struct r8180_priv));
5904 priv->pdev=pdev;
5905
5906
5907#ifdef CONFIG_RTL8180_IO_MAP
5908
5909 pio_start = (unsigned long)pci_resource_start (pdev, 0);
5910 pio_len = (unsigned long)pci_resource_len (pdev, 0);
5911 pio_flags = (unsigned long)pci_resource_flags (pdev, 0);
5912
5913 if (!(pio_flags & IORESOURCE_IO)) {
5914 DMESG("region #0 not a PIO resource, aborting");
5915 goto fail;
5916 }
5917
5918 //DMESG("IO space @ 0x%08lx", pio_start );
5919 if( ! request_region( pio_start, pio_len, RTL8180_MODULE_NAME ) ){
5920 DMESG("request_region failed!");
5921 goto fail;
5922 }
5923
5924 ioaddr = pio_start;
5925 dev->base_addr = ioaddr; // device I/O address
5926
5927#else
5928
5929 pmem_start = pci_resource_start(pdev, 1);
5930 pmem_len = pci_resource_len(pdev, 1);
5931 pmem_flags = pci_resource_flags (pdev, 1);
5932
5933 if (!(pmem_flags & IORESOURCE_MEM)) {
5934 DMESG("region #1 not a MMIO resource, aborting");
5935 goto fail;
5936 }
5937
5938 //DMESG("Memory mapped space @ 0x%08lx ", pmem_start);
5939 if( ! request_mem_region(pmem_start, pmem_len, RTL8180_MODULE_NAME)) {
5940 DMESG("request_mem_region failed!");
5941 goto fail;
5942 }
5943
5944
5945 ioaddr = (unsigned long)ioremap_nocache( pmem_start, pmem_len);
5946 if( ioaddr == (unsigned long)NULL ){
5947 DMESG("ioremap failed!");
5948 // release_mem_region( pmem_start, pmem_len );
5949 goto fail1;
5950 }
5951
5952 dev->mem_start = ioaddr; // shared mem start
5953 dev->mem_end = ioaddr + pci_resource_len(pdev, 0); // shared mem end
5954
5955#endif //end #ifdef RTL_IO_MAP
5956
5957#ifdef CONFIG_RTL8185B
5958 //pci_read_config_byte(pdev, 0x05, ptr);
5959 //pci_write_config_byte(pdev, 0x05, (*ptr) & (~0x04));
5960 pci_read_config_byte(pdev, 0x05, &unit);
5961 pci_write_config_byte(pdev, 0x05, unit & (~0x04));
5962#endif
5963
5964 dev->irq = pdev->irq;
5965 priv->irq = 0;
5966
5967 dev->open = rtl8180_open;
5968 dev->stop = rtl8180_close;
5969 //dev->hard_start_xmit = ieee80211_xmit;
5970 dev->tx_timeout = rtl8180_restart;
5971 dev->wireless_handlers = &r8180_wx_handlers_def;
5972 dev->do_ioctl = rtl8180_ioctl;
5973 dev->set_multicast_list = r8180_set_multicast;
5974 dev->set_mac_address = r8180_set_mac_adr;
5975
5976#if WIRELESS_EXT >= 12
5977#if WIRELESS_EXT < 17
5978 dev->get_wireless_stats = r8180_get_wireless_stats;
5979#endif
5980 dev->wireless_handlers = (struct iw_handler_def *) &r8180_wx_handlers_def;
5981#endif
5982
5983 dev->type=ARPHRD_ETHER;
5984 dev->watchdog_timeo = HZ*3; //added by david woo, 2007.12.13
5985
5986 if (dev_alloc_name(dev, ifname) < 0){
5987 DMESG("Oops: devname already taken! Trying wlan%%d...\n");
5988 ifname = "wlan%d";
5989 // ifname = "ath%d";
5990 dev_alloc_name(dev, ifname);
5991 }
5992
5993
5994 if(rtl8180_init(dev)!=0){
5995 DMESG("Initialization failed");
5996 goto fail1;
5997 }
5998
5999 netif_carrier_off(dev);
6000
6001 register_netdev(dev);
6002
6003 rtl8180_proc_init_one(dev);
6004
6005 DMESG("Driver probe completed\n");
6006 return 0;
6007
6008fail1:
6009
6010#ifdef CONFIG_RTL8180_IO_MAP
6011
6012 if( dev->base_addr != 0 ){
6013
6014 release_region(dev->base_addr,
6015 pci_resource_len(pdev, 0) );
6016 }
6017#else
6018 if( dev->mem_start != (unsigned long)NULL ){
6019 iounmap( (void *)dev->mem_start );
6020 release_mem_region( pci_resource_start(pdev, 1),
6021 pci_resource_len(pdev, 1) );
6022 }
6023#endif //end #ifdef RTL_IO_MAP
6024
6025
6026fail:
6027 if(dev){
6028
6029 if (priv->irq) {
6030 free_irq(dev->irq, dev);
6031 dev->irq=0;
6032 }
6033 free_ieee80211(dev);
6034 }
6035
6036 pci_disable_device(pdev);
6037
6038 DMESG("wlan driver load failed\n");
6039 pci_set_drvdata(pdev, NULL);
6040 return -ENODEV;
6041
6042}
6043
6044
6045static void __devexit rtl8180_pci_remove(struct pci_dev *pdev)
6046{
6047 struct r8180_priv *priv;
6048 struct net_device *dev = pci_get_drvdata(pdev);
6049 if(dev){
6050
6051 unregister_netdev(dev);
6052
6053 priv=ieee80211_priv(dev);
6054
6055 rtl8180_proc_remove_one(dev);
6056 rtl8180_down(dev);
6057 priv->rf_close(dev);
6058 rtl8180_reset(dev);
6059 //rtl8180_rtx_disable(dev);
6060 //rtl8180_irq_disable(dev);
6061 mdelay(10);
6062 //write_nic_word(dev,INTA,read_nic_word(dev,INTA));
6063 //force_pci_posting(dev);
6064 //mdelay(10);
6065
6066 if(priv->irq){
6067
6068 DMESG("Freeing irq %d",dev->irq);
6069 free_irq(dev->irq, dev);
6070 priv->irq=0;
6071
6072 }
6073
6074 free_rx_desc_ring(dev);
6075 free_tx_desc_rings(dev);
6076 // free_beacon_desc_ring(dev,priv->txbeaconcount);
6077
6078#ifdef CONFIG_RTL8180_IO_MAP
6079
6080 if( dev->base_addr != 0 ){
6081
6082 release_region(dev->base_addr,
6083 pci_resource_len(pdev, 0) );
6084 }
6085#else
6086 if( dev->mem_start != (unsigned long)NULL ){
6087 iounmap( (void *)dev->mem_start );
6088 release_mem_region( pci_resource_start(pdev, 1),
6089 pci_resource_len(pdev, 1) );
6090 }
6091#endif /*end #ifdef RTL_IO_MAP*/
6092
6093 free_ieee80211(dev);
6094 }
6095 pci_disable_device(pdev);
6096
6097 DMESG("wlan driver removed\n");
6098}
6099
6100
6101/* fun with the built-in ieee80211 stack... */
6102extern int ieee80211_crypto_init(void);
6103extern void ieee80211_crypto_deinit(void);
6104extern int ieee80211_crypto_tkip_init(void);
6105extern void ieee80211_crypto_tkip_exit(void);
6106extern int ieee80211_crypto_ccmp_init(void);
6107extern void ieee80211_crypto_ccmp_exit(void);
6108extern int ieee80211_crypto_wep_init(void);
6109extern void ieee80211_crypto_wep_exit(void);
6110
6111static int __init rtl8180_pci_module_init(void)
6112{
6113 int ret;
6114
6115 ret = ieee80211_crypto_init();
6116 if (ret) {
6117 printk(KERN_ERR "ieee80211_crypto_init() failed %d\n", ret);
6118 return ret;
6119 }
6120 ret = ieee80211_crypto_tkip_init();
6121 if (ret) {
6122 printk(KERN_ERR "ieee80211_crypto_tkip_init() failed %d\n", ret);
6123 return ret;
6124 }
6125 ret = ieee80211_crypto_ccmp_init();
6126 if (ret) {
6127 printk(KERN_ERR "ieee80211_crypto_ccmp_init() failed %d\n", ret);
6128 return ret;
6129 }
6130 ret = ieee80211_crypto_wep_init();
6131 if (ret) {
6132 printk(KERN_ERR "ieee80211_crypto_wep_init() failed %d\n", ret);
6133 return ret;
6134 }
6135
6136 printk(KERN_INFO "\nLinux kernel driver for RTL8180 \
6137/ RTL8185 based WLAN cards\n");
6138 printk(KERN_INFO "Copyright (c) 2004-2005, Andrea Merello\n");
6139 DMESG("Initializing module");
6140 DMESG("Wireless extensions version %d", WIRELESS_EXT);
6141 rtl8180_proc_module_init();
6142
6143#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22))
6144 if(0!=pci_module_init(&rtl8180_pci_driver))
6145#else
6146 if(0!=pci_register_driver(&rtl8180_pci_driver))
6147#endif
6148 //if(0!=pci_module_init(&rtl8180_pci_driver))
6149 {
6150 DMESG("No device found");
6151 /*pci_unregister_driver (&rtl8180_pci_driver);*/
6152 return -ENODEV;
6153 }
6154 return 0;
6155}
6156
6157
6158static void __exit rtl8180_pci_module_exit(void)
6159{
6160 pci_unregister_driver (&rtl8180_pci_driver);
6161 rtl8180_proc_module_remove();
6162 ieee80211_crypto_deinit();
6163 ieee80211_crypto_tkip_exit();
6164 ieee80211_crypto_ccmp_exit();
6165 ieee80211_crypto_wep_exit();
6166 DMESG("Exiting");
6167}
6168
6169
6170void rtl8180_try_wake_queue(struct net_device *dev, int pri)
6171{
6172 unsigned long flags;
6173 short enough_desc;
6174 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
6175
6176 spin_lock_irqsave(&priv->tx_lock,flags);
6177 enough_desc = check_nic_enought_desc(dev,pri);
6178 spin_unlock_irqrestore(&priv->tx_lock,flags);
6179
6180 if(enough_desc)
6181 ieee80211_wake_queue(priv->ieee80211);
6182}
6183
6184/*****************************************************************************
6185 -----------------------------IRQ STUFF---------------------------
6186******************************************************************************/
6187
6188void rtl8180_tx_isr(struct net_device *dev, int pri,short error)
6189{
6190 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
6191
6192 u32 *tail; //tail virtual addr
6193 u32 *head; //head virtual addr
6194 u32 *begin;//start of ring virtual addr
6195 u32 *nicv; //nic pointer virtual addr
6196// u32 *txdv; //packet just TXed
6197 u32 nic; //nic pointer physical addr
6198 u32 nicbegin;// start of ring physical addr
6199// short txed;
6200 unsigned long flag;
6201 /* physical addr are ok on 32 bits since we set DMA mask*/
6202
6203 int offs;
6204 int j,i;
6205 int hd;
6206 if (error) priv->stats.txretry++; //tony 20060601
6207 spin_lock_irqsave(&priv->tx_lock,flag);
6208 switch(pri) {
6209 case MANAGE_PRIORITY:
6210 tail = priv->txmapringtail;
6211 begin = priv->txmapring;
6212 head = priv->txmapringhead;
6213 nic = read_nic_dword(dev,TX_MANAGEPRIORITY_RING_ADDR);
6214 nicbegin = priv->txmapringdma;
6215 break;
6216
6217 case BK_PRIORITY:
6218 tail = priv->txbkpringtail;
6219 begin = priv->txbkpring;
6220 head = priv->txbkpringhead;
6221 nic = read_nic_dword(dev,TX_BKPRIORITY_RING_ADDR);
6222 nicbegin = priv->txbkpringdma;
6223 break;
6224
6225 case BE_PRIORITY:
6226 tail = priv->txbepringtail;
6227 begin = priv->txbepring;
6228 head = priv->txbepringhead;
6229 nic = read_nic_dword(dev,TX_BEPRIORITY_RING_ADDR);
6230 nicbegin = priv->txbepringdma;
6231 break;
6232
6233 case VI_PRIORITY:
6234 tail = priv->txvipringtail;
6235 begin = priv->txvipring;
6236 head = priv->txvipringhead;
6237 nic = read_nic_dword(dev,TX_VIPRIORITY_RING_ADDR);
6238 nicbegin = priv->txvipringdma;
6239 break;
6240
6241 case VO_PRIORITY:
6242 tail = priv->txvopringtail;
6243 begin = priv->txvopring;
6244 head = priv->txvopringhead;
6245 nic = read_nic_dword(dev,TX_VOPRIORITY_RING_ADDR);
6246 nicbegin = priv->txvopringdma;
6247 break;
6248
6249 case HI_PRIORITY:
6250 tail = priv->txhpringtail;
6251 begin = priv->txhpring;
6252 head = priv->txhpringhead;
6253 nic = read_nic_dword(dev,TX_HIGHPRIORITY_RING_ADDR);
6254 nicbegin = priv->txhpringdma;
6255 break;
6256
6257 default:
6258 spin_unlock_irqrestore(&priv->tx_lock,flag);
6259 return ;
6260 }
6261/* DMESG("%x %s %x %x",((int)nic & 0xfff)/8/4,
6262 *(priv->txnpring + ((int)nic&0xfff)/4/8) & (1<<31) ? "filled" : "empty",
6263 (priv->txnpringtail - priv->txnpring)/8,(priv->txnpringhead -
6264priv->txnpring)/8);
6265*/
6266 //nicv = (u32*) ((nic - nicbegin) + (int)begin);
6267 nicv = (u32*) ((nic - nicbegin) + (u8*)begin);
6268 if((head <= tail && (nicv > tail || nicv < head)) ||
6269 (head > tail && (nicv > tail && nicv < head))){
6270
6271 DMESGW("nic has lost pointer");
6272#ifdef DEBUG_TX_DESC
6273 //check_tx_ring(dev,NORM_PRIORITY);
6274 check_tx_ring(dev,pri);
6275#endif
6276 spin_unlock_irqrestore(&priv->tx_lock,flag);
6277 rtl8180_restart(dev);
6278 return;
6279 }
6280
6281 /* we check all the descriptors between the head and the nic,
6282 * but not the currenly pointed by the nic (the next to be txed)
6283 * and the previous of the pointed (might be in process ??)
6284 */
6285 //if (head == nic) return;
6286 //DMESG("%x %x",head,nic);
6287 offs = (nic - nicbegin);
6288 //DMESG("%x %x %x",nic ,(u32)nicbegin, (int)nic -nicbegin);
6289
6290 offs = offs / 8 /4;
6291
6292 hd = (head - begin) /8;
6293
6294 if(offs >= hd)
6295 j = offs - hd;
6296 else
6297 j = offs + (priv->txringcount -1 -hd);
6298 // j= priv->txringcount -1- (hd - offs);
6299
6300 j-=2;
6301 if(j<0) j=0;
6302
6303
6304 for(i=0;i<j;i++)
6305 {
6306// printk("+++++++++++++check status desc\n");
6307 if((*head) & (1<<31))
6308 break;
6309 if(((*head)&(0x10000000)) != 0){
6310// printk("++++++++++++++last desc,retry count is %d\n",((*head) & (0x000000ff)));
6311 priv->CurrRetryCnt += (u16)((*head) & (0x000000ff));
6312#if 1
6313 if(!error)
6314 {
6315 priv->NumTxOkTotal++;
6316// printk("NumTxOkTotal is %d\n",priv->NumTxOkTotal++);
6317 }
6318#endif
6319 // printk("in function %s:curr_retry_count is %d\n",__FUNCTION__,((*head) & (0x000000ff)));
6320 }
6321 if(!error){
6322 priv->NumTxOkBytesTotal += (*(head+3)) & (0x00000fff);
6323 }
6324// printk("in function %s:curr_txokbyte_count is %d\n",__FUNCTION__,(*(head+3)) & (0x00000fff));
6325 *head = *head &~ (1<<31);
6326
6327 if((head - begin)/8 == priv->txringcount-1)
6328 head=begin;
6329
6330 else
6331 head+=8;
6332 }
6333#if 0
6334 if(nicv == begin)
6335 txdv = begin + (priv->txringcount -1)*8;
6336 else
6337 txdv = nicv - 8;
6338
6339 txed = !(txdv[0] &(1<<31));
6340
6341 if(txed){
6342 if(!(txdv[0] & (1<<15))) error = 1;
6343 //if(!(txdv[0] & (1<<30))) error = 1;
6344 if(error)DMESG("%x",txdv[0]);
6345 }
6346#endif
6347 //DMESG("%x",txdv[0]);
6348 /* the head has been moved to the last certainly TXed
6349 * (or at least processed by the nic) packet.
6350 * The driver take forcefully owning of all these packets
6351 * If the packet previous of the nic pointer has been
6352 * processed this doesn't matter: it will be checked
6353 * here at the next round. Anyway if no more packet are
6354 * TXed no memory leak occour at all.
6355 */
6356
6357 switch(pri) {
6358 case MANAGE_PRIORITY:
6359 priv->txmapringhead = head;
6360 //printk("1==========================================> priority check!\n");
6361 if(priv->ack_tx_to_ieee){
6362 // try to implement power-save mode 2008.1.22
6363 // printk("2==========================================> priority check!\n");
6364#if 1
6365 if(rtl8180_is_tx_queue_empty(dev)){
6366 // printk("tx queue empty, after send null sleep packet, try to sleep !\n");
6367 priv->ack_tx_to_ieee = 0;
6368 ieee80211_ps_tx_ack(priv->ieee80211,!error);
6369 }
6370#endif
6371 }
6372 break;
6373
6374 case BK_PRIORITY:
6375 priv->txbkpringhead = head;
6376 break;
6377
6378 case BE_PRIORITY:
6379 priv->txbepringhead = head;
6380 break;
6381
6382 case VI_PRIORITY:
6383 priv->txvipringhead = head;
6384 break;
6385
6386 case VO_PRIORITY:
6387 priv->txvopringhead = head;
6388 break;
6389
6390 case HI_PRIORITY:
6391 priv->txhpringhead = head;
6392 break;
6393 }
6394
6395 /*DMESG("%x %x %x", (priv->txnpringhead - priv->txnpring) /8 ,
6396 (priv->txnpringtail - priv->txnpring) /8,
6397 offs );
6398 */
6399
6400 spin_unlock_irqrestore(&priv->tx_lock,flag);
6401
6402}
6403
6404#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
6405void rtl8180_tx_irq_wq(struct work_struct *work)
6406{
6407 //struct r8180_priv *priv = container_of(work, struct r8180_priv, reset_wq);
6408 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
6409 struct ieee80211_device * ieee = (struct ieee80211_device*)
6410 container_of(dwork, struct ieee80211_device, watch_dog_wq);
6411 struct net_device *dev = ieee->dev;
6412#else
6413void rtl8180_tx_irq_wq(struct net_device *dev)
6414{
6415 //struct r8180_priv *priv = ieee80211_priv(dev);
6416#endif
6417 rtl8180_tx_isr(dev,MANAGE_PRIORITY,0);
6418}
6419irqreturn_t rtl8180_interrupt(int irq, void *netdev, struct pt_regs *regs)
6420{
6421 struct net_device *dev = (struct net_device *) netdev;
6422 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
6423 unsigned long flags;
6424 u32 inta;
6425
6426 /* We should return IRQ_NONE, but for now let me keep this */
6427 if(priv->irq_enabled == 0) return IRQ_HANDLED;
6428
6429 spin_lock_irqsave(&priv->irq_th_lock,flags);
6430
6431#ifdef CONFIG_RTL8185B
6432 //ISR: 4bytes
6433 inta = read_nic_dword(dev, ISR);// & priv->IntrMask;
6434 write_nic_dword(dev,ISR,inta); // reset int situation
6435#else
6436 inta = read_nic_word(dev,INTA) & priv->irq_mask;
6437 write_nic_word(dev,INTA,inta); // reset int situation
6438#endif
6439
6440 priv->stats.shints++;
6441
6442 //DMESG("Enter interrupt, ISR value = 0x%08x", inta);
6443
6444 if(!inta){
6445 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
6446 return IRQ_HANDLED;
6447 /*
6448 most probably we can safely return IRQ_NONE,
6449 but for now is better to avoid problems
6450 */
6451 }
6452
6453 if(inta == 0xffff){
6454 /* HW disappared */
6455 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
6456 return IRQ_HANDLED;
6457 }
6458
6459 priv->stats.ints++;
6460#ifdef DEBUG_IRQ
6461 DMESG("NIC irq %x",inta);
6462#endif
6463 //priv->irqpending = inta;
6464
6465
6466 if(!netif_running(dev)) {
6467 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
6468 return IRQ_HANDLED;
6469 }
6470
6471 if(inta & ISR_TimeOut){
6472 write_nic_dword(dev, TimerInt, 0);
6473 //DMESG("=================>waking up");
6474// rtl8180_hw_wakeup(dev);
6475 }
6476
6477 if(inta & ISR_TBDOK){
6478 priv->stats.txbeacon++;
6479 }
6480
6481 if(inta & ISR_TBDER){
6482 priv->stats.txbeaconerr++;
6483 }
6484
6485 if(inta & IMR_TMGDOK ) {
6486// priv->NumTxOkTotal++;
6487 rtl8180_tx_isr(dev,MANAGE_PRIORITY,0);
6488// schedule_work(&priv->tx_irq_wq);
6489
6490 }
6491
6492 if(inta & ISR_THPDER){
6493#ifdef DEBUG_TX
6494 DMESG ("TX high priority ERR");
6495#endif
6496 priv->stats.txhperr++;
6497 rtl8180_tx_isr(dev,HI_PRIORITY,1);
6498 priv->ieee80211->stats.tx_errors++;
6499 }
6500
6501 if(inta & ISR_THPDOK){ //High priority tx ok
6502#ifdef DEBUG_TX
6503 DMESG ("TX high priority OK");
6504#endif
6505// priv->NumTxOkTotal++;
6506 //priv->NumTxOkInPeriod++; //YJ,del,080828
6507 priv->link_detect.NumTxOkInPeriod++; //YJ,add,080828
6508 priv->stats.txhpokint++;
6509 rtl8180_tx_isr(dev,HI_PRIORITY,0);
6510 }
6511
6512 if(inta & ISR_RER) {
6513 priv->stats.rxerr++;
6514#ifdef DEBUG_RX
6515 DMESGW("RX error int");
6516#endif
6517 }
6518#ifdef CONFIG_RTL8185B
6519 if(inta & ISR_TBKDER){ //corresponding to BK_PRIORITY
6520 priv->stats.txbkperr++;
6521 priv->ieee80211->stats.tx_errors++;
6522#ifdef DEBUG_TX
6523 DMESGW("TX bkp error int");
6524#endif
6525 //tasklet_schedule(&priv->irq_tx_tasklet);
6526 rtl8180_tx_isr(dev,BK_PRIORITY,1);
6527 rtl8180_try_wake_queue(dev, BE_PRIORITY);
6528 }
6529
6530 if(inta & ISR_TBEDER){ //corresponding to BE_PRIORITY
6531 priv->stats.txbeperr++;
6532 priv->ieee80211->stats.tx_errors++;
6533#ifdef DEBUG_TX
6534 DMESGW("TX bep error int");
6535#endif
6536 rtl8180_tx_isr(dev,BE_PRIORITY,1);
6537 //tasklet_schedule(&priv->irq_tx_tasklet);
6538 rtl8180_try_wake_queue(dev, BE_PRIORITY);
6539 }
6540#endif
6541 if(inta & ISR_TNPDER){ //corresponding to VO_PRIORITY
6542 priv->stats.txnperr++;
6543 priv->ieee80211->stats.tx_errors++;
6544#ifdef DEBUG_TX
6545 DMESGW("TX np error int");
6546#endif
6547 //tasklet_schedule(&priv->irq_tx_tasklet);
6548 rtl8180_tx_isr(dev,NORM_PRIORITY,1);
6549#ifdef CONFIG_RTL8185B
6550 rtl8180_try_wake_queue(dev, NORM_PRIORITY);
6551#endif
6552 }
6553
6554 if(inta & ISR_TLPDER){ //corresponding to VI_PRIORITY
6555 priv->stats.txlperr++;
6556 priv->ieee80211->stats.tx_errors++;
6557#ifdef DEBUG_TX
6558 DMESGW("TX lp error int");
6559#endif
6560 rtl8180_tx_isr(dev,LOW_PRIORITY,1);
6561 //tasklet_schedule(&priv->irq_tx_tasklet);
6562 rtl8180_try_wake_queue(dev, LOW_PRIORITY);
6563 }
6564
6565 if(inta & ISR_ROK){
6566#ifdef DEBUG_RX
6567 DMESG("Frame arrived !");
6568#endif
6569 //priv->NumRxOkInPeriod++; //YJ,del,080828
6570 priv->stats.rxint++;
6571 tasklet_schedule(&priv->irq_rx_tasklet);
6572 }
6573
6574 if(inta & ISR_RQoSOK ){
6575#ifdef DEBUG_RX
6576 DMESG("QoS Frame arrived !");
6577#endif
6578 //priv->NumRxOkInPeriod++; //YJ,del,080828
6579 priv->stats.rxint++;
6580 tasklet_schedule(&priv->irq_rx_tasklet);
6581 }
6582 if(inta & ISR_BcnInt) {
6583 //DMESG("Preparing Beacons");
6584 rtl8180_prepare_beacon(dev);
6585 }
6586
6587 if(inta & ISR_RDU){
6588//#ifdef DEBUG_RX
6589 DMESGW("No RX descriptor available");
6590 priv->stats.rxrdu++;
6591//#endif
6592 tasklet_schedule(&priv->irq_rx_tasklet);
6593 /*queue_work(priv->workqueue ,&priv->restart_work);*/
6594
6595 }
6596 if(inta & ISR_RXFOVW){
6597#ifdef DEBUG_RX
6598 DMESGW("RX fifo overflow");
6599#endif
6600 priv->stats.rxoverflow++;
6601 tasklet_schedule(&priv->irq_rx_tasklet);
6602 //queue_work(priv->workqueue ,&priv->restart_work);
6603 }
6604
6605 if(inta & ISR_TXFOVW) priv->stats.txoverflow++;
6606
6607 if(inta & ISR_TNPDOK){ //Normal priority tx ok
6608#ifdef DEBUG_TX
6609 DMESG ("TX normal priority OK");
6610#endif
6611// priv->NumTxOkTotal++;
6612 //priv->NumTxOkInPeriod++; //YJ,del,080828
6613 priv->link_detect.NumTxOkInPeriod++; //YJ,add,080828
6614 // priv->ieee80211->stats.tx_packets++;
6615 priv->stats.txnpokint++;
6616 rtl8180_tx_isr(dev,NORM_PRIORITY,0);
6617 }
6618
6619 if(inta & ISR_TLPDOK){ //Low priority tx ok
6620#ifdef DEBUG_TX
6621 DMESG ("TX low priority OK");
6622#endif
6623// priv->NumTxOkTotal++;
6624 //priv->NumTxOkInPeriod++; //YJ,del,080828
6625 priv->link_detect.NumTxOkInPeriod++; //YJ,add,080828
6626 // priv->ieee80211->stats.tx_packets++;
6627 priv->stats.txlpokint++;
6628 rtl8180_tx_isr(dev,LOW_PRIORITY,0);
6629 rtl8180_try_wake_queue(dev, LOW_PRIORITY);
6630 }
6631
6632#ifdef CONFIG_RTL8185B
6633 if(inta & ISR_TBKDOK){ //corresponding to BK_PRIORITY
6634 priv->stats.txbkpokint++;
6635#ifdef DEBUG_TX
6636 DMESGW("TX bk priority ok");
6637#endif
6638// priv->NumTxOkTotal++;
6639 //priv->NumTxOkInPeriod++; //YJ,del,080828
6640 priv->link_detect.NumTxOkInPeriod++; //YJ,add,080828
6641 rtl8180_tx_isr(dev,BK_PRIORITY,0);
6642 rtl8180_try_wake_queue(dev, BE_PRIORITY);
6643 }
6644
6645 if(inta & ISR_TBEDOK){ //corresponding to BE_PRIORITY
6646 priv->stats.txbeperr++;
6647#ifdef DEBUG_TX
6648 DMESGW("TX be priority ok");
6649#endif
6650// priv->NumTxOkTotal++;
6651 //priv->NumTxOkInPeriod++; //YJ,del,080828
6652 priv->link_detect.NumTxOkInPeriod++; //YJ,add,080828
6653 rtl8180_tx_isr(dev,BE_PRIORITY,0);
6654 rtl8180_try_wake_queue(dev, BE_PRIORITY);
6655 }
6656#endif
6657 force_pci_posting(dev);
6658 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
6659
6660 return IRQ_HANDLED;
6661}
6662
6663
6664void rtl8180_irq_rx_tasklet(struct r8180_priv* priv)
6665{
6666// unsigned long flags;
6667
6668/* spin_lock_irqsave(&priv->irq_lock, flags);
6669 priv->irq_mask &=~IMR_ROK;
6670 priv->irq_mask &=~IMR_RDU;
6671
6672 rtl8180_irq_enable(priv->dev);
6673 spin_unlock_irqrestore(&priv->irq_lock, flags);
6674*/
6675 rtl8180_rx(priv->dev);
6676
6677/* spin_lock_irqsave(&priv->irq_lock, flags);
6678 priv->irq_mask |= IMR_ROK;
6679 priv->irq_mask |= IMR_RDU;
6680 rtl8180_irq_enable(priv->dev);
6681 spin_unlock_irqrestore(&priv->irq_lock, flags);
6682*/
6683}
6684
6685/****************************************************************************
6686lizhaoming--------------------------- RF power on/power off -----------------
6687*****************************************************************************/
6688
6689#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
6690void GPIOChangeRFWorkItemCallBack(struct work_struct *work)
6691{
6692 //struct delayed_work *dwork = container_of(work, struct delayed_work, work);
6693 struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, GPIOChangeRFWorkItem.work);
6694 struct net_device *dev = ieee->dev;
6695 struct r8180_priv *priv = ieee80211_priv(dev);
6696#else
6697void GPIOChangeRFWorkItemCallBack(struct ieee80211_device *ieee)
6698{
6699 struct net_device *dev = ieee->dev;
6700 struct r8180_priv *priv = ieee80211_priv(dev);
6701#endif
6702
6703 //u16 tmp2byte;
6704 u8 btPSR;
6705 u8 btConfig0;
6706 RT_RF_POWER_STATE eRfPowerStateToSet;
6707 bool bActuallySet=false;
6708
6709 char *argv[3];
6710 static char *RadioPowerPath = "/etc/acpi/events/RadioPower.sh";
6711 static char *envp[] = {"HOME=/", "TERM=linux", "PATH=/usr/bin:/bin", NULL};
6712 static int readf_count = 0;
6713 //printk("============>%s in \n", __func__);
6714
6715#ifdef ENABLE_LPS
6716 if(readf_count % 10 == 0)
6717 priv->PowerProfile = read_acadapter_file("/proc/acpi/ac_adapter/AC0/state");
6718
6719 readf_count = (readf_count+1)%0xffff;
6720#endif
6721#if 0
6722 if(priv->up == 0)//driver stopped
6723 {
6724 printk("\nDo nothing...");
6725 goto out;
6726 }
6727 else
6728#endif
6729 {
6730 // We should turn off LED before polling FF51[4].
6731
6732 //Turn off LED.
6733 btPSR = read_nic_byte(dev, PSR);
6734 write_nic_byte(dev, PSR, (btPSR & ~BIT3));
6735
6736 //It need to delay 4us suggested by Jong, 2008-01-16
6737 udelay(4);
6738
6739 //HW radio On/Off according to the value of FF51[4](config0)
6740 btConfig0 = btPSR = read_nic_byte(dev, CONFIG0);
6741
6742 //Turn on LED.
6743 write_nic_byte(dev, PSR, btPSR| BIT3);
6744
6745 eRfPowerStateToSet = (btConfig0 & BIT4) ? eRfOn : eRfOff;
6746
6747 if((priv->ieee80211->bHwRadioOff == true) && (eRfPowerStateToSet == eRfOn))
6748 {
6749 priv->ieee80211->bHwRadioOff = false;
6750 bActuallySet = true;
6751 }
6752 else if((priv->ieee80211->bHwRadioOff == false) && (eRfPowerStateToSet == eRfOff))
6753 {
6754 priv->ieee80211->bHwRadioOff = true;
6755 bActuallySet = true;
6756 }
6757
6758 if(bActuallySet)
6759 {
6760 MgntActSet_RF_State(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW);
6761
6762 /* To update the UI status for Power status changed */
6763 if(priv->ieee80211->bHwRadioOff == true)
6764 argv[1] = "RFOFF";
6765 else{
6766 //if(!priv->RfOffReason)
6767 argv[1] = "RFON";
6768 //else
6769 // argv[1] = "RFOFF";
6770 }
6771 argv[0] = RadioPowerPath;
6772 argv[2] = NULL;
6773
6774 call_usermodehelper(RadioPowerPath,argv,envp,1);
6775 }
6776
6777 }
6778
6779}
6780
6781static u8 read_acadapter_file(char *filename)
6782{
6783//#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))
6784#if 0
6785 int fd;
6786 char buf[1];
6787 char ret[50];
6788 int i = 0;
6789 int n = 0;
6790 mm_segment_t old_fs = get_fs();
6791 set_fs(KERNEL_DS);
6792
6793 fd = sys_open(filename, O_RDONLY, 0);
6794 if (fd >= 0) {
6795 while (sys_read(fd, buf, 1) == 1)
6796 {
6797 i++;
6798 if(i>10)
6799 {
6800 if(buf[0]!=' ')
6801 {
6802 ret[n]=buf[0];
6803 n++;
6804 }
6805 }
6806 }
6807 sys_close(fd);
6808 }
6809 ret[n]='\0';
6810// printk("%s \n", ret);
6811 set_fs(old_fs);
6812
6813 if(strncmp(ret, "off-line",8) == 0)
6814 {
6815 return 1;
6816 }
6817#endif
6818 return 0;
6819}
6820
6821/***************************************************************************
6822 ------------------- module init / exit stubs ----------------
6823****************************************************************************/
6824module_init(rtl8180_pci_module_init);
6825module_exit(rtl8180_pci_module_exit);
6826
diff --git a/drivers/staging/rtl8187se/r8180_dm.c b/drivers/staging/rtl8187se/r8180_dm.c
new file mode 100644
index 000000000000..742dc11fcac9
--- /dev/null
+++ b/drivers/staging/rtl8187se/r8180_dm.c
@@ -0,0 +1,1725 @@
1//#include "r8180.h"
2#include "r8180_dm.h"
3#include "r8180_hw.h"
4#include "r8180_93cx6.h"
5//{by amy 080312
6
7//
8// Description:
9// Return TRUE if we shall perform High Power Mecahnism, FALSE otherwise.
10//
11//+by amy 080312
12#define RATE_ADAPTIVE_TIMER_PERIOD 300
13
14bool CheckHighPower(struct net_device *dev)
15{
16 struct r8180_priv *priv = ieee80211_priv(dev);
17 struct ieee80211_device *ieee = priv->ieee80211;
18
19 if(!priv->bRegHighPowerMechanism)
20 {
21 return false;
22 }
23
24 if(ieee->state == IEEE80211_LINKED_SCANNING)
25 {
26 return false;
27 }
28
29 return true;
30}
31
32//
33// Description:
34// Update Tx power level if necessary.
35// See also DoRxHighPower() and SetTxPowerLevel8185() for reference.
36//
37// Note:
38// The reason why we udpate Tx power level here instead of DoRxHighPower()
39// is the number of IO to change Tx power is much more than chane TR switch
40// and they are related to OFDM and MAC registers.
41// So, we don't want to update it so frequently in per-Rx packet base.
42//
43void
44DoTxHighPower(
45 struct net_device *dev
46 )
47{
48 struct r8180_priv *priv = ieee80211_priv(dev);
49 u16 HiPwrUpperTh = 0;
50 u16 HiPwrLowerTh = 0;
51 u8 RSSIHiPwrUpperTh;
52 u8 RSSIHiPwrLowerTh;
53 u8 u1bTmp;
54 char OfdmTxPwrIdx, CckTxPwrIdx;
55
56 //printk("----> DoTxHighPower()\n");
57
58 HiPwrUpperTh = priv->RegHiPwrUpperTh;
59 HiPwrLowerTh = priv->RegHiPwrLowerTh;
60
61 HiPwrUpperTh = HiPwrUpperTh * 10;
62 HiPwrLowerTh = HiPwrLowerTh * 10;
63 RSSIHiPwrUpperTh = priv->RegRSSIHiPwrUpperTh;
64 RSSIHiPwrLowerTh = priv->RegRSSIHiPwrLowerTh;
65
66 //lzm add 080826
67 OfdmTxPwrIdx = priv->chtxpwr_ofdm[priv->ieee80211->current_network.channel];
68 CckTxPwrIdx = priv->chtxpwr[priv->ieee80211->current_network.channel];
69
70 // printk("DoTxHighPower() - UndecoratedSmoothedSS:%d, CurCCKRSSI = %d , bCurCCKPkt= %d \n", priv->UndecoratedSmoothedSS, priv->CurCCKRSSI, priv->bCurCCKPkt );
71
72 if((priv->UndecoratedSmoothedSS > HiPwrUpperTh) ||
73 (priv->bCurCCKPkt && (priv->CurCCKRSSI > RSSIHiPwrUpperTh)))
74 {
75 // Stevenl suggested that degrade 8dbm in high power sate. 2007-12-04 Isaiah
76
77 // printk("=====>DoTxHighPower() - High Power - UndecoratedSmoothedSS:%d, HiPwrUpperTh = %d \n", priv->UndecoratedSmoothedSS, HiPwrUpperTh );
78 priv->bToUpdateTxPwr = true;
79 u1bTmp= read_nic_byte(dev, CCK_TXAGC);
80
81 // If it never enter High Power.
82 if( CckTxPwrIdx == u1bTmp)
83 {
84 u1bTmp = (u1bTmp > 16) ? (u1bTmp -16): 0; // 8dbm
85 write_nic_byte(dev, CCK_TXAGC, u1bTmp);
86
87 u1bTmp= read_nic_byte(dev, OFDM_TXAGC);
88 u1bTmp = (u1bTmp > 16) ? (u1bTmp -16): 0; // 8dbm
89 write_nic_byte(dev, OFDM_TXAGC, u1bTmp);
90 }
91
92 }
93 else if((priv->UndecoratedSmoothedSS < HiPwrLowerTh) &&
94 (!priv->bCurCCKPkt || priv->CurCCKRSSI < RSSIHiPwrLowerTh))
95 {
96 // printk("DoTxHighPower() - lower Power - UndecoratedSmoothedSS:%d, HiPwrUpperTh = %d \n", priv->UndecoratedSmoothedSS, HiPwrLowerTh );
97 if(priv->bToUpdateTxPwr)
98 {
99 priv->bToUpdateTxPwr = false;
100 //SD3 required.
101 u1bTmp= read_nic_byte(dev, CCK_TXAGC);
102 if(u1bTmp < CckTxPwrIdx)
103 {
104 //u1bTmp = ((u1bTmp+16) > 35) ? 35: (u1bTmp+16); // 8dbm
105 //write_nic_byte(dev, CCK_TXAGC, u1bTmp);
106 write_nic_byte(dev, CCK_TXAGC, CckTxPwrIdx);
107 }
108
109 u1bTmp= read_nic_byte(dev, OFDM_TXAGC);
110 if(u1bTmp < OfdmTxPwrIdx)
111 {
112 //u1bTmp = ((u1bTmp+16) > 35) ? 35: (u1bTmp+16); // 8dbm
113 //write_nic_byte(dev, OFDM_TXAGC, u1bTmp);
114 write_nic_byte(dev, OFDM_TXAGC, OfdmTxPwrIdx);
115 }
116 }
117 }
118
119 //printk("<---- DoTxHighPower()\n");
120}
121
122
123//
124// Description:
125// Callback function of UpdateTxPowerWorkItem.
126// Because of some event happend, e.g. CCX TPC, High Power Mechanism,
127// We update Tx power of current channel again.
128//
129#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
130void rtl8180_tx_pw_wq (struct work_struct *work)
131{
132// struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
133// struct ieee80211_device * ieee = (struct ieee80211_device*)
134// container_of(work, struct ieee80211_device, watch_dog_wq);
135 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
136 struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,tx_pw_wq);
137 struct net_device *dev = ieee->dev;
138#else
139void rtl8180_tx_pw_wq(struct net_device *dev)
140{
141 // struct r8180_priv *priv = ieee80211_priv(dev);
142#endif
143
144// printk("----> UpdateTxPowerWorkItemCallback()\n");
145
146 DoTxHighPower(dev);
147
148// printk("<---- UpdateTxPowerWorkItemCallback()\n");
149}
150
151
152//
153// Description:
154// Return TRUE if we shall perform DIG Mecahnism, FALSE otherwise.
155//
156bool
157CheckDig(
158 struct net_device *dev
159 )
160{
161 struct r8180_priv *priv = ieee80211_priv(dev);
162 struct ieee80211_device *ieee = priv->ieee80211;
163
164 if(!priv->bDigMechanism)
165 return false;
166
167 if(ieee->state != IEEE80211_LINKED)
168 return false;
169
170 //if(priv->CurrentOperaRate < 36) // Schedule Dig under all OFDM rates. By Bruce, 2007-06-01.
171 if((priv->ieee80211->rate/5) < 36) // Schedule Dig under all OFDM rates. By Bruce, 2007-06-01.
172 return false;
173 return true;
174}
175//
176// Description:
177// Implementation of DIG for Zebra and Zebra2.
178//
179void
180DIG_Zebra(
181 struct net_device *dev
182 )
183{
184 struct r8180_priv *priv = ieee80211_priv(dev);
185 u16 CCKFalseAlarm, OFDMFalseAlarm;
186 u16 OfdmFA1, OfdmFA2;
187 int InitialGainStep = 7; // The number of initial gain stages.
188 int LowestGainStage = 4; // The capable lowest stage of performing dig workitem.
189 u32 AwakePeriodIn2Sec=0;
190
191 //printk("---------> DIG_Zebra()\n");
192
193 CCKFalseAlarm = (u16)(priv->FalseAlarmRegValue & 0x0000ffff);
194 OFDMFalseAlarm = (u16)((priv->FalseAlarmRegValue >> 16) & 0x0000ffff);
195 OfdmFA1 = 0x15;
196 OfdmFA2 = ((u16)(priv->RegDigOfdmFaUpTh)) << 8;
197
198// printk("DIG**********CCK False Alarm: %#X \n",CCKFalseAlarm);
199// printk("DIG**********OFDM False Alarm: %#X \n",OFDMFalseAlarm);
200
201 // The number of initial gain steps is different, by Bruce, 2007-04-13.
202 if (priv->InitialGain == 0 ) //autoDIG
203 { // Advised from SD3 DZ
204 priv->InitialGain = 4; // In 87B, m74dBm means State 4 (m82dBm)
205 }
206 //if(pHalData->VersionID != VERSION_8187B_B)
207 { // Advised from SD3 DZ
208 OfdmFA1 = 0x20;
209 }
210
211#if 1 //lzm reserved 080826
212 AwakePeriodIn2Sec = (2000-priv ->DozePeriodInPast2Sec);
213 //printk("&&& DozePeriod=%d AwakePeriod=%d\n", priv->DozePeriodInPast2Sec, AwakePeriodIn2Sec);
214 priv ->DozePeriodInPast2Sec=0;
215
216 if(AwakePeriodIn2Sec)
217 {
218 //RT_TRACE(COMP_DIG, DBG_TRACE, ("DIG: AwakePeriodIn2Sec(%d) - FATh(0x%X , 0x%X) ->",AwakePeriodIn2Sec, OfdmFA1, OfdmFA2));
219 // adjuest DIG threshold.
220 OfdmFA1 = (u16)((OfdmFA1*AwakePeriodIn2Sec) / 2000) ;
221 OfdmFA2 = (u16)((OfdmFA2*AwakePeriodIn2Sec) / 2000) ;
222 //RT_TRACE(COMP_DIG, DBG_TRACE, ("( 0x%X , 0x%X)\n", OfdmFA1, OfdmFA2));
223 }
224 else
225 {
226 ;//RT_TRACE(COMP_DIG, DBG_WARNING, ("ERROR!! AwakePeriodIn2Sec should not be ZERO!!\n"));
227 }
228#endif
229
230 InitialGainStep = 8;
231 LowestGainStage = priv->RegBModeGainStage; // Lowest gain stage.
232
233 if (OFDMFalseAlarm > OfdmFA1)
234 {
235 if (OFDMFalseAlarm > OfdmFA2)
236 {
237 priv->DIG_NumberFallbackVote++;
238 if (priv->DIG_NumberFallbackVote >1)
239 {
240 //serious OFDM False Alarm, need fallback
241 if (priv->InitialGain < InitialGainStep)
242 {
243 priv->InitialGainBackUp= priv->InitialGain;
244
245 priv->InitialGain = (priv->InitialGain + 1);
246// printk("DIG**********OFDM False Alarm: %#X, OfdmFA1: %#X, OfdmFA2: %#X\n", OFDMFalseAlarm, OfdmFA1, OfdmFA2);
247// printk("DIG+++++++ fallback OFDM:%d \n", priv->InitialGain);
248 UpdateInitialGain(dev);
249 }
250 priv->DIG_NumberFallbackVote = 0;
251 priv->DIG_NumberUpgradeVote=0;
252 }
253 }
254 else
255 {
256 if (priv->DIG_NumberFallbackVote)
257 priv->DIG_NumberFallbackVote--;
258 }
259 priv->DIG_NumberUpgradeVote=0;
260 }
261 else
262 {
263 if (priv->DIG_NumberFallbackVote)
264 priv->DIG_NumberFallbackVote--;
265 priv->DIG_NumberUpgradeVote++;
266
267 if (priv->DIG_NumberUpgradeVote>9)
268 {
269 if (priv->InitialGain > LowestGainStage) // In 87B, m78dBm means State 4 (m864dBm)
270 {
271 priv->InitialGainBackUp= priv->InitialGain;
272
273 priv->InitialGain = (priv->InitialGain - 1);
274// printk("DIG**********OFDM False Alarm: %#X, OfdmFA1: %#X, OfdmFA2: %#X\n", OFDMFalseAlarm, OfdmFA1, OfdmFA2);
275// printk("DIG--------- Upgrade OFDM:%d \n", priv->InitialGain);
276 UpdateInitialGain(dev);
277 }
278 priv->DIG_NumberFallbackVote = 0;
279 priv->DIG_NumberUpgradeVote=0;
280 }
281 }
282
283// printk("DIG+++++++ OFDM:%d\n", priv->InitialGain);
284 //printk("<--------- DIG_Zebra()\n");
285}
286
287//
288// Description:
289// Dispatch DIG implementation according to RF.
290//
291void
292DynamicInitGain(
293 struct net_device *dev
294 )
295{
296 struct r8180_priv *priv = ieee80211_priv(dev);
297
298 switch(priv->rf_chip)
299 {
300 case RF_ZEBRA2: // [AnnieWorkaround] For Zebra2, 2005-08-01.
301 case RF_ZEBRA4:
302 DIG_Zebra( dev );
303 break;
304
305 default:
306 printk("DynamicInitGain(): unknown RFChipID(%d) !!!\n", priv->rf_chip);
307 break;
308 }
309}
310
311#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
312void rtl8180_hw_dig_wq (struct work_struct *work)
313{
314// struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
315// struct ieee80211_device * ieee = (struct ieee80211_device*)
316// container_of(work, struct ieee80211_device, watch_dog_wq);
317 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
318 struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_dig_wq);
319 struct net_device *dev = ieee->dev;
320#else
321void rtl8180_hw_dig_wq(struct net_device *dev)
322{
323
324#endif
325 struct r8180_priv *priv = ieee80211_priv(dev);
326
327 // Read CCK and OFDM False Alarm.
328 priv->FalseAlarmRegValue = read_nic_dword(dev, CCK_FALSE_ALARM);
329
330
331 // Adjust Initial Gain dynamically.
332 DynamicInitGain(dev);
333
334}
335
336int
337IncludedInSupportedRates(
338 struct r8180_priv *priv,
339 u8 TxRate )
340{
341 u8 rate_len;
342 u8 rate_ex_len;
343 u8 RateMask = 0x7F;
344 u8 idx;
345 unsigned short Found = 0;
346 u8 NaiveTxRate = TxRate&RateMask;
347
348 rate_len = priv->ieee80211->current_network.rates_len;
349 rate_ex_len = priv->ieee80211->current_network.rates_ex_len;
350 for( idx=0; idx< rate_len; idx++ )
351 {
352 if( (priv->ieee80211->current_network.rates[idx] & RateMask) == NaiveTxRate )
353 {
354 Found = 1;
355 goto found_rate;
356 }
357 }
358 for( idx=0; idx< rate_ex_len; idx++ )
359 {
360 if( (priv->ieee80211->current_network.rates_ex[idx] & RateMask) == NaiveTxRate )
361 {
362 Found = 1;
363 goto found_rate;
364 }
365 }
366 return Found;
367 found_rate:
368 return Found;
369}
370
371//
372// Description:
373// Get the Tx rate one degree up form the input rate in the supported rates.
374// Return the upgrade rate if it is successed, otherwise return the input rate.
375// By Bruce, 2007-06-05.
376//
377u8
378GetUpgradeTxRate(
379 struct net_device *dev,
380 u8 rate
381 )
382{
383 struct r8180_priv *priv = ieee80211_priv(dev);
384 u8 UpRate;
385
386 // Upgrade 1 degree.
387 switch(rate)
388 {
389 case 108: // Up to 54Mbps.
390 UpRate = 108;
391 break;
392
393 case 96: // Up to 54Mbps.
394 UpRate = 108;
395 break;
396
397 case 72: // Up to 48Mbps.
398 UpRate = 96;
399 break;
400
401 case 48: // Up to 36Mbps.
402 UpRate = 72;
403 break;
404
405 case 36: // Up to 24Mbps.
406 UpRate = 48;
407 break;
408
409 case 22: // Up to 18Mbps.
410 UpRate = 36;
411 break;
412
413 case 11: // Up to 11Mbps.
414 UpRate = 22;
415 break;
416
417 case 4: // Up to 5.5Mbps.
418 UpRate = 11;
419 break;
420
421 case 2: // Up to 2Mbps.
422 UpRate = 4;
423 break;
424
425 default:
426 printk("GetUpgradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate);
427 return rate;
428 }
429 // Check if the rate is valid.
430 if(IncludedInSupportedRates(priv, UpRate))
431 {
432// printk("GetUpgradeTxRate(): GetUpgrade Tx rate(%d) from %d !\n", UpRate, priv->CurrentOperaRate);
433 return UpRate;
434 }
435 else
436 {
437 //printk("GetUpgradeTxRate(): Tx rate (%d) is not in supported rates\n", UpRate);
438 return rate;
439 }
440 return rate;
441}
442//
443// Description:
444// Get the Tx rate one degree down form the input rate in the supported rates.
445// Return the degrade rate if it is successed, otherwise return the input rate.
446// By Bruce, 2007-06-05.
447//
448u8
449GetDegradeTxRate(
450 struct net_device *dev,
451 u8 rate
452 )
453{
454 struct r8180_priv *priv = ieee80211_priv(dev);
455 u8 DownRate;
456
457 // Upgrade 1 degree.
458 switch(rate)
459 {
460 case 108: // Down to 48Mbps.
461 DownRate = 96;
462 break;
463
464 case 96: // Down to 36Mbps.
465 DownRate = 72;
466 break;
467
468 case 72: // Down to 24Mbps.
469 DownRate = 48;
470 break;
471
472 case 48: // Down to 18Mbps.
473 DownRate = 36;
474 break;
475
476 case 36: // Down to 11Mbps.
477 DownRate = 22;
478 break;
479
480 case 22: // Down to 5.5Mbps.
481 DownRate = 11;
482 break;
483
484 case 11: // Down to 2Mbps.
485 DownRate = 4;
486 break;
487
488 case 4: // Down to 1Mbps.
489 DownRate = 2;
490 break;
491
492 case 2: // Down to 1Mbps.
493 DownRate = 2;
494 break;
495
496 default:
497 printk("GetDegradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate);
498 return rate;
499 }
500 // Check if the rate is valid.
501 if(IncludedInSupportedRates(priv, DownRate))
502 {
503// printk("GetDegradeTxRate(): GetDegrade Tx rate(%d) from %d!\n", DownRate, priv->CurrentOperaRate);
504 return DownRate;
505 }
506 else
507 {
508 //printk("GetDegradeTxRate(): Tx rate (%d) is not in supported rates\n", DownRate);
509 return rate;
510 }
511 return rate;
512}
513//
514// Helper function to determine if specified data rate is
515// CCK rate.
516// 2005.01.25, by rcnjko.
517//
518bool
519MgntIsCckRate(
520 u16 rate
521 )
522{
523 bool bReturn = false;
524
525 if((rate <= 22) && (rate != 12) && (rate != 18))
526 {
527 bReturn = true;
528 }
529
530 return bReturn;
531}
532#ifdef CONFIG_RTL818X_S
533//
534// Description:
535// Tx Power tracking mechanism routine on 87SE.
536// Created by Roger, 2007.12.11.
537//
538void
539TxPwrTracking87SE(
540 struct net_device *dev
541)
542{
543 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
544 u8 tmpu1Byte, CurrentThermal, Idx;
545 char CckTxPwrIdx, OfdmTxPwrIdx;
546 //u32 u4bRfReg;
547
548 tmpu1Byte = read_nic_byte(dev, EN_LPF_CAL);
549 CurrentThermal = (tmpu1Byte & 0xf0)>>4; //[ 7:4]: thermal meter indication.
550 CurrentThermal = (CurrentThermal>0x0c)? 0x0c:CurrentThermal;//lzm add 080826
551
552 //printk("TxPwrTracking87SE(): CurrentThermal(%d)\n", CurrentThermal);
553
554 if( CurrentThermal != priv->ThermalMeter)
555 {
556// printk("TxPwrTracking87SE(): Thermal meter changed!!!\n");
557
558 // Update Tx Power level on each channel.
559 for(Idx = 1; Idx<15; Idx++)
560 {
561 CckTxPwrIdx = priv->chtxpwr[Idx];
562 OfdmTxPwrIdx = priv->chtxpwr_ofdm[Idx];
563
564 if( CurrentThermal > priv->ThermalMeter )
565 { // higher thermal meter.
566 CckTxPwrIdx += (CurrentThermal - priv->ThermalMeter)*2;
567 OfdmTxPwrIdx += (CurrentThermal - priv->ThermalMeter)*2;
568
569 if(CckTxPwrIdx >35)
570 CckTxPwrIdx = 35; // Force TxPower to maximal index.
571 if(OfdmTxPwrIdx >35)
572 OfdmTxPwrIdx = 35;
573 }
574 else
575 { // lower thermal meter.
576 CckTxPwrIdx -= (priv->ThermalMeter - CurrentThermal)*2;
577 OfdmTxPwrIdx -= (priv->ThermalMeter - CurrentThermal)*2;
578
579 if(CckTxPwrIdx <0)
580 CckTxPwrIdx = 0;
581 if(OfdmTxPwrIdx <0)
582 OfdmTxPwrIdx = 0;
583 }
584
585 // Update TxPower level on CCK and OFDM resp.
586 priv->chtxpwr[Idx] = CckTxPwrIdx;
587 priv->chtxpwr_ofdm[Idx] = OfdmTxPwrIdx;
588 }
589
590 // Update TxPower level immediately.
591 rtl8225z2_SetTXPowerLevel(dev, priv->ieee80211->current_network.channel);
592 }
593 priv->ThermalMeter = CurrentThermal;
594}
595void
596StaRateAdaptive87SE(
597 struct net_device *dev
598 )
599{
600 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
601 unsigned long CurrTxokCnt;
602 u16 CurrRetryCnt;
603 u16 CurrRetryRate;
604 //u16 i,idx;
605 unsigned long CurrRxokCnt;
606 bool bTryUp = false;
607 bool bTryDown = false;
608 u8 TryUpTh = 1;
609 u8 TryDownTh = 2;
610 u32 TxThroughput;
611 long CurrSignalStrength;
612 bool bUpdateInitialGain = false;
613 u8 u1bOfdm=0, u1bCck = 0;
614 char OfdmTxPwrIdx, CckTxPwrIdx;
615
616 priv->RateAdaptivePeriod= RATE_ADAPTIVE_TIMER_PERIOD;
617
618
619 CurrRetryCnt = priv->CurrRetryCnt;
620 CurrTxokCnt = priv->NumTxOkTotal - priv->LastTxokCnt;
621 CurrRxokCnt = priv->ieee80211->NumRxOkTotal - priv->LastRxokCnt;
622 CurrSignalStrength = priv->Stats_RecvSignalPower;
623 TxThroughput = (u32)(priv->NumTxOkBytesTotal - priv->LastTxOKBytes);
624 priv->LastTxOKBytes = priv->NumTxOkBytesTotal;
625 priv->CurrentOperaRate = priv->ieee80211->rate/5;
626 //printk("priv->CurrentOperaRate is %d\n",priv->CurrentOperaRate);
627 //2 Compute retry ratio.
628 if (CurrTxokCnt>0)
629 {
630 CurrRetryRate = (u16)(CurrRetryCnt*100/CurrTxokCnt);
631 }
632 else
633 { // It may be serious retry. To distinguish serious retry or no packets modified by Bruce
634 CurrRetryRate = (u16)(CurrRetryCnt*100/1);
635 }
636
637
638 //
639 // Added by Roger, 2007.01.02.
640 // For debug information.
641 //
642 //printk("\n(1) pHalData->LastRetryRate: %d \n",priv->LastRetryRate);
643 //printk("(2) RetryCnt = %d \n", CurrRetryCnt);
644 //printk("(3) TxokCnt = %d \n", CurrTxokCnt);
645 //printk("(4) CurrRetryRate = %d \n", CurrRetryRate);
646 //printk("(5) CurrSignalStrength = %d \n",CurrSignalStrength);
647 //printk("(6) TxThroughput is %d\n",TxThroughput);
648 //printk("priv->NumTxOkBytesTotal is %d\n",priv->NumTxOkBytesTotal);
649
650 priv->LastRetryCnt = priv->CurrRetryCnt;
651 priv->LastTxokCnt = priv->NumTxOkTotal;
652 priv->LastRxokCnt = priv->ieee80211->NumRxOkTotal;
653 priv->CurrRetryCnt = 0;
654
655 //2No Tx packets, return to init_rate or not?
656 if (CurrRetryRate==0 && CurrTxokCnt == 0)
657 {
658 //
659 //After 9 (30*300ms) seconds in this condition, we try to raise rate.
660 //
661 priv->TryupingCountNoData++;
662
663// printk("No Tx packets, TryupingCountNoData(%d)\n", priv->TryupingCountNoData);
664 //[TRC Dell Lab] Extend raised period from 4.5sec to 9sec, Isaiah 2008-02-15 18:00
665 if (priv->TryupingCountNoData>30)
666 {
667 priv->TryupingCountNoData = 0;
668 priv->CurrentOperaRate = GetUpgradeTxRate(dev, priv->CurrentOperaRate);
669 // Reset Fail Record
670 priv->LastFailTxRate = 0;
671 priv->LastFailTxRateSS = -200;
672 priv->FailTxRateCount = 0;
673 }
674 goto SetInitialGain;
675 }
676 else
677 {
678 priv->TryupingCountNoData=0; //Reset trying up times.
679 }
680
681
682 //
683 // For Netgear case, I comment out the following signal strength estimation,
684 // which can results in lower rate to transmit when sample is NOT enough (e.g. PING request).
685 // 2007.04.09, by Roger.
686 //
687
688 //
689 // Restructure rate adaptive as the following main stages:
690 // (1) Add retry threshold in 54M upgrading condition with signal strength.
691 // (2) Add the mechanism to degrade to CCK rate according to signal strength
692 // and retry rate.
693 // (3) Remove all Initial Gain Updates over OFDM rate. To avoid the complicated
694 // situation, Initial Gain Update is upon on DIG mechanism except CCK rate.
695 // (4) Add the mehanism of trying to upgrade tx rate.
696 // (5) Record the information of upping tx rate to avoid trying upping tx rate constantly.
697 // By Bruce, 2007-06-05.
698 //
699 //
700
701 // 11Mbps or 36Mbps
702 // Check more times in these rate(key rates).
703 //
704 if(priv->CurrentOperaRate == 22 || priv->CurrentOperaRate == 72)
705 {
706 TryUpTh += 9;
707 }
708 //
709 // Let these rates down more difficult.
710 //
711 if(MgntIsCckRate(priv->CurrentOperaRate) || priv->CurrentOperaRate == 36)
712 {
713 TryDownTh += 1;
714 }
715
716 //1 Adjust Rate.
717 if (priv->bTryuping == true)
718 {
719 //2 For Test Upgrading mechanism
720 // Note:
721 // Sometimes the throughput is upon on the capability bwtween the AP and NIC,
722 // thus the low data rate does not improve the performance.
723 // We randomly upgrade the data rate and check if the retry rate is improved.
724
725 // Upgrading rate did not improve the retry rate, fallback to the original rate.
726 if ( (CurrRetryRate > 25) && TxThroughput < priv->LastTxThroughput)
727 {
728 //Not necessary raising rate, fall back rate.
729 bTryDown = true;
730 //printk("case1-1: Not necessary raising rate, fall back rate....\n");
731 //printk("case1-1: pMgntInfo->CurrentOperaRate =%d, TxThroughput = %d, LastThroughput = %d\n",
732 // priv->CurrentOperaRate, TxThroughput, priv->LastTxThroughput);
733 }
734 else
735 {
736 priv->bTryuping = false;
737 }
738 }
739 else if (CurrSignalStrength > -47 && (CurrRetryRate < 50))
740 {
741 //2For High Power
742 //
743 // Added by Roger, 2007.04.09.
744 // Return to highest data rate, if signal strength is good enough.
745 // SignalStrength threshold(-50dbm) is for RTL8186.
746 // Revise SignalStrength threshold to -51dbm.
747 //
748 // Also need to check retry rate for safety, by Bruce, 2007-06-05.
749 if(priv->CurrentOperaRate != priv->ieee80211->current_network.HighestOperaRate )
750 {
751 bTryUp = true;
752 // Upgrade Tx Rate directly.
753 priv->TryupingCount += TryUpTh;
754 }
755// printk("case2: StaRateAdaptive87SE: Power(%d) is high enough!!. \n", CurrSignalStrength);
756
757 }
758 else if(CurrTxokCnt > 9 && CurrTxokCnt< 100 && CurrRetryRate >= 600)
759 {
760 //2 For Serious Retry
761 //
762 // Traffic is not busy but our Tx retry is serious.
763 //
764 bTryDown = true;
765 // Let Rate Mechanism to degrade tx rate directly.
766 priv->TryDownCountLowData += TryDownTh;
767// printk("case3: RA: Tx Retry is serious. Degrade Tx Rate to %d directly...\n", priv->CurrentOperaRate);
768 }
769 else if ( priv->CurrentOperaRate == 108 )
770 {
771 //2For 54Mbps
772 // Air Link
773 if ( (CurrRetryRate>26)&&(priv->LastRetryRate>25))
774// if ( (CurrRetryRate>40)&&(priv->LastRetryRate>39))
775 {
776 //Down to rate 48Mbps.
777 bTryDown = true;
778 }
779 // Cable Link
780 else if ( (CurrRetryRate>17)&&(priv->LastRetryRate>16) && (CurrSignalStrength > -72))
781// else if ( (CurrRetryRate>17)&&(priv->LastRetryRate>16) && (CurrSignalStrength > -72))
782 {
783 //Down to rate 48Mbps.
784 bTryDown = true;
785 }
786
787 if(bTryDown && (CurrSignalStrength < -75)) //cable link
788 {
789 priv->TryDownCountLowData += TryDownTh;
790 }
791 //printk("case4---54M \n");
792
793 }
794 else if ( priv->CurrentOperaRate == 96 )
795 {
796 //2For 48Mbps
797 //Air Link
798 if ( ((CurrRetryRate>48) && (priv->LastRetryRate>47)))
799// if ( ((CurrRetryRate>65) && (priv->LastRetryRate>64)))
800
801 {
802 //Down to rate 36Mbps.
803 bTryDown = true;
804 }
805 //Cable Link
806 else if ( ((CurrRetryRate>21) && (priv->LastRetryRate>20)) && (CurrSignalStrength > -74))
807 {
808 //Down to rate 36Mbps.
809 bTryDown = true;
810 }
811 else if((CurrRetryRate> (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 ))
812// else if((CurrRetryRate> (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))
813 {
814 bTryDown = true;
815 priv->TryDownCountLowData += TryDownTh;
816 }
817 else if ( (CurrRetryRate<8) && (priv->LastRetryRate<8) ) //TO DO: need to consider (RSSI)
818// else if ( (CurrRetryRate<28) && (priv->LastRetryRate<8) )
819 {
820 bTryUp = true;
821 }
822
823 if(bTryDown && (CurrSignalStrength < -75))
824 {
825 priv->TryDownCountLowData += TryDownTh;
826 }
827 //printk("case5---48M \n");
828 }
829 else if ( priv->CurrentOperaRate == 72 )
830 {
831 //2For 36Mbps
832 if ( (CurrRetryRate>43) && (priv->LastRetryRate>41))
833// if ( (CurrRetryRate>60) && (priv->LastRetryRate>59))
834 {
835 //Down to rate 24Mbps.
836 bTryDown = true;
837 }
838 else if((CurrRetryRate> (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 ))
839// else if((CurrRetryRate> (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))
840 {
841 bTryDown = true;
842 priv->TryDownCountLowData += TryDownTh;
843 }
844 else if ( (CurrRetryRate<15) && (priv->LastRetryRate<16)) //TO DO: need to consider (RSSI)
845// else if ( (CurrRetryRate<35) && (priv->LastRetryRate<36))
846 {
847 bTryUp = true;
848 }
849
850 if(bTryDown && (CurrSignalStrength < -80))
851 {
852 priv->TryDownCountLowData += TryDownTh;
853 }
854 //printk("case6---36M \n");
855 }
856 else if ( priv->CurrentOperaRate == 48 )
857 {
858 //2For 24Mbps
859 // Air Link
860 if ( ((CurrRetryRate>63) && (priv->LastRetryRate>62)))
861// if ( ((CurrRetryRate>83) && (priv->LastRetryRate>82)))
862 {
863 //Down to rate 18Mbps.
864 bTryDown = true;
865 }
866 //Cable Link
867 else if ( ((CurrRetryRate>33) && (priv->LastRetryRate>32)) && (CurrSignalStrength > -82) )
868// else if ( ((CurrRetryRate>50) && (priv->LastRetryRate>49)) && (CurrSignalStrength > -82) )
869 {
870 //Down to rate 18Mbps.
871 bTryDown = true;
872 }
873 else if((CurrRetryRate> (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 ))
874// else if((CurrRetryRate> (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))
875
876 {
877 bTryDown = true;
878 priv->TryDownCountLowData += TryDownTh;
879 }
880 else if ( (CurrRetryRate<20) && (priv->LastRetryRate<21)) //TO DO: need to consider (RSSI)
881// else if ( (CurrRetryRate<40) && (priv->LastRetryRate<41))
882 {
883 bTryUp = true;
884 }
885
886 if(bTryDown && (CurrSignalStrength < -82))
887 {
888 priv->TryDownCountLowData += TryDownTh;
889 }
890 //printk("case7---24M \n");
891 }
892 else if ( priv->CurrentOperaRate == 36 )
893 {
894 //2For 18Mbps
895 // original (109, 109)
896 //[TRC Dell Lab] (90, 91), Isaiah 2008-02-18 23:24
897 // (85, 86), Isaiah 2008-02-18 24:00
898 if ( ((CurrRetryRate>85) && (priv->LastRetryRate>86)))
899// if ( ((CurrRetryRate>115) && (priv->LastRetryRate>116)))
900 {
901 //Down to rate 11Mbps.
902 bTryDown = true;
903 }
904 //[TRC Dell Lab] Isaiah 2008-02-18 23:24
905 else if((CurrRetryRate> (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 ))
906// else if((CurrRetryRate> (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))
907 {
908 bTryDown = true;
909 priv->TryDownCountLowData += TryDownTh;
910 }
911 else if ( (CurrRetryRate<22) && (priv->LastRetryRate<23)) //TO DO: need to consider (RSSI)
912// else if ( (CurrRetryRate<42) && (priv->LastRetryRate<43))
913 {
914 bTryUp = true;
915 }
916 //printk("case8---18M \n");
917 }
918 else if ( priv->CurrentOperaRate == 22 )
919 {
920 //2For 11Mbps
921 if (CurrRetryRate>95)
922// if (CurrRetryRate>155)
923 {
924 bTryDown = true;
925 }
926 else if ( (CurrRetryRate<29) && (priv->LastRetryRate <30) )//TO DO: need to consider (RSSI)
927// else if ( (CurrRetryRate<49) && (priv->LastRetryRate <50) )
928 {
929 bTryUp = true;
930 }
931 //printk("case9---11M \n");
932 }
933 else if ( priv->CurrentOperaRate == 11 )
934 {
935 //2For 5.5Mbps
936 if (CurrRetryRate>149)
937// if (CurrRetryRate>189)
938 {
939 bTryDown = true;
940 }
941 else if ( (CurrRetryRate<60) && (priv->LastRetryRate < 65))
942// else if ( (CurrRetryRate<80) && (priv->LastRetryRate < 85))
943
944 {
945 bTryUp = true;
946 }
947 //printk("case10---5.5M \n");
948 }
949 else if ( priv->CurrentOperaRate == 4 )
950 {
951 //2For 2 Mbps
952 if((CurrRetryRate>99) && (priv->LastRetryRate>99))
953// if((CurrRetryRate>199) && (priv->LastRetryRate>199))
954 {
955 bTryDown = true;
956 }
957 else if ( (CurrRetryRate < 65) && (priv->LastRetryRate < 70))
958// else if ( (CurrRetryRate < 85) && (priv->LastRetryRate < 90))
959 {
960 bTryUp = true;
961 }
962 //printk("case11---2M \n");
963 }
964 else if ( priv->CurrentOperaRate == 2 )
965 {
966 //2For 1 Mbps
967 if( (CurrRetryRate<70) && (priv->LastRetryRate<75))
968// if( (CurrRetryRate<90) && (priv->LastRetryRate<95))
969 {
970 bTryUp = true;
971 }
972 //printk("case12---1M \n");
973 }
974
975 if(bTryUp && bTryDown)
976 printk("StaRateAdaptive87B(): Tx Rate tried upping and downing simultaneously!\n");
977
978 //1 Test Upgrading Tx Rate
979 // Sometimes the cause of the low throughput (high retry rate) is the compatibility between the AP and NIC.
980 // To test if the upper rate may cause lower retry rate, this mechanism randomly occurs to test upgrading tx rate.
981 if(!bTryUp && !bTryDown && (priv->TryupingCount == 0) && (priv->TryDownCountLowData == 0)
982 && priv->CurrentOperaRate != priv->ieee80211->current_network.HighestOperaRate && priv->FailTxRateCount < 2)
983 {
984 if(jiffies% (CurrRetryRate + 101) == 0)
985 {
986 bTryUp = true;
987 priv->bTryuping = true;
988 //printk("StaRateAdaptive87SE(): Randomly try upgrading...\n");
989 }
990 }
991
992 //1 Rate Mechanism
993 if(bTryUp)
994 {
995 priv->TryupingCount++;
996 priv->TryDownCountLowData = 0;
997
998 {
999// printk("UP: pHalData->TryupingCount = %d\n", priv->TryupingCount);
1000// printk("UP: TryUpTh(%d)+ (FailTxRateCount(%d))^2 =%d\n",
1001// TryUpTh, priv->FailTxRateCount, (TryUpTh + priv->FailTxRateCount * priv->FailTxRateCount) );
1002// printk("UP: pHalData->bTryuping=%d\n", priv->bTryuping);
1003
1004 }
1005
1006 //
1007 // Check more times if we need to upgrade indeed.
1008 // Because the largest value of pHalData->TryupingCount is 0xFFFF and
1009 // the largest value of pHalData->FailTxRateCount is 0x14,
1010 // this condition will be satisfied at most every 2 min.
1011 //
1012
1013 if((priv->TryupingCount > (TryUpTh + priv->FailTxRateCount * priv->FailTxRateCount)) ||
1014 (CurrSignalStrength > priv->LastFailTxRateSS) || priv->bTryuping)
1015 {
1016 priv->TryupingCount = 0;
1017 //
1018 // When transfering from CCK to OFDM, DIG is an important issue.
1019 //
1020 if(priv->CurrentOperaRate == 22)
1021 bUpdateInitialGain = true;
1022
1023 // The difference in throughput between 48Mbps and 36Mbps is 8M.
1024 // So, we must be carefully in this rate scale. Isaiah 2008-02-15.
1025 //
1026 if( ((priv->CurrentOperaRate == 72) || (priv->CurrentOperaRate == 48) || (priv->CurrentOperaRate == 36)) &&
1027 (priv->FailTxRateCount > 2) )
1028 priv->RateAdaptivePeriod= (RATE_ADAPTIVE_TIMER_PERIOD/2);
1029
1030 // (1)To avoid upgrade frequently to the fail tx rate, add the FailTxRateCount into the threshold.
1031 // (2)If the signal strength is increased, it may be able to upgrade.
1032
1033 priv->CurrentOperaRate = GetUpgradeTxRate(dev, priv->CurrentOperaRate);
1034// printk("StaRateAdaptive87SE(): Upgrade Tx Rate to %d\n", priv->CurrentOperaRate);
1035
1036 //[TRC Dell Lab] Bypass 12/9/6, Isaiah 2008-02-18 20:00
1037 if(priv->CurrentOperaRate ==36)
1038 {
1039 priv->bUpdateARFR=true;
1040 write_nic_word(dev, ARFR, 0x0F8F); //bypass 12/9/6
1041// printk("UP: ARFR=0xF8F\n");
1042 }
1043 else if(priv->bUpdateARFR)
1044 {
1045 priv->bUpdateARFR=false;
1046 write_nic_word(dev, ARFR, 0x0FFF); //set 1M ~ 54Mbps.
1047// printk("UP: ARFR=0xFFF\n");
1048 }
1049
1050 // Update Fail Tx rate and count.
1051 if(priv->LastFailTxRate != priv->CurrentOperaRate)
1052 {
1053 priv->LastFailTxRate = priv->CurrentOperaRate;
1054 priv->FailTxRateCount = 0;
1055 priv->LastFailTxRateSS = -200; // Set lowest power.
1056 }
1057 }
1058 }
1059 else
1060 {
1061 if(priv->TryupingCount > 0)
1062 priv->TryupingCount --;
1063 }
1064
1065 if(bTryDown)
1066 {
1067 priv->TryDownCountLowData++;
1068 priv->TryupingCount = 0;
1069 {
1070// printk("DN: pHalData->TryDownCountLowData = %d\n",priv->TryDownCountLowData);
1071// printk("DN: TryDownTh =%d\n", TryDownTh);
1072// printk("DN: pHalData->bTryuping=%d\n", priv->bTryuping);
1073 }
1074
1075 //Check if Tx rate can be degraded or Test trying upgrading should fallback.
1076 if(priv->TryDownCountLowData > TryDownTh || priv->bTryuping)
1077 {
1078 priv->TryDownCountLowData = 0;
1079 priv->bTryuping = false;
1080 // Update fail information.
1081 if(priv->LastFailTxRate == priv->CurrentOperaRate)
1082 {
1083 priv->FailTxRateCount ++;
1084 // Record the Tx fail rate signal strength.
1085 if(CurrSignalStrength > priv->LastFailTxRateSS)
1086 {
1087 priv->LastFailTxRateSS = CurrSignalStrength;
1088 }
1089 }
1090 else
1091 {
1092 priv->LastFailTxRate = priv->CurrentOperaRate;
1093 priv->FailTxRateCount = 1;
1094 priv->LastFailTxRateSS = CurrSignalStrength;
1095 }
1096 priv->CurrentOperaRate = GetDegradeTxRate(dev, priv->CurrentOperaRate);
1097
1098 // Reduce chariot training time at weak signal strength situation. SD3 ED demand.
1099 //[TRC Dell Lab] Revise Signal Threshold from -75 to -80 , Isaiah 2008-02-18 20:00
1100 if( (CurrSignalStrength < -80) && (priv->CurrentOperaRate > 72 ))
1101 {
1102 priv->CurrentOperaRate = 72;
1103// printk("DN: weak signal strength (%d), degrade to 36Mbps\n", CurrSignalStrength);
1104 }
1105
1106 //[TRC Dell Lab] Bypass 12/9/6, Isaiah 2008-02-18 20:00
1107 if(priv->CurrentOperaRate ==36)
1108 {
1109 priv->bUpdateARFR=true;
1110 write_nic_word(dev, ARFR, 0x0F8F); //bypass 12/9/6
1111// printk("DN: ARFR=0xF8F\n");
1112 }
1113 else if(priv->bUpdateARFR)
1114 {
1115 priv->bUpdateARFR=false;
1116 write_nic_word(dev, ARFR, 0x0FFF); //set 1M ~ 54Mbps.
1117// printk("DN: ARFR=0xFFF\n");
1118 }
1119
1120 //
1121 // When it is CCK rate, it may need to update initial gain to receive lower power packets.
1122 //
1123 if(MgntIsCckRate(priv->CurrentOperaRate))
1124 {
1125 bUpdateInitialGain = true;
1126 }
1127// printk("StaRateAdaptive87SE(): Degrade Tx Rate to %d\n", priv->CurrentOperaRate);
1128 }
1129 }
1130 else
1131 {
1132 if(priv->TryDownCountLowData > 0)
1133 priv->TryDownCountLowData --;
1134 }
1135
1136 // Keep the Tx fail rate count to equal to 0x15 at most.
1137 // Reduce the fail count at least to 10 sec if tx rate is tending stable.
1138 if(priv->FailTxRateCount >= 0x15 ||
1139 (!bTryUp && !bTryDown && priv->TryDownCountLowData == 0 && priv->TryupingCount && priv->FailTxRateCount > 0x6))
1140 {
1141 priv->FailTxRateCount --;
1142 }
1143
1144
1145 OfdmTxPwrIdx = priv->chtxpwr_ofdm[priv->ieee80211->current_network.channel];
1146 CckTxPwrIdx = priv->chtxpwr[priv->ieee80211->current_network.channel];
1147
1148 //[TRC Dell Lab] Mac0x9e increase 2 level in 36M~18M situation, Isaiah 2008-02-18 24:00
1149 if((priv->CurrentOperaRate < 96) &&(priv->CurrentOperaRate > 22))
1150 {
1151 u1bCck = read_nic_byte(dev, CCK_TXAGC);
1152 u1bOfdm = read_nic_byte(dev, OFDM_TXAGC);
1153
1154 // case 1: Never enter High power
1155 if(u1bCck == CckTxPwrIdx )
1156 {
1157 if(u1bOfdm != (OfdmTxPwrIdx+2) )
1158 {
1159 priv->bEnhanceTxPwr= true;
1160 u1bOfdm = ((u1bOfdm+2) > 35) ? 35: (u1bOfdm+2);
1161 write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);
1162// printk("Enhance OFDM_TXAGC : +++++ u1bOfdm= 0x%x\n", u1bOfdm);
1163 }
1164 }
1165 // case 2: enter high power
1166 else if(u1bCck < CckTxPwrIdx)
1167 {
1168 if(!priv->bEnhanceTxPwr)
1169 {
1170 priv->bEnhanceTxPwr= true;
1171 u1bOfdm = ((u1bOfdm+2) > 35) ? 35: (u1bOfdm+2);
1172 write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);
1173 //RT_TRACE(COMP_RATE, DBG_TRACE, ("Enhance OFDM_TXAGC(2) : +++++ u1bOfdm= 0x%x\n", u1bOfdm));
1174 }
1175 }
1176 }
1177 else if(priv->bEnhanceTxPwr) //54/48/11/5.5/2/1
1178 {
1179 u1bCck = read_nic_byte(dev, CCK_TXAGC);
1180 u1bOfdm = read_nic_byte(dev, OFDM_TXAGC);
1181
1182 // case 1: Never enter High power
1183 if(u1bCck == CckTxPwrIdx )
1184 {
1185 priv->bEnhanceTxPwr= false;
1186 write_nic_byte(dev, OFDM_TXAGC, OfdmTxPwrIdx);
1187 //printk("Recover OFDM_TXAGC : ===== u1bOfdm= 0x%x\n", OfdmTxPwrIdx);
1188 }
1189 // case 2: enter high power
1190 else if(u1bCck < CckTxPwrIdx)
1191 {
1192 priv->bEnhanceTxPwr= false;
1193 u1bOfdm = ((u1bOfdm-2) > 0) ? (u1bOfdm-2): 0;
1194 write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);
1195 //RT_TRACE(COMP_RATE, DBG_TRACE, ("Recover OFDM_TXAGC(2): ===== u1bOfdm= 0x%x\n", u1bOfdm));
1196
1197 }
1198 }
1199
1200 //
1201 // We need update initial gain when we set tx rate "from OFDM to CCK" or
1202 // "from CCK to OFDM".
1203 //
1204SetInitialGain:
1205 if(bUpdateInitialGain)
1206 {
1207 if(MgntIsCckRate(priv->CurrentOperaRate)) // CCK
1208 {
1209 if(priv->InitialGain > priv->RegBModeGainStage)
1210 {
1211 priv->InitialGainBackUp= priv->InitialGain;
1212
1213 if(CurrSignalStrength < -85) // Low power, OFDM [0x17] = 26.
1214 {
1215 //SD3 SYs suggest that CurrSignalStrength < -65, ofdm 0x17=26.
1216 priv->InitialGain = priv->RegBModeGainStage;
1217 }
1218 else if(priv->InitialGain > priv->RegBModeGainStage + 1)
1219 {
1220 priv->InitialGain -= 2;
1221 }
1222 else
1223 {
1224 priv->InitialGain --;
1225 }
1226 printk("StaRateAdaptive87SE(): update init_gain to index %d for date rate %d\n",priv->InitialGain, priv->CurrentOperaRate);
1227 UpdateInitialGain(dev);
1228 }
1229 }
1230 else // OFDM
1231 {
1232 if(priv->InitialGain < 4)
1233 {
1234 priv->InitialGainBackUp= priv->InitialGain;
1235
1236 priv->InitialGain ++;
1237 printk("StaRateAdaptive87SE(): update init_gain to index %d for date rate %d\n",priv->InitialGain, priv->CurrentOperaRate);
1238 UpdateInitialGain(dev);
1239 }
1240 }
1241 }
1242
1243 //Record the related info
1244 priv->LastRetryRate = CurrRetryRate;
1245 priv->LastTxThroughput = TxThroughput;
1246 priv->ieee80211->rate = priv->CurrentOperaRate * 5;
1247}
1248
1249#endif
1250#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
1251void rtl8180_rate_adapter(struct work_struct * work)
1252{
1253 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
1254 struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,rate_adapter_wq);
1255 struct net_device *dev = ieee->dev;
1256#else
1257void rtl8180_rate_adapter(struct net_device *dev)
1258{
1259
1260#endif
1261 //struct r8180_priv *priv = ieee80211_priv(dev);
1262// DMESG("---->rtl8180_rate_adapter");
1263 StaRateAdaptive87SE(dev);
1264// DMESG("<----rtl8180_rate_adapter");
1265}
1266void timer_rate_adaptive(unsigned long data)
1267{
1268 struct r8180_priv* priv = ieee80211_priv((struct net_device *)data);
1269 //DMESG("---->timer_rate_adaptive()\n");
1270 if(!priv->up)
1271 {
1272// DMESG("<----timer_rate_adaptive():driver is not up!\n");
1273 return;
1274 }
1275 if((priv->ieee80211->iw_mode != IW_MODE_MASTER)
1276 && (priv->ieee80211->state == IEEE80211_LINKED) &&
1277 (priv->ForcedDataRate == 0) )
1278 {
1279// DMESG("timer_rate_adaptive():schedule rate_adapter_wq\n");
1280#ifdef CONFIG_RTL818X_S
1281 queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->rate_adapter_wq);
1282// StaRateAdaptive87SE((struct net_device *)data);
1283#endif
1284 }
1285 priv->rateadapter_timer.expires = jiffies + MSECS(priv->RateAdaptivePeriod);
1286 add_timer(&priv->rateadapter_timer);
1287 //DMESG("<----timer_rate_adaptive()\n");
1288}
1289//by amy 080312}
1290void
1291SwAntennaDiversityRxOk8185(
1292 struct net_device *dev,
1293 u8 SignalStrength
1294 )
1295{
1296 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1297
1298// printk("+SwAntennaDiversityRxOk8185: RxSs: %d\n", SignalStrength);
1299
1300 priv->AdRxOkCnt++;
1301
1302 if( priv->AdRxSignalStrength != -1)
1303 {
1304 priv->AdRxSignalStrength = ((priv->AdRxSignalStrength*7) + (SignalStrength*3)) / 10;
1305 }
1306 else
1307 { // Initialization case.
1308 priv->AdRxSignalStrength = SignalStrength;
1309 }
1310//{+by amy 080312
1311 if( priv->LastRxPktAntenna ) //Main antenna.
1312 priv->AdMainAntennaRxOkCnt++;
1313 else // Aux antenna.
1314 priv->AdAuxAntennaRxOkCnt++;
1315//+by amy 080312
1316// printk("-SwAntennaDiversityRxOk8185: AdRxOkCnt: %d AdRxSignalStrength: %d\n", priv->AdRxOkCnt, priv->AdRxSignalStrength);
1317}
1318//
1319// Description:
1320// Change Antenna Switch.
1321//
1322bool
1323SetAntenna8185(
1324 struct net_device *dev,
1325 u8 u1bAntennaIndex
1326 )
1327{
1328 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1329 bool bAntennaSwitched = false;
1330
1331// printk("+SetAntenna8185(): Antenna is switching to: %d \n", u1bAntennaIndex);
1332
1333 switch(u1bAntennaIndex)
1334 {
1335 case 0:
1336 switch(priv->rf_chip)
1337 {
1338 case RF_ZEBRA2:
1339 case RF_ZEBRA4:
1340#ifdef CONFIG_RTL8185B
1341#ifdef CONFIG_RTL818X_S
1342 // Mac register, main antenna
1343 write_nic_byte(dev, ANTSEL, 0x03);
1344 //base band
1345 write_phy_cck(dev,0x11, 0x9b); // Config CCK RX antenna.
1346 write_phy_ofdm(dev, 0x0d, 0x5c); // Config OFDM RX antenna.
1347
1348#else
1349 // Mac register, main antenna
1350 write_nic_byte(dev, ANTSEL, 0x03);
1351 //base band
1352 write_phy_cck(dev, 0x10, 0x9b); // Config CCK RX antenna.
1353 write_phy_ofdm(dev, 0x0d, 0x5c); // Config OFDM RX antenna.
1354#endif
1355#endif
1356
1357 bAntennaSwitched = true;
1358 break;
1359
1360 default:
1361 printk("SetAntenna8185: unkown RFChipID(%d)\n", priv->rf_chip);
1362 break;
1363 }
1364 break;
1365
1366 case 1:
1367 switch(priv->rf_chip)
1368 {
1369 case RF_ZEBRA2:
1370 case RF_ZEBRA4:
1371#ifdef CONFIG_RTL8185B
1372#ifdef CONFIG_RTL818X_S
1373 // Mac register, aux antenna
1374 write_nic_byte(dev, ANTSEL, 0x00);
1375 //base band
1376 write_phy_cck(dev, 0x11, 0xbb); // Config CCK RX antenna.
1377 write_phy_ofdm(dev, 0x0d, 0x54); // Config OFDM RX antenna.
1378#else
1379 // Mac register, aux antenna
1380 write_nic_byte(dev, ANTSEL, 0x00);
1381 //base band
1382 write_phy_cck(dev, 0x10, 0xbb); // Config CCK RX antenna.
1383 write_phy_ofdm(dev, 0x0d, 0x54); // Config OFDM RX antenna.
1384#endif
1385#endif
1386
1387 bAntennaSwitched = true;
1388 break;
1389
1390 default:
1391 printk("SetAntenna8185: unkown RFChipID(%d)\n", priv->rf_chip);
1392 break;
1393 }
1394 break;
1395
1396 default:
1397 printk("SetAntenna8185: unkown u1bAntennaIndex(%d)\n", u1bAntennaIndex);
1398 break;
1399 }
1400
1401 if(bAntennaSwitched)
1402 {
1403 priv->CurrAntennaIndex = u1bAntennaIndex;
1404 }
1405
1406// printk("-SetAntenna8185(): return (%#X)\n", bAntennaSwitched);
1407
1408 return bAntennaSwitched;
1409}
1410//
1411// Description:
1412// Toggle Antenna switch.
1413//
1414bool
1415SwitchAntenna(
1416 struct net_device *dev
1417 )
1418{
1419 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1420
1421 bool bResult;
1422
1423 if(priv->CurrAntennaIndex == 0)
1424 {
1425#if 0//lzm del 080826
1426//by amy 080312
1427#ifdef CONFIG_RTL818X_S
1428 if(priv->bSwAntennaDiverity)
1429 bResult = SetAntennaConfig87SE(dev, 1, true);
1430 else
1431#endif
1432#endif
1433 bResult = SetAntenna8185(dev, 1);
1434//by amy 080312
1435// printk("SwitchAntenna(): switching to antenna 1 ......\n");
1436// bResult = SetAntenna8185(dev, 1);//-by amy 080312
1437 }
1438 else
1439 {
1440#if 0//lzm del 080826
1441//by amy 080312
1442#ifdef CONFIG_RTL818X_S
1443 if(priv->bSwAntennaDiverity)
1444 bResult = SetAntennaConfig87SE(dev, 0, true);
1445 else
1446#endif
1447#endif
1448 bResult = SetAntenna8185(dev, 0);
1449//by amy 080312
1450// printk("SwitchAntenna(): switching to antenna 0 ......\n");
1451// bResult = SetAntenna8185(dev, 0);//-by amy 080312
1452 }
1453
1454 return bResult;
1455}
1456//
1457// Description:
1458// Engine of SW Antenna Diversity mechanism.
1459// Since 8187 has no Tx part information,
1460// this implementation is only dependend on Rx part information.
1461//
1462// 2006.04.17, by rcnjko.
1463//
1464void
1465SwAntennaDiversity(
1466 struct net_device *dev
1467 )
1468{
1469 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1470 bool bSwCheckSS=false;
1471// printk("+SwAntennaDiversity(): CurrAntennaIndex: %d\n", priv->CurrAntennaIndex);
1472// printk("AdTickCount is %d\n",priv->AdTickCount);
1473//by amy 080312
1474 if(bSwCheckSS)
1475 {
1476 priv->AdTickCount++;
1477
1478 printk("(1) AdTickCount: %d, AdCheckPeriod: %d\n",
1479 priv->AdTickCount, priv->AdCheckPeriod);
1480 printk("(2) AdRxSignalStrength: %ld, AdRxSsThreshold: %ld\n",
1481 priv->AdRxSignalStrength, priv->AdRxSsThreshold);
1482 }
1483// priv->AdTickCount++;//-by amy 080312
1484
1485 // Case 1. No Link.
1486 if(priv->ieee80211->state != IEEE80211_LINKED)
1487 {
1488 // printk("SwAntennaDiversity(): Case 1. No Link.\n");
1489
1490 priv->bAdSwitchedChecking = false;
1491 // I switch antenna here to prevent any one of antenna is broken before link established, 2006.04.18, by rcnjko..
1492 SwitchAntenna(dev);
1493 }
1494 // Case 2. Linked but no packet received.
1495 else if(priv->AdRxOkCnt == 0)
1496 {
1497 // printk("SwAntennaDiversity(): Case 2. Linked but no packet received.\n");
1498
1499 priv->bAdSwitchedChecking = false;
1500 SwitchAntenna(dev);
1501 }
1502 // Case 3. Evaluate last antenna switch action and undo it if necessary.
1503 else if(priv->bAdSwitchedChecking == true)
1504 {
1505 // printk("SwAntennaDiversity(): Case 3. Evaluate last antenna switch action.\n");
1506
1507 priv->bAdSwitchedChecking = false;
1508
1509 // Adjust Rx signal strength threashold.
1510 priv->AdRxSsThreshold = (priv->AdRxSignalStrength + priv->AdRxSsBeforeSwitched) / 2;
1511
1512 priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ?
1513 priv->AdMaxRxSsThreshold: priv->AdRxSsThreshold;
1514 if(priv->AdRxSignalStrength < priv->AdRxSsBeforeSwitched)
1515 { // Rx signal strength is not improved after we swtiched antenna. => Swich back.
1516// printk("SwAntennaDiversity(): Rx Signal Strength is not improved, CurrRxSs: %d, LastRxSs: %d\n",
1517// priv->AdRxSignalStrength, priv->AdRxSsBeforeSwitched);
1518//by amy 080312
1519 // Increase Antenna Diversity checking period due to bad decision.
1520 priv->AdCheckPeriod *= 2;
1521//by amy 080312
1522 // Increase Antenna Diversity checking period.
1523 if(priv->AdCheckPeriod > priv->AdMaxCheckPeriod)
1524 priv->AdCheckPeriod = priv->AdMaxCheckPeriod;
1525
1526 // Wrong deceision => switch back.
1527 SwitchAntenna(dev);
1528 }
1529 else
1530 { // Rx Signal Strength is improved.
1531// printk("SwAntennaDiversity(): Rx Signal Strength is improved, CurrRxSs: %d, LastRxSs: %d\n",
1532// priv->AdRxSignalStrength, priv->AdRxSsBeforeSwitched);
1533
1534 // Reset Antenna Diversity checking period to its min value.
1535 priv->AdCheckPeriod = priv->AdMinCheckPeriod;
1536 }
1537
1538// printk("SwAntennaDiversity(): AdRxSsThreshold: %d, AdCheckPeriod: %d\n",
1539// priv->AdRxSsThreshold, priv->AdCheckPeriod);
1540 }
1541 // Case 4. Evaluate if we shall switch antenna now.
1542 // Cause Table Speed is very fast in TRC Dell Lab, we check it every time.
1543 else// if(priv->AdTickCount >= priv->AdCheckPeriod)//-by amy 080312
1544 {
1545// printk("SwAntennaDiversity(): Case 4. Evaluate if we shall switch antenna now.\n");
1546
1547 priv->AdTickCount = 0;
1548
1549 //
1550 // <Roger_Notes> We evaluate RxOk counts for each antenna first and than
1551 // evaluate signal strength.
1552 // The following operation can overcome the disability of CCA on both two antennas
1553 // When signal strength was extremely low or high.
1554 // 2008.01.30.
1555 //
1556
1557 //
1558 // Evaluate RxOk count from each antenna if we shall switch default antenna now.
1559 // Added by Roger, 2008.02.21.
1560//{by amy 080312
1561 if((priv->AdMainAntennaRxOkCnt < priv->AdAuxAntennaRxOkCnt)
1562 && (priv->CurrAntennaIndex == 0))
1563 { // We set Main antenna as default but RxOk count was less than Aux ones.
1564
1565 // printk("SwAntennaDiversity(): Main antenna RxOK is poor, AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",
1566 // priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);
1567
1568 // Switch to Aux antenna.
1569 SwitchAntenna(dev);
1570 priv->bHWAdSwitched = true;
1571 }
1572 else if((priv->AdAuxAntennaRxOkCnt < priv->AdMainAntennaRxOkCnt)
1573 && (priv->CurrAntennaIndex == 1))
1574 { // We set Aux antenna as default but RxOk count was less than Main ones.
1575
1576 // printk("SwAntennaDiversity(): Aux antenna RxOK is poor, AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",
1577 // priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);
1578
1579 // Switch to Main antenna.
1580 SwitchAntenna(dev);
1581 priv->bHWAdSwitched = true;
1582 }
1583 else
1584 {// Default antenna is better.
1585
1586 // printk("SwAntennaDiversity(): Default antenna is better., AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",
1587 // priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);
1588
1589 // Still need to check current signal strength.
1590 priv->bHWAdSwitched = false;
1591 }
1592 //
1593 // <Roger_Notes> We evaluate Rx signal strength ONLY when default antenna
1594 // didn't changed by HW evaluation.
1595 // 2008.02.27.
1596 //
1597 // [TRC Dell Lab] SignalStrength is inaccuracy. Isaiah 2008-03-05
1598 // For example, Throughput of aux is better than main antenna(about 10M v.s 2M),
1599 // but AdRxSignalStrength is less than main.
1600 // Our guess is that main antenna have lower throughput and get many change
1601 // to receive more CCK packets(ex.Beacon) which have stronger SignalStrength.
1602 //
1603 if( (!priv->bHWAdSwitched) && (bSwCheckSS))
1604 {
1605//by amy 080312}
1606 // Evaluate Rx signal strength if we shall switch antenna now.
1607 if(priv->AdRxSignalStrength < priv->AdRxSsThreshold)
1608 { // Rx signal strength is weak => Switch Antenna.
1609// printk("SwAntennaDiversity(): Rx Signal Strength is weak, CurrRxSs: %d, RxSsThreshold: %d\n",
1610// priv->AdRxSignalStrength, priv->AdRxSsThreshold);
1611
1612 priv->AdRxSsBeforeSwitched = priv->AdRxSignalStrength;
1613 priv->bAdSwitchedChecking = true;
1614
1615 SwitchAntenna(dev);
1616 }
1617 else
1618 { // Rx signal strength is OK.
1619// printk("SwAntennaDiversity(): Rx Signal Strength is OK, CurrRxSs: %d, RxSsThreshold: %d\n",
1620// priv->AdRxSignalStrength, priv->AdRxSsThreshold);
1621
1622 priv->bAdSwitchedChecking = false;
1623 // Increase Rx signal strength threashold if necessary.
1624 if( (priv->AdRxSignalStrength > (priv->AdRxSsThreshold + 10)) && // Signal is much stronger than current threshold
1625 priv->AdRxSsThreshold <= priv->AdMaxRxSsThreshold) // Current threhold is not yet reach upper limit.
1626 {
1627 priv->AdRxSsThreshold = (priv->AdRxSsThreshold + priv->AdRxSignalStrength) / 2;
1628 priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ?
1629 priv->AdMaxRxSsThreshold: priv->AdRxSsThreshold;//+by amy 080312
1630 }
1631
1632 // Reduce Antenna Diversity checking period if possible.
1633 if( priv->AdCheckPeriod > priv->AdMinCheckPeriod )
1634 {
1635 priv->AdCheckPeriod /= 2;
1636 }
1637 }
1638 }
1639 }
1640//by amy 080312
1641 // Reset antenna diversity Rx related statistics.
1642 priv->AdRxOkCnt = 0;
1643 priv->AdMainAntennaRxOkCnt = 0;
1644 priv->AdAuxAntennaRxOkCnt = 0;
1645//by amy 080312
1646
1647// priv->AdRxOkCnt = 0;//-by amy 080312
1648
1649// printk("-SwAntennaDiversity()\n");
1650}
1651
1652//
1653// Description:
1654// Return TRUE if we shall perform Tx Power Tracking Mecahnism, FALSE otherwise.
1655//
1656bool
1657CheckTxPwrTracking( struct net_device *dev)
1658{
1659 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1660
1661 if(!priv->bTxPowerTrack)
1662 {
1663 return false;
1664 }
1665
1666//lzm reserved 080826
1667 //if(priv->bScanInProgress)
1668 //{
1669 // return false;
1670 //}
1671
1672 //if 87SE is in High Power , don't do Tx Power Tracking. asked by SD3 ED. 2008-08-08 Isaiah
1673 if(priv->bToUpdateTxPwr)
1674 {
1675 return false;
1676 }
1677
1678 return true;
1679}
1680
1681
1682//
1683// Description:
1684// Timer callback function of SW Antenna Diversity.
1685//
1686void
1687SwAntennaDiversityTimerCallback(
1688 struct net_device *dev
1689 )
1690{
1691 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1692 RT_RF_POWER_STATE rtState;
1693
1694 //printk("+SwAntennaDiversityTimerCallback()\n");
1695
1696 //
1697 // We do NOT need to switch antenna while RF is off.
1698 // 2007.05.09, added by Roger.
1699 //
1700 rtState = priv->eRFPowerState;
1701 do{
1702 if (rtState == eRfOff)
1703 {
1704// printk("SwAntennaDiversityTimer - RF is OFF.\n");
1705 break;
1706 }
1707 else if (rtState == eRfSleep)
1708 {
1709 // Don't access BB/RF under Disable PLL situation.
1710 //RT_TRACE((COMP_RF|COMP_ANTENNA), DBG_LOUD, ("SwAntennaDiversityTimerCallback(): RF is Sleep => skip it\n"));
1711 break;
1712 }
1713 SwAntennaDiversity(dev);
1714
1715 }while(false);
1716
1717 if(priv->up)
1718 {
1719 priv->SwAntennaDiversityTimer.expires = jiffies + MSECS(ANTENNA_DIVERSITY_TIMER_PERIOD);
1720 add_timer(&priv->SwAntennaDiversityTimer);
1721 }
1722
1723 //printk("-SwAntennaDiversityTimerCallback()\n");
1724}
1725
diff --git a/drivers/staging/rtl8187se/r8180_dm.h b/drivers/staging/rtl8187se/r8180_dm.h
new file mode 100644
index 000000000000..3de92f040f99
--- /dev/null
+++ b/drivers/staging/rtl8187se/r8180_dm.h
@@ -0,0 +1,41 @@
1#ifndef R8180_DM_H
2#define R8180_DM_H
3
4#include "r8180.h"
5//#include "r8180_hw.h"
6//#include "r8180_93cx6.h"
7void SwAntennaDiversityRxOk8185(struct net_device *dev, u8 SignalStrength);
8bool SetAntenna8185(struct net_device *dev, u8 u1bAntennaIndex);
9bool SwitchAntenna( struct net_device *dev);
10void SwAntennaDiversity(struct net_device *dev );
11void SwAntennaDiversityTimerCallback(struct net_device *dev);
12bool CheckDig(struct net_device *dev);
13bool CheckHighPower(struct net_device *dev);
14#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
15void rtl8180_hw_dig_wq (struct work_struct *work);
16#else
17void rtl8180_hw_dig_wq(struct net_device *dev);
18#endif
19#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
20void rtl8180_tx_pw_wq (struct work_struct *work);
21#else
22void rtl8180_tx_pw_wq(struct net_device *dev);
23#endif
24#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
25void rtl8180_rate_adapter(struct work_struct * work);
26
27#else
28void rtl8180_rate_adapter(struct net_device *dev);
29
30#endif
31void TxPwrTracking87SE(struct net_device *dev);
32bool CheckTxPwrTracking(struct net_device *dev);
33#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
34void rtl8180_rate_adapter(struct work_struct * work);
35#else
36void rtl8180_rate_adapter(struct net_device *dev);
37#endif
38void timer_rate_adaptive(unsigned long data);
39
40
41#endif
diff --git a/drivers/staging/rtl8187se/r8180_gct.c b/drivers/staging/rtl8187se/r8180_gct.c
new file mode 100644
index 000000000000..86cb427a7a40
--- /dev/null
+++ b/drivers/staging/rtl8187se/r8180_gct.c
@@ -0,0 +1,296 @@
1/*
2 This files contains GCT radio frontend programming routines.
3
4 This is part of rtl8180 OpenSource driver
5 Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it>
6 Released under the terms of GPL (General Public Licence)
7
8 Parts of this driver are based on the GPL part of the
9 official realtek driver
10
11 Parts of this driver are based on the rtl8180 driver skeleton
12 from Patric Schenke & Andres Salomon
13
14 Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
15
16 Code from Rtw8180 NetBSD driver by David Young has been really useful to
17 understand some things and gets some ideas
18
19 Code from rtl8181 project has been useful to me to understand some things.
20
21 Some code from 'Deuce' work
22
23 We want to tanks the Authors of such projects and the Ndiswrapper
24 project Authors.
25*/
26
27
28#include "r8180.h"
29#include "r8180_hw.h"
30#include "r8180_gct.h"
31
32
33//#define DEBUG_GCT
34
35/* the following experiment are just experiments.
36 * this means if you enable them you can have every kind
37 * of result, included damage the RF chip, so don't
38 * touch them if you don't know what you are doing.
39 * In any case, if you do it, do at your own risk
40 */
41
42//#define GCT_EXPERIMENT1 //improve RX sensivity
43
44//#define GCT_EXPERIMENT2
45
46//#define GCT_EXPERIMENT3 //iprove a bit RX signal quality ?
47
48//#define GCT_EXPERIMENT4 //maybe solve some brokeness with experiment1 ?
49
50//#define GCT_EXPERIMENT5
51
52//#define GCT_EXPERIMENT6 //not good
53
54
55u32 gct_chan[] = {
56 0x0, //dummy channel 0
57 0x0, //1
58 0x1, //2
59 0x2, //3
60 0x3, //4
61 0x4, //5
62 0x5, //6
63 0x6, //7
64 0x7, //8
65 0x8, //9
66 0x9, //10
67 0xa, //11
68 0xb, //12
69 0xc, //13
70 0xd, //14
71};
72
73int gct_encode[16] = {
74 0, 8, 4, 0xC,
75 2, 0xA, 6, 0xE,
76 1, 9, 5, 0xD,
77 3, 0xB, 7, 0xF
78};
79
80void gct_rf_stabilize(struct net_device *dev)
81{
82 force_pci_posting(dev);
83 mdelay(3); //for now use a great value.. we may optimize in future
84}
85
86
87void write_gct(struct net_device *dev, u8 adr, u32 data)
88{
89// struct r8180_priv *priv = ieee80211_priv(dev);
90 u32 phy_config;
91
92 phy_config = gct_encode[(data & 0xf00) >> 8];
93 phy_config |= gct_encode[(data & 0xf0) >> 4 ] << 4;
94 phy_config |= gct_encode[(data & 0xf) ] << 8;
95 phy_config |= gct_encode[(adr >> 1) & 0xf ] << 12;
96 phy_config |= (adr & 1 ) << 16;
97 phy_config |= gct_encode[(data & 0xf000)>>12] << 24;
98
99 phy_config |= 0x90000000; // MAC will bang bits to the chip
100
101
102 write_nic_dword(dev,PHY_CONFIG,phy_config);
103#ifdef DEBUG_GCT
104 DMESG("Writing GCT: %x (adr %x)",phy_config,adr);
105#endif
106 gct_rf_stabilize(dev);
107}
108
109
110
111void gct_write_phy_antenna(struct net_device *dev,short ch)
112{
113 struct r8180_priv *priv = ieee80211_priv(dev);
114 u8 ant;
115
116 ant = GCT_ANTENNA;
117 if(priv->antb) /*default antenna is antenna B */
118 ant |= BB_ANTENNA_B;
119 if(ch == 14)
120 ant |= BB_ANTATTEN_CHAN14;
121 write_phy(dev,0x10,ant);
122 //DMESG("BB antenna %x ",ant);
123}
124
125
126void gct_rf_set_chan(struct net_device *dev, short ch)
127{
128 struct r8180_priv *priv = ieee80211_priv(dev);
129 u32 txpw = 0xff & priv->chtxpwr[ch];
130 u32 chan = gct_chan[ch];
131
132 //write_phy(dev,3,txpw);
133#ifdef DEBUG_GCT
134 DMESG("Gct set channel");
135#endif
136 /* set TX power */
137 write_gct(dev,0x15,0);
138 write_gct(dev,6, txpw);
139 write_gct(dev,0x15, 0x10);
140 write_gct(dev,0x15,0);
141
142 /*set frequency*/
143 write_gct(dev,7, 0);
144 write_gct(dev,0xB, chan);
145 write_gct(dev,7, 0x1000);
146
147#ifdef DEBUG_GCT
148 DMESG("Gct set channel > write phy antenna");
149#endif
150
151
152 gct_write_phy_antenna(dev,ch);
153
154}
155
156
157void gct_rf_close(struct net_device *dev)
158{
159 u32 anaparam;
160
161 anaparam = read_nic_dword(dev,ANAPARAM);
162 anaparam &= 0x000fffff;
163 anaparam |= 0x3f900000;
164 rtl8180_set_anaparam(dev, anaparam);
165
166 write_gct(dev, 0x7, 0);
167 write_gct(dev, 0x1f, 0x45);
168 write_gct(dev, 0x1f, 0x5);
169 write_gct(dev, 0x0, 0x8e4);
170}
171
172
173void gct_rf_init(struct net_device *dev)
174{
175 struct r8180_priv *priv = ieee80211_priv(dev);
176 //u32 anaparam;
177
178
179 write_nic_byte(dev,PHY_DELAY,0x6); //this is general
180 write_nic_byte(dev,CARRIER_SENSE_COUNTER,0x4c); //this is general
181
182 //DMESG("%x", read_nic_dword(dev,ANAPARAM));
183 /* we should set anaparm here*/
184 //rtl8180_set_anaparam(dev,anaparam);
185
186 write_gct(dev,0x1f,0);
187 write_gct(dev,0x1f,0);
188 write_gct(dev,0x1f,0x40);
189 write_gct(dev,0x1f,0x60);
190 write_gct(dev,0x1f,0x61);
191 write_gct(dev,0x1f,0x61);
192 write_gct(dev,0x0,0xae4);
193 write_gct(dev,0x1f,0x1);
194 write_gct(dev,0x1f,0x41);
195 write_gct(dev,0x1f,0x61);
196 write_gct(dev,0x1,0x1a23);
197 write_gct(dev,0x2,0x4971);
198 write_gct(dev,0x3,0x41de);
199 write_gct(dev,0x4,0x2d80);
200#ifdef GCT_EXPERIMENT1
201 //write_gct(dev,0x5,0x6810); // from zydas driver. sens+ but quite slow
202 //write_gct(dev,0x5,0x681f); //good+ (somewhat stable, better sens, performance decent)
203 write_gct(dev,0x5,0x685f); //good performances, not sure sens is really so beeter
204 //write_gct(dev,0x5,0x687f); //good performances, maybe sens is not improved
205 //write_gct(dev,0x5,0x689f); //like above
206 //write_gct(dev,0x5,0x685e); //bad
207 //write_gct(dev,0x5,0x68ff); //good+ (somewhat stable, better sens(?), performance decent)
208 //write_gct(dev,0x5,0x68f0); //bad
209 //write_gct(dev,0x5,0x6cff); //sens+ but not so good
210 //write_gct(dev,0x5,0x6dff); //sens+,apparentely very good but broken
211 //write_gct(dev,0x5,0x65ff); //sens+,good
212 //write_gct(dev,0x5,0x78ff); //sens + but almost broken
213 //write_gct(dev,0x5,0x7810); //- //snes + but broken
214 //write_gct(dev,0x5,0x781f); //-- //sens +
215 //write_gct(dev,0x5,0x78f0); //low sens
216#else
217 write_gct(dev,0x5,0x61ff); //best performance but weak sensitivity
218#endif
219#ifdef GCT_EXPERIMENT2
220 write_gct(dev,0x6,0xe);
221#else
222 write_gct(dev,0x6,0x0);
223#endif
224 write_gct(dev,0x7,0x0);
225 write_gct(dev,0x8,0x7533);
226 write_gct(dev,0x9,0xc401);
227 write_gct(dev,0xa,0x0);
228 write_gct(dev,0xc,0x1c7);
229 write_gct(dev,0xd,0x29d3);
230 write_gct(dev,0xe,0x2e8);
231 write_gct(dev,0x10,0x192);
232#ifdef GCT_EXPERIMENT3
233 write_gct(dev,0x11,0x246);
234#else
235 write_gct(dev,0x11,0x248);
236#endif
237 write_gct(dev,0x12,0x0);
238 write_gct(dev,0x13,0x20c4);
239#ifdef GCT_EXPERIMENT4
240 write_gct(dev,0x14,0xf488);
241#else
242 write_gct(dev,0x14,0xf4fc);
243#endif
244#ifdef GCT_EXPERIMENT5
245 write_gct(dev,0x15,0xb152);
246#else
247 write_gct(dev,0x15,0x0);
248#endif
249#ifdef GCT_EXPERIMENT6
250 write_gct(dev,0x1e,0x1);
251#endif
252 write_gct(dev,0x16,0x1500);
253
254 write_gct(dev,0x7,0x1000);
255 /*write_gct(dev,0x15,0x0);
256 write_gct(dev,0x6,0x15);
257 write_gct(dev,0x15,0x8);
258 write_gct(dev,0x15,0x0);
259*/
260 write_phy(dev,0,0xa8);
261
262/* write_gct(dev,0x15,0x0);
263 write_gct(dev,0x6,0x12);
264 write_gct(dev,0x15,0x8);
265 write_gct(dev,0x15,0x0);
266*/
267 write_phy(dev,3,0x0);
268 write_phy(dev,4,0xc0); /* lna det*/
269 write_phy(dev,5,0x90);
270 write_phy(dev,6,0x1e);
271 write_phy(dev,7,0x64);
272
273#ifdef DEBUG_GCT
274 DMESG("Gct init> write phy antenna");
275#endif
276
277 gct_write_phy_antenna(dev,priv->chan);
278
279 write_phy(dev,0x11,0x88);
280 if(!priv->diversity)
281 write_phy(dev,0x12,0xc0);
282 else
283 write_phy(dev,0x12,0x40);
284
285 write_phy(dev,0x13,0x90 | priv->cs_treshold );
286
287 write_phy(dev,0x19,0x0);
288 write_phy(dev,0x1a,0xa0);
289 write_phy(dev,0x1b,0x44);
290
291#ifdef DEBUG_GCT
292 DMESG("Gct init > set channel2");
293#endif
294
295 gct_rf_set_chan(dev,priv->chan);
296}
diff --git a/drivers/staging/rtl8187se/r8180_gct.h b/drivers/staging/rtl8187se/r8180_gct.h
new file mode 100644
index 000000000000..fe965ca64304
--- /dev/null
+++ b/drivers/staging/rtl8187se/r8180_gct.h
@@ -0,0 +1,25 @@
1/*
2 This is part of rtl8180 OpenSource driver - v 0.20
3 Copyright (C) Andrea Merello 2004 <andreamrl@tiscali.it>
4 Released under the terms of GPL (General Public Licence)
5
6 Parts of this driver are based on the GPL part of the official realtek driver
7 Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon
8 Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
9
10 We want to tanks the Authors of such projects and the Ndiswrapper project Authors.
11*/
12
13#define GCT_ANTENNA 0xA3
14
15
16// we use the untouched eeprom value- cross your finger ;-)
17#define GCT_ANAPARAM_PWR1_ON ??
18#define GCT_ANAPARAM_PWR0_ON ??
19
20
21
22void gct_rf_init(struct net_device *dev);
23void gct_rf_set_chan(struct net_device *dev,short ch);
24
25void gct_rf_close(struct net_device *dev);
diff --git a/drivers/staging/rtl8187se/r8180_hw.h b/drivers/staging/rtl8187se/r8180_hw.h
new file mode 100644
index 000000000000..bf38934bc090
--- /dev/null
+++ b/drivers/staging/rtl8187se/r8180_hw.h
@@ -0,0 +1,956 @@
1/*
2 This is part of rtl8180 OpenSource driver.
3 Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it>
4 Released under the terms of GPL (General Public Licence)
5
6 Parts of this driver are based on the GPL part of the
7 official Realtek driver.
8 Parts of this driver are based on the rtl8180 driver skeleton
9 from Patric Schenke & Andres Salomon.
10 Parts of this driver are based on the Intel Pro Wireless
11 2100 GPL driver.
12
13 We want to tanks the Authors of those projects
14 and the Ndiswrapper project Authors.
15*/
16
17/* Mariusz Matuszek added full registers definition with Realtek's name */
18
19/* this file contains register definitions for the rtl8180 MAC controller */
20#ifndef R8180_HW
21#define R8180_HW
22
23#define CONFIG_RTL8185B //support for rtl8185B, xiong-2006-11-15
24#define CONFIG_RTL818X_S
25
26#define BIT0 0x00000001
27#define BIT1 0x00000002
28#define BIT2 0x00000004
29#define BIT3 0x00000008
30#define BIT4 0x00000010
31#define BIT5 0x00000020
32#define BIT6 0x00000040
33#define BIT7 0x00000080
34#define BIT8 0x00000100
35#define BIT9 0x00000200
36#define BIT10 0x00000400
37#define BIT11 0x00000800
38#define BIT12 0x00001000
39#define BIT13 0x00002000
40#define BIT14 0x00004000
41#define BIT15 0x00008000
42#define BIT16 0x00010000
43#define BIT17 0x00020000
44#define BIT18 0x00040000
45#define BIT19 0x00080000
46#define BIT20 0x00100000
47#define BIT21 0x00200000
48#define BIT22 0x00400000
49#define BIT23 0x00800000
50#define BIT24 0x01000000
51#define BIT25 0x02000000
52#define BIT26 0x04000000
53#define BIT27 0x08000000
54#define BIT28 0x10000000
55#define BIT29 0x20000000
56#define BIT30 0x40000000
57#define BIT31 0x80000000
58
59#define MAX_SLEEP_TIME (10000)
60#define MIN_SLEEP_TIME (50)
61
62#define BB_ANTATTEN_CHAN14 0x0c
63#define BB_ANTENNA_B 0x40
64
65#define BB_HOST_BANG (1<<30)
66#define BB_HOST_BANG_EN (1<<2)
67#define BB_HOST_BANG_CLK (1<<1)
68#define BB_HOST_BANG_DATA 1
69
70#define ANAPARAM_TXDACOFF_SHIFT 27
71#define ANAPARAM_PWR0_MASK ((1<<30)|(1<<29)|(1<<28))
72#define ANAPARAM_PWR0_SHIFT 28
73#define ANAPARAM_PWR1_MASK ((1<<26)|(1<<25)|(1<<24)|(1<<23)|(1<<22)|(1<<21)|(1<<20))
74#define ANAPARAM_PWR1_SHIFT 20
75
76#define MAC0 0
77#define MAC1 1
78#define MAC2 2
79#define MAC3 3
80#define MAC4 4
81#define MAC5 5
82#define CMD 0x37
83#define CMD_RST_SHIFT 4
84#define CMD_RESERVED_MASK ((1<<1) | (1<<5) | (1<<6) | (1<<7))
85#define CMD_RX_ENABLE_SHIFT 3
86#define CMD_TX_ENABLE_SHIFT 2
87
88#define EPROM_CMD 0x50
89#define EPROM_CMD_RESERVED_MASK ((1<<5)|(1<<4))
90#define EPROM_CMD_OPERATING_MODE_SHIFT 6
91#define EPROM_CMD_OPERATING_MODE_MASK ((1<<7)|(1<<6))
92#define EPROM_CMD_CONFIG 0x3
93#define EPROM_CMD_NORMAL 0
94#define EPROM_CMD_LOAD 1
95#define EPROM_CMD_PROGRAM 2
96#define EPROM_CS_SHIFT 3
97#define EPROM_CK_SHIFT 2
98#define EPROM_W_SHIFT 1
99#define EPROM_R_SHIFT 0
100#define CONFIG2_DMA_POLLING_MODE_SHIFT 3
101#define INTA 0x3e
102#define INTA_TXOVERFLOW (1<<15)
103#define INTA_TIMEOUT (1<<14)
104#define INTA_BEACONTIMEOUT (1<<13)
105#define INTA_ATIM (1<<12)
106#define INTA_BEACONDESCERR (1<<11)
107#define INTA_BEACONDESCOK (1<<10)
108#define INTA_HIPRIORITYDESCERR (1<<9)
109#define INTA_HIPRIORITYDESCOK (1<<8)
110#define INTA_NORMPRIORITYDESCERR (1<<7)
111#define INTA_NORMPRIORITYDESCOK (1<<6)
112#define INTA_RXOVERFLOW (1<<5)
113#define INTA_RXDESCERR (1<<4)
114#define INTA_LOWPRIORITYDESCERR (1<<3)
115#define INTA_LOWPRIORITYDESCOK (1<<2)
116#define INTA_RXCRCERR (1<<1)
117#define INTA_RXOK (1)
118#define INTA_MASK 0x3c
119#define RXRING_ADDR 0xe4 // page 0
120#define PGSELECT 0x5e
121#define PGSELECT_PG_SHIFT 0
122#define RX_CONF 0x44
123#define MAC_FILTER_MASK ((1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<5) | \
124(1<<12) | (1<<18) | (1<<19) | (1<<20) | (1<<21) | (1<<22) | (1<<23))
125#define RX_CHECK_BSSID_SHIFT 23
126#define ACCEPT_PWR_FRAME_SHIFT 22
127#define ACCEPT_MNG_FRAME_SHIFT 20
128#define ACCEPT_CTL_FRAME_SHIFT 19
129#define ACCEPT_DATA_FRAME_SHIFT 18
130#define ACCEPT_ICVERR_FRAME_SHIFT 12
131#define ACCEPT_CRCERR_FRAME_SHIFT 5
132#define ACCEPT_BCAST_FRAME_SHIFT 3
133#define ACCEPT_MCAST_FRAME_SHIFT 2
134#define ACCEPT_ALLMAC_FRAME_SHIFT 0
135#define ACCEPT_NICMAC_FRAME_SHIFT 1
136#define RX_FIFO_THRESHOLD_MASK ((1<<13) | (1<<14) | (1<<15))
137#define RX_FIFO_THRESHOLD_SHIFT 13
138#define RX_FIFO_THRESHOLD_128 3
139#define RX_FIFO_THRESHOLD_256 4
140#define RX_FIFO_THRESHOLD_512 5
141#define RX_FIFO_THRESHOLD_1024 6
142#define RX_FIFO_THRESHOLD_NONE 7
143#define RX_AUTORESETPHY_SHIFT 28
144#define EPROM_TYPE_SHIFT 6
145#define TX_CONF 0x40
146#define TX_CONF_HEADER_AUTOICREMENT_SHIFT 30
147#define TX_LOOPBACK_SHIFT 17
148#define TX_LOOPBACK_MAC 1
149#define TX_LOOPBACK_BASEBAND 2
150#define TX_LOOPBACK_NONE 0
151#define TX_LOOPBACK_CONTINUE 3
152#define TX_LOOPBACK_MASK ((1<<17)|(1<<18))
153#define TX_DPRETRY_SHIFT 0
154#define R8180_MAX_RETRY 255
155#define TX_RTSRETRY_SHIFT 8
156#define TX_NOICV_SHIFT 19
157#define TX_NOCRC_SHIFT 16
158#define TX_DMA_POLLING 0xd9
159#define TX_DMA_POLLING_BEACON_SHIFT 7
160#define TX_DMA_POLLING_HIPRIORITY_SHIFT 6
161#define TX_DMA_POLLING_NORMPRIORITY_SHIFT 5
162#define TX_DMA_POLLING_LOWPRIORITY_SHIFT 4
163#define TX_DMA_STOP_BEACON_SHIFT 3
164#define TX_DMA_STOP_HIPRIORITY_SHIFT 2
165#define TX_DMA_STOP_NORMPRIORITY_SHIFT 1
166#define TX_DMA_STOP_LOWPRIORITY_SHIFT 0
167#define TX_MANAGEPRIORITY_RING_ADDR 0x0C
168#define TX_BKPRIORITY_RING_ADDR 0x10
169#define TX_BEPRIORITY_RING_ADDR 0x14
170#define TX_VIPRIORITY_RING_ADDR 0x20
171#define TX_VOPRIORITY_RING_ADDR 0x24
172#define TX_HIGHPRIORITY_RING_ADDR 0x28
173//AC_VI and Low priority share the sane queue
174#define TX_LOWPRIORITY_RING_ADDR TX_VIPRIORITY_RING_ADDR
175//AC_VO and Norm priority share the same queue
176#define TX_NORMPRIORITY_RING_ADDR TX_VOPRIORITY_RING_ADDR
177
178#define MAX_RX_DMA_MASK ((1<<8) | (1<<9) | (1<<10))
179#define MAX_RX_DMA_2048 7
180#define MAX_RX_DMA_1024 6
181#define MAX_RX_DMA_SHIFT 10
182#define INT_TIMEOUT 0x48
183#define CONFIG3_CLKRUN_SHIFT 2
184#define CONFIG3_ANAPARAM_W_SHIFT 6
185#define ANAPARAM 0x54
186#define BEACON_INTERVAL 0x70
187#define BEACON_INTERVAL_MASK ((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)| \
188(1<<6)|(1<<7)|(1<<8)|(1<<9))
189#define ATIM_MASK ((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7)| \
190(1<<8)|(1<<9))
191#define ATIM 0x72
192#define EPROM_CS_SHIFT 3
193#define EPROM_CK_SHIFT 2
194#define PHY_DELAY 0x78
195#define PHY_CONFIG 0x80
196#define PHY_ADR 0x7c
197#define PHY_READ 0x7e
198#define CARRIER_SENSE_COUNTER 0x79 //byte
199#define SECURITY 0x5f //1209 this is sth wrong
200#define SECURITY_WEP_TX_ENABLE_SHIFT 1
201#define SECURITY_WEP_RX_ENABLE_SHIFT 0
202#define SECURITY_ENCRYP_104 1
203#define SECURITY_ENCRYP_SHIFT 4
204#define SECURITY_ENCRYP_MASK ((1<<4)|(1<<5))
205#define KEY0 0x90 //1209 this is sth wrong
206#define CONFIG2_ANTENNA_SHIFT 6
207#define TX_BEACON_RING_ADDR 0x4c
208#define CONFIG0_WEP40_SHIFT 7
209#define CONFIG0_WEP104_SHIFT 6
210#define AGCRESET_SHIFT 5
211
212
213
214/*
215 * Operational registers offsets in PCI (I/O) space.
216 * RealTek names are used.
217 */
218
219#define IDR0 0x0000
220#define IDR1 0x0001
221#define IDR2 0x0002
222#define IDR3 0x0003
223#define IDR4 0x0004
224#define IDR5 0x0005
225
226/* 0x0006 - 0x0007 - reserved */
227
228#define MAR0 0x0008
229#define MAR1 0x0009
230#define MAR2 0x000A
231#define MAR3 0x000B
232#define MAR4 0x000C
233#define MAR5 0x000D
234#define MAR6 0x000E
235#define MAR7 0x000F
236
237/* 0x0010 - 0x0017 - reserved */
238
239#define TSFTR 0x0018
240#define TSFTR_END 0x001F
241
242#define TLPDA 0x0020
243#define TLPDA_END 0x0023
244#define TNPDA 0x0024
245#define TNPDA_END 0x0027
246#define THPDA 0x0028
247#define THPDA_END 0x002B
248
249#define BSSID 0x002E
250#define BSSID_END 0x0033
251
252#define CR 0x0037
253
254#ifdef CONFIG_RTL8185B
255#define RF_SW_CONFIG 0x8 // store data which is transmitted to RF for driver
256#define RF_SW_CFG_SI BIT1
257#define PIFS 0x2C // PCF InterFrame Spacing Timer Setting.
258#define EIFS 0x2D // Extended InterFrame Space Timer, in unit of 4 us.
259
260#define BRSR 0x34 // Basic rate set
261
262#define IMR 0x006C
263#define ISR 0x003C
264#else
265#define BRSR 0x002C
266#define BRSR_END 0x002D
267
268/* 0x0034 - 0x0034 - reserved */
269#define EIFS 0x0035
270
271#define IMR 0x003C
272#define IMR_END 0x003D
273#define ISR 0x003E
274#define ISR_END 0x003F
275#endif
276
277#define TCR 0x0040
278#define TCR_END 0x0043
279
280#define RCR 0x0044
281#define RCR_END 0x0047
282
283#define TimerInt 0x0048
284#define TimerInt_END 0x004B
285
286#define TBDA 0x004C
287#define TBDA_END 0x004F
288
289#define CR9346 0x0050
290
291#define CONFIG0 0x0051
292#define CONFIG1 0x0052
293#define CONFIG2 0x0053
294
295#define ANA_PARM 0x0054
296#define ANA_PARM_END 0x0x0057
297
298#define MSR 0x0058
299
300#define CONFIG3 0x0059
301#define CONFIG4 0x005A
302#ifdef CONFIG_RTL8185B
303#ifdef CONFIG_RTL818X_S
304 // SD3 szuyitasi: Mac0x57= CC -> B0 Mac0x60= D1 -> C6
305 // Mac0x60 = 0x000004C6 power save parameters
306 #define ANAPARM_ASIC_ON 0xB0054D00
307 #define ANAPARM2_ASIC_ON 0x000004C6
308
309 #define ANAPARM_ON ANAPARM_ASIC_ON
310 #define ANAPARM2_ON ANAPARM2_ASIC_ON
311#else
312 // SD3 CMLin:
313 #define ANAPARM_ASIC_ON 0x45090658
314 #define ANAPARM2_ASIC_ON 0x727f3f52
315
316 #define ANAPARM_ON ANAPARM_ASIC_ON
317 #define ANAPARM2_ON ANAPARM2_ASIC_ON
318#endif
319#endif
320
321#define TESTR 0x005B
322
323/* 0x005C - 0x005D - reserved */
324
325#define PSR 0x005E
326
327/* 0x0060 - 0x006F - reserved */
328
329#define BcnItv 0x0070
330#define BcnItv_END 0x0071
331
332#define AtimWnd 0x0072
333#define AtimWnd_END 0x0073
334
335#define BintrItv 0x0074
336#define BintrItv_END 0x0075
337
338#define AtimtrItv 0x0076
339#define AtimtrItv_END 0x0077
340
341#define PhyDelay 0x0078
342
343#define CRCount 0x0079
344
345/* 0x007A - 0x007B - reserved */
346
347#define PhyAddr 0x007C
348#define PhyDataW 0x007D
349#define PhyDataR 0x007E
350
351#define PhyCFG 0x0080
352#define PhyCFG_END 0x0083
353
354/* following are for rtl8185 */
355#define RFPinsOutput 0x80
356#define RFPinsEnable 0x82
357#define RF_TIMING 0x8c
358#define RFPinsSelect 0x84
359#define ANAPARAM2 0x60
360#define RF_PARA 0x88
361#define RFPinsInput 0x86
362#define GP_ENABLE 0x90
363#define GPIO 0x91
364#define SW_CONTROL_GPIO 0x400
365#define TX_ANTENNA 0x9f
366#define TX_GAIN_OFDM 0x9e
367#define TX_GAIN_CCK 0x9d
368#define WPA_CONFIG 0xb0
369#define TX_AGC_CTL 0x9c
370#define TX_AGC_CTL_PERPACKET_GAIN_SHIFT 0
371#define TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT 1
372#define TX_AGC_CTL_FEEDBACK_ANT 2
373#define RESP_RATE 0x34
374#define SIFS 0xb4
375#define DIFS 0xb5
376
377#define SLOT 0xb6
378#define CW_CONF 0xbc
379#define CW_CONF_PERPACKET_RETRY_SHIFT 1
380#define CW_CONF_PERPACKET_CW_SHIFT 0
381#define CW_VAL 0xbd
382#define MAX_RESP_RATE_SHIFT 4
383#define MIN_RESP_RATE_SHIFT 0
384#define RATE_FALLBACK 0xbe
385/*
386 * 0x0084 - 0x00D3 is selected to page 1 when PSEn bit (bit0, PSR)
387 * is set to 1
388 */
389
390#define Wakeup0 0x0084
391#define Wakeup0_END 0x008B
392
393#define Wakeup1 0x008C
394#define Wakeup1_END 0x0093
395
396#define Wakeup2LD 0x0094
397#define Wakeup2LD_END 0x009B
398#define Wakeup2HD 0x009C
399#define Wakeup2HD_END 0x00A3
400
401#define Wakeup3LD 0x00A4
402#define Wakeup3LD_END 0x00AB
403#define Wakeup3HD 0x00AC
404#define Wakeup3HD_END 0x00B3
405
406#define Wakeup4LD 0x00B4
407#define Wakeup4LD_END 0x00BB
408#define Wakeup4HD 0x00BC
409#define Wakeup4HD_END 0x00C3
410
411#define CRC0 0x00C4
412#define CRC0_END 0x00C5
413#define CRC1 0x00C6
414#define CRC1_END 0x00C7
415#define CRC2 0x00C8
416#define CRC2_END 0x00C9
417#define CRC3 0x00CA
418#define CRC3_END 0x00CB
419#define CRC4 0x00CC
420#define CRC4_END 0x00CD
421
422/* 0x00CE - 0x00D3 - reserved */
423
424
425
426/*
427 * 0x0084 - 0x00D3 is selected to page 0 when PSEn bit (bit0, PSR)
428 * is set to 0
429 */
430
431/* 0x0084 - 0x008F - reserved */
432
433#define DK0 0x0090
434#define DK0_END 0x009F
435#define DK1 0x00A0
436#define DK1_END 0x00AF
437#define DK2 0x00B0
438#define DK2_END 0x00BF
439#define DK3 0x00C0
440#define DK3_END 0x00CF
441
442/* 0x00D0 - 0x00D3 - reserved */
443
444
445
446
447
448/* 0x00D4 - 0x00D7 - reserved */
449
450#define CONFIG5 0x00D8
451
452#define TPPoll 0x00D9
453
454/* 0x00DA - 0x00DB - reserved */
455
456#ifdef CONFIG_RTL818X_S
457#define PHYPR 0xDA //0xDA - 0x0B PHY Parameter Register.
458#endif
459
460#define CWR 0x00DC
461#define CWR_END 0x00DD
462
463#define RetryCTR 0x00DE
464
465/* 0x00DF - 0x00E3 - reserved */
466
467#define RDSAR 0x00E4
468#define RDSAR_END 0x00E7
469
470/* 0x00E8 - 0x00EF - reserved */
471#ifdef CONFIG_RTL818X_S
472#define LED_CONTROL 0xED
473#endif
474
475#define FER 0x00F0
476#define FER_END 0x00F3
477
478#ifdef CONFIG_RTL8185B
479#define FEMR 0x1D4 // Function Event Mask register
480#else
481#define FEMR 0x00F4
482#define FEMR_END 0x00F7
483#endif
484
485#define FPSR 0x00F8
486#define FPSR_END 0x00FB
487
488#define FFER 0x00FC
489#define FFER_END 0x00FF
490
491
492
493/*
494 * Bitmasks for specific register functions.
495 * Names are derived from the register name and function name.
496 *
497 * <REGISTER>_<FUNCTION>[<bit>]
498 *
499 * this leads to some awkward names...
500 */
501
502#define BRSR_BPLCP ((1<< 8))
503#define BRSR_MBR ((1<< 1)|(1<< 0))
504#define BRSR_MBR_8185 ((1<< 11)|(1<< 10)|(1<< 9)|(1<< 8)|(1<< 7)|(1<< 6)|(1<< 5)|(1<< 4)|(1<< 3)|(1<< 2)|(1<< 1)|(1<< 0))
505#define BRSR_MBR0 ((1<< 0))
506#define BRSR_MBR1 ((1<< 1))
507
508#define CR_RST ((1<< 4))
509#define CR_RE ((1<< 3))
510#define CR_TE ((1<< 2))
511#define CR_MulRW ((1<< 0))
512
513#ifdef CONFIG_RTL8185B
514#define IMR_Dot11hInt ((1<< 25)) // 802.11h Measurement Interrupt
515#define IMR_BcnDmaInt ((1<< 24)) // Beacon DMA Interrupt // What differenct between BcnDmaInt and BcnInt???
516#define IMR_WakeInt ((1<< 23)) // Wake Up Interrupt
517#define IMR_TXFOVW ((1<< 22)) // Tx FIFO Overflow Interrupt
518#define IMR_TimeOut1 ((1<< 21)) // Time Out Interrupt 1
519#define IMR_BcnInt ((1<< 20)) // Beacon Time out Interrupt
520#define IMR_ATIMInt ((1<< 19)) // ATIM Time Out Interrupt
521#define IMR_TBDER ((1<< 18)) // Tx Beacon Descriptor Error Interrupt
522#define IMR_TBDOK ((1<< 17)) // Tx Beacon Descriptor OK Interrupt
523#define IMR_THPDER ((1<< 16)) // Tx High Priority Descriptor Error Interrupt
524#define IMR_THPDOK ((1<< 15)) // Tx High Priority Descriptor OK Interrupt
525#define IMR_TVODER ((1<< 14)) // Tx AC_VO Descriptor Error Interrupt
526#define IMR_TVODOK ((1<< 13)) // Tx AC_VO Descriptor OK Interrupt
527#define IMR_FOVW ((1<< 12)) // Rx FIFO Overflow Interrupt
528#define IMR_RDU ((1<< 11)) // Rx Descriptor Unavailable Interrupt
529#define IMR_TVIDER ((1<< 10)) // Tx AC_VI Descriptor Error Interrupt
530#define IMR_TVIDOK ((1<< 9)) // Tx AC_VI Descriptor OK Interrupt
531#define IMR_RER ((1<< 8)) // Rx Error Interrupt
532#define IMR_ROK ((1<< 7)) // Receive OK Interrupt
533#define IMR_TBEDER ((1<< 6)) // Tx AC_BE Descriptor Error Interrupt
534#define IMR_TBEDOK ((1<< 5)) // Tx AC_BE Descriptor OK Interrupt
535#define IMR_TBKDER ((1<< 4)) // Tx AC_BK Descriptor Error Interrupt
536#define IMR_TBKDOK ((1<< 3)) // Tx AC_BK Descriptor OK Interrupt
537#define IMR_RQoSOK ((1<< 2)) // Rx QoS OK Interrupt
538#define IMR_TimeOut2 ((1<< 1)) // Time Out Interrupt 2
539#define IMR_TimeOut3 ((1<< 0)) // Time Out Interrupt 3
540#define IMR_TMGDOK ((1<<30))
541#define ISR_Dot11hInt ((1<< 25)) // 802.11h Measurement Interrupt
542#define ISR_BcnDmaInt ((1<< 24)) // Beacon DMA Interrupt // What differenct between BcnDmaInt and BcnInt???
543#define ISR_WakeInt ((1<< 23)) // Wake Up Interrupt
544#define ISR_TXFOVW ((1<< 22)) // Tx FIFO Overflow Interrupt
545#define ISR_TimeOut1 ((1<< 21)) // Time Out Interrupt 1
546#define ISR_BcnInt ((1<< 20)) // Beacon Time out Interrupt
547#define ISR_ATIMInt ((1<< 19)) // ATIM Time Out Interrupt
548#define ISR_TBDER ((1<< 18)) // Tx Beacon Descriptor Error Interrupt
549#define ISR_TBDOK ((1<< 17)) // Tx Beacon Descriptor OK Interrupt
550#define ISR_THPDER ((1<< 16)) // Tx High Priority Descriptor Error Interrupt
551#define ISR_THPDOK ((1<< 15)) // Tx High Priority Descriptor OK Interrupt
552#define ISR_TVODER ((1<< 14)) // Tx AC_VO Descriptor Error Interrupt
553#define ISR_TVODOK ((1<< 13)) // Tx AC_VO Descriptor OK Interrupt
554#define ISR_FOVW ((1<< 12)) // Rx FIFO Overflow Interrupt
555#define ISR_RDU ((1<< 11)) // Rx Descriptor Unavailable Interrupt
556#define ISR_TVIDER ((1<< 10)) // Tx AC_VI Descriptor Error Interrupt
557#define ISR_TVIDOK ((1<< 9)) // Tx AC_VI Descriptor OK Interrupt
558#define ISR_RER ((1<< 8)) // Rx Error Interrupt
559#define ISR_ROK ((1<< 7)) // Receive OK Interrupt
560#define ISR_TBEDER ((1<< 6)) // Tx AC_BE Descriptor Error Interrupt
561#define ISR_TBEDOK ((1<< 5)) // Tx AC_BE Descriptor OK Interrupt
562#define ISR_TBKDER ((1<< 4)) // Tx AC_BK Descriptor Error Interrupt
563#define ISR_TBKDOK ((1<< 3)) // Tx AC_BK Descriptor OK Interrupt
564#define ISR_RQoSOK ((1<< 2)) // Rx QoS OK Interrupt
565#define ISR_TimeOut2 ((1<< 1)) // Time Out Interrupt 2
566#define ISR_TimeOut3 ((1<< 0)) // Time Out Interrupt 3
567
568//these definition is used for Tx/Rx test temporarily
569#define ISR_TLPDER ISR_TVIDER
570#define ISR_TLPDOK ISR_TVIDOK
571#define ISR_TNPDER ISR_TVODER
572#define ISR_TNPDOK ISR_TVODOK
573#define ISR_TimeOut ISR_TimeOut1
574#define ISR_RXFOVW ISR_FOVW
575
576#else
577#define IMR_TXFOVW ((1<<15))
578#define IMR_TimeOut ((1<<14))
579#define IMR_BcnInt ((1<<13))
580#define IMR_ATIMInt ((1<<12))
581#define IMR_TBDER ((1<<11))
582#define IMR_TBDOK ((1<<10))
583#define IMR_THPDER ((1<< 9))
584#define IMR_THPDOK ((1<< 8))
585#define IMR_TNPDER ((1<< 7))
586#define IMR_TNPDOK ((1<< 6))
587#define IMR_RXFOVW ((1<< 5))
588#define IMR_RDU ((1<< 4))
589#define IMR_TLPDER ((1<< 3))
590#define IMR_TLPDOK ((1<< 2))
591#define IMR_RER ((1<< 1))
592#define IMR_ROK ((1<< 0))
593
594#define ISR_TXFOVW ((1<<15))
595#define ISR_TimeOut ((1<<14))
596#define ISR_BcnInt ((1<<13))
597#define ISR_ATIMInt ((1<<12))
598#define ISR_TBDER ((1<<11))
599#define ISR_TBDOK ((1<<10))
600#define ISR_THPDER ((1<< 9))
601#define ISR_THPDOK ((1<< 8))
602#define ISR_TNPDER ((1<< 7))
603#define ISR_TNPDOK ((1<< 6))
604#define ISR_RXFOVW ((1<< 5))
605#define ISR_RDU ((1<< 4))
606#define ISR_TLPDER ((1<< 3))
607#define ISR_TLPDOK ((1<< 2))
608#define ISR_RER ((1<< 1))
609#define ISR_ROK ((1<< 0))
610#endif
611
612#define HW_VERID_R8180_F 3
613#define HW_VERID_R8180_ABCD 2
614#define HW_VERID_R8185_ABC 4
615#define HW_VERID_R8185_D 5
616#ifdef CONFIG_RTL8185B
617#define HW_VERID_R8185B_B 6
618#endif
619
620#define TCR_CWMIN ((1<<31))
621#define TCR_SWSEQ ((1<<30))
622#define TCR_HWVERID_MASK ((1<<27)|(1<<26)|(1<<25))
623#define TCR_HWVERID_SHIFT 25
624#define TCR_SAT ((1<<24))
625#define TCR_PLCP_LEN TCR_SAT // rtl8180
626#define TCR_MXDMA_MASK ((1<<23)|(1<<22)|(1<<21))
627#define TCR_MXDMA_1024 6
628#define TCR_MXDMA_2048 7
629#define TCR_MXDMA_SHIFT 21
630#define TCR_DISCW ((1<<20))
631#define TCR_ICV ((1<<19))
632#define TCR_LBK ((1<<18)|(1<<17))
633#define TCR_LBK1 ((1<<18))
634#define TCR_LBK0 ((1<<17))
635#define TCR_CRC ((1<<16))
636#define TCR_DPRETRY_MASK ((1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9)|(1<<8))
637#define TCR_RTSRETRY_MASK ((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7))
638#define TCR_PROBE_NOTIMESTAMP_SHIFT 29 //rtl8185
639
640#define RCR_ONLYERLPKT ((1<<31))
641#define RCR_CS_SHIFT 29
642#define RCR_CS_MASK ((1<<30) | (1<<29))
643#define RCR_ENMARP ((1<<28))
644#define RCR_CBSSID ((1<<23))
645#define RCR_APWRMGT ((1<<22))
646#define RCR_ADD3 ((1<<21))
647#define RCR_AMF ((1<<20))
648#define RCR_ACF ((1<<19))
649#define RCR_ADF ((1<<18))
650#define RCR_RXFTH ((1<<15)|(1<<14)|(1<<13))
651#define RCR_RXFTH2 ((1<<15))
652#define RCR_RXFTH1 ((1<<14))
653#define RCR_RXFTH0 ((1<<13))
654#define RCR_AICV ((1<<12))
655#define RCR_MXDMA ((1<<10)|(1<< 9)|(1<< 8))
656#define RCR_MXDMA2 ((1<<10))
657#define RCR_MXDMA1 ((1<< 9))
658#define RCR_MXDMA0 ((1<< 8))
659#define RCR_9356SEL ((1<< 6))
660#define RCR_ACRC32 ((1<< 5))
661#define RCR_AB ((1<< 3))
662#define RCR_AM ((1<< 2))
663#define RCR_APM ((1<< 1))
664#define RCR_AAP ((1<< 0))
665
666#define CR9346_EEM ((1<<7)|(1<<6))
667#define CR9346_EEM1 ((1<<7))
668#define CR9346_EEM0 ((1<<6))
669#define CR9346_EECS ((1<<3))
670#define CR9346_EESK ((1<<2))
671#define CR9346_EED1 ((1<<1))
672#define CR9346_EED0 ((1<<0))
673
674#define CONFIG0_WEP104 ((1<<6))
675#define CONFIG0_LEDGPO_En ((1<<4))
676#define CONFIG0_Aux_Status ((1<<3))
677#define CONFIG0_GL ((1<<1)|(1<<0))
678#define CONFIG0_GL1 ((1<<1))
679#define CONFIG0_GL0 ((1<<0))
680
681#define CONFIG1_LEDS ((1<<7)|(1<<6))
682#define CONFIG1_LEDS1 ((1<<7))
683#define CONFIG1_LEDS0 ((1<<6))
684#define CONFIG1_LWACT ((1<<4))
685#define CONFIG1_MEMMAP ((1<<3))
686#define CONFIG1_IOMAP ((1<<2))
687#define CONFIG1_VPD ((1<<1))
688#define CONFIG1_PMEn ((1<<0))
689
690#define CONFIG2_LCK ((1<<7))
691#define CONFIG2_ANT ((1<<6))
692#define CONFIG2_DPS ((1<<3))
693#define CONFIG2_PAPE_sign ((1<<2))
694#define CONFIG2_PAPE_time ((1<<1)|(1<<0))
695#define CONFIG2_PAPE_time1 ((1<<1))
696#define CONFIG2_PAPE_time0 ((1<<0))
697
698#define CONFIG3_GNTSel ((1<<7))
699#define CONFIG3_PARM_En ((1<<6))
700#define CONFIG3_Magic ((1<<5))
701#define CONFIG3_CardB_En ((1<<3))
702#define CONFIG3_CLKRUN_En ((1<<2))
703#define CONFIG3_FuncRegEn ((1<<1))
704#define CONFIG3_FBtbEn ((1<<0))
705
706#define CONFIG4_VCOPDN ((1<<7))
707#define CONFIG4_PWROFF ((1<<6))
708#define CONFIG4_PWRMGT ((1<<5))
709#define CONFIG4_LWPME ((1<<4))
710#define CONFIG4_LWPTN ((1<<2))
711#define CONFIG4_RFTYPE ((1<<1)|(1<<0))
712#define CONFIG4_RFTYPE1 ((1<<1))
713#define CONFIG4_RFTYPE0 ((1<<0))
714
715#define CONFIG5_TX_FIFO_OK ((1<<7))
716#define CONFIG5_RX_FIFO_OK ((1<<6))
717#define CONFIG5_CALON ((1<<5))
718#define CONFIG5_EACPI ((1<<2))
719#define CONFIG5_LANWake ((1<<1))
720#define CONFIG5_PME_STS ((1<<0))
721
722#define MSR_LINK_MASK ((1<<2)|(1<<3))
723#define MSR_LINK_MANAGED 2
724#define MSR_LINK_NONE 0
725#define MSR_LINK_SHIFT 2
726#define MSR_LINK_ADHOC 1
727#define MSR_LINK_MASTER 3
728
729#define PSR_GPO ((1<<7))
730#define PSR_GPI ((1<<6))
731#define PSR_LEDGPO1 ((1<<5))
732#define PSR_LEDGPO0 ((1<<4))
733#define PSR_UWF ((1<<1))
734#define PSR_PSEn ((1<<0))
735
736#define SCR_KM ((1<<5)|(1<<4))
737#define SCR_KM1 ((1<<5))
738#define SCR_KM0 ((1<<4))
739#define SCR_TXSECON ((1<<1))
740#define SCR_RXSECON ((1<<0))
741
742#define BcnItv_BcnItv (0x01FF)
743
744#define AtimWnd_AtimWnd (0x01FF)
745
746#define BintrItv_BintrItv (0x01FF)
747
748#define AtimtrItv_AtimtrItv (0x01FF)
749
750#define PhyDelay_PhyDelay ((1<<2)|(1<<1)|(1<<0))
751
752#define TPPoll_BQ ((1<<7))
753#define TPPoll_HPQ ((1<<6))
754#define TPPoll_NPQ ((1<<5))
755#define TPPoll_LPQ ((1<<4))
756#define TPPoll_SBQ ((1<<3))
757#define TPPoll_SHPQ ((1<<2))
758#define TPPoll_SNPQ ((1<<1))
759#define TPPoll_SLPQ ((1<<0))
760
761#define CWR_CW (0x01FF)
762
763#define FER_INTR ((1<<15))
764#define FER_GWAKE ((1<< 4))
765
766#define FEMR_INTR ((1<<15))
767#define FEMR_WKUP ((1<<14))
768#define FEMR_GWAKE ((1<< 4))
769
770#define FPSR_INTR ((1<<15))
771#define FPSR_GWAKE ((1<< 4))
772
773#define FFER_INTR ((1<<15))
774#define FFER_GWAKE ((1<< 4))
775
776#ifdef CONFIG_RTL8185B
777// Three wire mode.
778#define SW_THREE_WIRE 0
779#define HW_THREE_WIRE 2
780//RTL8187S by amy
781#define HW_THREE_WIRE_PI 5
782#define HW_THREE_WIRE_SI 6
783//by amy
784#define TCR_LRL_OFFSET 0
785#define TCR_SRL_OFFSET 8
786#define TCR_MXDMA_OFFSET 21
787#define TCR_DISReqQsize_OFFSET 28
788#define TCR_DurProcMode_OFFSET 30
789
790#define RCR_MXDMA_OFFSET 8
791#define RCR_FIFO_OFFSET 13
792
793#define TMGDS 0x0C // Tx Management Descriptor Address
794#define TBKDS 0x10 // Tx AC_BK Descriptor Address
795#define TBEDS 0x14 // Tx AC_BE Descriptor Address
796#define TLPDS 0x20 // Tx AC_VI Descriptor Address
797#define TNPDS 0x24 // Tx AC_VO Descriptor Address
798#define THPDS 0x28 // Tx Hign Priority Descriptor Address
799
800#define TBDS 0x4c // Beacon descriptor queue start address
801
802#define RDSA 0xE4 // Receive descriptor queue start address
803
804#define AckTimeOutReg 0x79 // ACK timeout register, in unit of 4 us.
805
806#define RFTiming 0x8C
807
808#define TPPollStop 0x93
809
810#define TXAGC_CTL 0x9C // <RJ_TODO_8185B> TX_AGC_CONTROL (0x9C seems be removed at 8185B, see p37).
811#define CCK_TXAGC 0x9D
812#define OFDM_TXAGC 0x9E
813#define ANTSEL 0x9F
814
815#define ACM_CONTROL 0x00BF // ACM Control Registe
816
817#define RTL8185B_VER_REG 0xE1
818
819#define IntMig 0xE2 // Interrupt Migration (0xE2 ~ 0xE3)
820
821#define TID_AC_MAP 0xE8 // TID to AC Mapping Register
822
823#define ANAPARAM3 0xEE // <RJ_TODO_8185B> How to use it?
824
825#define AC_VO_PARAM 0xF0 // AC_VO Parameters Record
826#define AC_VI_PARAM 0xF4 // AC_VI Parameters Record
827#define AC_BE_PARAM 0xF8 // AC_BE Parameters Record
828#define AC_BK_PARAM 0xFC // AC_BK Parameters Record
829
830#ifdef CONFIG_RTL818X_S
831#define BcnTimingAdjust 0x16A // Beacon Timing Adjust Register.
832#define GPIOCtrl 0x16B // GPIO Control Register.
833#define PSByGC 0x180 // 0x180 - 0x183 Power Saving by Gated Clock.
834#endif
835#define ARFR 0x1E0 // Auto Rate Fallback Register (0x1e0 ~ 0x1e2)
836
837#define RFSW_CTRL 0x272 // 0x272-0x273.
838#define SW_3W_DB0 0x274 // Software 3-wire data buffer bit 31~0.
839#define SW_3W_DB1 0x278 // Software 3-wire data buffer bit 63~32.
840#define SW_3W_CMD0 0x27C // Software 3-wire Control/Status Register.
841#define SW_3W_CMD1 0x27D // Software 3-wire Control/Status Register.
842
843#ifdef CONFIG_RTL818X_S
844#define PI_DATA_READ 0X360 // 0x360 - 0x361 Parallel Interface Data Register.
845#define SI_DATA_READ 0x362 // 0x362 - 0x363 Serial Interface Data Register.
846#endif
847
848//----------------------------------------------------------------------------
849// 8185B TPPoll bits (offset 0xd9, 1 byte)
850//----------------------------------------------------------------------------
851#define TPPOLL_BQ (0x01 << 7)
852#define TPPOLL_HPQ (0x01 << 6)
853#define TPPOLL_AC_VOQ (0x01 << 5)
854#define TPPOLL_AC_VIQ (0x01 << 4)
855#define TPPOLL_AC_BEQ (0x01 << 3)
856#define TPPOLL_AC_BKQ (0x01 << 2)
857#define TPPOLL_AC_MGQ (0x01 << 1)
858
859//----------------------------------------------------------------------------
860// 8185B TPPollStop bits (offset 0x93, 1 byte)
861//----------------------------------------------------------------------------
862#define TPPOLLSTOP_BQ (0x01 << 7)
863#define TPPOLLSTOP_HPQ (0x01 << 6)
864#define TPPOLLSTOP_AC_VOQ (0x01 << 5)
865#define TPPOLLSTOP_AC_VIQ (0x01 << 4)
866#define TPPOLLSTOP_AC_BEQ (0x01 << 3)
867#define TPPOLLSTOP_AC_BKQ (0x01 << 2)
868#define TPPOLLSTOP_AC_MGQ (0x01 << 1)
869
870
871#define MSR_LINK_ENEDCA (1<<4)
872
873//----------------------------------------------------------------------------
874// 8187B AC_XX_PARAM bits
875//----------------------------------------------------------------------------
876#define AC_PARAM_TXOP_LIMIT_OFFSET 16
877#define AC_PARAM_ECW_MAX_OFFSET 12
878#define AC_PARAM_ECW_MIN_OFFSET 8
879#define AC_PARAM_AIFS_OFFSET 0
880
881//----------------------------------------------------------------------------
882// 8187B ACM_CONTROL bits (Offset 0xBF, 1 Byte)
883//----------------------------------------------------------------------------
884#define VOQ_ACM_EN (0x01 << 7) //BIT7
885#define VIQ_ACM_EN (0x01 << 6) //BIT6
886#define BEQ_ACM_EN (0x01 << 5) //BIT5
887#define ACM_HW_EN (0x01 << 4) //BIT4
888#define TXOPSEL (0x01 << 3) //BIT3
889#define VOQ_ACM_CTL (0x01 << 2) //BIT2 // Set to 1 when AC_VO used time reaches or exceeds the admitted time
890#define VIQ_ACM_CTL (0x01 << 1) //BIT1 // Set to 1 when AC_VI used time reaches or exceeds the admitted time
891#define BEQ_ACM_CTL (0x01 << 0) //BIT0 // Set to 1 when AC_BE used time reaches or exceeds the admitted time
892
893
894//----------------------------------------------------------------------------
895// 8185B SW_3W_CMD bits (Offset 0x27C-0x27D, 16bit)
896//----------------------------------------------------------------------------
897#define SW_3W_CMD0_HOLD ((1<< 7))
898#define SW_3W_CMD1_RE ((1<< 0)) // BIT8
899#define SW_3W_CMD1_WE ((1<< 1)) // BIT9
900#define SW_3W_CMD1_DONE ((1<< 2)) // BIT10
901
902#define BB_HOST_BANG_RW (1<<3)
903
904//----------------------------------------------------------------------------
905// 8185B RATE_FALLBACK_CTL bits (Offset 0xBE, 8bit)
906//----------------------------------------------------------------------------
907#define RATE_FALLBACK_CTL_ENABLE ((1<< 7))
908#define RATE_FALLBACK_CTL_ENABLE_RTSCTS ((1<< 6))
909// Auto rate fallback per 2^n retry.
910#define RATE_FALLBACK_CTL_AUTO_STEP0 0x00
911#define RATE_FALLBACK_CTL_AUTO_STEP1 0x01
912#define RATE_FALLBACK_CTL_AUTO_STEP2 0x02
913#define RATE_FALLBACK_CTL_AUTO_STEP3 0x03
914
915
916#define RTL8225z2_ANAPARAM_OFF 0x55480658
917#define RTL8225z2_ANAPARAM2_OFF 0x72003f70
918//by amy for power save
919#define RF_CHANGE_BY_SW BIT31
920#define RF_CHANGE_BY_HW BIT30
921#define RF_CHANGE_BY_PS BIT29
922#define RF_CHANGE_BY_IPS BIT28
923//by amy for power save
924//by amy for antenna
925#define EEPROM_SW_REVD_OFFSET 0x3f
926// BIT[8-9] is for SW Antenna Diversity. Only the value EEPROM_SW_AD_ENABLE means enable, other values are diable.
927#define EEPROM_SW_AD_MASK 0x0300
928#define EEPROM_SW_AD_ENABLE 0x0100
929
930// BIT[10-11] determine if Antenna 1 is the Default Antenna. Only the value EEPROM_DEF_ANT_1 means TRUE, other values are FALSE.
931#define EEPROM_DEF_ANT_MASK 0x0C00
932#define EEPROM_DEF_ANT_1 0x0400
933//by amy for antenna
934//{by amy 080312
935//0x7C, 0x7D Crystal calibration and Tx Power tracking mechanism. Added by Roger. 2007.12.10.
936#define EEPROM_RSV 0x7C
937#define EEPROM_XTAL_CAL_MASK 0x00FF // 0x7C[7:0], Crystal calibration mask.
938#define EEPROM_XTAL_CAL_XOUT_MASK 0x0F // 0x7C[3:0], Crystal calibration for Xout.
939#define EEPROM_XTAL_CAL_XIN_MASK 0xF0 // 0x7C[7:4], Crystal calibration for Xin.
940#define EEPROM_THERMAL_METER_MASK 0x0F00 // 0x7D[3:0], Thermal meter reference level.
941#define EEPROM_XTAL_CAL_ENABLE 0x1000 // 0x7D[4], Crystal calibration enabled/disabled BIT.
942#define EEPROM_THERMAL_METER_ENABLE 0x2000 // 0x7D[5], Thermal meter enabled/disabled BIT.
943#define EEPROM_CID_RSVD1 0x3F
944#define EN_LPF_CAL 0x238 // Enable LPF Calibration.
945#define PWR_METER_EN BIT1
946// <RJ_TODO_8185B> where are false alarm counters in 8185B?
947#define CCK_FALSE_ALARM 0xD0
948#define OFDM_FALSE_ALARM 0xD2
949//by amy 080312}
950
951//YJ,add for Country IE, 080630
952#define EEPROM_COUNTRY_CODE 0x2E
953//YJ,add,080630,end
954#endif
955
956#endif
diff --git a/drivers/staging/rtl8187se/r8180_max2820.c b/drivers/staging/rtl8187se/r8180_max2820.c
new file mode 100644
index 000000000000..cea08463d5ee
--- /dev/null
+++ b/drivers/staging/rtl8187se/r8180_max2820.c
@@ -0,0 +1,240 @@
1/*
2 This files contains MAXIM MAX2820 radio frontend programming routines.
3
4 This is part of rtl8180 OpenSource driver
5 Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it>
6 Released under the terms of GPL (General Public Licence)
7
8 Parts of this driver are based on the GPL part of the
9 official realtek driver
10
11 Parts of this driver are based on the rtl8180 driver skeleton
12 from Patric Schenke & Andres Salomon
13
14 Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
15
16 NetBSD rtl8180 driver from Dave Young has been really useful to
17 understand how to program the MAXIM radio. Thanks a lot!!!
18
19 'The Deuce' tested this and fixed some bugs.
20
21 Code from rtl8181 project has been useful to me to understand some things.
22
23 We want to tanks the Authors of such projects and the Ndiswrapper
24 project Authors.
25*/
26
27
28#include "r8180.h"
29#include "r8180_hw.h"
30#include "r8180_max2820.h"
31
32
33//#define DEBUG_MAXIM
34
35u32 maxim_chan[] = {
36 0, //dummy channel 0
37 12, //1
38 17, //2
39 22, //3
40 27, //4
41 32, //5
42 37, //6
43 42, //7
44 47, //8
45 52, //9
46 57, //10
47 62, //11
48 67, //12
49 72, //13
50 84, //14
51};
52
53#if 0
54/* maxim expects 4 bit address MSF, then 12 bit data MSF*/
55void write_maxim(struct net_device *dev,u8 adr, u32 data)
56{
57
58 int shift;
59 short bit;
60 u16 word;
61
62 adr = adr &0xf;
63 word = (u16)data & 0xfff;
64 word |= (adr<<12);
65 /*write_nic_dword(dev,PHY_CONFIG,BB_HOST_BANG | BB_HOST_BANG_EN);
66 read_nic_dword(dev,PHY_CONFIG);
67 mdelay(1);
68
69 write_nic_dword(dev,PHY_CONFIG,BB_HOST_BANG | BB_HOST_BANG_EN | BB_HOST_BANG_CLK);
70 read_nic_dword(dev,PHY_CONFIG);
71 mdelay(1);
72 */
73
74 /* MAX2820 will sample data on rising edge of clock */
75 for(shift = 15;shift >=0; shift--){
76 bit = word>>shift & 1;
77
78 write_nic_dword(dev,PHY_CONFIG,BB_HOST_BANG | (bit<<BB_HOST_BANG_DATA));
79
80 read_nic_dword(dev,PHY_CONFIG);
81 mdelay(2);
82
83 write_nic_dword(dev,PHY_CONFIG,BB_HOST_BANG |
84 (bit<<BB_HOST_BANG_DATA) | BB_HOST_BANG_CLK); /* sample data */
85
86 read_nic_dword(dev,PHY_CONFIG);
87 mdelay(1);
88
89 write_nic_dword(dev,PHY_CONFIG,BB_HOST_BANG |
90 (bit<<BB_HOST_BANG_DATA));
91
92 read_nic_dword(dev,PHY_CONFIG);
93 mdelay(2);
94
95 }
96 write_nic_dword(dev,PHY_CONFIG,BB_HOST_BANG | (bit<<BB_HOST_BANG_DATA)|
97 BB_HOST_BANG_EN);
98 read_nic_dword(dev,PHY_CONFIG);
99 mdelay(2);
100
101 /* The shift register fill flush to the requested register the
102 * last 12 bits data shifted in
103 */
104 write_nic_dword(dev,PHY_CONFIG,BB_HOST_BANG | (bit<<BB_HOST_BANG_DATA)|
105 BB_HOST_BANG_EN | BB_HOST_BANG_CLK);
106 read_nic_dword(dev,PHY_CONFIG);
107 mdelay(2);
108
109 write_nic_dword(dev,PHY_CONFIG,BB_HOST_BANG | (bit<<BB_HOST_BANG_DATA)|
110 BB_HOST_BANG_EN);
111 read_nic_dword(dev,PHY_CONFIG);
112 mdelay(2);
113
114
115#ifdef DEBUG_MAXIM
116 DMESG("Writing maxim: %x (adr %x)",phy_config,adr);
117#endif
118
119}
120#endif
121
122void write_maxim(struct net_device *dev,u8 adr, u32 data) {
123 u32 temp;
124 temp = 0x90 + (data & 0xf);
125 temp <<= 16;
126 temp += adr;
127 temp <<= 8;
128 temp += (data >> 4) & 0xff;
129#ifdef DEBUG_MAXIM
130 DMESG("write_maxim: %08x", temp);
131#endif
132 write_nic_dword(dev, PHY_CONFIG, temp);
133 force_pci_posting(dev);
134 mdelay(1);
135}
136
137
138void maxim_write_phy_antenna(struct net_device *dev,short ch)
139{
140 struct r8180_priv *priv = ieee80211_priv(dev);
141 u8 ant;
142
143 ant = MAXIM_ANTENNA;
144 if(priv->antb) /*default antenna is antenna B */
145 ant |= BB_ANTENNA_B;
146 if(ch == 14)
147 ant |= BB_ANTATTEN_CHAN14;
148 write_phy(dev,0x10,ant);
149 //DMESG("BB antenna %x ",ant);
150}
151
152
153void maxim_rf_set_chan(struct net_device *dev, short ch)
154{
155 struct r8180_priv *priv = ieee80211_priv(dev);
156 u32 txpw = 0xff & priv->chtxpwr[ch];
157 u32 chan = maxim_chan[ch];
158
159 /*While philips SA2400 drive the PA bias
160 *seems that for MAXIM we delegate this
161 *to the BB
162 */
163
164 //write_maxim(dev,5,txpw);
165 write_phy(dev,3,txpw);
166
167 maxim_write_phy_antenna(dev,ch);
168 write_maxim(dev,3,chan);
169}
170
171
172void maxim_rf_close(struct net_device *dev)
173{
174 write_phy(dev, 3, 0x8);
175 write_maxim(dev, 1, 0);
176}
177
178
179void maxim_rf_init(struct net_device *dev)
180{
181 struct r8180_priv *priv = ieee80211_priv(dev);
182 u32 anaparam;
183
184 write_nic_byte(dev,PHY_DELAY,0x6); //this is general
185 write_nic_byte(dev,CARRIER_SENSE_COUNTER,0x4c); //this is general
186
187 /*these are maxim specific*/
188 anaparam = read_nic_dword(dev,ANAPARAM);
189 anaparam = anaparam &~ (ANAPARAM_TXDACOFF_SHIFT);
190 anaparam = anaparam &~ANAPARAM_PWR1_MASK;
191 anaparam = anaparam &~ANAPARAM_PWR0_MASK;
192 anaparam |= (MAXIM_ANAPARAM_PWR1_ON<<ANAPARAM_PWR1_SHIFT);
193 anaparam |= (MAXIM_ANAPARAM_PWR0_ON<<ANAPARAM_PWR0_SHIFT);
194
195 //rtl8180_set_anaparam(dev,anaparam);
196
197 /* MAXIM from netbsd driver */
198
199 write_maxim(dev,0, 7); /* test mode as indicated in datasheet*/
200 write_maxim(dev,1, 0x1e); /* enable register*/
201 write_maxim(dev,2, 1); /* synt register */
202
203
204 maxim_rf_set_chan(dev,priv->chan);
205
206 write_maxim(dev,4, 0x313); /* rx register*/
207
208 /* PA is driven directly by the BB, we keep the MAXIM bias
209 * at the highest value in the boubt tha pleacing it to lower
210 * values may introduce some further attenuation somewhere..
211 */
212
213 write_maxim(dev,5, 0xf);
214
215
216 /*baseband configuration*/
217 write_phy(dev,0,0x88); //sys1
218 write_phy(dev,3,0x8); //txagc
219 write_phy(dev,4,0xf8); // lnadet
220 write_phy(dev,5,0x90); // ifagcinit
221 write_phy(dev,6,0x1a); // ifagclimit
222 write_phy(dev,7,0x64); // ifagcdet
223
224 /*Should be done something more here??*/
225
226 maxim_write_phy_antenna(dev,priv->chan);
227
228 write_phy(dev,0x11,0x88); //trl
229 if(priv->diversity)
230 write_phy(dev,0x12,0xc7);
231 else
232 write_phy(dev,0x12,0x47);
233
234 write_phy(dev,0x13,0x9b);
235
236 write_phy(dev,0x19,0x0); //CHESTLIM
237 write_phy(dev,0x1a,0x9f); //CHSQLIM
238
239 maxim_rf_set_chan(dev,priv->chan);
240}
diff --git a/drivers/staging/rtl8187se/r8180_max2820.h b/drivers/staging/rtl8187se/r8180_max2820.h
new file mode 100644
index 000000000000..5d4fb5504841
--- /dev/null
+++ b/drivers/staging/rtl8187se/r8180_max2820.h
@@ -0,0 +1,21 @@
1/*
2 This is part of rtl8180 OpenSource driver
3 Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it>
4 Released under the terms of GPL (General Public Licence)
5
6 Parts of this driver are based on the GPL part of the official realtek driver
7 Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon
8 Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
9
10 We want to tanks the Authors of such projects and the Ndiswrapper project Authors.
11*/
12
13#define MAXIM_ANTENNA 0xb3
14#define MAXIM_ANAPARAM_PWR1_ON 0x8
15#define MAXIM_ANAPARAM_PWR0_ON 0x0
16
17
18void maxim_rf_init(struct net_device *dev);
19void maxim_rf_set_chan(struct net_device *dev,short ch);
20
21void maxim_rf_close(struct net_device *dev);
diff --git a/drivers/staging/rtl8187se/r8180_pm.c b/drivers/staging/rtl8187se/r8180_pm.c
new file mode 100644
index 000000000000..3851b9368356
--- /dev/null
+++ b/drivers/staging/rtl8187se/r8180_pm.c
@@ -0,0 +1,90 @@
1/*
2 Power management interface routines.
3 Written by Mariusz Matuszek.
4 This code is currently just a placeholder for later work and
5 does not do anything useful.
6
7 This is part of rtl8180 OpenSource driver.
8 Copyright (C) Andrea Merello 2004 <andreamrl@tiscali.it>
9 Released under the terms of GPL (General Public Licence)
10*/
11
12#ifdef CONFIG_RTL8180_PM
13
14
15#include "r8180_hw.h"
16#include "r8180_pm.h"
17#include "r8180.h"
18
19int rtl8180_save_state (struct pci_dev *dev, u32 state)
20{
21 printk(KERN_NOTICE "r8180 save state call (state %u).\n", state);
22 return(-EAGAIN);
23}
24
25int rtl8180_suspend (struct pci_dev *pdev, pm_message_t state)
26{
27 struct net_device *dev = pci_get_drvdata(pdev);
28// struct r8180_priv *priv = ieee80211_priv(dev);
29
30 if (!netif_running(dev))
31 goto out_pci_suspend;
32
33 dev->stop(dev);
34
35 netif_device_detach(dev);
36
37out_pci_suspend:
38 pci_save_state(pdev);
39 pci_disable_device(pdev);
40 pci_set_power_state(pdev,pci_choose_state(pdev,state));
41 return 0;
42}
43
44int rtl8180_resume (struct pci_dev *pdev)
45{
46 struct net_device *dev = pci_get_drvdata(pdev);
47// struct r8180_priv *priv = ieee80211_priv(dev);
48 int err;
49 u32 val;
50
51 pci_set_power_state(pdev, PCI_D0);
52
53 err = pci_enable_device(pdev);
54 if(err) {
55 printk(KERN_ERR "%s: pci_enable_device failed on resume\n",
56 dev->name);
57
58 return err;
59 }
60 pci_restore_state(pdev);
61 /*
62 * Suspend/Resume resets the PCI configuration space, so we have to
63 * re-disable the RETRY_TIMEOUT register (0x41) to keep PCI Tx retries
64 * from interfering with C3 CPU state. pci_restore_state won't help
65 * here since it only restores the first 64 bytes pci config header.
66 */
67 pci_read_config_dword(pdev, 0x40, &val);
68 if ((val & 0x0000ff00) != 0)
69 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
70
71 if(!netif_running(dev))
72 goto out;
73
74 dev->open(dev);
75 netif_device_attach(dev);
76out:
77 return 0;
78}
79
80
81int rtl8180_enable_wake (struct pci_dev *dev, u32 state, int enable)
82{
83 printk(KERN_NOTICE "r8180 enable wake call (state %u, enable %d).\n",
84 state, enable);
85 return(-EAGAIN);
86}
87
88
89
90#endif //CONFIG_RTL8180_PM
diff --git a/drivers/staging/rtl8187se/r8180_pm.h b/drivers/staging/rtl8187se/r8180_pm.h
new file mode 100644
index 000000000000..7958b3a734db
--- /dev/null
+++ b/drivers/staging/rtl8187se/r8180_pm.h
@@ -0,0 +1,28 @@
1/*
2 Power management interface routines.
3 Written by Mariusz Matuszek.
4 This code is currently just a placeholder for later work and
5 does not do anything useful.
6
7 This is part of rtl8180 OpenSource driver.
8 Copyright (C) Andrea Merello 2004 <andreamrl@tiscali.it>
9 Released under the terms of GPL (General Public Licence)
10
11*/
12
13#ifdef CONFIG_RTL8180_PM
14
15#ifndef R8180_PM_H
16#define R8180_PM_H
17
18#include <linux/types.h>
19#include <linux/pci.h>
20
21int rtl8180_save_state (struct pci_dev *dev, u32 state);
22int rtl8180_suspend (struct pci_dev *pdev, pm_message_t state);
23int rtl8180_resume (struct pci_dev *pdev);
24int rtl8180_enable_wake (struct pci_dev *dev, u32 state, int enable);
25
26#endif //R8180_PM_H
27
28#endif // CONFIG_RTL8180_PM
diff --git a/drivers/staging/rtl8187se/r8180_rtl8225.c b/drivers/staging/rtl8187se/r8180_rtl8225.c
new file mode 100644
index 000000000000..96ed029ed64a
--- /dev/null
+++ b/drivers/staging/rtl8187se/r8180_rtl8225.c
@@ -0,0 +1,933 @@
1/*
2 This is part of the rtl8180-sa2400 driver
3 released under the GPL (See file COPYING for details).
4 Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
5
6 This files contains programming code for the rtl8225
7 radio frontend.
8
9 *Many* thanks to Realtek Corp. for their great support!
10
11*/
12
13
14
15#include "r8180_hw.h"
16#include "r8180_rtl8225.h"
17
18
19u8 rtl8225_gain[]={
20 0x23,0x88,0x7c,0xa5,// -82dbm
21 0x23,0x88,0x7c,0xb5,// -82dbm
22 0x23,0x88,0x7c,0xc5,// -82dbm
23 0x33,0x80,0x79,0xc5,// -78dbm
24 0x43,0x78,0x76,0xc5,// -74dbm
25 0x53,0x60,0x73,0xc5,// -70dbm
26 0x63,0x58,0x70,0xc5,// -66dbm
27};
28
29#if 0
30u8 rtl8225_init_gain[]={
31 //0x00,0x00,0x00,0x00,//0x00,0x00,0x00,0x00,
32 0x33,0x80,0x6c,0xc5,//0x00,0x49,0x06,0xb5,//Gain = 0 ~ -78dbm
33 0x43,0x78,0x69,0xc5,//0x00,0x45,0x06,0xb1,//Gain = 1 ~ -74dbm
34 0x53,0x60,0x66,0xc5,//0x00,0x41,0x06,0xab,//Gain = 2 ~ -70dbm
35 0x63,0x58,0x63,0xc5,//0x00,0x3d,0x06,0xa5,//Gain = 3 ~ -66dbm
36 0x73,0x50,0x62,0xc5,//0x00,0x39,0x06,0xa1,//Gain = 4 ~ -62dbm
37 0x83,0x43,0x61,0xc5,//0x00,0x35,0x06,0x9b,//Gain = 5 ~ -58dbm
38 0x93,0x38,0x5a,0xc5,//0x00,0x31,0x06,0x99,//Gain = 6 ~ -54dbm
39};
40#endif
41#ifdef CONFIG_RTL818X_S
42u32 rtl8225_chan[] ={
43 0,
44 0x0080, //ch1
45 0x0100, //ch2
46 0x0180, //ch3
47 0x0200, //ch4
48 0x0280,
49 0x0300,
50 0x0380,
51 0x0400,
52 0x0480,
53 0x0500,
54 0x0580,
55 0x0600,
56 0x0680,
57 0x074A, //ch14
58};
59#else
60u32 rtl8225_chan[] = {
61 0, //dummy channel 0
62 0x085c, //1
63 0x08dc, //2
64 0x095c, //3
65 0x09dc, //4
66 0x0a5c, //5
67 0x0adc, //6
68 0x0b5c, //7
69 0x0bdc, //8
70 0x0c5c, //9
71 0x0cdc, //10
72 0x0d5c, //11
73 0x0ddc, //12
74 0x0e5c, //13
75 //0x0f5c, //14
76 0x0f72, // 14
77};
78#endif
79
80u16 rtl8225bcd_rxgain[]={
81 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
82 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
83 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
84 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
85 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
86 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
87 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
88 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
89 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
90 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
91 0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3,
92 0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb
93
94};
95
96
97#if 0
98u16 rtl8225bc_rxgain[]={
99 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
100 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
101 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
102 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
103 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
104 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
105 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
106 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
107 0x0794, 0x0795, 0x0798, 0x0799, 0x039a, 0x039b, 0x039c, 0x039d,
108 0x03a0, 0x03a1, 0x03a2, 0x03a3, 0x03a4, 0x03a5, 0x03a8, 0x03a9,
109 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
110 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
111
112};
113
114
115u16 rtl8225a_rxgain[]={
116 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
117 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
118 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
119 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
120 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
121 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
122 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
123 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
124 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
125 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
126 0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07ad, 0x07ad, 0x07ad, 0x07ad,
127 0x07ad, 0x07ad, 0x07ad, 0x07ad, 0x07ad, 0x07ad, 0x07ad
128};
129#endif
130
131u8 rtl8225_agc[]={
132 0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9d,0x9c,0x9b,0x9a,0x99,0x98,0x97,0x96,
133 0x95,0x94,0x93,0x92,0x91,0x90,0x8f,0x8e,0x8d,0x8c,0x8b,0x8a,0x89,0x88,0x87,0x86,
134 0x85,0x84,0x83,0x82,0x81,0x80,0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38,0x37,0x36,
135 0x35,0x34,0x33,0x32,0x31,0x30,0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28,0x27,0x26,
136 0x25,0x24,0x23,0x22,0x21,0x20,0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18,0x17,0x16,
137 0x15,0x14,0x13,0x12,0x11,0x10,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06,
138 0x05,0x04,0x03,0x02,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
139 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
140};
141
142
143u8 rtl8225_tx_gain_cck_ofdm[]={
144 0x02,0x06,0x0e,0x1e,0x3e,0x7e
145};
146
147
148u8 rtl8225_tx_power_ofdm[]={
149 0x80,0x90,0xa2,0xb5,0xcb,0xe4
150};
151
152
153u8 rtl8225_tx_power_cck_ch14[]={
154 0x18,0x17,0x15,0x0c,0x00,0x00,0x00,0x00,
155 0x1b,0x1a,0x17,0x0e,0x00,0x00,0x00,0x00,
156 0x1f,0x1e,0x1a,0x0f,0x00,0x00,0x00,0x00,
157 0x22,0x21,0x1d,0x11,0x00,0x00,0x00,0x00,
158 0x26,0x25,0x21,0x13,0x00,0x00,0x00,0x00,
159 0x2b,0x2a,0x25,0x15,0x00,0x00,0x00,0x00
160};
161
162
163u8 rtl8225_tx_power_cck[]={
164 0x18,0x17,0x15,0x11,0x0c,0x08,0x04,0x02,
165 0x1b,0x1a,0x17,0x13,0x0e,0x09,0x04,0x02,
166 0x1f,0x1e,0x1a,0x15,0x10,0x0a,0x05,0x02,
167 0x22,0x21,0x1d,0x18,0x11,0x0b,0x06,0x02,
168 0x26,0x25,0x21,0x1b,0x14,0x0d,0x06,0x03,
169 0x2b,0x2a,0x25,0x1e,0x16,0x0e,0x07,0x03
170};
171
172
173void rtl8225_set_gain(struct net_device *dev, short gain)
174{
175 write_phy_ofdm(dev, 0x0d, rtl8225_gain[gain * 4]);
176 write_phy_ofdm(dev, 0x23, rtl8225_gain[gain * 4 + 1]);
177 write_phy_ofdm(dev, 0x1b, rtl8225_gain[gain * 4 + 2]);
178 write_phy_ofdm(dev, 0x1d, rtl8225_gain[gain * 4 + 3]);
179}
180#if 0
181
182void rtl8225_set_gain(struct net_device *dev, short gain)
183{
184 struct r8180_priv *priv = ieee80211_priv(dev);
185
186 rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
187
188 if(priv->card_8185 == 2)
189 write_phy_ofdm(dev, 0x21, 0x27);
190 else
191 write_phy_ofdm(dev, 0x21, 0x37);
192
193 write_phy_ofdm(dev, 0x25, 0x20);
194 write_phy_ofdm(dev, 0x11, 0x6);
195
196 if(priv->card_8185 == 1 && priv->card_8185_Bversion)
197 write_phy_ofdm(dev, 0x27, 0x8);
198 else
199 write_phy_ofdm(dev, 0x27, 0x88);
200
201 write_phy_ofdm(dev, 0x14, 0);
202 write_phy_ofdm(dev, 0x16, 0);
203 write_phy_ofdm(dev, 0x15, 0x40);
204 write_phy_ofdm(dev, 0x17, 0x40);
205
206 write_phy_ofdm(dev, 0x0d, rtl8225_gain[gain * 4]);
207 write_phy_ofdm(dev, 0x23, rtl8225_gain[gain * 4 + 1]);
208 write_phy_ofdm(dev, 0x1b, rtl8225_gain[gain * 4 + 2]);
209 write_phy_ofdm(dev, 0x1d, rtl8225_gain[gain * 4 + 3]);
210 //rtl8225_set_gain_usb(dev, gain);
211}
212#endif
213
214
215void write_rtl8225(struct net_device *dev, u8 adr, u16 data)
216{
217 int i;
218 u16 out,select;
219 u8 bit;
220 u32 bangdata = (data << 4) | (adr & 0xf);
221 struct r8180_priv *priv = ieee80211_priv(dev);
222
223 out = read_nic_word(dev, RFPinsOutput) & 0xfff3;
224
225 write_nic_word(dev,RFPinsEnable,
226 (read_nic_word(dev,RFPinsEnable) | 0x7));
227
228 select = read_nic_word(dev, RFPinsSelect);
229
230 write_nic_word(dev, RFPinsSelect, select | 0x7 |
231 ((priv->card_type == USB) ? 0 : SW_CONTROL_GPIO));
232
233 force_pci_posting(dev);
234 udelay(10);
235
236 write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN );//| 0x1fff);
237
238 force_pci_posting(dev);
239 udelay(2);
240
241 write_nic_word(dev, RFPinsOutput, out);
242
243 force_pci_posting(dev);
244 udelay(10);
245
246
247 for(i=15; i>=0;i--){
248
249 bit = (bangdata & (1<<i)) >> i;
250
251 write_nic_word(dev, RFPinsOutput, bit | out);
252
253 write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
254 write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
255
256 i--;
257 bit = (bangdata & (1<<i)) >> i;
258
259 write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
260 write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
261
262 write_nic_word(dev, RFPinsOutput, bit | out);
263
264 }
265
266 write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN);
267
268 force_pci_posting(dev);
269 udelay(10);
270
271 write_nic_word(dev, RFPinsOutput, out |
272 ((priv->card_type == USB) ? 4 : BB_HOST_BANG_EN));
273
274 write_nic_word(dev, RFPinsSelect, select |
275 ((priv->card_type == USB) ? 0 : SW_CONTROL_GPIO));
276
277 if(priv->card_type == USB)
278 mdelay(2);
279 else
280 rtl8185_rf_pins_enable(dev);
281}
282
283void rtl8225_rf_close(struct net_device *dev)
284{
285 write_rtl8225(dev, 0x4, 0x1f);
286
287 force_pci_posting(dev);
288 mdelay(1);
289
290 rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_OFF);
291 rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_OFF);
292}
293
294void rtl8225_SetTXPowerLevel(struct net_device *dev, short ch)
295{
296 struct r8180_priv *priv = ieee80211_priv(dev);
297
298 int GainIdx;
299 int GainSetting;
300 int i;
301 u8 power;
302 u8 *cck_power_table;
303 u8 max_cck_power_level;
304 u8 max_ofdm_power_level;
305 u8 min_ofdm_power_level;
306 u8 cck_power_level = 0xff & priv->chtxpwr[ch];
307 u8 ofdm_power_level = 0xff & priv->chtxpwr_ofdm[ch];
308
309 if(priv->card_type == USB){
310 max_cck_power_level = 11;
311 max_ofdm_power_level = 25; // 12 -> 25
312 min_ofdm_power_level = 10;
313 }else{
314 max_cck_power_level = 35;
315 max_ofdm_power_level = 35;
316 min_ofdm_power_level = 0;
317 }
318 /* CCK power setting */
319 if(cck_power_level > max_cck_power_level)
320 cck_power_level = max_cck_power_level;
321 GainIdx=cck_power_level % 6;
322 GainSetting=cck_power_level / 6;
323
324 if(ch == 14)
325 cck_power_table = rtl8225_tx_power_cck_ch14;
326 else
327 cck_power_table = rtl8225_tx_power_cck;
328
329// if(priv->card_8185 == 1 && priv->card_8185_Bversion ){
330 /*Ver B*/
331// write_nic_byte(dev, TX_GAIN_CCK, rtl8225_tx_gain_cck_ofdm[GainSetting]);
332// }else{
333 /*Ver C - D */
334 write_nic_byte(dev, TX_GAIN_CCK, rtl8225_tx_gain_cck_ofdm[GainSetting]>>1);
335// }
336
337 for(i=0;i<8;i++){
338
339 power = cck_power_table[GainIdx * 8 + i];
340 write_phy_cck(dev, 0x44 + i, power);
341 }
342
343 /* FIXME Is this delay really needeed ? */
344 force_pci_posting(dev);
345 mdelay(1);
346
347 /* OFDM power setting */
348// Old:
349// if(ofdm_power_level > max_ofdm_power_level)
350// ofdm_power_level = 35;
351// ofdm_power_level += min_ofdm_power_level;
352// Latest:
353 if(ofdm_power_level > (max_ofdm_power_level - min_ofdm_power_level))
354 ofdm_power_level = max_ofdm_power_level;
355 else
356 ofdm_power_level += min_ofdm_power_level;
357 if(ofdm_power_level > 35)
358 ofdm_power_level = 35;
359//
360
361 GainIdx=ofdm_power_level % 6;
362 GainSetting=ofdm_power_level / 6;
363#if 1
364// if(priv->card_type == USB){
365 rtl8185_set_anaparam2(dev,RTL8225_ANAPARAM2_ON);
366
367 write_phy_ofdm(dev,2,0x42);
368 write_phy_ofdm(dev,6,0);
369 write_phy_ofdm(dev,8,0);
370// }
371#endif
372// if(priv->card_8185 == 1 && priv->card_8185_Bversion){
373// /*Ver B*/
374// write_nic_byte(dev, TX_GAIN_OFDM, rtl8225_tx_gain_cck_ofdm[GainSetting]);
375// }else{
376 /*Ver C - D */
377 write_nic_byte(dev, TX_GAIN_OFDM, rtl8225_tx_gain_cck_ofdm[GainSetting]>>1);
378// }
379
380
381 power = rtl8225_tx_power_ofdm[GainIdx];
382
383 write_phy_ofdm(dev, 0x5, power);
384 write_phy_ofdm(dev, 0x7, power);
385
386 force_pci_posting(dev);
387 mdelay(1);
388 //write_nic_byte(dev, TX_AGC_CONTROL,4);
389}
390#if 0
391/* switch between mode B and G */
392void rtl8225_set_mode(struct net_device *dev, short modeb)
393{
394 write_phy_ofdm(dev, 0x15, (modeb ? 0x0 : 0x40));
395 write_phy_ofdm(dev, 0x17, (modeb ? 0x0 : 0x40));
396}
397#endif
398void rtl8225_rf_set_chan(struct net_device *dev, short ch)
399{
400 struct r8180_priv *priv = ieee80211_priv(dev);
401 short gset = (priv->ieee80211->state == IEEE80211_LINKED &&
402 ieee80211_is_54g(priv->ieee80211->current_network)) ||
403 priv->ieee80211->iw_mode == IW_MODE_MONITOR;
404
405 rtl8225_SetTXPowerLevel(dev, ch);
406
407 write_rtl8225(dev, 0x7, rtl8225_chan[ch]);
408
409 force_pci_posting(dev);
410 mdelay(10);
411
412 // A mode sifs 0x44, difs 34-14, slot 9, eifs 23, cwm 3, cwM 7, ctstoself 0x10
413 if(gset){
414 write_nic_byte(dev,SIFS,0x22);// SIFS: 0x22
415 write_nic_byte(dev,DIFS,0x14); //DIFS: 20
416 //write_nic_byte(dev,DIFS,20); //DIFS: 20
417 }else{
418 write_nic_byte(dev,SIFS,0x44);// SIFS: 0x22
419 write_nic_byte(dev,DIFS,50 - 14); //DIFS: 36
420 }
421 if(priv->ieee80211->state == IEEE80211_LINKED &&
422 ieee80211_is_shortslot(priv->ieee80211->current_network))
423 write_nic_byte(dev,SLOT,0x9); //SLOT: 9
424
425 else
426 write_nic_byte(dev,SLOT,0x14); //SLOT: 20 (0x14)
427
428
429 if(gset){
430 write_nic_byte(dev,EIFS,81);//91 - 20); // EIFS: 91 (0x5B)
431 write_nic_byte(dev,CW_VAL,0x73); //CW VALUE: 0x37
432 //DMESG("using G net params");
433 }else{
434 write_nic_byte(dev,EIFS,81); // EIFS: 91 (0x5B)
435 write_nic_byte(dev,CW_VAL,0xa5); //CW VALUE: 0x37
436 //DMESG("using B net params");
437 }
438
439
440}
441
442void rtl8225_host_pci_init(struct net_device *dev)
443{
444 write_nic_word(dev, RFPinsOutput, 0x480);
445
446 rtl8185_rf_pins_enable(dev);
447
448 //if(priv->card_8185 == 2 && priv->enable_gpio0 ) /* version D */
449 //write_nic_word(dev, RFPinsSelect, 0x88);
450 //else
451 write_nic_word(dev, RFPinsSelect, 0x88 | SW_CONTROL_GPIO); /* 0x488 | SW_CONTROL_GPIO */
452
453 write_nic_byte(dev, GP_ENABLE, 0);
454
455 force_pci_posting(dev);
456 mdelay(200);
457
458 write_nic_word(dev, GP_ENABLE, 0xff & (~(1<<6))); /* bit 6 is for RF on/off detection */
459
460
461}
462
463void rtl8225_host_usb_init(struct net_device *dev)
464{
465 #if 0
466 write_nic_byte(dev,RFPinsSelect+1,0);
467
468 write_nic_byte(dev,GPIO,0);
469
470 write_nic_byte_E(dev,0x53,read_nic_byte_E(dev,0x53) | (1<<7));
471
472 write_nic_byte(dev,RFPinsSelect+1,4);
473
474 write_nic_byte(dev,GPIO,0x20);
475
476 write_nic_byte(dev,GP_ENABLE,0);
477
478
479 /* Config BB & RF */
480 write_nic_word(dev, RFPinsOutput, 0x80);
481
482 write_nic_word(dev, RFPinsSelect, 0x80);
483
484 write_nic_word(dev, RFPinsEnable, 0x80);
485
486
487 mdelay(100);
488
489 mdelay(1000);
490#endif
491
492}
493
494void rtl8225_rf_sleep(struct net_device *dev)
495{
496 write_rtl8225(dev,0x4,0xdff);
497 force_pci_posting(dev);
498 mdelay(1);
499 rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_SLEEP);
500 rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_SLEEP);
501 force_pci_posting(dev);
502}
503
504void rtl8225_rf_wakeup(struct net_device *dev)
505{
506 write_rtl8225(dev,0x4,0x9ff);
507 rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
508 rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_ON);
509 force_pci_posting(dev);
510}
511
512void rtl8225_rf_init(struct net_device *dev)
513{
514 struct r8180_priv *priv = ieee80211_priv(dev);
515 int i;
516 short channel = 1;
517 u16 brsr;
518
519 priv->chan = channel;
520
521 rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
522
523
524 if(priv->card_type == USB)
525 rtl8225_host_usb_init(dev);
526 else
527 rtl8225_host_pci_init(dev);
528
529 write_nic_dword(dev, RF_TIMING, 0x000a8008);
530
531 brsr = read_nic_word(dev, BRSR);
532
533 write_nic_word(dev, BRSR, 0xffff);
534
535 #if 0
536 if(priv->card_8185 == 1){/* version C or B */
537 if(priv->card_8185_Bversion) /* version B*/
538 write_nic_dword(dev, RF_PARA, 0x44);
539 else /* version C */
540 write_nic_dword(dev, RF_PARA, 0x100044);
541 }else{ /* version D */
542 if(priv->enable_gpio0)
543 write_nic_dword(dev, RF_PARA, 0x20100044);
544 else /* also USB */
545 write_nic_dword(dev, RF_PARA, 0x100044);
546 }
547 #endif
548
549 write_nic_dword(dev, RF_PARA, 0x100044);
550
551 #if 1 //0->1
552 rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
553 write_nic_byte(dev, CONFIG3, 0x44);
554 rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
555 #endif
556
557 if(priv->card_type == USB){
558 rtl8185_rf_pins_enable(dev);
559
560 mdelay(1000);
561 }
562
563 write_rtl8225(dev, 0x0, 0x67); mdelay(1);
564
565
566 write_rtl8225(dev, 0x1, 0xfe0); mdelay(1);
567
568 write_rtl8225(dev, 0x2, 0x44d); mdelay(1);
569
570 write_rtl8225(dev, 0x3, 0x441); mdelay(1);
571
572 if(priv->card_type == USB)
573 write_rtl8225(dev, 0x4, 0x486);
574 else
575 write_rtl8225(dev, 0x4, 0x8be);
576
577 mdelay(1);
578
579
580 #if 0
581 }else if(priv->phy_ver == 1){
582 /* version A */
583 write_rtl8225(dev, 0x5, 0xbc0 + 2);
584 }else{
585 #endif
586 /* version B & C */
587
588 if(priv->card_type == USB)
589 write_rtl8225(dev, 0x5, 0xbc0);
590 else if(priv->card_type == MINIPCI)
591 write_rtl8225(dev, 0x5, 0xbc0 + 3 +(6<<3));
592 else
593 write_rtl8225(dev, 0x5, 0xbc0 + (6<<3));
594
595 mdelay(1);
596// }
597
598 write_rtl8225(dev, 0x6, 0xae6); mdelay(1);
599
600 write_rtl8225(dev, 0x7, ((priv->card_type == USB)? 0x82a : rtl8225_chan[channel])); mdelay(1);
601
602 write_rtl8225(dev, 0x8, 0x1f); mdelay(1);
603
604 write_rtl8225(dev, 0x9, 0x334); mdelay(1);
605
606 write_rtl8225(dev, 0xa, 0xfd4); mdelay(1);
607
608 write_rtl8225(dev, 0xb, 0x391); mdelay(1);
609
610 write_rtl8225(dev, 0xc, 0x50); mdelay(1);
611
612
613 write_rtl8225(dev, 0xd, 0x6db); mdelay(1);
614
615 write_rtl8225(dev, 0xe, 0x29); mdelay(1);
616
617 write_rtl8225(dev, 0xf, 0x914);
618
619 if(priv->card_type == USB){
620 //force_pci_posting(dev);
621 mdelay(100);
622 }
623
624 write_rtl8225(dev, 0x2, 0xc4d);
625
626 if(priv->card_type == USB){
627 // force_pci_posting(dev);
628 mdelay(200);
629
630 write_rtl8225(dev, 0x2, 0x44d);
631
632 // force_pci_posting(dev);
633 mdelay(100);
634
635 }//End of if(priv->card_type == USB)
636 /* FIXME!! rtl8187 we have to check if calibrarion
637 * is successful and eventually cal. again (repeat
638 * the two write on reg 2)
639 */
640 force_pci_posting(dev);
641
642 mdelay(100); //200 for 8187
643
644 //if(priv->card_type != USB) /* maybe not needed even for 8185 */
645// write_rtl8225(dev, 0x7, rtl8225_chan[channel]);
646
647 write_rtl8225(dev, 0x0, 0x127);
648
649 for(i=0;i<95;i++){
650 write_rtl8225(dev, 0x1, (u8)(i+1));
651
652 #if 0
653 if(priv->phy_ver == 1)
654 /* version A */
655 write_rtl8225(dev, 0x2, rtl8225a_rxgain[i]);
656 else
657 #endif
658 /* version B & C & D*/
659
660 write_rtl8225(dev, 0x2, rtl8225bcd_rxgain[i]);
661 }
662
663 write_rtl8225(dev, 0x0, 0x27);
664
665
666// //if(priv->card_type != USB){
667// write_rtl8225(dev, 0x2, 0x44d);
668// write_rtl8225(dev, 0x7, rtl8225_chan[channel]);
669// write_rtl8225(dev, 0x2, 0x47d);
670//
671// force_pci_posting(dev);
672// mdelay(100);
673//
674// write_rtl8225(dev, 0x2, 0x44d);
675// //}
676
677 write_rtl8225(dev, 0x0, 0x22f);
678
679 if(priv->card_type != USB)
680 rtl8185_rf_pins_enable(dev);
681
682 for(i=0;i<128;i++){
683 write_phy_ofdm(dev, 0xb, rtl8225_agc[i]);
684
685 mdelay(1);
686 write_phy_ofdm(dev, 0xa, (u8)i+ 0x80);
687
688 mdelay(1);
689 }
690
691 force_pci_posting(dev);
692 mdelay(1);
693
694 write_phy_ofdm(dev, 0x0, 0x1); mdelay(1);
695 write_phy_ofdm(dev, 0x1, 0x2); mdelay(1);
696 write_phy_ofdm(dev, 0x2, ((priv->card_type == USB)? 0x42 : 0x62)); mdelay(1);
697 write_phy_ofdm(dev, 0x3, 0x0); mdelay(1);
698 write_phy_ofdm(dev, 0x4, 0x0); mdelay(1);
699 write_phy_ofdm(dev, 0x5, 0x0); mdelay(1);
700 write_phy_ofdm(dev, 0x6, 0x40); mdelay(1);
701 write_phy_ofdm(dev, 0x7, 0x0); mdelay(1);
702 write_phy_ofdm(dev, 0x8, 0x40); mdelay(1);
703 write_phy_ofdm(dev, 0x9, 0xfe); mdelay(1);
704
705 #if 0
706 if(priv->card_type == USB){
707 write_phy_ofdm(dev, 0xa, 0x9);
708 }else{
709 if(priv->card_8185 == 1 && priv->card_8185_Bversion){
710 /* Ver B
711 * maybe later version can accept this also?
712 */
713 write_phy_ofdm(dev, 0xa, 0x6);
714 write_phy_ofdm(dev, 0x18, 0x6f);
715 }else{
716 #endif
717 /* ver C & D */
718 write_phy_ofdm(dev, 0xa, 0x9); mdelay(1);
719
720 //write_phy_ofdm(dev, 0x18, 0xef);
721 // }
722 //}
723 write_phy_ofdm(dev, 0xb, 0x80); mdelay(1);
724
725 write_phy_ofdm(dev, 0xc, 0x1);mdelay(1);
726
727
728 //if(priv->card_type != USB)
729 //write_phy_ofdm(dev, 0xd, 0x33); // <>
730
731 write_phy_ofdm(dev, 0xe, 0xd3);mdelay(1);
732
733
734 #if 0
735 if(priv->card_8185 == 1){
736 if(priv->card_8185_Bversion)
737 write_phy_ofdm(dev, 0xf, 0x20);/*ver B*/
738 else
739 write_phy_ofdm(dev, 0xf, 0x28);/*ver C*/
740 }else{
741 #endif
742 write_phy_ofdm(dev, 0xf, 0x38);mdelay(1);
743/*ver D & 8187*/
744// }
745
746// if(priv->card_8185 == 1 && priv->card_8185_Bversion)
747// write_phy_ofdm(dev, 0x10, 0x04);/*ver B*/
748// else
749 write_phy_ofdm(dev, 0x10, 0x84);mdelay(1);
750/*ver C & D & 8187*/
751
752 write_phy_ofdm(dev, 0x11, 0x06);mdelay(1);
753/*agc resp time 700*/
754
755
756// if(priv->card_8185 == 2){
757 /* Ver D & 8187*/
758 write_phy_ofdm(dev, 0x12, 0x20);mdelay(1);
759
760 write_phy_ofdm(dev, 0x13, 0x20);mdelay(1);
761
762#if 0
763 }else{
764 /* Ver B & C*/
765 write_phy_ofdm(dev, 0x12, 0x0);
766 write_phy_ofdm(dev, 0x13, 0x0);
767 }
768#endif
769 write_phy_ofdm(dev, 0x14, 0x0); mdelay(1);
770 write_phy_ofdm(dev, 0x15, 0x40); mdelay(1);
771 write_phy_ofdm(dev, 0x16, 0x0); mdelay(1);
772 write_phy_ofdm(dev, 0x17, 0x40); mdelay(1);
773
774// if (priv->card_type == USB)
775// write_phy_ofdm(dev, 0x18, 0xef);
776
777 write_phy_ofdm(dev, 0x18, 0xef);mdelay(1);
778
779
780 write_phy_ofdm(dev, 0x19, 0x19); mdelay(1);
781 write_phy_ofdm(dev, 0x1a, 0x20); mdelay(1);
782
783// if (priv->card_type != USB){
784// if(priv->card_8185 == 1 && priv->card_8185_Bversion)
785// write_phy_ofdm(dev, 0x1b, 0x66); /* Ver B */
786// else
787 write_phy_ofdm(dev, 0x1b, 0x76);mdelay(1);
788 /* Ver C & D */ //FIXME:MAYBE not needed
789// }
790
791 write_phy_ofdm(dev, 0x1c, 0x4);mdelay(1);
792
793#if 0
794 if(priv->card_8185 == 1){
795 if(priv->card_8185_Bversion){
796 /*ver B*/
797 write_phy_ofdm(dev, 0x1e, 0x95);
798 write_phy_ofdm(dev, 0x1f, 0x55);
799 }else{
800 /*ver C*/
801 write_phy_ofdm(dev, 0x1e, 0x90);
802 write_phy_ofdm(dev, 0x1f, 0x34);
803
804 }
805 }else{
806#endif
807 /*ver D & 8187*/
808 write_phy_ofdm(dev, 0x1e, 0x95);mdelay(1);
809
810 write_phy_ofdm(dev, 0x1f, 0x75); mdelay(1);
811
812// }
813
814 write_phy_ofdm(dev, 0x20, 0x1f);mdelay(1);
815
816 write_phy_ofdm(dev, 0x21, 0x27);mdelay(1);
817
818 write_phy_ofdm(dev, 0x22, 0x16);mdelay(1);
819
820// if(priv->card_type != USB)
821 //write_phy_ofdm(dev, 0x23, 0x43); //FIXME maybe not needed // <>
822
823 write_phy_ofdm(dev, 0x24, 0x46); mdelay(1);
824 write_phy_ofdm(dev, 0x25, 0x20); mdelay(1);
825 write_phy_ofdm(dev, 0x26, 0x90); mdelay(1);
826#if 0
827 if(priv->card_8185 == 1 && priv->card_8185_Bversion)
828 write_phy_ofdm(dev, 0x27, 0x08); /* Ver B. might work also fo ver C&D ?*/
829 else
830#endif
831 write_phy_ofdm(dev, 0x27, 0x88); mdelay(1);
832/* Ver C & D & 8187*/
833
834 // <> Set init. gain to m74dBm.
835 write_phy_ofdm(dev, 0x0d, 0x43); mdelay(1);
836 write_phy_ofdm(dev, 0x1b, 0x76); mdelay(1);
837 write_phy_ofdm(dev, 0x1d, 0xc5); mdelay(1);
838 write_phy_ofdm(dev, 0x23, 0x78); mdelay(1);
839
840 //if(priv->card_type == USB);
841 // rtl8225_set_gain_usb(dev, 1); /* FIXME this '2' is random */
842
843 write_phy_cck(dev, 0x0, 0x98); mdelay(1);
844 write_phy_cck(dev, 0x3, 0x20); mdelay(1);
845 write_phy_cck(dev, 0x4, 0x7e); mdelay(1);
846 write_phy_cck(dev, 0x5, 0x12); mdelay(1);
847 write_phy_cck(dev, 0x6, 0xfc); mdelay(1);
848#if 0
849 if(priv->card_8185 == 1 && priv->card_8185_Bversion)
850 write_phy_cck(dev, 0x7, 0xd8); /* Ver B */
851 else
852#endif
853 write_phy_cck(dev, 0x7, 0x78);mdelay(1);
854 /* Ver C & D & 8187*/
855
856 write_phy_cck(dev, 0x8, 0x2e);mdelay(1);
857
858 write_phy_cck(dev, 0x10, ((priv->card_type == USB) ? 0x9b: 0x93)); mdelay(1);
859 write_phy_cck(dev, 0x11, 0x88); mdelay(1);
860 write_phy_cck(dev, 0x12, 0x47); mdelay(1);
861#if 0
862 if(priv->card_8185 == 1 && priv->card_8185_Bversion)
863 write_phy_cck(dev, 0x13, 0x98); /* Ver B */
864 else
865#endif
866 write_phy_cck(dev, 0x13, 0xd0); /* Ver C & D & 8187*/
867
868 write_phy_cck(dev, 0x19, 0x0);
869 write_phy_cck(dev, 0x1a, 0xa0);
870 write_phy_cck(dev, 0x1b, 0x8);
871 write_phy_cck(dev, 0x40, 0x86); /* CCK Carrier Sense Threshold */
872
873 write_phy_cck(dev, 0x41, 0x8d);mdelay(1);
874
875
876 write_phy_cck(dev, 0x42, 0x15); mdelay(1);
877 write_phy_cck(dev, 0x43, 0x18); mdelay(1);
878 write_phy_cck(dev, 0x44, 0x1f); mdelay(1);
879 write_phy_cck(dev, 0x45, 0x1e); mdelay(1);
880 write_phy_cck(dev, 0x46, 0x1a); mdelay(1);
881 write_phy_cck(dev, 0x47, 0x15); mdelay(1);
882 write_phy_cck(dev, 0x48, 0x10); mdelay(1);
883 write_phy_cck(dev, 0x49, 0xa); mdelay(1);
884 write_phy_cck(dev, 0x4a, 0x5); mdelay(1);
885 write_phy_cck(dev, 0x4b, 0x2); mdelay(1);
886 write_phy_cck(dev, 0x4c, 0x5);mdelay(1);
887
888
889 write_nic_byte(dev, 0x5b, 0x0d); mdelay(1);
890
891
892
893// <>
894// // TESTR 0xb 8187
895// write_phy_cck(dev, 0x10, 0x93);// & 0xfb);
896//
897// //if(priv->card_type != USB){
898// write_phy_ofdm(dev, 0x2, 0x62);
899// write_phy_ofdm(dev, 0x6, 0x0);
900// write_phy_ofdm(dev, 0x8, 0x0);
901// //}
902
903 rtl8225_SetTXPowerLevel(dev, channel);
904
905 write_phy_cck(dev, 0x10, 0x9b); mdelay(1); /* Rx ant A, 0xdb for B */
906 write_phy_ofdm(dev, 0x26, 0x90); mdelay(1); /* Rx ant A, 0x10 for B */
907
908 rtl8185_tx_antenna(dev, 0x3); /* TX ant A, 0x0 for B */
909
910 /* switch to high-speed 3-wire
911 * last digit. 2 for both cck and ofdm
912 */
913 if(priv->card_type == USB)
914 write_nic_dword(dev, 0x94, 0x3dc00002);
915 else{
916 write_nic_dword(dev, 0x94, 0x15c00002);
917 rtl8185_rf_pins_enable(dev);
918 }
919
920// if(priv->card_type != USB)
921// rtl8225_set_gain(dev, 4); /* FIXME this '1' is random */ // <>
922// rtl8225_set_mode(dev, 1); /* FIXME start in B mode */ // <>
923//
924// /* make sure is waken up! */
925// write_rtl8225(dev,0x4, 0x9ff);
926// rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
927// rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_ON);
928
929 rtl8225_rf_set_chan(dev, priv->chan);
930
931 write_nic_word(dev,BRSR,brsr);
932
933}
diff --git a/drivers/staging/rtl8187se/r8180_rtl8225.h b/drivers/staging/rtl8187se/r8180_rtl8225.h
new file mode 100644
index 000000000000..458de6629ad0
--- /dev/null
+++ b/drivers/staging/rtl8187se/r8180_rtl8225.h
@@ -0,0 +1,44 @@
1/*
2 This is part of the rtl8180-sa2400 driver
3 released under the GPL (See file COPYING for details).
4 Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
5
6 This files contains programming code for the rtl8225
7 radio frontend.
8
9 *Many* thanks to Realtek Corp. for their great support!
10
11*/
12
13#include "r8180.h"
14
15#define RTL8225_ANAPARAM_ON 0xa0000b59
16#define RTL8225_ANAPARAM_OFF 0xa00beb59
17#define RTL8225_ANAPARAM2_OFF 0x840dec11
18#define RTL8225_ANAPARAM2_ON 0x860dec11
19#define RTL8225_ANAPARAM_SLEEP 0xa00bab59
20#define RTL8225_ANAPARAM2_SLEEP 0x840dec11
21
22#ifdef CONFIG_RTL8185B
23void rtl8225z2_rf_init(struct net_device *dev);
24void rtl8225z2_rf_set_chan(struct net_device *dev,short ch);
25void rtl8225z2_rf_close(struct net_device *dev);
26
27void rtl8225_host_pci_init(struct net_device *dev);
28void rtl8225_host_usb_init(struct net_device *dev);
29
30void write_rtl8225(struct net_device *dev, u8 adr, u16 data);
31void RF_WriteReg(struct net_device *dev, u8 offset, u32 data);
32u32 RF_ReadReg(struct net_device *dev, u8 offset);
33#endif
34void rtl8225_rf_init(struct net_device *dev);
35void rtl8225_rf_set_chan(struct net_device *dev,short ch);
36void rtl8225_rf_close(struct net_device *dev);
37void rtl8225_rf_sleep(struct net_device *dev);
38void rtl8225_rf_wakeup(struct net_device *dev);
39void rtl8180_set_mode(struct net_device *dev,int mode);
40void rtl8180_set_mode(struct net_device *dev,int mode);
41bool SetZebraRFPowerState8185(struct net_device *dev,RT_RF_POWER_STATE eRFPowerState);
42void rtl8225z4_rf_sleep(struct net_device *dev);
43void rtl8225z4_rf_wakeup(struct net_device *dev);
44
diff --git a/drivers/staging/rtl8187se/r8180_rtl8225z2.c b/drivers/staging/rtl8187se/r8180_rtl8225z2.c
new file mode 100644
index 000000000000..90a574d46da0
--- /dev/null
+++ b/drivers/staging/rtl8187se/r8180_rtl8225z2.c
@@ -0,0 +1,1587 @@
1/*
2 This is part of the rtl8180-sa2400 driver
3 released under the GPL (See file COPYING for details).
4 Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
5
6 This files contains programming code for the rtl8225
7 radio frontend.
8
9 *Many* thanks to Realtek Corp. for their great support!
10
11*/
12
13#include "r8180_hw.h"
14#include "r8180_rtl8225.h"
15#include "r8180_93cx6.h"
16
17#ifdef ENABLE_DOT11D
18#include "dot11d.h"
19#endif
20
21#ifdef CONFIG_RTL8185B
22
23extern u8 rtl8225_agc[];
24
25extern u32 rtl8225_chan[];
26
27//2005.11.16
28u8 rtl8225z2_threshold[]={
29 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd,
30};
31
32// 0xd 0x19 0x1b 0x21
33u8 rtl8225z2_gain_bg[]={
34 0x23, 0x15, 0xa5, // -82-1dbm
35 0x23, 0x15, 0xb5, // -82-2dbm
36 0x23, 0x15, 0xc5, // -82-3dbm
37 0x33, 0x15, 0xc5, // -78dbm
38 0x43, 0x15, 0xc5, // -74dbm
39 0x53, 0x15, 0xc5, // -70dbm
40 0x63, 0x15, 0xc5, // -66dbm
41};
42
43u8 rtl8225z2_gain_a[]={
44 0x13,0x27,0x5a,//,0x37,// -82dbm
45 0x23,0x23,0x58,//,0x37,// -82dbm
46 0x33,0x1f,0x56,//,0x37,// -82dbm
47 0x43,0x1b,0x54,//,0x37,// -78dbm
48 0x53,0x17,0x51,//,0x37,// -74dbm
49 0x63,0x24,0x4f,//,0x37,// -70dbm
50 0x73,0x0f,0x4c,//,0x37,// -66dbm
51};
52#if 0
53u32 rtl8225_chan[] = {
54 0, //dummy channel 0
55 0x085c, //1
56 0x08dc, //2
57 0x095c, //3
58 0x09dc, //4
59 0x0a5c, //5
60 0x0adc, //6
61 0x0b5c, //7
62 0x0bdc, //8
63 0x0c5c, //9
64 0x0cdc, //10
65 0x0d5c, //11
66 0x0ddc, //12
67 0x0e5c, //13
68 //0x0f5c, //14
69 0x0f72, // 14
70};
71#endif
72
73//-
74u16 rtl8225z2_rxgain[]={
75 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
76 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
77 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
78 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
79 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
80 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
81 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
82 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
83 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
84 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
85 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
86 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
87
88};
89
90//2005.11.16,
91u8 ZEBRA2_CCK_OFDM_GAIN_SETTING[]={
92 0x00,0x01,0x02,0x03,0x04,0x05,
93 0x06,0x07,0x08,0x09,0x0a,0x0b,
94 0x0c,0x0d,0x0e,0x0f,0x10,0x11,
95 0x12,0x13,0x14,0x15,0x16,0x17,
96 0x18,0x19,0x1a,0x1b,0x1c,0x1d,
97 0x1e,0x1f,0x20,0x21,0x22,0x23,
98};
99
100#if 0
101//-
102u8 rtl8225_agc[]={
103 0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9d,0x9c,0x9b,0x9a,0x99,0x98,0x97,0x96,
104 0x95,0x94,0x93,0x92,0x91,0x90,0x8f,0x8e,0x8d,0x8c,0x8b,0x8a,0x89,0x88,0x87,0x86,
105 0x85,0x84,0x83,0x82,0x81,0x80,0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38,0x37,0x36,
106 0x35,0x34,0x33,0x32,0x31,0x30,0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28,0x27,0x26,
107 0x25,0x24,0x23,0x22,0x21,0x20,0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18,0x17,0x16,
108 0x15,0x14,0x13,0x12,0x11,0x10,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06,
109 0x05,0x04,0x03,0x02,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
110 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
111};
112#endif
113/*
114 from 0 to 0x23
115u8 rtl8225_tx_gain_cck_ofdm[]={
116 0x02,0x06,0x0e,0x1e,0x3e,0x7e
117};
118*/
119
120//-
121u8 rtl8225z2_tx_power_ofdm[]={
122 0x42,0x00,0x40,0x00,0x40
123};
124
125
126//-
127u8 rtl8225z2_tx_power_cck_ch14[]={
128 0x36,0x35,0x2e,0x1b,0x00,0x00,0x00,0x00
129};
130
131
132//-
133u8 rtl8225z2_tx_power_cck[]={
134 0x36,0x35,0x2e,0x25,0x1c,0x12,0x09,0x04
135};
136
137
138void rtl8225z2_set_gain(struct net_device *dev, short gain)
139{
140 u8* rtl8225_gain;
141 struct r8180_priv *priv = ieee80211_priv(dev);
142
143 u8 mode = priv->ieee80211->mode;
144
145 if(mode == IEEE_B || mode == IEEE_G)
146 rtl8225_gain = rtl8225z2_gain_bg;
147 else
148 rtl8225_gain = rtl8225z2_gain_a;
149
150 //write_phy_ofdm(dev, 0x0d, rtl8225_gain[gain * 3]);
151 //write_phy_ofdm(dev, 0x19, rtl8225_gain[gain * 3 + 1]);
152 //write_phy_ofdm(dev, 0x1b, rtl8225_gain[gain * 3 + 2]);
153 //2005.11.17, by ch-hsu
154 write_phy_ofdm(dev, 0x0b, rtl8225_gain[gain * 3]);
155 write_phy_ofdm(dev, 0x1b, rtl8225_gain[gain * 3 + 1]);
156 write_phy_ofdm(dev, 0x1d, rtl8225_gain[gain * 3 + 2]);
157 write_phy_ofdm(dev, 0x21, 0x37);
158
159}
160
161#if 0
162
163void rtl8225_set_gain(struct net_device *dev, short gain)
164{
165 struct r8180_priv *priv = ieee80211_priv(dev);
166
167 rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
168
169 if(priv->card_8185 == 2)
170 write_phy_ofdm(dev, 0x21, 0x27);
171 else
172 write_phy_ofdm(dev, 0x21, 0x37);
173
174 write_phy_ofdm(dev, 0x25, 0x20);
175 write_phy_ofdm(dev, 0x11, 0x6);
176
177 if(priv->card_8185 == 1 && priv->card_8185_Bversion)
178 write_phy_ofdm(dev, 0x27, 0x8);
179 else
180 write_phy_ofdm(dev, 0x27, 0x88);
181
182 write_phy_ofdm(dev, 0x14, 0);
183 write_phy_ofdm(dev, 0x16, 0);
184 write_phy_ofdm(dev, 0x15, 0x40);
185 write_phy_ofdm(dev, 0x17, 0x40);
186
187 write_phy_ofdm(dev, 0x0d, rtl8225_gain[gain * 4]);
188 write_phy_ofdm(dev, 0x23, rtl8225_gain[gain * 4 + 1]);
189 write_phy_ofdm(dev, 0x1b, rtl8225_gain[gain * 4 + 2]);
190 write_phy_ofdm(dev, 0x1d, rtl8225_gain[gain * 4 + 3]);
191 //rtl8225_set_gain_usb(dev, gain);
192}
193#endif
194
195u32 read_rtl8225(struct net_device *dev, u8 adr)
196{
197 u32 data2Write = ((u32)(adr & 0x1f)) << 27;
198 u32 dataRead;
199 u32 mask;
200 u16 oval,oval2,oval3,tmp;
201// ThreeWireReg twreg;
202// ThreeWireReg tdata;
203 int i;
204 short bit, rw;
205
206 u8 wLength = 6;
207 u8 rLength = 12;
208 u8 low2high = 0;
209
210 oval = read_nic_word(dev, RFPinsOutput);
211 oval2 = read_nic_word(dev, RFPinsEnable);
212 oval3 = read_nic_word(dev, RFPinsSelect);
213
214 write_nic_word(dev, RFPinsEnable, (oval2|0xf));
215 write_nic_word(dev, RFPinsSelect, (oval3|0xf));
216
217 dataRead = 0;
218
219 oval &= ~0xf;
220
221 write_nic_word(dev, RFPinsOutput, oval | BB_HOST_BANG_EN ); udelay(4);
222
223 write_nic_word(dev, RFPinsOutput, oval ); udelay(5);
224
225 rw = 0;
226
227 mask = (low2high) ? 0x01 : (((u32)0x01)<<(32-1));
228 for(i = 0; i < wLength/2; i++)
229 {
230 bit = ((data2Write&mask) != 0) ? 1 : 0;
231 write_nic_word(dev, RFPinsOutput, bit|oval | rw); udelay(1);
232
233 write_nic_word(dev, RFPinsOutput, bit|oval | BB_HOST_BANG_CLK | rw); udelay(2);
234 write_nic_word(dev, RFPinsOutput, bit|oval | BB_HOST_BANG_CLK | rw); udelay(2);
235
236 mask = (low2high) ? (mask<<1): (mask>>1);
237
238 if(i == 2)
239 {
240 rw = BB_HOST_BANG_RW;
241 write_nic_word(dev, RFPinsOutput, bit|oval | BB_HOST_BANG_CLK | rw); udelay(2);
242 write_nic_word(dev, RFPinsOutput, bit|oval | rw); udelay(2);
243 break;
244 }
245
246 bit = ((data2Write&mask) != 0) ? 1: 0;
247
248 write_nic_word(dev, RFPinsOutput, oval|bit|rw| BB_HOST_BANG_CLK); udelay(2);
249 write_nic_word(dev, RFPinsOutput, oval|bit|rw| BB_HOST_BANG_CLK); udelay(2);
250
251 write_nic_word(dev, RFPinsOutput, oval| bit |rw); udelay(1);
252
253 mask = (low2high) ? (mask<<1) : (mask>>1);
254 }
255
256 //twreg.struc.clk = 0;
257 //twreg.struc.data = 0;
258 write_nic_word(dev, RFPinsOutput, rw|oval); udelay(2);
259 mask = (low2high) ? 0x01 : (((u32)0x01) << (12-1));
260
261 // We must set data pin to HW controled, otherwise RF can't driver it and
262 // value RF register won't be able to read back properly. 2006.06.13, by rcnjko.
263 write_nic_word(dev, RFPinsEnable, (oval2 & (~0x01)));
264
265 for(i = 0; i < rLength; i++)
266 {
267 write_nic_word(dev, RFPinsOutput, rw|oval); udelay(1);
268
269 write_nic_word(dev, RFPinsOutput, rw|oval|BB_HOST_BANG_CLK); udelay(2);
270 write_nic_word(dev, RFPinsOutput, rw|oval|BB_HOST_BANG_CLK); udelay(2);
271 write_nic_word(dev, RFPinsOutput, rw|oval|BB_HOST_BANG_CLK); udelay(2);
272 tmp = read_nic_word(dev, RFPinsInput);
273
274 dataRead |= (tmp & BB_HOST_BANG_CLK ? mask : 0);
275
276 write_nic_word(dev, RFPinsOutput, (rw|oval)); udelay(2);
277
278 mask = (low2high) ? (mask<<1) : (mask>>1);
279 }
280
281 write_nic_word(dev, RFPinsOutput, BB_HOST_BANG_EN|BB_HOST_BANG_RW|oval); udelay(2);
282
283 write_nic_word(dev, RFPinsEnable, oval2);
284 write_nic_word(dev, RFPinsSelect, oval3); // Set To SW Switch
285 write_nic_word(dev, RFPinsOutput, 0x3a0);
286
287 return dataRead;
288
289}
290#if 0
291void write_rtl8225(struct net_device *dev, u8 adr, u16 data)
292{
293 int i;
294 u16 out,select;
295 u8 bit;
296 u32 bangdata = (data << 4) | (adr & 0xf);
297 struct r8180_priv *priv = ieee80211_priv(dev);
298
299 out = read_nic_word(dev, RFPinsOutput) & 0xfff3;
300
301 write_nic_word(dev,RFPinsEnable,
302 (read_nic_word(dev,RFPinsEnable) | 0x7));
303
304 select = read_nic_word(dev, RFPinsSelect);
305
306 write_nic_word(dev, RFPinsSelect, select | 0x7 |
307 ((priv->card_type == USB) ? 0 : SW_CONTROL_GPIO));
308
309 force_pci_posting(dev);
310 udelay(10);
311
312 write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN );//| 0x1fff);
313
314 force_pci_posting(dev);
315 udelay(2);
316
317 write_nic_word(dev, RFPinsOutput, out);
318
319 force_pci_posting(dev);
320 udelay(10);
321
322
323 for(i=15; i>=0;i--){
324
325 bit = (bangdata & (1<<i)) >> i;
326
327 write_nic_word(dev, RFPinsOutput, bit | out);
328
329 write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
330 write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
331
332 i--;
333 bit = (bangdata & (1<<i)) >> i;
334
335 write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
336 write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
337
338 write_nic_word(dev, RFPinsOutput, bit | out);
339
340 }
341
342 write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN);
343
344 force_pci_posting(dev);
345 udelay(10);
346
347 write_nic_word(dev, RFPinsOutput, out |
348 ((priv->card_type == USB) ? 4 : BB_HOST_BANG_EN));
349
350 write_nic_word(dev, RFPinsSelect, select |
351 ((priv->card_type == USB) ? 0 : SW_CONTROL_GPIO));
352
353 if(priv->card_type == USB)
354 mdelay(2);
355 else
356 rtl8185_rf_pins_enable(dev);
357}
358
359#endif
360short rtl8225_is_V_z2(struct net_device *dev)
361{
362 short vz2 = 1;
363 //int i;
364 /* sw to reg pg 1 */
365 //write_rtl8225(dev, 0, 0x1b7);
366 //write_rtl8225(dev, 0, 0x0b7);
367
368 /* reg 8 pg 1 = 23*/
369 //printk(KERN_WARNING "RF Rigisters:\n");
370#if 0
371 for(i = 0; i <= 0xf; i++)
372 printk(KERN_WARNING "%08x,", read_rtl8225(dev, i));
373 //printk(KERN_WARNING "reg[9]@pg1 = 0x%x\n", read_rtl8225(dev, 0x0F));
374
375// printk(KERN_WARNING "RF:\n");
376#endif
377 if( read_rtl8225(dev, 8) != 0x588)
378 vz2 = 0;
379
380 else /* reg 9 pg 1 = 24 */
381 if( read_rtl8225(dev, 9) != 0x700)
382 vz2 = 0;
383
384 /* sw back to pg 0 */
385 write_rtl8225(dev, 0, 0xb7);
386
387 return vz2;
388
389}
390
391#if 0
392void rtl8225_rf_close(struct net_device *dev)
393{
394 write_rtl8225(dev, 0x4, 0x1f);
395
396 force_pci_posting(dev);
397 mdelay(1);
398
399 rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_OFF);
400 rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_OFF);
401}
402#endif
403#if 0
404short rtl8225_rf_set_sens(struct net_device *dev, short sens)
405{
406 if (sens <0 || sens > 6) return -1;
407
408 if(sens > 4)
409 write_rtl8225(dev, 0x0c, 0x850);
410 else
411 write_rtl8225(dev, 0x0c, 0x50);
412
413 sens= 6-sens;
414 rtl8225_set_gain(dev, sens);
415
416 write_phy_cck(dev, 0x41, rtl8225_threshold[sens]);
417 return 0;
418
419}
420#endif
421
422
423void rtl8225z2_rf_close(struct net_device *dev)
424{
425 RF_WriteReg(dev, 0x4, 0x1f);
426
427 force_pci_posting(dev);
428 mdelay(1);
429
430 rtl8180_set_anaparam(dev, RTL8225z2_ANAPARAM_OFF);
431 rtl8185_set_anaparam2(dev, RTL8225z2_ANAPARAM2_OFF);
432}
433
434#ifdef ENABLE_DOT11D
435//
436// Description:
437// Map dBm into Tx power index according to
438// current HW model, for example, RF and PA, and
439// current wireless mode.
440//
441s8
442DbmToTxPwrIdx(
443 struct r8180_priv *priv,
444 WIRELESS_MODE WirelessMode,
445 s32 PowerInDbm
446 )
447{
448 bool bUseDefault = true;
449 s8 TxPwrIdx = 0;
450
451#ifdef CONFIG_RTL818X_S
452 //
453 // 071011, SD3 SY:
454 // OFDM Power in dBm = Index * 0.5 + 0
455 // CCK Power in dBm = Index * 0.25 + 13
456 //
457 if(priv->card_8185 >= VERSION_8187S_B)
458 {
459 s32 tmp = 0;
460
461 if(WirelessMode == WIRELESS_MODE_G)
462 {
463 bUseDefault = false;
464 tmp = (2 * PowerInDbm);
465
466 if(tmp < 0)
467 TxPwrIdx = 0;
468 else if(tmp > 40) // 40 means 20 dBm.
469 TxPwrIdx = 40;
470 else
471 TxPwrIdx = (s8)tmp;
472 }
473 else if(WirelessMode == WIRELESS_MODE_B)
474 {
475 bUseDefault = false;
476 tmp = (4 * PowerInDbm) - 52;
477
478 if(tmp < 0)
479 TxPwrIdx = 0;
480 else if(tmp > 28) // 28 means 20 dBm.
481 TxPwrIdx = 28;
482 else
483 TxPwrIdx = (s8)tmp;
484 }
485 }
486#endif
487
488 //
489 // TRUE if we want to use a default implementation.
490 // We shall set it to FALSE when we have exact translation formular
491 // for target IC. 070622, by rcnjko.
492 //
493 if(bUseDefault)
494 {
495 if(PowerInDbm < 0)
496 TxPwrIdx = 0;
497 else if(PowerInDbm > 35)
498 TxPwrIdx = 35;
499 else
500 TxPwrIdx = (u8)PowerInDbm;
501 }
502
503 return TxPwrIdx;
504}
505#endif
506
507void rtl8225z2_SetTXPowerLevel(struct net_device *dev, short ch)
508{
509 struct r8180_priv *priv = ieee80211_priv(dev);
510
511// int GainIdx;
512// int GainSetting;
513 //int i;
514 //u8 power;
515 //u8 *cck_power_table;
516 u8 max_cck_power_level;
517 //u8 min_cck_power_level;
518 u8 max_ofdm_power_level;
519 u8 min_ofdm_power_level;
520// u8 cck_power_level = 0xff & priv->chtxpwr[ch];//-by amy 080312
521// u8 ofdm_power_level = 0xff & priv->chtxpwr_ofdm[ch];//-by amy 080312
522 char cck_power_level = (char)(0xff & priv->chtxpwr[ch]);//+by amy 080312
523 char ofdm_power_level = (char)(0xff & priv->chtxpwr_ofdm[ch]);//+by amy 080312
524#if 0
525 //
526 // CCX 2 S31, AP control of client transmit power:
527 // 1. We shall not exceed Cell Power Limit as possible as we can.
528 // 2. Tolerance is +/- 5dB.
529 // 3. 802.11h Power Contraint takes higher precedence over CCX Cell Power Limit.
530 //
531 // TODO:
532 // 1. 802.11h power contraint
533 //
534 // 071011, by rcnjko.
535 //
536 if( priv->OpMode == RT_OP_MODE_INFRASTRUCTURE &&
537 priv->bWithCcxCellPwr &&
538 ch == priv->dot11CurrentChannelNumber)
539 {
540 u8 CckCellPwrIdx = DbmToTxPwrIdx(dev, WIRELESS_MODE_B, pMgntInfo->CcxCellPwr);
541 u8 OfdmCellPwrIdx = DbmToTxPwrIdx(dev, WIRELESS_MODE_G, pMgntInfo->CcxCellPwr);
542
543 printk("CCX Cell Limit: %d dBm => CCK Tx power index : %d, OFDM Tx power index: %d\n",
544 priv->CcxCellPwr, CckCellPwrIdx, OfdmCellPwrIdx);
545 printk("EEPROM channel(%d) => CCK Tx power index: %d, OFDM Tx power index: %d\n",
546 channel, CckTxPwrIdx, OfdmTxPwrIdx);
547
548 if(cck_power_level > CckCellPwrIdx)
549 cck_power_level = CckCellPwrIdx;
550 if(ofdm_power_level > OfdmCellPwrIdx)
551 ofdm_power_level = OfdmCellPwrIdx;
552
553 printk("Altered CCK Tx power index : %d, OFDM Tx power index: %d\n",
554 CckTxPwrIdx, OfdmTxPwrIdx);
555 }
556#endif
557#ifdef ENABLE_DOT11D
558 if(IS_DOT11D_ENABLE(priv->ieee80211) &&
559 IS_DOT11D_STATE_DONE(priv->ieee80211) )
560 {
561 //PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(priv->ieee80211);
562 u8 MaxTxPwrInDbm = DOT11D_GetMaxTxPwrInDbm(priv->ieee80211, ch);
563 u8 CckMaxPwrIdx = DbmToTxPwrIdx(priv, WIRELESS_MODE_B, MaxTxPwrInDbm);
564 u8 OfdmMaxPwrIdx = DbmToTxPwrIdx(priv, WIRELESS_MODE_G, MaxTxPwrInDbm);
565
566 //printk("Max Tx Power dBm (%d) => CCK Tx power index : %d, OFDM Tx power index: %d\n", MaxTxPwrInDbm, CckMaxPwrIdx, OfdmMaxPwrIdx);
567
568 //printk("EEPROM channel(%d) => CCK Tx power index: %d, OFDM Tx power index: %d\n",
569 // ch, cck_power_level, ofdm_power_level);
570
571 if(cck_power_level > CckMaxPwrIdx)
572 cck_power_level = CckMaxPwrIdx;
573 if(ofdm_power_level > OfdmMaxPwrIdx)
574 ofdm_power_level = OfdmMaxPwrIdx;
575 }
576
577 //priv->CurrentCckTxPwrIdx = cck_power_level;
578 //priv->CurrentOfdmTxPwrIdx = ofdm_power_level;
579#endif
580
581 max_cck_power_level = 15;
582 max_ofdm_power_level = 25; // 12 -> 25
583 min_ofdm_power_level = 10;
584
585#ifdef CONFIG_RTL8185B
586#ifdef CONFIG_RTL818X_S
587
588 if(cck_power_level > 35)
589 {
590 cck_power_level = 35;
591 }
592 //
593 // Set up CCK TXAGC. suggested by SD3 SY.
594 //
595 write_nic_byte(dev, CCK_TXAGC, (ZEBRA2_CCK_OFDM_GAIN_SETTING[(u8)cck_power_level]) );
596 //printk("CCK TX power is %x\n", (ZEBRA2_CCK_OFDM_GAIN_SETTING[cck_power_level]));
597 force_pci_posting(dev);
598 mdelay(1);
599#else
600
601 /* CCK power setting */
602 if(cck_power_level > max_cck_power_level)
603 cck_power_level = max_cck_power_level;
604
605 cck_power_level += priv->cck_txpwr_base;
606
607 if(cck_power_level > 35)
608 cck_power_level = 35;
609
610 if(ch == 14)
611 cck_power_table = rtl8225z2_tx_power_cck_ch14;
612 else
613 cck_power_table = rtl8225z2_tx_power_cck;
614
615
616 for(i=0;i<8;i++){
617
618 power = cck_power_table[i];
619 write_phy_cck(dev, 0x44 + i, power);
620 }
621
622 //write_nic_byte(dev, TX_GAIN_CCK, power);
623 //2005.11.17,
624 write_nic_byte(dev, CCK_TXAGC, ZEBRA2_CCK_OFDM_GAIN_SETTING[(u8)cck_power_level]);
625
626 force_pci_posting(dev);
627 mdelay(1);
628#endif
629#endif
630 /* OFDM power setting */
631// Old:
632// if(ofdm_power_level > max_ofdm_power_level)
633// ofdm_power_level = 35;
634// ofdm_power_level += min_ofdm_power_level;
635// Latest:
636/* if(ofdm_power_level > (max_ofdm_power_level - min_ofdm_power_level))
637 ofdm_power_level = max_ofdm_power_level;
638 else
639 ofdm_power_level += min_ofdm_power_level;
640
641 ofdm_power_level += priv->ofdm_txpwr_base;
642*/
643 if(ofdm_power_level > 35)
644 ofdm_power_level = 35;
645
646// rtl8185_set_anaparam2(dev,RTL8225_ANAPARAM2_ON);
647
648 //rtl8185_set_anaparam2(dev, ANAPARM2_ASIC_ON);
649
650 if (priv->up == 0) {
651 //must add these for rtl8185B down, xiong-2006-11-21
652 write_phy_ofdm(dev,2,0x42);
653 write_phy_ofdm(dev,5,0);
654 write_phy_ofdm(dev,6,0x40);
655 write_phy_ofdm(dev,7,0);
656 write_phy_ofdm(dev,8,0x40);
657 }
658
659 //write_nic_byte(dev, TX_GAIN_OFDM, ofdm_power_level);
660 //2005.11.17,
661#ifdef CONFIG_RTL818X_S
662 write_nic_byte(dev, OFDM_TXAGC, ZEBRA2_CCK_OFDM_GAIN_SETTING[(u8)ofdm_power_level]);
663#else
664 write_nic_byte(dev, OFDM_TXAGC, ZEBRA2_CCK_OFDM_GAIN_SETTING[(u8)ofdm_power_level]*2);
665#endif
666 if(ofdm_power_level<=11)
667 {
668// write_nic_dword(dev,PHY_ADR,0x00005c87);
669// write_nic_dword(dev,PHY_ADR,0x00005c89);
670 write_phy_ofdm(dev,0x07,0x5c);
671 write_phy_ofdm(dev,0x09,0x5c);
672 }
673 if(ofdm_power_level<=17)
674 {
675// write_nic_dword(dev,PHY_ADR,0x00005487);
676// write_nic_dword(dev,PHY_ADR,0x00005489);
677 write_phy_ofdm(dev,0x07,0x54);
678 write_phy_ofdm(dev,0x09,0x54);
679 }
680 else
681 {
682// write_nic_dword(dev,PHY_ADR,0x00005087);
683// write_nic_dword(dev,PHY_ADR,0x00005089);
684 write_phy_ofdm(dev,0x07,0x50);
685 write_phy_ofdm(dev,0x09,0x50);
686 }
687 force_pci_posting(dev);
688 mdelay(1);
689
690}
691#if 0
692/* switch between mode B and G */
693void rtl8225_set_mode(struct net_device *dev, short modeb)
694{
695 write_phy_ofdm(dev, 0x15, (modeb ? 0x0 : 0x40));
696 write_phy_ofdm(dev, 0x17, (modeb ? 0x0 : 0x40));
697}
698#endif
699
700void rtl8225z2_rf_set_chan(struct net_device *dev, short ch)
701{
702/*
703 short gset = (priv->ieee80211->state == IEEE80211_LINKED &&
704 ieee80211_is_54g(priv->ieee80211->current_network)) ||
705 priv->ieee80211->iw_mode == IW_MODE_MONITOR;
706*/
707 rtl8225z2_SetTXPowerLevel(dev, ch);
708
709 RF_WriteReg(dev, 0x7, rtl8225_chan[ch]);
710
711 //YJ,add,080828, if set channel failed, write again
712 if((RF_ReadReg(dev, 0x7) & 0x0F80) != rtl8225_chan[ch])
713 {
714 RF_WriteReg(dev, 0x7, rtl8225_chan[ch]);
715 }
716
717 mdelay(1);
718
719 force_pci_posting(dev);
720 mdelay(10);
721//deleted by David : 2006/8/9
722#if 0
723 write_nic_byte(dev,SIFS,0x22);// SIFS: 0x22
724
725 if(gset)
726 write_nic_byte(dev,DIFS,20); //DIFS: 20
727 else
728 write_nic_byte(dev,DIFS,0x24); //DIFS: 36
729
730 if(priv->ieee80211->state == IEEE80211_LINKED &&
731 ieee80211_is_shortslot(priv->ieee80211->current_network))
732 write_nic_byte(dev,SLOT,0x9); //SLOT: 9
733
734 else
735 write_nic_byte(dev,SLOT,0x14); //SLOT: 20 (0x14)
736
737
738 if(gset){
739 write_nic_byte(dev,EIFS,91 - 20); // EIFS: 91 (0x5B)
740 write_nic_byte(dev,CW_VAL,0x73); //CW VALUE: 0x37
741 //DMESG("using G net params");
742 }else{
743 write_nic_byte(dev,EIFS,91 - 0x24); // EIFS: 91 (0x5B)
744 write_nic_byte(dev,CW_VAL,0xa5); //CW VALUE: 0x37
745 //DMESG("using B net params");
746 }
747#endif
748
749}
750#if 0
751void rtl8225_host_pci_init(struct net_device *dev)
752{
753 write_nic_word(dev, RFPinsOutput, 0x480);
754
755 rtl8185_rf_pins_enable(dev);
756
757 //if(priv->card_8185 == 2 && priv->enable_gpio0 ) /* version D */
758 //write_nic_word(dev, RFPinsSelect, 0x88);
759 //else
760 write_nic_word(dev, RFPinsSelect, 0x88 | SW_CONTROL_GPIO); /* 0x488 | SW_CONTROL_GPIO */
761
762 write_nic_byte(dev, GP_ENABLE, 0);
763
764 force_pci_posting(dev);
765 mdelay(200);
766
767 write_nic_word(dev, GP_ENABLE, 0xff & (~(1<<6))); /* bit 6 is for RF on/off detection */
768
769
770}
771
772void rtl8225_host_usb_init(struct net_device *dev)
773{
774 write_nic_byte(dev,RFPinsSelect+1,0);
775
776 write_nic_byte(dev,GPIO,0);
777
778 write_nic_byte_E(dev,0x53,read_nic_byte_E(dev,0x53) | (1<<7));
779
780 write_nic_byte(dev,RFPinsSelect+1,4);
781
782 write_nic_byte(dev,GPIO,0x20);
783
784 write_nic_byte(dev,GP_ENABLE,0);
785
786
787 /* Config BB & RF */
788 write_nic_word(dev, RFPinsOutput, 0x80);
789
790 write_nic_word(dev, RFPinsSelect, 0x80);
791
792 write_nic_word(dev, RFPinsEnable, 0x80);
793
794
795 mdelay(100);
796
797 mdelay(1000);
798
799}
800#endif
801void rtl8225z2_rf_init(struct net_device *dev)
802{
803 struct r8180_priv *priv = ieee80211_priv(dev);
804 int i;
805 short channel = 1;
806 u16 brsr;
807 u32 data,addr;
808
809 priv->chan = channel;
810
811// rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
812
813
814 if(priv->card_type == USB)
815 rtl8225_host_usb_init(dev);
816 else
817 rtl8225_host_pci_init(dev);
818
819 write_nic_dword(dev, RF_TIMING, 0x000a8008);
820
821 brsr = read_nic_word(dev, BRSR);
822
823 write_nic_word(dev, BRSR, 0xffff);
824
825
826 write_nic_dword(dev, RF_PARA, 0x100044);
827
828 #if 1 //0->1
829 rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
830 write_nic_byte(dev, CONFIG3, 0x44);
831 rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
832 #endif
833
834
835 rtl8185_rf_pins_enable(dev);
836
837// mdelay(1000);
838
839 write_rtl8225(dev, 0x0, 0x2bf); mdelay(1);
840
841
842 write_rtl8225(dev, 0x1, 0xee0); mdelay(1);
843
844 write_rtl8225(dev, 0x2, 0x44d); mdelay(1);
845
846 write_rtl8225(dev, 0x3, 0x441); mdelay(1);
847
848
849 write_rtl8225(dev, 0x4, 0x8c3);mdelay(1);
850
851
852
853 write_rtl8225(dev, 0x5, 0xc72);mdelay(1);
854// }
855
856 write_rtl8225(dev, 0x6, 0xe6); mdelay(1);
857
858 write_rtl8225(dev, 0x7, ((priv->card_type == USB)? 0x82a : rtl8225_chan[channel])); mdelay(1);
859
860 write_rtl8225(dev, 0x8, 0x3f); mdelay(1);
861
862 write_rtl8225(dev, 0x9, 0x335); mdelay(1);
863
864 write_rtl8225(dev, 0xa, 0x9d4); mdelay(1);
865
866 write_rtl8225(dev, 0xb, 0x7bb); mdelay(1);
867
868 write_rtl8225(dev, 0xc, 0x850); mdelay(1);
869
870
871 write_rtl8225(dev, 0xd, 0xcdf); mdelay(1);
872
873 write_rtl8225(dev, 0xe, 0x2b); mdelay(1);
874
875 write_rtl8225(dev, 0xf, 0x114);
876
877
878 mdelay(100);
879
880
881 //if(priv->card_type != USB) /* maybe not needed even for 8185 */
882// write_rtl8225(dev, 0x7, rtl8225_chan[channel]);
883
884 write_rtl8225(dev, 0x0, 0x1b7);
885
886 for(i=0;i<95;i++){
887 write_rtl8225(dev, 0x1, (u8)(i+1));
888
889 #if 0
890 if(priv->phy_ver == 1)
891 /* version A */
892 write_rtl8225(dev, 0x2, rtl8225a_rxgain[i]);
893 else
894 #endif
895 /* version B & C & D*/
896
897 write_rtl8225(dev, 0x2, rtl8225z2_rxgain[i]);
898 }
899 write_rtl8225(dev, 0x3, 0x80);
900 write_rtl8225(dev, 0x5, 0x4);
901
902 write_rtl8225(dev, 0x0, 0xb7);
903
904 write_rtl8225(dev, 0x2, 0xc4d);
905
906 if(priv->card_type == USB){
907 // force_pci_posting(dev);
908 mdelay(200);
909
910 write_rtl8225(dev, 0x2, 0x44d);
911
912 // force_pci_posting(dev);
913 mdelay(100);
914
915 }//End of if(priv->card_type == USB)
916 /* FIXME!! rtl8187 we have to check if calibrarion
917 * is successful and eventually cal. again (repeat
918 * the two write on reg 2)
919 */
920 // Check for calibration status, 2005.11.17,
921 data = read_rtl8225(dev, 6);
922 if (!(data&0x00000080))
923 {
924 write_rtl8225(dev, 0x02, 0x0c4d);
925 force_pci_posting(dev); mdelay(200);
926 write_rtl8225(dev, 0x02, 0x044d);
927 force_pci_posting(dev); mdelay(100);
928 data = read_rtl8225(dev, 6);
929 if (!(data&0x00000080))
930 {
931 DMESGW("RF Calibration Failed!!!!\n");
932 }
933 }
934 //force_pci_posting(dev);
935
936 mdelay(200); //200 for 8187
937
938
939// //if(priv->card_type != USB){
940// write_rtl8225(dev, 0x2, 0x44d);
941// write_rtl8225(dev, 0x7, rtl8225_chan[channel]);
942// write_rtl8225(dev, 0x2, 0x47d);
943//
944// force_pci_posting(dev);
945// mdelay(100);
946//
947// write_rtl8225(dev, 0x2, 0x44d);
948// //}
949
950 write_rtl8225(dev, 0x0, 0x2bf);
951
952 if(priv->card_type != USB)
953 rtl8185_rf_pins_enable(dev);
954 //set up ZEBRA AGC table, 2005.11.17,
955 for(i=0;i<128;i++){
956 data = rtl8225_agc[i];
957
958 addr = i + 0x80; //enable writing AGC table
959 write_phy_ofdm(dev, 0xb, data);
960
961 mdelay(1);
962 write_phy_ofdm(dev, 0xa, addr);
963
964 mdelay(1);
965 }
966#if 0
967 for(i=0;i<128;i++){
968 write_phy_ofdm(dev, 0xb, rtl8225_agc[i]);
969
970 mdelay(1);
971 write_phy_ofdm(dev, 0xa, (u8)i+ 0x80);
972
973 mdelay(1);
974 }
975#endif
976
977 force_pci_posting(dev);
978 mdelay(1);
979
980 write_phy_ofdm(dev, 0x0, 0x1); mdelay(1);
981 write_phy_ofdm(dev, 0x1, 0x2); mdelay(1);
982 write_phy_ofdm(dev, 0x2, ((priv->card_type == USB)? 0x42 : 0x62)); mdelay(1);
983 write_phy_ofdm(dev, 0x3, 0x0); mdelay(1);
984 write_phy_ofdm(dev, 0x4, 0x0); mdelay(1);
985 write_phy_ofdm(dev, 0x5, 0x0); mdelay(1);
986 write_phy_ofdm(dev, 0x6, 0x40); mdelay(1);
987 write_phy_ofdm(dev, 0x7, 0x0); mdelay(1);
988 write_phy_ofdm(dev, 0x8, 0x40); mdelay(1);
989 write_phy_ofdm(dev, 0x9, 0xfe); mdelay(1);
990
991 write_phy_ofdm(dev, 0xa, 0x8); mdelay(1);
992
993 //write_phy_ofdm(dev, 0x18, 0xef);
994 // }
995 //}
996 write_phy_ofdm(dev, 0xb, 0x80); mdelay(1);
997
998 write_phy_ofdm(dev, 0xc, 0x1);mdelay(1);
999
1000
1001 //if(priv->card_type != USB)
1002 write_phy_ofdm(dev, 0xd, 0x43);
1003
1004 write_phy_ofdm(dev, 0xe, 0xd3);mdelay(1);
1005
1006
1007 #if 0
1008 if(priv->card_8185 == 1){
1009 if(priv->card_8185_Bversion)
1010 write_phy_ofdm(dev, 0xf, 0x20);/*ver B*/
1011 else
1012 write_phy_ofdm(dev, 0xf, 0x28);/*ver C*/
1013 }else{
1014 #endif
1015 write_phy_ofdm(dev, 0xf, 0x38);mdelay(1);
1016/*ver D & 8187*/
1017// }
1018
1019// if(priv->card_8185 == 1 && priv->card_8185_Bversion)
1020// write_phy_ofdm(dev, 0x10, 0x04);/*ver B*/
1021// else
1022 write_phy_ofdm(dev, 0x10, 0x84);mdelay(1);
1023/*ver C & D & 8187*/
1024
1025 write_phy_ofdm(dev, 0x11, 0x07);mdelay(1);
1026/*agc resp time 700*/
1027
1028
1029// if(priv->card_8185 == 2){
1030 /* Ver D & 8187*/
1031 write_phy_ofdm(dev, 0x12, 0x20);mdelay(1);
1032
1033 write_phy_ofdm(dev, 0x13, 0x20);mdelay(1);
1034
1035#if 0
1036 }else{
1037 /* Ver B & C*/
1038 write_phy_ofdm(dev, 0x12, 0x0);
1039 write_phy_ofdm(dev, 0x13, 0x0);
1040 }
1041#endif
1042 write_phy_ofdm(dev, 0x14, 0x0); mdelay(1);
1043 write_phy_ofdm(dev, 0x15, 0x40); mdelay(1);
1044 write_phy_ofdm(dev, 0x16, 0x0); mdelay(1);
1045 write_phy_ofdm(dev, 0x17, 0x40); mdelay(1);
1046
1047// if (priv->card_type == USB)
1048// write_phy_ofdm(dev, 0x18, 0xef);
1049
1050 write_phy_ofdm(dev, 0x18, 0xef);mdelay(1);
1051
1052
1053 write_phy_ofdm(dev, 0x19, 0x19); mdelay(1);
1054 write_phy_ofdm(dev, 0x1a, 0x20); mdelay(1);
1055 write_phy_ofdm(dev, 0x1b, 0x15);mdelay(1);
1056
1057 write_phy_ofdm(dev, 0x1c, 0x4);mdelay(1);
1058
1059 write_phy_ofdm(dev, 0x1d, 0xc5);mdelay(1); //2005.11.17,
1060
1061 write_phy_ofdm(dev, 0x1e, 0x95);mdelay(1);
1062
1063 write_phy_ofdm(dev, 0x1f, 0x75); mdelay(1);
1064
1065// }
1066
1067 write_phy_ofdm(dev, 0x20, 0x1f);mdelay(1);
1068
1069 write_phy_ofdm(dev, 0x21, 0x17);mdelay(1);
1070
1071 write_phy_ofdm(dev, 0x22, 0x16);mdelay(1);
1072
1073// if(priv->card_type != USB)
1074 write_phy_ofdm(dev, 0x23, 0x80);mdelay(1); //FIXME maybe not needed // <>
1075
1076 write_phy_ofdm(dev, 0x24, 0x46); mdelay(1);
1077 write_phy_ofdm(dev, 0x25, 0x00); mdelay(1);
1078 write_phy_ofdm(dev, 0x26, 0x90); mdelay(1);
1079
1080 write_phy_ofdm(dev, 0x27, 0x88); mdelay(1);
1081
1082
1083 // <> Set init. gain to m74dBm.
1084
1085 rtl8225z2_set_gain(dev,4);
1086
1087 write_phy_cck(dev, 0x0, 0x98); mdelay(1);
1088 write_phy_cck(dev, 0x3, 0x20); mdelay(1);
1089 write_phy_cck(dev, 0x4, 0x7e); mdelay(1);
1090 write_phy_cck(dev, 0x5, 0x12); mdelay(1);
1091 write_phy_cck(dev, 0x6, 0xfc); mdelay(1);
1092
1093 write_phy_cck(dev, 0x7, 0x78);mdelay(1);
1094 /* Ver C & D & 8187*/
1095
1096 write_phy_cck(dev, 0x8, 0x2e);mdelay(1);
1097
1098 write_phy_cck(dev, 0x10, ((priv->card_type == USB) ? 0x9b: 0x93)); mdelay(1);
1099 write_phy_cck(dev, 0x11, 0x88); mdelay(1);
1100 write_phy_cck(dev, 0x12, 0x47); mdelay(1);
1101#if 0
1102 if(priv->card_8185 == 1 && priv->card_8185_Bversion)
1103 write_phy_cck(dev, 0x13, 0x98); /* Ver B */
1104 else
1105#endif
1106 write_phy_cck(dev, 0x13, 0xd0); /* Ver C & D & 8187*/
1107
1108 write_phy_cck(dev, 0x19, 0x0);
1109 write_phy_cck(dev, 0x1a, 0xa0);
1110 write_phy_cck(dev, 0x1b, 0x8);
1111 write_phy_cck(dev, 0x40, 0x86); /* CCK Carrier Sense Threshold */
1112
1113 write_phy_cck(dev, 0x41, 0x8d);mdelay(1);
1114
1115
1116 write_phy_cck(dev, 0x42, 0x15); mdelay(1);
1117 write_phy_cck(dev, 0x43, 0x18); mdelay(1);
1118
1119
1120 write_phy_cck(dev, 0x44, 0x36); mdelay(1);
1121 write_phy_cck(dev, 0x45, 0x35); mdelay(1);
1122 write_phy_cck(dev, 0x46, 0x2e); mdelay(1);
1123 write_phy_cck(dev, 0x47, 0x25); mdelay(1);
1124 write_phy_cck(dev, 0x48, 0x1c); mdelay(1);
1125 write_phy_cck(dev, 0x49, 0x12); mdelay(1);
1126 write_phy_cck(dev, 0x4a, 0x9); mdelay(1);
1127 write_phy_cck(dev, 0x4b, 0x4); mdelay(1);
1128 write_phy_cck(dev, 0x4c, 0x5);mdelay(1);
1129
1130
1131 write_nic_byte(dev, 0x5b, 0x0d); mdelay(1);
1132
1133
1134
1135// <>
1136// // TESTR 0xb 8187
1137// write_phy_cck(dev, 0x10, 0x93);// & 0xfb);
1138//
1139// //if(priv->card_type != USB){
1140// write_phy_ofdm(dev, 0x2, 0x62);
1141// write_phy_ofdm(dev, 0x6, 0x0);
1142// write_phy_ofdm(dev, 0x8, 0x0);
1143// //}
1144
1145 rtl8225z2_SetTXPowerLevel(dev, channel);
1146#ifdef CONFIG_RTL818X_S
1147 write_phy_cck(dev, 0x11, 0x9b); mdelay(1); /* Rx ant A, 0xdb for B */
1148#else
1149 write_phy_cck(dev, 0x10, 0x9b); mdelay(1); /* Rx ant A, 0xdb for B */
1150#endif
1151 write_phy_ofdm(dev, 0x26, 0x90); mdelay(1); /* Rx ant A, 0x10 for B */
1152
1153 rtl8185_tx_antenna(dev, 0x3); /* TX ant A, 0x0 for B */
1154
1155 /* switch to high-speed 3-wire
1156 * last digit. 2 for both cck and ofdm
1157 */
1158 if(priv->card_type == USB)
1159 write_nic_dword(dev, 0x94, 0x3dc00002);
1160 else{
1161 write_nic_dword(dev, 0x94, 0x15c00002);
1162 rtl8185_rf_pins_enable(dev);
1163 }
1164
1165// if(priv->card_type != USB)
1166// rtl8225_set_gain(dev, 4); /* FIXME this '1' is random */ // <>
1167// rtl8225_set_mode(dev, 1); /* FIXME start in B mode */ // <>
1168//
1169// /* make sure is waken up! */
1170// write_rtl8225(dev,0x4, 0x9ff);
1171// rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
1172// rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_ON);
1173
1174 rtl8225_rf_set_chan(dev, priv->chan);
1175
1176 //write_nic_word(dev,BRSR,brsr);
1177
1178 //rtl8225z2_rf_set_mode(dev);
1179}
1180
1181void rtl8225z2_rf_set_mode(struct net_device *dev)
1182{
1183 struct r8180_priv *priv = ieee80211_priv(dev);
1184
1185 if(priv->ieee80211->mode == IEEE_A)
1186 {
1187 write_rtl8225(dev, 0x5, 0x1865);
1188 write_nic_dword(dev, RF_PARA, 0x10084);
1189 write_nic_dword(dev, RF_TIMING, 0xa8008);
1190 write_phy_ofdm(dev, 0x0, 0x0);
1191 write_phy_ofdm(dev, 0xa, 0x6);
1192 write_phy_ofdm(dev, 0xb, 0x99);
1193 write_phy_ofdm(dev, 0xf, 0x20);
1194 write_phy_ofdm(dev, 0x11, 0x7);
1195
1196 rtl8225z2_set_gain(dev,4);
1197
1198 write_phy_ofdm(dev,0x15, 0x40);
1199 write_phy_ofdm(dev,0x17, 0x40);
1200
1201 write_nic_dword(dev, 0x94,0x10000000);
1202 }else{
1203
1204 write_rtl8225(dev, 0x5, 0x1864);
1205 write_nic_dword(dev, RF_PARA, 0x10044);
1206 write_nic_dword(dev, RF_TIMING, 0xa8008);
1207 write_phy_ofdm(dev, 0x0, 0x1);
1208 write_phy_ofdm(dev, 0xa, 0x6);
1209 write_phy_ofdm(dev, 0xb, 0x99);
1210 write_phy_ofdm(dev, 0xf, 0x20);
1211 write_phy_ofdm(dev, 0x11, 0x7);
1212
1213 rtl8225z2_set_gain(dev,4);
1214
1215 write_phy_ofdm(dev,0x15, 0x40);
1216 write_phy_ofdm(dev,0x17, 0x40);
1217
1218 write_nic_dword(dev, 0x94,0x04000002);
1219 }
1220}
1221
1222//lzm mod 080826
1223//#define MAX_DOZE_WAITING_TIMES_85B 64
1224//#define MAX_POLLING_24F_TIMES_87SE 5
1225#define MAX_DOZE_WAITING_TIMES_85B 20
1226#define MAX_POLLING_24F_TIMES_87SE 10
1227#define LPS_MAX_SLEEP_WAITING_TIMES_87SE 5
1228
1229bool
1230SetZebraRFPowerState8185(
1231 struct net_device *dev,
1232 RT_RF_POWER_STATE eRFPowerState
1233 )
1234{
1235 struct r8180_priv *priv = ieee80211_priv(dev);
1236 u8 btCR9346, btConfig3;
1237 bool bActionAllowed= true, bTurnOffBB = true;//lzm mod 080826
1238 //u32 DWordContent;
1239 u8 u1bTmp;
1240 int i;
1241 //u16 u2bTFPC = 0;
1242 bool bResult = true;
1243 u8 QueueID;
1244
1245 if(priv->SetRFPowerStateInProgress == true)
1246 return false;
1247
1248 priv->SetRFPowerStateInProgress = true;
1249
1250 // enable EEM0 and EEM1 in 9346CR
1251 btCR9346 = read_nic_byte(dev, CR9346);
1252 write_nic_byte(dev, CR9346, (btCR9346|0xC0) );
1253 // enable PARM_En in Config3
1254 btConfig3 = read_nic_byte(dev, CONFIG3);
1255 write_nic_byte(dev, CONFIG3, (btConfig3|CONFIG3_PARM_En) );
1256
1257 switch( priv->rf_chip )
1258 {
1259 case RF_ZEBRA2:
1260 switch( eRFPowerState )
1261 {
1262 case eRfOn:
1263 RF_WriteReg(dev,0x4,0x9FF);
1264
1265 write_nic_dword(dev, ANAPARAM, ANAPARM_ON);
1266 write_nic_dword(dev, ANAPARAM2, ANAPARM2_ON);
1267
1268 write_nic_byte(dev, CONFIG4, priv->RFProgType);
1269
1270 //Follow 87B, Isaiah 2007-04-27
1271 u1bTmp = read_nic_byte(dev, 0x24E);
1272 write_nic_byte(dev, 0x24E, (u1bTmp & (~(BIT5|BIT6))) );// 070124 SD1 Alex: turn on CCK and OFDM.
1273 break;
1274
1275 case eRfSleep:
1276 break;
1277
1278 case eRfOff:
1279 break;
1280
1281 default:
1282 bResult = false;
1283 break;
1284 }
1285 break;
1286
1287 case RF_ZEBRA4:
1288 switch( eRFPowerState )
1289 {
1290 case eRfOn:
1291 //printk("===================================power on@jiffies:%d\n",jiffies);
1292 write_nic_word(dev, 0x37C, 0x00EC);
1293
1294 //turn on AFE
1295 write_nic_byte(dev, 0x54, 0x00);
1296 write_nic_byte(dev, 0x62, 0x00);
1297
1298 //lzm mod 080826
1299 //turn on RF
1300 //RF_WriteReg(dev, 0x0, 0x009f); //mdelay(1);
1301 //RF_WriteReg(dev, 0x4, 0x0972); //mdelay(1);
1302 RF_WriteReg(dev, 0x0, 0x009f); udelay(500);
1303 RF_WriteReg(dev, 0x4, 0x0972); udelay(500);
1304 //turn on RF again, suggested by SD3 stevenl.
1305 RF_WriteReg(dev, 0x0, 0x009f); udelay(500);
1306 RF_WriteReg(dev, 0x4, 0x0972); udelay(500);
1307
1308 //turn on BB
1309// write_nic_dword(dev, PhyAddr, 0x4090); //ofdm 10=00
1310// write_nic_dword(dev, PhyAddr, 0x4092); //ofdm 12=00
1311 write_phy_ofdm(dev,0x10,0x40);
1312 write_phy_ofdm(dev,0x12,0x40);
1313 //Avoid power down at init time.
1314 write_nic_byte(dev, CONFIG4, priv->RFProgType);
1315
1316 u1bTmp = read_nic_byte(dev, 0x24E);
1317 write_nic_byte(dev, 0x24E, (u1bTmp & (~(BIT5|BIT6))) );
1318
1319 break;
1320
1321 case eRfSleep:
1322 // Make sure BusyQueue is empty befor turn off RFE pwoer.
1323 //printk("===================================power sleep@jiffies:%d\n",jiffies);
1324
1325 for(QueueID = 0, i = 0; QueueID < 6; )
1326 {
1327 if(get_curr_tx_free_desc(dev,QueueID) == priv->txringcount)
1328 {
1329 QueueID++;
1330 continue;
1331 }
1332#if 0 //reserved amy
1333 else if(priv->NdisAdapter.CurrentPowerState != NdisDeviceStateD0)
1334 {
1335 RT_TRACE(COMP_POWER, DBG_LOUD, ("eRfSleep: %d times TcbBusyQueue[%d] !=0 but lower power state!\n", (pMgntInfo->TxPollingTimes+1), QueueID));
1336 break;
1337 }
1338#endif
1339 else//lzm mod 080826
1340 {
1341 priv->TxPollingTimes ++;
1342 if(priv->TxPollingTimes >= LPS_MAX_SLEEP_WAITING_TIMES_87SE)
1343 {
1344 //RT_TRACE(COMP_POWER, DBG_WARNING, ("\n\n\n SetZebraRFPowerState8185B():eRfSleep: %d times TcbBusyQueue[%d] != 0 !!!\n\n\n", LPS_MAX_SLEEP_WAITING_TIMES_87SE, QueueID));
1345 bActionAllowed=false;
1346 break;
1347 }
1348 else
1349 {
1350 udelay(10); // Windows may delay 3~16ms actually.
1351 //RT_TRACE(COMP_POWER, DBG_LOUD, ("eRfSleep: %d times TcbBusyQueue[%d] !=0 before doze!\n", (pMgntInfo->TxPollingTimes), QueueID));
1352 }
1353 }
1354
1355 //lzm del 080826
1356 //if(i >= MAX_DOZE_WAITING_TIMES_85B)
1357 //{
1358 //printk("\n\n\n SetZebraRFPowerState8185B(): %d times BusyQueue[%d] != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_85B, QueueID);
1359 //break;
1360 //}
1361 }
1362
1363 if(bActionAllowed)//lzm add 080826
1364 {
1365 //turn off BB RXIQ matrix to cut off rx signal
1366// write_nic_dword(dev, PhyAddr, 0x0090); //ofdm 10=00
1367// write_nic_dword(dev, PhyAddr, 0x0092); //ofdm 12=00
1368 write_phy_ofdm(dev,0x10,0x00);
1369 write_phy_ofdm(dev,0x12,0x00);
1370 //turn off RF
1371 RF_WriteReg(dev, 0x4, 0x0000); //mdelay(1);
1372 RF_WriteReg(dev, 0x0, 0x0000); //mdelay(1);
1373 //turn off AFE except PLL
1374 write_nic_byte(dev, 0x62, 0xff);
1375 write_nic_byte(dev, 0x54, 0xec);
1376// mdelay(10);
1377
1378#if 1
1379 mdelay(1);
1380 {
1381 int i = 0;
1382 while (true)
1383 {
1384 u8 tmp24F = read_nic_byte(dev, 0x24f);
1385 if ((tmp24F == 0x01) || (tmp24F == 0x09))
1386 {
1387 bTurnOffBB = true;
1388 break;
1389 }
1390 else//lzm mod 080826
1391 {
1392 udelay(10);
1393 i++;
1394 priv->TxPollingTimes++;
1395
1396 if(priv->TxPollingTimes >= LPS_MAX_SLEEP_WAITING_TIMES_87SE)
1397 {
1398 //RT_TRACE(COMP_POWER, DBG_WARNING, ("\n\n\n SetZebraRFPowerState8185B(): eRfOff: %d times Rx Mac0x24F=0x%x !!!\n\n\n", i, u1bTmp24F));
1399 bTurnOffBB=false;
1400 break;
1401 }
1402 else
1403 {
1404 udelay(10);// Windows may delay 3~16ms actually.
1405 //RT_TRACE(COMP_POWER, DBG_LOUD,("(%d)eRfSleep- u1bTmp24F= 0x%X\n", i, u1bTmp24F));
1406
1407 }
1408 }
1409
1410 //lzm del 080826
1411 //if (i > MAX_POLLING_24F_TIMES_87SE)
1412 // break;
1413 }
1414 }
1415#endif
1416 if (bTurnOffBB)//lzm mod 080826
1417 {
1418 //turn off BB
1419 u1bTmp = read_nic_byte(dev, 0x24E);
1420 write_nic_byte(dev, 0x24E, (u1bTmp|BIT5|BIT6));
1421
1422 //turn off AFE PLL
1423 //write_nic_byte(dev, 0x54, 0xec);
1424 //write_nic_word(dev, 0x37C, 0x00ec);
1425 write_nic_byte(dev, 0x54, 0xFC); //[ECS] FC-> EC->FC, asked by SD3 Stevenl
1426 write_nic_word(dev, 0x37C, 0x00FC);//[ECS] FC-> EC->FC, asked by SD3 Stevenl
1427 }
1428 }
1429 break;
1430
1431 case eRfOff:
1432 // Make sure BusyQueue is empty befor turn off RFE pwoer.
1433 //printk("===================================power off@jiffies:%d\n",jiffies);
1434 for(QueueID = 0, i = 0; QueueID < 6; )
1435 {
1436 if(get_curr_tx_free_desc(dev,QueueID) == priv->txringcount)
1437 {
1438 QueueID++;
1439 continue;
1440 }
1441#if 0
1442 else if(Adapter->NdisAdapter.CurrentPowerState != NdisDeviceStateD0)
1443 {
1444 RT_TRACE(COMP_POWER, DBG_LOUD, ("%d times TcbBusyQueue[%d] !=0 but lower power state!\n", (i+1), QueueID));
1445 break;
1446 }
1447#endif
1448 else
1449 {
1450 udelay(10);
1451 i++;
1452 }
1453
1454 if(i >= MAX_DOZE_WAITING_TIMES_85B)
1455 {
1456 //printk("\n\n\n SetZebraRFPowerState8185B(): %d times BusyQueue[%d] != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_85B, QueueID);
1457 break;
1458 }
1459 }
1460
1461 //turn off BB RXIQ matrix to cut off rx signal
1462// write_nic_dword(dev, PhyAddr, 0x0090); //ofdm 10=00
1463// write_nic_dword(dev, PhyAddr, 0x0092); //ofdm 12=00
1464 write_phy_ofdm(dev,0x10,0x00);
1465 write_phy_ofdm(dev,0x12,0x00);
1466 //turn off RF
1467 RF_WriteReg(dev, 0x4, 0x0000); //mdelay(1);
1468 RF_WriteReg(dev, 0x0, 0x0000); //mdelay(1);
1469 //turn off AFE except PLL
1470 write_nic_byte(dev, 0x62, 0xff);
1471 write_nic_byte(dev, 0x54, 0xec);
1472// mdelay(10);
1473#if 1
1474 mdelay(1);
1475 {
1476 int i = 0;
1477 while (true)
1478 {
1479 u8 tmp24F = read_nic_byte(dev, 0x24f);
1480 if ((tmp24F == 0x01) || (tmp24F == 0x09))
1481 {
1482 bTurnOffBB = true;
1483 break;
1484 }
1485 else
1486 {
1487 bTurnOffBB = false;
1488 udelay(10);
1489 i++;
1490 }
1491 if (i > MAX_POLLING_24F_TIMES_87SE)
1492 break;
1493 }
1494 }
1495#endif
1496 if (bTurnOffBB)//lzm mod 080826
1497 {
1498
1499 //turn off BB
1500 u1bTmp = read_nic_byte(dev, 0x24E);
1501 write_nic_byte(dev, 0x24E, (u1bTmp|BIT5|BIT6));
1502 //turn off AFE PLL (80M)
1503 //write_nic_byte(dev, 0x54, 0xec);
1504 //write_nic_word(dev, 0x37C, 0x00ec);
1505 write_nic_byte(dev, 0x54, 0xFC); //[ECS] FC-> EC->FC, asked by SD3 Stevenl
1506 write_nic_word(dev, 0x37C, 0x00FC); //[ECS] FC-> EC->FC, asked by SD3 Stevenl
1507 }
1508
1509 break;
1510
1511 default:
1512 bResult = false;
1513 printk("SetZebraRFPowerState8185(): unknow state to set: 0x%X!!!\n", eRFPowerState);
1514 break;
1515 }
1516 break;
1517 }
1518
1519 // disable PARM_En in Config3
1520 btConfig3 &= ~(CONFIG3_PARM_En);
1521 write_nic_byte(dev, CONFIG3, btConfig3);
1522 // disable EEM0 and EEM1 in 9346CR
1523 btCR9346 &= ~(0xC0);
1524 write_nic_byte(dev, CR9346, btCR9346);
1525
1526 if(bResult && bActionAllowed)//lzm mod 080826
1527 {
1528 // Update current RF state variable.
1529 priv->eRFPowerState = eRFPowerState;
1530#if 0
1531 switch(priv->eRFPowerState)
1532 {
1533 case eRfOff:
1534 //
1535 //If Rf off reason is from IPS, Led should blink with no link, by Maddest 071015
1536 //
1537 if(priv->RfOffReason==RF_CHANGE_BY_IPS )
1538 {
1539 Adapter->HalFunc.LedControlHandler(Adapter,LED_CTL_NO_LINK);
1540 }
1541 else
1542 {
1543 // Turn off LED if RF is not ON.
1544 Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_POWER_OFF);
1545 }
1546 break;
1547
1548 case eRfOn:
1549 // Turn on RF we are still linked, which might happen when
1550 // we quickly turn off and on HW RF. 2006.05.12, by rcnjko.
1551 if( pMgntInfo->bMediaConnect == TRUE )
1552 {
1553 Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_LINK);
1554 }
1555 break;
1556
1557 default:
1558 // do nothing.
1559 break;
1560 }
1561#endif
1562
1563 }
1564
1565 priv->SetRFPowerStateInProgress = false;
1566
1567 return (bResult && bActionAllowed) ;
1568}
1569void rtl8225z4_rf_sleep(struct net_device *dev)
1570{
1571 //
1572 // Turn off RF power.
1573 //
1574 //printk("=========>%s()\n", __FUNCTION__);
1575 MgntActSet_RF_State(dev, eRfSleep, RF_CHANGE_BY_PS);
1576 //mdelay(2); //FIXME
1577}
1578void rtl8225z4_rf_wakeup(struct net_device *dev)
1579{
1580 //
1581 // Turn on RF power.
1582 //
1583 //printk("=========>%s()\n", __FUNCTION__);
1584 MgntActSet_RF_State(dev, eRfOn, RF_CHANGE_BY_PS);
1585}
1586#endif
1587
diff --git a/drivers/staging/rtl8187se/r8180_rtl8255.c b/drivers/staging/rtl8187se/r8180_rtl8255.c
new file mode 100644
index 000000000000..1a62444dcc50
--- /dev/null
+++ b/drivers/staging/rtl8187se/r8180_rtl8255.c
@@ -0,0 +1,1838 @@
1/*
2 This is part of the rtl8180-sa2400 driver
3 released under the GPL (See file COPYING for details).
4 Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
5
6 This files contains programming code for the rtl8255
7 radio frontend.
8
9 *Many* thanks to Realtek Corp. for their great support!
10
11*/
12
13#define BAND_A 1
14#define BAND_BG 2
15
16#include "r8180.h"
17#include "r8180_hw.h"
18#include "r8180_rtl8255.h"
19
20u32 rtl8255_chan[] = {
21 0, //dummy channel 0
22 0x13, //1
23 0x115, //2
24 0x217, //3
25 0x219, //4
26 0x31b, //5
27 0x41d, //6
28 0x41f, //7
29 0x621, //8
30 0x623, //9
31 0x625, //10
32 0x627, //11
33 0x829, //12
34 0x82b, //13
35 0x92f, // 14
36};
37
38static short rtl8255_gain_2G[]={
39 0x33, 0x17, 0x7c, 0xc5,//-78
40 0x43, 0x17, 0x7a, 0xc5,//-74
41 0x53, 0x17, 0x78, 0xc5,//-70
42 0x63, 0x17, 0x76, 0xc5,//-66
43};
44
45
46static short rtl8255_agc[]={
47 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,
48
49 0x1, 0x1, 0x2, 0x2, 0x3, 0x3, 0x4, 0x4, 0x5, 0x5,
50 0x6, 0x6, 0x7, 0x7, 0x8, 0x8, 0x9, 0x9, 0xa, 0xa,
51 0xb, 0xb, 0xc, 0xc, 0xd, 0xd, 0xe, 0xe, 0xf, 0xf,
52
53 0x10, 0x10, 0x11, 0x11, 0x12, 0x12, 0x13, 0x13, 0x14, 0x14,
54 0x15, 0x15, 0x16, 0x16, 0x17, 0x17, 0x18, 0x18, 0x19, 0x19,
55 0x1a, 0x1a, 0x1b, 0x1b, 0x1c, 0x1c, 0x1d, 0x1d, 0x1e, 0x1e,
56 0x1f, 0x1f,
57
58 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23, 0x24, 0x24,
59 0x25, 0x25, 0x26, 0x26, 0x27, 0x27, 0x28, 0x28, 0x29, 0x29,
60 0x2a, 0x2a,
61
62 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
63 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
64 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
65 0x2a, 0x2a, 0x2a, 0x2a
66
67};
68
69void rtl8255_set_gain(struct net_device *dev, short gain)
70{
71
72// struct r8180_priv *priv = ieee80211_priv(dev);
73
74 write_phy_ofdm(dev, 0x0d, rtl8255_gain_2G[gain * 4]);
75 write_phy_ofdm(dev, 0x23, rtl8255_gain_2G[gain * 4 + 1]);
76 write_phy_ofdm(dev, 0x1b, rtl8255_gain_2G[gain * 4 + 2]);
77 write_phy_ofdm(dev, 0x1d, rtl8255_gain_2G[gain * 4 + 3]);
78 //rtl8225_set_gain_usb(dev, gain);
79}
80
81void write_rtl8255_reg0c(struct net_device *dev, u32 d1, u32 d2, u32 d3, u32 d4,
82u32 d5, u32 d6, u32 d7, u32 d8, u32 d9, u32 d10)
83{
84 int i,j;
85 u16 out,select;
86 u8 bit;
87 u32 bangdata;
88// struct r8180_priv *priv = ieee80211_priv(dev);
89
90 write_nic_word(dev,RFPinsEnable,
91 (read_nic_word(dev,RFPinsEnable) | 0x7));
92
93 select = read_nic_word(dev, RFPinsSelect);
94
95 write_nic_word(dev, RFPinsSelect, select | 0x7 | SW_CONTROL_GPIO);
96
97 out = read_nic_word(dev, RFPinsOutput) & 0xfff3;
98
99 write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN );//| 0x1fff);
100
101 force_pci_posting(dev);
102 udelay(2);
103
104 write_nic_word(dev, RFPinsOutput, out);
105
106 force_pci_posting(dev);
107 udelay(2);
108
109 for(j=0;j<10;j++)
110 {
111 switch(j)
112 {
113 case 9:
114 bangdata = d10 | 0x0c;
115 break;
116 case 8:
117 bangdata = d9;
118 break;
119 case 7:
120 bangdata = d8;
121 break;
122 case 6:
123 bangdata = d7;
124 break;
125 case 5:
126 bangdata = d6;
127 break;
128 case 4:
129 bangdata = d5;
130 break;
131 case 3:
132 bangdata = d4;
133 break;
134 case 2:
135 bangdata = d3;
136 break;
137 case 1:
138 bangdata = d2;
139 break;
140 case 0:
141 bangdata = d1;
142 break;
143 default:
144 bangdata=0xbadc0de; /* avoid gcc complaints */
145 break;
146 }
147
148 for(i=31; i>=0;i--){
149
150 bit = (bangdata & (1<<i)) >> i;
151
152 write_nic_word(dev, RFPinsOutput, bit | out);
153 force_pci_posting(dev);
154 udelay(1);
155 write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
156 force_pci_posting(dev);
157 udelay(1);
158 // write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
159 i--;
160 bit = (bangdata & (1<<i)) >> i;
161
162 write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
163 force_pci_posting(dev);
164 udelay(1);
165 // write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
166 write_nic_word(dev, RFPinsOutput, bit | out);
167 force_pci_posting(dev);
168 udelay(1);
169 }
170 }
171
172 write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN);
173 force_pci_posting(dev);
174 udelay(10);
175
176// write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN);
177 write_nic_word(dev, RFPinsSelect, select | SW_CONTROL_GPIO);
178// rtl8185_rf_pins_enable(dev);
179
180}
181
182void write_rtl8255(struct net_device *dev, u8 adr, u16 data)
183{
184 int i;
185 u16 out,select;
186 u8 bit;
187 u32 bangdata = (data << 4) | (adr & 0xf);
188// struct r8180_priv *priv = ieee80211_priv(dev);
189
190 out = read_nic_word(dev, RFPinsOutput) & 0xfff3;
191
192 write_nic_word(dev,RFPinsEnable,
193 (read_nic_word(dev,RFPinsEnable) | 0x7));
194
195 select = read_nic_word(dev, RFPinsSelect);
196
197 write_nic_word(dev, RFPinsSelect, select | 0x7 | SW_CONTROL_GPIO);
198
199 force_pci_posting(dev);
200 udelay(10);
201
202 write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN );//| 0x1fff);
203
204 force_pci_posting(dev);
205 udelay(2);
206
207 write_nic_word(dev, RFPinsOutput, out);
208
209 force_pci_posting(dev);
210 udelay(10);
211
212
213 for(i=15; i>=0;i--){
214
215 bit = (bangdata & (1<<i)) >> i;
216
217 write_nic_word(dev, RFPinsOutput, bit | out);
218 write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
219 write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
220 i--;
221 bit = (bangdata & (1<<i)) >> i;
222
223 write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
224 write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
225 write_nic_word(dev, RFPinsOutput, bit | out);
226 }
227
228
229 write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN);
230
231 force_pci_posting(dev);
232 udelay(10);
233
234 write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN);
235 write_nic_word(dev, RFPinsSelect, select | SW_CONTROL_GPIO);
236
237 rtl8185_rf_pins_enable(dev);
238}
239
240void rtl8255_rf_close(struct net_device *dev)
241{
242
243// rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_OFF);
244// rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_OFF);
245}
246
247void rtl8255_SetTXPowerLevel(struct net_device *dev, short ch)
248{
249 struct r8180_priv *priv = ieee80211_priv(dev);
250
251 u8 cck_power_level = 0xff & priv->chtxpwr[ch];
252 u8 ofdm_power_level = 0xff & priv->chtxpwr_ofdm[ch];
253 write_nic_byte(dev, TX_GAIN_OFDM, ofdm_power_level);
254 write_nic_byte(dev, TX_GAIN_CCK, cck_power_level);
255 force_pci_posting(dev);
256 mdelay(1);
257 //write_nic_byte(dev, TX_AGC_CONTROL,4);
258}
259#if 0
260/* switch between mode B and G */
261void rtl8255_set_mode(struct net_device *dev, short modeb)
262{
263 write_phy_ofdm(dev, 0x15, (modeb ? 0x0 : 0x40));
264 write_phy_ofdm(dev, 0x17, (modeb ? 0x0 : 0x40));
265}
266#endif
267
268void rtl8255_rf_set_chan(struct net_device *dev, short ch)
269{
270 //write_rtl8225(dev, 0x7, rtl8225_chan[1]);
271 write_rtl8255(dev, 0x5, 0x65);
272 write_rtl8255(dev, 0x6, rtl8255_chan[ch]);
273 write_rtl8255(dev, 0x7, 0x7c);
274 write_rtl8255(dev, 0x8, 0x6);
275
276
277 force_pci_posting(dev);
278 set_current_state(TASK_INTERRUPTIBLE);
279 schedule_timeout(HZ);
280// rtl8225_set_mode_B(dev);
281
282 rtl8255_SetTXPowerLevel(dev, ch);
283 /* FIXME FIXME FIXME */
284
285 #if 0
286 write_nic_byte(dev,DIFS,0xe); //DIFS
287 write_nic_byte(dev,SLOT,0x14); //SLOT
288 write_nic_byte(dev,EIFS,0x5b); // EIFS
289 //write_nic_byte(dev,0xbc,0); //CW CONFIG
290 write_nic_byte(dev,0xbd,0xa4); //CW VALUE
291 //write_nic_byte(dev,TX_AGC_CONTROL,4);
292 //write_nic_byte(dev, 0x9d,7);
293//Apr 20 13:25:03 localhost kernel: w8. 409d<-7 // CCK AGC
294 /*write_nic_word(dev,0x84,0x488);
295 write_nic_byte(dev,0x91,0x3e);
296 write_nic_byte(dev,0x90,0x30);
297 write_nic_word(dev,0x84,0x488);
298 write_nic_byte(dev,0x91,0x3e);
299 write_nic_byte(dev,0x90,0x20);
300 */
301 //mdelay(100);
302 #endif
303}
304
305void rtl8255_init_BGband(struct net_device *dev)
306{
307 write_rtl8255(dev, 0x3, 0x0);
308 write_rtl8255(dev, 0x1, 0x807);
309 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x804187cf, 0x40000027,
310 0x92402ac0, 0xf0009, 0x28000, 0xc00, 0x0);
311 write_rtl8255(dev, 0x1, 0x807);
312 write_rtl8255(dev, 0x4, 0xc00);
313 write_rtl8255(dev, 0x4, 0xe00);
314 write_rtl8255(dev, 0x4, 0xc00);
315 write_rtl8255(dev, 0x1, 0x0);
316 write_rtl8255(dev, 0x4, 0x800);
317 write_rtl8255(dev, 0x3, 0x0);
318 write_rtl8255(dev, 0x2, 0x0);
319 write_rtl8255(dev, 0x4, 0xa00);
320 write_rtl8255(dev, 0x4, 0x800);
321 write_rtl8255(dev, 0x4, 0x400);
322 write_rtl8255(dev, 0x3, 0x26);
323 write_rtl8255(dev, 0x2, 0x27);
324 write_rtl8255(dev, 0x4, 0x600);
325 write_rtl8255(dev, 0x4, 0x400);
326 write_rtl8255(dev, 0x4, 0x400);
327 write_rtl8255(dev, 0x3, 0x100);
328 write_rtl8255(dev, 0x4, 0x600);
329 write_rtl8255(dev, 0x4, 0x400);
330 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x804187ce, 0x80000027,
331 0x92402ac0, 0xf0009, 0x28000, 0xc00, 0x0);
332 write_rtl8255(dev, 0x1, 0x807);
333 write_rtl8255(dev, 0x4, 0xc01);
334 write_rtl8255(dev, 0x4, 0xe01);
335 write_rtl8255(dev, 0x4, 0xc01);
336 write_rtl8255(dev, 0x1, 0x0);
337 write_rtl8255(dev, 0x4, 0x801);
338 write_rtl8255(dev, 0x3, 0x0);
339 write_rtl8255(dev, 0x2, 0x0);
340 write_rtl8255(dev, 0x4, 0xa01);
341 write_rtl8255(dev, 0x4, 0x801);
342 write_rtl8255(dev, 0x4, 0x401);
343 write_rtl8255(dev, 0x3, 0x26);
344 write_rtl8255(dev, 0x2, 0x27);
345 write_rtl8255(dev, 0x4, 0x601);
346 write_rtl8255(dev, 0x4, 0x401);
347 write_rtl8255(dev, 0x4, 0x401);
348 write_rtl8255(dev, 0x3, 0x100);
349 write_rtl8255(dev, 0x4, 0x601);
350 write_rtl8255(dev, 0x4, 0x401);
351 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80418bdf, 0x40000027,
352 0x92402ac4, 0xf0009, 0x28000, 0xc00, 0x0);
353 write_rtl8255(dev, 0x1, 0x807);
354 write_rtl8255(dev, 0x4, 0xc02);
355 write_rtl8255(dev, 0x4, 0xe02);
356 write_rtl8255(dev, 0x4, 0xc02);
357 write_rtl8255(dev, 0x1, 0x0);
358 write_rtl8255(dev, 0x4, 0x802);
359 write_rtl8255(dev, 0x3, 0x0);
360 write_rtl8255(dev, 0x2, 0x0);
361 write_rtl8255(dev, 0x4, 0xa02);
362 write_rtl8255(dev, 0x4, 0x802);
363 write_rtl8255(dev, 0x4, 0x402);
364 write_rtl8255(dev, 0x3, 0x26);
365 write_rtl8255(dev, 0x2, 0x26);
366 write_rtl8255(dev, 0x4, 0x602);
367 write_rtl8255(dev, 0x4, 0x402);
368 write_rtl8255(dev, 0x4, 0x402);
369 write_rtl8255(dev, 0x3, 0x100);
370 write_rtl8255(dev, 0x4, 0x602);
371 write_rtl8255(dev, 0x4, 0x402);
372 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80418bbf, 0x40000027,
373 0x92402ac4, 0xf0009, 0x28000, 0xc00, 0x0);
374 write_rtl8255(dev, 0x1, 0x807);
375 write_rtl8255(dev, 0x4, 0xc03);
376 write_rtl8255(dev, 0x4, 0xe03);
377 write_rtl8255(dev, 0x4, 0xc03);
378 write_rtl8255(dev, 0x1, 0x0);
379 write_rtl8255(dev, 0x4, 0x803);
380 write_rtl8255(dev, 0x3, 0x0);
381 write_rtl8255(dev, 0x2, 0x0);
382 write_rtl8255(dev, 0x4, 0xa03);
383 write_rtl8255(dev, 0x4, 0x803);
384 write_rtl8255(dev, 0x4, 0x403);
385 write_rtl8255(dev, 0x3, 0x26);
386 write_rtl8255(dev, 0x2, 0x26);
387 write_rtl8255(dev, 0x4, 0x603);
388 write_rtl8255(dev, 0x4, 0x403);
389 write_rtl8255(dev, 0x4, 0x403);
390 write_rtl8255(dev, 0x3, 0x100);
391 write_rtl8255(dev, 0x4, 0x603);
392 write_rtl8255(dev, 0x4, 0x403);
393 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80418b9f, 0x40000027,
394 0x92402ac8, 0xf0009, 0x28000, 0xc00, 0x0);
395 write_rtl8255(dev, 0x1, 0x807);
396 write_rtl8255(dev, 0x4, 0xc04);
397 write_rtl8255(dev, 0x4, 0xe04);
398 write_rtl8255(dev, 0x4, 0xc04);
399 write_rtl8255(dev, 0x1, 0x0);
400 write_rtl8255(dev, 0x4, 0x804);
401 write_rtl8255(dev, 0x3, 0x0);
402 write_rtl8255(dev, 0x2, 0x0);
403 write_rtl8255(dev, 0x4, 0xa04);
404 write_rtl8255(dev, 0x4, 0x804);
405 write_rtl8255(dev, 0x4, 0x404);
406 write_rtl8255(dev, 0x3, 0x26);
407 write_rtl8255(dev, 0x2, 0x26);
408 write_rtl8255(dev, 0x4, 0x604);
409 write_rtl8255(dev, 0x4, 0x404);
410 write_rtl8255(dev, 0x4, 0x404);
411 write_rtl8255(dev, 0x3, 0x100);
412 write_rtl8255(dev, 0x4, 0x604);
413 write_rtl8255(dev, 0x4, 0x404);
414 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x804183df, 0x40000027,
415 0x92402ac8, 0xf0009, 0x28000, 0xc00, 0x0);
416 write_rtl8255(dev, 0x1, 0x807);
417 write_rtl8255(dev, 0x4, 0xc05);
418 write_rtl8255(dev, 0x4, 0xe05);
419 write_rtl8255(dev, 0x4, 0xc05);
420 write_rtl8255(dev, 0x1, 0x0);
421 write_rtl8255(dev, 0x4, 0x805);
422 write_rtl8255(dev, 0x3, 0x0);
423 write_rtl8255(dev, 0x2, 0x0);
424 write_rtl8255(dev, 0x4, 0xa05);
425 write_rtl8255(dev, 0x4, 0x805);
426 write_rtl8255(dev, 0x4, 0x405);
427 write_rtl8255(dev, 0x3, 0x26);
428 write_rtl8255(dev, 0x2, 0x26);
429 write_rtl8255(dev, 0x4, 0x605);
430 write_rtl8255(dev, 0x4, 0x405);
431 write_rtl8255(dev, 0x4, 0x405);
432 write_rtl8255(dev, 0x3, 0x100);
433 write_rtl8255(dev, 0x4, 0x605);
434 write_rtl8255(dev, 0x4, 0x405);
435 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x804183cf, 0x27,
436 0x92402acc, 0xf0009, 0x28000, 0xc00, 0x0);
437 write_rtl8255(dev, 0x1, 0x807);
438 write_rtl8255(dev, 0x4, 0xc06);
439 write_rtl8255(dev, 0x4, 0xe06);
440 write_rtl8255(dev, 0x4, 0xc06);
441 write_rtl8255(dev, 0x1, 0x0);
442 write_rtl8255(dev, 0x4, 0x806);
443 write_rtl8255(dev, 0x3, 0x0);
444 write_rtl8255(dev, 0x2, 0x0);
445 write_rtl8255(dev, 0x4, 0xa06);
446 write_rtl8255(dev, 0x4, 0x806);
447 write_rtl8255(dev, 0x4, 0x406);
448 write_rtl8255(dev, 0x3, 0x25);
449 write_rtl8255(dev, 0x2, 0x26);
450 write_rtl8255(dev, 0x4, 0x606);
451 write_rtl8255(dev, 0x4, 0x406);
452 write_rtl8255(dev, 0x4, 0x406);
453 write_rtl8255(dev, 0x3, 0x100);
454 write_rtl8255(dev, 0x4, 0x606);
455 write_rtl8255(dev, 0x4, 0x406);
456 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x804183af, 0x27,
457 0x92402acc, 0xf0009, 0x28000, 0xc00, 0x0);
458 write_rtl8255(dev, 0x1, 0x807);
459 write_rtl8255(dev, 0x4, 0xc07);
460 write_rtl8255(dev, 0x4, 0xe07);
461 write_rtl8255(dev, 0x4, 0xc07);
462 write_rtl8255(dev, 0x1, 0x0);
463 write_rtl8255(dev, 0x4, 0x807);
464 write_rtl8255(dev, 0x3, 0x0);
465 write_rtl8255(dev, 0x2, 0x0);
466 write_rtl8255(dev, 0x4, 0xa07);
467 write_rtl8255(dev, 0x4, 0x807);
468 write_rtl8255(dev, 0x4, 0x407);
469 write_rtl8255(dev, 0x3, 0x25);
470 write_rtl8255(dev, 0x2, 0x26);
471 write_rtl8255(dev, 0x4, 0x607);
472 write_rtl8255(dev, 0x4, 0x407);
473 write_rtl8255(dev, 0x4, 0x407);
474 write_rtl8255(dev, 0x3, 0x100);
475 write_rtl8255(dev, 0x4, 0x607);
476 write_rtl8255(dev, 0x4, 0x407);
477 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x804083d7, 0x40000027,
478 0x92402ad0, 0xf0009, 0x28000, 0xc00, 0x0);
479 write_rtl8255(dev, 0x1, 0x807);
480 write_rtl8255(dev, 0x4, 0xc08);
481 write_rtl8255(dev, 0x4, 0xe08);
482 write_rtl8255(dev, 0x4, 0xc08);
483 write_rtl8255(dev, 0x1, 0x0);
484 write_rtl8255(dev, 0x4, 0x808);
485 write_rtl8255(dev, 0x3, 0x0);
486 write_rtl8255(dev, 0x2, 0x0);
487 write_rtl8255(dev, 0x4, 0xa08);
488 write_rtl8255(dev, 0x4, 0x808);
489 write_rtl8255(dev, 0x4, 0x408);
490 write_rtl8255(dev, 0x3, 0x25);
491 write_rtl8255(dev, 0x2, 0x26);
492 write_rtl8255(dev, 0x4, 0x608);
493 write_rtl8255(dev, 0x4, 0x408);
494 write_rtl8255(dev, 0x4, 0x408);
495 write_rtl8255(dev, 0x3, 0x100);
496 write_rtl8255(dev, 0x4, 0x608);
497 write_rtl8255(dev, 0x4, 0x408);
498 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x804083c7, 0x27,
499 0x92402ad0, 0xf0009, 0x28000, 0xc00, 0x0);
500 write_rtl8255(dev, 0x1, 0x807);
501 write_rtl8255(dev, 0x4, 0xc09);
502 write_rtl8255(dev, 0x4, 0xe09);
503 write_rtl8255(dev, 0x4, 0xc09);
504 write_rtl8255(dev, 0x1, 0x0);
505 write_rtl8255(dev, 0x4, 0x809);
506 write_rtl8255(dev, 0x3, 0x0);
507 write_rtl8255(dev, 0x2, 0x0);
508 write_rtl8255(dev, 0x4, 0xa09);
509 write_rtl8255(dev, 0x4, 0x809);
510 write_rtl8255(dev, 0x4, 0x409);
511 write_rtl8255(dev, 0x3, 0x25);
512 write_rtl8255(dev, 0x2, 0x26);
513 write_rtl8255(dev, 0x4, 0x609);
514 write_rtl8255(dev, 0x4, 0x409);
515 write_rtl8255(dev, 0x4, 0x409);
516 write_rtl8255(dev, 0x3, 0x100);
517 write_rtl8255(dev, 0x4, 0x609);
518 write_rtl8255(dev, 0x4, 0x409);
519 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x804043d7, 0x40000027,
520 0x92402ad4, 0xf0009, 0x28000, 0xc00, 0x0);
521 write_rtl8255(dev, 0x1, 0x807);
522 write_rtl8255(dev, 0x4, 0xc0a);
523 write_rtl8255(dev, 0x4, 0xe0a);
524 write_rtl8255(dev, 0x4, 0xc0a);
525 write_rtl8255(dev, 0x1, 0x0);
526 write_rtl8255(dev, 0x4, 0x80a);
527 write_rtl8255(dev, 0x3, 0x0);
528 write_rtl8255(dev, 0x2, 0x0);
529 write_rtl8255(dev, 0x4, 0xa0a);
530 write_rtl8255(dev, 0x4, 0x80a);
531 write_rtl8255(dev, 0x4, 0x40a);
532 write_rtl8255(dev, 0x3, 0x25);
533 write_rtl8255(dev, 0x2, 0x26);
534 write_rtl8255(dev, 0x4, 0x60a);
535 write_rtl8255(dev, 0x4, 0x40a);
536 write_rtl8255(dev, 0x4, 0x40a);
537 write_rtl8255(dev, 0x3, 0x100);
538 write_rtl8255(dev, 0x4, 0x60a);
539 write_rtl8255(dev, 0x4, 0x40a);
540 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x804043d7, 0x40000027,
541 0x92402ad4, 0xf0009, 0x28000, 0xc00, 0x0);
542 write_rtl8255(dev, 0x1, 0x807);
543 write_rtl8255(dev, 0x4, 0xc0b);
544 write_rtl8255(dev, 0x4, 0xe0b);
545 write_rtl8255(dev, 0x4, 0xc0b);
546 write_rtl8255(dev, 0x1, 0x0);
547 write_rtl8255(dev, 0x4, 0x80b);
548 write_rtl8255(dev, 0x3, 0x0);
549 write_rtl8255(dev, 0x2, 0x0);
550 write_rtl8255(dev, 0x4, 0xa0b);
551 write_rtl8255(dev, 0x4, 0x80b);
552 write_rtl8255(dev, 0x4, 0x40b);
553 write_rtl8255(dev, 0x3, 0x25);
554 write_rtl8255(dev, 0x2, 0x26);
555 write_rtl8255(dev, 0x4, 0x60b);
556 write_rtl8255(dev, 0x4, 0x40b);
557 write_rtl8255(dev, 0x4, 0x40b);
558 write_rtl8255(dev, 0x3, 0x100);
559 write_rtl8255(dev, 0x4, 0x60b);
560 write_rtl8255(dev, 0x4, 0x40b);
561 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x804043c7, 0x27,
562 0x92402ad8, 0xf0009, 0x28000, 0xc00, 0x0);
563 write_rtl8255(dev, 0x1, 0x807);
564 write_rtl8255(dev, 0x4, 0xc0c);
565 write_rtl8255(dev, 0x4, 0xe0c);
566 write_rtl8255(dev, 0x4, 0xc0c);
567 write_rtl8255(dev, 0x1, 0x0);
568 write_rtl8255(dev, 0x4, 0x80c);
569 write_rtl8255(dev, 0x3, 0x0);
570 write_rtl8255(dev, 0x2, 0x0);
571 write_rtl8255(dev, 0x4, 0xa0c);
572 write_rtl8255(dev, 0x4, 0x80c);
573 write_rtl8255(dev, 0x4, 0x40c);
574 write_rtl8255(dev, 0x3, 0x25);
575 write_rtl8255(dev, 0x2, 0x26);
576 write_rtl8255(dev, 0x4, 0x60c);
577 write_rtl8255(dev, 0x4, 0x40c);
578 write_rtl8255(dev, 0x4, 0x40c);
579 write_rtl8255(dev, 0x3, 0x100);
580 write_rtl8255(dev, 0x4, 0x60c);
581 write_rtl8255(dev, 0x4, 0x40c);
582 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x804043a7, 0x27,
583 0x92402ad8, 0xf0009, 0x28000, 0xc00, 0x0);
584 write_rtl8255(dev, 0x1, 0x807);
585 write_rtl8255(dev, 0x4, 0xc0d);
586 write_rtl8255(dev, 0x4, 0xe0d);
587 write_rtl8255(dev, 0x4, 0xc0d);
588 write_rtl8255(dev, 0x1, 0x0);
589 write_rtl8255(dev, 0x4, 0x80d);
590 write_rtl8255(dev, 0x3, 0x0);
591 write_rtl8255(dev, 0x2, 0x0);
592 write_rtl8255(dev, 0x4, 0xa0d);
593 write_rtl8255(dev, 0x4, 0x80d);
594 write_rtl8255(dev, 0x4, 0x40d);
595 write_rtl8255(dev, 0x3, 0x25);
596 write_rtl8255(dev, 0x2, 0x26);
597 write_rtl8255(dev, 0x4, 0x60d);
598 write_rtl8255(dev, 0x4, 0x40d);
599 write_rtl8255(dev, 0x4, 0x40d);
600 write_rtl8255(dev, 0x3, 0x100);
601 write_rtl8255(dev, 0x4, 0x60d);
602 write_rtl8255(dev, 0x4, 0x40d);
603 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404387, 0x27,
604 0x92402aa8, 0xf0009, 0x28000, 0xc00, 0x0);
605 write_rtl8255(dev, 0x1, 0x807);
606 write_rtl8255(dev, 0x4, 0xc0e);
607 write_rtl8255(dev, 0x4, 0xe0e);
608 write_rtl8255(dev, 0x4, 0xc0e);
609 write_rtl8255(dev, 0x1, 0x0);
610 write_rtl8255(dev, 0x4, 0x80e);
611 write_rtl8255(dev, 0x3, 0x0);
612 write_rtl8255(dev, 0x2, 0x0);
613 write_rtl8255(dev, 0x4, 0xa0e);
614 write_rtl8255(dev, 0x4, 0x80e);
615 write_rtl8255(dev, 0x4, 0x40e);
616 write_rtl8255(dev, 0x3, 0x25);
617 write_rtl8255(dev, 0x2, 0x26);
618 write_rtl8255(dev, 0x4, 0x60e);
619 write_rtl8255(dev, 0x4, 0x40e);
620 write_rtl8255(dev, 0x4, 0x40e);
621 write_rtl8255(dev, 0x3, 0x100);
622 write_rtl8255(dev, 0x4, 0x60e);
623 write_rtl8255(dev, 0x4, 0x40e);
624 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x804041c7, 0x27,
625 0x92402aa8, 0xf0009, 0x28000, 0xc00, 0x0);
626 write_rtl8255(dev, 0x1, 0x807);
627 write_rtl8255(dev, 0x4, 0xc0f);
628 write_rtl8255(dev, 0x4, 0xe0f);
629 write_rtl8255(dev, 0x4, 0xc0f);
630 write_rtl8255(dev, 0x1, 0x0);
631 write_rtl8255(dev, 0x4, 0x80f);
632 write_rtl8255(dev, 0x3, 0x0);
633 write_rtl8255(dev, 0x2, 0x0);
634 write_rtl8255(dev, 0x4, 0xa0f);
635 write_rtl8255(dev, 0x4, 0x80f);
636 write_rtl8255(dev, 0x4, 0x40f);
637 write_rtl8255(dev, 0x3, 0x25);
638 write_rtl8255(dev, 0x2, 0x26);
639 write_rtl8255(dev, 0x4, 0x60f);
640 write_rtl8255(dev, 0x4, 0x40f);
641 write_rtl8255(dev, 0x4, 0x40f);
642 write_rtl8255(dev, 0x3, 0x100);
643 write_rtl8255(dev, 0x4, 0x60f);
644 write_rtl8255(dev, 0x4, 0x40f);
645 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x804041a7, 0x27,
646 0x92402aac, 0xf0009, 0x28000, 0xc00, 0x0);
647 write_rtl8255(dev, 0x1, 0x807);
648 write_rtl8255(dev, 0x4, 0xc10);
649 write_rtl8255(dev, 0x4, 0xe10);
650 write_rtl8255(dev, 0x4, 0xc10);
651 write_rtl8255(dev, 0x1, 0x0);
652 write_rtl8255(dev, 0x4, 0x810);
653 write_rtl8255(dev, 0x3, 0x0);
654 write_rtl8255(dev, 0x2, 0x0);
655 write_rtl8255(dev, 0x4, 0xa10);
656 write_rtl8255(dev, 0x4, 0x810);
657 write_rtl8255(dev, 0x4, 0x410);
658 write_rtl8255(dev, 0x3, 0x25);
659 write_rtl8255(dev, 0x2, 0x26);
660 write_rtl8255(dev, 0x4, 0x610);
661 write_rtl8255(dev, 0x4, 0x410);
662 write_rtl8255(dev, 0x4, 0x410);
663 write_rtl8255(dev, 0x3, 0x100);
664 write_rtl8255(dev, 0x4, 0x610);
665 write_rtl8255(dev, 0x4, 0x410);
666 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404187, 0x27,
667 0x92402aac, 0xf0009, 0x28000, 0xc00, 0x0);
668 write_rtl8255(dev, 0x1, 0x807);
669 write_rtl8255(dev, 0x4, 0xc11);
670 write_rtl8255(dev, 0x4, 0xe11);
671 write_rtl8255(dev, 0x4, 0xc11);
672 write_rtl8255(dev, 0x1, 0x0);
673 write_rtl8255(dev, 0x4, 0x811);
674 write_rtl8255(dev, 0x3, 0x0);
675 write_rtl8255(dev, 0x2, 0x0);
676 write_rtl8255(dev, 0x4, 0xa11);
677 write_rtl8255(dev, 0x4, 0x811);
678 write_rtl8255(dev, 0x4, 0x411);
679 write_rtl8255(dev, 0x3, 0x25);
680 write_rtl8255(dev, 0x2, 0x26);
681 write_rtl8255(dev, 0x4, 0x611);
682 write_rtl8255(dev, 0x4, 0x411);
683 write_rtl8255(dev, 0x4, 0x411);
684 write_rtl8255(dev, 0x3, 0x100);
685 write_rtl8255(dev, 0x4, 0x611);
686 write_rtl8255(dev, 0x4, 0x411);
687 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404186, 0x80000027,
688 0x92402ab0, 0xf0009, 0x28000, 0xc00, 0x0);
689 write_rtl8255(dev, 0x1, 0x807);
690 write_rtl8255(dev, 0x4, 0xc12);
691 write_rtl8255(dev, 0x4, 0xe12);
692 write_rtl8255(dev, 0x4, 0xc12);
693 write_rtl8255(dev, 0x1, 0x0);
694 write_rtl8255(dev, 0x4, 0x812);
695 write_rtl8255(dev, 0x3, 0x0);
696 write_rtl8255(dev, 0x2, 0x0);
697 write_rtl8255(dev, 0x4, 0xa12);
698 write_rtl8255(dev, 0x4, 0x812);
699 write_rtl8255(dev, 0x4, 0x412);
700 write_rtl8255(dev, 0x3, 0x25);
701 write_rtl8255(dev, 0x2, 0x26);
702 write_rtl8255(dev, 0x4, 0x612);
703 write_rtl8255(dev, 0x4, 0x412);
704 write_rtl8255(dev, 0x4, 0x412);
705 write_rtl8255(dev, 0x3, 0x100);
706 write_rtl8255(dev, 0x4, 0x612);
707 write_rtl8255(dev, 0x4, 0x412);
708 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404186, 0x27,
709 0x92402ab0, 0xf0009, 0x28000, 0xc00, 0x0);
710 write_rtl8255(dev, 0x1, 0x807);
711 write_rtl8255(dev, 0x4, 0xc13);
712 write_rtl8255(dev, 0x4, 0xe13);
713 write_rtl8255(dev, 0x4, 0xc13);
714 write_rtl8255(dev, 0x1, 0x0);
715 write_rtl8255(dev, 0x4, 0x813);
716 write_rtl8255(dev, 0x3, 0x0);
717 write_rtl8255(dev, 0x2, 0x0);
718 write_rtl8255(dev, 0x4, 0xa13);
719 write_rtl8255(dev, 0x4, 0x813);
720 write_rtl8255(dev, 0x4, 0x413);
721 write_rtl8255(dev, 0x3, 0x25);
722 write_rtl8255(dev, 0x2, 0x26);
723 write_rtl8255(dev, 0x4, 0x613);
724 write_rtl8255(dev, 0x4, 0x413);
725 write_rtl8255(dev, 0x4, 0x413);
726 write_rtl8255(dev, 0x3, 0x100);
727 write_rtl8255(dev, 0x4, 0x613);
728 write_rtl8255(dev, 0x4, 0x413);
729 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404146, 0x27,
730 0x92402ab4, 0xf0009, 0x28000, 0xc00, 0x0);
731 write_rtl8255(dev, 0x1, 0x807);
732 write_rtl8255(dev, 0x4, 0xc14);
733 write_rtl8255(dev, 0x4, 0xe14);
734 write_rtl8255(dev, 0x4, 0xc14);
735 write_rtl8255(dev, 0x1, 0x0);
736 write_rtl8255(dev, 0x4, 0x814);
737 write_rtl8255(dev, 0x3, 0x0);
738 write_rtl8255(dev, 0x2, 0x0);
739 write_rtl8255(dev, 0x4, 0xa14);
740 write_rtl8255(dev, 0x4, 0x814);
741 write_rtl8255(dev, 0x4, 0x414);
742 write_rtl8255(dev, 0x3, 0x25);
743 write_rtl8255(dev, 0x2, 0x26);
744 write_rtl8255(dev, 0x4, 0x614);
745 write_rtl8255(dev, 0x4, 0x414);
746 write_rtl8255(dev, 0x4, 0x414);
747 write_rtl8255(dev, 0x3, 0x100);
748 write_rtl8255(dev, 0x4, 0x614);
749 write_rtl8255(dev, 0x4, 0x414);
750 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404126, 0x27,
751 0x92402ab4, 0xf0009, 0x28000, 0xc00, 0x0);
752 write_rtl8255(dev, 0x1, 0x807);
753 write_rtl8255(dev, 0x4, 0xc15);
754 write_rtl8255(dev, 0x4, 0xe15);
755 write_rtl8255(dev, 0x4, 0xc15);
756 write_rtl8255(dev, 0x1, 0x0);
757 write_rtl8255(dev, 0x4, 0x815);
758 write_rtl8255(dev, 0x3, 0x0);
759 write_rtl8255(dev, 0x2, 0x0);
760 write_rtl8255(dev, 0x4, 0xa15);
761 write_rtl8255(dev, 0x4, 0x815);
762 write_rtl8255(dev, 0x4, 0x415);
763 write_rtl8255(dev, 0x3, 0x25);
764 write_rtl8255(dev, 0x2, 0x26);
765 write_rtl8255(dev, 0x4, 0x615);
766 write_rtl8255(dev, 0x4, 0x415);
767 write_rtl8255(dev, 0x4, 0x415);
768 write_rtl8255(dev, 0x3, 0x100);
769 write_rtl8255(dev, 0x4, 0x615);
770 write_rtl8255(dev, 0x4, 0x415);
771 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404106, 0x27,
772 0x92402ab8, 0xf0009, 0x28000, 0xc00, 0x0);
773 write_rtl8255(dev, 0x1, 0x807);
774 write_rtl8255(dev, 0x4, 0xc16);
775 write_rtl8255(dev, 0x4, 0xe16);
776 write_rtl8255(dev, 0x4, 0xc16);
777 write_rtl8255(dev, 0x1, 0x0);
778 write_rtl8255(dev, 0x4, 0x816);
779 write_rtl8255(dev, 0x3, 0x0);
780 write_rtl8255(dev, 0x2, 0x0);
781 write_rtl8255(dev, 0x4, 0xa16);
782 write_rtl8255(dev, 0x4, 0x816);
783 write_rtl8255(dev, 0x4, 0x416);
784 write_rtl8255(dev, 0x3, 0x25);
785 write_rtl8255(dev, 0x2, 0x26);
786 write_rtl8255(dev, 0x4, 0x616);
787 write_rtl8255(dev, 0x4, 0x416);
788 write_rtl8255(dev, 0x4, 0x416);
789 write_rtl8255(dev, 0x3, 0x100);
790 write_rtl8255(dev, 0x4, 0x616);
791 write_rtl8255(dev, 0x4, 0x416);
792 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404105, 0x27,
793 0x92402ab8, 0xf0009, 0x28000, 0xc00, 0x0);
794 write_rtl8255(dev, 0x1, 0x807);
795 write_rtl8255(dev, 0x4, 0xc17);
796 write_rtl8255(dev, 0x4, 0xe17);
797 write_rtl8255(dev, 0x4, 0xc17);
798 write_rtl8255(dev, 0x1, 0x0);
799 write_rtl8255(dev, 0x4, 0x817);
800 write_rtl8255(dev, 0x3, 0x0);
801 write_rtl8255(dev, 0x2, 0x0);
802 write_rtl8255(dev, 0x4, 0xa17);
803 write_rtl8255(dev, 0x4, 0x817);
804 write_rtl8255(dev, 0x4, 0x417);
805 write_rtl8255(dev, 0x3, 0x25);
806 write_rtl8255(dev, 0x2, 0x26);
807 write_rtl8255(dev, 0x4, 0x617);
808 write_rtl8255(dev, 0x4, 0x417);
809 write_rtl8255(dev, 0x4, 0x417);
810 write_rtl8255(dev, 0x3, 0x100);
811 write_rtl8255(dev, 0x4, 0x617);
812 write_rtl8255(dev, 0x4, 0x417);
813 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404104, 0x80000027,
814 0x92402a88, 0xf0009, 0x28000, 0xc00, 0x0);
815 write_rtl8255(dev, 0x1, 0x807);
816 write_rtl8255(dev, 0x4, 0xc18);
817 write_rtl8255(dev, 0x4, 0xe18);
818 write_rtl8255(dev, 0x4, 0xc18);
819 write_rtl8255(dev, 0x1, 0x0);
820 write_rtl8255(dev, 0x4, 0x818);
821 write_rtl8255(dev, 0x3, 0x0);
822 write_rtl8255(dev, 0x2, 0x0);
823 write_rtl8255(dev, 0x4, 0xa18);
824 write_rtl8255(dev, 0x4, 0x818);
825 write_rtl8255(dev, 0x4, 0x418);
826 write_rtl8255(dev, 0x3, 0x25);
827 write_rtl8255(dev, 0x2, 0x26);
828 write_rtl8255(dev, 0x4, 0x618);
829 write_rtl8255(dev, 0x4, 0x418);
830 write_rtl8255(dev, 0x4, 0x418);
831 write_rtl8255(dev, 0x3, 0x100);
832 write_rtl8255(dev, 0x4, 0x618);
833 write_rtl8255(dev, 0x4, 0x418);
834 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404104, 0x27,
835 0x92402a88, 0xf0009, 0x28000, 0xc00, 0x0);
836 write_rtl8255(dev, 0x1, 0x807);
837 write_rtl8255(dev, 0x4, 0xc19);
838 write_rtl8255(dev, 0x4, 0xe19);
839 write_rtl8255(dev, 0x4, 0xc19);
840 write_rtl8255(dev, 0x1, 0x0);
841 write_rtl8255(dev, 0x4, 0x819);
842 write_rtl8255(dev, 0x3, 0x0);
843 write_rtl8255(dev, 0x2, 0x0);
844 write_rtl8255(dev, 0x4, 0xa19);
845 write_rtl8255(dev, 0x4, 0x819);
846 write_rtl8255(dev, 0x4, 0x419);
847 write_rtl8255(dev, 0x3, 0x25);
848 write_rtl8255(dev, 0x2, 0x26);
849 write_rtl8255(dev, 0x4, 0x619);
850 write_rtl8255(dev, 0x4, 0x419);
851 write_rtl8255(dev, 0x4, 0x419);
852 write_rtl8255(dev, 0x3, 0x100);
853 write_rtl8255(dev, 0x4, 0x619);
854 write_rtl8255(dev, 0x4, 0x419);
855 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404044, 0x27,
856 0x92402a8c, 0xf0009, 0x28000, 0xc00, 0x0);
857 write_rtl8255(dev, 0x1, 0x807);
858 write_rtl8255(dev, 0x4, 0xc1a);
859 write_rtl8255(dev, 0x4, 0xe1a);
860 write_rtl8255(dev, 0x4, 0xc1a);
861 write_rtl8255(dev, 0x1, 0x0);
862 write_rtl8255(dev, 0x4, 0x81a);
863 write_rtl8255(dev, 0x3, 0x0);
864 write_rtl8255(dev, 0x2, 0x0);
865 write_rtl8255(dev, 0x4, 0xa1a);
866 write_rtl8255(dev, 0x4, 0x81a);
867 write_rtl8255(dev, 0x4, 0x41a);
868 write_rtl8255(dev, 0x3, 0x25);
869 write_rtl8255(dev, 0x2, 0x26);
870 write_rtl8255(dev, 0x4, 0x61a);
871 write_rtl8255(dev, 0x4, 0x41a);
872 write_rtl8255(dev, 0x4, 0x41a);
873 write_rtl8255(dev, 0x3, 0x100);
874 write_rtl8255(dev, 0x4, 0x61a);
875 write_rtl8255(dev, 0x4, 0x41a);
876 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404024, 0x27,
877 0x92402a8c, 0xf0009, 0x28000, 0xc00, 0x0);
878 write_rtl8255(dev, 0x1, 0x807);
879 write_rtl8255(dev, 0x4, 0xc1b);
880 write_rtl8255(dev, 0x4, 0xe1b);
881 write_rtl8255(dev, 0x4, 0xc1b);
882 write_rtl8255(dev, 0x1, 0x0);
883 write_rtl8255(dev, 0x4, 0x81b);
884 write_rtl8255(dev, 0x3, 0x0);
885 write_rtl8255(dev, 0x2, 0x0);
886 write_rtl8255(dev, 0x4, 0xa1b);
887 write_rtl8255(dev, 0x4, 0x81b);
888 write_rtl8255(dev, 0x4, 0x41b);
889 write_rtl8255(dev, 0x3, 0x25);
890 write_rtl8255(dev, 0x2, 0x26);
891 write_rtl8255(dev, 0x4, 0x61b);
892 write_rtl8255(dev, 0x4, 0x41b);
893 write_rtl8255(dev, 0x4, 0x41b);
894 write_rtl8255(dev, 0x3, 0x100);
895 write_rtl8255(dev, 0x4, 0x61b);
896 write_rtl8255(dev, 0x4, 0x41b);
897 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404004, 0x27,
898 0x92402a90, 0xf0009, 0x28000, 0xc00, 0x0);
899 write_rtl8255(dev, 0x1, 0x807);
900 write_rtl8255(dev, 0x4, 0xc1c);
901 write_rtl8255(dev, 0x4, 0xe1c);
902 write_rtl8255(dev, 0x4, 0xc1c);
903 write_rtl8255(dev, 0x1, 0x0);
904 write_rtl8255(dev, 0x4, 0x81c);
905 write_rtl8255(dev, 0x3, 0x0);
906 write_rtl8255(dev, 0x2, 0x0);
907 write_rtl8255(dev, 0x4, 0xa1c);
908 write_rtl8255(dev, 0x4, 0x81c);
909 write_rtl8255(dev, 0x4, 0x41c);
910 write_rtl8255(dev, 0x3, 0x25);
911 write_rtl8255(dev, 0x2, 0x26);
912 write_rtl8255(dev, 0x4, 0x61c);
913 write_rtl8255(dev, 0x4, 0x41c);
914 write_rtl8255(dev, 0x4, 0x41c);
915 write_rtl8255(dev, 0x3, 0x100);
916 write_rtl8255(dev, 0x4, 0x61c);
917 write_rtl8255(dev, 0x4, 0x41c);
918 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404001, 0x27,
919 0x92402a90, 0xf0009, 0x28000, 0xc00, 0x0);
920 write_rtl8255(dev, 0x1, 0x807);
921 write_rtl8255(dev, 0x4, 0xc1d);
922 write_rtl8255(dev, 0x4, 0xe1d);
923 write_rtl8255(dev, 0x4, 0xc1d);
924 write_rtl8255(dev, 0x1, 0x0);
925 write_rtl8255(dev, 0x4, 0x81d);
926 write_rtl8255(dev, 0x3, 0x0);
927 write_rtl8255(dev, 0x2, 0x0);
928 write_rtl8255(dev, 0x4, 0xa1d);
929 write_rtl8255(dev, 0x4, 0x81d);
930 write_rtl8255(dev, 0x4, 0x41d);
931 write_rtl8255(dev, 0x3, 0x25);
932 write_rtl8255(dev, 0x2, 0x26);
933 write_rtl8255(dev, 0x4, 0x61d);
934 write_rtl8255(dev, 0x4, 0x41d);
935 write_rtl8255(dev, 0x4, 0x41d);
936 write_rtl8255(dev, 0x3, 0x100);
937 write_rtl8255(dev, 0x4, 0x61d);
938 write_rtl8255(dev, 0x4, 0x41d);
939 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
940 0x92402a94, 0xf0009, 0x28000, 0xc00, 0x0);
941 write_rtl8255(dev, 0x1, 0x807);
942 write_rtl8255(dev, 0x4, 0xc1e);
943 write_rtl8255(dev, 0x4, 0xe1e);
944 write_rtl8255(dev, 0x4, 0xc1e);
945 write_rtl8255(dev, 0x1, 0x0);
946 write_rtl8255(dev, 0x4, 0x81e);
947 write_rtl8255(dev, 0x3, 0x0);
948 write_rtl8255(dev, 0x2, 0x0);
949 write_rtl8255(dev, 0x4, 0xa1e);
950 write_rtl8255(dev, 0x4, 0x81e);
951 write_rtl8255(dev, 0x4, 0x41e);
952 write_rtl8255(dev, 0x3, 0x25);
953 write_rtl8255(dev, 0x2, 0x26);
954 write_rtl8255(dev, 0x4, 0x61e);
955 write_rtl8255(dev, 0x4, 0x41e);
956 write_rtl8255(dev, 0x4, 0x41e);
957 write_rtl8255(dev, 0x3, 0x100);
958 write_rtl8255(dev, 0x4, 0x61e);
959 write_rtl8255(dev, 0x4, 0x41e);
960 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x27,
961 0x92402a94, 0xf0009, 0x28000, 0xc00, 0x0);
962 write_rtl8255(dev, 0x1, 0x807);
963 write_rtl8255(dev, 0x4, 0xc1f);
964 write_rtl8255(dev, 0x4, 0xe1f);
965 write_rtl8255(dev, 0x4, 0xc1f);
966 write_rtl8255(dev, 0x1, 0x0);
967 write_rtl8255(dev, 0x4, 0x81f);
968 write_rtl8255(dev, 0x3, 0x0);
969 write_rtl8255(dev, 0x2, 0x0);
970 write_rtl8255(dev, 0x4, 0xa1f);
971 write_rtl8255(dev, 0x4, 0x81f);
972 write_rtl8255(dev, 0x4, 0x41f);
973 write_rtl8255(dev, 0x3, 0x25);
974 write_rtl8255(dev, 0x2, 0x26);
975 write_rtl8255(dev, 0x4, 0x61f);
976 write_rtl8255(dev, 0x4, 0x41f);
977 write_rtl8255(dev, 0x4, 0x41f);
978 write_rtl8255(dev, 0x3, 0x100);
979 write_rtl8255(dev, 0x4, 0x61f);
980 write_rtl8255(dev, 0x4, 0x41f);
981 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404020, 0x80000027,
982 0x92402a98, 0xf8009, 0x28000, 0xc00, 0x0);
983 write_rtl8255(dev, 0x1, 0x807);
984 write_rtl8255(dev, 0x4, 0xc20);
985 write_rtl8255(dev, 0x4, 0xe20);
986 write_rtl8255(dev, 0x4, 0xc20);
987 write_rtl8255(dev, 0x1, 0x0);
988 write_rtl8255(dev, 0x4, 0x820);
989 write_rtl8255(dev, 0x3, 0x0);
990 write_rtl8255(dev, 0x2, 0x0);
991 write_rtl8255(dev, 0x4, 0xa20);
992 write_rtl8255(dev, 0x4, 0x820);
993 write_rtl8255(dev, 0x4, 0x420);
994 write_rtl8255(dev, 0x3, 0x25);
995 write_rtl8255(dev, 0x2, 0x26);
996 write_rtl8255(dev, 0x4, 0x620);
997 write_rtl8255(dev, 0x4, 0x420);
998 write_rtl8255(dev, 0x4, 0x420);
999 write_rtl8255(dev, 0x3, 0x100);
1000 write_rtl8255(dev, 0x4, 0x620);
1001 write_rtl8255(dev, 0x4, 0x420);
1002 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404020, 0x27,
1003 0x92402a98, 0xf8009, 0x28000, 0xc00, 0x0);
1004 write_rtl8255(dev, 0x1, 0x807);
1005 write_rtl8255(dev, 0x4, 0xc21);
1006 write_rtl8255(dev, 0x4, 0xe21);
1007 write_rtl8255(dev, 0x4, 0xc21);
1008 write_rtl8255(dev, 0x1, 0x0);
1009 write_rtl8255(dev, 0x4, 0x821);
1010 write_rtl8255(dev, 0x3, 0x0);
1011 write_rtl8255(dev, 0x2, 0x0);
1012 write_rtl8255(dev, 0x4, 0xa21);
1013 write_rtl8255(dev, 0x4, 0x821);
1014 write_rtl8255(dev, 0x4, 0x421);
1015 write_rtl8255(dev, 0x3, 0x25);
1016 write_rtl8255(dev, 0x2, 0x26);
1017 write_rtl8255(dev, 0x4, 0x621);
1018 write_rtl8255(dev, 0x4, 0x421);
1019 write_rtl8255(dev, 0x4, 0x421);
1020 write_rtl8255(dev, 0x3, 0x100);
1021 write_rtl8255(dev, 0x4, 0x621);
1022 write_rtl8255(dev, 0x4, 0x421);
1023 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
1024 0x92402a68, 0xf0009, 0x10028000, 0xc00, 0x0);
1025 write_rtl8255(dev, 0x1, 0x807);
1026 write_rtl8255(dev, 0x4, 0xc22);
1027 write_rtl8255(dev, 0x4, 0xe22);
1028 write_rtl8255(dev, 0x4, 0xc22);
1029 write_rtl8255(dev, 0x1, 0x0);
1030 write_rtl8255(dev, 0x4, 0x822);
1031 write_rtl8255(dev, 0x3, 0x0);
1032 write_rtl8255(dev, 0x2, 0x0);
1033 write_rtl8255(dev, 0x4, 0xa22);
1034 write_rtl8255(dev, 0x4, 0x822);
1035 write_rtl8255(dev, 0x4, 0x422);
1036 write_rtl8255(dev, 0x3, 0x25);
1037 write_rtl8255(dev, 0x2, 0x26);
1038 write_rtl8255(dev, 0x4, 0x622);
1039 write_rtl8255(dev, 0x4, 0x422);
1040 write_rtl8255(dev, 0x4, 0x422);
1041 write_rtl8255(dev, 0x3, 0x100);
1042 write_rtl8255(dev, 0x4, 0x622);
1043 write_rtl8255(dev, 0x4, 0x422);
1044 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404010, 0x80000027,
1045 0x92402a68, 0xf0009, 0x20028000, 0xc00, 0x0);
1046 write_rtl8255(dev, 0x1, 0x807);
1047 write_rtl8255(dev, 0x4, 0xc23);
1048 write_rtl8255(dev, 0x4, 0xe23);
1049 write_rtl8255(dev, 0x4, 0xc23);
1050 write_rtl8255(dev, 0x1, 0x0);
1051 write_rtl8255(dev, 0x4, 0x823);
1052 write_rtl8255(dev, 0x3, 0x0);
1053 write_rtl8255(dev, 0x2, 0x0);
1054 write_rtl8255(dev, 0x4, 0xa23);
1055 write_rtl8255(dev, 0x4, 0x823);
1056 write_rtl8255(dev, 0x4, 0x423);
1057 write_rtl8255(dev, 0x3, 0x25);
1058 write_rtl8255(dev, 0x2, 0x26);
1059 write_rtl8255(dev, 0x4, 0x623);
1060 write_rtl8255(dev, 0x4, 0x423);
1061 write_rtl8255(dev, 0x4, 0x423);
1062 write_rtl8255(dev, 0x3, 0x100);
1063 write_rtl8255(dev, 0x4, 0x623);
1064 write_rtl8255(dev, 0x4, 0x423);
1065 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404010, 0x80000027,
1066 0x92402a6c, 0xf0009, 0x30028000, 0xc00, 0x0);
1067 write_rtl8255(dev, 0x1, 0x807);
1068 write_rtl8255(dev, 0x4, 0xc24);
1069 write_rtl8255(dev, 0x4, 0xe24);
1070 write_rtl8255(dev, 0x4, 0xc24);
1071 write_rtl8255(dev, 0x1, 0x0);
1072 write_rtl8255(dev, 0x4, 0x824);
1073 write_rtl8255(dev, 0x3, 0x0);
1074 write_rtl8255(dev, 0x2, 0x0);
1075 write_rtl8255(dev, 0x4, 0xa24);
1076 write_rtl8255(dev, 0x4, 0x824);
1077 write_rtl8255(dev, 0x4, 0x424);
1078 write_rtl8255(dev, 0x3, 0x25);
1079 write_rtl8255(dev, 0x2, 0x26);
1080 write_rtl8255(dev, 0x4, 0x624);
1081 write_rtl8255(dev, 0x4, 0x424);
1082 write_rtl8255(dev, 0x4, 0x424);
1083 write_rtl8255(dev, 0x3, 0x100);
1084 write_rtl8255(dev, 0x4, 0x624);
1085 write_rtl8255(dev, 0x4, 0x424);
1086 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404010, 0x80000027,
1087 0x92402a6c, 0xf0009, 0x40028000, 0xc00, 0x0);
1088 write_rtl8255(dev, 0x1, 0x807);
1089 write_rtl8255(dev, 0x4, 0xc25);
1090 write_rtl8255(dev, 0x4, 0xe25);
1091 write_rtl8255(dev, 0x4, 0xc25);
1092 write_rtl8255(dev, 0x1, 0x0);
1093 write_rtl8255(dev, 0x4, 0x825);
1094 write_rtl8255(dev, 0x3, 0x0);
1095 write_rtl8255(dev, 0x2, 0x0);
1096 write_rtl8255(dev, 0x4, 0xa25);
1097 write_rtl8255(dev, 0x4, 0x825);
1098 write_rtl8255(dev, 0x4, 0x425);
1099 write_rtl8255(dev, 0x3, 0x25);
1100 write_rtl8255(dev, 0x2, 0x26);
1101 write_rtl8255(dev, 0x4, 0x625);
1102 write_rtl8255(dev, 0x4, 0x425);
1103 write_rtl8255(dev, 0x4, 0x425);
1104 write_rtl8255(dev, 0x3, 0x100);
1105 write_rtl8255(dev, 0x4, 0x625);
1106 write_rtl8255(dev, 0x4, 0x425);
1107 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
1108 0x92402a70, 0xf0009, 0x60028000, 0xc00, 0x0);
1109 write_rtl8255(dev, 0x1, 0x807);
1110 write_rtl8255(dev, 0x4, 0xc26);
1111 write_rtl8255(dev, 0x4, 0xe26);
1112 write_rtl8255(dev, 0x4, 0xc26);
1113 write_rtl8255(dev, 0x1, 0x0);
1114 write_rtl8255(dev, 0x4, 0x826);
1115 write_rtl8255(dev, 0x3, 0x0);
1116 write_rtl8255(dev, 0x2, 0x0);
1117 write_rtl8255(dev, 0x4, 0xa26);
1118 write_rtl8255(dev, 0x4, 0x826);
1119 write_rtl8255(dev, 0x4, 0x426);
1120 write_rtl8255(dev, 0x3, 0x25);
1121 write_rtl8255(dev, 0x2, 0x26);
1122 write_rtl8255(dev, 0x4, 0x626);
1123 write_rtl8255(dev, 0x4, 0x426);
1124 write_rtl8255(dev, 0x4, 0x426);
1125 write_rtl8255(dev, 0x3, 0x100);
1126 write_rtl8255(dev, 0x4, 0x626);
1127 write_rtl8255(dev, 0x4, 0x426);
1128 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404031, 0x40000027,
1129 0x92402a70, 0xf0011, 0x60028000, 0xc00, 0x0);
1130 write_rtl8255(dev, 0x1, 0x807);
1131 write_rtl8255(dev, 0x4, 0xc27);
1132 write_rtl8255(dev, 0x4, 0xe27);
1133 write_rtl8255(dev, 0x4, 0xc27);
1134 write_rtl8255(dev, 0x1, 0x0);
1135 write_rtl8255(dev, 0x4, 0x827);
1136 write_rtl8255(dev, 0x3, 0x0);
1137 write_rtl8255(dev, 0x2, 0x0);
1138 write_rtl8255(dev, 0x4, 0xa27);
1139 write_rtl8255(dev, 0x4, 0x827);
1140 write_rtl8255(dev, 0x4, 0x427);
1141 write_rtl8255(dev, 0x3, 0x25);
1142 write_rtl8255(dev, 0x2, 0x26);
1143 write_rtl8255(dev, 0x4, 0x627);
1144 write_rtl8255(dev, 0x4, 0x427);
1145 write_rtl8255(dev, 0x4, 0x427);
1146 write_rtl8255(dev, 0x3, 0x100);
1147 write_rtl8255(dev, 0x4, 0x627);
1148 write_rtl8255(dev, 0x4, 0x427);
1149 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404011, 0x40000027,
1150 0x92402a74, 0xf0011, 0x60028000, 0xc00, 0x0);
1151 write_rtl8255(dev, 0x1, 0x807);
1152 write_rtl8255(dev, 0x4, 0xc28);
1153 write_rtl8255(dev, 0x4, 0xe28);
1154 write_rtl8255(dev, 0x4, 0xc28);
1155 write_rtl8255(dev, 0x1, 0x0);
1156 write_rtl8255(dev, 0x4, 0x828);
1157 write_rtl8255(dev, 0x3, 0x0);
1158 write_rtl8255(dev, 0x2, 0x0);
1159 write_rtl8255(dev, 0x4, 0xa28);
1160 write_rtl8255(dev, 0x4, 0x828);
1161 write_rtl8255(dev, 0x4, 0x428);
1162 write_rtl8255(dev, 0x3, 0x25);
1163 write_rtl8255(dev, 0x2, 0x26);
1164 write_rtl8255(dev, 0x4, 0x628);
1165 write_rtl8255(dev, 0x4, 0x428);
1166 write_rtl8255(dev, 0x4, 0x428);
1167 write_rtl8255(dev, 0x3, 0x100);
1168 write_rtl8255(dev, 0x4, 0x628);
1169 write_rtl8255(dev, 0x4, 0x428);
1170 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404010, 0xc0000027,
1171 0x92402a74, 0xf0011, 0x60028000, 0xc00, 0x0);
1172 write_rtl8255(dev, 0x1, 0x807);
1173 write_rtl8255(dev, 0x4, 0xc29);
1174 write_rtl8255(dev, 0x4, 0xe29);
1175 write_rtl8255(dev, 0x4, 0xc29);
1176 write_rtl8255(dev, 0x1, 0x0);
1177 write_rtl8255(dev, 0x4, 0x829);
1178 write_rtl8255(dev, 0x3, 0x0);
1179 write_rtl8255(dev, 0x2, 0x0);
1180 write_rtl8255(dev, 0x4, 0xa29);
1181 write_rtl8255(dev, 0x4, 0x829);
1182 write_rtl8255(dev, 0x4, 0x429);
1183 write_rtl8255(dev, 0x3, 0x25);
1184 write_rtl8255(dev, 0x2, 0x26);
1185 write_rtl8255(dev, 0x4, 0x629);
1186 write_rtl8255(dev, 0x4, 0x429);
1187 write_rtl8255(dev, 0x4, 0x429);
1188 write_rtl8255(dev, 0x3, 0x100);
1189 write_rtl8255(dev, 0x4, 0x629);
1190 write_rtl8255(dev, 0x4, 0x429);
1191 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
1192 0x92402a78, 0xf0011, 0x60028000, 0xc00, 0x0);
1193 write_rtl8255(dev, 0x1, 0x807);
1194 write_rtl8255(dev, 0x4, 0xc2a);
1195 write_rtl8255(dev, 0x4, 0xe2a);
1196 write_rtl8255(dev, 0x4, 0xc2a);
1197 write_rtl8255(dev, 0x1, 0x0);
1198 write_rtl8255(dev, 0x4, 0x82a);
1199 write_rtl8255(dev, 0x3, 0x0);
1200 write_rtl8255(dev, 0x2, 0x0);
1201 write_rtl8255(dev, 0x4, 0xa2a);
1202 write_rtl8255(dev, 0x4, 0x82a);
1203 write_rtl8255(dev, 0x4, 0x42a);
1204 write_rtl8255(dev, 0x3, 0x24);
1205 write_rtl8255(dev, 0x2, 0x26);
1206 write_rtl8255(dev, 0x4, 0x62a);
1207 write_rtl8255(dev, 0x4, 0x42a);
1208 write_rtl8255(dev, 0x4, 0x42a);
1209 write_rtl8255(dev, 0x3, 0x100);
1210 write_rtl8255(dev, 0x4, 0x62a);
1211 write_rtl8255(dev, 0x4, 0x42a);
1212 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
1213 0x92402a78, 0xf0011, 0x70028000, 0xc00, 0x0);
1214 write_rtl8255(dev, 0x1, 0x807);
1215 write_rtl8255(dev, 0x4, 0xc2b);
1216 write_rtl8255(dev, 0x4, 0xe2b);
1217 write_rtl8255(dev, 0x4, 0xc2b);
1218 write_rtl8255(dev, 0x1, 0x0);
1219 write_rtl8255(dev, 0x4, 0x82b);
1220 write_rtl8255(dev, 0x3, 0x0);
1221 write_rtl8255(dev, 0x2, 0x0);
1222 write_rtl8255(dev, 0x4, 0xa2b);
1223 write_rtl8255(dev, 0x4, 0x82b);
1224 write_rtl8255(dev, 0x4, 0x42b);
1225 write_rtl8255(dev, 0x3, 0x24);
1226 write_rtl8255(dev, 0x2, 0x26);
1227 write_rtl8255(dev, 0x4, 0x62b);
1228 write_rtl8255(dev, 0x4, 0x42b);
1229 write_rtl8255(dev, 0x4, 0x42b);
1230 write_rtl8255(dev, 0x3, 0x100);
1231 write_rtl8255(dev, 0x4, 0x62b);
1232 write_rtl8255(dev, 0x4, 0x42b);
1233 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
1234 0x92402a48, 0xf0019, 0x70028000, 0xc00, 0x0);
1235 write_rtl8255(dev, 0x1, 0x807);
1236 write_rtl8255(dev, 0x4, 0xc2c);
1237 write_rtl8255(dev, 0x4, 0xe2c);
1238 write_rtl8255(dev, 0x4, 0xc2c);
1239 write_rtl8255(dev, 0x1, 0x0);
1240 write_rtl8255(dev, 0x4, 0x82c);
1241 write_rtl8255(dev, 0x3, 0x0);
1242 write_rtl8255(dev, 0x2, 0x0);
1243 write_rtl8255(dev, 0x4, 0xa2c);
1244 write_rtl8255(dev, 0x4, 0x82c);
1245 write_rtl8255(dev, 0x4, 0x42c);
1246 write_rtl8255(dev, 0x3, 0x24);
1247 write_rtl8255(dev, 0x2, 0x26);
1248 write_rtl8255(dev, 0x4, 0x62c);
1249 write_rtl8255(dev, 0x4, 0x42c);
1250 write_rtl8255(dev, 0x4, 0x42c);
1251 write_rtl8255(dev, 0x3, 0x100);
1252 write_rtl8255(dev, 0x4, 0x62c);
1253 write_rtl8255(dev, 0x4, 0x42c);
1254 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
1255 0x92402a48, 0xf8019, 0x70028000, 0xc00, 0x0);
1256 write_rtl8255(dev, 0x1, 0x807);
1257 write_rtl8255(dev, 0x4, 0xc2d);
1258 write_rtl8255(dev, 0x4, 0xe2d);
1259 write_rtl8255(dev, 0x4, 0xc2d);
1260 write_rtl8255(dev, 0x1, 0x0);
1261 write_rtl8255(dev, 0x4, 0x82d);
1262 write_rtl8255(dev, 0x3, 0x0);
1263 write_rtl8255(dev, 0x2, 0x0);
1264 write_rtl8255(dev, 0x4, 0xa2d);
1265 write_rtl8255(dev, 0x4, 0x82d);
1266 write_rtl8255(dev, 0x4, 0x42d);
1267 write_rtl8255(dev, 0x3, 0x24);
1268 write_rtl8255(dev, 0x2, 0x26);
1269 write_rtl8255(dev, 0x4, 0x62d);
1270 write_rtl8255(dev, 0x4, 0x42d);
1271 write_rtl8255(dev, 0x4, 0x42d);
1272 write_rtl8255(dev, 0x3, 0x100);
1273 write_rtl8255(dev, 0x4, 0x62d);
1274 write_rtl8255(dev, 0x4, 0x42d);
1275 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
1276 0x92402a4c, 0xf8019, 0x70028000, 0xc00, 0x0);
1277 write_rtl8255(dev, 0x1, 0x807);
1278 write_rtl8255(dev, 0x4, 0xc2e);
1279 write_rtl8255(dev, 0x4, 0xe2e);
1280 write_rtl8255(dev, 0x4, 0xc2e);
1281 write_rtl8255(dev, 0x1, 0x0);
1282 write_rtl8255(dev, 0x4, 0x82e);
1283 write_rtl8255(dev, 0x3, 0x0);
1284 write_rtl8255(dev, 0x2, 0x0);
1285 write_rtl8255(dev, 0x4, 0xa2e);
1286 write_rtl8255(dev, 0x4, 0x82e);
1287 write_rtl8255(dev, 0x4, 0x42e);
1288 write_rtl8255(dev, 0x3, 0x24);
1289 write_rtl8255(dev, 0x2, 0x26);
1290 write_rtl8255(dev, 0x4, 0x62e);
1291 write_rtl8255(dev, 0x4, 0x42e);
1292 write_rtl8255(dev, 0x4, 0x42e);
1293 write_rtl8255(dev, 0x3, 0x100);
1294 write_rtl8255(dev, 0x4, 0x62e);
1295 write_rtl8255(dev, 0x4, 0x42e);
1296 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
1297 0x92402a4c, 0xf8019, 0x70028000, 0xc00, 0x0);
1298 write_rtl8255(dev, 0x1, 0x807);
1299 write_rtl8255(dev, 0x4, 0xc2f);
1300 write_rtl8255(dev, 0x4, 0xe2f);
1301 write_rtl8255(dev, 0x4, 0xc2f);
1302 write_rtl8255(dev, 0x1, 0x0);
1303 write_rtl8255(dev, 0x4, 0x82f);
1304 write_rtl8255(dev, 0x3, 0x0);
1305 write_rtl8255(dev, 0x2, 0x0);
1306 write_rtl8255(dev, 0x4, 0xa2f);
1307 write_rtl8255(dev, 0x4, 0x82f);
1308 write_rtl8255(dev, 0x4, 0x42f);
1309 write_rtl8255(dev, 0x3, 0x24);
1310 write_rtl8255(dev, 0x2, 0x26);
1311 write_rtl8255(dev, 0x4, 0x62f);
1312 write_rtl8255(dev, 0x4, 0x42f);
1313 write_rtl8255(dev, 0x4, 0x42f);
1314 write_rtl8255(dev, 0x3, 0x100);
1315 write_rtl8255(dev, 0x4, 0x62f);
1316 write_rtl8255(dev, 0x4, 0x42f);
1317 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
1318 0x92402a50, 0xf8019, 0x70028000, 0xc00, 0x0);
1319 write_rtl8255(dev, 0x1, 0x807);
1320 write_rtl8255(dev, 0x4, 0xc30);
1321 write_rtl8255(dev, 0x4, 0xe30);
1322 write_rtl8255(dev, 0x4, 0xc30);
1323 write_rtl8255(dev, 0x1, 0x0);
1324 write_rtl8255(dev, 0x4, 0x830);
1325 write_rtl8255(dev, 0x3, 0x0);
1326 write_rtl8255(dev, 0x2, 0x0);
1327 write_rtl8255(dev, 0x4, 0xa30);
1328 write_rtl8255(dev, 0x4, 0x830);
1329 write_rtl8255(dev, 0x4, 0x430);
1330 write_rtl8255(dev, 0x3, 0x24);
1331 write_rtl8255(dev, 0x2, 0x26);
1332 write_rtl8255(dev, 0x4, 0x630);
1333 write_rtl8255(dev, 0x4, 0x430);
1334 write_rtl8255(dev, 0x4, 0x430);
1335 write_rtl8255(dev, 0x3, 0x100);
1336 write_rtl8255(dev, 0x4, 0x630);
1337 write_rtl8255(dev, 0x4, 0x430);
1338 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
1339 0x92402a50, 0xf8019, 0x70028000, 0xc00, 0x0);
1340 write_rtl8255(dev, 0x1, 0x807);
1341 write_rtl8255(dev, 0x4, 0xc31);
1342 write_rtl8255(dev, 0x4, 0xe31);
1343 write_rtl8255(dev, 0x4, 0xc31);
1344 write_rtl8255(dev, 0x1, 0x0);
1345 write_rtl8255(dev, 0x4, 0x831);
1346 write_rtl8255(dev, 0x3, 0x0);
1347 write_rtl8255(dev, 0x2, 0x0);
1348 write_rtl8255(dev, 0x4, 0xa31);
1349 write_rtl8255(dev, 0x4, 0x831);
1350 write_rtl8255(dev, 0x4, 0x431);
1351 write_rtl8255(dev, 0x3, 0x24);
1352 write_rtl8255(dev, 0x2, 0x26);
1353 write_rtl8255(dev, 0x4, 0x631);
1354 write_rtl8255(dev, 0x4, 0x431);
1355 write_rtl8255(dev, 0x4, 0x431);
1356 write_rtl8255(dev, 0x3, 0x100);
1357 write_rtl8255(dev, 0x4, 0x631);
1358 write_rtl8255(dev, 0x4, 0x431);
1359 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
1360 0x92402a54, 0xf8019, 0x70028000, 0xc00, 0x0);
1361 write_rtl8255(dev, 0x1, 0x807);
1362 write_rtl8255(dev, 0x4, 0xc32);
1363 write_rtl8255(dev, 0x4, 0xe32);
1364 write_rtl8255(dev, 0x4, 0xc32);
1365 write_rtl8255(dev, 0x1, 0x0);
1366 write_rtl8255(dev, 0x4, 0x832);
1367 write_rtl8255(dev, 0x3, 0x0);
1368 write_rtl8255(dev, 0x2, 0x0);
1369 write_rtl8255(dev, 0x4, 0xa32);
1370 write_rtl8255(dev, 0x4, 0x832);
1371 write_rtl8255(dev, 0x4, 0x432);
1372 write_rtl8255(dev, 0x3, 0x24);
1373 write_rtl8255(dev, 0x2, 0x26);
1374 write_rtl8255(dev, 0x4, 0x632);
1375 write_rtl8255(dev, 0x4, 0x432);
1376 write_rtl8255(dev, 0x4, 0x432);
1377 write_rtl8255(dev, 0x3, 0x100);
1378 write_rtl8255(dev, 0x4, 0x632);
1379 write_rtl8255(dev, 0x4, 0x432);
1380 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
1381 0x92402a54, 0xf8019, 0x70028000, 0xc00, 0x0);
1382 write_rtl8255(dev, 0x1, 0x807);
1383 write_rtl8255(dev, 0x4, 0xc33);
1384 write_rtl8255(dev, 0x4, 0xe33);
1385 write_rtl8255(dev, 0x4, 0xc33);
1386 write_rtl8255(dev, 0x1, 0x0);
1387 write_rtl8255(dev, 0x4, 0x833);
1388 write_rtl8255(dev, 0x3, 0x0);
1389 write_rtl8255(dev, 0x2, 0x0);
1390 write_rtl8255(dev, 0x4, 0xa33);
1391 write_rtl8255(dev, 0x4, 0x833);
1392 write_rtl8255(dev, 0x4, 0x433);
1393 write_rtl8255(dev, 0x3, 0x24);
1394 write_rtl8255(dev, 0x2, 0x26);
1395 write_rtl8255(dev, 0x4, 0x633);
1396 write_rtl8255(dev, 0x4, 0x433);
1397 write_rtl8255(dev, 0x4, 0x433);
1398 write_rtl8255(dev, 0x3, 0x100);
1399 write_rtl8255(dev, 0x4, 0x633);
1400 write_rtl8255(dev, 0x4, 0x433);
1401 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
1402 0x92402a58, 0xf8019, 0x70028000, 0xc00, 0x0);
1403 write_rtl8255(dev, 0x1, 0x807);
1404 write_rtl8255(dev, 0x4, 0xc34);
1405 write_rtl8255(dev, 0x4, 0xe34);
1406 write_rtl8255(dev, 0x4, 0xc34);
1407 write_rtl8255(dev, 0x1, 0x0);
1408 write_rtl8255(dev, 0x4, 0x834);
1409 write_rtl8255(dev, 0x3, 0x0);
1410 write_rtl8255(dev, 0x2, 0x0);
1411 write_rtl8255(dev, 0x4, 0xa34);
1412 write_rtl8255(dev, 0x4, 0x834);
1413 write_rtl8255(dev, 0x4, 0x434);
1414 write_rtl8255(dev, 0x3, 0x24);
1415 write_rtl8255(dev, 0x2, 0x26);
1416 write_rtl8255(dev, 0x4, 0x634);
1417 write_rtl8255(dev, 0x4, 0x434);
1418 write_rtl8255(dev, 0x4, 0x434);
1419 write_rtl8255(dev, 0x3, 0x100);
1420 write_rtl8255(dev, 0x4, 0x634);
1421 write_rtl8255(dev, 0x4, 0x434);
1422 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
1423 0x92402a58, 0xf8019, 0x70028000, 0xc00, 0x0);
1424 write_rtl8255(dev, 0x1, 0x807);
1425 write_rtl8255(dev, 0x4, 0xc35);
1426 write_rtl8255(dev, 0x4, 0xe35);
1427 write_rtl8255(dev, 0x4, 0xc35);
1428 write_rtl8255(dev, 0x1, 0x0);
1429 write_rtl8255(dev, 0x4, 0x835);
1430 write_rtl8255(dev, 0x3, 0x0);
1431 write_rtl8255(dev, 0x2, 0x0);
1432 write_rtl8255(dev, 0x4, 0xa35);
1433 write_rtl8255(dev, 0x4, 0x835);
1434 write_rtl8255(dev, 0x4, 0x435);
1435 write_rtl8255(dev, 0x3, 0x24);
1436 write_rtl8255(dev, 0x2, 0x26);
1437 write_rtl8255(dev, 0x4, 0x635);
1438 write_rtl8255(dev, 0x4, 0x435);
1439 write_rtl8255(dev, 0x4, 0x435);
1440 write_rtl8255(dev, 0x3, 0x100);
1441 write_rtl8255(dev, 0x4, 0x635);
1442 write_rtl8255(dev, 0x4, 0x435);
1443 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
1444 0x92402a24, 0xf8019, 0x70028000, 0xc00, 0x0);
1445 write_rtl8255(dev, 0x1, 0x807);
1446 write_rtl8255(dev, 0x4, 0xc36);
1447 write_rtl8255(dev, 0x4, 0xe36);
1448 write_rtl8255(dev, 0x4, 0xc36);
1449 write_rtl8255(dev, 0x1, 0x0);
1450 write_rtl8255(dev, 0x4, 0x836);
1451 write_rtl8255(dev, 0x3, 0x0);
1452 write_rtl8255(dev, 0x2, 0x0);
1453 write_rtl8255(dev, 0x4, 0xa36);
1454 write_rtl8255(dev, 0x4, 0x836);
1455 write_rtl8255(dev, 0x4, 0x436);
1456 write_rtl8255(dev, 0x3, 0x24);
1457 write_rtl8255(dev, 0x2, 0x25);
1458 write_rtl8255(dev, 0x4, 0x636);
1459 write_rtl8255(dev, 0x4, 0x436);
1460 write_rtl8255(dev, 0x4, 0x436);
1461 write_rtl8255(dev, 0x3, 0x100);
1462 write_rtl8255(dev, 0x4, 0x636);
1463 write_rtl8255(dev, 0x4, 0x436);
1464 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
1465 0x92402a24, 0xf8019, 0x70028000, 0xc00, 0x0);
1466 write_rtl8255(dev, 0x1, 0x807);
1467 write_rtl8255(dev, 0x4, 0xc37);
1468 write_rtl8255(dev, 0x4, 0xe37);
1469 write_rtl8255(dev, 0x4, 0xc37);
1470 write_rtl8255(dev, 0x1, 0x0);
1471 write_rtl8255(dev, 0x4, 0x837);
1472 write_rtl8255(dev, 0x3, 0x0);
1473 write_rtl8255(dev, 0x2, 0x0);
1474 write_rtl8255(dev, 0x4, 0xa37);
1475 write_rtl8255(dev, 0x4, 0x837);
1476 write_rtl8255(dev, 0x4, 0x437);
1477 write_rtl8255(dev, 0x3, 0x24);
1478 write_rtl8255(dev, 0x2, 0x25);
1479 write_rtl8255(dev, 0x4, 0x637);
1480 write_rtl8255(dev, 0x4, 0x437);
1481 write_rtl8255(dev, 0x4, 0x437);
1482 write_rtl8255(dev, 0x3, 0x100);
1483 write_rtl8255(dev, 0x4, 0x637);
1484 write_rtl8255(dev, 0x4, 0x437);
1485 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
1486 0x92402a28, 0xf8019, 0x70028000, 0xc00, 0x0);
1487 write_rtl8255(dev, 0x1, 0x807);
1488 write_rtl8255(dev, 0x4, 0xc38);
1489 write_rtl8255(dev, 0x4, 0xe38);
1490 write_rtl8255(dev, 0x4, 0xc38);
1491 write_rtl8255(dev, 0x1, 0x0);
1492 write_rtl8255(dev, 0x4, 0x838);
1493 write_rtl8255(dev, 0x3, 0x0);
1494 write_rtl8255(dev, 0x2, 0x0);
1495 write_rtl8255(dev, 0x4, 0xa38);
1496 write_rtl8255(dev, 0x4, 0x838);
1497 write_rtl8255(dev, 0x4, 0x438);
1498 write_rtl8255(dev, 0x3, 0x24);
1499 write_rtl8255(dev, 0x2, 0x25);
1500 write_rtl8255(dev, 0x4, 0x638);
1501 write_rtl8255(dev, 0x4, 0x438);
1502 write_rtl8255(dev, 0x4, 0x438);
1503 write_rtl8255(dev, 0x3, 0x100);
1504 write_rtl8255(dev, 0x4, 0x638);
1505 write_rtl8255(dev, 0x4, 0x438);
1506 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
1507 0x92402a28, 0xf8019, 0x70028000, 0xc00, 0x0);
1508 write_rtl8255(dev, 0x1, 0x807);
1509 write_rtl8255(dev, 0x4, 0xc39);
1510 write_rtl8255(dev, 0x4, 0xe39);
1511 write_rtl8255(dev, 0x4, 0xc39);
1512 write_rtl8255(dev, 0x1, 0x0);
1513 write_rtl8255(dev, 0x4, 0x839);
1514 write_rtl8255(dev, 0x3, 0x0);
1515 write_rtl8255(dev, 0x2, 0x0);
1516 write_rtl8255(dev, 0x4, 0xa39);
1517 write_rtl8255(dev, 0x4, 0x839);
1518 write_rtl8255(dev, 0x4, 0x439);
1519 write_rtl8255(dev, 0x3, 0x24);
1520 write_rtl8255(dev, 0x2, 0x25);
1521 write_rtl8255(dev, 0x4, 0x639);
1522 write_rtl8255(dev, 0x4, 0x439);
1523 write_rtl8255(dev, 0x4, 0x439);
1524 write_rtl8255(dev, 0x3, 0x100);
1525 write_rtl8255(dev, 0x4, 0x639);
1526 write_rtl8255(dev, 0x4, 0x439);
1527 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
1528 0x92402a00, 0xf8019, 0x70028000, 0xc00, 0x0);
1529 write_rtl8255(dev, 0x1, 0x807);
1530 write_rtl8255(dev, 0x4, 0xc3a);
1531 write_rtl8255(dev, 0x4, 0xe3a);
1532 write_rtl8255(dev, 0x4, 0xc3a);
1533 write_rtl8255(dev, 0x1, 0x0);
1534 write_rtl8255(dev, 0x4, 0x83a);
1535 write_rtl8255(dev, 0x3, 0x0);
1536 write_rtl8255(dev, 0x2, 0x0);
1537 write_rtl8255(dev, 0x4, 0xa3a);
1538 write_rtl8255(dev, 0x4, 0x83a);
1539 write_rtl8255(dev, 0x4, 0x43a);
1540 write_rtl8255(dev, 0x3, 0x0);
1541 write_rtl8255(dev, 0x2, 0x0);
1542 write_rtl8255(dev, 0x4, 0x63a);
1543 write_rtl8255(dev, 0x4, 0x43a);
1544 write_rtl8255(dev, 0x4, 0x43a);
1545 write_rtl8255(dev, 0x3, 0x100);
1546 write_rtl8255(dev, 0x4, 0x63a);
1547 write_rtl8255(dev, 0x4, 0x43a);
1548 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
1549 0x92402a00, 0xf8019, 0x70028000, 0xc00, 0x0);
1550 write_rtl8255(dev, 0x1, 0x807);
1551 write_rtl8255(dev, 0x4, 0xc3b);
1552 write_rtl8255(dev, 0x4, 0xe3b);
1553 write_rtl8255(dev, 0x4, 0xc3b);
1554 write_rtl8255(dev, 0x1, 0x0);
1555 write_rtl8255(dev, 0x4, 0x83b);
1556 write_rtl8255(dev, 0x3, 0x0);
1557 write_rtl8255(dev, 0x2, 0x0);
1558 write_rtl8255(dev, 0x4, 0xa3b);
1559 write_rtl8255(dev, 0x4, 0x83b);
1560 write_rtl8255(dev, 0x4, 0x43b);
1561 write_rtl8255(dev, 0x3, 0x0);
1562 write_rtl8255(dev, 0x2, 0x0);
1563 write_rtl8255(dev, 0x4, 0x63b);
1564 write_rtl8255(dev, 0x4, 0x43b);
1565 write_rtl8255(dev, 0x4, 0x43b);
1566 write_rtl8255(dev, 0x3, 0x100);
1567 write_rtl8255(dev, 0x4, 0x63b);
1568 write_rtl8255(dev, 0x4, 0x43b);
1569 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
1570 0x92402a00, 0xf8019, 0x70028000, 0xc00, 0x0);
1571 write_rtl8255(dev, 0x1, 0x807);
1572 write_rtl8255(dev, 0x4, 0xc3c);
1573 write_rtl8255(dev, 0x4, 0xe3c);
1574 write_rtl8255(dev, 0x4, 0xc3c);
1575 write_rtl8255(dev, 0x1, 0x0);
1576 write_rtl8255(dev, 0x4, 0x83c);
1577 write_rtl8255(dev, 0x3, 0x0);
1578 write_rtl8255(dev, 0x2, 0x0);
1579 write_rtl8255(dev, 0x4, 0xa3c);
1580 write_rtl8255(dev, 0x4, 0x83c);
1581 write_rtl8255(dev, 0x4, 0x43c);
1582 write_rtl8255(dev, 0x3, 0x0);
1583 write_rtl8255(dev, 0x2, 0x0);
1584 write_rtl8255(dev, 0x4, 0x63c);
1585 write_rtl8255(dev, 0x4, 0x43c);
1586 write_rtl8255(dev, 0x4, 0x43c);
1587 write_rtl8255(dev, 0x3, 0x100);
1588 write_rtl8255(dev, 0x4, 0x63c);
1589 write_rtl8255(dev, 0x4, 0x43c);
1590 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
1591 0x92402a00, 0xf8019, 0x70028000, 0xc00, 0x0);
1592 write_rtl8255(dev, 0x1, 0x807);
1593 write_rtl8255(dev, 0x4, 0xc3d);
1594 write_rtl8255(dev, 0x4, 0xe3d);
1595 write_rtl8255(dev, 0x4, 0xc3d);
1596 write_rtl8255(dev, 0x1, 0x0);
1597 write_rtl8255(dev, 0x4, 0x83d);
1598 write_rtl8255(dev, 0x3, 0x0);
1599 write_rtl8255(dev, 0x2, 0x0);
1600 write_rtl8255(dev, 0x4, 0xa3d);
1601 write_rtl8255(dev, 0x4, 0x83d);
1602 write_rtl8255(dev, 0x4, 0x43d);
1603 write_rtl8255(dev, 0x3, 0x0);
1604 write_rtl8255(dev, 0x2, 0x0);
1605 write_rtl8255(dev, 0x4, 0x63d);
1606 write_rtl8255(dev, 0x4, 0x43d);
1607 write_rtl8255(dev, 0x4, 0x43d);
1608 write_rtl8255(dev, 0x3, 0x100);
1609 write_rtl8255(dev, 0x4, 0x63d);
1610 write_rtl8255(dev, 0x4, 0x43d);
1611 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
1612 0x92402a00, 0xf8019, 0x70028000, 0xc00, 0x0);
1613 write_rtl8255(dev, 0x1, 0x807);
1614 write_rtl8255(dev, 0x4, 0xc3e);
1615 write_rtl8255(dev, 0x4, 0xe3e);
1616 write_rtl8255(dev, 0x4, 0xc3e);
1617 write_rtl8255(dev, 0x1, 0x0);
1618 write_rtl8255(dev, 0x4, 0x83e);
1619 write_rtl8255(dev, 0x3, 0x0);
1620 write_rtl8255(dev, 0x2, 0x0);
1621 write_rtl8255(dev, 0x4, 0xa3e);
1622 write_rtl8255(dev, 0x4, 0x83e);
1623 write_rtl8255(dev, 0x4, 0x43e);
1624 write_rtl8255(dev, 0x3, 0x0);
1625 write_rtl8255(dev, 0x2, 0x0);
1626 write_rtl8255(dev, 0x4, 0x63e);
1627 write_rtl8255(dev, 0x4, 0x43e);
1628 write_rtl8255(dev, 0x4, 0x43e);
1629 write_rtl8255(dev, 0x3, 0x100);
1630 write_rtl8255(dev, 0x4, 0x63e);
1631 write_rtl8255(dev, 0x4, 0x43e);
1632 write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
1633 0x92402a00, 0xf8011, 0x70028000, 0xc00, 0x0);
1634 write_rtl8255(dev, 0x1, 0x807);
1635 write_rtl8255(dev, 0x4, 0xc3f);
1636 write_rtl8255(dev, 0x4, 0xe3f);
1637 write_rtl8255(dev, 0x4, 0xc3f);
1638 write_rtl8255(dev, 0x1, 0x0);
1639 write_rtl8255(dev, 0x4, 0x83f);
1640 write_rtl8255(dev, 0x3, 0x0);
1641 write_rtl8255(dev, 0x2, 0x0);
1642 write_rtl8255(dev, 0x4, 0xa3f);
1643 write_rtl8255(dev, 0x4, 0x83f);
1644 write_rtl8255(dev, 0x4, 0x43f);
1645 write_rtl8255(dev, 0x3, 0x0);
1646 write_rtl8255(dev, 0x2, 0x0);
1647 write_rtl8255(dev, 0x4, 0x63f);
1648 write_rtl8255(dev, 0x4, 0x43f);
1649 write_rtl8255(dev, 0x4, 0x43f);
1650 write_rtl8255(dev, 0x3, 0x100);
1651 write_rtl8255(dev, 0x4, 0x63f);
1652 write_rtl8255(dev, 0x4, 0x43f);
1653 write_rtl8255(dev, 0x4, 0x0);
1654 write_rtl8255(dev, 0x1, 0x0);
1655 write_rtl8255_reg0c(dev, 0x3539, 0x70000c03, 0xfef46178, 0x408000, 0x403307,
1656 0x924f80c0, 0xf955c, 0x8400, 0x429200, 0x1ce20);
1657 write_rtl8255(dev, 0x1, 0x1c7);
1658 write_rtl8255(dev, 0x2, 0x26);
1659 write_rtl8255(dev, 0x3, 0x27);
1660 write_rtl8255(dev, 0x1, 0x47);
1661 write_rtl8255(dev, 0x4, 0x98c);
1662 write_rtl8255(dev, 0x5, 0x65);
1663 write_rtl8255(dev, 0x6, 0x13);
1664 write_rtl8255(dev, 0x7, 0x7c);
1665 write_rtl8255(dev, 0x8, 0x6);
1666 write_rtl8255(dev, 0x8, 0x7);
1667 write_rtl8255(dev, 0x8, 0x6);
1668 write_rtl8255(dev, 0x9, 0xce2);
1669 write_rtl8255(dev, 0xb, 0x1c5);
1670 write_rtl8255(dev, 0xd, 0xd7f);
1671 write_rtl8255(dev, 0xe, 0x369);
1672 write_rtl8255(dev, 0xa, 0xd56);
1673 write_rtl8255(dev, 0xa, 0xd57);
1674 mdelay(20);
1675 write_rtl8255(dev, 0xd, 0xd7e);
1676
1677}
1678
1679
1680void rtl8255_set_band_param(struct net_device *dev, short band)
1681{
1682 if(band != BAND_A){
1683 write_nic_dword(dev, 0x94, 0x3dc00002);
1684 write_nic_dword(dev, 0x88, 0x00100040);
1685
1686 write_phy_cck(dev, 0x13, 0xd0);
1687
1688 write_phy_cck(dev, 0x41, 0x9d);
1689 write_nic_dword(dev, 0x8c, 0x00082205);
1690 write_nic_byte(dev, 0xb4, 0x66);
1691 }
1692}
1693
1694void rtl8255_rf_init(struct net_device *dev)
1695{
1696 struct r8180_priv *priv = ieee80211_priv(dev);
1697 int i;
1698 u16 brsr;
1699// short channel /*= priv->chan*/ = 1;
1700 priv->chan = 1;
1701
1702 write_nic_word(dev, RFPinsOutput, 0x80);
1703 write_nic_word(dev, RFPinsSelect, 0x80 | SW_CONTROL_GPIO);
1704 write_nic_word(dev, RFPinsEnable, 0x80);
1705 write_nic_word(dev, RFPinsSelect, SW_CONTROL_GPIO);
1706
1707 write_nic_dword(dev, RF_TIMING, 0x000f800f);
1708
1709 brsr = read_nic_word(dev, BRSR);
1710
1711 write_nic_word(dev, 0x2c, 0xffff);
1712
1713
1714 rtl8180_set_anaparam(dev, RTL8255_ANAPARAM_ON);
1715 rtl8185_set_anaparam2(dev, RTL8255_ANAPARAM2_ON);
1716
1717 write_nic_dword(dev, 0x94, 0x11c00002);
1718
1719 write_nic_dword(dev, RF_PARA, 0x100040);
1720
1721 rtl8185_rf_pins_enable(dev);
1722
1723 rtl8255_init_BGband(dev);
1724 rtl8255_set_band_param(dev,BAND_BG);
1725
1726 write_phy_cck(dev, 0x0, 0x98);
1727 write_phy_cck(dev, 0x3, 0x20);
1728 write_phy_cck(dev, 0x4, 0x2e);
1729 write_phy_cck(dev, 0x5, 0x12);
1730 write_phy_cck(dev, 0x6, 0xfc);
1731 write_phy_cck(dev, 0x7, 0xd8);
1732 write_phy_cck(dev, 0x8, 0x2e);
1733 write_phy_cck(dev, 0x10, 0xd3);
1734 write_phy_cck(dev, 0x11, 0x88);
1735 write_phy_cck(dev, 0x12, 0x47);
1736 write_phy_cck(dev, 0x13, 0xd0); /* Ver C & D & 8187*/
1737
1738 write_phy_cck(dev, 0x19, 0x0);
1739 write_phy_cck(dev, 0x1a, 0xa0);
1740 write_phy_cck(dev, 0x1b, 0x8);
1741 write_phy_cck(dev, 0x40, 0x86); /* CCK Carrier Sense Threshold */
1742 write_phy_cck(dev, 0x41, 0x9d); /* Energy Threshold */
1743 //write_phy_cck(dev, 0x42, 0x0);
1744 write_phy_cck(dev, 0x43, 0x8);
1745
1746 write_nic_byte(dev, TESTR,0x8);
1747
1748 for(i=0;i<128;i++){
1749 write_phy_ofdm(dev, 0x4b, rtl8255_agc[i]);
1750 write_phy_ofdm(dev, 0x4a, (u8)i+ 0x80);
1751 }
1752
1753
1754 write_phy_ofdm(dev, 0x0, 0x1);
1755 write_phy_ofdm(dev, 0x1, 0x2);
1756 write_phy_ofdm(dev, 0x2, 0x43);
1757 write_phy_ofdm(dev, 0x3, 0x0);
1758 write_phy_ofdm(dev, 0x4, 0x0);
1759 write_phy_ofdm(dev, 0x5, 0x0);
1760 write_phy_ofdm(dev, 0x6, 0x40);
1761 write_phy_ofdm(dev, 0x7, 0x0);
1762 write_phy_ofdm(dev, 0x8, 0x40);
1763 write_phy_ofdm(dev, 0x9, 0xfe);
1764 write_phy_ofdm(dev, 0xa, 0x9);
1765 write_phy_ofdm(dev, 0xb, 0x80);
1766 write_phy_ofdm(dev, 0xc, 0x1);
1767 write_phy_ofdm(dev, 0xd, 0x43);
1768 write_phy_ofdm(dev, 0xe, 0xd3);
1769 write_phy_ofdm(dev, 0xf, 0x38);
1770 write_phy_ofdm(dev, 0x10, 0x4);
1771 write_phy_ofdm(dev, 0x11, 0x06);/*agc resp time 700*/
1772 write_phy_ofdm(dev, 0x12, 0x20);
1773 write_phy_ofdm(dev, 0x13, 0x20);
1774 write_phy_ofdm(dev, 0x14, 0x0);
1775 write_phy_ofdm(dev, 0x15, 0x40);
1776 write_phy_ofdm(dev, 0x16, 0x0);
1777 write_phy_ofdm(dev, 0x17, 0x40);
1778 write_phy_ofdm(dev, 0x18, 0xef);
1779 write_phy_ofdm(dev, 0x19, 0x25);
1780 write_phy_ofdm(dev, 0x1a, 0x20);
1781 write_phy_ofdm(dev, 0x1b, 0x7a);
1782 write_phy_ofdm(dev, 0x1c, 0x84);
1783 write_phy_ofdm(dev, 0x1e, 0x95);
1784 write_phy_ofdm(dev, 0x1f, 0x75);
1785 write_phy_ofdm(dev, 0x20, 0x1f);
1786 write_phy_ofdm(dev, 0x21, 0x17);
1787 write_phy_ofdm(dev, 0x22, 0x16);
1788 write_phy_ofdm(dev, 0x23, 0x70); //FIXME maybe not needed
1789 write_phy_ofdm(dev, 0x24, 0x70);
1790 write_phy_ofdm(dev, 0x25, 0x0);
1791 write_phy_ofdm(dev, 0x26, 0x10);
1792 write_phy_ofdm(dev, 0x27, 0x88);
1793
1794
1795 write_nic_dword(dev, 0x94, 0x3dc00002); //BAND DEPEND.
1796// write_nic_dword(dev, 0x94, 0x15c00002); //BAND DEPEND.
1797
1798 write_phy_cck(dev, 0x4, 0x18);
1799 write_phy_cck(dev, 0x43, 0x18);
1800 write_phy_cck(dev, 0x6, 0xdc);
1801 write_phy_cck(dev, 0x44, 0x2b);
1802 write_phy_cck(dev, 0x45, 0x2b);
1803 write_phy_cck(dev, 0x46, 0x25);
1804 write_phy_cck(dev, 0x47, 0x15);
1805 write_phy_cck(dev, 0x48, 0x0);
1806 write_phy_cck(dev, 0x49, 0x0);
1807 write_phy_cck(dev, 0x4a, 0x0);
1808 write_phy_cck(dev, 0x4b, 0x0);
1809// write_phy_cck(dev, 0x4c, 0x5);
1810#if 0
1811 write_phy_cck(dev, 0x41, 0x9d); /* Energy Threshold */
1812 // TESTR 0xb 8187
1813 write_phy_cck(dev, 0x10, 0x93);// & 0xfb);
1814#endif
1815 //rtl8255_set_gain(dev, 1); /* FIXME this '1' is random */
1816
1817 rtl8255_SetTXPowerLevel(dev, priv->chan);
1818
1819 write_phy_cck(dev, 0x10, 0x93 |0x4); /* Rx ant B, 0xd3 for A */
1820 write_phy_ofdm(dev, 0x26, 0x90); /* Rx ant B, 0x10 for A */
1821
1822 rtl8185_tx_antenna(dev, 0x3); /* TX ant B, 0x0 for A*/
1823 /* make sure is waken up! */
1824 rtl8180_set_anaparam(dev, RTL8255_ANAPARAM_ON);
1825 rtl8185_set_anaparam2(dev, RTL8255_ANAPARAM2_ON);
1826
1827 rtl8255_set_band_param(dev,BAND_BG);
1828
1829 write_phy_cck(dev, 0x41, 0x9d);
1830
1831 rtl8255_set_gain(dev, 4);
1832 //rtl8255_set_energy_threshold(dev);
1833 write_phy_cck(dev, 0x41, 0x9d);
1834 rtl8255_rf_set_chan(dev, priv->chan);
1835
1836 write_nic_word(dev, BRSR, brsr);
1837}
1838
diff --git a/drivers/staging/rtl8187se/r8180_rtl8255.h b/drivers/staging/rtl8187se/r8180_rtl8255.h
new file mode 100644
index 000000000000..be44ca6eb1d3
--- /dev/null
+++ b/drivers/staging/rtl8187se/r8180_rtl8255.h
@@ -0,0 +1,19 @@
1/*
2 This is part of the rtl8180-sa2400 driver
3 released under the GPL (See file COPYING for details).
4 Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
5
6 This files contains programming code for the rtl8255
7 radio frontend.
8
9 *Many* thanks to Realtek Corp. for their great support!
10
11*/
12
13#define RTL8255_ANAPARAM_ON 0xa0000b59
14#define RTL8255_ANAPARAM2_ON 0x840cf311
15
16
17void rtl8255_rf_init(struct net_device *dev);
18void rtl8255_rf_set_chan(struct net_device *dev,short ch);
19void rtl8255_rf_close(struct net_device *dev);
diff --git a/drivers/staging/rtl8187se/r8180_sa2400.c b/drivers/staging/rtl8187se/r8180_sa2400.c
new file mode 100644
index 000000000000..d6495601715f
--- /dev/null
+++ b/drivers/staging/rtl8187se/r8180_sa2400.c
@@ -0,0 +1,233 @@
1/*
2 This files contains PHILIPS SA2400 radio frontend programming routines.
3
4 This is part of rtl8180 OpenSource driver
5 Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it>
6 Released under the terms of GPL (General Public Licence)
7
8 Parts of this driver are based on the GPL part of the
9 official realtek driver
10
11 Parts of this driver are based on the rtl8180 driver skeleton
12 from Patric Schenke & Andres Salomon
13
14 Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
15
16 Code at http://che.ojctech.com/~dyoung/rtw/ has been useful to me to
17 understand some things.
18
19 Code from rtl8181 project has been useful to me to understand some things.
20
21 We want to tanks the Authors of such projects and the Ndiswrapper
22 project Authors.
23*/
24
25
26#include "r8180.h"
27#include "r8180_hw.h"
28#include "r8180_sa2400.h"
29
30
31//#define DEBUG_SA2400
32
33u32 sa2400_chan[] = {
34 0x0, //dummy channel 0
35 0x00096c, //1
36 0x080970, //2
37 0x100974, //3
38 0x180978, //4
39 0x000980, //5
40 0x080984, //6
41 0x100988, //7
42 0x18098c, //8
43 0x000994, //9
44 0x080998, //10
45 0x10099c, //11
46 0x1809a0, //12
47 0x0009a8, //13
48 0x0009b4, //14
49};
50
51
52void rf_stabilize(struct net_device *dev)
53{
54 force_pci_posting(dev);
55 mdelay(3); //for now use a great value.. we may optimize in future
56}
57
58
59void write_sa2400(struct net_device *dev,u8 adr, u32 data)
60{
61// struct r8180_priv *priv = ieee80211_priv(dev);
62 u32 phy_config;
63
64 // philips sa2400 expects 24 bits data
65
66 /*if(adr == 4 && priv->digphy){
67 phy_config=0x60000000;
68 }else{
69 phy_config=0xb0000000;
70 }*/
71
72 phy_config = 0xb0000000; // MAC will bang bits to the sa2400
73
74 phy_config |= (((u32)(adr&0xf))<< 24);
75 phy_config |= (data & 0xffffff);
76 write_nic_dword(dev,PHY_CONFIG,phy_config);
77#ifdef DEBUG_SA2400
78 DMESG("Writing sa2400: %x (adr %x)",phy_config,adr);
79#endif
80 rf_stabilize(dev);
81}
82
83
84
85void sa2400_write_phy_antenna(struct net_device *dev,short ch)
86{
87 struct r8180_priv *priv = ieee80211_priv(dev);
88 u8 ant;
89
90 ant = SA2400_ANTENNA;
91 if(priv->antb) /*default antenna is antenna B */
92 ant |= BB_ANTENNA_B;
93 if(ch == 14)
94 ant |= BB_ANTATTEN_CHAN14;
95 write_phy(dev,0x10,ant);
96 //DMESG("BB antenna %x ",ant);
97}
98
99
100/* from the rtl8181 embedded driver */
101short sa2400_rf_set_sens(struct net_device *dev, short sens)
102{
103 u8 finetune = 0;
104 if ((sens > 85) || (sens < 54)) return -1;
105
106 write_sa2400(dev,5,0x1dfb | (sens-54) << 15 |(finetune<<20)); // AGC 0xc9dfb
107
108 return 0;
109}
110
111
112void sa2400_rf_set_chan(struct net_device *dev, short ch)
113{
114 struct r8180_priv *priv = ieee80211_priv(dev);
115 u32 txpw = 0xff & priv->chtxpwr[ch];
116 u32 chan = sa2400_chan[ch];
117
118 write_sa2400(dev,7,txpw);
119 //write_phy(dev,0x10,0xd1);
120 sa2400_write_phy_antenna(dev,ch);
121 write_sa2400(dev,0,chan);
122 write_sa2400(dev,1,0xbb50);
123 write_sa2400(dev,2,0x80);
124 write_sa2400(dev,3,0);
125}
126
127
128void sa2400_rf_close(struct net_device *dev)
129{
130 write_sa2400(dev, 4, 0);
131}
132
133
134void sa2400_rf_init(struct net_device *dev)
135{
136 struct r8180_priv *priv = ieee80211_priv(dev);
137 u32 anaparam;
138 u8 firdac;
139
140 write_nic_byte(dev,PHY_DELAY,0x6); //this is general
141 write_nic_byte(dev,CARRIER_SENSE_COUNTER,0x4c); //this is general
142
143 /*these are philips sa2400 specific*/
144 anaparam = read_nic_dword(dev,ANAPARAM);
145 anaparam = anaparam &~ (1<<ANAPARAM_TXDACOFF_SHIFT);
146
147 anaparam = anaparam &~ANAPARAM_PWR1_MASK;
148 anaparam = anaparam &~ANAPARAM_PWR0_MASK;
149 if(priv->digphy){
150 anaparam |= (SA2400_DIG_ANAPARAM_PWR1_ON<<ANAPARAM_PWR1_SHIFT);
151 anaparam |= (SA2400_ANAPARAM_PWR0_ON<<ANAPARAM_PWR0_SHIFT);
152 }else{
153 anaparam |= (SA2400_ANA_ANAPARAM_PWR1_ON<<ANAPARAM_PWR1_SHIFT);
154 }
155
156 rtl8180_set_anaparam(dev,anaparam);
157
158 firdac = (priv->digphy) ? (1<<SA2400_REG4_FIRDAC_SHIFT) : 0;
159 write_sa2400(dev,0,sa2400_chan[priv->chan]);
160 write_sa2400(dev,1,0xbb50);
161 write_sa2400(dev,2,0x80);
162 write_sa2400(dev,3,0);
163 write_sa2400(dev,4,0x19340 | firdac);
164 write_sa2400(dev,5,0xc9dfb); // AGC
165 write_sa2400(dev,4,0x19348 | firdac); //calibrates VCO
166
167 if(priv->digphy)
168 write_sa2400(dev,4,0x1938c); /*???*/
169
170 write_sa2400(dev,4,0x19340 | firdac);
171
172 write_sa2400(dev,0,sa2400_chan[priv->chan]);
173 write_sa2400(dev,1,0xbb50);
174 write_sa2400(dev,2,0x80);
175 write_sa2400(dev,3,0);
176 write_sa2400(dev,4,0x19344 | firdac); //calibrates filter
177
178 /* new from rtl8180 embedded driver (rtl8181 project) */
179 write_sa2400(dev,6,0x13ff | (1<<23)); // MANRX
180 write_sa2400(dev,8,0); //VCO
181
182 if(!priv->digphy)
183 {
184 rtl8180_set_anaparam(dev, anaparam | \
185 (1<<ANAPARAM_TXDACOFF_SHIFT));
186
187 rtl8180_conttx_enable(dev);
188
189 write_sa2400(dev, 4, 0x19341); // calibrates DC
190
191 /* a 5us sleep is required here,
192 we rely on the 3ms delay introduced in write_sa2400
193 */
194 write_sa2400(dev, 4, 0x19345);
195 /* a 20us sleep is required here,
196 we rely on the 3ms delay introduced in write_sa2400
197 */
198 rtl8180_conttx_disable(dev);
199
200 rtl8180_set_anaparam(dev, anaparam);
201 }
202 /* end new */
203
204 write_sa2400(dev,4,0x19341 | firdac ); //RTX MODE
205
206 // Set tx power level !?
207
208
209 /*baseband configuration*/
210 write_phy(dev,0,0x98);
211 write_phy(dev,3,0x38);
212 write_phy(dev,4,0xe0);
213 write_phy(dev,5,0x90);
214 write_phy(dev,6,0x1a);
215 write_phy(dev,7,0x64);
216
217 /*Should be done something more here??*/
218
219 sa2400_write_phy_antenna(dev,priv->chan);
220
221 write_phy(dev,0x11,0x80);
222 if(priv->diversity)
223 write_phy(dev,0x12,0xc7);
224 else
225 write_phy(dev,0x12,0x47);
226
227 write_phy(dev,0x13,0x90 | priv->cs_treshold );
228
229 write_phy(dev,0x19,0x0);
230 write_phy(dev,0x1a,0xa0);
231
232 sa2400_rf_set_chan(dev,priv->chan);
233}
diff --git a/drivers/staging/rtl8187se/r8180_sa2400.h b/drivers/staging/rtl8187se/r8180_sa2400.h
new file mode 100644
index 000000000000..683a69b96af4
--- /dev/null
+++ b/drivers/staging/rtl8187se/r8180_sa2400.h
@@ -0,0 +1,26 @@
1/*
2 This is part of rtl8180 OpenSource driver - v 0.7
3 Copyright (C) Andrea Merello 2004 <andreamrl@tiscali.it>
4 Released under the terms of GPL (General Public Licence)
5
6 Parts of this driver are based on the GPL part of the official realtek driver
7 Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon
8 Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
9
10 We want to tanks the Authors of such projects and the Ndiswrapper project Authors.
11*/
12
13#define SA2400_ANTENNA 0x91
14#define SA2400_DIG_ANAPARAM_PWR1_ON 0x8
15#define SA2400_ANA_ANAPARAM_PWR1_ON 0x28
16#define SA2400_ANAPARAM_PWR0_ON 0x3
17
18#define SA2400_RF_MAX_SENS 85
19#define SA2400_RF_DEF_SENS 80
20
21#define SA2400_REG4_FIRDAC_SHIFT 7
22
23void sa2400_rf_init(struct net_device *dev);
24void sa2400_rf_set_chan(struct net_device *dev,short ch);
25short sa2400_rf_set_sens(struct net_device *dev,short sens);
26void sa2400_rf_close(struct net_device *dev);
diff --git a/drivers/staging/rtl8187se/r8180_wx.c b/drivers/staging/rtl8187se/r8180_wx.c
new file mode 100644
index 000000000000..c77abe502b79
--- /dev/null
+++ b/drivers/staging/rtl8187se/r8180_wx.c
@@ -0,0 +1,1644 @@
1/*
2 This file contains wireless extension handlers.
3
4 This is part of rtl8180 OpenSource driver.
5 Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it>
6 Released under the terms of GPL (General Public Licence)
7
8 Parts of this driver are based on the GPL part
9 of the official realtek driver.
10
11 Parts of this driver are based on the rtl8180 driver skeleton
12 from Patric Schenke & Andres Salomon.
13
14 Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
15
16 We want to tanks the Authors of those projects and the Ndiswrapper
17 project Authors.
18*/
19
20
21#include "r8180.h"
22#include "r8180_hw.h"
23#include "r8180_sa2400.h"
24
25#ifdef ENABLE_DOT11D
26#include "dot11d.h"
27#endif
28
29//#define RATE_COUNT 4
30u32 rtl8180_rates[] = {1000000,2000000,5500000,11000000,
31 6000000,9000000,12000000,18000000,24000000,36000000,48000000,54000000};
32
33#define RATE_COUNT (sizeof(rtl8180_rates)/sizeof(rtl8180_rates[0]))
34
35static CHANNEL_LIST DefaultChannelPlan[] = {
36// {{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14}, //Default channel plan
37 {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64},19}, //FCC
38 {{1,2,3,4,5,6,7,8,9,10,11},11}, //IC
39 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //ETSI
40 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //Spain. Change to ETSI.
41 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //France. Change to ETSI.
42 {{14,36,40,44,48,52,56,60,64},9}, //MKK
43 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14, 36,40,44,48,52,56,60,64},22},//MKK1
44 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //Israel.
45 {{1,2,3,4,5,6,7,8,9,10,11,12,13,34,38,42,46},17}, // For 11a , TELEC
46 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14} //For Global Domain. 1-11:active scan, 12-14 passive scan. //+YJ, 080626
47};
48static int r8180_wx_get_freq(struct net_device *dev,
49 struct iw_request_info *a,
50 union iwreq_data *wrqu, char *b)
51{
52 struct r8180_priv *priv = ieee80211_priv(dev);
53
54 return ieee80211_wx_get_freq(priv->ieee80211, a, wrqu, b);
55}
56
57
58int r8180_wx_set_key(struct net_device *dev, struct iw_request_info *info,
59 union iwreq_data *wrqu, char *key)
60{
61 struct r8180_priv *priv = ieee80211_priv(dev);
62 struct iw_point *erq = &(wrqu->encoding);
63
64 if(priv->ieee80211->bHwRadioOff)
65 return 0;
66
67 if (erq->flags & IW_ENCODE_DISABLED) {
68 }
69
70
71/* i = erq->flags & IW_ENCODE_INDEX;
72 if (i < 1 || i > 4)
73*/
74
75 if (erq->length > 0) {
76
77 //int len = erq->length <= 5 ? 5 : 13;
78
79 u32* tkey= (u32*) key;
80 priv->key0[0] = tkey[0];
81 priv->key0[1] = tkey[1];
82 priv->key0[2] = tkey[2];
83 priv->key0[3] = tkey[3] &0xff;
84 DMESG("Setting wep key to %x %x %x %x",
85 tkey[0],tkey[1],tkey[2],tkey[3]);
86 rtl8180_set_hw_wep(dev);
87 }
88 return 0;
89}
90
91
92static int r8180_wx_set_beaconinterval(struct net_device *dev, struct iw_request_info *aa,
93 union iwreq_data *wrqu, char *b)
94{
95 int *parms = (int *)b;
96 int bi = parms[0];
97
98 struct r8180_priv *priv = ieee80211_priv(dev);
99
100 if(priv->ieee80211->bHwRadioOff)
101 return 0;
102
103 down(&priv->wx_sem);
104 DMESG("setting beacon interval to %x",bi);
105
106 priv->ieee80211->current_network.beacon_interval=bi;
107 rtl8180_commit(dev);
108 up(&priv->wx_sem);
109
110 return 0;
111}
112
113
114
115static int r8180_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
116 union iwreq_data *wrqu, char *b)
117{
118 struct r8180_priv *priv = ieee80211_priv(dev);
119 return ieee80211_wx_get_mode(priv->ieee80211,a,wrqu,b);
120}
121
122
123
124static int r8180_wx_get_rate(struct net_device *dev,
125 struct iw_request_info *info,
126 union iwreq_data *wrqu, char *extra)
127{
128 struct r8180_priv *priv = ieee80211_priv(dev);
129 return ieee80211_wx_get_rate(priv->ieee80211,info,wrqu,extra);
130}
131
132
133
134static int r8180_wx_set_rate(struct net_device *dev,
135 struct iw_request_info *info,
136 union iwreq_data *wrqu, char *extra)
137{
138 int ret;
139 struct r8180_priv *priv = ieee80211_priv(dev);
140
141
142 if(priv->ieee80211->bHwRadioOff)
143 return 0;
144
145 down(&priv->wx_sem);
146
147 ret = ieee80211_wx_set_rate(priv->ieee80211,info,wrqu,extra);
148
149 up(&priv->wx_sem);
150
151 return ret;
152}
153
154
155static int r8180_wx_set_crcmon(struct net_device *dev,
156 struct iw_request_info *info,
157 union iwreq_data *wrqu, char *extra)
158{
159 struct r8180_priv *priv = ieee80211_priv(dev);
160 int *parms = (int *)extra;
161 int enable = (parms[0] > 0);
162 short prev = priv->crcmon;
163
164
165 if(priv->ieee80211->bHwRadioOff)
166 return 0;
167
168 down(&priv->wx_sem);
169
170 if(enable)
171 priv->crcmon=1;
172 else
173 priv->crcmon=0;
174
175 DMESG("bad CRC in monitor mode are %s",
176 priv->crcmon ? "accepted" : "rejected");
177
178 if(prev != priv->crcmon && priv->up){
179 rtl8180_down(dev);
180 rtl8180_up(dev);
181 }
182
183 up(&priv->wx_sem);
184
185 return 0;
186}
187
188
189static int r8180_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
190 union iwreq_data *wrqu, char *b)
191{
192 struct r8180_priv *priv = ieee80211_priv(dev);
193 int ret;
194
195
196 if(priv->ieee80211->bHwRadioOff)
197 return 0;
198
199 down(&priv->wx_sem);
200#ifdef ENABLE_IPS
201// printk("set mode ENABLE_IPS\n");
202 if(priv->bInactivePs){
203 if(wrqu->mode == IW_MODE_ADHOC)
204 IPSLeave(dev);
205 }
206#endif
207 ret = ieee80211_wx_set_mode(priv->ieee80211,a,wrqu,b);
208
209 //rtl8180_commit(dev);
210
211 up(&priv->wx_sem);
212 return ret;
213}
214
215//YJ,add,080819,for hidden ap
216struct iw_range_with_scan_capa
217{
218 /* Informative stuff (to choose between different interface) */
219 __u32 throughput; /* To give an idea... */
220 /* In theory this value should be the maximum benchmarked
221 * TCP/IP throughput, because with most of these devices the
222 * bit rate is meaningless (overhead an co) to estimate how
223 * fast the connection will go and pick the fastest one.
224 * I suggest people to play with Netperf or any benchmark...
225 */
226
227 /* NWID (or domain id) */
228 __u32 min_nwid; /* Minimal NWID we are able to set */
229 __u32 max_nwid; /* Maximal NWID we are able to set */
230
231 /* Old Frequency (backward compat - moved lower ) */
232 __u16 old_num_channels;
233 __u8 old_num_frequency;
234
235 /* Scan capabilities */
236 __u8 scan_capa;
237};
238//YJ,add,080819,for hidden ap
239
240
241static int rtl8180_wx_get_range(struct net_device *dev,
242 struct iw_request_info *info,
243 union iwreq_data *wrqu, char *extra)
244{
245 struct iw_range *range = (struct iw_range *)extra;
246 struct r8180_priv *priv = ieee80211_priv(dev);
247 u16 val;
248 int i;
249 //struct iw_range_with_scan_capa* tmp = (struct iw_range_with_scan_capa*)range; //YJ,add,080819,for hidden ap
250
251 wrqu->data.length = sizeof(*range);
252 memset(range, 0, sizeof(*range));
253
254 /* Let's try to keep this struct in the same order as in
255 * linux/include/wireless.h
256 */
257
258 /* TODO: See what values we can set, and remove the ones we can't
259 * set, or fill them with some default data.
260 */
261
262 /* ~5 Mb/s real (802.11b) */
263 range->throughput = 5 * 1000 * 1000;
264
265 // TODO: Not used in 802.11b?
266// range->min_nwid; /* Minimal NWID we are able to set */
267 // TODO: Not used in 802.11b?
268// range->max_nwid; /* Maximal NWID we are able to set */
269
270 /* Old Frequency (backward compat - moved lower ) */
271// range->old_num_channels;
272// range->old_num_frequency;
273// range->old_freq[6]; /* Filler to keep "version" at the same offset */
274 if(priv->rf_set_sens != NULL)
275 range->sensitivity = priv->max_sens; /* signal level threshold range */
276
277 range->max_qual.qual = 100;
278 /* TODO: Find real max RSSI and stick here */
279 range->max_qual.level = 0;
280 range->max_qual.noise = -98;
281 range->max_qual.updated = 7; /* Updated all three */
282
283 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
284 /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
285 range->avg_qual.level = 20 + -98;
286 range->avg_qual.noise = 0;
287 range->avg_qual.updated = 7; /* Updated all three */
288
289 range->num_bitrates = RATE_COUNT;
290
291 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) {
292 range->bitrate[i] = rtl8180_rates[i];
293 }
294
295 range->min_frag = MIN_FRAG_THRESHOLD;
296 range->max_frag = MAX_FRAG_THRESHOLD;
297
298 range->pm_capa = 0;
299
300 range->we_version_compiled = WIRELESS_EXT;
301 range->we_version_source = 16;
302
303// range->retry_capa; /* What retry options are supported */
304// range->retry_flags; /* How to decode max/min retry limit */
305// range->r_time_flags; /* How to decode max/min retry life */
306// range->min_retry; /* Minimal number of retries */
307// range->max_retry; /* Maximal number of retries */
308// range->min_r_time; /* Minimal retry lifetime */
309// range->max_r_time; /* Maximal retry lifetime */
310
311 range->num_channels = 14;
312
313 for (i = 0, val = 0; i < 14; i++) {
314
315 // Include only legal frequencies for some countries
316#ifdef ENABLE_DOT11D
317 if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
318#else
319 if ((priv->ieee80211->channel_map)[i+1]) {
320#endif
321 range->freq[val].i = i + 1;
322 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
323 range->freq[val].e = 1;
324 val++;
325 } else {
326 // FIXME: do we need to set anything for channels
327 // we don't use ?
328 }
329
330 if (val == IW_MAX_FREQUENCIES)
331 break;
332 }
333
334 range->num_frequency = val;
335 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
336 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
337
338 //tmp->scan_capa = 0x01; //YJ,add,080819,for hidden ap
339
340 return 0;
341}
342
343
344static int r8180_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
345 union iwreq_data *wrqu, char *b)
346{
347 struct r8180_priv *priv = ieee80211_priv(dev);
348 int ret;
349 struct ieee80211_device* ieee = priv->ieee80211;
350
351
352 if(priv->ieee80211->bHwRadioOff)
353 return 0;
354
355//YJ,add,080819, for hidden ap
356 //printk("==*&*&*&==>%s in\n", __func__);
357 //printk("=*&*&*&*===>flag:%x, %x\n", wrqu->data.flags, IW_SCAN_THIS_ESSID);
358 if (wrqu->data.flags & IW_SCAN_THIS_ESSID)
359 {
360 struct iw_scan_req* req = (struct iw_scan_req*)b;
361 if (req->essid_len)
362 {
363 //printk("==**&*&*&**===>scan set ssid:%s\n", req->essid);
364 ieee->current_network.ssid_len = req->essid_len;
365 memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
366 //printk("=====>network ssid:%s\n", ieee->current_network.ssid);
367 }
368 }
369//YJ,add,080819, for hidden ap, end
370
371 down(&priv->wx_sem);
372 if(priv->up){
373#ifdef ENABLE_IPS
374// printk("set scan ENABLE_IPS\n");
375 priv->ieee80211->actscanning = true;
376 if(priv->bInactivePs && (priv->ieee80211->state != IEEE80211_LINKED)){
377 IPSLeave(dev);
378// down(&priv->ieee80211->wx_sem);
379
380// if (priv->ieee80211->iw_mode == IW_MODE_MONITOR || !(priv->ieee80211->proto_started)){
381// ret = -1;
382// up(&priv->ieee80211->wx_sem);
383// up(&priv->wx_sem);
384// return ret;
385// }
386
387 // queue_work(priv->ieee80211->wq, &priv->ieee80211->wx_sync_scan_wq);
388 //printk("start scan============================>\n");
389 ieee80211_softmac_ips_scan_syncro(priv->ieee80211);
390//ieee80211_start_scan(priv->ieee80211);
391 /* intentionally forget to up sem */
392// up(&priv->ieee80211->wx_sem);
393 ret = 0;
394 }
395 else
396#endif
397 {
398 //YJ,add,080828, prevent scan in BusyTraffic
399 //FIXME: Need to consider last scan time
400 if ((priv->link_detect.bBusyTraffic) && (true))
401 {
402 ret = 0;
403 printk("Now traffic is busy, please try later!\n");
404 }
405 else
406 //YJ,add,080828, prevent scan in BusyTraffic,end
407 ret = ieee80211_wx_set_scan(priv->ieee80211,a,wrqu,b);
408 }
409 }
410 else
411 ret = -1;
412
413 up(&priv->wx_sem);
414
415 return ret;
416}
417
418
419static int r8180_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
420 union iwreq_data *wrqu, char *b)
421{
422
423 int ret;
424 struct r8180_priv *priv = ieee80211_priv(dev);
425
426 down(&priv->wx_sem);
427 if(priv->up)
428 ret = ieee80211_wx_get_scan(priv->ieee80211,a,wrqu,b);
429 else
430 ret = -1;
431
432 up(&priv->wx_sem);
433 return ret;
434}
435
436
437static int r8180_wx_set_essid(struct net_device *dev,
438 struct iw_request_info *a,
439 union iwreq_data *wrqu, char *b)
440{
441 struct r8180_priv *priv = ieee80211_priv(dev);
442
443 int ret;
444
445 if(priv->ieee80211->bHwRadioOff)
446 return 0;
447
448 down(&priv->wx_sem);
449#ifdef ENABLE_IPS
450 //printk("set essid ENABLE_IPS\n");
451 if(priv->bInactivePs)
452 IPSLeave(dev);
453#endif
454// printk("haha:set essid %s essid_len = %d essid_flgs = %d\n",b, wrqu->essid.length, wrqu->essid.flags);
455
456 ret = ieee80211_wx_set_essid(priv->ieee80211,a,wrqu,b);
457
458 up(&priv->wx_sem);
459 return ret;
460}
461
462
463static int r8180_wx_get_essid(struct net_device *dev,
464 struct iw_request_info *a,
465 union iwreq_data *wrqu, char *b)
466{
467 int ret;
468 struct r8180_priv *priv = ieee80211_priv(dev);
469
470 down(&priv->wx_sem);
471
472 ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
473
474 up(&priv->wx_sem);
475
476 return ret;
477}
478
479
480static int r8180_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
481 union iwreq_data *wrqu, char *b)
482{
483 int ret;
484 struct r8180_priv *priv = ieee80211_priv(dev);
485
486
487 if(priv->ieee80211->bHwRadioOff)
488 return 0;
489
490 down(&priv->wx_sem);
491
492 ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
493
494 up(&priv->wx_sem);
495 return ret;
496}
497
498
499static int r8180_wx_get_name(struct net_device *dev,
500 struct iw_request_info *info,
501 union iwreq_data *wrqu, char *extra)
502{
503 struct r8180_priv *priv = ieee80211_priv(dev);
504 return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
505}
506
507static int r8180_wx_set_frag(struct net_device *dev,
508 struct iw_request_info *info,
509 union iwreq_data *wrqu, char *extra)
510{
511 struct r8180_priv *priv = ieee80211_priv(dev);
512
513 if(priv->ieee80211->bHwRadioOff)
514 return 0;
515
516 if (wrqu->frag.disabled)
517 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
518 else {
519 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
520 wrqu->frag.value > MAX_FRAG_THRESHOLD)
521 return -EINVAL;
522
523 priv->ieee80211->fts = wrqu->frag.value & ~0x1;
524 }
525
526 return 0;
527}
528
529
530static int r8180_wx_get_frag(struct net_device *dev,
531 struct iw_request_info *info,
532 union iwreq_data *wrqu, char *extra)
533{
534 struct r8180_priv *priv = ieee80211_priv(dev);
535
536 wrqu->frag.value = priv->ieee80211->fts;
537 wrqu->frag.fixed = 0; /* no auto select */
538 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
539
540 return 0;
541}
542
543
544static int r8180_wx_set_wap(struct net_device *dev,
545 struct iw_request_info *info,
546 union iwreq_data *awrq,
547 char *extra)
548{
549 int ret;
550 struct r8180_priv *priv = ieee80211_priv(dev);
551
552 if(priv->ieee80211->bHwRadioOff)
553 return 0;
554
555 down(&priv->wx_sem);
556
557 ret = ieee80211_wx_set_wap(priv->ieee80211,info,awrq,extra);
558
559 up(&priv->wx_sem);
560 return ret;
561
562}
563
564
565static int r8180_wx_get_wap(struct net_device *dev,
566 struct iw_request_info *info,
567 union iwreq_data *wrqu, char *extra)
568{
569 struct r8180_priv *priv = ieee80211_priv(dev);
570
571 return ieee80211_wx_get_wap(priv->ieee80211,info,wrqu,extra);
572}
573
574
575static int r8180_wx_set_enc(struct net_device *dev,
576 struct iw_request_info *info,
577 union iwreq_data *wrqu, char *key)
578{
579 struct r8180_priv *priv = ieee80211_priv(dev);
580 int ret;
581
582 if(priv->ieee80211->bHwRadioOff)
583 return 0;
584
585
586 down(&priv->wx_sem);
587
588 if(priv->hw_wep) ret = r8180_wx_set_key(dev,info,wrqu,key);
589 else{
590 DMESG("Setting SW wep key");
591 ret = ieee80211_wx_set_encode(priv->ieee80211,info,wrqu,key);
592 }
593
594 up(&priv->wx_sem);
595 return ret;
596}
597
598
599static int r8180_wx_get_enc(struct net_device *dev,
600 struct iw_request_info *info,
601 union iwreq_data *wrqu, char *key)
602{
603 struct r8180_priv *priv = ieee80211_priv(dev);
604
605 return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
606}
607
608
609static int r8180_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union
610 iwreq_data *wrqu, char *p){
611
612 struct r8180_priv *priv = ieee80211_priv(dev);
613 int *parms=(int*)p;
614 int mode=parms[0];
615
616 if(priv->ieee80211->bHwRadioOff)
617 return 0;
618
619 priv->ieee80211->active_scan = mode;
620
621 return 1;
622}
623
624
625/* added by christian */
626/*
627static int r8180_wx_set_monitor_type(struct net_device *dev, struct iw_request_info *aa, union
628 iwreq_data *wrqu, char *p){
629
630 struct r8180_priv *priv = ieee80211_priv(dev);
631 int *parms=(int*)p;
632 int mode=parms[0];
633
634 if(priv->ieee80211->iw_mode != IW_MODE_MONITOR) return -1;
635 priv->prism_hdr = mode;
636 if(!mode)dev->type=ARPHRD_IEEE80211;
637 else dev->type=ARPHRD_IEEE80211_PRISM;
638 DMESG("using %s RX encap", mode ? "AVS":"80211");
639 return 0;
640
641}
642*/
643//of r8180_wx_set_monitor_type
644/* end added christian */
645
646static int r8180_wx_set_retry(struct net_device *dev,
647 struct iw_request_info *info,
648 union iwreq_data *wrqu, char *extra)
649{
650 struct r8180_priv *priv = ieee80211_priv(dev);
651 int err = 0;
652
653 if(priv->ieee80211->bHwRadioOff)
654 return 0;
655
656 down(&priv->wx_sem);
657
658 if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
659 wrqu->retry.disabled){
660 err = -EINVAL;
661 goto exit;
662 }
663 if (!(wrqu->retry.flags & IW_RETRY_LIMIT)){
664 err = -EINVAL;
665 goto exit;
666 }
667
668 if(wrqu->retry.value > R8180_MAX_RETRY){
669 err= -EINVAL;
670 goto exit;
671 }
672 if (wrqu->retry.flags & IW_RETRY_MAX) {
673 priv->retry_rts = wrqu->retry.value;
674 DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
675
676 }else {
677 priv->retry_data = wrqu->retry.value;
678 DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
679 }
680
681 /* FIXME !
682 * We might try to write directly the TX config register
683 * or to restart just the (R)TX process.
684 * I'm unsure if whole reset is really needed
685 */
686
687 rtl8180_commit(dev);
688 /*
689 if(priv->up){
690 rtl8180_rtx_disable(dev);
691 rtl8180_rx_enable(dev);
692 rtl8180_tx_enable(dev);
693
694 }
695 */
696exit:
697 up(&priv->wx_sem);
698
699 return err;
700}
701
702static int r8180_wx_get_retry(struct net_device *dev,
703 struct iw_request_info *info,
704 union iwreq_data *wrqu, char *extra)
705{
706 struct r8180_priv *priv = ieee80211_priv(dev);
707
708
709 wrqu->retry.disabled = 0; /* can't be disabled */
710
711 if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
712 IW_RETRY_LIFETIME)
713 return -EINVAL;
714
715 if (wrqu->retry.flags & IW_RETRY_MAX) {
716 wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MAX;
717 wrqu->retry.value = priv->retry_rts;
718 } else {
719 wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MIN;
720 wrqu->retry.value = priv->retry_data;
721 }
722 //DMESG("returning %d",wrqu->retry.value);
723
724
725 return 0;
726}
727
728static int r8180_wx_get_sens(struct net_device *dev,
729 struct iw_request_info *info,
730 union iwreq_data *wrqu, char *extra)
731{
732 struct r8180_priv *priv = ieee80211_priv(dev);
733 if(priv->rf_set_sens == NULL)
734 return -1; /* we have not this support for this radio */
735 wrqu->sens.value = priv->sens;
736 return 0;
737}
738
739
740static int r8180_wx_set_sens(struct net_device *dev,
741 struct iw_request_info *info,
742 union iwreq_data *wrqu, char *extra)
743{
744
745 struct r8180_priv *priv = ieee80211_priv(dev);
746
747 short err = 0;
748
749 if(priv->ieee80211->bHwRadioOff)
750 return 0;
751
752 down(&priv->wx_sem);
753 //DMESG("attempt to set sensivity to %ddb",wrqu->sens.value);
754 if(priv->rf_set_sens == NULL) {
755 err= -1; /* we have not this support for this radio */
756 goto exit;
757 }
758 if(priv->rf_set_sens(dev, wrqu->sens.value) == 0)
759 priv->sens = wrqu->sens.value;
760 else
761 err= -EINVAL;
762
763exit:
764 up(&priv->wx_sem);
765
766 return err;
767}
768
769
770static int r8180_wx_set_rawtx(struct net_device *dev,
771 struct iw_request_info *info,
772 union iwreq_data *wrqu, char *extra)
773{
774 struct r8180_priv *priv = ieee80211_priv(dev);
775 int ret;
776
777 if(priv->ieee80211->bHwRadioOff)
778 return 0;
779
780 down(&priv->wx_sem);
781
782 ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
783
784 up(&priv->wx_sem);
785
786 return ret;
787
788}
789
790static int r8180_wx_get_power(struct net_device *dev,
791 struct iw_request_info *info,
792 union iwreq_data *wrqu, char *extra)
793{
794 int ret;
795 struct r8180_priv *priv = ieee80211_priv(dev);
796
797 down(&priv->wx_sem);
798
799 ret = ieee80211_wx_get_power(priv->ieee80211, info, wrqu, extra);
800
801 up(&priv->wx_sem);
802
803 return ret;
804}
805
806static int r8180_wx_set_power(struct net_device *dev,
807 struct iw_request_info *info,
808 union iwreq_data *wrqu, char *extra)
809{
810 int ret;
811 struct r8180_priv *priv = ieee80211_priv(dev);
812
813
814 if(priv->ieee80211->bHwRadioOff)
815 return 0;
816
817 down(&priv->wx_sem);
818 printk("=>>>>>>>>>>=============================>set power:%d,%d!\n",wrqu->power.disabled, wrqu->power.flags);
819 if (wrqu->power.disabled==0) {
820 wrqu->power.flags|=IW_POWER_ALL_R;
821 wrqu->power.flags|=IW_POWER_TIMEOUT;
822 wrqu->power.value =1000;
823 }
824
825 ret = ieee80211_wx_set_power(priv->ieee80211, info, wrqu, extra);
826
827 up(&priv->wx_sem);
828
829 return ret;
830}
831
832static int r8180_wx_set_rts(struct net_device *dev,
833 struct iw_request_info *info,
834 union iwreq_data *wrqu, char *extra)
835{
836 struct r8180_priv *priv = ieee80211_priv(dev);
837
838
839 if(priv->ieee80211->bHwRadioOff)
840 return 0;
841
842 if (wrqu->rts.disabled)
843 priv->rts = DEFAULT_RTS_THRESHOLD;
844 else {
845 if (wrqu->rts.value < MIN_RTS_THRESHOLD ||
846 wrqu->rts.value > MAX_RTS_THRESHOLD)
847 return -EINVAL;
848
849 priv->rts = wrqu->rts.value;
850 }
851
852 return 0;
853}
854static int r8180_wx_get_rts(struct net_device *dev,
855 struct iw_request_info *info,
856 union iwreq_data *wrqu, char *extra)
857{
858 struct r8180_priv *priv = ieee80211_priv(dev);
859
860
861
862 wrqu->rts.value = priv->rts;
863 wrqu->rts.fixed = 0; /* no auto select */
864 wrqu->rts.disabled = (wrqu->rts.value == 0);
865
866 return 0;
867}
868static int dummy(struct net_device *dev, struct iw_request_info *a,
869 union iwreq_data *wrqu,char *b)
870{
871 return -1;
872}
873
874/*
875static int r8180_wx_get_psmode(struct net_device *dev,
876 struct iw_request_info *info,
877 union iwreq_data *wrqu, char *extra)
878{
879 struct r8180_priv *priv = ieee80211_priv(dev);
880 struct ieee80211_device *ieee;
881 int ret = 0;
882
883
884
885 down(&priv->wx_sem);
886
887 if(priv) {
888 ieee = priv->ieee80211;
889 if(ieee->ps == IEEE80211_PS_DISABLED) {
890 *((unsigned int *)extra) = IEEE80211_PS_DISABLED;
891 goto exit;
892 }
893 *((unsigned int *)extra) = IW_POWER_TIMEOUT;
894 if (ieee->ps & IEEE80211_PS_MBCAST)
895 *((unsigned int *)extra) |= IW_POWER_ALL_R;
896 else
897 *((unsigned int *)extra) |= IW_POWER_UNICAST_R;
898 } else
899 ret = -1;
900exit:
901 up(&priv->wx_sem);
902
903 return ret;
904}
905static int r8180_wx_set_psmode(struct net_device *dev,
906 struct iw_request_info *info,
907 union iwreq_data *wrqu, char *extra)
908{
909 struct r8180_priv *priv = ieee80211_priv(dev);
910 //struct ieee80211_device *ieee;
911 int ret = 0;
912
913
914
915 down(&priv->wx_sem);
916
917 ret = ieee80211_wx_set_power(priv->ieee80211, info, wrqu, extra);
918
919 up(&priv->wx_sem);
920
921 return ret;
922
923}
924*/
925
926static int r8180_wx_get_iwmode(struct net_device *dev,
927 struct iw_request_info *info,
928 union iwreq_data *wrqu, char *extra)
929{
930 struct r8180_priv *priv = ieee80211_priv(dev);
931 struct ieee80211_device *ieee;
932 int ret = 0;
933
934
935
936 down(&priv->wx_sem);
937
938 ieee = priv->ieee80211;
939
940 strcpy(extra, "802.11");
941 if(ieee->modulation & IEEE80211_CCK_MODULATION) {
942 strcat(extra, "b");
943 if(ieee->modulation & IEEE80211_OFDM_MODULATION)
944 strcat(extra, "/g");
945 } else if(ieee->modulation & IEEE80211_OFDM_MODULATION)
946 strcat(extra, "g");
947
948 up(&priv->wx_sem);
949
950 return ret;
951}
952static int r8180_wx_set_iwmode(struct net_device *dev,
953 struct iw_request_info *info,
954 union iwreq_data *wrqu, char *extra)
955{
956 struct r8180_priv *priv = ieee80211_priv(dev);
957 struct ieee80211_device *ieee = priv->ieee80211;
958 int *param = (int *)extra;
959 int ret = 0;
960 int modulation = 0, mode = 0;
961
962
963 if(priv->ieee80211->bHwRadioOff)
964 return 0;
965
966 down(&priv->wx_sem);
967
968 if (*param == 1) {
969 modulation |= IEEE80211_CCK_MODULATION;
970 mode = IEEE_B;
971 printk(KERN_INFO "B mode!\n");
972 } else if (*param == 2) {
973 modulation |= IEEE80211_OFDM_MODULATION;
974 mode = IEEE_G;
975 printk(KERN_INFO "G mode!\n");
976 } else if (*param == 3) {
977 modulation |= IEEE80211_CCK_MODULATION;
978 modulation |= IEEE80211_OFDM_MODULATION;
979 mode = IEEE_B|IEEE_G;
980 printk(KERN_INFO "B/G mode!\n");
981 }
982
983 if(ieee->proto_started) {
984 ieee80211_stop_protocol(ieee);
985 ieee->mode = mode;
986 ieee->modulation = modulation;
987 ieee80211_start_protocol(ieee);
988 } else {
989 ieee->mode = mode;
990 ieee->modulation = modulation;
991// ieee80211_start_protocol(ieee);
992 }
993
994 up(&priv->wx_sem);
995
996 return ret;
997}
998static int r8180_wx_get_preamble(struct net_device *dev,
999 struct iw_request_info *info,
1000 union iwreq_data *wrqu, char *extra)
1001{
1002 struct r8180_priv *priv = ieee80211_priv(dev);
1003
1004
1005
1006 down(&priv->wx_sem);
1007
1008
1009
1010 *extra = (char) priv->plcp_preamble_mode; // 0:auto 1:short 2:long
1011 up(&priv->wx_sem);
1012
1013 return 0;
1014}
1015static int r8180_wx_set_preamble(struct net_device *dev,
1016 struct iw_request_info *info,
1017 union iwreq_data *wrqu, char *extra)
1018{
1019 struct r8180_priv *priv = ieee80211_priv(dev);
1020 int ret = 0;
1021
1022
1023 if(priv->ieee80211->bHwRadioOff)
1024 return 0;
1025
1026 down(&priv->wx_sem);
1027 if (*extra<0||*extra>2)
1028 ret = -1;
1029 else
1030 priv->plcp_preamble_mode = *((short *)extra) ;
1031
1032
1033
1034 up(&priv->wx_sem);
1035
1036 return ret;
1037}
1038static int r8180_wx_get_siglevel(struct net_device *dev,
1039 struct iw_request_info *info,
1040 union iwreq_data *wrqu, char *extra)
1041{
1042 struct r8180_priv *priv = ieee80211_priv(dev);
1043 //struct ieee80211_network *network = &(priv->ieee80211->current_network);
1044 int ret = 0;
1045
1046
1047
1048 down(&priv->wx_sem);
1049 // Modify by hikaru 6.5
1050 *((int *)extra) = priv->wstats.qual.level;//for interface test ,it should be the priv->wstats.qual.level;
1051
1052
1053
1054 up(&priv->wx_sem);
1055
1056 return ret;
1057}
1058static int r8180_wx_get_sigqual(struct net_device *dev,
1059 struct iw_request_info *info,
1060 union iwreq_data *wrqu, char *extra)
1061{
1062 struct r8180_priv *priv = ieee80211_priv(dev);
1063 //struct ieee80211_network *network = &(priv->ieee80211->current_network);
1064 int ret = 0;
1065
1066
1067
1068 down(&priv->wx_sem);
1069 // Modify by hikaru 6.5
1070 *((int *)extra) = priv->wstats.qual.qual;//for interface test ,it should be the priv->wstats.qual.qual;
1071
1072
1073
1074 up(&priv->wx_sem);
1075
1076 return ret;
1077}
1078static int r8180_wx_reset_stats(struct net_device *dev,
1079 struct iw_request_info *info,
1080 union iwreq_data *wrqu, char *extra)
1081{
1082 struct r8180_priv *priv =ieee80211_priv(dev);
1083 down(&priv->wx_sem);
1084
1085 priv->stats.txrdu = 0;
1086 priv->stats.rxrdu = 0;
1087 priv->stats.rxnolast = 0;
1088 priv->stats.rxnodata = 0;
1089 priv->stats.rxnopointer = 0;
1090 priv->stats.txnperr = 0;
1091 priv->stats.txresumed = 0;
1092 priv->stats.rxerr = 0;
1093 priv->stats.rxoverflow = 0;
1094 priv->stats.rxint = 0;
1095
1096 priv->stats.txnpokint = 0;
1097 priv->stats.txhpokint = 0;
1098 priv->stats.txhperr = 0;
1099 priv->stats.ints = 0;
1100 priv->stats.shints = 0;
1101 priv->stats.txoverflow = 0;
1102 priv->stats.rxdmafail = 0;
1103 priv->stats.txbeacon = 0;
1104 priv->stats.txbeaconerr = 0;
1105 priv->stats.txlpokint = 0;
1106 priv->stats.txlperr = 0;
1107 priv->stats.txretry =0;//20060601
1108 priv->stats.rxcrcerrmin=0;
1109 priv->stats.rxcrcerrmid=0;
1110 priv->stats.rxcrcerrmax=0;
1111 priv->stats.rxicverr=0;
1112
1113 up(&priv->wx_sem);
1114
1115 return 0;
1116
1117}
1118static int r8180_wx_radio_on(struct net_device *dev,
1119 struct iw_request_info *info,
1120 union iwreq_data *wrqu, char *extra)
1121{
1122 struct r8180_priv *priv =ieee80211_priv(dev);
1123
1124 if(priv->ieee80211->bHwRadioOff)
1125 return 0;
1126
1127
1128 down(&priv->wx_sem);
1129 priv->rf_wakeup(dev);
1130
1131 up(&priv->wx_sem);
1132
1133 return 0;
1134
1135}
1136
1137static int r8180_wx_radio_off(struct net_device *dev,
1138 struct iw_request_info *info,
1139 union iwreq_data *wrqu, char *extra)
1140{
1141 struct r8180_priv *priv =ieee80211_priv(dev);
1142
1143 if(priv->ieee80211->bHwRadioOff)
1144 return 0;
1145
1146
1147 down(&priv->wx_sem);
1148 priv->rf_sleep(dev);
1149
1150 up(&priv->wx_sem);
1151
1152 return 0;
1153
1154}
1155static int r8180_wx_get_channelplan(struct net_device *dev,
1156 struct iw_request_info *info,
1157 union iwreq_data *wrqu, char *extra)
1158{
1159 struct r8180_priv *priv = ieee80211_priv(dev);
1160
1161
1162
1163 down(&priv->wx_sem);
1164 *extra = priv->channel_plan;
1165
1166
1167
1168 up(&priv->wx_sem);
1169
1170 return 0;
1171}
1172static int r8180_wx_set_channelplan(struct net_device *dev,
1173 struct iw_request_info *info,
1174 union iwreq_data *wrqu, char *extra)
1175{
1176 struct r8180_priv *priv = ieee80211_priv(dev);
1177 //struct ieee80211_device *ieee = netdev_priv(dev);
1178 int *val = (int *)extra;
1179 int i;
1180 printk("-----in fun %s\n", __FUNCTION__);
1181
1182 if(priv->ieee80211->bHwRadioOff)
1183 return 0;
1184
1185 //unsigned long flags;
1186 down(&priv->wx_sem);
1187 if (DefaultChannelPlan[*val].Len != 0){
1188 priv ->channel_plan = *val;
1189 // Clear old channel map
1190 for (i=1;i<=MAX_CHANNEL_NUMBER;i++)
1191 {
1192#ifdef ENABLE_DOT11D
1193 GET_DOT11D_INFO(priv->ieee80211)->channel_map[i] = 0;
1194#else
1195 priv->ieee80211->channel_map[i] = 0;
1196#endif
1197 }
1198 // Set new channel map
1199 for (i=1;i<=DefaultChannelPlan[*val].Len;i++)
1200 {
1201#ifdef ENABLE_DOT11D
1202 GET_DOT11D_INFO(priv->ieee80211)->channel_map[DefaultChannelPlan[*val].Channel[i-1]] = 1;
1203#else
1204 priv->ieee80211->channel_map[DefaultChannelPlan[*val].Channel[i-1]] = 1;
1205#endif
1206 }
1207 }
1208 up(&priv->wx_sem);
1209
1210 return 0;
1211}
1212
1213static int r8180_wx_get_version(struct net_device *dev,
1214 struct iw_request_info *info,
1215 union iwreq_data *wrqu, char *extra)
1216{
1217 struct r8180_priv *priv = ieee80211_priv(dev);
1218 //struct ieee80211_device *ieee;
1219
1220 down(&priv->wx_sem);
1221 strcpy(extra, "1020.0808");
1222 up(&priv->wx_sem);
1223
1224 return 0;
1225}
1226
1227//added by amy 080818
1228//receive datarate from user typing valid rate is from 2 to 108 (1 - 54M), if input 0, return to normal rate adaptive.
1229static int r8180_wx_set_forcerate(struct net_device *dev,
1230 struct iw_request_info *info,
1231 union iwreq_data *wrqu, char *extra)
1232{
1233 struct r8180_priv *priv = ieee80211_priv(dev);
1234 u8 forcerate = *extra;
1235
1236 down(&priv->wx_sem);
1237
1238 printk("==============>%s(): forcerate is %d\n",__FUNCTION__,forcerate);
1239 if((forcerate == 2) || (forcerate == 4) || (forcerate == 11) || (forcerate == 22) || (forcerate == 12) ||
1240 (forcerate == 18) || (forcerate == 24) || (forcerate == 36) || (forcerate == 48) || (forcerate == 72) ||
1241 (forcerate == 96) || (forcerate == 108))
1242 {
1243 priv->ForcedDataRate = 1;
1244 priv->ieee80211->rate = forcerate * 5;
1245 }
1246 else if(forcerate == 0)
1247 {
1248 priv->ForcedDataRate = 0;
1249 printk("OK! return rate adaptive\n");
1250 }
1251 else
1252 printk("ERR: wrong rate\n");
1253 up(&priv->wx_sem);
1254 return 0;
1255}
1256
1257static int r8180_wx_set_enc_ext(struct net_device *dev,
1258 struct iw_request_info *info,
1259 union iwreq_data *wrqu, char *extra)
1260{
1261
1262 struct r8180_priv *priv = ieee80211_priv(dev);
1263 //printk("===>%s()\n", __FUNCTION__);
1264
1265 int ret=0;
1266
1267 if(priv->ieee80211->bHwRadioOff)
1268 return 0;
1269
1270 down(&priv->wx_sem);
1271 ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra);
1272 up(&priv->wx_sem);
1273 return ret;
1274
1275}
1276static int r8180_wx_set_auth(struct net_device *dev,
1277 struct iw_request_info *info,
1278 struct iw_param *data, char *extra)
1279{
1280 //printk("====>%s()\n", __FUNCTION__);
1281 struct r8180_priv *priv = ieee80211_priv(dev);
1282 int ret=0;
1283
1284 if(priv->ieee80211->bHwRadioOff)
1285 return 0;
1286
1287 down(&priv->wx_sem);
1288 ret = ieee80211_wx_set_auth(priv->ieee80211, info, data, extra);
1289 up(&priv->wx_sem);
1290 return ret;
1291}
1292
1293static int r8180_wx_set_mlme(struct net_device *dev,
1294 struct iw_request_info *info,
1295 union iwreq_data *wrqu, char *extra)
1296{
1297 //printk("====>%s()\n", __FUNCTION__);
1298
1299 int ret=0;
1300 struct r8180_priv *priv = ieee80211_priv(dev);
1301
1302
1303 if(priv->ieee80211->bHwRadioOff)
1304 return 0;
1305
1306
1307 down(&priv->wx_sem);
1308#if 1
1309 ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
1310#endif
1311 up(&priv->wx_sem);
1312 return ret;
1313}
1314static int r8180_wx_set_gen_ie(struct net_device *dev,
1315 struct iw_request_info *info,
1316 struct iw_point *data, char *extra)
1317{
1318// printk("====>%s(), len:%d\n", __FUNCTION__, data->length);
1319 int ret=0;
1320 struct r8180_priv *priv = ieee80211_priv(dev);
1321
1322
1323 if(priv->ieee80211->bHwRadioOff)
1324 return 0;
1325
1326 down(&priv->wx_sem);
1327#if 1
1328 ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->length);
1329#endif
1330 up(&priv->wx_sem);
1331 //printk("<======%s(), ret:%d\n", __FUNCTION__, ret);
1332 return ret;
1333
1334
1335}
1336static iw_handler r8180_wx_handlers[] =
1337{
1338 NULL, /* SIOCSIWCOMMIT */
1339 r8180_wx_get_name, /* SIOCGIWNAME */
1340 dummy, /* SIOCSIWNWID */
1341 dummy, /* SIOCGIWNWID */
1342 r8180_wx_set_freq, /* SIOCSIWFREQ */
1343 r8180_wx_get_freq, /* SIOCGIWFREQ */
1344 r8180_wx_set_mode, /* SIOCSIWMODE */
1345 r8180_wx_get_mode, /* SIOCGIWMODE */
1346 r8180_wx_set_sens, /* SIOCSIWSENS */
1347 r8180_wx_get_sens, /* SIOCGIWSENS */
1348 NULL, /* SIOCSIWRANGE */
1349 rtl8180_wx_get_range, /* SIOCGIWRANGE */
1350 NULL, /* SIOCSIWPRIV */
1351 NULL, /* SIOCGIWPRIV */
1352 NULL, /* SIOCSIWSTATS */
1353 NULL, /* SIOCGIWSTATS */
1354 dummy, /* SIOCSIWSPY */
1355 dummy, /* SIOCGIWSPY */
1356 NULL, /* SIOCGIWTHRSPY */
1357 NULL, /* SIOCWIWTHRSPY */
1358 r8180_wx_set_wap, /* SIOCSIWAP */
1359 r8180_wx_get_wap, /* SIOCGIWAP */
1360 r8180_wx_set_mlme, /* SIOCSIWMLME*/
1361 dummy, /* SIOCGIWAPLIST -- depricated */
1362 r8180_wx_set_scan, /* SIOCSIWSCAN */
1363 r8180_wx_get_scan, /* SIOCGIWSCAN */
1364 r8180_wx_set_essid, /* SIOCSIWESSID */
1365 r8180_wx_get_essid, /* SIOCGIWESSID */
1366 dummy, /* SIOCSIWNICKN */
1367 dummy, /* SIOCGIWNICKN */
1368 NULL, /* -- hole -- */
1369 NULL, /* -- hole -- */
1370 r8180_wx_set_rate, /* SIOCSIWRATE */
1371 r8180_wx_get_rate, /* SIOCGIWRATE */
1372 r8180_wx_set_rts, /* SIOCSIWRTS */
1373 r8180_wx_get_rts, /* SIOCGIWRTS */
1374 r8180_wx_set_frag, /* SIOCSIWFRAG */
1375 r8180_wx_get_frag, /* SIOCGIWFRAG */
1376 dummy, /* SIOCSIWTXPOW */
1377 dummy, /* SIOCGIWTXPOW */
1378 r8180_wx_set_retry, /* SIOCSIWRETRY */
1379 r8180_wx_get_retry, /* SIOCGIWRETRY */
1380 r8180_wx_set_enc, /* SIOCSIWENCODE */
1381 r8180_wx_get_enc, /* SIOCGIWENCODE */
1382 r8180_wx_set_power, /* SIOCSIWPOWER */
1383 r8180_wx_get_power, /* SIOCGIWPOWER */
1384 NULL, /*---hole---*/
1385 NULL, /*---hole---*/
1386 r8180_wx_set_gen_ie, /* SIOCSIWGENIE */
1387 NULL, /* SIOCSIWGENIE */
1388 r8180_wx_set_auth, /* SIOCSIWAUTH */
1389 NULL, /* SIOCSIWAUTH */
1390 r8180_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
1391 NULL, /* SIOCSIWENCODEEXT */
1392 NULL, /* SIOCSIWPMKSA */
1393 NULL, /*---hole---*/
1394};
1395
1396
1397static const struct iw_priv_args r8180_private_args[] = {
1398 {
1399 SIOCIWFIRSTPRIV + 0x0,
1400 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
1401 },
1402 { SIOCIWFIRSTPRIV + 0x1,
1403 0, 0, "dummy"
1404
1405 },
1406 {
1407 SIOCIWFIRSTPRIV + 0x2,
1408 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "beaconint"
1409 },
1410 { SIOCIWFIRSTPRIV + 0x3,
1411 0, 0, "dummy"
1412
1413 },
1414 /* added by christian */
1415 //{
1416 // SIOCIWFIRSTPRIV + 0x2,
1417 // IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "prismhdr"
1418 //},
1419 /* end added by christian */
1420 {
1421 SIOCIWFIRSTPRIV + 0x4,
1422 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
1423
1424 },
1425 { SIOCIWFIRSTPRIV + 0x5,
1426 0, 0, "dummy"
1427
1428 },
1429 {
1430 SIOCIWFIRSTPRIV + 0x6,
1431 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
1432
1433 },
1434 { SIOCIWFIRSTPRIV + 0x7,
1435 0, 0, "dummy"
1436
1437 },
1438// {
1439// SIOCIWFIRSTPRIV + 0x5,
1440// 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getpsmode"
1441// },
1442// {
1443// SIOCIWFIRSTPRIV + 0x6,
1444// IW_PRIV_SIZE_FIXED, 0, "setpsmode"
1445// },
1446//set/get mode have been realized in public handlers
1447
1448 {
1449 SIOCIWFIRSTPRIV + 0x8,
1450 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setiwmode"
1451 },
1452 {
1453 SIOCIWFIRSTPRIV + 0x9,
1454 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 32, "getiwmode"
1455 },
1456 {
1457 SIOCIWFIRSTPRIV + 0xA,
1458 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setpreamble"
1459 },
1460 {
1461 SIOCIWFIRSTPRIV + 0xB,
1462 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getpreamble"
1463 },
1464 { SIOCIWFIRSTPRIV + 0xC,
1465 0, 0, "dummy"
1466 },
1467 {
1468 SIOCIWFIRSTPRIV + 0xD,
1469 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getrssi"
1470 },
1471 { SIOCIWFIRSTPRIV + 0xE,
1472 0, 0, "dummy"
1473 },
1474 {
1475 SIOCIWFIRSTPRIV + 0xF,
1476 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getlinkqual"
1477 },
1478 {
1479 SIOCIWFIRSTPRIV + 0x10,
1480 0, 0, "resetstats"
1481 },
1482 {
1483 SIOCIWFIRSTPRIV + 0x11,
1484 0,0, "dummy"
1485 },
1486 {
1487 SIOCIWFIRSTPRIV + 0x12,
1488 0, 0, "radioon"
1489 },
1490 {
1491 SIOCIWFIRSTPRIV + 0x13,
1492 0, 0, "radiooff"
1493 },
1494 {
1495 SIOCIWFIRSTPRIV + 0x14,
1496 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setchannel"
1497 },
1498 {
1499 SIOCIWFIRSTPRIV + 0x15,
1500 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getchannel"
1501 },
1502 {
1503 SIOCIWFIRSTPRIV + 0x16,
1504 0,0, "dummy"
1505 },
1506 {
1507 SIOCIWFIRSTPRIV + 0x17,
1508 0,IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 32, "getversion"
1509 },
1510 {
1511 SIOCIWFIRSTPRIV + 0x18,
1512 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setrate"
1513 },
1514};
1515
1516
1517static iw_handler r8180_private_handler[] = {
1518 r8180_wx_set_crcmon, /*SIOCIWSECONDPRIV*/
1519 dummy,
1520 r8180_wx_set_beaconinterval,
1521 dummy,
1522 //r8180_wx_set_monitor_type,
1523 r8180_wx_set_scan_type,
1524 dummy,
1525 r8180_wx_set_rawtx,
1526 dummy,
1527 r8180_wx_set_iwmode,
1528 r8180_wx_get_iwmode,
1529 r8180_wx_set_preamble,
1530 r8180_wx_get_preamble,
1531 dummy,
1532 r8180_wx_get_siglevel,
1533 dummy,
1534 r8180_wx_get_sigqual,
1535 r8180_wx_reset_stats,
1536 dummy,//r8180_wx_get_stats
1537 r8180_wx_radio_on,
1538 r8180_wx_radio_off,
1539 r8180_wx_set_channelplan,
1540 r8180_wx_get_channelplan,
1541 dummy,
1542 r8180_wx_get_version,
1543 r8180_wx_set_forcerate,
1544};
1545
1546#if WIRELESS_EXT >= 17
1547static inline int is_same_network(struct ieee80211_network *src,
1548 struct ieee80211_network *dst,
1549 struct ieee80211_device *ieee)
1550{
1551 /* A network is only a duplicate if the channel, BSSID, ESSID
1552 * and the capability field (in particular IBSS and BSS) all match.
1553 * We treat all <hidden> with the same BSSID and channel
1554 * as one network */
1555 return (((src->ssid_len == dst->ssid_len)||(ieee->iw_mode == IW_MODE_INFRA)) && //YJ,mod, 080819,for hidden ap
1556 //((src->ssid_len == dst->ssid_len) &&
1557 (src->channel == dst->channel) &&
1558 !memcmp(src->bssid, dst->bssid, ETH_ALEN) &&
1559 (!memcmp(src->ssid, dst->ssid, src->ssid_len)||(ieee->iw_mode == IW_MODE_INFRA)) && //YJ,mod, 080819,for hidden ap
1560 //!memcmp(src->ssid, dst->ssid, src->ssid_len) &&
1561 ((src->capability & WLAN_CAPABILITY_IBSS) ==
1562 (dst->capability & WLAN_CAPABILITY_IBSS)) &&
1563 ((src->capability & WLAN_CAPABILITY_BSS) ==
1564 (dst->capability & WLAN_CAPABILITY_BSS)));
1565}
1566
1567//WB modefied to show signal to GUI on 18-01-2008
1568static struct iw_statistics *r8180_get_wireless_stats(struct net_device *dev)
1569{
1570 struct r8180_priv *priv = ieee80211_priv(dev);
1571 struct ieee80211_device* ieee = priv->ieee80211;
1572 struct iw_statistics* wstats = &priv->wstats;
1573 //struct ieee80211_network* target = NULL;
1574 int tmp_level = 0;
1575 int tmp_qual = 0;
1576 int tmp_noise = 0;
1577 //unsigned long flag;
1578
1579 if (ieee->state < IEEE80211_LINKED)
1580 {
1581 wstats->qual.qual = 0;
1582 wstats->qual.level = 0;
1583 wstats->qual.noise = 0;
1584 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1585 return wstats;
1586 }
1587#if 0
1588 spin_lock_irqsave(&ieee->lock, flag);
1589 list_for_each_entry(target, &ieee->network_list, list)
1590 {
1591 if (is_same_network(target, &ieee->current_network, ieee))
1592 {
1593 printk("it's same network:%s\n", target->ssid);
1594#if 0
1595 if (!tmp_level)
1596 {
1597 tmp_level = target->stats.signalstrength;
1598 tmp_qual = target->stats.signal;
1599 }
1600 else
1601 {
1602
1603 tmp_level = (15*tmp_level + target->stats.signalstrength)/16;
1604 tmp_qual = (15*tmp_qual + target->stats.signal)/16;
1605 }
1606#else
1607 tmp_level = target->stats.signal;
1608 tmp_qual = target->stats.signalstrength;
1609 tmp_noise = target->stats.noise;
1610 printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
1611#endif
1612 break;
1613 }
1614 }
1615 spin_unlock_irqrestore(&ieee->lock, flag);
1616#endif
1617 tmp_level = (&ieee->current_network)->stats.signal;
1618 tmp_qual = (&ieee->current_network)->stats.signalstrength;
1619 tmp_noise = (&ieee->current_network)->stats.noise;
1620 //printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
1621
1622// printk("level:%d\n", tmp_level);
1623 wstats->qual.level = tmp_level;
1624 wstats->qual.qual = tmp_qual;
1625 wstats->qual.noise = tmp_noise;
1626 wstats->qual.updated = IW_QUAL_ALL_UPDATED| IW_QUAL_DBM;
1627 return wstats;
1628}
1629#endif
1630
1631
1632struct iw_handler_def r8180_wx_handlers_def={
1633 .standard = r8180_wx_handlers,
1634 .num_standard = sizeof(r8180_wx_handlers) / sizeof(iw_handler),
1635 .private = r8180_private_handler,
1636 .num_private = sizeof(r8180_private_handler) / sizeof(iw_handler),
1637 .num_private_args = sizeof(r8180_private_args) / sizeof(struct iw_priv_args),
1638#if WIRELESS_EXT >= 17
1639 .get_wireless_stats = r8180_get_wireless_stats,
1640#endif
1641 .private_args = (struct iw_priv_args *)r8180_private_args,
1642};
1643
1644
diff --git a/drivers/staging/rtl8187se/r8180_wx.h b/drivers/staging/rtl8187se/r8180_wx.h
new file mode 100644
index 000000000000..b20a67d33411
--- /dev/null
+++ b/drivers/staging/rtl8187se/r8180_wx.h
@@ -0,0 +1,21 @@
1/*
2 This is part of rtl8180 OpenSource driver - v 0.3
3 Copyright (C) Andrea Merello 2004 <andreamrl@tiscali.it>
4 Released under the terms of GPL (General Public Licence)
5
6 Parts of this driver are based on the GPL part of the official realtek driver
7 Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon
8 Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
9
10 We want to tanks the Authors of such projects and the Ndiswrapper project Authors.
11*/
12
13/* this file (will) contains wireless extension handlers*/
14
15#ifndef R8180_WX_H
16#define R8180_WX_H
17#include <linux/wireless.h>
18#include "ieee80211.h"
19extern struct iw_handler_def r8180_wx_handlers_def;
20
21#endif
diff --git a/drivers/staging/rtl8187se/r8185b_init.c b/drivers/staging/rtl8187se/r8185b_init.c
new file mode 100644
index 000000000000..4b885a2319ee
--- /dev/null
+++ b/drivers/staging/rtl8187se/r8185b_init.c
@@ -0,0 +1,3342 @@
1/*++
2Copyright (c) Realtek Semiconductor Corp. All rights reserved.
3
4Module Name:
5 r8185b_init.c
6
7Abstract:
8 Hardware Initialization and Hardware IO for RTL8185B
9
10Major Change History:
11 When Who What
12 ---------- --------------- -------------------------------
13 2006-11-15 Xiong Created
14
15Notes:
16 This file is ported from RTL8185B Windows driver.
17
18
19--*/
20
21/*--------------------------Include File------------------------------------*/
22#include <linux/spinlock.h>
23#include "r8180_hw.h"
24#include "r8180.h"
25#include "r8180_sa2400.h" /* PHILIPS Radio frontend */
26#include "r8180_max2820.h" /* MAXIM Radio frontend */
27#include "r8180_gct.h" /* GCT Radio frontend */
28#include "r8180_rtl8225.h" /* RTL8225 Radio frontend */
29#include "r8180_rtl8255.h" /* RTL8255 Radio frontend */
30#include "r8180_93cx6.h" /* Card EEPROM */
31#include "r8180_wx.h"
32
33#ifdef CONFIG_RTL8180_PM
34#include "r8180_pm.h"
35#endif
36
37#ifdef ENABLE_DOT11D
38#include "dot11d.h"
39#endif
40
41#ifdef CONFIG_RTL8185B
42
43//#define CONFIG_RTL8180_IO_MAP
44
45#define TC_3W_POLL_MAX_TRY_CNT 5
46#ifdef CONFIG_RTL818X_S
47static u8 MAC_REG_TABLE[][2]={
48 //PAGA 0:
49 // 0x34(BRSR), 0xBE(RATE_FALLBACK_CTL), 0x1E0(ARFR) would set in HwConfigureRTL8185()
50 // 0x272(RFSW_CTRL), 0x1CE(AESMSK_QC) set in InitializeAdapter8185().
51 // 0x1F0~0x1F8 set in MacConfig_85BASIC()
52 {0x08, 0xae}, {0x0a, 0x72}, {0x5b, 0x42},
53 {0x84, 0x88}, {0x85, 0x24}, {0x88, 0x54}, {0x8b, 0xb8}, {0x8c, 0x03},
54 {0x8d, 0x40}, {0x8e, 0x00}, {0x8f, 0x00}, {0x5b, 0x18}, {0x91, 0x03},
55 {0x94, 0x0F}, {0x95, 0x32},
56 {0x96, 0x00}, {0x97, 0x07}, {0xb4, 0x22}, {0xdb, 0x00},
57 {0xf0, 0x32}, {0xf1, 0x32}, {0xf2, 0x00}, {0xf3, 0x00}, {0xf4, 0x32},
58 {0xf5, 0x43}, {0xf6, 0x00}, {0xf7, 0x00}, {0xf8, 0x46}, {0xf9, 0xa4},
59 {0xfa, 0x00}, {0xfb, 0x00}, {0xfc, 0x96}, {0xfd, 0xa4}, {0xfe, 0x00},
60 {0xff, 0x00},
61
62 //PAGE 1:
63 // For Flextronics system Logo PCIHCT failure:
64 // 0x1C4~0x1CD set no-zero value to avoid PCI configuration space 0x45[7]=1
65 {0x5e, 0x01},
66 {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x04}, {0x5b, 0x00}, {0x60, 0x24},
67 {0x61, 0x97}, {0x62, 0xF0}, {0x63, 0x09}, {0x80, 0x0F}, {0x81, 0xFF},
68 {0x82, 0xFF}, {0x83, 0x03},
69 {0xC4, 0x22}, {0xC5, 0x22}, {0xC6, 0x22}, {0xC7, 0x22}, {0xC8, 0x22}, //lzm add 080826
70 {0xC9, 0x22}, {0xCA, 0x22}, {0xCB, 0x22}, {0xCC, 0x22}, {0xCD, 0x22},//lzm add 080826
71 {0xe2, 0x00},
72
73
74 //PAGE 2:
75 {0x5e, 0x02},
76 {0x0c, 0x04}, {0x4c, 0x30}, {0x4d, 0x08}, {0x50, 0x05}, {0x51, 0xf5},
77 {0x52, 0x04}, {0x53, 0xa0}, {0x54, 0xff}, {0x55, 0xff}, {0x56, 0xff},
78 {0x57, 0xff}, {0x58, 0x08}, {0x59, 0x08}, {0x5a, 0x08}, {0x5b, 0x08},
79 {0x60, 0x08}, {0x61, 0x08}, {0x62, 0x08}, {0x63, 0x08}, {0x64, 0x2f},
80 {0x8c, 0x3f}, {0x8d, 0x3f}, {0x8e, 0x3f},
81 {0x8f, 0x3f}, {0xc4, 0xff}, {0xc5, 0xff}, {0xc6, 0xff}, {0xc7, 0xff},
82 {0xc8, 0x00}, {0xc9, 0x00}, {0xca, 0x80}, {0xcb, 0x00},
83
84 //PAGA 0:
85 {0x5e, 0x00},{0x9f, 0x03}
86 };
87
88
89static u8 ZEBRA_AGC[]={
90 0,
91 0x7E,0x7E,0x7E,0x7E,0x7D,0x7C,0x7B,0x7A,0x79,0x78,0x77,0x76,0x75,0x74,0x73,0x72,
92 0x71,0x70,0x6F,0x6E,0x6D,0x6C,0x6B,0x6A,0x69,0x68,0x67,0x66,0x65,0x64,0x63,0x62,
93 0x48,0x47,0x46,0x45,0x44,0x29,0x28,0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x08,0x07,
94 0x06,0x05,0x04,0x03,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
95 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x10,0x11,0x12,0x13,0x15,0x16,
96 0x17,0x17,0x18,0x18,0x19,0x1a,0x1a,0x1b,0x1b,0x1c,0x1c,0x1d,0x1d,0x1d,0x1e,0x1e,
97 0x1f,0x1f,0x1f,0x20,0x20,0x20,0x20,0x21,0x21,0x21,0x22,0x22,0x22,0x23,0x23,0x24,
98 0x24,0x25,0x25,0x25,0x26,0x26,0x27,0x27,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F
99 };
100
101static u32 ZEBRA_RF_RX_GAIN_TABLE[]={
102 0x0096,0x0076,0x0056,0x0036,0x0016,0x01f6,0x01d6,0x01b6,
103 0x0196,0x0176,0x00F7,0x00D7,0x00B7,0x0097,0x0077,0x0057,
104 0x0037,0x00FB,0x00DB,0x00BB,0x00FF,0x00E3,0x00C3,0x00A3,
105 0x0083,0x0063,0x0043,0x0023,0x0003,0x01E3,0x01C3,0x01A3,
106 0x0183,0x0163,0x0143,0x0123,0x0103
107 };
108
109static u8 OFDM_CONFIG[]={
110 // OFDM reg0x06[7:0]=0xFF: Enable power saving mode in RX
111 // OFDM reg0x3C[4]=1'b1: Enable RX power saving mode
112 // ofdm 0x3a = 0x7b ,(original : 0xfb) For ECS shielding room TP test
113
114 // 0x00
115 0x10, 0x0F, 0x0A, 0x0C, 0x14, 0xFA, 0xFF, 0x50,
116 0x00, 0x50, 0x00, 0x00, 0x00, 0x5C, 0x00, 0x00,
117 // 0x10
118 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0xA8, 0x26,
119 0x32, 0x33, 0x06, 0xA5, 0x6F, 0x55, 0xC8, 0xBB,
120 // 0x20
121 0x0A, 0xE1, 0x2C, 0x4A, 0x86, 0x83, 0x34, 0x00,
122 0x4F, 0x24, 0x6F, 0xC2, 0x03, 0x40, 0x80, 0x00,
123 // 0x30
124 0xC0, 0xC1, 0x58, 0xF1, 0x00, 0xC4, 0x90, 0x3e,
125 0xD8, 0x3C, 0x7B, 0x10, 0x10
126 };
127#else
128 static u8 MAC_REG_TABLE[][2]={
129 //PAGA 0:
130 {0xf0, 0x32}, {0xf1, 0x32}, {0xf2, 0x00}, {0xf3, 0x00}, {0xf4, 0x32},
131 {0xf5, 0x43}, {0xf6, 0x00}, {0xf7, 0x00}, {0xf8, 0x46}, {0xf9, 0xa4},
132 {0xfa, 0x00}, {0xfb, 0x00}, {0xfc, 0x96}, {0xfd, 0xa4}, {0xfe, 0x00},
133 {0xff, 0x00},
134
135 //PAGE 1:
136 {0x5e, 0x01},
137 {0x58, 0x4b}, {0x59, 0x00}, {0x5a, 0x4b}, {0x5b, 0x00}, {0x60, 0x4b},
138 {0x61, 0x09}, {0x62, 0x4b}, {0x63, 0x09}, {0xce, 0x0f}, {0xcf, 0x00},
139 {0xe0, 0xff}, {0xe1, 0x0f}, {0xe2, 0x00}, {0xf0, 0x4e}, {0xf1, 0x01},
140 {0xf2, 0x02}, {0xf3, 0x03}, {0xf4, 0x04}, {0xf5, 0x05}, {0xf6, 0x06},
141 {0xf7, 0x07}, {0xf8, 0x08},
142
143
144 //PAGE 2:
145 {0x5e, 0x02},
146 {0x0c, 0x04}, {0x21, 0x61}, {0x22, 0x68}, {0x23, 0x6f}, {0x24, 0x76},
147 {0x25, 0x7d}, {0x26, 0x84}, {0x27, 0x8d}, {0x4d, 0x08}, {0x4e, 0x00},
148 {0x50, 0x05}, {0x51, 0xf5}, {0x52, 0x04}, {0x53, 0xa0}, {0x54, 0x1f},
149 {0x55, 0x23}, {0x56, 0x45}, {0x57, 0x67}, {0x58, 0x08}, {0x59, 0x08},
150 {0x5a, 0x08}, {0x5b, 0x08}, {0x60, 0x08}, {0x61, 0x08}, {0x62, 0x08},
151 {0x63, 0x08}, {0x64, 0xcf}, {0x72, 0x56}, {0x73, 0x9a},
152
153 //PAGA 0:
154 {0x5e, 0x00},
155 {0x34, 0xff}, {0x35, 0x0f}, {0x5b, 0x40}, {0x84, 0x88}, {0x85, 0x24},
156 {0x88, 0x54}, {0x8b, 0xb8}, {0x8c, 0x07}, {0x8d, 0x00}, {0x94, 0x1b},
157 {0x95, 0x12}, {0x96, 0x00}, {0x97, 0x06}, {0x9d, 0x1a}, {0x9f, 0x10},
158 {0xb4, 0x22}, {0xbe, 0x80}, {0xdb, 0x00}, {0xee, 0x00}, {0x5b, 0x42},
159 {0x91, 0x03},
160
161 //PAGE 2:
162 {0x5e, 0x02},
163 {0x4c, 0x03},
164
165 //PAGE 0:
166 {0x5e, 0x00},
167
168 //PAGE 3:
169 {0x5e, 0x03},
170 {0x9f, 0x00},
171
172 //PAGE 0:
173 {0x5e, 0x00},
174 {0x8c, 0x01}, {0x8d, 0x10},{0x8e, 0x08}, {0x8f, 0x00}
175 };
176
177
178static u8 ZEBRA_AGC[]={
179 0,
180 0x5e,0x5e,0x5e,0x5e,0x5d,0x5b,0x59,0x57,0x55,0x53,0x51,0x4f,0x4d,0x4b,0x49,0x47,
181 0x45,0x43,0x41,0x3f,0x3d,0x3b,0x39,0x37,0x35,0x33,0x31,0x2f,0x2d,0x2b,0x29,0x27,
182 0x25,0x23,0x21,0x1f,0x1d,0x1b,0x19,0x17,0x15,0x13,0x11,0x0f,0x0d,0x0b,0x09,0x07,
183 0x05,0x03,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
184 0x19,0x19,0x19,0x019,0x19,0x19,0x19,0x19,0x19,0x19,0x1e,0x1f,0x20,0x21,0x21,0x22,
185 0x23,0x24,0x24,0x25,0x25,0x26,0x26,0x27,0x27,0x28,0x28,0x28,0x29,0x2a,0x2a,0x2b,
186 0x2b,0x2b,0x2c,0x2c,0x2c,0x2d,0x2d,0x2d,0x2e,0x2e,0x2f,0x30,0x31,0x31,0x31,0x31,
187 0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31
188 };
189
190static u32 ZEBRA_RF_RX_GAIN_TABLE[]={
191 0,
192 0x0400,0x0401,0x0402,0x0403,0x0404,0x0405,0x0408,0x0409,
193 0x040a,0x040b,0x0502,0x0503,0x0504,0x0505,0x0540,0x0541,
194 0x0542,0x0543,0x0544,0x0545,0x0580,0x0581,0x0582,0x0583,
195 0x0584,0x0585,0x0588,0x0589,0x058a,0x058b,0x0643,0x0644,
196 0x0645,0x0680,0x0681,0x0682,0x0683,0x0684,0x0685,0x0688,
197 0x0689,0x068a,0x068b,0x068c,0x0742,0x0743,0x0744,0x0745,
198 0x0780,0x0781,0x0782,0x0783,0x0784,0x0785,0x0788,0x0789,
199 0x078a,0x078b,0x078c,0x078d,0x0790,0x0791,0x0792,0x0793,
200 0x0794,0x0795,0x0798,0x0799,0x079a,0x079b,0x079c,0x079d,
201 0x07a0,0x07a1,0x07a2,0x07a3,0x07a4,0x07a5,0x07a8,0x07a9,
202 0x03aa,0x03ab,0x03ac,0x03ad,0x03b0,0x03b1,0x03b2,0x03b3,
203 0x03b4,0x03b5,0x03b8,0x03b9,0x03ba,0x03bb,0x03bb
204};
205
206// 2006.07.13, SD3 szuyitasi:
207// OFDM.0x03=0x0C (original is 0x0F)
208// Use the new SD3 given param, by shien chang, 2006.07.14
209static u8 OFDM_CONFIG[]={
210 0x10, 0x0d, 0x01, 0x0C, 0x14, 0xfb, 0x0f, 0x60, 0x00, 0x60,
211 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00,
212 0x00, 0x00, 0xa8, 0x46, 0xb2, 0x33, 0x07, 0xa5, 0x6f, 0x55,
213 0xc8, 0xb3, 0x0a, 0xe1, 0x1c, 0x8a, 0xb6, 0x83, 0x34, 0x0f,
214 0x4f, 0x23, 0x6f, 0xc2, 0x6b, 0x40, 0x80, 0x00, 0xc0, 0xc1,
215 0x58, 0xf1, 0x00, 0xe4, 0x90, 0x3e, 0x6d, 0x3c, 0xff, 0x07
216};
217#endif
218
219/*---------------------------------------------------------------
220 * Hardware IO
221 * the code is ported from Windows source code
222 ----------------------------------------------------------------*/
223
224void
225PlatformIOWrite1Byte(
226 struct net_device *dev,
227 u32 offset,
228 u8 data
229 )
230{
231#ifndef CONFIG_RTL8180_IO_MAP
232 write_nic_byte(dev, offset, data);
233 read_nic_byte(dev, offset); // To make sure write operation is completed, 2005.11.09, by rcnjko.
234
235#else // Port IO
236 u32 Page = (offset >> 8);
237
238 switch(Page)
239 {
240 case 0: // Page 0
241 write_nic_byte(dev, offset, data);
242 break;
243
244 case 1: // Page 1
245 case 2: // Page 2
246 case 3: // Page 3
247 {
248 u8 psr = read_nic_byte(dev, PSR);
249
250 write_nic_byte(dev, PSR, ((psr & 0xfc) | (u8)Page)); // Switch to page N.
251 write_nic_byte(dev, (offset & 0xff), data);
252 write_nic_byte(dev, PSR, (psr & 0xfc)); // Switch to page 0.
253 }
254 break;
255
256 default:
257 // Illegal page number.
258 DMESGE("PlatformIOWrite1Byte(): illegal page number: %d, offset: %#X", Page, offset);
259 break;
260 }
261#endif
262}
263
264void
265PlatformIOWrite2Byte(
266 struct net_device *dev,
267 u32 offset,
268 u16 data
269 )
270{
271#ifndef CONFIG_RTL8180_IO_MAP
272 write_nic_word(dev, offset, data);
273 read_nic_word(dev, offset); // To make sure write operation is completed, 2005.11.09, by rcnjko.
274
275
276#else // Port IO
277 u32 Page = (offset >> 8);
278
279 switch(Page)
280 {
281 case 0: // Page 0
282 write_nic_word(dev, offset, data);
283 break;
284
285 case 1: // Page 1
286 case 2: // Page 2
287 case 3: // Page 3
288 {
289 u8 psr = read_nic_byte(dev, PSR);
290
291 write_nic_byte(dev, PSR, ((psr & 0xfc) | (u8)Page)); // Switch to page N.
292 write_nic_word(dev, (offset & 0xff), data);
293 write_nic_byte(dev, PSR, (psr & 0xfc)); // Switch to page 0.
294 }
295 break;
296
297 default:
298 // Illegal page number.
299 DMESGE("PlatformIOWrite2Byte(): illegal page number: %d, offset: %#X", Page, offset);
300 break;
301 }
302#endif
303}
304u8 PlatformIORead1Byte(struct net_device *dev, u32 offset);
305
306void
307PlatformIOWrite4Byte(
308 struct net_device *dev,
309 u32 offset,
310 u32 data
311 )
312{
313#ifndef CONFIG_RTL8180_IO_MAP
314//{by amy 080312
315if (offset == PhyAddr)
316 {//For Base Band configuration.
317 unsigned char cmdByte;
318 unsigned long dataBytes;
319 unsigned char idx;
320 u8 u1bTmp;
321
322 cmdByte = (u8)(data & 0x000000ff);
323 dataBytes = data>>8;
324
325 //
326 // 071010, rcnjko:
327 // The critical section is only BB read/write race condition.
328 // Assumption:
329 // 1. We assume NO one will access BB at DIRQL, otherwise, system will crash for
330 // acquiring the spinlock in such context.
331 // 2. PlatformIOWrite4Byte() MUST NOT be recursive.
332 //
333// NdisAcquireSpinLock( &(pDevice->IoSpinLock) );
334
335 for(idx = 0; idx < 30; idx++)
336 { // Make sure command bit is clear before access it.
337 u1bTmp = PlatformIORead1Byte(dev, PhyAddr);
338 if((u1bTmp & BIT7) == 0)
339 break;
340 else
341 mdelay(10);
342 }
343
344 for(idx=0; idx < 3; idx++)
345 {
346 PlatformIOWrite1Byte(dev,offset+1+idx,((u8*)&dataBytes)[idx] );
347 }
348 write_nic_byte(dev, offset, cmdByte);
349
350// NdisReleaseSpinLock( &(pDevice->IoSpinLock) );
351 }
352//by amy 080312}
353 else{
354 write_nic_dword(dev, offset, data);
355 read_nic_dword(dev, offset); // To make sure write operation is completed, 2005.11.09, by rcnjko.
356 }
357#else // Port IO
358 u32 Page = (offset >> 8);
359
360 switch(Page)
361 {
362 case 0: // Page 0
363 write_nic_word(dev, offset, data);
364 break;
365
366 case 1: // Page 1
367 case 2: // Page 2
368 case 3: // Page 3
369 {
370 u8 psr = read_nic_byte(dev, PSR);
371
372 write_nic_byte(dev, PSR, ((psr & 0xfc) | (u8)Page)); // Switch to page N.
373 write_nic_dword(dev, (offset & 0xff), data);
374 write_nic_byte(dev, PSR, (psr & 0xfc)); // Switch to page 0.
375 }
376 break;
377
378 default:
379 // Illegal page number.
380 DMESGE("PlatformIOWrite4Byte(): illegal page number: %d, offset: %#X", Page, offset);
381 break;
382 }
383#endif
384}
385
386u8
387PlatformIORead1Byte(
388 struct net_device *dev,
389 u32 offset
390 )
391{
392 u8 data = 0;
393
394#ifndef CONFIG_RTL8180_IO_MAP
395 data = read_nic_byte(dev, offset);
396
397#else // Port IO
398 u32 Page = (offset >> 8);
399
400 switch(Page)
401 {
402 case 0: // Page 0
403 data = read_nic_byte(dev, offset);
404 break;
405
406 case 1: // Page 1
407 case 2: // Page 2
408 case 3: // Page 3
409 {
410 u8 psr = read_nic_byte(dev, PSR);
411
412 write_nic_byte(dev, PSR, ((psr & 0xfc) | (u8)Page)); // Switch to page N.
413 data = read_nic_byte(dev, (offset & 0xff));
414 write_nic_byte(dev, PSR, (psr & 0xfc)); // Switch to page 0.
415 }
416 break;
417
418 default:
419 // Illegal page number.
420 DMESGE("PlatformIORead1Byte(): illegal page number: %d, offset: %#X", Page, offset);
421 break;
422 }
423#endif
424
425 return data;
426}
427
428u16
429PlatformIORead2Byte(
430 struct net_device *dev,
431 u32 offset
432 )
433{
434 u16 data = 0;
435
436#ifndef CONFIG_RTL8180_IO_MAP
437 data = read_nic_word(dev, offset);
438
439#else // Port IO
440 u32 Page = (offset >> 8);
441
442 switch(Page)
443 {
444 case 0: // Page 0
445 data = read_nic_word(dev, offset);
446 break;
447
448 case 1: // Page 1
449 case 2: // Page 2
450 case 3: // Page 3
451 {
452 u8 psr = read_nic_byte(dev, PSR);
453
454 write_nic_byte(dev, PSR, ((psr & 0xfc) | (u8)Page)); // Switch to page N.
455 data = read_nic_word(dev, (offset & 0xff));
456 write_nic_byte(dev, PSR, (psr & 0xfc)); // Switch to page 0.
457 }
458 break;
459
460 default:
461 // Illegal page number.
462 DMESGE("PlatformIORead2Byte(): illegal page number: %d, offset: %#X", Page, offset);
463 break;
464 }
465#endif
466
467 return data;
468}
469
470u32
471PlatformIORead4Byte(
472 struct net_device *dev,
473 u32 offset
474 )
475{
476 u32 data = 0;
477
478#ifndef CONFIG_RTL8180_IO_MAP
479 data = read_nic_dword(dev, offset);
480
481#else // Port IO
482 u32 Page = (offset >> 8);
483
484 switch(Page)
485 {
486 case 0: // Page 0
487 data = read_nic_dword(dev, offset);
488 break;
489
490 case 1: // Page 1
491 case 2: // Page 2
492 case 3: // Page 3
493 {
494 u8 psr = read_nic_byte(dev, PSR);
495
496 write_nic_byte(dev, PSR, ((psr & 0xfc) | (u8)Page)); // Switch to page N.
497 data = read_nic_dword(dev, (offset & 0xff));
498 write_nic_byte(dev, PSR, (psr & 0xfc)); // Switch to page 0.
499 }
500 break;
501
502 default:
503 // Illegal page number.
504 DMESGE("PlatformIORead4Byte(): illegal page number: %d, offset: %#X\n", Page, offset);
505 break;
506 }
507#endif
508
509 return data;
510}
511
512void
513SetOutputEnableOfRfPins(
514 struct net_device *dev
515 )
516{
517 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
518
519 switch(priv->rf_chip)
520 {
521 case RFCHIPID_RTL8225:
522 case RF_ZEBRA2:
523 case RF_ZEBRA4:
524 write_nic_word(dev, RFPinsEnable, 0x1bff);
525 //write_nic_word(dev, RFPinsEnable, 0x1fff);
526 break;
527 }
528}
529
530void
531ZEBRA_RFSerialWrite(
532 struct net_device *dev,
533 u32 data2Write,
534 u8 totalLength,
535 u8 low2high
536 )
537{
538 ThreeWireReg twreg;
539 int i;
540 u16 oval,oval2,oval3;
541 u32 mask;
542 u16 UshortBuffer;
543
544 u8 u1bTmp;
545#ifdef CONFIG_RTL818X_S
546 // RTL8187S HSSI Read/Write Function
547 u1bTmp = read_nic_byte(dev, RF_SW_CONFIG);
548 u1bTmp |= RF_SW_CFG_SI; //reg08[1]=1 Serial Interface(SI)
549 write_nic_byte(dev, RF_SW_CONFIG, u1bTmp);
550#endif
551 UshortBuffer = read_nic_word(dev, RFPinsOutput);
552 oval = UshortBuffer & 0xfff8; // We shall clear bit0, 1, 2 first, 2005.10.28, by rcnjko.
553
554 oval2 = read_nic_word(dev, RFPinsEnable);
555 oval3 = read_nic_word(dev, RFPinsSelect);
556
557 // <RJ_NOTE> 3-wire should be controled by HW when we finish SW 3-wire programming. 2005.08.10, by rcnjko.
558 oval3 &= 0xfff8;
559
560 write_nic_word(dev, RFPinsEnable, (oval2|0x0007)); // Set To Output Enable
561 write_nic_word(dev, RFPinsSelect, (oval3|0x0007)); // Set To SW Switch
562 udelay(10);
563
564 // Add this to avoid hardware and software 3-wire conflict.
565 // 2005.03.01, by rcnjko.
566 twreg.longData = 0;
567 twreg.struc.enableB = 1;
568 write_nic_word(dev, RFPinsOutput, (twreg.longData|oval)); // Set SI_EN (RFLE)
569 udelay(2);
570 twreg.struc.enableB = 0;
571 write_nic_word(dev, RFPinsOutput, (twreg.longData|oval)); // Clear SI_EN (RFLE)
572 udelay(10);
573
574 mask = (low2high)?0x01:((u32)0x01<<(totalLength-1));
575
576 for(i=0; i<totalLength/2; i++)
577 {
578 twreg.struc.data = ((data2Write&mask)!=0) ? 1 : 0;
579 write_nic_word(dev, RFPinsOutput, (twreg.longData|oval));
580 twreg.struc.clk = 1;
581 write_nic_word(dev, RFPinsOutput, (twreg.longData|oval));
582 write_nic_word(dev, RFPinsOutput, (twreg.longData|oval));
583
584 mask = (low2high)?(mask<<1):(mask>>1);
585 twreg.struc.data = ((data2Write&mask)!=0) ? 1 : 0;
586 write_nic_word(dev, RFPinsOutput, (twreg.longData|oval));
587 write_nic_word(dev, RFPinsOutput, (twreg.longData|oval));
588 twreg.struc.clk = 0;
589 write_nic_word(dev, RFPinsOutput, (twreg.longData|oval));
590 mask = (low2high)?(mask<<1):(mask>>1);
591 }
592
593 twreg.struc.enableB = 1;
594 twreg.struc.clk = 0;
595 twreg.struc.data = 0;
596 write_nic_word(dev, RFPinsOutput, twreg.longData|oval);
597 udelay(10);
598
599 write_nic_word(dev, RFPinsOutput, oval|0x0004);
600 write_nic_word(dev, RFPinsSelect, oval3|0x0000);
601
602 SetOutputEnableOfRfPins(dev);
603}
604//by amy
605
606
607int
608HwHSSIThreeWire(
609 struct net_device *dev,
610 u8 *pDataBuf,
611 u8 nDataBufBitCnt,
612 int bSI,
613 int bWrite
614 )
615{
616 int bResult = 1;
617 u8 TryCnt;
618 u8 u1bTmp;
619
620 do
621 {
622 // Check if WE and RE are cleared.
623 for(TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++)
624 {
625 u1bTmp = read_nic_byte(dev, SW_3W_CMD1);
626 if( (u1bTmp & (SW_3W_CMD1_RE|SW_3W_CMD1_WE)) == 0 )
627 {
628 break;
629 }
630 udelay(10);
631 }
632 if (TryCnt == TC_3W_POLL_MAX_TRY_CNT)
633 panic("HwThreeWire(): CmdReg: %#X RE|WE bits are not clear!!\n", u1bTmp);
634
635 // RTL8187S HSSI Read/Write Function
636 u1bTmp = read_nic_byte(dev, RF_SW_CONFIG);
637
638 if(bSI)
639 {
640 u1bTmp |= RF_SW_CFG_SI; //reg08[1]=1 Serial Interface(SI)
641 }else
642 {
643 u1bTmp &= ~RF_SW_CFG_SI; //reg08[1]=0 Parallel Interface(PI)
644 }
645
646 write_nic_byte(dev, RF_SW_CONFIG, u1bTmp);
647
648 if(bSI)
649 {
650 // jong: HW SI read must set reg84[3]=0.
651 u1bTmp = read_nic_byte(dev, RFPinsSelect);
652 u1bTmp &= ~BIT3;
653 write_nic_byte(dev, RFPinsSelect, u1bTmp );
654 }
655 // Fill up data buffer for write operation.
656
657 if(bWrite)
658 {
659 if(nDataBufBitCnt == 16)
660 {
661 write_nic_word(dev, SW_3W_DB0, *((u16*)pDataBuf));
662 }
663 else if(nDataBufBitCnt == 64) // RTL8187S shouldn't enter this case
664 {
665 write_nic_dword(dev, SW_3W_DB0, *((u32*)pDataBuf));
666 write_nic_dword(dev, SW_3W_DB1, *((u32*)(pDataBuf + 4)));
667 }
668 else
669 {
670 int idx;
671 int ByteCnt = nDataBufBitCnt / 8;
672 //printk("%d\n",nDataBufBitCnt);
673 if ((nDataBufBitCnt % 8) != 0)
674 panic("HwThreeWire(): nDataBufBitCnt(%d) should be multiple of 8!!!\n",
675 nDataBufBitCnt);
676
677 if (nDataBufBitCnt > 64)
678 panic("HwThreeWire(): nDataBufBitCnt(%d) should <= 64!!!\n",
679 nDataBufBitCnt);
680
681 for(idx = 0; idx < ByteCnt; idx++)
682 {
683 write_nic_byte(dev, (SW_3W_DB0+idx), *(pDataBuf+idx));
684 }
685 }
686 }
687 else //read
688 {
689 if(bSI)
690 {
691 // SI - reg274[3:0] : RF register's Address
692 write_nic_word(dev, SW_3W_DB0, *((u16*)pDataBuf) );
693 }
694 else
695 {
696 // PI - reg274[15:12] : RF register's Address
697 write_nic_word(dev, SW_3W_DB0, (*((u16*)pDataBuf)) << 12);
698 }
699 }
700
701 // Set up command: WE or RE.
702 if(bWrite)
703 {
704 write_nic_byte(dev, SW_3W_CMD1, SW_3W_CMD1_WE);
705 }
706 else
707 {
708 write_nic_byte(dev, SW_3W_CMD1, SW_3W_CMD1_RE);
709 }
710
711 // Check if DONE is set.
712 for(TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++)
713 {
714 u1bTmp = read_nic_byte(dev, SW_3W_CMD1);
715 if( (u1bTmp & SW_3W_CMD1_DONE) != 0 )
716 {
717 break;
718 }
719 udelay(10);
720 }
721
722 write_nic_byte(dev, SW_3W_CMD1, 0);
723
724 // Read back data for read operation.
725 if(bWrite == 0)
726 {
727 if(bSI)
728 {
729 //Serial Interface : reg363_362[11:0]
730 *((u16*)pDataBuf) = read_nic_word(dev, SI_DATA_READ) ;
731 }
732 else
733 {
734 //Parallel Interface : reg361_360[11:0]
735 *((u16*)pDataBuf) = read_nic_word(dev, PI_DATA_READ);
736 }
737
738 *((u16*)pDataBuf) &= 0x0FFF;
739 }
740
741 }while(0);
742
743 return bResult;
744}
745//by amy
746
747int
748HwThreeWire(
749 struct net_device *dev,
750 u8 *pDataBuf,
751 u8 nDataBufBitCnt,
752 int bHold,
753 int bWrite
754 )
755{
756 int bResult = 1;
757 u8 TryCnt;
758 u8 u1bTmp;
759
760 do
761 {
762 // Check if WE and RE are cleared.
763 for(TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++)
764 {
765 u1bTmp = read_nic_byte(dev, SW_3W_CMD1);
766 if( (u1bTmp & (SW_3W_CMD1_RE|SW_3W_CMD1_WE)) == 0 )
767 {
768 break;
769 }
770 udelay(10);
771 }
772 if (TryCnt == TC_3W_POLL_MAX_TRY_CNT)
773 panic("HwThreeWire(): CmdReg: %#X RE|WE bits are not clear!!\n", u1bTmp);
774
775 // Fill up data buffer for write operation.
776 if(nDataBufBitCnt == 16)
777 {
778 write_nic_word(dev, SW_3W_DB0, *((u16 *)pDataBuf));
779 }
780 else if(nDataBufBitCnt == 64)
781 {
782 write_nic_dword(dev, SW_3W_DB0, *((u32 *)pDataBuf));
783 write_nic_dword(dev, SW_3W_DB1, *((u32 *)(pDataBuf + 4)));
784 }
785 else
786 {
787 int idx;
788 int ByteCnt = nDataBufBitCnt / 8;
789
790 if ((nDataBufBitCnt % 8) != 0)
791 panic("HwThreeWire(): nDataBufBitCnt(%d) should be multiple of 8!!!\n",
792 nDataBufBitCnt);
793
794 if (nDataBufBitCnt > 64)
795 panic("HwThreeWire(): nDataBufBitCnt(%d) should <= 64!!!\n",
796 nDataBufBitCnt);
797
798 for(idx = 0; idx < ByteCnt; idx++)
799 {
800 write_nic_byte(dev, (SW_3W_DB0+idx), *(pDataBuf+idx));
801 }
802 }
803
804 // Fill up length field.
805 u1bTmp = (u8)(nDataBufBitCnt - 1); // Number of bits - 1.
806 if(bHold)
807 u1bTmp |= SW_3W_CMD0_HOLD;
808 write_nic_byte(dev, SW_3W_CMD0, u1bTmp);
809
810 // Set up command: WE or RE.
811 if(bWrite)
812 {
813 write_nic_byte(dev, SW_3W_CMD1, SW_3W_CMD1_WE);
814 }
815 else
816 {
817 write_nic_byte(dev, SW_3W_CMD1, SW_3W_CMD1_RE);
818 }
819
820 // Check if WE and RE are cleared and DONE is set.
821 for(TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++)
822 {
823 u1bTmp = read_nic_byte(dev, SW_3W_CMD1);
824 if( (u1bTmp & (SW_3W_CMD1_RE|SW_3W_CMD1_WE)) == 0 &&
825 (u1bTmp & SW_3W_CMD1_DONE) != 0 )
826 {
827 break;
828 }
829 udelay(10);
830 }
831 if(TryCnt == TC_3W_POLL_MAX_TRY_CNT)
832 {
833 //RT_ASSERT(TryCnt != TC_3W_POLL_MAX_TRY_CNT,
834 // ("HwThreeWire(): CmdReg: %#X RE|WE bits are not clear or DONE is not set!!\n", u1bTmp));
835 // Workaround suggested by wcchu: clear WE here. 2006.07.07, by rcnjko.
836 write_nic_byte(dev, SW_3W_CMD1, 0);
837 }
838
839 // Read back data for read operation.
840 // <RJ_TODO> I am not sure if this is correct output format of a read operation.
841 if(bWrite == 0)
842 {
843 if(nDataBufBitCnt == 16)
844 {
845 *((u16 *)pDataBuf) = read_nic_word(dev, SW_3W_DB0);
846 }
847 else if(nDataBufBitCnt == 64)
848 {
849 *((u32 *)pDataBuf) = read_nic_dword(dev, SW_3W_DB0);
850 *((u32 *)(pDataBuf + 4)) = read_nic_dword(dev, SW_3W_DB1);
851 }
852 else
853 {
854 int idx;
855 int ByteCnt = nDataBufBitCnt / 8;
856
857 if ((nDataBufBitCnt % 8) != 0)
858 panic("HwThreeWire(): nDataBufBitCnt(%d) should be multiple of 8!!!\n",
859 nDataBufBitCnt);
860
861 if (nDataBufBitCnt > 64)
862 panic("HwThreeWire(): nDataBufBitCnt(%d) should <= 64!!!\n",
863 nDataBufBitCnt);
864
865 for(idx = 0; idx < ByteCnt; idx++)
866 {
867 *(pDataBuf+idx) = read_nic_byte(dev, (SW_3W_DB0+idx));
868 }
869 }
870 }
871
872 }while(0);
873
874 return bResult;
875}
876
877
878void
879RF_WriteReg(
880 struct net_device *dev,
881 u8 offset,
882 u32 data
883 )
884{
885 //RFReg reg;
886 u32 data2Write;
887 u8 len;
888 u8 low2high;
889 //u32 RF_Read = 0;
890 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
891
892
893 switch(priv->rf_chip)
894 {
895 case RFCHIPID_RTL8225:
896 case RF_ZEBRA2: // Annie 2006-05-12.
897 case RF_ZEBRA4: //by amy
898 switch(priv->RegThreeWireMode)
899 {
900 case SW_THREE_WIRE:
901 { // Perform SW 3-wire programming by driver.
902 data2Write = (data << 4) | (u32)(offset & 0x0f);
903 len = 16;
904 low2high = 0;
905 ZEBRA_RFSerialWrite(dev, data2Write, len, low2high);
906 }
907 break;
908
909 case HW_THREE_WIRE:
910 { // Pure HW 3-wire.
911 data2Write = (data << 4) | (u32)(offset & 0x0f);
912 len = 16;
913 HwThreeWire(
914 dev,
915 (u8 *)(&data2Write), // pDataBuf,
916 len, // nDataBufBitCnt,
917 0, // bHold,
918 1); // bWrite
919 }
920 break;
921 #ifdef CONFIG_RTL818X_S
922 case HW_THREE_WIRE_PI: //Parallel Interface
923 { // Pure HW 3-wire.
924 data2Write = (data << 4) | (u32)(offset & 0x0f);
925 len = 16;
926 HwHSSIThreeWire(
927 dev,
928 (u8*)(&data2Write), // pDataBuf,
929 len, // nDataBufBitCnt,
930 0, // bSI
931 1); // bWrite
932
933 //printk("33333\n");
934 }
935 break;
936
937 case HW_THREE_WIRE_SI: //Serial Interface
938 { // Pure HW 3-wire.
939 data2Write = (data << 4) | (u32)(offset & 0x0f);
940 len = 16;
941// printk(" enter ZEBRA_RFSerialWrite\n ");
942// low2high = 0;
943// ZEBRA_RFSerialWrite(dev, data2Write, len, low2high);
944
945 HwHSSIThreeWire(
946 dev,
947 (u8*)(&data2Write), // pDataBuf,
948 len, // nDataBufBitCnt,
949 1, // bSI
950 1); // bWrite
951
952// printk(" exit ZEBRA_RFSerialWrite\n ");
953 }
954 break;
955 #endif
956
957
958 default:
959 DMESGE("RF_WriteReg(): invalid RegThreeWireMode(%d) !!!", priv->RegThreeWireMode);
960 break;
961 }
962 break;
963
964 default:
965 DMESGE("RF_WriteReg(): unknown RFChipID: %#X", priv->rf_chip);
966 break;
967 }
968}
969
970
971void
972ZEBRA_RFSerialRead(
973 struct net_device *dev,
974 u32 data2Write,
975 u8 wLength,
976 u32 *data2Read,
977 u8 rLength,
978 u8 low2high
979 )
980{
981 ThreeWireReg twreg;
982 int i;
983 u16 oval,oval2,oval3,tmp, wReg80;
984 u32 mask;
985 u8 u1bTmp;
986 ThreeWireReg tdata;
987 //PHAL_DATA_8187 pHalData = GetHalData8187(pAdapter);
988#ifdef CONFIG_RTL818X_S
989 { // RTL8187S HSSI Read/Write Function
990 u1bTmp = read_nic_byte(dev, RF_SW_CONFIG);
991 u1bTmp |= RF_SW_CFG_SI; //reg08[1]=1 Serial Interface(SI)
992 write_nic_byte(dev, RF_SW_CONFIG, u1bTmp);
993 }
994#endif
995
996 wReg80 = oval = read_nic_word(dev, RFPinsOutput);
997 oval2 = read_nic_word(dev, RFPinsEnable);
998 oval3 = read_nic_word(dev, RFPinsSelect);
999
1000 write_nic_word(dev, RFPinsEnable, oval2|0xf);
1001 write_nic_word(dev, RFPinsSelect, oval3|0xf);
1002
1003 *data2Read = 0;
1004
1005 // We must clear BIT0-3 here, otherwise,
1006 // SW_Enalbe will be true when we first call ZEBRA_RFSerialRead() after 8187MPVC open,
1007 // which will cause the value read become 0. 2005.04.11, by rcnjko.
1008 oval &= ~0xf;
1009
1010 // Avoid collision with hardware three-wire.
1011 twreg.longData = 0;
1012 twreg.struc.enableB = 1;
1013 write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(4);
1014
1015 twreg.longData = 0;
1016 twreg.struc.enableB = 0;
1017 twreg.struc.clk = 0;
1018 twreg.struc.read_write = 0;
1019 write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(5);
1020
1021 mask = (low2high) ? 0x01 : ((u32)0x01<<(32-1));
1022 for(i = 0; i < wLength/2; i++)
1023 {
1024 twreg.struc.data = ((data2Write&mask) != 0) ? 1 : 0;
1025 write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(1);
1026 twreg.struc.clk = 1;
1027 write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
1028 write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
1029
1030 mask = (low2high) ? (mask<<1): (mask>>1);
1031
1032 if(i == 2)
1033 {
1034 // Commented out by Jackie, 2004.08.26. <RJ_NOTE> We must comment out the following two lines for we cannot pull down VCOPDN during RF Serail Read.
1035 //PlatformEFIOWrite2Byte(pAdapter, RFPinsEnable, 0xe); // turn off data enable
1036 //PlatformEFIOWrite2Byte(pAdapter, RFPinsSelect, 0xe);
1037
1038 twreg.struc.read_write=1;
1039 write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
1040 twreg.struc.clk = 0;
1041 write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
1042 break;
1043 }
1044 twreg.struc.data = ((data2Write&mask) != 0) ? 1: 0;
1045 write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
1046 write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
1047
1048 twreg.struc.clk = 0;
1049 write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(1);
1050
1051 mask = (low2high) ? (mask<<1) : (mask>>1);
1052 }
1053
1054 twreg.struc.clk = 0;
1055 twreg.struc.data = 0;
1056 write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
1057 mask = (low2high) ? 0x01 : ((u32)0x01 << (12-1));
1058
1059 //
1060 // 061016, by rcnjko:
1061 // We must set data pin to HW controled, otherwise RF can't driver it and
1062 // value RF register won't be able to read back properly.
1063 //
1064 write_nic_word(dev, RFPinsEnable, ( ((oval2|0x0E) & (~0x01))) );
1065
1066 for(i = 0; i < rLength; i++)
1067 {
1068 write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(1);
1069 twreg.struc.clk = 1;
1070 write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
1071 write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
1072 write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
1073 tmp = read_nic_word(dev, RFPinsInput);
1074 tdata.longData = tmp;
1075 *data2Read |= tdata.struc.clk ? mask : 0;
1076
1077 twreg.struc.clk = 0;
1078 write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
1079
1080 mask = (low2high) ? (mask<<1) : (mask>>1);
1081 }
1082 twreg.struc.enableB = 1;
1083 twreg.struc.clk = 0;
1084 twreg.struc.data = 0;
1085 twreg.struc.read_write = 1;
1086 write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
1087
1088 //PlatformEFIOWrite2Byte(pAdapter, RFPinsEnable, oval2|0x8); // Set To Output Enable
1089 write_nic_word(dev, RFPinsEnable, oval2); // Set To Output Enable, <RJ_NOTE> We cannot enable BIT3 here, otherwise, we will failed to switch channel. 2005.04.12.
1090 //PlatformEFIOWrite2Byte(pAdapter, RFPinsEnable, 0x1bff);
1091 write_nic_word(dev, RFPinsSelect, oval3); // Set To SW Switch
1092 //PlatformEFIOWrite2Byte(pAdapter, RFPinsSelect, 0x0488);
1093 write_nic_word(dev, RFPinsOutput, 0x3a0);
1094 //PlatformEFIOWrite2Byte(pAdapter, RFPinsOutput, 0x0480);
1095}
1096
1097
1098u32
1099RF_ReadReg(
1100 struct net_device *dev,
1101 u8 offset
1102 )
1103{
1104 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1105 u32 data2Write;
1106 u8 wlen;
1107 u8 rlen;
1108 u8 low2high;
1109 u32 dataRead;
1110
1111 switch(priv->rf_chip)
1112 {
1113 case RFCHIPID_RTL8225:
1114 case RF_ZEBRA2:
1115 case RF_ZEBRA4:
1116 switch(priv->RegThreeWireMode)
1117 {
1118#ifdef CONFIG_RTL818X_S
1119 case HW_THREE_WIRE_PI: // For 87S Parallel Interface.
1120 {
1121 data2Write = ((u32)(offset&0x0f));
1122 wlen=16;
1123 HwHSSIThreeWire(
1124 dev,
1125 (u8*)(&data2Write), // pDataBuf,
1126 wlen, // nDataBufBitCnt,
1127 0, // bSI
1128 0); // bWrite
1129 dataRead= data2Write;
1130 }
1131 break;
1132
1133 case HW_THREE_WIRE_SI: // For 87S Serial Interface.
1134 {
1135 data2Write = ((u32)(offset&0x0f)) ;
1136 wlen=16;
1137 HwHSSIThreeWire(
1138 dev,
1139 (u8*)(&data2Write), // pDataBuf,
1140 wlen, // nDataBufBitCnt,
1141 1, // bSI
1142 0 // bWrite
1143 );
1144 dataRead= data2Write;
1145 }
1146 break;
1147
1148#endif
1149 // Perform SW 3-wire programming by driver.
1150 default:
1151 {
1152 data2Write = ((u32)(offset&0x1f)) << 27; // For Zebra E-cut. 2005.04.11, by rcnjko.
1153 wlen = 6;
1154 rlen = 12;
1155 low2high = 0;
1156 ZEBRA_RFSerialRead(dev, data2Write, wlen,&dataRead,rlen, low2high);
1157 }
1158 break;
1159 }
1160 break;
1161 default:
1162 dataRead = 0;
1163 break;
1164 }
1165
1166 return dataRead;
1167}
1168
1169
1170// by Owen on 04/07/14 for writing BB register successfully
1171void
1172WriteBBPortUchar(
1173 struct net_device *dev,
1174 u32 Data
1175 )
1176{
1177 //u8 TimeoutCounter;
1178 u8 RegisterContent;
1179 u8 UCharData;
1180
1181 UCharData = (u8)((Data & 0x0000ff00) >> 8);
1182 PlatformIOWrite4Byte(dev, PhyAddr, Data);
1183 //for(TimeoutCounter = 10; TimeoutCounter > 0; TimeoutCounter--)
1184 {
1185 PlatformIOWrite4Byte(dev, PhyAddr, Data & 0xffffff7f);
1186 RegisterContent = PlatformIORead1Byte(dev, PhyDataR);
1187 //if(UCharData == RegisterContent)
1188 // break;
1189 }
1190}
1191
1192u8
1193ReadBBPortUchar(
1194 struct net_device *dev,
1195 u32 addr
1196 )
1197{
1198 //u8 TimeoutCounter;
1199 u8 RegisterContent;
1200
1201 PlatformIOWrite4Byte(dev, PhyAddr, addr & 0xffffff7f);
1202 RegisterContent = PlatformIORead1Byte(dev, PhyDataR);
1203
1204 return RegisterContent;
1205}
1206//{by amy 080312
1207#ifdef CONFIG_RTL818X_S
1208//
1209// Description:
1210// Perform Antenna settings with antenna diversity on 87SE.
1211// Created by Roger, 2008.01.25.
1212//
1213bool
1214SetAntennaConfig87SE(
1215 struct net_device *dev,
1216 u8 DefaultAnt, // 0: Main, 1: Aux.
1217 bool bAntDiversity // 1:Enable, 0: Disable.
1218)
1219{
1220 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1221 bool bAntennaSwitched = true;
1222
1223 //printk("SetAntennaConfig87SE(): DefaultAnt(%d), bAntDiversity(%d)\n", DefaultAnt, bAntDiversity);
1224
1225 // Threshold for antenna diversity.
1226 write_phy_cck(dev, 0x0c, 0x09); // Reg0c : 09
1227
1228 if( bAntDiversity ) // Enable Antenna Diversity.
1229 {
1230 if( DefaultAnt == 1 ) // aux antenna
1231 {
1232 // Mac register, aux antenna
1233 write_nic_byte(dev, ANTSEL, 0x00);
1234
1235 // Config CCK RX antenna.
1236 write_phy_cck(dev, 0x11, 0xbb); // Reg11 : bb
1237 write_phy_cck(dev, 0x01, 0xc7); // Reg01 : c7
1238
1239 // Config OFDM RX antenna.
1240 write_phy_ofdm(dev, 0x0D, 0x54); // Reg0d : 54
1241 write_phy_ofdm(dev, 0x18, 0xb2); // Reg18 : b2
1242 }
1243 else // use main antenna
1244 {
1245 // Mac register, main antenna
1246 write_nic_byte(dev, ANTSEL, 0x03);
1247 //base band
1248 // Config CCK RX antenna.
1249 write_phy_cck(dev, 0x11, 0x9b); // Reg11 : 9b
1250 write_phy_cck(dev, 0x01, 0xc7); // Reg01 : c7
1251
1252 // Config OFDM RX antenna.
1253 write_phy_ofdm(dev, 0x0d, 0x5c); // Reg0d : 5c
1254 write_phy_ofdm(dev, 0x18, 0xb2); // Reg18 : b2
1255 }
1256 }
1257 else // Disable Antenna Diversity.
1258 {
1259 if( DefaultAnt == 1 ) // aux Antenna
1260 {
1261 // Mac register, aux antenna
1262 write_nic_byte(dev, ANTSEL, 0x00);
1263
1264 // Config CCK RX antenna.
1265 write_phy_cck(dev, 0x11, 0xbb); // Reg11 : bb
1266 write_phy_cck(dev, 0x01, 0x47); // Reg01 : 47
1267
1268 // Config OFDM RX antenna.
1269 write_phy_ofdm(dev, 0x0D, 0x54); // Reg0d : 54
1270 write_phy_ofdm(dev, 0x18, 0x32); // Reg18 : 32
1271 }
1272 else // main Antenna
1273 {
1274 // Mac register, main antenna
1275 write_nic_byte(dev, ANTSEL, 0x03);
1276
1277 // Config CCK RX antenna.
1278 write_phy_cck(dev, 0x11, 0x9b); // Reg11 : 9b
1279 write_phy_cck(dev, 0x01, 0x47); // Reg01 : 47
1280
1281 // Config OFDM RX antenna.
1282 write_phy_ofdm(dev, 0x0D, 0x5c); // Reg0d : 5c
1283 write_phy_ofdm(dev, 0x18, 0x32); // Reg18 : 32
1284 }
1285 }
1286 priv->CurrAntennaIndex = DefaultAnt; // Update default settings.
1287 return bAntennaSwitched;
1288}
1289#endif
1290//by amy 080312
1291/*---------------------------------------------------------------
1292 * Hardware Initialization.
1293 * the code is ported from Windows source code
1294 ----------------------------------------------------------------*/
1295
1296void
1297ZEBRA_Config_85BASIC_HardCode(
1298 struct net_device *dev
1299 )
1300{
1301
1302 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1303 u32 i;
1304 u32 addr,data;
1305 u32 u4bRegOffset, u4bRegValue, u4bRF23, u4bRF24;
1306 u8 u1b24E;
1307
1308#ifdef CONFIG_RTL818X_S
1309
1310 //=============================================================================
1311 // 87S_PCIE :: RADIOCFG.TXT
1312 //=============================================================================
1313
1314
1315 // Page1 : reg16-reg30
1316 RF_WriteReg(dev, 0x00, 0x013f); mdelay(1); // switch to page1
1317 u4bRF23= RF_ReadReg(dev, 0x08); mdelay(1);
1318 u4bRF24= RF_ReadReg(dev, 0x09); mdelay(1);
1319
1320 if (u4bRF23==0x818 && u4bRF24==0x70C && priv->card_8185 == VERSION_8187S_C)
1321 priv->card_8185 = VERSION_8187S_D;
1322
1323 // Page0 : reg0-reg15
1324
1325// RF_WriteReg(dev, 0x00, 0x003f); mdelay(1);//1
1326 RF_WriteReg(dev, 0x00, 0x009f); mdelay(1);// 1
1327
1328 RF_WriteReg(dev, 0x01, 0x06e0); mdelay(1);
1329
1330// RF_WriteReg(dev, 0x02, 0x004c); mdelay(1);//2
1331 RF_WriteReg(dev, 0x02, 0x004d); mdelay(1);// 2
1332
1333// RF_WriteReg(dev, 0x03, 0x0000); mdelay(1);//3
1334 RF_WriteReg(dev, 0x03, 0x07f1); mdelay(1);// 3
1335
1336 RF_WriteReg(dev, 0x04, 0x0975); mdelay(1);
1337 RF_WriteReg(dev, 0x05, 0x0c72); mdelay(1);
1338 RF_WriteReg(dev, 0x06, 0x0ae6); mdelay(1);
1339 RF_WriteReg(dev, 0x07, 0x00ca); mdelay(1);
1340 RF_WriteReg(dev, 0x08, 0x0e1c); mdelay(1);
1341 RF_WriteReg(dev, 0x09, 0x02f0); mdelay(1);
1342 RF_WriteReg(dev, 0x0a, 0x09d0); mdelay(1);
1343 RF_WriteReg(dev, 0x0b, 0x01ba); mdelay(1);
1344 RF_WriteReg(dev, 0x0c, 0x0640); mdelay(1);
1345 RF_WriteReg(dev, 0x0d, 0x08df); mdelay(1);
1346 RF_WriteReg(dev, 0x0e, 0x0020); mdelay(1);
1347 RF_WriteReg(dev, 0x0f, 0x0990); mdelay(1);
1348
1349
1350 // Page1 : reg16-reg30
1351 RF_WriteReg(dev, 0x00, 0x013f); mdelay(1);
1352
1353 RF_WriteReg(dev, 0x03, 0x0806); mdelay(1);
1354
1355 if(priv->card_8185 < VERSION_8187S_C)
1356 {
1357 RF_WriteReg(dev, 0x04, 0x03f7); mdelay(1);
1358 RF_WriteReg(dev, 0x05, 0x05ab); mdelay(1);
1359 RF_WriteReg(dev, 0x06, 0x00c1); mdelay(1);
1360 }
1361 else
1362 {
1363 RF_WriteReg(dev, 0x04, 0x03a7); mdelay(1);
1364 RF_WriteReg(dev, 0x05, 0x059b); mdelay(1);
1365 RF_WriteReg(dev, 0x06, 0x0081); mdelay(1);
1366 }
1367
1368
1369 RF_WriteReg(dev, 0x07, 0x01A0); mdelay(1);
1370// Don't write RF23/RF24 to make a difference between 87S C cut and D cut. asked by SD3 stevenl.
1371// RF_WriteReg(dev, 0x08, 0x0597); mdelay(1);
1372// RF_WriteReg(dev, 0x09, 0x050a); mdelay(1);
1373 RF_WriteReg(dev, 0x0a, 0x0001); mdelay(1);
1374 RF_WriteReg(dev, 0x0b, 0x0418); mdelay(1);
1375
1376 if(priv->card_8185 == VERSION_8187S_D)
1377 {
1378 RF_WriteReg(dev, 0x0c, 0x0fbe); mdelay(1);
1379 RF_WriteReg(dev, 0x0d, 0x0008); mdelay(1);
1380 RF_WriteReg(dev, 0x0e, 0x0807); mdelay(1); // RX LO buffer
1381 }
1382 else
1383 {
1384 RF_WriteReg(dev, 0x0c, 0x0fbe); mdelay(1);
1385 RF_WriteReg(dev, 0x0d, 0x0008); mdelay(1);
1386 RF_WriteReg(dev, 0x0e, 0x0806); mdelay(1); // RX LO buffer
1387 }
1388
1389 RF_WriteReg(dev, 0x0f, 0x0acc); mdelay(1);
1390
1391// RF_WriteReg(dev, 0x00, 0x017f); mdelay(1);//6
1392 RF_WriteReg(dev, 0x00, 0x01d7); mdelay(1);// 6
1393
1394 RF_WriteReg(dev, 0x03, 0x0e00); mdelay(1);
1395 RF_WriteReg(dev, 0x04, 0x0e50); mdelay(1);
1396 for(i=0;i<=36;i++)
1397 {
1398 RF_WriteReg(dev, 0x01, i); mdelay(1);
1399 RF_WriteReg(dev, 0x02, ZEBRA_RF_RX_GAIN_TABLE[i]); mdelay(1);
1400 //DbgPrint("RF - 0x%x = 0x%x", i, ZEBRA_RF_RX_GAIN_TABLE[i]);
1401 }
1402
1403 RF_WriteReg(dev, 0x05, 0x0203); mdelay(1); /// 203, 343
1404 //RF_WriteReg(dev, 0x06, 0x0300); mdelay(1); // 400
1405 RF_WriteReg(dev, 0x06, 0x0200); mdelay(1); // 400
1406
1407 RF_WriteReg(dev, 0x00, 0x0137); mdelay(1); // switch to reg16-reg30, and HSSI disable 137
1408 mdelay(10); // Deay 10 ms. //0xfd
1409
1410// RF_WriteReg(dev, 0x0c, 0x09be); mdelay(1); // 7
1411 //RF_WriteReg(dev, 0x0c, 0x07be); mdelay(1);
1412 //mdelay(10); // Deay 10 ms. //0xfd
1413
1414 RF_WriteReg(dev, 0x0d, 0x0008); mdelay(1); // Z4 synthesizer loop filter setting, 392
1415 mdelay(10); // Deay 10 ms. //0xfd
1416
1417 RF_WriteReg(dev, 0x00, 0x0037); mdelay(1); // switch to reg0-reg15, and HSSI disable
1418 mdelay(10); // Deay 10 ms. //0xfd
1419
1420 RF_WriteReg(dev, 0x04, 0x0160); mdelay(1); // CBC on, Tx Rx disable, High gain
1421 mdelay(10); // Deay 10 ms. //0xfd
1422
1423 RF_WriteReg(dev, 0x07, 0x0080); mdelay(1); // Z4 setted channel 1
1424 mdelay(10); // Deay 10 ms. //0xfd
1425
1426 RF_WriteReg(dev, 0x02, 0x088D); mdelay(1); // LC calibration
1427 mdelay(200); // Deay 200 ms. //0xfd
1428 mdelay(10); // Deay 10 ms. //0xfd
1429 mdelay(10); // Deay 10 ms. //0xfd
1430
1431 RF_WriteReg(dev, 0x00, 0x0137); mdelay(1); // switch to reg16-reg30 137, and HSSI disable 137
1432 mdelay(10); // Deay 10 ms. //0xfd
1433
1434 RF_WriteReg(dev, 0x07, 0x0000); mdelay(1);
1435 RF_WriteReg(dev, 0x07, 0x0180); mdelay(1);
1436 RF_WriteReg(dev, 0x07, 0x0220); mdelay(1);
1437 RF_WriteReg(dev, 0x07, 0x03E0); mdelay(1);
1438
1439 // DAC calibration off 20070702
1440 RF_WriteReg(dev, 0x06, 0x00c1); mdelay(1);
1441 RF_WriteReg(dev, 0x0a, 0x0001); mdelay(1);
1442//{by amy 080312
1443 // For crystal calibration, added by Roger, 2007.12.11.
1444 if( priv->bXtalCalibration ) // reg 30.
1445 { // enable crystal calibration.
1446 // RF Reg[30], (1)Xin:[12:9], Xout:[8:5], addr[4:0].
1447 // (2)PA Pwr delay timer[15:14], default: 2.4us, set BIT15=0
1448 // (3)RF signal on/off when calibration[13], default: on, set BIT13=0.
1449 // So we should minus 4 BITs offset.
1450 RF_WriteReg(dev, 0x0f, (priv->XtalCal_Xin<<5)|(priv->XtalCal_Xout<<1)|BIT11|BIT9); mdelay(1);
1451 printk("ZEBRA_Config_85BASIC_HardCode(): (%02x)\n",
1452 (priv->XtalCal_Xin<<5) | (priv->XtalCal_Xout<<1) | BIT11| BIT9);
1453 }
1454 else
1455 { // using default value. Xin=6, Xout=6.
1456 RF_WriteReg(dev, 0x0f, 0x0acc); mdelay(1);
1457 }
1458//by amy 080312
1459// RF_WriteReg(dev, 0x0f, 0x0acc); mdelay(1); //-by amy 080312
1460
1461 RF_WriteReg(dev, 0x00, 0x00bf); mdelay(1); // switch to reg0-reg15, and HSSI enable
1462// RF_WriteReg(dev, 0x0d, 0x009f); mdelay(1); // Rx BB start calibration, 00c//-edward
1463 RF_WriteReg(dev, 0x0d, 0x08df); mdelay(1); // Rx BB start calibration, 00c//+edward
1464 RF_WriteReg(dev, 0x02, 0x004d); mdelay(1); // temperature meter off
1465 RF_WriteReg(dev, 0x04, 0x0975); mdelay(1); // Rx mode
1466 mdelay(10); // Deay 10 ms. //0xfe
1467 mdelay(10); // Deay 10 ms. //0xfe
1468 mdelay(10); // Deay 10 ms. //0xfe
1469 RF_WriteReg(dev, 0x00, 0x0197); mdelay(1); // Rx mode//+edward
1470 RF_WriteReg(dev, 0x05, 0x05ab); mdelay(1); // Rx mode//+edward
1471 RF_WriteReg(dev, 0x00, 0x009f); mdelay(1); // Rx mode//+edward
1472
1473#if 0//-edward
1474 RF_WriteReg(dev, 0x00, 0x0197); mdelay(1);
1475 RF_WriteReg(dev, 0x05, 0x05ab); mdelay(1);
1476 RF_WriteReg(dev, 0x00, 0x009F); mdelay(1);
1477#endif
1478 RF_WriteReg(dev, 0x01, 0x0000); mdelay(1); // Rx mode//+edward
1479 RF_WriteReg(dev, 0x02, 0x0000); mdelay(1); // Rx mode//+edward
1480 //power save parameters.
1481 u1b24E = read_nic_byte(dev, 0x24E);
1482 write_nic_byte(dev, 0x24E, (u1b24E & (~(BIT5|BIT6))));
1483
1484 //=============================================================================
1485
1486 //=============================================================================
1487 // CCKCONF.TXT
1488 //=============================================================================
1489
1490 /* [POWER SAVE] Power Saving Parameters by jong. 2007-11-27
1491 CCK reg0x00[7]=1'b1 :power saving for TX (default)
1492 CCK reg0x00[6]=1'b1: power saving for RX (default)
1493 CCK reg0x06[4]=1'b1: turn off channel estimation related circuits if not doing channel estimation.
1494 CCK reg0x06[3]=1'b1: turn off unused circuits before cca = 1
1495 CCK reg0x06[2]=1'b1: turn off cck's circuit if macrst =0
1496 */
1497#if 0
1498 write_nic_dword(dev, PHY_ADR, 0x0100c880);
1499 write_nic_dword(dev, PHY_ADR, 0x01001c86);
1500 write_nic_dword(dev, PHY_ADR, 0x01007890);
1501 write_nic_dword(dev, PHY_ADR, 0x0100d0ae);
1502 write_nic_dword(dev, PHY_ADR, 0x010006af);
1503 write_nic_dword(dev, PHY_ADR, 0x01004681);
1504#endif
1505 write_phy_cck(dev,0x00,0xc8);
1506 write_phy_cck(dev,0x06,0x1c);
1507 write_phy_cck(dev,0x10,0x78);
1508 write_phy_cck(dev,0x2e,0xd0);
1509 write_phy_cck(dev,0x2f,0x06);
1510 write_phy_cck(dev,0x01,0x46);
1511
1512 // power control
1513 write_nic_byte(dev, CCK_TXAGC, 0x10);
1514 write_nic_byte(dev, OFDM_TXAGC, 0x1B);
1515 write_nic_byte(dev, ANTSEL, 0x03);
1516#else
1517 //=============================================================================
1518 // RADIOCFG.TXT
1519 //=============================================================================
1520
1521 RF_WriteReg(dev, 0x00, 0x00b7); mdelay(1);
1522 RF_WriteReg(dev, 0x01, 0x0ee0); mdelay(1);
1523 RF_WriteReg(dev, 0x02, 0x044d); mdelay(1);
1524 RF_WriteReg(dev, 0x03, 0x0441); mdelay(1);
1525 RF_WriteReg(dev, 0x04, 0x08c3); mdelay(1);
1526 RF_WriteReg(dev, 0x05, 0x0c72); mdelay(1);
1527 RF_WriteReg(dev, 0x06, 0x00e6); mdelay(1);
1528 RF_WriteReg(dev, 0x07, 0x082a); mdelay(1);
1529 RF_WriteReg(dev, 0x08, 0x003f); mdelay(1);
1530 RF_WriteReg(dev, 0x09, 0x0335); mdelay(1);
1531 RF_WriteReg(dev, 0x0a, 0x09d4); mdelay(1);
1532 RF_WriteReg(dev, 0x0b, 0x07bb); mdelay(1);
1533 RF_WriteReg(dev, 0x0c, 0x0850); mdelay(1);
1534 RF_WriteReg(dev, 0x0d, 0x0cdf); mdelay(1);
1535 RF_WriteReg(dev, 0x0e, 0x002b); mdelay(1);
1536 RF_WriteReg(dev, 0x0f, 0x0114); mdelay(1);
1537
1538 RF_WriteReg(dev, 0x00, 0x01b7); mdelay(1);
1539
1540
1541 for(i=1;i<=95;i++)
1542 {
1543 RF_WriteReg(dev, 0x01, i); mdelay(1);
1544 RF_WriteReg(dev, 0x02, ZEBRA_RF_RX_GAIN_TABLE[i]); mdelay(1);
1545 //DbgPrint("RF - 0x%x = 0x%x", i, ZEBRA_RF_RX_GAIN_TABLE[i]);
1546 }
1547
1548 RF_WriteReg(dev, 0x03, 0x0080); mdelay(1); // write reg 18
1549 RF_WriteReg(dev, 0x05, 0x0004); mdelay(1); // write reg 20
1550 RF_WriteReg(dev, 0x00, 0x00b7); mdelay(1); // switch to reg0-reg15
1551 //0xfd
1552 //0xfd
1553 //0xfd
1554 RF_WriteReg(dev, 0x02, 0x0c4d); mdelay(1);
1555 mdelay(100); // Deay 100 ms. //0xfe
1556 mdelay(100); // Deay 100 ms. //0xfe
1557 RF_WriteReg(dev, 0x02, 0x044d); mdelay(1);
1558 RF_WriteReg(dev, 0x00, 0x02bf); mdelay(1); //0x002f disable 6us corner change, 06f--> enable
1559
1560 //=============================================================================
1561
1562 //=============================================================================
1563 // CCKCONF.TXT
1564 //=============================================================================
1565
1566 //=============================================================================
1567
1568 //=============================================================================
1569 // Follow WMAC RTL8225_Config()
1570 //=============================================================================
1571
1572 // power control
1573 write_nic_byte(dev, CCK_TXAGC, 0x03);
1574 write_nic_byte(dev, OFDM_TXAGC, 0x07);
1575 write_nic_byte(dev, ANTSEL, 0x03);
1576
1577 //=============================================================================
1578
1579 // OFDM BBP setup
1580// SetOutputEnableOfRfPins(dev);//by amy
1581#endif
1582
1583
1584
1585 //=============================================================================
1586 // AGC.txt
1587 //=============================================================================
1588
1589// PlatformIOWrite4Byte( dev, PhyAddr, 0x00001280); // Annie, 2006-05-05
1590 write_phy_ofdm(dev, 0x00, 0x12);
1591 //WriteBBPortUchar(dev, 0x00001280);
1592
1593 for (i=0; i<128; i++)
1594 {
1595 //DbgPrint("AGC - [%x+1] = 0x%x\n", i, ZEBRA_AGC[i+1]);
1596
1597 data = ZEBRA_AGC[i+1];
1598 data = data << 8;
1599 data = data | 0x0000008F;
1600
1601 addr = i + 0x80; //enable writing AGC table
1602 addr = addr << 8;
1603 addr = addr | 0x0000008E;
1604
1605 WriteBBPortUchar(dev, data);
1606 WriteBBPortUchar(dev, addr);
1607 WriteBBPortUchar(dev, 0x0000008E);
1608 }
1609
1610 PlatformIOWrite4Byte( dev, PhyAddr, 0x00001080); // Annie, 2006-05-05
1611 //WriteBBPortUchar(dev, 0x00001080);
1612
1613 //=============================================================================
1614
1615 //=============================================================================
1616 // OFDMCONF.TXT
1617 //=============================================================================
1618
1619 for(i=0; i<60; i++)
1620 {
1621 u4bRegOffset=i;
1622 u4bRegValue=OFDM_CONFIG[i];
1623
1624 //DbgPrint("OFDM - 0x%x = 0x%x\n", u4bRegOffset, u4bRegValue);
1625
1626 WriteBBPortUchar(dev,
1627 (0x00000080 |
1628 (u4bRegOffset & 0x7f) |
1629 ((u4bRegValue & 0xff) << 8)));
1630 }
1631
1632 //=============================================================================
1633//by amy for antenna
1634 //=============================================================================
1635//{by amy 080312
1636#ifdef CONFIG_RTL818X_S
1637 // Config Sw/Hw Combinational Antenna Diversity. Added by Roger, 2008.02.26.
1638 SetAntennaConfig87SE(dev, priv->bDefaultAntenna1, priv->bSwAntennaDiverity);
1639#endif
1640//by amy 080312}
1641#if 0
1642 // Config Sw/Hw Antenna Diversity
1643 if( priv->bSwAntennaDiverity ) // Use SW+Hw Antenna Diversity
1644 {
1645 if( priv->bDefaultAntenna1 == true ) // aux antenna
1646 {
1647 // Mac register, aux antenna
1648 write_nic_byte(dev, ANTSEL, 0x00);
1649 // Config CCK RX antenna.
1650 write_phy_cck(dev, 0x11, 0xbb); // Reg11 : bb
1651 write_phy_cck(dev, 0x0c, 0x09); // Reg0c : 09
1652 write_phy_cck(dev, 0x01, 0xc7); // Reg01 : c7
1653 // Config OFDM RX antenna.
1654 write_phy_ofdm(dev, 0x0d, 0x54); // Reg0d : 54
1655 write_phy_ofdm(dev, 0x18, 0xb2); // Reg18 : b2
1656 }
1657 else // main antenna
1658 {
1659 // Mac register, main antenna
1660 write_nic_byte(dev, ANTSEL, 0x03);
1661 //base band
1662 // Config CCK RX antenna.
1663 write_phy_cck(dev, 0x11, 0x9b); // Reg11 : 9b
1664 write_phy_cck(dev, 0x0c, 0x09); // Reg0c : 09
1665 write_phy_cck(dev, 0x01, 0xc7); // Reg01 : c7
1666 // Config OFDM RX antenna.
1667 write_phy_ofdm(dev, 0x0d, 0x5c); // Reg0d : 5c
1668 write_phy_ofdm(dev, 0x18, 0xb2); // Reg18 : b2
1669 }
1670 }
1671 else // Disable Antenna Diversity
1672 {
1673 if( priv->bDefaultAntenna1 == true ) // aux Antenna
1674 {
1675 // Mac register, aux antenna
1676 write_nic_byte(dev, ANTSEL, 0x00);
1677 // Config CCK RX antenna.
1678 write_phy_cck(dev, 0x11, 0xbb); // Reg11 : bb
1679 write_phy_cck(dev, 0x0c, 0x09); // Reg0c : 09
1680 write_phy_cck(dev, 0x01, 0x47); // Reg01 : 47
1681 // Config OFDM RX antenna.
1682 write_phy_ofdm(dev, 0x0d, 0x54); // Reg0d : 54
1683 write_phy_ofdm(dev, 0x18, 0x32); // Reg18 : 32
1684 }
1685 else // main Antenna
1686 {
1687 // Mac register, main antenna
1688 write_nic_byte(dev, ANTSEL, 0x03);
1689 // Config CCK RX antenna.
1690 write_phy_cck(dev, 0x11, 0x9b); // Reg11 : 9b
1691 write_phy_cck(dev, 0x0c, 0x09); // Reg0c : 09
1692 write_phy_cck(dev, 0x01, 0x47); // Reg01 : 47
1693 // Config OFDM RX antenna.
1694 write_phy_ofdm(dev, 0x0d, 0x5c); // Reg0d : 5c
1695 write_phy_ofdm(dev, 0x18, 0x32); // Reg18 : 32
1696 }
1697 }
1698#endif
1699//by amy for antenna
1700}
1701
1702
1703void
1704UpdateInitialGain(
1705 struct net_device *dev
1706 )
1707{
1708 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1709 //unsigned char* IGTable;
1710 //u8 DIG_CurrentInitialGain = 4;
1711 //unsigned char u1Tmp;
1712
1713 //lzm add 080826
1714 if(priv->eRFPowerState != eRfOn)
1715 {
1716 //Don't access BB/RF under disable PLL situation.
1717 //RT_TRACE(COMP_DIG, DBG_LOUD, ("UpdateInitialGain - pHalData->eRFPowerState!=eRfOn\n"));
1718 // Back to the original state
1719 priv->InitialGain= priv->InitialGainBackUp;
1720 return;
1721 }
1722
1723 switch(priv->rf_chip)
1724 {
1725#if 0
1726 case RF_ZEBRA2:
1727 // Dynamic set initial gain, by shien chang, 2006.07.14
1728 switch(priv->InitialGain)
1729 {
1730 case 1: //m861dBm
1731 DMESG("RTL8185B + 8225 Initial Gain State 1: -82 dBm \n");
1732 write_nic_dword(dev, PhyAddr, 0x2697); mdelay(1);
1733 write_nic_dword(dev, PhyAddr, 0x86a4); mdelay(1);
1734 write_nic_dword(dev, PhyAddr, 0xfa85); mdelay(1);
1735 break;
1736
1737 case 2: //m862dBm
1738 DMESG("RTL8185B + 8225 Initial Gain State 2: -82 dBm \n");
1739 write_nic_dword(dev, PhyAddr, 0x2697); mdelay(1);
1740 write_nic_dword(dev, PhyAddr, 0x86a4); mdelay(1);
1741 write_nic_dword(dev, PhyAddr, 0xfb85); mdelay(1);
1742 break;
1743
1744 case 3: //m863dBm
1745 DMESG("RTL8185B + 8225 Initial Gain State 3: -82 dBm \n");
1746 write_nic_dword(dev, PhyAddr, 0x2697); mdelay(1);
1747 write_nic_dword(dev, PhyAddr, 0x96a4); mdelay(1);
1748 write_nic_dword(dev, PhyAddr, 0xfb85); mdelay(1);
1749 break;
1750
1751 case 4: //m864dBm
1752 DMESG("RTL8185B + 8225 Initial Gain State 4: -78 dBm \n");
1753 write_nic_dword(dev, PhyAddr, 0x2697); mdelay(1);
1754 write_nic_dword(dev, PhyAddr, 0xa6a4); mdelay(1);
1755 write_nic_dword(dev, PhyAddr, 0xfb85); mdelay(1);
1756 break;
1757
1758 case 5: //m82dBm
1759 DMESG("RTL8185B + 8225 Initial Gain State 5: -74 dBm \n");
1760 write_nic_dword(dev, PhyAddr, 0x3697); mdelay(1);
1761 write_nic_dword(dev, PhyAddr, 0xa6a4); mdelay(1);
1762 write_nic_dword(dev, PhyAddr, 0xfb85); mdelay(1);
1763 break;
1764
1765 case 6: //m78dBm
1766 DMESG("RTL8185B + 8225 Initial Gain State 6: -70 dBm \n");
1767 write_nic_dword(dev, PhyAddr, 0x4697); mdelay(1);
1768 write_nic_dword(dev, PhyAddr, 0xa6a4); mdelay(1);
1769 write_nic_dword(dev, PhyAddr, 0xfb85); mdelay(1);
1770 break;
1771
1772 case 7: //m74dBm
1773 DMESG("RTL8185B + 8225 Initial Gain State 7: -66 dBm \n");
1774 write_nic_dword(dev, PhyAddr, 0x5697); mdelay(1);
1775 write_nic_dword(dev, PhyAddr, 0xa6a4); mdelay(1);
1776 write_nic_dword(dev, PhyAddr, 0xfb85); mdelay(1);
1777 break;
1778
1779 default: //MP
1780 DMESG("RTL8185B + 8225 Initial Gain State 1: -82 dBm (default)\n");
1781 write_nic_dword(dev, PhyAddr, 0x2697); mdelay(1);
1782 write_nic_dword(dev, PhyAddr, 0x86a4); mdelay(1);
1783 write_nic_dword(dev, PhyAddr, 0xfa85); mdelay(1);
1784 break;
1785 }
1786 break;
1787#endif
1788 case RF_ZEBRA4:
1789 // Dynamic set initial gain, follow 87B
1790 switch(priv->InitialGain)
1791 {
1792 case 1: //m861dBm
1793 //DMESG("RTL8187 + 8225 Initial Gain State 1: -82 dBm \n");
1794 write_phy_ofdm(dev, 0x17, 0x26); mdelay(1);
1795 write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
1796 write_phy_ofdm(dev, 0x05, 0xfa); mdelay(1);
1797 break;
1798
1799 case 2: //m862dBm
1800 //DMESG("RTL8187 + 8225 Initial Gain State 2: -82 dBm \n");
1801 write_phy_ofdm(dev, 0x17, 0x36); mdelay(1);
1802 write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
1803 write_phy_ofdm(dev, 0x05, 0xfa); mdelay(1);
1804 break;
1805
1806 case 3: //m863dBm
1807 //DMESG("RTL8187 + 8225 Initial Gain State 3: -82 dBm \n");
1808 write_phy_ofdm(dev, 0x17, 0x36); mdelay(1);
1809 write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
1810 write_phy_ofdm(dev, 0x05, 0xfb); mdelay(1);
1811 break;
1812
1813 case 4: //m864dBm
1814 //DMESG("RTL8187 + 8225 Initial Gain State 4: -78 dBm \n");
1815 write_phy_ofdm(dev, 0x17, 0x46); mdelay(1);
1816 write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
1817 write_phy_ofdm(dev, 0x05, 0xfb); mdelay(1);
1818 break;
1819
1820 case 5: //m82dBm
1821 //DMESG("RTL8187 + 8225 Initial Gain State 5: -74 dBm \n");
1822 write_phy_ofdm(dev, 0x17, 0x46); mdelay(1);
1823 write_phy_ofdm(dev, 0x24, 0x96); mdelay(1);
1824 write_phy_ofdm(dev, 0x05, 0xfb); mdelay(1);
1825 break;
1826
1827 case 6: //m78dBm
1828 //DMESG ("RTL8187 + 8225 Initial Gain State 6: -70 dBm \n");
1829 write_phy_ofdm(dev, 0x17, 0x56); mdelay(1);
1830 write_phy_ofdm(dev, 0x24, 0x96); mdelay(1);
1831 write_phy_ofdm(dev, 0x05, 0xfc); mdelay(1);
1832 break;
1833
1834 case 7: //m74dBm
1835 //DMESG("RTL8187 + 8225 Initial Gain State 7: -66 dBm \n");
1836 write_phy_ofdm(dev, 0x17, 0x56); mdelay(1);
1837 write_phy_ofdm(dev, 0x24, 0xa6); mdelay(1);
1838 write_phy_ofdm(dev, 0x05, 0xfc); mdelay(1);
1839 break;
1840
1841 case 8:
1842 //DMESG("RTL8187 + 8225 Initial Gain State 8:\n");
1843 write_phy_ofdm(dev, 0x17, 0x66); mdelay(1);
1844 write_phy_ofdm(dev, 0x24, 0xb6); mdelay(1);
1845 write_phy_ofdm(dev, 0x05, 0xfc); mdelay(1);
1846 break;
1847
1848
1849 default: //MP
1850 //DMESG("RTL8187 + 8225 Initial Gain State 1: -82 dBm (default)\n");
1851 write_phy_ofdm(dev, 0x17, 0x26); mdelay(1);
1852 write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
1853 write_phy_ofdm(dev, 0x05, 0xfa); mdelay(1);
1854 break;
1855 }
1856 break;
1857
1858
1859 default:
1860 DMESG("UpdateInitialGain(): unknown RFChipID: %#X\n", priv->rf_chip);
1861 break;
1862 }
1863}
1864#ifdef CONFIG_RTL818X_S
1865//
1866// Description:
1867// Tx Power tracking mechanism routine on 87SE.
1868// Created by Roger, 2007.12.11.
1869//
1870void
1871InitTxPwrTracking87SE(
1872 struct net_device *dev
1873)
1874{
1875 //struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1876 u32 u4bRfReg;
1877
1878 u4bRfReg = RF_ReadReg(dev, 0x02);
1879
1880 // Enable Thermal meter indication.
1881 //printk("InitTxPwrTracking87SE(): Enable thermal meter indication, Write RF[0x02] = %#x", u4bRfReg|PWR_METER_EN);
1882 RF_WriteReg(dev, 0x02, u4bRfReg|PWR_METER_EN); mdelay(1);
1883}
1884
1885#endif
1886void
1887PhyConfig8185(
1888 struct net_device *dev
1889 )
1890{
1891 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1892 write_nic_dword(dev, RCR, priv->ReceiveConfig);
1893 priv->RFProgType = read_nic_byte(dev, CONFIG4) & 0x03;
1894 // RF config
1895 switch(priv->rf_chip)
1896 {
1897 case RF_ZEBRA2:
1898 case RF_ZEBRA4:
1899 ZEBRA_Config_85BASIC_HardCode( dev);
1900 break;
1901 }
1902//{by amy 080312
1903#ifdef CONFIG_RTL818X_S
1904 // Set default initial gain state to 4, approved by SD3 DZ, by Bruce, 2007-06-06.
1905 if(priv->bDigMechanism)
1906 {
1907 if(priv->InitialGain == 0)
1908 priv->InitialGain = 4;
1909 //printk("PhyConfig8185(): DIG is enabled, set default initial gain index to %d\n", priv->InitialGain);
1910 }
1911
1912 //
1913 // Enable thermal meter indication to implement TxPower tracking on 87SE.
1914 // We initialize thermal meter here to avoid unsuccessful configuration.
1915 // Added by Roger, 2007.12.11.
1916 //
1917 if(priv->bTxPowerTrack)
1918 InitTxPwrTracking87SE(dev);
1919
1920#endif
1921//by amy 080312}
1922 priv->InitialGainBackUp= priv->InitialGain;
1923 UpdateInitialGain(dev);
1924
1925 return;
1926}
1927
1928
1929
1930
1931void
1932HwConfigureRTL8185(
1933 struct net_device *dev
1934 )
1935{
1936 //RTL8185_TODO: Determine Retrylimit, TxAGC, AutoRateFallback control.
1937// u8 bUNIVERSAL_CONTROL_RL = 1;
1938 u8 bUNIVERSAL_CONTROL_RL = 0;
1939
1940 u8 bUNIVERSAL_CONTROL_AGC = 1;
1941 u8 bUNIVERSAL_CONTROL_ANT = 1;
1942 u8 bAUTO_RATE_FALLBACK_CTL = 1;
1943 u8 val8;
1944 //struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1945 //struct ieee80211_device *ieee = priv->ieee80211;
1946 //if(IS_WIRELESS_MODE_A(dev) || IS_WIRELESS_MODE_G(dev))
1947//{by amy 080312 if((ieee->mode == IEEE_G)||(ieee->mode == IEEE_A))
1948// {
1949// write_nic_word(dev, BRSR, 0xffff);
1950// }
1951// else
1952// {
1953// write_nic_word(dev, BRSR, 0x000f);
1954// }
1955//by amy 080312}
1956 write_nic_word(dev, BRSR, 0x0fff);
1957 // Retry limit
1958 val8 = read_nic_byte(dev, CW_CONF);
1959
1960 if(bUNIVERSAL_CONTROL_RL)
1961 val8 = val8 & 0xfd;
1962 else
1963 val8 = val8 | 0x02;
1964
1965 write_nic_byte(dev, CW_CONF, val8);
1966
1967 // Tx AGC
1968 val8 = read_nic_byte(dev, TXAGC_CTL);
1969 if(bUNIVERSAL_CONTROL_AGC)
1970 {
1971 write_nic_byte(dev, CCK_TXAGC, 128);
1972 write_nic_byte(dev, OFDM_TXAGC, 128);
1973 val8 = val8 & 0xfe;
1974 }
1975 else
1976 {
1977 val8 = val8 | 0x01 ;
1978 }
1979
1980
1981 write_nic_byte(dev, TXAGC_CTL, val8);
1982
1983 // Tx Antenna including Feedback control
1984 val8 = read_nic_byte(dev, TXAGC_CTL );
1985
1986 if(bUNIVERSAL_CONTROL_ANT)
1987 {
1988 write_nic_byte(dev, ANTSEL, 0x00);
1989 val8 = val8 & 0xfd;
1990 }
1991 else
1992 {
1993 val8 = val8 & (val8|0x02); //xiong-2006-11-15
1994 }
1995
1996 write_nic_byte(dev, TXAGC_CTL, val8);
1997
1998 // Auto Rate fallback control
1999 val8 = read_nic_byte(dev, RATE_FALLBACK);
2000 val8 &= 0x7c;
2001 if( bAUTO_RATE_FALLBACK_CTL )
2002 {
2003 val8 |= RATE_FALLBACK_CTL_ENABLE | RATE_FALLBACK_CTL_AUTO_STEP1;
2004
2005 // <RJ_TODO_8185B> We shall set up the ARFR according to user's setting.
2006 //write_nic_word(dev, ARFR, 0x0fff); // set 1M ~ 54M
2007//by amy
2008#if 0
2009 PlatformIOWrite2Byte(dev, ARFR, 0x0fff); // set 1M ~ 54M
2010#endif
2011#ifdef CONFIG_RTL818X_S
2012 // Aadded by Roger, 2007.11.15.
2013 PlatformIOWrite2Byte(dev, ARFR, 0x0fff); //set 1M ~ 54Mbps.
2014#else
2015 PlatformIOWrite2Byte(dev, ARFR, 0x0c00); //set 48Mbps, 54Mbps.
2016 // By SD3 szuyi's request. by Roger, 2007.03.26.
2017#endif
2018//by amy
2019 }
2020 else
2021 {
2022 }
2023 write_nic_byte(dev, RATE_FALLBACK, val8);
2024}
2025
2026
2027
2028static void
2029MacConfig_85BASIC_HardCode(
2030 struct net_device *dev)
2031{
2032 //============================================================================
2033 // MACREG.TXT
2034 //============================================================================
2035 int nLinesRead = 0;
2036
2037 u32 u4bRegOffset, u4bRegValue,u4bPageIndex = 0;
2038 int i;
2039
2040 nLinesRead=sizeof(MAC_REG_TABLE)/2;
2041
2042 for(i = 0; i < nLinesRead; i++) //nLinesRead=101
2043 {
2044 u4bRegOffset=MAC_REG_TABLE[i][0];
2045 u4bRegValue=MAC_REG_TABLE[i][1];
2046
2047 if(u4bRegOffset == 0x5e)
2048 {
2049 u4bPageIndex = u4bRegValue;
2050 }
2051 else
2052 {
2053 u4bRegOffset |= (u4bPageIndex << 8);
2054 }
2055 //DbgPrint("MAC - 0x%x = 0x%x\n", u4bRegOffset, u4bRegValue);
2056 write_nic_byte(dev, u4bRegOffset, (u8)u4bRegValue);
2057 }
2058 //============================================================================
2059}
2060
2061
2062
2063static void
2064MacConfig_85BASIC(
2065 struct net_device *dev)
2066{
2067
2068 u8 u1DA;
2069 MacConfig_85BASIC_HardCode(dev);
2070
2071 //============================================================================
2072
2073 // Follow TID_AC_MAP of WMac.
2074 write_nic_word(dev, TID_AC_MAP, 0xfa50);
2075
2076 // Interrupt Migration, Jong suggested we use set 0x0000 first, 2005.12.14, by rcnjko.
2077 write_nic_word(dev, IntMig, 0x0000);
2078
2079 // Prevent TPC to cause CRC error. Added by Annie, 2006-06-10.
2080 PlatformIOWrite4Byte(dev, 0x1F0, 0x00000000);
2081 PlatformIOWrite4Byte(dev, 0x1F4, 0x00000000);
2082 PlatformIOWrite1Byte(dev, 0x1F8, 0x00);
2083
2084 // Asked for by SD3 CM Lin, 2006.06.27, by rcnjko.
2085 //PlatformIOWrite4Byte(dev, RFTiming, 0x00004001);
2086//by amy
2087#if 0
2088 write_nic_dword(dev, RFTiming, 0x00004001);
2089#endif
2090#ifdef CONFIG_RTL818X_S
2091 // power save parameter based on "87SE power save parameters 20071127.doc", as follow.
2092
2093 //Enable DA10 TX power saving
2094 u1DA = read_nic_byte(dev, PHYPR);
2095 write_nic_byte(dev, PHYPR, (u1DA | BIT2) );
2096
2097 //POWER:
2098 write_nic_word(dev, 0x360, 0x1000);
2099 write_nic_word(dev, 0x362, 0x1000);
2100
2101 // AFE.
2102 write_nic_word(dev, 0x370, 0x0560);
2103 write_nic_word(dev, 0x372, 0x0560);
2104 write_nic_word(dev, 0x374, 0x0DA4);
2105 write_nic_word(dev, 0x376, 0x0DA4);
2106 write_nic_word(dev, 0x378, 0x0560);
2107 write_nic_word(dev, 0x37A, 0x0560);
2108 write_nic_word(dev, 0x37C, 0x00EC);
2109// write_nic_word(dev, 0x37E, 0x00FE);//-edward
2110 write_nic_word(dev, 0x37E, 0x00EC);//+edward
2111#else
2112 write_nic_dword(dev, RFTiming, 0x00004003);
2113#endif
2114 write_nic_byte(dev, 0x24E,0x01);
2115//by amy
2116
2117}
2118
2119
2120
2121
2122u8
2123GetSupportedWirelessMode8185(
2124 struct net_device *dev
2125)
2126{
2127 u8 btSupportedWirelessMode = 0;
2128 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
2129
2130 switch(priv->rf_chip)
2131 {
2132 case RF_ZEBRA2:
2133 case RF_ZEBRA4:
2134 btSupportedWirelessMode = (WIRELESS_MODE_B | WIRELESS_MODE_G);
2135 break;
2136 default:
2137 btSupportedWirelessMode = WIRELESS_MODE_B;
2138 break;
2139 }
2140
2141 return btSupportedWirelessMode;
2142}
2143
2144void
2145ActUpdateChannelAccessSetting(
2146 struct net_device *dev,
2147 WIRELESS_MODE WirelessMode,
2148 PCHANNEL_ACCESS_SETTING ChnlAccessSetting
2149 )
2150{
2151 struct r8180_priv *priv = ieee80211_priv(dev);
2152 struct ieee80211_device *ieee = priv->ieee80211;
2153 AC_CODING eACI;
2154 AC_PARAM AcParam;
2155 //PSTA_QOS pStaQos = Adapter->MgntInfo.pStaQos;
2156 u8 bFollowLegacySetting = 0;
2157 u8 u1bAIFS;
2158
2159 //
2160 // <RJ_TODO_8185B>
2161 // TODO: We still don't know how to set up these registers, just follow WMAC to
2162 // verify 8185B FPAG.
2163 //
2164 // <RJ_TODO_8185B>
2165 // Jong said CWmin/CWmax register are not functional in 8185B,
2166 // so we shall fill channel access realted register into AC parameter registers,
2167 // even in nQBss.
2168 //
2169 ChnlAccessSetting->SIFS_Timer = 0x22; // Suggested by Jong, 2005.12.08.
2170 ChnlAccessSetting->DIFS_Timer = 0x1C; // 2006.06.02, by rcnjko.
2171 ChnlAccessSetting->SlotTimeTimer = 9; // 2006.06.02, by rcnjko.
2172 ChnlAccessSetting->EIFS_Timer = 0x5B; // Suggested by wcchu, it is the default value of EIFS register, 2005.12.08.
2173 ChnlAccessSetting->CWminIndex = 3; // 2006.06.02, by rcnjko.
2174 ChnlAccessSetting->CWmaxIndex = 7; // 2006.06.02, by rcnjko.
2175
2176 write_nic_byte(dev, SIFS, ChnlAccessSetting->SIFS_Timer);
2177 //Adapter->HalFunc.SetHwRegHandler( Adapter, HW_VAR_SLOT_TIME, &ChnlAccessSetting->SlotTimeTimer ); // Rewrited from directly use PlatformEFIOWrite1Byte(), by Annie, 2006-03-29.
2178 write_nic_byte(dev, SLOT, ChnlAccessSetting->SlotTimeTimer); // Rewrited from directly use PlatformEFIOWrite1Byte(), by Annie, 2006-03-29.
2179
2180 u1bAIFS = aSifsTime + (2 * ChnlAccessSetting->SlotTimeTimer );
2181
2182 //write_nic_byte(dev, AC_VO_PARAM, u1bAIFS);
2183 //write_nic_byte(dev, AC_VI_PARAM, u1bAIFS);
2184 //write_nic_byte(dev, AC_BE_PARAM, u1bAIFS);
2185 //write_nic_byte(dev, AC_BK_PARAM, u1bAIFS);
2186
2187 write_nic_byte(dev, EIFS, ChnlAccessSetting->EIFS_Timer);
2188
2189 write_nic_byte(dev, AckTimeOutReg, 0x5B); // <RJ_EXPR_QOS> Suggested by wcchu, it is the default value of EIFS register, 2005.12.08.
2190
2191#ifdef TODO
2192 // <RJ_TODO_NOW_8185B> Update ECWmin/ECWmax, AIFS, TXOP Limit of each AC to the value defined by SPEC.
2193 if( pStaQos->CurrentQosMode > QOS_DISABLE )
2194 { // QoS mode.
2195 if(pStaQos->QBssWirelessMode == WirelessMode)
2196 {
2197 // Follow AC Parameters of the QBSS.
2198 for(eACI = 0; eACI < AC_MAX; eACI++)
2199 {
2200 Adapter->HalFunc.SetHwRegHandler(Adapter, HW_VAR_AC_PARAM, (pu1Byte)(&(pStaQos->WMMParamEle.AcParam[eACI])) );
2201 }
2202 }
2203 else
2204 {
2205 // Follow Default WMM AC Parameters.
2206 bFollowLegacySetting = 1;
2207 }
2208 }
2209 else
2210#endif
2211 { // Legacy 802.11.
2212 bFollowLegacySetting = 1;
2213
2214 }
2215
2216 // this setting is copied from rtl8187B. xiong-2006-11-13
2217 if(bFollowLegacySetting)
2218 {
2219
2220
2221 //
2222 // Follow 802.11 seeting to AC parameter, all AC shall use the same parameter.
2223 // 2005.12.01, by rcnjko.
2224 //
2225 AcParam.longData = 0;
2226 AcParam.f.AciAifsn.f.AIFSN = 2; // Follow 802.11 DIFS.
2227 AcParam.f.AciAifsn.f.ACM = 0;
2228 AcParam.f.Ecw.f.ECWmin = ChnlAccessSetting->CWminIndex; // Follow 802.11 CWmin.
2229 AcParam.f.Ecw.f.ECWmax = ChnlAccessSetting->CWmaxIndex; // Follow 802.11 CWmax.
2230 AcParam.f.TXOPLimit = 0;
2231
2232 //lzm reserved 080826
2233#if 1
2234#ifdef THOMAS_TURBO
2235 // For turbo mode setting. port from 87B by Isaiah 2008-08-01
2236 if( ieee->current_network.Turbo_Enable == 1 )
2237 AcParam.f.TXOPLimit = 0x01FF;
2238#endif
2239 // For 87SE with Intel 4965 Ad-Hoc mode have poor throughput (19MB)
2240 if (ieee->iw_mode == IW_MODE_ADHOC)
2241 AcParam.f.TXOPLimit = 0x0020;
2242#endif
2243
2244 for(eACI = 0; eACI < AC_MAX; eACI++)
2245 {
2246 AcParam.f.AciAifsn.f.ACI = (u8)eACI;
2247 {
2248 PAC_PARAM pAcParam = (PAC_PARAM)(&AcParam);
2249 AC_CODING eACI;
2250 u8 u1bAIFS;
2251 u32 u4bAcParam;
2252
2253 // Retrive paramters to udpate.
2254 eACI = pAcParam->f.AciAifsn.f.ACI;
2255 u1bAIFS = pAcParam->f.AciAifsn.f.AIFSN * ChnlAccessSetting->SlotTimeTimer + aSifsTime;
2256 u4bAcParam = ( (((u32)(pAcParam->f.TXOPLimit)) << AC_PARAM_TXOP_LIMIT_OFFSET) |
2257 (((u32)(pAcParam->f.Ecw.f.ECWmax)) << AC_PARAM_ECW_MAX_OFFSET) |
2258 (((u32)(pAcParam->f.Ecw.f.ECWmin)) << AC_PARAM_ECW_MIN_OFFSET) |
2259 (((u32)u1bAIFS) << AC_PARAM_AIFS_OFFSET));
2260
2261 switch(eACI)
2262 {
2263 case AC1_BK:
2264 //write_nic_dword(dev, AC_BK_PARAM, u4bAcParam);
2265 break;
2266
2267 case AC0_BE:
2268 //write_nic_dword(dev, AC_BE_PARAM, u4bAcParam);
2269 break;
2270
2271 case AC2_VI:
2272 //write_nic_dword(dev, AC_VI_PARAM, u4bAcParam);
2273 break;
2274
2275 case AC3_VO:
2276 //write_nic_dword(dev, AC_VO_PARAM, u4bAcParam);
2277 break;
2278
2279 default:
2280 DMESGW( "SetHwReg8185(): invalid ACI: %d !\n", eACI);
2281 break;
2282 }
2283
2284 // Cehck ACM bit.
2285 // If it is set, immediately set ACM control bit to downgrading AC for passing WMM testplan. Annie, 2005-12-13.
2286 //write_nic_byte(dev, ACM_CONTROL, pAcParam->f.AciAifsn);
2287 {
2288 PACI_AIFSN pAciAifsn = (PACI_AIFSN)(&pAcParam->f.AciAifsn);
2289 AC_CODING eACI = pAciAifsn->f.ACI;
2290
2291 //modified Joseph
2292 //for 8187B AsynIORead issue
2293#ifdef TODO
2294 u8 AcmCtrl = pHalData->AcmControl;
2295#else
2296 u8 AcmCtrl = 0;
2297#endif
2298 if( pAciAifsn->f.ACM )
2299 { // ACM bit is 1.
2300 switch(eACI)
2301 {
2302 case AC0_BE:
2303 AcmCtrl |= (BEQ_ACM_EN|BEQ_ACM_CTL|ACM_HW_EN); // or 0x21
2304 break;
2305
2306 case AC2_VI:
2307 AcmCtrl |= (VIQ_ACM_EN|VIQ_ACM_CTL|ACM_HW_EN); // or 0x42
2308 break;
2309
2310 case AC3_VO:
2311 AcmCtrl |= (VOQ_ACM_EN|VOQ_ACM_CTL|ACM_HW_EN); // or 0x84
2312 break;
2313
2314 default:
2315 DMESGW("SetHwReg8185(): [HW_VAR_ACM_CTRL] ACM set failed: eACI is %d\n", eACI );
2316 break;
2317 }
2318 }
2319 else
2320 { // ACM bit is 0.
2321 switch(eACI)
2322 {
2323 case AC0_BE:
2324 AcmCtrl &= ( (~BEQ_ACM_EN) & (~BEQ_ACM_CTL) & (~ACM_HW_EN) ); // and 0xDE
2325 break;
2326
2327 case AC2_VI:
2328 AcmCtrl &= ( (~VIQ_ACM_EN) & (~VIQ_ACM_CTL) & (~ACM_HW_EN) ); // and 0xBD
2329 break;
2330
2331 case AC3_VO:
2332 AcmCtrl &= ( (~VOQ_ACM_EN) & (~VOQ_ACM_CTL) & (~ACM_HW_EN) ); // and 0x7B
2333 break;
2334
2335 default:
2336 break;
2337 }
2338 }
2339
2340 //printk(KERN_WARNING "SetHwReg8185(): [HW_VAR_ACM_CTRL] Write 0x%X\n", AcmCtrl);
2341
2342#ifdef TO_DO
2343 pHalData->AcmControl = AcmCtrl;
2344#endif
2345 //write_nic_byte(dev, ACM_CONTROL, AcmCtrl);
2346 write_nic_byte(dev, ACM_CONTROL, 0);
2347 }
2348 }
2349 }
2350
2351
2352 }
2353}
2354
2355void
2356ActSetWirelessMode8185(
2357 struct net_device *dev,
2358 u8 btWirelessMode
2359 )
2360{
2361 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
2362 struct ieee80211_device *ieee = priv->ieee80211;
2363 //PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo);
2364 u8 btSupportedWirelessMode = GetSupportedWirelessMode8185(dev);
2365
2366 if( (btWirelessMode & btSupportedWirelessMode) == 0 )
2367 { // Don't switch to unsupported wireless mode, 2006.02.15, by rcnjko.
2368 DMESGW("ActSetWirelessMode8185(): WirelessMode(%d) is not supported (%d)!\n",
2369 btWirelessMode, btSupportedWirelessMode);
2370 return;
2371 }
2372
2373 // 1. Assign wireless mode to swtich if necessary.
2374 if (btWirelessMode == WIRELESS_MODE_AUTO)
2375 {
2376 if((btSupportedWirelessMode & WIRELESS_MODE_A))
2377 {
2378 btWirelessMode = WIRELESS_MODE_A;
2379 }
2380 else if((btSupportedWirelessMode & WIRELESS_MODE_G))
2381 {
2382 btWirelessMode = WIRELESS_MODE_G;
2383 }
2384 else if((btSupportedWirelessMode & WIRELESS_MODE_B))
2385 {
2386 btWirelessMode = WIRELESS_MODE_B;
2387 }
2388 else
2389 {
2390 DMESGW("ActSetWirelessMode8185(): No valid wireless mode supported, btSupportedWirelessMode(%x)!!!\n",
2391 btSupportedWirelessMode);
2392 btWirelessMode = WIRELESS_MODE_B;
2393 }
2394 }
2395
2396
2397 // 2. Swtich band: RF or BB specific actions,
2398 // for example, refresh tables in omc8255, or change initial gain if necessary.
2399 switch(priv->rf_chip)
2400 {
2401 case RF_ZEBRA2:
2402 case RF_ZEBRA4:
2403 {
2404 // Nothing to do for Zebra to switch band.
2405 // Update current wireless mode if we swtich to specified band successfully.
2406 ieee->mode = (WIRELESS_MODE)btWirelessMode;
2407 }
2408 break;
2409
2410 default:
2411 DMESGW("ActSetWirelessMode8185(): unsupported RF: 0x%X !!!\n", priv->rf_chip);
2412 break;
2413 }
2414
2415 // 3. Change related setting.
2416 if( ieee->mode == WIRELESS_MODE_A ){
2417 DMESG("WIRELESS_MODE_A\n");
2418 }
2419 else if( ieee->mode == WIRELESS_MODE_B ){
2420 DMESG("WIRELESS_MODE_B\n");
2421 }
2422 else if( ieee->mode == WIRELESS_MODE_G ){
2423 DMESG("WIRELESS_MODE_G\n");
2424 }
2425
2426 ActUpdateChannelAccessSetting( dev, ieee->mode, &priv->ChannelAccessSetting);
2427}
2428
2429void rtl8185b_irq_enable(struct net_device *dev)
2430{
2431 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
2432
2433 priv->irq_enabled = 1;
2434 write_nic_dword(dev, IMR, priv->IntrMask);
2435}
2436//by amy for power save
2437void
2438DrvIFIndicateDisassociation(
2439 struct net_device *dev,
2440 u16 reason
2441 )
2442{
2443 //printk("==> DrvIFIndicateDisassociation()\n");
2444
2445 // nothing is needed after disassociation request.
2446
2447 //printk("<== DrvIFIndicateDisassociation()\n");
2448}
2449void
2450MgntDisconnectIBSS(
2451 struct net_device *dev
2452)
2453{
2454 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
2455 u8 i;
2456
2457 //printk("XXXXXXXXXX MgntDisconnect IBSS\n");
2458
2459 DrvIFIndicateDisassociation(dev, unspec_reason);
2460
2461// PlatformZeroMemory( pMgntInfo->Bssid, 6 );
2462 for(i=0;i<6;i++) priv->ieee80211->current_network.bssid[i] = 0x55;
2463
2464 priv->ieee80211->state = IEEE80211_NOLINK;
2465
2466 //Stop Beacon.
2467
2468 // Vista add a Adhoc profile, HW radio off untill OID_DOT11_RESET_REQUEST
2469 // Driver would set MSR=NO_LINK, then HW Radio ON, MgntQueue Stuck.
2470 // Because Bcn DMA isn't complete, mgnt queue would stuck until Bcn packet send.
2471
2472 // Disable Beacon Queue Own bit, suggested by jong
2473// Adapter->HalFunc.SetTxDescOWNHandler(Adapter, BEACON_QUEUE, 0, 0);
2474 ieee80211_stop_send_beacons(priv->ieee80211);
2475
2476 priv->ieee80211->link_change(dev);
2477 notify_wx_assoc_event(priv->ieee80211);
2478
2479 // Stop SW Beacon.Use hw beacon so do not need to do so.by amy
2480#if 0
2481 if(pMgntInfo->bEnableSwBeaconTimer)
2482 {
2483 // SwBeaconTimer will stop if pMgntInfo->mIbss==FALSE, see SwBeaconCallback() for details.
2484// comment out by haich, 2007.10.01
2485//#if DEV_BUS_TYPE==USB_INTERFACE
2486 PlatformCancelTimer( Adapter, &pMgntInfo->SwBeaconTimer);
2487//#endif
2488 }
2489#endif
2490
2491// MgntIndicateMediaStatus( Adapter, RT_MEDIA_DISCONNECT, GENERAL_INDICATE );
2492
2493}
2494void
2495MlmeDisassociateRequest(
2496 struct net_device *dev,
2497 u8* asSta,
2498 u8 asRsn
2499 )
2500{
2501 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
2502 u8 i;
2503
2504 SendDisassociation(priv->ieee80211, asSta, asRsn );
2505
2506 if( memcmp(priv->ieee80211->current_network.bssid, asSta, 6 ) == 0 ){
2507 //ShuChen TODO: change media status.
2508 //ShuChen TODO: What to do when disassociate.
2509 DrvIFIndicateDisassociation(dev, unspec_reason);
2510
2511
2512 // pMgntInfo->AsocTimestamp = 0;
2513 for(i=0;i<6;i++) priv->ieee80211->current_network.bssid[i] = 0x22;
2514// pMgntInfo->mBrates.Length = 0;
2515// Adapter->HalFunc.SetHwRegHandler( Adapter, HW_VAR_BASIC_RATE, (pu1Byte)(&pMgntInfo->mBrates) );
2516
2517 ieee80211_disassociate(priv->ieee80211);
2518
2519
2520 }
2521
2522}
2523
2524void
2525MgntDisconnectAP(
2526 struct net_device *dev,
2527 u8 asRsn
2528)
2529{
2530 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
2531
2532//
2533// Commented out by rcnjko, 2005.01.27:
2534// I move SecClearAllKeys() to MgntActSet_802_11_DISASSOCIATE().
2535//
2536// //2004/09/15, kcwu, the key should be cleared, or the new handshaking will not success
2537// SecClearAllKeys(Adapter);
2538
2539 // In WPA WPA2 need to Clear all key ... because new key will set after new handshaking.
2540#ifdef TODO
2541 if( pMgntInfo->SecurityInfo.AuthMode > RT_802_11AuthModeAutoSwitch ||
2542 (pMgntInfo->bAPSuportCCKM && pMgntInfo->bCCX8021xenable) ) // In CCKM mode will Clear key
2543 {
2544 SecClearAllKeys(Adapter);
2545 RT_TRACE(COMP_SEC, DBG_LOUD,("======>CCKM clear key..."))
2546 }
2547#endif
2548 // 2004.10.11, by rcnjko.
2549 //MlmeDisassociateRequest( Adapter, pMgntInfo->Bssid, disas_lv_ss );
2550 MlmeDisassociateRequest( dev, priv->ieee80211->current_network.bssid, asRsn );
2551
2552 priv->ieee80211->state = IEEE80211_NOLINK;
2553// pMgntInfo->AsocTimestamp = 0;
2554}
2555bool
2556MgntDisconnect(
2557 struct net_device *dev,
2558 u8 asRsn
2559)
2560{
2561 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
2562 //
2563 // Schedule an workitem to wake up for ps mode, 070109, by rcnjko.
2564 //
2565#ifdef TODO
2566 if(pMgntInfo->mPss != eAwake)
2567 {
2568 //
2569 // Using AwkaeTimer to prevent mismatch ps state.
2570 // In the timer the state will be changed according to the RF is being awoke or not. By Bruce, 2007-10-31.
2571 //
2572 // PlatformScheduleWorkItem( &(pMgntInfo->AwakeWorkItem) );
2573 PlatformSetTimer( Adapter, &(pMgntInfo->AwakeTimer), 0 );
2574 }
2575#endif
2576
2577 // Indication of disassociation event.
2578 //DrvIFIndicateDisassociation(Adapter, asRsn);
2579#ifdef ENABLE_DOT11D
2580 if(IS_DOT11D_ENABLE(priv->ieee80211))
2581 Dot11d_Reset(priv->ieee80211);
2582#endif
2583 // In adhoc mode, update beacon frame.
2584 if( priv->ieee80211->state == IEEE80211_LINKED )
2585 {
2586 if( priv->ieee80211->iw_mode == IW_MODE_ADHOC )
2587 {
2588// RT_TRACE(COMP_MLME, DBG_LOUD, ("MgntDisconnect() ===> MgntDisconnectIBSS\n"));
2589 //printk("MgntDisconnect() ===> MgntDisconnectIBSS\n");
2590 MgntDisconnectIBSS(dev);
2591 }
2592 if( priv->ieee80211->iw_mode == IW_MODE_INFRA )
2593 {
2594 // We clear key here instead of MgntDisconnectAP() because that
2595 // MgntActSet_802_11_DISASSOCIATE() is an interface called by OS,
2596 // e.g. OID_802_11_DISASSOCIATE in Windows while as MgntDisconnectAP() is
2597 // used to handle disassociation related things to AP, e.g. send Disassoc
2598 // frame to AP. 2005.01.27, by rcnjko.
2599// SecClearAllKeys(Adapter);
2600
2601// RT_TRACE(COMP_MLME, DBG_LOUD, ("MgntDisconnect() ===> MgntDisconnectAP\n"));
2602 //printk("MgntDisconnect() ===> MgntDisconnectAP\n");
2603 MgntDisconnectAP(dev, asRsn);
2604 }
2605
2606 // Inidicate Disconnect, 2005.02.23, by rcnjko.
2607// MgntIndicateMediaStatus( Adapter, RT_MEDIA_DISCONNECT, GENERAL_INDICATE);
2608 }
2609
2610 return true;
2611}
2612//
2613// Description:
2614// Chang RF Power State.
2615// Note that, only MgntActSet_RF_State() is allowed to set HW_VAR_RF_STATE.
2616//
2617// Assumption:
2618// PASSIVE LEVEL.
2619//
2620bool
2621SetRFPowerState(
2622 struct net_device *dev,
2623 RT_RF_POWER_STATE eRFPowerState
2624 )
2625{
2626 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
2627 bool bResult = false;
2628
2629// printk("---------> SetRFPowerState(): eRFPowerState(%d)\n", eRFPowerState);
2630 if(eRFPowerState == priv->eRFPowerState)
2631 {
2632// printk("<--------- SetRFPowerState(): discard the request for eRFPowerState(%d) is the same.\n", eRFPowerState);
2633 return bResult;
2634 }
2635
2636 switch(priv->rf_chip)
2637 {
2638 case RF_ZEBRA2:
2639 case RF_ZEBRA4:
2640 bResult = SetZebraRFPowerState8185(dev, eRFPowerState);
2641 break;
2642
2643 default:
2644 printk("SetRFPowerState8185(): unknown RFChipID: 0x%X!!!\n", priv->rf_chip);
2645 break;;
2646}
2647// printk("<--------- SetRFPowerState(): bResult(%d)\n", bResult);
2648
2649 return bResult;
2650}
2651void
2652HalEnableRx8185Dummy(
2653 struct net_device *dev
2654 )
2655{
2656}
2657void
2658HalDisableRx8185Dummy(
2659 struct net_device *dev
2660 )
2661{
2662}
2663
2664bool
2665MgntActSet_RF_State(
2666 struct net_device *dev,
2667 RT_RF_POWER_STATE StateToSet,
2668 u32 ChangeSource
2669 )
2670{
2671 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
2672 bool bActionAllowed = false;
2673 bool bConnectBySSID = false;
2674 RT_RF_POWER_STATE rtState;
2675 u16 RFWaitCounter = 0;
2676 unsigned long flag;
2677// printk("===>MgntActSet_RF_State(): StateToSet(%d), ChangeSource(0x%x)\n",StateToSet, ChangeSource);
2678 //
2679 // Prevent the race condition of RF state change. By Bruce, 2007-11-28.
2680 // Only one thread can change the RF state at one time, and others should wait to be executed.
2681 //
2682#if 1
2683 while(true)
2684 {
2685// down(&priv->rf_state);
2686 spin_lock_irqsave(&priv->rf_ps_lock,flag);
2687 if(priv->RFChangeInProgress)
2688 {
2689// printk("====================>haha111111111\n");
2690// up(&priv->rf_state);
2691// RT_TRACE(COMP_RF, DBG_LOUD, ("MgntActSet_RF_State(): RF Change in progress! Wait to set..StateToSet(%d).\n", StateToSet));
2692 spin_unlock_irqrestore(&priv->rf_ps_lock,flag);
2693 // Set RF after the previous action is done.
2694 while(priv->RFChangeInProgress)
2695 {
2696 RFWaitCounter ++;
2697// RT_TRACE(COMP_RF, DBG_LOUD, ("MgntActSet_RF_State(): Wait 1 ms (%d times)...\n", RFWaitCounter));
2698 udelay(1000); // 1 ms
2699
2700 // Wait too long, return FALSE to avoid to be stuck here.
2701 if(RFWaitCounter > 1000) // 1sec
2702 {
2703// RT_ASSERT(FALSE, ("MgntActSet_RF_State(): Wait too logn to set RF\n"));
2704 printk("MgntActSet_RF_State(): Wait too long to set RF\n");
2705 // TODO: Reset RF state?
2706 return false;
2707 }
2708 }
2709 }
2710 else
2711 {
2712// printk("========================>haha2\n");
2713 priv->RFChangeInProgress = true;
2714// up(&priv->rf_state);
2715 spin_unlock_irqrestore(&priv->rf_ps_lock,flag);
2716 break;
2717 }
2718 }
2719#endif
2720 rtState = priv->eRFPowerState;
2721
2722
2723 switch(StateToSet)
2724 {
2725 case eRfOn:
2726 //
2727 // Turn On RF no matter the IPS setting because we need to update the RF state to Ndis under Vista, or
2728 // the Windows does not allow the driver to perform site survey any more. By Bruce, 2007-10-02.
2729 //
2730 priv->RfOffReason &= (~ChangeSource);
2731
2732 if(! priv->RfOffReason)
2733 {
2734 priv->RfOffReason = 0;
2735 bActionAllowed = true;
2736
2737 if(rtState == eRfOff && ChangeSource >=RF_CHANGE_BY_HW && !priv->bInHctTest)
2738 {
2739 bConnectBySSID = true;
2740 }
2741 }
2742 else
2743// RT_TRACE(COMP_RF, DBG_LOUD, ("MgntActSet_RF_State - eRfon reject pMgntInfo->RfOffReason= 0x%x, ChangeSource=0x%X\n", pMgntInfo->RfOffReason, ChangeSource));
2744 ;
2745 break;
2746
2747 case eRfOff:
2748 // 070125, rcnjko: we always keep connected in AP mode.
2749
2750 if (priv->RfOffReason > RF_CHANGE_BY_IPS)
2751 {
2752 //
2753 // 060808, Annie:
2754 // Disconnect to current BSS when radio off. Asked by QuanTa.
2755 //
2756
2757 //
2758 // Calling MgntDisconnect() instead of MgntActSet_802_11_DISASSOCIATE(),
2759 // because we do NOT need to set ssid to dummy ones.
2760 // Revised by Roger, 2007.12.04.
2761 //
2762 MgntDisconnect( dev, disas_lv_ss );
2763
2764 // Clear content of bssDesc[] and bssDesc4Query[] to avoid reporting old bss to UI.
2765 // 2007.05.28, by shien chang.
2766// PlatformZeroMemory( pMgntInfo->bssDesc, sizeof(RT_WLAN_BSS)*MAX_BSS_DESC );
2767// pMgntInfo->NumBssDesc = 0;
2768// PlatformZeroMemory( pMgntInfo->bssDesc4Query, sizeof(RT_WLAN_BSS)*MAX_BSS_DESC );
2769// pMgntInfo->NumBssDesc4Query = 0;
2770 }
2771
2772
2773
2774 priv->RfOffReason |= ChangeSource;
2775 bActionAllowed = true;
2776 break;
2777
2778 case eRfSleep:
2779 priv->RfOffReason |= ChangeSource;
2780 bActionAllowed = true;
2781 break;
2782
2783 default:
2784 break;
2785 }
2786
2787 if(bActionAllowed)
2788 {
2789// RT_TRACE(COMP_RF, DBG_LOUD, ("MgntActSet_RF_State(): Action is allowed.... StateToSet(%d), RfOffReason(%#X)\n", StateToSet, pMgntInfo->RfOffReason));
2790 // Config HW to the specified mode.
2791// printk("MgntActSet_RF_State(): Action is allowed.... StateToSet(%d), RfOffReason(%#X)\n", StateToSet, priv->RfOffReason);
2792 SetRFPowerState(dev, StateToSet);
2793
2794 // Turn on RF.
2795 if(StateToSet == eRfOn)
2796 {
2797 HalEnableRx8185Dummy(dev);
2798 if(bConnectBySSID)
2799 {
2800 // by amy not supported
2801// MgntActSet_802_11_SSID(Adapter, Adapter->MgntInfo.Ssid.Octet, Adapter->MgntInfo.Ssid.Length, TRUE );
2802 }
2803 }
2804 // Turn off RF.
2805 else if(StateToSet == eRfOff)
2806 {
2807 HalDisableRx8185Dummy(dev);
2808 }
2809 }
2810 else
2811 {
2812 // printk("MgntActSet_RF_State(): Action is rejected.... StateToSet(%d), ChangeSource(%#X), RfOffReason(%#X)\n", StateToSet, ChangeSource, priv->RfOffReason);
2813 }
2814
2815 // Release RF spinlock
2816// down(&priv->rf_state);
2817 spin_lock_irqsave(&priv->rf_ps_lock,flag);
2818 priv->RFChangeInProgress = false;
2819// up(&priv->rf_state);
2820 spin_unlock_irqrestore(&priv->rf_ps_lock,flag);
2821// printk("<===MgntActSet_RF_State()\n");
2822 return bActionAllowed;
2823}
2824void
2825InactivePowerSave(
2826 struct net_device *dev
2827 )
2828{
2829 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
2830 //u8 index = 0;
2831
2832 //
2833 // This flag "bSwRfProcessing", indicates the status of IPS procedure, should be set if the IPS workitem
2834 // is really scheduled.
2835 // The old code, sets this flag before scheduling the IPS workitem and however, at the same time the
2836 // previous IPS workitem did not end yet, fails to schedule the current workitem. Thus, bSwRfProcessing
2837 // blocks the IPS procedure of switching RF.
2838 // By Bruce, 2007-12-25.
2839 //
2840 priv->bSwRfProcessing = true;
2841
2842 MgntActSet_RF_State(dev, priv->eInactivePowerState, RF_CHANGE_BY_IPS);
2843
2844 //
2845 // To solve CAM values miss in RF OFF, rewrite CAM values after RF ON. By Bruce, 2007-09-20.
2846 //
2847#if 0
2848 while( index < 4 )
2849 {
2850 if( ( pMgntInfo->SecurityInfo.PairwiseEncAlgorithm == WEP104_Encryption ) ||
2851 (pMgntInfo->SecurityInfo.PairwiseEncAlgorithm == WEP40_Encryption) )
2852 {
2853 if( pMgntInfo->SecurityInfo.KeyLen[index] != 0)
2854 pAdapter->HalFunc.SetKeyHandler(pAdapter, index, 0, FALSE, pMgntInfo->SecurityInfo.PairwiseEncAlgorithm, TRUE, FALSE);
2855
2856 }
2857 index++;
2858 }
2859#endif
2860 priv->bSwRfProcessing = false;
2861}
2862
2863//
2864// Description:
2865// Enter the inactive power save mode. RF will be off
2866// 2007.08.17, by shien chang.
2867//
2868void
2869IPSEnter(
2870 struct net_device *dev
2871 )
2872{
2873 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
2874 RT_RF_POWER_STATE rtState;
2875 //printk("==============================>enter IPS\n");
2876 if (priv->bInactivePs)
2877 {
2878 rtState = priv->eRFPowerState;
2879
2880 //
2881 // Added by Bruce, 2007-12-25.
2882 // Do not enter IPS in the following conditions:
2883 // (1) RF is already OFF or Sleep
2884 // (2) bSwRfProcessing (indicates the IPS is still under going)
2885 // (3) Connectted (only disconnected can trigger IPS)
2886 // (4) IBSS (send Beacon)
2887 // (5) AP mode (send Beacon)
2888 //
2889 if (rtState == eRfOn && !priv->bSwRfProcessing
2890 && (priv->ieee80211->state != IEEE80211_LINKED ))
2891 {
2892 // printk("IPSEnter(): Turn off RF.\n");
2893 priv->eInactivePowerState = eRfOff;
2894 InactivePowerSave(dev);
2895 }
2896 }
2897// printk("priv->eRFPowerState is %d\n",priv->eRFPowerState);
2898}
2899void
2900IPSLeave(
2901 struct net_device *dev
2902 )
2903{
2904 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
2905 RT_RF_POWER_STATE rtState;
2906 //printk("===================================>leave IPS\n");
2907 if (priv->bInactivePs)
2908 {
2909 rtState = priv->eRFPowerState;
2910 if ((rtState == eRfOff || rtState == eRfSleep) && (!priv->bSwRfProcessing) && priv->RfOffReason <= RF_CHANGE_BY_IPS)
2911 {
2912// printk("IPSLeave(): Turn on RF.\n");
2913 priv->eInactivePowerState = eRfOn;
2914 InactivePowerSave(dev);
2915 }
2916 }
2917// printk("priv->eRFPowerState is %d\n",priv->eRFPowerState);
2918}
2919//by amy for power save
2920void rtl8185b_adapter_start(struct net_device *dev)
2921{
2922 struct r8180_priv *priv = ieee80211_priv(dev);
2923 struct ieee80211_device *ieee = priv->ieee80211;
2924
2925 u8 SupportedWirelessMode;
2926 u8 InitWirelessMode;
2927 u8 bInvalidWirelessMode = 0;
2928 //int i;
2929 u8 tmpu8;
2930 //u8 u1tmp,u2tmp;
2931 u8 btCR9346;
2932 u8 TmpU1b;
2933 u8 btPSR;
2934
2935 //rtl8180_rtx_disable(dev);
2936//{by amy 080312
2937 write_nic_byte(dev,0x24e, (BIT5|BIT6|BIT0));
2938//by amy 080312}
2939 rtl8180_reset(dev);
2940
2941 priv->dma_poll_mask = 0;
2942 priv->dma_poll_stop_mask = 0;
2943
2944 //rtl8180_beacon_tx_disable(dev);
2945
2946 HwConfigureRTL8185(dev);
2947
2948 write_nic_dword(dev, MAC0, ((u32*)dev->dev_addr)[0]);
2949 write_nic_word(dev, MAC4, ((u32*)dev->dev_addr)[1] & 0xffff );
2950
2951 write_nic_byte(dev, MSR, read_nic_byte(dev, MSR) & 0xf3); // default network type to 'No Link'
2952
2953 //write_nic_byte(dev, BRSR, 0x0); // Set BRSR= 1M
2954
2955 write_nic_word(dev, BcnItv, 100);
2956 write_nic_word(dev, AtimWnd, 2);
2957
2958 //PlatformEFIOWrite2Byte(dev, FEMR, 0xFFFF);
2959 PlatformIOWrite2Byte(dev, FEMR, 0xFFFF);
2960
2961 write_nic_byte(dev, WPA_CONFIG, 0);
2962
2963 MacConfig_85BASIC(dev);
2964
2965 // Override the RFSW_CTRL (MAC offset 0x272-0x273), 2006.06.07, by rcnjko.
2966 // BT_DEMO_BOARD type
2967 PlatformIOWrite2Byte(dev, RFSW_CTRL, 0x569a);
2968//by amy
2969//#ifdef CONFIG_RTL818X_S
2970 // for jong required
2971// PlatformIOWrite2Byte(dev, RFSW_CTRL, 0x9a56);
2972//#endif
2973//by amy
2974 //BT_QA_BOARD
2975 //PlatformIOWrite2Byte(dev, RFSW_CTRL, 0x9a56);
2976
2977 //-----------------------------------------------------------------------------
2978 // Set up PHY related.
2979 //-----------------------------------------------------------------------------
2980 // Enable Config3.PARAM_En to revise AnaaParm.
2981 write_nic_byte(dev, CR9346, 0xc0); // enable config register write
2982//by amy
2983 tmpu8 = read_nic_byte(dev, CONFIG3);
2984#ifdef CONFIG_RTL818X_S
2985 write_nic_byte(dev, CONFIG3, (tmpu8 |CONFIG3_PARM_En) );
2986#else
2987 write_nic_byte(dev, CONFIG3, (tmpu8 |CONFIG3_PARM_En | CONFIG3_CLKRUN_En) );
2988#endif
2989//by amy
2990 // Turn on Analog power.
2991 // Asked for by William, otherwise, MAC 3-wire can't work, 2006.06.27, by rcnjko.
2992 write_nic_dword(dev, ANAPARAM2, ANAPARM2_ASIC_ON);
2993 write_nic_dword(dev, ANAPARAM, ANAPARM_ASIC_ON);
2994//by amy
2995#ifdef CONFIG_RTL818X_S
2996 write_nic_word(dev, ANAPARAM3, 0x0010);
2997#else
2998 write_nic_byte(dev, ANAPARAM3, 0x00);
2999#endif
3000//by amy
3001
3002 write_nic_byte(dev, CONFIG3, tmpu8);
3003 write_nic_byte(dev, CR9346, 0x00);
3004//{by amy 080312 for led
3005 // enable EEM0 and EEM1 in 9346CR
3006 btCR9346 = read_nic_byte(dev, CR9346);
3007 write_nic_byte(dev, CR9346, (btCR9346|0xC0) );
3008
3009 // B cut use LED1 to control HW RF on/off
3010 TmpU1b = read_nic_byte(dev, CONFIG5);
3011 TmpU1b = TmpU1b & ~BIT3;
3012 write_nic_byte(dev,CONFIG5, TmpU1b);
3013
3014 // disable EEM0 and EEM1 in 9346CR
3015 btCR9346 &= ~(0xC0);
3016 write_nic_byte(dev, CR9346, btCR9346);
3017
3018 //Enable Led (suggested by Jong)
3019 // B-cut RF Radio on/off 5e[3]=0
3020 btPSR = read_nic_byte(dev, PSR);
3021 write_nic_byte(dev, PSR, (btPSR | BIT3));
3022//by amy 080312 for led}
3023 // setup initial timing for RFE.
3024 write_nic_word(dev, RFPinsOutput, 0x0480);
3025 SetOutputEnableOfRfPins(dev);
3026 write_nic_word(dev, RFPinsSelect, 0x2488);
3027
3028 // PHY config.
3029 PhyConfig8185(dev);
3030
3031 // We assume RegWirelessMode has already been initialized before,
3032 // however, we has to validate the wireless mode here and provide a reasonble
3033 // initialized value if necessary. 2005.01.13, by rcnjko.
3034 SupportedWirelessMode = GetSupportedWirelessMode8185(dev);
3035 if( (ieee->mode != WIRELESS_MODE_B) &&
3036 (ieee->mode != WIRELESS_MODE_G) &&
3037 (ieee->mode != WIRELESS_MODE_A) &&
3038 (ieee->mode != WIRELESS_MODE_AUTO))
3039 { // It should be one of B, G, A, or AUTO.
3040 bInvalidWirelessMode = 1;
3041 }
3042 else
3043 { // One of B, G, A, or AUTO.
3044 // Check if the wireless mode is supported by RF.
3045 if( (ieee->mode != WIRELESS_MODE_AUTO) &&
3046 (ieee->mode & SupportedWirelessMode) == 0 )
3047 {
3048 bInvalidWirelessMode = 1;
3049 }
3050 }
3051
3052 if(bInvalidWirelessMode || ieee->mode==WIRELESS_MODE_AUTO)
3053 { // Auto or other invalid value.
3054 // Assigne a wireless mode to initialize.
3055 if((SupportedWirelessMode & WIRELESS_MODE_A))
3056 {
3057 InitWirelessMode = WIRELESS_MODE_A;
3058 }
3059 else if((SupportedWirelessMode & WIRELESS_MODE_G))
3060 {
3061 InitWirelessMode = WIRELESS_MODE_G;
3062 }
3063 else if((SupportedWirelessMode & WIRELESS_MODE_B))
3064 {
3065 InitWirelessMode = WIRELESS_MODE_B;
3066 }
3067 else
3068 {
3069 DMESGW("InitializeAdapter8185(): No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n",
3070 SupportedWirelessMode);
3071 InitWirelessMode = WIRELESS_MODE_B;
3072 }
3073
3074 // Initialize RegWirelessMode if it is not a valid one.
3075 if(bInvalidWirelessMode)
3076 {
3077 ieee->mode = (WIRELESS_MODE)InitWirelessMode;
3078 }
3079 }
3080 else
3081 { // One of B, G, A.
3082 InitWirelessMode = ieee->mode;
3083 }
3084//by amy for power save
3085#ifdef ENABLE_IPS
3086// printk("initialize ENABLE_IPS\n");
3087 priv->eRFPowerState = eRfOff;
3088 priv->RfOffReason = 0;
3089 {
3090 // u32 tmp2;
3091 // u32 tmp = jiffies;
3092 MgntActSet_RF_State(dev, eRfOn, 0);
3093 // tmp2 = jiffies;
3094 // printk("rf on cost jiffies:%lx\n", (tmp2-tmp)*1000/HZ);
3095 }
3096// DrvIFIndicateCurrentPhyStatus(priv);
3097 //
3098 // If inactive power mode is enabled, disable rf while in disconnected state.
3099 // 2007.07.16, by shien chang.
3100 //
3101 if (priv->bInactivePs)
3102 {
3103 // u32 tmp2;
3104 // u32 tmp = jiffies;
3105 MgntActSet_RF_State(dev,eRfOff, RF_CHANGE_BY_IPS);
3106 // tmp2 = jiffies;
3107 // printk("rf off cost jiffies:%lx\n", (tmp2-tmp)*1000/HZ);
3108
3109 }
3110#endif
3111// IPSEnter(dev);
3112//by amy for power save
3113#ifdef TODO
3114 // Turn off RF if necessary. 2005.08.23, by rcnjko.
3115 // We shall turn off RF after setting CMDR, otherwise,
3116 // RF will be turnned on after we enable MAC Tx/Rx.
3117 if(Adapter->MgntInfo.RegRfOff == TRUE)
3118 {
3119 SetRFPowerState8185(Adapter, RF_OFF);
3120 }
3121 else
3122 {
3123 SetRFPowerState8185(Adapter, RF_ON);
3124 }
3125#endif
3126
3127/* //these is equal with above TODO.
3128 write_nic_byte(dev, CR9346, 0xc0); // enable config register write
3129 write_nic_byte(dev, CONFIG3, read_nic_byte(dev, CONFIG3) | CONFIG3_PARM_En);
3130 RF_WriteReg(dev, 0x4, 0x9FF);
3131 write_nic_dword(dev, ANAPARAM2, ANAPARM2_ASIC_ON);
3132 write_nic_dword(dev, ANAPARAM, ANAPARM_ASIC_ON);
3133 write_nic_byte(dev, CONFIG3, (read_nic_byte(dev, CONFIG3)&(~CONFIG3_PARM_En)));
3134 write_nic_byte(dev, CR9346, 0x00);
3135*/
3136
3137 ActSetWirelessMode8185(dev, (u8)(InitWirelessMode));
3138
3139 //-----------------------------------------------------------------------------
3140
3141 rtl8185b_irq_enable(dev);
3142
3143 netif_start_queue(dev);
3144
3145 }
3146
3147
3148void rtl8185b_rx_enable(struct net_device *dev)
3149{
3150 u8 cmd;
3151 //u32 rxconf;
3152 /* for now we accept data, management & ctl frame*/
3153 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
3154#if 0
3155 rxconf=read_nic_dword(dev,RX_CONF);
3156 rxconf = rxconf &~ MAC_FILTER_MASK;
3157 rxconf = rxconf | (1<<ACCEPT_MNG_FRAME_SHIFT);
3158 rxconf = rxconf | (1<<ACCEPT_DATA_FRAME_SHIFT);
3159 rxconf = rxconf | (1<<ACCEPT_BCAST_FRAME_SHIFT);
3160 rxconf = rxconf | (1<<ACCEPT_MCAST_FRAME_SHIFT);
3161// rxconf = rxconf | (1<<ACCEPT_CRCERR_FRAME_SHIFT);
3162 if (dev->flags & IFF_PROMISC) DMESG ("NIC in promisc mode");
3163
3164 if(priv->ieee80211->iw_mode == IW_MODE_MONITOR || \
3165 dev->flags & IFF_PROMISC){
3166 rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT);
3167 }else{
3168 rxconf = rxconf | (1<<ACCEPT_NICMAC_FRAME_SHIFT);
3169 if(priv->card_8185 == 0)
3170 rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT);
3171 }
3172
3173 /*if(priv->ieee80211->iw_mode == IW_MODE_MASTER){
3174 rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT);
3175 rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT);
3176 }*/
3177
3178 if(priv->ieee80211->iw_mode == IW_MODE_MONITOR){
3179 rxconf = rxconf | (1<<ACCEPT_CTL_FRAME_SHIFT);
3180 rxconf = rxconf | (1<<ACCEPT_ICVERR_FRAME_SHIFT);
3181 rxconf = rxconf | (1<<ACCEPT_PWR_FRAME_SHIFT);
3182 }
3183
3184 if( priv->crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR)
3185 rxconf = rxconf | (1<<ACCEPT_CRCERR_FRAME_SHIFT);
3186
3187 //if(!priv->card_8185){
3188 rxconf = rxconf &~ RX_FIFO_THRESHOLD_MASK;
3189 rxconf = rxconf | (RX_FIFO_THRESHOLD_NONE<<RX_FIFO_THRESHOLD_SHIFT);
3190 //}
3191
3192 rxconf = rxconf | (1<<RX_AUTORESETPHY_SHIFT);
3193 rxconf = rxconf &~ MAX_RX_DMA_MASK;
3194 rxconf = rxconf | (MAX_RX_DMA_2048<<MAX_RX_DMA_SHIFT);
3195
3196 //if(!priv->card_8185)
3197 rxconf = rxconf | RCR_ONLYERLPKT;
3198
3199 rxconf = rxconf &~ RCR_CS_MASK;
3200 if(!priv->card_8185)
3201 rxconf |= (priv->rcr_csense<<RCR_CS_SHIFT);
3202// rxconf &=~ 0xfff00000;
3203// rxconf |= 0x90100000;//9014f76f;
3204 write_nic_dword(dev, RX_CONF, rxconf);
3205#endif
3206
3207 if (dev->flags & IFF_PROMISC) DMESG ("NIC in promisc mode");
3208
3209 if(priv->ieee80211->iw_mode == IW_MODE_MONITOR || \
3210 dev->flags & IFF_PROMISC){
3211 priv->ReceiveConfig = priv->ReceiveConfig & (~RCR_APM);
3212 priv->ReceiveConfig = priv->ReceiveConfig | RCR_AAP;
3213 }
3214
3215 /*if(priv->ieee80211->iw_mode == IW_MODE_MASTER){
3216 rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT);
3217 rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT);
3218 }*/
3219
3220 if(priv->ieee80211->iw_mode == IW_MODE_MONITOR){
3221 priv->ReceiveConfig = priv->ReceiveConfig | RCR_ACF | RCR_APWRMGT | RCR_AICV;
3222 }
3223
3224 if( priv->crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR)
3225 priv->ReceiveConfig = priv->ReceiveConfig | RCR_ACRC32;
3226
3227 write_nic_dword(dev, RCR, priv->ReceiveConfig);
3228
3229 fix_rx_fifo(dev);
3230
3231#ifdef DEBUG_RX
3232 DMESG("rxconf: %x %x",priv->ReceiveConfig ,read_nic_dword(dev,RCR));
3233#endif
3234 cmd=read_nic_byte(dev,CMD);
3235 write_nic_byte(dev,CMD,cmd | (1<<CMD_RX_ENABLE_SHIFT));
3236
3237}
3238
3239void rtl8185b_tx_enable(struct net_device *dev)
3240{
3241 u8 cmd;
3242 //u8 tx_agc_ctl;
3243 u8 byte;
3244 //u32 txconf;
3245 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
3246
3247#if 0
3248 txconf= read_nic_dword(dev,TX_CONF);
3249 if(priv->card_8185){
3250
3251
3252 byte = read_nic_byte(dev,CW_CONF);
3253 byte &= ~(1<<CW_CONF_PERPACKET_CW_SHIFT);
3254 byte &= ~(1<<CW_CONF_PERPACKET_RETRY_SHIFT);
3255 write_nic_byte(dev, CW_CONF, byte);
3256
3257 tx_agc_ctl = read_nic_byte(dev, TX_AGC_CTL);
3258 tx_agc_ctl &= ~(1<<TX_AGC_CTL_PERPACKET_GAIN_SHIFT);
3259 tx_agc_ctl &= ~(1<<TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT);
3260 tx_agc_ctl |=(1<<TX_AGC_CTL_FEEDBACK_ANT);
3261 write_nic_byte(dev, TX_AGC_CTL, tx_agc_ctl);
3262 /*
3263 write_nic_word(dev, 0x5e, 0x01);
3264 force_pci_posting(dev);
3265 mdelay(1);
3266 write_nic_word(dev, 0xfe, 0x10);
3267 force_pci_posting(dev);
3268 mdelay(1);
3269 write_nic_word(dev, 0x5e, 0x00);
3270 force_pci_posting(dev);
3271 mdelay(1);
3272 */
3273 write_nic_byte(dev, 0xec, 0x3f); /* Disable early TX */
3274 }
3275
3276 if(priv->card_8185){
3277
3278 txconf = txconf &~ (1<<TCR_PROBE_NOTIMESTAMP_SHIFT);
3279
3280 }else{
3281
3282 if(hwseqnum)
3283 txconf= txconf &~ (1<<TX_CONF_HEADER_AUTOICREMENT_SHIFT);
3284 else
3285 txconf= txconf | (1<<TX_CONF_HEADER_AUTOICREMENT_SHIFT);
3286 }
3287
3288 txconf = txconf &~ TX_LOOPBACK_MASK;
3289 txconf = txconf | (TX_LOOPBACK_NONE <<TX_LOOPBACK_SHIFT);
3290 txconf = txconf &~ TCR_DPRETRY_MASK;
3291 txconf = txconf &~ TCR_RTSRETRY_MASK;
3292 txconf = txconf | (priv->retry_data<<TX_DPRETRY_SHIFT);
3293 txconf = txconf | (priv->retry_rts<<TX_RTSRETRY_SHIFT);
3294 txconf = txconf &~ (1<<TX_NOCRC_SHIFT);
3295
3296 if(priv->card_8185){
3297 if(priv->hw_plcp_len)
3298 txconf = txconf &~ TCR_PLCP_LEN;
3299 else
3300 txconf = txconf | TCR_PLCP_LEN;
3301 }else{
3302 txconf = txconf &~ TCR_SAT;
3303 }
3304 txconf = txconf &~ TCR_MXDMA_MASK;
3305 txconf = txconf | (TCR_MXDMA_2048<<TCR_MXDMA_SHIFT);
3306 txconf = txconf | TCR_CWMIN;
3307 txconf = txconf | TCR_DISCW;
3308
3309// if(priv->ieee80211->hw_wep)
3310// txconf=txconf &~ (1<<TX_NOICV_SHIFT);
3311// else
3312 txconf=txconf | (1<<TX_NOICV_SHIFT);
3313
3314 write_nic_dword(dev,TX_CONF,txconf);
3315#endif
3316
3317 write_nic_dword(dev, TCR, priv->TransmitConfig);
3318 byte = read_nic_byte(dev, MSR);
3319 byte |= MSR_LINK_ENEDCA;
3320 write_nic_byte(dev, MSR, byte);
3321
3322 fix_tx_fifo(dev);
3323
3324#ifdef DEBUG_TX
3325 DMESG("txconf: %x %x",priv->TransmitConfig,read_nic_dword(dev,TCR));
3326#endif
3327
3328 cmd=read_nic_byte(dev,CMD);
3329 write_nic_byte(dev,CMD,cmd | (1<<CMD_TX_ENABLE_SHIFT));
3330
3331 //write_nic_dword(dev,TX_CONF,txconf);
3332
3333
3334/*
3335 rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
3336 write_nic_byte(dev, TX_DMA_POLLING, priv->dma_poll_mask);
3337 rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
3338 */
3339}
3340
3341
3342#endif