staging: rtl8723au: whitespace and blank line cleaning
[cascardo/linux.git] / drivers / staging / rtl8723au / core / rtw_mlme.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  ******************************************************************************/
15 #define _RTW_MLME_C_
16
17 #include <osdep_service.h>
18 #include <drv_types.h>
19 #include <recv_osdep.h>
20 #include <xmit_osdep.h>
21 #include <hal_intf.h>
22 #include <mlme_osdep.h>
23 #include <sta_info.h>
24 #include <linux/ieee80211.h>
25 #include <wifi.h>
26 #include <wlan_bssdef.h>
27 #include <rtw_sreset.h>
28
29 static struct wlan_network *
30 rtw_select_candidate_from_queue(struct mlme_priv *pmlmepriv);
31 static int rtw_do_join(struct rtw_adapter *padapter);
32
33 static void rtw_init_mlme_timer(struct rtw_adapter *padapter)
34 {
35         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
36
37         setup_timer(&pmlmepriv->assoc_timer, rtw23a_join_to_handler,
38                     (unsigned long)padapter);
39
40         setup_timer(&pmlmepriv->scan_to_timer, rtw_scan_timeout_handler23a,
41                     (unsigned long)padapter);
42
43         setup_timer(&pmlmepriv->dynamic_chk_timer,
44                     rtw_dynamic_check_timer_handler, (unsigned long)padapter);
45
46         setup_timer(&pmlmepriv->set_scan_deny_timer,
47                     rtw_set_scan_deny_timer_hdl, (unsigned long)padapter);
48 }
49
50 int rtw_init_mlme_priv23a(struct rtw_adapter *padapter)
51 {
52         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
53
54         pmlmepriv->nic_hdl = padapter;
55
56         pmlmepriv->fw_state = 0;
57         pmlmepriv->cur_network.network.ifmode = NL80211_IFTYPE_UNSPECIFIED;
58         /*  1: active, 0: pasive. Maybe someday we should rename this
59             varable to "active_mode" (Jeff) */
60         pmlmepriv->scan_mode = SCAN_ACTIVE;
61
62         spin_lock_init(&pmlmepriv->lock);
63         _rtw_init_queue23a(&pmlmepriv->scanned_queue);
64
65         memset(&pmlmepriv->assoc_ssid, 0, sizeof(struct cfg80211_ssid));
66
67         rtw_clear_scan_deny(padapter);
68
69         rtw_init_mlme_timer(padapter);
70         return _SUCCESS;
71 }
72
73 #ifdef CONFIG_8723AU_AP_MODE
74 static void rtw_free_mlme_ie_data(u8 **ppie, u32 *plen)
75 {
76         if (*ppie) {
77                 kfree(*ppie);
78                 *plen = 0;
79                 *ppie = NULL;
80         }
81 }
82 #endif
83
84 void rtw23a_free_mlme_priv_ie_data(struct mlme_priv *pmlmepriv)
85 {
86 #ifdef CONFIG_8723AU_AP_MODE
87         kfree(pmlmepriv->assoc_req);
88         kfree(pmlmepriv->assoc_rsp);
89         rtw_free_mlme_ie_data(&pmlmepriv->wps_probe_req_ie,
90                               &pmlmepriv->wps_probe_req_ie_len);
91 #endif
92 }
93
94 void rtw_free_mlme_priv23a(struct mlme_priv *pmlmepriv)
95 {
96         RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
97                  "rtw_free_mlme_priv23a\n");
98
99         rtw23a_free_mlme_priv_ie_data(pmlmepriv);
100 }
101
102 struct wlan_network *rtw_alloc_network(struct mlme_priv *pmlmepriv, gfp_t gfp)
103 {
104         struct wlan_network *pnetwork;
105
106         pnetwork = kzalloc(sizeof(struct wlan_network), gfp);
107         if (pnetwork) {
108                 INIT_LIST_HEAD(&pnetwork->list);
109                 pnetwork->network_type = 0;
110                 pnetwork->fixed = false;
111                 pnetwork->last_scanned = jiffies;
112                 pnetwork->join_res = 0;
113         }
114
115         return pnetwork;
116 }
117
118 static void _rtw_free_network23a(struct mlme_priv *pmlmepriv,
119                                  struct wlan_network *pnetwork)
120 {
121         if (!pnetwork)
122                 return;
123
124         if (pnetwork->fixed == true)
125                 return;
126
127         list_del_init(&pnetwork->list);
128
129         kfree(pnetwork);
130 }
131
132 /*
133  return the wlan_network with the matching addr
134
135  Shall be called under atomic context... to avoid possible racing condition...
136 */
137 struct wlan_network *
138 rtw_find_network23a(struct rtw_queue *scanned_queue, u8 *addr)
139 {
140         struct list_head *phead, *plist;
141         struct wlan_network *pnetwork = NULL;
142
143         if (is_zero_ether_addr(addr)) {
144                 pnetwork = NULL;
145                 goto exit;
146         }
147
148         /* spin_lock_bh(&scanned_queue->lock); */
149
150         phead = get_list_head(scanned_queue);
151         plist = phead->next;
152
153         while (plist != phead) {
154                 pnetwork = container_of(plist, struct wlan_network, list);
155
156                 if (ether_addr_equal(addr, pnetwork->network.MacAddress))
157                         break;
158
159                 plist = plist->next;
160         }
161
162         if (plist == phead)
163                 pnetwork = NULL;
164
165         /* spin_unlock_bh(&scanned_queue->lock); */
166
167 exit:
168
169         return pnetwork;
170 }
171
172 void rtw_free_network_queue23a(struct rtw_adapter *padapter)
173 {
174         struct list_head *phead;
175         struct wlan_network *pnetwork, *ptmp;
176         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
177         struct rtw_queue *scanned_queue = &pmlmepriv->scanned_queue;
178
179         spin_lock_bh(&scanned_queue->lock);
180         phead = get_list_head(scanned_queue);
181         list_for_each_entry_safe(pnetwork, ptmp, phead, list)
182                 _rtw_free_network23a(pmlmepriv, pnetwork);
183         spin_unlock_bh(&scanned_queue->lock);
184 }
185
186 int rtw_if_up23a(struct rtw_adapter *padapter)
187 {
188         int res;
189
190         if (padapter->bDriverStopped || padapter->bSurpriseRemoved ||
191             !check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
192                 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
193                          "rtw_if_up23a:bDriverStopped(%d) OR bSurpriseRemoved(%d)\n",
194                          padapter->bDriverStopped, padapter->bSurpriseRemoved);
195                 res = false;
196         } else
197                 res =  true;
198
199         return res;
200 }
201
202 void rtw_generate_random_ibss23a(u8 *pibss)
203 {
204         unsigned long curtime = jiffies;
205
206         pibss[0] = 0x02;  /* in ad-hoc mode bit1 must set to 1 */
207         pibss[1] = 0x11;
208         pibss[2] = 0x87;
209         pibss[3] = curtime & 0xff;/* p[0]; */
210         pibss[4] = (curtime >> 8) & 0xff;/* p[1]; */
211         pibss[5] = (curtime >> 16) & 0xff;/* p[2]; */
212 }
213
214 void rtw_set_roaming(struct rtw_adapter *adapter, u8 to_roaming)
215 {
216         if (to_roaming == 0)
217                 adapter->mlmepriv.to_join = false;
218         adapter->mlmepriv.to_roaming = to_roaming;
219 }
220
221 static void _rtw_roaming(struct rtw_adapter *padapter,
222                          struct wlan_network *tgt_network)
223 {
224         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
225         struct wlan_network *pnetwork;
226         int do_join_r;
227
228         if (tgt_network)
229                 pnetwork = tgt_network;
230         else
231                 pnetwork = &pmlmepriv->cur_network;
232
233         if (padapter->mlmepriv.to_roaming > 0) {
234                 DBG_8723A("roaming from %s(%pM), length:%d\n",
235                           pnetwork->network.Ssid.ssid,
236                           pnetwork->network.MacAddress,
237                           pnetwork->network.Ssid.ssid_len);
238                 memcpy(&pmlmepriv->assoc_ssid, &pnetwork->network.Ssid,
239                        sizeof(struct cfg80211_ssid));
240
241                 pmlmepriv->assoc_by_bssid = false;
242
243                 while (1) {
244                         do_join_r = rtw_do_join(padapter);
245                         if (do_join_r == _SUCCESS)
246                                 break;
247                         else {
248                                 DBG_8723A("roaming do_join return %d\n",
249                                           do_join_r);
250                                 pmlmepriv->to_roaming--;
251
252                                 if (padapter->mlmepriv.to_roaming > 0)
253                                         continue;
254                                 else {
255                                         DBG_8723A("%s(%d) -to roaming fail, "
256                                                   "indicate_disconnect\n",
257                                                   __func__, __LINE__);
258                                         rtw_indicate_disconnect23a(padapter);
259                                         break;
260                                 }
261                         }
262                 }
263         }
264 }
265
266 void rtw23a_roaming(struct rtw_adapter *padapter,
267                     struct wlan_network *tgt_network)
268 {
269         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
270
271         spin_lock_bh(&pmlmepriv->lock);
272         _rtw_roaming(padapter, tgt_network);
273         spin_unlock_bh(&pmlmepriv->lock);
274 }
275
276 static void rtw_free_network_nolock(struct mlme_priv *pmlmepriv,
277                                     struct wlan_network *pnetwork)
278 {
279         _rtw_free_network23a(pmlmepriv, pnetwork);
280 }
281
282 bool rtw_is_same_ibss23a(struct rtw_adapter *adapter,
283                          struct wlan_network *pnetwork)
284 {
285         int ret;
286         struct security_priv *psecuritypriv = &adapter->securitypriv;
287
288         if (psecuritypriv->dot11PrivacyAlgrthm != 0 &&
289             pnetwork->network.Privacy == 0)
290                 ret = false;
291         else if (psecuritypriv->dot11PrivacyAlgrthm == 0 &&
292                  pnetwork->network.Privacy == 1)
293                 ret = false;
294         else
295                 ret = true;
296
297         return ret;
298 }
299
300 inline int is_same_ess(struct wlan_bssid_ex *a, struct wlan_bssid_ex *b);
301 inline int is_same_ess(struct wlan_bssid_ex *a, struct wlan_bssid_ex *b)
302 {
303         return (a->Ssid.ssid_len == b->Ssid.ssid_len) &&
304                 !memcmp(a->Ssid.ssid, b->Ssid.ssid, a->Ssid.ssid_len);
305 }
306
307 int is_same_network23a(struct wlan_bssid_ex *src, struct wlan_bssid_ex *dst)
308 {
309         u16 s_cap, d_cap;
310
311         s_cap = src->capability;
312         d_cap = dst->capability;
313
314         return ((src->Ssid.ssid_len == dst->Ssid.ssid_len) &&
315                 /*      (src->DSConfig == dst->DSConfig) && */
316                 ether_addr_equal(src->MacAddress, dst->MacAddress) &&
317                 !memcmp(src->Ssid.ssid, dst->Ssid.ssid, src->Ssid.ssid_len) &&
318                 (s_cap & WLAN_CAPABILITY_IBSS) ==
319                 (d_cap & WLAN_CAPABILITY_IBSS) &&
320                 (s_cap & WLAN_CAPABILITY_ESS) == (d_cap & WLAN_CAPABILITY_ESS));
321 }
322
323 struct wlan_network *
324 rtw_get_oldest_wlan_network23a(struct rtw_queue *scanned_queue)
325 {
326         struct list_head *phead;
327         struct wlan_network *pwlan;
328         struct wlan_network *oldest = NULL;
329
330         phead = get_list_head(scanned_queue);
331         list_for_each_entry(pwlan, phead, list) {
332                 if (pwlan->fixed != true) {
333                         if (!oldest || time_after(oldest->last_scanned,
334                                                   pwlan->last_scanned))
335                                 oldest = pwlan;
336                 }
337         }
338
339         return oldest;
340 }
341
342 void update_network23a(struct wlan_bssid_ex *dst, struct wlan_bssid_ex *src,
343                        struct rtw_adapter *padapter, bool update_ie)
344 {
345         u8 ss_ori = dst->SignalStrength;
346         u8 sq_ori = dst->SignalQuality;
347         long rssi_ori = dst->Rssi;
348
349         u8 ss_smp = src->SignalStrength;
350         u8 sq_smp = src->SignalQuality;
351         long rssi_smp = src->Rssi;
352
353         u8 ss_final;
354         u8 sq_final;
355         long rssi_final;
356
357         DBG_8723A("%s %s(%pM, ch%u) ss_ori:%3u, sq_ori:%3u, rssi_ori:%3ld, "
358                   "ss_smp:%3u, sq_smp:%3u, rssi_smp:%3ld\n",
359                   __func__, src->Ssid.ssid, src->MacAddress,
360                   src->DSConfig, ss_ori, sq_ori, rssi_ori,
361                   ss_smp, sq_smp, rssi_smp
362         );
363
364         /* The rule below is 1/5 for sample value, 4/5 for history value */
365         if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) &&
366             is_same_network23a(&padapter->mlmepriv.cur_network.network, src)) {
367                 /* Take the recvpriv's value for the connected AP*/
368                 ss_final = padapter->recvpriv.signal_strength;
369                 sq_final = padapter->recvpriv.signal_qual;
370                 /* the rssi value here is undecorated, and will be
371                    used for antenna diversity */
372                 if (sq_smp != 101) /* from the right channel */
373                         rssi_final = (src->Rssi+dst->Rssi*4)/5;
374                 else
375                         rssi_final = rssi_ori;
376         } else {
377                 if (sq_smp != 101) { /* from the right channel */
378                         ss_final = ((u32)src->SignalStrength +
379                                     (u32)dst->SignalStrength * 4) / 5;
380                         sq_final = ((u32)src->SignalQuality +
381                                     (u32)dst->SignalQuality * 4) / 5;
382                         rssi_final = src->Rssi+dst->Rssi * 4 / 5;
383                 } else {
384                         /* bss info not receiving from the right channel, use
385                            the original RX signal infos */
386                         ss_final = dst->SignalStrength;
387                         sq_final = dst->SignalQuality;
388                         rssi_final = dst->Rssi;
389                 }
390
391         }
392
393         if (update_ie)
394                 memcpy(dst, src, get_wlan_bssid_ex_sz(src));
395
396         dst->SignalStrength = ss_final;
397         dst->SignalQuality = sq_final;
398         dst->Rssi = rssi_final;
399
400         DBG_8723A("%s %s(%pM), SignalStrength:%u, SignalQuality:%u, "
401                   "RawRSSI:%ld\n",  __func__, dst->Ssid.ssid, dst->MacAddress,
402                   dst->SignalStrength, dst->SignalQuality, dst->Rssi);
403 }
404
405 static void update_current_network(struct rtw_adapter *adapter,
406                                    struct wlan_bssid_ex *pnetwork)
407 {
408         struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
409
410         if (check_fwstate(pmlmepriv, _FW_LINKED) &&
411             is_same_network23a(&pmlmepriv->cur_network.network, pnetwork)) {
412                 update_network23a(&pmlmepriv->cur_network.network,
413                                   pnetwork, adapter, true);
414
415                 rtw_update_protection23a(adapter,
416                                          pmlmepriv->cur_network.network.IEs,
417                                          pmlmepriv->cur_network.network.IELength);
418         }
419 }
420
421 /*
422
423 Caller must hold pmlmepriv->lock first.
424
425 */
426 static void rtw_update_scanned_network(struct rtw_adapter *adapter,
427                                        struct wlan_bssid_ex *target)
428 {
429         struct list_head *plist, *phead;
430         struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
431         struct wlan_network *pnetwork = NULL;
432         struct wlan_network *oldest = NULL;
433         struct rtw_queue *queue = &pmlmepriv->scanned_queue;
434         u32 bssid_ex_sz;
435         int found = 0;
436
437         spin_lock_bh(&queue->lock);
438         phead = get_list_head(queue);
439         list_for_each(plist, phead) {
440                 pnetwork = container_of(plist, struct wlan_network, list);
441
442                 if (is_same_network23a(&pnetwork->network, target)) {
443                         found = 1;
444                         break;
445                 }
446                 if (!oldest || time_after(oldest->last_scanned,
447                                           pnetwork->last_scanned))
448                         oldest = pnetwork;
449         }
450
451         /* If we didn't find a match, then get a new network slot to initialize
452          * with this beacon's information */
453         if (!found) {
454                 pnetwork = rtw_alloc_network(pmlmepriv, GFP_ATOMIC);
455                 if (!pnetwork) {
456                         if (!oldest) {
457                                 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
458                                          "something wrong here\n");
459                                 goto exit;
460                         }
461                         pnetwork = oldest;
462                 } else
463                         list_add_tail(&pnetwork->list, &queue->queue);
464
465                 bssid_ex_sz = get_wlan_bssid_ex_sz(target);
466                 target->Length = bssid_ex_sz;
467                 memcpy(&pnetwork->network, target, bssid_ex_sz);
468
469                 /*  variable initialize */
470                 pnetwork->fixed = false;
471                 pnetwork->last_scanned = jiffies;
472
473                 pnetwork->network_type = 0;
474                 pnetwork->join_res = 0;
475
476                 /* bss info not receiving from the right channel */
477                 if (pnetwork->network.SignalQuality == 101)
478                         pnetwork->network.SignalQuality = 0;
479         } else {
480                 /*
481                  * we have an entry and we are going to update it. But
482                  * this entry may be already expired. In this case we
483                  * do the same as we found a new net and call the
484                  * new_net handler
485                  */
486                 bool update_ie = true;
487
488                 pnetwork->last_scanned = jiffies;
489
490                 /* target.reserved == 1, means that scanned network is
491                  * a bcn frame. */
492                 if (pnetwork->network.IELength > target->IELength &&
493                     target->reserved == 1)
494                         update_ie = false;
495
496                 update_network23a(&pnetwork->network, target, adapter,
497                                   update_ie);
498         }
499
500 exit:
501         spin_unlock_bh(&queue->lock);
502 }
503
504 static void rtw_add_network(struct rtw_adapter *adapter,
505                             struct wlan_bssid_ex *pnetwork)
506 {
507         update_current_network(adapter, pnetwork);
508         rtw_update_scanned_network(adapter, pnetwork);
509 }
510
511 /* select the desired network based on the capability of the (i)bss. */
512 /*  check items: (1) security */
513 /*                         (2) network_type */
514 /*                         (3) WMM */
515 /*                         (4) HT */
516 /*                      (5) others */
517 static int rtw_is_desired_network(struct rtw_adapter *adapter,
518                                   struct wlan_network *pnetwork)
519 {
520         struct security_priv *psecuritypriv = &adapter->securitypriv;
521         struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
522         u32 desired_encmode;
523         u32 privacy;
524         int bselected = true;
525
526         desired_encmode = psecuritypriv->ndisencryptstatus;
527         privacy = pnetwork->network.Privacy;
528
529         if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) {
530                 if (cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
531                                             WLAN_OUI_TYPE_MICROSOFT_WPA,
532                                             pnetwork->network.IEs,
533                                             pnetwork->network.IELength))
534                         return true;
535                 else
536                         return false;
537         }
538         if (adapter->registrypriv.wifi_spec == 1) {
539                 /* for  correct flow of 8021X  to do.... */
540                 if (desired_encmode == Ndis802_11EncryptionDisabled &&
541                     privacy != 0)
542                         bselected = false;
543         }
544
545         if (desired_encmode != Ndis802_11EncryptionDisabled && privacy == 0) {
546                 DBG_8723A("desired_encmode: %d, privacy: %d\n",
547                           desired_encmode, privacy);
548                 bselected = false;
549         }
550
551         if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
552                 if (pnetwork->network.ifmode !=
553                     pmlmepriv->cur_network.network.ifmode)
554                         bselected = false;
555         }
556
557         return bselected;
558 }
559
560 void rtw_survey_event_cb23a(struct rtw_adapter *adapter, const u8 *pbuf)
561 {
562         u32 len;
563         struct wlan_bssid_ex *pnetwork;
564         struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
565         struct survey_event *survey = (struct survey_event *)pbuf;
566
567         pnetwork = survey->bss;
568
569         RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
570                  "rtw_survey_event_cb23a, ssid=%s\n", pnetwork->Ssid.ssid);
571
572         len = get_wlan_bssid_ex_sz(pnetwork);
573         if (len > (sizeof(struct wlan_bssid_ex))) {
574                 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
575                          "****rtw_survey_event_cb23a: return a wrong bss ***\n");
576                 return;
577         }
578
579         spin_lock_bh(&pmlmepriv->lock);
580
581         /*  update IBSS_network 's timestamp */
582         if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
583                 if (ether_addr_equal(pmlmepriv->cur_network.network.MacAddress,
584                                      pnetwork->MacAddress)) {
585                         struct wlan_network *ibss_wlan;
586
587                         pmlmepriv->cur_network.network.beacon_interval =
588                                 pnetwork->beacon_interval;
589                         pmlmepriv->cur_network.network.capability =
590                                 pnetwork->capability;
591                         pmlmepriv->cur_network.network.tsf = pnetwork->tsf;
592                         spin_lock_bh(&pmlmepriv->scanned_queue.lock);
593                         ibss_wlan = rtw_find_network23a(
594                                 &pmlmepriv->scanned_queue,
595                                 pnetwork->MacAddress);
596                         if (ibss_wlan) {
597                                 pmlmepriv->cur_network.network.beacon_interval =
598                                         ibss_wlan->network.beacon_interval;
599                                 pmlmepriv->cur_network.network.capability =
600                                         ibss_wlan->network.capability;
601                                 pmlmepriv->cur_network.network.tsf =
602                                         ibss_wlan->network.tsf;
603                                 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
604                                 goto exit;
605                         }
606                         spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
607                 }
608         }
609
610         /*  lock pmlmepriv->lock when you accessing network_q */
611         if (!check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) {
612                 if (pnetwork->Ssid.ssid[0] == 0)
613                         pnetwork->Ssid.ssid_len = 0;
614
615                 rtw_add_network(adapter, pnetwork);
616         }
617
618 exit:
619
620         spin_unlock_bh(&pmlmepriv->lock);
621
622         kfree(survey->bss);
623         survey->bss = NULL;
624 }
625
626 void
627 rtw_surveydone_event_callback23a(struct rtw_adapter *adapter, const u8 *pbuf)
628 {
629         struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
630         struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
631         int ret;
632
633         spin_lock_bh(&pmlmepriv->lock);
634
635         if (pmlmepriv->wps_probe_req_ie) {
636                 pmlmepriv->wps_probe_req_ie_len = 0;
637                 kfree(pmlmepriv->wps_probe_req_ie);
638                 pmlmepriv->wps_probe_req_ie = NULL;
639         }
640
641         RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
642                  "rtw_surveydone_event_callback23a: fw_state:%x\n",
643                  get_fwstate(pmlmepriv));
644
645         if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) {
646                 del_timer_sync(&pmlmepriv->scan_to_timer);
647
648                 _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
649         } else {
650                 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
651                          "nic status =%x, survey done event comes too late!\n",
652                          get_fwstate(pmlmepriv));
653         }
654
655         rtw_set_signal_stat_timer(&adapter->recvpriv);
656
657         if (pmlmepriv->to_join == true) {
658                 set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
659                 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
660                         ret = rtw_select_and_join_from_scanned_queue23a(
661                                 pmlmepriv);
662                         if (ret != _SUCCESS)
663                                 rtw_do_join_adhoc(adapter);
664                 } else {
665                         pmlmepriv->to_join = false;
666                         ret = rtw_select_and_join_from_scanned_queue23a(
667                                 pmlmepriv);
668                         if (ret != _SUCCESS) {
669                                 DBG_8723A("try_to_join, but select scanning "
670                                           "queue fail, to_roaming:%d\n",
671                                           adapter->mlmepriv.to_roaming);
672                                 if (adapter->mlmepriv.to_roaming) {
673                                         if (--pmlmepriv->to_roaming == 0 ||
674                                             rtw_sitesurvey_cmd23a(
675                                                     adapter,
676                                                     &pmlmepriv->assoc_ssid, 1,
677                                                     NULL, 0) != _SUCCESS) {
678                                                 rtw_set_roaming(adapter, 0);
679                                                 rtw_free_assoc_resources23a(
680                                                         adapter, 1);
681                                                 rtw_indicate_disconnect23a(
682                                                         adapter);
683                                         } else
684                                                 pmlmepriv->to_join = true;
685                                 }
686                                 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
687                         }
688                 }
689         }
690
691         spin_unlock_bh(&pmlmepriv->lock);
692
693         rtw_os_xmit_schedule23a(adapter);
694
695         if (pmlmeext->sitesurvey_res.bss_cnt == 0)
696                 rtw_sreset_reset(adapter);
697
698         rtw_cfg80211_surveydone_event_callback(adapter);
699 }
700
701 static void free_scanqueue(struct mlme_priv *pmlmepriv)
702 {
703         struct wlan_network *pnetwork, *ptemp;
704         struct rtw_queue *scan_queue = &pmlmepriv->scanned_queue;
705         struct list_head *phead;
706
707         RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, "+free_scanqueue\n");
708         spin_lock_bh(&scan_queue->lock);
709         phead = get_list_head(scan_queue);
710         list_for_each_entry_safe(pnetwork, ptemp, phead, list) {
711                 pnetwork->fixed = false;
712                 _rtw_free_network23a(pmlmepriv, pnetwork);
713         }
714         spin_unlock_bh(&scan_queue->lock);
715 }
716
717 /*
718  *rtw_free_assoc_resources23a: the caller has to lock pmlmepriv->lock
719  */
720 void rtw_free_assoc_resources23a(struct rtw_adapter *adapter,
721                                  int lock_scanned_queue)
722 {
723         struct wlan_network *pwlan;
724         struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
725         struct sta_priv *pstapriv = &adapter->stapriv;
726         struct wlan_network *tgt_network = &pmlmepriv->cur_network;
727         struct sta_info *psta;
728
729         RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
730                  "+rtw_free_assoc_resources23a\n");
731         RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
732                  "tgt_network->network.MacAddress=%pM ssid=%s\n",
733                  tgt_network->network.MacAddress,
734                  tgt_network->network.Ssid.ssid);
735
736         if (check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_AP_STATE)) {
737                 psta = rtw_get_stainfo23a(&adapter->stapriv,
738                                           tgt_network->network.MacAddress);
739
740                 spin_lock_bh(&pstapriv->sta_hash_lock);
741                 rtw_free_stainfo23a(adapter,  psta);
742                 spin_unlock_bh(&pstapriv->sta_hash_lock);
743         }
744
745         if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE |
746                           WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE)) {
747                 rtw_free_all_stainfo23a(adapter);
748
749                 psta = rtw_get_bcmc_stainfo23a(adapter);
750                 spin_lock_bh(&pstapriv->sta_hash_lock);
751                 rtw_free_stainfo23a(adapter, psta);
752                 spin_unlock_bh(&pstapriv->sta_hash_lock);
753
754                 rtw_init_bcmc_stainfo23a(adapter);
755         }
756
757         if (lock_scanned_queue)
758                 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
759
760         pwlan = rtw_find_network23a(&pmlmepriv->scanned_queue,
761                                     tgt_network->network.MacAddress);
762         if (pwlan)
763                 pwlan->fixed = false;
764         else
765                 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
766                          "rtw_free_assoc_resources23a : pwlan== NULL\n");
767
768         if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) &&
769             adapter->stapriv.asoc_sta_count == 1)
770                 rtw_free_network_nolock(pmlmepriv, pwlan);
771
772         if (lock_scanned_queue)
773                 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
774
775         pmlmepriv->key_mask = 0;
776 }
777
778 /*
779 *rtw_indicate_connect23a: the caller has to lock pmlmepriv->lock
780 */
781 void rtw_indicate_connect23a(struct rtw_adapter *padapter)
782 {
783         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
784
785         RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
786                  "+rtw_indicate_connect23a\n");
787
788         pmlmepriv->to_join = false;
789
790         if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
791                 set_fwstate(pmlmepriv, _FW_LINKED);
792
793                 rtw_cfg80211_indicate_connect(padapter);
794
795                 netif_carrier_on(padapter->pnetdev);
796
797                 if (padapter->pid[2] != 0)
798                         kill_pid(find_vpid(padapter->pid[2]), SIGALRM, 1);
799         }
800
801         rtw_set_roaming(padapter, 0);
802
803         rtw_set_scan_deny(padapter, 3000);
804
805         RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
806                  "-rtw_indicate_connect23a: fw_state=0x%08x\n",
807                  get_fwstate(pmlmepriv));
808 }
809
810 /*
811  *rtw_indicate_disconnect23a: the caller has to lock pmlmepriv->lock
812  */
813 void rtw_indicate_disconnect23a(struct rtw_adapter *padapter)
814 {
815         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
816
817         RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
818                  "+rtw_indicate_disconnect23a\n");
819
820         _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING|WIFI_UNDER_WPS);
821
822         /* DBG_8723A("clear wps when %s\n", __func__); */
823
824         if (padapter->mlmepriv.to_roaming > 0)
825                 _clr_fwstate_(pmlmepriv, _FW_LINKED);
826
827         if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) ||
828             padapter->mlmepriv.to_roaming <= 0) {
829                 rtw_os_indicate_disconnect23a(padapter);
830
831                 /* set ips_deny_time to avoid enter IPS before LPS leave */
832                 padapter->pwrctrlpriv.ips_deny_time =
833                         jiffies + msecs_to_jiffies(3000);
834
835                 _clr_fwstate_(pmlmepriv, _FW_LINKED);
836
837                 rtw_clear_scan_deny(padapter);
838         }
839
840         rtw_lps_ctrl_wk_cmd23a(padapter, LPS_CTRL_DISCONNECT, 1);
841 }
842
843 void rtw_scan_abort23a(struct rtw_adapter *adapter)
844 {
845         unsigned long start;
846         struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
847         struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
848
849         start = jiffies;
850         pmlmeext->scan_abort = true;
851         while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) &&
852                jiffies_to_msecs(jiffies - start) <= 200) {
853                 if (adapter->bDriverStopped || adapter->bSurpriseRemoved)
854                         break;
855
856                 DBG_8723A("%s(%s): fw_state = _FW_UNDER_SURVEY!\n",
857                           __func__, adapter->pnetdev->name);
858                 msleep(20);
859         }
860
861         if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) {
862                 if (!adapter->bDriverStopped && !adapter->bSurpriseRemoved)
863                         DBG_8723A("%s(%s): waiting for scan_abort time out!\n",
864                                   __func__, adapter->pnetdev->name);
865                 rtw_cfg80211_indicate_scan_done(wdev_to_priv(adapter->rtw_wdev),
866                                                 true);
867         }
868         pmlmeext->scan_abort = false;
869 }
870
871 static struct sta_info *
872 rtw_joinbss_update_stainfo(struct rtw_adapter *padapter,
873                            struct wlan_network *pnetwork)
874 {
875         int i;
876         struct sta_info *bmc_sta, *psta;
877         struct recv_reorder_ctrl *preorder_ctrl;
878         struct sta_priv *pstapriv = &padapter->stapriv;
879
880         psta = rtw_get_stainfo23a(pstapriv, pnetwork->network.MacAddress);
881         if (!psta)
882                 psta = rtw_alloc_stainfo23a(pstapriv,
883                                             pnetwork->network.MacAddress,
884                                             GFP_ATOMIC);
885
886         if (psta) { /* update ptarget_sta */
887                 DBG_8723A("%s\n", __func__);
888
889                 psta->aid  = pnetwork->join_res;
890                 psta->mac_id = 0;
891
892                 /* sta mode */
893                 rtl8723a_SetHalODMVar(padapter, HAL_ODM_STA_INFO, psta, true);
894
895                 /* security related */
896                 if (padapter->securitypriv.dot11AuthAlgrthm ==
897                     dot11AuthAlgrthm_8021X) {
898                         padapter->securitypriv.binstallGrpkey = 0;
899                         padapter->securitypriv.busetkipkey = 0;
900
901                         psta->ieee8021x_blocked = true;
902                         psta->dot118021XPrivacy =
903                                 padapter->securitypriv.dot11PrivacyAlgrthm;
904
905                         memset(&psta->dot118021x_UncstKey, 0,
906                                sizeof (union Keytype));
907
908                         memset(&psta->dot11tkiprxmickey, 0,
909                                sizeof (union Keytype));
910                         memset(&psta->dot11tkiptxmickey, 0,
911                                sizeof (union Keytype));
912
913                         memset(&psta->dot11txpn, 0, sizeof (union pn48));
914                         memset(&psta->dot11rxpn, 0, sizeof (union pn48));
915                 }
916
917                 /*      Commented by Albert 2012/07/21 */
918                 /*      When doing the WPS, the wps_ie_len won't equal to 0 */
919                 /*      And the Wi-Fi driver shouldn't allow the data packet
920                         to be transmitted. */
921                 if (padapter->securitypriv.wps_ie_len != 0) {
922                         psta->ieee8021x_blocked = true;
923                         padapter->securitypriv.wps_ie_len = 0;
924                 }
925
926                 /* for A-MPDU Rx reordering buffer control for bmc_sta &
927                  * sta_info */
928                 /* if A-MPDU Rx is enabled, resetting
929                    rx_ordering_ctrl wstart_b(indicate_seq) to default
930                    value = 0xffff */
931                 /* todo: check if AP can send A-MPDU packets */
932                 for (i = 0; i < 16 ; i++) {
933                         /* preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; */
934                         preorder_ctrl = &psta->recvreorder_ctrl[i];
935                         preorder_ctrl->enable = false;
936                         preorder_ctrl->indicate_seq = 0xffff;
937                         preorder_ctrl->wend_b = 0xffff;
938                         /* max_ampdu_sz; ex. 32(kbytes) -> wsize_b = 32 */
939                         preorder_ctrl->wsize_b = 64;
940                 }
941
942                 bmc_sta = rtw_get_bcmc_stainfo23a(padapter);
943                 if (bmc_sta) {
944                         for (i = 0; i < 16 ; i++) {
945                                 preorder_ctrl = &bmc_sta->recvreorder_ctrl[i];
946                                 preorder_ctrl->enable = false;
947                                 preorder_ctrl->indicate_seq = 0xffff;
948                                 preorder_ctrl->wend_b = 0xffff;
949                                 /* max_ampdu_sz; ex. 32(kbytes) ->
950                                    wsize_b = 32 */
951                                 preorder_ctrl->wsize_b = 64;
952                         }
953                 }
954
955                 /* misc. */
956                 update_sta_info23a(padapter, psta);
957
958         }
959
960         return psta;
961 }
962
963 /* pnetwork : returns from rtw23a_joinbss_event_cb */
964 /* ptarget_wlan: found from scanned_queue */
965 static void
966 rtw_joinbss_update_network23a(struct rtw_adapter *padapter,
967                               struct wlan_network *ptarget_wlan,
968                               struct wlan_network  *pnetwork)
969 {
970         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
971         struct wlan_network *cur_network = &pmlmepriv->cur_network;
972
973         DBG_8723A("%s\n", __func__);
974
975         RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
976                  "fw_state:%x, BSSID:%pM\n",
977                  get_fwstate(pmlmepriv),
978                  pnetwork->network.MacAddress);
979
980         /*  why not use ptarget_wlan?? */
981         memcpy(&cur_network->network, &pnetwork->network,
982                pnetwork->network.Length);
983         /*  some IEs in pnetwork is wrong, so we should use ptarget_wlan IEs */
984         cur_network->network.IELength = ptarget_wlan->network.IELength;
985         memcpy(&cur_network->network.IEs[0], &ptarget_wlan->network.IEs[0],
986                MAX_IE_SZ);
987
988         cur_network->network.capability = ptarget_wlan->network.capability;
989         cur_network->network.beacon_interval =
990                 ptarget_wlan->network.beacon_interval;
991         cur_network->network.tsf = ptarget_wlan->network.tsf;
992
993         rtw_set_signal_stat_timer(&padapter->recvpriv);
994         padapter->recvpriv.signal_strength =
995                 ptarget_wlan->network.SignalStrength;
996         padapter->recvpriv.signal_qual = ptarget_wlan->network.SignalQuality;
997         /*
998          * the ptarget_wlan->network.Rssi is raw data, we use
999          * ptarget_wlan->network.SignalStrength instead (has scaled)
1000          */
1001         DBG_8723A("%s signal_strength:%3u, signal_qual:%3u\n",
1002                   __func__, padapter->recvpriv.signal_strength,
1003                   padapter->recvpriv.signal_qual);
1004         rtw_set_signal_stat_timer(&padapter->recvpriv);
1005
1006         /* update fw_state will clr _FW_UNDER_LINKING here indirectly */
1007         switch (pnetwork->network.ifmode) {
1008         case NL80211_IFTYPE_P2P_CLIENT:
1009         case NL80211_IFTYPE_STATION:
1010                 if (pmlmepriv->fw_state & WIFI_UNDER_WPS)
1011                         pmlmepriv->fw_state = WIFI_STATION_STATE|WIFI_UNDER_WPS;
1012                 else
1013                         pmlmepriv->fw_state = WIFI_STATION_STATE;
1014                 break;
1015         case NL80211_IFTYPE_ADHOC:
1016                 pmlmepriv->fw_state = WIFI_ADHOC_STATE;
1017                 break;
1018         default:
1019                 pmlmepriv->fw_state = WIFI_NULL_STATE;
1020                 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1021                          "Invalid network_mode\n");
1022                 break;
1023         }
1024
1025         rtw_update_protection23a(padapter, cur_network->network.IEs,
1026                                  cur_network->network.IELength);
1027
1028         rtw_update_ht_cap23a(padapter, cur_network->network.IEs,
1029                              cur_network->network.IELength);
1030 }
1031
1032 /*
1033  * Notes:
1034  * the function could be > passive_level (the same context as Rx tasklet)
1035  * pnetwork : returns from rtw23a_joinbss_event_cb
1036  * ptarget_wlan: found from scanned_queue
1037  * if join_res > 0, for (fw_state==WIFI_STATION_STATE),
1038  * we check if  "ptarget_sta" & "ptarget_wlan" exist.
1039  * if join_res > 0, for (fw_state==WIFI_ADHOC_STATE),
1040  * we only check if "ptarget_wlan" exist.
1041  * if join_res > 0, update "cur_network->network" from "pnetwork->network"
1042  * if (ptarget_wlan !=NULL).
1043  */
1044
1045 void rtw_joinbss_event_prehandle23a(struct rtw_adapter *adapter, u8 *pbuf)
1046 {
1047         struct sta_info *ptarget_sta, *pcur_sta;
1048         struct sta_priv *pstapriv = &adapter->stapriv;
1049         struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1050         struct wlan_network *pnetwork = (struct wlan_network *)pbuf;
1051         struct wlan_network *cur_network = &pmlmepriv->cur_network;
1052         struct wlan_network *pcur_wlan, *ptarget_wlan = NULL;
1053         bool the_same_macaddr;
1054
1055         RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
1056                  "joinbss event call back received with res=%d\n",
1057                  pnetwork->join_res);
1058
1059         if (pmlmepriv->assoc_ssid.ssid_len == 0) {
1060                 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1061                          "@@@@@   joinbss event call back  for Any SSid\n");
1062         } else {
1063                 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1064                          "@@@@@   rtw23a_joinbss_event_cb for SSid:%s\n",
1065                          pmlmepriv->assoc_ssid.ssid);
1066         }
1067
1068         if (ether_addr_equal(pnetwork->network.MacAddress,
1069                              cur_network->network.MacAddress))
1070                 the_same_macaddr = true;
1071         else
1072                 the_same_macaddr = false;
1073
1074         pnetwork->network.Length = get_wlan_bssid_ex_sz(&pnetwork->network);
1075         if (pnetwork->network.Length > sizeof(struct wlan_bssid_ex)) {
1076                 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1077                          "***joinbss_evt_callback return a wrong bss ***\n");
1078                 return;
1079         }
1080
1081         spin_lock_bh(&pmlmepriv->lock);
1082
1083         RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
1084                  "rtw23a_joinbss_event_cb !! _enter_critical\n");
1085
1086         if (pnetwork->join_res > 0) {
1087                 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
1088                 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) {
1089                         /* s1. find ptarget_wlan */
1090                         if (check_fwstate(pmlmepriv, _FW_LINKED)) {
1091                                 if (the_same_macaddr) {
1092                                         ptarget_wlan = rtw_find_network23a(&pmlmepriv->scanned_queue, cur_network->network.MacAddress);
1093                                 } else {
1094                                         pcur_wlan = rtw_find_network23a(&pmlmepriv->scanned_queue, cur_network->network.MacAddress);
1095                                         if (pcur_wlan)
1096                                                 pcur_wlan->fixed = false;
1097
1098                                         pcur_sta = rtw_get_stainfo23a(pstapriv, cur_network->network.MacAddress);
1099                                         if (pcur_sta) {
1100                                                 spin_lock_bh(&pstapriv->sta_hash_lock);
1101                                                 rtw_free_stainfo23a(adapter,
1102                                                                     pcur_sta);
1103                                                 spin_unlock_bh(&pstapriv->sta_hash_lock);
1104                                         }
1105
1106                                         ptarget_wlan = rtw_find_network23a(&pmlmepriv->scanned_queue, pnetwork->network.MacAddress);
1107                                         if (check_fwstate(pmlmepriv,
1108                                                           WIFI_STATION_STATE)) {
1109                                                 if (ptarget_wlan)
1110                                                         ptarget_wlan->fixed =
1111                                                                 true;
1112                                         }
1113                                 }
1114
1115                         } else {
1116                                 ptarget_wlan = rtw_find_network23a(
1117                                         &pmlmepriv->scanned_queue,
1118                                         pnetwork->network.MacAddress);
1119                                 if (check_fwstate(pmlmepriv,
1120                                                   WIFI_STATION_STATE)) {
1121                                         if (ptarget_wlan)
1122                                                 ptarget_wlan->fixed = true;
1123                                 }
1124                         }
1125
1126                         /* s2. update cur_network */
1127                         if (ptarget_wlan)
1128                                 rtw_joinbss_update_network23a(adapter,
1129                                                               ptarget_wlan,
1130                                                               pnetwork);
1131                         else {
1132                                 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1133                                          "Can't find ptarget_wlan when joinbss_event callback\n");
1134                                 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1135                                 goto ignore_joinbss_callback;
1136                         }
1137
1138                         /* s3. find ptarget_sta & update ptarget_sta after
1139                            update cur_network only for station mode */
1140                         if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
1141                                 ptarget_sta = rtw_joinbss_update_stainfo(
1142                                         adapter, pnetwork);
1143                                 if (!ptarget_sta) {
1144                                         RT_TRACE(_module_rtl871x_mlme_c_,
1145                                                  _drv_err_,
1146                                                  "Can't update stainfo when joinbss_event callback\n");
1147                                         spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1148                                         goto ignore_joinbss_callback;
1149                                 }
1150                         }
1151
1152                         /* s4. indicate connect */
1153                         if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
1154                                 rtw_indicate_connect23a(adapter);
1155                         else {
1156                                 /* adhoc mode will rtw_indicate_connect23a
1157                                    when rtw_stassoc_event_callback23a */
1158                                 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
1159                                          "adhoc mode, fw_state:%x\n",
1160                                          get_fwstate(pmlmepriv));
1161                         }
1162
1163                         /* s5. Cancle assoc_timer */
1164                         del_timer_sync(&pmlmepriv->assoc_timer);
1165
1166                         RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
1167                                  "Cancle assoc_timer\n");
1168                 } else {
1169                         RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1170                                  "rtw23a_joinbss_event_cb err: fw_state:%x\n",
1171                                  get_fwstate(pmlmepriv));
1172                         spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1173                         goto ignore_joinbss_callback;
1174                 }
1175                 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1176         } else if (pnetwork->join_res == -4) {
1177                 rtw_reset_securitypriv23a(adapter);
1178                 mod_timer(&pmlmepriv->assoc_timer,
1179                           jiffies + msecs_to_jiffies(1));
1180
1181                 /* rtw_free_assoc_resources23a(adapter, 1); */
1182
1183                 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) {
1184                         RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1185                                  "fail! clear _FW_UNDER_LINKING ^^^fw_state=%x\n",
1186                                  get_fwstate(pmlmepriv));
1187                         _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
1188                 }
1189         } else {
1190                 /* if join_res < 0 (join fails), then try again */
1191                 mod_timer(&pmlmepriv->assoc_timer,
1192                           jiffies + msecs_to_jiffies(1));
1193                 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
1194         }
1195
1196 ignore_joinbss_callback:
1197
1198         spin_unlock_bh(&pmlmepriv->lock);
1199 }
1200
1201 void rtw23a_joinbss_event_cb(struct rtw_adapter *adapter, const u8 *pbuf)
1202 {
1203         struct wlan_network *pnetwork = (struct wlan_network *)pbuf;
1204
1205         mlmeext_joinbss_event_callback23a(adapter, pnetwork->join_res);
1206
1207         rtw_os_xmit_schedule23a(adapter);
1208 }
1209
1210 void rtw_stassoc_event_callback23a(struct rtw_adapter *adapter, const u8 *pbuf)
1211 {
1212         struct sta_info *psta;
1213         struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1214         struct stassoc_event *pstassoc = (struct stassoc_event *)pbuf;
1215         struct wlan_network *cur_network = &pmlmepriv->cur_network;
1216         struct wlan_network *ptarget_wlan;
1217
1218         if (rtw_access_ctrl23a(adapter, pstassoc->macaddr) == false)
1219                 return;
1220
1221 #ifdef CONFIG_8723AU_AP_MODE
1222         if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1223                 psta = rtw_get_stainfo23a(&adapter->stapriv, pstassoc->macaddr);
1224                 if (psta) {
1225                         /* bss_cap_update_on_sta_join23a(adapter, psta); */
1226                         /* sta_info_update23a(adapter, psta); */
1227                         ap_sta_info_defer_update23a(adapter, psta);
1228                 }
1229                 return;
1230         }
1231 #endif
1232         /* for AD-HOC mode */
1233         psta = rtw_get_stainfo23a(&adapter->stapriv, pstassoc->macaddr);
1234         if (psta != NULL) {
1235                 /* the sta have been in sta_info_queue => do nothing */
1236                 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1237                          "Error: rtw_stassoc_event_callback23a: sta has been in sta_hash_queue\n");
1238                 /* between drv has received this event before and
1239                    fw have not yet to set key to CAM_ENTRY) */
1240                 return;
1241         }
1242
1243         psta = rtw_alloc_stainfo23a(&adapter->stapriv, pstassoc->macaddr,
1244                 GFP_KERNEL);
1245         if (!psta) {
1246                 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1247                          "Can't alloc sta_info when rtw_stassoc_event_callback23a\n");
1248                 return;
1249         }
1250
1251         /* to do : init sta_info variable */
1252         psta->qos_option = 0;
1253         psta->mac_id = (uint)pstassoc->cam_id;
1254         /* psta->aid = (uint)pstassoc->cam_id; */
1255         DBG_8723A("%s\n", __func__);
1256         /* for ad-hoc mode */
1257         rtl8723a_SetHalODMVar(adapter, HAL_ODM_STA_INFO, psta, true);
1258
1259         if (adapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)
1260                 psta->dot118021XPrivacy =
1261                         adapter->securitypriv.dot11PrivacyAlgrthm;
1262
1263         psta->ieee8021x_blocked = false;
1264
1265         spin_lock_bh(&pmlmepriv->lock);
1266
1267         if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) ||
1268             check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
1269                 if (adapter->stapriv.asoc_sta_count == 2) {
1270                         spin_lock_bh(&pmlmepriv->scanned_queue.lock);
1271                         ptarget_wlan =
1272                                 rtw_find_network23a(&pmlmepriv->scanned_queue,
1273                                                     cur_network->network.MacAddress);
1274                         if (ptarget_wlan)
1275                                 ptarget_wlan->fixed = true;
1276                         spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1277                         /*  a sta + bc/mc_stainfo (not Ibss_stainfo) */
1278                         rtw_indicate_connect23a(adapter);
1279                 }
1280         }
1281
1282         spin_unlock_bh(&pmlmepriv->lock);
1283
1284         mlmeext_sta_add_event_callback23a(adapter, psta);
1285 }
1286
1287 void rtw_stadel_event_callback23a(struct rtw_adapter *adapter, const u8 *pbuf)
1288 {
1289         int mac_id;
1290         struct sta_info *psta;
1291         struct wlan_network *pwlan;
1292         struct wlan_bssid_ex *pdev_network;
1293         struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1294         struct stadel_event *pstadel = (struct stadel_event *)pbuf;
1295         struct sta_priv *pstapriv = &adapter->stapriv;
1296         struct wlan_network *tgt_network = &pmlmepriv->cur_network;
1297
1298         psta = rtw_get_stainfo23a(&adapter->stapriv, pstadel->macaddr);
1299         if (psta)
1300                 mac_id = psta->mac_id;
1301         else
1302                 mac_id = pstadel->mac_id;
1303
1304         DBG_8723A("%s(mac_id=%d)=%pM\n", __func__, mac_id, pstadel->macaddr);
1305
1306         if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
1307                 return;
1308
1309         mlmeext_sta_del_event_callback23a(adapter);
1310
1311         spin_lock_bh(&pmlmepriv->lock);
1312
1313         if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
1314                 if (adapter->mlmepriv.to_roaming > 0) {
1315                         /* this stadel_event is caused by roaming,
1316                            decrease to_roaming */
1317                         pmlmepriv->to_roaming--;
1318                 } else if (adapter->mlmepriv.to_roaming == 0)
1319                         rtw_set_roaming(adapter, adapter->registrypriv.max_roaming_times);
1320                 if (*((u16 *)pstadel->rsvd) != WLAN_REASON_EXPIRATION_CHK)
1321                         rtw_set_roaming(adapter, 0); /* don't roam */
1322
1323                 rtw_free_uc_swdec_pending_queue23a(adapter);
1324
1325                 rtw_free_assoc_resources23a(adapter, 1);
1326                 rtw_indicate_disconnect23a(adapter);
1327                 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
1328                 /*  remove the network entry in scanned_queue */
1329                 pwlan = rtw_find_network23a(&pmlmepriv->scanned_queue,
1330                                             tgt_network->network.MacAddress);
1331                 if (pwlan) {
1332                         pwlan->fixed = false;
1333                         rtw_free_network_nolock(pmlmepriv, pwlan);
1334                 }
1335                 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1336
1337                 _rtw_roaming(adapter, tgt_network);
1338         }
1339
1340         if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) ||
1341             check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
1342
1343                 spin_lock_bh(&pstapriv->sta_hash_lock);
1344                 rtw_free_stainfo23a(adapter,  psta);
1345                 spin_unlock_bh(&pstapriv->sta_hash_lock);
1346
1347                 /* a sta + bc/mc_stainfo (not Ibss_stainfo) */
1348                 if (adapter->stapriv.asoc_sta_count == 1) {
1349                         spin_lock_bh(&pmlmepriv->scanned_queue.lock);
1350                         /* free old ibss network */
1351                         /* pwlan = rtw_find_network23a(
1352                            &pmlmepriv->scanned_queue, pstadel->macaddr); */
1353                         pwlan = rtw_find_network23a(&pmlmepriv->scanned_queue,
1354                                                     tgt_network->network.MacAddress);
1355                         if (pwlan) {
1356                                 pwlan->fixed = false;
1357                                 rtw_free_network_nolock(pmlmepriv, pwlan);
1358                         }
1359                         spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1360                         /* re-create ibss */
1361                         pdev_network = &adapter->registrypriv.dev_network;
1362
1363                         memcpy(pdev_network, &tgt_network->network,
1364                                get_wlan_bssid_ex_sz(&tgt_network->network));
1365
1366                         rtw_do_join_adhoc(adapter);
1367                 }
1368         }
1369
1370         spin_unlock_bh(&pmlmepriv->lock);
1371 }
1372
1373 /*
1374 * rtw23a_join_to_handler - Timeout/failure handler for CMD JoinBss
1375 * @adapter: pointer to _adapter structure
1376 */
1377 void rtw23a_join_to_handler (unsigned long data)
1378 {
1379         struct rtw_adapter *adapter = (struct rtw_adapter *)data;
1380         struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1381         int do_join_r;
1382
1383         DBG_8723A("%s, fw_state=%x\n", __func__, get_fwstate(pmlmepriv));
1384
1385         if (adapter->bDriverStopped || adapter->bSurpriseRemoved)
1386                 return;
1387
1388         spin_lock_bh(&pmlmepriv->lock);
1389
1390         if (adapter->mlmepriv.to_roaming > 0) {
1391                 /* join timeout caused by roaming */
1392                 while (1) {
1393                         pmlmepriv->to_roaming--;
1394                         if (adapter->mlmepriv.to_roaming != 0) {
1395                                 /* try another */
1396                                 DBG_8723A("%s try another roaming\n", __func__);
1397                                 do_join_r = rtw_do_join(adapter);
1398                                 if (do_join_r != _SUCCESS) {
1399                                         DBG_8723A("%s roaming do_join return "
1400                                                   "%d\n", __func__ , do_join_r);
1401                                         continue;
1402                                 }
1403                                 break;
1404                         } else {
1405                                 DBG_8723A("%s We've try roaming but fail\n",
1406                                           __func__);
1407                                 rtw_indicate_disconnect23a(adapter);
1408                                 break;
1409                         }
1410                 }
1411         } else {
1412                 rtw_indicate_disconnect23a(adapter);
1413                 free_scanqueue(pmlmepriv);/*  */
1414
1415                 /* indicate disconnect for the case that join_timeout and
1416                    check_fwstate != FW_LINKED */
1417                 rtw_cfg80211_indicate_disconnect(adapter);
1418         }
1419
1420         spin_unlock_bh(&pmlmepriv->lock);
1421
1422 }
1423
1424 /*
1425 * rtw_scan_timeout_handler23a - Timeout/Failure handler for CMD SiteSurvey
1426 * @data: pointer to _adapter structure
1427 */
1428 void rtw_scan_timeout_handler23a(unsigned long data)
1429 {
1430         struct rtw_adapter *adapter = (struct rtw_adapter *)data;
1431         struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1432
1433         DBG_8723A("%s(%s): fw_state =%x\n", __func__, adapter->pnetdev->name,
1434                   get_fwstate(pmlmepriv));
1435
1436         spin_lock_bh(&pmlmepriv->lock);
1437
1438         _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
1439
1440         spin_unlock_bh(&pmlmepriv->lock);
1441
1442         rtw_cfg80211_indicate_scan_done(wdev_to_priv(adapter->rtw_wdev), true);
1443 }
1444
1445 void rtw_dynamic_check_timer_handler(unsigned long data)
1446 {
1447         struct rtw_adapter *adapter = (struct rtw_adapter *)data;
1448
1449         if (adapter->hw_init_completed == false)
1450                 goto out;
1451
1452         if (adapter->bDriverStopped == true ||
1453             adapter->bSurpriseRemoved == true)
1454                 goto out;
1455
1456         if (adapter->net_closed == true)
1457                 goto out;
1458
1459         rtw_dynamic_chk_wk_cmd23a(adapter);
1460
1461 out:
1462         mod_timer(&adapter->mlmepriv.dynamic_chk_timer,
1463                   jiffies + msecs_to_jiffies(2000));
1464 }
1465
1466 inline bool rtw_is_scan_deny(struct rtw_adapter *adapter)
1467 {
1468         struct mlme_priv *mlmepriv = &adapter->mlmepriv;
1469
1470         return (atomic_read(&mlmepriv->set_scan_deny) != 0) ? true : false;
1471 }
1472
1473 void rtw_clear_scan_deny(struct rtw_adapter *adapter)
1474 {
1475         struct mlme_priv *mlmepriv = &adapter->mlmepriv;
1476
1477         atomic_set(&mlmepriv->set_scan_deny, 0);
1478 }
1479
1480 void rtw_set_scan_deny_timer_hdl(unsigned long data)
1481 {
1482         struct rtw_adapter *adapter = (struct rtw_adapter *)data;
1483
1484         rtw_clear_scan_deny(adapter);
1485 }
1486
1487 void rtw_set_scan_deny(struct rtw_adapter *adapter, u32 ms)
1488 {
1489         struct mlme_priv *mlmepriv = &adapter->mlmepriv;
1490
1491         atomic_set(&mlmepriv->set_scan_deny, 1);
1492         mod_timer(&mlmepriv->set_scan_deny_timer,
1493                   jiffies + msecs_to_jiffies(ms));
1494 }
1495
1496 #if defined(IEEE80211_SCAN_RESULT_EXPIRE)
1497 #define RTW_SCAN_RESULT_EXPIRE  \
1498         ((IEEE80211_SCAN_RESULT_EXPIRE / (HZ*1000)) - 1000) /* 3000 -1000 */
1499 #else
1500 #define RTW_SCAN_RESULT_EXPIRE 2000
1501 #endif
1502
1503 /*
1504 * Select a new join candidate from the original @param candidate and
1505 *     @param competitor
1506 * @return true: candidate is updated
1507 * @return false: candidate is not updated
1508 */
1509 static int rtw_check_join_candidate(struct mlme_priv *pmlmepriv,
1510                                     struct wlan_network **candidate,
1511                                     struct wlan_network *competitor)
1512 {
1513         int updated = false;
1514         struct rtw_adapter *adapter;
1515
1516         adapter = container_of(pmlmepriv, struct rtw_adapter, mlmepriv);
1517
1518         /* check bssid, if needed */
1519         if (pmlmepriv->assoc_by_bssid == true) {
1520                 if (!ether_addr_equal(competitor->network.MacAddress,
1521                                       pmlmepriv->assoc_bssid))
1522                         goto exit;
1523         }
1524
1525         /* check ssid, if needed */
1526         if (pmlmepriv->assoc_ssid.ssid_len) {
1527                 if (competitor->network.Ssid.ssid_len !=
1528                     pmlmepriv->assoc_ssid.ssid_len ||
1529                     memcmp(competitor->network.Ssid.ssid,
1530                            pmlmepriv->assoc_ssid.ssid,
1531                            pmlmepriv->assoc_ssid.ssid_len))
1532                         goto exit;
1533         }
1534
1535         if (rtw_is_desired_network(adapter, competitor) == false)
1536                 goto exit;
1537
1538         if (adapter->mlmepriv.to_roaming > 0) {
1539                 unsigned int passed;
1540
1541                 passed = jiffies_to_msecs(jiffies - competitor->last_scanned);
1542                 if (passed >= RTW_SCAN_RESULT_EXPIRE ||
1543                     is_same_ess(&competitor->network,
1544                                 &pmlmepriv->cur_network.network) == false)
1545                         goto exit;
1546         }
1547
1548         if (!*candidate ||
1549             (*candidate)->network.Rssi<competitor->network.Rssi) {
1550                 *candidate = competitor;
1551                 updated = true;
1552         }
1553
1554         if (updated) {
1555                 DBG_8723A("[by_bssid:%u][assoc_ssid:%s][to_roaming:%u] new candidate: %s(%pM) rssi:%d\n",
1556                           pmlmepriv->assoc_by_bssid,
1557                           pmlmepriv->assoc_ssid.ssid,
1558                           adapter->mlmepriv.to_roaming,
1559                           (*candidate)->network.Ssid.ssid,
1560                           (*candidate)->network.MacAddress,
1561                           (int)(*candidate)->network.Rssi);
1562         }
1563
1564 exit:
1565         return updated;
1566 }
1567
1568 /*
1569 Calling context:
1570 The caller of the sub-routine will be in critical section...
1571
1572 The caller must hold the following spinlock
1573
1574 pmlmepriv->lock
1575
1576 */
1577
1578 static int rtw_do_join(struct rtw_adapter *padapter)
1579 {
1580         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1581         int ret;
1582
1583         pmlmepriv->cur_network.join_res = -2;
1584
1585         set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
1586
1587         pmlmepriv->to_join = true;
1588
1589         ret = rtw_select_and_join_from_scanned_queue23a(pmlmepriv);
1590         if (ret == _SUCCESS) {
1591                 pmlmepriv->to_join = false;
1592         } else {
1593                 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
1594                         /* switch to ADHOC_MASTER */
1595                         ret = rtw_do_join_adhoc(padapter);
1596                         if (ret != _SUCCESS)
1597                                 goto exit;
1598                 } else {
1599                         /*  can't associate ; reset under-linking */
1600                         _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
1601
1602                         ret = _FAIL;
1603                         pmlmepriv->to_join = false;
1604                 }
1605         }
1606
1607 exit:
1608         return ret;
1609 }
1610
1611 static struct wlan_network *
1612 rtw_select_candidate_from_queue(struct mlme_priv *pmlmepriv)
1613 {
1614         struct wlan_network *pnetwork, *ptmp, *candidate = NULL;
1615         struct rtw_queue *queue = &pmlmepriv->scanned_queue;
1616         struct list_head *phead;
1617
1618         spin_lock_bh(&pmlmepriv->scanned_queue.lock);
1619         phead = get_list_head(queue);
1620         list_for_each_entry_safe(pnetwork, ptmp, phead, list) {
1621                 if (!pnetwork) {
1622                         RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1623                                  "%s: return _FAIL:(pnetwork == NULL)\n",
1624                                  __func__);
1625                         goto exit;
1626                 }
1627
1628                 rtw_check_join_candidate(pmlmepriv, &candidate, pnetwork);
1629         }
1630
1631 exit:
1632         spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1633         return candidate;
1634 }
1635
1636
1637 int rtw_do_join_adhoc(struct rtw_adapter *adapter)
1638 {
1639         struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1640         struct wlan_bssid_ex *pdev_network;
1641         u8 *ibss;
1642         int ret;
1643
1644         pdev_network = &adapter->registrypriv.dev_network;
1645         ibss = adapter->registrypriv.dev_network.MacAddress;
1646
1647         _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
1648
1649         RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1650                  "switching to adhoc master\n");
1651
1652         memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid,
1653                sizeof(struct cfg80211_ssid));
1654
1655         rtw_update_registrypriv_dev_network23a(adapter);
1656         rtw_generate_random_ibss23a(ibss);
1657
1658         pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;
1659
1660         ret = rtw_createbss_cmd23a(adapter);
1661         if (ret != _SUCCESS) {
1662                 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1663                          "Error =>rtw_createbss_cmd23a status FAIL\n");
1664         } else  {
1665                 pmlmepriv->to_join = false;
1666         }
1667
1668         return ret;
1669 }
1670
1671 int rtw_do_join_network(struct rtw_adapter *adapter,
1672                         struct wlan_network *candidate)
1673 {
1674         int ret;
1675
1676         /*  check for situation of  _FW_LINKED */
1677         if (check_fwstate(&adapter->mlmepriv, _FW_LINKED)) {
1678                 DBG_8723A("%s: _FW_LINKED while ask_for_joinbss!\n", __func__);
1679
1680                 rtw_disassoc_cmd23a(adapter, 0, true);
1681                 rtw_indicate_disconnect23a(adapter);
1682                 rtw_free_assoc_resources23a(adapter, 0);
1683         }
1684         set_fwstate(&adapter->mlmepriv, _FW_UNDER_LINKING);
1685
1686         ret = rtw_joinbss_cmd23a(adapter, candidate);
1687
1688         if (ret == _SUCCESS)
1689                 mod_timer(&adapter->mlmepriv.assoc_timer,
1690                           jiffies + msecs_to_jiffies(MAX_JOIN_TIMEOUT));
1691
1692         return ret;
1693 }
1694
1695 int rtw_select_and_join_from_scanned_queue23a(struct mlme_priv *pmlmepriv)
1696 {
1697         struct rtw_adapter *adapter;
1698         struct wlan_network *candidate = NULL;
1699         int ret;
1700
1701         adapter = pmlmepriv->nic_hdl;
1702
1703         candidate = rtw_select_candidate_from_queue(pmlmepriv);
1704         if (!candidate) {
1705                 DBG_8723A("%s: return _FAIL(candidate == NULL)\n", __func__);
1706                 ret = _FAIL;
1707                 goto exit;
1708         } else {
1709                 DBG_8723A("%s: candidate: %s(%pM, ch:%u)\n",
1710                           __func__,
1711                           candidate->network.Ssid.ssid,
1712                           candidate->network.MacAddress,
1713                           candidate->network.DSConfig);
1714         }
1715
1716         ret = rtw_do_join_network(adapter, candidate);
1717
1718 exit:
1719         return ret;
1720 }
1721
1722 int rtw_set_auth23a(struct rtw_adapter *adapter,
1723                     struct security_priv *psecuritypriv)
1724 {
1725         struct cmd_obj *pcmd;
1726         struct setauth_parm *psetauthparm;
1727         struct cmd_priv *pcmdpriv = &adapter->cmdpriv;
1728         int res = _SUCCESS;
1729
1730         pcmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
1731         if (!pcmd) {
1732                 res = _FAIL;  /* try again */
1733                 goto exit;
1734         }
1735
1736         psetauthparm = kzalloc(sizeof(struct setauth_parm), GFP_KERNEL);
1737         if (!psetauthparm) {
1738                 kfree(pcmd);
1739                 res = _FAIL;
1740                 goto exit;
1741         }
1742
1743         psetauthparm->mode = (unsigned char)psecuritypriv->dot11AuthAlgrthm;
1744
1745         pcmd->cmdcode = _SetAuth_CMD_;
1746         pcmd->parmbuf = (unsigned char *)psetauthparm;
1747         pcmd->cmdsz =  (sizeof(struct setauth_parm));
1748         pcmd->rsp = NULL;
1749         pcmd->rspsz = 0;
1750
1751         RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1752                  "after enqueue set_auth_cmd, auth_mode=%x\n",
1753                  psecuritypriv->dot11AuthAlgrthm);
1754
1755         res = rtw_enqueue_cmd23a(pcmdpriv, pcmd);
1756
1757 exit:
1758
1759         return res;
1760 }
1761
1762 int rtw_set_key23a(struct rtw_adapter *adapter,
1763                    struct security_priv *psecuritypriv, int keyid, u8 set_tx)
1764 {
1765         u8 keylen;
1766         struct cmd_obj *pcmd;
1767         struct setkey_parm *psetkeyparm;
1768         struct cmd_priv *pcmdpriv = &adapter->cmdpriv;
1769         struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1770         int res = _SUCCESS;
1771
1772         if (keyid >= 4) {
1773                 res = _FAIL;
1774                 goto exit;
1775         }
1776
1777         pcmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
1778         if (!pcmd) {
1779                 res = _FAIL;  /* try again */
1780                 goto exit;
1781         }
1782         psetkeyparm = kzalloc(sizeof(struct setkey_parm), GFP_KERNEL);
1783         if (!psetkeyparm) {
1784                 kfree(pcmd);
1785                 res = _FAIL;
1786                 goto exit;
1787         }
1788
1789         if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) {
1790                 psetkeyparm->algorithm = (unsigned char)
1791                         psecuritypriv->dot118021XGrpPrivacy;
1792                 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1793                          "rtw_set_key23a: psetkeyparm->algorithm = (unsigned char)psecuritypriv->dot118021XGrpPrivacy =%d\n",
1794                          psetkeyparm->algorithm);
1795         } else {
1796                 psetkeyparm->algorithm = (u8)psecuritypriv->dot11PrivacyAlgrthm;
1797                 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1798                          "rtw_set_key23a: psetkeyparm->algorithm = (u8)psecuritypriv->dot11PrivacyAlgrthm =%d\n",
1799                          psetkeyparm->algorithm);
1800         }
1801         psetkeyparm->keyid = keyid;/* 0~3 */
1802         psetkeyparm->set_tx = set_tx;
1803         if (is_wep_enc(psetkeyparm->algorithm))
1804                 pmlmepriv->key_mask |= BIT(psetkeyparm->keyid);
1805
1806         DBG_8723A("==> rtw_set_key23a algorithm(%x), keyid(%x), key_mask(%x)\n",
1807                   psetkeyparm->algorithm, psetkeyparm->keyid,
1808                   pmlmepriv->key_mask);
1809         RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1810                  "rtw_set_key23a: psetkeyparm->algorithm =%d psetkeyparm->keyid = (u8)keyid =%d\n",
1811                  psetkeyparm->algorithm, keyid);
1812
1813         switch (psetkeyparm->algorithm) {
1814         case WLAN_CIPHER_SUITE_WEP40:
1815                 keylen = 5;
1816                 memcpy(&psetkeyparm->key[0],
1817                        &psecuritypriv->wep_key[keyid].key, keylen);
1818                 break;
1819         case WLAN_CIPHER_SUITE_WEP104:
1820                 keylen = 13;
1821                 memcpy(&psetkeyparm->key[0],
1822                        &psecuritypriv->wep_key[keyid].key, keylen);
1823                 break;
1824         case WLAN_CIPHER_SUITE_TKIP:
1825                 keylen = 16;
1826                 memcpy(&psetkeyparm->key,
1827                        &psecuritypriv->dot118021XGrpKey[keyid], keylen);
1828                 psetkeyparm->grpkey = 1;
1829                 break;
1830         case WLAN_CIPHER_SUITE_CCMP:
1831                 keylen = 16;
1832                 memcpy(&psetkeyparm->key,
1833                        &psecuritypriv->dot118021XGrpKey[keyid], keylen);
1834                 psetkeyparm->grpkey = 1;
1835                 break;
1836         default:
1837                 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1838                          "rtw_set_key23a:psecuritypriv->dot11PrivacyAlgrthm = %x (must be 1 or 2 or 4 or 5)\n",
1839                          psecuritypriv->dot11PrivacyAlgrthm);
1840                 res = _FAIL;
1841                 kfree(pcmd);
1842                 kfree(psetkeyparm);
1843                 goto exit;
1844         }
1845
1846         pcmd->cmdcode = _SetKey_CMD_;
1847         pcmd->parmbuf = (u8 *)psetkeyparm;
1848         pcmd->cmdsz =  (sizeof(struct setkey_parm));
1849         pcmd->rsp = NULL;
1850         pcmd->rspsz = 0;
1851
1852         /* sema_init(&pcmd->cmd_sem, 0); */
1853
1854         res = rtw_enqueue_cmd23a(pcmdpriv, pcmd);
1855
1856 exit:
1857
1858         return res;
1859 }
1860
1861 /* adjust IEs for rtw_joinbss_cmd23a in WMM */
1862 int rtw_restruct_wmm_ie23a(struct rtw_adapter *adapter, u8 *in_ie,
1863                            u8 *out_ie, uint in_len, uint initial_out_len)
1864 {
1865         int ielength;
1866         const u8 *p;
1867
1868         ielength = initial_out_len;
1869
1870         p = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
1871                                     WLAN_OUI_TYPE_MICROSOFT_WMM,
1872                                     in_ie, in_len);
1873
1874         if (p && p[1]) {
1875                 memcpy(out_ie + initial_out_len, p, 9);
1876
1877                 out_ie[initial_out_len + 1] = 7;
1878                 out_ie[initial_out_len + 6] = 0;
1879                 out_ie[initial_out_len + 8] = 0;
1880
1881                 ielength += 9;
1882         }
1883
1884         return ielength;
1885 }
1886
1887 /*  */
1888 /*  Ported from 8185: IsInPreAuthKeyList().
1889     (Renamed from SecIsInPreAuthKeyList(), 2006-10-13.) */
1890 /*  Added by Annie, 2006-05-07. */
1891 /*  */
1892 /*  Search by BSSID, */
1893 /*  Return Value: */
1894 /*              -1      :if there is no pre-auth key in the  table */
1895 /*              >= 0    :if there is pre-auth key, and   return the entry id */
1896 /*  */
1897 /*  */
1898
1899 static int SecIsInPMKIDList(struct rtw_adapter *Adapter, u8 *bssid)
1900 {
1901         struct security_priv *psecuritypriv = &Adapter->securitypriv;
1902         int i = 0;
1903
1904         do {
1905                 if (psecuritypriv->PMKIDList[i].bUsed &&
1906                     ether_addr_equal(psecuritypriv->PMKIDList[i].Bssid, bssid)) {
1907                         break;
1908                 } else {
1909                         i++;
1910                         /* continue; */
1911                 }
1912         } while (i < NUM_PMKID_CACHE);
1913
1914         if (i == NUM_PMKID_CACHE)
1915                 i = -1;/*  Could not find. */
1916         else {
1917                 /*  There is one Pre-Authentication Key for
1918                     the specific BSSID. */
1919         }
1920
1921         return i;
1922 }
1923
1924 /*  */
1925 /*  Check the RSN IE length */
1926 /*  If the RSN IE length <= 20, the RSN IE didn't include
1927     the PMKID information */
1928 /*  0-11th element in the array are the fixed IE */
1929 /*  12th element in the array is the IE */
1930 /*  13th element in the array is the IE length */
1931 /*  */
1932
1933 static int rtw_append_pmkid(struct rtw_adapter *Adapter, int iEntry,
1934                             u8 *ie, uint ie_len)
1935 {
1936         struct security_priv *psecuritypriv = &Adapter->securitypriv;
1937
1938         if (ie[1] <= 20) {
1939                 /*  The RSN IE didn't include the PMK ID,
1940                     append the PMK information */
1941                         ie[ie_len] = 1;
1942                         ie_len++;
1943                         ie[ie_len] = 0; /* PMKID count = 0x0100 */
1944                         ie_len++;
1945                         memcpy(&ie[ie_len],
1946                                &psecuritypriv->PMKIDList[iEntry].PMKID, 16);
1947
1948                         ie_len += 16;
1949                         ie[1] += 18;/* PMKID length = 2+16 */
1950         }
1951         return ie_len;
1952 }
1953
1954 int rtw_restruct_sec_ie23a(struct rtw_adapter *adapter, u8 *in_ie, u8 *out_ie,
1955                            uint in_len)
1956 {
1957         u8 authmode;
1958         uint ielength;
1959         int iEntry;
1960         struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1961         struct security_priv *psecuritypriv = &adapter->securitypriv;
1962         uint ndisauthmode = psecuritypriv->ndisauthtype;
1963         uint ndissecuritytype = psecuritypriv->ndisencryptstatus;
1964
1965         RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
1966                  "+rtw_restruct_sec_ie23a: ndisauthmode=%d ndissecuritytype=%d\n",
1967                  ndisauthmode, ndissecuritytype);
1968
1969         ielength = 0;
1970         if (ndisauthmode == Ndis802_11AuthModeWPA ||
1971             ndisauthmode == Ndis802_11AuthModeWPAPSK)
1972                 authmode = WLAN_EID_VENDOR_SPECIFIC;
1973         if (ndisauthmode == Ndis802_11AuthModeWPA2 ||
1974             ndisauthmode == Ndis802_11AuthModeWPA2PSK)
1975                 authmode = WLAN_EID_RSN;
1976
1977         if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) {
1978                 memcpy(out_ie + ielength, psecuritypriv->wps_ie,
1979                        psecuritypriv->wps_ie_len);
1980
1981                 ielength += psecuritypriv->wps_ie_len;
1982         } else if (authmode == WLAN_EID_VENDOR_SPECIFIC ||
1983                    authmode == WLAN_EID_RSN) {
1984                 /* copy RSN or SSN */
1985                 memcpy(&out_ie[ielength], &psecuritypriv->supplicant_ie[0],
1986                        psecuritypriv->supplicant_ie[1] + 2);
1987                 ielength += psecuritypriv->supplicant_ie[1] + 2;
1988         }
1989
1990         iEntry = SecIsInPMKIDList(adapter, pmlmepriv->assoc_bssid);
1991         if (iEntry < 0)
1992                 return ielength;
1993         else {
1994                 if (authmode == WLAN_EID_RSN)
1995                         ielength = rtw_append_pmkid(adapter, iEntry,
1996                                                     out_ie, ielength);
1997         }
1998
1999         return ielength;
2000 }
2001
2002 void rtw_init_registrypriv_dev_network23a(struct rtw_adapter *adapter)
2003 {
2004         struct registry_priv *pregistrypriv = &adapter->registrypriv;
2005         struct eeprom_priv *peepriv = &adapter->eeprompriv;
2006         struct wlan_bssid_ex    *pdev_network = &pregistrypriv->dev_network;
2007         u8 *myhwaddr = myid(peepriv);
2008
2009         ether_addr_copy(pdev_network->MacAddress, myhwaddr);
2010
2011         memcpy(&pdev_network->Ssid, &pregistrypriv->ssid,
2012                sizeof(struct cfg80211_ssid));
2013
2014         pdev_network->beacon_interval = 100;
2015 }
2016
2017 void rtw_update_registrypriv_dev_network23a(struct rtw_adapter *adapter)
2018 {
2019         int sz = 0;
2020         struct registry_priv *pregistrypriv = &adapter->registrypriv;
2021         struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network;
2022         struct security_priv *psecuritypriv = &adapter->securitypriv;
2023         struct wlan_network *cur_network = &adapter->mlmepriv.cur_network;
2024         /* struct       xmit_priv       *pxmitpriv = &adapter->xmitpriv; */
2025
2026         pdev_network->Privacy =
2027                 (psecuritypriv->dot11PrivacyAlgrthm > 0 ? 1 : 0);
2028
2029         pdev_network->Rssi = 0;
2030
2031         pdev_network->DSConfig = pregistrypriv->channel;
2032         RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
2033                  "pregistrypriv->channel =%d, pdev_network->DSConfig = 0x%x\n",
2034                  pregistrypriv->channel, pdev_network->DSConfig);
2035
2036         if (cur_network->network.ifmode == NL80211_IFTYPE_ADHOC)
2037                 pdev_network->ATIMWindow = 0;
2038
2039         pdev_network->ifmode = cur_network->network.ifmode;
2040
2041         /*  1. Supported rates */
2042         /*  2. IE */
2043
2044         sz = rtw_generate_ie23a(pregistrypriv);
2045
2046         pdev_network->IELength = sz;
2047
2048         pdev_network->Length =
2049                 get_wlan_bssid_ex_sz(pdev_network);
2050
2051         /* notes: translate IELength & Length after assign the
2052            Length to cmdsz in createbss_cmd(); */
2053         /* pdev_network->IELength = cpu_to_le32(sz); */
2054 }
2055
2056 /* the function is at passive_level */
2057 void rtw_joinbss_reset23a(struct rtw_adapter *padapter)
2058 {
2059         u8 threshold;
2060         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2061         struct ht_priv *phtpriv = &pmlmepriv->htpriv;
2062
2063         /* todo: if you want to do something io/reg/hw setting
2064            before join_bss, please add code here */
2065
2066         pmlmepriv->num_FortyMHzIntolerant = 0;
2067
2068         pmlmepriv->num_sta_no_ht = 0;
2069
2070         phtpriv->ampdu_enable = false;/* reset to disabled */
2071
2072         /*  TH = 1 => means that invalidate usb rx aggregation */
2073         /*  TH = 0 => means that validate usb rx aggregation, use init value. */
2074         if (phtpriv->ht_option) {
2075                 if (padapter->registrypriv.wifi_spec == 1)
2076                         threshold = 1;
2077                 else
2078                         threshold = 0;
2079         } else
2080                 threshold = 1;
2081
2082         rtl8723a_set_rxdma_agg_pg_th(padapter, threshold);
2083 }
2084
2085 /* the function is >= passive_level */
2086 bool rtw_restructure_ht_ie23a(struct rtw_adapter *padapter, u8 *in_ie,
2087                               u8 *out_ie, uint in_len, uint *pout_len)
2088 {
2089         u32 out_len;
2090         int max_rx_ampdu_factor;
2091         unsigned char *pframe;
2092         const u8 *p;
2093         struct ieee80211_ht_cap ht_capie;
2094         u8 WMM_IE[7] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
2095         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2096         struct ht_priv *phtpriv = &pmlmepriv->htpriv;
2097
2098         phtpriv->ht_option = false;
2099
2100         p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, in_ie, in_len);
2101
2102         if (p && p[1] > 0) {
2103                 u32 rx_packet_offset, max_recvbuf_sz;
2104
2105                 if (pmlmepriv->qos_option == 0) {
2106                         out_len = *pout_len;
2107                         pframe = rtw_set_ie23a(out_ie + out_len,
2108                                                WLAN_EID_VENDOR_SPECIFIC,
2109                                                sizeof(WMM_IE), WMM_IE,
2110                                                pout_len);
2111
2112                         pmlmepriv->qos_option = 1;
2113                 }
2114
2115                 out_len = *pout_len;
2116
2117                 memset(&ht_capie, 0, sizeof(struct ieee80211_ht_cap));
2118
2119                 ht_capie.cap_info = cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
2120                         IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 |
2121                         IEEE80211_HT_CAP_TX_STBC | IEEE80211_HT_CAP_DSSSCCK40);
2122
2123                 GetHalDefVar8192CUsb(padapter, HAL_DEF_RX_PACKET_OFFSET,
2124                                      &rx_packet_offset);
2125                 GetHalDefVar8192CUsb(padapter, HAL_DEF_MAX_RECVBUF_SZ,
2126                                      &max_recvbuf_sz);
2127
2128                 GetHalDefVar8192CUsb(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR,
2129                                      &max_rx_ampdu_factor);
2130                 ht_capie.ampdu_params_info = max_rx_ampdu_factor & 0x03;
2131
2132                 if (padapter->securitypriv.dot11PrivacyAlgrthm ==
2133                     WLAN_CIPHER_SUITE_CCMP)
2134                         ht_capie.ampdu_params_info |=
2135                                 (IEEE80211_HT_AMPDU_PARM_DENSITY& (0x07 << 2));
2136                 else
2137                         ht_capie.ampdu_params_info |=
2138                                 (IEEE80211_HT_AMPDU_PARM_DENSITY & 0x00);
2139
2140                 pframe = rtw_set_ie23a(out_ie + out_len, WLAN_EID_HT_CAPABILITY,
2141                                     sizeof(struct ieee80211_ht_cap),
2142                                     (unsigned char *)&ht_capie, pout_len);
2143
2144                 phtpriv->ht_option = true;
2145
2146                 p = cfg80211_find_ie(WLAN_EID_HT_OPERATION, in_ie, in_len);
2147                 if (p && (p[1] == sizeof(struct ieee80211_ht_operation))) {
2148                         out_len = *pout_len;
2149                         pframe = rtw_set_ie23a(out_ie + out_len,
2150                                                WLAN_EID_HT_OPERATION,
2151                                                p[1], p + 2 , pout_len);
2152                 }
2153         }
2154
2155         return phtpriv->ht_option;
2156 }
2157
2158 /* the function is > passive_level (in critical_section) */
2159 void rtw_update_ht_cap23a(struct rtw_adapter *padapter, u8 *pie, uint ie_len)
2160 {
2161         u8 max_ampdu_sz;
2162         const u8 *p;
2163         struct ieee80211_ht_cap *pht_capie;
2164         struct ieee80211_ht_operation *pht_addtinfo;
2165         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2166         struct ht_priv *phtpriv = &pmlmepriv->htpriv;
2167         struct registry_priv *pregistrypriv = &padapter->registrypriv;
2168         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2169         struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2170
2171         if (!phtpriv->ht_option)
2172                 return;
2173
2174         if ((!pmlmeinfo->HT_info_enable) || (!pmlmeinfo->HT_caps_enable))
2175                 return;
2176
2177         DBG_8723A("+rtw_update_ht_cap23a()\n");
2178
2179         /* maybe needs check if ap supports rx ampdu. */
2180         if (!phtpriv->ampdu_enable && pregistrypriv->ampdu_enable == 1) {
2181                 if (pregistrypriv->wifi_spec == 1)
2182                         phtpriv->ampdu_enable = false;
2183                 else
2184                         phtpriv->ampdu_enable = true;
2185         } else if (pregistrypriv->ampdu_enable == 2)
2186                 phtpriv->ampdu_enable = true;
2187
2188         /* check Max Rx A-MPDU Size */
2189         p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, pie, ie_len);
2190
2191         if (p && p[1] > 0) {
2192                 pht_capie = (struct ieee80211_ht_cap *)(p + 2);
2193                 max_ampdu_sz = pht_capie->ampdu_params_info &
2194                         IEEE80211_HT_AMPDU_PARM_FACTOR;
2195                 /*  max_ampdu_sz (kbytes); */
2196                 max_ampdu_sz = 1 << (max_ampdu_sz + 3);
2197
2198                 phtpriv->rx_ampdu_maxlen = max_ampdu_sz;
2199         }
2200
2201         p = cfg80211_find_ie(WLAN_EID_HT_OPERATION, pie, ie_len);
2202         if (p && p[1] > 0) {
2203                 pht_addtinfo = (struct ieee80211_ht_operation *)(p + 2);
2204                 /* todo: */
2205         }
2206
2207         /* update cur_bwmode & cur_ch_offset */
2208         if (pregistrypriv->cbw40_enable &&
2209             pmlmeinfo->ht_cap.cap_info &
2210             cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH_20_40) &&
2211             pmlmeinfo->HT_info.ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY) {
2212                 int i;
2213                 u8 rf_type;
2214
2215                 rf_type = rtl8723a_get_rf_type(padapter);
2216
2217                 /* update the MCS rates */
2218                 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
2219                         if (rf_type == RF_1T1R || rf_type == RF_1T2R)
2220                                 pmlmeinfo->ht_cap.mcs.rx_mask[i] &=
2221                                         MCS_rate_1R23A[i];
2222                         else
2223                                 pmlmeinfo->ht_cap.mcs.rx_mask[i] &=
2224                                         MCS_rate_2R23A[i];
2225                 }
2226                 /* switch to the 40M Hz mode according to the AP */
2227                 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
2228                 switch (pmlmeinfo->HT_info.ht_param &
2229                         IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
2230                 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
2231                         pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
2232                         break;
2233
2234                 case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
2235                         pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
2236                         break;
2237
2238                 default:
2239                         pmlmeext->cur_ch_offset =
2240                                 HAL_PRIME_CHNL_OFFSET_DONT_CARE;
2241                         break;
2242                 }
2243         }
2244
2245         /*  */
2246         /*  Config SM Power Save setting */
2247         /*  */
2248         pmlmeinfo->SM_PS =
2249                 (le16_to_cpu(pmlmeinfo->ht_cap.cap_info) &
2250                  IEEE80211_HT_CAP_SM_PS) >> IEEE80211_HT_CAP_SM_PS_SHIFT;
2251         if (pmlmeinfo->SM_PS == WLAN_HT_CAP_SM_PS_STATIC)
2252                 DBG_8723A("%s(): WLAN_HT_CAP_SM_PS_STATIC\n", __func__);
2253
2254         /*  */
2255         /*  Config current HT Protection mode. */
2256         /*  */
2257         pmlmeinfo->HT_protection =
2258                 le16_to_cpu(pmlmeinfo->HT_info.operation_mode) &
2259                 IEEE80211_HT_OP_MODE_PROTECTION;
2260 }
2261
2262 void rtw_issue_addbareq_cmd23a(struct rtw_adapter *padapter,
2263                                struct xmit_frame *pxmitframe)
2264 {
2265         u8 issued;
2266         int priority;
2267         struct sta_info *psta;
2268         struct ht_priv  *phtpriv;
2269         struct pkt_attrib *pattrib = &pxmitframe->attrib;
2270         s32 bmcst = is_multicast_ether_addr(pattrib->ra);
2271
2272         if (bmcst || padapter->mlmepriv.LinkDetectInfo.NumTxOkInPeriod < 100)
2273                 return;
2274
2275         priority = pattrib->priority;
2276
2277         if (pattrib->psta)
2278                 psta = pattrib->psta;
2279         else {
2280                 DBG_8723A("%s, call rtw_get_stainfo23a()\n", __func__);
2281                 psta = rtw_get_stainfo23a(&padapter->stapriv, pattrib->ra);
2282         }
2283
2284         if (!psta) {
2285                 DBG_8723A("%s, psta == NUL\n", __func__);
2286                 return;
2287         }
2288
2289         if (!(psta->state &_FW_LINKED)) {
2290                 DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n",
2291                           __func__, psta->state);
2292                 return;
2293         }
2294
2295         phtpriv = &psta->htpriv;
2296
2297         if (phtpriv->ht_option && phtpriv->ampdu_enable) {
2298                 issued = (phtpriv->agg_enable_bitmap>>priority)&0x1;
2299                 issued |= (phtpriv->candidate_tid_bitmap>>priority)&0x1;
2300
2301                 if (issued == 0) {
2302                         DBG_8723A("rtw_issue_addbareq_cmd23a, p =%d\n",
2303                                   priority);
2304                         psta->htpriv.candidate_tid_bitmap |= BIT(priority);
2305                         rtw_addbareq_cmd23a(padapter, (u8) priority,
2306                                             pattrib->ra);
2307                 }
2308         }
2309 }
2310
2311 int rtw_linked_check(struct rtw_adapter *padapter)
2312 {
2313         if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) ||
2314             check_fwstate(&padapter->mlmepriv,
2315                           WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE)) {
2316                 if (padapter->stapriv.asoc_sta_count > 2)
2317                         return true;
2318         } else {        /* Station mode */
2319                 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED))
2320                         return true;
2321         }
2322         return false;
2323 }