diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-22 10:38:37 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-22 10:38:37 -0500 |
commit | fcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch) | |
tree | a57612d1888735a2ec7972891b68c1ac5ec8faea /drivers/staging/ath6kl/wlan | |
parent | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff) |
Diffstat (limited to 'drivers/staging/ath6kl/wlan')
-rw-r--r-- | drivers/staging/ath6kl/wlan/include/ieee80211.h | 397 | ||||
-rw-r--r-- | drivers/staging/ath6kl/wlan/include/ieee80211_node.h | 93 | ||||
-rw-r--r-- | drivers/staging/ath6kl/wlan/src/wlan_node.c | 636 | ||||
-rw-r--r-- | drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c | 199 | ||||
-rw-r--r-- | drivers/staging/ath6kl/wlan/src/wlan_utils.c | 58 |
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 | */ | ||
99 | PREPACK 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 | |||
110 | PREPACK 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 | |||
214 | enum { | ||
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 | |||
302 | typedef 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 | */ | ||
320 | typedef 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 | |||
383 | enum 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 | */ | ||
67 | struct 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 | |||
42 | static struct ath_debug_mask_description wlan_debug_desc[] = { | ||
43 | { ATH_DEBUG_WLAN , "General WLAN Node Tracing"}, | ||
44 | }; | ||
45 | |||
46 | ATH_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 | ||
56 | static void wlan_node_timeout(unsigned long arg); | ||
57 | #endif | ||
58 | |||
59 | static bss_t * _ieee80211_find_node (struct ieee80211_node_table *nt, | ||
60 | const u8 *macaddr); | ||
61 | |||
62 | bss_t * | ||
63 | wlan_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 | |||
102 | void | ||
103 | wlan_node_free(bss_t *ni) | ||
104 | { | ||
105 | if (ni->ni_buf != NULL) { | ||
106 | kfree(ni->ni_buf); | ||
107 | } | ||
108 | kfree(ni); | ||
109 | } | ||
110 | |||
111 | void | ||
112 | wlan_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 | |||
160 | static 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 | |||
179 | bss_t * | ||
180 | wlan_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 | */ | ||
195 | void | ||
196 | wlan_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 | |||
241 | static void | ||
242 | wlan_node_dec_free(bss_t *ni) | ||
243 | { | ||
244 | if (ieee80211_node_dectestref(ni)) { | ||
245 | wlan_node_free(ni); | ||
246 | } | ||
247 | } | ||
248 | |||
249 | void | ||
250 | wlan_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 | |||
259 | void | ||
260 | wlan_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 | */ | ||
283 | void | ||
284 | wlan_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 | |||
317 | void | ||
318 | wlan_set_nodeage(struct ieee80211_node_table *nt, u32 nodeAge) | ||
319 | { | ||
320 | nt->nt_nodeAge = nodeAge; | ||
321 | return; | ||
322 | } | ||
323 | void | ||
324 | wlan_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 | ||
376 | static void | ||
377 | wlan_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 | |||
422 | void | ||
423 | wlan_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 | |||
433 | bss_t * | ||
434 | wlan_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 | |||
479 | void | ||
480 | wlan_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 | |||
487 | void | ||
488 | wlan_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 | |||
528 | bss_t * | ||
529 | wlan_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 | |||
555 | bss_t * | ||
556 | wlan_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 | |||
60 | static int __inline | ||
61 | iswpaoui(const u8 *frm) | ||
62 | { | ||
63 | return frm[1] > 3 && LE_READ_4(frm+2) == ((WPA_OUI_TYPE<<24)|WPA_OUI); | ||
64 | } | ||
65 | |||
66 | static int __inline | ||
67 | iswmmoui(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 | ||
74 | static int __inline | ||
75 | iswmmparam(const u8 *frm) | ||
76 | { | ||
77 | return frm[1] > 5 && frm[6] == WMM_PARAM_OUI_SUBTYPE; | ||
78 | } | ||
79 | |||
80 | static int __inline | ||
81 | iswmminfo(const u8 *frm) | ||
82 | { | ||
83 | return frm[1] > 5 && frm[6] == WMM_INFO_OUI_SUBTYPE; | ||
84 | } | ||
85 | #endif | ||
86 | |||
87 | static int __inline | ||
88 | isatherosoui(const u8 *frm) | ||
89 | { | ||
90 | return frm[1] > 3 && LE_READ_4(frm+2) == ((ATH_OUI_TYPE<<24)|ATH_OUI); | ||
91 | } | ||
92 | |||
93 | static int __inline | ||
94 | iswscoui(const u8 *frm) | ||
95 | { | ||
96 | return frm[1] > 3 && LE_READ_4(frm+2) == ((0x04<<24)|WPA_OUI); | ||
97 | } | ||
98 | |||
99 | int | ||
100 | wlan_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 | */ | ||
32 | u16 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 | */ | ||
49 | u32 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 | } | ||