Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(237)

Side by Side Diff: chromeos/drivers/ath6kl/wlan/src/wlan_node.c

Issue 646055: Atheros AR600x driver + build glue (Closed)
Patch Set: Created 10 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 //------------------------------------------------------------------------------
2 // <copyright file="wlan_node.c" company="Atheros">
3 // Copyright (c) 2004-2008 Atheros Corporation. All rights reserved.
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License version 2 as
7 // published by the Free Software Foundation;
8 //
9 // Software distributed under the License is distributed on an "AS
10 // IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
11 // implied. See the License for the specific language governing
12 // rights and limitations under the License.
13 //
14 //
15 //------------------------------------------------------------------------------
16 //==============================================================================
17 // IEEE 802.11 node handling support.
18 //
19 // Author(s): ="Atheros"
20 //==============================================================================
21 #include <a_config.h>
22 #include <athdefs.h>
23 #include <a_types.h>
24 #include <a_osapi.h>
25 #define ATH_MODULE_NAME wlan
26 #include <a_debug.h>
27 #include "htc.h"
28 #include "htc_api.h"
29 #include <wmi.h>
30 #include <ieee80211.h>
31 #include <wlan_api.h>
32 #include <wmi_api.h>
33 #include <ieee80211_node.h>
34
35 #define ATH_DEBUG_WLAN ATH_DEBUG_MAKE_MODULE_MASK(0)
36
37 #ifdef DEBUG
38
39 static ATH_DEBUG_MASK_DESCRIPTION wlan_debug_desc[] = {
40 { ATH_DEBUG_WLAN , "General WLAN Node Tracing"},
41 };
42
43 ATH_DEBUG_INSTANTIATE_MODULE_VAR(wlan,
44 "wlan",
45 "WLAN Node Management",
46 ATH_DEBUG_MASK_DEFAULTS,
47 ATH_DEBUG_DESCRIPTION_COUNT(wlan_debug_desc),
48 wlan_debug_desc);
49
50 #endif
51
52 static void wlan_node_timeout(A_ATH_TIMER arg);
53
54 static bss_t * _ieee80211_find_node (struct ieee80211_node_table *nt,
55 const A_UINT8 *macaddr);
56
57 bss_t *
58 wlan_node_alloc(struct ieee80211_node_table *nt, int wh_size)
59 {
60 bss_t *ni;
61
62 ni = A_MALLOC_NOWAIT(sizeof(bss_t));
63
64 if (ni != NULL) {
65 if (wh_size)
66 {
67 ni->ni_buf = A_MALLOC_NOWAIT(wh_size);
68 if (ni->ni_buf == NULL) {
69 A_FREE(ni);
70 ni = NULL;
71 return ni;
72 }
73 }
74 } else {
75 return ni;
76 }
77
78 /* Make sure our lists are clean */
79 ni->ni_list_next = NULL;
80 ni->ni_list_prev = NULL;
81 ni->ni_hash_next = NULL;
82 ni->ni_hash_prev = NULL;
83
84 //
85 // ni_scangen never initialized before and during suspend/resume of winmobil e,
86 // that some junk has been stored in this, due to this scan list didn't prop erly updated
87 //
88 ni->ni_scangen = 0;
89
90 #ifdef OS_ROAM_MANAGEMENT
91 ni->ni_si_gen = 0;
92 #endif
93
94 return ni;
95 }
96
97 void
98 wlan_node_free(bss_t *ni)
99 {
100 if (ni->ni_buf != NULL) {
101 A_FREE(ni->ni_buf);
102 }
103 A_FREE(ni);
104 }
105
106 void
107 wlan_setup_node(struct ieee80211_node_table *nt, bss_t *ni,
108 const A_UINT8 *macaddr)
109 {
110 int hash;
111 A_UINT32 timeoutValue = 0;
112
113 A_MEMCPY(ni->ni_macaddr, macaddr, IEEE80211_ADDR_LEN);
114 hash = IEEE80211_NODE_HASH (macaddr);
115 ieee80211_node_initref (ni); /* mark referenced */
116
117 timeoutValue = nt->nt_nodeAge;
118
119 ni->ni_tstamp = A_GET_MS (timeoutValue);
120
121 IEEE80211_NODE_LOCK_BH(nt);
122
123 /* Insert at the end of the node list */
124 ni->ni_list_next = NULL;
125 ni->ni_list_prev = nt->nt_node_last;
126 if(nt->nt_node_last != NULL)
127 {
128 nt->nt_node_last->ni_list_next = ni;
129 }
130 nt->nt_node_last = ni;
131 if(nt->nt_node_first == NULL)
132 {
133 nt->nt_node_first = ni;
134 }
135
136 /* Insert into the hash list i.e. the bucket */
137 if((ni->ni_hash_next = nt->nt_hash[hash]) != NULL)
138 {
139 nt->nt_hash[hash]->ni_hash_prev = ni;
140 }
141 ni->ni_hash_prev = NULL;
142 nt->nt_hash[hash] = ni;
143
144 if (!nt->isTimerArmed) {
145 A_TIMEOUT_MS(&nt->nt_inact_timer, timeoutValue, 0);
146 nt->isTimerArmed = TRUE;
147 }
148
149 IEEE80211_NODE_UNLOCK_BH(nt);
150 }
151
152 static bss_t *
153 _ieee80211_find_node(struct ieee80211_node_table *nt,
154 const A_UINT8 *macaddr)
155 {
156 bss_t *ni;
157 int hash;
158
159 IEEE80211_NODE_LOCK_ASSERT(nt);
160
161 hash = IEEE80211_NODE_HASH(macaddr);
162 for(ni = nt->nt_hash[hash]; ni; ni = ni->ni_hash_next) {
163 if (IEEE80211_ADDR_EQ(ni->ni_macaddr, macaddr)) {
164 ieee80211_node_incref(ni); /* mark referenced */
165 return ni;
166 }
167 }
168 return NULL;
169 }
170
171 bss_t *
172 wlan_find_node(struct ieee80211_node_table *nt, const A_UINT8 *macaddr)
173 {
174 bss_t *ni;
175
176 IEEE80211_NODE_LOCK(nt);
177 ni = _ieee80211_find_node(nt, macaddr);
178 IEEE80211_NODE_UNLOCK(nt);
179 return ni;
180 }
181
182 /*
183 * Reclaim a node. If this is the last reference count then
184 * do the normal free work. Otherwise remove it from the node
185 * table and mark it gone by clearing the back-reference.
186 */
187 void
188 wlan_node_reclaim(struct ieee80211_node_table *nt, bss_t *ni)
189 {
190 IEEE80211_NODE_LOCK(nt);
191
192 if(ni->ni_list_prev == NULL)
193 {
194 /* First in list so fix the list head */
195 nt->nt_node_first = ni->ni_list_next;
196 }
197 else
198 {
199 ni->ni_list_prev->ni_list_next = ni->ni_list_next;
200 }
201
202 if(ni->ni_list_next == NULL)
203 {
204 /* Last in list so fix list tail */
205 nt->nt_node_last = ni->ni_list_prev;
206 }
207 else
208 {
209 ni->ni_list_next->ni_list_prev = ni->ni_list_prev;
210 }
211
212 if(ni->ni_hash_prev == NULL)
213 {
214 /* First in list so fix the list head */
215 int hash;
216 hash = IEEE80211_NODE_HASH(ni->ni_macaddr);
217 nt->nt_hash[hash] = ni->ni_hash_next;
218 }
219 else
220 {
221 ni->ni_hash_prev->ni_hash_next = ni->ni_hash_next;
222 }
223
224 if(ni->ni_hash_next != NULL)
225 {
226 ni->ni_hash_next->ni_hash_prev = ni->ni_hash_prev;
227 }
228 wlan_node_free(ni);
229
230 IEEE80211_NODE_UNLOCK(nt);
231 }
232
233 static void
234 wlan_node_dec_free(bss_t *ni)
235 {
236 if (ieee80211_node_dectestref(ni)) {
237 wlan_node_free(ni);
238 }
239 }
240
241 void
242 wlan_free_allnodes(struct ieee80211_node_table *nt)
243 {
244 bss_t *ni;
245
246 while ((ni = nt->nt_node_first) != NULL) {
247 wlan_node_reclaim(nt, ni);
248 }
249 }
250
251 void
252 wlan_iterate_nodes(struct ieee80211_node_table *nt, wlan_node_iter_func *f,
253 void *arg)
254 {
255 bss_t *ni;
256 A_UINT32 gen;
257
258 gen = ++nt->nt_scangen;
259
260 IEEE80211_NODE_LOCK(nt);
261 for (ni = nt->nt_node_first; ni; ni = ni->ni_list_next) {
262 if (ni->ni_scangen != gen) {
263 ni->ni_scangen = gen;
264 (void) ieee80211_node_incref(ni);
265 (*f)(arg, ni);
266 wlan_node_dec_free(ni);
267 }
268 }
269 IEEE80211_NODE_UNLOCK(nt);
270 }
271
272 /*
273 * Node table support.
274 */
275 void
276 wlan_node_table_init(void *wmip, struct ieee80211_node_table *nt)
277 {
278 int i;
279
280 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN, ("node table = 0x%x\n", (A_UINT32)nt));
281 IEEE80211_NODE_LOCK_INIT(nt);
282
283 A_REGISTER_MODULE_DEBUG_INFO(wlan);
284
285 nt->nt_node_first = nt->nt_node_last = NULL;
286 for(i = 0; i < IEEE80211_NODE_HASHSIZE; i++)
287 {
288 nt->nt_hash[i] = NULL;
289 }
290
291 A_INIT_TIMER(&nt->nt_inact_timer, wlan_node_timeout, nt);
292 nt->isTimerArmed = FALSE;
293 nt->nt_wmip = wmip;
294 nt->nt_nodeAge = WLAN_NODE_INACT_TIMEOUT_MSEC;
295
296 //
297 // nt_scangen never initialized before and during suspend/resume of winmobil e,
298 // that some junk has been stored in this, due to this scan list didn't prop erly updated
299 //
300 nt->nt_scangen = 0;
301
302 #ifdef OS_ROAM_MANAGEMENT
303 nt->nt_si_gen = 0;
304 #endif
305 }
306
307 void
308 wlan_set_nodeage(struct ieee80211_node_table *nt, A_UINT32 nodeAge)
309 {
310 nt->nt_nodeAge = nodeAge;
311 return;
312 }
313 static void
314 wlan_node_timeout (A_ATH_TIMER arg)
315 {
316 struct ieee80211_node_table *nt = (struct ieee80211_node_table *)arg;
317 bss_t *bss, *nextBss;
318 A_UINT8 myBssid[IEEE80211_ADDR_LEN], reArmTimer = FALSE;
319 A_UINT32 timeoutValue = 0;
320
321 timeoutValue = nt->nt_nodeAge;
322
323 wmi_get_current_bssid(nt->nt_wmip, myBssid);
324
325 bss = nt->nt_node_first;
326 while (bss != NULL)
327 {
328 nextBss = bss->ni_list_next;
329 if (A_MEMCMP(myBssid, bss->ni_macaddr, sizeof(myBssid)) != 0)
330 {
331
332 if (bss->ni_tstamp <= A_GET_MS(0))
333 {
334 /*
335 * free up all but the current bss - if set
336 */
337 wlan_node_reclaim(nt, bss);
338 }
339 else
340 {
341 /*
342 * Re-arm timer, only when we have a bss other than
343 * current bss AND it is not aged-out.
344 */
345 reArmTimer = TRUE;
346 }
347 }
348 bss = nextBss;
349 }
350
351 if (reArmTimer)
352 A_TIMEOUT_MS (&nt->nt_inact_timer, timeoutValue, 0);
353
354 nt->isTimerArmed = reArmTimer;
355 }
356
357 void
358 wlan_node_table_cleanup(struct ieee80211_node_table *nt)
359 {
360 A_UNTIMEOUT(&nt->nt_inact_timer);
361 A_DELETE_TIMER(&nt->nt_inact_timer);
362 wlan_free_allnodes(nt);
363 IEEE80211_NODE_LOCK_DESTROY(nt);
364 }
365
366 bss_t *
367 wlan_find_Ssidnode (struct ieee80211_node_table *nt, A_UCHAR *pSsid,
368 A_UINT32 ssidLength, A_BOOL bIsWPA2, A_BOOL bMatchSSID)
369 {
370 bss_t *ni = NULL;
371 A_UCHAR *pIESsid = NULL;
372
373 IEEE80211_NODE_LOCK (nt);
374
375 for (ni = nt->nt_node_first; ni; ni = ni->ni_list_next) {
376 pIESsid = ni->ni_cie.ie_ssid;
377 if (pIESsid[1] <= 32) {
378
379 // Step 1 : Check SSID
380 if (0x00 == memcmp (pSsid, &pIESsid[2], ssidLength)) {
381
382 //
383 // Step 2.1 : Check MatchSSID is TRUE, if so, return Matched SSI D
384 // Profile, otherwise check whether WPA2 or WPA
385 //
386 if (TRUE == bMatchSSID) {
387 ieee80211_node_incref (ni); /* mark referenced */
388 IEEE80211_NODE_UNLOCK (nt);
389 return ni;
390 }
391
392 // Step 2 : if SSID matches, check WPA or WPA2
393 if (TRUE == bIsWPA2 && NULL != ni->ni_cie.ie_rsn) {
394 ieee80211_node_incref (ni); /* mark referenced */
395 IEEE80211_NODE_UNLOCK (nt);
396 return ni;
397 }
398 if (FALSE == bIsWPA2 && NULL != ni->ni_cie.ie_wpa) {
399 ieee80211_node_incref(ni); /* mark referenced */
400 IEEE80211_NODE_UNLOCK (nt);
401 return ni;
402 }
403 }
404 }
405 }
406
407 IEEE80211_NODE_UNLOCK (nt);
408
409 return NULL;
410 }
411
412 void
413 wlan_node_return (struct ieee80211_node_table *nt, bss_t *ni)
414 {
415 IEEE80211_NODE_LOCK (nt);
416 wlan_node_dec_free (ni);
417 IEEE80211_NODE_UNLOCK (nt);
418 }
419
420 void
421 wlan_node_remove_core (struct ieee80211_node_table *nt, bss_t *ni)
422 {
423 if(ni->ni_list_prev == NULL)
424 {
425 /* First in list so fix the list head */
426 nt->nt_node_first = ni->ni_list_next;
427 }
428 else
429 {
430 ni->ni_list_prev->ni_list_next = ni->ni_list_next;
431 }
432
433 if(ni->ni_list_next == NULL)
434 {
435 /* Last in list so fix list tail */
436 nt->nt_node_last = ni->ni_list_prev;
437 }
438 else
439 {
440 ni->ni_list_next->ni_list_prev = ni->ni_list_prev;
441 }
442
443 if(ni->ni_hash_prev == NULL)
444 {
445 /* First in list so fix the list head */
446 int hash;
447 hash = IEEE80211_NODE_HASH(ni->ni_macaddr);
448 nt->nt_hash[hash] = ni->ni_hash_next;
449 }
450 else
451 {
452 ni->ni_hash_prev->ni_hash_next = ni->ni_hash_next;
453 }
454
455 if(ni->ni_hash_next != NULL)
456 {
457 ni->ni_hash_next->ni_hash_prev = ni->ni_hash_prev;
458 }
459 }
460
461 bss_t *
462 wlan_node_remove(struct ieee80211_node_table *nt, A_UINT8 *bssid)
463 {
464 bss_t *bss, *nextBss;
465
466 IEEE80211_NODE_LOCK(nt);
467
468 bss = nt->nt_node_first;
469
470 while (bss != NULL)
471 {
472 nextBss = bss->ni_list_next;
473
474 if (A_MEMCMP(bssid, bss->ni_macaddr, 6) == 0)
475 {
476 wlan_node_remove_core (nt, bss);
477 IEEE80211_NODE_UNLOCK(nt);
478 return bss;
479 }
480
481 bss = nextBss;
482 }
483
484 IEEE80211_NODE_UNLOCK(nt);
485 return NULL;
486 }
OLDNEW
« no previous file with comments | « chromeos/drivers/ath6kl/wlan/src/makefile ('k') | chromeos/drivers/ath6kl/wlan/src/wlan_recv_beacon.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698