1
2
3
4
5
6
7#define _RTW_MLME_C_
8
9#include <linux/ieee80211.h>
10
11#include <osdep_service.h>
12#include <drv_types.h>
13#include <recv_osdep.h>
14#include <xmit_osdep.h>
15#include <hal_intf.h>
16#include <mlme_osdep.h>
17#include <sta_info.h>
18#include <wifi.h>
19#include <wlan_bssdef.h>
20#include <rtw_ioctl_set.h>
21#include <linux/vmalloc.h>
22#include <linux/etherdevice.h>
23
24extern const u8 MCS_rate_1R[16];
25
26int rtw_init_mlme_priv(struct adapter *padapter)
27{
28 int i;
29 u8 *pbuf;
30 struct wlan_network *pnetwork;
31 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
32 int res = _SUCCESS;
33
34
35
36 pmlmepriv->pscanned = NULL;
37 pmlmepriv->fw_state = 0;
38 pmlmepriv->cur_network.network.InfrastructureMode = Ndis802_11AutoUnknown;
39 pmlmepriv->scan_mode = SCAN_ACTIVE;
40
41 spin_lock_init(&pmlmepriv->lock);
42 _rtw_init_queue(&pmlmepriv->free_bss_pool);
43 _rtw_init_queue(&pmlmepriv->scanned_queue);
44
45 memset(&pmlmepriv->assoc_ssid, 0, sizeof(struct ndis_802_11_ssid));
46
47 pbuf = vzalloc(array_size(MAX_BSS_CNT, sizeof(struct wlan_network)));
48
49 if (!pbuf) {
50 res = _FAIL;
51 goto exit;
52 }
53 pmlmepriv->free_bss_buf = pbuf;
54
55 pnetwork = (struct wlan_network *)pbuf;
56
57 for (i = 0; i < MAX_BSS_CNT; i++) {
58 INIT_LIST_HEAD(&pnetwork->list);
59
60 list_add_tail(&pnetwork->list, &pmlmepriv->free_bss_pool.queue);
61
62 pnetwork++;
63 }
64
65
66
67 rtw_clear_scan_deny(padapter);
68
69 rtw_init_mlme_timer(padapter);
70
71exit:
72 return res;
73}
74
75#if defined(CONFIG_88EU_AP_MODE)
76static void rtw_free_mlme_ie_data(u8 **ppie, u32 *plen)
77{
78 kfree(*ppie);
79 *plen = 0;
80 *ppie = NULL;
81}
82
83void rtw_free_mlme_priv_ie_data(struct mlme_priv *pmlmepriv)
84{
85 rtw_buf_free(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len);
86 rtw_buf_free(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len);
87 rtw_free_mlme_ie_data(&pmlmepriv->wps_beacon_ie, &pmlmepriv->wps_beacon_ie_len);
88 rtw_free_mlme_ie_data(&pmlmepriv->wps_probe_req_ie, &pmlmepriv->wps_probe_req_ie_len);
89 rtw_free_mlme_ie_data(&pmlmepriv->wps_probe_resp_ie, &pmlmepriv->wps_probe_resp_ie_len);
90 rtw_free_mlme_ie_data(&pmlmepriv->wps_assoc_resp_ie, &pmlmepriv->wps_assoc_resp_ie_len);
91}
92#else
93void rtw_free_mlme_priv_ie_data(struct mlme_priv *pmlmepriv)
94{
95}
96#endif
97
98void rtw_free_mlme_priv(struct mlme_priv *pmlmepriv)
99{
100 if (pmlmepriv) {
101 rtw_free_mlme_priv_ie_data(pmlmepriv);
102 vfree(pmlmepriv->free_bss_buf);
103 }
104}
105
106struct wlan_network *rtw_alloc_network(struct mlme_priv *pmlmepriv)
107
108{
109 struct wlan_network *pnetwork;
110 struct __queue *free_queue = &pmlmepriv->free_bss_pool;
111
112 spin_lock_bh(&free_queue->lock);
113 pnetwork = list_first_entry_or_null(&free_queue->queue,
114 struct wlan_network, list);
115 if (!pnetwork)
116 goto exit;
117
118 list_del_init(&pnetwork->list);
119
120 pnetwork->network_type = 0;
121 pnetwork->fixed = false;
122 pnetwork->last_scanned = jiffies;
123 pnetwork->aid = 0;
124 pnetwork->join_res = 0;
125
126exit:
127 spin_unlock_bh(&free_queue->lock);
128
129 return pnetwork;
130}
131
132static void _rtw_free_network(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork, u8 isfreeall)
133{
134 unsigned long curr_time;
135 u32 delta_time;
136 u32 lifetime = SCANQUEUE_LIFETIME;
137 struct __queue *free_queue = &pmlmepriv->free_bss_pool;
138
139 if (!pnetwork)
140 return;
141
142 if (pnetwork->fixed)
143 return;
144 curr_time = jiffies;
145 if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) ||
146 (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)))
147 lifetime = 1;
148 if (!isfreeall) {
149 delta_time = (curr_time - pnetwork->last_scanned) / HZ;
150 if (delta_time < lifetime)
151 return;
152 }
153 spin_lock_bh(&free_queue->lock);
154 list_del_init(&pnetwork->list);
155 list_add_tail(&pnetwork->list, &free_queue->queue);
156 spin_unlock_bh(&free_queue->lock);
157}
158
159static void rtw_free_network_nolock(struct mlme_priv *pmlmepriv,
160 struct wlan_network *pnetwork)
161{
162 struct __queue *free_queue = &pmlmepriv->free_bss_pool;
163
164 if (!pnetwork)
165 return;
166 if (pnetwork->fixed)
167 return;
168 list_del_init(&pnetwork->list);
169 list_add_tail(&pnetwork->list, get_list_head(free_queue));
170}
171
172
173
174
175
176
177struct wlan_network *rtw_find_network(struct __queue *scanned_queue, u8 *addr)
178{
179 struct list_head *phead, *plist;
180 struct wlan_network *pnetwork = NULL;
181
182 if (is_zero_ether_addr(addr)) {
183 pnetwork = NULL;
184 goto exit;
185 }
186 phead = get_list_head(scanned_queue);
187 list_for_each(plist, phead) {
188 pnetwork = list_entry(plist, struct wlan_network, list);
189 if (!memcmp(addr, pnetwork->network.MacAddress, ETH_ALEN))
190 break;
191 }
192 if (plist == phead)
193 pnetwork = NULL;
194exit:
195 return pnetwork;
196}
197
198void rtw_free_network_queue(struct adapter *padapter, u8 isfreeall)
199{
200 struct list_head *phead;
201 struct wlan_network *pnetwork, *temp;
202 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
203 struct __queue *scanned_queue = &pmlmepriv->scanned_queue;
204
205 spin_lock_bh(&scanned_queue->lock);
206
207 phead = get_list_head(scanned_queue);
208 list_for_each_entry_safe(pnetwork, temp, phead, list)
209 _rtw_free_network(pmlmepriv, pnetwork, isfreeall);
210
211 spin_unlock_bh(&scanned_queue->lock);
212}
213
214int rtw_if_up(struct adapter *padapter)
215{
216 int res;
217
218 if (padapter->bDriverStopped || padapter->bSurpriseRemoved ||
219 !check_fwstate(&padapter->mlmepriv, _FW_LINKED))
220 res = false;
221 else
222 res = true;
223 return res;
224}
225
226void rtw_generate_random_ibss(u8 *pibss)
227{
228 unsigned long curtime = jiffies;
229
230 pibss[0] = 0x02;
231 pibss[1] = 0x11;
232 pibss[2] = 0x87;
233 pibss[3] = (u8)(curtime & 0xff);
234 pibss[4] = (u8)((curtime >> 8) & 0xff);
235 pibss[5] = (u8)((curtime >> 16) & 0xff);
236}
237
238u8 *rtw_get_capability_from_ie(u8 *ie)
239{
240 return ie + 8 + 2;
241}
242
243u16 rtw_get_capability(struct wlan_bssid_ex *bss)
244{
245 __le16 val;
246
247 memcpy((u8 *)&val, rtw_get_capability_from_ie(bss->ies), 2);
248
249 return le16_to_cpu(val);
250}
251
252u8 *rtw_get_beacon_interval_from_ie(u8 *ie)
253{
254 return ie + 8;
255}
256
257int rtw_is_same_ibss(struct adapter *adapter, struct wlan_network *pnetwork)
258{
259 int ret = true;
260 struct security_priv *psecuritypriv = &adapter->securitypriv;
261
262 if ((psecuritypriv->dot11PrivacyAlgrthm != _NO_PRIVACY_) &&
263 (pnetwork->network.Privacy == 0))
264 ret = false;
265 else if ((psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_) &&
266 (pnetwork->network.Privacy == 1))
267 ret = false;
268 else
269 ret = true;
270 return ret;
271}
272
273static int is_same_ess(struct wlan_bssid_ex *a, struct wlan_bssid_ex *b)
274{
275 return (a->ssid.ssid_length == b->ssid.ssid_length) &&
276 !memcmp(a->ssid.ssid, b->ssid.ssid, a->ssid.ssid_length);
277}
278
279int is_same_network(struct wlan_bssid_ex *src, struct wlan_bssid_ex *dst)
280{
281 u16 s_cap, d_cap;
282 __le16 le_scap, le_dcap;
283
284 memcpy((u8 *)&le_scap, rtw_get_capability_from_ie(src->ies), 2);
285 memcpy((u8 *)&le_dcap, rtw_get_capability_from_ie(dst->ies), 2);
286
287 s_cap = le16_to_cpu(le_scap);
288 d_cap = le16_to_cpu(le_dcap);
289
290 return ((src->ssid.ssid_length == dst->ssid.ssid_length) &&
291 (!memcmp(src->MacAddress, dst->MacAddress, ETH_ALEN)) &&
292 (!memcmp(src->ssid.ssid, dst->ssid.ssid, src->ssid.ssid_length)) &&
293 ((s_cap & WLAN_CAPABILITY_IBSS) ==
294 (d_cap & WLAN_CAPABILITY_IBSS)) &&
295 ((s_cap & WLAN_CAPABILITY_ESS) ==
296 (d_cap & WLAN_CAPABILITY_ESS)));
297}
298
299struct wlan_network *rtw_get_oldest_wlan_network(struct __queue *scanned_queue)
300{
301 struct list_head *plist, *phead;
302 struct wlan_network *pwlan = NULL;
303 struct wlan_network *oldest = NULL;
304
305 phead = get_list_head(scanned_queue);
306
307 for (plist = phead->next; plist != phead; plist = plist->next) {
308 pwlan = container_of(plist, struct wlan_network, list);
309
310 if (!pwlan->fixed) {
311 if (!oldest || time_after(oldest->last_scanned, pwlan->last_scanned))
312 oldest = pwlan;
313 }
314 }
315 return oldest;
316}
317
318void update_network(struct wlan_bssid_ex *dst, struct wlan_bssid_ex *src,
319 struct adapter *padapter, bool update_ie)
320{
321 long rssi_ori = dst->Rssi;
322 u8 sq_smp = src->PhyInfo.SignalQuality;
323 u8 ss_final;
324 u8 sq_final;
325 long rssi_final;
326
327 rtw_hal_antdiv_rssi_compared(padapter, dst, src);
328
329
330 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) &&
331 is_same_network(&padapter->mlmepriv.cur_network.network, src)) {
332
333 ss_final = padapter->recvpriv.signal_strength;
334 sq_final = padapter->recvpriv.signal_qual;
335
336 if (sq_smp != 101)
337 rssi_final = (src->Rssi + dst->Rssi * 4) / 5;
338 else
339 rssi_final = rssi_ori;
340 } else {
341 if (sq_smp != 101) {
342 ss_final = ((u32)(src->PhyInfo.SignalStrength) + (u32)(dst->PhyInfo.SignalStrength) * 4) / 5;
343 sq_final = ((u32)(src->PhyInfo.SignalQuality) + (u32)(dst->PhyInfo.SignalQuality) * 4) / 5;
344 rssi_final = (src->Rssi + dst->Rssi * 4) / 5;
345 } else {
346
347 ss_final = dst->PhyInfo.SignalStrength;
348 sq_final = dst->PhyInfo.SignalQuality;
349 rssi_final = dst->Rssi;
350 }
351 }
352 if (update_ie)
353 memcpy((u8 *)dst, (u8 *)src, get_wlan_bssid_ex_sz(src));
354 dst->PhyInfo.SignalStrength = ss_final;
355 dst->PhyInfo.SignalQuality = sq_final;
356 dst->Rssi = rssi_final;
357}
358
359static void update_current_network(struct adapter *adapter, struct wlan_bssid_ex *pnetwork)
360{
361 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
362
363 if (check_fwstate(pmlmepriv, _FW_LINKED) &&
364 is_same_network(&pmlmepriv->cur_network.network, pnetwork)) {
365 update_network(&pmlmepriv->cur_network.network, pnetwork, adapter, true);
366 rtw_update_protection(adapter, (pmlmepriv->cur_network.network.ies) + sizeof(struct ndis_802_11_fixed_ie),
367 pmlmepriv->cur_network.network.ie_length);
368 }
369}
370
371
372
373
374void rtw_update_scanned_network(struct adapter *adapter, struct wlan_bssid_ex *target)
375{
376 struct list_head *plist, *phead;
377 u32 bssid_ex_sz;
378 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
379 struct __queue *queue = &pmlmepriv->scanned_queue;
380 struct wlan_network *pnetwork = NULL;
381 struct wlan_network *oldest = NULL;
382
383 spin_lock_bh(&queue->lock);
384 phead = get_list_head(queue);
385 list_for_each(plist, phead) {
386 pnetwork = list_entry(plist, struct wlan_network, list);
387
388 if (is_same_network(&pnetwork->network, target))
389 break;
390 if ((oldest == ((struct wlan_network *)0)) ||
391 time_after(oldest->last_scanned, pnetwork->last_scanned))
392 oldest = pnetwork;
393 }
394
395
396
397 if (phead == plist) {
398 if (list_empty(&pmlmepriv->free_bss_pool.queue)) {
399
400 pnetwork = oldest;
401
402 rtw_hal_get_def_var(adapter, HAL_DEF_CURRENT_ANTENNA,
403 &target->PhyInfo.Optimum_antenna);
404 memcpy(&pnetwork->network, target,
405 get_wlan_bssid_ex_sz(target));
406
407 pnetwork->fixed = false;
408 pnetwork->last_scanned = jiffies;
409
410 pnetwork->network_type = 0;
411 pnetwork->aid = 0;
412 pnetwork->join_res = 0;
413
414
415 if (pnetwork->network.PhyInfo.SignalQuality == 101)
416 pnetwork->network.PhyInfo.SignalQuality = 0;
417 } else {
418
419
420 pnetwork = rtw_alloc_network(pmlmepriv);
421
422 if (!pnetwork)
423 goto exit;
424
425 bssid_ex_sz = get_wlan_bssid_ex_sz(target);
426 target->Length = bssid_ex_sz;
427 rtw_hal_get_def_var(adapter, HAL_DEF_CURRENT_ANTENNA,
428 &target->PhyInfo.Optimum_antenna);
429 memcpy(&pnetwork->network, target, bssid_ex_sz);
430
431 pnetwork->last_scanned = jiffies;
432
433
434 if (pnetwork->network.PhyInfo.SignalQuality == 101)
435 pnetwork->network.PhyInfo.SignalQuality = 0;
436 list_add_tail(&pnetwork->list, &queue->queue);
437 }
438 } else {
439
440
441
442
443 bool update_ie = true;
444
445 pnetwork->last_scanned = jiffies;
446
447
448 if ((pnetwork->network.ie_length > target->ie_length) && (target->Reserved[0] == 1))
449 update_ie = false;
450
451 update_network(&pnetwork->network, target, adapter, update_ie);
452 }
453
454exit:
455 spin_unlock_bh(&queue->lock);
456}
457
458static void rtw_add_network(struct adapter *adapter,
459 struct wlan_bssid_ex *pnetwork)
460{
461 update_current_network(adapter, pnetwork);
462 rtw_update_scanned_network(adapter, pnetwork);
463}
464
465
466
467
468
469
470
471
472
473static int rtw_is_desired_network(struct adapter *adapter, struct wlan_network *pnetwork)
474{
475 struct security_priv *psecuritypriv = &adapter->securitypriv;
476 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
477 u32 desired_encmode;
478 u32 privacy;
479
480
481 uint wps_ielen;
482
483 int bselected = true;
484
485 desired_encmode = psecuritypriv->ndisencryptstatus;
486 privacy = pnetwork->network.Privacy;
487
488 if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) {
489 if (rtw_get_wps_ie(pnetwork->network.ies + _FIXED_IE_LENGTH_, pnetwork->network.ie_length - _FIXED_IE_LENGTH_, NULL, &wps_ielen))
490 return true;
491 else
492 return false;
493 }
494 if (adapter->registrypriv.wifi_spec == 1) {
495 if ((desired_encmode == Ndis802_11EncryptionDisabled) && (privacy != 0))
496 bselected = false;
497 }
498
499 if ((desired_encmode != Ndis802_11EncryptionDisabled) && (privacy == 0))
500 bselected = false;
501
502 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
503 if (pnetwork->network.InfrastructureMode != pmlmepriv->cur_network.network.InfrastructureMode)
504 bselected = false;
505 }
506
507 return bselected;
508}
509
510void rtw_survey_event_callback(struct adapter *adapter, u8 *pbuf)
511{
512 u32 len;
513 struct wlan_bssid_ex *pnetwork;
514 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
515
516 pnetwork = (struct wlan_bssid_ex *)pbuf;
517
518 len = get_wlan_bssid_ex_sz(pnetwork);
519 if (len > (sizeof(struct wlan_bssid_ex)))
520 return;
521 spin_lock_bh(&pmlmepriv->lock);
522
523
524 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
525 if (!memcmp(&pmlmepriv->cur_network.network.MacAddress, pnetwork->MacAddress, ETH_ALEN)) {
526 struct wlan_network *ibss_wlan = NULL;
527
528 memcpy(pmlmepriv->cur_network.network.ies, pnetwork->ies, 8);
529 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
530 ibss_wlan = rtw_find_network(&pmlmepriv->scanned_queue, pnetwork->MacAddress);
531 if (ibss_wlan) {
532 memcpy(ibss_wlan->network.ies, pnetwork->ies, 8);
533 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
534 goto exit;
535 }
536 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
537 }
538 }
539
540
541 if (!check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) {
542 if (pnetwork->ssid.ssid[0] == 0)
543 pnetwork->ssid.ssid_length = 0;
544 rtw_add_network(adapter, pnetwork);
545 }
546
547exit:
548 spin_unlock_bh(&pmlmepriv->lock);
549}
550
551void rtw_surveydone_event_callback(struct adapter *adapter, u8 *pbuf)
552{
553 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
554
555 spin_lock_bh(&pmlmepriv->lock);
556
557 if (pmlmepriv->wps_probe_req_ie) {
558 pmlmepriv->wps_probe_req_ie_len = 0;
559 kfree(pmlmepriv->wps_probe_req_ie);
560 pmlmepriv->wps_probe_req_ie = NULL;
561 }
562
563 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) {
564 del_timer_sync(&pmlmepriv->scan_to_timer);
565 _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
566 }
567
568 rtw_set_signal_stat_timer(&adapter->recvpriv);
569
570 if (pmlmepriv->to_join) {
571 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
572 if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
573 set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
574
575 if (rtw_select_and_join_from_scanned_queue(pmlmepriv) == _SUCCESS) {
576 mod_timer(&pmlmepriv->assoc_timer,
577 jiffies + msecs_to_jiffies(MAX_JOIN_TIMEOUT));
578 } else {
579 struct wlan_bssid_ex *pdev_network = &adapter->registrypriv.dev_network;
580 u8 *pibss = adapter->registrypriv.dev_network.MacAddress;
581
582 _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
583
584 memcpy(&pdev_network->ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid));
585
586 rtw_update_registrypriv_dev_network(adapter);
587 rtw_generate_random_ibss(pibss);
588
589 pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;
590
591 rtw_createbss_cmd(adapter);
592 pmlmepriv->to_join = false;
593 }
594 }
595 } else {
596 int s_ret;
597
598 set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
599 pmlmepriv->to_join = false;
600 s_ret = rtw_select_and_join_from_scanned_queue(pmlmepriv);
601 if (s_ret == _SUCCESS) {
602 mod_timer(&pmlmepriv->assoc_timer,
603 jiffies + msecs_to_jiffies(MAX_JOIN_TIMEOUT));
604 } else if (s_ret == 2) {
605 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
606 rtw_indicate_connect(adapter);
607 } else {
608 if (pmlmepriv->to_roaming != 0) {
609 if (--pmlmepriv->to_roaming == 0 ||
610 rtw_sitesurvey_cmd(adapter, &pmlmepriv->assoc_ssid, 1, NULL, 0) != _SUCCESS) {
611 pmlmepriv->to_roaming = 0;
612 rtw_free_assoc_resources(adapter);
613 rtw_indicate_disconnect(adapter);
614 } else {
615 pmlmepriv->to_join = true;
616 }
617 }
618 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
619 }
620 }
621 }
622
623 indicate_wx_scan_complete_event(adapter);
624
625 spin_unlock_bh(&pmlmepriv->lock);
626
627 rtw_os_xmit_schedule(adapter);
628}
629
630void rtw_dummy_event_callback(struct adapter *adapter, u8 *pbuf)
631{
632}
633
634void rtw_fwdbg_event_callback(struct adapter *adapter, u8 *pbuf)
635{
636}
637
638static void free_scanqueue(struct mlme_priv *pmlmepriv)
639{
640 struct __queue *free_queue = &pmlmepriv->free_bss_pool;
641 struct __queue *scan_queue = &pmlmepriv->scanned_queue;
642 struct list_head *plist, *phead, *ptemp;
643
644 spin_lock_bh(&scan_queue->lock);
645 spin_lock_bh(&free_queue->lock);
646
647 phead = get_list_head(scan_queue);
648 plist = phead->next;
649
650 while (plist != phead) {
651 ptemp = plist->next;
652 list_del_init(plist);
653 list_add_tail(plist, &free_queue->queue);
654 plist = ptemp;
655 }
656
657 spin_unlock_bh(&free_queue->lock);
658 spin_unlock_bh(&scan_queue->lock);
659}
660
661
662
663
664void rtw_free_assoc_resources(struct adapter *adapter)
665{
666 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
667
668 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
669 rtw_free_assoc_resources_locked(adapter);
670 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
671}
672
673
674
675
676void rtw_free_assoc_resources_locked(struct adapter *adapter)
677{
678 struct wlan_network *pwlan = NULL;
679 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
680 struct sta_priv *pstapriv = &adapter->stapriv;
681 struct wlan_network *tgt_network = &pmlmepriv->cur_network;
682
683 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_AP_STATE)) {
684 struct sta_info *psta;
685
686 psta = rtw_get_stainfo(&adapter->stapriv, tgt_network->network.MacAddress);
687
688 spin_lock_bh(&pstapriv->sta_hash_lock);
689 rtw_free_stainfo(adapter, psta);
690 spin_unlock_bh(&pstapriv->sta_hash_lock);
691 }
692
693 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE)) {
694 struct sta_info *psta;
695
696 rtw_free_all_stainfo(adapter);
697
698 psta = rtw_get_bcmc_stainfo(adapter);
699 spin_lock_bh(&pstapriv->sta_hash_lock);
700 rtw_free_stainfo(adapter, psta);
701 spin_unlock_bh(&pstapriv->sta_hash_lock);
702
703 rtw_init_bcmc_stainfo(adapter);
704 }
705
706 pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.MacAddress);
707 if (pwlan)
708 pwlan->fixed = false;
709
710 if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) && (adapter->stapriv.asoc_sta_count == 1)))
711 rtw_free_network_nolock(pmlmepriv, pwlan);
712
713 pmlmepriv->key_mask = 0;
714}
715
716
717
718
719void rtw_indicate_connect(struct adapter *padapter)
720{
721 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
722
723 pmlmepriv->to_join = false;
724
725 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
726 set_fwstate(pmlmepriv, _FW_LINKED);
727
728 led_control_8188eu(padapter, LED_CTL_LINK);
729
730 rtw_os_indicate_connect(padapter);
731 }
732
733 pmlmepriv->to_roaming = 0;
734
735 rtw_set_scan_deny(padapter, 3000);
736}
737
738
739
740
741void rtw_indicate_disconnect(struct adapter *padapter)
742{
743 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
744
745 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING | WIFI_UNDER_WPS);
746
747 if (pmlmepriv->to_roaming > 0)
748 _clr_fwstate_(pmlmepriv, _FW_LINKED);
749
750 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) ||
751 (pmlmepriv->to_roaming <= 0)) {
752 rtw_os_indicate_disconnect(padapter);
753
754 _clr_fwstate_(pmlmepriv, _FW_LINKED);
755 led_control_8188eu(padapter, LED_CTL_NO_LINK);
756 rtw_clear_scan_deny(padapter);
757 }
758
759 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_DISCONNECT, 1);
760}
761
762inline void rtw_indicate_scan_done(struct adapter *padapter, bool aborted)
763{
764 indicate_wx_scan_complete_event(padapter);
765}
766
767static struct sta_info *rtw_joinbss_update_stainfo(struct adapter *padapter, struct wlan_network *pnetwork)
768{
769 int i;
770 struct sta_info *bmc_sta, *psta = NULL;
771 struct recv_reorder_ctrl *preorder_ctrl;
772 struct sta_priv *pstapriv = &padapter->stapriv;
773
774 psta = rtw_get_stainfo(pstapriv, pnetwork->network.MacAddress);
775 if (!psta)
776 psta = rtw_alloc_stainfo(pstapriv, pnetwork->network.MacAddress);
777
778 if (psta) {
779 psta->aid = pnetwork->join_res;
780 psta->mac_id = 0;
781
782 rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, true);
783
784 if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) {
785 padapter->securitypriv.binstallGrpkey = false;
786 padapter->securitypriv.busetkipkey = false;
787 padapter->securitypriv.bgrpkey_handshake = false;
788 psta->ieee8021x_blocked = true;
789 psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
790 memset((u8 *)&psta->dot118021x_UncstKey, 0, sizeof(union Keytype));
791 memset((u8 *)&psta->dot11tkiprxmickey, 0, sizeof(union Keytype));
792 memset((u8 *)&psta->dot11tkiptxmickey, 0, sizeof(union Keytype));
793 memset((u8 *)&psta->dot11txpn, 0, sizeof(union pn48));
794 memset((u8 *)&psta->dot11rxpn, 0, sizeof(union pn48));
795 }
796
797
798
799
800
801
802 if (padapter->securitypriv.wps_ie_len != 0) {
803 psta->ieee8021x_blocked = true;
804 padapter->securitypriv.wps_ie_len = 0;
805 }
806
807
808
809 for (i = 0; i < 16; i++) {
810
811 preorder_ctrl = &psta->recvreorder_ctrl[i];
812 preorder_ctrl->enable = false;
813 preorder_ctrl->indicate_seq = 0xffff;
814 preorder_ctrl->wend_b = 0xffff;
815 preorder_ctrl->wsize_b = 64;
816 }
817 bmc_sta = rtw_get_bcmc_stainfo(padapter);
818 if (bmc_sta) {
819 for (i = 0; i < 16; i++) {
820
821 preorder_ctrl = &bmc_sta->recvreorder_ctrl[i];
822 preorder_ctrl->enable = false;
823 preorder_ctrl->indicate_seq = 0xffff;
824 preorder_ctrl->wend_b = 0xffff;
825 preorder_ctrl->wsize_b = 64;
826 }
827 }
828
829 update_sta_info(padapter, psta);
830 }
831 return psta;
832}
833
834
835
836static void rtw_joinbss_update_network(struct adapter *padapter, struct wlan_network *ptarget_wlan, struct wlan_network *pnetwork)
837{
838 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
839 struct wlan_network *cur_network = &pmlmepriv->cur_network;
840
841
842 memcpy(&cur_network->network, &pnetwork->network, pnetwork->network.Length);
843
844 cur_network->network.ie_length = ptarget_wlan->network.ie_length;
845 memcpy(&cur_network->network.ies[0], &ptarget_wlan->network.ies[0], MAX_IE_SZ);
846
847 cur_network->aid = pnetwork->join_res;
848
849 rtw_set_signal_stat_timer(&padapter->recvpriv);
850 padapter->recvpriv.signal_strength = ptarget_wlan->network.PhyInfo.SignalStrength;
851 padapter->recvpriv.signal_qual = ptarget_wlan->network.PhyInfo.SignalQuality;
852
853 padapter->recvpriv.rssi = translate_percentage_to_dbm(ptarget_wlan->network.PhyInfo.SignalStrength);
854 rtw_set_signal_stat_timer(&padapter->recvpriv);
855
856
857 switch (pnetwork->network.InfrastructureMode) {
858 case Ndis802_11Infrastructure:
859 if (pmlmepriv->fw_state & WIFI_UNDER_WPS)
860 pmlmepriv->fw_state = WIFI_STATION_STATE | WIFI_UNDER_WPS;
861 else
862 pmlmepriv->fw_state = WIFI_STATION_STATE;
863 break;
864 case Ndis802_11IBSS:
865 pmlmepriv->fw_state = WIFI_ADHOC_STATE;
866 break;
867 default:
868 pmlmepriv->fw_state = WIFI_NULL_STATE;
869 break;
870 }
871
872 rtw_update_protection(padapter, (cur_network->network.ies) +
873 sizeof(struct ndis_802_11_fixed_ie),
874 (cur_network->network.ie_length));
875 rtw_update_ht_cap(padapter, cur_network->network.ies, cur_network->network.ie_length);
876}
877
878
879
880
881
882
883
884
885void rtw_joinbss_event_prehandle(struct adapter *adapter, u8 *pbuf)
886{
887 struct sta_info *ptarget_sta = NULL, *pcur_sta = NULL;
888 struct sta_priv *pstapriv = &adapter->stapriv;
889 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
890 struct wlan_network *pnetwork = (struct wlan_network *)pbuf;
891 struct wlan_network *cur_network = &pmlmepriv->cur_network;
892 struct wlan_network *pcur_wlan = NULL, *ptarget_wlan = NULL;
893 unsigned int the_same_macaddr = false;
894
895 rtw_get_encrypt_decrypt_from_registrypriv(adapter);
896
897 the_same_macaddr = !memcmp(pnetwork->network.MacAddress, cur_network->network.MacAddress, ETH_ALEN);
898
899 pnetwork->network.Length = get_wlan_bssid_ex_sz(&pnetwork->network);
900 if (pnetwork->network.Length > sizeof(struct wlan_bssid_ex))
901 return;
902
903 spin_lock_bh(&pmlmepriv->lock);
904
905 if (pnetwork->join_res > 0) {
906 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
907 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) {
908
909 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
910 if (the_same_macaddr) {
911 ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.MacAddress);
912 } else {
913 pcur_wlan = rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.MacAddress);
914 if (pcur_wlan)
915 pcur_wlan->fixed = false;
916
917 pcur_sta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress);
918 if (pcur_sta) {
919 spin_lock_bh(&pstapriv->sta_hash_lock);
920 rtw_free_stainfo(adapter, pcur_sta);
921 spin_unlock_bh(&pstapriv->sta_hash_lock);
922 }
923
924 ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, pnetwork->network.MacAddress);
925 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
926 if (ptarget_wlan)
927 ptarget_wlan->fixed = true;
928 }
929 }
930 } else {
931 ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, pnetwork->network.MacAddress);
932 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
933 if (ptarget_wlan)
934 ptarget_wlan->fixed = true;
935 }
936 }
937
938
939 if (ptarget_wlan) {
940 rtw_joinbss_update_network(adapter, ptarget_wlan, pnetwork);
941 } else {
942 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
943 goto ignore_joinbss_callback;
944 }
945
946
947 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
948 ptarget_sta = rtw_joinbss_update_stainfo(adapter, pnetwork);
949 if (!ptarget_sta) {
950 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
951 goto ignore_joinbss_callback;
952 }
953 }
954
955
956 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
957 rtw_indicate_connect(adapter);
958 }
959
960
961 del_timer_sync(&pmlmepriv->assoc_timer);
962 } else {
963 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
964 goto ignore_joinbss_callback;
965 }
966
967 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
968
969 } else if (pnetwork->join_res == -4) {
970 rtw_reset_securitypriv(adapter);
971 mod_timer(&pmlmepriv->assoc_timer,
972 jiffies + msecs_to_jiffies(1));
973
974 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
975 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
976 } else {
977 mod_timer(&pmlmepriv->assoc_timer,
978 jiffies + msecs_to_jiffies(1));
979 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
980 }
981
982ignore_joinbss_callback:
983 spin_unlock_bh(&pmlmepriv->lock);
984}
985
986void rtw_joinbss_event_callback(struct adapter *adapter, u8 *pbuf)
987{
988 struct wlan_network *pnetwork = (struct wlan_network *)pbuf;
989
990 mlmeext_joinbss_event_callback(adapter, pnetwork->join_res);
991
992 rtw_os_xmit_schedule(adapter);
993}
994
995static u8 search_max_mac_id(struct adapter *padapter)
996{
997 u8 mac_id;
998#if defined(CONFIG_88EU_AP_MODE)
999 u8 aid;
1000 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1001 struct sta_priv *pstapriv = &padapter->stapriv;
1002#endif
1003 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1004 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1005
1006#if defined(CONFIG_88EU_AP_MODE)
1007 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1008 for (aid = pstapriv->max_num_sta; aid > 0; aid--) {
1009 if (pstapriv->sta_aid[aid - 1])
1010 break;
1011 }
1012 mac_id = aid + 1;
1013 } else
1014#endif
1015 {
1016 for (mac_id = NUM_STA - 1; mac_id >= IBSS_START_MAC_ID; mac_id--) {
1017 if (pmlmeinfo->FW_sta_info[mac_id].status == 1)
1018 break;
1019 }
1020 }
1021 return mac_id;
1022}
1023
1024
1025void rtw_stassoc_hw_rpt(struct adapter *adapter, struct sta_info *psta)
1026{
1027 u16 media_status;
1028 u8 macid;
1029
1030 if (!psta)
1031 return;
1032
1033 macid = search_max_mac_id(adapter);
1034 rtw_hal_set_hwreg(adapter, HW_VAR_TX_RPT_MAX_MACID, (u8 *)&macid);
1035 media_status = (psta->mac_id << 8) | 1;
1036 rtw_hal_set_hwreg(adapter, HW_VAR_H2C_MEDIA_STATUS_RPT, (u8 *)&media_status);
1037}
1038
1039void rtw_stassoc_event_callback(struct adapter *adapter, u8 *pbuf)
1040{
1041 struct sta_info *psta;
1042 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1043 struct stassoc_event *pstassoc = (struct stassoc_event *)pbuf;
1044 struct wlan_network *cur_network = &pmlmepriv->cur_network;
1045 struct wlan_network *ptarget_wlan = NULL;
1046
1047 if (!rtw_access_ctrl(adapter, pstassoc->macaddr))
1048 return;
1049
1050#if defined(CONFIG_88EU_AP_MODE)
1051 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1052 psta = rtw_get_stainfo(&adapter->stapriv, pstassoc->macaddr);
1053 if (psta) {
1054 ap_sta_info_defer_update(adapter, psta);
1055 rtw_stassoc_hw_rpt(adapter, psta);
1056 }
1057 return;
1058 }
1059#endif
1060
1061 psta = rtw_get_stainfo(&adapter->stapriv, pstassoc->macaddr);
1062 if (psta)
1063
1064 return;
1065 psta = rtw_alloc_stainfo(&adapter->stapriv, pstassoc->macaddr);
1066 if (!psta)
1067 return;
1068
1069
1070 psta->qos_option = 0;
1071 psta->mac_id = (uint)pstassoc->cam_id;
1072
1073 rtw_hal_set_odm_var(adapter, HAL_ODM_STA_INFO, psta, true);
1074 rtw_stassoc_hw_rpt(adapter, psta);
1075 if (adapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)
1076 psta->dot118021XPrivacy = adapter->securitypriv.dot11PrivacyAlgrthm;
1077 psta->ieee8021x_blocked = false;
1078 spin_lock_bh(&pmlmepriv->lock);
1079 if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) ||
1080 (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE))) {
1081 if (adapter->stapriv.asoc_sta_count == 2) {
1082 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
1083 ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.MacAddress);
1084 if (ptarget_wlan)
1085 ptarget_wlan->fixed = true;
1086 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1087
1088 rtw_indicate_connect(adapter);
1089 }
1090 }
1091 spin_unlock_bh(&pmlmepriv->lock);
1092 mlmeext_sta_add_event_callback(adapter, psta);
1093}
1094
1095void rtw_stadel_event_callback(struct adapter *adapter, u8 *pbuf)
1096{
1097 int mac_id = -1;
1098 struct sta_info *psta;
1099 struct wlan_network *pwlan = NULL;
1100 struct wlan_bssid_ex *pdev_network = NULL;
1101 u8 *pibss = NULL;
1102 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1103 struct stadel_event *pstadel = (struct stadel_event *)pbuf;
1104 struct sta_priv *pstapriv = &adapter->stapriv;
1105 struct wlan_network *tgt_network = &pmlmepriv->cur_network;
1106
1107 psta = rtw_get_stainfo(&adapter->stapriv, pstadel->macaddr);
1108 if (psta)
1109 mac_id = psta->mac_id;
1110 else
1111 mac_id = pstadel->mac_id;
1112
1113 if (mac_id >= 0) {
1114 u16 media_status;
1115
1116 media_status = (mac_id << 8) | 0;
1117
1118 rtw_hal_set_hwreg(adapter, HW_VAR_H2C_MEDIA_STATUS_RPT, (u8 *)&media_status);
1119 }
1120
1121 if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
1122 return;
1123
1124 mlmeext_sta_del_event_callback(adapter);
1125
1126 spin_lock_bh(&pmlmepriv->lock);
1127
1128 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
1129 if (pmlmepriv->to_roaming > 0)
1130 pmlmepriv->to_roaming--;
1131 else if (pmlmepriv->to_roaming == 0)
1132 pmlmepriv->to_roaming = adapter->registrypriv.max_roaming_times;
1133
1134 if (*((unsigned short *)(pstadel->rsvd)) != WLAN_REASON_EXPIRATION_CHK)
1135 pmlmepriv->to_roaming = 0;
1136
1137 rtw_free_uc_swdec_pending_queue(adapter);
1138
1139 rtw_free_assoc_resources(adapter);
1140 rtw_indicate_disconnect(adapter);
1141 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
1142
1143 pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.MacAddress);
1144 if (pwlan) {
1145 pwlan->fixed = false;
1146 rtw_free_network_nolock(pmlmepriv, pwlan);
1147 }
1148 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1149 _rtw_roaming(adapter, tgt_network);
1150 }
1151 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) ||
1152 check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
1153 spin_lock_bh(&pstapriv->sta_hash_lock);
1154 rtw_free_stainfo(adapter, psta);
1155 spin_unlock_bh(&pstapriv->sta_hash_lock);
1156
1157 if (adapter->stapriv.asoc_sta_count == 1) {
1158 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
1159
1160 pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.MacAddress);
1161 if (pwlan) {
1162 pwlan->fixed = false;
1163 rtw_free_network_nolock(pmlmepriv, pwlan);
1164 }
1165 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1166
1167 pdev_network = &adapter->registrypriv.dev_network;
1168 pibss = adapter->registrypriv.dev_network.MacAddress;
1169
1170 memcpy(pdev_network, &tgt_network->network, get_wlan_bssid_ex_sz(&tgt_network->network));
1171
1172 memcpy(&pdev_network->ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid));
1173
1174 rtw_update_registrypriv_dev_network(adapter);
1175
1176 rtw_generate_random_ibss(pibss);
1177
1178 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
1179 set_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
1180 _clr_fwstate_(pmlmepriv, WIFI_ADHOC_STATE);
1181 }
1182
1183 rtw_createbss_cmd(adapter);
1184 }
1185 }
1186 spin_unlock_bh(&pmlmepriv->lock);
1187}
1188
1189
1190
1191
1192
1193void _rtw_join_timeout_handler (struct timer_list *t)
1194{
1195 struct adapter *adapter = from_timer(adapter, t, mlmepriv.assoc_timer);
1196 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1197 int do_join_r;
1198
1199 if (adapter->bDriverStopped || adapter->bSurpriseRemoved)
1200 return;
1201
1202 spin_lock_bh(&pmlmepriv->lock);
1203
1204 if (pmlmepriv->to_roaming > 0) {
1205 while (1) {
1206 pmlmepriv->to_roaming--;
1207 if (pmlmepriv->to_roaming != 0) {
1208 do_join_r = rtw_do_join(adapter);
1209 if (do_join_r != _SUCCESS)
1210 continue;
1211 break;
1212 }
1213 rtw_indicate_disconnect(adapter);
1214 break;
1215 }
1216 } else {
1217 rtw_indicate_disconnect(adapter);
1218 free_scanqueue(pmlmepriv);
1219 }
1220 spin_unlock_bh(&pmlmepriv->lock);
1221}
1222
1223
1224
1225
1226
1227void rtw_scan_timeout_handler (struct timer_list *t)
1228{
1229 struct adapter *adapter = from_timer(adapter, t,
1230 mlmepriv.scan_to_timer);
1231 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1232
1233 spin_lock_bh(&pmlmepriv->lock);
1234 _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
1235 spin_unlock_bh(&pmlmepriv->lock);
1236 rtw_indicate_scan_done(adapter, true);
1237}
1238
1239static void rtw_auto_scan_handler(struct adapter *padapter)
1240{
1241 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1242
1243
1244 if (pmlmepriv->scan_interval > 0) {
1245 pmlmepriv->scan_interval--;
1246 if (pmlmepriv->scan_interval == 0) {
1247 rtw_set_802_11_bssid_list_scan(padapter, NULL, 0);
1248 pmlmepriv->scan_interval = SCAN_INTERVAL;
1249 }
1250 }
1251}
1252
1253void rtw_dynamic_check_timer_handlder(struct timer_list *t)
1254{
1255 struct adapter *adapter = from_timer(adapter, t,
1256 mlmepriv.dynamic_chk_timer);
1257 struct registry_priv *pregistrypriv = &adapter->registrypriv;
1258
1259 if (!adapter)
1260 return;
1261 if (!adapter->hw_init_completed)
1262 goto exit;
1263 if ((adapter->bDriverStopped) || (adapter->bSurpriseRemoved))
1264 goto exit;
1265 if (adapter->net_closed)
1266 goto exit;
1267 rtw_dynamic_chk_wk_cmd(adapter);
1268
1269 if (pregistrypriv->wifi_spec == 1) {
1270
1271 rtw_auto_scan_handler(adapter);
1272 }
1273exit:
1274 mod_timer(&adapter->mlmepriv.dynamic_chk_timer,
1275 jiffies + msecs_to_jiffies(2000));
1276}
1277
1278#define RTW_SCAN_RESULT_EXPIRE 2000
1279
1280
1281
1282
1283
1284
1285static int rtw_check_join_candidate(struct mlme_priv *pmlmepriv
1286 , struct wlan_network **candidate, struct wlan_network *competitor)
1287{
1288 int updated = false;
1289 unsigned long since_scan;
1290 struct adapter *adapter = container_of(pmlmepriv, struct adapter,
1291 mlmepriv);
1292
1293
1294 if (pmlmepriv->assoc_by_bssid) {
1295 if (memcmp(competitor->network.MacAddress, pmlmepriv->assoc_bssid, ETH_ALEN))
1296 goto exit;
1297 }
1298
1299
1300 if (pmlmepriv->assoc_ssid.ssid_length) {
1301 if (competitor->network.ssid.ssid_length != pmlmepriv->assoc_ssid.ssid_length ||
1302 memcmp(competitor->network.ssid.ssid, pmlmepriv->assoc_ssid.ssid, pmlmepriv->assoc_ssid.ssid_length))
1303 goto exit;
1304 }
1305
1306 if (!rtw_is_desired_network(adapter, competitor))
1307 goto exit;
1308
1309 if (pmlmepriv->to_roaming) {
1310 since_scan = jiffies - competitor->last_scanned;
1311 if (jiffies_to_msecs(since_scan) >= RTW_SCAN_RESULT_EXPIRE ||
1312 !is_same_ess(&competitor->network, &pmlmepriv->cur_network.network))
1313 goto exit;
1314 }
1315
1316 if (!*candidate || (*candidate)->network.Rssi < competitor->network.Rssi) {
1317 *candidate = competitor;
1318 updated = true;
1319 }
1320
1321exit:
1322 return updated;
1323}
1324
1325
1326
1327
1328
1329
1330
1331
1332int rtw_select_and_join_from_scanned_queue(struct mlme_priv *pmlmepriv)
1333{
1334 int ret;
1335 struct list_head *phead;
1336 struct adapter *adapter = container_of(pmlmepriv, struct adapter, mlmepriv);
1337 struct __queue *queue = &pmlmepriv->scanned_queue;
1338 struct wlan_network *pnetwork = NULL;
1339 struct wlan_network *candidate = NULL;
1340 u8 supp_ant_div = false;
1341
1342 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
1343 phead = get_list_head(queue);
1344 list_for_each(pmlmepriv->pscanned, phead) {
1345 pnetwork = list_entry(pmlmepriv->pscanned,
1346 struct wlan_network, list);
1347 rtw_check_join_candidate(pmlmepriv, &candidate, pnetwork);
1348 }
1349 if (!candidate) {
1350 ret = _FAIL;
1351 goto exit;
1352 }
1353
1354
1355 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
1356 rtw_disassoc_cmd(adapter, 0, true);
1357 rtw_indicate_disconnect(adapter);
1358 rtw_free_assoc_resources_locked(adapter);
1359 }
1360
1361 rtw_hal_get_def_var(adapter, HAL_DEF_IS_SUPPORT_ANT_DIV, &(supp_ant_div));
1362 if (supp_ant_div) {
1363 u8 cur_ant;
1364
1365 rtw_hal_get_def_var(adapter, HAL_DEF_CURRENT_ANTENNA, &(cur_ant));
1366 }
1367
1368 ret = rtw_joinbss_cmd(adapter, candidate);
1369
1370exit:
1371 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1372 return ret;
1373}
1374
1375int rtw_set_auth(struct adapter *adapter, struct security_priv *psecuritypriv)
1376{
1377 struct cmd_obj *pcmd;
1378 struct setauth_parm *psetauthparm;
1379 struct cmd_priv *pcmdpriv = &adapter->cmdpriv;
1380 int res = _SUCCESS;
1381
1382 pcmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
1383 if (!pcmd) {
1384 res = _FAIL;
1385 goto exit;
1386 }
1387
1388 psetauthparm = kzalloc(sizeof(struct setauth_parm), GFP_KERNEL);
1389 if (!psetauthparm) {
1390 kfree(pcmd);
1391 res = _FAIL;
1392 goto exit;
1393 }
1394 psetauthparm->mode = (unsigned char)psecuritypriv->dot11AuthAlgrthm;
1395 pcmd->cmdcode = _SetAuth_CMD_;
1396 pcmd->parmbuf = (unsigned char *)psetauthparm;
1397 pcmd->cmdsz = sizeof(struct setauth_parm);
1398 pcmd->rsp = NULL;
1399 pcmd->rspsz = 0;
1400 INIT_LIST_HEAD(&pcmd->list);
1401 res = rtw_enqueue_cmd(pcmdpriv, pcmd);
1402exit:
1403 return res;
1404}
1405
1406int rtw_set_key(struct adapter *adapter, struct security_priv *psecuritypriv, int keyid, u8 set_tx)
1407{
1408 u8 keylen;
1409 struct cmd_obj *pcmd;
1410 struct setkey_parm *psetkeyparm;
1411 struct cmd_priv *pcmdpriv = &adapter->cmdpriv;
1412 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1413 int res = _SUCCESS;
1414
1415 pcmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
1416 if (!pcmd)
1417 return _FAIL;
1418
1419 psetkeyparm = kzalloc(sizeof(struct setkey_parm), GFP_KERNEL);
1420 if (!psetkeyparm) {
1421 res = _FAIL;
1422 goto err_free_cmd;
1423 }
1424
1425 if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)
1426 psetkeyparm->algorithm = (unsigned char)psecuritypriv->dot118021XGrpPrivacy;
1427 else
1428 psetkeyparm->algorithm = (u8)psecuritypriv->dot11PrivacyAlgrthm;
1429 psetkeyparm->keyid = (u8)keyid;
1430 psetkeyparm->set_tx = set_tx;
1431 pmlmepriv->key_mask |= BIT(psetkeyparm->keyid);
1432
1433 switch (psetkeyparm->algorithm) {
1434 case _WEP40_:
1435 keylen = 5;
1436 memcpy(&psetkeyparm->key[0],
1437 &psecuritypriv->dot11DefKey[keyid].skey[0], keylen);
1438 break;
1439 case _WEP104_:
1440 keylen = 13;
1441 memcpy(&psetkeyparm->key[0],
1442 &psecuritypriv->dot11DefKey[keyid].skey[0], keylen);
1443 break;
1444 case _TKIP_:
1445 keylen = 16;
1446 memcpy(&psetkeyparm->key, &psecuritypriv->dot118021XGrpKey[keyid], keylen);
1447 psetkeyparm->grpkey = 1;
1448 break;
1449 case _AES_:
1450 keylen = 16;
1451 memcpy(&psetkeyparm->key, &psecuritypriv->dot118021XGrpKey[keyid], keylen);
1452 psetkeyparm->grpkey = 1;
1453 break;
1454 default:
1455 res = _FAIL;
1456 goto err_free_parm;
1457 }
1458 pcmd->cmdcode = _SetKey_CMD_;
1459 pcmd->parmbuf = (u8 *)psetkeyparm;
1460 pcmd->cmdsz = sizeof(struct setkey_parm);
1461 pcmd->rsp = NULL;
1462 pcmd->rspsz = 0;
1463 INIT_LIST_HEAD(&pcmd->list);
1464 return rtw_enqueue_cmd(pcmdpriv, pcmd);
1465
1466err_free_parm:
1467 kfree(psetkeyparm);
1468err_free_cmd:
1469 kfree(pcmd);
1470 return res;
1471}
1472
1473
1474int rtw_restruct_wmm_ie(struct adapter *adapter, u8 *in_ie, u8 *out_ie, uint in_len, uint initial_out_len)
1475{
1476 unsigned int ielength = 0;
1477 unsigned int i, j;
1478
1479
1480 for (i = 12; i < in_len; i += (in_ie[i + 1] + 2) ) {
1481 ielength = initial_out_len;
1482
1483 if (in_ie[i] == 0xDD && in_ie[i + 2] == 0x00 && in_ie[i + 3] == 0x50 && in_ie[i + 4] == 0xF2 && in_ie[i + 5] == 0x02 && i + 5 < in_len) {
1484
1485
1486
1487 for (j = i; j < i + 9; j++) {
1488 out_ie[ielength] = in_ie[j];
1489 ielength++;
1490 }
1491 out_ie[initial_out_len + 1] = 0x07;
1492 out_ie[initial_out_len + 6] = 0x00;
1493 out_ie[initial_out_len + 8] = 0x00;
1494 break;
1495 }
1496 }
1497 return ielength;
1498}
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509static int SecIsInPMKIDList(struct adapter *Adapter, u8 *bssid)
1510{
1511 struct security_priv *psecuritypriv = &Adapter->securitypriv;
1512 int i = 0;
1513
1514 do {
1515 if ((psecuritypriv->PMKIDList[i].used) &&
1516 (!memcmp(psecuritypriv->PMKIDList[i].bssid, bssid, ETH_ALEN)))
1517 break;
1518 } while (++i < NUM_PMKID_CACHE);
1519
1520 if (i == NUM_PMKID_CACHE)
1521 i = -1;
1522
1523 return i;
1524}
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534static int rtw_append_pmkid(struct adapter *Adapter, int iEntry, u8 *ie, uint ie_len)
1535{
1536 struct security_priv *psecuritypriv = &Adapter->securitypriv;
1537
1538 if (ie[13] <= 20) {
1539
1540 ie[ie_len] = 1;
1541 ie_len++;
1542 ie[ie_len] = 0;
1543 ie_len++;
1544 memcpy(&ie[ie_len], &psecuritypriv->PMKIDList[iEntry].PMKID, 16);
1545
1546 ie_len += 16;
1547 ie[13] += 18;
1548 }
1549 return ie_len;
1550}
1551
1552int rtw_restruct_sec_ie(struct adapter *adapter, u8 *in_ie, u8 *out_ie, uint in_len)
1553{
1554 u8 authmode;
1555 uint ielength;
1556 int iEntry;
1557 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1558 struct security_priv *psecuritypriv = &adapter->securitypriv;
1559 uint ndisauthmode = psecuritypriv->ndisauthtype;
1560
1561
1562 memcpy(out_ie, in_ie, 12);
1563 ielength = 12;
1564 if ((ndisauthmode == Ndis802_11AuthModeWPA) ||
1565 (ndisauthmode == Ndis802_11AuthModeWPAPSK))
1566 authmode = WLAN_EID_VENDOR_SPECIFIC;
1567 else if ((ndisauthmode == Ndis802_11AuthModeWPA2) ||
1568 (ndisauthmode == Ndis802_11AuthModeWPA2PSK))
1569 authmode = WLAN_EID_RSN;
1570 else
1571 authmode = 0x0;
1572
1573 if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) {
1574 memcpy(out_ie + ielength, psecuritypriv->wps_ie, psecuritypriv->wps_ie_len);
1575
1576 ielength += psecuritypriv->wps_ie_len;
1577 } else if ((authmode == WLAN_EID_VENDOR_SPECIFIC) || (authmode == WLAN_EID_RSN)) {
1578
1579 memcpy(&out_ie[ielength], &psecuritypriv->supplicant_ie[0], psecuritypriv->supplicant_ie[1] + 2);
1580 ielength += psecuritypriv->supplicant_ie[1] + 2;
1581 rtw_report_sec_ie(adapter, authmode, psecuritypriv->supplicant_ie);
1582 }
1583
1584 iEntry = SecIsInPMKIDList(adapter, pmlmepriv->assoc_bssid);
1585 if (iEntry >= 0 && authmode == WLAN_EID_RSN)
1586 ielength = rtw_append_pmkid(adapter, iEntry, out_ie, ielength);
1587
1588 return ielength;
1589}
1590
1591void rtw_init_registrypriv_dev_network(struct adapter *adapter)
1592{
1593 struct registry_priv *pregistrypriv = &adapter->registrypriv;
1594 struct eeprom_priv *peepriv = &adapter->eeprompriv;
1595 struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network;
1596 u8 *myhwaddr = myid(peepriv);
1597
1598 memcpy(pdev_network->MacAddress, myhwaddr, ETH_ALEN);
1599
1600 memcpy(&pdev_network->ssid, &pregistrypriv->ssid, sizeof(struct ndis_802_11_ssid));
1601
1602 pdev_network->Configuration.Length = sizeof(struct ndis_802_11_config);
1603 pdev_network->Configuration.BeaconPeriod = 100;
1604 pdev_network->Configuration.FHConfig.Length = 0;
1605 pdev_network->Configuration.FHConfig.HopPattern = 0;
1606 pdev_network->Configuration.FHConfig.HopSet = 0;
1607 pdev_network->Configuration.FHConfig.DwellTime = 0;
1608}
1609
1610void rtw_update_registrypriv_dev_network(struct adapter *adapter)
1611{
1612 int sz = 0;
1613 struct registry_priv *pregistrypriv = &adapter->registrypriv;
1614 struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network;
1615 struct security_priv *psecuritypriv = &adapter->securitypriv;
1616 struct wlan_network *cur_network = &adapter->mlmepriv.cur_network;
1617
1618 pdev_network->Privacy = psecuritypriv->dot11PrivacyAlgrthm > 0 ? 1 : 0;
1619
1620 pdev_network->Rssi = 0;
1621
1622 switch (pregistrypriv->wireless_mode) {
1623 case WIRELESS_11B:
1624 pdev_network->NetworkTypeInUse = Ndis802_11DS;
1625 break;
1626 case WIRELESS_11G:
1627 case WIRELESS_11BG:
1628 case WIRELESS_11_24N:
1629 case WIRELESS_11G_24N:
1630 case WIRELESS_11BG_24N:
1631 pdev_network->NetworkTypeInUse = Ndis802_11OFDM24;
1632 break;
1633 default:
1634 pdev_network->NetworkTypeInUse = Ndis802_11OFDM24;
1635 break;
1636 }
1637
1638 pdev_network->Configuration.DSConfig = pregistrypriv->channel;
1639
1640 if (cur_network->network.InfrastructureMode == Ndis802_11IBSS)
1641 pdev_network->Configuration.ATIMWindow = 0;
1642
1643 pdev_network->InfrastructureMode = cur_network->network.InfrastructureMode;
1644
1645
1646
1647
1648 sz = rtw_generate_ie(pregistrypriv);
1649 pdev_network->ie_length = sz;
1650 pdev_network->Length = get_wlan_bssid_ex_sz(pdev_network);
1651
1652
1653
1654}
1655
1656void rtw_get_encrypt_decrypt_from_registrypriv(struct adapter *adapter)
1657{
1658}
1659
1660
1661void rtw_joinbss_reset(struct adapter *padapter)
1662{
1663 u8 threshold;
1664 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1665 struct ht_priv *phtpriv = &pmlmepriv->htpriv;
1666
1667
1668 pmlmepriv->num_FortyMHzIntolerant = 0;
1669
1670 pmlmepriv->num_sta_no_ht = 0;
1671
1672 phtpriv->ampdu_enable = false;
1673
1674
1675
1676 if (phtpriv->ht_option) {
1677 if (padapter->registrypriv.wifi_spec == 1)
1678 threshold = 1;
1679 else
1680 threshold = 0;
1681 rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold));
1682 } else {
1683 threshold = 1;
1684 rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold));
1685 }
1686}
1687
1688
1689unsigned int rtw_restructure_ht_ie(struct adapter *padapter, u8 *in_ie, u8 *out_ie, uint in_len, uint *pout_len)
1690{
1691 u32 ielen, out_len;
1692 enum ht_cap_ampdu_factor max_rx_ampdu_factor;
1693 unsigned char *p;
1694 unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
1695 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1696 struct qos_priv *pqospriv = &pmlmepriv->qospriv;
1697 struct ht_priv *phtpriv = &pmlmepriv->htpriv;
1698 u32 rx_packet_offset, max_recvbuf_sz;
1699
1700 phtpriv->ht_option = false;
1701
1702 p = rtw_get_ie(in_ie + 12, WLAN_EID_HT_CAPABILITY, &ielen, in_len - 12);
1703
1704 if (p && ielen > 0) {
1705 struct ieee80211_ht_cap ht_cap;
1706
1707 if (pqospriv->qos_option == 0) {
1708 out_len = *pout_len;
1709 rtw_set_ie(out_ie + out_len, WLAN_EID_VENDOR_SPECIFIC,
1710 _WMM_IE_Length_, WMM_IE, pout_len);
1711
1712 pqospriv->qos_option = 1;
1713 }
1714
1715 out_len = *pout_len;
1716
1717 memset(&ht_cap, 0, sizeof(struct ieee80211_ht_cap));
1718
1719 ht_cap.cap_info = cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
1720 IEEE80211_HT_CAP_SGI_20 |
1721 IEEE80211_HT_CAP_SGI_40 |
1722 IEEE80211_HT_CAP_TX_STBC |
1723 IEEE80211_HT_CAP_DSSSCCK40);
1724
1725 rtw_hal_get_def_var(padapter, HAL_DEF_RX_PACKET_OFFSET, &rx_packet_offset);
1726 rtw_hal_get_def_var(padapter, HAL_DEF_MAX_RECVBUF_SZ, &max_recvbuf_sz);
1727
1728
1729
1730
1731
1732
1733 rtw_hal_get_def_var(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor);
1734 ht_cap.ampdu_params_info = max_rx_ampdu_factor & 0x03;
1735
1736 if (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)
1737 ht_cap.ampdu_params_info |= IEEE80211_HT_AMPDU_PARM_DENSITY & (0x07 << 2);
1738 else
1739 ht_cap.ampdu_params_info |= IEEE80211_HT_AMPDU_PARM_DENSITY & 0x00;
1740
1741 rtw_set_ie(out_ie + out_len, WLAN_EID_HT_CAPABILITY,
1742 sizeof(struct ieee80211_ht_cap),
1743 (unsigned char *)&ht_cap, pout_len);
1744
1745 phtpriv->ht_option = true;
1746
1747 p = rtw_get_ie(in_ie + 12, WLAN_EID_HT_OPERATION, &ielen, in_len - 12);
1748 if (p && (ielen == sizeof(struct ieee80211_ht_addt_info))) {
1749 out_len = *pout_len;
1750 rtw_set_ie(out_ie + out_len, WLAN_EID_HT_OPERATION, ielen, p + 2, pout_len);
1751 }
1752 }
1753 return phtpriv->ht_option;
1754}
1755
1756
1757void rtw_update_ht_cap(struct adapter *padapter, u8 *pie, uint ie_len)
1758{
1759 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1760 struct ht_priv *phtpriv = &pmlmepriv->htpriv;
1761 struct registry_priv *pregistrypriv = &padapter->registrypriv;
1762 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1763 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1764
1765 if (!phtpriv->ht_option)
1766 return;
1767
1768 if ((!pmlmeinfo->HT_info_enable) || (!pmlmeinfo->HT_caps_enable))
1769 return;
1770
1771
1772 if ((!phtpriv->ampdu_enable) && (pregistrypriv->ampdu_enable == 1)) {
1773 if (pregistrypriv->wifi_spec == 1)
1774 phtpriv->ampdu_enable = false;
1775 else
1776 phtpriv->ampdu_enable = true;
1777 } else if (pregistrypriv->ampdu_enable == 2) {
1778 phtpriv->ampdu_enable = true;
1779 }
1780
1781
1782 if ((pregistrypriv->cbw40_enable) &&
1783 (le16_to_cpu(pmlmeinfo->HT_caps.cap_info) & BIT(1)) &&
1784 (pmlmeinfo->HT_info.infos[0] & BIT(2))) {
1785 int i;
1786
1787
1788 for (i = 0; i < 16; i++)
1789 ((u8 *)&pmlmeinfo->HT_caps.mcs)[i] &= MCS_rate_1R[i];
1790
1791 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
1792 switch ((pmlmeinfo->HT_info.infos[0] & 0x3)) {
1793 case HT_EXTCHNL_OFFSET_UPPER:
1794 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
1795 break;
1796 case HT_EXTCHNL_OFFSET_LOWER:
1797 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
1798 break;
1799 default:
1800 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
1801 break;
1802 }
1803 }
1804
1805
1806 pmlmeinfo->SM_PS = (le16_to_cpu(pmlmeinfo->HT_caps.cap_info) & 0x0C) >> 2;
1807
1808
1809 pmlmeinfo->HT_protection = pmlmeinfo->HT_info.infos[1] & 0x3;
1810}
1811
1812void rtw_issue_addbareq_cmd(struct adapter *padapter, struct xmit_frame *pxmitframe)
1813{
1814 u8 issued;
1815 int priority;
1816 struct sta_info *psta = NULL;
1817 struct ht_priv *phtpriv;
1818 struct pkt_attrib *pattrib = &pxmitframe->attrib;
1819
1820 if (is_multicast_ether_addr(pattrib->ra) ||
1821 padapter->mlmepriv.LinkDetectInfo.NumTxOkInPeriod < 100)
1822 return;
1823
1824 priority = pattrib->priority;
1825
1826 if (pattrib->psta)
1827 psta = pattrib->psta;
1828 else
1829 psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
1830
1831 if (!psta)
1832 return;
1833
1834 phtpriv = &psta->htpriv;
1835
1836 if ((phtpriv->ht_option) && (phtpriv->ampdu_enable)) {
1837 issued = (phtpriv->agg_enable_bitmap >> priority) & 0x1;
1838 issued |= (phtpriv->candidate_tid_bitmap >> priority) & 0x1;
1839
1840 if (issued == 0) {
1841 psta->htpriv.candidate_tid_bitmap |= BIT((u8)priority);
1842 rtw_addbareq_cmd(padapter, (u8)priority, pattrib->ra);
1843 }
1844 }
1845}
1846
1847void rtw_roaming(struct adapter *padapter, struct wlan_network *tgt_network)
1848{
1849 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1850
1851 spin_lock_bh(&pmlmepriv->lock);
1852 _rtw_roaming(padapter, tgt_network);
1853 spin_unlock_bh(&pmlmepriv->lock);
1854}
1855
1856void _rtw_roaming(struct adapter *padapter, struct wlan_network *tgt_network)
1857{
1858 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1859 int do_join_r;
1860 struct wlan_network *pnetwork;
1861
1862 if (tgt_network)
1863 pnetwork = tgt_network;
1864 else
1865 pnetwork = &pmlmepriv->cur_network;
1866
1867 if (pmlmepriv->to_roaming > 0) {
1868 memcpy(&pmlmepriv->assoc_ssid, &pnetwork->network.ssid, sizeof(struct ndis_802_11_ssid));
1869
1870 pmlmepriv->assoc_by_bssid = false;
1871
1872 while (1) {
1873 do_join_r = rtw_do_join(padapter);
1874 if (do_join_r == _SUCCESS)
1875 break;
1876
1877 pmlmepriv->to_roaming--;
1878
1879 if (pmlmepriv->to_roaming > 0) {
1880 continue;
1881 } else {
1882 rtw_indicate_disconnect(padapter);
1883 break;
1884 }
1885 }
1886 }
1887}
1888