OSDN Git Service

Only ODM_SUPPORTED_TYPE == ODM_CE is compiled on Linux
[android-x86/external-modules-rtl8723au.git] / 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  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17  *
18  *
19  ******************************************************************************/
20 #define _RTW_MLME_C_
21
22 #include <drv_conf.h>
23 #include <osdep_service.h>
24 #include <drv_types.h>
25 #include <recv_osdep.h>
26 #include <xmit_osdep.h>
27 #include <hal_intf.h>
28 #include <mlme_osdep.h>
29 #include <sta_info.h>
30 #include <linux/ieee80211.h>
31 #include <wifi.h>
32 #include <wlan_bssdef.h>
33 #include <rtw_ioctl_set.h>
34
35 extern void indicate_wx_scan_complete_event(_adapter *padapter);
36 extern u8 rtw_do_join(_adapter * padapter);
37
38 #ifdef CONFIG_DISABLE_MCS13TO15
39 extern unsigned char    MCS_rate_2R_MCS13TO15_OFF[16];
40 extern unsigned char    MCS_rate_2R[16];
41 #else /* CONFIG_DISABLE_MCS13TO15 */
42 extern unsigned char    MCS_rate_2R[16];
43 #endif /* CONFIG_DISABLE_MCS13TO15 */
44 extern unsigned char    MCS_rate_1R[16];
45
46 int     _rtw_init_mlme_priv (_adapter* padapter)
47 {
48         int     i;
49         u8      *pbuf;
50         struct wlan_network     *pnetwork;
51         struct mlme_priv                *pmlmepriv = &padapter->mlmepriv;
52         int     res = _SUCCESS;
53
54 _func_enter_;
55
56         /*  We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc(). */
57         /* memset((u8 *)pmlmepriv, 0, sizeof(struct mlme_priv)); */
58
59         pmlmepriv->nic_hdl = (u8 *)padapter;
60
61         pmlmepriv->pscanned = NULL;
62         pmlmepriv->fw_state = 0;
63         pmlmepriv->cur_network.network.InfrastructureMode = Ndis802_11AutoUnknown;
64         pmlmepriv->scan_mode=SCAN_ACTIVE;/*  1: active, 0: pasive. Maybe someday we should rename this varable to "active_mode" (Jeff) */
65
66         spin_lock_init(&(pmlmepriv->lock));
67         _rtw_init_queue(&(pmlmepriv->free_bss_pool));
68         _rtw_init_queue(&(pmlmepriv->scanned_queue));
69
70         set_scanned_network_val(pmlmepriv, 0);
71
72         memset(&pmlmepriv->assoc_ssid,0,sizeof(NDIS_802_11_SSID));
73
74         pbuf = rtw_zvmalloc(MAX_BSS_CNT * (sizeof(struct wlan_network)));
75
76         if (pbuf == NULL){
77                 res=_FAIL;
78                 goto exit;
79         }
80         pmlmepriv->free_bss_buf = pbuf;
81
82         pnetwork = (struct wlan_network *)pbuf;
83
84         for(i = 0; i < MAX_BSS_CNT; i++)
85         {
86                 INIT_LIST_HEAD(&(pnetwork->list));
87
88                 list_add_tail(&(pnetwork->list), &(pmlmepriv->free_bss_pool.queue));
89
90                 pnetwork++;
91         }
92
93         /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */
94
95         rtw_clear_scan_deny(padapter);
96
97         #ifdef CONFIG_FTP_PROTECT
98         pmlmepriv->ftp_lock_flag = 0;
99         #endif /* CONFIG_FTP_PROTECT */
100
101         rtw_init_mlme_timer(padapter);
102
103 exit:
104
105 _func_exit_;
106
107         return res;
108 }
109
110 static void rtw_free_mlme_ie_data(u8 **ppie, u32 *plen)
111 {
112         if(*ppie)
113         {
114                 rtw_mfree(*ppie, *plen);
115                 *plen = 0;
116                 *ppie=NULL;
117         }
118 }
119
120 void rtw_free_mlme_priv_ie_data(struct mlme_priv *pmlmepriv)
121 {
122 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
123         rtw_buf_free(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len);
124         rtw_buf_free(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len);
125         rtw_free_mlme_ie_data(&pmlmepriv->wps_beacon_ie, &pmlmepriv->wps_beacon_ie_len);
126         rtw_free_mlme_ie_data(&pmlmepriv->wps_probe_req_ie, &pmlmepriv->wps_probe_req_ie_len);
127         rtw_free_mlme_ie_data(&pmlmepriv->wps_probe_resp_ie, &pmlmepriv->wps_probe_resp_ie_len);
128         rtw_free_mlme_ie_data(&pmlmepriv->wps_assoc_resp_ie, &pmlmepriv->wps_assoc_resp_ie_len);
129
130         rtw_free_mlme_ie_data(&pmlmepriv->p2p_beacon_ie, &pmlmepriv->p2p_beacon_ie_len);
131         rtw_free_mlme_ie_data(&pmlmepriv->p2p_probe_req_ie, &pmlmepriv->p2p_probe_req_ie_len);
132         rtw_free_mlme_ie_data(&pmlmepriv->p2p_probe_resp_ie, &pmlmepriv->p2p_probe_resp_ie_len);
133         rtw_free_mlme_ie_data(&pmlmepriv->p2p_go_probe_resp_ie, &pmlmepriv->p2p_go_probe_resp_ie_len);
134         rtw_free_mlme_ie_data(&pmlmepriv->p2p_assoc_req_ie, &pmlmepriv->p2p_assoc_req_ie_len);
135 #endif
136
137 #if defined(CONFIG_WFD) && defined(CONFIG_IOCTL_CFG80211)
138         rtw_free_mlme_ie_data(&pmlmepriv->wfd_beacon_ie, &pmlmepriv->wfd_beacon_ie_len);
139         rtw_free_mlme_ie_data(&pmlmepriv->wfd_probe_req_ie, &pmlmepriv->wfd_probe_req_ie_len);
140         rtw_free_mlme_ie_data(&pmlmepriv->wfd_probe_resp_ie, &pmlmepriv->wfd_probe_resp_ie_len);
141         rtw_free_mlme_ie_data(&pmlmepriv->wfd_go_probe_resp_ie, &pmlmepriv->wfd_go_probe_resp_ie_len);
142         rtw_free_mlme_ie_data(&pmlmepriv->wfd_assoc_req_ie, &pmlmepriv->wfd_assoc_req_ie_len);
143 #endif
144 }
145
146 void _rtw_free_mlme_priv (struct mlme_priv *pmlmepriv)
147 {
148 _func_enter_;
149
150         rtw_free_mlme_priv_ie_data(pmlmepriv);
151
152         if(pmlmepriv){
153                 if (pmlmepriv->free_bss_buf) {
154                         rtw_vmfree(pmlmepriv->free_bss_buf, MAX_BSS_CNT * sizeof(struct wlan_network));
155                 }
156         }
157 _func_exit_;
158 }
159
160 int     _rtw_enqueue_network(_queue *queue, struct wlan_network *pnetwork)
161 {
162 _func_enter_;
163
164         if (pnetwork == NULL)
165                 goto exit;
166
167         spin_lock_bh(&queue->lock);
168
169         list_add_tail(&pnetwork->list, &queue->queue);
170
171         spin_unlock_bh(&queue->lock);
172
173 exit:
174
175 _func_exit_;
176
177         return _SUCCESS;
178 }
179
180 struct  wlan_network *_rtw_dequeue_network(_queue *queue)
181 {
182         struct wlan_network *pnetwork;
183
184 _func_enter_;
185
186         spin_lock_bh(&queue->lock);
187
188         if (_rtw_queue_empty(queue) == _TRUE)
189
190                 pnetwork = NULL;
191
192         else
193         {
194                 pnetwork = LIST_CONTAINOR(get_next(&queue->queue), struct wlan_network, list);
195
196                 list_del_init(&(pnetwork->list));
197         }
198
199         spin_unlock_bh(&queue->lock);
200
201 _func_exit_;
202
203         return pnetwork;
204 }
205
206 struct  wlan_network *_rtw_alloc_network(struct mlme_priv *pmlmepriv )/* _queue *free_queue) */
207 {
208         struct  wlan_network    *pnetwork;
209         _queue *free_queue = &pmlmepriv->free_bss_pool;
210         struct list_head* plist = NULL;
211
212 _func_enter_;
213
214         spin_lock_bh(&free_queue->lock);
215
216         if (_rtw_queue_empty(free_queue) == _TRUE) {
217                 pnetwork=NULL;
218                 goto exit;
219         }
220         plist = get_next(&(free_queue->queue));
221
222         pnetwork = LIST_CONTAINOR(plist , struct wlan_network, list);
223
224         list_del_init(&pnetwork->list);
225
226         RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("_rtw_alloc_network: ptr=%p\n", plist));
227         pnetwork->network_type = 0;
228         pnetwork->fixed = _FALSE;
229         pnetwork->last_scanned = rtw_get_current_time();
230         pnetwork->aid=0;
231         pnetwork->join_res=0;
232
233         pmlmepriv->num_of_scanned ++;
234
235 exit:
236         spin_unlock_bh(&free_queue->lock);
237
238 _func_exit_;
239
240         return pnetwork;
241 }
242
243 void _rtw_free_network(struct   mlme_priv *pmlmepriv ,struct wlan_network *pnetwork, u8 isfreeall)
244 {
245         u32 curr_time, delta_time;
246         u32 lifetime = SCANQUEUE_LIFETIME;
247         _queue *free_queue = &(pmlmepriv->free_bss_pool);
248
249 _func_enter_;
250
251         if (pnetwork == NULL)
252                 goto exit;
253
254         if (pnetwork->fixed == _TRUE)
255                 goto exit;
256
257         curr_time = rtw_get_current_time();
258
259         if ( (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)==_TRUE ) ||
260                 (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)==_TRUE ) )
261                 lifetime = 1;
262
263         if(!isfreeall)
264         {
265                 delta_time = (curr_time -pnetwork->last_scanned)/HZ;
266
267                 if(delta_time < lifetime)/*  unit:sec */
268                 {
269                         goto exit;
270                 }
271         }
272
273         spin_lock_bh(&free_queue->lock);
274
275         list_del_init(&(pnetwork->list));
276
277         list_add_tail(&(pnetwork->list),&(free_queue->queue));
278
279         pmlmepriv->num_of_scanned --;
280
281         /* DBG_8723A("_rtw_free_network:SSID=%s\n", pnetwork->network.Ssid.Ssid); */
282
283         spin_unlock_bh(&free_queue->lock);
284
285 exit:
286
287 _func_exit_;
288 }
289
290 void _rtw_free_network_nolock(struct    mlme_priv *pmlmepriv, struct wlan_network *pnetwork)
291 {
292
293         _queue *free_queue = &(pmlmepriv->free_bss_pool);
294
295 _func_enter_;
296
297         if (pnetwork == NULL)
298                 goto exit;
299
300         if (pnetwork->fixed == _TRUE)
301                 goto exit;
302
303         /* spin_lock_irqsave(&free_queue->lock); */
304
305         list_del_init(&(pnetwork->list));
306
307         list_add_tail(&(pnetwork->list), get_list_head(free_queue));
308
309         pmlmepriv->num_of_scanned --;
310
311         /* spin_unlock_irqrestore(&free_queue->lock); */
312
313 exit:
314
315 _func_exit_;
316 }
317
318 /*
319         return the wlan_network with the matching addr
320
321         Shall be calle under atomic context... to avoid possible racing condition...
322 */
323 struct wlan_network *_rtw_find_network(_queue *scanned_queue, u8 *addr)
324 {
325         struct list_head        *phead, *plist;
326         struct  wlan_network *pnetwork = NULL;
327         u8 zero_addr[ETH_ALEN] = {0,0,0,0,0,0};
328
329 _func_enter_;
330
331         if (!memcmp(zero_addr, addr, ETH_ALEN)){
332                 pnetwork=NULL;
333                 goto exit;
334         }
335
336         /* spin_lock_bh(&scanned_queue->lock); */
337
338         phead = get_list_head(scanned_queue);
339         plist = get_next(phead);
340
341         while (plist != phead)
342        {
343                 pnetwork = LIST_CONTAINOR(plist, struct wlan_network ,list);
344
345                 if (!memcmp(addr, pnetwork->network.MacAddress, ETH_ALEN))
346                         break;
347
348                 plist = get_next(plist);
349         }
350
351         if(plist == phead)
352                 pnetwork = NULL;
353
354         /* spin_unlock_bh(&scanned_queue->lock); */
355
356 exit:
357
358 _func_exit_;
359
360         return pnetwork;
361 }
362
363 void _rtw_free_network_queue(_adapter *padapter, u8 isfreeall)
364 {
365         struct list_head *phead, *plist;
366         struct wlan_network *pnetwork;
367         struct mlme_priv* pmlmepriv = &padapter->mlmepriv;
368         _queue *scanned_queue = &pmlmepriv->scanned_queue;
369
370 _func_enter_;
371
372         spin_lock_bh(&scanned_queue->lock);
373
374         phead = get_list_head(scanned_queue);
375         plist = get_next(phead);
376
377         while (rtw_end_of_queue_search(phead, plist) == _FALSE)
378         {
379
380                 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
381
382                 plist = get_next(plist);
383
384                 _rtw_free_network(pmlmepriv,pnetwork, isfreeall);
385
386         }
387
388         spin_unlock_bh(&scanned_queue->lock);
389
390 _func_exit_;
391 }
392
393 int rtw_if_up(_adapter *padapter)       {
394
395         int res;
396 _func_enter_;
397
398         if( padapter->bDriverStopped || padapter->bSurpriseRemoved ||
399                 (check_fwstate(&padapter->mlmepriv, _FW_LINKED)== _FALSE)){
400                 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_if_up:bDriverStopped(%d) OR bSurpriseRemoved(%d)", padapter->bDriverStopped, padapter->bSurpriseRemoved));
401                 res=_FALSE;
402         }
403         else
404                 res=  _TRUE;
405
406 _func_exit_;
407         return res;
408 }
409
410 void rtw_generate_random_ibss(u8* pibss)
411 {
412         u32     curtime = rtw_get_current_time();
413
414 _func_enter_;
415         pibss[0] = 0x02;  /* in ad-hoc mode bit1 must set to 1 */
416         pibss[1] = 0x11;
417         pibss[2] = 0x87;
418         pibss[3] = (u8)(curtime & 0xff) ;/* p[0]; */
419         pibss[4] = (u8)((curtime>>8) & 0xff) ;/* p[1]; */
420         pibss[5] = (u8)((curtime>>16) & 0xff) ;/* p[2]; */
421 _func_exit_;
422         return;
423 }
424
425 u8 *rtw_get_capability_from_ie(u8 *ie)
426 {
427         return (ie + 8 + 2);
428 }
429
430 u16 rtw_get_capability(WLAN_BSSID_EX *bss)
431 {
432         u16     val;
433 _func_enter_;
434
435         memcpy((u8 *)&val, rtw_get_capability_from_ie(bss->IEs), 2);
436
437 _func_exit_;
438         return le16_to_cpu(val);
439 }
440
441 u8 *rtw_get_timestampe_from_ie(u8 *ie)
442 {
443         return (ie + 0);
444 }
445
446 u8 *rtw_get_beacon_interval_from_ie(u8 *ie)
447 {
448         return (ie + 8);
449 }
450
451 int     rtw_init_mlme_priv (_adapter *padapter)/* struct        mlme_priv *pmlmepriv) */
452 {
453         int     res;
454 _func_enter_;
455         res = _rtw_init_mlme_priv(padapter);/*  (pmlmepriv); */
456 _func_exit_;
457         return res;
458 }
459
460 void rtw_free_mlme_priv (struct mlme_priv *pmlmepriv)
461 {
462 _func_enter_;
463         RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("rtw_free_mlme_priv\n"));
464         _rtw_free_mlme_priv (pmlmepriv);
465 _func_exit_;
466 }
467
468 int     rtw_enqueue_network(_queue *queue, struct wlan_network *pnetwork);
469 int     rtw_enqueue_network(_queue *queue, struct wlan_network *pnetwork)
470 {
471         int     res;
472 _func_enter_;
473         res = _rtw_enqueue_network(queue, pnetwork);
474 _func_exit_;
475         return res;
476 }
477
478 static struct   wlan_network *rtw_dequeue_network(_queue *queue)
479 {
480         struct wlan_network *pnetwork;
481 _func_enter_;
482         pnetwork = _rtw_dequeue_network(queue);
483 _func_exit_;
484         return pnetwork;
485 }
486
487 struct  wlan_network *rtw_alloc_network(struct  mlme_priv *pmlmepriv );
488 struct  wlan_network *rtw_alloc_network(struct  mlme_priv *pmlmepriv )/* _queue *free_queue) */
489 {
490         struct  wlan_network    *pnetwork;
491 _func_enter_;
492         pnetwork = _rtw_alloc_network(pmlmepriv);
493 _func_exit_;
494         return pnetwork;
495 }
496
497 void rtw_free_network(struct mlme_priv *pmlmepriv, struct       wlan_network *pnetwork, u8 is_freeall);
498 void rtw_free_network(struct mlme_priv *pmlmepriv, struct       wlan_network *pnetwork, u8 is_freeall)/* struct wlan_network *pnetwork, _queue  *free_queue) */
499 {
500 _func_enter_;
501         RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("rtw_free_network==> ssid = %s \n\n" , pnetwork->network.Ssid.Ssid));
502         _rtw_free_network(pmlmepriv, pnetwork, is_freeall);
503 _func_exit_;
504 }
505
506 void rtw_free_network_nolock(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork );
507 void rtw_free_network_nolock(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork )
508 {
509 _func_enter_;
510         /* RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("rtw_free_network==> ssid = %s \n\n" , pnetwork->network.Ssid.Ssid)); */
511         _rtw_free_network_nolock(pmlmepriv, pnetwork);
512 _func_exit_;
513 }
514
515 void rtw_free_network_queue(_adapter* dev, u8 isfreeall)
516 {
517 _func_enter_;
518         _rtw_free_network_queue(dev, isfreeall);
519 _func_exit_;
520 }
521
522 /*
523         return the wlan_network with the matching addr
524
525         Shall be calle under atomic context... to avoid possible racing condition...
526 */
527 struct  wlan_network *rtw_find_network(_queue *scanned_queue, u8 *addr)
528 {
529         struct  wlan_network *pnetwork = _rtw_find_network(scanned_queue, addr);
530
531         return pnetwork;
532 }
533
534 int rtw_is_same_ibss(_adapter *adapter, struct wlan_network *pnetwork)
535 {
536         int ret=_TRUE;
537         struct security_priv *psecuritypriv = &adapter->securitypriv;
538
539         if ( (psecuritypriv->dot11PrivacyAlgrthm != _NO_PRIVACY_ ) &&
540                     ( pnetwork->network.Privacy == 0 ) )
541         {
542                 ret=_FALSE;
543         }
544         else if((psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_ ) &&
545                  ( pnetwork->network.Privacy == 1 ) )
546         {
547                 ret=_FALSE;
548         }
549         else
550         {
551                 ret=_TRUE;
552         }
553
554         return ret;
555 }
556
557 inline int is_same_ess(WLAN_BSSID_EX *a, WLAN_BSSID_EX *b);
558 inline int is_same_ess(WLAN_BSSID_EX *a, WLAN_BSSID_EX *b)
559 {
560         /* RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("(%s,%d)(%s,%d)\n", */
561         /*              a->Ssid.Ssid,a->Ssid.SsidLength,b->Ssid.Ssid,b->Ssid.SsidLength)); */
562         return (a->Ssid.SsidLength == b->Ssid.SsidLength) &&
563                 !memcmp(a->Ssid.Ssid, b->Ssid.Ssid, a->Ssid.SsidLength);
564 }
565
566 int is_same_network(WLAN_BSSID_EX *src, WLAN_BSSID_EX *dst)
567 {
568          u16 s_cap, d_cap;
569
570 _func_enter_;
571
572         memcpy((u8 *)&s_cap, rtw_get_capability_from_ie(src->IEs), 2);
573         memcpy((u8 *)&d_cap, rtw_get_capability_from_ie(dst->IEs), 2);
574
575         s_cap = le16_to_cpu(s_cap);
576         d_cap = le16_to_cpu(d_cap);
577
578 _func_exit_;
579
580         return ((src->Ssid.SsidLength == dst->Ssid.SsidLength) &&
581                 /*      (src->Configuration.DSConfig == dst->Configuration.DSConfig) && */
582                 ((!memcmp(src->MacAddress, dst->MacAddress, ETH_ALEN))) &&
583                 ((!memcmp(src->Ssid.Ssid, dst->Ssid.Ssid, src->Ssid.SsidLength))) &&
584                 ((s_cap & WLAN_CAPABILITY_IBSS) ==
585                  (d_cap & WLAN_CAPABILITY_IBSS)) &&
586                 ((s_cap & WLAN_CAPABILITY_ESS) ==
587                  (d_cap & WLAN_CAPABILITY_ESS)));
588 }
589
590 struct  wlan_network    * rtw_get_oldest_wlan_network(_queue *scanned_queue)
591 {
592         struct list_head        *plist, *phead;
593
594         struct  wlan_network    *pwlan = NULL;
595         struct  wlan_network    *oldest = NULL;
596 _func_enter_;
597         phead = get_list_head(scanned_queue);
598
599         plist = get_next(phead);
600
601         while(1)
602         {
603
604                 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
605                         break;
606
607                 pwlan= LIST_CONTAINOR(plist, struct wlan_network, list);
608
609                 if(pwlan->fixed!=_TRUE)
610                 {
611                         if (oldest == NULL ||time_after(oldest->last_scanned, pwlan->last_scanned))
612                                 oldest = pwlan;
613                 }
614
615                 plist = get_next(plist);
616         }
617 _func_exit_;
618         return oldest;
619 }
620
621 void update_network(WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src,
622         _adapter * padapter, bool update_ie)
623 {
624         u8 ss_ori = dst->PhyInfo.SignalStrength;
625         u8 sq_ori = dst->PhyInfo.SignalQuality;
626         long rssi_ori = dst->Rssi;
627
628         u8 ss_smp = src->PhyInfo.SignalStrength;
629         u8 sq_smp = src->PhyInfo.SignalQuality;
630         long rssi_smp = src->Rssi;
631
632         u8 ss_final;
633         u8 sq_final;
634         long rssi_final;
635
636 _func_enter_;
637
638 #ifdef CONFIG_ANTENNA_DIVERSITY
639         rtw_hal_antdiv_rssi_compared(padapter, dst, src); /* this will update src.Rssi, need consider again */
640 #endif
641
642         #if defined(DBG_RX_SIGNAL_DISPLAY_PROCESSING) && 1
643         if(strcmp(dst->Ssid.Ssid, DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) == 0) {
644                 DBG_8723A("%s %s("MAC_FMT", ch%u) ss_ori:%3u, sq_ori:%3u, rssi_ori:%3ld, ss_smp:%3u, sq_smp:%3u, rssi_smp:%3ld\n"
645                         , __FUNCTION__
646                         , src->Ssid.Ssid, MAC_ARG(src->MacAddress), src->Configuration.DSConfig
647                         ,ss_ori, sq_ori, rssi_ori
648                         ,ss_smp, sq_smp, rssi_smp
649                 );
650         }
651         #endif
652
653         /* The rule below is 1/5 for sample value, 4/5 for history value */
654         if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) && is_same_network(&(padapter->mlmepriv.cur_network.network), src)) {
655                 /* Take the recvpriv's value for the connected AP*/
656                 ss_final = padapter->recvpriv.signal_strength;
657                 sq_final = padapter->recvpriv.signal_qual;
658                 /* the rssi value here is undecorated, and will be used for antenna diversity */
659                 if(sq_smp != 101) /* from the right channel */
660                         rssi_final = (src->Rssi+dst->Rssi*4)/5;
661                 else
662                         rssi_final = rssi_ori;
663         }
664         else {
665                 if(sq_smp != 101) { /* from the right channel */
666                         ss_final = ((u32)(src->PhyInfo.SignalStrength)+(u32)(dst->PhyInfo.SignalStrength)*4)/5;
667                         sq_final = ((u32)(src->PhyInfo.SignalQuality)+(u32)(dst->PhyInfo.SignalQuality)*4)/5;
668                         rssi_final = (src->Rssi+dst->Rssi*4)/5;
669                 } else {
670                         /* bss info not receving from the right channel, use the original RX signal infos */
671                         ss_final = dst->PhyInfo.SignalStrength;
672                         sq_final = dst->PhyInfo.SignalQuality;
673                         rssi_final = dst->Rssi;
674                 }
675
676         }
677
678         if (update_ie)
679                 memcpy((u8 *)dst, (u8 *)src, get_WLAN_BSSID_EX_sz(src));
680
681         dst->PhyInfo.SignalStrength = ss_final;
682         dst->PhyInfo.SignalQuality = sq_final;
683         dst->Rssi = rssi_final;
684
685         #if defined(DBG_RX_SIGNAL_DISPLAY_PROCESSING) && 1
686         if(strcmp(dst->Ssid.Ssid, DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) == 0) {
687                 DBG_8723A("%s %s("MAC_FMT"), SignalStrength:%u, SignalQuality:%u, RawRSSI:%ld\n"
688                         , __FUNCTION__
689                         , dst->Ssid.Ssid, MAC_ARG(dst->MacAddress), dst->PhyInfo.SignalStrength, dst->PhyInfo.SignalQuality, dst->Rssi);
690         }
691         #endif
692
693 _func_exit_;
694 }
695
696 static void update_current_network(_adapter *adapter, WLAN_BSSID_EX *pnetwork)
697 {
698         struct  mlme_priv       *pmlmepriv = &(adapter->mlmepriv);
699
700 _func_enter_;
701
702         if ( (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) && (is_same_network(&(pmlmepriv->cur_network.network), pnetwork)))
703         {
704                 /* RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,"Same Network\n"); */
705
706                 /* if(pmlmepriv->cur_network.network.IELength<= pnetwork->IELength) */
707                 {
708                         update_network(&(pmlmepriv->cur_network.network), pnetwork,adapter, _TRUE);
709                         rtw_update_protection(adapter, (pmlmepriv->cur_network.network.IEs) + sizeof (NDIS_802_11_FIXED_IEs),
710                                                                         pmlmepriv->cur_network.network.IELength);
711                 }
712         }
713
714 _func_exit_;
715 }
716
717 /*
718
719 Caller must hold pmlmepriv->lock first.
720
721 */
722 void rtw_update_scanned_network(_adapter *adapter, WLAN_BSSID_EX *target)
723 {
724         struct list_head        *plist, *phead;
725         u32     bssid_ex_sz;
726         struct mlme_priv        *pmlmepriv = &(adapter->mlmepriv);
727         _queue  *queue  = &(pmlmepriv->scanned_queue);
728         struct wlan_network     *pnetwork = NULL;
729         struct wlan_network     *oldest = NULL;
730
731 _func_enter_;
732
733         spin_lock_bh(&queue->lock);
734         phead = get_list_head(queue);
735         plist = get_next(phead);
736
737         while(1)
738         {
739                 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
740                         break;
741
742                 pnetwork        = LIST_CONTAINOR(plist, struct wlan_network, list);
743
744                 if (is_same_network(&(pnetwork->network), target))
745                         break;
746
747                 if ((oldest == ((struct wlan_network *)0)) ||
748                 time_after(oldest->last_scanned, pnetwork->last_scanned))
749                         oldest = pnetwork;
750
751                 plist = get_next(plist);
752
753         }
754
755         /* If we didn't find a match, then get a new network slot to initialize
756          * with this beacon's information */
757         if (rtw_end_of_queue_search(phead,plist)== _TRUE) {
758
759                 if (_rtw_queue_empty(&(pmlmepriv->free_bss_pool)) == _TRUE) {
760                         /* If there are no more slots, expire the oldest */
761                         /* list_del_init(&oldest->list); */
762                         pnetwork = oldest;
763
764 #ifdef CONFIG_ANTENNA_DIVERSITY
765                         rtw_hal_get_def_var(adapter, HAL_DEF_CURRENT_ANTENNA, &(target->PhyInfo.Optimum_antenna));
766 #endif
767                         memcpy(&(pnetwork->network), target,  get_WLAN_BSSID_EX_sz(target));
768                         /* pnetwork->last_scanned = rtw_get_current_time(); */
769                         /*  variable initialize */
770                         pnetwork->fixed = _FALSE;
771                         pnetwork->last_scanned = rtw_get_current_time();
772
773                         pnetwork->network_type = 0;
774                         pnetwork->aid=0;
775                         pnetwork->join_res=0;
776
777                         /* bss info not receving from the right channel */
778                         if (pnetwork->network.PhyInfo.SignalQuality == 101)
779                                 pnetwork->network.PhyInfo.SignalQuality = 0;
780                 }
781                 else {
782                         /* Otherwise just pull from the free list */
783
784                         pnetwork = rtw_alloc_network(pmlmepriv); /*  will update scan_time */
785
786                         if(pnetwork==NULL){
787                                 RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("\n\n\nsomething wrong here\n\n\n"));
788                                 goto exit;
789                         }
790
791                         bssid_ex_sz = get_WLAN_BSSID_EX_sz(target);
792                         target->Length = bssid_ex_sz;
793 #ifdef CONFIG_ANTENNA_DIVERSITY
794                         /* target->PhyInfo.Optimum_antenna = pHalData->CurAntenna; */
795                         rtw_hal_get_def_var(adapter, HAL_DEF_CURRENT_ANTENNA, &(target->PhyInfo.Optimum_antenna));
796 #endif
797                         memcpy(&(pnetwork->network), target, bssid_ex_sz );
798
799                         pnetwork->last_scanned = rtw_get_current_time();
800
801                         /* bss info not receving from the right channel */
802                         if (pnetwork->network.PhyInfo.SignalQuality == 101)
803                                 pnetwork->network.PhyInfo.SignalQuality = 0;
804
805                         list_add_tail(&(pnetwork->list),&(queue->queue));
806
807                 }
808         }
809         else {
810                 /* we have an entry and we are going to update it. But this entry may
811                  * be already expired. In this case we do the same as we found a new
812                  * net and call the new_net handler
813                  */
814                 bool update_ie = _TRUE;
815
816                 pnetwork->last_scanned = rtw_get_current_time();
817
818                 /* target.Reserved[0]==1, means that scaned network is a bcn frame. */
819                 if((pnetwork->network.IELength>target->IELength) && (target->Reserved[0]==1))
820                         update_ie = _FALSE;
821
822                 update_network(&(pnetwork->network), target,adapter, update_ie);
823         }
824
825 exit:
826         spin_unlock_bh(&queue->lock);
827
828 _func_exit_;
829 }
830
831 void rtw_add_network(_adapter *adapter, WLAN_BSSID_EX *pnetwork);
832 void rtw_add_network(_adapter *adapter, WLAN_BSSID_EX *pnetwork)
833 {
834         struct  mlme_priv       *pmlmepriv = &(((_adapter *)adapter)->mlmepriv);
835         /* _queue       *queue  = &(pmlmepriv->scanned_queue); */
836
837 _func_enter_;
838
839         /* spin_lock_bh(&queue->lock); */
840
841         #if defined(CONFIG_P2P) && defined(CONFIG_P2P_REMOVE_GROUP_INFO)
842         rtw_WLAN_BSSID_EX_remove_p2p_attr(pnetwork, P2P_ATTR_GROUP_INFO);
843         #endif
844
845         update_current_network(adapter, pnetwork);
846
847         rtw_update_scanned_network(adapter, pnetwork);
848
849         /* spin_unlock_bh(&queue->lock); */
850
851 _func_exit_;
852 }
853
854 /* select the desired network based on the capability of the (i)bss. */
855 /*  check items: (1) security */
856 /*                         (2) network_type */
857 /*                         (3) WMM */
858 /*                         (4) HT */
859 /*                      (5) others */
860 int rtw_is_desired_network(_adapter *adapter, struct wlan_network *pnetwork);
861 int rtw_is_desired_network(_adapter *adapter, struct wlan_network *pnetwork)
862 {
863         struct security_priv *psecuritypriv = &adapter->securitypriv;
864         struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
865         u32 desired_encmode;
866         u32 privacy;
867
868         /* u8 wps_ie[512]; */
869         uint wps_ielen;
870
871         int bselected = _TRUE;
872
873         desired_encmode = psecuritypriv->ndisencryptstatus;
874         privacy = pnetwork->network.Privacy;
875
876         if(check_fwstate(pmlmepriv, WIFI_UNDER_WPS))
877         {
878                 if(rtw_get_wps_ie(pnetwork->network.IEs+_FIXED_IE_LENGTH_, pnetwork->network.IELength-_FIXED_IE_LENGTH_, NULL, &wps_ielen)!=NULL)
879                 {
880                         return _TRUE;
881                 }
882                 else
883                 {
884                         return _FALSE;
885                 }
886         }
887         if (adapter->registrypriv.wifi_spec == 1) /* for  correct flow of 8021X  to do.... */
888         {
889                 if ((desired_encmode == Ndis802_11EncryptionDisabled) && (privacy != 0))
890                     bselected = _FALSE;
891         }
892
893         if ((desired_encmode != Ndis802_11EncryptionDisabled) && (privacy == 0)) {
894                 DBG_8723A("desired_encmode: %d, privacy: %d\n", desired_encmode, privacy);
895                 bselected = _FALSE;
896         }
897
898         if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE)
899         {
900                 if(pnetwork->network.InfrastructureMode != pmlmepriv->cur_network.network.InfrastructureMode)
901                         bselected = _FALSE;
902         }
903
904         return bselected;
905 }
906
907 /* TODO: Perry : For Power Management */
908 void rtw_atimdone_event_callback(_adapter       *adapter , u8 *pbuf)
909 {
910
911 _func_enter_;
912         RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("receive atimdone_evet\n"));
913 _func_exit_;
914         return;
915 }
916
917 void rtw_survey_event_callback(_adapter *adapter, u8 *pbuf)
918 {
919         u32 len;
920         WLAN_BSSID_EX *pnetwork;
921         struct  mlme_priv       *pmlmepriv = &(adapter->mlmepriv);
922
923 _func_enter_;
924
925         pnetwork = (WLAN_BSSID_EX *)pbuf;
926
927         RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_survey_event_callback, ssid=%s\n",  pnetwork->Ssid.Ssid));
928
929 #ifdef CONFIG_RTL8712
930         /* endian_convert */
931         pnetwork->Length = le32_to_cpu(pnetwork->Length);
932         pnetwork->Ssid.SsidLength = le32_to_cpu(pnetwork->Ssid.SsidLength);
933         pnetwork->Privacy =le32_to_cpu( pnetwork->Privacy);
934         pnetwork->Rssi = le32_to_cpu(pnetwork->Rssi);
935         pnetwork->NetworkTypeInUse =le32_to_cpu(pnetwork->NetworkTypeInUse);
936         pnetwork->Configuration.ATIMWindow = le32_to_cpu(pnetwork->Configuration.ATIMWindow);
937         pnetwork->Configuration.BeaconPeriod = le32_to_cpu(pnetwork->Configuration.BeaconPeriod);
938         pnetwork->Configuration.DSConfig =le32_to_cpu(pnetwork->Configuration.DSConfig);
939         pnetwork->Configuration.FHConfig.DwellTime=le32_to_cpu(pnetwork->Configuration.FHConfig.DwellTime);
940         pnetwork->Configuration.FHConfig.HopPattern=le32_to_cpu(pnetwork->Configuration.FHConfig.HopPattern);
941         pnetwork->Configuration.FHConfig.HopSet=le32_to_cpu(pnetwork->Configuration.FHConfig.HopSet);
942         pnetwork->Configuration.FHConfig.Length=le32_to_cpu(pnetwork->Configuration.FHConfig.Length);
943         pnetwork->Configuration.Length = le32_to_cpu(pnetwork->Configuration.Length);
944         pnetwork->InfrastructureMode = le32_to_cpu(pnetwork->InfrastructureMode);
945         pnetwork->IELength = le32_to_cpu(pnetwork->IELength);
946 #endif
947
948         len = get_WLAN_BSSID_EX_sz(pnetwork);
949         if(len > (sizeof(WLAN_BSSID_EX)))
950         {
951                 RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("\n ****rtw_survey_event_callback: return a wrong bss ***\n"));
952                 return;
953         }
954
955         spin_lock_bh(&pmlmepriv->lock);
956
957         /*  update IBSS_network 's timestamp */
958         if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) == _TRUE)
959         {
960                 /* RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,"rtw_survey_event_callback : WIFI_ADHOC_MASTER_STATE \n\n"); */
961                 if (!memcmp(&(pmlmepriv->cur_network.network.MacAddress),
962                             pnetwork->MacAddress, ETH_ALEN))
963                 {
964                         struct wlan_network* ibss_wlan = NULL;
965
966                         memcpy(pmlmepriv->cur_network.network.IEs, pnetwork->IEs, 8);
967                         spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
968                         ibss_wlan = rtw_find_network(&pmlmepriv->scanned_queue,  pnetwork->MacAddress);
969                         if(ibss_wlan)
970                         {
971                                 memcpy(ibss_wlan->network.IEs , pnetwork->IEs, 8);
972                                 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
973                                 goto exit;
974                         }
975                         spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
976                 }
977         }
978
979         /*  lock pmlmepriv->lock when you accessing network_q */
980         if ((check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) == _FALSE)
981         {
982                 if( pnetwork->Ssid.Ssid[0] == 0 )
983                 {
984                         pnetwork->Ssid.SsidLength = 0;
985                 }
986                 rtw_add_network(adapter, pnetwork);
987         }
988
989 exit:
990
991         spin_unlock_bh(&pmlmepriv->lock);
992
993 _func_exit_;
994
995         return;
996 }
997
998 void rtw_surveydone_event_callback(_adapter     *adapter, u8 *pbuf)
999 {
1000         struct  mlme_priv       *pmlmepriv = &(adapter->mlmepriv);
1001
1002 #ifdef CONFIG_MLME_EXT
1003
1004         mlmeext_surveydone_event_callback(adapter);
1005
1006 #endif
1007
1008 _func_enter_;
1009
1010         spin_lock_bh(&pmlmepriv->lock);
1011
1012         if(pmlmepriv->wps_probe_req_ie)
1013         {
1014                 u32 free_len = pmlmepriv->wps_probe_req_ie_len;
1015                 pmlmepriv->wps_probe_req_ie_len = 0;
1016                 rtw_mfree(pmlmepriv->wps_probe_req_ie, free_len);
1017                 pmlmepriv->wps_probe_req_ie = NULL;
1018         }
1019
1020         RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_surveydone_event_callback: fw_state:%x\n\n", get_fwstate(pmlmepriv)));
1021
1022         if (check_fwstate(pmlmepriv,_FW_UNDER_SURVEY))
1023         {
1024                 u8 timer_cancelled;
1025
1026                 _cancel_timer(&pmlmepriv->scan_to_timer, &timer_cancelled);
1027
1028                 _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
1029         }
1030         else {
1031
1032                 RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("nic status =%x, survey done event comes too late!\n", get_fwstate(pmlmepriv)));
1033         }
1034
1035         #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
1036         rtw_set_signal_stat_timer(&adapter->recvpriv);
1037         #endif
1038
1039         if(pmlmepriv->to_join == _TRUE)
1040         {
1041                 if((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)==_TRUE) )
1042                 {
1043                         if(check_fwstate(pmlmepriv, _FW_LINKED)==_FALSE)
1044                         {
1045                                 set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
1046
1047                                 if(rtw_select_and_join_from_scanned_queue(pmlmepriv)==_SUCCESS)
1048                                 {
1049                                         _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT );
1050                                 }
1051                                 else
1052                                 {
1053                                         WLAN_BSSID_EX    *pdev_network = &(adapter->registrypriv.dev_network);
1054                                         u8 *pibss = adapter->registrypriv.dev_network.MacAddress;
1055
1056                                         _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
1057
1058                                         RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("switching to adhoc master\n"));
1059
1060                                         memset(&pdev_network->Ssid, 0, sizeof(NDIS_802_11_SSID));
1061                                         memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(NDIS_802_11_SSID));
1062
1063                                         rtw_update_registrypriv_dev_network(adapter);
1064                                         rtw_generate_random_ibss(pibss);
1065
1066                                         pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;
1067
1068                                         if(rtw_createbss_cmd(adapter)!=_SUCCESS)
1069                                         {
1070                                         RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("Error=>rtw_createbss_cmd status FAIL\n"));
1071                                         }
1072
1073                                         pmlmepriv->to_join = _FALSE;
1074                                 }
1075                         }
1076                 }
1077                 else
1078                 {
1079                         int s_ret;
1080                         set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
1081                         pmlmepriv->to_join = _FALSE;
1082                         if(_SUCCESS == (s_ret=rtw_select_and_join_from_scanned_queue(pmlmepriv)))
1083                         {
1084                              _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT);
1085                         }
1086                         else if(s_ret == 2)/* there is no need to wait for join */
1087                         {
1088                                 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
1089                                 rtw_indicate_connect(adapter);
1090                         }
1091                         else
1092                         {
1093                                 DBG_8723A("try_to_join, but select scanning queue fail, to_roaming:%d\n", rtw_to_roaming(adapter));
1094                                 #ifdef CONFIG_LAYER2_ROAMING
1095                                 if (rtw_to_roaming(adapter) != 0) {
1096                                         if( --pmlmepriv->to_roaming == 0
1097                                                 || _SUCCESS != rtw_sitesurvey_cmd(adapter, &pmlmepriv->assoc_ssid, 1, NULL, 0)
1098                                         ) {
1099                                                 rtw_set_roaming(adapter, 0);
1100                                                 rtw_free_assoc_resources(adapter, 1);
1101                                                 rtw_indicate_disconnect(adapter);
1102                                         } else {
1103                                                 pmlmepriv->to_join = _TRUE;
1104                                         }
1105                                 }
1106                                 #endif
1107                                 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
1108                         }
1109                 }
1110         }
1111
1112         indicate_wx_scan_complete_event(adapter);
1113         /* DBG_8723A("scan complete in %dms\n",rtw_get_passing_time_ms(pmlmepriv->scan_start_time)); */
1114
1115         spin_unlock_bh(&pmlmepriv->lock);
1116
1117 #ifdef CONFIG_P2P_PS
1118         if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
1119                 p2p_ps_wk_cmd(adapter, P2P_PS_SCAN_DONE, 0);
1120         }
1121 #endif /*  CONFIG_P2P_PS */
1122
1123         rtw_os_xmit_schedule(adapter);
1124 #ifdef CONFIG_CONCURRENT_MODE
1125         rtw_os_xmit_schedule(adapter->pbuddy_adapter);
1126 #endif
1127 #ifdef CONFIG_DUALMAC_CONCURRENT
1128         dc_resume_xmit(adapter);
1129 #endif
1130
1131 #ifdef CONFIG_DRVEXT_MODULE_WSC
1132         drvext_surveydone_callback(&adapter->drvextpriv);
1133 #endif
1134
1135 #ifdef DBG_CONFIG_ERROR_DETECT
1136         {
1137                 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
1138                 if(pmlmeext->sitesurvey_res.bss_cnt == 0){
1139                         rtw_hal_sreset_reset(adapter);
1140                 }
1141         }
1142 #endif
1143
1144 #ifdef CONFIG_IOCTL_CFG80211
1145         rtw_cfg80211_surveydone_event_callback(adapter);
1146 #endif /* CONFIG_IOCTL_CFG80211 */
1147
1148 _func_exit_;
1149 }
1150
1151 void rtw_dummy_event_callback(_adapter *adapter , u8 *pbuf)
1152 {
1153 }
1154
1155 void rtw_fwdbg_event_callback(_adapter *adapter , u8 *pbuf)
1156 {
1157 }
1158
1159 static void free_scanqueue(struct       mlme_priv *pmlmepriv)
1160 {
1161         _queue *free_queue = &pmlmepriv->free_bss_pool;
1162         _queue *scan_queue = &pmlmepriv->scanned_queue;
1163         struct list_head        *plist, *phead, *ptemp;
1164
1165 _func_enter_;
1166
1167         RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, ("+free_scanqueue\n"));
1168         spin_lock_bh(&scan_queue->lock);
1169         spin_lock_bh(&free_queue->lock);
1170
1171         phead = get_list_head(scan_queue);
1172         plist = get_next(phead);
1173
1174         while (plist != phead)
1175        {
1176                 ptemp = get_next(plist);
1177                 list_del_init(plist);
1178                 list_add_tail(plist, &free_queue->queue);
1179                 plist =ptemp;
1180                 pmlmepriv->num_of_scanned --;
1181         }
1182
1183         spin_unlock_bh(&free_queue->lock);
1184         spin_unlock_bh(&scan_queue->lock);
1185
1186 _func_exit_;
1187 }
1188
1189 /*
1190 *rtw_free_assoc_resources: the caller has to lock pmlmepriv->lock
1191 */
1192 void rtw_free_assoc_resources(_adapter *adapter, int lock_scanned_queue)
1193 {
1194         struct wlan_network* pwlan = NULL;
1195         struct  mlme_priv *pmlmepriv = &adapter->mlmepriv;
1196         struct  sta_priv *pstapriv = &adapter->stapriv;
1197         struct wlan_network *tgt_network = &pmlmepriv->cur_network;
1198
1199 #ifdef CONFIG_TDLS
1200         struct tdls_info *ptdlsinfo = &adapter->tdlsinfo;
1201 #endif /* CONFIG_TDLS */
1202 _func_enter_;
1203
1204         RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, ("+rtw_free_assoc_resources\n"));
1205         RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("tgt_network->network.MacAddress="MAC_FMT" ssid=%s\n",
1206                 MAC_ARG(tgt_network->network.MacAddress), tgt_network->network.Ssid.Ssid));
1207
1208         if(check_fwstate( pmlmepriv, WIFI_STATION_STATE|WIFI_AP_STATE))
1209         {
1210                 struct sta_info* psta;
1211
1212                 psta = rtw_get_stainfo(&adapter->stapriv, tgt_network->network.MacAddress);
1213
1214 #ifdef CONFIG_TDLS
1215                 if(ptdlsinfo->setup_state != TDLS_STATE_NONE)
1216                 {
1217                         rtw_tdls_cmd(adapter, myid(&(adapter->eeprompriv)), TDLS_RS_RCR);
1218                         rtw_reset_tdls_info(adapter);
1219                         rtw_free_all_stainfo(adapter);
1220                         spin_lock_bh(&(pstapriv->sta_hash_lock));
1221                 }
1222                 else
1223 #endif /* CONFIG_TDLS */
1224                 {
1225                         spin_lock_bh(&(pstapriv->sta_hash_lock));
1226                         rtw_free_stainfo(adapter,  psta);
1227                 }
1228
1229                 spin_unlock_bh(&(pstapriv->sta_hash_lock));
1230
1231         }
1232
1233         if(check_fwstate( pmlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE))
1234         {
1235                 struct sta_info* psta;
1236
1237                 rtw_free_all_stainfo(adapter);
1238
1239                 psta = rtw_get_bcmc_stainfo(adapter);
1240                 spin_lock_bh(&(pstapriv->sta_hash_lock));
1241                 rtw_free_stainfo(adapter, psta);
1242                 spin_unlock_bh(&(pstapriv->sta_hash_lock));
1243
1244                 rtw_init_bcmc_stainfo(adapter);
1245         }
1246
1247         if(lock_scanned_queue)
1248                 spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
1249
1250         pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.MacAddress);
1251         if(pwlan)
1252         {
1253                 pwlan->fixed = _FALSE;
1254         }
1255         else
1256         {
1257                 RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("rtw_free_assoc_resources : pwlan== NULL \n\n"));
1258         }
1259
1260         if((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) && (adapter->stapriv.asoc_sta_count== 1))
1261                 /*||check_fwstate(pmlmepriv, WIFI_STATION_STATE)*/)
1262         {
1263                 rtw_free_network_nolock(pmlmepriv, pwlan);
1264         }
1265
1266         if(lock_scanned_queue)
1267                 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
1268
1269         pmlmepriv->key_mask = 0;
1270
1271 _func_exit_;
1272 }
1273
1274 /*
1275 *rtw_indicate_connect: the caller has to lock pmlmepriv->lock
1276 */
1277 void rtw_indicate_connect(_adapter *padapter)
1278 {
1279         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
1280         struct xmit_priv        *pxmitpriv = &padapter->xmitpriv;
1281
1282 _func_enter_;
1283
1284         RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("+rtw_indicate_connect\n"));
1285
1286         pmlmepriv->to_join = _FALSE;
1287
1288         if(!check_fwstate(&padapter->mlmepriv, _FW_LINKED))
1289         {
1290
1291 #ifdef CONFIG_SW_ANTENNA_DIVERSITY
1292                 rtw_hal_set_hwreg(padapter, HW_VAR_ANTENNA_DIVERSITY_LINK, 0);
1293 #endif
1294
1295                 set_fwstate(pmlmepriv, _FW_LINKED);
1296
1297                 rtw_led_control(padapter, LED_CTL_LINK);
1298
1299 #ifdef CONFIG_DRVEXT_MODULE
1300                 if(padapter->drvextpriv.enable_wpa)
1301                 {
1302                         indicate_l2_connect(padapter);
1303                 }
1304                 else
1305 #endif
1306                 {
1307                         rtw_os_indicate_connect(padapter);
1308                 }
1309
1310         }
1311
1312         rtw_set_roaming(padapter, 0);
1313
1314         rtw_set_scan_deny(padapter, 3000);
1315
1316         RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("-rtw_indicate_connect: fw_state=0x%08x\n", get_fwstate(pmlmepriv)));
1317
1318 _func_exit_;
1319 }
1320
1321 /*
1322 *rtw_indicate_disconnect: the caller has to lock pmlmepriv->lock
1323 */
1324 void rtw_indicate_disconnect( _adapter *padapter )
1325 {
1326         struct  mlme_priv *pmlmepriv = &padapter->mlmepriv;
1327         struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
1328         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1329         WLAN_BSSID_EX   *cur_network = &(pmlmeinfo->network);
1330         struct sta_info *psta;
1331         struct sta_priv *pstapriv = &padapter->stapriv;
1332
1333 _func_enter_;
1334
1335         RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("+rtw_indicate_disconnect\n"));
1336
1337         _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING|WIFI_UNDER_WPS);
1338
1339         /* DBG_8723A("clear wps when %s\n", __func__); */
1340
1341         if(rtw_to_roaming(padapter) > 0)
1342                 _clr_fwstate_(pmlmepriv, _FW_LINKED);
1343
1344         if(check_fwstate(&padapter->mlmepriv, _FW_LINKED)
1345                 || (rtw_to_roaming(padapter) <= 0)
1346         )
1347         {
1348                 rtw_os_indicate_disconnect(padapter);
1349
1350                 /* set ips_deny_time to avoid enter IPS before LPS leave */
1351                 padapter->pwrctrlpriv.ips_deny_time = rtw_get_current_time() + rtw_ms_to_systime(3000);
1352
1353               _clr_fwstate_(pmlmepriv, _FW_LINKED);
1354
1355                 rtw_led_control(padapter, LED_CTL_NO_LINK);
1356
1357                 rtw_clear_scan_deny(padapter);
1358
1359         }
1360
1361 #ifdef CONFIG_P2P_PS
1362         p2p_ps_wk_cmd(padapter, P2P_PS_DISABLE, 1);
1363 #endif /*  CONFIG_P2P_PS */
1364
1365 #ifdef CONFIG_LPS
1366 #ifdef CONFIG_WOWLAN
1367         if(padapter->pwrctrlpriv.wowlan_mode==_FALSE)
1368 #endif /* CONFIG_WOWLAN */
1369         rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_DISCONNECT, 1);
1370 #endif
1371
1372 _func_exit_;
1373 }
1374
1375 inline void rtw_indicate_scan_done( _adapter *padapter, bool aborted)
1376 {
1377         rtw_os_indicate_scan_done(padapter, aborted);
1378 }
1379
1380 void rtw_scan_abort(_adapter *adapter)
1381 {
1382         u32 cnt=0;
1383         u32 start;
1384         struct mlme_priv        *pmlmepriv = &(adapter->mlmepriv);
1385         struct mlme_ext_priv    *pmlmeext = &(adapter->mlmeextpriv);
1386
1387         start = rtw_get_current_time();
1388         pmlmeext->scan_abort = _TRUE;
1389         while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)
1390                 && rtw_get_passing_time_ms(start) <= 200) {
1391
1392                 if (adapter->bDriverStopped || adapter->bSurpriseRemoved)
1393                         break;
1394
1395                 DBG_8723A(FUNC_NDEV_FMT"fw_state=_FW_UNDER_SURVEY!\n", FUNC_NDEV_ARG(adapter->pnetdev));
1396                 rtw_msleep_os(20);
1397         }
1398
1399         if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) {
1400                 if (!adapter->bDriverStopped && !adapter->bSurpriseRemoved)
1401                         DBG_8723A(FUNC_NDEV_FMT"waiting for scan_abort time out!\n", FUNC_NDEV_ARG(adapter->pnetdev));
1402                 rtw_indicate_scan_done(adapter, _TRUE);
1403         }
1404         pmlmeext->scan_abort = _FALSE;
1405 }
1406
1407 static struct sta_info *rtw_joinbss_update_stainfo(_adapter *padapter, struct wlan_network *pnetwork)
1408 {
1409         int i;
1410         struct sta_info *bmc_sta, *psta=NULL;
1411         struct recv_reorder_ctrl *preorder_ctrl;
1412         struct sta_priv *pstapriv = &padapter->stapriv;
1413
1414         psta = rtw_get_stainfo(pstapriv, pnetwork->network.MacAddress);
1415         if(psta==NULL) {
1416                 psta = rtw_alloc_stainfo(pstapriv, pnetwork->network.MacAddress);
1417         }
1418
1419         if(psta) /* update ptarget_sta */
1420         {
1421                 DBG_8723A("%s\n", __FUNCTION__);
1422
1423                 psta->aid  = pnetwork->join_res;
1424 #ifdef CONFIG_CONCURRENT_MODE
1425
1426                         if(PRIMARY_ADAPTER == padapter->adapter_type)
1427                                 psta->mac_id=0;
1428                         else
1429                                 psta->mac_id=2;
1430 #else
1431                         psta->mac_id=0;
1432 #endif
1433
1434                 /* sta mode */
1435                 rtw_hal_set_odm_var(padapter,HAL_ODM_STA_INFO,psta,_TRUE);
1436
1437                 /* security related */
1438                 if(padapter->securitypriv.dot11AuthAlgrthm== dot11AuthAlgrthm_8021X)
1439                 {
1440                         padapter->securitypriv.binstallGrpkey=_FALSE;
1441                         padapter->securitypriv.busetkipkey=_FALSE;
1442                         padapter->securitypriv.bgrpkey_handshake=_FALSE;
1443
1444                         psta->ieee8021x_blocked=_TRUE;
1445                         psta->dot118021XPrivacy=padapter->securitypriv.dot11PrivacyAlgrthm;
1446
1447                         memset((u8 *)&psta->dot118021x_UncstKey, 0, sizeof (union Keytype));
1448
1449                         memset((u8 *)&psta->dot11tkiprxmickey, 0, sizeof (union Keytype));
1450                         memset((u8 *)&psta->dot11tkiptxmickey, 0, sizeof (union Keytype));
1451
1452                         memset((u8 *)&psta->dot11txpn, 0, sizeof (union pn48));
1453                         memset((u8 *)&psta->dot11rxpn, 0, sizeof (union pn48));
1454                 }
1455
1456                 /*      Commented by Albert 2012/07/21 */
1457                 /*      When doing the WPS, the wps_ie_len won't equal to 0 */
1458                 /*      And the Wi-Fi driver shouldn't allow the data packet to be tramsmitted. */
1459                 if ( padapter->securitypriv.wps_ie_len != 0 )
1460                 {
1461                         psta->ieee8021x_blocked=_TRUE;
1462                         padapter->securitypriv.wps_ie_len = 0;
1463                 }
1464
1465                 /* for A-MPDU Rx reordering buffer control for bmc_sta & sta_info */
1466                 /* if A-MPDU Rx is enabled, reseting  rx_ordering_ctrl wstart_b(indicate_seq) to default value=0xffff */
1467                 /* todo: check if AP can send A-MPDU packets */
1468                 for(i=0; i < 16 ; i++)
1469                 {
1470                         /* preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; */
1471                         preorder_ctrl = &psta->recvreorder_ctrl[i];
1472                         preorder_ctrl->enable = _FALSE;
1473                         preorder_ctrl->indicate_seq = 0xffff;
1474                         #ifdef DBG_RX_SEQ
1475                         DBG_8723A("DBG_RX_SEQ %s:%d indicate_seq:%u \n", __FUNCTION__, __LINE__,
1476                                 preorder_ctrl->indicate_seq);
1477                         #endif
1478                         preorder_ctrl->wend_b= 0xffff;
1479                         preorder_ctrl->wsize_b = 64;/* max_ampdu_sz; ex. 32(kbytes) -> wsize_b=32 */
1480                 }
1481
1482                 bmc_sta = rtw_get_bcmc_stainfo(padapter);
1483                 if(bmc_sta)
1484                 {
1485                         for(i=0; i < 16 ; i++)
1486                         {
1487                                 /* preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; */
1488                                 preorder_ctrl = &bmc_sta->recvreorder_ctrl[i];
1489                                 preorder_ctrl->enable = _FALSE;
1490                                 preorder_ctrl->indicate_seq = 0xffff;
1491                                 #ifdef DBG_RX_SEQ
1492                                 DBG_8723A("DBG_RX_SEQ %s:%d indicate_seq:%u \n", __FUNCTION__, __LINE__,
1493                                         preorder_ctrl->indicate_seq);
1494                                 #endif
1495                                 preorder_ctrl->wend_b= 0xffff;
1496                                 preorder_ctrl->wsize_b = 64;/* max_ampdu_sz; ex. 32(kbytes) -> wsize_b=32 */
1497                         }
1498                 }
1499
1500                 /* misc. */
1501                 update_sta_info(padapter, psta);
1502
1503         }
1504
1505         return psta;
1506 }
1507
1508 /* pnetwork : returns from rtw_joinbss_event_callback */
1509 /* ptarget_wlan: found from scanned_queue */
1510 static void rtw_joinbss_update_network(_adapter *padapter, struct wlan_network *ptarget_wlan, struct wlan_network  *pnetwork)
1511 {
1512         struct mlme_priv        *pmlmepriv = &(padapter->mlmepriv);
1513         struct wlan_network  *cur_network = &(pmlmepriv->cur_network);
1514
1515         DBG_8723A("%s\n", __FUNCTION__);
1516
1517         RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("\nfw_state:%x, BSSID:"MAC_FMT"\n"
1518                 ,get_fwstate(pmlmepriv), MAC_ARG(pnetwork->network.MacAddress)));
1519
1520         /*  why not use ptarget_wlan?? */
1521         memcpy(&cur_network->network, &pnetwork->network, pnetwork->network.Length);
1522         /*  some IEs in pnetwork is wrong, so we should use ptarget_wlan IEs */
1523         cur_network->network.IELength = ptarget_wlan->network.IELength;
1524         memcpy(&cur_network->network.IEs[0], &ptarget_wlan->network.IEs[0], MAX_IE_SZ);
1525
1526         cur_network->aid = pnetwork->join_res;
1527
1528 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
1529         rtw_set_signal_stat_timer(&padapter->recvpriv);
1530 #endif
1531         padapter->recvpriv.signal_strength = ptarget_wlan->network.PhyInfo.SignalStrength;
1532         padapter->recvpriv.signal_qual = ptarget_wlan->network.PhyInfo.SignalQuality;
1533         /* the ptarget_wlan->network.Rssi is raw data, we use ptarget_wlan->network.PhyInfo.SignalStrength instead (has scaled) */
1534         padapter->recvpriv.rssi = translate_percentage_to_dbm(ptarget_wlan->network.PhyInfo.SignalStrength);
1535         #if defined(DBG_RX_SIGNAL_DISPLAY_PROCESSING) && 1
1536                 DBG_8723A("%s signal_strength:%3u, rssi:%3d, signal_qual:%3u"
1537                         "\n"
1538                         , __FUNCTION__
1539                         , padapter->recvpriv.signal_strength
1540                         , padapter->recvpriv.rssi
1541                         , padapter->recvpriv.signal_qual
1542         );
1543         #endif
1544 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
1545         rtw_set_signal_stat_timer(&padapter->recvpriv);
1546 #endif
1547
1548         /* update fw_state will clr _FW_UNDER_LINKING here indirectly */
1549         switch(pnetwork->network.InfrastructureMode)
1550         {
1551                 case Ndis802_11Infrastructure:
1552
1553                                 if(pmlmepriv->fw_state&WIFI_UNDER_WPS)
1554                                         pmlmepriv->fw_state = WIFI_STATION_STATE|WIFI_UNDER_WPS;
1555                                 else
1556                                         pmlmepriv->fw_state = WIFI_STATION_STATE;
1557
1558                                 break;
1559                 case Ndis802_11IBSS:
1560                                 pmlmepriv->fw_state = WIFI_ADHOC_STATE;
1561                                 break;
1562                 default:
1563                                 pmlmepriv->fw_state = WIFI_NULL_STATE;
1564                                 RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("Invalid network_mode\n"));
1565                                 break;
1566         }
1567
1568         rtw_update_protection(padapter, (cur_network->network.IEs) + sizeof (NDIS_802_11_FIXED_IEs),
1569                                                                         (cur_network->network.IELength));
1570
1571 #ifdef CONFIG_80211N_HT
1572         rtw_update_ht_cap(padapter, cur_network->network.IEs, cur_network->network.IELength);
1573 #endif
1574 }
1575
1576 /* Notes: the fucntion could be > passive_level (the same context as Rx tasklet) */
1577 /* pnetwork : returns from rtw_joinbss_event_callback */
1578 /* ptarget_wlan: found from scanned_queue */
1579 /* if join_res > 0, for (fw_state==WIFI_STATION_STATE), we check if  "ptarget_sta" & "ptarget_wlan" exist. */
1580 /* if join_res > 0, for (fw_state==WIFI_ADHOC_STATE), we only check if "ptarget_wlan" exist. */
1581 /* if join_res > 0, update "cur_network->network" from "pnetwork->network" if (ptarget_wlan !=NULL). */
1582 /*  */
1583 /* define REJOIN */
1584 void rtw_joinbss_event_prehandle(_adapter *adapter, u8 *pbuf)
1585 {
1586         static u8 retry=0;
1587         u8 timer_cancelled;
1588         struct sta_info *ptarget_sta= NULL, *pcur_sta = NULL;
1589         struct  sta_priv *pstapriv = &adapter->stapriv;
1590         struct  mlme_priv       *pmlmepriv = &(adapter->mlmepriv);
1591         struct wlan_network     *pnetwork       = (struct wlan_network *)pbuf;
1592         struct wlan_network     *cur_network = &(pmlmepriv->cur_network);
1593         struct wlan_network     *pcur_wlan = NULL, *ptarget_wlan = NULL;
1594         unsigned int            the_same_macaddr = _FALSE;
1595
1596 _func_enter_;
1597
1598 #ifdef CONFIG_RTL8712
1599        /* endian_convert */
1600         pnetwork->join_res = le32_to_cpu(pnetwork->join_res);
1601         pnetwork->network_type = le32_to_cpu(pnetwork->network_type);
1602         pnetwork->network.Length = le32_to_cpu(pnetwork->network.Length);
1603         pnetwork->network.Ssid.SsidLength = le32_to_cpu(pnetwork->network.Ssid.SsidLength);
1604         pnetwork->network.Privacy =le32_to_cpu( pnetwork->network.Privacy);
1605         pnetwork->network.Rssi = le32_to_cpu(pnetwork->network.Rssi);
1606         pnetwork->network.NetworkTypeInUse =le32_to_cpu(pnetwork->network.NetworkTypeInUse) ;
1607         pnetwork->network.Configuration.ATIMWindow = le32_to_cpu(pnetwork->network.Configuration.ATIMWindow);
1608         pnetwork->network.Configuration.BeaconPeriod = le32_to_cpu(pnetwork->network.Configuration.BeaconPeriod);
1609         pnetwork->network.Configuration.DSConfig = le32_to_cpu(pnetwork->network.Configuration.DSConfig);
1610         pnetwork->network.Configuration.FHConfig.DwellTime=le32_to_cpu(pnetwork->network.Configuration.FHConfig.DwellTime);
1611         pnetwork->network.Configuration.FHConfig.HopPattern=le32_to_cpu(pnetwork->network.Configuration.FHConfig.HopPattern);
1612         pnetwork->network.Configuration.FHConfig.HopSet=le32_to_cpu(pnetwork->network.Configuration.FHConfig.HopSet);
1613         pnetwork->network.Configuration.FHConfig.Length=le32_to_cpu(pnetwork->network.Configuration.FHConfig.Length);
1614         pnetwork->network.Configuration.Length = le32_to_cpu(pnetwork->network.Configuration.Length);
1615         pnetwork->network.InfrastructureMode = le32_to_cpu(pnetwork->network.InfrastructureMode);
1616         pnetwork->network.IELength = le32_to_cpu(pnetwork->network.IELength );
1617 #endif
1618
1619         RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("joinbss event call back received with res=%d\n", pnetwork->join_res));
1620
1621         rtw_get_encrypt_decrypt_from_registrypriv(adapter);
1622
1623         if (pmlmepriv->assoc_ssid.SsidLength == 0)
1624         {
1625                 RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("@@@@@   joinbss event call back  for Any SSid\n"));
1626         }
1627         else
1628         {
1629                 RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("@@@@@   rtw_joinbss_event_callback for SSid:%s\n", pmlmepriv->assoc_ssid.Ssid));
1630         }
1631
1632         if (!memcmp(pnetwork->network.MacAddress, cur_network->network.MacAddress, ETH_ALEN))
1633                 the_same_macaddr = _TRUE;
1634         else
1635                 the_same_macaddr = _FALSE;
1636
1637         pnetwork->network.Length = get_WLAN_BSSID_EX_sz(&pnetwork->network);
1638         if(pnetwork->network.Length > sizeof(WLAN_BSSID_EX))
1639         {
1640                 RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("\n\n ***joinbss_evt_callback return a wrong bss ***\n\n"));
1641                 goto ignore_joinbss_callback;
1642         }
1643
1644         spin_lock_bh(&pmlmepriv->lock);
1645
1646         RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("\n rtw_joinbss_event_callback !! _enter_critical \n"));
1647
1648         if(pnetwork->join_res > 0)
1649         {
1650                 spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
1651                 retry = 0;
1652                 if (check_fwstate(pmlmepriv,_FW_UNDER_LINKING) )
1653                 {
1654                         /* s1. find ptarget_wlan */
1655                         if(check_fwstate(pmlmepriv, _FW_LINKED) )
1656                         {
1657                                 if(the_same_macaddr == _TRUE)
1658                                 {
1659                                         ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.MacAddress);
1660                                 }
1661                                 else
1662                                 {
1663                                         pcur_wlan = rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.MacAddress);
1664                                         if(pcur_wlan)   pcur_wlan->fixed = _FALSE;
1665
1666                                         pcur_sta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress);
1667                                         if(pcur_sta){
1668                                                 spin_lock_bh(&(pstapriv->sta_hash_lock));
1669                                                 rtw_free_stainfo(adapter,  pcur_sta);
1670                                                 spin_unlock_bh(&(pstapriv->sta_hash_lock));
1671                                         }
1672
1673                                         ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, pnetwork->network.MacAddress);
1674                                         if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE){
1675                                                 if(ptarget_wlan)        ptarget_wlan->fixed = _TRUE;
1676                                         }
1677                                 }
1678
1679                         }
1680                         else
1681                         {
1682                                 ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, pnetwork->network.MacAddress);
1683                                 if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE){
1684                                         if(ptarget_wlan)        ptarget_wlan->fixed = _TRUE;
1685                                 }
1686                         }
1687
1688                         /* s2. update cur_network */
1689                         if(ptarget_wlan)
1690                         {
1691                                 rtw_joinbss_update_network(adapter, ptarget_wlan, pnetwork);
1692                         }
1693                         else
1694                         {
1695                                 RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("Can't find ptarget_wlan when joinbss_event callback\n"));
1696                                 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
1697                                 goto ignore_joinbss_callback;
1698                         }
1699
1700                         /* s3. find ptarget_sta & update ptarget_sta after update cur_network only for station mode */
1701                         if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
1702                         {
1703                                 ptarget_sta = rtw_joinbss_update_stainfo(adapter, pnetwork);
1704                                 if(ptarget_sta==NULL)
1705                                 {
1706                                         RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("Can't update stainfo when joinbss_event callback\n"));
1707                                         spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
1708                                         goto ignore_joinbss_callback;
1709                                 }
1710                         }
1711
1712                         /* s4. indicate connect */
1713                                 if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
1714                                 {
1715                                         rtw_indicate_connect(adapter);
1716                                 }
1717                                 else
1718                                 {
1719                                         /* adhoc mode will rtw_indicate_connect when rtw_stassoc_event_callback */
1720                                         RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("adhoc mode, fw_state:%x", get_fwstate(pmlmepriv)));
1721                                 }
1722
1723                         /* s5. Cancle assoc_timer */
1724                         _cancel_timer(&pmlmepriv->assoc_timer, &timer_cancelled);
1725
1726                         RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("Cancle assoc_timer \n"));
1727
1728                 }
1729                 else
1730                 {
1731                         RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("rtw_joinbss_event_callback err: fw_state:%x", get_fwstate(pmlmepriv)));
1732                         spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
1733                         goto ignore_joinbss_callback;
1734                 }
1735
1736                 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
1737
1738         }
1739         else if(pnetwork->join_res == -4)
1740         {
1741                 rtw_reset_securitypriv(adapter);
1742                 _set_timer(&pmlmepriv->assoc_timer, 1);
1743
1744                 /* rtw_free_assoc_resources(adapter, 1); */
1745
1746                 if((check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) == _TRUE)
1747                 {
1748                         RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("fail! clear _FW_UNDER_LINKING ^^^fw_state=%x\n", get_fwstate(pmlmepriv)));
1749                         _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
1750                 }
1751
1752         }
1753         else /* if join_res < 0 (join fails), then try again */
1754         {
1755
1756                 #ifdef REJOIN
1757                 res = _FAIL;
1758                 if(retry < 2) {
1759                         res = rtw_select_and_join_from_scanned_queue(pmlmepriv);
1760                         RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("rtw_select_and_join_from_scanned_queue again! res:%d\n",res));
1761                 }
1762
1763                  if(res == _SUCCESS)
1764                 {
1765                         /* extend time of assoc_timer */
1766                         _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT);
1767                         retry++;
1768                 }
1769                 else if(res == 2)/* there is no need to wait for join */
1770                 {
1771                         _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
1772                         rtw_indicate_connect(adapter);
1773                 }
1774                 else
1775                 {
1776                         RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("Set Assoc_Timer = 1; can't find match ssid in scanned_q \n"));
1777                 #endif
1778
1779                         _set_timer(&pmlmepriv->assoc_timer, 1);
1780                         /* rtw_free_assoc_resources(adapter, 1); */
1781                         _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
1782
1783                 #ifdef REJOIN
1784                         retry = 0;
1785                 }
1786                 #endif
1787         }
1788
1789 ignore_joinbss_callback:
1790
1791         spin_unlock_bh(&pmlmepriv->lock);
1792         _func_exit_;
1793 }
1794
1795 void rtw_joinbss_event_callback(_adapter *adapter, u8 *pbuf)
1796 {
1797         struct wlan_network     *pnetwork       = (struct wlan_network *)pbuf;
1798
1799 _func_enter_;
1800
1801         mlmeext_joinbss_event_callback(adapter, pnetwork->join_res);
1802
1803         rtw_os_xmit_schedule(adapter);
1804
1805 #ifdef CONFIG_CONCURRENT_MODE
1806         rtw_os_xmit_schedule(adapter->pbuddy_adapter);
1807 #endif
1808
1809 #ifdef CONFIG_DUALMAC_CONCURRENT
1810         dc_resume_xmit(adapter);
1811 #endif
1812
1813 _func_exit_;
1814 }
1815
1816 u8 search_max_mac_id(_adapter *padapter)
1817 {
1818         u8 mac_id, aid;
1819 #if (RATE_ADAPTIVE_SUPPORT==1)  /* for 88E RA */
1820         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1821         struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
1822         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
1823         struct sta_priv *pstapriv = &padapter->stapriv;
1824
1825 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
1826         if(check_fwstate(pmlmepriv, WIFI_AP_STATE)){
1827
1828                 for (aid = (pstapriv->max_num_sta); aid > 0; aid--)
1829                 {
1830                         if (pstapriv->sta_aid[aid-1] != NULL)
1831                                 break;
1832                 }
1833 /*
1834                 for (mac_id = (pstapriv->max_num_sta-1); mac_id >= 0; mac_id--)
1835                 {
1836                         if (pstapriv->sta_aid[mac_id] != NULL)
1837                                 break;
1838                 }
1839 */
1840                 mac_id = aid + 1;
1841         }
1842         else
1843 #endif
1844         {/* adhoc  id =  31~2 */
1845                 for (mac_id = (NUM_STA-1); mac_id >= IBSS_START_MAC_ID ; mac_id--)
1846                 {
1847                         if (pmlmeinfo->FW_sta_info[mac_id].status == 1)
1848                         {
1849                                 break;
1850                         }
1851                 }
1852         }
1853 #endif
1854         return mac_id;
1855 }
1856
1857 /* FOR AP ,AD-HOC mode */
1858 void rtw_stassoc_hw_rpt(_adapter *adapter,struct sta_info *psta)
1859 {
1860         u16 media_status;
1861
1862         if(psta==NULL)  return;
1863
1864         #if (RATE_ADAPTIVE_SUPPORT==1)  /* for 88E RA */
1865         {
1866                 u8 macid = search_max_mac_id(adapter);
1867                 rtw_hal_set_hwreg(adapter,HW_VAR_TX_RPT_MAX_MACID, (u8*)&macid);
1868         }
1869         #endif
1870         media_status = (psta->mac_id<<8)|1; /*   MACID|OPMODE:1 connect */
1871         rtw_hal_set_hwreg(adapter,HW_VAR_H2C_MEDIA_STATUS_RPT,(u8 *)&media_status);
1872 }
1873
1874 void rtw_stassoc_event_callback(_adapter *adapter, u8 *pbuf)
1875 {
1876         struct sta_info *psta;
1877         struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
1878         struct stassoc_event    *pstassoc       = (struct stassoc_event*)pbuf;
1879         struct wlan_network     *cur_network = &(pmlmepriv->cur_network);
1880         struct wlan_network     *ptarget_wlan = NULL;
1881
1882 _func_enter_;
1883
1884         if(rtw_access_ctrl(adapter, pstassoc->macaddr) == _FALSE)
1885                 return;
1886
1887 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
1888         if(check_fwstate(pmlmepriv, WIFI_AP_STATE))
1889         {
1890                 psta = rtw_get_stainfo(&adapter->stapriv, pstassoc->macaddr);
1891                 if(psta)
1892                 {
1893 #ifdef CONFIG_IOCTL_CFG80211
1894                         #ifdef COMPAT_KERNEL_RELEASE
1895
1896                         #elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)) || defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
1897                         u8 *passoc_req = NULL;
1898                         u32 assoc_req_len;
1899
1900                         spin_lock_bh(&psta->lock);
1901                         if(psta->passoc_req && psta->assoc_req_len>0)
1902                         {
1903                                 passoc_req = rtw_zmalloc(psta->assoc_req_len);
1904                                 if(passoc_req)
1905                                 {
1906                                         assoc_req_len = psta->assoc_req_len;
1907                                         memcpy(passoc_req, psta->passoc_req, assoc_req_len);
1908
1909                                         rtw_mfree(psta->passoc_req , psta->assoc_req_len);
1910                                         psta->passoc_req = NULL;
1911                                         psta->assoc_req_len = 0;
1912                                 }
1913                         }
1914                         spin_unlock_bh(&psta->lock);
1915
1916                         if(passoc_req && assoc_req_len>0)
1917                         {
1918                                 rtw_cfg80211_indicate_sta_assoc(adapter, passoc_req, assoc_req_len);
1919
1920                                 rtw_mfree(passoc_req, assoc_req_len);
1921                         }
1922                         #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)) || defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER) */
1923 #endif /* CONFIG_IOCTL_CFG80211 */
1924
1925                         /* bss_cap_update_on_sta_join(adapter, psta); */
1926                         /* sta_info_update(adapter, psta); */
1927                         ap_sta_info_defer_update(adapter, psta);
1928
1929                         rtw_stassoc_hw_rpt(adapter,psta);
1930
1931                 }
1932
1933                 goto exit;
1934         }
1935 #endif
1936         /* for AD-HOC mode */
1937         psta = rtw_get_stainfo(&adapter->stapriv, pstassoc->macaddr);
1938         if( psta != NULL)
1939         {
1940                 /* the sta have been in sta_info_queue => do nothing */
1941
1942                 RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("Error: rtw_stassoc_event_callback: sta has been in sta_hash_queue \n"));
1943
1944                 goto exit; /* between drv has received this event before and  fw have not yet to set key to CAM_ENTRY) */
1945         }
1946
1947         psta = rtw_alloc_stainfo(&adapter->stapriv, pstassoc->macaddr);
1948         if (psta == NULL) {
1949                 RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("Can't alloc sta_info when rtw_stassoc_event_callback\n"));
1950                 goto exit;
1951         }
1952
1953         /* to do : init sta_info variable */
1954         psta->qos_option = 0;
1955         psta->mac_id = (uint)pstassoc->cam_id;
1956         /* psta->aid = (uint)pstassoc->cam_id; */
1957         DBG_8723A("%s\n",__FUNCTION__);
1958         /* for ad-hoc mode */
1959         rtw_hal_set_odm_var(adapter,HAL_ODM_STA_INFO,psta,_TRUE);
1960
1961         rtw_stassoc_hw_rpt(adapter,psta);
1962
1963         if(adapter->securitypriv.dot11AuthAlgrthm==dot11AuthAlgrthm_8021X)
1964                 psta->dot118021XPrivacy = adapter->securitypriv.dot11PrivacyAlgrthm;
1965
1966         psta->ieee8021x_blocked = _FALSE;
1967
1968         spin_lock_bh(&pmlmepriv->lock);
1969
1970         if ( (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)==_TRUE ) ||
1971                 (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)==_TRUE ) )
1972         {
1973                 if(adapter->stapriv.asoc_sta_count== 2)
1974                 {
1975                         spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
1976                         ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.MacAddress);
1977                         if(ptarget_wlan)        ptarget_wlan->fixed = _TRUE;
1978                         spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
1979                         /*  a sta + bc/mc_stainfo (not Ibss_stainfo) */
1980                         rtw_indicate_connect(adapter);
1981                 }
1982         }
1983
1984         spin_unlock_bh(&pmlmepriv->lock);
1985
1986         mlmeext_sta_add_event_callback(adapter, psta);
1987
1988 #ifdef CONFIG_RTL8711
1989         /* submit SetStaKey_cmd to tell fw, fw will allocate an CAM entry for this sta */
1990         rtw_setstakey_cmd(adapter, (unsigned char*)psta, _FALSE);
1991 #endif
1992
1993 exit:
1994
1995 _func_exit_;
1996 }
1997
1998 void rtw_stadel_event_callback(_adapter *adapter, u8 *pbuf)
1999 {
2000         int mac_id=-1;
2001         struct sta_info *psta;
2002         struct wlan_network* pwlan = NULL;
2003         WLAN_BSSID_EX    *pdev_network=NULL;
2004         u8* pibss = NULL;
2005         struct  mlme_priv       *pmlmepriv = &(adapter->mlmepriv);
2006         struct  stadel_event *pstadel   = (struct stadel_event*)pbuf;
2007         struct  sta_priv *pstapriv = &adapter->stapriv;
2008         struct wlan_network *tgt_network = &(pmlmepriv->cur_network);
2009
2010 _func_enter_;
2011
2012         psta = rtw_get_stainfo(&adapter->stapriv, pstadel->macaddr);
2013         if(psta)
2014                 mac_id = psta->mac_id;
2015         else
2016                 mac_id = pstadel->mac_id;
2017
2018         DBG_8723A("%s(mac_id=%d)=" MAC_FMT "\n", __func__, mac_id, MAC_ARG(pstadel->macaddr));
2019
2020         if(mac_id>=0){
2021                 u16 media_status;
2022                 media_status = (mac_id<<8)|0; /*   MACID|OPMODE:0 means disconnect */
2023                 /* for STA,AP,ADHOC mode, report disconnect stauts to FW */
2024                 rtw_hal_set_hwreg(adapter, HW_VAR_H2C_MEDIA_STATUS_RPT, (u8 *)&media_status);
2025         }
2026
2027         if(check_fwstate(pmlmepriv, WIFI_AP_STATE))
2028         {
2029 #ifdef CONFIG_IOCTL_CFG80211
2030                 #ifdef COMPAT_KERNEL_RELEASE
2031
2032                 #elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)) || defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
2033                 rtw_cfg80211_indicate_sta_disassoc(adapter, pstadel->macaddr, *(u16*)pstadel->rsvd);
2034                 #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)) || defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER) */
2035 #endif /* CONFIG_IOCTL_CFG80211 */
2036
2037                 return;
2038         }
2039
2040         mlmeext_sta_del_event_callback(adapter);
2041
2042         spin_lock_bh(&pmlmepriv->lock);
2043
2044         if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) )
2045         {
2046                 #ifdef CONFIG_LAYER2_ROAMING
2047                 if (rtw_to_roaming(adapter) > 0)
2048                         pmlmepriv->to_roaming--; /* this stadel_event is caused by roaming, decrease to_roaming */
2049                 else if (rtw_to_roaming(adapter) == 0)
2050                         rtw_set_roaming(adapter, adapter->registrypriv.max_roaming_times);
2051                 if(*((unsigned short *)(pstadel->rsvd)) != WLAN_REASON_EXPIRATION_CHK)
2052                         rtw_set_roaming(adapter, 0); /* don't roam */
2053                 #endif
2054
2055                 rtw_free_uc_swdec_pending_queue(adapter);
2056
2057                 rtw_free_assoc_resources(adapter, 1);
2058                 rtw_indicate_disconnect(adapter);
2059                 spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
2060                 /*  remove the network entry in scanned_queue */
2061                 pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.MacAddress);
2062                 if (pwlan) {
2063                         pwlan->fixed = _FALSE;
2064                         rtw_free_network_nolock(pmlmepriv, pwlan);
2065                 }
2066                 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
2067
2068                 #ifdef CONFIG_LAYER2_ROAMING
2069                 _rtw_roaming(adapter, tgt_network);
2070                 #endif /* CONFIG_LAYER2_ROAMING */
2071
2072         }
2073
2074         if ( check_fwstate(pmlmepriv,WIFI_ADHOC_MASTER_STATE) ||
2075               check_fwstate(pmlmepriv,WIFI_ADHOC_STATE))
2076         {
2077
2078                 spin_lock_bh(&(pstapriv->sta_hash_lock));
2079                 rtw_free_stainfo(adapter,  psta);
2080                 spin_unlock_bh(&(pstapriv->sta_hash_lock));
2081
2082                 if(adapter->stapriv.asoc_sta_count== 1) /* a sta + bc/mc_stainfo (not Ibss_stainfo) */
2083                 {
2084                         spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
2085                         /* free old ibss network */
2086                         /* pwlan = rtw_find_network(&pmlmepriv->scanned_queue, pstadel->macaddr); */
2087                         pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.MacAddress);
2088                         if(pwlan)
2089                         {
2090                                 pwlan->fixed = _FALSE;
2091                                 rtw_free_network_nolock(pmlmepriv, pwlan);
2092                         }
2093                         spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
2094                         /* re-create ibss */
2095                         pdev_network = &(adapter->registrypriv.dev_network);
2096                         pibss = adapter->registrypriv.dev_network.MacAddress;
2097
2098                         memcpy(pdev_network, &tgt_network->network, get_WLAN_BSSID_EX_sz(&tgt_network->network));
2099
2100                         memset(&pdev_network->Ssid, 0, sizeof(NDIS_802_11_SSID));
2101                         memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(NDIS_802_11_SSID));
2102
2103                         rtw_update_registrypriv_dev_network(adapter);
2104
2105                         rtw_generate_random_ibss(pibss);
2106
2107                         if(check_fwstate(pmlmepriv,WIFI_ADHOC_STATE))
2108                         {
2109                                 set_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
2110                                 _clr_fwstate_(pmlmepriv, WIFI_ADHOC_STATE);
2111                         }
2112
2113                         if(rtw_createbss_cmd(adapter)!=_SUCCESS)
2114                         {
2115
2116                                 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("***Error=>stadel_event_callback: rtw_createbss_cmd status FAIL*** \n "));
2117
2118                         }
2119
2120                 }
2121
2122         }
2123
2124         spin_unlock_bh(&pmlmepriv->lock);
2125
2126 _func_exit_;
2127 }
2128
2129 void rtw_cpwm_event_callback(PADAPTER padapter, u8 *pbuf)
2130 {
2131 #ifdef CONFIG_LPS_LCLK
2132         struct reportpwrstate_parm *preportpwrstate;
2133 #endif
2134
2135 _func_enter_;
2136
2137         RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("+rtw_cpwm_event_callback !!!\n"));
2138 #ifdef CONFIG_LPS_LCLK
2139         preportpwrstate = (struct reportpwrstate_parm*)pbuf;
2140         preportpwrstate->state |= (u8)(padapter->pwrctrlpriv.cpwm_tog + 0x80);
2141         cpwm_int_hdl(padapter, preportpwrstate);
2142 #endif
2143
2144 _func_exit_;
2145 }
2146
2147 /*
2148 * _rtw_join_timeout_handler - Timeout/faliure handler for CMD JoinBss
2149 * @adapter: pointer to _adapter structure
2150 */
2151 void _rtw_join_timeout_handler (_adapter *adapter)
2152 {
2153         struct  mlme_priv *pmlmepriv = &adapter->mlmepriv;
2154 #ifdef CONFIG_LAYER2_ROAMING
2155         int do_join_r;
2156 #endif /* CONFIG_LAYER2_ROAMING */
2157
2158 _func_enter_;
2159
2160         DBG_8723A("%s, fw_state=%x\n", __FUNCTION__, get_fwstate(pmlmepriv));
2161
2162         if(adapter->bDriverStopped ||adapter->bSurpriseRemoved)
2163                 return;
2164
2165         spin_lock_bh(&pmlmepriv->lock);
2166
2167         #ifdef CONFIG_LAYER2_ROAMING
2168         if (rtw_to_roaming(adapter) > 0) { /* join timeout caused by roaming */
2169                 while(1) {
2170                         pmlmepriv->to_roaming--;
2171                         if (rtw_to_roaming(adapter) != 0) { /* try another */
2172                                 DBG_8723A("%s try another roaming\n", __FUNCTION__);
2173                                 if( _SUCCESS!=(do_join_r=rtw_do_join(adapter)) ) {
2174                                         DBG_8723A("%s roaming do_join return %d\n", __FUNCTION__ ,do_join_r);
2175                                         continue;
2176                                 }
2177                                 break;
2178                         } else {
2179                                 DBG_8723A("%s We've try roaming but fail\n", __FUNCTION__);
2180                                 rtw_indicate_disconnect(adapter);
2181                                 break;
2182                         }
2183                 }
2184
2185         } else
2186         #endif
2187         {
2188                 rtw_indicate_disconnect(adapter);
2189                 free_scanqueue(pmlmepriv);/*  */
2190
2191 #ifdef CONFIG_IOCTL_CFG80211
2192                 /* indicate disconnect for the case that join_timeout and check_fwstate != FW_LINKED */
2193                 rtw_cfg80211_indicate_disconnect(adapter);
2194 #endif /* CONFIG_IOCTL_CFG80211 */
2195
2196         }
2197
2198         spin_unlock_bh(&pmlmepriv->lock);
2199
2200 #ifdef CONFIG_DRVEXT_MODULE_WSC
2201         drvext_assoc_fail_indicate(&adapter->drvextpriv);
2202 #endif
2203
2204 _func_exit_;
2205 }
2206
2207 /*
2208 * rtw_scan_timeout_handler - Timeout/Faliure handler for CMD SiteSurvey
2209 * @adapter: pointer to _adapter structure
2210 */
2211 void rtw_scan_timeout_handler (_adapter *adapter)
2212 {
2213         struct  mlme_priv *pmlmepriv = &adapter->mlmepriv;
2214
2215         DBG_8723A(FUNC_ADPT_FMT" fw_state=%x\n", FUNC_ADPT_ARG(adapter), get_fwstate(pmlmepriv));
2216
2217         spin_lock_bh(&pmlmepriv->lock);
2218
2219         _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
2220
2221         spin_unlock_bh(&pmlmepriv->lock);
2222
2223         rtw_indicate_scan_done(adapter, _TRUE);
2224 }
2225
2226 static void rtw_auto_scan_handler(_adapter *padapter)
2227 {
2228         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2229         struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv;
2230
2231         /* auto site survey per 60sec */
2232         if(pmlmepriv->scan_interval >0)
2233         {
2234                 pmlmepriv->scan_interval--;
2235                 if(pmlmepriv->scan_interval==0)
2236                 {
2237 /*
2238                         if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
2239                         {
2240                                 DBG_8723A("exit %s when _FW_UNDER_SURVEY|_FW_UNDER_LINKING -> \n", __FUNCTION__);
2241                                 return;
2242                         }
2243
2244                         if(pmlmepriv->sitesurveyctrl.traffic_busy == _TRUE)
2245                         {
2246                                 DBG_8723A("%s exit cause traffic_busy(%x)\n",__FUNCTION__, pmlmepriv->sitesurveyctrl.traffic_busy);
2247                                 return;
2248                         }
2249 */
2250
2251 #ifdef CONFIG_CONCURRENT_MODE
2252                         if (rtw_buddy_adapter_up(padapter))
2253                         {
2254                                 if ((check_buddy_fwstate(padapter, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE) ||
2255                                         (padapter->pbuddy_adapter->mlmepriv.LinkDetectInfo.bBusyTraffic == _TRUE))
2256                                 {
2257                                         DBG_8723A("%s, but buddy_intf is under scanning or linking or BusyTraffic\n", __FUNCTION__);
2258                                         return;
2259                                 }
2260                         }
2261 #endif
2262
2263                         DBG_8723A("%s\n", __FUNCTION__);
2264
2265                         rtw_set_802_11_bssid_list_scan(padapter, NULL, 0);
2266
2267                         pmlmepriv->scan_interval = SCAN_INTERVAL;/*  30*2 sec = 60sec */
2268
2269                 }
2270
2271         }
2272 }
2273
2274 void rtw_dynamic_check_timer_handler(_adapter *adapter)
2275 {
2276 #ifdef CONFIG_AP_MODE
2277         struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
2278 #endif /* CONFIG_AP_MODE */
2279         struct registry_priv *pregistrypriv = &adapter->registrypriv;
2280 #ifdef CONFIG_CONCURRENT_MODE
2281         PADAPTER pbuddy_adapter = adapter->pbuddy_adapter;
2282 #endif
2283
2284         if(!adapter)
2285                 return;
2286 #if defined(CONFIG_CHECK_BT_HANG) && defined(CONFIG_BT_COEXIST)
2287         if(adapter->HalFunc.hal_checke_bt_hang)
2288                 adapter->HalFunc.hal_checke_bt_hang(adapter);
2289 #endif
2290         if(adapter->hw_init_completed == _FALSE)
2291                 return;
2292
2293         if ((adapter->bDriverStopped == _TRUE)||(adapter->bSurpriseRemoved== _TRUE))
2294                 return;
2295
2296 #ifdef CONFIG_CONCURRENT_MODE
2297         if(pbuddy_adapter)
2298         {
2299                 if(adapter->net_closed == _TRUE && pbuddy_adapter->net_closed == _TRUE)
2300                 {
2301                         return;
2302                 }
2303         }
2304         else
2305 #endif /* CONFIG_CONCURRENT_MODE */
2306         if(adapter->net_closed == _TRUE)
2307         {
2308                 return;
2309         }
2310
2311         rtw_dynamic_chk_wk_cmd(adapter);
2312
2313         if(pregistrypriv->wifi_spec==1)
2314         {
2315 #ifdef CONFIG_P2P
2316                 struct wifidirect_info *pwdinfo = &adapter->wdinfo;
2317                 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
2318 #endif
2319                 {
2320                         /* auto site survey */
2321                         rtw_auto_scan_handler(adapter);
2322                 }
2323         }
2324
2325 #ifndef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
2326 #ifdef CONFIG_AP_MODE
2327         if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
2328         {
2329                 expire_timeout_chk(adapter);
2330         }
2331 #endif
2332 #endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */
2333
2334 #ifdef CONFIG_BR_EXT
2335
2336 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35))
2337         rcu_read_lock();
2338 #endif  /*  (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35)) */
2339
2340 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
2341         if( adapter->pnetdev->br_port
2342 #else   /*  (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) */
2343         if( rcu_dereference(adapter->pnetdev->rx_handler_data)
2344 #endif  /*  (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) */
2345                 && (check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE) == _TRUE) )
2346         {
2347                 /*  expire NAT2.5 entry */
2348                 void nat25_db_expire(_adapter *priv);
2349                 nat25_db_expire(adapter);
2350
2351                 if (adapter->pppoe_connection_in_progress > 0) {
2352                         adapter->pppoe_connection_in_progress--;
2353                 }
2354
2355                 /*  due to rtw_dynamic_check_timer_handler() is called every 2 seconds */
2356                 if (adapter->pppoe_connection_in_progress > 0) {
2357                         adapter->pppoe_connection_in_progress--;
2358                 }
2359         }
2360
2361 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35))
2362         rcu_read_unlock();
2363 #endif  /*  (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35)) */
2364
2365 #endif  /*  CONFIG_BR_EXT */
2366 }
2367
2368 #ifdef CONFIG_SET_SCAN_DENY_TIMER
2369 inline bool rtw_is_scan_deny(_adapter *adapter)
2370 {
2371         struct mlme_priv *mlmepriv = &adapter->mlmepriv;
2372         return (atomic_read(&mlmepriv->set_scan_deny) != 0) ? _TRUE : _FALSE;
2373 }
2374
2375 inline void rtw_clear_scan_deny(_adapter *adapter)
2376 {
2377         struct mlme_priv *mlmepriv = &adapter->mlmepriv;
2378         atomic_set(&mlmepriv->set_scan_deny, 0);
2379         if (0)
2380         DBG_8723A(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(adapter));
2381 }
2382
2383 void rtw_set_scan_deny_timer_hdl(_adapter *adapter)
2384 {
2385         rtw_clear_scan_deny(adapter);
2386 }
2387
2388 void rtw_set_scan_deny(_adapter *adapter, u32 ms)
2389 {
2390         struct mlme_priv *mlmepriv = &adapter->mlmepriv;
2391 #ifdef CONFIG_CONCURRENT_MODE
2392         struct mlme_priv *b_mlmepriv;
2393 #endif
2394
2395         if (0)
2396         DBG_8723A(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(adapter));
2397         atomic_set(&mlmepriv->set_scan_deny, 1);
2398         _set_timer(&mlmepriv->set_scan_deny_timer, ms);
2399
2400 #ifdef CONFIG_CONCURRENT_MODE
2401         if (!adapter->pbuddy_adapter)
2402                 return;
2403
2404         if (0)
2405         DBG_8723A(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(adapter->pbuddy_adapter));
2406         b_mlmepriv = &adapter->pbuddy_adapter->mlmepriv;
2407         atomic_set(&b_mlmepriv->set_scan_deny, 1);
2408         _set_timer(&b_mlmepriv->set_scan_deny_timer, ms);
2409 #endif
2410 }
2411 #endif
2412
2413 #if defined(IEEE80211_SCAN_RESULT_EXPIRE)
2414 #define RTW_SCAN_RESULT_EXPIRE IEEE80211_SCAN_RESULT_EXPIRE/HZ*1000 -1000 /* 3000 -1000 */
2415 #else
2416 #define RTW_SCAN_RESULT_EXPIRE 2000
2417 #endif
2418
2419 /*
2420 * Select a new join candidate from the original @param candidate and @param competitor
2421 * @return _TRUE: candidate is updated
2422 * @return _FALSE: candidate is not updated
2423 */
2424 static int rtw_check_join_candidate(struct mlme_priv *pmlmepriv
2425         , struct wlan_network **candidate, struct wlan_network *competitor)
2426 {
2427         int updated = _FALSE;
2428         _adapter *adapter = container_of(pmlmepriv, _adapter, mlmepriv);
2429
2430         /* check bssid, if needed */
2431         if (pmlmepriv->assoc_by_bssid==_TRUE) {
2432                 if (memcmp(competitor->network.MacAddress,
2433                            pmlmepriv->assoc_bssid, ETH_ALEN))
2434                         goto exit;
2435         }
2436
2437         /* check ssid, if needed */
2438         if (pmlmepriv->assoc_ssid.Ssid && pmlmepriv->assoc_ssid.SsidLength) {
2439                 if (competitor->network.Ssid.SsidLength !=
2440                     pmlmepriv->assoc_ssid.SsidLength ||
2441                     memcmp(competitor->network.Ssid.Ssid,
2442                            pmlmepriv->assoc_ssid.Ssid,
2443                            pmlmepriv->assoc_ssid.SsidLength))
2444                         goto exit;
2445         }
2446
2447         if(rtw_is_desired_network(adapter, competitor)  == _FALSE)
2448                 goto exit;
2449
2450 #ifdef  CONFIG_LAYER2_ROAMING
2451         if(rtw_to_roaming(adapter) > 0) {
2452                 if(     rtw_get_passing_time_ms((u32)competitor->last_scanned) >= RTW_SCAN_RESULT_EXPIRE
2453                         || is_same_ess(&competitor->network, &pmlmepriv->cur_network.network) == _FALSE
2454                 )
2455                         goto exit;
2456         }
2457 #endif
2458
2459         if(*candidate == NULL ||(*candidate)->network.Rssi<competitor->network.Rssi )
2460         {
2461                 *candidate = competitor;
2462                 updated = _TRUE;
2463         }
2464
2465         if(updated){
2466 #ifdef  CONFIG_LAYER2_ROAMING
2467                 DBG_8723A("[by_bssid:%u][assoc_ssid:%s][to_roaming:%u] new candidate: %s("MAC_FMT") rssi:%d\n",
2468                         pmlmepriv->assoc_by_bssid,
2469                         pmlmepriv->assoc_ssid.Ssid,
2470                         rtw_to_roaming(adapter),
2471                         (*candidate)->network.Ssid.Ssid,
2472                         MAC_ARG((*candidate)->network.MacAddress),
2473                         (int)(*candidate)->network.Rssi);
2474 #else
2475                 DBG_8723A("[by_bssid:%u][assoc_ssid:%s][to_roaming:%u] new candidate: %s("MAC_FMT") rssi:%d\n",
2476                         pmlmepriv->assoc_by_bssid,
2477                         pmlmepriv->assoc_ssid.Ssid,
2478                         rtw_to_roaming(adapter),
2479                         (*candidate)->network.Ssid.Ssid,
2480                         MAC_ARG((*candidate)->network.MacAddress),
2481                         (int)(*candidate)->network.Rssi);
2482 #endif
2483         }
2484
2485 exit:
2486         return updated;
2487 }
2488
2489 /*
2490 Calling context:
2491 The caller of the sub-routine will be in critical section...
2492
2493 The caller must hold the following spinlock
2494
2495 pmlmepriv->lock
2496
2497 */
2498
2499 int rtw_select_and_join_from_scanned_queue(struct mlme_priv *pmlmepriv )
2500 {
2501         int ret;
2502         struct list_head        *phead;
2503         _adapter *adapter;
2504         _queue  *queue  = &(pmlmepriv->scanned_queue);
2505         struct  wlan_network    *pnetwork = NULL;
2506         struct  wlan_network    *candidate = NULL;
2507         u8              bSupportAntDiv = _FALSE;
2508
2509 _func_enter_;
2510
2511         spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
2512         phead = get_list_head(queue);
2513         adapter = (_adapter *)pmlmepriv->nic_hdl;
2514
2515         pmlmepriv->pscanned = get_next( phead );
2516
2517         while (!rtw_end_of_queue_search(phead, pmlmepriv->pscanned)) {
2518
2519                 pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned, struct wlan_network, list);
2520                 if(pnetwork==NULL){
2521                         RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("%s return _FAIL:(pnetwork==NULL)\n", __FUNCTION__));
2522                         ret = _FAIL;
2523                         goto exit;
2524                 }
2525
2526                 pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
2527
2528                 rtw_check_join_candidate(pmlmepriv, &candidate, pnetwork);
2529
2530         }
2531
2532         if(candidate == NULL) {
2533                 DBG_8723A("%s: return _FAIL(candidate == NULL)\n", __FUNCTION__);
2534 #ifdef CONFIG_WOWLAN
2535                 _clr_fwstate_(pmlmepriv, _FW_LINKED|_FW_UNDER_LINKING);
2536 #endif
2537                 ret = _FAIL;
2538                 goto exit;
2539         } else {
2540                 DBG_8723A("%s: candidate: %s("MAC_FMT", ch:%u)\n", __FUNCTION__,
2541                         candidate->network.Ssid.Ssid, MAC_ARG(candidate->network.MacAddress),
2542                         candidate->network.Configuration.DSConfig);
2543         }
2544
2545         /*  check for situation of  _FW_LINKED */
2546         if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
2547         {
2548                 DBG_8723A("%s: _FW_LINKED while ask_for_joinbss!!!\n", __FUNCTION__);
2549
2550                 rtw_disassoc_cmd(adapter, 0, _TRUE);
2551                 rtw_indicate_disconnect(adapter);
2552                 rtw_free_assoc_resources(adapter, 0);
2553         }
2554
2555         #ifdef CONFIG_ANTENNA_DIVERSITY
2556         rtw_hal_get_def_var(adapter, HAL_DEF_IS_SUPPORT_ANT_DIV, &(bSupportAntDiv));
2557         if(_TRUE == bSupportAntDiv)
2558         {
2559                 u8 CurrentAntenna;
2560                 rtw_hal_get_def_var(adapter, HAL_DEF_CURRENT_ANTENNA, &(CurrentAntenna));
2561                 DBG_8723A("#### Opt_Ant_(%s) , cur_Ant(%s)\n",
2562                         (2==candidate->network.PhyInfo.Optimum_antenna)?"A":"B",
2563                         (2==CurrentAntenna)?"A":"B"
2564                 );
2565         }
2566         #endif
2567         set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
2568         ret = rtw_joinbss_cmd(adapter, candidate);
2569
2570 exit:
2571         spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
2572
2573 _func_exit_;
2574
2575         return ret;
2576 }
2577
2578 int rtw_set_auth(_adapter * adapter,struct security_priv *psecuritypriv)
2579 {
2580         struct  cmd_obj* pcmd;
2581         struct  setauth_parm *psetauthparm;
2582         struct  cmd_priv        *pcmdpriv=&(adapter->cmdpriv);
2583         int             res=_SUCCESS;
2584
2585 _func_enter_;
2586
2587         pcmd = (struct  cmd_obj*)rtw_zmalloc(sizeof(struct      cmd_obj));
2588         if(pcmd==NULL){
2589                 res= _FAIL;  /* try again */
2590                 goto exit;
2591         }
2592
2593         psetauthparm=(struct setauth_parm*)rtw_zmalloc(sizeof(struct setauth_parm));
2594         if(psetauthparm==NULL){
2595                 rtw_mfree((unsigned char *)pcmd, sizeof(struct  cmd_obj));
2596                 res= _FAIL;
2597                 goto exit;
2598         }
2599
2600         memset(psetauthparm, 0, sizeof(struct setauth_parm));
2601         psetauthparm->mode=(unsigned char)psecuritypriv->dot11AuthAlgrthm;
2602
2603         pcmd->cmdcode = _SetAuth_CMD_;
2604         pcmd->parmbuf = (unsigned char *)psetauthparm;
2605         pcmd->cmdsz =  (sizeof(struct setauth_parm));
2606         pcmd->rsp = NULL;
2607         pcmd->rspsz = 0;
2608
2609         INIT_LIST_HEAD(&pcmd->list);
2610
2611         RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("after enqueue set_auth_cmd, auth_mode=%x\n", psecuritypriv->dot11AuthAlgrthm));
2612
2613         res = rtw_enqueue_cmd(pcmdpriv, pcmd);
2614
2615 exit:
2616
2617 _func_exit_;
2618
2619         return res;
2620 }
2621
2622 int rtw_set_key(_adapter * adapter,struct security_priv *psecuritypriv,int keyid, u8 set_tx)
2623 {
2624         u8      keylen;
2625         struct cmd_obj          *pcmd;
2626         struct setkey_parm      *psetkeyparm;
2627         struct cmd_priv         *pcmdpriv = &(adapter->cmdpriv);
2628         struct mlme_priv                *pmlmepriv = &(adapter->mlmepriv);
2629         int     res=_SUCCESS;
2630
2631 _func_enter_;
2632
2633         pcmd = (struct  cmd_obj*)rtw_zmalloc(sizeof(struct      cmd_obj));
2634         if(pcmd==NULL){
2635                 res= _FAIL;  /* try again */
2636                 goto exit;
2637         }
2638         psetkeyparm=(struct setkey_parm*)rtw_zmalloc(sizeof(struct setkey_parm));
2639         if(psetkeyparm==NULL){
2640                 rtw_mfree((unsigned char *)pcmd, sizeof(struct  cmd_obj));
2641                 res= _FAIL;
2642                 goto exit;
2643         }
2644
2645         memset(psetkeyparm, 0, sizeof(struct setkey_parm));
2646
2647         if(psecuritypriv->dot11AuthAlgrthm ==dot11AuthAlgrthm_8021X){
2648                 psetkeyparm->algorithm=(unsigned char)psecuritypriv->dot118021XGrpPrivacy;
2649                 RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("\n rtw_set_key: psetkeyparm->algorithm=(unsigned char)psecuritypriv->dot118021XGrpPrivacy=%d \n", psetkeyparm->algorithm));
2650         }
2651         else{
2652                 psetkeyparm->algorithm=(u8)psecuritypriv->dot11PrivacyAlgrthm;
2653                 RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("\n rtw_set_key: psetkeyparm->algorithm=(u8)psecuritypriv->dot11PrivacyAlgrthm=%d \n", psetkeyparm->algorithm));
2654
2655         }
2656         psetkeyparm->keyid = (u8)keyid;/* 0~3 */
2657         psetkeyparm->set_tx = set_tx;
2658         if (is_wep_enc(psetkeyparm->algorithm))
2659                 pmlmepriv->key_mask |= BIT(psetkeyparm->keyid);
2660
2661 #ifdef CONFIG_AUTOSUSPEND
2662         if( _TRUE  == adapter->pwrctrlpriv.bInternalAutoSuspend)
2663         {
2664                 adapter->pwrctrlpriv.wepkeymask = pmlmepriv->key_mask;
2665                 DBG_8723A("....AutoSuspend pwrctrlpriv.wepkeymask(%x)\n",adapter->pwrctrlpriv.wepkeymask);
2666         }
2667 #endif
2668         DBG_8723A("==> rtw_set_key algorithm(%x),keyid(%x),key_mask(%x)\n",psetkeyparm->algorithm,psetkeyparm->keyid,pmlmepriv->key_mask);
2669         RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("\n rtw_set_key: psetkeyparm->algorithm=%d psetkeyparm->keyid=(u8)keyid=%d \n",psetkeyparm->algorithm, keyid));
2670
2671         switch(psetkeyparm->algorithm){
2672
2673                 case _WEP40_:
2674                         keylen=5;
2675                         memcpy(&(psetkeyparm->key[0]), &(psecuritypriv->dot11DefKey[keyid].skey[0]), keylen);
2676                         break;
2677                 case _WEP104_:
2678                         keylen=13;
2679                         memcpy(&(psetkeyparm->key[0]), &(psecuritypriv->dot11DefKey[keyid].skey[0]), keylen);
2680                         break;
2681                 case _TKIP_:
2682                         keylen=16;
2683                         memcpy(&psetkeyparm->key, &psecuritypriv->dot118021XGrpKey[keyid], keylen);
2684                         psetkeyparm->grpkey=1;
2685                         break;
2686                 case _AES_:
2687                         keylen=16;
2688                         memcpy(&psetkeyparm->key, &psecuritypriv->dot118021XGrpKey[keyid], keylen);
2689                         psetkeyparm->grpkey=1;
2690                         break;
2691                 default:
2692                         RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("\n rtw_set_key:psecuritypriv->dot11PrivacyAlgrthm = %x (must be 1 or 2 or 4 or 5)\n",psecuritypriv->dot11PrivacyAlgrthm));
2693                         res= _FAIL;
2694                         goto exit;
2695         }
2696
2697         pcmd->cmdcode = _SetKey_CMD_;
2698         pcmd->parmbuf = (u8 *)psetkeyparm;
2699         pcmd->cmdsz =  (sizeof(struct setkey_parm));
2700         pcmd->rsp = NULL;
2701         pcmd->rspsz = 0;
2702
2703         INIT_LIST_HEAD(&pcmd->list);
2704
2705         /* sema_init(&(pcmd->cmd_sem), 0); */
2706
2707         res = rtw_enqueue_cmd(pcmdpriv, pcmd);
2708
2709 exit:
2710 _func_exit_;
2711         return res;
2712 }
2713
2714 /* adjust IEs for rtw_joinbss_cmd in WMM */
2715 int rtw_restruct_wmm_ie(_adapter *adapter, u8 *in_ie, u8 *out_ie, uint in_len, uint initial_out_len)
2716 {
2717         unsigned        int ielength=0;
2718         unsigned int i, j;
2719
2720         i = 12; /* after the fixed IE */
2721         while(i<in_len)
2722         {
2723                 ielength = initial_out_len;
2724
2725                 if(in_ie[i] == 0xDD && in_ie[i+2] == 0x00 && in_ie[i+3] == 0x50  && in_ie[i+4] == 0xF2 && in_ie[i+5] == 0x02 && i+5 < in_len) /* WMM element ID and OUI */
2726                 {
2727
2728                         /* Append WMM IE to the last index of out_ie */
2729                         for ( j = i; j < i + 9; j++ )
2730                         {
2731                             out_ie[ ielength] = in_ie[ j ];
2732                             ielength++;
2733                         }
2734                         out_ie[ initial_out_len + 1 ] = 0x07;
2735                         out_ie[ initial_out_len + 6 ] = 0x00;
2736                         out_ie[ initial_out_len + 8 ] = 0x00;
2737
2738                         break;
2739                 }
2740
2741                 i+=(in_ie[i+1]+2); /*  to the next IE element */
2742         }
2743
2744         return ielength;
2745 }
2746
2747 /*  */
2748 /*  Ported from 8185: IsInPreAuthKeyList(). (Renamed from SecIsInPreAuthKeyList(), 2006-10-13.) */
2749 /*  Added by Annie, 2006-05-07. */
2750 /*  */
2751 /*  Search by BSSID, */
2752 /*  Return Value: */
2753 /*              -1              :if there is no pre-auth key in the  table */
2754 /*              >=0             :if there is pre-auth key, and   return the entry id */
2755 /*  */
2756 /*  */
2757
2758 static int SecIsInPMKIDList(_adapter *Adapter, u8 *bssid)
2759 {
2760         struct security_priv *psecuritypriv=&Adapter->securitypriv;
2761         int i=0;
2762
2763         do
2764         {
2765                 if (psecuritypriv->PMKIDList[i].bUsed &&
2766                     !memcmp(psecuritypriv->PMKIDList[i].Bssid, bssid, ETH_ALEN))
2767                 {
2768                         break;
2769                 } else {
2770                         i++;
2771                         /* continue; */
2772                 }
2773
2774         }while(i<NUM_PMKID_CACHE);
2775
2776         if( i == NUM_PMKID_CACHE )
2777         {
2778                 i = -1;/*  Could not find. */
2779         }
2780         else
2781         {
2782                 /*  There is one Pre-Authentication Key for the specific BSSID. */
2783         }
2784
2785         return (i);
2786 }
2787
2788 /*  */
2789 /*  Check the RSN IE length */
2790 /*  If the RSN IE length <= 20, the RSN IE didn't include the PMKID information */
2791 /*  0-11th element in the array are the fixed IE */
2792 /*  12th element in the array is the IE */
2793 /*  13th element in the array is the IE length */
2794 /*  */
2795
2796 static int rtw_append_pmkid(_adapter *Adapter,int iEntry, u8 *ie, uint ie_len)
2797 {
2798         struct security_priv *psecuritypriv=&Adapter->securitypriv;
2799
2800         if(ie[13]<=20){
2801                 /*  The RSN IE didn't include the PMK ID, append the PMK information */
2802                         ie[ie_len]=1;
2803                         ie_len++;
2804                         ie[ie_len]=0;   /* PMKID count = 0x0100 */
2805                         ie_len++;
2806                         memcpy( &ie[ie_len], &psecuritypriv->PMKIDList[iEntry].PMKID, 16);
2807
2808                         ie_len+=16;
2809                         ie[13]+=18;/* PMKID length = 2+16 */
2810
2811         }
2812         return (ie_len);
2813 }
2814 int rtw_restruct_sec_ie(_adapter *adapter,u8 *in_ie, u8 *out_ie, uint in_len)
2815 {
2816         u8 authmode, securitytype, match;
2817         u8 sec_ie[255], uncst_oui[4], bkup_ie[255];
2818         u8 wpa_oui[4]={0x0, 0x50, 0xf2, 0x01};
2819         uint    ielength, cnt, remove_cnt;
2820         int iEntry;
2821
2822         struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
2823         struct security_priv *psecuritypriv=&adapter->securitypriv;
2824         uint    ndisauthmode=psecuritypriv->ndisauthtype;
2825         uint ndissecuritytype = psecuritypriv->ndisencryptstatus;
2826
2827 _func_enter_;
2828
2829         RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
2830                  ("+rtw_restruct_sec_ie: ndisauthmode=%d ndissecuritytype=%d\n",
2831                   ndisauthmode, ndissecuritytype));
2832
2833         /* copy fixed ie only */
2834         memcpy(out_ie, in_ie,12);
2835         ielength=12;
2836         if((ndisauthmode==Ndis802_11AuthModeWPA)||(ndisauthmode==Ndis802_11AuthModeWPAPSK))
2837                         authmode=_WPA_IE_ID_;
2838         if((ndisauthmode==Ndis802_11AuthModeWPA2)||(ndisauthmode==Ndis802_11AuthModeWPA2PSK))
2839                         authmode=_WPA2_IE_ID_;
2840
2841         if(check_fwstate(pmlmepriv, WIFI_UNDER_WPS))
2842         {
2843                 memcpy(out_ie+ielength, psecuritypriv->wps_ie, psecuritypriv->wps_ie_len);
2844
2845                 ielength += psecuritypriv->wps_ie_len;
2846         }
2847         else if((authmode==_WPA_IE_ID_)||(authmode==_WPA2_IE_ID_))
2848         {
2849                 /* copy RSN or SSN */
2850                 memcpy(&out_ie[ielength], &psecuritypriv->supplicant_ie[0], psecuritypriv->supplicant_ie[1]+2);
2851                 ielength+=psecuritypriv->supplicant_ie[1]+2;
2852                 rtw_report_sec_ie(adapter, authmode, psecuritypriv->supplicant_ie);
2853
2854 #ifdef CONFIG_DRVEXT_MODULE
2855                 drvext_report_sec_ie(&adapter->drvextpriv, authmode, sec_ie);
2856 #endif
2857         }
2858
2859         iEntry = SecIsInPMKIDList(adapter, pmlmepriv->assoc_bssid);
2860         if(iEntry<0)
2861         {
2862                 return ielength;
2863         }
2864         else
2865         {
2866                 if(authmode == _WPA2_IE_ID_)
2867                 {
2868                         ielength=rtw_append_pmkid(adapter, iEntry, out_ie, ielength);
2869                 }
2870         }
2871
2872 _func_exit_;
2873
2874         return ielength;
2875 }
2876
2877 void rtw_init_registrypriv_dev_network( _adapter* adapter)
2878 {
2879         struct registry_priv* pregistrypriv = &adapter->registrypriv;
2880         struct eeprom_priv* peepriv = &adapter->eeprompriv;
2881         WLAN_BSSID_EX    *pdev_network = &pregistrypriv->dev_network;
2882         u8 *myhwaddr = myid(peepriv);
2883
2884 _func_enter_;
2885
2886         memcpy(pdev_network->MacAddress, myhwaddr, ETH_ALEN);
2887
2888         memcpy(&pdev_network->Ssid, &pregistrypriv->ssid, sizeof(NDIS_802_11_SSID));
2889
2890         pdev_network->Configuration.Length=sizeof(NDIS_802_11_CONFIGURATION);
2891         pdev_network->Configuration.BeaconPeriod = 100;
2892         pdev_network->Configuration.FHConfig.Length = 0;
2893         pdev_network->Configuration.FHConfig.HopPattern = 0;
2894         pdev_network->Configuration.FHConfig.HopSet = 0;
2895         pdev_network->Configuration.FHConfig.DwellTime = 0;
2896
2897 _func_exit_;
2898 }
2899
2900 void rtw_update_registrypriv_dev_network(_adapter* adapter)
2901 {
2902         int sz=0;
2903         struct registry_priv* pregistrypriv = &adapter->registrypriv;
2904         WLAN_BSSID_EX    *pdev_network = &pregistrypriv->dev_network;
2905         struct  security_priv*  psecuritypriv = &adapter->securitypriv;
2906         struct  wlan_network    *cur_network = &adapter->mlmepriv.cur_network;
2907         /* struct       xmit_priv       *pxmitpriv = &adapter->xmitpriv; */
2908
2909 _func_enter_;
2910
2911         pdev_network->Privacy = (psecuritypriv->dot11PrivacyAlgrthm > 0 ? 1 : 0) ; /*  adhoc no 802.1x */
2912
2913         pdev_network->Rssi = 0;
2914
2915         switch(pregistrypriv->wireless_mode)
2916         {
2917                 case WIRELESS_11B:
2918                         pdev_network->NetworkTypeInUse = (Ndis802_11DS);
2919                         break;
2920                 case WIRELESS_11G:
2921                 case WIRELESS_11BG:
2922                 case WIRELESS_11_24N:
2923                 case WIRELESS_11G_24N:
2924                 case WIRELESS_11BG_24N:
2925                         pdev_network->NetworkTypeInUse = (Ndis802_11OFDM24);
2926                         break;
2927                 case WIRELESS_11A:
2928                 case WIRELESS_11A_5N:
2929                         pdev_network->NetworkTypeInUse = (Ndis802_11OFDM5);
2930                         break;
2931                 case WIRELESS_11ABGN:
2932                         if(pregistrypriv->channel > 14)
2933                                 pdev_network->NetworkTypeInUse = (Ndis802_11OFDM5);
2934                         else
2935                                 pdev_network->NetworkTypeInUse = (Ndis802_11OFDM24);
2936                         break;
2937                 default :
2938                         /*  TODO */
2939                         break;
2940         }
2941
2942         pdev_network->Configuration.DSConfig = (pregistrypriv->channel);
2943         RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("pregistrypriv->channel=%d, pdev_network->Configuration.DSConfig=0x%x\n", pregistrypriv->channel, pdev_network->Configuration.DSConfig));
2944
2945         if(cur_network->network.InfrastructureMode == Ndis802_11IBSS)
2946                 pdev_network->Configuration.ATIMWindow = (0);
2947
2948         pdev_network->InfrastructureMode = (cur_network->network.InfrastructureMode);
2949
2950         /*  1. Supported rates */
2951         /*  2. IE */
2952
2953         sz = rtw_generate_ie(pregistrypriv);
2954
2955         pdev_network->IELength = sz;
2956
2957         pdev_network->Length = get_WLAN_BSSID_EX_sz((WLAN_BSSID_EX  *)pdev_network);
2958
2959         /* notes: translate IELength & Length after assign the Length to cmdsz in createbss_cmd(); */
2960         /* pdev_network->IELength = cpu_to_le32(sz); */
2961
2962 _func_exit_;
2963 }
2964
2965 void rtw_get_encrypt_decrypt_from_registrypriv(_adapter* adapter)
2966 {
2967 _func_enter_;
2968
2969 _func_exit_;
2970 }
2971
2972 /* the fucntion is at passive_level */
2973 void rtw_joinbss_reset(_adapter *padapter)
2974 {
2975         u8      threshold;
2976         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
2977
2978 #ifdef CONFIG_80211N_HT
2979         struct ht_priv          *phtpriv = &pmlmepriv->htpriv;
2980 #endif
2981
2982         /* todo: if you want to do something io/reg/hw setting before join_bss, please add code here */
2983
2984 #ifdef CONFIG_80211N_HT
2985
2986         pmlmepriv->num_FortyMHzIntolerant = 0;
2987
2988         pmlmepriv->num_sta_no_ht = 0;
2989
2990         phtpriv->ampdu_enable = _FALSE;/* reset to disabled */
2991
2992         /*  TH=1 => means that invalidate usb rx aggregation */
2993         /*  TH=0 => means that validate usb rx aggregation, use init value. */
2994         if(phtpriv->ht_option)
2995         {
2996                 if(padapter->registrypriv.wifi_spec==1)
2997                         threshold = 1;
2998                 else
2999                         threshold = 0;
3000                 rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold));
3001         }
3002         else
3003         {
3004                 threshold = 1;
3005                 rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold));
3006         }
3007
3008 #endif
3009 }
3010
3011 #ifdef CONFIG_80211N_HT
3012
3013 /* the fucntion is >= passive_level */
3014 unsigned int rtw_restructure_ht_ie(_adapter *padapter, u8 *in_ie, u8 *out_ie, uint in_len, uint *pout_len)
3015 {
3016         u32 ielen, out_len;
3017         int max_rx_ampdu_factor;
3018         unsigned char *p, *pframe;
3019         struct ieee80211_ht_cap ht_capie;
3020         unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
3021         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
3022         struct qos_priv         *pqospriv= &pmlmepriv->qospriv;
3023         struct ht_priv          *phtpriv = &pmlmepriv->htpriv;
3024
3025         phtpriv->ht_option = _FALSE;
3026
3027         p = rtw_get_ie(in_ie+12, _HT_CAPABILITY_IE_, &ielen, in_len-12);
3028
3029         if(p && ielen>0)
3030         {
3031                 if(pqospriv->qos_option == 0)
3032                 {
3033                         out_len = *pout_len;
3034                         pframe = rtw_set_ie(out_ie+out_len, _VENDOR_SPECIFIC_IE_,
3035                                                                 _WMM_IE_Length_, WMM_IE, pout_len);
3036
3037                         pqospriv->qos_option = 1;
3038                 }
3039
3040                 out_len = *pout_len;
3041
3042                 memset(&ht_capie, 0, sizeof(struct ieee80211_ht_cap));
3043
3044                 ht_capie.cap_info = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
3045                         IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 |
3046                         IEEE80211_HT_CAP_TX_STBC | IEEE80211_HT_CAP_DSSSCCK40;
3047
3048                 {
3049                         u32 rx_packet_offset, max_recvbuf_sz;
3050                         rtw_hal_get_def_var(padapter, HAL_DEF_RX_PACKET_OFFSET, &rx_packet_offset);
3051                         rtw_hal_get_def_var(padapter, HAL_DEF_MAX_RECVBUF_SZ, &max_recvbuf_sz);
3052                         /* if(max_recvbuf_sz-rx_packet_offset>(8191-256)) { */
3053                         /*      DBG_8723A("%s IEEE80211_HT_CAP_MAX_AMSDU is set\n", __FUNCTION__); */
3054                         /*      ht_capie.cap_info = ht_capie.cap_info |IEEE80211_HT_CAP_MAX_AMSDU; */
3055                         /*  */
3056                 }
3057                 rtw_hal_get_def_var(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor);
3058                 ht_capie.ampdu_params_info = (max_rx_ampdu_factor&0x03);
3059
3060                 if(padapter->securitypriv.dot11PrivacyAlgrthm == _AES_ )
3061                         ht_capie.ampdu_params_info |= (IEEE80211_HT_AMPDU_PARM_DENSITY&(0x07<<2));
3062                 else
3063                         ht_capie.ampdu_params_info |= (IEEE80211_HT_AMPDU_PARM_DENSITY&0x00);
3064
3065                 pframe = rtw_set_ie(out_ie+out_len, _HT_CAPABILITY_IE_,
3066                                                         sizeof(struct ieee80211_ht_cap), (unsigned char*)&ht_capie, pout_len);
3067
3068                 phtpriv->ht_option = _TRUE;
3069
3070                 p = rtw_get_ie(in_ie+12, _HT_ADD_INFO_IE_, &ielen, in_len-12);
3071                 if(p && (ielen==sizeof(struct ieee80211_ht_addt_info)))
3072                 {
3073                         out_len = *pout_len;
3074                         pframe = rtw_set_ie(out_ie+out_len, _HT_ADD_INFO_IE_, ielen, p+2 , pout_len);
3075                 }
3076
3077         }
3078
3079         return (phtpriv->ht_option);
3080 }
3081
3082 /* the fucntion is > passive_level (in critical_section) */
3083 void rtw_update_ht_cap(_adapter *padapter, u8 *pie, uint ie_len)
3084 {
3085         u8 *p, max_ampdu_sz;
3086         int len;
3087         /* struct sta_info *bmc_sta, *psta; */
3088         struct ieee80211_ht_cap *pht_capie;
3089         struct ieee80211_ht_addt_info *pht_addtinfo;
3090         /* struct recv_reorder_ctrl *preorder_ctrl; */
3091         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
3092         struct ht_priv          *phtpriv = &pmlmepriv->htpriv;
3093         /* struct recv_priv *precvpriv = &padapter->recvpriv; */
3094         struct registry_priv *pregistrypriv = &padapter->registrypriv;
3095         /* struct wlan_network *pcur_network = &(pmlmepriv->cur_network);; */
3096         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
3097         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
3098
3099         if(!phtpriv->ht_option)
3100                 return;
3101
3102         if ((!pmlmeinfo->HT_info_enable) || (!pmlmeinfo->HT_caps_enable))
3103                 return;
3104
3105         DBG_8723A("+rtw_update_ht_cap()\n");
3106
3107         /* maybe needs check if ap supports rx ampdu. */
3108         if((phtpriv->ampdu_enable==_FALSE) &&(pregistrypriv->ampdu_enable==1))
3109         {
3110                 if(pregistrypriv->wifi_spec==1)
3111                 {
3112                         phtpriv->ampdu_enable = _FALSE;
3113                 }
3114                 else
3115                 {
3116                         phtpriv->ampdu_enable = _TRUE;
3117                 }
3118         }
3119         else if(pregistrypriv->ampdu_enable==2)
3120         {
3121                 phtpriv->ampdu_enable = _TRUE;
3122         }
3123
3124         /* check Max Rx A-MPDU Size */
3125         len = 0;
3126         p = rtw_get_ie(pie+sizeof (NDIS_802_11_FIXED_IEs), _HT_CAPABILITY_IE_, &len, ie_len-sizeof (NDIS_802_11_FIXED_IEs));
3127         if(p && len>0)
3128         {
3129                 pht_capie = (struct ieee80211_ht_cap *)(p+2);
3130                 max_ampdu_sz = (pht_capie->ampdu_params_info & IEEE80211_HT_AMPDU_PARM_FACTOR);
3131                 max_ampdu_sz = 1 << (max_ampdu_sz+3); /*  max_ampdu_sz (kbytes); */
3132
3133                 /* DBG_8723A("rtw_update_ht_cap(): max_ampdu_sz=%d\n", max_ampdu_sz); */
3134                 phtpriv->rx_ampdu_maxlen = max_ampdu_sz;
3135
3136         }
3137
3138         len=0;
3139         p = rtw_get_ie(pie+sizeof (NDIS_802_11_FIXED_IEs), _HT_ADD_INFO_IE_, &len, ie_len-sizeof (NDIS_802_11_FIXED_IEs));
3140         if(p && len>0)
3141         {
3142                 pht_addtinfo = (struct ieee80211_ht_addt_info *)(p+2);
3143                 /* todo: */
3144         }
3145
3146         /* update cur_bwmode & cur_ch_offset */
3147         if ((pregistrypriv->cbw40_enable) &&
3148                 (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & BIT(1)) &&
3149                 (pmlmeinfo->HT_info.infos[0] & BIT(2)))
3150         {
3151                 int i;
3152                 u8      rf_type;
3153
3154                 padapter->HalFunc.GetHwRegHandler(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
3155
3156                 /* update the MCS rates */
3157                 for (i = 0; i < 16; i++)
3158                 {
3159                         if((rf_type == RF_1T1R) || (rf_type == RF_1T2R))
3160                         {
3161                                 pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[i];
3162                         }
3163                         else
3164                         {
3165                                 #ifdef CONFIG_DISABLE_MCS13TO15
3166                                 if(pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40 && pregistrypriv->wifi_spec != 1 )
3167                                 {
3168                                         pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_2R_MCS13TO15_OFF[i];
3169                                 }
3170                                 else
3171                                         pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_2R[i];
3172                                 #else
3173                                 pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_2R[i];
3174                                 #endif /* CONFIG_DISABLE_MCS13TO15 */
3175                         }
3176                         #ifdef RTL8192C_RECONFIG_TO_1T1R
3177                         {
3178                                 pmlmeinfo->HT_caps.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[i];
3179                         }
3180                         #endif
3181                 }
3182                 /* switch to the 40M Hz mode accoring to the AP */
3183                 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
3184                 switch ((pmlmeinfo->HT_info.infos[0] & 0x3))
3185                 {
3186                         case HT_EXTCHNL_OFFSET_UPPER:
3187                                 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
3188                                 break;
3189
3190                         case HT_EXTCHNL_OFFSET_LOWER:
3191                                 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
3192                                 break;
3193
3194                         default:
3195                                 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
3196                                 break;
3197                 }
3198         }
3199
3200         /*  */
3201         /*  Config SM Power Save setting */
3202         /*  */
3203         pmlmeinfo->SM_PS = (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & 0x0C) >> 2;
3204         if(pmlmeinfo->SM_PS == WLAN_HT_CAP_SM_PS_STATIC)
3205                 DBG_8723A("%s(): WLAN_HT_CAP_SM_PS_STATIC\n",__FUNCTION__);
3206
3207         /*  */
3208         /*  Config current HT Protection mode. */
3209         /*  */
3210         pmlmeinfo->HT_protection = pmlmeinfo->HT_info.infos[1] & 0x3;
3211 }
3212
3213 void rtw_issue_addbareq_cmd(_adapter *padapter, struct xmit_frame *pxmitframe)
3214 {
3215         u8 issued;
3216         int priority;
3217         struct sta_info *psta=NULL;
3218         struct ht_priv  *phtpriv;
3219         struct pkt_attrib *pattrib =&pxmitframe->attrib;
3220         s32 bmcst = IS_MCAST(pattrib->ra);
3221
3222         if(bmcst || (padapter->mlmepriv.LinkDetectInfo.NumTxOkInPeriod<100))
3223                 return;
3224
3225         priority = pattrib->priority;
3226
3227         if (pattrib->psta)
3228                 psta = pattrib->psta;
3229         else
3230         {
3231                 DBG_8723A("%s, call rtw_get_stainfo()\n", __func__);
3232                 psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
3233         }
3234
3235         if(psta==NULL)
3236         {
3237                 DBG_8723A("%s, psta==NUL\n", __func__);
3238                 return;
3239         }
3240
3241         if(!(psta->state &_FW_LINKED))
3242         {
3243                 DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);
3244                 return;
3245         }
3246
3247         phtpriv = &psta->htpriv;
3248
3249         if((phtpriv->ht_option==_TRUE) && (phtpriv->ampdu_enable==_TRUE))
3250         {
3251                 issued = (phtpriv->agg_enable_bitmap>>priority)&0x1;
3252                 issued |= (phtpriv->candidate_tid_bitmap>>priority)&0x1;
3253
3254                 if(0==issued)
3255                 {
3256                         DBG_8723A("rtw_issue_addbareq_cmd, p=%d\n", priority);
3257                         psta->htpriv.candidate_tid_bitmap |= BIT((u8)priority);
3258                         rtw_addbareq_cmd(padapter,(u8) priority, pattrib->ra);
3259                 }
3260         }
3261 }
3262
3263 #endif
3264
3265 #ifdef CONFIG_LAYER2_ROAMING
3266 inline void rtw_set_roaming(_adapter *adapter, u8 to_roaming)
3267 {
3268         if (to_roaming == 0)
3269                 adapter->mlmepriv.to_join = _FALSE;
3270         adapter->mlmepriv.to_roaming = to_roaming;
3271 }
3272
3273 inline u8 rtw_to_roaming(_adapter *adapter)
3274 {
3275         return adapter->mlmepriv.to_roaming;
3276 }
3277
3278 void rtw_roaming(_adapter *padapter, struct wlan_network *tgt_network)
3279 {
3280         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
3281
3282         spin_lock_bh(&pmlmepriv->lock);
3283         _rtw_roaming(padapter, tgt_network);
3284         spin_unlock_bh(&pmlmepriv->lock);
3285 }
3286 void _rtw_roaming(_adapter *padapter, struct wlan_network *tgt_network)
3287 {
3288         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
3289         int do_join_r;
3290
3291         struct wlan_network *pnetwork;
3292
3293         if(tgt_network != NULL)
3294                 pnetwork = tgt_network;
3295         else
3296                 pnetwork = &pmlmepriv->cur_network;
3297
3298         if(0 < rtw_to_roaming(padapter)) {
3299                 DBG_8723A("roaming from %s("MAC_FMT"), length:%d\n",
3300                                 pnetwork->network.Ssid.Ssid, MAC_ARG(pnetwork->network.MacAddress),
3301                                 pnetwork->network.Ssid.SsidLength);
3302                 memcpy(&pmlmepriv->assoc_ssid, &pnetwork->network.Ssid, sizeof(NDIS_802_11_SSID));
3303
3304                 pmlmepriv->assoc_by_bssid = _FALSE;
3305
3306                 while(1) {
3307                         if( _SUCCESS==(do_join_r=rtw_do_join(padapter)) ) {
3308                                 break;
3309                         } else {
3310                                 DBG_8723A("roaming do_join return %d\n", do_join_r);
3311                                 pmlmepriv->to_roaming--;
3312
3313                                 if(0< rtw_to_roaming(padapter)) {
3314                                         continue;
3315                                 } else {
3316                                         DBG_8723A("%s(%d) -to roaming fail, indicate_disconnect\n", __FUNCTION__,__LINE__);
3317                                         rtw_indicate_disconnect(padapter);
3318                                         break;
3319                                 }
3320                         }
3321                 }
3322         }
3323 }
3324 #endif
3325
3326 int rtw_linked_check(_adapter *padapter)
3327 {
3328         if(     (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE) ||
3329                         (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE) == _TRUE))
3330         {
3331                 if(padapter->stapriv.asoc_sta_count > 2)
3332                         return _TRUE;
3333         }
3334         else
3335         {       /* Station mode */
3336                 if(check_fwstate(&padapter->mlmepriv, _FW_LINKED)== _TRUE)
3337                         return _TRUE;
3338         }
3339         return _FALSE;
3340 }
3341
3342 #ifdef CONFIG_CONCURRENT_MODE
3343 int rtw_buddy_adapter_up(_adapter *padapter)
3344 {
3345         int res = _FALSE;
3346
3347         if(padapter == NULL)
3348                 return res;
3349
3350         if(padapter->pbuddy_adapter == NULL)
3351         {
3352                 res = _FALSE;
3353         }
3354         else if( (padapter->pbuddy_adapter->bDriverStopped) || (padapter->pbuddy_adapter->bSurpriseRemoved) ||
3355                 (padapter->pbuddy_adapter->bup == _FALSE) || (padapter->pbuddy_adapter->hw_init_completed == _FALSE))
3356         {
3357                 res = _FALSE;
3358         }
3359         else
3360         {
3361                 res = _TRUE;
3362         }
3363
3364         return res;
3365 }
3366
3367 int check_buddy_fwstate(_adapter *padapter, int state)
3368 {
3369         if(padapter == NULL)
3370                 return _FALSE;
3371
3372         if(padapter->pbuddy_adapter == NULL)
3373                 return _FALSE;
3374
3375         if ((state == WIFI_FW_NULL_STATE) &&
3376                 (padapter->pbuddy_adapter->mlmepriv.fw_state == WIFI_FW_NULL_STATE))
3377                 return _TRUE;
3378
3379         if (padapter->pbuddy_adapter->mlmepriv.fw_state & state)
3380                 return _TRUE;
3381
3382         return _FALSE;
3383 }
3384
3385 #endif /* CONFIG_CONCURRENT_MODE */