aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/ath6kl/wlan
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
commitfcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch)
treea57612d1888735a2ec7972891b68c1ac5ec8faea /drivers/staging/ath6kl/wlan
parent8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff)
Added missing tegra files.HEADmaster
Diffstat (limited to 'drivers/staging/ath6kl/wlan')
-rw-r--r--drivers/staging/ath6kl/wlan/include/ieee80211.h397
-rw-r--r--drivers/staging/ath6kl/wlan/include/ieee80211_node.h93
-rw-r--r--drivers/staging/ath6kl/wlan/src/wlan_node.c636
-rw-r--r--drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c199
-rw-r--r--drivers/staging/ath6kl/wlan/src/wlan_utils.c58
5 files changed, 1383 insertions, 0 deletions
diff --git a/drivers/staging/ath6kl/wlan/include/ieee80211.h b/drivers/staging/ath6kl/wlan/include/ieee80211.h
new file mode 100644
index 00000000000..cf47d0657e7
--- /dev/null
+++ b/drivers/staging/ath6kl/wlan/include/ieee80211.h
@@ -0,0 +1,397 @@
1//------------------------------------------------------------------------------
2// <copyright file="ieee80211.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23#ifndef _NET80211_IEEE80211_H_
24#define _NET80211_IEEE80211_H_
25
26/*
27 * 802.11 protocol definitions.
28 */
29#define IEEE80211_WEP_KEYLEN 5 /* 40bit */
30#define IEEE80211_WEP_IVLEN 3 /* 24bit */
31#define IEEE80211_WEP_KIDLEN 1 /* 1 octet */
32#define IEEE80211_WEP_CRCLEN 4 /* CRC-32 */
33#define IEEE80211_WEP_NKID 4 /* number of key ids */
34
35/*
36 * 802.11i defines an extended IV for use with non-WEP ciphers.
37 * When the EXTIV bit is set in the key id byte an additional
38 * 4 bytes immediately follow the IV for TKIP. For CCMP the
39 * EXTIV bit is likewise set but the 8 bytes represent the
40 * CCMP header rather than IV+extended-IV.
41 */
42#define IEEE80211_WEP_EXTIV 0x20
43#define IEEE80211_WEP_EXTIVLEN 4 /* extended IV length */
44#define IEEE80211_WEP_MICLEN 8 /* trailing MIC */
45
46#define IEEE80211_CRC_LEN 4
47
48#ifdef WAPI_ENABLE
49#define IEEE80211_WAPI_EXTIVLEN 10 /* extended IV length */
50#endif /* WAPI ENABLE */
51
52
53#define IEEE80211_ADDR_LEN 6 /* size of 802.11 address */
54/* is 802.11 address multicast/broadcast? */
55#define IEEE80211_IS_MULTICAST(_a) (*(_a) & 0x01)
56#define IEEE80211_IS_BROADCAST(_a) (*(_a) == 0xFF)
57#define WEP_HEADER (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN)
58#define WEP_TRAILER IEEE80211_WEP_CRCLEN
59#define CCMP_HEADER (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + \
60 IEEE80211_WEP_EXTIVLEN)
61#define CCMP_TRAILER IEEE80211_WEP_MICLEN
62#define TKIP_HEADER (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + \
63 IEEE80211_WEP_EXTIVLEN)
64#define TKIP_TRAILER IEEE80211_WEP_CRCLEN
65#define TKIP_MICLEN IEEE80211_WEP_MICLEN
66
67
68#define IEEE80211_ADDR_EQ(addr1, addr2) \
69 (memcmp(addr1, addr2, IEEE80211_ADDR_LEN) == 0)
70
71#define IEEE80211_ADDR_COPY(dst,src) memcpy(dst,src,IEEE80211_ADDR_LEN)
72
73#define IEEE80211_KEYBUF_SIZE 16
74#define IEEE80211_MICBUF_SIZE (8+8) /* space for both tx and rx */
75
76/*
77 * NB: these values are ordered carefully; there are lots of
78 * of implications in any reordering. In particular beware
79 * that 4 is not used to avoid conflicting with IEEE80211_F_PRIVACY.
80 */
81#define IEEE80211_CIPHER_WEP 0
82#define IEEE80211_CIPHER_TKIP 1
83#define IEEE80211_CIPHER_AES_OCB 2
84#define IEEE80211_CIPHER_AES_CCM 3
85#define IEEE80211_CIPHER_CKIP 5
86#define IEEE80211_CIPHER_CCKM_KRK 6
87#define IEEE80211_CIPHER_NONE 7 /* pseudo value */
88
89#define IEEE80211_CIPHER_MAX (IEEE80211_CIPHER_NONE+1)
90
91#define IEEE80211_IS_VALID_WEP_CIPHER_LEN(len) \
92 (((len) == 5) || ((len) == 13) || ((len) == 16))
93
94
95
96/*
97 * generic definitions for IEEE 802.11 frames
98 */
99PREPACK struct ieee80211_frame {
100 u8 i_fc[2];
101 u8 i_dur[2];
102 u8 i_addr1[IEEE80211_ADDR_LEN];
103 u8 i_addr2[IEEE80211_ADDR_LEN];
104 u8 i_addr3[IEEE80211_ADDR_LEN];
105 u8 i_seq[2];
106 /* possibly followed by addr4[IEEE80211_ADDR_LEN]; */
107 /* see below */
108} POSTPACK;
109
110PREPACK struct ieee80211_qosframe {
111 u8 i_fc[2];
112 u8 i_dur[2];
113 u8 i_addr1[IEEE80211_ADDR_LEN];
114 u8 i_addr2[IEEE80211_ADDR_LEN];
115 u8 i_addr3[IEEE80211_ADDR_LEN];
116 u8 i_seq[2];
117 u8 i_qos[2];
118} POSTPACK;
119
120#define IEEE80211_FC0_VERSION_MASK 0x03
121#define IEEE80211_FC0_VERSION_SHIFT 0
122#define IEEE80211_FC0_VERSION_0 0x00
123#define IEEE80211_FC0_TYPE_MASK 0x0c
124#define IEEE80211_FC0_TYPE_SHIFT 2
125#define IEEE80211_FC0_TYPE_MGT 0x00
126#define IEEE80211_FC0_TYPE_CTL 0x04
127#define IEEE80211_FC0_TYPE_DATA 0x08
128
129#define IEEE80211_FC0_SUBTYPE_MASK 0xf0
130#define IEEE80211_FC0_SUBTYPE_SHIFT 4
131/* for TYPE_MGT */
132#define IEEE80211_FC0_SUBTYPE_ASSOC_REQ 0x00
133#define IEEE80211_FC0_SUBTYPE_ASSOC_RESP 0x10
134#define IEEE80211_FC0_SUBTYPE_REASSOC_REQ 0x20
135#define IEEE80211_FC0_SUBTYPE_REASSOC_RESP 0x30
136#define IEEE80211_FC0_SUBTYPE_PROBE_REQ 0x40
137#define IEEE80211_FC0_SUBTYPE_PROBE_RESP 0x50
138#define IEEE80211_FC0_SUBTYPE_BEACON 0x80
139#define IEEE80211_FC0_SUBTYPE_ATIM 0x90
140#define IEEE80211_FC0_SUBTYPE_DISASSOC 0xa0
141#define IEEE80211_FC0_SUBTYPE_AUTH 0xb0
142#define IEEE80211_FC0_SUBTYPE_DEAUTH 0xc0
143/* for TYPE_CTL */
144#define IEEE80211_FC0_SUBTYPE_PS_POLL 0xa0
145#define IEEE80211_FC0_SUBTYPE_RTS 0xb0
146#define IEEE80211_FC0_SUBTYPE_CTS 0xc0
147#define IEEE80211_FC0_SUBTYPE_ACK 0xd0
148#define IEEE80211_FC0_SUBTYPE_CF_END 0xe0
149#define IEEE80211_FC0_SUBTYPE_CF_END_ACK 0xf0
150/* for TYPE_DATA (bit combination) */
151#define IEEE80211_FC0_SUBTYPE_DATA 0x00
152#define IEEE80211_FC0_SUBTYPE_CF_ACK 0x10
153#define IEEE80211_FC0_SUBTYPE_CF_POLL 0x20
154#define IEEE80211_FC0_SUBTYPE_CF_ACPL 0x30
155#define IEEE80211_FC0_SUBTYPE_NODATA 0x40
156#define IEEE80211_FC0_SUBTYPE_CFACK 0x50
157#define IEEE80211_FC0_SUBTYPE_CFPOLL 0x60
158#define IEEE80211_FC0_SUBTYPE_CF_ACK_CF_ACK 0x70
159#define IEEE80211_FC0_SUBTYPE_QOS 0x80
160#define IEEE80211_FC0_SUBTYPE_QOS_NULL 0xc0
161
162#define IEEE80211_FC1_DIR_MASK 0x03
163#define IEEE80211_FC1_DIR_NODS 0x00 /* STA->STA */
164#define IEEE80211_FC1_DIR_TODS 0x01 /* STA->AP */
165#define IEEE80211_FC1_DIR_FROMDS 0x02 /* AP ->STA */
166#define IEEE80211_FC1_DIR_DSTODS 0x03 /* AP ->AP */
167
168#define IEEE80211_FC1_MORE_FRAG 0x04
169#define IEEE80211_FC1_RETRY 0x08
170#define IEEE80211_FC1_PWR_MGT 0x10
171#define IEEE80211_FC1_MORE_DATA 0x20
172#define IEEE80211_FC1_WEP 0x40
173#define IEEE80211_FC1_ORDER 0x80
174
175#define IEEE80211_SEQ_FRAG_MASK 0x000f
176#define IEEE80211_SEQ_FRAG_SHIFT 0
177#define IEEE80211_SEQ_SEQ_MASK 0xfff0
178#define IEEE80211_SEQ_SEQ_SHIFT 4
179
180#define IEEE80211_NWID_LEN 32
181
182/*
183 * 802.11 rate set.
184 */
185#define IEEE80211_RATE_SIZE 8 /* 802.11 standard */
186#define IEEE80211_RATE_MAXSIZE 15 /* max rates we'll handle */
187
188#define WMM_NUM_AC 4 /* 4 AC categories */
189
190#define WMM_PARAM_ACI_M 0x60 /* Mask for ACI field */
191#define WMM_PARAM_ACI_S 5 /* Shift for ACI field */
192#define WMM_PARAM_ACM_M 0x10 /* Mask for ACM bit */
193#define WMM_PARAM_ACM_S 4 /* Shift for ACM bit */
194#define WMM_PARAM_AIFSN_M 0x0f /* Mask for aifsn field */
195#define WMM_PARAM_LOGCWMIN_M 0x0f /* Mask for CwMin field (in log) */
196#define WMM_PARAM_LOGCWMAX_M 0xf0 /* Mask for CwMax field (in log) */
197#define WMM_PARAM_LOGCWMAX_S 4 /* Shift for CwMax field */
198
199#define WMM_AC_TO_TID(_ac) ( \
200 ((_ac) == WMM_AC_VO) ? 6 : \
201 ((_ac) == WMM_AC_VI) ? 5 : \
202 ((_ac) == WMM_AC_BK) ? 1 : \
203 0)
204
205#define TID_TO_WMM_AC(_tid) ( \
206 ((_tid) < 1) ? WMM_AC_BE : \
207 ((_tid) < 3) ? WMM_AC_BK : \
208 ((_tid) < 6) ? WMM_AC_VI : \
209 WMM_AC_VO)
210/*
211 * Management information element payloads.
212 */
213
214enum {
215 IEEE80211_ELEMID_SSID = 0,
216 IEEE80211_ELEMID_RATES = 1,
217 IEEE80211_ELEMID_FHPARMS = 2,
218 IEEE80211_ELEMID_DSPARMS = 3,
219 IEEE80211_ELEMID_CFPARMS = 4,
220 IEEE80211_ELEMID_TIM = 5,
221 IEEE80211_ELEMID_IBSSPARMS = 6,
222 IEEE80211_ELEMID_COUNTRY = 7,
223 IEEE80211_ELEMID_CHALLENGE = 16,
224 /* 17-31 reserved for challenge text extension */
225 IEEE80211_ELEMID_PWRCNSTR = 32,
226 IEEE80211_ELEMID_PWRCAP = 33,
227 IEEE80211_ELEMID_TPCREQ = 34,
228 IEEE80211_ELEMID_TPCREP = 35,
229 IEEE80211_ELEMID_SUPPCHAN = 36,
230 IEEE80211_ELEMID_CHANSWITCH = 37,
231 IEEE80211_ELEMID_MEASREQ = 38,
232 IEEE80211_ELEMID_MEASREP = 39,
233 IEEE80211_ELEMID_QUIET = 40,
234 IEEE80211_ELEMID_IBSSDFS = 41,
235 IEEE80211_ELEMID_ERP = 42,
236 IEEE80211_ELEMID_HTCAP_ANA = 45, /* Address ANA, and non-ANA story, for interop. CL#171733 */
237 IEEE80211_ELEMID_RSN = 48,
238 IEEE80211_ELEMID_XRATES = 50,
239 IEEE80211_ELEMID_HTINFO_ANA = 61,
240#ifdef WAPI_ENABLE
241 IEEE80211_ELEMID_WAPI = 68,
242#endif
243 IEEE80211_ELEMID_TPC = 150,
244 IEEE80211_ELEMID_CCKM = 156,
245 IEEE80211_ELEMID_VENDOR = 221, /* vendor private */
246};
247
248#define ATH_OUI 0x7f0300 /* Atheros OUI */
249#define ATH_OUI_TYPE 0x01
250#define ATH_OUI_SUBTYPE 0x01
251#define ATH_OUI_VERSION 0x00
252
253#define WPA_OUI 0xf25000
254#define WPA_OUI_TYPE 0x01
255#define WPA_VERSION 1 /* current supported version */
256
257#define WPA_CSE_NULL 0x00
258#define WPA_CSE_WEP40 0x01
259#define WPA_CSE_TKIP 0x02
260#define WPA_CSE_CCMP 0x04
261#define WPA_CSE_WEP104 0x05
262
263#define WPA_ASE_NONE 0x00
264#define WPA_ASE_8021X_UNSPEC 0x01
265#define WPA_ASE_8021X_PSK 0x02
266
267#define RSN_OUI 0xac0f00
268#define RSN_VERSION 1 /* current supported version */
269
270#define RSN_CSE_NULL 0x00
271#define RSN_CSE_WEP40 0x01
272#define RSN_CSE_TKIP 0x02
273#define RSN_CSE_WRAP 0x03
274#define RSN_CSE_CCMP 0x04
275#define RSN_CSE_WEP104 0x05
276
277#define RSN_ASE_NONE 0x00
278#define RSN_ASE_8021X_UNSPEC 0x01
279#define RSN_ASE_8021X_PSK 0x02
280
281#define RSN_CAP_PREAUTH 0x01
282
283#define WMM_OUI 0xf25000
284#define WMM_OUI_TYPE 0x02
285#define WMM_INFO_OUI_SUBTYPE 0x00
286#define WMM_PARAM_OUI_SUBTYPE 0x01
287#define WMM_VERSION 1
288
289/* WMM stream classes */
290#define WMM_NUM_AC 4
291#define WMM_AC_BE 0 /* best effort */
292#define WMM_AC_BK 1 /* background */
293#define WMM_AC_VI 2 /* video */
294#define WMM_AC_VO 3 /* voice */
295
296/* TSPEC related */
297#define ACTION_CATEGORY_CODE_TSPEC 17
298#define ACTION_CODE_TSPEC_ADDTS 0
299#define ACTION_CODE_TSPEC_ADDTS_RESP 1
300#define ACTION_CODE_TSPEC_DELTS 2
301
302typedef enum {
303 TSPEC_STATUS_CODE_ADMISSION_ACCEPTED = 0,
304 TSPEC_STATUS_CODE_ADDTS_INVALID_PARAMS = 0x1,
305 TSPEC_STATUS_CODE_ADDTS_REQUEST_REFUSED = 0x3,
306 TSPEC_STATUS_CODE_UNSPECIFIED_QOS_RELATED_FAILURE = 0xC8,
307 TSPEC_STATUS_CODE_REQUESTED_REFUSED_POLICY_CONFIGURATION = 0xC9,
308 TSPEC_STATUS_CODE_INSUFFCIENT_BANDWIDTH = 0xCA,
309 TSPEC_STATUS_CODE_INVALID_PARAMS = 0xCB,
310 TSPEC_STATUS_CODE_DELTS_SENT = 0x30,
311 TSPEC_STATUS_CODE_DELTS_RECV = 0x31,
312} TSPEC_STATUS_CODE;
313
314#define TSPEC_TSID_MASK 0xF
315#define TSPEC_TSID_S 1
316
317/*
318 * WMM/802.11e Tspec Element
319 */
320typedef PREPACK struct wmm_tspec_ie_t {
321 u8 elementId;
322 u8 len;
323 u8 oui[3];
324 u8 ouiType;
325 u8 ouiSubType;
326 u8 version;
327 u16 tsInfo_info;
328 u8 tsInfo_reserved;
329 u16 nominalMSDU;
330 u16 maxMSDU;
331 u32 minServiceInt;
332 u32 maxServiceInt;
333 u32 inactivityInt;
334 u32 suspensionInt;
335 u32 serviceStartTime;
336 u32 minDataRate;
337 u32 meanDataRate;
338 u32 peakDataRate;
339 u32 maxBurstSize;
340 u32 delayBound;
341 u32 minPhyRate;
342 u16 sba;
343 u16 mediumTime;
344} POSTPACK WMM_TSPEC_IE;
345
346
347/*
348 * BEACON management packets
349 *
350 * octet timestamp[8]
351 * octet beacon interval[2]
352 * octet capability information[2]
353 * information element
354 * octet elemid
355 * octet length
356 * octet information[length]
357 */
358
359#define IEEE80211_BEACON_INTERVAL(beacon) \
360 ((beacon)[8] | ((beacon)[9] << 8))
361#define IEEE80211_BEACON_CAPABILITY(beacon) \
362 ((beacon)[10] | ((beacon)[11] << 8))
363
364#define IEEE80211_CAPINFO_ESS 0x0001
365#define IEEE80211_CAPINFO_IBSS 0x0002
366#define IEEE80211_CAPINFO_CF_POLLABLE 0x0004
367#define IEEE80211_CAPINFO_CF_POLLREQ 0x0008
368#define IEEE80211_CAPINFO_PRIVACY 0x0010
369#define IEEE80211_CAPINFO_SHORT_PREAMBLE 0x0020
370#define IEEE80211_CAPINFO_PBCC 0x0040
371#define IEEE80211_CAPINFO_CHNL_AGILITY 0x0080
372/* bits 8-9 are reserved */
373#define IEEE80211_CAPINFO_SHORT_SLOTTIME 0x0400
374#define IEEE80211_CAPINFO_APSD 0x0800
375/* bit 12 is reserved */
376#define IEEE80211_CAPINFO_DSSSOFDM 0x2000
377/* bits 14-15 are reserved */
378
379/*
380 * Authentication Modes
381 */
382
383enum ieee80211_authmode {
384 IEEE80211_AUTH_NONE = 0,
385 IEEE80211_AUTH_OPEN = 1,
386 IEEE80211_AUTH_SHARED = 2,
387 IEEE80211_AUTH_8021X = 3,
388 IEEE80211_AUTH_AUTO = 4, /* auto-select/accept */
389 /* NB: these are used only for ioctls */
390 IEEE80211_AUTH_WPA = 5, /* WPA/RSN w/ 802.1x */
391 IEEE80211_AUTH_WPA_PSK = 6, /* WPA/RSN w/ PSK */
392 IEEE80211_AUTH_WPA_CCKM = 7, /* WPA/RSN IE w/ CCKM */
393};
394
395#define IEEE80211_PS_MAX_QUEUE 50 /*Maximum no of buffers that can be queues for PS*/
396
397#endif /* _NET80211_IEEE80211_H_ */
diff --git a/drivers/staging/ath6kl/wlan/include/ieee80211_node.h b/drivers/staging/ath6kl/wlan/include/ieee80211_node.h
new file mode 100644
index 00000000000..1cb01671c0d
--- /dev/null
+++ b/drivers/staging/ath6kl/wlan/include/ieee80211_node.h
@@ -0,0 +1,93 @@
1//------------------------------------------------------------------------------
2// <copyright file="ieee80211_node.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23#ifndef _IEEE80211_NODE_H_
24#define _IEEE80211_NODE_H_
25
26/*
27 * Node locking definitions.
28 */
29#define IEEE80211_NODE_LOCK_INIT(_nt) A_MUTEX_INIT(&(_nt)->nt_nodelock)
30#define IEEE80211_NODE_LOCK_DESTROY(_nt) if (A_IS_MUTEX_VALID(&(_nt)->nt_nodelock)) { \
31 A_MUTEX_DELETE(&(_nt)->nt_nodelock); }
32
33#define IEEE80211_NODE_LOCK(_nt) A_MUTEX_LOCK(&(_nt)->nt_nodelock)
34#define IEEE80211_NODE_UNLOCK(_nt) A_MUTEX_UNLOCK(&(_nt)->nt_nodelock)
35#define IEEE80211_NODE_LOCK_BH(_nt) A_MUTEX_LOCK(&(_nt)->nt_nodelock)
36#define IEEE80211_NODE_UNLOCK_BH(_nt) A_MUTEX_UNLOCK(&(_nt)->nt_nodelock)
37#define IEEE80211_NODE_LOCK_ASSERT(_nt)
38
39/*
40 * Node reference counting definitions.
41 *
42 * ieee80211_node_initref initialize the reference count to 1
43 * ieee80211_node_incref add a reference
44 * ieee80211_node_decref remove a reference
45 * ieee80211_node_dectestref remove a reference and return 1 if this
46 * is the last reference, otherwise 0
47 * ieee80211_node_refcnt reference count for printing (only)
48 */
49#define ieee80211_node_initref(_ni) ((_ni)->ni_refcnt = 1)
50#define ieee80211_node_incref(_ni) ((_ni)->ni_refcnt++)
51#define ieee80211_node_decref(_ni) ((_ni)->ni_refcnt--)
52#define ieee80211_node_dectestref(_ni) (((_ni)->ni_refcnt--) == 1)
53#define ieee80211_node_refcnt(_ni) ((_ni)->ni_refcnt)
54
55#define IEEE80211_NODE_HASHSIZE 32
56/* simple hash is enough for variation of macaddr */
57#define IEEE80211_NODE_HASH(addr) \
58 (((const u8 *)(addr))[IEEE80211_ADDR_LEN - 1] % \
59 IEEE80211_NODE_HASHSIZE)
60
61/*
62 * Table of ieee80211_node instances. Each ieee80211com
63 * has at least one for holding the scan candidates.
64 * When operating as an access point or in ibss mode there
65 * is a second table for associated stations or neighbors.
66 */
67struct ieee80211_node_table {
68 void *nt_wmip; /* back reference */
69 A_MUTEX_T nt_nodelock; /* on node table */
70 struct bss *nt_node_first; /* information of all nodes */
71 struct bss *nt_node_last; /* information of all nodes */
72 struct bss *nt_hash[IEEE80211_NODE_HASHSIZE];
73 const char *nt_name; /* for debugging */
74 u32 nt_scangen; /* gen# for timeout scan */
75#ifdef THREAD_X
76 A_TIMER nt_inact_timer;
77 u8 isTimerArmed; /* is the node timer armed */
78#endif
79 u32 nt_nodeAge; /* node aging time */
80#ifdef OS_ROAM_MANAGEMENT
81 u32 nt_si_gen; /* gen# for scan indication*/
82#endif
83};
84
85#ifdef THREAD_X
86#define WLAN_NODE_INACT_TIMEOUT_MSEC 20000
87#else
88#define WLAN_NODE_INACT_TIMEOUT_MSEC 120000
89#endif
90
91#define WLAN_NODE_INACT_CNT 4
92
93#endif /* _IEEE80211_NODE_H_ */
diff --git a/drivers/staging/ath6kl/wlan/src/wlan_node.c b/drivers/staging/ath6kl/wlan/src/wlan_node.c
new file mode 100644
index 00000000000..0fe5f4b1346
--- /dev/null
+++ b/drivers/staging/ath6kl/wlan/src/wlan_node.c
@@ -0,0 +1,636 @@
1//------------------------------------------------------------------------------
2// <copyright file="wlan_node.c" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// IEEE 802.11 node handling support.
22//
23// Author(s): ="Atheros"
24//==============================================================================
25#include <a_config.h>
26#include <athdefs.h>
27#include <a_osapi.h>
28#define ATH_MODULE_NAME wlan
29#include <a_debug.h>
30#include "htc.h"
31#include "htc_api.h"
32#include <wmi.h>
33#include <ieee80211.h>
34#include <wlan_api.h>
35#include <wmi_api.h>
36#include <ieee80211_node.h>
37
38#define ATH_DEBUG_WLAN ATH_DEBUG_MAKE_MODULE_MASK(0)
39
40#ifdef ATH_DEBUG_MODULE
41
42static struct ath_debug_mask_description wlan_debug_desc[] = {
43 { ATH_DEBUG_WLAN , "General WLAN Node Tracing"},
44};
45
46ATH_DEBUG_INSTANTIATE_MODULE_VAR(wlan,
47 "wlan",
48 "WLAN Node Management",
49 ATH_DEBUG_MASK_DEFAULTS,
50 ATH_DEBUG_DESCRIPTION_COUNT(wlan_debug_desc),
51 wlan_debug_desc);
52
53#endif
54
55#ifdef THREAD_X
56static void wlan_node_timeout(unsigned long arg);
57#endif
58
59static bss_t * _ieee80211_find_node (struct ieee80211_node_table *nt,
60 const u8 *macaddr);
61
62bss_t *
63wlan_node_alloc(struct ieee80211_node_table *nt, int wh_size)
64{
65 bss_t *ni;
66
67 ni = A_MALLOC_NOWAIT(sizeof(bss_t));
68
69 if (ni != NULL) {
70 if (wh_size)
71 {
72 ni->ni_buf = A_MALLOC_NOWAIT(wh_size);
73 if (ni->ni_buf == NULL) {
74 kfree(ni);
75 ni = NULL;
76 return ni;
77 }
78 }
79 } else {
80 return ni;
81 }
82
83 /* Make sure our lists are clean */
84 ni->ni_list_next = NULL;
85 ni->ni_list_prev = NULL;
86 ni->ni_hash_next = NULL;
87 ni->ni_hash_prev = NULL;
88
89 //
90 // ni_scangen never initialized before and during suspend/resume of winmobile,
91 // that some junk has been stored in this, due to this scan list didn't properly updated
92 //
93 ni->ni_scangen = 0;
94
95#ifdef OS_ROAM_MANAGEMENT
96 ni->ni_si_gen = 0;
97#endif
98
99 return ni;
100}
101
102void
103wlan_node_free(bss_t *ni)
104{
105 if (ni->ni_buf != NULL) {
106 kfree(ni->ni_buf);
107 }
108 kfree(ni);
109}
110
111void
112wlan_setup_node(struct ieee80211_node_table *nt, bss_t *ni,
113 const u8 *macaddr)
114{
115 int hash;
116 u32 timeoutValue = 0;
117
118 memcpy(ni->ni_macaddr, macaddr, IEEE80211_ADDR_LEN);
119 hash = IEEE80211_NODE_HASH (macaddr);
120 ieee80211_node_initref (ni); /* mark referenced */
121
122 timeoutValue = nt->nt_nodeAge;
123
124 ni->ni_tstamp = A_GET_MS (0);
125 ni->ni_actcnt = WLAN_NODE_INACT_CNT;
126
127 IEEE80211_NODE_LOCK_BH(nt);
128
129 /* Insert at the end of the node list */
130 ni->ni_list_next = NULL;
131 ni->ni_list_prev = nt->nt_node_last;
132 if(nt->nt_node_last != NULL)
133 {
134 nt->nt_node_last->ni_list_next = ni;
135 }
136 nt->nt_node_last = ni;
137 if(nt->nt_node_first == NULL)
138 {
139 nt->nt_node_first = ni;
140 }
141
142 /* Insert into the hash list i.e. the bucket */
143 if((ni->ni_hash_next = nt->nt_hash[hash]) != NULL)
144 {
145 nt->nt_hash[hash]->ni_hash_prev = ni;
146 }
147 ni->ni_hash_prev = NULL;
148 nt->nt_hash[hash] = ni;
149
150#ifdef THREAD_X
151 if (!nt->isTimerArmed) {
152 A_TIMEOUT_MS(&nt->nt_inact_timer, timeoutValue, 0);
153 nt->isTimerArmed = true;
154 }
155#endif
156
157 IEEE80211_NODE_UNLOCK_BH(nt);
158}
159
160static bss_t *
161_ieee80211_find_node(struct ieee80211_node_table *nt,
162 const u8 *macaddr)
163{
164 bss_t *ni;
165 int hash;
166
167 IEEE80211_NODE_LOCK_ASSERT(nt);
168
169 hash = IEEE80211_NODE_HASH(macaddr);
170 for(ni = nt->nt_hash[hash]; ni; ni = ni->ni_hash_next) {
171 if (IEEE80211_ADDR_EQ(ni->ni_macaddr, macaddr)) {
172 ieee80211_node_incref(ni); /* mark referenced */
173 return ni;
174 }
175 }
176 return NULL;
177}
178
179bss_t *
180wlan_find_node(struct ieee80211_node_table *nt, const u8 *macaddr)
181{
182 bss_t *ni;
183
184 IEEE80211_NODE_LOCK(nt);
185 ni = _ieee80211_find_node(nt, macaddr);
186 IEEE80211_NODE_UNLOCK(nt);
187 return ni;
188}
189
190/*
191 * Reclaim a node. If this is the last reference count then
192 * do the normal free work. Otherwise remove it from the node
193 * table and mark it gone by clearing the back-reference.
194 */
195void
196wlan_node_reclaim(struct ieee80211_node_table *nt, bss_t *ni)
197{
198 IEEE80211_NODE_LOCK(nt);
199
200 if(ni->ni_list_prev == NULL)
201 {
202 /* First in list so fix the list head */
203 nt->nt_node_first = ni->ni_list_next;
204 }
205 else
206 {
207 ni->ni_list_prev->ni_list_next = ni->ni_list_next;
208 }
209
210 if(ni->ni_list_next == NULL)
211 {
212 /* Last in list so fix list tail */
213 nt->nt_node_last = ni->ni_list_prev;
214 }
215 else
216 {
217 ni->ni_list_next->ni_list_prev = ni->ni_list_prev;
218 }
219
220 if(ni->ni_hash_prev == NULL)
221 {
222 /* First in list so fix the list head */
223 int hash;
224 hash = IEEE80211_NODE_HASH(ni->ni_macaddr);
225 nt->nt_hash[hash] = ni->ni_hash_next;
226 }
227 else
228 {
229 ni->ni_hash_prev->ni_hash_next = ni->ni_hash_next;
230 }
231
232 if(ni->ni_hash_next != NULL)
233 {
234 ni->ni_hash_next->ni_hash_prev = ni->ni_hash_prev;
235 }
236 wlan_node_free(ni);
237
238 IEEE80211_NODE_UNLOCK(nt);
239}
240
241static void
242wlan_node_dec_free(bss_t *ni)
243{
244 if (ieee80211_node_dectestref(ni)) {
245 wlan_node_free(ni);
246 }
247}
248
249void
250wlan_free_allnodes(struct ieee80211_node_table *nt)
251{
252 bss_t *ni;
253
254 while ((ni = nt->nt_node_first) != NULL) {
255 wlan_node_reclaim(nt, ni);
256 }
257}
258
259void
260wlan_iterate_nodes(struct ieee80211_node_table *nt, wlan_node_iter_func *f,
261 void *arg)
262{
263 bss_t *ni;
264 u32 gen;
265
266 gen = ++nt->nt_scangen;
267
268 IEEE80211_NODE_LOCK(nt);
269 for (ni = nt->nt_node_first; ni; ni = ni->ni_list_next) {
270 if (ni->ni_scangen != gen) {
271 ni->ni_scangen = gen;
272 (void) ieee80211_node_incref(ni);
273 (*f)(arg, ni);
274 wlan_node_dec_free(ni);
275 }
276 }
277 IEEE80211_NODE_UNLOCK(nt);
278}
279
280/*
281 * Node table support.
282 */
283void
284wlan_node_table_init(void *wmip, struct ieee80211_node_table *nt)
285{
286 int i;
287
288 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN, ("node table = 0x%lx\n", (unsigned long)nt));
289 IEEE80211_NODE_LOCK_INIT(nt);
290
291 A_REGISTER_MODULE_DEBUG_INFO(wlan);
292
293 nt->nt_node_first = nt->nt_node_last = NULL;
294 for(i = 0; i < IEEE80211_NODE_HASHSIZE; i++)
295 {
296 nt->nt_hash[i] = NULL;
297 }
298
299#ifdef THREAD_X
300 A_INIT_TIMER(&nt->nt_inact_timer, wlan_node_timeout, nt);
301 nt->isTimerArmed = false;
302#endif
303 nt->nt_wmip = wmip;
304 nt->nt_nodeAge = WLAN_NODE_INACT_TIMEOUT_MSEC;
305
306 //
307 // nt_scangen never initialized before and during suspend/resume of winmobile,
308 // that some junk has been stored in this, due to this scan list didn't properly updated
309 //
310 nt->nt_scangen = 0;
311
312#ifdef OS_ROAM_MANAGEMENT
313 nt->nt_si_gen = 0;
314#endif
315}
316
317void
318wlan_set_nodeage(struct ieee80211_node_table *nt, u32 nodeAge)
319{
320 nt->nt_nodeAge = nodeAge;
321 return;
322}
323void
324wlan_refresh_inactive_nodes (struct ieee80211_node_table *nt)
325{
326#ifdef THREAD_X
327 bss_t *bss, *nextBss;
328 u8 myBssid[IEEE80211_ADDR_LEN], reArmTimer = false;
329
330 wmi_get_current_bssid(nt->nt_wmip, myBssid);
331
332 bss = nt->nt_node_first;
333 while (bss != NULL)
334 {
335 nextBss = bss->ni_list_next;
336 if (memcmp(myBssid, bss->ni_macaddr, sizeof(myBssid)) != 0)
337 {
338 /*
339 * free up all but the current bss - if set
340 */
341 wlan_node_reclaim(nt, bss);
342
343 }
344 bss = nextBss;
345 }
346#else
347 bss_t *bss, *nextBss;
348 u8 myBssid[IEEE80211_ADDR_LEN];
349 u32 timeoutValue = 0;
350 u32 now = A_GET_MS(0);
351 timeoutValue = nt->nt_nodeAge;
352
353 wmi_get_current_bssid(nt->nt_wmip, myBssid);
354
355 bss = nt->nt_node_first;
356 while (bss != NULL)
357 {
358 nextBss = bss->ni_list_next;
359 if (memcmp(myBssid, bss->ni_macaddr, sizeof(myBssid)) != 0)
360 {
361
362 if (((now - bss->ni_tstamp) > timeoutValue) || --bss->ni_actcnt == 0)
363 {
364 /*
365 * free up all but the current bss - if set
366 */
367 wlan_node_reclaim(nt, bss);
368 }
369 }
370 bss = nextBss;
371 }
372#endif
373}
374
375#ifdef THREAD_X
376static void
377wlan_node_timeout (unsigned long arg)
378{
379 struct ieee80211_node_table *nt = (struct ieee80211_node_table *)arg;
380 bss_t *bss, *nextBss;
381 u8 myBssid[IEEE80211_ADDR_LEN], reArmTimer = false;
382 u32 timeoutValue = 0;
383 u32 now = A_GET_MS(0);
384
385 timeoutValue = nt->nt_nodeAge;
386
387 wmi_get_current_bssid(nt->nt_wmip, myBssid);
388
389 bss = nt->nt_node_first;
390 while (bss != NULL)
391 {
392 nextBss = bss->ni_list_next;
393 if (memcmp(myBssid, bss->ni_macaddr, sizeof(myBssid)) != 0)
394 {
395
396 if ((now - bss->ni_tstamp) > timeoutValue)
397 {
398 /*
399 * free up all but the current bss - if set
400 */
401 wlan_node_reclaim(nt, bss);
402 }
403 else
404 {
405 /*
406 * Re-arm timer, only when we have a bss other than
407 * current bss AND it is not aged-out.
408 */
409 reArmTimer = true;
410 }
411 }
412 bss = nextBss;
413 }
414
415 if (reArmTimer)
416 A_TIMEOUT_MS (&nt->nt_inact_timer, timeoutValue, 0);
417
418 nt->isTimerArmed = reArmTimer;
419}
420#endif
421
422void
423wlan_node_table_cleanup(struct ieee80211_node_table *nt)
424{
425#ifdef THREAD_X
426 A_UNTIMEOUT(&nt->nt_inact_timer);
427 A_DELETE_TIMER(&nt->nt_inact_timer);
428#endif
429 wlan_free_allnodes(nt);
430 IEEE80211_NODE_LOCK_DESTROY(nt);
431}
432
433bss_t *
434wlan_find_Ssidnode (struct ieee80211_node_table *nt, u8 *pSsid,
435 u32 ssidLength, bool bIsWPA2, bool bMatchSSID)
436{
437 bss_t *ni = NULL;
438 u8 *pIESsid = NULL;
439
440 IEEE80211_NODE_LOCK (nt);
441
442 for (ni = nt->nt_node_first; ni; ni = ni->ni_list_next) {
443 pIESsid = ni->ni_cie.ie_ssid;
444 if (pIESsid[1] <= 32) {
445
446 // Step 1 : Check SSID
447 if (0x00 == memcmp (pSsid, &pIESsid[2], ssidLength)) {
448
449 //
450 // Step 2.1 : Check MatchSSID is true, if so, return Matched SSID
451 // Profile, otherwise check whether WPA2 or WPA
452 //
453 if (true == bMatchSSID) {
454 ieee80211_node_incref (ni); /* mark referenced */
455 IEEE80211_NODE_UNLOCK (nt);
456 return ni;
457 }
458
459 // Step 2 : if SSID matches, check WPA or WPA2
460 if (true == bIsWPA2 && NULL != ni->ni_cie.ie_rsn) {
461 ieee80211_node_incref (ni); /* mark referenced */
462 IEEE80211_NODE_UNLOCK (nt);
463 return ni;
464 }
465 if (false == bIsWPA2 && NULL != ni->ni_cie.ie_wpa) {
466 ieee80211_node_incref(ni); /* mark referenced */
467 IEEE80211_NODE_UNLOCK (nt);
468 return ni;
469 }
470 }
471 }
472 }
473
474 IEEE80211_NODE_UNLOCK (nt);
475
476 return NULL;
477}
478
479void
480wlan_node_return (struct ieee80211_node_table *nt, bss_t *ni)
481{
482 IEEE80211_NODE_LOCK (nt);
483 wlan_node_dec_free (ni);
484 IEEE80211_NODE_UNLOCK (nt);
485}
486
487void
488wlan_node_remove_core (struct ieee80211_node_table *nt, bss_t *ni)
489{
490 if(ni->ni_list_prev == NULL)
491 {
492 /* First in list so fix the list head */
493 nt->nt_node_first = ni->ni_list_next;
494 }
495 else
496 {
497 ni->ni_list_prev->ni_list_next = ni->ni_list_next;
498 }
499
500 if(ni->ni_list_next == NULL)
501 {
502 /* Last in list so fix list tail */
503 nt->nt_node_last = ni->ni_list_prev;
504 }
505 else
506 {
507 ni->ni_list_next->ni_list_prev = ni->ni_list_prev;
508 }
509
510 if(ni->ni_hash_prev == NULL)
511 {
512 /* First in list so fix the list head */
513 int hash;
514 hash = IEEE80211_NODE_HASH(ni->ni_macaddr);
515 nt->nt_hash[hash] = ni->ni_hash_next;
516 }
517 else
518 {
519 ni->ni_hash_prev->ni_hash_next = ni->ni_hash_next;
520 }
521
522 if(ni->ni_hash_next != NULL)
523 {
524 ni->ni_hash_next->ni_hash_prev = ni->ni_hash_prev;
525 }
526}
527
528bss_t *
529wlan_node_remove(struct ieee80211_node_table *nt, u8 *bssid)
530{
531 bss_t *bss, *nextBss;
532
533 IEEE80211_NODE_LOCK(nt);
534
535 bss = nt->nt_node_first;
536
537 while (bss != NULL)
538 {
539 nextBss = bss->ni_list_next;
540
541 if (memcmp(bssid, bss->ni_macaddr, 6) == 0)
542 {
543 wlan_node_remove_core (nt, bss);
544 IEEE80211_NODE_UNLOCK(nt);
545 return bss;
546 }
547
548 bss = nextBss;
549 }
550
551 IEEE80211_NODE_UNLOCK(nt);
552 return NULL;
553}
554
555bss_t *
556wlan_find_matching_Ssidnode (struct ieee80211_node_table *nt, u8 *pSsid,
557 u32 ssidLength, u32 dot11AuthMode, u32 authMode,
558 u32 pairwiseCryptoType, u32 grpwiseCryptoTyp)
559{
560 bss_t *ni = NULL;
561 bss_t *best_ni = NULL;
562 u8 *pIESsid = NULL;
563
564 IEEE80211_NODE_LOCK (nt);
565
566 for (ni = nt->nt_node_first; ni; ni = ni->ni_list_next) {
567 pIESsid = ni->ni_cie.ie_ssid;
568 if (pIESsid[1] <= 32) {
569
570 // Step 1 : Check SSID
571 if (0x00 == memcmp (pSsid, &pIESsid[2], ssidLength)) {
572
573 if (ni->ni_cie.ie_capInfo & 0x10)
574 {
575
576 if ((NULL != ni->ni_cie.ie_rsn) && (WPA2_PSK_AUTH == authMode))
577 {
578 /* WPA2 */
579 if (NULL == best_ni)
580 {
581 best_ni = ni;
582 }
583 else if (ni->ni_rssi > best_ni->ni_rssi)
584 {
585 best_ni = ni;
586 }
587 }
588 else if ((NULL != ni->ni_cie.ie_wpa) && (WPA_PSK_AUTH == authMode))
589 {
590 /* WPA */
591 if (NULL == best_ni)
592 {
593 best_ni = ni;
594 }
595 else if (ni->ni_rssi > best_ni->ni_rssi)
596 {
597 best_ni = ni;
598 }
599 }
600 else if (WEP_CRYPT == pairwiseCryptoType)
601 {
602 /* WEP */
603 if (NULL == best_ni)
604 {
605 best_ni = ni;
606 }
607 else if (ni->ni_rssi > best_ni->ni_rssi)
608 {
609 best_ni = ni;
610 }
611 }
612 }
613 else
614 {
615 /* open AP */
616 if ((OPEN_AUTH == authMode) && (NONE_CRYPT == pairwiseCryptoType))
617 {
618 if (NULL == best_ni)
619 {
620 best_ni = ni;
621 }
622 else if (ni->ni_rssi > best_ni->ni_rssi)
623 {
624 best_ni = ni;
625 }
626 }
627 }
628 }
629 }
630 }
631
632 IEEE80211_NODE_UNLOCK (nt);
633
634 return best_ni;
635}
636
diff --git a/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c b/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c
new file mode 100644
index 00000000000..07b8313b16e
--- /dev/null
+++ b/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c
@@ -0,0 +1,199 @@
1//------------------------------------------------------------------------------
2// <copyright file="wlan_recv_beacon.c" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// IEEE 802.11 input handling.
22//
23// Author(s): ="Atheros"
24//==============================================================================
25
26#include "a_config.h"
27#include "athdefs.h"
28#include "a_osapi.h"
29#include <wmi.h>
30#include <ieee80211.h>
31#include <wlan_api.h>
32
33#define IEEE80211_VERIFY_LENGTH(_len, _minlen) do { \
34 if ((_len) < (_minlen)) { \
35 return A_EINVAL; \
36 } \
37} while (0)
38
39#define IEEE80211_VERIFY_ELEMENT(__elem, __maxlen) do { \
40 if ((__elem) == NULL) { \
41 return A_EINVAL; \
42 } \
43 if ((__elem)[1] > (__maxlen)) { \
44 return A_EINVAL; \
45 } \
46} while (0)
47
48
49/* unaligned little endian access */
50#define LE_READ_2(p) \
51 ((u16) \
52 ((((u8 *)(p))[0] ) | (((u8 *)(p))[1] << 8)))
53
54#define LE_READ_4(p) \
55 ((u32) \
56 ((((u8 *)(p))[0] ) | (((u8 *)(p))[1] << 8) | \
57 (((u8 *)(p))[2] << 16) | (((u8 *)(p))[3] << 24)))
58
59
60static int __inline
61iswpaoui(const u8 *frm)
62{
63 return frm[1] > 3 && LE_READ_4(frm+2) == ((WPA_OUI_TYPE<<24)|WPA_OUI);
64}
65
66static int __inline
67iswmmoui(const u8 *frm)
68{
69 return frm[1] > 3 && LE_READ_4(frm+2) == ((WMM_OUI_TYPE<<24)|WMM_OUI);
70}
71
72/* unused functions for now */
73#if 0
74static int __inline
75iswmmparam(const u8 *frm)
76{
77 return frm[1] > 5 && frm[6] == WMM_PARAM_OUI_SUBTYPE;
78}
79
80static int __inline
81iswmminfo(const u8 *frm)
82{
83 return frm[1] > 5 && frm[6] == WMM_INFO_OUI_SUBTYPE;
84}
85#endif
86
87static int __inline
88isatherosoui(const u8 *frm)
89{
90 return frm[1] > 3 && LE_READ_4(frm+2) == ((ATH_OUI_TYPE<<24)|ATH_OUI);
91}
92
93static int __inline
94iswscoui(const u8 *frm)
95{
96 return frm[1] > 3 && LE_READ_4(frm+2) == ((0x04<<24)|WPA_OUI);
97}
98
99int
100wlan_parse_beacon(u8 *buf, int framelen, struct ieee80211_common_ie *cie)
101{
102 u8 *frm, *efrm;
103 u8 elemid_ssid = false;
104
105 frm = buf;
106 efrm = (u8 *) (frm + framelen);
107
108 /*
109 * beacon/probe response frame format
110 * [8] time stamp
111 * [2] beacon interval
112 * [2] capability information
113 * [tlv] ssid
114 * [tlv] supported rates
115 * [tlv] country information
116 * [tlv] parameter set (FH/DS)
117 * [tlv] erp information
118 * [tlv] extended supported rates
119 * [tlv] WMM
120 * [tlv] WPA or RSN
121 * [tlv] Atheros Advanced Capabilities
122 */
123 IEEE80211_VERIFY_LENGTH(efrm - frm, 12);
124 A_MEMZERO(cie, sizeof(*cie));
125
126 cie->ie_tstamp = frm; frm += 8;
127 cie->ie_beaconInt = A_LE2CPU16(*(u16 *)frm); frm += 2;
128 cie->ie_capInfo = A_LE2CPU16(*(u16 *)frm); frm += 2;
129 cie->ie_chan = 0;
130
131 while (frm < efrm) {
132 switch (*frm) {
133 case IEEE80211_ELEMID_SSID:
134 if (!elemid_ssid) {
135 cie->ie_ssid = frm;
136 elemid_ssid = true;
137 }
138 break;
139 case IEEE80211_ELEMID_RATES:
140 cie->ie_rates = frm;
141 break;
142 case IEEE80211_ELEMID_COUNTRY:
143 cie->ie_country = frm;
144 break;
145 case IEEE80211_ELEMID_FHPARMS:
146 break;
147 case IEEE80211_ELEMID_DSPARMS:
148 cie->ie_chan = frm[2];
149 break;
150 case IEEE80211_ELEMID_TIM:
151 cie->ie_tim = frm;
152 break;
153 case IEEE80211_ELEMID_IBSSPARMS:
154 break;
155 case IEEE80211_ELEMID_XRATES:
156 cie->ie_xrates = frm;
157 break;
158 case IEEE80211_ELEMID_ERP:
159 if (frm[1] != 1) {
160 //A_PRINTF("Discarding ERP Element - Bad Len\n");
161 return A_EINVAL;
162 }
163 cie->ie_erp = frm[2];
164 break;
165 case IEEE80211_ELEMID_RSN:
166 cie->ie_rsn = frm;
167 break;
168 case IEEE80211_ELEMID_HTCAP_ANA:
169 cie->ie_htcap = frm;
170 break;
171 case IEEE80211_ELEMID_HTINFO_ANA:
172 cie->ie_htop = frm;
173 break;
174#ifdef WAPI_ENABLE
175 case IEEE80211_ELEMID_WAPI:
176 cie->ie_wapi = frm;
177 break;
178#endif
179 case IEEE80211_ELEMID_VENDOR:
180 if (iswpaoui(frm)) {
181 cie->ie_wpa = frm;
182 } else if (iswmmoui(frm)) {
183 cie->ie_wmm = frm;
184 } else if (isatherosoui(frm)) {
185 cie->ie_ath = frm;
186 } else if(iswscoui(frm)) {
187 cie->ie_wsc = frm;
188 }
189 break;
190 default:
191 break;
192 }
193 frm += frm[1] + 2;
194 }
195 IEEE80211_VERIFY_ELEMENT(cie->ie_rates, IEEE80211_RATE_MAXSIZE);
196 IEEE80211_VERIFY_ELEMENT(cie->ie_ssid, IEEE80211_NWID_LEN);
197
198 return 0;
199}
diff --git a/drivers/staging/ath6kl/wlan/src/wlan_utils.c b/drivers/staging/ath6kl/wlan/src/wlan_utils.c
new file mode 100644
index 00000000000..bc91599d9bf
--- /dev/null
+++ b/drivers/staging/ath6kl/wlan/src/wlan_utils.c
@@ -0,0 +1,58 @@
1//------------------------------------------------------------------------------
2// <copyright file="wlan_utils.c" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// This module implements frequently used wlan utilies
22//
23// Author(s): ="Atheros"
24//==============================================================================
25#include <a_config.h>
26#include <athdefs.h>
27#include <a_osapi.h>
28
29/*
30 * converts ieee channel number to frequency
31 */
32u16 wlan_ieee2freq(int chan)
33{
34 if (chan == 14) {
35 return 2484;
36 }
37 if (chan < 14) { /* 0-13 */
38 return (2407 + (chan*5));
39 }
40 if (chan < 27) { /* 15-26 */
41 return (2512 + ((chan-15)*20));
42 }
43 return (5000 + (chan*5));
44}
45
46/*
47 * Converts MHz frequency to IEEE channel number.
48 */
49u32 wlan_freq2ieee(u16 freq)
50{
51 if (freq == 2484)
52 return 14;
53 if (freq < 2484)
54 return (freq - 2407) / 5;
55 if (freq < 5000)
56 return 15 + ((freq - 2512) / 20);
57 return (freq - 5000) / 5;
58}