Mention branches and keyring.
[releases.git] / core / rtw_mlme.c
1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3  *
4  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
5  *
6  ******************************************************************************/
7 #include <linux/etherdevice.h>
8 #include <drv_types.h>
9 #include <rtw_debug.h>
10 #include <hal_btcoex.h>
11 #include <linux/jiffies.h>
12
13 int     rtw_init_mlme_priv(struct adapter *padapter)
14 {
15         int     i;
16         u8 *pbuf;
17         struct wlan_network     *pnetwork;
18         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
19         int     res = _SUCCESS;
20
21         pmlmepriv->nic_hdl = (u8 *)padapter;
22
23         pmlmepriv->pscanned = NULL;
24         pmlmepriv->fw_state = WIFI_STATION_STATE; /*  Must sync with rtw_wdev_alloc() */
25         /*  wdev->iftype = NL80211_IFTYPE_STATION */
26         pmlmepriv->cur_network.network.infrastructure_mode = Ndis802_11AutoUnknown;
27         pmlmepriv->scan_mode = SCAN_ACTIVE;/*  1: active, 0: passive. Maybe someday we should rename this varable to "active_mode" (Jeff) */
28
29         spin_lock_init(&pmlmepriv->lock);
30         INIT_LIST_HEAD(&pmlmepriv->free_bss_pool.queue);
31         spin_lock_init(&pmlmepriv->free_bss_pool.lock);
32         INIT_LIST_HEAD(&pmlmepriv->scanned_queue.queue);
33         spin_lock_init(&pmlmepriv->scanned_queue.lock);
34
35         set_scanned_network_val(pmlmepriv, 0);
36
37         memset(&pmlmepriv->assoc_ssid, 0, sizeof(struct ndis_802_11_ssid));
38
39         pbuf = vzalloc(array_size(MAX_BSS_CNT, sizeof(struct wlan_network)));
40
41         if (!pbuf) {
42                 res = _FAIL;
43                 goto exit;
44         }
45         pmlmepriv->free_bss_buf = pbuf;
46
47         pnetwork = (struct wlan_network *)pbuf;
48
49         for (i = 0; i < MAX_BSS_CNT; i++) {
50                 INIT_LIST_HEAD(&pnetwork->list);
51
52                 list_add_tail(&pnetwork->list, &pmlmepriv->free_bss_pool.queue);
53
54                 pnetwork++;
55         }
56
57         /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */
58
59         rtw_clear_scan_deny(padapter);
60
61         #define RTW_ROAM_SCAN_RESULT_EXP_MS 5000
62         #define RTW_ROAM_RSSI_DIFF_TH 10
63         #define RTW_ROAM_SCAN_INTERVAL_MS 10000
64
65         pmlmepriv->roam_flags = 0
66                 | RTW_ROAM_ON_EXPIRED
67                 | RTW_ROAM_ON_RESUME
68                 ;
69
70         pmlmepriv->roam_scanr_exp_ms = RTW_ROAM_SCAN_RESULT_EXP_MS;
71         pmlmepriv->roam_rssi_diff_th = RTW_ROAM_RSSI_DIFF_TH;
72         pmlmepriv->roam_scan_int_ms = RTW_ROAM_SCAN_INTERVAL_MS;
73
74         rtw_init_mlme_timer(padapter);
75
76 exit:
77
78         return res;
79 }
80
81 static void rtw_free_mlme_ie_data(u8 **ppie, u32 *plen)
82 {
83         if (*ppie) {
84                 kfree(*ppie);
85                 *plen = 0;
86                 *ppie = NULL;
87         }
88 }
89
90 void rtw_free_mlme_priv_ie_data(struct mlme_priv *pmlmepriv)
91 {
92         rtw_buf_free(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len);
93         rtw_buf_free(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len);
94         rtw_free_mlme_ie_data(&pmlmepriv->wps_beacon_ie, &pmlmepriv->wps_beacon_ie_len);
95         rtw_free_mlme_ie_data(&pmlmepriv->wps_probe_req_ie, &pmlmepriv->wps_probe_req_ie_len);
96         rtw_free_mlme_ie_data(&pmlmepriv->wps_probe_resp_ie, &pmlmepriv->wps_probe_resp_ie_len);
97         rtw_free_mlme_ie_data(&pmlmepriv->wps_assoc_resp_ie, &pmlmepriv->wps_assoc_resp_ie_len);
98
99         rtw_free_mlme_ie_data(&pmlmepriv->p2p_beacon_ie, &pmlmepriv->p2p_beacon_ie_len);
100         rtw_free_mlme_ie_data(&pmlmepriv->p2p_probe_req_ie, &pmlmepriv->p2p_probe_req_ie_len);
101         rtw_free_mlme_ie_data(&pmlmepriv->p2p_probe_resp_ie, &pmlmepriv->p2p_probe_resp_ie_len);
102         rtw_free_mlme_ie_data(&pmlmepriv->p2p_go_probe_resp_ie, &pmlmepriv->p2p_go_probe_resp_ie_len);
103         rtw_free_mlme_ie_data(&pmlmepriv->p2p_assoc_req_ie, &pmlmepriv->p2p_assoc_req_ie_len);
104 }
105
106 void _rtw_free_mlme_priv(struct mlme_priv *pmlmepriv)
107 {
108         if (pmlmepriv) {
109                 rtw_free_mlme_priv_ie_data(pmlmepriv);
110                 vfree(pmlmepriv->free_bss_buf);
111         }
112 }
113
114 /*
115 struct  wlan_network *_rtw_dequeue_network(struct __queue *queue)
116 {
117         _irqL irqL;
118
119         struct wlan_network *pnetwork;
120
121         spin_lock_bh(&queue->lock);
122
123         if (list_empty(&queue->queue))
124
125                 pnetwork = NULL;
126
127         else
128         {
129                 pnetwork = container_of(get_next(&queue->queue), struct wlan_network, list);
130
131                 list_del_init(&(pnetwork->list));
132         }
133
134         spin_unlock_bh(&queue->lock);
135
136         return pnetwork;
137 }
138 */
139
140 struct  wlan_network *rtw_alloc_network(struct  mlme_priv *pmlmepriv)
141 {
142         struct  wlan_network    *pnetwork;
143         struct __queue *free_queue = &pmlmepriv->free_bss_pool;
144         struct list_head *plist = NULL;
145
146         spin_lock_bh(&free_queue->lock);
147
148         if (list_empty(&free_queue->queue)) {
149                 pnetwork = NULL;
150                 goto exit;
151         }
152         plist = get_next(&(free_queue->queue));
153
154         pnetwork = container_of(plist, struct wlan_network, list);
155
156         list_del_init(&pnetwork->list);
157
158         pnetwork->network_type = 0;
159         pnetwork->fixed = false;
160         pnetwork->last_scanned = jiffies;
161         pnetwork->aid = 0;
162         pnetwork->join_res = 0;
163
164         pmlmepriv->num_of_scanned++;
165
166 exit:
167         spin_unlock_bh(&free_queue->lock);
168
169         return pnetwork;
170 }
171
172 void _rtw_free_network(struct   mlme_priv *pmlmepriv, struct wlan_network *pnetwork, u8 isfreeall)
173 {
174         unsigned int delta_time;
175         u32 lifetime = SCANQUEUE_LIFETIME;
176 /*      _irqL irqL; */
177         struct __queue *free_queue = &(pmlmepriv->free_bss_pool);
178
179         if (!pnetwork)
180                 return;
181
182         if (pnetwork->fixed)
183                 return;
184
185         if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) ||
186                 (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true))
187                 lifetime = 1;
188
189         if (!isfreeall) {
190                 delta_time = jiffies_to_msecs(jiffies - pnetwork->last_scanned);
191                 if (delta_time < lifetime)/*  unit:msec */
192                         return;
193         }
194
195         spin_lock_bh(&free_queue->lock);
196
197         list_del_init(&(pnetwork->list));
198
199         list_add_tail(&(pnetwork->list), &(free_queue->queue));
200
201         pmlmepriv->num_of_scanned--;
202
203         spin_unlock_bh(&free_queue->lock);
204 }
205
206 void _rtw_free_network_nolock(struct    mlme_priv *pmlmepriv, struct wlan_network *pnetwork)
207 {
208
209         struct __queue *free_queue = &(pmlmepriv->free_bss_pool);
210
211         if (!pnetwork)
212                 return;
213
214         if (pnetwork->fixed)
215                 return;
216
217         /* spin_lock_irqsave(&free_queue->lock, irqL); */
218
219         list_del_init(&(pnetwork->list));
220
221         list_add_tail(&(pnetwork->list), get_list_head(free_queue));
222
223         pmlmepriv->num_of_scanned--;
224
225         /* spin_unlock_irqrestore(&free_queue->lock, irqL); */
226 }
227
228 /*
229         return the wlan_network with the matching addr
230
231         Shall be called under atomic context... to avoid possible racing condition...
232 */
233 struct wlan_network *_rtw_find_network(struct __queue *scanned_queue, u8 *addr)
234 {
235         struct list_head        *phead, *plist;
236         struct  wlan_network *pnetwork = NULL;
237         u8 zero_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0};
238
239         if (!memcmp(zero_addr, addr, ETH_ALEN)) {
240                 pnetwork = NULL;
241                 goto exit;
242         }
243
244         /* spin_lock_bh(&scanned_queue->lock); */
245
246         phead = get_list_head(scanned_queue);
247         list_for_each(plist, phead) {
248                 pnetwork = list_entry(plist, struct wlan_network, list);
249
250                 if (!memcmp(addr, pnetwork->network.mac_address, ETH_ALEN))
251                         break;
252         }
253
254         if (plist == phead)
255                 pnetwork = NULL;
256
257         /* spin_unlock_bh(&scanned_queue->lock); */
258
259 exit:
260         return pnetwork;
261 }
262
263 void rtw_free_network_queue(struct adapter *padapter, u8 isfreeall)
264 {
265         struct list_head *phead, *plist, *tmp;
266         struct wlan_network *pnetwork;
267         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
268         struct __queue *scanned_queue = &pmlmepriv->scanned_queue;
269
270         spin_lock_bh(&scanned_queue->lock);
271
272         phead = get_list_head(scanned_queue);
273         list_for_each_safe(plist, tmp, phead) {
274
275                 pnetwork = list_entry(plist, struct wlan_network, list);
276
277                 _rtw_free_network(pmlmepriv, pnetwork, isfreeall);
278
279         }
280
281         spin_unlock_bh(&scanned_queue->lock);
282 }
283
284 signed int rtw_if_up(struct adapter *padapter)
285 {
286         signed int res;
287
288         if (padapter->bDriverStopped || padapter->bSurpriseRemoved ||
289                 (check_fwstate(&padapter->mlmepriv, _FW_LINKED) == false))
290                 res = false;
291         else
292                 res =  true;
293
294         return res;
295 }
296
297 void rtw_generate_random_ibss(u8 *pibss)
298 {
299         unsigned long curtime = jiffies;
300
301         pibss[0] = 0x02;  /* in ad-hoc mode bit1 must set to 1 */
302         pibss[1] = 0x11;
303         pibss[2] = 0x87;
304         pibss[3] = (u8)(curtime & 0xff) ;/* p[0]; */
305         pibss[4] = (u8)((curtime>>8) & 0xff) ;/* p[1]; */
306         pibss[5] = (u8)((curtime>>16) & 0xff) ;/* p[2]; */
307 }
308
309 u8 *rtw_get_capability_from_ie(u8 *ie)
310 {
311         return ie + 8 + 2;
312 }
313
314 u16 rtw_get_capability(struct wlan_bssid_ex *bss)
315 {
316         __le16  val;
317
318         memcpy((u8 *)&val, rtw_get_capability_from_ie(bss->ies), 2);
319
320         return le16_to_cpu(val);
321 }
322
323 u8 *rtw_get_beacon_interval_from_ie(u8 *ie)
324 {
325         return ie + 8;
326 }
327
328 void rtw_free_mlme_priv(struct mlme_priv *pmlmepriv)
329 {
330         _rtw_free_mlme_priv(pmlmepriv);
331 }
332
333 /*
334 static struct   wlan_network *rtw_dequeue_network(struct __queue *queue)
335 {
336         struct wlan_network *pnetwork;
337
338         pnetwork = _rtw_dequeue_network(queue);
339         return pnetwork;
340 }
341 */
342
343 void rtw_free_network_nolock(struct adapter *padapter, struct wlan_network *pnetwork);
344 void rtw_free_network_nolock(struct adapter *padapter, struct wlan_network *pnetwork)
345 {
346         _rtw_free_network_nolock(&(padapter->mlmepriv), pnetwork);
347         rtw_cfg80211_unlink_bss(padapter, pnetwork);
348 }
349
350 /*
351         return the wlan_network with the matching addr
352
353         Shall be called under atomic context... to avoid possible racing condition...
354 */
355 struct  wlan_network *rtw_find_network(struct __queue *scanned_queue, u8 *addr)
356 {
357         struct  wlan_network *pnetwork = _rtw_find_network(scanned_queue, addr);
358
359         return pnetwork;
360 }
361
362 int rtw_is_same_ibss(struct adapter *adapter, struct wlan_network *pnetwork)
363 {
364         int ret = true;
365         struct security_priv *psecuritypriv = &adapter->securitypriv;
366
367         if ((psecuritypriv->dot11PrivacyAlgrthm != _NO_PRIVACY_) &&
368                     (pnetwork->network.privacy == 0))
369                 ret = false;
370         else if ((psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_) &&
371                  (pnetwork->network.privacy == 1))
372                 ret = false;
373         else
374                 ret = true;
375
376         return ret;
377
378 }
379
380 inline int is_same_ess(struct wlan_bssid_ex *a, struct wlan_bssid_ex *b)
381 {
382         return (a->ssid.ssid_length == b->ssid.ssid_length)
383                 &&  !memcmp(a->ssid.ssid, b->ssid.ssid, a->ssid.ssid_length);
384 }
385
386 int is_same_network(struct wlan_bssid_ex *src, struct wlan_bssid_ex *dst, u8 feature)
387 {
388         u16 s_cap, d_cap;
389         __le16 tmps, tmpd;
390
391         if (rtw_bug_check(dst, src, &s_cap, &d_cap) == false)
392                         return false;
393
394         memcpy((u8 *)&tmps, rtw_get_capability_from_ie(src->ies), 2);
395         memcpy((u8 *)&tmpd, rtw_get_capability_from_ie(dst->ies), 2);
396
397         s_cap = le16_to_cpu(tmps);
398         d_cap = le16_to_cpu(tmpd);
399
400         return (src->ssid.ssid_length == dst->ssid.ssid_length) &&
401                 /*      (src->configuration.ds_config == dst->configuration.ds_config) && */
402                         ((!memcmp(src->mac_address, dst->mac_address, ETH_ALEN))) &&
403                         ((!memcmp(src->ssid.ssid, dst->ssid.ssid, src->ssid.ssid_length))) &&
404                         ((s_cap & WLAN_CAPABILITY_IBSS) ==
405                         (d_cap & WLAN_CAPABILITY_IBSS)) &&
406                         ((s_cap & WLAN_CAPABILITY_ESS) ==
407                         (d_cap & WLAN_CAPABILITY_ESS));
408
409 }
410
411 struct wlan_network *_rtw_find_same_network(struct __queue *scanned_queue, struct wlan_network *network)
412 {
413         struct list_head *phead, *plist;
414         struct wlan_network *found = NULL;
415
416         phead = get_list_head(scanned_queue);
417         list_for_each(plist, phead) {
418                 found = list_entry(plist, struct wlan_network, list);
419
420                 if (is_same_network(&network->network, &found->network, 0))
421                         break;
422         }
423
424         if (plist == phead)
425                 found = NULL;
426
427         return found;
428 }
429
430 struct  wlan_network    *rtw_get_oldest_wlan_network(struct __queue *scanned_queue)
431 {
432         struct list_head        *plist, *phead;
433
434         struct  wlan_network    *pwlan = NULL;
435         struct  wlan_network    *oldest = NULL;
436
437         phead = get_list_head(scanned_queue);
438
439         list_for_each(plist, phead) {
440
441                 pwlan = list_entry(plist, struct wlan_network, list);
442
443                 if (!pwlan->fixed) {
444                         if (!oldest || time_after(oldest->last_scanned, pwlan->last_scanned))
445                                 oldest = pwlan;
446                 }
447         }
448         return oldest;
449
450 }
451
452 void update_network(struct wlan_bssid_ex *dst, struct wlan_bssid_ex *src,
453         struct adapter *padapter, bool update_ie)
454 {
455         long rssi_ori = dst->rssi;
456
457         u8 sq_smp = src->phy_info.signal_quality;
458
459         u8 ss_final;
460         u8 sq_final;
461         long rssi_final;
462
463         /* The rule below is 1/5 for sample value, 4/5 for history value */
464         if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) && is_same_network(&(padapter->mlmepriv.cur_network.network), src, 0)) {
465                 /* Take the recvpriv's value for the connected AP*/
466                 ss_final = padapter->recvpriv.signal_strength;
467                 sq_final = padapter->recvpriv.signal_qual;
468                 /* the rssi value here is undecorated, and will be used for antenna diversity */
469                 if (sq_smp != 101) /* from the right channel */
470                         rssi_final = (src->rssi+dst->rssi*4)/5;
471                 else
472                         rssi_final = rssi_ori;
473         } else {
474                 if (sq_smp != 101) { /* from the right channel */
475                         ss_final = ((u32)(src->phy_info.signal_strength)+(u32)(dst->phy_info.signal_strength)*4)/5;
476                         sq_final = ((u32)(src->phy_info.signal_quality)+(u32)(dst->phy_info.signal_quality)*4)/5;
477                         rssi_final = (src->rssi+dst->rssi*4)/5;
478                 } else {
479                         /* bss info not receiving from the right channel, use the original RX signal infos */
480                         ss_final = dst->phy_info.signal_strength;
481                         sq_final = dst->phy_info.signal_quality;
482                         rssi_final = dst->rssi;
483                 }
484
485         }
486
487         if (update_ie) {
488                 dst->reserved[0] = src->reserved[0];
489                 dst->reserved[1] = src->reserved[1];
490                 memcpy((u8 *)dst, (u8 *)src, get_wlan_bssid_ex_sz(src));
491         }
492
493         dst->phy_info.signal_strength = ss_final;
494         dst->phy_info.signal_quality = sq_final;
495         dst->rssi = rssi_final;
496 }
497
498 static void update_current_network(struct adapter *adapter, struct wlan_bssid_ex *pnetwork)
499 {
500         struct  mlme_priv *pmlmepriv = &(adapter->mlmepriv);
501
502         rtw_bug_check(&(pmlmepriv->cur_network.network),
503                 &(pmlmepriv->cur_network.network),
504                 &(pmlmepriv->cur_network.network),
505                 &(pmlmepriv->cur_network.network));
506
507         if ((check_fwstate(pmlmepriv, _FW_LINKED) == true) && (is_same_network(&(pmlmepriv->cur_network.network), pnetwork, 0))) {
508                 /* if (pmlmepriv->cur_network.network.ie_length<= pnetwork->ie_length) */
509                 {
510                         update_network(&(pmlmepriv->cur_network.network), pnetwork, adapter, true);
511                         rtw_update_protection(adapter, (pmlmepriv->cur_network.network.ies) + sizeof(struct ndis_802_11_fix_ie),
512                                                                         pmlmepriv->cur_network.network.ie_length);
513                 }
514         }
515 }
516
517 /*
518 Caller must hold pmlmepriv->lock first.
519 */
520 void rtw_update_scanned_network(struct adapter *adapter, struct wlan_bssid_ex *target)
521 {
522         struct list_head        *plist, *phead;
523         u32 bssid_ex_sz;
524         struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
525         struct __queue  *queue  = &(pmlmepriv->scanned_queue);
526         struct wlan_network     *pnetwork = NULL;
527         struct wlan_network     *oldest = NULL;
528         int target_find = 0;
529         u8 feature = 0;
530
531         spin_lock_bh(&queue->lock);
532         phead = get_list_head(queue);
533         list_for_each(plist, phead) {
534                 pnetwork = list_entry(plist, struct wlan_network, list);
535
536                 rtw_bug_check(pnetwork, pnetwork, pnetwork, pnetwork);
537
538                 if (is_same_network(&(pnetwork->network), target, feature)) {
539                         target_find = 1;
540                         break;
541                 }
542
543                 if (rtw_roam_flags(adapter)) {
544                         /* TODO: don't select network in the same ess as oldest if it's new enough*/
545                 }
546
547                 if (!oldest || time_after(oldest->last_scanned, pnetwork->last_scanned))
548                         oldest = pnetwork;
549
550         }
551
552         /* If we didn't find a match, then get a new network slot to initialize
553          * with this beacon's information */
554         /* if (phead == plist) { */
555         if (!target_find) {
556                 if (list_empty(&pmlmepriv->free_bss_pool.queue)) {
557                         /* If there are no more slots, expire the oldest */
558                         /* list_del_init(&oldest->list); */
559                         pnetwork = oldest;
560                         if (!pnetwork)
561                                 goto exit;
562
563                         memcpy(&(pnetwork->network), target,  get_wlan_bssid_ex_sz(target));
564                         /*  variable initialize */
565                         pnetwork->fixed = false;
566                         pnetwork->last_scanned = jiffies;
567
568                         pnetwork->network_type = 0;
569                         pnetwork->aid = 0;
570                         pnetwork->join_res = 0;
571
572                         /* bss info not receiving from the right channel */
573                         if (pnetwork->network.phy_info.signal_quality == 101)
574                                 pnetwork->network.phy_info.signal_quality = 0;
575                 } else {
576                         /* Otherwise just pull from the free list */
577
578                         pnetwork = rtw_alloc_network(pmlmepriv); /*  will update scan_time */
579
580                         if (!pnetwork)
581                                 goto exit;
582
583                         bssid_ex_sz = get_wlan_bssid_ex_sz(target);
584                         target->length = bssid_ex_sz;
585                         memcpy(&(pnetwork->network), target, bssid_ex_sz);
586
587                         pnetwork->last_scanned = jiffies;
588
589                         /* bss info not receiving from the right channel */
590                         if (pnetwork->network.phy_info.signal_quality == 101)
591                                 pnetwork->network.phy_info.signal_quality = 0;
592
593                         list_add_tail(&(pnetwork->list), &(queue->queue));
594
595                 }
596         } else {
597                 /* we have an entry and we are going to update it. But this entry may
598                  * be already expired. In this case we do the same as we found a new
599                  * net and call the new_net handler
600                  */
601                 bool update_ie = true;
602
603                 pnetwork->last_scanned = jiffies;
604
605                 /* target.reserved[0]== 1, means that scanned network is a bcn frame. */
606                 if (pnetwork->network.ie_length > target->ie_length && target->reserved[0] == 1)
607                         update_ie = false;
608
609                 /*  probe resp(3) > beacon(1) > probe req(2) */
610                 if (target->reserved[0] != 2 &&
611                     target->reserved[0] >= pnetwork->network.reserved[0]) {
612                         update_ie = true;
613                 } else {
614                         update_ie = false;
615                 }
616
617                 update_network(&(pnetwork->network), target, adapter, update_ie);
618         }
619
620 exit:
621         spin_unlock_bh(&queue->lock);
622 }
623
624 void rtw_add_network(struct adapter *adapter, struct wlan_bssid_ex *pnetwork);
625 void rtw_add_network(struct adapter *adapter, struct wlan_bssid_ex *pnetwork)
626 {
627         /* struct __queue       *queue  = &(pmlmepriv->scanned_queue); */
628
629         /* spin_lock_bh(&queue->lock); */
630
631         update_current_network(adapter, pnetwork);
632
633         rtw_update_scanned_network(adapter, pnetwork);
634
635         /* spin_unlock_bh(&queue->lock); */
636 }
637
638 /* select the desired network based on the capability of the (i)bss. */
639 /*  check items: (1) security */
640 /*                         (2) network_type */
641 /*                         (3) WMM */
642 /*                         (4) HT */
643 /*                      (5) others */
644 int rtw_is_desired_network(struct adapter *adapter, struct wlan_network *pnetwork);
645 int rtw_is_desired_network(struct adapter *adapter, struct wlan_network *pnetwork)
646 {
647         struct security_priv *psecuritypriv = &adapter->securitypriv;
648         struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
649         u32 desired_encmode;
650         u32 privacy;
651
652         /* u8 wps_ie[512]; */
653         uint wps_ielen;
654
655         int bselected = true;
656
657         desired_encmode = psecuritypriv->ndisencryptstatus;
658         privacy = pnetwork->network.privacy;
659
660         if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) {
661                 if (rtw_get_wps_ie(pnetwork->network.ies+_FIXED_IE_LENGTH_, pnetwork->network.ie_length-_FIXED_IE_LENGTH_, NULL, &wps_ielen))
662                         return true;
663                 else
664                         return false;
665
666         }
667         if (adapter->registrypriv.wifi_spec == 1) { /* for  correct flow of 8021X  to do.... */
668                 u8 *p = NULL;
669                 uint ie_len = 0;
670
671                 if ((desired_encmode == Ndis802_11EncryptionDisabled) && (privacy != 0))
672             bselected = false;
673
674                 if (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) {
675                         p = rtw_get_ie(pnetwork->network.ies + _BEACON_IE_OFFSET_, WLAN_EID_RSN, &ie_len, (pnetwork->network.ie_length - _BEACON_IE_OFFSET_));
676                         if (p && ie_len > 0)
677                                 bselected = true;
678                         else
679                                 bselected = false;
680                 }
681         }
682
683         if ((desired_encmode != Ndis802_11EncryptionDisabled) && (privacy == 0))
684                 bselected = false;
685
686         if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true) {
687                 if (pnetwork->network.infrastructure_mode != pmlmepriv->cur_network.network.infrastructure_mode)
688                         bselected = false;
689         }
690
691         return bselected;
692 }
693
694 /* TODO: Perry : For Power Management */
695 void rtw_atimdone_event_callback(struct adapter *adapter, u8 *pbuf)
696 {
697 }
698
699 void rtw_survey_event_callback(struct adapter   *adapter, u8 *pbuf)
700 {
701         u32 len;
702         struct wlan_bssid_ex *pnetwork;
703         struct  mlme_priv *pmlmepriv = &(adapter->mlmepriv);
704
705         pnetwork = (struct wlan_bssid_ex *)pbuf;
706
707         len = get_wlan_bssid_ex_sz(pnetwork);
708         if (len > (sizeof(struct wlan_bssid_ex)))
709                 return;
710
711         spin_lock_bh(&pmlmepriv->lock);
712
713         /*  update IBSS_network 's timestamp */
714         if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) == true) {
715                 if (!memcmp(&(pmlmepriv->cur_network.network.mac_address), pnetwork->mac_address, ETH_ALEN)) {
716                         struct wlan_network *ibss_wlan = NULL;
717
718                         memcpy(pmlmepriv->cur_network.network.ies, pnetwork->ies, 8);
719                         spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
720                         ibss_wlan = rtw_find_network(&pmlmepriv->scanned_queue,  pnetwork->mac_address);
721                         if (ibss_wlan) {
722                                 memcpy(ibss_wlan->network.ies, pnetwork->ies, 8);
723                                 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
724                                 goto exit;
725                         }
726                         spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
727                 }
728         }
729
730         /*  lock pmlmepriv->lock when you accessing network_q */
731         if ((check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) == false) {
732                 if (pnetwork->ssid.ssid[0] == 0)
733                         pnetwork->ssid.ssid_length = 0;
734                 rtw_add_network(adapter, pnetwork);
735         }
736
737 exit:
738
739         spin_unlock_bh(&pmlmepriv->lock);
740 }
741
742 void rtw_surveydone_event_callback(struct adapter       *adapter, u8 *pbuf)
743 {
744         struct  mlme_priv *pmlmepriv = &(adapter->mlmepriv);
745
746         spin_lock_bh(&pmlmepriv->lock);
747         if (pmlmepriv->wps_probe_req_ie) {
748                 pmlmepriv->wps_probe_req_ie_len = 0;
749                 kfree(pmlmepriv->wps_probe_req_ie);
750                 pmlmepriv->wps_probe_req_ie = NULL;
751         }
752
753         if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) {
754                 spin_unlock_bh(&pmlmepriv->lock);
755                 del_timer_sync(&pmlmepriv->scan_to_timer);
756                 spin_lock_bh(&pmlmepriv->lock);
757                 _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
758         }
759
760         rtw_set_signal_stat_timer(&adapter->recvpriv);
761
762         if (pmlmepriv->to_join) {
763                 if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true)) {
764                         if (check_fwstate(pmlmepriv, _FW_LINKED) == false) {
765                                 set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
766
767                                 if (rtw_select_and_join_from_scanned_queue(pmlmepriv) == _SUCCESS) {
768                                         _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT);
769                                 } else {
770                                         u8 ret = _SUCCESS;
771                                         struct wlan_bssid_ex    *pdev_network = &(adapter->registrypriv.dev_network);
772                                         u8 *pibss = adapter->registrypriv.dev_network.mac_address;
773
774                                         /* pmlmepriv->fw_state ^= _FW_UNDER_SURVEY;because don't set assoc_timer */
775                                         _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
776
777                                         memcpy(&pdev_network->ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid));
778
779                                         rtw_update_registrypriv_dev_network(adapter);
780                                         rtw_generate_random_ibss(pibss);
781
782                                         pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;
783
784                                         pmlmepriv->to_join = false;
785
786                                         ret = rtw_createbss_cmd(adapter);
787                                         if (ret != _SUCCESS)
788                                                 goto unlock;
789                                 }
790                         }
791                 } else {
792                         int s_ret;
793
794                         set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
795                         pmlmepriv->to_join = false;
796                         s_ret = rtw_select_and_join_from_scanned_queue(pmlmepriv);
797                         if (s_ret == _SUCCESS) {
798                              _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT);
799                         } else if (s_ret == 2) {/* there is no need to wait for join */
800                                 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
801                                 rtw_indicate_connect(adapter);
802                         } else {
803                                 if (rtw_to_roam(adapter) != 0) {
804                                         if (rtw_dec_to_roam(adapter) == 0
805                                                 || _SUCCESS != rtw_sitesurvey_cmd(adapter, &pmlmepriv->assoc_ssid, 1, NULL, 0)
806                                         ) {
807                                                 rtw_set_to_roam(adapter, 0);
808                                                 rtw_free_assoc_resources(adapter, 1);
809                                                 rtw_indicate_disconnect(adapter);
810                                         } else {
811                                                 pmlmepriv->to_join = true;
812                                         }
813                                 } else
814                                         rtw_indicate_disconnect(adapter);
815
816                                 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
817                         }
818                 }
819         } else {
820                 if (rtw_chk_roam_flags(adapter, RTW_ROAM_ACTIVE)) {
821                         if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)
822                                 && check_fwstate(pmlmepriv, _FW_LINKED)) {
823                                 if (rtw_select_roaming_candidate(pmlmepriv) == _SUCCESS) {
824                                         receive_disconnect(adapter, pmlmepriv->cur_network.network.mac_address
825                                                 , WLAN_REASON_ACTIVE_ROAM);
826                                 }
827                         }
828                 }
829         }
830
831 unlock:
832         spin_unlock_bh(&pmlmepriv->lock);
833
834         rtw_os_xmit_schedule(adapter);
835
836         rtw_cfg80211_surveydone_event_callback(adapter);
837
838         rtw_indicate_scan_done(adapter, false);
839 }
840
841 void rtw_dummy_event_callback(struct adapter *adapter, u8 *pbuf)
842 {
843 }
844
845 void rtw_fwdbg_event_callback(struct adapter *adapter, u8 *pbuf)
846 {
847 }
848
849 static void free_scanqueue(struct       mlme_priv *pmlmepriv)
850 {
851         struct __queue *free_queue = &pmlmepriv->free_bss_pool;
852         struct __queue *scan_queue = &pmlmepriv->scanned_queue;
853         struct list_head        *plist, *phead, *ptemp;
854
855         spin_lock_bh(&scan_queue->lock);
856         spin_lock_bh(&free_queue->lock);
857
858         phead = get_list_head(scan_queue);
859         plist = get_next(phead);
860
861         while (plist != phead) {
862                 ptemp = get_next(plist);
863                 list_del_init(plist);
864                 list_add_tail(plist, &free_queue->queue);
865                 plist = ptemp;
866                 pmlmepriv->num_of_scanned--;
867         }
868
869         spin_unlock_bh(&free_queue->lock);
870         spin_unlock_bh(&scan_queue->lock);
871 }
872
873 static void rtw_reset_rx_info(struct debug_priv *pdbgpriv)
874 {
875         pdbgpriv->dbg_rx_ampdu_drop_count = 0;
876         pdbgpriv->dbg_rx_ampdu_forced_indicate_count = 0;
877         pdbgpriv->dbg_rx_ampdu_loss_count = 0;
878         pdbgpriv->dbg_rx_dup_mgt_frame_drop_count = 0;
879         pdbgpriv->dbg_rx_ampdu_window_shift_cnt = 0;
880 }
881
882 static void find_network(struct adapter *adapter)
883 {
884         struct wlan_network *pwlan = NULL;
885         struct  mlme_priv *pmlmepriv = &adapter->mlmepriv;
886         struct wlan_network *tgt_network = &pmlmepriv->cur_network;
887
888         pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.mac_address);
889         if (pwlan)
890                 pwlan->fixed = false;
891
892         if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) &&
893             (adapter->stapriv.asoc_sta_count == 1))
894                 rtw_free_network_nolock(adapter, pwlan);
895 }
896
897 /*
898 *rtw_free_assoc_resources: the caller has to lock pmlmepriv->lock
899 */
900 void rtw_free_assoc_resources(struct adapter *adapter, int lock_scanned_queue)
901 {
902         struct  mlme_priv *pmlmepriv = &adapter->mlmepriv;
903         struct wlan_network *tgt_network = &pmlmepriv->cur_network;
904         struct dvobj_priv *psdpriv = adapter->dvobj;
905         struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
906
907         if (check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_AP_STATE)) {
908                 struct sta_info *psta;
909
910                 psta = rtw_get_stainfo(&adapter->stapriv, tgt_network->network.mac_address);
911                 rtw_free_stainfo(adapter,  psta);
912         }
913
914         if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE)) {
915                 struct sta_info *psta;
916
917                 rtw_free_all_stainfo(adapter);
918
919                 psta = rtw_get_bcmc_stainfo(adapter);
920                 rtw_free_stainfo(adapter, psta);
921
922                 rtw_init_bcmc_stainfo(adapter);
923         }
924
925         find_network(adapter);
926
927         if (lock_scanned_queue)
928                 adapter->securitypriv.key_mask = 0;
929
930         rtw_reset_rx_info(pdbgpriv);
931 }
932
933 /*
934 *rtw_indicate_connect: the caller has to lock pmlmepriv->lock
935 */
936 void rtw_indicate_connect(struct adapter *padapter)
937 {
938         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
939
940         pmlmepriv->to_join = false;
941
942         if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
943
944                 set_fwstate(pmlmepriv, _FW_LINKED);
945
946                 rtw_os_indicate_connect(padapter);
947         }
948
949         rtw_set_to_roam(padapter, 0);
950         rtw_set_scan_deny(padapter, 3000);
951
952 }
953
954 /*
955 *rtw_indicate_disconnect: the caller has to lock pmlmepriv->lock
956 */
957 void rtw_indicate_disconnect(struct adapter *padapter)
958 {
959         struct  mlme_priv *pmlmepriv = &padapter->mlmepriv;
960
961         _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING|WIFI_UNDER_WPS);
962
963         if (rtw_to_roam(padapter) > 0)
964                 _clr_fwstate_(pmlmepriv, _FW_LINKED);
965
966         if (check_fwstate(&padapter->mlmepriv, _FW_LINKED)
967                 || (rtw_to_roam(padapter) <= 0)
968         ) {
969                 rtw_os_indicate_disconnect(padapter);
970
971                 /* set ips_deny_time to avoid enter IPS before LPS leave */
972                 rtw_set_ips_deny(padapter, 3000);
973
974                 _clr_fwstate_(pmlmepriv, _FW_LINKED);
975
976                 rtw_clear_scan_deny(padapter);
977         }
978
979         rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_DISCONNECT, 1);
980 }
981
982 inline void rtw_indicate_scan_done(struct adapter *padapter, bool aborted)
983 {
984         rtw_os_indicate_scan_done(padapter, aborted);
985
986         if (is_primary_adapter(padapter) &&
987             (!adapter_to_pwrctl(padapter)->bInSuspend) &&
988             (!check_fwstate(&padapter->mlmepriv,
989                             WIFI_ASOC_STATE|WIFI_UNDER_LINKING))) {
990                 rtw_set_ips_deny(padapter, 0);
991                 _set_timer(&padapter->mlmepriv.dynamic_chk_timer, 1);
992         }
993 }
994
995 void rtw_scan_abort(struct adapter *adapter)
996 {
997         unsigned long start;
998         struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
999         struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
1000
1001         start = jiffies;
1002         pmlmeext->scan_abort = true;
1003         while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)
1004                 && jiffies_to_msecs(start) <= 200) {
1005
1006                 if (adapter->bDriverStopped || adapter->bSurpriseRemoved)
1007                         break;
1008
1009                 msleep(20);
1010         }
1011
1012         if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
1013                 rtw_indicate_scan_done(adapter, true);
1014
1015         pmlmeext->scan_abort = false;
1016 }
1017
1018 static struct sta_info *rtw_joinbss_update_stainfo(struct adapter *padapter, struct wlan_network *pnetwork)
1019 {
1020         int i;
1021         struct sta_info *bmc_sta, *psta = NULL;
1022         struct recv_reorder_ctrl *preorder_ctrl;
1023         struct sta_priv *pstapriv = &padapter->stapriv;
1024         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1025
1026         psta = rtw_get_stainfo(pstapriv, pnetwork->network.mac_address);
1027         if (!psta)
1028                 psta = rtw_alloc_stainfo(pstapriv, pnetwork->network.mac_address);
1029
1030         if (psta) { /* update ptarget_sta */
1031
1032                 psta->aid  = pnetwork->join_res;
1033
1034                 update_sta_info(padapter, psta);
1035
1036                 /* update station supportRate */
1037                 psta->bssratelen = rtw_get_rateset_len(pnetwork->network.supported_rates);
1038                 memcpy(psta->bssrateset, pnetwork->network.supported_rates, psta->bssratelen);
1039                 rtw_hal_update_sta_rate_mask(padapter, psta);
1040
1041                 psta->wireless_mode = pmlmeext->cur_wireless_mode;
1042                 psta->raid = networktype_to_raid_ex(padapter, psta);
1043
1044                 /* sta mode */
1045                 rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, true);
1046
1047                 /* security related */
1048                 if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) {
1049                         padapter->securitypriv.binstallGrpkey = false;
1050                         padapter->securitypriv.busetkipkey = false;
1051                         padapter->securitypriv.bgrpkey_handshake = false;
1052
1053                         psta->ieee8021x_blocked = true;
1054                         psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
1055
1056                         memset((u8 *)&psta->dot118021x_UncstKey, 0, sizeof(union Keytype));
1057
1058                         memset((u8 *)&psta->dot11tkiprxmickey, 0, sizeof(union Keytype));
1059                         memset((u8 *)&psta->dot11tkiptxmickey, 0, sizeof(union Keytype));
1060
1061                         memset((u8 *)&psta->dot11txpn, 0, sizeof(union pn48));
1062                         psta->dot11txpn.val = psta->dot11txpn.val + 1;
1063                         memset((u8 *)&psta->dot11wtxpn, 0, sizeof(union pn48));
1064                         memset((u8 *)&psta->dot11rxpn, 0, sizeof(union pn48));
1065                 }
1066
1067                 /*      Commented by Albert 2012/07/21 */
1068                 /*      When doing the WPS, the wps_ie_len won't equal to 0 */
1069                 /*      And the Wi-Fi driver shouldn't allow the data packet to be transmitted. */
1070                 if (padapter->securitypriv.wps_ie_len != 0) {
1071                         psta->ieee8021x_blocked = true;
1072                         padapter->securitypriv.wps_ie_len = 0;
1073                 }
1074
1075                 /* for A-MPDU Rx reordering buffer control for bmc_sta & sta_info */
1076                 /* if A-MPDU Rx is enabled, resetting  rx_ordering_ctrl wstart_b(indicate_seq) to default value = 0xffff */
1077                 /* todo: check if AP can send A-MPDU packets */
1078                 for (i = 0; i < 16 ; i++) {
1079                         /* preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; */
1080                         preorder_ctrl = &psta->recvreorder_ctrl[i];
1081                         preorder_ctrl->enable = false;
1082                         preorder_ctrl->indicate_seq = 0xffff;
1083                         preorder_ctrl->wend_b = 0xffff;
1084                         preorder_ctrl->wsize_b = 64;/* max_ampdu_sz;ex. 32(kbytes) -> wsize_b =32 */
1085                 }
1086
1087                 bmc_sta = rtw_get_bcmc_stainfo(padapter);
1088                 if (bmc_sta) {
1089                         for (i = 0; i < 16 ; i++) {
1090                                 /* preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; */
1091                                 preorder_ctrl = &bmc_sta->recvreorder_ctrl[i];
1092                                 preorder_ctrl->enable = false;
1093                                 preorder_ctrl->indicate_seq = 0xffff;
1094                                 preorder_ctrl->wend_b = 0xffff;
1095                                 preorder_ctrl->wsize_b = 64;/* max_ampdu_sz;ex. 32(kbytes) -> wsize_b =32 */
1096                         }
1097                 }
1098         }
1099
1100         return psta;
1101
1102 }
1103
1104 /* pnetwork : returns from rtw_joinbss_event_callback */
1105 /* ptarget_wlan: found from scanned_queue */
1106 static void rtw_joinbss_update_network(struct adapter *padapter, struct wlan_network *ptarget_wlan, struct wlan_network  *pnetwork)
1107 {
1108         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1109         struct wlan_network  *cur_network = &(pmlmepriv->cur_network);
1110
1111         /*  why not use ptarget_wlan?? */
1112         memcpy(&cur_network->network, &pnetwork->network, pnetwork->network.length);
1113         /*  some ies in pnetwork is wrong, so we should use ptarget_wlan ies */
1114         cur_network->network.ie_length = ptarget_wlan->network.ie_length;
1115         memcpy(&cur_network->network.ies[0], &ptarget_wlan->network.ies[0], MAX_IE_SZ);
1116
1117         cur_network->aid = pnetwork->join_res;
1118
1119         rtw_set_signal_stat_timer(&padapter->recvpriv);
1120
1121         padapter->recvpriv.signal_strength = ptarget_wlan->network.phy_info.signal_strength;
1122         padapter->recvpriv.signal_qual = ptarget_wlan->network.phy_info.signal_quality;
1123         /* the ptarget_wlan->network.rssi is raw data, we use ptarget_wlan->network.phy_info.signal_strength instead (has scaled) */
1124         padapter->recvpriv.rssi = translate_percentage_to_dbm(ptarget_wlan->network.phy_info.signal_strength);
1125
1126         rtw_set_signal_stat_timer(&padapter->recvpriv);
1127
1128         /* update fw_state will clr _FW_UNDER_LINKING here indirectly */
1129         switch (pnetwork->network.infrastructure_mode) {
1130         case Ndis802_11Infrastructure:
1131
1132                         if (pmlmepriv->fw_state&WIFI_UNDER_WPS)
1133                                 pmlmepriv->fw_state = WIFI_STATION_STATE|WIFI_UNDER_WPS;
1134                         else
1135                                 pmlmepriv->fw_state = WIFI_STATION_STATE;
1136
1137                         break;
1138         case Ndis802_11IBSS:
1139                         pmlmepriv->fw_state = WIFI_ADHOC_STATE;
1140                         break;
1141         default:
1142                         pmlmepriv->fw_state = WIFI_NULL_STATE;
1143                         break;
1144         }
1145
1146         rtw_update_protection(padapter, (cur_network->network.ies) + sizeof(struct ndis_802_11_fix_ie),
1147                                                                         (cur_network->network.ie_length));
1148
1149         rtw_update_ht_cap(padapter, cur_network->network.ies, cur_network->network.ie_length, (u8) cur_network->network.configuration.ds_config);
1150 }
1151
1152 /* Notes: the function could be > passive_level (the same context as Rx tasklet) */
1153 /* pnetwork : returns from rtw_joinbss_event_callback */
1154 /* ptarget_wlan: found from scanned_queue */
1155 /* if join_res > 0, for (fw_state ==WIFI_STATION_STATE), we check if  "ptarget_sta" & "ptarget_wlan" exist. */
1156 /* if join_res > 0, for (fw_state ==WIFI_ADHOC_STATE), we only check if "ptarget_wlan" exist. */
1157 /* if join_res > 0, update "cur_network->network" from "pnetwork->network" if (ptarget_wlan != NULL). */
1158 /*  */
1159 /* define REJOIN */
1160 void rtw_joinbss_event_prehandle(struct adapter *adapter, u8 *pbuf)
1161 {
1162         static u8 __maybe_unused retry;
1163         struct sta_info *ptarget_sta = NULL, *pcur_sta = NULL;
1164         struct  sta_priv *pstapriv = &adapter->stapriv;
1165         struct  mlme_priv *pmlmepriv = &(adapter->mlmepriv);
1166         struct wlan_network     *pnetwork       = (struct wlan_network *)pbuf;
1167         struct wlan_network     *cur_network = &(pmlmepriv->cur_network);
1168         struct wlan_network     *pcur_wlan = NULL, *ptarget_wlan = NULL;
1169         unsigned int            the_same_macaddr = false;
1170
1171         rtw_get_encrypt_decrypt_from_registrypriv(adapter);
1172
1173         the_same_macaddr = !memcmp(pnetwork->network.mac_address, cur_network->network.mac_address, ETH_ALEN);
1174
1175         pnetwork->network.length = get_wlan_bssid_ex_sz(&pnetwork->network);
1176         if (pnetwork->network.length > sizeof(struct wlan_bssid_ex))
1177                 return;
1178
1179         spin_lock_bh(&pmlmepriv->lock);
1180
1181         pmlmepriv->LinkDetectInfo.TrafficTransitionCount = 0;
1182         pmlmepriv->LinkDetectInfo.LowPowerTransitionCount = 0;
1183
1184         if (pnetwork->join_res > 0) {
1185                 spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
1186                 retry = 0;
1187                 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) {
1188                         /* s1. find ptarget_wlan */
1189                         if (check_fwstate(pmlmepriv, _FW_LINKED)) {
1190                                 if (the_same_macaddr) {
1191                                         ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.mac_address);
1192                                 } else {
1193                                         pcur_wlan = rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.mac_address);
1194                                         if (pcur_wlan)
1195                                                 pcur_wlan->fixed = false;
1196
1197                                         pcur_sta = rtw_get_stainfo(pstapriv, cur_network->network.mac_address);
1198                                         if (pcur_sta)
1199                                                 rtw_free_stainfo(adapter,  pcur_sta);
1200
1201                                         ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, pnetwork->network.mac_address);
1202                                         if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true) {
1203                                                 if (ptarget_wlan)
1204                                                         ptarget_wlan->fixed = true;
1205                                         }
1206                                 }
1207
1208                         } else {
1209                                 ptarget_wlan = _rtw_find_same_network(&pmlmepriv->scanned_queue, pnetwork);
1210                                 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true) {
1211                                         if (ptarget_wlan)
1212                                                 ptarget_wlan->fixed = true;
1213                                 }
1214                         }
1215
1216                         /* s2. update cur_network */
1217                         if (ptarget_wlan) {
1218                                 rtw_joinbss_update_network(adapter, ptarget_wlan, pnetwork);
1219                         } else {
1220                                 netdev_dbg(adapter->pnetdev,
1221                                            "Can't find ptarget_wlan when joinbss_event callback\n");
1222                                 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
1223                                 goto ignore_joinbss_callback;
1224                         }
1225
1226                         /* s3. find ptarget_sta & update ptarget_sta after update cur_network only for station mode */
1227                         if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true) {
1228                                 ptarget_sta = rtw_joinbss_update_stainfo(adapter, pnetwork);
1229                                 if (!ptarget_sta) {
1230                                         spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
1231                                         goto ignore_joinbss_callback;
1232                                 }
1233                         }
1234
1235                         /* s4. indicate connect */
1236                         if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true) {
1237                                 pmlmepriv->cur_network_scanned = ptarget_wlan;
1238                                 rtw_indicate_connect(adapter);
1239                         }
1240
1241                         spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1242
1243                         spin_unlock_bh(&pmlmepriv->lock);
1244                         /* s5. Cancel assoc_timer */
1245                         del_timer_sync(&pmlmepriv->assoc_timer);
1246                         spin_lock_bh(&pmlmepriv->lock);
1247                 } else {
1248                         spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
1249                 }
1250         } else if (pnetwork->join_res == -4) {
1251                 rtw_reset_securitypriv(adapter);
1252                 _set_timer(&pmlmepriv->assoc_timer, 1);
1253
1254                 /* rtw_free_assoc_resources(adapter, 1); */
1255
1256                 if ((check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) == true)
1257                         _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
1258
1259         } else {/* if join_res < 0 (join fails), then try again */
1260
1261                 #ifdef REJOIN
1262                 res = _FAIL;
1263                 if (retry < 2)
1264                         res = rtw_select_and_join_from_scanned_queue(pmlmepriv);
1265
1266                 if (res == _SUCCESS) {
1267                         /* extend time of assoc_timer */
1268                         _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT);
1269                         retry++;
1270                 } else if (res == 2) {/* there is no need to wait for join */
1271                         _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
1272                         rtw_indicate_connect(adapter);
1273                 } else {
1274                 #endif
1275
1276                         _set_timer(&pmlmepriv->assoc_timer, 1);
1277                         /* rtw_free_assoc_resources(adapter, 1); */
1278                         _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
1279
1280                 #ifdef REJOIN
1281                         retry = 0;
1282                 }
1283                 #endif
1284         }
1285
1286 ignore_joinbss_callback:
1287
1288         spin_unlock_bh(&pmlmepriv->lock);
1289 }
1290
1291 void rtw_joinbss_event_callback(struct adapter *adapter, u8 *pbuf)
1292 {
1293         struct wlan_network     *pnetwork       = (struct wlan_network *)pbuf;
1294
1295         mlmeext_joinbss_event_callback(adapter, pnetwork->join_res);
1296
1297         rtw_os_xmit_schedule(adapter);
1298 }
1299
1300 /* FOR STA, AP , AD-HOC mode */
1301 void rtw_sta_media_status_rpt(struct adapter *adapter, struct sta_info *psta, u32 mstatus)
1302 {
1303         u16 media_status_rpt;
1304
1305         if (!psta)
1306                 return;
1307
1308         media_status_rpt = (u16)((psta->mac_id<<8)|mstatus); /*   MACID|OPMODE:1 connect */
1309         rtw_hal_set_hwreg(adapter, HW_VAR_H2C_MEDIA_STATUS_RPT, (u8 *)&media_status_rpt);
1310 }
1311
1312 void rtw_stassoc_event_callback(struct adapter *adapter, u8 *pbuf)
1313 {
1314         struct sta_info *psta;
1315         struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
1316         struct stassoc_event    *pstassoc       = (struct stassoc_event *)pbuf;
1317         struct wlan_network     *cur_network = &(pmlmepriv->cur_network);
1318         struct wlan_network     *ptarget_wlan = NULL;
1319
1320         if (rtw_access_ctrl(adapter, pstassoc->macaddr) == false)
1321                 return;
1322
1323         if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1324                 psta = rtw_get_stainfo(&adapter->stapriv, pstassoc->macaddr);
1325                 if (psta) {
1326                         u8 *passoc_req = NULL;
1327                         u32 assoc_req_len = 0;
1328
1329                         rtw_sta_media_status_rpt(adapter, psta, 1);
1330
1331                         ap_sta_info_defer_update(adapter, psta);
1332
1333                         /* report to upper layer */
1334                         spin_lock_bh(&psta->lock);
1335                         if (psta->passoc_req && psta->assoc_req_len > 0) {
1336                                 passoc_req = rtw_zmalloc(psta->assoc_req_len);
1337                                 if (passoc_req) {
1338                                         assoc_req_len = psta->assoc_req_len;
1339                                         memcpy(passoc_req, psta->passoc_req, assoc_req_len);
1340
1341                                         kfree(psta->passoc_req);
1342                                         psta->passoc_req = NULL;
1343                                         psta->assoc_req_len = 0;
1344                                 }
1345                         }
1346                         spin_unlock_bh(&psta->lock);
1347
1348                         if (passoc_req && assoc_req_len > 0) {
1349                                 rtw_cfg80211_indicate_sta_assoc(adapter, passoc_req, assoc_req_len);
1350
1351                                 kfree(passoc_req);
1352                         }
1353                 }
1354                 return;
1355         }
1356
1357         /* for AD-HOC mode */
1358         psta = rtw_get_stainfo(&adapter->stapriv, pstassoc->macaddr);
1359         if (psta) {
1360                 /* the sta have been in sta_info_queue => do nothing */
1361
1362                 return; /* between drv has received this event before and  fw have not yet to set key to CAM_ENTRY) */
1363         }
1364
1365         psta = rtw_alloc_stainfo(&adapter->stapriv, pstassoc->macaddr);
1366         if (!psta)
1367                 return;
1368
1369         /* to do : init sta_info variable */
1370         psta->qos_option = 0;
1371         psta->mac_id = (uint)pstassoc->cam_id;
1372         /* psta->aid = (uint)pstassoc->cam_id; */
1373
1374         /* for ad-hoc mode */
1375         rtw_hal_set_odm_var(adapter, HAL_ODM_STA_INFO, psta, true);
1376
1377         rtw_sta_media_status_rpt(adapter, psta, 1);
1378
1379         if (adapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)
1380                 psta->dot118021XPrivacy = adapter->securitypriv.dot11PrivacyAlgrthm;
1381
1382         psta->ieee8021x_blocked = false;
1383
1384         spin_lock_bh(&pmlmepriv->lock);
1385
1386         if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) ||
1387                 (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true)) {
1388                 if (adapter->stapriv.asoc_sta_count == 2) {
1389                         spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
1390                         ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.mac_address);
1391                         pmlmepriv->cur_network_scanned = ptarget_wlan;
1392                         if (ptarget_wlan)
1393                                 ptarget_wlan->fixed = true;
1394                         spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
1395                         /*  a sta + bc/mc_stainfo (not Ibss_stainfo) */
1396                         rtw_indicate_connect(adapter);
1397                 }
1398         }
1399
1400         spin_unlock_bh(&pmlmepriv->lock);
1401
1402         mlmeext_sta_add_event_callback(adapter, psta);
1403 }
1404
1405 void rtw_stadel_event_callback(struct adapter *adapter, u8 *pbuf)
1406 {
1407         int mac_id = (-1);
1408         struct sta_info *psta;
1409         struct wlan_network *pwlan = NULL;
1410         struct wlan_bssid_ex    *pdev_network = NULL;
1411         u8 *pibss = NULL;
1412         struct  mlme_priv *pmlmepriv = &(adapter->mlmepriv);
1413         struct  stadel_event *pstadel   = (struct stadel_event *)pbuf;
1414         struct wlan_network *tgt_network = &(pmlmepriv->cur_network);
1415         struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
1416         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1417
1418         psta = rtw_get_stainfo(&adapter->stapriv, pstadel->macaddr);
1419         if (psta)
1420                 mac_id = psta->mac_id;
1421         else
1422                 mac_id = pstadel->mac_id;
1423
1424         if (mac_id >= 0) {
1425                 u16 media_status;
1426
1427                 media_status = (mac_id<<8)|0; /*   MACID|OPMODE:0 means disconnect */
1428                 /* for STA, AP, ADHOC mode, report disconnect stauts to FW */
1429                 rtw_hal_set_hwreg(adapter, HW_VAR_H2C_MEDIA_STATUS_RPT, (u8 *)&media_status);
1430         }
1431
1432         /* if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) */
1433         if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
1434                 return;
1435
1436         mlmeext_sta_del_event_callback(adapter);
1437
1438         spin_lock_bh(&pmlmepriv->lock);
1439
1440         if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
1441                 u16 reason = *((unsigned short *)(pstadel->rsvd));
1442                 bool roam = false;
1443                 struct wlan_network *roam_target = NULL;
1444
1445                 if (adapter->registrypriv.wifi_spec == 1) {
1446                         roam = false;
1447                 } else if (reason == WLAN_REASON_EXPIRATION_CHK && rtw_chk_roam_flags(adapter, RTW_ROAM_ON_EXPIRED)) {
1448                         roam = true;
1449                 } else if (reason == WLAN_REASON_ACTIVE_ROAM && rtw_chk_roam_flags(adapter, RTW_ROAM_ACTIVE)) {
1450                         roam = true;
1451                         roam_target = pmlmepriv->roam_network;
1452                 }
1453
1454                 if (roam) {
1455                         if (rtw_to_roam(adapter) > 0)
1456                                 rtw_dec_to_roam(adapter); /* this stadel_event is caused by roaming, decrease to_roam */
1457                         else if (rtw_to_roam(adapter) == 0)
1458                                 rtw_set_to_roam(adapter, adapter->registrypriv.max_roaming_times);
1459                 } else {
1460                         rtw_set_to_roam(adapter, 0);
1461                 }
1462
1463                 rtw_free_uc_swdec_pending_queue(adapter);
1464
1465                 rtw_free_assoc_resources(adapter, 1);
1466                 rtw_indicate_disconnect(adapter);
1467
1468                 spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
1469                 /*  remove the network entry in scanned_queue */
1470                 pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.mac_address);
1471                 if (pwlan) {
1472                         pwlan->fixed = false;
1473                         rtw_free_network_nolock(adapter, pwlan);
1474                 }
1475                 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
1476
1477                 _rtw_roaming(adapter, roam_target);
1478         }
1479
1480         if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) ||
1481               check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
1482
1483                 rtw_free_stainfo(adapter,  psta);
1484
1485                 if (adapter->stapriv.asoc_sta_count == 1) {/* a sta + bc/mc_stainfo (not Ibss_stainfo) */
1486                         u8 ret = _SUCCESS;
1487                         /* rtw_indicate_disconnect(adapter);removed@20091105 */
1488                         spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
1489                         /* free old ibss network */
1490                         /* pwlan = rtw_find_network(&pmlmepriv->scanned_queue, pstadel->macaddr); */
1491                         pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.mac_address);
1492                         if (pwlan) {
1493                                 pwlan->fixed = false;
1494                                 rtw_free_network_nolock(adapter, pwlan);
1495                         }
1496                         spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
1497                         /* re-create ibss */
1498                         pdev_network = &(adapter->registrypriv.dev_network);
1499                         pibss = adapter->registrypriv.dev_network.mac_address;
1500
1501                         memcpy(pdev_network, &tgt_network->network, get_wlan_bssid_ex_sz(&tgt_network->network));
1502
1503                         memcpy(&pdev_network->ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid));
1504
1505                         rtw_update_registrypriv_dev_network(adapter);
1506
1507                         rtw_generate_random_ibss(pibss);
1508
1509                         if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
1510                                 set_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
1511                                 _clr_fwstate_(pmlmepriv, WIFI_ADHOC_STATE);
1512                         }
1513
1514                         ret = rtw_createbss_cmd(adapter);
1515                         if (ret != _SUCCESS)
1516                                 goto unlock;
1517                 }
1518
1519         }
1520
1521 unlock:
1522         spin_unlock_bh(&pmlmepriv->lock);
1523 }
1524
1525 void rtw_cpwm_event_callback(struct adapter *padapter, u8 *pbuf)
1526 {
1527         struct reportpwrstate_parm *preportpwrstate;
1528
1529         preportpwrstate = (struct reportpwrstate_parm *)pbuf;
1530         preportpwrstate->state |= (u8)(adapter_to_pwrctl(padapter)->cpwm_tog + 0x80);
1531         cpwm_int_hdl(padapter, preportpwrstate);
1532 }
1533
1534 void rtw_wmm_event_callback(struct adapter *padapter, u8 *pbuf)
1535 {
1536         WMMOnAssocRsp(padapter);
1537 }
1538
1539 /*
1540 * _rtw_join_timeout_handler - Timeout/failure handler for CMD JoinBss
1541 * @adapter: pointer to struct adapter structure
1542 */
1543 void _rtw_join_timeout_handler(struct timer_list *t)
1544 {
1545         struct adapter *adapter = from_timer(adapter, t,
1546                                                   mlmepriv.assoc_timer);
1547         struct  mlme_priv *pmlmepriv = &adapter->mlmepriv;
1548
1549         if (adapter->bDriverStopped || adapter->bSurpriseRemoved)
1550                 return;
1551
1552         spin_lock_irq(&pmlmepriv->lock);
1553
1554         if (rtw_to_roam(adapter) > 0) { /* join timeout caused by roaming */
1555                 while (1) {
1556                         rtw_dec_to_roam(adapter);
1557                         if (rtw_to_roam(adapter) != 0) { /* try another */
1558                                 int do_join_r;
1559
1560                                 do_join_r = rtw_do_join(adapter);
1561                                 if (do_join_r != _SUCCESS) {
1562                                         continue;
1563                                 }
1564                                 break;
1565                         } else {
1566                                 rtw_indicate_disconnect(adapter);
1567                                 break;
1568                         }
1569                 }
1570
1571         } else {
1572                 rtw_indicate_disconnect(adapter);
1573                 free_scanqueue(pmlmepriv);/*  */
1574
1575                 /* indicate disconnect for the case that join_timeout and check_fwstate != FW_LINKED */
1576                 rtw_cfg80211_indicate_disconnect(adapter);
1577
1578         }
1579
1580         spin_unlock_irq(&pmlmepriv->lock);
1581 }
1582
1583 /*
1584 * rtw_scan_timeout_handler - Timeout/Failure handler for CMD SiteSurvey
1585 * @adapter: pointer to struct adapter structure
1586 */
1587 void rtw_scan_timeout_handler(struct timer_list *t)
1588 {
1589         struct adapter *adapter = from_timer(adapter, t,
1590                                                   mlmepriv.scan_to_timer);
1591         struct  mlme_priv *pmlmepriv = &adapter->mlmepriv;
1592
1593         spin_lock_irq(&pmlmepriv->lock);
1594
1595         _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
1596
1597         spin_unlock_irq(&pmlmepriv->lock);
1598
1599         rtw_indicate_scan_done(adapter, true);
1600 }
1601
1602 void rtw_mlme_reset_auto_scan_int(struct adapter *adapter)
1603 {
1604         struct mlme_priv *mlme = &adapter->mlmepriv;
1605         struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
1606         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1607
1608         if (pmlmeinfo->VHT_enable) /* disable auto scan when connect to 11AC AP */
1609                 mlme->auto_scan_int_ms = 0;
1610         else if (adapter->registrypriv.wifi_spec && is_client_associated_to_ap(adapter) == true)
1611                 mlme->auto_scan_int_ms = 60*1000;
1612         else if (rtw_chk_roam_flags(adapter, RTW_ROAM_ACTIVE)) {
1613                 if (check_fwstate(mlme, WIFI_STATION_STATE) && check_fwstate(mlme, _FW_LINKED))
1614                         mlme->auto_scan_int_ms = mlme->roam_scan_int_ms;
1615         } else
1616                 mlme->auto_scan_int_ms = 0; /* disabled */
1617 }
1618
1619 static void rtw_auto_scan_handler(struct adapter *padapter)
1620 {
1621         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1622
1623         rtw_mlme_reset_auto_scan_int(padapter);
1624
1625         if (pmlmepriv->auto_scan_int_ms != 0
1626                 && jiffies_to_msecs(jiffies - pmlmepriv->scan_start_time) > pmlmepriv->auto_scan_int_ms) {
1627
1628                 if (!padapter->registrypriv.wifi_spec) {
1629                         if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING) == true)
1630                                 goto exit;
1631
1632                         if (pmlmepriv->LinkDetectInfo.bBusyTraffic)
1633                                 goto exit;
1634                 }
1635
1636                 rtw_set_802_11_bssid_list_scan(padapter, NULL, 0);
1637         }
1638
1639 exit:
1640         return;
1641 }
1642
1643 void rtw_dynamic_check_timer_handler(struct adapter *adapter)
1644 {
1645         if (!adapter)
1646                 return;
1647
1648         if (!adapter->hw_init_completed)
1649                 return;
1650
1651         if (adapter->bDriverStopped || adapter->bSurpriseRemoved)
1652                 return;
1653
1654         if (adapter->net_closed)
1655                 return;
1656
1657         if ((adapter_to_pwrctl(adapter)->fw_current_in_ps_mode)
1658                 && !(hal_btcoex_IsBtControlLps(adapter))
1659                 ) {
1660                 u8 bEnterPS;
1661
1662                 linked_status_chk(adapter);
1663
1664                 bEnterPS = traffic_status_watchdog(adapter, 1);
1665                 if (bEnterPS) {
1666                         /* rtw_lps_ctrl_wk_cmd(adapter, LPS_CTRL_ENTER, 1); */
1667                         rtw_hal_dm_watchdog_in_lps(adapter);
1668                 } else {
1669                         /* call rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_LEAVE, 1) in traffic_status_watchdog() */
1670                 }
1671
1672         } else {
1673                 if (is_primary_adapter(adapter))
1674                         rtw_dynamic_chk_wk_cmd(adapter);
1675         }
1676
1677         /* auto site survey */
1678         rtw_auto_scan_handler(adapter);
1679 }
1680
1681 inline bool rtw_is_scan_deny(struct adapter *adapter)
1682 {
1683         struct mlme_priv *mlmepriv = &adapter->mlmepriv;
1684
1685         return (atomic_read(&mlmepriv->set_scan_deny) != 0) ? true : false;
1686 }
1687
1688 inline void rtw_clear_scan_deny(struct adapter *adapter)
1689 {
1690         struct mlme_priv *mlmepriv = &adapter->mlmepriv;
1691
1692         atomic_set(&mlmepriv->set_scan_deny, 0);
1693 }
1694
1695 void rtw_set_scan_deny(struct adapter *adapter, u32 ms)
1696 {
1697         struct mlme_priv *mlmepriv = &adapter->mlmepriv;
1698
1699         atomic_set(&mlmepriv->set_scan_deny, 1);
1700         _set_timer(&mlmepriv->set_scan_deny_timer, ms);
1701 }
1702
1703 /*
1704 * Select a new roaming candidate from the original @param candidate and @param competitor
1705 * @return true: candidate is updated
1706 * @return false: candidate is not updated
1707 */
1708 static int rtw_check_roaming_candidate(struct mlme_priv *mlme
1709         , struct wlan_network **candidate, struct wlan_network *competitor)
1710 {
1711         int updated = false;
1712         struct adapter *adapter = container_of(mlme, struct adapter, mlmepriv);
1713
1714         if (is_same_ess(&competitor->network, &mlme->cur_network.network) == false)
1715                 goto exit;
1716
1717         if (rtw_is_desired_network(adapter, competitor) == false)
1718                 goto exit;
1719
1720         /* got specific addr to roam */
1721         if (!is_zero_mac_addr(mlme->roam_tgt_addr)) {
1722                 if (!memcmp(mlme->roam_tgt_addr, competitor->network.mac_address, ETH_ALEN))
1723                         goto update;
1724                 else
1725                         goto exit;
1726         }
1727         if (jiffies_to_msecs(jiffies - competitor->last_scanned) >= mlme->roam_scanr_exp_ms)
1728                 goto exit;
1729
1730         if (competitor->network.rssi - mlme->cur_network_scanned->network.rssi < mlme->roam_rssi_diff_th)
1731                 goto exit;
1732
1733         if (*candidate && (*candidate)->network.rssi >= competitor->network.rssi)
1734                 goto exit;
1735
1736 update:
1737         *candidate = competitor;
1738         updated = true;
1739
1740 exit:
1741         return updated;
1742 }
1743
1744 int rtw_select_roaming_candidate(struct mlme_priv *mlme)
1745 {
1746         int ret = _FAIL;
1747         struct list_head        *phead;
1748         struct __queue  *queue  = &(mlme->scanned_queue);
1749         struct  wlan_network    *pnetwork = NULL;
1750         struct  wlan_network    *candidate = NULL;
1751
1752         if (!mlme->cur_network_scanned) {
1753                 rtw_warn_on(1);
1754                 return ret;
1755         }
1756
1757         spin_lock_bh(&(mlme->scanned_queue.lock));
1758         phead = get_list_head(queue);
1759
1760         list_for_each(mlme->pscanned, phead) {
1761
1762                 pnetwork = list_entry(mlme->pscanned, struct wlan_network,
1763                                       list);
1764
1765                 rtw_check_roaming_candidate(mlme, &candidate, pnetwork);
1766
1767         }
1768
1769         if (!candidate) {
1770                 ret = _FAIL;
1771                 goto exit;
1772         } else {
1773                 mlme->roam_network = candidate;
1774
1775                 if (!memcmp(candidate->network.mac_address, mlme->roam_tgt_addr, ETH_ALEN))
1776                         eth_zero_addr(mlme->roam_tgt_addr);
1777         }
1778
1779         ret = _SUCCESS;
1780 exit:
1781         spin_unlock_bh(&(mlme->scanned_queue.lock));
1782
1783         return ret;
1784 }
1785
1786 /*
1787 * Select a new join candidate from the original @param candidate and @param competitor
1788 * @return true: candidate is updated
1789 * @return false: candidate is not updated
1790 */
1791 static int rtw_check_join_candidate(struct mlme_priv *mlme
1792         , struct wlan_network **candidate, struct wlan_network *competitor)
1793 {
1794         int updated = false;
1795         struct adapter *adapter = container_of(mlme, struct adapter, mlmepriv);
1796
1797         /* check bssid, if needed */
1798         if (mlme->assoc_by_bssid) {
1799                 if (memcmp(competitor->network.mac_address, mlme->assoc_bssid, ETH_ALEN))
1800                         goto exit;
1801         }
1802
1803         /* check ssid, if needed */
1804         if (mlme->assoc_ssid.ssid[0] && mlme->assoc_ssid.ssid_length) {
1805                 if (competitor->network.ssid.ssid_length != mlme->assoc_ssid.ssid_length
1806                         || memcmp(competitor->network.ssid.ssid, mlme->assoc_ssid.ssid, mlme->assoc_ssid.ssid_length)
1807                 )
1808                         goto exit;
1809         }
1810
1811         if (rtw_is_desired_network(adapter, competitor)  == false)
1812                 goto exit;
1813
1814         if (rtw_to_roam(adapter) > 0) {
1815                 if (jiffies_to_msecs(jiffies - competitor->last_scanned) >= mlme->roam_scanr_exp_ms
1816                         || is_same_ess(&competitor->network, &mlme->cur_network.network) == false
1817                 )
1818                         goto exit;
1819         }
1820
1821         if (!*candidate || (*candidate)->network.rssi < competitor->network.rssi) {
1822                 *candidate = competitor;
1823                 updated = true;
1824         }
1825
1826 exit:
1827         return updated;
1828 }
1829
1830 /*
1831 Calling context:
1832 The caller of the sub-routine will be in critical section...
1833 The caller must hold the following spinlock
1834 pmlmepriv->lock
1835 */
1836
1837 int rtw_select_and_join_from_scanned_queue(struct mlme_priv *pmlmepriv)
1838 {
1839         int ret;
1840         struct list_head        *phead;
1841         struct adapter *adapter;
1842         struct __queue  *queue  = &(pmlmepriv->scanned_queue);
1843         struct  wlan_network    *pnetwork = NULL;
1844         struct  wlan_network    *candidate = NULL;
1845
1846         adapter = (struct adapter *)pmlmepriv->nic_hdl;
1847
1848         spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
1849
1850         if (pmlmepriv->roam_network) {
1851                 candidate = pmlmepriv->roam_network;
1852                 pmlmepriv->roam_network = NULL;
1853                 goto candidate_exist;
1854         }
1855
1856         phead = get_list_head(queue);
1857         list_for_each(pmlmepriv->pscanned, phead) {
1858
1859                 pnetwork = list_entry(pmlmepriv->pscanned,
1860                                       struct wlan_network, list);
1861
1862                 rtw_check_join_candidate(pmlmepriv, &candidate, pnetwork);
1863
1864         }
1865
1866         if (!candidate) {
1867                 ret = _FAIL;
1868                 goto exit;
1869         } else {
1870                 goto candidate_exist;
1871         }
1872
1873 candidate_exist:
1874
1875         /*  check for situation of  _FW_LINKED */
1876         if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
1877                 rtw_disassoc_cmd(adapter, 0, true);
1878                 rtw_indicate_disconnect(adapter);
1879                 rtw_free_assoc_resources(adapter, 0);
1880         }
1881
1882         set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
1883         ret = rtw_joinbss_cmd(adapter, candidate);
1884
1885 exit:
1886         spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
1887         return ret;
1888 }
1889
1890 signed int rtw_set_auth(struct adapter *adapter, struct security_priv *psecuritypriv)
1891 {
1892         struct  cmd_obj *pcmd;
1893         struct  setauth_parm *psetauthparm;
1894         struct  cmd_priv *pcmdpriv = &(adapter->cmdpriv);
1895         signed int              res = _SUCCESS;
1896
1897         pcmd = rtw_zmalloc(sizeof(struct cmd_obj));
1898         if (!pcmd) {
1899                 res = _FAIL;  /* try again */
1900                 goto exit;
1901         }
1902
1903         psetauthparm = rtw_zmalloc(sizeof(struct setauth_parm));
1904         if (!psetauthparm) {
1905                 kfree(pcmd);
1906                 res = _FAIL;
1907                 goto exit;
1908         }
1909
1910         psetauthparm->mode = (unsigned char)psecuritypriv->dot11AuthAlgrthm;
1911
1912         pcmd->cmdcode = _SetAuth_CMD_;
1913         pcmd->parmbuf = (unsigned char *)psetauthparm;
1914         pcmd->cmdsz =  (sizeof(struct setauth_parm));
1915         pcmd->rsp = NULL;
1916         pcmd->rspsz = 0;
1917
1918         INIT_LIST_HEAD(&pcmd->list);
1919
1920         res = rtw_enqueue_cmd(pcmdpriv, pcmd);
1921
1922 exit:
1923         return res;
1924 }
1925
1926 signed int rtw_set_key(struct adapter *adapter, struct security_priv *psecuritypriv, signed int keyid, u8 set_tx, bool enqueue)
1927 {
1928         u8 keylen;
1929         struct cmd_obj          *pcmd;
1930         struct setkey_parm      *psetkeyparm;
1931         struct cmd_priv         *pcmdpriv = &(adapter->cmdpriv);
1932         signed int      res = _SUCCESS;
1933
1934         psetkeyparm = rtw_zmalloc(sizeof(struct setkey_parm));
1935         if (!psetkeyparm) {
1936                 res = _FAIL;
1937                 goto exit;
1938         }
1939
1940         if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)
1941                 psetkeyparm->algorithm = (unsigned char)psecuritypriv->dot118021XGrpPrivacy;
1942         else
1943                 psetkeyparm->algorithm = (u8)psecuritypriv->dot11PrivacyAlgrthm;
1944
1945         psetkeyparm->keyid = (u8)keyid;/* 0~3 */
1946         psetkeyparm->set_tx = set_tx;
1947         if (is_wep_enc(psetkeyparm->algorithm))
1948                 adapter->securitypriv.key_mask |= BIT(psetkeyparm->keyid);
1949
1950         switch (psetkeyparm->algorithm) {
1951
1952         case _WEP40_:
1953                 keylen = 5;
1954                 memcpy(&(psetkeyparm->key[0]), &(psecuritypriv->dot11DefKey[keyid].skey[0]), keylen);
1955                 break;
1956         case _WEP104_:
1957                 keylen = 13;
1958                 memcpy(&(psetkeyparm->key[0]), &(psecuritypriv->dot11DefKey[keyid].skey[0]), keylen);
1959                 break;
1960         case _TKIP_:
1961                 keylen = 16;
1962                 memcpy(&psetkeyparm->key, &psecuritypriv->dot118021XGrpKey[keyid], keylen);
1963                 psetkeyparm->grpkey = 1;
1964                 break;
1965         case _AES_:
1966                 keylen = 16;
1967                 memcpy(&psetkeyparm->key, &psecuritypriv->dot118021XGrpKey[keyid], keylen);
1968                 psetkeyparm->grpkey = 1;
1969                 break;
1970         default:
1971                 res = _FAIL;
1972                 kfree(psetkeyparm);
1973                 goto exit;
1974         }
1975
1976         if (enqueue) {
1977                 pcmd = rtw_zmalloc(sizeof(struct cmd_obj));
1978                 if (!pcmd) {
1979                         kfree(psetkeyparm);
1980                         res = _FAIL;  /* try again */
1981                         goto exit;
1982                 }
1983
1984                 pcmd->cmdcode = _SetKey_CMD_;
1985                 pcmd->parmbuf = (u8 *)psetkeyparm;
1986                 pcmd->cmdsz =  (sizeof(struct setkey_parm));
1987                 pcmd->rsp = NULL;
1988                 pcmd->rspsz = 0;
1989
1990                 INIT_LIST_HEAD(&pcmd->list);
1991
1992                 res = rtw_enqueue_cmd(pcmdpriv, pcmd);
1993         } else {
1994                 setkey_hdl(adapter, (u8 *)psetkeyparm);
1995                 kfree(psetkeyparm);
1996         }
1997 exit:
1998         return res;
1999 }
2000
2001 /* adjust ies for rtw_joinbss_cmd in WMM */
2002 int rtw_restruct_wmm_ie(struct adapter *adapter, u8 *in_ie, u8 *out_ie, uint in_len, uint initial_out_len)
2003 {
2004         unsigned        int ielength = 0;
2005         unsigned int i, j;
2006
2007         i = 12; /* after the fixed IE */
2008         while (i < in_len) {
2009                 ielength = initial_out_len;
2010
2011                 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) { /* WMM element ID and OUI */
2012                         for (j = i; j < i + 9; j++) {
2013                                         out_ie[ielength] = in_ie[j];
2014                                         ielength++;
2015                         }
2016                         out_ie[initial_out_len + 1] = 0x07;
2017                         out_ie[initial_out_len + 6] = 0x00;
2018                         out_ie[initial_out_len + 8] = 0x00;
2019
2020                         break;
2021                 }
2022
2023                 i += (in_ie[i+1]+2); /*  to the next IE element */
2024         }
2025
2026         return ielength;
2027
2028 }
2029
2030 /*  */
2031 /*  Ported from 8185: IsInPreAuthKeyList(). (Renamed from SecIsInPreAuthKeyList(), 2006-10-13.) */
2032 /*  Added by Annie, 2006-05-07. */
2033 /*  */
2034 /*  Search by BSSID, */
2035 /*  Return Value: */
2036 /*              -1              :if there is no pre-auth key in the  table */
2037 /*              >= 0            :if there is pre-auth key, and   return the entry id */
2038 /*  */
2039 /*  */
2040
2041 static int SecIsInPMKIDList(struct adapter *Adapter, u8 *bssid)
2042 {
2043         struct security_priv *p = &Adapter->securitypriv;
2044         int i;
2045
2046         for (i = 0; i < NUM_PMKID_CACHE; i++)
2047                 if ((p->PMKIDList[i].bUsed) &&
2048                                 (!memcmp(p->PMKIDList[i].Bssid, bssid, ETH_ALEN)))
2049                         return i;
2050         return -1;
2051 }
2052
2053 /*  */
2054 /*  Check the RSN IE length */
2055 /*  If the RSN IE length <= 20, the RSN IE didn't include the PMKID information */
2056 /*  0-11th element in the array are the fixed IE */
2057 /*  12th element in the array is the IE */
2058 /*  13th element in the array is the IE length */
2059 /*  */
2060
2061 static int rtw_append_pmkid(struct adapter *Adapter, int iEntry, u8 *ie, uint ie_len)
2062 {
2063         struct security_priv *psecuritypriv = &Adapter->securitypriv;
2064
2065         if (ie[13] <= 20) {
2066                 /*  The RSN IE didn't include the PMK ID, append the PMK information */
2067                         ie[ie_len] = 1;
2068                         ie_len++;
2069                         ie[ie_len] = 0; /* PMKID count = 0x0100 */
2070                         ie_len++;
2071                         memcpy(&ie[ie_len], &psecuritypriv->PMKIDList[iEntry].PMKID, 16);
2072
2073                         ie_len += 16;
2074                         ie[13] += 18;/* PMKID length = 2+16 */
2075
2076         }
2077         return ie_len;
2078 }
2079
2080 signed int rtw_restruct_sec_ie(struct adapter *adapter, u8 *in_ie, u8 *out_ie, uint in_len)
2081 {
2082         u8 authmode = 0x0;
2083         uint    ielength;
2084         int iEntry;
2085
2086         struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
2087         struct security_priv *psecuritypriv = &adapter->securitypriv;
2088         uint    ndisauthmode = psecuritypriv->ndisauthtype;
2089
2090         /* copy fixed ie only */
2091         memcpy(out_ie, in_ie, 12);
2092         ielength = 12;
2093         if ((ndisauthmode == Ndis802_11AuthModeWPA) || (ndisauthmode == Ndis802_11AuthModeWPAPSK))
2094                         authmode = WLAN_EID_VENDOR_SPECIFIC;
2095         if ((ndisauthmode == Ndis802_11AuthModeWPA2) || (ndisauthmode == Ndis802_11AuthModeWPA2PSK))
2096                         authmode = WLAN_EID_RSN;
2097
2098         if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) {
2099                 memcpy(out_ie+ielength, psecuritypriv->wps_ie, psecuritypriv->wps_ie_len);
2100
2101                 ielength += psecuritypriv->wps_ie_len;
2102         } else if ((authmode == WLAN_EID_VENDOR_SPECIFIC) || (authmode == WLAN_EID_RSN)) {
2103                 /* copy RSN or SSN */
2104                 memcpy(&out_ie[ielength], &psecuritypriv->supplicant_ie[0], psecuritypriv->supplicant_ie[1]+2);
2105                 /* debug for CONFIG_IEEE80211W
2106                 {
2107                         int jj;
2108                         printk("supplicant_ie_length =%d &&&&&&&&&&&&&&&&&&&\n", psecuritypriv->supplicant_ie[1]+2);
2109                         for (jj = 0; jj < psecuritypriv->supplicant_ie[1]+2; jj++)
2110                                 printk(" %02x ", psecuritypriv->supplicant_ie[jj]);
2111                         printk("\n");
2112                 }*/
2113                 ielength += psecuritypriv->supplicant_ie[1]+2;
2114                 rtw_report_sec_ie(adapter, authmode, psecuritypriv->supplicant_ie);
2115         }
2116
2117         iEntry = SecIsInPMKIDList(adapter, pmlmepriv->assoc_bssid);
2118         if (iEntry < 0) {
2119                 return ielength;
2120         } else {
2121                 if (authmode == WLAN_EID_RSN)
2122                         ielength = rtw_append_pmkid(adapter, iEntry, out_ie, ielength);
2123         }
2124         return ielength;
2125 }
2126
2127 void rtw_init_registrypriv_dev_network(struct adapter *adapter)
2128 {
2129         struct registry_priv *pregistrypriv = &adapter->registrypriv;
2130         struct eeprom_priv *peepriv = &adapter->eeprompriv;
2131         struct wlan_bssid_ex    *pdev_network = &pregistrypriv->dev_network;
2132         u8 *myhwaddr = myid(peepriv);
2133
2134         memcpy(pdev_network->mac_address, myhwaddr, ETH_ALEN);
2135
2136         memcpy(&pdev_network->ssid, &pregistrypriv->ssid, sizeof(struct ndis_802_11_ssid));
2137
2138         pdev_network->configuration.length = sizeof(struct ndis_802_11_conf);
2139         pdev_network->configuration.beacon_period = 100;
2140 }
2141
2142 void rtw_update_registrypriv_dev_network(struct adapter *adapter)
2143 {
2144         int sz = 0;
2145         struct registry_priv *pregistrypriv = &adapter->registrypriv;
2146         struct wlan_bssid_ex    *pdev_network = &pregistrypriv->dev_network;
2147         struct  security_priv *psecuritypriv = &adapter->securitypriv;
2148         struct  wlan_network    *cur_network = &adapter->mlmepriv.cur_network;
2149         /* struct       xmit_priv *pxmitpriv = &adapter->xmitpriv; */
2150
2151         pdev_network->privacy = (psecuritypriv->dot11PrivacyAlgrthm > 0 ? 1 : 0) ; /*  adhoc no 802.1x */
2152
2153         pdev_network->rssi = 0;
2154
2155         switch (pregistrypriv->wireless_mode) {
2156         case WIRELESS_11B:
2157                 pdev_network->network_type_in_use = (Ndis802_11DS);
2158                 break;
2159         case WIRELESS_11G:
2160         case WIRELESS_11BG:
2161         case WIRELESS_11_24N:
2162         case WIRELESS_11G_24N:
2163         case WIRELESS_11BG_24N:
2164                 pdev_network->network_type_in_use = (Ndis802_11OFDM24);
2165                 break;
2166         default:
2167                 /*  TODO */
2168                 break;
2169         }
2170
2171         pdev_network->configuration.ds_config = (pregistrypriv->channel);
2172
2173         if (cur_network->network.infrastructure_mode == Ndis802_11IBSS)
2174                 pdev_network->configuration.atim_window = (0);
2175
2176         pdev_network->infrastructure_mode = (cur_network->network.infrastructure_mode);
2177
2178         /*  1. Supported rates */
2179         /*  2. IE */
2180
2181         /* rtw_set_supported_rate(pdev_network->supported_rates, pregistrypriv->wireless_mode) ;  will be called in rtw_generate_ie */
2182         sz = rtw_generate_ie(pregistrypriv);
2183
2184         pdev_network->ie_length = sz;
2185
2186         pdev_network->length = get_wlan_bssid_ex_sz((struct wlan_bssid_ex  *)pdev_network);
2187
2188         /* notes: translate ie_length & length after assign the length to cmdsz in createbss_cmd(); */
2189         /* pdev_network->ie_length = cpu_to_le32(sz); */
2190 }
2191
2192 void rtw_get_encrypt_decrypt_from_registrypriv(struct adapter *adapter)
2193 {
2194 }
2195
2196 /* the function is at passive_level */
2197 void rtw_joinbss_reset(struct adapter *padapter)
2198 {
2199         u8 threshold;
2200         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2201
2202         struct ht_priv  *phtpriv = &pmlmepriv->htpriv;
2203
2204         /* todo: if you want to do something io/reg/hw setting before join_bss, please add code here */
2205
2206         pmlmepriv->num_FortyMHzIntolerant = 0;
2207
2208         pmlmepriv->num_sta_no_ht = 0;
2209
2210         phtpriv->ampdu_enable = false;/* reset to disabled */
2211
2212         /*  TH = 1 => means that invalidate usb rx aggregation */
2213         /*  TH = 0 => means that validate usb rx aggregation, use init value. */
2214         if (phtpriv->ht_option) {
2215                 if (padapter->registrypriv.wifi_spec == 1)
2216                         threshold = 1;
2217                 else
2218                         threshold = 0;
2219                 rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold));
2220         } else {
2221                 threshold = 1;
2222                 rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold));
2223         }
2224 }
2225
2226 void rtw_ht_use_default_setting(struct adapter *padapter)
2227 {
2228         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
2229         struct ht_priv  *phtpriv = &pmlmepriv->htpriv;
2230         struct registry_priv *pregistrypriv = &padapter->registrypriv;
2231         bool            bHwLDPCSupport = false, bHwSTBCSupport = false;
2232         bool            bHwSupportBeamformer = false, bHwSupportBeamformee = false;
2233
2234         if (pregistrypriv->wifi_spec)
2235                 phtpriv->bss_coexist = 1;
2236         else
2237                 phtpriv->bss_coexist = 0;
2238
2239         phtpriv->sgi_40m = TEST_FLAG(pregistrypriv->short_gi, BIT1) ? true : false;
2240         phtpriv->sgi_20m = TEST_FLAG(pregistrypriv->short_gi, BIT0) ? true : false;
2241
2242         /*  LDPC support */
2243         rtw_hal_get_def_var(padapter, HAL_DEF_RX_LDPC, (u8 *)&bHwLDPCSupport);
2244         CLEAR_FLAGS(phtpriv->ldpc_cap);
2245         if (bHwLDPCSupport) {
2246                 if (TEST_FLAG(pregistrypriv->ldpc_cap, BIT4))
2247                         SET_FLAG(phtpriv->ldpc_cap, LDPC_HT_ENABLE_RX);
2248         }
2249         rtw_hal_get_def_var(padapter, HAL_DEF_TX_LDPC, (u8 *)&bHwLDPCSupport);
2250         if (bHwLDPCSupport) {
2251                 if (TEST_FLAG(pregistrypriv->ldpc_cap, BIT5))
2252                         SET_FLAG(phtpriv->ldpc_cap, LDPC_HT_ENABLE_TX);
2253         }
2254
2255         /*  STBC */
2256         rtw_hal_get_def_var(padapter, HAL_DEF_TX_STBC, (u8 *)&bHwSTBCSupport);
2257         CLEAR_FLAGS(phtpriv->stbc_cap);
2258         if (bHwSTBCSupport) {
2259                 if (TEST_FLAG(pregistrypriv->stbc_cap, BIT5))
2260                         SET_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_TX);
2261         }
2262         rtw_hal_get_def_var(padapter, HAL_DEF_RX_STBC, (u8 *)&bHwSTBCSupport);
2263         if (bHwSTBCSupport) {
2264                 if (TEST_FLAG(pregistrypriv->stbc_cap, BIT4))
2265                         SET_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_RX);
2266         }
2267
2268         /*  Beamforming setting */
2269         rtw_hal_get_def_var(padapter, HAL_DEF_EXPLICIT_BEAMFORMER, (u8 *)&bHwSupportBeamformer);
2270         rtw_hal_get_def_var(padapter, HAL_DEF_EXPLICIT_BEAMFORMEE, (u8 *)&bHwSupportBeamformee);
2271         CLEAR_FLAGS(phtpriv->beamform_cap);
2272         if (TEST_FLAG(pregistrypriv->beamform_cap, BIT4) && bHwSupportBeamformer)
2273                 SET_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE);
2274
2275         if (TEST_FLAG(pregistrypriv->beamform_cap, BIT5) && bHwSupportBeamformee)
2276                 SET_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE);
2277 }
2278
2279 void rtw_build_wmm_ie_ht(struct adapter *padapter, u8 *out_ie, uint *pout_len)
2280 {
2281         unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
2282         int out_len;
2283
2284         if (padapter->mlmepriv.qospriv.qos_option == 0) {
2285                 out_len = *pout_len;
2286                 rtw_set_ie(out_ie+out_len, WLAN_EID_VENDOR_SPECIFIC,
2287                            _WMM_IE_Length_, WMM_IE, pout_len);
2288
2289                 padapter->mlmepriv.qospriv.qos_option = 1;
2290         }
2291 }
2292
2293 /* the function is >= passive_level */
2294 unsigned int rtw_restructure_ht_ie(struct adapter *padapter, u8 *in_ie, u8 *out_ie, uint in_len, uint *pout_len, u8 channel)
2295 {
2296         u32 ielen, out_len;
2297         enum ieee80211_max_ampdu_length_exp max_rx_ampdu_factor;
2298         unsigned char *p;
2299         struct ieee80211_ht_cap ht_capie;
2300         u8 cbw40_enable = 0, stbc_rx_enable = 0, operation_bw = 0;
2301         struct registry_priv *pregistrypriv = &padapter->registrypriv;
2302         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2303         struct ht_priv  *phtpriv = &pmlmepriv->htpriv;
2304         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2305
2306         phtpriv->ht_option = false;
2307
2308         out_len = *pout_len;
2309
2310         memset(&ht_capie, 0, sizeof(struct ieee80211_ht_cap));
2311
2312         ht_capie.cap_info = cpu_to_le16(IEEE80211_HT_CAP_DSSSCCK40);
2313
2314         if (phtpriv->sgi_20m)
2315                 ht_capie.cap_info |= cpu_to_le16(IEEE80211_HT_CAP_SGI_20);
2316
2317         /* Get HT BW */
2318         if (!in_ie) {
2319                 /* TDLS: TODO 20/40 issue */
2320                 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
2321                         operation_bw = padapter->mlmeextpriv.cur_bwmode;
2322                         if (operation_bw > CHANNEL_WIDTH_40)
2323                                 operation_bw = CHANNEL_WIDTH_40;
2324                 } else
2325                         /* TDLS: TODO 40? */
2326                         operation_bw = CHANNEL_WIDTH_40;
2327         } else {
2328                 p = rtw_get_ie(in_ie, WLAN_EID_HT_OPERATION, &ielen, in_len);
2329                 if (p && (ielen == sizeof(struct ieee80211_ht_addt_info))) {
2330                         struct HT_info_element *pht_info = (struct HT_info_element *)(p+2);
2331
2332                         if (pht_info->infos[0] & BIT(2)) {
2333                                 switch (pht_info->infos[0] & 0x3) {
2334                                 case 1:
2335                                 case 3:
2336                                         operation_bw = CHANNEL_WIDTH_40;
2337                                         break;
2338                                 default:
2339                                         operation_bw = CHANNEL_WIDTH_20;
2340                                         break;
2341                                 }
2342                         } else {
2343                                 operation_bw = CHANNEL_WIDTH_20;
2344                         }
2345                 }
2346         }
2347
2348         /* to disable 40M Hz support while gd_bw_40MHz_en = 0 */
2349         if (channel > 14) {
2350                 if ((pregistrypriv->bw_mode & 0xf0) > 0)
2351                         cbw40_enable = 1;
2352         } else {
2353                 if ((pregistrypriv->bw_mode & 0x0f) > 0)
2354                         cbw40_enable = 1;
2355         }
2356
2357         if ((cbw40_enable == 1) && (operation_bw == CHANNEL_WIDTH_40)) {
2358                 ht_capie.cap_info |= cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH);
2359                 if (phtpriv->sgi_40m)
2360                         ht_capie.cap_info |= cpu_to_le16(IEEE80211_HT_CAP_SGI_40);
2361         }
2362
2363         if (TEST_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_TX))
2364                 ht_capie.cap_info |= cpu_to_le16(IEEE80211_HT_CAP_TX_STBC);
2365
2366         /* todo: disable SM power save mode */
2367         ht_capie.cap_info |= cpu_to_le16(IEEE80211_HT_CAP_SM_PS);
2368
2369         if (TEST_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_RX)) {
2370                 if ((channel <= 14 && pregistrypriv->rx_stbc == 0x1) || /* enable for 2.4GHz */
2371                         (pregistrypriv->wifi_spec == 1))
2372                         stbc_rx_enable = 1;
2373         }
2374
2375         /* fill default supported_mcs_set */
2376         memcpy(&ht_capie.mcs, pmlmeext->default_supported_mcs_set, 16);
2377
2378         /* update default supported_mcs_set */
2379         if (stbc_rx_enable)
2380                 ht_capie.cap_info |= cpu_to_le16(IEEE80211_HT_CAP_RX_STBC_1R);/* RX STBC One spatial stream */
2381
2382         set_mcs_rate_by_mask(ht_capie.mcs.rx_mask, MCS_RATE_1R);
2383
2384         {
2385                 u32 rx_packet_offset, max_recvbuf_sz;
2386
2387                 rtw_hal_get_def_var(padapter, HAL_DEF_RX_PACKET_OFFSET, &rx_packet_offset);
2388                 rtw_hal_get_def_var(padapter, HAL_DEF_MAX_RECVBUF_SZ, &max_recvbuf_sz);
2389         }
2390
2391         if (padapter->driver_rx_ampdu_factor != 0xFF)
2392                 max_rx_ampdu_factor =
2393                   (enum ieee80211_max_ampdu_length_exp)padapter->driver_rx_ampdu_factor;
2394         else
2395                 rtw_hal_get_def_var(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR,
2396                                     &max_rx_ampdu_factor);
2397
2398         /* rtw_hal_get_def_var(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor); */
2399         ht_capie.ampdu_params_info = (max_rx_ampdu_factor&0x03);
2400
2401         if (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)
2402                 ht_capie.ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&(0x07<<2));
2403         else
2404                 ht_capie.ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&0x00);
2405
2406         rtw_set_ie(out_ie+out_len, WLAN_EID_HT_CAPABILITY,
2407                    sizeof(struct ieee80211_ht_cap), (unsigned char *)&ht_capie, pout_len);
2408
2409         phtpriv->ht_option = true;
2410
2411         if (in_ie) {
2412                 p = rtw_get_ie(in_ie, WLAN_EID_HT_OPERATION, &ielen, in_len);
2413                 if (p && (ielen == sizeof(struct ieee80211_ht_addt_info))) {
2414                         out_len = *pout_len;
2415                         rtw_set_ie(out_ie+out_len, WLAN_EID_HT_OPERATION, ielen, p+2, pout_len);
2416                 }
2417         }
2418
2419         return phtpriv->ht_option;
2420
2421 }
2422
2423 /* the function is > passive_level (in critical_section) */
2424 void rtw_update_ht_cap(struct adapter *padapter, u8 *pie, uint ie_len, u8 channel)
2425 {
2426         u8 *p, max_ampdu_sz;
2427         int len;
2428         /* struct sta_info *bmc_sta, *psta; */
2429         struct ieee80211_ht_cap *pht_capie;
2430         /* struct recv_reorder_ctrl *preorder_ctrl; */
2431         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2432         struct ht_priv  *phtpriv = &pmlmepriv->htpriv;
2433         /* struct recv_priv *precvpriv = &padapter->recvpriv; */
2434         struct registry_priv *pregistrypriv = &padapter->registrypriv;
2435         /* struct wlan_network *pcur_network = &(pmlmepriv->cur_network);; */
2436         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2437         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2438         u8 cbw40_enable = 0;
2439
2440         if (!phtpriv->ht_option)
2441                 return;
2442
2443         if ((!pmlmeinfo->HT_info_enable) || (!pmlmeinfo->HT_caps_enable))
2444                 return;
2445
2446         /* maybe needs check if ap supports rx ampdu. */
2447         if (!(phtpriv->ampdu_enable) && pregistrypriv->ampdu_enable == 1) {
2448                 phtpriv->ampdu_enable = true;
2449         }
2450
2451         /* check Max Rx A-MPDU Size */
2452         len = 0;
2453         p = rtw_get_ie(pie+sizeof(struct ndis_802_11_fix_ie), WLAN_EID_HT_CAPABILITY, &len, ie_len-sizeof(struct ndis_802_11_fix_ie));
2454         if (p && len > 0) {
2455                 pht_capie = (struct ieee80211_ht_cap *)(p+2);
2456                 max_ampdu_sz = (pht_capie->ampdu_params_info & IEEE80211_HT_CAP_AMPDU_FACTOR);
2457                 max_ampdu_sz = 1 << (max_ampdu_sz+3); /*  max_ampdu_sz (kbytes); */
2458
2459                 phtpriv->rx_ampdu_maxlen = max_ampdu_sz;
2460
2461         }
2462
2463         len = 0;
2464         p = rtw_get_ie(pie+sizeof(struct ndis_802_11_fix_ie), WLAN_EID_HT_OPERATION, &len, ie_len-sizeof(struct ndis_802_11_fix_ie));
2465         if (p && len > 0) {
2466                 /* todo: */
2467         }
2468
2469         if (channel > 14) {
2470                 if ((pregistrypriv->bw_mode & 0xf0) > 0)
2471                         cbw40_enable = 1;
2472         } else {
2473                 if ((pregistrypriv->bw_mode & 0x0f) > 0)
2474                         cbw40_enable = 1;
2475         }
2476
2477         /* update cur_bwmode & cur_ch_offset */
2478         if ((cbw40_enable) &&
2479             (le16_to_cpu(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info) &
2480               BIT(1)) && (pmlmeinfo->HT_info.infos[0] & BIT(2))) {
2481                 int i;
2482
2483                 /* update the MCS set */
2484                 for (i = 0; i < 16; i++)
2485                         pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= pmlmeext->default_supported_mcs_set[i];
2486
2487                 /* update the MCS rates */
2488                 set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_1R);
2489
2490                 /* switch to the 40M Hz mode according to the AP */
2491                 /* pmlmeext->cur_bwmode = CHANNEL_WIDTH_40; */
2492                 switch ((pmlmeinfo->HT_info.infos[0] & 0x3)) {
2493                 case EXTCHNL_OFFSET_UPPER:
2494                         pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
2495                         break;
2496
2497                 case EXTCHNL_OFFSET_LOWER:
2498                         pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
2499                         break;
2500
2501                 default:
2502                         pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
2503                         break;
2504                 }
2505         }
2506
2507         /*  */
2508         /*  Config SM Power Save setting */
2509         /*  */
2510         pmlmeinfo->SM_PS =
2511                 (le16_to_cpu(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info) &
2512                  0x0C) >> 2;
2513
2514         /*  */
2515         /*  Config current HT Protection mode. */
2516         /*  */
2517         pmlmeinfo->HT_protection = pmlmeinfo->HT_info.infos[1] & 0x3;
2518 }
2519
2520 void rtw_issue_addbareq_cmd(struct adapter *padapter, struct xmit_frame *pxmitframe)
2521 {
2522         u8 issued;
2523         int priority;
2524         struct sta_info *psta = NULL;
2525         struct ht_priv *phtpriv;
2526         struct pkt_attrib *pattrib = &pxmitframe->attrib;
2527         s32 bmcst = IS_MCAST(pattrib->ra);
2528
2529         /* if (bmcst || (padapter->mlmepriv.LinkDetectInfo.bTxBusyTraffic == false)) */
2530         if (bmcst || (padapter->mlmepriv.LinkDetectInfo.NumTxOkInPeriod < 100))
2531                 return;
2532
2533         priority = pattrib->priority;
2534
2535         psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
2536         if (pattrib->psta != psta)
2537                 return;
2538
2539         if (!psta)
2540                 return;
2541
2542         if (!(psta->state & _FW_LINKED))
2543                 return;
2544
2545         phtpriv = &psta->htpriv;
2546
2547         if (phtpriv->ht_option && phtpriv->ampdu_enable) {
2548                 issued = (phtpriv->agg_enable_bitmap>>priority)&0x1;
2549                 issued |= (phtpriv->candidate_tid_bitmap>>priority)&0x1;
2550
2551                 if (issued == 0) {
2552                         psta->htpriv.candidate_tid_bitmap |= BIT((u8)priority);
2553                         rtw_addbareq_cmd(padapter, (u8) priority, pattrib->ra);
2554                 }
2555         }
2556
2557 }
2558
2559 void rtw_append_exented_cap(struct adapter *padapter, u8 *out_ie, uint *pout_len)
2560 {
2561         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2562         struct ht_priv  *phtpriv = &pmlmepriv->htpriv;
2563         u8 cap_content[8] = {0};
2564
2565         if (phtpriv->bss_coexist)
2566                 SET_EXT_CAPABILITY_ELE_BSS_COEXIST(cap_content, 1);
2567
2568         rtw_set_ie(out_ie + *pout_len, WLAN_EID_EXT_CAPABILITY, 8, cap_content, pout_len);
2569 }
2570
2571 inline void rtw_set_to_roam(struct adapter *adapter, u8 to_roam)
2572 {
2573         if (to_roam == 0)
2574                 adapter->mlmepriv.to_join = false;
2575         adapter->mlmepriv.to_roam = to_roam;
2576 }
2577
2578 inline u8 rtw_dec_to_roam(struct adapter *adapter)
2579 {
2580         adapter->mlmepriv.to_roam--;
2581         return adapter->mlmepriv.to_roam;
2582 }
2583
2584 inline u8 rtw_to_roam(struct adapter *adapter)
2585 {
2586         return adapter->mlmepriv.to_roam;
2587 }
2588
2589 void rtw_roaming(struct adapter *padapter, struct wlan_network *tgt_network)
2590 {
2591         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2592
2593         spin_lock_bh(&pmlmepriv->lock);
2594         _rtw_roaming(padapter, tgt_network);
2595         spin_unlock_bh(&pmlmepriv->lock);
2596 }
2597 void _rtw_roaming(struct adapter *padapter, struct wlan_network *tgt_network)
2598 {
2599         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2600         struct wlan_network *cur_network = &pmlmepriv->cur_network;
2601
2602         if (rtw_to_roam(padapter) > 0) {
2603                 memcpy(&pmlmepriv->assoc_ssid, &cur_network->network.ssid, sizeof(struct ndis_802_11_ssid));
2604
2605                 pmlmepriv->assoc_by_bssid = false;
2606
2607                 while (rtw_do_join(padapter) != _SUCCESS) {
2608                         rtw_dec_to_roam(padapter);
2609                         if (rtw_to_roam(padapter) <= 0) {
2610                                 rtw_indicate_disconnect(padapter);
2611                                 break;
2612                         }
2613                 }
2614         }
2615 }
2616
2617 signed int rtw_linked_check(struct adapter *padapter)
2618 {
2619         if ((check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == true) ||
2620                         (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE) == true)) {
2621                 if (padapter->stapriv.asoc_sta_count > 2)
2622                         return true;
2623         } else {        /* Station mode */
2624                 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) == true)
2625                         return true;
2626         }
2627         return false;
2628 }